summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.mailmap1
-rw-r--r--AUTHORS.md2
-rw-r--r--DONORS.md59
-rw-r--r--core/crypto/crypto.cpp3
-rw-r--r--core/input/gamecontrollerdb.txt17
-rw-r--r--core/io/image.cpp38
-rw-r--r--core/math/dynamic_bvh.cpp29
-rw-r--r--core/math/dynamic_bvh.h35
-rw-r--r--core/math/quat.cpp9
-rw-r--r--core/object/class_db.cpp4
-rw-r--r--core/os/os.cpp28
-rw-r--r--core/os/os.h7
-rw-r--r--core/string/ustring.cpp2
-rw-r--r--core/templates/list.h2
-rw-r--r--core/templates/vector.h4
-rw-r--r--core/variant/array.cpp37
-rw-r--r--core/variant/array.h9
-rw-r--r--core/variant/binder_common.h66
-rw-r--r--core/variant/variant_call.cpp365
-rw-r--r--core/variant/variant_setget.cpp120
-rw-r--r--doc/classes/Array.xml14
-rw-r--r--doc/classes/ArrayMesh.xml10
-rw-r--r--doc/classes/ColorPicker.xml12
-rw-r--r--doc/classes/Control.xml65
-rw-r--r--doc/classes/Directory.xml1
-rw-r--r--doc/classes/EditorInterface.xml8
-rw-r--r--doc/classes/EditorPlugin.xml2
-rw-r--r--doc/classes/Environment.xml2
-rw-r--r--doc/classes/GIProbe.xml1
-rw-r--r--doc/classes/ImageTexture.xml6
-rw-r--r--doc/classes/PackedByteArray.xml14
-rw-r--r--doc/classes/PackedColorArray.xml14
-rw-r--r--doc/classes/PackedFloat32Array.xml14
-rw-r--r--doc/classes/PackedFloat64Array.xml14
-rw-r--r--doc/classes/PackedInt32Array.xml14
-rw-r--r--doc/classes/PackedInt64Array.xml14
-rw-r--r--doc/classes/PackedStringArray.xml14
-rw-r--r--doc/classes/PackedVector2Array.xml14
-rw-r--r--doc/classes/PackedVector3Array.xml14
-rw-r--r--doc/classes/Skeleton3D.xml10
-rw-r--r--doc/classes/StreamPeerTCP.xml4
-rw-r--r--doc/classes/Tabs.xml3
-rw-r--r--doc/classes/TextParagraph.xml14
-rw-r--r--doc/classes/TextServer.xml25
-rw-r--r--doc/classes/Texture2D.xml12
-rw-r--r--doc/classes/Theme.xml2
-rw-r--r--doc/classes/TileMap.xml2
-rw-r--r--doc/classes/Viewport.xml4
-rw-r--r--doc/classes/VisualShaderNodeComment.xml23
-rw-r--r--doc/classes/XRPositionalTracker.xml2
-rw-r--r--doc/classes/XRServer.xml45
-rw-r--r--doc/classes/bool.xml4
-rw-r--r--doc/classes/float.xml45
-rw-r--r--doc/classes/int.xml98
-rw-r--r--drivers/png/resource_saver_png.cpp2
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp19
-rw-r--r--drivers/vulkan/vulkan_context.cpp333
-rw-r--r--drivers/vulkan/vulkan_context.h45
-rw-r--r--editor/animation_bezier_editor.cpp2
-rw-r--r--editor/animation_track_editor.cpp4
-rw-r--r--editor/animation_track_editor_plugins.cpp72
-rw-r--r--editor/code_editor.cpp4
-rw-r--r--editor/debugger/editor_profiler.cpp196
-rw-r--r--editor/debugger/editor_profiler.h6
-rw-r--r--editor/dependency_editor.cpp6
-rw-r--r--editor/editor_audio_buses.cpp2
-rw-r--r--editor/editor_export.cpp13
-rw-r--r--editor/editor_export.h1
-rw-r--r--editor/editor_file_dialog.cpp2
-rw-r--r--editor/editor_help.cpp2
-rw-r--r--editor/editor_inspector.cpp10
-rw-r--r--editor/editor_node.cpp44
-rw-r--r--editor/editor_plugin.cpp5
-rw-r--r--editor/editor_plugin.h1
-rw-r--r--editor/editor_properties.cpp12
-rw-r--r--editor/editor_resource_preview.cpp2
-rw-r--r--editor/editor_run_native.cpp2
-rw-r--r--editor/editor_spin_slider.cpp2
-rw-r--r--editor/editor_themes.cpp3
-rw-r--r--editor/editor_translation_parser.cpp6
-rw-r--r--editor/filesystem_dock.cpp12
-rw-r--r--editor/icons/GuiScrollBg.svg2
-rw-r--r--editor/icons/GuiScrollGrabber.svg2
-rw-r--r--editor/icons/PickerCursor.svg1
-rw-r--r--editor/import/editor_import_collada.cpp2
-rw-r--r--editor/import/resource_importer_obj.cpp2
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp6
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp22
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp2
-rw-r--r--editor/plugins/editor_preview_plugins.cpp4
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp51
-rw-r--r--editor/plugins/node_3d_editor_plugin.h2
-rw-r--r--editor/plugins/script_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp3
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp57
-rw-r--r--editor/plugins/sprite_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp2
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp177
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h23
-rw-r--r--editor/project_export.cpp1
-rw-r--r--editor/project_manager.cpp78
-rw-r--r--editor/project_manager.h5
-rw-r--r--editor/property_editor.cpp3
-rw-r--r--editor/scene_tree_dock.cpp12
-rw-r--r--editor/settings_config_dialog.cpp5
-rw-r--r--editor/translations/af.po22
-rw-r--r--editor/translations/ar.po9
-rw-r--r--editor/translations/bg.po9
-rw-r--r--editor/translations/bn.po9
-rw-r--r--editor/translations/br.po9
-rw-r--r--editor/translations/ca.po9
-rw-r--r--editor/translations/cs.po51
-rw-r--r--editor/translations/da.po119
-rw-r--r--editor/translations/de.po15
-rw-r--r--editor/translations/editor.pot9
-rw-r--r--editor/translations/el.po24
-rw-r--r--editor/translations/eo.po9
-rw-r--r--editor/translations/es.po61
-rw-r--r--editor/translations/es_AR.po15
-rw-r--r--editor/translations/et.po9
-rw-r--r--editor/translations/eu.po9
-rw-r--r--editor/translations/fa.po9
-rw-r--r--editor/translations/fi.po20
-rw-r--r--editor/translations/fil.po9
-rw-r--r--editor/translations/fr.po19
-rw-r--r--editor/translations/ga.po9
-rw-r--r--editor/translations/gl.po9
-rw-r--r--editor/translations/he.po9
-rw-r--r--editor/translations/hi.po9
-rw-r--r--editor/translations/hr.po9
-rw-r--r--editor/translations/hu.po445
-rw-r--r--editor/translations/id.po353
-rw-r--r--editor/translations/is.po9
-rw-r--r--editor/translations/it.po37
-rw-r--r--editor/translations/ja.po19
-rw-r--r--editor/translations/ka.po9
-rw-r--r--editor/translations/ko.po17
-rw-r--r--editor/translations/lt.po9
-rw-r--r--editor/translations/lv.po9
-rw-r--r--editor/translations/mi.po9
-rw-r--r--editor/translations/mk.po9
-rw-r--r--editor/translations/ml.po9
-rw-r--r--editor/translations/mr.po9
-rw-r--r--editor/translations/ms.po9
-rw-r--r--editor/translations/nb.po227
-rw-r--r--editor/translations/nl.po9
-rw-r--r--editor/translations/or.po9
-rw-r--r--editor/translations/pl.po17
-rw-r--r--editor/translations/pr.po9
-rw-r--r--editor/translations/pt.po9
-rw-r--r--editor/translations/pt_BR.po64
-rw-r--r--editor/translations/ro.po69
-rw-r--r--editor/translations/ru.po21
-rw-r--r--editor/translations/si.po9
-rw-r--r--editor/translations/sk.po9
-rw-r--r--editor/translations/sl.po9
-rw-r--r--editor/translations/sq.po9
-rw-r--r--editor/translations/sr_Cyrl.po9
-rw-r--r--editor/translations/sr_Latn.po9
-rw-r--r--editor/translations/sv.po653
-rw-r--r--editor/translations/ta.po9
-rw-r--r--editor/translations/te.po9
-rw-r--r--editor/translations/th.po121
-rw-r--r--editor/translations/tr.po26
-rw-r--r--editor/translations/tzm.po9
-rw-r--r--editor/translations/uk.po17
-rw-r--r--editor/translations/ur_PK.po9
-rw-r--r--editor/translations/vi.po2062
-rw-r--r--editor/translations/zh_CN.po25
-rw-r--r--editor/translations/zh_HK.po9
-rw-r--r--editor/translations/zh_TW.po9
-rw-r--r--main/main.cpp28
-rw-r--r--modules/bullet/space_bullet.cpp4
-rw-r--r--modules/csg/csg.cpp2
-rw-r--r--modules/csg/csg_shape.cpp2
-rw-r--r--modules/fbx/data/fbx_skeleton.cpp2
-rw-r--r--modules/fbx/editor_scene_importer_fbx.cpp15
-rw-r--r--modules/fbx/editor_scene_importer_fbx.h2
-rw-r--r--modules/fbx/fbx_parser/ByteSwapper.h3
-rw-r--r--modules/fbx/fbx_parser/FBXAnimation.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXDocument.cpp4
-rw-r--r--modules/fbx/fbx_parser/FBXDocument.h2
-rw-r--r--modules/fbx/fbx_parser/FBXDocumentUtil.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXImportSettings.h71
-rw-r--r--modules/fbx/fbx_parser/FBXMaterial.cpp8
-rw-r--r--modules/fbx/fbx_parser/FBXMeshGeometry.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXParseTools.h2
-rw-r--r--modules/fbx/fbx_parser/FBXParser.cpp2
-rw-r--r--modules/fbx/fbx_parser/FBXProperties.cpp14
-rw-r--r--modules/fbx/fbx_parser/FBXProperties.h1
-rw-r--r--modules/fbx/fbx_parser/FBXUtil.cpp6
-rw-r--r--modules/fbx/tools/import_utils.h2
-rw-r--r--modules/fbx/tools/validation_tools.h3
-rw-r--r--modules/gdnative/gdnative.cpp2
-rw-r--r--modules/gdnative/gdnative_api.json2
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h1
-rw-r--r--modules/gdnative/include/text/godot_text.h3
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp40
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp7
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h1
-rw-r--r--modules/gdnative/text/text_server_gdnative.cpp10
-rw-r--r--modules/gdnative/text/text_server_gdnative.h2
-rw-r--r--modules/gdnative/xr/xr_interface_gdnative.cpp25
-rw-r--r--modules/gdnavigation/nav_map.cpp4
-rw-r--r--modules/gdscript/gdscript.cpp40
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp325
-rw-r--r--modules/gdscript/gdscript_analyzer.h5
-rw-r--r--modules/gdscript/gdscript_byte_codegen.cpp152
-rw-r--r--modules/gdscript/gdscript_byte_codegen.h53
-rw-r--r--modules/gdscript/gdscript_codegen.h6
-rw-r--r--modules/gdscript/gdscript_compiler.cpp78
-rw-r--r--modules/gdscript/gdscript_compiler.h2
-rw-r--r--modules/gdscript/gdscript_disassembler.cpp153
-rw-r--r--modules/gdscript/gdscript_editor.cpp56
-rw-r--r--modules/gdscript/gdscript_function.h99
-rw-r--r--modules/gdscript/gdscript_parser.cpp159
-rw-r--r--modules/gdscript/gdscript_parser.h63
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp2
-rw-r--r--modules/gdscript/gdscript_vm.cpp447
-rw-r--r--modules/gdscript/register_types.cpp1
-rw-r--r--modules/glslang/register_types.cpp63
-rw-r--r--modules/gltf/editor_scene_importer_gltf.h6
-rw-r--r--modules/gltf/gltf_document.cpp176
-rw-r--r--modules/minimp3/audio_stream_mp3.cpp3
-rw-r--r--modules/opensimplex/doc_classes/NoiseTexture.xml5
-rw-r--r--modules/opensimplex/noise_texture.cpp14
-rw-r--r--modules/opensimplex/noise_texture.h6
-rw-r--r--modules/text_server_adv/dynamic_font_adv.cpp31
-rw-r--r--modules/text_server_adv/dynamic_font_adv.h2
-rw-r--r--modules/text_server_adv/font_adv.h6
-rw-r--r--modules/text_server_adv/script_iterator.cpp6
-rw-r--r--modules/text_server_adv/text_server_adv.cpp10
-rw-r--r--modules/text_server_adv/text_server_adv.h2
-rw-r--r--modules/text_server_fb/dynamic_font_fb.cpp23
-rw-r--r--modules/text_server_fb/dynamic_font_fb.h2
-rw-r--r--modules/text_server_fb/font_fb.h2
-rw-r--r--modules/text_server_fb/text_server_fb.cpp7
-rw-r--r--modules/text_server_fb/text_server_fb.h2
-rw-r--r--modules/visual_script/visual_script.cpp17
-rw-r--r--modules/visual_script/visual_script_editor.cpp6
-rw-r--r--modules/websocket/doc_classes/WebSocketClient.xml1
-rw-r--r--modules/webxr/webxr_interface.h2
-rw-r--r--modules/webxr/webxr_interface_js.cpp10
-rw-r--r--modules/webxr/webxr_interface_js.h2
-rw-r--r--platform/android/export/export.cpp16
-rw-r--r--platform/android/export/gradle_export_util.h15
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java24
-rw-r--r--platform/javascript/display_server_javascript.cpp4
-rw-r--r--platform/javascript/export/export.cpp2
-rw-r--r--platform/javascript/godot_js.h1
-rw-r--r--platform/javascript/js/engine/engine.js28
-rw-r--r--platform/javascript/js/engine/preloader.js17
-rw-r--r--platform/javascript/js/libs/library_godot_display.js13
-rw-r--r--platform/javascript/js/libs/library_godot_fetch.js13
-rw-r--r--platform/linuxbsd/display_server_x11.cpp12
-rw-r--r--platform/linuxbsd/joypad_linux.cpp9
-rw-r--r--platform/osx/display_server_osx.mm4
-rw-r--r--platform/osx/export/export.cpp14
-rw-r--r--platform/uwp/export/export.cpp20
-rw-r--r--platform/windows/display_server_windows.cpp6
-rw-r--r--scene/2d/animated_sprite_2d.cpp3
-rw-r--r--scene/2d/touch_screen_button.cpp2
-rw-r--r--scene/3d/skeleton_3d.cpp12
-rw-r--r--scene/3d/skeleton_3d.h1
-rw-r--r--scene/3d/skeleton_ik_3d.cpp85
-rw-r--r--scene/3d/skeleton_ik_3d.h2
-rw-r--r--scene/3d/sprite_3d.h4
-rw-r--r--scene/3d/voxelizer.cpp4
-rw-r--r--scene/3d/xr_nodes.cpp32
-rw-r--r--scene/animation/animation_node_state_machine.cpp2
-rw-r--r--scene/gui/base_button.cpp4
-rw-r--r--scene/gui/color_picker.cpp388
-rw-r--r--scene/gui/color_picker.h49
-rw-r--r--scene/gui/control.cpp95
-rw-r--r--scene/gui/control.h7
-rw-r--r--scene/gui/file_dialog.cpp2
-rw-r--r--scene/gui/gradient_edit.cpp2
-rw-r--r--scene/gui/graph_edit.cpp25
-rw-r--r--scene/gui/graph_edit.h2
-rw-r--r--scene/gui/graph_node.cpp2
-rw-r--r--scene/gui/item_list.cpp2
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/menu_button.cpp2
-rw-r--r--scene/gui/popup_menu.cpp2
-rw-r--r--scene/gui/rich_text_label.cpp26
-rw-r--r--scene/gui/scroll_bar.cpp2
-rw-r--r--scene/gui/scroll_container.cpp2
-rw-r--r--scene/gui/slider.cpp2
-rw-r--r--scene/gui/spin_box.cpp2
-rw-r--r--scene/gui/split_container.cpp2
-rw-r--r--scene/gui/subviewport_container.cpp4
-rw-r--r--scene/gui/tab_container.cpp2
-rw-r--r--scene/gui/tabs.cpp61
-rw-r--r--scene/gui/tabs.h4
-rw-r--r--scene/gui/text_edit.cpp2
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/main/canvas_item.cpp4
-rw-r--r--scene/main/canvas_item.h2
-rw-r--r--scene/main/http_request.cpp2
-rw-r--r--scene/main/node.cpp7
-rw-r--r--scene/main/viewport.cpp20
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/register_scene_types.cpp5
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp2
-rw-r--r--scene/resources/default_theme/default_theme.cpp3
-rw-r--r--scene/resources/default_theme/picker_cursor.pngbin0 -> 300 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/material.cpp18
-rw-r--r--scene/resources/mesh.cpp17
-rw-r--r--scene/resources/mesh.h2
-rw-r--r--scene/resources/polygon_path_finder.cpp2
-rw-r--r--scene/resources/primitive_meshes.cpp3
-rw-r--r--scene/resources/primitive_meshes.h1
-rw-r--r--scene/resources/text_paragraph.cpp17
-rw-r--r--scene/resources/text_paragraph.h3
-rw-r--r--scene/resources/texture.cpp22
-rw-r--r--scene/resources/texture.h12
-rw-r--r--scene/resources/theme.cpp8
-rw-r--r--scene/resources/visual_shader.cpp64
-rw-r--r--scene/resources/visual_shader.h33
-rw-r--r--scene/resources/visual_shader_nodes.cpp48
-rw-r--r--scene/resources/visual_shader_nodes.h7
-rw-r--r--servers/camera_server.cpp2
-rw-r--r--servers/physics_2d/area_2d_sw.cpp8
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp8
-rw-r--r--servers/physics_3d/area_3d_sw.cpp8
-rw-r--r--servers/physics_3d/shape_3d_sw.cpp3
-rw-r--r--servers/physics_3d/step_3d_sw.cpp5
-rw-r--r--servers/rendering/renderer_rd/SCsub1
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/SCsub5
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp (renamed from servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp)1019
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h (renamed from servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h)191
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp807
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h210
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_compositor_rd.h2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp21
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_gi_rd.h3
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.cpp86
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_render_rd.h10
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp10
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.h73
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_render.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl9
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl12
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl2
-rw-r--r--servers/rendering/renderer_scene_render.h2
-rw-r--r--servers/rendering/rendering_device.cpp2
-rw-r--r--servers/rendering/rendering_device.h35
-rw-r--r--servers/rendering/shader_language.cpp14
-rw-r--r--servers/text_server.cpp22
-rw-r--r--servers/text_server.h11
-rw-r--r--servers/xr/xr_positional_tracker.h4
-rw-r--r--servers/xr_server.cpp23
-rw-r--r--servers/xr_server.h10
-rw-r--r--tests/test_dictionary.h159
-rw-r--r--tests/test_geometry_2d.h2
-rw-r--r--tests/test_list.h2
-rw-r--r--tests/test_main.cpp2
-rw-r--r--tests/test_path_3d.h85
362 files changed, 8951 insertions, 5133 deletions
diff --git a/.mailmap b/.mailmap
index dfbd13e612..3cb0a91356 100644
--- a/.mailmap
+++ b/.mailmap
@@ -66,6 +66,7 @@ Juan Linietsky <reduzio@gmail.com> <red@kyoko>
Julian Murgia <the.straton@gmail.com>
Kanabenki <lucien.menassol@gmail.com> <18357657+Kanabenki@users.noreply.github.com>
Kelly Thomas <kelly.thomas@hotmail.com.au>
+Kongfa Waroros <gongpha@hotmail.com>
K. S. Ernest (iFire) Lee <ernest.lee@chibifire.com>
Leon Krause <lk@leonkrause.com> <eska@eska.me>
Leon Krause <lk@leonkrause.com> <eska014@users.noreply.github.com>
diff --git a/AUTHORS.md b/AUTHORS.md
index 8c26d2892b..7c5eb0c56b 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -100,6 +100,7 @@ name is available.
James Buck (jbuck3)
Jérôme Gully (Nutriz)
Jia Jun Chai (SkyLucilfer)
+ jmb462
Joan Fons Sanchez (JFonS)
Johannes Witt (HaSa1002)
Johan Manuel (29jm)
@@ -108,6 +109,7 @@ name is available.
Julian Murgia (StraToN)
Justo Delgado (mrcdk)
Kelly Thomas (KellyThomas)
+ Kongfa Waroros (gongpha)
Kostadin Damyanov (Max-Might)
K. S. Ernest (iFire) Lee (fire)
lawnjelly
diff --git a/DONORS.md b/DONORS.md
index 614ef1486a..77fa564a1b 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -40,6 +40,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Alejandro Saucedo
alex brown
Andrew Dunai
+ anti666
Ben Nolan
blurp
CD
@@ -51,6 +52,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Digital Grows
Dov Zimring
Edward Flick
+ Florian Neumann
Gamechuck
GameDev.net
Hein-Pieter van Braam
@@ -78,7 +80,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Steve
Thomas Krampl
Tristan Pemble
- VilliHaukka
Violin Iliev
Xwdit
@@ -98,7 +99,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Don B
Ed Morley
Ellen Poe
- Florian Neumann
Florian Rämisch
Forge
Gamejunkey
@@ -110,6 +110,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Jon Woodward
Karl Werf
Klavdij Voncina
+ kuku
Lex Steers
Luke
Maciej Pendolski
@@ -144,14 +145,12 @@ generous deed immortalized in the next stable release of Godot Engine.
Adam Nakonieczny
Adrian Adamiak
- Aleksey Korotkevich
Alexander J Maynard
Alex de la Mare
Alexey Dyadchenko
Alex Khayrullin
alice gambrell
Andreas Funke
- André Frélicot
Andrew Cunningham
Antanas Paskauskas
Antoni Batchelli
@@ -180,7 +179,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Donn Eddy
Easypete
Edgar Sun
+ Eric Brand
Eugenio Hugo Salgüero Jáñez
+ EXUREI
flesk
F S
Gabrielius Vaiškūnas
@@ -207,6 +208,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Joshie Sparks
Joshua Flores
Joshua Lesperance
+ Juan T Chen
Juan Velandia
Judd
Julian Todd
@@ -217,7 +219,6 @@ generous deed immortalized in the next stable release of Godot Engine.
kickmaniac
kinfox
Kos
- kuku
Lachie
Lain Ballard
Laszlo Kiss
@@ -225,7 +226,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Leo Fidel R Liban
Liam Smyth
Luc-Frédéric Langis
- luka duren
+ Åukasz Nowak
MadScientistCarl
Marcelo Dornbusch Lopes
Marcus Dobler
@@ -241,13 +242,13 @@ generous deed immortalized in the next stable release of Godot Engine.
medecau
Michael
Michael Dürwald
- Michael Noll
Michael Policastro
MightyPossum
MikadoSC
MuffinManKen
+ nate etan
Nick Abousselam
- Nick Barovic
+ Nicole Barovic
Oliver Dick
Oscar Campos
Patrick Ting
@@ -262,6 +263,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Raymond Harris
Raz A
Rene Tailleur
+ Rhodochrone
Ricardo Alcantara
Robert Larnach
Robert Willes
@@ -282,10 +284,11 @@ generous deed immortalized in the next stable release of Godot Engine.
Shishir Tandale
SKison
Song Junwoo
- spilldata
+ spacechase0
Stephan Hennion
Steven Landow
Stoned Xander
+ Sven F.
Thomas Bjarnelöf
Thomas Kurz
Tim Howard
@@ -310,6 +313,7 @@ generous deed immortalized in the next stable release of Godot Engine.
1D_Inc
Abraham Haskins
Adam
+ Adam Brown
Adam Brunnmeier
Adam Carr
Adam Long
@@ -322,7 +326,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Agustinus Arya
Ahmet Kalyoncu
Aidan O'Flannagain
- AJ Austinson
Aki Mimoto
Alan Beauchamp
Alberto Vilches
@@ -335,7 +338,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Alexander Walter (SilvanuZ)
Alexandre Beaudoin
alex clavelle
- Alex Schmidt
+ Alex (Well Done Games)
Allan Davis
Allen Schade
Anders Marstein Kruke
@@ -389,7 +392,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Chad Steadman
Charles Alston
Chris Chapin
- Chris Jagusch
Chris Langford
Christian Clavet
Christian Mauduit
@@ -413,7 +415,9 @@ generous deed immortalized in the next stable release of Godot Engine.
David May
David Maziarka
David Woodard
+ deadwithbread
Devin Carraway
+ Diego Pereira
Dmitry Fisher
Dmytro Korchynskyi
Dominik Wetzel
@@ -431,20 +435,20 @@ generous deed immortalized in the next stable release of Godot Engine.
Elgenzay
Elias Nykrem
Ephemeral
+ Eric Stokes
Eric Walkingshaw
Eric Williams
Erkki Seppälä
Evan Rose
Faisal Alkubaisi
Fancy Ants Studios
+ fby
Fekinox
Felix Bohmann
Flaredown
Forty Doubleu
Francois Holland
Frank
- FuDiggity
- gamedev by Celio
Game Endeavor
Gareth Knowles
Gary Thomas
@@ -477,12 +481,13 @@ generous deed immortalized in the next stable release of Godot Engine.
Jako Danar
James
James A F Manley
+ James Quincy
James Thomas
Jamie Massey
Jan Vetulani
JARKKO PARVIAINEN
+ Jason Bolton
Jason Uechi
- Jean-Baptiste LEPESME
Jeff Hungerford
Jennifer Graves
Jesse Dubay
@@ -504,8 +509,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Jorge Araya Navarro
Jose C. Rubio
Joseph Catrambone
+ Josep Sanchez
Josh Taylor
- Josue David
+ Joshua Heidrich
jromkjrom
Juanfran
Juan Uys
@@ -526,7 +532,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Kenneth Lee
Kent Jofur
Ketafuki
- Kevin McPhillips
Kiri Jolly
Kjetil Haugland
Konstantin Goncharov
@@ -544,7 +549,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Leonardo Dimano
Lin Chear
Linus Lind Lundgren
- Lionel Gaillard
Luigi Renna
Luis Gaemperle
Luis M
@@ -564,6 +568,7 @@ generous deed immortalized in the next stable release of Godot Engine.
Mathieu
Matt Edwards
Matthew Booe
+ Matt Sylvia
Max Fiedler
Maxime Blade
Maxwell
@@ -577,15 +582,17 @@ generous deed immortalized in the next stable release of Godot Engine.
Michał Skwarek
MidoriBunn 'tis BS
Mikayla
+ Mike
Mike Birkhead
+ Mike Copley
Mike Cunningham
Mitchell J. Wagner
+ MJacred
Molinghu
Molly Jameson
MrAZIE
Nathan Fish
Nathaniel
- Natrim
nee
neighty
Neil Blakey-Milner
@@ -593,7 +600,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Nerdforge
Nerdyninja
Nicholas
- Nick Allen
Nick Macholl
Niclas Eriksen
Nicolas Goll-Perrier
@@ -602,16 +608,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Nima Farid
NZ
oceoh
+ Okatima
OKV
Oleg Reva
Oleksandr Kryvonos
Omar Delarosa
Oriol Muñoz Princep
Oscar Domingo
- Parinya Teerakasemsuk
- patricio lara briones
Patrick Brock
- Patrick Dully
Patrick Nafarrete
Paul Gieske
Paweł Kowal
@@ -620,9 +624,9 @@ generous deed immortalized in the next stable release of Godot Engine.
Peter Richmond
Petrus Prinsloo
Philip Cohoe
+ Philip Ludington (MrPhil)
Pierre Caye
Piotr Góral
- Pipo
Point08
Preethi Vaidyanathan
pwab
@@ -655,7 +659,6 @@ generous deed immortalized in the next stable release of Godot Engine.
Sean Lynch
Sebastian Michailidis
SeongWan Kim
- Serenitor
Sergey
Sergiy Onenko
Shane
@@ -671,6 +674,7 @@ generous deed immortalized in the next stable release of Godot Engine.
smo1704
soft circles
Squirrel
+ Stéphane Roussel
Steve Cloete
summerblind
Sung soo Choi
@@ -679,7 +683,6 @@ generous deed immortalized in the next stable release of Godot Engine.
tannhauser_gate
Tarch
Terry
- The Liquidator
Theodore Lindsey
TheVoiceInMyHead
thomas
@@ -690,12 +693,14 @@ generous deed immortalized in the next stable release of Godot Engine.
Tim Erskine
Tim Gleason
Timothy B. MacDonald
+ TMoney
Tobias Bradtke
Tom Coxon
Toni Duran
Tony Zhao
Torgeir Lilleskog
Torsten Crass
+ toupeira
Travis O'Brien
Trent Skinner
tril zerobyte
@@ -725,8 +730,8 @@ generous deed immortalized in the next stable release of Godot Engine.
x1212
xenomat
Yegor Smirnov
- Zack Yang
Zak Stephens
+ Эльдар Будагов
蕭惟å…
## Bronze donors
diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp
index 6b3953f588..fe913549c9 100644
--- a/core/crypto/crypto.cpp
+++ b/core/crypto/crypto.cpp
@@ -157,8 +157,9 @@ RES ResourceFormatLoaderCrypto::load(const String &p_path, const String &p_origi
return key;
} else if (el == "pub") {
CryptoKey *key = CryptoKey::create();
- if (key)
+ if (key) {
key->load(p_path, true);
+ }
return key;
}
return nullptr;
diff --git a/core/input/gamecontrollerdb.txt b/core/input/gamecontrollerdb.txt
index f2a3135b05..884fb9550c 100644
--- a/core/input/gamecontrollerdb.txt
+++ b/core/input/gamecontrollerdb.txt
@@ -65,6 +65,7 @@
03000000808300000300000000000000,Betop Gamepad,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a4,start:b9,x:b3,y:b0,platform:Windows,
030000006b1400000055000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Windows,
030000006b1400000103000000000000,Bigben PS3 Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Windows,
+03000000120c0000210e000000000000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Windows,
0300000066f700000500000000000000,BrutalLegendTest,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b9,x:b0,y:b3,platform:Windows,
03000000d81d00000b00000000000000,BUFFALO BSGP1601 Series ,a:b5,b:b3,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b8,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b9,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b13,x:b4,y:b2,platform:Windows,
03000000e82000006058000000000000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Windows,
@@ -374,6 +375,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c62400001a89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b12,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b14,leftshoulder:b6,leftstick:b15,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b16,righttrigger:a4,rightx:a2,righty:a3,start:b13,x:b3,y:b4,platform:Mac OS X,
03000000c62400001b89000000010000,BDA MOGA XP5-X Plus,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Mac OS X,
03000000d62000002a79000000010000,BDA PS4 Fightpad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Mac OS X,
+03000000120c0000200e000000010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Mac OS X,
+03000000120c0000210e000000010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Mac OS X,
030000008305000031b0000000000000,Cideko AK08b,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Mac OS X,
03000000260900008888000088020000,Cyber Gadget GameCube Controller,a:b0,b:b1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,lefttrigger:a4,leftx:a0,lefty:a1,rightshoulder:b6,righttrigger:a5,rightx:a2,righty:a3~,start:b7,x:b2,y:b3,platform:Mac OS X,
03000000a306000022f6000001030000,Cyborg V.3 Rumble Pad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:+a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:-a3,rightx:a2,righty:a4,start:b9,x:b0,y:b3,platform:Mac OS X,
@@ -552,6 +555,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c31100000791000011010000,Be1 GC101 GAMEPAD 1.03 mode,a:b0,b:b1,back:b10,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b14,righttrigger:a4,rightx:a2,righty:a3,start:b11,x:b3,y:b4,platform:Linux,
030000005e0400008e02000003030000,Be1 GC101 Xbox 360 Controller mode,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,platform:Linux,
+03000000120c0000200e000011010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a5,lefttrigger:a3,righttrigger:a4,platform:Linux,
+03000000120c0000210e000011010000,Brook Mars,a:b1,b:b2,x:b0,y:b3,back:b8,guide:b12,start:b9,leftstick:b10,rightstick:b11,leftshoulder:b4,rightshoulder:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:b6,righttrigger:b7,platform:Linux,
03000000ffff0000ffff000000010000,Chinese-made Xbox Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b5,leftstick:b8,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b2,rightstick:b9,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b3,y:b4,platform:Linux,
03000000e82000006058000001010000,Cideko AK08b,a:b2,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b0,platform:Linux,
030000000b0400003365000000010000,Competition Pro,a:b0,b:b1,back:b2,leftx:a0,lefty:a1,start:b3,platform:Linux,
@@ -680,9 +685,11 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
060000007e0500000820000000000000,Nintendo Combined Joy-Cons (joycond),a:b0,b:b1,back:b9,dpdown:b15,dpleft:b16,dpright:b17,dpup:b14,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
030000007e0500003703000000016800,Nintendo GameCube Controller,a:b0,b:b2,dpdown:b6,dpleft:b4,dpright:b5,dpup:b7,lefttrigger:a4,leftx:a0,lefty:a1~,rightshoulder:b9,righttrigger:a5,rightx:a2,righty:a3~,start:b8,x:b1,y:b3,platform:Linux,
03000000790000004618000010010000,Nintendo GameCube Controller Adapter,a:b1,b:b2,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,rightx:a5~,righty:a2~,start:b9,x:b0,y:b3,platform:Linux,
+050000007e0500000620000001800000,Nintendo Switch Left Joy-Con,a:b9,b:b8,x:b7,y:b10,back:b5,start:b0,leftstick:b6,leftshoulder:b2,rightshoulder:b4,leftx:a1,lefty:a0~,platform:Linux,
+050000007e0500000720000001800000,Nintendo Switch Right Joy-Con,a:b1,b:b2,x:b0,y:b3,back:b9,start:b8,leftstick:b10,leftshoulder:b4,rightshoulder:b6,leftx:a1~,lefty:a0~,platform:Linux,
050000007e0500000920000001000000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
-050000007e0500000920000001800000,Nintendo Switch Pro Controller (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
-030000007e0500000920000011810000,Nintendo Switch Pro Controller Wired (joycond),a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
+050000007e0500000920000001800000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
+030000007e0500000920000011810000,Nintendo Switch Pro Controller,a:b0,b:b1,back:b9,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b11,leftshoulder:b5,leftstick:b12,lefttrigger:b7,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b13,righttrigger:b8,rightx:a2,righty:a3,start:b10,x:b3,y:b2,platform:Linux,
050000007e0500003003000001000000,Nintendo Wii Remote Pro Controller,a:b0,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b16,dpup:b13,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b3,y:b2,platform:Linux,
05000000010000000100000003000000,Nintendo Wiimote,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b10,leftshoulder:b4,leftstick:b11,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b12,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b2,y:b3,platform:Linux,
030000000d0500000308000010010000,Nostromo n45 Dual Analog Gamepad,a:b0,b:b1,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b9,leftshoulder:b4,leftstick:b12,lefttrigger:b5,leftx:a0,lefty:a1,rightshoulder:b6,rightstick:b11,righttrigger:b7,rightx:a3,righty:a2,start:b10,x:b2,y:b3,platform:Linux,
@@ -715,7 +722,9 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000c62400000053000000010000,PowerA,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400003a54000001010000,PowerA 1428124-01,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000d62000006dca000011010000,PowerA Pro Ex,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
+03000000d62000000228000001010000,PowerA Wired Controller for Xbox One,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
03000000c62400001a58000001010000,PowerA Xbox One Cabled,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
+03000000c62400001a54000001010000,PowerA Xbox One Mini Wired Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
030000006d040000d2ca000011010000,Precision Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
03000000ff1100004133000010010000,PS2 Controller,a:b2,b:b1,back:b8,leftshoulder:b6,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b5,start:b9,x:b3,y:b0,platform:Linux,
03000000341a00003608000011010000,PS3 Controller,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:b7,rightx:a2,righty:a3,start:b9,x:b0,y:b3,platform:Linux,
@@ -801,7 +810,8 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
03000000de2800000112000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800000211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
03000000de2800004211000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
-03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
+03000000de2800000211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
+03000000de2800004211000011010000,Steam Controller,a:b2,b:b3,back:b10,dpdown:b18,dpleft:b19,dpright:b20,dpup:b17,guide:b12,leftshoulder:b6,leftstick:b13,lefttrigger:b8,leftx:a0,lefty:a1,paddle1:b15,paddle2:b16,rightshoulder:b7,righttrigger:b9,rightx:a2,righty:a3,start:b11,x:b4,y:b5,platform:Linux,
03000000de280000fc11000001000000,Steam Controller,a:b0,b:b1,back:b6,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b10,righttrigger:a5,rightx:a3,righty:a4,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000212000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
05000000de2800000511000001000000,Steam Controller,a:b0,b:b1,back:b6,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,guide:b8,leftshoulder:b4,leftstick:b9,lefttrigger:a2,leftx:a0,lefty:a1,paddle1:b11,paddle2:b10,rightshoulder:b5,righttrigger:a3,start:b7,x:b2,y:b3,platform:Linux,
@@ -890,6 +900,7 @@ xinput,XInput Controller,a:b0,b:b1,back:b6,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,
050000003512000020ab000000780f00,8BitDo SNES30 Gamepad,a:b21,b:b20,back:b30,dpdown:+a1,dpleft:-a0,dpright:+a0,dpup:-a1,leftshoulder:b26,rightshoulder:b27,start:b31,x:b24,y:b23,platform:Android,
05000000c82d000018900000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
05000000c82d000030320000ffff0f00,8BitDo Zero 2,a:b1,b:b0,back:b4,leftshoulder:b9,leftx:a0,lefty:a1,rightshoulder:b10,start:b6,x:b3,y:b2,platform:Android,
+38383337343564366131323064613561,Brook Mars,a:b1,b:b19,x:b0,y:b2,leftshoulder:b3,rightshoulder:b20,lefttrigger:b9,righttrigger:b10,back:b17,start:b18,leftx:a0,lefty:a1,rightx:a2,righty:a3,leftstick:b15,rightstick:b6,platform:Android,
05000000bc20000000550000ffff3f00,GameSir G3w,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a5,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
05000000d6020000e5890000dfff3f00,GPD XD Plus,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:a4,rightx:a2,righty:a5,start:b6,x:b2,y:b3,platform:Android,
0500000031366332860c44aadfff0f00,GS Gamepad,a:b0,b:b1,back:b4,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b9,leftstick:b7,lefttrigger:b15,leftx:a0,lefty:a1,rightshoulder:b10,rightstick:b8,righttrigger:b16,rightx:a2,righty:a3,start:b6,x:b2,y:b3,platform:Android,
diff --git a/core/io/image.cpp b/core/io/image.cpp
index 5d46d75efe..873eb66f33 100644
--- a/core/io/image.cpp
+++ b/core/io/image.cpp
@@ -3010,26 +3010,28 @@ Image::UsedChannels Image::detect_used_channels(CompressSource p_source) {
ERR_FAIL_COND_V(is_compressed(), USED_CHANNELS_RGBA);
bool r = false, g = false, b = false, a = false, c = false;
- for (int i = 0; i < width; i++) {
- for (int j = 0; j < height; j++) {
- Color col = get_pixel(i, j);
+ const uint8_t *data_ptr = data.ptr();
- if (col.r > 0.001) {
- r = true;
- }
- if (col.g > 0.001) {
- g = true;
- }
- if (col.b > 0.001) {
- b = true;
- }
- if (col.a < 0.999) {
- a = true;
- }
+ uint32_t data_total = width * height;
- if (col.r != col.b || col.r != col.g || col.b != col.g) {
- c = true;
- }
+ for (uint32_t i = 0; i < data_total; i++) {
+ Color col = _get_color_at_ofs(data_ptr, i);
+
+ if (col.r > 0.001) {
+ r = true;
+ }
+ if (col.g > 0.001) {
+ g = true;
+ }
+ if (col.b > 0.001) {
+ b = true;
+ }
+ if (col.a < 0.999) {
+ a = true;
+ }
+
+ if (col.r != col.b || col.r != col.g || col.b != col.g) {
+ c = true;
}
}
diff --git a/core/math/dynamic_bvh.cpp b/core/math/dynamic_bvh.cpp
index 4639a52278..200095d8cb 100644
--- a/core/math/dynamic_bvh.cpp
+++ b/core/math/dynamic_bvh.cpp
@@ -61,7 +61,7 @@ DynamicBVH::Node *DynamicBVH::_create_node_with_volume(Node *p_parent, const Vol
void DynamicBVH::_insert_leaf(Node *p_root, Node *p_leaf) {
if (!bvh_root) {
bvh_root = p_leaf;
- p_leaf->parent = 0;
+ p_leaf->parent = nullptr;
} else {
if (!p_root->is_leaf()) {
do {
@@ -71,7 +71,7 @@ void DynamicBVH::_insert_leaf(Node *p_root, Node *p_leaf) {
} while (!p_root->is_leaf());
}
Node *prev = p_root->parent;
- Node *node = _create_node_with_volume(prev, p_leaf->volume.merge(p_root->volume), 0);
+ Node *node = _create_node_with_volume(prev, p_leaf->volume.merge(p_root->volume), nullptr);
if (prev) {
prev->childs[p_root->get_index_in_parent()] = node;
node->childs[0] = p_root;
@@ -85,7 +85,7 @@ void DynamicBVH::_insert_leaf(Node *p_root, Node *p_leaf) {
break;
}
node = prev;
- } while (0 != (prev = node->parent));
+ } while (nullptr != (prev = node->parent));
} else {
node->childs[0] = p_root;
p_root->parent = node;
@@ -98,8 +98,8 @@ void DynamicBVH::_insert_leaf(Node *p_root, Node *p_leaf) {
DynamicBVH::Node *DynamicBVH::_remove_leaf(Node *leaf) {
if (leaf == bvh_root) {
- bvh_root = 0;
- return (0);
+ bvh_root = nullptr;
+ return (nullptr);
} else {
Node *parent = leaf->parent;
Node *prev = parent->parent;
@@ -113,13 +113,14 @@ DynamicBVH::Node *DynamicBVH::_remove_leaf(Node *leaf) {
prev->volume = prev->childs[0]->volume.merge(prev->childs[1]->volume);
if (pb.is_not_equal_to(prev->volume)) {
prev = prev->parent;
- } else
+ } else {
break;
+ }
}
return (prev ? prev : bvh_root);
} else {
bvh_root = sibling;
- sibling->parent = 0;
+ sibling->parent = nullptr;
_delete_node(parent);
return (bvh_root);
}
@@ -262,10 +263,11 @@ DynamicBVH::Node *DynamicBVH::_node_sort(Node *n, Node *&r) {
Node *s = p->childs[j];
Node *q = p->parent;
ERR_FAIL_COND_V(n != p->childs[i], nullptr);
- if (q)
+ if (q) {
q->childs[p->get_index_in_parent()] = n;
- else
+ } else {
r = n;
+ }
s->parent = n;
p->parent = n;
n->parent = q;
@@ -307,8 +309,9 @@ void DynamicBVH::optimize_top_down(int bu_threshold) {
}
void DynamicBVH::optimize_incremental(int passes) {
- if (passes < 0)
+ if (passes < 0) {
passes = total_leaves;
+ }
if (bvh_root && (passes > 0)) {
do {
Node *node = bvh_root;
@@ -345,8 +348,9 @@ void DynamicBVH::_update(Node *leaf, int lookahead) {
for (int i = 0; (i < lookahead) && root->parent; ++i) {
root = root->parent;
}
- } else
+ } else {
root = bvh_root;
+ }
}
_insert_leaf(root, leaf);
}
@@ -370,8 +374,9 @@ bool DynamicBVH::update(const ID &p_id, const AABB &p_box) {
for (int i = 0; (i < lkhd) && base->parent; ++i) {
base = base->parent;
}
- } else
+ } else {
base = bvh_root;
+ }
}
leaf->volume = volume;
_insert_leaf(base, leaf);
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index c71db2d24d..3fb22515a2 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -87,14 +87,16 @@ private:
_FORCE_INLINE_ Volume merge(const Volume &b) const {
Volume r;
for (int i = 0; i < 3; ++i) {
- if (min[i] < b.min[i])
+ if (min[i] < b.min[i]) {
r.min[i] = min[i];
- else
+ } else {
r.min[i] = b.min[i];
- if (max[i] > b.max[i])
+ }
+ if (max[i] > b.max[i]) {
r.max[i] = max[i];
- else
+ } else {
r.max[i] = b.max[i];
+ }
}
return r;
}
@@ -202,10 +204,11 @@ private:
//
int count_leaves() const {
- if (is_internal())
+ if (is_internal()) {
return childs[0]->count_leaves() + childs[1]->count_leaves();
- else
+ } else {
return (1);
+ }
}
bool is_left_of_axis(const Vector3 &org, const Vector3 &axis) const {
@@ -254,31 +257,37 @@ private:
tymin = (bounds[raySign[1]].y - rayFrom.y) * rayInvDirection.y;
tymax = (bounds[1 - raySign[1]].y - rayFrom.y) * rayInvDirection.y;
- if ((tmin > tymax) || (tymin > tmax))
+ if ((tmin > tymax) || (tymin > tmax)) {
return false;
+ }
- if (tymin > tmin)
+ if (tymin > tmin) {
tmin = tymin;
+ }
- if (tymax < tmax)
+ if (tymax < tmax) {
tmax = tymax;
+ }
tzmin = (bounds[raySign[2]].z - rayFrom.z) * rayInvDirection.z;
tzmax = (bounds[1 - raySign[2]].z - rayFrom.z) * rayInvDirection.z;
- if ((tmin > tzmax) || (tzmin > tmax))
+ if ((tmin > tzmax) || (tzmin > tmax)) {
return false;
- if (tzmin > tmin)
+ }
+ if (tzmin > tmin) {
tmin = tzmin;
- if (tzmax < tmax)
+ }
+ if (tzmax < tmax) {
tmax = tzmax;
+ }
return ((tmin < lambda_max) && (tmax > lambda_min));
}
public:
// Methods
void clear();
- bool is_empty() const { return (0 == bvh_root); }
+ bool is_empty() const { return (nullptr == bvh_root); }
void optimize_bottom_up();
void optimize_top_down(int bu_threshold = 128);
void optimize_incremental(int passes);
diff --git a/core/math/quat.cpp b/core/math/quat.cpp
index a9a21a1ba3..6f13e04027 100644
--- a/core/math/quat.cpp
+++ b/core/math/quat.cpp
@@ -55,10 +55,13 @@ Vector3 Quat::get_euler_yxz() const {
}
void Quat::operator*=(const Quat &p_q) {
- x = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
- y = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
- z = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
+ real_t xx = w * p_q.x + x * p_q.w + y * p_q.z - z * p_q.y;
+ real_t yy = w * p_q.y + y * p_q.w + z * p_q.x - x * p_q.z;
+ real_t zz = w * p_q.z + z * p_q.w + x * p_q.y - y * p_q.x;
w = w * p_q.w - x * p_q.x - y * p_q.y - z * p_q.z;
+ x = xx;
+ y = yy;
+ z = zz;
}
Quat Quat::operator*(const Quat &p_q) const {
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 375ad8fae1..fb7eb42738 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -1095,6 +1095,8 @@ bool ClassDB::get_property_info(StringName p_class, StringName p_property, Prope
}
bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) {
+ ERR_FAIL_NULL_V(p_object, false);
+
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
while (check) {
@@ -1142,6 +1144,8 @@ bool ClassDB::set_property(Object *p_object, const StringName &p_property, const
}
bool ClassDB::get_property(Object *p_object, const StringName &p_property, Variant &r_value) {
+ ERR_FAIL_NULL_V(p_object, false);
+
ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type;
while (check) {
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 182bab4058..ca1b798e11 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -106,10 +106,18 @@ void OS::add_logger(Logger *p_logger) {
}
void OS::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, Logger::ErrorType p_type) {
+ if (!_stderr_enabled) {
+ return;
+ }
+
_logger->log_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
}
void OS::print(const char *p_format, ...) {
+ if (!_stdout_enabled) {
+ return;
+ }
+
va_list argp;
va_start(argp, p_format);
@@ -119,6 +127,10 @@ void OS::print(const char *p_format, ...) {
}
void OS::printerr(const char *p_format, ...) {
+ if (!_stderr_enabled) {
+ return;
+ }
+
va_list argp;
va_start(argp, p_format);
@@ -163,6 +175,22 @@ bool OS::is_stdout_debug_enabled() const {
return _debug_stdout;
}
+bool OS::is_stdout_enabled() const {
+ return _stdout_enabled;
+}
+
+bool OS::is_stderr_enabled() const {
+ return _stderr_enabled;
+}
+
+void OS::set_stdout_enabled(bool p_enabled) {
+ _stdout_enabled = p_enabled;
+}
+
+void OS::set_stderr_enabled(bool p_enabled) {
+ _stderr_enabled = p_enabled;
+}
+
void OS::dump_memory_to_file(const char *p_file) {
//Memory::dump_static_mem_to_file(p_file);
}
diff --git a/core/os/os.h b/core/os/os.h
index e41d788e12..7198607237 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -60,6 +60,8 @@ class OS {
bool _allow_layered = false;
bool _use_vsync;
bool _vsync_via_compositor;
+ bool _stdout_enabled = true;
+ bool _stderr_enabled = true;
char *last_error;
@@ -219,6 +221,11 @@ public:
bool is_stdout_verbose() const;
bool is_stdout_debug_enabled() const;
+ bool is_stdout_enabled() const;
+ bool is_stderr_enabled() const;
+ void set_stdout_enabled(bool p_enabled);
+ void set_stderr_enabled(bool p_enabled);
+
virtual void disable_crash_handler() {}
virtual bool is_disable_crash_handler() const { return false; }
virtual void initialize_debugging() {}
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 736248e6ee..cf0040353d 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -1138,7 +1138,7 @@ Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int
remaining_len = left_edge;
}
- ret.invert();
+ ret.reverse();
return ret;
}
diff --git a/core/templates/list.h b/core/templates/list.h
index eaf1dbb4a0..010e35eed8 100644
--- a/core/templates/list.h
+++ b/core/templates/list.h
@@ -492,7 +492,7 @@ public:
_data->last = p_I;
}
- void invert() {
+ void reverse() {
int s = size() / 2;
Element *F = front();
Element *B = back();
diff --git a/core/templates/vector.h b/core/templates/vector.h
index 6a8902707c..a56a941dbc 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -74,7 +74,7 @@ public:
remove(idx);
}
}
- void invert();
+ void reverse();
_FORCE_INLINE_ T *ptrw() { return _cowdata.ptrw(); }
_FORCE_INLINE_ const T *ptr() const { return _cowdata.ptr(); }
@@ -194,7 +194,7 @@ public:
};
template <class T>
-void Vector<T>::invert() {
+void Vector<T>::reverse() {
for (int i = 0; i < size() / 2; i++) {
T *p = ptrw();
SWAP(p[i], p[size() - i - 1]);
diff --git a/core/variant/array.cpp b/core/variant/array.cpp
index 347c6cd82e..2ad728ec5e 100644
--- a/core/variant/array.cpp
+++ b/core/variant/array.cpp
@@ -139,7 +139,7 @@ uint32_t Array::hash() const {
return h;
}
-void Array::_assign(const Array &p_array) {
+bool Array::_assign(const Array &p_array) {
if (_p->typed.type != Variant::OBJECT && _p->typed.type == p_array._p->typed.type) {
//same type or untyped, just reference, should be fine
_ref(p_array);
@@ -150,7 +150,7 @@ void Array::_assign(const Array &p_array) {
//for objects, it needs full validation, either can be converted or fail
for (int i = 0; i < p_array._p->array.size(); i++) {
if (!_p->typed.validate(p_array._p->array[i], "assign")) {
- return;
+ return false;
}
}
_p->array = p_array._p->array; //then just copy, which is cheap anyway
@@ -168,10 +168,10 @@ void Array::_assign(const Array &p_array) {
Callable::CallError ce;
Variant::construct(_p->typed.type, new_array.write[i], (const Variant **)&ptr, 1, ce);
if (ce.error != Callable::CallError::CALL_OK) {
- ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
}
} else {
- ERR_FAIL_MSG("Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
+ ERR_FAIL_V_MSG(false, "Unable to convert array index " + itos(i) + " from '" + Variant::get_type_name(src_val.get_type()) + "' to '" + Variant::get_type_name(_p->typed.type) + "'.");
}
}
@@ -180,12 +180,13 @@ void Array::_assign(const Array &p_array) {
} else if (_p->typed.can_reference(p_array._p->typed)) { //same type or compatible
_ref(p_array);
} else {
- ERR_FAIL_MSG("Assignment of arrays of incompatible types.");
+ ERR_FAIL_V_MSG(false, "Assignment of arrays of incompatible types.");
}
+ return true;
}
void Array::operator=(const Array &p_array) {
- _assign(p_array);
+ _ref(p_array);
}
void Array::push_back(const Variant &p_value) {
@@ -445,8 +446,8 @@ int Array::bsearch_custom(const Variant &p_value, Callable p_callable, bool p_be
return bisect(_p->array, p_value, p_before, less);
}
-void Array::invert() {
- _p->array.invert();
+void Array::reverse() {
+ _p->array.reverse();
}
void Array::push_front(const Variant &p_value) {
@@ -528,6 +529,10 @@ Array::Array(const Array &p_from, uint32_t p_type, const StringName &p_class_nam
_assign(p_from);
}
+bool Array::typed_assign(const Array &p_other) {
+ return _assign(p_other);
+}
+
void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script) {
ERR_FAIL_COND_MSG(_p->array.size() > 0, "Type can only be set when array is empty.");
ERR_FAIL_COND_MSG(_p->refcount.get() > 1, "Type can only be set when array has no more than one user.");
@@ -542,6 +547,22 @@ void Array::set_typed(uint32_t p_type, const StringName &p_class_name, const Var
_p->typed.where = "TypedArray";
}
+bool Array::is_typed() const {
+ return _p->typed.type != Variant::NIL;
+}
+
+uint32_t Array::get_typed_builtin() const {
+ return _p->typed.type;
+}
+
+StringName Array::get_typed_class_name() const {
+ return _p->typed.class_name;
+}
+
+Variant Array::get_typed_script() const {
+ return _p->typed.script;
+}
+
Array::Array(const Array &p_from) {
_p = nullptr;
_ref(p_from);
diff --git a/core/variant/array.h b/core/variant/array.h
index d8f2402330..6b58ed12cb 100644
--- a/core/variant/array.h
+++ b/core/variant/array.h
@@ -48,7 +48,7 @@ class Array {
protected:
Array(const Array &p_base, uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
- void _assign(const Array &p_array);
+ bool _assign(const Array &p_array);
public:
Variant &operator[](int p_idx);
@@ -83,7 +83,7 @@ public:
void shuffle();
int bsearch(const Variant &p_value, bool p_before = true);
int bsearch_custom(const Variant &p_value, Callable p_callable, bool p_before = true);
- void invert();
+ void reverse();
int find(const Variant &p_value, int p_from = 0) const;
int rfind(const Variant &p_value, int p_from = -1) const;
@@ -111,7 +111,12 @@ public:
const void *id() const;
+ bool typed_assign(const Array &p_other);
void set_typed(uint32_t p_type, const StringName &p_class_name, const Variant &p_script);
+ bool is_typed() const;
+ uint32_t get_typed_builtin() const;
+ StringName get_typed_class_name() const;
+ Variant get_typed_script() const;
Array(const Array &p_from);
Array();
~Array();
diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h
index 8c0b7907e3..86bbf43266 100644
--- a/core/variant/binder_common.h
+++ b/core/variant/binder_common.h
@@ -233,6 +233,11 @@ void call_with_ptr_args_retc_helper(T *p_instance, R (T::*p_method)(P...) const,
PtrToArg<R>::encode((p_instance->*p_method)(PtrToArg<P>::convert(p_args[Is])...), r_ret);
}
+template <class T, class... P, size_t... Is>
+void call_with_ptr_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const void **p_args, IndexSequence<Is...>) {
+ p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...);
+}
+
template <class T, class R, class... P, size_t... Is>
void call_with_ptr_args_static_retc_helper(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret, IndexSequence<Is...>) {
PtrToArg<R>::encode(p_method(p_instance, PtrToArg<P>::convert(p_args[Is])...), r_ret);
@@ -273,6 +278,11 @@ void call_with_validated_variant_args_static_retc_helper(T *p_instance, R (*p_me
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
}
+template <class T, class... P, size_t... Is>
+void call_with_validated_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, IndexSequence<Is...>) {
+ p_method(p_instance, (VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...);
+}
+
template <class R, class... P, size_t... Is>
void call_with_validated_variant_args_static_method_ret_helper(R (*p_method)(P...), const Variant **p_args, Variant *r_ret, IndexSequence<Is...>) {
VariantInternalAccessor<typename GetSimpleTypeT<R>::type_t>::set(r_ret, p_method((VariantInternalAccessor<typename GetSimpleTypeT<P>::type_t>::get(p_args[Is]))...));
@@ -471,6 +481,11 @@ void call_with_ptr_args_retc(T *p_instance, R (T::*p_method)(P...) const, const
call_with_ptr_args_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
+template <class T, class... P>
+void call_with_ptr_args_static(T *p_instance, void (*p_method)(T *, P...), const void **p_args) {
+ call_with_ptr_args_static_helper<T, P...>(p_instance, p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
+}
+
template <class T, class R, class... P>
void call_with_ptr_args_static_retc(T *p_instance, R (*p_method)(T *, P...), const void **p_args, void *r_ret) {
call_with_ptr_args_static_retc_helper<T, R, P...>(p_instance, p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
@@ -501,6 +516,11 @@ void call_with_validated_variant_args_retc(Variant *base, R (T::*p_method)(P...)
call_with_validated_variant_args_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
}
+template <class T, class... P>
+void call_with_validated_variant_args_static(Variant *base, void (*p_method)(T *, P...), const Variant **p_args) {
+ call_with_validated_variant_args_static_helper<T, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, BuildIndexSequence<sizeof...(P)>{});
+}
+
template <class T, class R, class... P>
void call_with_validated_variant_args_static_retc(Variant *base, R (*p_method)(T *, P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_retc_helper<T, R, P...>(VariantGetInternalPtr<T>::get_ptr(base), p_method, p_args, r_ret, BuildIndexSequence<sizeof...(P)>{});
@@ -758,6 +778,52 @@ void call_with_variant_args_retc_static_helper_dv(T *p_instance, R (*p_method)(T
call_with_variant_args_retc_static_helper(p_instance, p_method, args, r_ret, r_error, BuildIndexSequence<sizeof...(P)>{});
}
+template <class T, class... P, size_t... Is>
+void call_with_variant_args_static_helper(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, Callable::CallError &r_error, IndexSequence<Is...>) {
+ r_error.error = Callable::CallError::CALL_OK;
+
+#ifdef DEBUG_METHODS_ENABLED
+ (p_method)(p_instance, VariantCasterAndValidate<P>::cast(p_args, Is, r_error)...);
+#else
+ (p_method)(p_instance, VariantCaster<P>::cast(*p_args[Is])...);
+#endif
+
+ (void)p_args;
+}
+
+template <class T, class... P>
+void call_with_variant_args_static_helper_dv(T *p_instance, void (*p_method)(T *, P...), const Variant **p_args, int p_argcount, const Vector<Variant> &default_values, Callable::CallError &r_error) {
+#ifdef DEBUG_ENABLED
+ if ((size_t)p_argcount > sizeof...(P)) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+#endif
+
+ int32_t missing = (int32_t)sizeof...(P) - (int32_t)p_argcount;
+
+ int32_t dvs = default_values.size();
+#ifdef DEBUG_ENABLED
+ if (missing > dvs) {
+ r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = sizeof...(P);
+ return;
+ }
+#endif
+
+ const Variant *args[sizeof...(P) == 0 ? 1 : sizeof...(P)]; //avoid zero sized array
+ for (int32_t i = 0; i < (int32_t)sizeof...(P); i++) {
+ if (i < p_argcount) {
+ args[i] = p_args[i];
+ } else {
+ args[i] = &default_values[i - p_argcount + (dvs - missing)];
+ }
+ }
+
+ call_with_variant_args_static_helper(p_instance, p_method, args, r_error, BuildIndexSequence<sizeof...(P)>{});
+}
+
template <class R, class... P>
void call_with_variant_args_static_ret_dv(R (*p_method)(P...), const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error, const Vector<Variant> &default_values) {
#ifdef DEBUG_ENABLED
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 8c1d8066d6..61f3f7d82e 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -34,6 +34,7 @@
#include "core/crypto/crypto_core.h"
#include "core/debugger/engine_debugger.h"
#include "core/io/compression.h"
+#include "core/io/marshalls.h"
#include "core/object/class_db.h"
#include "core/os/os.h"
#include "core/templates/local_vector.h"
@@ -73,6 +74,16 @@ static _FORCE_INLINE_ void vc_method_call(void (T::*method)(P...) const, Variant
}
template <class R, class T, class... P>
+static _FORCE_INLINE_ void vc_method_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
+ call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, r_ret, p_defvals, r_error);
+}
+
+template <class T, class... P>
+static _FORCE_INLINE_ void vc_method_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) {
+ call_with_variant_args_static_helper_dv(VariantGetInternalPtr<T>::get_ptr(base), method, p_args, p_argcount, p_defvals, r_error);
+}
+
+template <class R, class T, class... P>
static _FORCE_INLINE_ void vc_validated_call(R (T::*method)(P...), Variant *base, const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_ret(base, method, p_args, r_ret);
}
@@ -91,6 +102,16 @@ static _FORCE_INLINE_ void vc_validated_call(void (T::*method)(P...) const, Vari
call_with_validated_variant_argsc(base, method, p_args);
}
+template <class R, class T, class... P>
+static _FORCE_INLINE_ void vc_validated_call_static(R (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) {
+ call_with_validated_variant_args_static_retc(base, method, p_args, r_ret);
+}
+
+template <class T, class... P>
+static _FORCE_INLINE_ void vc_validated_call_static(void (*method)(T *, P...), Variant *base, const Variant **p_args, Variant *r_ret) {
+ call_with_validated_variant_args_static(base, method, p_args);
+}
+
template <class R, class... P>
static _FORCE_INLINE_ void vc_validated_static_call(R (*method)(P...), const Variant **p_args, Variant *r_ret) {
call_with_validated_variant_args_static_method_ret(method, p_args, r_ret);
@@ -146,6 +167,11 @@ static _FORCE_INLINE_ void vc_change_return_type(R (*method)(P...), Variant *v)
VariantTypeAdjust<R>::adjust(v);
}
+template <class... P>
+static _FORCE_INLINE_ void vc_change_return_type(void (*method)(P...), Variant *v) {
+ VariantInternal::clear(v);
+}
+
template <class R, class T, class... P>
static _FORCE_INLINE_ int vc_get_argument_count(R (T::*method)(P...)) {
return sizeof...(P);
@@ -229,6 +255,11 @@ static _FORCE_INLINE_ Variant::Type vc_get_return_type(R (*method)(P...)) {
return GetTypeInfo<R>::VARIANT_TYPE;
}
+template <class... P>
+static _FORCE_INLINE_ Variant::Type vc_get_return_type(void (*method)(P...)) {
+ return Variant::NIL;
+}
+
template <class R, class T, class... P>
static _FORCE_INLINE_ bool vc_has_return_type(R (T::*method)(P...)) {
return true;
@@ -393,45 +424,50 @@ static _FORCE_INLINE_ void vc_ptrcall(R (*method)(T *, P...), void *p_base, cons
call_with_ptr_args_static_retc<T, R, P...>(reinterpret_cast<T *>(p_base), method, p_args, r_ret);
}
-#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr) \
- struct Method_##m_class##_##m_method_name { \
- static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
- call_with_variant_args_retc_static_helper_dv(VariantGetInternalPtr<m_class>::get_ptr(base), m_method_ptr, p_args, p_argcount, r_ret, p_defvals, r_error); \
- } \
- static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \
- vc_change_return_type(m_method_ptr, r_ret); \
- call_with_validated_variant_args_static_retc(base, m_method_ptr, p_args, r_ret); \
- } \
- static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \
- vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \
- } \
- static int get_argument_count() { \
- return vc_get_argument_count(m_method_ptr); \
- } \
- static Variant::Type get_argument_type(int p_arg) { \
- return vc_get_argument_type(m_method_ptr, p_arg); \
- } \
- static Variant::Type get_return_type() { \
- return vc_get_return_type(m_method_ptr); \
- } \
- static bool has_return_type() { \
- return true; \
- } \
- static bool is_const() { \
- return true; \
- } \
- static bool is_static() { \
- return false; \
- } \
- static bool is_vararg() { \
- return false; \
- } \
- static Variant::Type get_base_type() { \
- return GetTypeInfo<m_class>::VARIANT_TYPE; \
- } \
- static StringName get_name() { \
- return #m_method_name; \
- } \
+template <class T, class... P>
+static _FORCE_INLINE_ void vc_ptrcall(void (*method)(T *, P...), void *p_base, const void **p_args, void *r_ret) {
+ call_with_ptr_args_static<T, P...>(reinterpret_cast<T *>(p_base), method, p_args);
+}
+
+#define FUNCTION_CLASS(m_class, m_method_name, m_method_ptr, m_const) \
+ struct Method_##m_class##_##m_method_name { \
+ static void call(Variant *base, const Variant **p_args, int p_argcount, Variant &r_ret, const Vector<Variant> &p_defvals, Callable::CallError &r_error) { \
+ vc_method_call_static(m_method_ptr, base, p_args, p_argcount, r_ret, p_defvals, r_error); \
+ } \
+ static void validated_call(Variant *base, const Variant **p_args, int p_argcount, Variant *r_ret) { \
+ vc_change_return_type(m_method_ptr, r_ret); \
+ vc_validated_call_static(m_method_ptr, base, p_args, r_ret); \
+ } \
+ static void ptrcall(void *p_base, const void **p_args, void *r_ret, int p_argcount) { \
+ vc_ptrcall(m_method_ptr, p_base, p_args, r_ret); \
+ } \
+ static int get_argument_count() { \
+ return vc_get_argument_count(m_method_ptr); \
+ } \
+ static Variant::Type get_argument_type(int p_arg) { \
+ return vc_get_argument_type(m_method_ptr, p_arg); \
+ } \
+ static Variant::Type get_return_type() { \
+ return vc_get_return_type(m_method_ptr); \
+ } \
+ static bool has_return_type() { \
+ return vc_has_return_type_static(m_method_ptr); \
+ } \
+ static bool is_const() { \
+ return m_const; \
+ } \
+ static bool is_static() { \
+ return false; \
+ } \
+ static bool is_vararg() { \
+ return false; \
+ } \
+ static Variant::Type get_base_type() { \
+ return GetTypeInfo<m_class>::VARIANT_TYPE; \
+ } \
+ static StringName get_name() { \
+ return #m_method_name; \
+ } \
};
#define VARARG_CLASS(m_class, m_method_name, m_method_ptr, m_has_return, m_return_type) \
@@ -590,6 +626,195 @@ struct _VariantCall {
return s;
}
+ static int64_t func_PackedByteArray_decode_u8(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0);
+ const uint8_t *r = p_instance->ptr();
+ return r[p_offset];
+ }
+ static int64_t func_PackedByteArray_decode_s8(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > int64_t(size) - 1, 0);
+ const uint8_t *r = p_instance->ptr();
+ return *((const int8_t *)&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_u16(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0);
+ const uint8_t *r = p_instance->ptr();
+ return decode_uint16(&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_s16(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0);
+ const uint8_t *r = p_instance->ptr();
+ return (int16_t)decode_uint16(&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_u32(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0);
+ const uint8_t *r = p_instance->ptr();
+ return decode_uint32(&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_s32(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0);
+ const uint8_t *r = p_instance->ptr();
+ return (int32_t)decode_uint32(&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_u64(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0);
+ const uint8_t *r = p_instance->ptr();
+ return (int64_t)decode_uint64(&r[p_offset]);
+ }
+ static int64_t func_PackedByteArray_decode_s64(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0);
+ const uint8_t *r = p_instance->ptr();
+ return (int64_t)decode_uint64(&r[p_offset]);
+ }
+ static double func_PackedByteArray_decode_half(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 2), 0);
+ const uint8_t *r = p_instance->ptr();
+ return Math::half_to_float(decode_uint16(&r[p_offset]));
+ }
+ static double func_PackedByteArray_decode_float(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 4), 0);
+ const uint8_t *r = p_instance->ptr();
+ return decode_float(&r[p_offset]);
+ }
+
+ static double func_PackedByteArray_decode_double(PackedByteArray *p_instance, int64_t p_offset) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0 || p_offset > (int64_t(size) - 8), 0);
+ const uint8_t *r = p_instance->ptr();
+ return decode_double(&r[p_offset]);
+ }
+
+ static bool func_PackedByteArray_has_encoded_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0, false);
+ const uint8_t *r = p_instance->ptr();
+ Variant ret;
+ Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects);
+ return err == OK;
+ }
+
+ static Variant func_PackedByteArray_decode_var(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0, Variant());
+ const uint8_t *r = p_instance->ptr();
+ Variant ret;
+ Error err = decode_variant(ret, r + p_offset, size - p_offset, nullptr, p_allow_objects);
+ if (err != OK) {
+ ret = Variant();
+ }
+ return ret;
+ }
+
+ static int64_t func_PackedByteArray_decode_var_size(PackedByteArray *p_instance, int64_t p_offset, bool p_allow_objects) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0, 0);
+ const uint8_t *r = p_instance->ptr();
+ Variant ret;
+ int r_size;
+ Error err = decode_variant(ret, r + p_offset, size - p_offset, &r_size, p_allow_objects);
+ if (err == OK) {
+ return r_size;
+ }
+ return 0;
+ }
+
+ static void func_PackedByteArray_encode_u8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1);
+ uint8_t *w = p_instance->ptrw();
+ *((uint8_t *)&w[p_offset]) = p_value;
+ }
+ static void func_PackedByteArray_encode_s8(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 1);
+ uint8_t *w = p_instance->ptrw();
+ *((int8_t *)&w[p_offset]) = p_value;
+ }
+
+ static void func_PackedByteArray_encode_u16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint16((uint16_t)p_value, &w[p_offset]);
+ }
+ static void func_PackedByteArray_encode_s16(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint16((int16_t)p_value, &w[p_offset]);
+ }
+
+ static void func_PackedByteArray_encode_u32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint32((uint32_t)p_value, &w[p_offset]);
+ }
+ static void func_PackedByteArray_encode_s32(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint32((int32_t)p_value, &w[p_offset]);
+ }
+
+ static void func_PackedByteArray_encode_u64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint64((uint64_t)p_value, &w[p_offset]);
+ }
+ static void func_PackedByteArray_encode_s64(PackedByteArray *p_instance, int64_t p_offset, int64_t p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint64((int64_t)p_value, &w[p_offset]);
+ }
+
+ static void func_PackedByteArray_encode_half(PackedByteArray *p_instance, int64_t p_offset, double p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 2);
+ uint8_t *w = p_instance->ptrw();
+ encode_uint16(Math::make_half_float(p_value), &w[p_offset]);
+ }
+ static void func_PackedByteArray_encode_float(PackedByteArray *p_instance, int64_t p_offset, double p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 4);
+ uint8_t *w = p_instance->ptrw();
+ encode_float(p_value, &w[p_offset]);
+ }
+ static void func_PackedByteArray_encode_double(PackedByteArray *p_instance, int64_t p_offset, double p_value) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND(p_offset < 0 || p_offset > int64_t(size) - 8);
+ uint8_t *w = p_instance->ptrw();
+ encode_double(p_value, &w[p_offset]);
+ }
+ static int64_t func_PackedByteArray_encode_var(PackedByteArray *p_instance, int64_t p_offset, const Variant &p_value, bool p_allow_objects) {
+ uint64_t size = p_instance->size();
+ ERR_FAIL_COND_V(p_offset < 0, -1);
+ uint8_t *w = p_instance->ptrw();
+ int len;
+ Error err = encode_variant(p_value, nullptr, len, p_allow_objects);
+ if (err != OK) {
+ return -1;
+ }
+ if (uint64_t(p_offset + len) > size) {
+ return -1; // did not fit
+ }
+ encode_variant(p_value, w + p_offset, len, p_allow_objects);
+
+ return len;
+ }
+
static void func_Callable_call(Variant *v, const Variant **p_args, int p_argcount, Variant &r_ret, Callable::CallError &r_error) {
Callable *callable = VariantGetInternalPtr<Callable>::get_ptr(v);
callable->call(p_args, p_argcount, r_ret, r_error);
@@ -1005,11 +1230,21 @@ Variant Variant::get_constant_value(Variant::Type p_type, const StringName &p_va
#ifdef DEBUG_METHODS_ENABLED
#define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \
- FUNCTION_CLASS(m_type, m_name, m_method); \
+ FUNCTION_CLASS(m_type, m_name, m_method, true); \
register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args);
#else
#define bind_function(m_type, m_name, m_method, m_arg_names, m_default_args) \
- FUNCTION_CLASS(m_type, m_name, m_method); \
+ FUNCTION_CLASS(m_type, m_name, m_method, true); \
+ register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args);
+#endif
+
+#ifdef DEBUG_METHODS_ENABLED
+#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \
+ FUNCTION_CLASS(m_type, m_name, m_method, false); \
+ register_builtin_method<Method_##m_type##_##m_name>(m_arg_names, m_default_args);
+#else
+#define bind_functionnc(m_type, m_name, m_method, m_arg_names, m_default_args) \
+ FUNCTION_CLASS(m_type, m_name, m_method, false); \
register_builtin_method<Method_##m_type##_##m_name>(sarray(), m_default_args);
#endif
@@ -1460,7 +1695,7 @@ static void _register_variant_builtin_methods() {
bind_method(Array, shuffle, sarray(), varray());
bind_method(Array, bsearch, sarray("value", "before"), varray(true));
bind_method(Array, bsearch_custom, sarray("value", "func", "before"), varray(true));
- bind_method(Array, invert, sarray(), varray());
+ bind_method(Array, reverse, sarray(), varray());
bind_method(Array, duplicate, sarray("deep"), varray(false));
bind_method(Array, slice, sarray("begin", "end", "step", "deep"), varray(1, false));
bind_method(Array, max, sarray(), varray());
@@ -1477,7 +1712,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedByteArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedByteArray, resize, sarray("new_size"), varray());
bind_method(PackedByteArray, has, sarray("value"), varray());
- bind_method(PackedByteArray, invert, sarray(), varray());
+ bind_method(PackedByteArray, reverse, sarray(), varray());
bind_method(PackedByteArray, subarray, sarray("from", "to"), varray());
bind_method(PackedByteArray, sort, sarray(), varray());
bind_method(PackedByteArray, duplicate, sarray(), varray());
@@ -1491,6 +1726,34 @@ static void _register_variant_builtin_methods() {
bind_function(PackedByteArray, decompress, _VariantCall::func_PackedByteArray_decompress, sarray("buffer_size", "compression_mode"), varray(0));
bind_function(PackedByteArray, decompress_dynamic, _VariantCall::func_PackedByteArray_decompress_dynamic, sarray("max_output_size", "compression_mode"), varray(0));
+ bind_function(PackedByteArray, decode_u8, _VariantCall::func_PackedByteArray_decode_u8, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_s8, _VariantCall::func_PackedByteArray_decode_s8, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_u16, _VariantCall::func_PackedByteArray_decode_u16, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_s16, _VariantCall::func_PackedByteArray_decode_s16, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_u32, _VariantCall::func_PackedByteArray_decode_u32, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_s32, _VariantCall::func_PackedByteArray_decode_s32, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_u64, _VariantCall::func_PackedByteArray_decode_u64, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_s64, _VariantCall::func_PackedByteArray_decode_s64, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_half, _VariantCall::func_PackedByteArray_decode_half, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_float, _VariantCall::func_PackedByteArray_decode_float, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, decode_double, _VariantCall::func_PackedByteArray_decode_double, sarray("byte_offset"), varray());
+ bind_function(PackedByteArray, has_encoded_var, _VariantCall::func_PackedByteArray_has_encoded_var, sarray("byte_offset", "allow_objects"), varray(false));
+ bind_function(PackedByteArray, decode_var, _VariantCall::func_PackedByteArray_decode_var, sarray("byte_offset", "allow_objects"), varray(false));
+ bind_function(PackedByteArray, decode_var_size, _VariantCall::func_PackedByteArray_decode_var_size, sarray("byte_offset", "allow_objects"), varray(false));
+
+ bind_functionnc(PackedByteArray, encode_u8, _VariantCall::func_PackedByteArray_encode_u8, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_s8, _VariantCall::func_PackedByteArray_encode_s8, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_u16, _VariantCall::func_PackedByteArray_encode_u16, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_s16, _VariantCall::func_PackedByteArray_encode_s16, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_u32, _VariantCall::func_PackedByteArray_encode_u32, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_s32, _VariantCall::func_PackedByteArray_encode_s32, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_u64, _VariantCall::func_PackedByteArray_encode_u64, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_s64, _VariantCall::func_PackedByteArray_encode_s64, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_half, _VariantCall::func_PackedByteArray_encode_half, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_float, _VariantCall::func_PackedByteArray_encode_float, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_double, _VariantCall::func_PackedByteArray_encode_double, sarray("byte_offset", "value"), varray());
+ bind_functionnc(PackedByteArray, encode_var, _VariantCall::func_PackedByteArray_encode_var, sarray("byte_offset", "value", "allow_objects"), varray(false));
+
/* Int32 Array */
bind_method(PackedInt32Array, size, sarray(), varray());
@@ -1503,7 +1766,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt32Array, resize, sarray("new_size"), varray());
bind_method(PackedInt32Array, has, sarray("value"), varray());
- bind_method(PackedInt32Array, invert, sarray(), varray());
+ bind_method(PackedInt32Array, reverse, sarray(), varray());
bind_method(PackedInt32Array, subarray, sarray("from", "to"), varray());
bind_method(PackedInt32Array, to_byte_array, sarray(), varray());
bind_method(PackedInt32Array, sort, sarray(), varray());
@@ -1521,7 +1784,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedInt64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedInt64Array, resize, sarray("new_size"), varray());
bind_method(PackedInt64Array, has, sarray("value"), varray());
- bind_method(PackedInt64Array, invert, sarray(), varray());
+ bind_method(PackedInt64Array, reverse, sarray(), varray());
bind_method(PackedInt64Array, subarray, sarray("from", "to"), varray());
bind_method(PackedInt64Array, to_byte_array, sarray(), varray());
bind_method(PackedInt64Array, sort, sarray(), varray());
@@ -1539,7 +1802,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat32Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat32Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat32Array, has, sarray("value"), varray());
- bind_method(PackedFloat32Array, invert, sarray(), varray());
+ bind_method(PackedFloat32Array, reverse, sarray(), varray());
bind_method(PackedFloat32Array, subarray, sarray("from", "to"), varray());
bind_method(PackedFloat32Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat32Array, sort, sarray(), varray());
@@ -1557,7 +1820,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedFloat64Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedFloat64Array, resize, sarray("new_size"), varray());
bind_method(PackedFloat64Array, has, sarray("value"), varray());
- bind_method(PackedFloat64Array, invert, sarray(), varray());
+ bind_method(PackedFloat64Array, reverse, sarray(), varray());
bind_method(PackedFloat64Array, subarray, sarray("from", "to"), varray());
bind_method(PackedFloat64Array, to_byte_array, sarray(), varray());
bind_method(PackedFloat64Array, sort, sarray(), varray());
@@ -1575,7 +1838,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedStringArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedStringArray, resize, sarray("new_size"), varray());
bind_method(PackedStringArray, has, sarray("value"), varray());
- bind_method(PackedStringArray, invert, sarray(), varray());
+ bind_method(PackedStringArray, reverse, sarray(), varray());
bind_method(PackedStringArray, subarray, sarray("from", "to"), varray());
bind_method(PackedStringArray, to_byte_array, sarray(), varray());
bind_method(PackedStringArray, sort, sarray(), varray());
@@ -1593,7 +1856,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector2Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector2Array, resize, sarray("new_size"), varray());
bind_method(PackedVector2Array, has, sarray("value"), varray());
- bind_method(PackedVector2Array, invert, sarray(), varray());
+ bind_method(PackedVector2Array, reverse, sarray(), varray());
bind_method(PackedVector2Array, subarray, sarray("from", "to"), varray());
bind_method(PackedVector2Array, to_byte_array, sarray(), varray());
bind_method(PackedVector2Array, sort, sarray(), varray());
@@ -1611,7 +1874,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedVector3Array, insert, sarray("at_index", "value"), varray());
bind_method(PackedVector3Array, resize, sarray("new_size"), varray());
bind_method(PackedVector3Array, has, sarray("value"), varray());
- bind_method(PackedVector3Array, invert, sarray(), varray());
+ bind_method(PackedVector3Array, reverse, sarray(), varray());
bind_method(PackedVector3Array, subarray, sarray("from", "to"), varray());
bind_method(PackedVector3Array, to_byte_array, sarray(), varray());
bind_method(PackedVector3Array, sort, sarray(), varray());
@@ -1629,7 +1892,7 @@ static void _register_variant_builtin_methods() {
bind_method(PackedColorArray, insert, sarray("at_index", "value"), varray());
bind_method(PackedColorArray, resize, sarray("new_size"), varray());
bind_method(PackedColorArray, has, sarray("value"), varray());
- bind_method(PackedColorArray, invert, sarray(), varray());
+ bind_method(PackedColorArray, reverse, sarray(), varray());
bind_method(PackedColorArray, subarray, sarray("from", "to"), varray());
bind_method(PackedColorArray, to_byte_array, sarray(), varray());
bind_method(PackedColorArray, sort, sarray(), varray());
diff --git a/core/variant/variant_setget.cpp b/core/variant/variant_setget.cpp
index f9cc7c4ff4..f319631ce5 100644
--- a/core/variant/variant_setget.cpp
+++ b/core/variant/variant_setget.cpp
@@ -875,65 +875,66 @@ Variant Variant::get_named(const StringName &p_member, bool &r_valid) const {
static uint64_t get_indexed_size(const Variant *base) { return m_max; } \
};
-#define INDEXED_SETGET_STRUCT_VARIANT(m_base_type) \
- struct VariantIndexedSetGet_##m_base_type { \
- static void get(const Variant *base, int64_t index, Variant *value, bool *oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- *oob = true; \
- return; \
- } \
- *value = (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index]; \
- *oob = false; \
- } \
- static void ptr_get(const void *base, int64_t index, void *member) { \
- /* avoid ptrconvert for performance*/ \
- const m_base_type &v = *reinterpret_cast<const m_base_type *>(base); \
- if (index < 0) \
- index += v.size(); \
- OOB_TEST(index, v.size()); \
- PtrToArg<Variant>::encode(v[index], member); \
- } \
- static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- *oob = true; \
- *valid = false; \
- return; \
- } \
- (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \
- *oob = false; \
- *valid = true; \
- } \
- static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) { \
- int64_t size = VariantGetInternalPtr<m_base_type>::get_ptr(base)->size(); \
- if (index < 0) { \
- index += size; \
- } \
- if (index < 0 || index >= size) { \
- *oob = true; \
- return; \
- } \
- (*VariantGetInternalPtr<m_base_type>::get_ptr(base))[index] = *value; \
- *oob = false; \
- } \
- static void ptr_set(void *base, int64_t index, const void *member) { \
- /* avoid ptrconvert for performance*/ \
- m_base_type &v = *reinterpret_cast<m_base_type *>(base); \
- if (index < 0) \
- index += v.size(); \
- OOB_TEST(index, v.size()); \
- v[index] = PtrToArg<Variant>::convert(member); \
- } \
- static Variant::Type get_index_type() { return Variant::NIL; } \
- static uint64_t get_indexed_size(const Variant *base) { return 0; } \
- };
+struct VariantIndexedSetGet_Array {
+ static void get(const Variant *base, int64_t index, Variant *value, bool *oob) {
+ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
+ if (index < 0) {
+ index += size;
+ }
+ if (index < 0 || index >= size) {
+ *oob = true;
+ return;
+ }
+ *value = (*VariantGetInternalPtr<Array>::get_ptr(base))[index];
+ *oob = false;
+ }
+ static void ptr_get(const void *base, int64_t index, void *member) {
+ /* avoid ptrconvert for performance*/
+ const Array &v = *reinterpret_cast<const Array *>(base);
+ if (index < 0) {
+ index += v.size();
+ }
+ OOB_TEST(index, v.size());
+ PtrToArg<Variant>::encode(v[index], member);
+ }
+ static void set(Variant *base, int64_t index, const Variant *value, bool *valid, bool *oob) {
+ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
+ if (index < 0) {
+ index += size;
+ }
+ if (index < 0 || index >= size) {
+ *oob = true;
+ *valid = false;
+ return;
+ }
+ VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
+ *oob = false;
+ *valid = true;
+ }
+ static void validated_set(Variant *base, int64_t index, const Variant *value, bool *oob) {
+ int64_t size = VariantGetInternalPtr<Array>::get_ptr(base)->size();
+ if (index < 0) {
+ index += size;
+ }
+ if (index < 0 || index >= size) {
+ *oob = true;
+ return;
+ }
+ VariantGetInternalPtr<Array>::get_ptr(base)->set(index, *value);
+ *oob = false;
+ }
+ static void ptr_set(void *base, int64_t index, const void *member) {
+ /* avoid ptrconvert for performance*/
+ Array &v = *reinterpret_cast<Array *>(base);
+ if (index < 0) {
+ index += v.size();
+ }
+ OOB_TEST(index, v.size());
+ v.set(index, PtrToArg<Variant>::convert(member));
+ }
+ static Variant::Type get_index_type() { return Variant::NIL; }
+ static uint64_t get_indexed_size(const Variant *base) { return 0; }
+};
#define INDEXED_SETGET_STRUCT_DICT(m_base_type) \
struct VariantIndexedSetGet_##m_base_type { \
@@ -990,7 +991,6 @@ INDEXED_SETGET_STRUCT_TYPED(PackedVector3Array, Vector3)
INDEXED_SETGET_STRUCT_TYPED(PackedStringArray, String)
INDEXED_SETGET_STRUCT_TYPED(PackedColorArray, Color)
-INDEXED_SETGET_STRUCT_VARIANT(Array)
INDEXED_SETGET_STRUCT_DICT(Dictionary)
struct VariantIndexedSetterGetterInfo {
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index dcfb91eb61..54bbe7a94b 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -328,13 +328,6 @@
[b]Note:[/b] On large arrays, this method will be slower if the inserted element is close to the beginning of the array (index 0). This is because all elements placed after the newly inserted element have to be reindexed.
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -474,6 +467,13 @@
Resizes the array to contain a different number of elements. If the array size is smaller, elements are cleared, if bigger, new elements are [code]null[/code].
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="rfind" qualifiers="const">
<return type="int">
</return>
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index e2c4ed1430..7c1c4656f8 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -128,6 +128,16 @@
Will regenerate normal maps for the [ArrayMesh].
</description>
</method>
+ <method name="set_blend_shape_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="name" type="StringName">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="surface_find_by_name" qualifiers="const">
<return type="int">
</return>
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index 2fc4313e47..83223bb645 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -51,6 +51,9 @@
If [code]true[/code], allows editing the color with Hue/Saturation/Value sliders.
[b]Note:[/b] Cannot be enabled if raw mode is on.
</member>
+ <member name="picker_shape" type="int" setter="set_picker_shape" getter="get_picker_shape" default="0">
+ The shape of the color space view. See [enum PickerShapeType].
+ </member>
<member name="presets_enabled" type="bool" setter="set_presets_enabled" getter="are_presets_enabled" default="true">
If [code]true[/code], the "add preset" button is enabled.
</member>
@@ -86,6 +89,15 @@
</signal>
</signals>
<constants>
+ <constant name="SHAPE_HSV_RECTANGLE" value="0" enum="PickerShapeType">
+ HSV Color Model rectangle color space.
+ </constant>
+ <constant name="SHAPE_HSV_WHEEL" value="1" enum="PickerShapeType">
+ HSV Color Model rectangle color space with a wheel.
+ </constant>
+ <constant name="SHAPE_VHS_CIRCLE" value="2" enum="PickerShapeType">
+ HSV Color Model circle color space. Use Saturation as a radius.
+ </constant>
</constants>
<theme_items>
<theme_item name="add_preset" type="Texture2D">
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index b22878e56a..c0f918a01f 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -150,7 +150,6 @@
</argument>
<description>
Overrides the [Color] with given [code]name[/code] in the [member theme] resource the control uses.
- [b]Note:[/b] Unlike other theme overrides, there is no way to undo a color override without manually assigning the previous color.
[b]Example of overriding a label's color and resetting it later:[/b]
[codeblocks]
[gdscript]
@@ -178,7 +177,7 @@
<argument index="1" name="constant" type="int">
</argument>
<description>
- Overrides an integer constant with given [code]name[/code] in the [member theme] resource the control uses. If the [code]constant[/code] is [code]0[/code], the override is cleared and the constant from assigned [Theme] is used.
+ Overrides an integer constant with given [code]name[/code] in the [member theme] resource the control uses.
</description>
</method>
<method name="add_theme_font_override">
@@ -189,7 +188,7 @@
<argument index="1" name="font" type="Font">
</argument>
<description>
- Overrides the font with given [code]name[/code] in the [member theme] resource the control uses. If [code]font[/code] is [code]null[/code] or invalid, the override is cleared and the font from assigned [Theme] is used.
+ Overrides the font with given [code]name[/code] in the [member theme] resource the control uses.
</description>
</method>
<method name="add_theme_font_size_override">
@@ -200,7 +199,7 @@
<argument index="1" name="font_size" type="int">
</argument>
<description>
- Overrides the font size with given [code]name[/code] in the [member theme] resource the control uses. If [code]font_size[/code] is [code]-1[/code], the override is cleared and the font size from assigned [Theme] is used.
+ Overrides the font size with given [code]name[/code] in the [member theme] resource the control uses.
</description>
</method>
<method name="add_theme_icon_override">
@@ -211,7 +210,7 @@
<argument index="1" name="texture" type="Texture2D">
</argument>
<description>
- Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses. If [code]icon[/code] is [code]null[/code] or invalid, the override is cleared and the icon from assigned [Theme] is used.
+ Overrides the icon with given [code]name[/code] in the [member theme] resource the control uses.
</description>
</method>
<method name="add_theme_stylebox_override">
@@ -222,7 +221,7 @@
<argument index="1" name="stylebox" type="StyleBox">
</argument>
<description>
- Overrides the [StyleBox] with given [code]name[/code] in the [member theme] resource the control uses. If [code]stylebox[/code] is empty or invalid, the override is cleared and the [StyleBox] from assigned [Theme] is used.
+ Overrides the [StyleBox] with given [code]name[/code] in the [member theme] resource the control uses.
[b]Example of modifying a property in a StyleBox by duplicating it:[/b]
[codeblocks]
[gdscript]
@@ -730,6 +729,60 @@
Give up the focus. No other control will be able to receive keyboard input.
</description>
</method>
+ <method name="remove_theme_color_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for a [Color] with the given [code]name[/code].
+ </description>
+ </method>
+ <method name="remove_theme_constant_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for a constant with the given [code]name[/code].
+ </description>
+ </method>
+ <method name="remove_theme_font_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for a [Font] with the given [code]name[/code].
+ </description>
+ </method>
+ <method name="remove_theme_font_size_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for a font size with the given [code]name[/code].
+ </description>
+ </method>
+ <method name="remove_theme_icon_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for an icon with the given [code]name[/code].
+ </description>
+ </method>
+ <method name="remove_theme_stylebox_override">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="StringName">
+ </argument>
+ <description>
+ Removes a theme override for a [StyleBox] with the given [code]name[/code].
+ </description>
+ </method>
<method name="set_anchor">
<return type="void">
</return>
diff --git a/doc/classes/Directory.xml b/doc/classes/Directory.xml
index 6a126204c6..a9d7960501 100644
--- a/doc/classes/Directory.xml
+++ b/doc/classes/Directory.xml
@@ -6,6 +6,7 @@
<description>
Directory type. It is used to manage directories and their content (not restricted to the project folder).
When creating a new [Directory], it must be explicitly opened using [method open] before most methods can be used. However, [method file_exists] and [method dir_exists] can be used without opening a directory. If so, they use a path relative to [code]res://[/code].
+ [b]Note:[/b] Many resources types are imported (e.g. textures or sound files), and their source asset will not be included in the exported game, as only the imported version is used. Use [ResourceLoader] to access imported resources.
Here is an example on how to iterate through the files of a directory:
[codeblocks]
[gdscript]
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index b01af71852..4d0e11fb19 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -48,6 +48,14 @@
[b]Note:[/b] This returns the main editor control containing the whole editor, not the 2D or 3D viewports specifically.
</description>
</method>
+ <method name="get_editor_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ Returns the actual scale of the editor UI ([code]1.0[/code] being 100% scale). This can be used to adjust position and dimensions of the UI added by plugins.
+ [b]Note:[/b] This value is set via the [code]interface/editor/display_scale[/code] and [code]interface/editor/custom_display_scale[/code] editor settings. Editor must be restarted for changes to be properly applied.
+ </description>
+ </method>
<method name="get_editor_settings">
<return type="EditorSettings">
</return>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 8dcffb0b74..61f1761249 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -214,7 +214,7 @@
[gdscript]
func forward_canvas_draw_over_viewport(overlay):
# Draw a circle at cursor position.
- overlay.draw_circle(overlay.get_local_mouse_position(), 64)
+ overlay.draw_circle(overlay.get_local_mouse_position(), 64, Color.white)
func forward_canvas_gui_input(event):
if event is InputEventMouseMotion:
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 821aa91d21..6909fac2b7 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -176,6 +176,8 @@
<member name="sdfgi_cascades" type="int" setter="set_sdfgi_cascades" getter="get_sdfgi_cascades" enum="Environment.SDFGICascades" default="1">
</member>
<member name="sdfgi_enabled" type="bool" setter="set_sdfgi_enabled" getter="is_sdfgi_enabled" default="false">
+ If [code]true[/code], enables signed distance field global illumination.
+ [b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh.
</member>
<member name="sdfgi_energy" type="float" setter="set_sdfgi_energy" getter="get_sdfgi_energy" default="1.0">
</member>
diff --git a/doc/classes/GIProbe.xml b/doc/classes/GIProbe.xml
index dd51248fd9..4f56d1ad3e 100644
--- a/doc/classes/GIProbe.xml
+++ b/doc/classes/GIProbe.xml
@@ -6,6 +6,7 @@
<description>
[GIProbe]s are used to provide high-quality real-time indirect light to scenes. They precompute the effect of objects that emit light and the effect of static geometry to simulate the behavior of complex light in real-time. [GIProbe]s need to be baked before using, however, once baked, dynamic objects will receive light from them. Further, lights can be fully dynamic or baked.
Having [GIProbe]s in a scene can be expensive, the quality of the probe can be turned down in exchange for better performance in the [ProjectSettings] using [member ProjectSettings.rendering/global_illumination/gi_probes/quality].
+ [b]Note:[/b] Meshes should have sufficiently thick walls to avoid light leaks (avoid one-sided walls). For interior levels, enclose your level geometry in a sufficiently large box and bridge the loops to close the mesh.
</description>
<tutorials>
<link title="GI probes">https://docs.godotengine.org/en/latest/tutorials/3d/gi_probes.html</link>
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index 2bea482bc1..5fef56e354 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -18,11 +18,11 @@
var texture = load("res://icon.png")
$Sprite2D.texture = texture
[/codeblock]
- This is because images have to be imported as [StreamTexture2D] first to be loaded with [method @GDScript.load]. If you'd still like to load an image file just like any other [Resource], import it as an [Image] resource instead, and then load it normally using the [method @GDScript.load] method.
- But do note that the image data can still be retrieved from an imported texture as well using the [method Texture2D.get_data] method, which returns a copy of the data:
+ This is because images have to be imported as a [StreamTexture2D] first to be loaded with [method @GDScript.load]. If you'd still like to load an image file just like any other [Resource], import it as an [Image] resource instead, and then load it normally using the [method @GDScript.load] method.
+ [b]Note:[/b] The image can be retrieved from an imported texture using the [method Texture2D.get_image] method, which returns a copy of the image:
[codeblock]
var texture = load("res://icon.png")
- var image : Image = texture.get_data()
+ var image : Image = texture.get_image()
[/codeblock]
An [ImageTexture] is not meant to be operated from within the editor interface directly, and is mostly useful for rendering images on screen dynamically via code. If you need to generate images procedurally from within the editor, consider saving and importing images as custom texture resources implementing a new [EditorImportPlugin].
[b]Note:[/b] The maximum texture size is 16384×16384 pixels due to graphics hardware limitations.
diff --git a/doc/classes/PackedByteArray.xml b/doc/classes/PackedByteArray.xml
index 3c7f0f4fad..21f835a53c 100644
--- a/doc/classes/PackedByteArray.xml
+++ b/doc/classes/PackedByteArray.xml
@@ -157,13 +157,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -230,6 +223,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedColorArray.xml b/doc/classes/PackedColorArray.xml
index abfedc84cc..38240b3154 100644
--- a/doc/classes/PackedColorArray.xml
+++ b/doc/classes/PackedColorArray.xml
@@ -79,13 +79,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -152,6 +145,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedFloat32Array.xml b/doc/classes/PackedFloat32Array.xml
index 8918312dc7..6be1d24b5d 100644
--- a/doc/classes/PackedFloat32Array.xml
+++ b/doc/classes/PackedFloat32Array.xml
@@ -80,13 +80,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -145,6 +138,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedFloat64Array.xml b/doc/classes/PackedFloat64Array.xml
index fbb832299e..fb7817cb41 100644
--- a/doc/classes/PackedFloat64Array.xml
+++ b/doc/classes/PackedFloat64Array.xml
@@ -80,13 +80,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -153,6 +146,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedInt32Array.xml b/doc/classes/PackedInt32Array.xml
index ecef2d508b..4ee428dfbc 100644
--- a/doc/classes/PackedInt32Array.xml
+++ b/doc/classes/PackedInt32Array.xml
@@ -80,13 +80,6 @@
Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -153,6 +146,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedInt64Array.xml b/doc/classes/PackedInt64Array.xml
index 19619d60cf..51948fcbc8 100644
--- a/doc/classes/PackedInt64Array.xml
+++ b/doc/classes/PackedInt64Array.xml
@@ -80,13 +80,6 @@
Inserts a new integer at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -153,6 +146,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedStringArray.xml b/doc/classes/PackedStringArray.xml
index c241573b93..9748301dae 100644
--- a/doc/classes/PackedStringArray.xml
+++ b/doc/classes/PackedStringArray.xml
@@ -80,13 +80,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -153,6 +146,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedVector2Array.xml b/doc/classes/PackedVector2Array.xml
index 9138dc68e1..1b3201b072 100644
--- a/doc/classes/PackedVector2Array.xml
+++ b/doc/classes/PackedVector2Array.xml
@@ -80,13 +80,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -161,6 +154,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/PackedVector3Array.xml b/doc/classes/PackedVector3Array.xml
index 0a3b0cf2c0..25d854016a 100644
--- a/doc/classes/PackedVector3Array.xml
+++ b/doc/classes/PackedVector3Array.xml
@@ -79,13 +79,6 @@
Inserts a new element at a given position in the array. The position must be valid, or at the end of the array ([code]idx == size()[/code]).
</description>
</method>
- <method name="invert">
- <return type="void">
- </return>
- <description>
- Reverses the order of the elements in the array.
- </description>
- </method>
<method name="is_empty" qualifiers="const">
<return type="bool">
</return>
@@ -160,6 +153,13 @@
Sets the size of the array. If the array is grown, reserves elements at the end of the array. If the array is shrunk, truncates the array to the new size.
</description>
</method>
+ <method name="reverse">
+ <return type="void">
+ </return>
+ <description>
+ Reverses the order of the elements in the array.
+ </description>
+ </method>
<method name="set">
<return type="void">
</return>
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml
index cb72ae7e4c..c6dd6fb142 100644
--- a/doc/classes/Skeleton3D.xml
+++ b/doc/classes/Skeleton3D.xml
@@ -245,6 +245,16 @@
[b]Note[/b]: The pose transform needs to be in bone space. Use [method world_transform_to_bone_transform] to convert a world transform, like one you can get from a [Node3D], to bone space.
</description>
</method>
+ <method name="set_bone_name">
+ <return type="void">
+ </return>
+ <argument index="0" name="bone_idx" type="int">
+ </argument>
+ <argument index="1" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_bone_parent">
<return type="void">
</return>
diff --git a/doc/classes/StreamPeerTCP.xml b/doc/classes/StreamPeerTCP.xml
index bb85d94bf9..b6d91715ee 100644
--- a/doc/classes/StreamPeerTCP.xml
+++ b/doc/classes/StreamPeerTCP.xml
@@ -61,8 +61,8 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- Disables Nagle's algorithm to improve latency for small packets.
- [b]Note:[/b] For applications that send large packets or need to transfer a lot of data, this can decrease the total available bandwidth.
+ If [code]enabled[/code] is [code]true[/code], packets will be sent immediately. If [code]enabled[/code] is [code]false[/code] (the default), packet transfers will be delayed and combined using [url=https://en.wikipedia.org/wiki/Nagle%27s_algorithm]Nagle's algorithm[/url].
+ [b]Note:[/b] It's recommended to leave this disabled for applications that send large packets or need to transfer a lot of data, as enabling this can decrease the total available bandwidth.
</description>
</method>
</methods>
diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml
index 24c114c18b..79fa8896e3 100644
--- a/doc/classes/Tabs.xml
+++ b/doc/classes/Tabs.xml
@@ -254,6 +254,9 @@
</method>
</methods>
<members>
+ <member name="clip_tabs" type="bool" setter="set_clip_tabs" getter="get_clip_tabs" default="true">
+ If [code]true[/code], tabs overflowing this node's width will be hidden, displaying two navigation buttons instead. Otherwise, this node's minimum size is updated so that all tabs are visible.
+ </member>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab" default="0">
Select tab at index [code]tab_idx[/code].
</member>
diff --git a/doc/classes/TextParagraph.xml b/doc/classes/TextParagraph.xml
index 69bf823ccd..8df53b8423 100644
--- a/doc/classes/TextParagraph.xml
+++ b/doc/classes/TextParagraph.xml
@@ -289,6 +289,20 @@
Returns the size of the bounding box of the paragraph.
</description>
</method>
+ <method name="get_spacing_bottom" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns extra spacing at the bottom of the line. See [member Font.extra_spacing_bottom].
+ </description>
+ </method>
+ <method name="get_spacing_top" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns extra spacing at the top of the line. See [member Font.extra_spacing_top].
+ </description>
+ </method>
<method name="hit_test" qualifiers="const">
<return type="int">
</return>
diff --git a/doc/classes/TextServer.xml b/doc/classes/TextServer.xml
index 4a41b68fee..fe63e434c9 100644
--- a/doc/classes/TextServer.xml
+++ b/doc/classes/TextServer.xml
@@ -258,6 +258,22 @@
Returns advance of the glyph.
</description>
</method>
+ <method name="font_get_glyph_contours" qualifiers="const">
+ <return type="Dictionary">
+ </return>
+ <argument index="0" name="font" type="RID">
+ </argument>
+ <argument index="1" name="size" type="int">
+ </argument>
+ <argument index="2" name="index" type="int">
+ </argument>
+ <description>
+ Returns outline contours of the glyph in a Dictionary.
+ [code]points[/code] - [PackedVector3Array], containing outline points. [code]x[/code] and [code]y[/code] are point coordinates. [code]z[/code] is the type of the point, using the [enum ContourPointTag] values.
+ [code]contours[/code] - [PackedInt32Array], containing indices the end points of each contour.
+ [code]orientation[/code] - [bool], contour orientation. If [code]true[/code], clockwise contours must be filled.
+ </description>
+ </method>
<method name="font_get_glyph_index" qualifiers="const">
<return type="int">
</return>
@@ -1301,5 +1317,14 @@
<constant name="FEATURE_USE_SUPPORT_DATA" value="128" enum="Feature">
TextServer require external data file for some features.
</constant>
+ <constant name="CONTOUR_CURVE_TAG_ON" value="1" enum="ContourPointTag">
+ Contour point is on the curve.
+ </constant>
+ <constant name="CONTOUR_CURVE_TAG_OFF_CONIC" value="0" enum="ContourPointTag">
+ Contour point isn't on the curve, but serves as a control point for a conic (quadratic) Bézier arc.
+ </constant>
+ <constant name="CONTOUR_CURVE_TAG_OFF_CUBIC" value="2" enum="ContourPointTag">
+ Contour point isn't on the curve, but serves as a control point for a cubic Bézier arc.
+ </constant>
</constants>
</class>
diff --git a/doc/classes/Texture2D.xml b/doc/classes/Texture2D.xml
index 2270b95c63..c33f32c9e4 100644
--- a/doc/classes/Texture2D.xml
+++ b/doc/classes/Texture2D.xml
@@ -63,18 +63,18 @@
Draws a part of the texture using a [CanvasItem] with the [RenderingServer] API.
</description>
</method>
- <method name="get_data" qualifiers="const">
- <return type="Image">
+ <method name="get_height" qualifiers="const">
+ <return type="int">
</return>
<description>
- Returns an [Image] that is a copy of data from this [Texture2D]. [Image]s can be accessed and manipulated directly.
+ Returns the texture height.
</description>
</method>
- <method name="get_height" qualifiers="const">
- <return type="int">
+ <method name="get_image" qualifiers="const">
+ <return type="Image">
</return>
<description>
- Returns the texture height.
+ Returns an [Image] that is a copy of data from this [Texture2D]. [Image]s can be accessed and manipulated directly.
</description>
</method>
<method name="get_size" qualifiers="const">
diff --git a/doc/classes/Theme.xml b/doc/classes/Theme.xml
index ad22573eb8..3173dddb42 100644
--- a/doc/classes/Theme.xml
+++ b/doc/classes/Theme.xml
@@ -278,7 +278,7 @@
</description>
</method>
<method name="get_theme_item" qualifiers="const">
- <return type="StyleBox">
+ <return type="Variant">
</return>
<argument index="0" name="data_type" type="int" enum="Theme.DataType">
</argument>
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 7ed8ad6d4a..205b342ba8 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -174,7 +174,7 @@
Overriding this method also overrides it internally, allowing custom logic to be implemented when tiles are placed/removed:
[codeblocks]
[gdscript]
- func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, autotile_coord=Vector2())
+ func set_cell(x, y, tile, flip_x=false, flip_y=false, transpose=false, autotile_coord=Vector2()):
# Write your custom logic here.
# To call the default method:
.set_cell(x, y, tile, flip_x, flip_y, transpose, autotile_coord)
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 8120ae539e..471d21374d 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -80,9 +80,9 @@
</return>
<description>
Returns the viewport's texture.
- [b]Note:[/b] Due to the way OpenGL works, the resulting [ViewportTexture] is flipped vertically. You can use [method Image.flip_y] on the result of [method Texture2D.get_data] to flip it back, for example:
+ [b]Note:[/b] Due to the way OpenGL works, the resulting [ViewportTexture] is flipped vertically. You can use [method Image.flip_y] on the result of [method Texture2D.get_image] to flip it back, for example:
[codeblock]
- var img = get_viewport().get_texture().get_data()
+ var img = get_viewport().get_texture().get_image()
img.flip_y()
[/codeblock]
</description>
diff --git a/doc/classes/VisualShaderNodeComment.xml b/doc/classes/VisualShaderNodeComment.xml
new file mode 100644
index 0000000000..8970e2fabb
--- /dev/null
+++ b/doc/classes/VisualShaderNodeComment.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeComment" inherits="VisualShaderNodeResizableBase" version="4.0">
+ <brief_description>
+ A comment node to be placed on visual shader graph.
+ </brief_description>
+ <description>
+ A resizable rectangular area with changeable [member title] and [member description] used for better organizing of other visual shader nodes.
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="description" type="String" setter="set_description" getter="get_description" default="&quot;&quot;">
+ An additional description which placed below the title.
+ </member>
+ <member name="title" type="String" setter="set_title" getter="get_title" default="&quot;Comment&quot;">
+ A title of the node.
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/XRPositionalTracker.xml b/doc/classes/XRPositionalTracker.xml
index 36cd6e2ea0..5274d952fd 100644
--- a/doc/classes/XRPositionalTracker.xml
+++ b/doc/classes/XRPositionalTracker.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="XRPositionalTracker" inherits="Object" version="4.0">
+<class name="XRPositionalTracker" inherits="Reference" version="4.0">
<brief_description>
A tracked object.
</brief_description>
diff --git a/doc/classes/XRServer.xml b/doc/classes/XRServer.xml
index 75a05bef17..d0edf91fed 100644
--- a/doc/classes/XRServer.xml
+++ b/doc/classes/XRServer.xml
@@ -10,6 +10,24 @@
<link title="VR tutorial index">https://docs.godotengine.org/en/latest/tutorials/vr/index.html</link>
</tutorials>
<methods>
+ <method name="add_interface">
+ <return type="void">
+ </return>
+ <argument index="0" name="interface" type="XRInterface">
+ </argument>
+ <description>
+ Registers an [XRInterface] object.
+ </description>
+ </method>
+ <method name="add_tracker">
+ <return type="void">
+ </return>
+ <argument index="0" name="tracker" type="XRPositionalTracker">
+ </argument>
+ <description>
+ Registers a new [XRPositionalTracker] that tracks a spatial location in real space.
+ </description>
+ </method>
<method name="center_on_hmd">
<return type="void">
</return>
@@ -26,6 +44,15 @@
You should call this method after a few seconds have passed. For instance, when the user requests a realignment of the display holding a designated button on a controller for a short period of time, or when implementing a teleport mechanism.
</description>
</method>
+ <method name="clear_primary_interface_if">
+ <return type="void">
+ </return>
+ <argument index="0" name="interface" type="XRInterface">
+ </argument>
+ <description>
+ Clears our current primary interface if it is set to the provided interface.
+ </description>
+ </method>
<method name="find_interface" qualifiers="const">
<return type="XRInterface">
</return>
@@ -109,6 +136,24 @@
Returns the number of trackers currently registered.
</description>
</method>
+ <method name="remove_interface">
+ <return type="void">
+ </return>
+ <argument index="0" name="interface" type="XRInterface">
+ </argument>
+ <description>
+ Removes this interface.
+ </description>
+ </method>
+ <method name="remove_tracker">
+ <return type="void">
+ </return>
+ <argument index="0" name="tracker" type="XRPositionalTracker">
+ </argument>
+ <description>
+ Removes this positional tracker.
+ </description>
+ </method>
</methods>
<members>
<member name="primary_interface" type="XRInterface" setter="set_primary_interface" getter="get_primary_interface">
diff --git a/doc/classes/bool.xml b/doc/classes/bool.xml
index 8da1eb3c88..48f336d58c 100644
--- a/doc/classes/bool.xml
+++ b/doc/classes/bool.xml
@@ -132,6 +132,7 @@
<argument index="0" name="right" type="bool">
</argument>
<description>
+ Returns [code]true[/code] if two bools are different, i.e. one is [code]true[/code] and the other is [code]false[/code].
</description>
</method>
<method name="operator &lt;" qualifiers="operator">
@@ -140,6 +141,7 @@
<argument index="0" name="right" type="bool">
</argument>
<description>
+ Returns [code]true[/code] if left operand is [code]false[/code] and right operand is [code]true[/code].
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -148,6 +150,7 @@
<argument index="0" name="right" type="bool">
</argument>
<description>
+ Returns [code]true[/code] if two bools are equal, i.e. both are [code]true[/code] or both are [code]false[/code].
</description>
</method>
<method name="operator &gt;" qualifiers="operator">
@@ -156,6 +159,7 @@
<argument index="0" name="right" type="bool">
</argument>
<description>
+ Returns [code]true[/code] if left operand is [code]true[/code] and right operand is [code]false[/code].
</description>
</method>
</methods>
diff --git a/doc/classes/float.xml b/doc/classes/float.xml
index 85fe31eec8..11f6d91b05 100644
--- a/doc/classes/float.xml
+++ b/doc/classes/float.xml
@@ -49,6 +49,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if two floats are different from each other.
</description>
</method>
<method name="operator !=" qualifiers="operator">
@@ -57,6 +58,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if the integer has different value than the float.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -65,6 +67,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Multiplies two [float]s.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -73,6 +76,10 @@
<argument index="0" name="right" type="Vector2">
</argument>
<description>
+ Multiplies each component of the [Vector2] by the given [float].
+ [codeblock]
+ print(2.5 * Vector2(1, 1)) # Vector2(2.5, 2.5)
+ [/codeblock]
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -81,6 +88,10 @@
<argument index="0" name="right" type="Vector2i">
</argument>
<description>
+ Multiplies each component of the [Vector2i] by the given [float].
+ [codeblock]
+ print(2.0 * Vector2i(1, 1)) # Vector2i(2.0, 2.0)
+ [/codeblock]
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -89,6 +100,7 @@
<argument index="0" name="right" type="Vector3">
</argument>
<description>
+ Multiplies each component of the [Vector3] by the given [float].
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -97,6 +109,7 @@
<argument index="0" name="right" type="Vector3i">
</argument>
<description>
+ Multiplies each component of the [Vector3i] by the given [float].
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -105,6 +118,7 @@
<argument index="0" name="right" type="Quat">
</argument>
<description>
+ Multiplies each component of the [Quat] by the given [float].
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -113,6 +127,10 @@
<argument index="0" name="right" type="Color">
</argument>
<description>
+ Multiplies each component of the [Color] by the given [float].
+ [codeblock]
+ print(1.5 * Color(0.5, 0.5, 0.5)) # Color(0.75, 0.75, 0.75)
+ [/codeblock]
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -121,12 +139,17 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Multiplies a [float] and an [int]. The result is a [float].
</description>
</method>
<method name="operator +" qualifiers="operator">
<return type="float">
</return>
<description>
+ Unary plus operator. Doesn't have any effect.
+ [codeblock]
+ var a = +2.5 # a is 2.5.
+ [/codeblock]
</description>
</method>
<method name="operator +" qualifiers="operator">
@@ -135,6 +158,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Adds two floats.
</description>
</method>
<method name="operator +" qualifiers="operator">
@@ -143,12 +167,18 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Adds a [float] and an [int]. The result is a [float].
</description>
</method>
<method name="operator -" qualifiers="operator">
<return type="float">
</return>
<description>
+ Unary minus operator. Negates the number.
+ [codeblock]
+ var a = -2.5 # a is -2.5.
+ print(-a) # 2.5
+ [/codeblock]
</description>
</method>
<method name="operator -" qualifiers="operator">
@@ -157,6 +187,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Subtracts a float from a float.
</description>
</method>
<method name="operator -" qualifiers="operator">
@@ -165,6 +196,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Subtracts an [int] from a [float]. The result is a [float].
</description>
</method>
<method name="operator /" qualifiers="operator">
@@ -173,6 +205,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Divides two floats.
</description>
</method>
<method name="operator /" qualifiers="operator">
@@ -181,6 +214,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Divides a [float] by an [int]. The result is a [float].
</description>
</method>
<method name="operator &lt;" qualifiers="operator">
@@ -189,6 +223,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] the left float is less than the right one.
</description>
</method>
<method name="operator &lt;" qualifiers="operator">
@@ -197,6 +232,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if this [float] is less than the given [int].
</description>
</method>
<method name="operator &lt;=" qualifiers="operator">
@@ -205,6 +241,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] the left integer is less than or equal to the right one.
</description>
</method>
<method name="operator &lt;=" qualifiers="operator">
@@ -213,6 +250,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if this [float] is less than or equal to the given [int].
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -221,6 +259,8 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if both floats are exactly equal.
+ [b]Note:[/b] Due to floating-point precision errors, consider using [method @GlobalScope.is_equal_approx] or [method @GlobalScope.is_zero_approx] instead, which are more reliable.
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -229,6 +269,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if the [float] and the given [int] are equal.
</description>
</method>
<method name="operator &gt;" qualifiers="operator">
@@ -237,6 +278,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] the left float is greater than the right one.
</description>
</method>
<method name="operator &gt;" qualifiers="operator">
@@ -245,6 +287,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if this [float] is greater than the given [int].
</description>
</method>
<method name="operator &gt;=" qualifiers="operator">
@@ -253,6 +296,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] the left float is greater than or equal to the right one.
</description>
</method>
<method name="operator &gt;=" qualifiers="operator">
@@ -261,6 +305,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if this [float] is greater than or equal to the given [int].
</description>
</method>
</methods>
diff --git a/doc/classes/int.xml b/doc/classes/int.xml
index a63c509937..119cdf8eeb 100644
--- a/doc/classes/int.xml
+++ b/doc/classes/int.xml
@@ -79,6 +79,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if operands are different from each other.
</description>
</method>
<method name="operator !=" qualifiers="operator">
@@ -87,6 +88,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if operands are different from each other.
</description>
</method>
<method name="operator %" qualifiers="operator">
@@ -95,6 +97,12 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns the result of the modulo operator for two integers, i.e. the remainder after dividing both numbers.
+ [codeblock]
+ print(5 % 2) # 1
+ print(12 % 4) # 0
+ print(12 % 2) # 2
+ [/codeblock]
</description>
</method>
<method name="operator &amp;" qualifiers="operator">
@@ -103,6 +111,18 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns the result of bitwise [code]AND[/code] operation for two integers.
+ [codeblock]
+ print(3 &amp; 1) # 1
+ print(11 &amp; 3) # 3
+ [/codeblock]
+ It's useful to retrieve binary flags from a variable.
+ [codeblock]
+ var flags = 5
+ # Do something if the first bit is enabled.
+ if flags &amp; 1:
+ do_stuff()
+ [/codeblock]
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -111,6 +131,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Multiplies an [int] and a [float]. The result is a [float].
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -119,6 +140,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Multiplies two [int]s.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -127,6 +149,10 @@
<argument index="0" name="right" type="Vector2">
</argument>
<description>
+ Multiplies each component of the vector by the given integer.
+ [codeblock]
+ print(2 * Vector2(1, 1)) # Vector2(2, 2)
+ [/codeblock]
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -135,6 +161,7 @@
<argument index="0" name="right" type="Vector2i">
</argument>
<description>
+ Multiplies each component of the integer vector by the given integer.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -143,6 +170,7 @@
<argument index="0" name="right" type="Vector3">
</argument>
<description>
+ Multiplies each component of the vector by the given integer.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -151,6 +179,7 @@
<argument index="0" name="right" type="Vector3i">
</argument>
<description>
+ Multiplies each component of the integer vector by the given integer.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -159,6 +188,7 @@
<argument index="0" name="right" type="Quat">
</argument>
<description>
+ Multiplies each component of the quaternion by the given integer.
</description>
</method>
<method name="operator *" qualifiers="operator">
@@ -167,12 +197,20 @@
<argument index="0" name="right" type="Color">
</argument>
<description>
+ Multiplies each component of the color by the given integer.
+ [codeblock]
+ print(2 * Color(0.5, 0.5, 0.5)) # Color(1, 1, 1)
+ [/codeblock]
</description>
</method>
<method name="operator +" qualifiers="operator">
<return type="int">
</return>
<description>
+ Unary plus operator. Doesn't have any effect.
+ [codeblock]
+ var a = +1 # a is 1.
+ [/codeblock]
</description>
</method>
<method name="operator +" qualifiers="operator">
@@ -181,6 +219,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Adds an [int] to a [float]. The result is a [float].
</description>
</method>
<method name="operator +" qualifiers="operator">
@@ -189,12 +228,18 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Adds two integers.
</description>
</method>
<method name="operator -" qualifiers="operator">
<return type="int">
</return>
<description>
+ Unary minus operator. Negates the number.
+ [codeblock]
+ var a = -1 # a is -1.
+ print(-a) # 1
+ [/codeblock]
</description>
</method>
<method name="operator -" qualifiers="operator">
@@ -203,6 +248,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Subtracts a [float] from an [int]. The result is a [float].
</description>
</method>
<method name="operator -" qualifiers="operator">
@@ -211,6 +257,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Subtracts two integers.
</description>
</method>
<method name="operator /" qualifiers="operator">
@@ -219,6 +266,10 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Divides an [int] by a [float]. The result is a [float].
+ [codeblock]
+ print(10 / 3.0) # 3.333...
+ [/codeblock]
</description>
</method>
<method name="operator /" qualifiers="operator">
@@ -227,6 +278,11 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Divides two integers. The decimal part of the result is discarded (truncated).
+ [codeblock]
+ print(10 / 2) # 5
+ print(10 / 3) # 3
+ [/codeblock]
</description>
</method>
<method name="operator &lt;" qualifiers="operator">
@@ -235,6 +291,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if this [int] is less than the given [float].
</description>
</method>
<method name="operator &lt;" qualifiers="operator">
@@ -243,6 +300,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] the left integer is less than the right one.
</description>
</method>
<method name="operator &lt;&lt;" qualifiers="operator">
@@ -251,6 +309,11 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Performs bitwise shift left operation on the integer. Effectively the same as multiplying by a power of 2.
+ [codeblock]
+ print(10 &lt;&lt; 1) # 20
+ print(10 &lt;&lt; 4) # 160
+ [/codeblock]
</description>
</method>
<method name="operator &lt;=" qualifiers="operator">
@@ -259,6 +322,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if this [int] is less than or equal to the given [float].
</description>
</method>
<method name="operator &lt;=" qualifiers="operator">
@@ -267,6 +331,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] the left integer is less than or equal to the right one.
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -275,6 +340,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if the integer is equal to the given [float].
</description>
</method>
<method name="operator ==" qualifiers="operator">
@@ -283,6 +349,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] if both integers are equal.
</description>
</method>
<method name="operator &gt;" qualifiers="operator">
@@ -291,6 +358,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if this [int] is greater than the given [float].
</description>
</method>
<method name="operator &gt;" qualifiers="operator">
@@ -299,6 +367,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] the left integer is greater than the right one.
</description>
</method>
<method name="operator &gt;=" qualifiers="operator">
@@ -307,6 +376,7 @@
<argument index="0" name="right" type="float">
</argument>
<description>
+ Returns [code]true[/code] if this [int] is greater than or equal to the given [float].
</description>
</method>
<method name="operator &gt;=" qualifiers="operator">
@@ -315,6 +385,7 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns [code]true[/code] the left integer is greater than or equal to the right one.
</description>
</method>
<method name="operator &gt;&gt;" qualifiers="operator">
@@ -323,6 +394,11 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Performs bitwise shift right operation on the integer. Effectively the same as dividing by a power of 2.
+ [codeblock]
+ print(10 &gt;&gt; 1) # 5
+ print(10 &gt;&gt; 2) # 2
+ [/codeblock]
</description>
</method>
<method name="operator ^" qualifiers="operator">
@@ -331,6 +407,11 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns the result of bitwise [code]XOR[/code] operation for two integers.
+ [codeblock]
+ print(5 ^ 1) # 4
+ print(4 ^ 7) # 3
+ [/codeblock]
</description>
</method>
<method name="operator |" qualifiers="operator">
@@ -339,12 +420,29 @@
<argument index="0" name="right" type="int">
</argument>
<description>
+ Returns the result of bitwise [code]OR[/code] operation for two integers.
+ [codeblock]
+ print(2 | 4) # 6
+ print(1 | 3) # 3
+ [/codeblock]
+ It's useful to store binary flags in a variable.
+ [codeblock]
+ var flags = 0
+ # Turn first and third bit on.
+ flags |= 1
+ flags |= 4
+ [/codeblock]
</description>
</method>
<method name="operator ~" qualifiers="operator">
<return type="int">
</return>
<description>
+ Returns the result of bitwise [code]NOT[/code] operation for the integer. It's effectively equal to [code]-int + 1[/code].
+ [codeblock]
+ print(~4) # -3
+ print(~7) # -6
+ [/codeblock]
</description>
</method>
</methods>
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index f47fc403cc..b737a287d1 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -41,7 +41,7 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
ERR_FAIL_COND_V_MSG(!texture.is_valid(), ERR_INVALID_PARAMETER, "Can't save invalid texture as PNG.");
ERR_FAIL_COND_V_MSG(!texture->get_width(), ERR_INVALID_PARAMETER, "Can't save empty texture as PNG.");
- Ref<Image> img = texture->get_data();
+ Ref<Image> img = texture->get_image();
Error err = save_image(p_path, img);
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 469d80368d..09e2b4546a 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -1486,7 +1486,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
// possible in a single frame
if (staging_buffer_blocks[staging_buffer_current].frame_used == frames_drawn) {
//guess we did.. ok, let's see if we can insert a new block..
- if (staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) {
+ if ((uint64_t)staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) {
//we can, so we are safe
Error err = _insert_staging_block();
if (err) {
@@ -1530,7 +1530,7 @@ Error RenderingDeviceVulkan::_staging_buffer_allocate(uint32_t p_amount, uint32_
staging_buffer_blocks.write[staging_buffer_current].fill_amount = 0;
} else if (staging_buffer_blocks[staging_buffer_current].frame_used > frames_drawn - frame_count) {
//this block may still be in use, let's not touch it unless we have to, so.. can we create a new one?
- if (staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) {
+ if ((uint64_t)staging_buffer_blocks.size() * staging_buffer_block_size < staging_buffer_max_size) {
//we are still allowed to create a new block, so let's do that and insert it for current pos
Error err = _insert_staging_block();
if (err) {
@@ -2566,7 +2566,7 @@ Vector<uint8_t> RenderingDeviceVulkan::_texture_get_data_from_image(Texture *tex
for (uint32_t y = 0; y < height; y++) {
const uint8_t *rptr = slice_read_ptr + y * layout.rowPitch;
uint8_t *wptr = write_ptr + y * pixel_size * width;
- copymem(wptr, rptr, pixel_size * width);
+ copymem(wptr, rptr, (uint64_t)pixel_size * width);
}
}
}
@@ -7834,6 +7834,18 @@ void RenderingDeviceVulkan::_flush(bool p_current_frame) {
}
void RenderingDeviceVulkan::initialize(VulkanContext *p_context, bool p_local_device) {
+ // get our device capabilities
+ {
+ device_capabilities.version_major = p_context->get_vulkan_major();
+ device_capabilities.version_minor = p_context->get_vulkan_minor();
+
+ // get info about subgroups
+ VulkanContext::SubgroupCapabilities subgroup_capabilities = p_context->get_subgroup_capabilities();
+ device_capabilities.subgroup_size = subgroup_capabilities.size;
+ device_capabilities.subgroup_in_shaders = subgroup_capabilities.supported_stages_flags_rd();
+ device_capabilities.subgroup_operations = subgroup_capabilities.supported_operations_flags_rd();
+ }
+
context = p_context;
device = p_context->get_device();
if (p_local_device) {
@@ -8253,6 +8265,7 @@ RenderingDevice *RenderingDeviceVulkan::create_local_device() {
}
RenderingDeviceVulkan::RenderingDeviceVulkan() {
+ device_capabilities.device_family = DEVICE_VULKAN;
}
RenderingDeviceVulkan::~RenderingDeviceVulkan() {
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp
index 69517b17ba..504e63392f 100644
--- a/drivers/vulkan/vulkan_context.cpp
+++ b/drivers/vulkan/vulkan_context.cpp
@@ -34,6 +34,7 @@
#include "core/config/project_settings.h"
#include "core/string/ustring.h"
#include "core/version.h"
+#include "servers/rendering/rendering_device.h"
#include "vk_enum_string_helper.h"
@@ -163,6 +164,35 @@ VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_messenger_callback(
return VK_FALSE;
}
+VKAPI_ATTR VkBool32 VKAPI_CALL VulkanContext::_debug_report_callback(
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char *pLayerPrefix,
+ const char *pMessage,
+ void *pUserData) {
+ String debugMessage = String("Vulkan Debug Report: object - ") +
+ String::num_int64(object) + "\n" + pMessage;
+
+ switch (flags) {
+ case VK_DEBUG_REPORT_DEBUG_BIT_EXT:
+ case VK_DEBUG_REPORT_INFORMATION_BIT_EXT:
+ print_line(debugMessage);
+ break;
+ case VK_DEBUG_REPORT_WARNING_BIT_EXT:
+ case VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT:
+ WARN_PRINT(debugMessage);
+ break;
+ case VK_DEBUG_REPORT_ERROR_BIT_EXT:
+ ERR_PRINT(debugMessage);
+ break;
+ }
+
+ return VK_FALSE;
+}
+
VkBool32 VulkanContext::_check_layers(uint32_t check_count, const char **check_names, uint32_t layer_count, VkLayerProperties *layers) {
for (uint32_t i = 0; i < check_count; i++) {
VkBool32 found = 0;
@@ -234,12 +264,46 @@ Error VulkanContext::_create_validation_layers() {
return OK;
}
+typedef VkResult(VKAPI_PTR *_vkEnumerateInstanceVersion)(uint32_t *);
+
+Error VulkanContext::_obtain_vulkan_version() {
+ // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/VkApplicationInfo.html#_description
+ // for Vulkan 1.0 vkEnumerateInstanceVersion is not available, including not in the loader we compile against on Android.
+ _vkEnumerateInstanceVersion func = (_vkEnumerateInstanceVersion)vkGetInstanceProcAddr(nullptr, "vkEnumerateInstanceVersion");
+ if (func != nullptr) {
+ uint32_t api_version;
+ VkResult res = func(&api_version);
+ if (res == VK_SUCCESS) {
+ vulkan_major = VK_VERSION_MAJOR(api_version);
+ vulkan_minor = VK_VERSION_MINOR(api_version);
+ uint32_t vulkan_patch = VK_VERSION_PATCH(api_version);
+
+ print_line("Vulkan API " + itos(vulkan_major) + "." + itos(vulkan_minor) + "." + itos(vulkan_patch));
+ } else {
+ // according to the documentation this shouldn't fail with anything except a memory allocation error
+ // in which case we're in deep trouble anyway
+ ERR_FAIL_V(ERR_CANT_CREATE);
+ }
+ } else {
+ print_line("vkEnumerateInstanceVersion not available, assuming Vulkan 1.0");
+ }
+
+ // we don't go above 1.2
+ if ((vulkan_major > 1) || (vulkan_major == 1 && vulkan_minor > 2)) {
+ vulkan_major = 1;
+ vulkan_minor = 2;
+ }
+
+ return OK;
+}
+
Error VulkanContext::_initialize_extensions() {
uint32_t instance_extension_count = 0;
enabled_extension_count = 0;
enabled_layer_count = 0;
enabled_debug_utils = false;
+ enabled_debug_report = false;
/* Look for instance extensions */
VkBool32 surfaceExtFound = 0;
VkBool32 platformSurfaceExtFound = 0;
@@ -268,6 +332,7 @@ Error VulkanContext::_initialize_extensions() {
if (!strcmp(VK_EXT_DEBUG_REPORT_EXTENSION_NAME, instance_extensions[i].extensionName)) {
if (use_validation_layers) {
extension_names[enabled_extension_count++] = VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
+ enabled_debug_report = true;
}
}
if (!strcmp(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, instance_extensions[i].extensionName)) {
@@ -289,12 +354,200 @@ Error VulkanContext::_initialize_extensions() {
return OK;
}
+typedef void(VKAPI_PTR *_vkGetPhysicalDeviceProperties2)(VkPhysicalDevice, VkPhysicalDeviceProperties2 *);
+
+uint32_t VulkanContext::SubgroupCapabilities::supported_stages_flags_rd() const {
+ uint32_t flags = 0;
+
+ if (supportedStages & VK_SHADER_STAGE_VERTEX_BIT) {
+ flags += RenderingDevice::ShaderStage::SHADER_STAGE_VERTEX_BIT;
+ }
+ if (supportedStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
+ flags += RenderingDevice::ShaderStage::SHADER_STAGE_TESSELATION_CONTROL_BIT;
+ }
+ if (supportedStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
+ flags += RenderingDevice::ShaderStage::SHADER_STAGE_TESSELATION_EVALUATION_BIT;
+ }
+ // if (supportedStages & VK_SHADER_STAGE_GEOMETRY_BIT) {
+ // flags += RenderingDevice::ShaderStage::SHADER_STAGE_GEOMETRY_BIT;
+ // }
+ if (supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) {
+ flags += RenderingDevice::ShaderStage::SHADER_STAGE_FRAGMENT_BIT;
+ }
+ if (supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) {
+ flags += RenderingDevice::ShaderStage::SHADER_STAGE_COMPUTE_BIT;
+ }
+
+ return flags;
+}
+
+String VulkanContext::SubgroupCapabilities::supported_stages_desc() const {
+ String res;
+
+ if (supportedStages & VK_SHADER_STAGE_VERTEX_BIT) {
+ res += ", STAGE_VERTEX";
+ }
+ if (supportedStages & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) {
+ res += ", STAGE_TESSELLATION_CONTROL";
+ }
+ if (supportedStages & VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) {
+ res += ", STAGE_TESSELLATION_EVALUATION";
+ }
+ if (supportedStages & VK_SHADER_STAGE_GEOMETRY_BIT) {
+ res += ", STAGE_GEOMETRY";
+ }
+ if (supportedStages & VK_SHADER_STAGE_FRAGMENT_BIT) {
+ res += ", STAGE_FRAGMENT";
+ }
+ if (supportedStages & VK_SHADER_STAGE_COMPUTE_BIT) {
+ res += ", STAGE_COMPUTE";
+ }
+
+ /* these are not defined on Android GRMBL */
+ if (supportedStages & 0x00000100 /* VK_SHADER_STAGE_RAYGEN_BIT_KHR */) {
+ res += ", STAGE_RAYGEN_KHR";
+ }
+ if (supportedStages & 0x00000200 /* VK_SHADER_STAGE_ANY_HIT_BIT_KHR */) {
+ res += ", STAGE_ANY_HIT_KHR";
+ }
+ if (supportedStages & 0x00000400 /* VK_SHADER_STAGE_CLOSEST_HIT_BIT_KHR */) {
+ res += ", STAGE_CLOSEST_HIT_KHR";
+ }
+ if (supportedStages & 0x00000800 /* VK_SHADER_STAGE_MISS_BIT_KHR */) {
+ res += ", STAGE_MISS_KHR";
+ }
+ if (supportedStages & 0x00001000 /* VK_SHADER_STAGE_INTERSECTION_BIT_KHR */) {
+ res += ", STAGE_INTERSECTION_KHR";
+ }
+ if (supportedStages & 0x00002000 /* VK_SHADER_STAGE_CALLABLE_BIT_KHR */) {
+ res += ", STAGE_CALLABLE_KHR";
+ }
+ if (supportedStages & 0x00000040 /* VK_SHADER_STAGE_TASK_BIT_NV */) {
+ res += ", STAGE_TASK_NV";
+ }
+ if (supportedStages & 0x00000080 /* VK_SHADER_STAGE_MESH_BIT_NV */) {
+ res += ", STAGE_MESH_NV";
+ }
+
+ return res.substr(2); // remove first ", "
+}
+
+uint32_t VulkanContext::SubgroupCapabilities::supported_operations_flags_rd() const {
+ uint32_t flags = 0;
+
+ if (supportedOperations & VK_SUBGROUP_FEATURE_BASIC_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_BASIC_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_VOTE_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_VOTE_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_ARITHMETIC_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_BALLOT_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_SHUFFLE_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_SHUFFLE_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_SHUFFLE_RELATIVE_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_CLUSTERED_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_CLUSTERED_BIT;
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_QUAD_BIT) {
+ flags += RenderingDevice::SubgroupOperations::SUBGROUP_QUAD_BIT;
+ }
+
+ return flags;
+}
+
+String VulkanContext::SubgroupCapabilities::supported_operations_desc() const {
+ String res;
+
+ if (supportedOperations & VK_SUBGROUP_FEATURE_BASIC_BIT) {
+ res += ", FEATURE_BASIC";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_VOTE_BIT) {
+ res += ", FEATURE_VOTE";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_ARITHMETIC_BIT) {
+ res += ", FEATURE_ARITHMETIC";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_BALLOT_BIT) {
+ res += ", FEATURE_BALLOT";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_SHUFFLE_BIT) {
+ res += ", FEATURE_SHUFFLE";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_SHUFFLE_RELATIVE_BIT) {
+ res += ", FEATURE_SHUFFLE_RELATIVE";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_CLUSTERED_BIT) {
+ res += ", FEATURE_CLUSTERED";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_QUAD_BIT) {
+ res += ", FEATURE_QUAD";
+ }
+ if (supportedOperations & VK_SUBGROUP_FEATURE_PARTITIONED_BIT_NV) {
+ res += ", FEATURE_PARTITIONED_NV";
+ }
+
+ return res.substr(2); // remove first ", "
+}
+
+Error VulkanContext::_check_capabilities() {
+ // check subgroups
+ // https://www.khronos.org/blog/vulkan-subgroup-tutorial
+ // for Vulkan 1.0 vkGetPhysicalDeviceProperties2 is not available, including not in the loader we compile against on Android.
+ _vkGetPhysicalDeviceProperties2 func = (_vkGetPhysicalDeviceProperties2)vkGetInstanceProcAddr(inst, "vkGetPhysicalDeviceProperties2");
+ if (func != nullptr) {
+ VkPhysicalDeviceSubgroupProperties subgroupProperties;
+ subgroupProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES;
+ subgroupProperties.pNext = nullptr;
+
+ VkPhysicalDeviceProperties2 physicalDeviceProperties;
+ physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
+ physicalDeviceProperties.pNext = &subgroupProperties;
+
+ func(gpu, &physicalDeviceProperties);
+
+ subgroup_capabilities.size = subgroupProperties.subgroupSize;
+ subgroup_capabilities.supportedStages = subgroupProperties.supportedStages;
+ subgroup_capabilities.supportedOperations = subgroupProperties.supportedOperations;
+ // Note: quadOperationsInAllStages will be true if:
+ // - supportedStages has VK_SHADER_STAGE_ALL_GRAPHICS + VK_SHADER_STAGE_COMPUTE_BIT
+ // - supportedOperations has VK_SUBGROUP_FEATURE_QUAD_BIT
+ subgroup_capabilities.quadOperationsInAllStages = subgroupProperties.quadOperationsInAllStages;
+
+ // only output this when debugging?
+ print_line("- Vulkan subgroup size " + itos(subgroup_capabilities.size));
+ print_line("- Vulkan subgroup stages " + subgroup_capabilities.supported_stages_desc());
+ print_line("- Vulkan subgroup supported ops " + subgroup_capabilities.supported_operations_desc());
+ if (subgroup_capabilities.quadOperationsInAllStages) {
+ print_line("- Vulkan subgroup quad operations in all stages");
+ }
+ } else {
+ subgroup_capabilities.size = 0;
+ subgroup_capabilities.supportedStages = 0;
+ subgroup_capabilities.supportedOperations = 0;
+ subgroup_capabilities.quadOperationsInAllStages = false;
+ }
+
+ return OK;
+}
+
Error VulkanContext::_create_physical_device() {
+ /* obtain version */
+ _obtain_vulkan_version();
+
/* Look for validation layers */
if (use_validation_layers) {
_create_validation_layers();
}
+ /* initialise extensions */
{
Error err = _initialize_extensions();
if (err != OK) {
@@ -312,7 +565,7 @@ Error VulkanContext::_create_physical_device() {
/*applicationVersion*/ 0,
/*pEngineName*/ namecs.get_data(),
/*engineVersion*/ 0,
- /*apiVersion*/ VK_API_VERSION_1_0,
+ /*apiVersion*/ VK_MAKE_VERSION(vulkan_major, vulkan_minor, 0)
};
VkInstanceCreateInfo inst_info = {
/*sType*/ VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
@@ -331,6 +584,7 @@ Error VulkanContext::_create_physical_device() {
* function to register the final callback.
*/
VkDebugUtilsMessengerCreateInfoEXT dbg_messenger_create_info;
+ VkDebugReportCallbackCreateInfoEXT dbg_report_callback_create_info{};
if (enabled_debug_utils) {
// VK_EXT_debug_utils style
dbg_messenger_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT;
@@ -344,6 +598,16 @@ Error VulkanContext::_create_physical_device() {
dbg_messenger_create_info.pfnUserCallback = _debug_messenger_callback;
dbg_messenger_create_info.pUserData = this;
inst_info.pNext = &dbg_messenger_create_info;
+ } else if (enabled_debug_report) {
+ dbg_report_callback_create_info.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT;
+ dbg_report_callback_create_info.flags = VK_DEBUG_REPORT_INFORMATION_BIT_EXT |
+ VK_DEBUG_REPORT_WARNING_BIT_EXT |
+ VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT |
+ VK_DEBUG_REPORT_ERROR_BIT_EXT |
+ VK_DEBUG_REPORT_DEBUG_BIT_EXT;
+ dbg_report_callback_create_info.pfnCallback = _debug_report_callback;
+ dbg_report_callback_create_info.pUserData = this;
+ inst_info.pNext = &dbg_report_callback_create_info;
}
uint32_t gpu_count;
@@ -532,6 +796,33 @@ Error VulkanContext::_create_physical_device() {
ERR_FAIL_V(ERR_CANT_CREATE);
break;
}
+ } else if (enabled_debug_report) {
+ CreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(inst, "vkCreateDebugReportCallbackEXT");
+ DebugReportMessageEXT = (PFN_vkDebugReportMessageEXT)vkGetInstanceProcAddr(inst, "vkDebugReportMessageEXT");
+ DestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(inst, "vkDestroyDebugReportCallbackEXT");
+
+ if (nullptr == CreateDebugReportCallbackEXT || nullptr == DebugReportMessageEXT || nullptr == DestroyDebugReportCallbackEXT) {
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE,
+ "GetProcAddr: Failed to init VK_EXT_debug_report\n"
+ "GetProcAddr: Failure");
+ }
+
+ err = CreateDebugReportCallbackEXT(inst, &dbg_report_callback_create_info, nullptr, &dbg_debug_report);
+ switch (err) {
+ case VK_SUCCESS:
+ break;
+ case VK_ERROR_OUT_OF_HOST_MEMORY:
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE,
+ "CreateDebugReportCallbackEXT: out of host memory\n"
+ "CreateDebugReportCallbackEXT Failure");
+ break;
+ default:
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE,
+ "CreateDebugReportCallbackEXT: unknown failure\n"
+ "CreateDebugReportCallbackEXT Failure");
+ ERR_FAIL_V(ERR_CANT_CREATE);
+ break;
+ }
}
/* Call with NULL data to get count */
@@ -561,6 +852,14 @@ Error VulkanContext::_create_physical_device() {
GET_INSTANCE_PROC_ADDR(inst, GetPhysicalDeviceSurfacePresentModesKHR);
GET_INSTANCE_PROC_ADDR(inst, GetSwapchainImagesKHR);
+ // get info about what our vulkan driver is capable off
+ {
+ Error res = _check_capabilities();
+ if (res != OK) {
+ return res;
+ }
+ }
+
return OK;
}
@@ -692,16 +991,39 @@ Error VulkanContext::_initialize_queues(VkSurfaceKHR surface) {
// If the format list includes just one entry of VK_FORMAT_UNDEFINED,
// the surface has no preferred format. Otherwise, at least one
// supported format will be returned.
- if (true || (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED)) {
+ if (formatCount == 1 && surfFormats[0].format == VK_FORMAT_UNDEFINED) {
format = VK_FORMAT_B8G8R8A8_UNORM;
+ color_space = surfFormats[0].colorSpace;
} else {
+ // These should be ordered with the ones we want to use on top and fallback modes further down
+ // we want an 32bit RGBA unsigned normalised buffer or similar
+ const VkFormat allowed_formats[] = {
+ VK_FORMAT_B8G8R8A8_UNORM,
+ VK_FORMAT_R8G8B8A8_UNORM
+ };
+ uint32_t allowed_formats_count = sizeof(allowed_formats) / sizeof(VkFormat);
+
if (formatCount < 1) {
free(surfFormats);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "formatCount less than 1");
}
- format = surfFormats[0].format;
+
+ // Find the first format that we support
+ format = VK_FORMAT_UNDEFINED;
+ for (uint32_t af = 0; af < allowed_formats_count && format == VK_FORMAT_UNDEFINED; af++) {
+ for (uint32_t sf = 0; sf < formatCount && format == VK_FORMAT_UNDEFINED; sf++) {
+ if (surfFormats[sf].format == allowed_formats[af]) {
+ format = surfFormats[sf].format;
+ color_space = surfFormats[sf].colorSpace;
+ }
+ }
+ }
+
+ if (format == VK_FORMAT_UNDEFINED) {
+ free(surfFormats);
+ ERR_FAIL_V_MSG(ERR_CANT_CREATE, "No usable surface format found.");
+ }
}
- color_space = surfFormats[0].colorSpace;
free(surfFormats);
@@ -1708,6 +2030,9 @@ VulkanContext::~VulkanContext() {
if (inst_initialized && enabled_debug_utils) {
DestroyDebugUtilsMessengerEXT(inst, dbg_messenger, nullptr);
}
+ if (inst_initialized && dbg_debug_report != VK_NULL_HANDLE) {
+ DestroyDebugReportCallbackEXT(inst, dbg_debug_report, nullptr);
+ }
vkDestroyDevice(device, nullptr);
}
if (inst_initialized) {
diff --git a/drivers/vulkan/vulkan_context.h b/drivers/vulkan/vulkan_context.h
index dc6b0410bc..b788181ab9 100644
--- a/drivers/vulkan/vulkan_context.h
+++ b/drivers/vulkan/vulkan_context.h
@@ -41,6 +41,20 @@
#include <vulkan/vulkan.h>
class VulkanContext {
+public:
+ struct SubgroupCapabilities {
+ uint32_t size;
+ VkShaderStageFlags supportedStages;
+ VkSubgroupFeatureFlags supportedOperations;
+ VkBool32 quadOperationsInAllStages;
+
+ uint32_t supported_stages_flags_rd() const;
+ String supported_stages_desc() const;
+ uint32_t supported_operations_flags_rd() const;
+ String supported_operations_desc() const;
+ };
+
+private:
enum {
MAX_EXTENSIONS = 128,
MAX_LAYERS = 64,
@@ -57,6 +71,11 @@ class VulkanContext {
bool device_initialized = false;
bool inst_initialized = false;
+ // Vulkan 1.0 doesn't return version info so we assume this by default until we know otherwise
+ uint32_t vulkan_major = 1;
+ uint32_t vulkan_minor = 0;
+ SubgroupCapabilities subgroup_capabilities;
+
String device_vendor;
String device_name;
String pipeline_cache_id;
@@ -126,6 +145,12 @@ class VulkanContext {
const char *extension_names[MAX_EXTENSIONS];
bool enabled_debug_utils = false;
+ /**
+ * True if VK_EXT_debug_report extension is used. VK_EXT_debug_report is deprecated but it is
+ * still used if VK_EXT_debug_utils is not available.
+ */
+ bool enabled_debug_report = false;
+
uint32_t enabled_layer_count = 0;
const char *enabled_layers[MAX_LAYERS];
@@ -136,6 +161,9 @@ class VulkanContext {
PFN_vkCmdEndDebugUtilsLabelEXT CmdEndDebugUtilsLabelEXT;
PFN_vkCmdInsertDebugUtilsLabelEXT CmdInsertDebugUtilsLabelEXT;
PFN_vkSetDebugUtilsObjectNameEXT SetDebugUtilsObjectNameEXT;
+ PFN_vkCreateDebugReportCallbackEXT CreateDebugReportCallbackEXT;
+ PFN_vkDebugReportMessageEXT DebugReportMessageEXT;
+ PFN_vkDestroyDebugReportCallbackEXT DestroyDebugReportCallbackEXT;
PFN_vkGetPhysicalDeviceSurfaceSupportKHR fpGetPhysicalDeviceSurfaceSupportKHR;
PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fpGetPhysicalDeviceSurfaceCapabilitiesKHR;
PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fpGetPhysicalDeviceSurfaceFormatsKHR;
@@ -149,9 +177,12 @@ class VulkanContext {
PFN_vkGetPastPresentationTimingGOOGLE fpGetPastPresentationTimingGOOGLE;
VkDebugUtilsMessengerEXT dbg_messenger = VK_NULL_HANDLE;
+ VkDebugReportCallbackEXT dbg_debug_report = VK_NULL_HANDLE;
+ Error _obtain_vulkan_version();
Error _create_validation_layers();
Error _initialize_extensions();
+ Error _check_capabilities();
VkBool32 _check_layers(uint32_t check_count, const char **check_names, uint32_t layer_count, VkLayerProperties *layers);
static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_messenger_callback(
@@ -160,6 +191,16 @@ class VulkanContext {
const VkDebugUtilsMessengerCallbackDataEXT *pCallbackData,
void *pUserData);
+ static VKAPI_ATTR VkBool32 VKAPI_CALL _debug_report_callback(
+ VkDebugReportFlagsEXT flags,
+ VkDebugReportObjectTypeEXT objectType,
+ uint64_t object,
+ size_t location,
+ int32_t messageCode,
+ const char *pLayerPrefix,
+ const char *pMessage,
+ void *pUserData);
+
Error _create_physical_device();
Error _initialize_queues(VkSurfaceKHR surface);
@@ -186,6 +227,10 @@ protected:
}
public:
+ uint32_t get_vulkan_major() const { return vulkan_major; };
+ uint32_t get_vulkan_minor() const { return vulkan_minor; };
+ SubgroupCapabilities get_subgroup_capabilities() const { return subgroup_capabilities; };
+
VkDevice get_device();
VkPhysicalDevice get_physical_device();
int get_swapchain_image_count() const;
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index 92b4683018..ab8ae71904 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -602,6 +602,8 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
}
void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (p_event->is_pressed()) {
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->is_shortcut(p_event)) {
duplicate_selection();
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index 4274fb993f..4fe2d2bb2a 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1641,6 +1641,8 @@ void AnimationTimelineEdit::_play_position_draw() {
}
void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT && hsize_rect.has_point(mb->get_position())) {
@@ -2522,6 +2524,8 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
}
void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (p_event->is_pressed()) {
if (ED_GET_SHORTCUT("animation_editor/duplicate_selection")->is_shortcut(p_event)) {
emit_signal("duplicate_request");
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index fa27dfb3e5..506a327ffc 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -101,47 +101,67 @@ void AnimationTrackEditColor::draw_key_link(int p_index, float p_pixels_sec, int
int font_size = get_theme_font_size("font_size", "Label");
int fh = (font->get_height(font_size) * 0.8);
+ fh /= 3;
+
int x_from = p_x + fh / 2 - 1;
int x_to = p_next_x - fh / 2 + 1;
- fh /= 3;
+ x_from = MAX(x_from, p_clip_left);
+ x_to = MIN(x_to, p_clip_right);
+
+ int y_from = (get_size().height - fh) / 2;
if (x_from > p_clip_right || x_to < p_clip_left) {
return;
}
- Color color = get_animation()->track_get_key_value(get_track(), p_index);
- Color color_next = get_animation()->track_get_key_value(get_track(), p_index + 1);
+ Vector<Color> color_samples;
+ color_samples.append(get_animation()->track_get_key_value(get_track(), p_index));
- if (x_from < p_clip_left) {
- float c = float(p_clip_left - x_from) / (x_to - x_from);
- color = color.lerp(color_next, c);
- x_from = p_clip_left;
- }
+ if (get_animation()->track_get_type(get_track()) == Animation::TYPE_VALUE) {
+ if (get_animation()->track_get_interpolation_type(get_track()) != Animation::INTERPOLATION_NEAREST &&
+ (get_animation()->value_track_get_update_mode(get_track()) == Animation::UPDATE_CONTINUOUS ||
+ get_animation()->value_track_get_update_mode(get_track()) == Animation::UPDATE_CAPTURE) &&
+ !Math::is_zero_approx(get_animation()->track_get_key_transition(get_track(), p_index))) {
+ float start_time = get_animation()->track_get_key_time(get_track(), p_index);
+ float end_time = get_animation()->track_get_key_time(get_track(), p_index + 1);
- if (x_to > p_clip_right) {
- float c = float(p_clip_right - x_from) / (x_to - x_from);
- color_next = color.lerp(color_next, c);
- x_to = p_clip_right;
- }
+ Color color_next = get_animation()->value_track_interpolate(get_track(), end_time);
- int y_from = (get_size().height - fh) / 2;
+ if (!color_samples[0].is_equal_approx(color_next)) {
+ color_samples.resize(1 + (x_to - x_from) / 64); // Make a color sample every 64 px.
+ for (int i = 1; i < color_samples.size(); i++) {
+ float j = i;
+ color_samples.write[i] = get_animation()->value_track_interpolate(
+ get_track(),
+ Math::lerp(start_time, end_time, j / color_samples.size()));
+ }
+ }
+ color_samples.append(color_next);
+ } else {
+ color_samples.append(color_samples[0]);
+ }
+ } else {
+ color_samples.append(get_animation()->track_get_key_value(get_track(), p_index + 1));
+ }
- Vector<Vector2> points;
- Vector<Color> colors;
+ for (int i = 0; i < color_samples.size() - 1; i++) {
+ Vector<Vector2> points;
+ Vector<Color> colors;
- points.push_back(Vector2(x_from, y_from));
- colors.push_back(color);
+ points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from));
+ colors.push_back(color_samples[i]);
- points.push_back(Vector2(x_to, y_from));
- colors.push_back(color_next);
+ points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from));
+ colors.push_back(color_samples[i + 1]);
- points.push_back(Vector2(x_to, y_from + fh));
- colors.push_back(color_next);
+ points.push_back(Vector2(Math::lerp(x_from, x_to, float(i + 1) / (color_samples.size() - 1)), y_from + fh));
+ colors.push_back(color_samples[i + 1]);
- points.push_back(Vector2(x_from, y_from + fh));
- colors.push_back(color);
+ points.push_back(Vector2(Math::lerp(x_from, x_to, float(i) / (color_samples.size() - 1)), y_from + fh));
+ colors.push_back(color_samples[i]);
- draw_primitive(points, colors, Vector<Vector2>());
+ draw_primitive(points, colors, Vector<Vector2>());
+ }
}
void AnimationTrackEditColor::draw_key(int p_index, float p_pixels_sec, int p_x, bool p_selected, int p_clip_left, int p_clip_right) {
@@ -1016,6 +1036,8 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
}
void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseMotion> mm = p_event;
if (!len_resizing && mm.is_valid()) {
bool use_hsize_cursor = false;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 11be365f0a..ac8bef817b 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -109,6 +109,8 @@ void FindReplaceBar::_notification(int p_what) {
}
void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (!k.is_valid() || !k->is_pressed()) {
return;
@@ -691,6 +693,8 @@ FindReplaceBar::FindReplaceBar() {
// This function should be used to handle shortcuts that could otherwise
// be handled too late if they weren't handled here.
void CodeTextEditor::_input(const Ref<InputEvent> &event) {
+ ERR_FAIL_COND(event.is_null());
+
const Ref<InputEventKey> key_event = event;
if (!key_event.is_valid() || !key_event->is_pressed() || !text_editor->has_focus()) {
return;
diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp
index c4290b7cca..6befee090b 100644
--- a/editor/debugger/editor_profiler.cpp
+++ b/editor/debugger/editor_profiler.cpp
@@ -43,28 +43,34 @@ void EditorProfiler::_make_metric_ptrs(Metric &m) {
}
}
+EditorProfiler::Metric EditorProfiler::_get_frame_metric(int index) {
+ return frame_metrics[(frame_metrics.size() + last_metric - (total_metrics - 1) + index) % frame_metrics.size()];
+}
+
void EditorProfiler::add_frame_metric(const Metric &p_metric, bool p_final) {
++last_metric;
if (last_metric >= frame_metrics.size()) {
last_metric = 0;
}
+ total_metrics++;
+ if (total_metrics > frame_metrics.size()) {
+ total_metrics = frame_metrics.size();
+ }
+
frame_metrics.write[last_metric] = p_metric;
_make_metric_ptrs(frame_metrics.write[last_metric]);
updating_frame = true;
- cursor_metric_edit->set_max(frame_metrics[last_metric].frame_number);
- cursor_metric_edit->set_min(MAX(frame_metrics[last_metric].frame_number - frame_metrics.size(), 0));
+ clear_button->set_disabled(false);
+ cursor_metric_edit->set_editable(true);
+ cursor_metric_edit->set_max(p_metric.frame_number);
+ cursor_metric_edit->set_min(_get_frame_metric(0).frame_number);
if (!seeking) {
- cursor_metric_edit->set_value(frame_metrics[last_metric].frame_number);
- if (hover_metric != -1) {
- hover_metric++;
- if (hover_metric >= frame_metrics.size()) {
- hover_metric = 0;
- }
- }
+ cursor_metric_edit->set_value(p_metric.frame_number);
}
+
updating_frame = false;
if (frame_delay->is_stopped()) {
@@ -83,6 +89,7 @@ void EditorProfiler::clear() {
metric_size = CLAMP(metric_size, 60, 1024);
frame_metrics.clear();
frame_metrics.resize(metric_size);
+ total_metrics = 0;
last_metric = -1;
variables->clear();
plot_sigs.clear();
@@ -93,6 +100,7 @@ void EditorProfiler::clear() {
cursor_metric_edit->set_min(0);
cursor_metric_edit->set_max(100); // Doesn't make much sense, but we can't have min == max. Doesn't hurt.
cursor_metric_edit->set_value(0);
+ cursor_metric_edit->set_editable(false);
updating_frame = false;
hover_metric = -1;
seeking = false;
@@ -187,11 +195,8 @@ void EditorProfiler::_update_plot() {
const bool use_self = display_time->get_selected() == DISPLAY_SELF_TIME;
float highest = 0;
- for (int i = 0; i < frame_metrics.size(); i++) {
- const Metric &m = frame_metrics[i];
- if (!m.valid) {
- continue;
- }
+ for (int i = 0; i < total_metrics; i++) {
+ const Metric &m = _get_frame_metric(i);
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
@@ -220,78 +225,43 @@ void EditorProfiler::_update_plot() {
int *column = columnv.ptrw();
- Map<StringName, int> plot_prev;
- //Map<StringName,int> plot_max;
+ Map<StringName, int> prev_plots;
- for (int i = 0; i < w; i++) {
+ for (int i = 0; i < total_metrics * w / frame_metrics.size() - 1; i++) {
for (int j = 0; j < h * 4; j++) {
column[j] = 0;
}
int current = i * frame_metrics.size() / w;
- int next = (i + 1) * frame_metrics.size() / w;
- if (next > frame_metrics.size()) {
- next = frame_metrics.size();
- }
- if (next == current) {
- next = current + 1; //just because for loop must work
- }
for (Set<StringName>::Element *E = plot_sigs.front(); E; E = E->next()) {
- int plot_pos = -1;
+ const Metric &m = _get_frame_metric(current);
- for (int j = current; j < next; j++) {
- //wrap
- int idx = last_metric + 1 + j;
- while (idx >= frame_metrics.size()) {
- idx -= frame_metrics.size();
- }
-
- //get
- const Metric &m = frame_metrics[idx];
- if (!m.valid) {
- continue; //skip because invalid
- }
+ float value = 0;
- float value = 0;
-
- const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
- if (F) {
- value = F->get()->total_time;
- }
+ const Map<StringName, Metric::Category *>::Element *F = m.category_ptrs.find(E->get());
+ if (F) {
+ value = F->get()->total_time;
+ }
- const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
- if (G) {
- if (use_self) {
- value = G->get()->self;
- } else {
- value = G->get()->total;
- }
+ const Map<StringName, Metric::Category::Item *>::Element *G = m.item_ptrs.find(E->get());
+ if (G) {
+ if (use_self) {
+ value = G->get()->self;
+ } else {
+ value = G->get()->total;
}
-
- plot_pos = MAX(CLAMP(int(value * h / highest), 0, h - 1), plot_pos);
}
+ int plot_pos = CLAMP(int(value * h / highest), 0, h - 1);
+
int prev_plot = plot_pos;
- Map<StringName, int>::Element *H = plot_prev.find(E->get());
+ Map<StringName, int>::Element *H = prev_plots.find(E->get());
if (H) {
prev_plot = H->get();
H->get() = plot_pos;
} else {
- plot_prev[E->get()] = plot_pos;
- }
-
- if (plot_pos == -1 && prev_plot == -1) {
- //don't bother drawing
- continue;
- }
-
- if (prev_plot != -1 && plot_pos == -1) {
- plot_pos = prev_plot;
- }
-
- if (prev_plot == -1 && plot_pos != -1) {
- prev_plot = plot_pos;
+ prev_plots[E->get()] = plot_pos;
}
plot_pos = h - plot_pos - 1;
@@ -352,15 +322,13 @@ void EditorProfiler::_update_plot() {
}
void EditorProfiler::_update_frame() {
- int cursor_metric = _get_cursor_index();
-
- ERR_FAIL_INDEX(cursor_metric, frame_metrics.size());
+ int cursor_metric = cursor_metric_edit->get_value() - _get_frame_metric(0).frame_number;
updating_frame = true;
variables->clear();
TreeItem *root = variables->create_item();
- const Metric &m = frame_metrics[cursor_metric];
+ const Metric &m = _get_frame_metric(cursor_metric);
int dtime = display_time->get_selected();
@@ -410,6 +378,7 @@ void EditorProfiler::_activate_pressed() {
if (activate->is_pressed()) {
activate->set_icon(get_theme_icon("Stop", "EditorIcons"));
activate->set_text(TTR("Stop"));
+ _clear_pressed();
} else {
activate->set_icon(get_theme_icon("Play", "EditorIcons"));
activate->set_text(TTR("Start"));
@@ -418,6 +387,7 @@ void EditorProfiler::_activate_pressed() {
}
void EditorProfiler::_clear_pressed() {
+ clear_button->set_disabled(true);
clear();
_update_plot();
}
@@ -430,30 +400,16 @@ void EditorProfiler::_notification(int p_what) {
}
void EditorProfiler::_graph_tex_draw() {
- if (last_metric < 0) {
+ if (total_metrics == 0) {
return;
}
if (seeking) {
- int max_frames = frame_metrics.size();
- int frame = cursor_metric_edit->get_value() - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0) {
- frame = 0;
- }
-
- int cur_x = frame * graph->get_size().x / max_frames;
-
+ int frame = cursor_metric_edit->get_value() - _get_frame_metric(0).frame_number;
+ int cur_x = (2 * frame + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1;
graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.8));
}
-
- if (hover_metric != -1 && frame_metrics[hover_metric].valid) {
- int max_frames = frame_metrics.size();
- int frame = frame_metrics[hover_metric].frame_number - (frame_metrics[last_metric].frame_number - max_frames + 1);
- if (frame < 0) {
- frame = 0;
- }
-
- int cur_x = frame * graph->get_size().x / max_frames;
-
+ if (hover_metric > -1 && hover_metric < total_metrics) {
+ int cur_x = (2 * hover_metric + 1) * graph->get_size().x / (2 * frame_metrics.size()) + 1;
graph->draw_line(Vector2(cur_x, 0), Vector2(cur_x, graph->get_size().y), Color(1, 1, 1, 0.4));
}
}
@@ -484,10 +440,10 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (
(mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT && mb->is_pressed()) ||
(mm.is_valid())) {
- int x = me->get_position().x;
+ int x = me->get_position().x - 1;
x = x * frame_metrics.size() / graph->get_size().width;
- bool show_hover = x >= 0 && x < frame_metrics.size();
+ hover_metric = x;
if (x < 0) {
x = 0;
@@ -497,41 +453,11 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
x = frame_metrics.size() - 1;
}
- int metric = frame_metrics.size() - x - 1;
- metric = last_metric - metric;
- while (metric < 0) {
- metric += frame_metrics.size();
- }
-
- if (show_hover) {
- hover_metric = metric;
-
- } else {
- hover_metric = -1;
- }
-
if (mb.is_valid() || mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
- //cursor_metric=x;
updating_frame = true;
- //metric may be invalid, so look for closest metric that is valid, this makes snap feel better
- bool valid = false;
- for (int i = 0; i < frame_metrics.size(); i++) {
- if (frame_metrics[metric].valid) {
- valid = true;
- break;
- }
-
- metric++;
- if (metric >= frame_metrics.size()) {
- metric = 0;
- }
- }
-
- if (valid) {
- cursor_metric_edit->set_value(frame_metrics[metric].frame_number);
- }
-
+ if (x < total_metrics)
+ cursor_metric_edit->set_value(_get_frame_metric(x).frame_number);
updating_frame = false;
if (activate->is_pressed()) {
@@ -552,24 +478,6 @@ void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
}
}
-int EditorProfiler::_get_cursor_index() const {
- if (last_metric < 0) {
- return 0;
- }
- if (!frame_metrics[last_metric].valid) {
- return 0;
- }
-
- int diff = (frame_metrics[last_metric].frame_number - cursor_metric_edit->get_value());
-
- int idx = last_metric - diff;
- while (idx < 0) {
- idx += frame_metrics.size();
- }
-
- return idx;
-}
-
void EditorProfiler::disable_seeking() {
seeking = false;
graph->update();
@@ -659,6 +567,7 @@ EditorProfiler::EditorProfiler() {
clear_button = memnew(Button);
clear_button->set_text(TTR("Clear"));
clear_button->connect("pressed", callable_mp(this, &EditorProfiler::_clear_pressed));
+ clear_button->set_disabled(true);
hb->add_child(clear_button);
hb->add_child(memnew(Label(TTR("Measure:"))));
@@ -687,6 +596,8 @@ EditorProfiler::EditorProfiler() {
cursor_metric_edit = memnew(SpinBox);
cursor_metric_edit->set_h_size_flags(SIZE_FILL);
+ cursor_metric_edit->set_value(0);
+ cursor_metric_edit->set_editable(false);
hb->add_child(cursor_metric_edit);
cursor_metric_edit->connect("value_changed", callable_mp(this, &EditorProfiler::_cursor_metric_changed));
@@ -726,6 +637,7 @@ EditorProfiler::EditorProfiler() {
int metric_size = CLAMP(int(EDITOR_DEF("debugger/profiler_frame_history_size", 600)), 60, 1024);
frame_metrics.resize(metric_size);
+ total_metrics = 0;
last_metric = -1;
hover_metric = -1;
diff --git a/editor/debugger/editor_profiler.h b/editor/debugger/editor_profiler.h
index e16bde41f6..8880824b87 100644
--- a/editor/debugger/editor_profiler.h
+++ b/editor/debugger/editor_profiler.h
@@ -106,13 +106,13 @@ private:
SpinBox *cursor_metric_edit;
Vector<Metric> frame_metrics;
+ int total_metrics;
int last_metric;
int max_functions;
bool updating_frame;
- //int cursor_metric;
int hover_metric;
float graph_height;
@@ -139,14 +139,14 @@ private:
void _graph_tex_draw();
void _graph_tex_input(const Ref<InputEvent> &p_ev);
- int _get_cursor_index() const;
-
Color _get_color_from_signature(const StringName &p_signature) const;
void _cursor_metric_changed(double);
void _combo_changed(int);
+ Metric _get_frame_metric(int index);
+
protected:
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 25e155aafe..57d44ca56c 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -86,11 +86,11 @@ void DependencyEditor::_fix_and_find(EditorFileSystemDirectory *efsd, Map<String
String lost = E->key().replace_first("res://", "");
Vector<String> existingv = existing.split("/");
- existingv.invert();
+ existingv.reverse();
Vector<String> currentv = current.split("/");
- currentv.invert();
+ currentv.reverse();
Vector<String> lostv = lost.split("/");
- lostv.invert();
+ lostv.reverse();
int existing_score = 0;
int current_score = 0;
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 3a5ebe8e85..e7934bed0a 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -531,6 +531,8 @@ void EditorAudioBus::_effect_add(int p_which) {
}
void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_RIGHT && mb->is_pressed()) {
Vector2 pos = Vector2(mb->get_position().x, mb->get_position().y);
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 3c0fe1571c..a5ebfbfb8a 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -730,6 +730,12 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
if (p_preset->get_export_filter() == EditorExportPreset::EXPORT_ALL_RESOURCES) {
//find stuff
_export_find_resources(EditorFileSystem::get_singleton()->get_filesystem(), paths);
+ } else if (p_preset->get_export_filter() == EditorExportPreset::EXCLUDE_SELECTED_RESOURCES) {
+ _export_find_resources(EditorFileSystem::get_singleton()->get_filesystem(), paths);
+ Vector<String> files = p_preset->get_files_to_export();
+ for (int i = 0; i < files.size(); i++) {
+ paths.erase(files[i]);
+ }
} else {
bool scenes_only = p_preset->get_export_filter() == EditorExportPreset::EXPORT_SELECTED_SCENES;
@@ -1394,6 +1400,10 @@ void EditorExport::_save() {
config->set_value(section, "export_filter", "resources");
save_files = true;
} break;
+ case EditorExportPreset::EXCLUDE_SELECTED_RESOURCES: {
+ config->set_value(section, "export_filter", "exclude");
+ save_files = true;
+ } break;
}
if (save_files) {
@@ -1572,6 +1582,9 @@ void EditorExport::load_config() {
} else if (export_filter == "resources") {
preset->set_export_filter(EditorExportPreset::EXPORT_SELECTED_RESOURCES);
get_files = true;
+ } else if (export_filter == "exclude") {
+ preset->set_export_filter(EditorExportPreset::EXCLUDE_SELECTED_RESOURCES);
+ get_files = true;
}
if (get_files) {
diff --git a/editor/editor_export.h b/editor/editor_export.h
index e6026e7aae..c96c8fdbce 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -50,6 +50,7 @@ public:
EXPORT_ALL_RESOURCES,
EXPORT_SELECTED_SCENES,
EXPORT_SELECTED_RESOURCES,
+ EXCLUDE_SELECTED_RESOURCES,
};
enum ScriptExportMode {
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index f78da9569f..75815fa750 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -125,6 +125,8 @@ void EditorFileDialog::_notification(int p_what) {
}
void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 283713cd3c..a747652a2f 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -1908,6 +1908,8 @@ void FindBar::_hide_bar() {
}
void FindBar::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (k.is_valid()) {
if (k->is_pressed() && (rich_text_label->has_focus() || is_a_parent_of(get_focus_owner()))) {
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index 70d1a514b5..738b2f9f82 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -682,6 +682,8 @@ bool EditorProperty::is_selected() const {
}
void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (property == StringName()) {
return;
}
@@ -1354,6 +1356,8 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
}
void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!foldable) {
return;
}
@@ -2566,9 +2570,9 @@ void EditorInspector::_update_script_class_properties(const Object &p_object, Li
}
// Script Variables -> to insert: NodeC..B..A -> bottom (insert_here)
- List<PropertyInfo>::Element *script_variables = NULL;
- List<PropertyInfo>::Element *bottom = NULL;
- List<PropertyInfo>::Element *insert_here = NULL;
+ List<PropertyInfo>::Element *script_variables = nullptr;
+ List<PropertyInfo>::Element *bottom = nullptr;
+ List<PropertyInfo>::Element *insert_here = nullptr;
for (List<PropertyInfo>::Element *E = r_list.front(); E; E = E->next()) {
PropertyInfo &pi = E->get();
if (pi.name != "Script Variables") {
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 156cb6694a..055baeb81e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -390,6 +390,8 @@ void EditorNode::_update_title() {
}
void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && !k->is_echo()) {
EditorPlugin *old_editor = editor_plugin_screen;
@@ -792,17 +794,27 @@ void EditorNode::_fs_changed() {
}
preset.unref();
}
+
if (preset.is_null()) {
- export_error = vformat(
- "Invalid export preset name: %s. Make sure `export_presets.cfg` is present in the current directory.",
- preset_name);
+ DirAccessRef da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (da->file_exists("res://export_presets.cfg")) {
+ export_error = vformat(
+ "Invalid export preset name: %s.\nThe following presets were detected in this project's `export_presets.cfg`:\n\n",
+ preset_name);
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); ++i) {
+ // Write the preset name between double quotes since it needs to be written between quotes on the command line if it contains spaces.
+ export_error += vformat(" \"%s\"\n", EditorExport::get_singleton()->get_export_preset(i)->get_name());
+ }
+ } else {
+ export_error = "This project doesn't have an `export_presets.cfg` file at its root.\nCreate an export preset from the \"Project > Export\" dialog and try again.";
+ }
} else {
Ref<EditorExportPlatform> platform = preset->get_platform();
const String export_path = export_defer.path.is_empty() ? preset->get_export_path() : export_defer.path;
if (export_path.is_empty()) {
- export_error = vformat("Export preset '%s' doesn't have a default export path, and none was specified.", preset_name);
+ export_error = vformat("Export preset \"%s\" doesn't have a default export path, and none was specified.", preset_name);
} else if (platform.is_null()) {
- export_error = vformat("Export preset '%s' doesn't have a matching platform.", preset_name);
+ export_error = vformat("Export preset \"%s\" doesn't have a matching platform.", preset_name);
} else {
Error err = OK;
if (export_defer.pack_only) { // Only export .pck or .zip data pack.
@@ -815,7 +827,7 @@ void EditorNode::_fs_changed() {
String config_error;
bool missing_templates;
if (!platform->can_export(preset, config_error, missing_templates)) {
- ERR_PRINT(vformat("Cannot export project with preset '%s' due to configuration errors:\n%s", preset_name, config_error));
+ ERR_PRINT(vformat("Cannot export project with preset \"%s\" due to configuration errors:\n%s", preset_name, config_error));
err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED;
} else {
err = platform->export_project(preset, export_defer.debug, export_path);
@@ -825,13 +837,13 @@ void EditorNode::_fs_changed() {
case OK:
break;
case ERR_FILE_NOT_FOUND:
- export_error = vformat("Project export failed for preset '%s', the export template appears to be missing.", preset_name);
+ export_error = vformat("Project export failed for preset \"%s\". The export template appears to be missing.", preset_name);
break;
case ERR_FILE_BAD_PATH:
- export_error = vformat("Project export failed for preset '%s', the target path '%s' appears to be invalid.", preset_name, export_path);
+ export_error = vformat("Project export failed for preset \"%s\". The target path \"%s\" appears to be invalid.", preset_name, export_path);
break;
default:
- export_error = vformat("Project export failed with error code %d for preset '%s'.", (int)err, preset_name);
+ export_error = vformat("Project export failed with error code %d for preset \"%s\".", (int)err, preset_name);
break;
}
}
@@ -1377,18 +1389,18 @@ void EditorNode::_save_scene_with_preview(String p_file, int p_idx) {
// which would result in an invalid texture.
if (c3d == 0 && c2d == 0) {
img.instance();
- img->create(1, 1, 0, Image::FORMAT_RGB8);
+ img->create(1, 1, false, Image::FORMAT_RGB8);
} else if (c3d < c2d) {
Ref<ViewportTexture> viewport_texture = scene_root->get_texture();
if (viewport_texture->get_width() > 0 && viewport_texture->get_height() > 0) {
- img = viewport_texture->get_data();
+ img = viewport_texture->get_image();
}
} else {
// The 3D editor may be disabled as a feature, but scenes can still be opened.
// This check prevents the preview from regenerating in case those scenes are then saved.
Ref<EditorFeatureProfile> profile = feature_profile_manager->get_current_profile();
if (profile.is_valid() && !profile->is_feature_disabled(EditorFeatureProfile::FEATURE_3D)) {
- img = Node3DEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_data();
+ img = Node3DEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_image();
}
}
@@ -2835,7 +2847,7 @@ void EditorNode::_save_screenshot(NodePath p_path) {
ERR_FAIL_COND_MSG(!viewport, "Cannot get editor main control viewport.");
Ref<ViewportTexture> texture = viewport->get_texture();
ERR_FAIL_COND_MSG(texture.is_null(), "Cannot get editor main control viewport texture.");
- Ref<Image> img = texture->get_data();
+ Ref<Image> img = texture->get_image();
ERR_FAIL_COND_MSG(img.is_null(), "Cannot get editor main control viewport texture image.");
Error error = img->save_png(p_path);
ERR_FAIL_COND_MSG(error != OK, "Cannot save screenshot to file '" + p_path + "'.");
@@ -5108,8 +5120,8 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
{
//todo make proper previews
- Ref<ImageTexture> pic = gui_base->get_theme_icon("FileBigThumb", "EditorIcons");
- Ref<Image> img = pic->get_data();
+ Ref<ImageTexture> texture = gui_base->get_theme_icon("FileBigThumb", "EditorIcons");
+ Ref<Image> img = texture->get_image();
img = img->duplicate();
img->resize(48, 48); //meh
Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture));
@@ -5880,6 +5892,8 @@ EditorNode::EditorNode() {
EDITOR_DEF("interface/inspector/resources_to_open_in_new_inspector", "Script,MeshLibrary,TileSet");
EDITOR_DEF("interface/inspector/default_color_picker_mode", 0);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_mode", PROPERTY_HINT_ENUM, "RGB,HSV,RAW", PROPERTY_USAGE_DEFAULT));
+ EDITOR_DEF("interface/inspector/default_color_picker_shape", (int32_t)ColorPicker::SHAPE_VHS_CIRCLE);
+ EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "interface/inspector/default_color_picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle", PROPERTY_USAGE_DEFAULT));
EDITOR_DEF("run/auto_save/save_before_running", true);
theme_base = memnew(Control);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index c0cecbc651..064271fce8 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -262,6 +262,10 @@ Control *EditorInterface::get_base_control() {
return EditorNode::get_singleton()->get_gui_base();
}
+float EditorInterface::get_editor_scale() const {
+ return EDSCALE;
+}
+
void EditorInterface::set_plugin_enabled(const String &p_plugin, bool p_enabled) {
EditorNode::get_singleton()->set_addon_plugin_enabled(p_plugin, p_enabled, true);
}
@@ -306,6 +310,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_editor_settings"), &EditorInterface::get_editor_settings);
ClassDB::bind_method(D_METHOD("get_script_editor"), &EditorInterface::get_script_editor);
ClassDB::bind_method(D_METHOD("get_base_control"), &EditorInterface::get_base_control);
+ ClassDB::bind_method(D_METHOD("get_editor_scale"), &EditorInterface::get_editor_scale);
ClassDB::bind_method(D_METHOD("edit_resource", "resource"), &EditorInterface::edit_resource);
ClassDB::bind_method(D_METHOD("open_scene_from_path", "scene_filepath"), &EditorInterface::open_scene_from_path);
ClassDB::bind_method(D_METHOD("reload_scene_from_path", "scene_filepath"), &EditorInterface::reload_scene_from_path);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index ae9fcfb28a..b0713c641b 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -100,6 +100,7 @@ public:
FileSystemDock *get_file_system_dock();
Control *get_base_control();
+ float get_editor_scale() const;
void set_plugin_enabled(const String &p_plugin, bool p_enabled);
bool is_plugin_enabled(const String &p_plugin) const;
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index d09e3726fb..4ea993af5b 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -649,14 +649,16 @@ public:
Color color = get_theme_color("highlight_color", "Editor");
for (int i = 0; i < 2; i++) {
Point2 ofs(4, vofs);
- if (i == 1)
+ if (i == 1) {
ofs.y += bsize + 1;
+ }
ofs += rect.position;
for (int j = 0; j < 10; j++) {
Point2 o = ofs + Point2(j * (bsize + 1), 0);
- if (j >= 5)
+ if (j >= 5) {
o.x += 1;
+ }
const int idx = i * 10 + j;
const bool on = value & (1 << idx);
@@ -2188,6 +2190,9 @@ void EditorPropertyColor::_picker_created() {
} else if (default_color_mode == 2) {
picker->get_picker()->set_raw_mode(true);
}
+
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ picker->get_picker()->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
}
void EditorPropertyColor::_picker_opening() {
@@ -2975,6 +2980,7 @@ void EditorPropertyResource::update_property() {
if (res == RES()) {
assign->set_icon(Ref<Texture2D>());
assign->set_text(TTR("[empty]"));
+ assign->set_custom_minimum_size(Size2(1, 1));
} else {
assign->set_icon(EditorNode::get_singleton()->get_object_icon(res.operator->(), "Object"));
@@ -3281,7 +3287,7 @@ void EditorInspectorDefaultPlugin::parse_begin(Object *p_object) {
}
bool EditorInspectorDefaultPlugin::parse_property(Object *p_object, Variant::Type p_type, const String &p_path, PropertyHint p_hint, const String &p_hint_text, int p_usage, bool p_wide) {
- float default_float_step = EDITOR_GET("interface/inspector/default_float_step");
+ double default_float_step = EDITOR_GET("interface/inspector/default_float_step");
switch (p_type) {
// atomic types
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 77288be614..138830cdc6 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -174,7 +174,7 @@ void EditorResourcePreview::_generate_preview(Ref<ImageTexture> &r_texture, Ref<
}
if (!r_small_texture.is_valid() && r_texture.is_valid() && preview_generators[i]->generate_small_preview_automatically()) {
- Ref<Image> small_image = r_texture->get_data();
+ Ref<Image> small_image = r_texture->get_image();
small_image = small_image->duplicate();
small_image->resize(small_thumbnail_size, small_thumbnail_size, Image::INTERPOLATE_CUBIC);
r_small_texture.instance();
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 9b92134368..1ffa20d1ea 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -43,7 +43,7 @@ void EditorRunNative::_notification(int p_what) {
}
Ref<ImageTexture> icon = eep->get_run_icon();
if (!icon.is_null()) {
- Ref<Image> im = icon->get_data();
+ Ref<Image> im = icon->get_image();
im = im->duplicate();
im->clear_mipmaps();
if (!im->is_empty()) {
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index c09d78826c..8577ccb9db 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -47,6 +47,8 @@ String EditorSpinSlider::get_text_value() const {
}
void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (read_only) {
return;
}
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 4526ded68b..4c5c3af765 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -91,7 +91,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}
Ref<ImageTexture> texture(memnew(ImageTexture));
- Ref<Image> img = p_texture->get_data();
+ Ref<Image> img = p_texture->get_image();
img = img->duplicate();
if (p_flip_y) {
@@ -1282,6 +1282,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_icon("preset_bg", "ColorPicker", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
theme->set_icon("overbright_indicator", "ColorPicker", theme->get_icon("OverbrightIndicator", "EditorIcons"));
theme->set_icon("bar_arrow", "ColorPicker", theme->get_icon("ColorPickerBarArrow", "EditorIcons"));
+ theme->set_icon("picker_cursor", "ColorPicker", theme->get_icon("PickerCursor", "EditorIcons"));
theme->set_icon("bg", "ColorPickerButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp
index 51bd9b3383..fd36372dde 100644
--- a/editor/editor_translation_parser.cpp
+++ b/editor/editor_translation_parser.cpp
@@ -38,8 +38,9 @@
EditorTranslationParser *EditorTranslationParser::singleton = nullptr;
Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural) {
- if (!get_script_instance())
+ if (!get_script_instance()) {
return ERR_UNAVAILABLE;
+ }
if (get_script_instance()->has_method("parse_file")) {
Array ids;
@@ -70,8 +71,9 @@ Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<Str
}
void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_extensions) const {
- if (!get_script_instance())
+ if (!get_script_instance()) {
return;
+ }
if (get_script_instance()->has_method("get_recognized_extensions")) {
Array extensions = get_script_instance()->call("get_recognized_extensions");
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index c9ccd5b0fe..899070f036 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -680,17 +680,17 @@ void FileSystemDock::_sort_file_info_list(List<FileSystemDock::FileInfo> &r_file
break;
case FILE_SORT_TYPE_REVERSE:
r_file_list.sort_custom<FileInfoTypeComparator>();
- r_file_list.invert();
+ r_file_list.reverse();
break;
case FILE_SORT_MODIFIED_TIME:
r_file_list.sort_custom<FileInfoModifiedTimeComparator>();
break;
case FILE_SORT_MODIFIED_TIME_REVERSE:
r_file_list.sort_custom<FileInfoModifiedTimeComparator>();
- r_file_list.invert();
+ r_file_list.reverse();
break;
case FILE_SORT_NAME_REVERSE:
- r_file_list.invert();
+ r_file_list.reverse();
break;
default: // FILE_SORT_NAME
break;
@@ -2621,8 +2621,9 @@ void FileSystemDock::_get_imported_files(const String &p_path, Vector<String> &f
}
void FileSystemDock::_update_import_dock() {
- if (!import_dock_needs_update)
+ if (!import_dock_needs_update) {
return;
+ }
// List selected.
Vector<String> selected;
@@ -2633,8 +2634,9 @@ void FileSystemDock::_update_import_dock() {
} else {
// Use the file list.
for (int i = 0; i < files->get_item_count(); i++) {
- if (!files->is_selected(i))
+ if (!files->is_selected(i)) {
continue;
+ }
selected.push_back(files->get_item_metadata(i));
}
diff --git a/editor/icons/GuiScrollBg.svg b/editor/icons/GuiScrollBg.svg
index dd5c60e534..7cfe647368 100644
--- a/editor/icons/GuiScrollBg.svg
+++ b/editor/icons/GuiScrollBg.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"/>
+<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".082353" r="2"/></svg>
diff --git a/editor/icons/GuiScrollGrabber.svg b/editor/icons/GuiScrollGrabber.svg
index 16edfb567c..935f9361dd 100644
--- a/editor/icons/GuiScrollGrabber.svg
+++ b/editor/icons/GuiScrollGrabber.svg
@@ -1 +1 @@
-<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".27451" r="2"/></svg>
+<svg height="12" viewBox="0 0 12 11.999999" width="12" xmlns="http://www.w3.org/2000/svg"><circle cx="6" cy="6" fill="#fff" fill-opacity=".294118" r="3"/></svg>
diff --git a/editor/icons/PickerCursor.svg b/editor/icons/PickerCursor.svg
new file mode 100644
index 0000000000..88ee3f55ce
--- /dev/null
+++ b/editor/icons/PickerCursor.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 1a5 5 0 0 1 5 5 5 5 0 0 1 -5 5 5 5 0 0 1 -5-5 5 5 0 0 1 5-5z" fill="#fff"/><path d="m8 3a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5-5 5 5 0 0 0 -5-5zm-.0605469 1a4 4 0 0 1 .0605469 0 4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 3.9394531-4z"/></svg>
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 080393e570..d3183e5a8d 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -1688,7 +1688,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
state.use_mesh_builtin_materials = true;
state.bake_fps = p_bake_fps;
- Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, 0);
+ Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, false);
if (r_err) {
*r_err = err;
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 5c522e3176..dd62c72d8a 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -427,7 +427,7 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
List<Ref<Mesh>> meshes;
- Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, 0, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
+ Error err = _parse_obj(p_path, meshes, false, p_flags & IMPORT_GENERATE_TANGENT_ARRAYS, false, Vector3(1, 1, 1), Vector3(0, 0, 0), r_missing_deps);
if (err != OK) {
if (r_err) {
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index 7c623505b5..612a8f30a4 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -117,8 +117,8 @@ void AnimationPlayerEditor::_notification(int p_what) {
autoplay_icon = get_theme_icon("AutoPlay", "EditorIcons");
reset_icon = get_theme_icon("Reload", "EditorIcons");
{
- Ref<Image> autoplay_img = autoplay_icon->get_data();
- Ref<Image> reset_img = reset_icon->get_data();
+ Ref<Image> autoplay_img = autoplay_icon->get_image();
+ Ref<Image> reset_img = reset_icon->get_image();
Ref<Image> autoplay_reset_img;
Size2 icon_size = Size2(autoplay_img->get_width(), autoplay_img->get_height());
autoplay_reset_img.instance();
@@ -1219,6 +1219,8 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
}
void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
Ref<InputEventKey> k = p_ev;
if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->get_alt() && !k->get_control() && !k->get_metakey()) {
switch (k->get_keycode()) {
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index b7484aa748..fd47d9964e 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -144,8 +144,8 @@ void EditorAssetLibraryItemDescription::set_image(int p_type, int p_index, const
for (int i = 0; i < preview_images.size(); i++) {
if (preview_images[i].id == p_index) {
if (preview_images[i].is_video) {
- Ref<Image> overlay = previews->get_theme_icon("PlayOverlay", "EditorIcons")->get_data();
- Ref<Image> thumbnail = p_image->get_data();
+ Ref<Image> overlay = previews->get_theme_icon("PlayOverlay", "EditorIcons")->get_image();
+ Ref<Image> thumbnail = p_image->get_image();
thumbnail = thumbnail->duplicate();
Point2 overlay_pos = Point2((thumbnail->get_width() - overlay->get_width()) / 2, (thumbnail->get_height() - overlay->get_height()) / 2);
@@ -557,8 +557,15 @@ void EditorAssetLibrary::_notification(int p_what) {
error_label->raise();
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
- if (is_visible() && initial_loading) {
- _repository_changed(0); // Update when shown for the first time.
+ if (is_visible()) {
+ // Focus the search box automatically when switching to the Templates tab (in the Project Manager)
+ // or switching to the AssetLib tab (in the editor).
+ // The Project Manager's project filter box is automatically focused in the project manager code.
+ filter->grab_focus();
+
+ if (initial_loading) {
+ _repository_changed(0); // Update when shown for the first time.
+ }
}
} break;
case NOTIFICATION_PROCESS: {
@@ -606,6 +613,8 @@ void EditorAssetLibrary::_update_repository_options() {
}
void EditorAssetLibrary::_unhandled_key_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
const Ref<InputEventKey> key = p_event;
if (key.is_valid() && key->is_pressed()) {
@@ -1332,6 +1341,11 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
library_main->add_theme_constant_override("separation", 10 * EDSCALE);
filter = memnew(LineEdit);
+ if (templates_only) {
+ filter->set_placeholder(TTR("Search templates, projects, and demos"));
+ } else {
+ filter->set_placeholder(TTR("Search assets (excluding templates, projects, and demos)"));
+ }
search_hb->add_child(filter);
filter->set_h_size_flags(Control::SIZE_EXPAND_FILL);
filter->connect("text_changed", callable_mp(this, &EditorAssetLibrary::_search_text_changed));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index d4e06aa9ca..b678197037 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -472,6 +472,8 @@ float CanvasItemEditor::snap_angle(float p_target, float p_start) const {
}
void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
Ref<InputEventKey> k = p_ev;
if (!is_visible_in_tree()) {
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index eb3c06fba1..d3e5854786 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -88,7 +88,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Siz
return Ref<Texture2D>();
}
- Ref<Image> atlas = tex->get_data();
+ Ref<Image> atlas = tex->get_image();
if (!atlas.is_valid()) {
return Ref<Texture2D>();
}
@@ -99,7 +99,7 @@ Ref<Texture2D> EditorTexturePreviewPlugin::generate(const RES &p_from, const Siz
} else {
Ref<Texture2D> tex = p_from;
if (tex.is_valid()) {
- img = tex->get_data();
+ img = tex->get_image();
if (img.is_valid()) {
img = img->duplicate();
}
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 77719104b1..9d29c31522 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -33,6 +33,8 @@
#include "editor/editor_scale.h"
void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
rot_x -= mm->get_relative().y * 0.01;
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index fccc042a02..3df092bc13 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -185,6 +185,8 @@ void ViewportRotationControl::_get_sorted_axis(Vector<Axis2D> &r_axis) {
}
void ViewportRotationControl::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
const Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
Vector2 pos = mb->get_position();
@@ -1277,7 +1279,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
clicked = ObjectID();
clicked_includes_current = false;
- if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
+ if ((spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT && b->get_command()) || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
/* HANDLE ROTATION */
if (get_selected_count() == 0) {
break; //bye
@@ -1472,7 +1474,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 ray_pos = _get_ray_pos(m->get_position());
Vector3 ray = _get_ray(m->get_position());
- float snap = EDITOR_GET("interface/inspector/default_float_step");
+ double snap = EDITOR_GET("interface/inspector/default_float_step");
int snap_step_decimals = Math::range_step_decimals(snap);
switch (_edit.mode) {
@@ -1766,7 +1768,7 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
Vector3 y_axis = (click - _edit.center).normalized();
Vector3 x_axis = plane.normal.cross(y_axis).normalized();
- float angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
+ double angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
if (_edit.snap || spatial_editor->is_snap_enabled()) {
snap = spatial_editor->get_rotate_snap();
@@ -2213,6 +2215,12 @@ void Node3DEditorViewport::scale_cursor_distance(real_t scale) {
cursor.distance = CLAMP(cursor.distance * scale, min_distance, max_distance);
}
+ if (cursor.distance == max_distance || cursor.distance == min_distance) {
+ zoom_failed_attempts_count++;
+ } else {
+ zoom_failed_attempts_count = 0;
+ }
+
zoom_indicator_delay = ZOOM_FREELOOK_INDICATOR_DELAY_S;
surface->update();
}
@@ -2394,6 +2402,7 @@ void Node3DEditorViewport::_notification(int p_what) {
zoom_indicator_delay -= delta;
if (zoom_indicator_delay <= 0) {
surface->update();
+ zoom_limit_label->hide();
}
}
@@ -2533,6 +2542,8 @@ void Node3DEditorViewport::_notification(int p_what) {
cpu_time += cpu_time_history[i];
}
cpu_time /= FRAME_TIME_HISTORY;
+ // Prevent unrealistically low values.
+ cpu_time = MAX(0.01, cpu_time);
gpu_time_history[gpu_time_history_index] = RS::get_singleton()->viewport_get_measured_render_time_gpu(viewport->get_viewport_rid());
gpu_time_history_index = (gpu_time_history_index + 1) % FRAME_TIME_HISTORY;
@@ -2541,16 +2552,19 @@ void Node3DEditorViewport::_notification(int p_what) {
gpu_time += gpu_time_history[i];
}
gpu_time /= FRAME_TIME_HISTORY;
+ // Prevent division by zero for the FPS counter (and unrealistically low values).
+ // This limits the reported FPS to 100000.
+ gpu_time = MAX(0.01, gpu_time);
// Color labels depending on performance level ("good" = green, "OK" = yellow, "bad" = red).
// Middle point is at 15 ms.
- cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), String::num(cpu_time, 1)));
+ cpu_time_label->set_text(vformat(TTR("CPU Time: %s ms"), rtos(cpu_time).pad_decimals(1)));
cpu_time_label->add_theme_color_override(
"font_color",
frame_time_gradient->get_color_at_offset(
Math::range_lerp(cpu_time, 0, 30, 0, 1)));
- gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), String::num(gpu_time, 1)));
+ gpu_time_label->set_text(vformat(TTR("GPU Time: %s ms"), rtos(gpu_time).pad_decimals(1)));
// Middle point is at 15 ms.
gpu_time_label->add_theme_color_override(
"font_color",
@@ -2768,6 +2782,7 @@ void Node3DEditorViewport::_draw() {
} else {
// Show zoom
+ zoom_limit_label->set_visible(zoom_failed_attempts_count > 15);
real_t min_distance = MAX(camera->get_near() * 4, ZOOM_FREELOOK_MIN);
real_t max_distance = MIN(camera->get_far() / 4, ZOOM_FREELOOK_MAX);
@@ -3645,9 +3660,9 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const
AABB Node3DEditorViewport::_calculate_spatial_bounds(const Node3D *p_parent, bool p_exclude_top_level_transform) {
AABB bounds;
- const MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_parent);
- if (mesh_instance) {
- bounds = mesh_instance->get_aabb();
+ const VisualInstance3D *visual_instance = Object::cast_to<VisualInstance3D>(p_parent);
+ if (visual_instance) {
+ bounds = visual_instance->get_aabb();
}
for (int i = 0; i < p_parent->get_child_count(); i++) {
@@ -4130,6 +4145,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito
locked_label->set_text(TTR("View Rotation Locked"));
locked_label->hide();
+ zoom_limit_label = memnew(Label);
+ zoom_limit_label->set_anchors_and_offsets_preset(LayoutPreset::PRESET_BOTTOM_LEFT);
+ zoom_limit_label->set_offset(Side::SIDE_TOP, -28 * EDSCALE);
+ zoom_limit_label->set_text(TTR("To zoom further, change the camera's clipping planes (View -> Settings...)"));
+ zoom_limit_label->set_name("ZoomLimitMessageLabel");
+ zoom_limit_label->add_theme_color_override("font_color", Color(1, 1, 1, 1));
+ zoom_limit_label->hide();
+ surface->add_child(zoom_limit_label);
+
frame_time_gradient = memnew(Gradient);
// The color is set when the theme changes.
frame_time_gradient->add_point(0.5, Color());
@@ -4192,6 +4216,8 @@ Node3DEditorViewport::~Node3DEditorViewport() {
//////////////////////////////////////////////////////////////
void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
@@ -4577,7 +4603,12 @@ void _update_all_gizmos(Node *p_node) {
void Node3DEditor::update_all_gizmos(Node *p_node) {
if (!p_node) {
- p_node = SceneTree::get_singleton()->get_root();
+ if (SceneTree::get_singleton()) {
+ p_node = SceneTree::get_singleton()->get_root();
+ } else {
+ // No scene tree, so nothing to update.
+ return;
+ }
}
_update_all_gizmos(p_node);
}
@@ -6154,6 +6185,8 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
}
void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!is_visible_in_tree()) {
return;
}
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index ff4a941b06..70329f90c7 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -295,6 +295,7 @@ private:
Label *info_label;
Label *cinema_label;
Label *locked_label;
+ Label *zoom_limit_label;
VBoxContainer *top_right_vbox;
ViewportRotationControl *rotation_control;
@@ -418,6 +419,7 @@ private:
void scale_freelook_speed(real_t scale);
real_t zoom_indicator_delay;
+ int zoom_failed_attempts_count = 0;
RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[4], scale_gizmo_instance[3], scale_plane_gizmo_instance[3];
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index b298474406..58e6717a3d 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -2706,6 +2706,8 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
void ScriptEditor::_unhandled_key_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!is_visible_in_tree() || !p_event->is_pressed() || p_event->is_echo()) {
return;
}
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 3534809891..c982207224 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1721,6 +1721,9 @@ void ScriptTextEditor::_enable_code_editor() {
color_picker->set_raw_mode(true);
}
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
+
quick_open = memnew(ScriptEditorQuickOpen);
quick_open->connect("goto_line", callable_mp(this, &ScriptTextEditor::_goto_line));
add_child(quick_open);
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 121ccfa417..ad60984ad1 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -167,16 +167,18 @@ void BoneTransformEditor::_notification(int p_what) {
}
void BoneTransformEditor::_value_changed(const double p_value) {
- if (updating)
+ if (updating) {
return;
+ }
Transform tform = compute_transform_from_vector3s();
_change_transform(tform);
}
void BoneTransformEditor::_value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean) {
- if (updating)
+ if (updating) {
return;
+ }
Transform tform = compute_transform_from_vector3s();
_change_transform(tform);
}
@@ -194,8 +196,9 @@ Transform BoneTransformEditor::compute_transform_from_vector3s() const {
}
void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform p_transform, const StringName p_edited_property_name, const bool p_boolean) {
- if (updating)
+ if (updating) {
return;
+ }
_change_transform(p_transform);
}
@@ -222,11 +225,13 @@ void BoneTransformEditor::update_enabled_checkbox() {
}
void BoneTransformEditor::_update_properties() {
- if (updating)
+ if (updating) {
return;
+ }
- if (skeleton == nullptr)
+ if (skeleton == nullptr) {
return;
+ }
updating = true;
@@ -235,11 +240,13 @@ void BoneTransformEditor::_update_properties() {
}
void BoneTransformEditor::_update_custom_pose_properties() {
- if (updating)
+ if (updating) {
return;
+ }
- if (skeleton == nullptr)
+ if (skeleton == nullptr) {
return;
+ }
updating = true;
@@ -287,14 +294,16 @@ void BoneTransformEditor::set_toggle_enabled(const bool p_enabled) {
}
void BoneTransformEditor::_key_button_pressed() {
- if (skeleton == nullptr)
+ if (skeleton == nullptr) {
return;
+ }
const BoneId bone_id = property.get_slicec('/', 1).to_int();
const String name = skeleton->get_bone_name(bone_id);
- if (name.is_empty())
+ if (name.is_empty()) {
return;
+ }
// Need to normalize the basis before you key it
Transform tform = compute_transform_from_vector3s();
@@ -405,8 +414,9 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
Variant Skeleton3DEditor::get_drag_data_fw(const Point2 &p_point, Control *p_from) {
TreeItem *selected = joint_tree->get_selected();
- if (!selected)
+ if (!selected) {
return Variant();
+ }
Ref<Texture> icon = selected->get_icon(0);
@@ -431,27 +441,32 @@ Variant Skeleton3DEditor::get_drag_data_fw(const Point2 &p_point, Control *p_fro
bool Skeleton3DEditor::can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const {
TreeItem *target = joint_tree->get_item_at_position(p_point);
- if (!target)
+ if (!target) {
return false;
+ }
const String path = target->get_metadata(0);
- if (!path.begins_with("bones/"))
+ if (!path.begins_with("bones/")) {
return false;
+ }
TreeItem *selected = Object::cast_to<TreeItem>(Dictionary(p_data)["node"]);
- if (target == selected)
+ if (target == selected) {
return false;
+ }
const String path2 = target->get_metadata(0);
- if (!path2.begins_with("bones/"))
+ if (!path2.begins_with("bones/")) {
return false;
+ }
return true;
}
void Skeleton3DEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) {
- if (!can_drop_data_fw(p_point, p_data, p_from))
+ if (!can_drop_data_fw(p_point, p_data, p_from)) {
return;
+ }
TreeItem *target = joint_tree->get_item_at_position(p_point);
TreeItem *selected = Object::cast_to<TreeItem>(Dictionary(p_data)["node"]);
@@ -510,19 +525,23 @@ void Skeleton3DEditor::_joint_tree_rmb_select(const Vector2 &p_pos) {
}
void Skeleton3DEditor::_update_properties() {
- if (rest_editor)
+ if (rest_editor) {
rest_editor->_update_properties();
- if (pose_editor)
+ }
+ if (pose_editor) {
pose_editor->_update_properties();
- if (custom_pose_editor)
+ }
+ if (custom_pose_editor) {
custom_pose_editor->_update_custom_pose_properties();
+ }
}
void Skeleton3DEditor::update_joint_tree() {
joint_tree->clear();
- if (skeleton == nullptr)
+ if (skeleton == nullptr) {
return;
+ }
TreeItem *root = joint_tree->create_item();
diff --git a/editor/plugins/sprite_2d_editor_plugin.cpp b/editor/plugins/sprite_2d_editor_plugin.cpp
index 4acacf3058..4a7f6c0f7e 100644
--- a/editor/plugins/sprite_2d_editor_plugin.cpp
+++ b/editor/plugins/sprite_2d_editor_plugin.cpp
@@ -171,7 +171,7 @@ void Sprite2DEditor::_update_mesh_data() {
return;
}
- Ref<Image> image = texture->get_data();
+ Ref<Image> image = texture->get_image();
ERR_FAIL_COND(image.is_null());
if (image->is_compressed()) {
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index 265d4ccc1e..89ed98d53e 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -35,6 +35,8 @@
#include "editor/editor_settings.h"
void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) {
y_rot += -mm->get_relative().x * 0.01;
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index cca4f594e9..feaf609557 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -2928,7 +2928,7 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
}
if (p_total < 0) {
- points.invert();
+ points.reverse();
}
shape->set_points(points);
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index 69bdc05b3a..b2fa9c540e 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -384,6 +384,20 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id) {
port_offset += 2;
}
+ if (is_resizable) {
+ Ref<VisualShaderNodeComment> comment_node = Object::cast_to<VisualShaderNodeComment>(vsnode.ptr());
+ if (comment_node.is_valid()) {
+ node->set_comment(true);
+
+ Label *comment_label = memnew(Label);
+ node->add_child(comment_label);
+ comment_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ comment_label->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ comment_label->set_mouse_filter(Control::MouseFilter::MOUSE_FILTER_STOP);
+ comment_label->set_text(comment_node->get_description());
+ }
+ }
+
Ref<VisualShaderNodeUniform> uniform = vsnode;
if (uniform.is_valid()) {
VisualShaderEditor::get_singleton()->graph->add_child(node);
@@ -1624,6 +1638,92 @@ void VisualShaderEditor::_preview_select_port(int p_node, int p_port) {
undo_redo->commit_action();
}
+void VisualShaderEditor::_comment_title_popup_show(const Point2 &p_position, int p_node_id) {
+ VisualShader::Type type = get_current_shader_type();
+ Ref<VisualShaderNodeComment> node = visual_shader->get_node(type, p_node_id);
+ if (node.is_null()) {
+ return;
+ }
+ comment_title_change_edit->set_text(node->get_title());
+ comment_title_change_popup->set_meta("id", p_node_id);
+ comment_title_change_popup->popup();
+ comment_title_change_popup->set_position(p_position);
+}
+
+void VisualShaderEditor::_comment_title_text_changed(const String &p_new_text) {
+ comment_title_change_edit->set_size(Size2(-1, -1));
+ comment_title_change_popup->set_size(Size2(-1, -1));
+}
+
+void VisualShaderEditor::_comment_title_text_entered(const String &p_new_text) {
+ comment_title_change_popup->hide();
+}
+
+void VisualShaderEditor::_comment_title_popup_focus_out() {
+ comment_title_change_popup->hide();
+}
+
+void VisualShaderEditor::_comment_title_popup_hide() {
+ ERR_FAIL_COND(!comment_title_change_popup->has_meta("id"));
+ int node_id = (int)comment_title_change_popup->get_meta("id");
+
+ VisualShader::Type type = get_current_shader_type();
+ Ref<VisualShaderNodeComment> node = visual_shader->get_node(type, node_id);
+
+ ERR_FAIL_COND(node.is_null());
+
+ if (node->get_title() == comment_title_change_edit->get_text()) {
+ return; // nothing changed - ignored
+ }
+ undo_redo->create_action(TTR("Set Comment Node Title"));
+ undo_redo->add_do_method(node.ptr(), "set_title", comment_title_change_edit->get_text());
+ undo_redo->add_undo_method(node.ptr(), "set_title", node->get_title());
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
+ undo_redo->commit_action();
+}
+
+void VisualShaderEditor::_comment_desc_popup_show(const Point2 &p_position, int p_node_id) {
+ VisualShader::Type type = get_current_shader_type();
+ Ref<VisualShaderNodeComment> node = visual_shader->get_node(type, p_node_id);
+ if (node.is_null()) {
+ return;
+ }
+ comment_desc_change_edit->set_text(node->get_description());
+ comment_desc_change_popup->set_meta("id", p_node_id);
+ comment_desc_change_popup->popup();
+ comment_desc_change_popup->set_position(p_position);
+}
+
+void VisualShaderEditor::_comment_desc_text_changed() {
+ comment_desc_change_edit->set_size(Size2(-1, -1));
+ comment_desc_change_popup->set_size(Size2(-1, -1));
+}
+
+void VisualShaderEditor::_comment_desc_confirm() {
+ comment_desc_change_popup->hide();
+}
+
+void VisualShaderEditor::_comment_desc_popup_hide() {
+ ERR_FAIL_COND(!comment_desc_change_popup->has_meta("id"));
+ int node_id = (int)comment_desc_change_popup->get_meta("id");
+
+ VisualShader::Type type = get_current_shader_type();
+ Ref<VisualShaderNodeComment> node = visual_shader->get_node(type, node_id);
+
+ ERR_FAIL_COND(node.is_null());
+
+ if (node->get_description() == comment_desc_change_edit->get_text()) {
+ return; // nothing changed - ignored
+ }
+ undo_redo->create_action(TTR("Set Comment Node Description"));
+ undo_redo->add_do_method(node.ptr(), "set_description", comment_desc_change_edit->get_text());
+ undo_redo->add_undo_method(node.ptr(), "set_description", node->get_title());
+ undo_redo->add_do_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "update_node", (int)type, node_id);
+ undo_redo->commit_action();
+}
+
void VisualShaderEditor::_uniform_line_edit_changed(const String &p_text, int p_node_id) {
VisualShader::Type type = get_current_shader_type();
@@ -2507,6 +2607,7 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
selected_constants.clear();
selected_uniforms.clear();
+ selected_comment = -1;
List<int> to_change;
for (int i = 0; i < graph->get_child_count(); i++) {
@@ -2517,17 +2618,27 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
to_change.push_back(id);
Ref<VisualShaderNode> node = visual_shader->get_node(type, id);
- VisualShaderNodeConstant *cnode = Object::cast_to<VisualShaderNodeConstant>(node.ptr());
- if (cnode != nullptr) {
+
+ VisualShaderNodeComment *comment_node = Object::cast_to<VisualShaderNodeComment>(node.ptr());
+ if (comment_node != nullptr) {
+ selected_comment = id;
+ }
+ VisualShaderNodeConstant *constant_node = Object::cast_to<VisualShaderNodeConstant>(node.ptr());
+ if (constant_node != nullptr) {
selected_constants.insert(id);
}
- VisualShaderNodeUniform *unode = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
- if (unode != nullptr) {
+ VisualShaderNodeUniform *uniform_node = Object::cast_to<VisualShaderNodeUniform>(node.ptr());
+ if (uniform_node != nullptr && uniform_node->is_convertible_to_constant()) {
selected_uniforms.insert(id);
}
}
}
}
+
+ if (to_change.size() > 1) {
+ selected_comment = -1;
+ }
+
if (to_change.is_empty() && copy_nodes_buffer.is_empty()) {
_show_members_dialog(true);
} else {
@@ -2548,16 +2659,34 @@ void VisualShaderEditor::_graph_gui_input(const Ref<InputEvent> &p_event) {
if (temp != -1) {
popup_menu->remove_item(temp);
}
+ temp = popup_menu->get_item_index(NodeMenuOptions::SEPARATOR3);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
+ temp = popup_menu->get_item_index(NodeMenuOptions::SET_COMMENT_TITLE);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
+ temp = popup_menu->get_item_index(NodeMenuOptions::SET_COMMENT_DESCRIPTION);
+ if (temp != -1) {
+ popup_menu->remove_item(temp);
+ }
- if (selected_constants.size() > 0 || selected_uniforms.size() > 0) {
+ if (selected_comment != -1) {
popup_menu->add_separator("", NodeMenuOptions::SEPARATOR2);
+ popup_menu->add_item(TTR("Set Comment Title"), NodeMenuOptions::SET_COMMENT_TITLE);
+ popup_menu->add_item(TTR("Set Comment Description"), NodeMenuOptions::SET_COMMENT_DESCRIPTION);
+ }
+
+ if (selected_constants.size() > 0 || selected_uniforms.size() > 0) {
+ popup_menu->add_separator("", NodeMenuOptions::SEPARATOR3);
if (selected_constants.size() > 0) {
popup_menu->add_item(TTR("Convert Constant(s) to Uniform(s)"), NodeMenuOptions::CONVERT_CONSTANTS_TO_UNIFORMS);
}
if (selected_uniforms.size() > 0) {
- popup_menu->add_item(TTR("Convert Uniforms(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS);
+ popup_menu->add_item(TTR("Convert Uniform(s) to Constant(s)"), NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS);
}
}
@@ -3111,6 +3240,12 @@ void VisualShaderEditor::_node_menu_id_pressed(int p_idx) {
case NodeMenuOptions::CONVERT_UNIFORMS_TO_CONSTANTS:
_convert_constants_to_uniforms(true);
break;
+ case NodeMenuOptions::SET_COMMENT_TITLE:
+ _comment_title_popup_show(get_global_mouse_position(), selected_comment);
+ break;
+ case NodeMenuOptions::SET_COMMENT_DESCRIPTION:
+ _comment_desc_popup_show(get_global_mouse_position(), selected_comment);
+ break;
default:
break;
}
@@ -3534,6 +3669,35 @@ VisualShaderEditor::VisualShaderEditor() {
alert->get_label()->set_custom_minimum_size(Size2(400, 60) * EDSCALE);
add_child(alert);
+ comment_title_change_popup = memnew(PopupPanel);
+ comment_title_change_edit = memnew(LineEdit);
+ comment_title_change_edit->set_expand_to_text_length(true);
+ comment_title_change_edit->connect("text_changed", callable_mp(this, &VisualShaderEditor::_comment_title_text_changed));
+ comment_title_change_edit->connect("text_entered", callable_mp(this, &VisualShaderEditor::_comment_title_text_entered));
+ comment_title_change_popup->add_child(comment_title_change_edit);
+ comment_title_change_edit->set_size(Size2(-1, -1));
+ comment_title_change_popup->set_size(Size2(-1, -1));
+ comment_title_change_popup->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_comment_title_popup_focus_out));
+ comment_title_change_popup->connect("popup_hide", callable_mp(this, &VisualShaderEditor::_comment_title_popup_hide));
+ add_child(comment_title_change_popup);
+
+ comment_desc_change_popup = memnew(PopupPanel);
+ VBoxContainer *comment_desc_vbox = memnew(VBoxContainer);
+ comment_desc_change_popup->add_child(comment_desc_vbox);
+ comment_desc_change_edit = memnew(TextEdit);
+ comment_desc_change_edit->connect("text_changed", callable_mp(this, &VisualShaderEditor::_comment_desc_text_changed));
+ comment_desc_vbox->add_child(comment_desc_change_edit);
+ comment_desc_change_edit->set_custom_minimum_size(Size2(300 * EDSCALE, 150 * EDSCALE));
+ comment_desc_change_edit->set_size(Size2(-1, -1));
+ comment_desc_change_popup->set_size(Size2(-1, -1));
+ comment_desc_change_popup->connect("focus_exited", callable_mp(this, &VisualShaderEditor::_comment_desc_confirm));
+ comment_desc_change_popup->connect("popup_hide", callable_mp(this, &VisualShaderEditor::_comment_desc_popup_hide));
+ Button *comment_desc_confirm_button = memnew(Button);
+ comment_desc_confirm_button->set_text(TTR("OK"));
+ comment_desc_vbox->add_child(comment_desc_confirm_button);
+ comment_desc_confirm_button->connect("pressed", callable_mp(this, &VisualShaderEditor::_comment_desc_confirm));
+ add_child(comment_desc_change_popup);
+
///////////////////////////////////////
// SHADER NODES TREE OPTIONS
///////////////////////////////////////
@@ -3971,6 +4135,7 @@ VisualShaderEditor::VisualShaderEditor() {
// SPECIAL
+ add_options.push_back(AddOption("Comment", "Special", "", "VisualShaderNodeComment", TTR("A rectangular area with a description string for better graph organization.")));
add_options.push_back(AddOption("Expression", "Special", "", "VisualShaderNodeExpression", TTR("Custom Godot Shader Language expression, with custom amount of input and output ports. This is a direct injection of code into the vertex/fragment/light function, do not use it to write the function declarations inside.")));
add_options.push_back(AddOption("Fresnel", "Special", "", "VisualShaderNodeFresnel", TTR("Returns falloff based on the dot product of surface normal and view direction of camera (pass associated inputs to it)."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("GlobalExpression", "Special", "", "VisualShaderNodeGlobalExpression", TTR("Custom Godot Shader Language expression, which is placed on top of the resulted shader. You can place various function definitions inside and call it later in the Expressions. You can also declare varyings, uniforms and constants.")));
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index 182bed6ba6..517dc6056f 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -67,7 +67,7 @@ private:
VisualShader::Type type = VisualShader::Type::TYPE_MAX;
VisualShaderNode *visual_node = nullptr;
GraphNode *graph_node = nullptr;
- bool preview_visible = 0;
+ bool preview_visible = false;
int preview_pos = 0;
Map<int, InputPort> input_ports;
Map<int, Port> output_ports;
@@ -161,6 +161,12 @@ class VisualShaderEditor : public VBoxContainer {
PopupMenu *popup_menu;
MenuButton *tools;
+ PopupPanel *comment_title_change_popup = nullptr;
+ LineEdit *comment_title_change_edit = nullptr;
+
+ PopupPanel *comment_desc_change_popup = nullptr;
+ TextEdit *comment_desc_change_edit = nullptr;
+
bool preview_first = true;
bool preview_showed = false;
bool particles_mode;
@@ -192,6 +198,9 @@ class VisualShaderEditor : public VBoxContainer {
SEPARATOR2, // ignore
CONVERT_CONSTANTS_TO_UNIFORMS,
CONVERT_UNIFORMS_TO_CONSTANTS,
+ SEPARATOR3, // ignore
+ SET_COMMENT_TITLE,
+ SET_COMMENT_DESCRIPTION,
};
Tree *members;
@@ -325,6 +334,7 @@ class VisualShaderEditor : public VBoxContainer {
Set<int> selected_constants;
Set<int> selected_uniforms;
+ int selected_comment = -1;
void _convert_constants_to_uniforms(bool p_vice_versa);
void _replace_node(VisualShader::Type p_type_id, int p_node_id, const StringName &p_from, const StringName &p_to);
@@ -334,6 +344,17 @@ class VisualShaderEditor : public VBoxContainer {
void _connection_to_empty(const String &p_from, int p_from_slot, const Vector2 &p_release_position);
void _connection_from_empty(const String &p_to, int p_to_slot, const Vector2 &p_release_position);
+ void _comment_title_popup_show(const Point2 &p_position, int p_node_id);
+ void _comment_title_popup_hide();
+ void _comment_title_popup_focus_out();
+ void _comment_title_text_changed(const String &p_new_text);
+ void _comment_title_text_entered(const String &p_new_text);
+
+ void _comment_desc_popup_show(const Point2 &p_position, int p_node_id);
+ void _comment_desc_popup_hide();
+ void _comment_desc_confirm();
+ void _comment_desc_text_changed();
+
void _uniform_line_edit_changed(const String &p_text, int p_node_id);
void _uniform_line_edit_focus_out(Object *line_edit, int p_node_id);
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index b7dd1013f3..3ede50320a 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -1082,6 +1082,7 @@ ProjectExportDialog::ProjectExportDialog() {
export_filter->add_item(TTR("Export all resources in the project"));
export_filter->add_item(TTR("Export selected scenes (and dependencies)"));
export_filter->add_item(TTR("Export selected resources (and dependencies)"));
+ export_filter->add_item(TTR("Export all resources in the project except resources checked below"));
resources_vb->add_margin_child(TTR("Export Mode:"), export_filter);
export_filter->connect("item_selected", callable_mp(this, &ProjectExportDialog::_export_type_changed));
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 914806039f..d3def86bd1 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -100,6 +100,7 @@ private:
FileDialog *fdialog_install;
String zip_path;
String zip_title;
+ String zip_root;
AcceptDialog *dialog_error;
String fav_dir;
@@ -200,7 +201,9 @@ private:
char fname[16384];
ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, nullptr, 0, nullptr, 0);
- if (String(fname).ends_with("project.godot")) {
+ String fname_str = String(fname);
+ if (fname_str.ends_with("project.godot")) {
+ zip_root = fname_str.substr(0, fname_str.rfind("project.godot"));
break;
}
@@ -533,44 +536,34 @@ private:
String path = fname;
- int depth = 1; //stuff from github comes with tag
- bool skip = false;
- while (depth > 0) {
- int pp = path.find("/");
- if (pp == -1) {
- skip = true;
- break;
- }
- path = path.substr(pp + 1, path.length());
- depth--;
- }
-
- if (skip || path == String()) {
+ if (path == String() || path == zip_root || !zip_root.is_subsequence_of(path)) {
//
} else if (path.ends_with("/")) { // a dir
path = path.substr(0, path.length() - 1);
+ String rel_path = path.substr(zip_root.length());
DirAccess *da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->make_dir(dir.plus_file(path));
+ da->make_dir(dir.plus_file(rel_path));
memdelete(da);
} else {
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
+ String rel_path = path.substr(zip_root.length());
//read
unzOpenCurrentFile(pkg);
unzReadCurrentFile(pkg, data.ptrw(), data.size());
unzCloseCurrentFile(pkg);
- FileAccess *f = FileAccess::open(dir.plus_file(path), FileAccess::WRITE);
+ FileAccess *f = FileAccess::open(dir.plus_file(rel_path), FileAccess::WRITE);
if (f) {
f->store_buffer(data.ptr(), data.size());
memdelete(f);
} else {
- failed_files.push_back(path);
+ failed_files.push_back(rel_path);
}
}
@@ -1038,7 +1031,7 @@ public:
int get_project_count() const;
void select_project(int p_index);
void select_first_visible_project();
- void erase_selected_projects();
+ void erase_selected_projects(bool p_delete_project_contents);
Vector<Item> get_selected_projects() const;
const Set<String> &get_selected_project_keys() const;
void ensure_project_visible(int p_index);
@@ -1693,7 +1686,7 @@ void ProjectList::toggle_select(int p_index) {
item.control->update();
}
-void ProjectList::erase_selected_projects() {
+void ProjectList::erase_selected_projects(bool p_delete_project_contents) {
if (_selected_project_keys.size() == 0) {
return;
}
@@ -1704,6 +1697,10 @@ void ProjectList::erase_selected_projects() {
EditorSettings::get_singleton()->erase("projects/" + item.project_key);
EditorSettings::get_singleton()->erase("favorite_projects/" + item.project_key);
+ if (p_delete_project_contents) {
+ OS::get_singleton()->move_to_trash(item.path);
+ }
+
memdelete(item.control);
_projects.remove(i);
--i;
@@ -1889,6 +1886,8 @@ void ProjectManager::_update_project_buttons() {
}
void ProjectManager::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
Ref<InputEventKey> k = p_ev;
if (k.is_valid()) {
@@ -2222,7 +2221,7 @@ void ProjectManager::_rename_project() {
}
void ProjectManager::_erase_project_confirm() {
- _project_list->erase_selected_projects();
+ _project_list->erase_selected_projects(delete_project_contents->is_pressed());
_update_project_buttons();
}
@@ -2240,12 +2239,13 @@ void ProjectManager::_erase_project() {
String confirm_message;
if (selected_list.size() >= 2) {
- confirm_message = vformat(TTR("Remove %d projects from the list?\nThe project folders' contents won't be modified."), selected_list.size());
+ confirm_message = vformat(TTR("Remove %d projects from the list?"), selected_list.size());
} else {
- confirm_message = TTR("Remove this project from the list?\nThe project folder's contents won't be modified.");
+ confirm_message = TTR("Remove this project from the list?");
}
- erase_ask->set_text(confirm_message);
+ erase_ask_label->set_text(confirm_message);
+ delete_project_contents->set_pressed(false);
erase_ask->popup_centered();
}
@@ -2338,6 +2338,17 @@ void ProjectManager::_on_order_option_changed(int p_idx) {
}
}
+void ProjectManager::_on_tab_changed(int p_tab) {
+ if (p_tab == 0) { // Projects
+ // Automatically grab focus when the user moves from the Templates tab
+ // back to the Projects tab.
+ search_box->grab_focus();
+ }
+
+ // The Templates tab's search field is focused on display in the asset
+ // library editor plugin code.
+}
+
void ProjectManager::_on_search_term_changed(const String &p_term) {
_project_list->set_search_term(p_term);
_project_list->sort_projects();
@@ -2425,8 +2436,10 @@ ProjectManager::ProjectManager() {
// Define a minimum window size to prevent UI elements from overlapping or being cut off
DisplayServer::get_singleton()->window_set_min_size(Size2(750, 420) * EDSCALE);
- // TODO: Resize windows on hiDPI displays on Windows and Linux and remove the line below
- DisplayServer::get_singleton()->window_set_size(DisplayServer::get_singleton()->window_get_size() * MAX(1, EDSCALE));
+ // TODO: Resize windows on hiDPI displays on Windows and Linux and remove the lines below
+ float scale_factor = MAX(1, EDSCALE);
+ Vector2i window_size = DisplayServer::get_singleton()->window_get_size();
+ DisplayServer::get_singleton()->window_set_size(Vector2i(window_size.x * scale_factor, window_size.y * scale_factor));
}
// TRANSLATORS: This refers to the application where users manage their Godot projects.
@@ -2461,6 +2474,7 @@ ProjectManager::ProjectManager() {
center_box->add_child(tabs);
tabs->set_anchors_and_offsets_preset(Control::PRESET_WIDE);
tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->connect("tab_changed", callable_mp(this, &ProjectManager::_on_tab_changed));
HBoxContainer *projects_hb = memnew(HBoxContainer);
projects_hb->set_name(TTR("Projects"));
@@ -2477,8 +2491,8 @@ ProjectManager::ProjectManager() {
search_tree_vb->add_child(hb);
search_box = memnew(LineEdit);
- search_box->set_placeholder(TTR("Search"));
- search_box->set_tooltip(TTR("The search box filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character."));
+ search_box->set_placeholder(TTR("Filter projects"));
+ search_box->set_tooltip(TTR("This field filters projects by name and last path component.\nTo filter projects by name and full path, the query must contain at least one `/` character."));
search_box->connect("text_changed", callable_mp(this, &ProjectManager::_on_search_term_changed));
search_box->set_h_size_flags(Control::SIZE_EXPAND_FILL);
hb->add_child(search_box);
@@ -2656,6 +2670,16 @@ ProjectManager::ProjectManager() {
erase_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_erase_project_confirm));
add_child(erase_ask);
+ VBoxContainer *erase_ask_vb = memnew(VBoxContainer);
+ erase_ask->add_child(erase_ask_vb);
+
+ erase_ask_label = memnew(Label);
+ erase_ask_vb->add_child(erase_ask_label);
+
+ delete_project_contents = memnew(CheckBox);
+ delete_project_contents->set_text(TTR("Also delete project contents (no undo!)"));
+ erase_ask_vb->add_child(delete_project_contents);
+
multi_open_ask = memnew(ConfirmationDialog);
multi_open_ask->get_ok_button()->set_text(TTR("Edit"));
multi_open_ask->get_ok_button()->connect("pressed", callable_mp(this, &ProjectManager::_open_selected_projects));
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 6dc0e67cba..d13315c022 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -67,7 +67,11 @@ class ProjectManager : public Control {
FileDialog *scan_dir;
ConfirmationDialog *language_restart_ask;
+
ConfirmationDialog *erase_ask;
+ Label *erase_ask_label;
+ CheckBox *delete_project_contents;
+
ConfirmationDialog *erase_missing_ask;
ConfirmationDialog *multi_open_ask;
ConfirmationDialog *multi_run_ask;
@@ -116,6 +120,7 @@ class ProjectManager : public Control {
void _files_dropped(PackedStringArray p_files, int p_screen);
void _on_order_option_changed(int p_idx);
+ void _on_tab_changed(int p_tab);
void _on_search_term_changed(const String &p_term);
protected:
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 0a4f432e4a..1a010b9168 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -832,6 +832,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
} else if (default_color_mode == 2) {
color_picker->set_raw_mode(true);
}
+
+ int picker_shape = EDITOR_GET("interface/inspector/default_color_picker_shape");
+ color_picker->set_picker_shape((ColorPicker::PickerShapeType)picker_shape);
}
color_picker->show();
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 023019b2aa..c62e9cbe5f 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -61,6 +61,8 @@ void SceneTreeDock::_quick_open() {
}
void SceneTreeDock::_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == MOUSE_BUTTON_LEFT) {
@@ -69,6 +71,8 @@ void SceneTreeDock::_input(Ref<InputEvent> p_event) {
}
void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (get_focus_owner() && get_focus_owner()->is_text_field()) {
return;
}
@@ -608,7 +612,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
List<Node *> selection = editor_selection->get_selected_node_list();
selection.sort_custom<Node::Comparator>(); // sort by index
if (MOVING_DOWN) {
- selection.invert();
+ selection.reverse();
}
int lowest_id = common_parent->get_child_count() - 1;
@@ -1384,7 +1388,7 @@ void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pai
base_path.push_back(n->get_name());
n = n->get_parent();
}
- base_path.invert();
+ base_path.reverse();
Vector<StringName> new_base_path;
if (p_new_parent) {
@@ -1394,7 +1398,7 @@ void SceneTreeDock::fill_path_renames(Node *p_node, Node *p_new_parent, List<Pai
n = n->get_parent();
}
- new_base_path.invert();
+ new_base_path.reverse();
}
_fill_path_renames(base_path, new_base_path, p_node, p_renames);
@@ -1580,7 +1584,7 @@ void SceneTreeDock::_node_prerenamed(Node *p_node, const String &p_new_name) {
base_path.push_back(n->get_name());
n = n->get_parent();
}
- base_path.invert();
+ base_path.reverse();
Vector<StringName> new_base_path = base_path;
base_path.push_back(p_node->get_name());
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 3852c389c7..81af4996ed 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -139,6 +139,8 @@ void EditorSettingsDialog::_notification(int p_what) {
}
void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
const Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed()) {
@@ -391,9 +393,10 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
TreeItem *ti = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!ti);
+ button_idx = p_idx;
+
if (ti->get_metadata(0) == "Common") {
// Editing a Built-in action, which can have multiple bindings.
- button_idx = p_idx;
editing_action = true;
current_action = ti->get_text(0);
diff --git a/editor/translations/af.po b/editor/translations/af.po
index bda0eed750..a60466f417 100644
--- a/editor/translations/af.po
+++ b/editor/translations/af.po
@@ -6,12 +6,13 @@
# Julius Stopforth <jjstopforth@gmail.com>, 2018.
# Isa Tippens <isatippens2@gmail.com>, 2019.
# Henry Geyser <thegoat187@gmail.com>, 2020.
+# Henry LeRoux <henry.leroux@ocsbstudent.ca>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-12-01 20:29+0000\n"
-"Last-Translator: Henry Geyser <thegoat187@gmail.com>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Henry LeRoux <henry.leroux@ocsbstudent.ca>\n"
"Language-Team: Afrikaans <https://hosted.weblate.org/projects/godot-engine/"
"godot/af/>\n"
"Language: af\n"
@@ -19,7 +20,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.4-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -216,14 +217,12 @@ msgid "Animation Playback Track"
msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (frames)"
-msgstr "Animasie lengte (in sekondes)."
+msgstr "Animasie lengte (in rame)."
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Animation length (seconds)"
-msgstr "Animasie lengte (in sekondes)."
+msgstr "Animasie lengte (in sekondes)"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -3667,6 +3666,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4095,6 +4099,10 @@ msgid "Reset to Defaults"
msgstr "Laai Verstek"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Vind"
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 5c03984e01..f4b65c0065 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -3691,6 +3691,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "الحالة: إستيراد Ø§Ù„Ù…Ù„Ù ÙØ´Ù„. من ÙØ¶Ù„Ùƒ أصلح المل٠و أعد إستيراده يدوياً."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "لا يمكن مسح/إعادة تسمية جذر الموارد."
@@ -4092,6 +4097,10 @@ msgid "Reset to Defaults"
msgstr "تحميل Ø§Ù„Ø¥ÙØªØ±Ø§Ø¶ÙŠ"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Ù…Ù„ÙØ§Øª"
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index 848574a1f1..cb2b9e1bd2 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -3537,6 +3537,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3927,6 +3932,10 @@ msgid "Reset to Defaults"
msgstr "Връщане на Ñтандартните наÑтройки"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d файла"
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index ca8fff0724..c8d082fbd5 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -3872,6 +3872,11 @@ msgstr ""
"ইমà§à¦ªà§‹à¦°à§à¦Ÿ করà§à¦¨à¥¤"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Cannot move/rename resources root."
msgstr "ফনà§à¦Ÿà§‡à¦° উৎস লোড/পà§à¦°à¦¸à§‡à¦¸ করা সমà§à¦­à¦¬ হচà§à¦›à§‡ না।"
@@ -4323,6 +4328,10 @@ msgid "Reset to Defaults"
msgstr "পà§à¦°à¦¾à¦¥à¦®à¦¿à¦• sRGB বà§à¦¯à¦¬à¦¹à¦¾à¦° করà§à¦¨"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "ফাইল"
diff --git a/editor/translations/br.po b/editor/translations/br.po
index 7600dd4eb1..29f9cd2d79 100644
--- a/editor/translations/br.po
+++ b/editor/translations/br.po
@@ -3512,6 +3512,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3902,6 +3907,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 141f2cd58f..ca28ea5eaf 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -3714,6 +3714,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "Estat: No s'ha pogut importar. Corregiu el fitxer i torneu a importar."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "No es pot moure/reanomenar l'arrel dels recursos."
@@ -4121,6 +4126,10 @@ msgid "Reset to Defaults"
msgstr "Carrega Valors predeterminats"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fitxers"
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 2c21fc0e63..17e44a4863 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -19,17 +19,18 @@
# Emil Jiří Tywoniak <emil.tywoniak@gmail.com>, 2020, 2021.
# Filip Vincůrek <vincurek.f@gmail.com>, 2020.
# Ondrej Pavelka <ondrej.pavelka@outlook.com>, 2020.
-# Zbyněk <zbynek.fiala@gmail.com>, 2020.
+# Zbyněk <zbynek.fiala@gmail.com>, 2020, 2021.
# Daniel Kříž <Daniel.kriz@protonmail.com>, 2020.
# VladimirBlazek <vblazek042@gmail.com>, 2020.
# kubajz22 <til.jakubesko@seznam.cz>, 2020.
# Václav Blažej <vaclavblazej@seznam.cz>, 2020, 2021.
+# ProfJack <profjackcz@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-08 15:33+0000\n"
-"Last-Translator: Václav Blažej <vaclavblazej@seznam.cz>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: ProfJack <profjackcz@gmail.com>\n"
"Language-Team: Czech <https://hosted.weblate.org/projects/godot-engine/godot/"
"cs/>\n"
"Language: cs\n"
@@ -37,7 +38,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -354,7 +355,7 @@ msgstr "Změnit režim interpolace animace"
#: editor/animation_track_editor.cpp
msgid "Change Animation Loop Mode"
-msgstr "ZmÄ›nit režim smyÄky animace"
+msgstr "ZmÄ›nit mód smyÄky animace"
#: editor/animation_track_editor.cpp
msgid "Remove Anim Track"
@@ -3674,6 +3675,12 @@ msgstr ""
"znovu ruÄnÄ›."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Importování tohoto souboru bylo zakázáno, takže jej nelze otevřít pro úpravy."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Nelze přesunout/přejmenovat kořen zdrojů."
@@ -4062,19 +4069,20 @@ msgid "Saving..."
msgstr "Ukládání..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Režim výběru"
+msgstr "Vybrat Importér"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Import"
+msgstr "Importér:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "NaÄíst výchozí"
+msgstr "Obnovit výchozí"
+
+#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Zachovat soubor (bez importu)"
#: editor/import_dock.cpp
msgid "%d Files"
@@ -5083,11 +5091,11 @@ msgstr "Stahování tohoto assetu právě probíhá!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr "Naposledy upravené"
+msgstr "Nedávno aktualizované"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr "Naposledy neupravené"
+msgstr "Dlouho neaktualizované"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
@@ -5175,7 +5183,7 @@ msgid ""
"Can't determine a save path for lightmap images.\n"
"Save your scene and try again."
msgstr ""
-"Nelze urÄit cestu uložení pro svÄ›telnou mapu obrázku.\n"
+"Nelze urÄit cestu pro uložení obrázků svÄ›telné mapy.\n"
"Uložte scénu (obrázky se uloží do stejného adresáře) nebo vyberte cestu pro "
"uložení z vlastnosti BakedLightmap."
@@ -7340,9 +7348,8 @@ msgid "Yaw"
msgstr "Náklon"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Size"
-msgstr "Velikost: "
+msgstr "Velikost"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -10390,7 +10397,6 @@ msgid "Plugins"
msgstr "Pluginy"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Import Defaults"
msgstr "NaÄíst výchozí"
@@ -10642,9 +10648,8 @@ msgid "Instance Child Scene"
msgstr "Přidat instanci scény"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't paste root node into the same scene."
-msgstr "Nelze manipulovat s uzly z cizí scény!"
+msgstr "Nelze vložit kořenový uzel do stejné scény."
#: editor/scene_tree_dock.cpp
msgid "Paste Node(s)"
@@ -11612,7 +11617,7 @@ msgstr "Následné zpracování"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
#, fuzzy
msgid "Plotting lightmaps"
-msgstr "Vykreslení světel:"
+msgstr "Vykreslování světelných map"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -12427,11 +12432,11 @@ msgstr "Prázdný CollisionPolygon2D nemá při kolizi žádný efekt."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
-msgstr ""
+msgstr "Chybný polygon. Alespoň 3 body jsou potřeba v 'Solids' build módu."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
-msgstr ""
+msgstr "Chybný polygon. Alespoň 2 body jsou potřeba v 'Segments' build módu."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -13050,6 +13055,8 @@ msgid ""
"The sampler port is connected but not used. Consider changing the source to "
"'SamplerPort'."
msgstr ""
+"Sampler port je připojen, ale není použitý. Zvažte změnu zdroje na "
+"'SamplerPort'."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/da.po b/editor/translations/da.po
index 72b2bf0e81..7de7e428c5 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-16 10:40+0000\n"
+"PO-Revision-Date: 2021-03-20 04:18+0000\n"
"Last-Translator: snakatk <snaqii@live.dk>\n"
"Language-Team: Danish <https://hosted.weblate.org/projects/godot-engine/"
"godot/da/>\n"
@@ -406,7 +406,7 @@ msgstr "Anim Indsæt Nøgle"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Change Animation Step"
-msgstr "Ændre Animation Navn:"
+msgstr "Ændre animationsskridt"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -549,7 +549,7 @@ msgstr "Grupper spor efter node eller vis dem som almindelig liste."
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Snap:"
-msgstr "Trin: "
+msgstr "Trin:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -595,8 +595,9 @@ msgid "Duplicate Selection"
msgstr "Duplikér Valgte"
#: editor/animation_track_editor.cpp
+#, fuzzy
msgid "Duplicate Transposed"
-msgstr "Duplicate transposed"
+msgstr "Duplikér Transposed"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -673,7 +674,7 @@ msgstr "Skalaforhold:"
#: editor/animation_track_editor.cpp
#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "Vælg spor til kopiering:"
+msgstr "Vælg spor til kopiering"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -690,9 +691,8 @@ msgid "Select All/None"
msgstr "Vælg Node"
#: editor/animation_track_editor_plugins.cpp
-#, fuzzy
msgid "Add Audio Track Clip"
-msgstr "Lydklip:"
+msgstr "Tilføj lydspor klip"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
@@ -798,7 +798,7 @@ msgstr "Metode i target Node skal angives!"
#: editor/connections_dialog.cpp
#, fuzzy
msgid "Method name must be a valid identifier."
-msgstr "Navnet er ikke et gyldigt id:"
+msgstr "Metodenavnet er ikke et gyldigt id."
#: editor/connections_dialog.cpp
#, fuzzy
@@ -856,7 +856,7 @@ msgstr "Ekstra Call Argumenter:"
#: editor/connections_dialog.cpp
#, fuzzy
msgid "Receiver Method:"
-msgstr "Vælg Method"
+msgstr "Modtager Metode:"
#: editor/connections_dialog.cpp
#, fuzzy
@@ -936,9 +936,8 @@ msgid "Connect a Signal to a Method"
msgstr "Forbind Signal: "
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Edit Connection:"
-msgstr "Redigere Forbindelse: "
+msgstr "Redigér Forbindelse:"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from the \"%s\" signal?"
@@ -1082,14 +1081,15 @@ msgid "Owners Of:"
msgstr "Ejere af:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Fjern de valgte filer fra projektet? (ej fortrydes)"
+msgstr ""
+"Fjern de valgte filer fra projektet? (ej fortrydes)\n"
+"Du kan finde de fjernede filer i systemets skraldespand for at genoprette "
+"dem."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1097,7 +1097,9 @@ msgid ""
"You can find the removed files in the system trash to restore them."
msgstr ""
"De filer der fjernes er nødvendige for, at andre ressourcer kan fungere.\n"
-"Fjern dem alligevel? (ej fortrydes)"
+"Fjern dem alligevel? (ej fortrydes)\n"
+"Du kan finde de fjernede filer i systemets skraldespand for at genoprette "
+"dem."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1129,7 +1131,7 @@ msgstr "Fejl ved indlæsning!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "Slette %d styk(s) permanent? (ej fortryd)"
+msgstr "Slet %d styk(s) permanent? (ej fortrydes)"
#: editor/dependency_editor.cpp
#, fuzzy
@@ -1204,14 +1206,12 @@ msgid "Gold Sponsors"
msgstr "Guld Sponsorer"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Silver Sponsors"
-msgstr "Sølv Donorer"
+msgstr "Sølv Sponsorer"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Bronze Sponsors"
-msgstr "Bronze Donorer"
+msgstr "Bronze Sponsorer"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -1238,22 +1238,21 @@ msgid "License"
msgstr "Licens"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
-msgstr "Tredjeparts Licens"
+msgstr "Tredjepartslicenser"
#: editor/editor_about.cpp
-#, fuzzy
msgid ""
"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
"is an exhaustive list of all such third-party components with their "
"respective copyright statements and license terms."
msgstr ""
-"Godot Engine er afhængig af en række tredjeparts biblioteker som er gratis "
+"Godot Engine er afhængig af en række tredjepartsbiblioteker, som er gratis "
"og open source. Alle bibliotekerne er kompatible med vilkårene i MIT-"
-"licensen. Følgende er en udtømmende liste over alle sådanne tredjeparts "
-"komponenter med deres respektive ophavsretlige udsagn og licensbetingelser."
+"licensen. Følgende er en udtømmende liste over alle sådanne "
+"tredjepartskomponenter med deres respektive ophavsretlige udsagn og "
+"licensbetingelser."
#: editor/editor_about.cpp
msgid "All Components"
@@ -1268,9 +1267,8 @@ msgid "Licenses"
msgstr "Licenser"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file, not in ZIP format."
-msgstr "Fejl ved åbning af pakke fil, ikke i zip format."
+msgstr "Fejl ved åbning af pakkefil, ikke i ZIP-format."
#: editor/editor_asset_installer.cpp
#, fuzzy
@@ -1286,9 +1284,8 @@ msgid "The following files failed extraction from package:"
msgstr "De følgende filer kunne ikke trækkes ud af pakken:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
-msgstr "%d flere filer"
+msgstr "Og %s flere filer."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1380,7 +1377,7 @@ msgstr "Bus muligheder"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr "Duplikere"
+msgstr "Duplikér"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -1431,12 +1428,10 @@ msgid "Open Audio Bus Layout"
msgstr "Ã…ben Audio Bus Layout"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "There is no '%s' file."
msgstr "Der er ingen '%s' fil."
#: editor/editor_audio_buses.cpp editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Layout"
msgstr "Layout"
@@ -1454,9 +1449,8 @@ msgid "Add Bus"
msgstr "Tilføj Bus"
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Add a new Audio Bus to this layout."
-msgstr "Gem Audio Bus Layout Som..."
+msgstr "Tilføj en ny Audio Bus til dette layout."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1550,9 +1544,8 @@ msgid "Rearrange Autoloads"
msgstr "Flytte om på Autoloads"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Can't add autoload:"
-msgstr "Kan ikke tilføje autoload:"
+msgstr "Autoload kan ikke tilføjes:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1604,9 +1597,8 @@ msgid "[unsaved]"
msgstr "[ikke gemt]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
-msgstr "Vælg en basis mappe først"
+msgstr "Vælg en basismappe først."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1639,16 +1631,14 @@ msgid "Storing File:"
msgstr "Lagrings Fil:"
#: editor/editor_export.cpp
-#, fuzzy
msgid "No export template found at the expected path:"
-msgstr "Ingen eksporterings-skabelon fundet ved den forventede sti:"
+msgstr "Ingen eksporterings-skabelon fundet på den forventede sti:"
#: editor/editor_export.cpp
msgid "Packing"
msgstr "Pakker"
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
@@ -1657,7 +1647,6 @@ msgstr ""
"i Projektindstillingerne."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
@@ -1672,18 +1661,25 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"Målplatform kræver 'ETC' teksturkomprimering for driver fallback til GLES2.\n"
+"Aktivér 'Import Etc' i Projektindstillingerne, eller deaktivér 'Driver "
+"Fallback Aktiveret'."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
"'Import Pvrtc' in Project Settings."
msgstr ""
+"Målplatform kræver 'PVRTC' teksturkomprimering for GLES2. Aktivér 'Import "
+"Pvrtc' i Projektindstillingerne."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
+"Målplatformen kræver 'ETC2' eller 'PVRTC' teksturkomprimering for GLES3. "
+"Aktivér 'Import Etc 2' eller 'Import Pvrtc' i Projektindstillingerne."
#: editor/editor_export.cpp
msgid ""
@@ -1692,12 +1688,16 @@ msgid ""
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"Målplatform kræver 'PVRTC' teksturkomprimering for driver fallback til "
+"GLES2.\n"
+"Aktivér 'Import Pvrtc' i Projektindstillingerne, eller deaktivér 'Driver "
+"Fallback Aktiveret'."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom debug template not found."
-msgstr "Brugerdefineret debug skabelonfil ikke fundet:"
+msgstr "Brugerdefineret debug skabelonfil ikke fundet."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1711,7 +1711,7 @@ msgstr "Skabelonfil ikke fundet:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "Den indlejrede PCK kan ikke overstige 4 GiB ved 32-bit eksport."
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1797,7 +1797,7 @@ msgstr "Funktions Liste:"
#: editor/editor_feature_profile.cpp
#, fuzzy
msgid "Enabled Classes:"
-msgstr "Søg Classes"
+msgstr "Aktiverede Classes:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
@@ -2074,14 +2074,13 @@ msgid "Inherited by:"
msgstr "Arvet af:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Beskrivelse:"
+msgstr "Beskrivelse"
#: editor/editor_help.cpp
#, fuzzy
msgid "Online Tutorials"
-msgstr "Online Undervisning:"
+msgstr "Online Vejledninger"
#: editor/editor_help.cpp
msgid "Properties"
@@ -2092,9 +2091,8 @@ msgid "override:"
msgstr ""
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "Standard"
+msgstr "standardindstilling:"
#: editor/editor_help.cpp
msgid "Methods"
@@ -2117,9 +2115,8 @@ msgid "Property Descriptions"
msgstr "Egenskab beskrivelser"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "Værdi:"
+msgstr "(værdi)"
#: editor/editor_help.cpp
msgid ""
@@ -2880,7 +2877,7 @@ msgstr "Projekt Indstillinger"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
#, fuzzy
msgid "Version Control"
-msgstr "Version:"
+msgstr "Versionskontrol"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
@@ -3773,14 +3770,17 @@ msgid "Favorites"
msgstr "Favoritter"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
-"\n"
"Status: Import af filen fejlede. Venligst reparer filen og genimporter "
"manuelt."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Kan ikke flytte/omdøbe resourcen root."
@@ -4219,6 +4219,10 @@ msgid "Reset to Defaults"
msgstr "Indlæs Default"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -9994,9 +9998,8 @@ msgid "Export All"
msgstr "Eksporter"
#: editor/project_export.cpp editor/project_manager.cpp
-#, fuzzy
msgid "ZIP File"
-msgstr " Filer"
+msgstr "ZIP-Fil"
#: editor/project_export.cpp
msgid "Godot Game Pack"
diff --git a/editor/translations/de.po b/editor/translations/de.po
index ffd8a8874e..f70522a365 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -71,7 +71,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-09 04:13+0000\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
"Last-Translator: So Wieso <sowieso@dukun.de>\n"
"Language-Team: German <https://hosted.weblate.org/projects/godot-engine/"
"godot/de/>\n"
@@ -80,7 +80,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3758,6 +3758,13 @@ msgstr ""
"Status: Dateiimport fehlgeschlagen. Manuelle Reparatur und Neuimport nötig."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Für diese Datei wurde die Import-Funktion deaktiviert, sie kann folglich "
+"nicht zum Bearbeiten geöffnet werden."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Ressourcen-Wurzel kann nicht verschoben oder umbenannt werden."
@@ -4160,6 +4167,10 @@ msgid "Reset to Defaults"
msgstr "Auf Standardwerte zurücksetzen"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Datei behalten (kein Import)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Dateien"
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index d11d4f42ac..2c0294e8b8 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -3490,6 +3490,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3880,6 +3885,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 8cd3397399..2aa33c39aa 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -11,12 +11,13 @@
# KostasMSC <kargyris@athtech.gr>, 2020.
# lawfulRobot <czavantias@gmail.com>, 2020.
# Michalis <michalisntovas@yahoo.gr>, 2021.
+# leriaz <leriaz@live.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-03 15:50+0000\n"
-"Last-Translator: Michalis <michalisntovas@yahoo.gr>\n"
+"PO-Revision-Date: 2021-03-29 21:57+0000\n"
+"Last-Translator: leriaz <leriaz@live.com>\n"
"Language-Team: Greek <https://hosted.weblate.org/projects/godot-engine/godot/"
"el/>\n"
"Language: el\n"
@@ -24,7 +25,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.1-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -825,7 +826,7 @@ msgstr "Μέθοδος Δέκτη:"
#: editor/connections_dialog.cpp
msgid "Advanced"
-msgstr "Για ΠÏοχωÏημένους"
+msgstr "Για Ï€ÏοχωÏημένους"
#: editor/connections_dialog.cpp
msgid "Deferred"
@@ -1041,11 +1042,13 @@ msgid "Owners Of:"
msgstr "Ιδιοκτήτες του:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "ΑφαίÏεση επιλεγμένων αÏχείων από το έÏγο; (Αδυναμία αναίÏεσης)"
+msgstr ""
+"ΑφαίÏεση επιλεγμένων αÏχείων από το έÏγο; (Αδυναμία αναίÏεσης)\n"
+"ΜποÏείτε να βÏείτε τα διεγÏαμμένα αÏχεία στον κάδο ανακÏκλωσης για να τα "
+"επαναφέÏετε."
#: editor/dependency_editor.cpp
#, fuzzy
@@ -3700,6 +3703,11 @@ msgstr ""
"επανεισάγετε το χειÏοκίνητα."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Δεν ήταν δυνατή η μετακίνηση/μετονομασία του πηγαίου καταλόγου."
@@ -4104,6 +4112,10 @@ msgid "Reset to Defaults"
msgstr "ΧÏήση Ï€Ïοεπιλεγμένου sRGB"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d αÏχεία"
diff --git a/editor/translations/eo.po b/editor/translations/eo.po
index 46e3a6b28d..3cb57c4089 100644
--- a/editor/translations/eo.po
+++ b/editor/translations/eo.po
@@ -3593,6 +3593,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3994,6 +3999,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Trovi en dosierojn"
diff --git a/editor/translations/es.po b/editor/translations/es.po
index 4f8441fbfc..7fc20c2f14 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -63,7 +63,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
"Last-Translator: Javier Ocampos <xavier.ocampos@gmail.com>\n"
"Language-Team: Spanish <https://hosted.weblate.org/projects/godot-engine/"
"godot/es/>\n"
@@ -72,7 +72,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -211,7 +211,7 @@ msgstr "Cambiar Transformación de la Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Change Keyframe Value"
-msgstr "Cambiar Valor de la Clave de Animación"
+msgstr "Cambiar Valor de Fotogramas Clave de Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Change Call"
@@ -219,7 +219,7 @@ msgstr "Cambiar Llamada de Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
-msgstr "Cambiar Tiempo de Múltiples Keyframes de Animación"
+msgstr "Cambiar Tiempo de Múltiples Fotogramas Clave de Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Transition"
@@ -231,7 +231,7 @@ msgstr "Cambiar Múltiples Transforms de Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Value"
-msgstr "Cambiar Valor de Múltiples Keyframes de Animación"
+msgstr "Cambiar Valor de Múltiples Fotogramas Clave de Animación"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Call"
@@ -272,7 +272,7 @@ msgstr "Pista de Reproducción de Animación"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
-msgstr "Duración de la animación (frames)"
+msgstr "Duración de la animación (fotogramas)"
#: editor/animation_track_editor.cpp
msgid "Animation length (seconds)"
@@ -3314,7 +3314,7 @@ msgstr "Medida:"
#: editor/editor_profiler.cpp
msgid "Frame Time (sec)"
-msgstr "Duración de Frame (seg)"
+msgstr "Duración de Fotogramas (seg)"
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
@@ -3322,11 +3322,11 @@ msgstr "Tiempo Promedio (seg)"
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr "Frame %"
+msgstr "Fotograma %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr "Frames de Física %"
+msgstr "Fotogramas de Física %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
@@ -3338,7 +3338,7 @@ msgstr "Propio"
#: editor/editor_profiler.cpp
msgid "Frame #:"
-msgstr "Frame #:"
+msgstr "Fotograma #:"
#: editor/editor_profiler.cpp
msgid "Time"
@@ -3756,6 +3756,13 @@ msgstr ""
"reimpórtalo manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Se ha desactivado la importación de este archivo, por lo que no se puede "
+"abrir para editarlo."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "No se puede mover/renombrar la raíz de los recursos."
@@ -4157,6 +4164,10 @@ msgid "Reset to Defaults"
msgstr "Restablecer Valores por Defecto"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Mantener Archivo (No Importar)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d archivos"
@@ -5796,7 +5807,7 @@ msgstr "Centrar Selección"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr "Encuadrar Selección"
+msgstr "Seleccionar Fotogramas"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -7945,15 +7956,15 @@ msgstr "Configuración:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "No Frames Selected"
-msgstr "No hay Frames Seleccionados"
+msgstr "No hay Fotogramas Seleccionados"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr "Añadir %d Frame(s)"
+msgstr "Añadir %d Fotograma(s)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr "Añadir Frame"
+msgstr "Añadir Fotograma"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Unable to load images"
@@ -7961,7 +7972,7 @@ msgstr "No se pueden cargar las imágenes"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
-msgstr "ERROR: ¡No se pudo cargar el recurso de frames!"
+msgstr "ERROR: ¡No se pudo cargar el recurso de fotogramas!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Resource clipboard is empty or not a texture!"
@@ -7969,7 +7980,7 @@ msgstr "¡El portapapeles de recursos esta vacío o no es una textura!"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Paste Frame"
-msgstr "Pegar Frame"
+msgstr "Pegar Fotograma"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
@@ -7985,7 +7996,7 @@ msgstr "(vacío)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move Frame"
-msgstr "Mover Frame"
+msgstr "Mover Fotograma"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Animations:"
@@ -8005,7 +8016,7 @@ msgstr "Loop"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Animation Frames:"
-msgstr "Frames de Animación:"
+msgstr "Fotogramas de Animación:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add a Texture from File"
@@ -8013,7 +8024,7 @@ msgstr "Añadir Textura desde Archivo"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
-msgstr "Añadir Frames desde un Sprite Sheet"
+msgstr "Añadir Fotogramas desde un Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
@@ -8033,7 +8044,7 @@ msgstr "Mover (Después)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select Frames"
-msgstr "Seleccionar Frames"
+msgstr "Seleccionar Fotogramas"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
@@ -8045,11 +8056,11 @@ msgstr "Vertical:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select/Clear All Frames"
-msgstr "Seleccionar/Limpiar Todos los Frames"
+msgstr "Seleccionar/Limpiar Todos los Fotogramas"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Create Frames from Sprite Sheet"
-msgstr "Crear Frames a partir de Sprite Sheet"
+msgstr "Crear Fotogramas a partir de un Sprite Sheet"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
@@ -11324,7 +11335,7 @@ msgstr "Inspeccionar Instancia Siguiente"
#: editor/script_editor_debugger.cpp
msgid "Stack Frames"
-msgstr "Frames del Stack"
+msgstr "Fotogramas Apilados"
#: editor/script_editor_debugger.cpp
msgid "Profiler"
@@ -12561,7 +12572,7 @@ msgid ""
"order for AnimatedSprite to display frames."
msgstr ""
"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
-"\" para que AnimatedSprite pueda mostrar frames."
+"\" para que AnimatedSprite pueda mostrar los fotogramas."
#: scene/2d/canvas_modulate.cpp
msgid ""
@@ -13046,7 +13057,7 @@ msgid ""
"order for AnimatedSprite3D to display frames."
msgstr ""
"Se debe crear o establecer un recurso SpriteFrames en la propiedad \"Frames"
-"\" para que AnimatedSprite3D pueda mostrar frames."
+"\" para que AnimatedSprite3D pueda mostrar los fotogramas."
#: scene/3d/vehicle_body.cpp
msgid ""
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 11e55b2dfa..ef65c1d220 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-09 04:13+0000\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
"Last-Translator: Lisandro Lorea <lisandrolorea@gmail.com>\n"
"Language-Team: Spanish (Argentina) <https://hosted.weblate.org/projects/"
"godot-engine/godot/es_AR/>\n"
@@ -30,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3708,6 +3708,13 @@ msgstr ""
"reimportá manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Se ha desactivado la importación de este archivo, por lo que no se puede "
+"abrir para editarlo."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "No se puede mover/renombrar la raiz de recursos."
@@ -4108,6 +4115,10 @@ msgid "Reset to Defaults"
msgstr "Restablecer Valores Por Defecto"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Mantener Archivo (No Importar)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Archivos"
diff --git a/editor/translations/et.po b/editor/translations/et.po
index ba7272db84..d1f68d4402 100644
--- a/editor/translations/et.po
+++ b/editor/translations/et.po
@@ -3545,6 +3545,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3938,6 +3943,10 @@ msgid "Reset to Defaults"
msgstr "Laadi vaikimisi"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/eu.po b/editor/translations/eu.po
index 95e87167e5..0fda17a8d5 100644
--- a/editor/translations/eu.po
+++ b/editor/translations/eu.po
@@ -3507,6 +3507,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3901,6 +3906,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d fitxategi"
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index 1ac27a6fd6..4b2ad80f34 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -3585,6 +3585,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4017,6 +4022,10 @@ msgid "Reset to Defaults"
msgstr "بارگیری پیش ÙØ±Ø¶"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr " پوشه ها"
diff --git a/editor/translations/fi.po b/editor/translations/fi.po
index 4d690bd29d..c60ab24d1d 100644
--- a/editor/translations/fi.po
+++ b/editor/translations/fi.po
@@ -11,12 +11,13 @@
# Tapani Niemi <tapani.niemi@kapsi.fi>, 2018, 2019, 2020, 2021.
# Tuomas Lähteenmäki <lahtis@gmail.com>, 2019.
# Matti Niskanen <matti.t.niskanen@gmail.com>, 2020.
+# Severi Vidnäs <severi.vidnas@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
-"Last-Translator: Tapani Niemi <tapani.niemi@kapsi.fi>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Severi Vidnäs <severi.vidnas@gmail.com>\n"
"Language-Team: Finnish <https://hosted.weblate.org/projects/godot-engine/"
"godot/fi/>\n"
"Language: fi\n"
@@ -24,7 +25,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -1760,7 +1761,7 @@ msgstr "Uusi"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr "Tuonti"
+msgstr "Tuo"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
@@ -3666,6 +3667,13 @@ msgstr ""
"Tila: Tuonti epäonnistui. Ole hyvä, korjaa tiedosto ja tuo se uudelleen."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Tuonti on poistettu käytöstä tälle tiedostolle, joten sitä ei voi avata "
+"muokkausta varten."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Ei voitu siirtää/nimetä uudelleen resurssien päätasoa."
@@ -4068,6 +4076,10 @@ msgid "Reset to Defaults"
msgstr "Palauta oletusarvoihin"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Pidä tiedosto (ei tuontia)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d tiedostoa"
diff --git a/editor/translations/fil.po b/editor/translations/fil.po
index e9c24cf0f2..ef48d8b143 100644
--- a/editor/translations/fil.po
+++ b/editor/translations/fil.po
@@ -3507,6 +3507,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3897,6 +3902,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 7b9d411e6d..3e6dc5fb35 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -82,7 +82,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-01-22 10:21+0000\n"
+"PO-Revision-Date: 2021-03-21 12:25+0000\n"
"Last-Translator: Pierre Caye <pierrecaye@laposte.net>\n"
"Language-Team: French <https://hosted.weblate.org/projects/godot-engine/"
"godot/fr/>\n"
@@ -91,7 +91,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.5-dev\n"
+"X-Generator: Weblate 4.5.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3779,6 +3779,13 @@ msgstr ""
"le réimporter manuellement."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"L'importation a été désactivée pour ce fichier, il ne peut donc pas être "
+"ouvert dans l'éditeur."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Impossible de déplacer / renommer les ressources root."
@@ -4180,6 +4187,10 @@ msgid "Reset to Defaults"
msgstr "Réinitialiser"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Conserver le fichier (non importé)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d fichiers"
@@ -12648,10 +12659,14 @@ msgstr "Un CollisionPolygon2D vide n'a pas d'effet sur les collisions."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
msgstr ""
+"Polygone non valide. Il doit avoir au moins trois points en mode de "
+"construction 'Solide'."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
msgstr ""
+"Polygone non valide. Il doit y avoir au moins 2 points en mode de "
+"construction 'Segments'."
#: scene/2d/collision_shape_2d.cpp
msgid ""
diff --git a/editor/translations/ga.po b/editor/translations/ga.po
index 4e537d9882..3bedee8314 100644
--- a/editor/translations/ga.po
+++ b/editor/translations/ga.po
@@ -3500,6 +3500,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3892,6 +3897,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Amharc ar Chomhaid"
diff --git a/editor/translations/gl.po b/editor/translations/gl.po
index 5559444f0c..519fc06c8d 100644
--- a/editor/translations/gl.po
+++ b/editor/translations/gl.po
@@ -3657,6 +3657,11 @@ msgstr ""
"impórtao manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4060,6 +4065,10 @@ msgid "Reset to Defaults"
msgstr "Cargar Valores por Defecto"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Arquivos"
diff --git a/editor/translations/he.po b/editor/translations/he.po
index ab97d97c0a..30a3212661 100644
--- a/editor/translations/he.po
+++ b/editor/translations/he.po
@@ -3646,6 +3646,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "מצב: ×™×™×‘×•× ×”×§×•×‘×¥ נכשל. × × ×œ×ª×§×Ÿ ×ת הקובץ ×•×œ×™×™×‘× ×ž×—×“×© ידנית."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "×œ× × ×™×ª×Ÿ להעביר/לשנות ×©× ×œ×ž×§×•×¨ של מש×בי×."
@@ -4071,6 +4076,10 @@ msgid "Reset to Defaults"
msgstr "טעינת בררת המחדל"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d קבצי×"
diff --git a/editor/translations/hi.po b/editor/translations/hi.po
index 034451542b..8425dd284f 100644
--- a/editor/translations/hi.po
+++ b/editor/translations/hi.po
@@ -3646,6 +3646,11 @@ msgstr ""
"सà¥à¤¥à¤¿à¤¤à¤¿: फाइल का आयात विफल रहा। कृपया फाइल को ठीक करें और मैनà¥à¤¯à¥à¤…ल रूप से पà¥à¤¨à¤°à¥à¤†à¤¯à¤¾à¤¤ करें।"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "संसाधनों की जड़ को सà¥à¤¥à¤¾à¤¨à¤¾à¤‚तरित/नाम नहीं दे सकते ।"
@@ -4051,6 +4056,10 @@ msgid "Reset to Defaults"
msgstr "पà¥à¤°à¤¾à¤¯à¤¿à¤• लोड कीजिये"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/hr.po b/editor/translations/hr.po
index 047363db63..861f3e6c1c 100644
--- a/editor/translations/hr.po
+++ b/editor/translations/hr.po
@@ -3512,6 +3512,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3909,6 +3914,10 @@ msgid "Reset to Defaults"
msgstr "UÄitaj Zadano"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fajlovi"
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 3966959f91..448c79c7f1 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -15,12 +15,13 @@
# thekeymethod <csokan.andras87@protonmail.ch>, 2020.
# Czmorek Dávid <czmdav.soft@gmail.com>, 2020.
# Újvári Marcell <mmarci72@gmail.com>, 2021.
+# Gergő Pistai <gergopistai@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-01-22 10:21+0000\n"
-"Last-Translator: Újvári Marcell <mmarci72@gmail.com>\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
+"Last-Translator: Gergő Pistai <gergopistai@gmail.com>\n"
"Language-Team: Hungarian <https://hosted.weblate.org/projects/godot-engine/"
"godot/hu/>\n"
"Language: hu\n"
@@ -28,7 +29,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -673,15 +674,15 @@ msgstr "Összes/semmi kijelölése"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
-msgstr ""
+msgstr "Hangsávklip hozzáadása"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr ""
+msgstr "Hangsáv klip eltolt kezdési idejének módosítása"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
-msgstr ""
+msgstr "Hangsáv klip eltolt befejezési idejének módosítása"
#: editor/array_property_edit.cpp
msgid "Resize Array"
@@ -732,9 +733,8 @@ msgid "Replace All"
msgstr "Összes cseréje"
#: editor/code_editor.cpp
-#, fuzzy
msgid "Selection Only"
-msgstr "Csak a kijelölés"
+msgstr "Csak kijelölés"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
@@ -771,7 +771,7 @@ msgstr "Sor és oszlopszámok."
#: editor/connections_dialog.cpp
msgid "Method in target node must be specified."
-msgstr ""
+msgstr "Nevezze el a metódust a cél node-ban."
#: editor/connections_dialog.cpp
msgid "Method name must be a valid identifier."
@@ -915,9 +915,8 @@ msgid "Signals"
msgstr "Jelzések"
#: editor/connections_dialog.cpp
-#, fuzzy
msgid "Filter signals"
-msgstr "Csempék szűrése"
+msgstr "Jelek szűrése"
#: editor/connections_dialog.cpp
msgid "Are you sure you want to remove all connections from this signal?"
@@ -1045,14 +1044,14 @@ msgid "Owners Of:"
msgstr "Tulajdonosai:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Eltávolítja a kiválasztott fájlokat a projektből? (nem visszavonható)"
+msgstr ""
+"Eltávolítja a kiválasztott fájlokat a projektből? (nem visszavonható)\n"
+"Az eltávolított fájlokat a lomtárban találja, ha visszaállítaná őket."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1060,7 +1059,8 @@ msgid ""
"You can find the removed files in the system trash to restore them."
msgstr ""
"Az eltávolítandó fájlokat szükségelik más források a működésükhöz.\n"
-"Eltávolítja őket ennek ellenére? (nem visszavonható)"
+"Eltávolítja őket ennek ellenére? (nem visszavonható)\n"
+"Az eltávolított fájlokat a lomtárban találja, ha visszaállítaná őket."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1202,7 +1202,6 @@ msgid "Third-party Licenses"
msgstr "Harmadik féltől származó licencek"
#: editor/editor_about.cpp
-#, fuzzy
msgid ""
"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
@@ -1591,12 +1590,16 @@ msgid ""
"Target platform requires 'ETC' texture compression for GLES2. Enable 'Import "
"Etc' in Project Settings."
msgstr ""
+"A célplatformnak 'ETC' textúra tömörítésre van szüksége GLES2-höz. "
+"Engedélyezze az 'Import Etc' beállítást a Projekt Beállításokban."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' texture compression for GLES3. Enable "
"'Import Etc 2' in Project Settings."
msgstr ""
+"A célplatformnak 'ETC2' textúra tömörítésre van szüksége GLES3-höz. "
+"Engedélyezze az 'Import Etc 2' beállítást a Projekt Beállításokban."
#: editor/editor_export.cpp
msgid ""
@@ -1605,18 +1608,27 @@ msgid ""
"Enable 'Import Etc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"A célplatformnak 'ETC' textúra tömörítésre van szüksége a tartalék driverhez "
+"GLES2-höz.\n"
+"Engedélyezze az 'Import Etc' beállítást a Projekt Beállításokban, vagy "
+"kapcsolja ki a 'Driver Fallback Enabled' beállítást."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
"'Import Pvrtc' in Project Settings."
msgstr ""
+"A célplatformnak 'PVRTC' textúra tömörítésre van szüksége GLES2-höz. "
+"Engedélyezze az 'Import Pvrtc' beállítást a Projekt Beállításokban."
#: editor/editor_export.cpp
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
+"A célplatformnak 'ETC2' vagy 'PVRTC' textúra tömörítésre van szüksége GLES3-"
+"hoz. Engedélyezze az 'Import Etc 2' vagy 'Import Pvrtc' beállítást a Projekt "
+"Beállításokban."
#: editor/editor_export.cpp
msgid ""
@@ -1625,6 +1637,9 @@ msgid ""
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
+"A célplatformnak 'PVRTC' textúra tömörítésre van szüksége GLES2-höz.\n"
+"Engedélyezze az 'Import Pvrtc' beállítást a Projekt Beállításokban, vagy "
+"kapcsolja ki a 'Driver Fallback Enabled' beállítást."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1644,7 +1659,7 @@ msgstr "Sablon fájl nem található:"
#: editor/editor_export.cpp
msgid "On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."
-msgstr ""
+msgstr "32-bites exportokon a beágyazott PCK nem lehet nagyobb mint 4 GiB."
#: editor/editor_feature_profile.cpp
msgid "3D Editor"
@@ -1664,12 +1679,11 @@ msgstr "Jelenetfa szerkesztése"
#: editor/editor_feature_profile.cpp
msgid "Node Dock"
-msgstr ""
+msgstr "Node dokk"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem Dock"
-msgstr "Fájlrendszer"
+msgstr "Fájlrendszer dokk"
#: editor/editor_feature_profile.cpp
msgid "Import Dock"
@@ -1810,7 +1824,7 @@ msgstr "Válassza ezt a mappát"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr "Útvonal másolása"
+msgstr "Útvonal Másolása"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Open in File Manager"
@@ -1879,11 +1893,11 @@ msgstr "Ugrás Fel"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr ""
+msgstr "Rejtett fálok megjelenítése/elrejtése"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr ""
+msgstr "Kedvencek Mutatása/Elrejtése"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
@@ -1891,7 +1905,7 @@ msgstr "Mód váltása"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
-msgstr ""
+msgstr "Elérési Út Fókuszálása"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
@@ -1926,7 +1940,6 @@ msgid "Toggle the visibility of hidden files."
msgstr "A rejtett fájlok láthatóságának ki- és bekapcsolása."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
-#, fuzzy
msgid "View items as a grid of thumbnails."
msgstr "Az elemek megtekintése bélyegkép-rácsként."
@@ -2117,9 +2130,8 @@ msgid "Property:"
msgstr "Tulajdonság:"
#: editor/editor_inspector.cpp
-#, fuzzy
msgid "Set"
-msgstr "Beállítás"
+msgstr "Beállít"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
@@ -2272,6 +2284,9 @@ msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
+"Ezt a jelenetet nem lehet elmenteni, mivel ciklikus peldányosítást "
+"tartalmaz.\n"
+"Kérem oldja meg a problémát, aztán próbáljon meg ismét menteni."
#: editor/editor_node.cpp
msgid ""
@@ -2306,6 +2321,9 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Hiba történt a szerkesztő elrendezésének mentése közben.\n"
+"Bizonyosodjon meg róla, hogy a szerkesztő felhasználói elérési útján "
+"engedélyezve van az írás."
#: editor/editor_node.cpp
msgid ""
@@ -2313,16 +2331,19 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Alapértelmezett szerkesztő elrendezés felülírva.\n"
+"Hogy visszaállítsa az alapértelmezett elrendezést az eredeti beállításokra, "
+"használja az Elrendezés Törlése opciót és törölje az alapértelmezett "
+"elrendezést."
#: editor/editor_node.cpp
msgid "Layout name not found!"
msgstr "Elrendezés neve nem található!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restored the Default layout to its base settings."
msgstr ""
-"Az alapértelmezett elrendezés vissza lett állítva az alap beállításokra."
+"Az alapértelmezett elrendezés vissza lett állítva az eredeti beállításokra."
#: editor/editor_node.cpp
msgid ""
@@ -2382,7 +2403,7 @@ msgstr "Nincs meghatározva Scene a futtatáshoz."
#: editor/editor_node.cpp
msgid "Save scene before running..."
-msgstr ""
+msgstr "Futtatás előtt mentse a jelenetet..."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
@@ -2390,23 +2411,23 @@ msgstr "Az alprocesszt nem lehetett elindítani!"
#: editor/editor_node.cpp editor/filesystem_dock.cpp
msgid "Open Scene"
-msgstr "Scene megnyitás"
+msgstr "Jelenet megnyitása"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr "Alap Scene megnyitás"
+msgstr "Alap Jelenet Megnyitása"
#: editor/editor_node.cpp
msgid "Quick Open..."
-msgstr "Gyors megnyitás..."
+msgstr "Gyors Megnyitás..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr "Jelenet gyors megnyitása..."
+msgstr "Jelenet Gyors Megnyitása..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr "Szkript gyors megnyitás..."
+msgstr "Szkript Gyors Megnyitás..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2422,11 +2443,11 @@ msgstr "%s módosított erőforrás mentve."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "Egy gyökér node szükséges a jelenet mentéséhez."
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr "Scene mentés másként..."
+msgstr "Scene Mentése Másként..."
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
@@ -2530,7 +2551,6 @@ msgstr ""
"megbukott."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
"Nem található szkript mező az addon pluginnak a következő helyen: 'res://"
@@ -2737,7 +2757,7 @@ msgstr "Legutóbbi Megnyitása"
#: editor/editor_node.cpp
msgid "Save Scene"
-msgstr "Scene mentés"
+msgstr "Jelenet Mentése"
#: editor/editor_node.cpp
msgid "Save All Scenes"
@@ -2763,7 +2783,7 @@ msgstr "Visszavonás"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr "Mégis"
+msgstr "Újra"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
@@ -2834,12 +2854,10 @@ msgid ""
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Small Deploy with Network Filesystem"
-msgstr "Kis Telepítés Hálózati FS-sel"
+msgstr "Kis Telepítés Hálózati Fájlrendszerrel"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, using one-click deploy for Android will only "
"export an executable without the project data.\n"
@@ -2860,52 +2878,46 @@ msgid "Visible Collision Shapes"
msgstr "Látható Ütközési Alakzatok"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, collision shapes and raycast nodes (for 2D and "
"3D) will be visible in the running project."
msgstr ""
-"Az ütközési alakzatok és a fénysugárkövető Node-ok (mind 2D-hez és 3D-hez) "
-"láthatóak lesznek a játék futásakor, ha ez az opció be van kapcsolva."
+"Ha ez az opció be van kapcsolva, az ütközési alakzatok és a sugárkövető Node-"
+"ok (mind 2D-hez és 3D-hez) láthatóak lesznek a játék futásakor."
#: editor/editor_node.cpp
msgid "Visible Navigation"
msgstr "Látható Navigáció"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
-"A navigációs hálók és sokszögek láthatóak lesznek a játék futásakor, ha ez "
-"az opció be van kapcsolva."
+"Ha ez az opció be van kapcsolva, a navigációs hálók és sokszögek láthatóak "
+"lesznek a játék futásakor."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Synchronize Scene Changes"
-msgstr "Jelenet változtatások szinkronizálása"
+msgstr "Jelenet Változások Szinkronizálása"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any changes made to the scene in the editor "
"will be replicated in the running project.\n"
"When used remotely on a device, this is more efficient when the network "
"filesystem option is enabled."
msgstr ""
-"Ha ez a beállítás be van kapcsolva, bármilyen változtatás a jeleneten a "
-"szerkesztőben le lesz másolva a futó játékba.\n"
-"Ha egy távoli eszközön használja, sokkal hatékonyabb a hálózati "
-"fájlrendszerrel együtt."
+"Ha ez a beállítás be van kapcsolva, bármely a jeleneten való változtatás a "
+"szerkesztből, a futó projekre is alkalmazva lesz.\n"
+"Távoli eszköz használatakor hatékonyabb, ha a hálózati fájlrendszer opció "
+"engedélyezve van."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Synchronize Script Changes"
msgstr "Szkript Változtatások Szinkronizálása"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"When this option is enabled, any script that is saved will be reloaded in "
"the running project.\n"
@@ -2914,8 +2926,8 @@ msgid ""
msgstr ""
"Ha ez a beállítás be van kapcsolva, bármilyen szkript, amit elment, újra "
"betöltődik a futó játékba.\n"
-"Ha egy távoli eszközön használja, sokkal hatékonyabb a hálózati "
-"fájlrendszerrel együtt."
+"Távoli eszköz használatakor hatékonyabb, ha a hálózati fájlrendszer opció "
+"engedélyezve van."
#: editor/editor_node.cpp editor/script_create_dialog.cpp
msgid "Editor"
@@ -2950,9 +2962,8 @@ msgid "Open Editor Data/Settings Folder"
msgstr "Szerkesztő adatok/beállítások mappa megnyitása"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Editor Data Folder"
-msgstr "A szerkesztő adatmappájának megnyitása"
+msgstr "Szerkesztő Adatmappájának Megnyitása"
#: editor/editor_node.cpp
msgid "Open Editor Settings Folder"
@@ -2984,9 +2995,8 @@ msgid "Report a Bug"
msgstr "Hiba bejelentése"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Send Docs Feedback"
-msgstr "Visszajelzés a Dokumentumokról"
+msgstr "Visszajelzé Küldése s A Dokumentumokról"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3022,7 +3032,7 @@ msgstr "Szerkesztett Scene futtatása."
#: editor/editor_node.cpp
msgid "Play Scene"
-msgstr "Scene futtatás"
+msgstr "Scene Futtatása"
#: editor/editor_node.cpp
msgid "Play custom scene"
@@ -3081,6 +3091,7 @@ msgstr "Nincs Mentés"
#: editor/editor_node.cpp
msgid "Android build template is missing, please install relevant templates."
msgstr ""
+"Hiányzó Android építési-sablon, kérem telepítse az ide tartozó sablonokat."
#: editor/editor_node.cpp
msgid "Manage Templates"
@@ -3104,6 +3115,10 @@ msgid ""
"Remove the \"res://android/build\" directory manually before attempting this "
"operation again."
msgstr ""
+"Az Android építési-sablon már telepítve van a projektbe és nem lesz "
+"felülírva.\n"
+"Távolítsa el a(z) \"res://android/build\" könyvtárat manuálisan, mivelőtt "
+"újra megkísérelné a műveletet."
#: editor/editor_node.cpp
msgid "Import Templates From ZIP File"
@@ -3126,13 +3141,12 @@ msgid "Open & Run a Script"
msgstr "Szkriptet Megnyit és Futtat"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?"
msgstr ""
"A alábbi fájlok újabbak a lemezen.\n"
-"Mit szeretne lépni?:"
+"Mit szeretne tenni?"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -3154,7 +3168,7 @@ msgstr "Betöltési Hibák"
#: editor/editor_node.cpp editor/plugins/tile_map_editor_plugin.cpp
msgid "Select"
-msgstr "Kiválaszt"
+msgstr "Kiválasztás"
#: editor/editor_node.cpp
msgid "Open 2D Editor"
@@ -3385,14 +3399,13 @@ msgid "Add Key/Value Pair"
msgstr "Kulcs/érték pár hozzáadása"
#: editor/editor_run_native.cpp
-#, fuzzy
msgid ""
"No runnable export preset found for this platform.\n"
"Please add a runnable preset in the Export menu or define an existing preset "
"as runnable."
msgstr ""
"Nem található futtatható exportállomány ehhez a platformhoz.\n"
-"Adjon hozzá egy futtatható exportállományt az export menüben."
+"Kérem adjon hozzá egy futtatható exportállományt az export menüben."
#: editor/editor_run_script.cpp
msgid "Write your logic in the _run() method."
@@ -3553,12 +3566,11 @@ msgid "Cannot remove temporary file:"
msgstr "Az ideiglenes fájl nem távolítható el:"
#: editor/export_template_manager.cpp
-#, fuzzy
msgid ""
"Templates installation failed.\n"
"The problematic templates archives can be found at '%s'."
msgstr ""
-"A sablonok telepítése nem sikerült.\n"
+"A sablonok telepítése sikertelen.\n"
"A problémás sablonok archívuma megtalálható a következő helyen: '%s'."
#: editor/export_template_manager.cpp
@@ -3663,6 +3675,11 @@ msgstr ""
"újra manuálisan."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Az erőforrások gyökere nem mozgatható vagy átnevezhető."
@@ -3787,9 +3804,8 @@ msgid "Duplicate..."
msgstr "Megkettőzés..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Move to Trash"
-msgstr "AutoLoad Ãthelyezése"
+msgstr "Lomtárba Helyezés"
#: editor/filesystem_dock.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Rename..."
@@ -3898,19 +3914,16 @@ msgid "Searching..."
msgstr "Keresés…"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d match in %d file."
-msgstr "%d egyezés."
+msgstr "%d egyezés %d fájlban."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d matches in %d file."
-msgstr "%d egyezés."
+msgstr "%d egyezés %d fájlban."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d matches in %d files."
-msgstr "%d egyezés."
+msgstr "%d egyezések %d fájlban."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4048,19 +4061,20 @@ msgid "Saving..."
msgstr "Mentés..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Kiválasztó Mód"
+msgstr "Importer Kiválasztása"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Importálás"
+msgstr "Importáló:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "Alapértelmezett Betöltése"
+msgstr "Visszaállítás Alapértelmezettre"
+
+#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
#: editor/import_dock.cpp
msgid "%d Files"
@@ -4096,7 +4110,6 @@ msgstr ""
"Az importált fájl típusának módosításához a szerkesztőt újra kell indítani."
#: editor/import_dock.cpp
-#, fuzzy
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
@@ -4381,7 +4394,6 @@ msgid "BlendSpace2D does not belong to an AnimationTree node."
msgstr ""
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "No triangles exist, so no blending can take place."
msgstr "Nincsenek háromszögek, így nem történhet keverés."
@@ -4811,7 +4823,7 @@ msgstr "Lejátszási mód:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "AnimationTree"
-msgstr ""
+msgstr "AnimációFa"
#: editor/plugins/animation_tree_player_editor_plugin.cpp
msgid "New name:"
@@ -5020,9 +5032,8 @@ msgid "Got:"
msgstr "Kapott:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "sha256 hash ellenőrzés megbukott"
+msgstr "SHA-256 hash ellenőrzés megbukot"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5200,7 +5211,7 @@ msgstr "Fény Besütése"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "Válasszon sablonfájlt"
+msgstr "Válasszon fénytérkép sablonfájlt:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5272,19 +5283,17 @@ msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate %d CanvasItems"
-msgstr "CanvasItem forgatása"
+msgstr "%d CanvasItem Forgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem \"%s\" to %d degrees"
-msgstr "CanvasItem forgatása"
+msgstr "\"%s\" CanvasItem Forgatása %d fokra"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Move CanvasItem \"%s\" Anchor"
-msgstr "CanvasItem áthelyezése"
+msgstr "CanvasItem \"%s\" Horgony Mozgatása"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale Node2D \"%s\" to (%s, %s)"
@@ -5295,24 +5304,20 @@ msgid "Resize Control \"%s\" to (%d, %d)"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale %d CanvasItems"
-msgstr "CanvasItem méretezése"
+msgstr "%d CanvasItem Méretezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem \"%s\" to (%s, %s)"
-msgstr "CanvasItem méretezése"
+msgstr "\"%s\" CanvasItem Méretezése (%s, %s)-ra/re"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move %d CanvasItems"
-msgstr "CanvasItem áthelyezése"
+msgstr "%d CanvasItem Ãthelyezése"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" to (%d, %d)"
-msgstr "CanvasItem áthelyezése"
+msgstr "%s CanvasItem mozgatása (%d, %d)-ra/re"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5391,9 +5396,8 @@ msgid "HCenter Wide"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Full Rect"
-msgstr "Teljes téglalap"
+msgstr "Teljes Téglalap"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Keep Ratio"
@@ -5413,10 +5417,13 @@ msgstr "Horgonyok Módosítása"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid ""
"Game Camera Override\n"
"Overrides game camera with editor viewport camera."
msgstr ""
+"Játék Kamera Felülírás.\n"
+"Felülírja a játék kamerát szerkesztői nézetablak kamerával."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5507,12 +5514,12 @@ msgstr "Alt + Jobb Egérgomb: Mélységi lista választás"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Move Mode"
-msgstr ""
+msgstr "Mozgató Mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Mode"
-msgstr "Forgató mód"
+msgstr "Forgató Mód"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5855,7 +5862,6 @@ msgid "Emission Colors"
msgstr "Kibocsátási színek"
#: editor/plugins/cpu_particles_editor_plugin.cpp
-#, fuzzy
msgid "CPUParticles"
msgstr "CPU-részecskék"
@@ -5870,7 +5876,6 @@ msgid "Create Emission Points From Node"
msgstr "Kibocsátási pontok létrehozása a Node alapján"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Flat 0"
msgstr "Lapos 0"
@@ -5919,9 +5924,8 @@ msgid "Right Linear"
msgstr "Jobb lineáris"
#: editor/plugins/curve_editor_plugin.cpp
-#, fuzzy
msgid "Load Preset"
-msgstr "Előre beállított betöltése"
+msgstr "Beállítás Betöltése"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Remove Curve Point"
@@ -6262,7 +6266,6 @@ msgstr "Navigációs Sokszög Létrehozása"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Convert to CPUParticles"
msgstr "Konvertálás CPU-részecskékké"
@@ -6279,9 +6282,8 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Csak egy ParticlesMaterial feldolgozó anyagba állíthat pontot"
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Convert to CPUParticles2D"
-msgstr "Konvertálás CPU-részecskékké"
+msgstr "Konvertálás CPUParticles2D-re"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -6566,18 +6568,16 @@ msgid "Move Points"
msgstr "Pontok mozgatása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Command: Rotate"
-msgstr "Húzás: Forgatás"
+msgstr "Command: Forgatás"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
msgstr "Shift: Mind Mozgatása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Shift+Command: Scale"
-msgstr "Shift + Ctrl: Skálázás"
+msgstr "Shif+Command: Méretezés"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
@@ -6622,14 +6622,12 @@ msgid "Radius:"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy Polygon to UV"
-msgstr "Sokszög és UV létrehozása"
+msgstr "Sokszög UV-ba másolása"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy UV to Polygon"
-msgstr "Csontok szinkronizálása a sokszöggel"
+msgstr "UV Másolása Sokszögbe"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
@@ -6676,9 +6674,8 @@ msgid "Grid Step Y:"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Sync Bones to Polygon"
-msgstr "Csontok szinkronizálása a sokszöggel"
+msgstr "Csontok Szinkronizálása Sokszögre"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
@@ -6838,7 +6835,6 @@ msgid "Filter scripts"
msgstr "Szkriptek szűrése"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Toggle alphabetical sorting of the method list."
msgstr "Ãbécészerinti rendezés változtatása a metóduslistában."
@@ -7112,7 +7108,7 @@ msgstr "Ãtváltás Megjegyzésre"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
-msgstr "Sor Összezárása / Kibontása"
+msgstr "Sor Összezárása/Kibontása"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
@@ -7132,7 +7128,7 @@ msgstr "Szimbólum Befejezése"
#: editor/plugins/script_text_editor.cpp
msgid "Evaluate Selection"
-msgstr ""
+msgstr "Kijelölés Kiértékelése"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
@@ -7222,7 +7218,6 @@ msgid "Set Rest Pose to Bones"
msgstr ""
#: editor/plugins/skeleton_2d_editor_plugin.cpp
-#, fuzzy
msgid "Skeleton2D"
msgstr "Csontváz2D"
@@ -7252,27 +7247,27 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Orthogonal"
-msgstr ""
+msgstr "Ortogonális"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective"
-msgstr ""
+msgstr "Perspektíva"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Aborted."
-msgstr ""
+msgstr "Ãtalakítás Megszakítva."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "X-Axis Transform."
-msgstr ""
+msgstr "X-Tengely Transzformáció."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Y-Axis Transform."
-msgstr ""
+msgstr "Y-tengely Transzformáció."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Z-Axis Transform."
-msgstr "Z-Tengely transzformáció"
+msgstr "Z-Tengely Transzformáció."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Plane Transform."
@@ -7307,9 +7302,8 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Size"
-msgstr "Méret: "
+msgstr "Méret"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -7563,7 +7557,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
-msgstr ""
+msgstr "Animációs Kulcs Beszúrása"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
@@ -7852,9 +7846,8 @@ msgid "Loop"
msgstr "Ciklus"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animation Frames:"
-msgstr "Animációs képkockák:"
+msgstr "Animációs Képkockák:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add a Texture from File"
@@ -7909,9 +7902,8 @@ msgid "Set Region Rect"
msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
-#, fuzzy
msgid "Set Margin"
-msgstr "Margó beállítása"
+msgstr "Margó Beállítása"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
@@ -8035,12 +8027,10 @@ msgid "Submenu"
msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Subitem 1"
msgstr "Alelem 1"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Subitem 2"
msgstr "Alelem 2"
@@ -8116,7 +8106,7 @@ msgstr "Érvénytelen csempék javítása"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
msgid "Cut Selection"
-msgstr "Kijelölés kivágása"
+msgstr "Kijelölés Kivágása"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
@@ -8144,16 +8134,15 @@ msgstr "Csempe keresése"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr ""
+msgstr "Transzpozálás"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Enable Priority"
-msgstr "Prioritás engedélyezése"
+msgstr "Prioritás Engedélyezése"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Filter tiles"
@@ -8208,9 +8197,8 @@ msgid "Add Texture(s) to TileSet."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "Távolítsa el a kijelölt textúrát a csempekészletből."
+msgstr "Kijelölj textúra eltávolítása TileSet-ből."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8249,7 +8237,6 @@ msgid "Select the previous shape, subtile, or Tile."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region"
msgstr "Régió"
@@ -8266,7 +8253,6 @@ msgid "Navigation"
msgstr "Navigáció"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask"
msgstr "Bitmaszk"
@@ -8327,23 +8313,20 @@ msgid "Create a new rectangle."
msgstr "Új téglalap létrehozása."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Rectangle"
-msgstr "Új Scene"
+msgstr "Új Négyszög"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new polygon."
msgstr "Új sokszög létrehozása."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Polygon"
-msgstr "Sokszög Mozgatása"
+msgstr "Új Sokszög"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete Selected Shape"
-msgstr "Kijelöltek törlése"
+msgstr "Kijelölt Alakzat Törlése"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
@@ -8667,7 +8650,6 @@ msgid "Remove output port"
msgstr "Kimeneti port eltávolítása"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set expression"
msgstr "Kifejezés beállítása"
@@ -8688,9 +8670,8 @@ msgid "Add Node to Visual Shader"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node(s) Moved"
-msgstr "Node eltávolítva"
+msgstr "Node(ok) Ãthelyezve"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Duplicate Nodes"
@@ -8710,9 +8691,8 @@ msgid "Visual Shader Input Type Changed"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "UniformRef Name Changed"
-msgstr "A paraméter megváltozott"
+msgstr "UniformRef Név Megváltozott"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -8735,7 +8715,6 @@ msgid "Create Shader Node"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
msgstr "Szín függvény."
@@ -8796,7 +8775,6 @@ msgid "SoftLight operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
msgstr "Színállandó."
@@ -8871,7 +8849,6 @@ msgid ""
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Boolean constant."
msgstr "Logikai állandó."
@@ -8884,7 +8861,6 @@ msgid "'%s' input parameter for all shader modes."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Input parameter."
msgstr "Bemeneti paraméter."
@@ -8913,12 +8889,10 @@ msgid "'%s' input parameter for vertex and fragment shader mode."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
msgstr "Skalárfüggvény."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar operator."
msgstr "Skalár operátor."
@@ -9145,9 +9119,8 @@ msgid "Subtracts scalar from scalar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar constant."
-msgstr "Skaláris állandó."
+msgstr "Skalár állandó."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar uniform."
@@ -9225,12 +9198,10 @@ msgid "Transform uniform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Vektor függvény."
+msgstr "Vektorfüggvény."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector operator."
msgstr "Vektor operátor."
@@ -9349,7 +9320,6 @@ msgid "Subtracts vector from vector."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector constant."
msgstr "Vektor állandó."
@@ -9490,9 +9460,8 @@ msgid ""
msgstr ""
#: editor/project_export.cpp
-#, fuzzy
msgid "Export Path"
-msgstr "Exportálási útvonal"
+msgstr "Exportálási Útvonal"
#: editor/project_export.cpp
msgid "Resources"
@@ -9532,7 +9501,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr ""
+msgstr "Funkciók"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9547,9 +9516,8 @@ msgid "Script"
msgstr "Szkript"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script Export Mode:"
-msgstr "Szkript exportálás módja:"
+msgstr "Szkript Exportálás Mód:"
#: editor/project_export.cpp
msgid "Text"
@@ -9612,9 +9580,8 @@ msgid "The path specified doesn't exist."
msgstr "A megadott útvonal nem létezik."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file (it's not in ZIP format)."
-msgstr "Hiba a csomagfájl megnyitása során (az nem ZIP formátumú)."
+msgstr "Hiba a csomagfájl megnyitása során (nem ZIP formátumú)."
#: editor/project_manager.cpp
msgid ""
@@ -9764,12 +9731,10 @@ msgid "Error: Project is missing on the filesystem."
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "Can't open project at '%s'."
msgstr "A projekt nem nyitható meg a(z) %s helyen."
#: editor/project_manager.cpp
-#, fuzzy
msgid "Are you sure to open more than one project?"
msgstr "Biztos, hogy egynél több projektet nyit meg?"
@@ -9861,9 +9826,8 @@ msgid "Projects"
msgstr "Projektek"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Loading, please wait..."
-msgstr "Tükrök letöltése, kérjük várjon..."
+msgstr "Betöltés, kérem várjon..."
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -9958,10 +9922,9 @@ msgstr "Eszköz"
#: editor/project_settings_editor.cpp editor/settings_config_dialog.cpp
msgid "Press a Key..."
-msgstr "Nyomjon le egy billentyűt"
+msgstr "Nyomjon meg egy billentyűt..."
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Mouse Button Index:"
msgstr "Egérgomb index:"
@@ -10042,9 +10005,8 @@ msgid "Middle Button."
msgstr "Középső Egérgomb."
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Wheel Up."
-msgstr "Felfelé görgetés."
+msgstr "Felfelé Görgetés."
#: editor/project_settings_editor.cpp
msgid "Wheel Down."
@@ -10173,7 +10135,6 @@ msgid "Index:"
msgstr "Index:"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Localization"
msgstr "Lokalizáció"
@@ -10391,8 +10352,9 @@ msgid "snake_case to PascalCase"
msgstr ""
#: editor/rename_dialog.cpp
+#, fuzzy
msgid "Case"
-msgstr ""
+msgstr "Eset"
#: editor/rename_dialog.cpp
msgid "To Lowercase"
@@ -10411,45 +10373,46 @@ msgid "Regular Expression Error:"
msgstr "Reguláris Kifejezési Hiba:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "At character %s"
msgstr "A(z) %s karakternél"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
-msgstr ""
+msgstr "Node új szülőhöz rendelése"
#: editor/reparent_dialog.cpp
msgid "Reparent Location (Select new Parent):"
-msgstr ""
+msgstr "Helyszín új szülőhöz rendelése (Új szülő kiválasztása):"
#: editor/reparent_dialog.cpp
msgid "Keep Global Transform"
-msgstr ""
+msgstr "Globális Transzformáció Megtartása"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent"
-msgstr ""
+msgstr "Új szülő hozzárendelése"
#: editor/run_settings_dialog.cpp
msgid "Run Mode:"
-msgstr ""
+msgstr "Futás Mód:"
#: editor/run_settings_dialog.cpp
+#, fuzzy
msgid "Current Scene"
-msgstr ""
+msgstr "Jelenlegi Jelenet"
#: editor/run_settings_dialog.cpp
msgid "Main Scene"
-msgstr ""
+msgstr "FÅ‘ Jelenet"
#: editor/run_settings_dialog.cpp
msgid "Main Scene Arguments:"
-msgstr ""
+msgstr "FÅ‘ Jelenet Argumentumok:"
#: editor/run_settings_dialog.cpp
+#, fuzzy
msgid "Scene Run Settings"
-msgstr ""
+msgstr "Jelenet Indítási Beállítások"
#: editor/scene_tree_dock.cpp
msgid "No parent to instance the scenes at."
@@ -10467,24 +10430,24 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Instance Scene(s)"
-msgstr ""
+msgstr "Jelenet(ek) Példányosítása"
#: editor/scene_tree_dock.cpp
+#, fuzzy
msgid "Replace with Branch Scene"
-msgstr ""
+msgstr "Kicserélés Ãg Jelenettel"
#: editor/scene_tree_dock.cpp
msgid "Instance Child Scene"
-msgstr ""
+msgstr "Gyermek Jelenet Peldányosítása"
#: editor/scene_tree_dock.cpp
msgid "Can't paste root node into the same scene."
-msgstr ""
+msgstr "Gyökér node nem illeszthető be azonos jelenetbe."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Paste Node(s)"
-msgstr "Node-ok beillesztése"
+msgstr "Node(ok) beillesztése"
#: editor/scene_tree_dock.cpp
msgid "Detach Script"
@@ -10504,7 +10467,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Duplicate Node(s)"
-msgstr ""
+msgstr "Node(ok) Megkettőzése"
#: editor/scene_tree_dock.cpp
msgid "Can't reparent nodes in inherited scenes, order of nodes can't change."
@@ -10532,7 +10495,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
-msgstr ""
+msgstr "Gyökér node törlése \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Delete node \"%s\" and its children?"
@@ -10576,23 +10539,23 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Create Root Node:"
-msgstr "Gyökér node létrehozása:"
+msgstr "Gyökér Node Létrehozása:"
#: editor/scene_tree_dock.cpp
msgid "2D Scene"
-msgstr "2D jelenet"
+msgstr "2D Jelenet"
#: editor/scene_tree_dock.cpp
msgid "3D Scene"
-msgstr "3D jelenet"
+msgstr "3D Jelenet"
#: editor/scene_tree_dock.cpp
msgid "User Interface"
-msgstr ""
+msgstr "Felhasználói Felület"
#: editor/scene_tree_dock.cpp
msgid "Other Node"
-msgstr ""
+msgstr "Másik Node"
#: editor/scene_tree_dock.cpp
msgid "Can't operate on nodes from a foreign scene!"
@@ -10607,9 +10570,8 @@ msgid "Attach Script"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Cut Node(s)"
-msgstr "Node-ok kivágása"
+msgstr "Node(ok) Kivágása"
#: editor/scene_tree_dock.cpp
msgid "Remove Node(s)"
@@ -10735,14 +10697,12 @@ msgid "Unlock Node"
msgstr "Node feloldása"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Button Group"
msgstr "Gombcsoport"
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "(Connecting From)"
-msgstr "(Csatlakozás innen)"
+msgstr "(Csatlakozás Innen)"
#: editor/scene_tree_editor.cpp
msgid "Node configuration warning:"
@@ -10825,9 +10785,8 @@ msgid "Path is not local."
msgstr "Az útvonal nem helyi."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid base path."
-msgstr "Érvénytelen alapútvonal."
+msgstr "Érvénytelen Alapútvonal."
#: editor/script_create_dialog.cpp
msgid "A directory with the same name exists."
@@ -11085,7 +11044,7 @@ msgstr ""
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
-msgstr ""
+msgstr "Gyorsbillentyű törlése"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
@@ -11410,29 +11369,24 @@ msgid "Preparing data structures"
msgstr ""
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Generate buffers"
-msgstr "AABB Generálása"
+msgstr "Bufferek Generálása"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Direct lighting"
-msgstr "Irányok"
+msgstr "Közvetlen megvilágítás"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Indirect lighting"
-msgstr "Behúzás Jobbra"
+msgstr "Közvetett megvilágítás"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
-msgstr "Kifejezés beállítása"
+msgstr "Utófeldolgozás"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Plotting lightmaps"
-msgstr "Fénytérképek Létrehozása"
+msgstr "Fénytérképek Ãbrázolása"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -11644,7 +11598,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Duplicate VisualScript Nodes"
-msgstr ""
+msgstr "VisualScript Node-ok Megkettőzése"
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Getter. Hold Shift to drop a generic signature."
@@ -12121,7 +12075,6 @@ msgid "Using default boot splash image."
msgstr ""
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package short name."
msgstr "Érvénytelen rövid csomagnév."
@@ -12130,19 +12083,16 @@ msgid "Invalid package unique name."
msgstr "Érvénytelen egyedi csomagnév."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid package publisher display name."
msgstr "Érvénytelen csomagközzétevő megjelenítendő neve."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid product GUID."
-msgstr "Érvénytelen termékazonosító."
+msgstr "Érvénytelen termék GUID."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid publisher GUID."
-msgstr "Érvénytelen közzétevői GUID."
+msgstr "Érvénytelen kiadó GUID."
#: platform/uwp/export/export.cpp
msgid "Invalid background color."
@@ -12384,14 +12334,12 @@ msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing geometry (%d/%d)"
-msgstr "Geometria Elemzése…"
+msgstr "Geometria Előkészítése (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing environment"
-msgstr "Geometria Elemzése…"
+msgstr "Környezet előkészítése"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
@@ -12404,9 +12352,8 @@ msgid "Saving lightmaps"
msgstr "Fénytérképek Létrehozása"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Done"
-msgstr "Kész!"
+msgstr "Kész"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12682,9 +12629,8 @@ msgid "Must use a valid extension."
msgstr "Használjon érvényes kiterjesztést."
#: scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Enable grid minimap."
-msgstr "Illesztés Engedélyezése"
+msgstr "Rács kistérkép engedélyezése."
#: scene/gui/popup.cpp
msgid ""
@@ -12737,7 +12683,6 @@ msgid ""
msgstr ""
#: scene/resources/visual_shader_nodes.cpp
-#, fuzzy
msgid "Invalid source for preview."
msgstr "Érvénytelen forrás az előnézethez."
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 5dc5b9751a..6657101598 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -11,7 +11,7 @@
# Khairul Hidayat <khairulcyber4rt@gmail.com>, 2016.
# Reza Hidayat Bayu Prabowo <rh.bayu.prabowo@gmail.com>, 2018, 2019.
# Romi Kusuma Bakti <romikusumab@gmail.com>, 2017, 2018.
-# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018, 2019, 2020.
+# Sofyan Sugianto <sofyanartem@gmail.com>, 2017-2018, 2019, 2020, 2021.
# Tito <ijavadroid@gmail.com>, 2018.
# Tom My <tom.asadinawan@gmail.com>, 2017.
# yursan9 <rizal.sagi@gmail.com>, 2016.
@@ -24,17 +24,19 @@
# Modeus Darksono <garuga17@gmail.com>, 2019.
# Akhmad Zulfikar <azuldegratz@gmail.com>, 2020.
# Ade Fikri Malihuddin <ade.fm97@gmail.com>, 2020.
-# zephyroths <ridho.hikaru@gmail.com>, 2020.
+# zephyroths <ridho.hikaru@gmail.com>, 2020, 2021.
# Richard Urban <redasuio1@gmail.com>, 2020.
# yusuf afandi <afandi.yusuf.04@gmail.com>, 2020.
# Habib Rohman <revolusi147id@gmail.com>, 2020.
# Hanz <hanzhaxors@gmail.com>, 2021.
+# Reza Almanda <rezaalmanda27@gmail.com>, 2021.
+# Naufal Adriansyah <naufaladrn90@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-08 15:33+0000\n"
-"Last-Translator: Hanz <hanzhaxors@gmail.com>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Naufal Adriansyah <naufaladrn90@gmail.com>\n"
"Language-Team: Indonesian <https://hosted.weblate.org/projects/godot-engine/"
"godot/id/>\n"
"Language: id\n"
@@ -42,13 +44,12 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr ""
-"Tipe argumen salah dalam menggunakan convert(), gunakan konstanta TYPE_*."
+msgstr "Tipe argumen salah dalam penggunaan convert(), gunakan konstan TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
@@ -59,7 +60,8 @@ msgstr "String dengan panjang 1 (karakter) yang diharapkan."
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
msgstr ""
-"Tidak cukup bytes untuk merubah bytes ke nilai asal, atau format tidak valid."
+"Tidak memiliki bytes yang cukup untuk merubah bytes ke nilai asal, atau "
+"format tidak valid."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -534,7 +536,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
-msgstr "Hanya tampilkan track dari node terpilih dalam tree."
+msgstr "Hanya tampilkan track dari node terpilih dalam tree."
#: editor/animation_track_editor.cpp
msgid "Group tracks by node or display them as plain list."
@@ -597,11 +599,11 @@ msgstr "Hapus Pilihan"
#: editor/animation_track_editor.cpp
msgid "Go to Next Step"
-msgstr "Menuju Langkah Berikutnya"
+msgstr "Pergi ke Langkah Berikutnya"
#: editor/animation_track_editor.cpp
msgid "Go to Previous Step"
-msgstr "Menuju Langkah Sebelumnya"
+msgstr "Pergi ke Langkah Sebelumnya"
#: editor/animation_track_editor.cpp
msgid "Optimize Animation"
@@ -1751,7 +1753,7 @@ msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
msgstr ""
-"Sudah ada profil '%s'. Hapus profil ini terlebih dahulu sebelum mengimpor, "
+"Sudah ada profil '%s'. Hapus profil ini terlebih dahulu sebelum mengimpor, "
"impor dibatalkan."
#: editor/editor_feature_profile.cpp
@@ -2851,7 +2853,7 @@ msgstr ""
"file yang bisa dieksekusi mencoba untuk terhubung ke IP komputer ini, "
"sehingga proyek yang sedang berajalan dapat didebug.\n"
"Pilihan ini dimaksudkan untuk digunakan sebagai cara men-debug jarak jauh "
-"(biasanya menggunakan perangkat selular).\n"
+"(biasanya menggunakan perangkat selular).\n"
"Kamu tidak perlu mengaktifkan ini jika menggunakan GDScript debugger secara "
"lokal."
@@ -3689,6 +3691,13 @@ msgstr ""
"manual."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Mengimpor telah didisable untuk berkas ini, jadi itu tidak bisa dibuka untuk "
+"disunting."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Tidak bisa memindah/mengubah nama resource root."
@@ -3938,9 +3947,8 @@ msgid "%d matches in %d file."
msgstr "Ditemukan %d kecocokan."
#: editor/find_in_files.cpp
-#, fuzzy
msgid "%d matches in %d files."
-msgstr "Ditemukan %d kecocokan."
+msgstr "Ditemukan %d kecocokan dalam %d berkas."
#: editor/groups_editor.cpp
msgid "Add to Group"
@@ -4071,25 +4079,27 @@ msgstr "Kesalahan saat menjalankan skrip post-import:"
#: editor/import/resource_importer_scene.cpp
msgid "Did you return a Node-derived object in the `post_import()` method?"
msgstr ""
+"Apakan Anda mengembalikan objek berturunan Node dalam method `post_import()`?"
#: editor/import/resource_importer_scene.cpp
msgid "Saving..."
msgstr "Menyimpan..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Mode Seleksi"
+msgstr "Pilih Importir"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Impor"
+msgstr "Importir:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "Muat Default"
+msgstr "Kembalikan ke Nilai Baku"
+
+#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Simpan Berkas (Tanpa Impor)"
#: editor/import_dock.cpp
msgid "%d Files"
@@ -5054,9 +5064,8 @@ msgid "Got:"
msgstr "Yang Didapat:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "Gagal mengecek hash sha256"
+msgstr "Gagal mengecek hash SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5187,14 +5196,12 @@ msgid "Assets ZIP File"
msgstr "Berkas Aset ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
"Save your scene and try again."
msgstr ""
"Tidak dapat menentukan lokasi penyimpanan untuk gambar lightmap.\n"
-"Simpan skena Anda (untuk gambar yang akan disimpan di direktori yang sama), "
-"atau pilih lokasi penyimpanan dari properti BakedLightmap."
+"Simpan skena Anda dan coba lagi."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5211,26 +5218,30 @@ msgstr "Gagal membuat gambar lightmap, pastikan path dapat ditulis."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed determining lightmap size. Maximum lightmap size too small?"
msgstr ""
+"Gagal menentukan ukuran lightmap. Ukuran lightmap maksimumnya terlalu kecil?"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Some mesh is invalid. Make sure the UV2 channel values are contained within "
"the [0.0,1.0] square region."
msgstr ""
+"Banyak mesh tak valid. Pastikan nilai kanal UV2 diisi dalam rentang wilayah "
+"persegi [0.0,1.0]."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Godot editor was built without ray tracing support, lightmaps can't be baked."
msgstr ""
+"Editor Godot di-build tanpa dukungan ray tracing, sehingga lightmaps tidak "
+"dapat di-bake."
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "Panggang Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "Pilih berkas templat"
+msgstr "Pilih berkas lightmap bake:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5299,50 +5310,43 @@ msgstr "Buat Panduan Horisontal dan Vertikal"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
-msgstr ""
+msgstr "Atur Offset Pivot CanvasItem \"%s\" ke (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate %d CanvasItems"
-msgstr "Putar CanvasItem"
+msgstr "Putar %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem \"%s\" to %d degrees"
-msgstr "Putar CanvasItem"
+msgstr "Putar CanvasItem \"%s\" menjadi %d derajat"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" Anchor"
-msgstr "Pindahkan CanvasItem"
+msgstr "Pindahkan Anchor CanvasItem \"%s\""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale Node2D \"%s\" to (%s, %s)"
-msgstr ""
+msgstr "Skalakan Node2D \"%s\" menjadi (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Resize Control \"%s\" to (%d, %d)"
-msgstr ""
+msgstr "Ubah ukuran Control \"%s\" menjadi (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale %d CanvasItems"
-msgstr "Skalakan CanvasItem"
+msgstr "Skalakan %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem \"%s\" to (%s, %s)"
-msgstr "Skalakan CanvasItem"
+msgstr "Skalakan CanvasItem \"%s\" menjadi (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move %d CanvasItems"
-msgstr "Pindahkan CanvasItem"
+msgstr "Pindahkan %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" to (%d, %d)"
-msgstr "Pindahkan CanvasItem"
+msgstr "Pindahkan CanvasItem \"%s\" ke (%d,%d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5677,7 +5681,7 @@ msgstr "Tampilkan Tulang-tulang"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make Custom Bone(s) from Node(s)"
-msgstr "Buat Tulang Kustom(satu/lebih) dari Node(satu/lebih)"
+msgstr "Buat Tulang Kustom(satu/lebih) dari Node(satu/lebih)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Custom Bones"
@@ -6335,9 +6339,8 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "Hanya dapat mengatur titik ke dalam material proses ParticlesMaterial"
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Convert to CPUParticles2D"
-msgstr "Konversikan menjadi CPUParticles"
+msgstr "Konversikan menjadi CPUParticles2D"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -6626,18 +6629,16 @@ msgid "Move Points"
msgstr "Geser Titik"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Command: Rotate"
-msgstr "Geser: Putar"
+msgstr "Comand: Putar"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
msgstr "Shift: Geser Semua"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Shift+Command: Scale"
-msgstr "Shift+Ctrl: Skala"
+msgstr "Shift+Command: Skala"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
@@ -6684,14 +6685,12 @@ msgid "Radius:"
msgstr "Radius:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy Polygon to UV"
-msgstr "Buat Poligon & UV"
+msgstr "Salin Polygon ke UV"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Copy UV to Polygon"
-msgstr "Konversikan menjadi Polygon2D"
+msgstr "Salin UV ke Polygon"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Clear UV"
@@ -7086,9 +7085,8 @@ msgstr ""
"'%s' ke node '%s'."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "[Ignore]"
-msgstr "(abaikan)"
+msgstr "[abaikan]"
#: editor/plugins/script_text_editor.cpp
msgid "Line"
@@ -7376,9 +7374,8 @@ msgid "Yaw"
msgstr "Oleng"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Size"
-msgstr "Ukuran: "
+msgstr "Ukuran"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -7580,6 +7577,12 @@ msgid ""
"Closed eye: Gizmo is hidden.\n"
"Half-open eye: Gizmo is also visible through opaque surfaces (\"x-ray\")."
msgstr ""
+"Klik untuk mengatur visibilitas.\n"
+"\n"
+"Mata terbuka: Gizmo tampak.\n"
+"Mata tertutup: Gizmo disembunyikan.\n"
+"Mata setengah terbuka: Gizmo juga tampak melalui permukaan tidak tembus "
+"pandang (\"sinar-x\")."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
@@ -7919,9 +7922,8 @@ msgid "New Animation"
msgstr "Animasi Baru"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Speed:"
-msgstr "Kecepatan (FPS):"
+msgstr "Kecepatan:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
@@ -8239,13 +8241,12 @@ msgid "Paint Tile"
msgstr "Cat Tile"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid ""
"Shift+LMB: Line Draw\n"
"Shift+Command+LMB: Rectangle Paint"
msgstr ""
"Shift + Klik Kiri: Menggambar Garis\n"
-"Shift + Ctrl + Klik Kiri: Cat Persegi Panjang"
+"Shift + Command + Klik Kiri: Cat Persegi Panjang"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8400,23 +8401,20 @@ msgid "Create a new rectangle."
msgstr "Buat persegi panjang baru."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Rectangle"
-msgstr "Cat Persegi Panjang"
+msgstr "Persegi Panjang Baru"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create a new polygon."
msgstr "Buat poligon baru."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "New Polygon"
-msgstr "Geser Poligon"
+msgstr "Poligon Baru"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete Selected Shape"
-msgstr "Hapus yang Dipilih"
+msgstr "Hapus Shape yang Dipilih"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Keep polygon inside region Rect."
@@ -8781,7 +8779,6 @@ msgid "Add Node to Visual Shader"
msgstr "Tambah Node ke Visual Shader"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node(s) Moved"
msgstr "Node Dipindahkan"
@@ -8803,9 +8800,8 @@ msgid "Visual Shader Input Type Changed"
msgstr "Tipe Input Visual Shader Berubah"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "UniformRef Name Changed"
-msgstr "Tetapkan Nama Uniform"
+msgstr "Nama UniformRef diubah"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -9230,7 +9226,7 @@ msgstr "Mengembalikan nilai tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic tangent of the parameter."
-msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
+msgstr "Mengembalikan nilai hiperbolik tangen dari parameter."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the truncated value of the parameter."
@@ -9527,7 +9523,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "A reference to an existing uniform."
-msgstr ""
+msgstr "Referensi ke uniform yang ada."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(Fragment/Light mode only) Scalar derivative function."
@@ -9702,7 +9698,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr "Fitur"
+msgstr "Fitur-fitur"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -9897,7 +9893,7 @@ msgstr "OpenGL ES 3.0"
#: editor/project_manager.cpp
msgid "Not supported by your GPU drivers."
-msgstr ""
+msgstr "Tidak didukung oleh driver GPU Anda."
#: editor/project_manager.cpp
msgid ""
@@ -10074,9 +10070,8 @@ msgid "Projects"
msgstr "Proyek"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Loading, please wait..."
-msgstr "Mendapatkan informasi cermin, silakan tunggu..."
+msgstr "Memuat, tunggu sejenak..."
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -10383,7 +10378,7 @@ msgstr "Aksi"
#: editor/project_settings_editor.cpp
msgid "Deadzone"
-msgstr "Deadzone"
+msgstr "Zona tidak aktif"
#: editor/project_settings_editor.cpp
msgid "Device:"
@@ -10450,9 +10445,8 @@ msgid "Plugins"
msgstr "Pengaya"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Import Defaults"
-msgstr "Muat Default"
+msgstr "Impor Nilai Baku"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -10515,19 +10509,16 @@ msgid "Batch Rename"
msgstr "Ubah Nama Massal"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "Ganti: "
+msgstr "Ganti:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Prefix:"
-msgstr "Awalan"
+msgstr "Awalan:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Suffix:"
-msgstr "Akhiran"
+msgstr "Akhiran:"
#: editor/rename_dialog.cpp
msgid "Use Regular Expressions"
@@ -10574,9 +10565,9 @@ msgid "Per-level Counter"
msgstr "Penghitung per Level"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "If set, the counter restarts for each group of child nodes."
-msgstr "Jika diatur, penghitung akan dimulai ulang untuk setiap grup node anak"
+msgstr ""
+"Jika diatur, penghitung akan dimulai ulang untuk setiap grup node anak."
#: editor/rename_dialog.cpp
msgid "Initial value for the counter"
@@ -10635,9 +10626,8 @@ msgid "Reset"
msgstr "Reset"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expression Error:"
-msgstr "Kesalahan Ekspresi Reguler"
+msgstr "Kesalahan Ekspresi Reguler:"
#: editor/rename_dialog.cpp
msgid "At character %s"
@@ -10708,19 +10698,16 @@ msgid "Instance Child Scene"
msgstr "Instansi Skena Anak"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't paste root node into the same scene."
-msgstr "Tidak dapat bekerja pada node dari skena luar!"
+msgstr "Tidak dapat menempelkan node akar ke dalam skena yang sama."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Paste Node(s)"
-msgstr "Rekatkan Node"
+msgstr "Tempel Node"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach Script"
-msgstr "Lampirkan Skrip"
+msgstr "Lepas Skrip"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
@@ -10757,9 +10744,8 @@ msgid "Make node as Root"
msgstr "Jadikan node sebagai Dasar"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Hapus node \"%s\" dan anak-anaknya?"
+msgstr "Hapus %d node dan semua anaknya?"
#: editor/scene_tree_dock.cpp
msgid "Delete %d nodes?"
@@ -10849,7 +10835,6 @@ msgid "Attach Script"
msgstr "Lampirkan Skrip"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Cut Node(s)"
msgstr "Potong Node"
@@ -10898,14 +10883,14 @@ msgid "Open Documentation"
msgstr "Buka Dokumentasi"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid ""
"Cannot attach a script: there are no languages registered.\n"
"This is probably because this editor was built with all language modules "
"disabled."
msgstr ""
-"Tidak dapat melampirkan skrip: tidak ada bahasa yang terdaftar.\n"
-"Ini mungkin karena editor ini dibuat dengan semua modul bahasa dinonaktifkan."
+"Tidak dapat melampirkan skrip: tidak ada bahasa terdaftar.\n"
+"Ini mungkin karena editor ini di-build dengan semua modul bahasa "
+"dinonaktifkan."
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
@@ -10956,14 +10941,12 @@ msgstr ""
"akar."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Attach a new or existing script to the selected node."
msgstr "Lampirkan skrip baru atau yang sudah ada untuk node yang dipilih."
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Detach the script from the selected node."
-msgstr "Bersihkan skrip untuk node yang dipilih."
+msgstr "Lepas skrip dari node yang dipilih."
#: editor/scene_tree_dock.cpp
msgid "Remote"
@@ -11664,36 +11647,31 @@ msgstr ""
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Begin Bake"
-msgstr ""
+msgstr "Mulai Bake"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Preparing data structures"
-msgstr ""
+msgstr "Menyiapkan struktur data"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Generate buffers"
-msgstr "Buat AABB"
+msgstr "Ciptakan buffer"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Direct lighting"
-msgstr "Arah"
+msgstr "PEncahayaan langsung"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Indirect lighting"
-msgstr "Indentasi Kanan"
+msgstr "Pencahayaan tak langsung"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
-msgstr "Pasca Proses"
+msgstr "Pasca pemrosesan"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Plotting lightmaps"
-msgstr "Plotting Lights:"
+msgstr "Memetakan lightmap"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -12209,7 +12187,7 @@ msgstr "Pilih perangkat pada daftar"
#: platform/android/export/export.cpp
msgid "Unable to find the 'apksigner' tool."
-msgstr ""
+msgstr "Tak dapat menemukan perkakas 'apksigner'."
#: platform/android/export/export.cpp
msgid ""
@@ -12226,48 +12204,37 @@ msgstr ""
"prasetel proyek."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Release keystore incorrectly configured in the export preset."
-msgstr ""
-"Berkas debug keystore belum dikonfigurasi dalam Pengaturan Editor maupun di "
-"prasetel proyek."
+msgstr "Berkas keystore rilis belum dikonfigurasi di prasetel ekspor."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "A valid Android SDK path is required in Editor Settings."
-msgstr ""
-"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
-"Editor."
+msgstr "Lokasi Android SDK yang valid dibutuhkan di Pengaturan Editor."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid Android SDK path in Editor Settings."
-msgstr ""
-"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
-"Editor."
+msgstr "Lokasi Android SDK tidak valid di Pengaturan Editor."
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
-msgstr ""
+msgstr "Direktori 'platform-tools' tidak ada!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK platform-tools' adb command."
-msgstr ""
+msgstr "Tidak dapat menemukan perintah adb di Android SDK platform-tools."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Please check in the Android SDK directory specified in Editor Settings."
msgstr ""
-"Lokasi Android SDK tidak valid untuk membuat kustom APK dalam Pengaturan "
-"Editor."
+"Silakan cek direktori Android SDK yang diisikan dalam Pengaturan Editor."
#: platform/android/export/export.cpp
msgid "Missing 'build-tools' directory!"
-msgstr ""
+msgstr "Direktori 'build-tools' tidak ditemukan!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK build-tools' apksigner command."
-msgstr ""
+msgstr "Tidak dapat menemukan apksigner dalam Android SDK build-tools."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12282,42 +12249,51 @@ msgid ""
"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
"project setting (changed in Godot 3.2.2).\n"
msgstr ""
+"Modul \"GodotPaymentV3\" tidak valid yang dimasukkan dalam pengaturan proyek "
+"\"android/modules\" (diubah di Godot 3.2.2)\n"
#: platform/android/export/export.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
-msgstr ""
+msgstr "\"Gunakan Build Custom\" harus diaktifkan untuk menggunakan plugin."
#: platform/android/export/export.cpp
msgid ""
"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
"\"."
msgstr ""
+"\"Derajat Kebebasan\" hanya valid ketika \"Mode Xr\" bernilai \"Occulus "
+"Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
msgstr ""
+"\"Pelacakan Tangan\" hanya valid ketika \"Mode Xr\" bernilai \"Oculus Mobile "
+"VR\"."
#: platform/android/export/export.cpp
msgid ""
"\"Focus Awareness\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
msgstr ""
+"\"Focus Awareness\" hanya valid ketika \"Mode Xr\" bernilai \"Oculus Mobile "
+"VR\"."
#: platform/android/export/export.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
msgstr ""
+"\"Expor AAB\" hanya bisa valid ketika \"Gunakan Build Custom\" diaktifkan."
#: platform/android/export/export.cpp
msgid "Invalid filename! Android App Bundle requires the *.aab extension."
-msgstr ""
+msgstr "Nama berkas tak valid! Android App Bundle memerlukan ekstensi *.aab ."
#: platform/android/export/export.cpp
msgid "APK Expansion not compatible with Android App Bundle."
-msgstr ""
+msgstr "Ekspansi APK tidak kompatibel dengan Android App Bundle."
#: platform/android/export/export.cpp
msgid "Invalid filename! Android APK requires the *.apk extension."
-msgstr ""
+msgstr "Nama berkas tidak valid! APK Android memerlukan ekstensi *.apk ."
#: platform/android/export/export.cpp
msgid ""
@@ -12353,13 +12329,15 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Moving output"
-msgstr ""
+msgstr "Memindahkan keluaran"
#: platform/android/export/export.cpp
msgid ""
"Unable to copy and rename export file, check gradle project directory for "
"outputs."
msgstr ""
+"Tidak dapat menyalin dan mengubah nama berkas ekspor, cek direktori proyek "
+"gradle untuk hasilnya."
#: platform/iphone/export/export.cpp
msgid "Identifier is missing."
@@ -12517,10 +12495,14 @@ msgstr ""
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
msgstr ""
+"Poligon tidak valid. Minimal 3 titik dibutuhkan untuk mode pembangunan "
+"'Solid'."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
msgstr ""
+"Poligon tidak valid. Minimal 2 titik dibutuhkan untuk mode pembangunan "
+"'Segmen\"."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12542,14 +12524,13 @@ msgstr ""
"ciptakan resource shape untuknya!"
#: scene/2d/collision_shape_2d.cpp
-#, fuzzy
msgid ""
"Polygon-based shapes are not meant be used nor edited directly through the "
"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
msgstr ""
-"Bentuk Polygon-based tidak dimaksudkan untuk digunakan atau diedit secara "
-"langsung melalui node CollisionShape2D. Silakan gunakan node "
-"CollisionPolygon2D sebagai gantinya."
+"Bentuk Polygon-based tidak dimaksudkan untuk digunakan atau diedit langsung "
+"melalui node CollisionShape2D. Gunakan node CollisionPolygon2D sebagai "
+"gantinya."
#: scene/2d/cpu_particles_2d.cpp
msgid ""
@@ -12561,23 +12542,23 @@ msgstr ""
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A dan Node B harus berupa PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node A harus PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Node B harus PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Persendian tidak terkoneksi dengan 2 PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Node A dan Node B harus PhysicsBody2D yang berbeda"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12736,32 +12717,27 @@ msgstr "ARVROrigin membutuhkan node anak ARVRCamera."
#: scene/3d/baked_lightmap.cpp
msgid "Finding meshes and lights"
-msgstr ""
+msgstr "Mencari mesh dan cahaya"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing geometry (%d/%d)"
-msgstr "Mengurai Geometri..."
+msgstr "Menyiapkan geometri (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing environment"
-msgstr "Tampilkan Lingkungan"
+msgstr "Menyiapkan lingkungan"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Generating capture"
-msgstr "Membuat Pemetaan Cahaya"
+msgstr "Membuat capture"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Saving lightmaps"
-msgstr "Membuat Pemetaan Cahaya"
+msgstr "Menyimpan lightmap"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Done"
-msgstr "Selesai!"
+msgstr "Selesai"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12769,6 +12745,10 @@ msgid ""
"Consider adding a CollisionShape or CollisionPolygon as a child to define "
"its shape."
msgstr ""
+"Node ini tidak memiliki shape, jadi tidak bisa bertabrakan atau berinteraksi "
+"dengan objek lain.\n"
+"Pertimbangkan untuk menambah CollisionShape atau CollisionPolygon sebagai "
+"anak untuk mendefinisikan shape-nya."
#: scene/3d/collision_polygon.cpp
msgid ""
@@ -12809,22 +12789,26 @@ msgid ""
"Plane shapes don't work well and will be removed in future versions. Please "
"don't use them."
msgstr ""
+"Bentuk plane tidak bekerja baik dan akan dihapus dalam versi mendatang. "
+"Mohon untuk tidak menggunakannya."
#: scene/3d/collision_shape.cpp
msgid ""
"ConcavePolygonShape doesn't support RigidBody in another mode than static."
msgstr ""
+"ConcavePolygonShape tidak mendukung RigidBody dengan mode selain statis."
#: scene/3d/cpu_particles.cpp
-#, fuzzy
msgid "Nothing is visible because no mesh has been assigned."
-msgstr "Tidak ada yang tampak karena tidak ada mesh yang ditetapkan."
+msgstr "Tidak ada yang tampil karena tidak ada mesh yang ditetapkan."
#: scene/3d/cpu_particles.cpp
msgid ""
"CPUParticles animation requires the usage of a SpatialMaterial whose "
"Billboard Mode is set to \"Particle Billboard\"."
msgstr ""
+"Animasi CPUParticle membutuhkan penggunaan SpatialMaterial yang Mode "
+"Billboard nya diatur ke \"Particle Billboard\"."
#: scene/3d/gi_probe.cpp
msgid "Plotting Meshes"
@@ -12845,6 +12829,7 @@ msgstr ""
#: scene/3d/light.cpp
msgid "A SpotLight with an angle wider than 90 degrees cannot cast shadows."
msgstr ""
+"SpotLight dengan sudut lebih dari 90 derajat tidak dapat memberikan bayangan."
#: scene/3d/navigation_mesh.cpp
msgid "A NavigationMesh resource must be set or created for this node to work."
@@ -12866,17 +12851,24 @@ msgid ""
"Use the CPUParticles node instead. You can use the \"Convert to CPUParticles"
"\" option for this purpose."
msgstr ""
+"Partikel berbasis GPU tidak didukung oleh driver video GLES2.\n"
+"Gunakan CPUParticles saja. Anda dapat menggunakan opsi \"Konversikan ke "
+"CPUParticles\" untuk ini."
#: scene/3d/particles.cpp
msgid ""
"Nothing is visible because meshes have not been assigned to draw passes."
msgstr ""
+"Tidak ada yang ditampilkan karena mesh tidak ditetapkan untuk menggambar "
+"lintasan."
#: scene/3d/particles.cpp
msgid ""
"Particles animation requires the usage of a SpatialMaterial whose Billboard "
"Mode is set to \"Particle Billboard\"."
msgstr ""
+"Animasi Partikel memerlukan penggunaan SpatialMaterial dengan Mode Billboard "
+"\"Particle Billboard\"."
#: scene/3d/path.cpp
msgid "PathFollow only works when set as a child of a Path node."
@@ -12898,39 +12890,41 @@ msgid ""
"by the physics engine when running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"Perubahan ukuran RigidBody (dalam mode karakter atau rigid) akan ditimpa "
+"oleh mesin fisika ketika dijalankan.\n"
+"Ubah ukuran dari \"collision shape\"-anaknya saja."
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be PhysicsBodies"
-msgstr ""
+msgstr "Node A dan Node B harus PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A must be a PhysicsBody"
-msgstr ""
+msgstr "Node A harus PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node B must be a PhysicsBody"
-msgstr ""
+msgstr "Node B harus PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Joint is not connected to any PhysicsBodies"
-msgstr ""
+msgstr "Persendian tidak terkoneksi dengan PhysicsBody"
#: scene/3d/physics_joint.cpp
msgid "Node A and Node B must be different PhysicsBodies"
-msgstr ""
+msgstr "Node A dan Node B harus PhysicsBody yang berbeda"
#: scene/3d/remote_transform.cpp
-#, fuzzy
msgid ""
"The \"Remote Path\" property must point to a valid Spatial or Spatial-"
"derived node to work."
msgstr ""
-"Properti path harus menunjuk ke sebuah node Particles2D yang sah agar "
-"bekerja."
+"Properti \"Remote Path\" harus menunjuk ke Spatial atau turunannya yang "
+"valid agar bekerja."
#: scene/3d/soft_body.cpp
msgid "This body will be ignored until you set a mesh."
-msgstr ""
+msgstr "Body ini akan diabaikan hingga Anda mengatur mesh-nya."
#: scene/3d/soft_body.cpp
msgid ""
@@ -12938,6 +12932,8 @@ msgid ""
"running.\n"
"Change the size in children collision shapes instead."
msgstr ""
+"Perubahan ukuran SoftBody akan ditimpa oleh mesin fisika ketika dijalankan.\n"
+"Ubah ukurannya melalui \"collision shape\"-anaknya saja."
#: scene/3d/sprite_3d.cpp
msgid ""
@@ -12952,6 +12948,8 @@ msgid ""
"VehicleWheel serves to provide a wheel system to a VehicleBody. Please use "
"it as a child of a VehicleBody."
msgstr ""
+"VehicleWheel berfungsi menyediakan sistem roda ke VehicleBody. Gunakan itu "
+"sebagai anak dari VehicleBody."
#: scene/3d/world_environment.cpp
msgid ""
@@ -13082,9 +13080,8 @@ msgid "Must use a valid extension."
msgstr "Harus menggunakan ekstensi yang sah."
#: scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Enable grid minimap."
-msgstr "Aktifkan Pengancingan"
+msgstr "Aktifkan peta mini grid."
#: scene/gui/popup.cpp
msgid ""
@@ -13147,6 +13144,8 @@ msgid ""
"The sampler port is connected but not used. Consider changing the source to "
"'SamplerPort'."
msgstr ""
+"Porta sampler terhubung tapi tidak digunakan. Pertimbangkan untuk mengubah "
+"sumbernya ke 'SamplerPort'."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/is.po b/editor/translations/is.po
index 8d36556c04..9ae40b5085 100644
--- a/editor/translations/is.po
+++ b/editor/translations/is.po
@@ -3542,6 +3542,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3937,6 +3942,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/it.po b/editor/translations/it.po
index 67b524937c..a0fb10367a 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -29,8 +29,8 @@
# Giuseppe Guerra <me@nyodev.xyz>, 2019.
# RHC <rhc.throwaway@gmail.com>, 2019, 2020.
# Antonio Giungato <antonio.giungato@gmail.com>, 2019, 2020.
-# Marco Galli <mrcgll98@gmail.com>, 2019, 2020.
-# MassiminoilTrace <omino.gis@gmail.com>, 2019, 2020.
+# Marco Galli <mrcgll98@gmail.com>, 2019, 2020, 2021.
+# MassiminoilTrace <omino.gis@gmail.com>, 2019, 2020, 2021.
# MARCO BANFI <mbanfi@gmail.com>, 2019.
# Marco <rodomar705@gmail.com>, 2019.
# Davide Giuliano <davidegiuliano00@gmail.com>, 2019.
@@ -56,12 +56,13 @@
# Federico Manzella <ferdiu.manzella@gmail.com>, 2020.
# Ziv D <wizdavid@gmail.com>, 2020.
# Riteo Siuga <lorenzocerqua@tutanota.com>, 2021.
+# Alessandro Mandelli <mandelli.alessandro@ngi.it>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
-"Last-Translator: riccardo boffelli <riccardo.boffelli.96@gmail.com>\n"
+"PO-Revision-Date: 2021-03-24 23:44+0000\n"
+"Last-Translator: Alessandro Mandelli <mandelli.alessandro@ngi.it>\n"
"Language-Team: Italian <https://hosted.weblate.org/projects/godot-engine/"
"godot/it/>\n"
"Language: it\n"
@@ -391,9 +392,8 @@ msgid "Remove Anim Track"
msgstr "Rimuovi una traccia d'animazione"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Create NEW track for %s and insert key?"
-msgstr "Creare una NUOVA traccia per %s e inserirci la chiave?"
+msgstr "Creare una NUOVA traccia per %s e inserire la chiave?"
#: editor/animation_track_editor.cpp
msgid "Create %d NEW tracks and insert keys?"
@@ -1159,7 +1159,7 @@ msgstr "Possiede"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr "Risorse non Possedute Esplicitamente:"
+msgstr "Risorse senza proprietario esplicito:"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Key"
@@ -1890,7 +1890,7 @@ msgstr "Aggiorna"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr "Tutti i risconosciuti"
+msgstr "Tutti i formati riconosciuti"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -2007,7 +2007,7 @@ msgstr "File:"
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr "Scansiona sorgenti"
+msgstr "Scansiona i sorgenti"
#: editor/editor_file_system.cpp
msgid ""
@@ -2379,8 +2379,8 @@ msgid ""
"option and delete the Default layout."
msgstr ""
"Layout predefinito dell'editor sovrascritto.\n"
-"Per ripristinare il layout predefinito alle impostazioni di base, usa "
-"l'opzione elimina layout ed elimina il layout predefinito."
+"Per ripristinare il layout predefinito alle impostazioni di base, usare "
+"l'opzione elimina layout ed eliminare il layout predefinito."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -3746,6 +3746,11 @@ msgstr ""
"reimportarlo manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Impossibile spostare/rinominare risorse root."
@@ -4135,20 +4140,22 @@ msgid "Saving..."
msgstr "Salvataggio..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Modalità di selezione"
+msgstr "Seleziona Importatore"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Importare"
+msgstr "Importatore:"
#: editor/import_defaults_editor.cpp
msgid "Reset to Defaults"
msgstr "Ripristinare le impostazioni predefinite"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d File"
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index 8afa2de349..6c6340e9b8 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -36,8 +36,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-08 15:33+0000\n"
-"Last-Translator: Wataru Onuki <bettawat@yahoo.co.jp>\n"
+"PO-Revision-Date: 2021-04-01 02:04+0000\n"
+"Last-Translator: nitenook <admin@alterbaum.net>\n"
"Language-Team: Japanese <https://hosted.weblate.org/projects/godot-engine/"
"godot/ja/>\n"
"Language: ja\n"
@@ -45,7 +45,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3692,6 +3692,11 @@ msgstr ""
"ンãƒãƒ¼ãƒˆã—ã¦ä¸‹ã•ã„。"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "ルートã®ãƒªã‚½ãƒ¼ã‚¹ã¯ç§»å‹•/リãƒãƒ¼ãƒ ã§ãã¾ã›ã‚“。"
@@ -4095,6 +4100,10 @@ msgid "Reset to Defaults"
msgstr "デフォルトを読込む"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d ファイル"
@@ -11249,7 +11258,7 @@ msgstr "グラフを表示ã™ã‚‹ã«ã¯ã€ãƒªã‚¹ãƒˆã‹ã‚‰ã‚¢ã‚¤ãƒ†ãƒ ã‚’1ã¤ä»¥ä¸
#: editor/script_editor_debugger.cpp
msgid "List of Video Memory Usage by Resource:"
-msgstr "リソースã«ã‚ˆã‚‹ãƒ“デオメモリーã®ä½¿ç”¨ä¸€è¦§:"
+msgstr "リソースã«ã‚ˆã‚‹ãƒ“ãƒ‡ã‚ªãƒ¡ãƒ¢ãƒªãƒ¼ã®æ¶ˆè²»é‡ä¸€è¦§:"
#: editor/script_editor_debugger.cpp
msgid "Total:"
@@ -11273,7 +11282,7 @@ msgstr "フォーマット"
#: editor/script_editor_debugger.cpp
msgid "Usage"
-msgstr "使用法"
+msgstr "消費é‡"
#: editor/script_editor_debugger.cpp
msgid "Misc"
diff --git a/editor/translations/ka.po b/editor/translations/ka.po
index 6828baf211..6d7d40a6ad 100644
--- a/editor/translations/ka.po
+++ b/editor/translations/ka.po
@@ -3633,6 +3633,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4042,6 +4047,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 693b726ebf..0fcbd51720 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -21,12 +21,13 @@
# Jun Hyung Shin <shmishmi79@gmail.com>, 2020.
# Yongjin Jo <wnrhd114@gmail.com>, 2020.
# Yungjoong Song <yungjoong.song@gmail.com>, 2020.
+# Henry LeRoux <henry.leroux@ocsbstudent.ca>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-12 09:17+0000\n"
-"Last-Translator: Myeongjin Lee <aranet100@gmail.com>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Henry LeRoux <henry.leroux@ocsbstudent.ca>\n"
"Language-Team: Korean <https://hosted.weblate.org/projects/godot-engine/"
"godot/ko/>\n"
"Language: ko\n"
@@ -34,7 +35,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3664,6 +3665,12 @@ msgstr ""
"ìš”."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"ì´ íŒŒì¼ì— 대해 가져 오기가 비활성화ë˜ì—ˆìœ¼ë©° íŽ¸ì§‘ì„ ìœ„í•´ ì—´ 수 없습니다."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "리소스 루트를 옮기거나 ì´ë¦„ì„ ë°”ê¿€ 수 없습니다."
@@ -4063,6 +4070,10 @@ msgid "Reset to Defaults"
msgstr "기본값으로 재설정"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "íŒŒì¼ %dê°œ"
diff --git a/editor/translations/lt.po b/editor/translations/lt.po
index 585e4d4447..0796f01fbe 100644
--- a/editor/translations/lt.po
+++ b/editor/translations/lt.po
@@ -3591,6 +3591,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4001,6 +4006,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Redaguoti Filtrus"
diff --git a/editor/translations/lv.po b/editor/translations/lv.po
index 5512d59238..d8a665caa6 100644
--- a/editor/translations/lv.po
+++ b/editor/translations/lv.po
@@ -3543,6 +3543,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3938,6 +3943,10 @@ msgid "Reset to Defaults"
msgstr "IelÄdÄ“t NoklusÄ“jumu"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d FailÄ"
diff --git a/editor/translations/mi.po b/editor/translations/mi.po
index 260543a475..5198022282 100644
--- a/editor/translations/mi.po
+++ b/editor/translations/mi.po
@@ -3488,6 +3488,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3878,6 +3883,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/mk.po b/editor/translations/mk.po
index cd72ecd259..0b4e23cccf 100644
--- a/editor/translations/mk.po
+++ b/editor/translations/mk.po
@@ -3495,6 +3495,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3885,6 +3890,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/ml.po b/editor/translations/ml.po
index fb9de4a419..a445086dd6 100644
--- a/editor/translations/ml.po
+++ b/editor/translations/ml.po
@@ -3500,6 +3500,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3890,6 +3895,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/mr.po b/editor/translations/mr.po
index cf3a24a739..00e8ced169 100644
--- a/editor/translations/mr.po
+++ b/editor/translations/mr.po
@@ -3495,6 +3495,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3885,6 +3890,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/ms.po b/editor/translations/ms.po
index c0a7f7cea2..363f8895a3 100644
--- a/editor/translations/ms.po
+++ b/editor/translations/ms.po
@@ -3810,6 +3810,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4208,6 +4213,10 @@ msgid "Reset to Defaults"
msgstr "Muatkan Lalai"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index 9e69510739..172439dc43 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -16,12 +16,13 @@
# Revolution <revosw@gmail.com>, 2019.
# Petter Reinholdtsen <pere-weblate@hungry.com>, 2019, 2020.
# Patrick Sletvold <patricksletvold@hotmail.com>, 2021.
+# Kristoffer <kskau93@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-02-27 00:47+0000\n"
-"Last-Translator: Anonymous <GentleSaucepan@protonmail.com>\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
+"Last-Translator: Kristoffer <kskau93@gmail.com>\n"
"Language-Team: Norwegian Bokmål <https://hosted.weblate.org/projects/godot-"
"engine/godot/nb_NO/>\n"
"Language: nb\n"
@@ -29,7 +30,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -663,7 +664,7 @@ msgstr "Velg spor å kopiere"
#: editor/plugins/sprite_frames_editor_plugin.cpp editor/property_editor.cpp
#: editor/scene_tree_dock.cpp scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Copy"
-msgstr "Lim inn"
+msgstr "Kopier"
#: editor/animation_track_editor.cpp
#, fuzzy
@@ -1591,7 +1592,7 @@ msgstr "Velg en Mappe"
#: editor/filesystem_dock.cpp editor/project_manager.cpp
#: scene/gui/file_dialog.cpp
msgid "Create Folder"
-msgstr "Lag mappe"
+msgstr "Lag Mappe"
#: editor/editor_dir_dialog.cpp editor/editor_file_dialog.cpp
#: editor/editor_plugin_settings.cpp editor/filesystem_dock.cpp
@@ -1706,9 +1707,8 @@ msgid "3D Editor"
msgstr "Redigeringsverktøy"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Script Editor"
-msgstr "Ã…pne SkriptEditor"
+msgstr "Skript Redigeringsverktøy"
#: editor/editor_feature_profile.cpp
msgid "Asset Library"
@@ -1724,9 +1724,8 @@ msgid "Node Dock"
msgstr "Flytt Modus"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "FileSystem Dock"
-msgstr "FilSystem"
+msgstr "FilSystem Panel"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1882,7 +1881,7 @@ msgstr "Kutt Noder"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr "Kopier Sti"
+msgstr "Kopier Bane"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
#, fuzzy
@@ -1941,27 +1940,27 @@ msgstr "Lagre ei fil"
#: editor/editor_file_dialog.cpp
msgid "Go Back"
-msgstr "GÃ¥ tilbake"
+msgstr "GÃ¥ Tilbake"
#: editor/editor_file_dialog.cpp
msgid "Go Forward"
-msgstr "GÃ¥ framover"
+msgstr "GÃ¥ Fremover"
#: editor/editor_file_dialog.cpp
msgid "Go Up"
-msgstr "GÃ¥ oppover"
+msgstr "GÃ¥ Oppover"
#: editor/editor_file_dialog.cpp
msgid "Toggle Hidden Files"
-msgstr "Veksle visning av skjulte filer"
+msgstr "Veksle Visning av Skjulte Filer"
#: editor/editor_file_dialog.cpp
msgid "Toggle Favorite"
-msgstr "Veksle favorittmerkering"
+msgstr "Veksle Favorittmarkering"
#: editor/editor_file_dialog.cpp
msgid "Toggle Mode"
-msgstr "Veksle modus"
+msgstr "Veksle Modus"
#: editor/editor_file_dialog.cpp
msgid "Focus Path"
@@ -2132,7 +2131,7 @@ msgstr ""
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Søk hjelp"
+msgstr "Søk Hjelp"
#: editor/editor_help_search.cpp
msgid "Case Sensitive"
@@ -2244,7 +2243,7 @@ msgstr "Tøm"
#: editor/editor_log.cpp
msgid "Clear Output"
-msgstr "Nullstill resultat"
+msgstr "Nullstill Resultat"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
@@ -2619,9 +2618,8 @@ msgid "Close Scene"
msgstr "Lukk Scene"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "Lukk Scene"
+msgstr "Gjenåpne Lukket Scene"
#: editor/editor_node.cpp
#, fuzzy
@@ -2842,9 +2840,8 @@ msgid "Save Scene"
msgstr "Lagre Scene"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Save All Scenes"
-msgstr "Lagre alle Scener"
+msgstr "Lagre Alle Scener"
#: editor/editor_node.cpp
msgid "Convert To..."
@@ -3036,9 +3033,8 @@ msgid "Editor Layout"
msgstr "Redigeringsverktøy Layout"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Take Screenshot"
-msgstr "Lagre Scene"
+msgstr "Ta Skjermbilde"
#: editor/editor_node.cpp
msgid "Screenshots are stored in the Editor Data/Settings Folder."
@@ -3046,7 +3042,7 @@ msgstr "Skjermavbildninger lagres i redigeringsdata/innstillingsmappen."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "Skru av/på Fullskjerm"
+msgstr "Veksle Fullskjerm"
#: editor/editor_node.cpp
#, fuzzy
@@ -3119,7 +3115,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Pause Scene"
-msgstr "Sett scenen på pause"
+msgstr "Sett Scenen PÃ¥ Pause"
#: editor/editor_node.cpp
msgid "Stop the scene."
@@ -3180,9 +3176,8 @@ msgid "Inspector"
msgstr "Inspektør"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Expand Bottom Panel"
-msgstr "Utvid alle"
+msgstr "Utvid Nederste Panel"
#: editor/editor_node.cpp
msgid "Output"
@@ -3282,7 +3277,7 @@ msgstr "Åpne 3D-redigeringsverktøy"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Ã…pne SkriptEditor"
+msgstr "Åpne Skriptredigeringsverktøy"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3804,6 +3799,11 @@ msgstr ""
"Status: Import av fil feilet. Reparer filen eller importer igjen manuelt."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Cannot move/rename resources root."
msgstr "Kan ikke flytte/endre navn ressursrot"
@@ -4009,9 +4009,8 @@ msgid "Create Script"
msgstr "Opprett skript"
#: editor/find_in_files.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Find in Files"
-msgstr "%d flere filer"
+msgstr "Finn i Filer"
#: editor/find_in_files.cpp
#, fuzzy
@@ -4238,6 +4237,10 @@ msgid "Reset to Defaults"
msgstr "Last Standard"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -5757,9 +5760,8 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Zoom Reset"
-msgstr "Zoom Ut"
+msgstr "Zoom Resett"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5795,9 +5797,8 @@ msgstr "Roter Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Scale Mode"
-msgstr "Velg Modus"
+msgstr "Skaler Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5818,9 +5819,8 @@ msgid "Pan Mode"
msgstr "Panorerings-Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Ruler Mode"
-msgstr "Velg Modus"
+msgstr "Linjal Modus"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5828,9 +5828,8 @@ msgid "Toggle smart snapping."
msgstr "Slå av/på snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Smart Snap"
-msgstr "Bruk Snap"
+msgstr "Bruk Smart Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5838,9 +5837,8 @@ msgid "Toggle grid snapping."
msgstr "Slå av/på snapping"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Grid Snap"
-msgstr "Bruk Snap"
+msgstr "Bruk Rutenett Snap"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5948,13 +5946,12 @@ msgid "View"
msgstr "Visning"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Always Show Grid"
-msgstr "Vis Rutenett"
+msgstr "Alltid Vis Rutenett"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
-msgstr "Vis hjelpere"
+msgstr "Vis Hjelpere"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Rulers"
@@ -5962,7 +5959,7 @@ msgstr "Vis linjaler"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Guides"
-msgstr "Vis veiledere"
+msgstr "Vis Veiledere"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -6036,7 +6033,7 @@ msgstr "Kopier Pose"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
-msgstr "Fjern Pose"
+msgstr "Fjern Posering"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
@@ -6047,9 +6044,8 @@ msgid "Divide grid step by 2"
msgstr "Del rutenett-steg med 2"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Pan View"
-msgstr "Bakvisning"
+msgstr "Panoreringsvisning"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Add %s"
@@ -7179,12 +7175,12 @@ msgstr "%s-klassereferanse"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr "Finn neste"
+msgstr "Finn Neste"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Previous"
-msgstr "Finn forrige"
+msgstr "Finn Forrige"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7234,13 +7230,12 @@ msgid "Open..."
msgstr "Ã…pne"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Reopen Closed Script"
-msgstr "Kjør Skript"
+msgstr "Gjenåpne Lukket Skript"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr "Lagre Alle"
+msgstr "Lagre Alt"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
@@ -7251,9 +7246,8 @@ msgid "Copy Script Path"
msgstr "Kopier Skript-Sti"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "History Previous"
-msgstr "Finn forrige"
+msgstr "Historie Forrige"
#: editor/plugins/script_editor_plugin.cpp
msgid "History Next"
@@ -7299,7 +7293,7 @@ msgstr "Søk"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Into"
-msgstr "Tre inn i"
+msgstr "Tre Inn I"
#: editor/plugins/script_editor_plugin.cpp editor/script_editor_debugger.cpp
msgid "Step Over"
@@ -7394,9 +7388,8 @@ msgid "Line"
msgstr "Linje:"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function"
-msgstr "Fjern Funksjon"
+msgstr "GÃ¥ til Funksjon"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
@@ -7421,7 +7414,7 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Uppercase"
-msgstr "Store versaler"
+msgstr "Store bokstaver"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Lowercase"
@@ -7461,9 +7454,8 @@ msgid "Select All"
msgstr "Velg Alle"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Delete Line"
-msgstr "Slett Valgte"
+msgstr "Slett Linje"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Left"
@@ -7475,12 +7467,11 @@ msgstr "Innrykk Høyre"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Comment"
-msgstr "Veksle kommentar"
+msgstr "Veksle Kommentar"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Fold/Unfold Line"
-msgstr "Slett Valgte"
+msgstr "Veksle Linjebretting"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
@@ -7492,34 +7483,31 @@ msgstr "Brett ut alle linjer"
#: editor/plugins/script_text_editor.cpp
msgid "Clone Down"
-msgstr "Klon nedover"
+msgstr "Klon Nedover"
#: editor/plugins/script_text_editor.cpp
msgid "Complete Symbol"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Evaluate Selection"
-msgstr "Skaler Utvalg"
+msgstr "Evaluer Seleksjon"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Spaces"
-msgstr "Konverter til store versaler"
+msgstr "Konverter Innrykk til Mellomrom"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Convert Indent to Tabs"
-msgstr "Konverter til store versaler"
+msgstr "Konverter Inrykk til Tabs"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr "Automatisk innrykk"
+msgstr "Automatisk Innrykk"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7531,19 +7519,16 @@ msgid "Contextual Help"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Toggle Bookmark"
-msgstr "Veksle kommentar"
+msgstr "Veksle Bokmerke"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Next Bookmark"
-msgstr "GÃ¥ til Neste Steg"
+msgstr "GÃ¥ til Neste Bokmerke"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Previous Bookmark"
-msgstr "GÃ¥ til tidligere redigert dokument."
+msgstr "GÃ¥ til Forrige Bokmerke"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7575,9 +7560,8 @@ msgid "Go to Next Breakpoint"
msgstr "GÃ¥ til Neste Steg"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Previous Breakpoint"
-msgstr "GÃ¥ til tidligere redigert dokument."
+msgstr "GÃ¥ til Forrige Steg"
#: editor/plugins/shader_editor_plugin.cpp
msgid ""
@@ -7950,7 +7934,7 @@ msgstr "Høyrevisning"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
-msgstr "Bytt perspektiv/ortogonal fremvisning"
+msgstr "Bytt Perspektiv/Ortogonal Fremvisning"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
@@ -7974,9 +7958,8 @@ msgid "Transform"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Snap Object to Floor"
-msgstr "Snap til rutenett"
+msgstr "Snap Objekt til Gulv"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Dialog..."
@@ -8529,9 +8512,8 @@ msgid "Theme File"
msgstr "Tema"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Erase Selection"
-msgstr "Fjern Utvalg"
+msgstr "Fjern Seleksjon"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8540,9 +8522,8 @@ msgstr "Ugyldig navn."
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Cut Selection"
-msgstr "Plasser Utvalg I Midten"
+msgstr "Klipp ut Seleksjon"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
@@ -8565,9 +8546,8 @@ msgid "Erase TileMap"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Find Tile"
-msgstr "Finn neste"
+msgstr "Finn Flis"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
@@ -8612,14 +8592,12 @@ msgid "Pick Tile"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Left"
-msgstr "Roter Modus"
+msgstr "Roter til Venstre"
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Rotate Right"
-msgstr "Roter Polygon"
+msgstr "Roter til Høyre"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
@@ -8630,9 +8608,8 @@ msgid "Flip Vertically"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Clear Transform"
-msgstr "Anim Forandre Omforming"
+msgstr "Nullstill Transformasjon"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8667,18 +8644,16 @@ msgid "New Atlas"
msgstr "Ny %s"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Next Coordinate"
-msgstr "Neste skript"
+msgstr "Neste Koordinat"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the next shape, subtile, or Tile."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Previous Coordinate"
-msgstr "Forrige skript"
+msgstr "Forrige Koordinat"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the previous shape, subtile, or Tile."
@@ -8700,9 +8675,8 @@ msgid "Occlusion"
msgstr "Rediger Poly"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation"
-msgstr "Animasjonsnode"
+msgstr "Navigasjon"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8720,44 +8694,36 @@ msgid "Z Index"
msgstr "Panorerings-Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Region Mode"
-msgstr "Roter Modus"
+msgstr "Region Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Collision Mode"
-msgstr "Animasjonsnode"
+msgstr "Kollisjon Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Occlusion Mode"
-msgstr "Rediger Poly"
+msgstr "Okklusjon Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Navigation Mode"
-msgstr "Animasjonsnode"
+msgstr "Navigasjon Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Bitmask Mode"
-msgstr "Roter Modus"
+msgstr "Bitmaske Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Priority Mode"
-msgstr "Eksporter Prosjekt"
+msgstr "Prioritet Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Icon Mode"
-msgstr "Panorerings-Modus"
+msgstr "Ikon Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Z Index Mode"
-msgstr "Panorerings-Modus"
+msgstr "Z Indeks Modus"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Copy bitmask."
@@ -9049,9 +9015,8 @@ msgid "Detect new changes"
msgstr "Lag ny %s"
#: editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Changes"
-msgstr "Forandre"
+msgstr "Endringer"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Modified"
@@ -10016,7 +9981,7 @@ msgstr "Ressurser"
#: editor/project_export.cpp
msgid "Export all resources in the project"
-msgstr "Eksporter alle ressurser til prosjektet"
+msgstr "Eksporter alle ressurser i prosjektet"
#: editor/project_export.cpp
msgid "Export selected scenes (and dependencies)"
@@ -10024,7 +9989,7 @@ msgstr "Eksporter valgte scener (og avhengigheter)"
#: editor/project_export.cpp
msgid "Export selected resources (and dependencies)"
-msgstr "Exporter valgte ressurs (og avhengigheter)"
+msgstr "Exporter valgte ressurser (og avhengigheter)"
#: editor/project_export.cpp
msgid "Export Mode:"
@@ -10048,7 +10013,7 @@ msgstr ""
#: editor/project_export.cpp
msgid "Features"
-msgstr ""
+msgstr "Egenskaper"
#: editor/project_export.cpp
msgid "Custom (comma-separated):"
@@ -10846,9 +10811,8 @@ msgid "Select Method"
msgstr ""
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Batch Rename"
-msgstr "Endre navn"
+msgstr "Endre Navn på Parti"
#: editor/rename_dialog.cpp
msgid "Replace:"
@@ -11267,9 +11231,8 @@ msgid "Save Branch as Scene"
msgstr ""
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Copy Node Path"
-msgstr "Kopier Noder"
+msgstr "Kopier Node-bane"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
@@ -12479,24 +12442,20 @@ msgid "Copy Nodes"
msgstr "Kopier Noder"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Cut Nodes"
-msgstr "Kutt Noder"
+msgstr "Klipp ut Noder"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "Fjern Funksjon"
+msgstr "Lag Funksjon"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "Oppdater"
+msgstr "Oppdater Graf"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Edit Member"
-msgstr "Medlemmer"
+msgstr "Rediger Medlem"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 52c63ffa85..2716664b7a 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -3726,6 +3726,11 @@ msgstr ""
"handmatig."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Kan de hoofdmap voor bronnen niet verplaatsen of van naam veranderen."
@@ -4129,6 +4134,10 @@ msgid "Reset to Defaults"
msgstr "Laad standaard"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Bestanden"
diff --git a/editor/translations/or.po b/editor/translations/or.po
index 19b87260d6..5e396315c2 100644
--- a/editor/translations/or.po
+++ b/editor/translations/or.po
@@ -3494,6 +3494,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3884,6 +3889,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index d55fee8b72..7da98bc87c 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -51,7 +51,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
+"PO-Revision-Date: 2021-04-01 02:04+0000\n"
"Last-Translator: Tomek <kobewi4e@gmail.com>\n"
"Language-Team: Polish <https://hosted.weblate.org/projects/godot-engine/"
"godot/pl/>\n"
@@ -61,7 +61,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 "
"|| n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3702,6 +3702,13 @@ msgstr ""
"zaimportować ręcznie."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Importowanie zostało wyłączone dla tego pliku, więc nie może być otwarty do "
+"edytowania."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Nie można przenieść/zmienić nazwy korzenia zasobów."
@@ -4104,6 +4111,10 @@ msgid "Reset to Defaults"
msgstr "Resetuj do domyślnych"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Zachowaj plik (brak importu)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d plików"
@@ -10446,7 +10457,7 @@ msgstr "Wtyczki"
#: editor/project_settings_editor.cpp
msgid "Import Defaults"
-msgstr "Importuj domyślne"
+msgstr "Domyślny import"
#: editor/property_editor.cpp
msgid "Preset..."
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 09d967e01d..6f67b1c1be 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -3609,6 +3609,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -4018,6 +4023,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Edit yer Variable:"
diff --git a/editor/translations/pt.po b/editor/translations/pt.po
index dd745d7c56..6020f0557f 100644
--- a/editor/translations/pt.po
+++ b/editor/translations/pt.po
@@ -3687,6 +3687,11 @@ msgstr ""
"manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Não consegui mover/renomear raiz dos recursos."
@@ -4087,6 +4092,10 @@ msgid "Reset to Defaults"
msgstr "Restaurar Predefinições"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Ficheiros"
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index c2e8116938..45e2050732 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -112,12 +112,14 @@
# Lucas Castro <castroclucas@gmail.com>, 2021.
# Ricardo Zamarrenho Carvalho Correa <ricardozcc17@gmail.com>, 2021.
# Diego dos Reis Macedo <diego_dragon97@hotmail.com>, 2021.
+# Lucas E. <lukas.ed45@gmail.com>, 2021.
+# Gabriel Silveira <gabomfim99@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: 2016-05-30\n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
-"Last-Translator: Renato Rotenberg <renato.rotenberg@gmail.com>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Gabriel Silveira <gabomfim99@gmail.com>\n"
"Language-Team: Portuguese (Brazil) <https://hosted.weblate.org/projects/"
"godot-engine/godot/pt_BR/>\n"
"Language: pt_BR\n"
@@ -125,7 +127,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2635,23 +2637,24 @@ msgstr ""
"falhou."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Unable to find script field for addon plugin at: '%s'."
msgstr ""
-"Não foi possível encontrar o campo de script para o plugin em: 'res://addons/"
-"%s'."
+"Não foi possível localizar a área do script para o complemento do plugin em: "
+"'%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr "Não foi possível carregar o script complementar do caminho: '%s'."
+msgstr ""
+"Não foi possível localizar a área do script para o complemento do plugin em: "
+"'%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
-"Não foi possível carregar o script complementar do caminho: '%s' Parece "
-"haver um erro no código, por favor verifique a sintaxe."
+"Não foi possível localizar a área do script para o complemento do plugin em: "
+"'%s'."
#: editor/editor_node.cpp
msgid ""
@@ -3785,6 +3788,13 @@ msgstr ""
"reimporte manualmente."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"A importação foi desativada para este arquivo, por isso não pode ser aberto "
+"para edição."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Impossível mover/renomear raiz dos recursos."
@@ -4173,19 +4183,20 @@ msgid "Saving..."
msgstr "Salvando..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "Modo de Seleção"
+msgstr "Selecione o arquivo para importar"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Importar"
+msgstr "Importar:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "Usar sRGB Padrão"
+msgstr "Redefinir para os padrões"
+
+#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Manter Arquivo (Sem Importação)"
#: editor/import_dock.cpp
msgid "%d Files"
@@ -5159,9 +5170,8 @@ msgid "Got:"
msgstr "Obtido:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "Falha na verificação da hash sha256"
+msgstr "Falha na verificação do hash SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5336,7 +5346,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
-msgstr "Bake Lightmaps"
+msgstr "Faça mapas de luz"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Select lightmap bake file:"
@@ -7446,7 +7456,7 @@ msgstr "Escala: "
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translating: "
-msgstr "Transladando: "
+msgstr "Transladar: "
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotating %s degrees."
@@ -8892,7 +8902,7 @@ msgstr "Tipo de Entrada de Shader Visual Alterado"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "UniformRef Name Changed"
-msgstr "UniformRef Name foi altearado"
+msgstr "Ref. Uniforme Nome alterado"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
@@ -10500,7 +10510,7 @@ msgstr "Remapeamentos por Localidade:"
#: editor/project_settings_editor.cpp
msgid "Locale"
-msgstr "Locale"
+msgstr "Localizar"
#: editor/project_settings_editor.cpp
msgid "Locales Filter"
@@ -10531,9 +10541,8 @@ msgid "Plugins"
msgstr "Plugins"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Import Defaults"
-msgstr "Carregar Padrão"
+msgstr "Importar padrões"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -10545,11 +10554,11 @@ msgstr "Zero"
#: editor/property_editor.cpp
msgid "Easing In-Out"
-msgstr "Easing In-Out"
+msgstr "Facilitar Entrada-Saída"
#: editor/property_editor.cpp
msgid "Easing Out-In"
-msgstr "Easing Out-In"
+msgstr "Facilitar Saída-Entrada"
#: editor/property_editor.cpp
msgid "File..."
@@ -11750,12 +11759,10 @@ msgid "Indirect lighting"
msgstr "Iluminação indireta"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
msgstr "Pós-processamento"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Plotting lightmaps"
msgstr "Traçando mapas de luz"
@@ -12826,9 +12833,8 @@ msgid "Generating capture"
msgstr "Gerando captura"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Saving lightmaps"
-msgstr "Salvando mapas de luz"
+msgstr "Salvando mapas de luz"
#: scene/3d/baked_lightmap.cpp
msgid "Done"
diff --git a/editor/translations/ro.po b/editor/translations/ro.po
index 33f5264d71..c1ee0a6492 100644
--- a/editor/translations/ro.po
+++ b/editor/translations/ro.po
@@ -14,12 +14,13 @@
# Teodor <teo.virghi@yahoo.ro>, 2020.
# f0roots <f0rootss@gmail.com>, 2020.
# Gigel2 <mihalacher02@gmail.com>, 2020.
+# R3ktGamerRO <bluegamermc1@gmail.com>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-10-22 21:37+0000\n"
-"Last-Translator: Gigel2 <mihalacher02@gmail.com>\n"
+"PO-Revision-Date: 2021-03-20 04:18+0000\n"
+"Last-Translator: R3ktGamerRO <bluegamermc1@gmail.com>\n"
"Language-Team: Romanian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ro/>\n"
"Language: ro\n"
@@ -28,18 +29,16 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < "
"20)) ? 1 : 2;\n"
-"X-Generator: Weblate 4.3.1\n"
+"X-Generator: Weblate 4.5.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
-#, fuzzy
msgid "Invalid type argument to convert(), use TYPE_* constants."
-msgstr "Argument invalid pentru transformare(), folosiți constante TYPE_*."
+msgstr "Argument invalid pentru convert(), folosiți constante TYPE_*."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
-#, fuzzy
msgid "Expected a string of length 1 (a character)."
-msgstr "Se așteaptă un șir de lungime 1 (un caracter)."
+msgstr "Se așteaptă un text cu lungime de 1 (un caracter)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
@@ -52,9 +51,8 @@ msgid "Invalid input %i (not passed) in expression"
msgstr "Intrare invalida %i (nu a fost transmisă) in expresie"
#: core/math/expression.cpp
-#, fuzzy
msgid "self can't be used because instance is null (not passed)"
-msgstr "insuși nu poate fi folosit deoarece instanța este nulă(nu a trecut)"
+msgstr "insuși nu poate fi folosit deoarece instanța este nulă (nu a trecut)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -314,7 +312,7 @@ msgstr "Linear"
#: editor/animation_track_editor.cpp
msgid "Cubic"
-msgstr "Cubic"
+msgstr "Cub"
#: editor/animation_track_editor.cpp
msgid "Clamp Loop Interp"
@@ -703,7 +701,7 @@ msgstr "Linia Numărul:"
#: editor/code_editor.cpp
msgid "%d replaced."
-msgstr "%d ÃŽnlocuit"
+msgstr "%d ÃŽnlocuit."
#: editor/code_editor.cpp editor/editor_help.cpp
msgid "%d match."
@@ -1042,14 +1040,14 @@ msgid "Owners Of:"
msgstr "Stăpâni La:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Ștergeți fișierele selectate din proiect? (Acțiune ireversibilă)"
+msgstr ""
+"Ștergeți fișierele selectate din proiect? (Acțiune ireversibilă)\n"
+"Poți gasi fișierele șterse in coșul de gunoi dacă vrei să le restabilești."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1058,7 +1056,8 @@ msgid ""
msgstr ""
"Fișierele în proces de ștergere sunt necesare pentru alte resurse ca ele să "
"sa funcționeze.\n"
-"Ștergeți oricum? (fără anulare)"
+"Ștergeți oricum? (fără anulare)\n"
+"Poți găsi fișierele șterse in coșul de gunoi dacă vrei să le restabilești."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -2665,9 +2664,8 @@ msgid "Close Other Tabs"
msgstr "Închideți Celelalte File"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Close Tabs to the Right"
-msgstr "ÃŽnchidere file la dreapta"
+msgstr "ÃŽnchidere file de la dreapta"
#: editor/editor_node.cpp
msgid "Close All Tabs"
@@ -3141,11 +3139,12 @@ msgid "Open & Run a Script"
msgstr "Deschide și Execută un Script"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?"
-msgstr "Următoarele file au eșuat extragerea din pachet:"
+msgstr ""
+"Următoarele fișiere sunt mai noi pe disk.\n"
+"Ce măsuri ar trebui luate?"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -3673,6 +3672,11 @@ msgstr ""
"manual."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Nu se poate muta/redenumi rădăcina resurselor."
@@ -4062,9 +4066,8 @@ msgid "Select Importer"
msgstr "Selectare mod"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Importare"
+msgstr "Importator:"
#: editor/import_defaults_editor.cpp
#, fuzzy
@@ -4072,6 +4075,10 @@ msgid "Reset to Defaults"
msgstr "Încărcați Implicit"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Fișiere"
@@ -5239,9 +5246,8 @@ msgid "Bake Lightmaps"
msgstr "Procesează Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "Selectare fișier șablon"
+msgstr "Selectare fișier șablon pentru harta de lumină:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -10534,7 +10540,7 @@ msgstr "Redenumește"
#: editor/rename_dialog.cpp
#, fuzzy
msgid "Replace:"
-msgstr "Înlocuiți: "
+msgstr "Înlocuiți:"
#: editor/rename_dialog.cpp
msgid "Prefix:"
@@ -10648,9 +10654,8 @@ msgid "Reset"
msgstr "Resetați Zoom-area"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Regular Expression Error:"
-msgstr "Folosiți expresii regulate"
+msgstr "Eroare de expresie regulată:"
#: editor/rename_dialog.cpp
msgid "At character %s"
@@ -12674,14 +12679,12 @@ msgid "Finding meshes and lights"
msgstr ""
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing geometry (%d/%d)"
-msgstr "Analiza geometriei..."
+msgstr "Analiza geometriei (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing environment"
-msgstr "Analiza geometriei..."
+msgstr "Pregătim mediul de lucru"
#: scene/3d/baked_lightmap.cpp
#, fuzzy
@@ -12694,9 +12697,8 @@ msgid "Saving lightmaps"
msgstr "Se Genereaza Lightmaps"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Done"
-msgstr "Efectuat!"
+msgstr "Efectuat"
#: scene/3d/collision_object.cpp
msgid ""
@@ -12975,9 +12977,8 @@ msgid "Must use a valid extension."
msgstr "Trebuie să utilizaţi o extensie valida."
#: scene/gui/graph_edit.cpp
-#, fuzzy
msgid "Enable grid minimap."
-msgstr "Activează aliniere"
+msgstr "Activează minimapa in format grilă."
#: scene/gui/popup.cpp
msgid ""
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 5a443fd1e3..193b47de8c 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -96,8 +96,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-16 10:40+0000\n"
-"Last-Translator: Danil Alexeev <danil@alexeev.xyz>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: narrnika <narr13niki@gmail.com>\n"
"Language-Team: Russian <https://hosted.weblate.org/projects/godot-engine/"
"godot/ru/>\n"
"Language: ru\n"
@@ -106,7 +106,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3564,7 +3564,7 @@ msgstr "(Текущий)"
#: editor/export_template_manager.cpp
msgid "Retrieving mirrors, please wait..."
-msgstr "Получение зеркал, пожалуйÑта, подождите..."
+msgstr "Получение зеркал, пожалуйÑта, ждите..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
@@ -3756,6 +3756,13 @@ msgstr ""
"переимпортируйте вручную."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Импорт был отключён Ð´Ð»Ñ Ñтого файла, поÑтому его Ð½ÐµÐ»ÑŒÐ·Ñ Ð¾Ñ‚ÐºÑ€Ñ‹Ñ‚ÑŒ Ð´Ð»Ñ "
+"редактированиÑ."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "ÐÐµÐ»ÑŒÐ·Ñ Ð¿ÐµÑ€ÐµÐ¼ÐµÑтить/переименовать корень."
@@ -3919,7 +3926,7 @@ msgid ""
"Please Wait..."
msgstr ""
"Сканирование файлов,\n"
-"пожалуйÑта, подождите..."
+"пожалуйÑта, ждите..."
#: editor/filesystem_dock.cpp
msgid "Move"
@@ -4156,6 +4163,10 @@ msgid "Reset to Defaults"
msgstr "СброÑить наÑтройки"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Сохранить файл (без импорта)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d файлов"
diff --git a/editor/translations/si.po b/editor/translations/si.po
index 0c3a01f0e4..67903c8677 100644
--- a/editor/translations/si.po
+++ b/editor/translations/si.po
@@ -3521,6 +3521,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3913,6 +3918,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 68da1b1221..3bed9c2661 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -3655,6 +3655,11 @@ msgstr ""
"Status:Import súboru zlihal. Prosím opravte súbor a manuálne reimportujte."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Nedá sa presunúť/premenovať \"resources root\"."
@@ -4056,6 +4061,10 @@ msgid "Reset to Defaults"
msgstr "NaÄítaÅ¥ predvolené"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Súbory"
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index 69819f0a36..55c60530b7 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -3794,6 +3794,11 @@ msgstr ""
"Stanje: Uvoz datoteke ni uspel. Popravi datoteko in ponovno roÄno uvozi."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Ni mogoÄe premakniti/preimenovati osnovne vire."
@@ -4225,6 +4230,10 @@ msgid "Reset to Defaults"
msgstr "Naložite Prevzeto"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr " Datoteke"
diff --git a/editor/translations/sq.po b/editor/translations/sq.po
index f53d0b630a..4ed115ecfb 100644
--- a/editor/translations/sq.po
+++ b/editor/translations/sq.po
@@ -3733,6 +3733,11 @@ msgstr ""
"importoje manualisht."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Nuk mund të leviz/riemërtoj rrenjën e resurseve."
@@ -4148,6 +4153,10 @@ msgid "Reset to Defaults"
msgstr "Ngarko të Parazgjedhur"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr " Skedarët"
diff --git a/editor/translations/sr_Cyrl.po b/editor/translations/sr_Cyrl.po
index 4fe901f414..b8edfd5d95 100644
--- a/editor/translations/sr_Cyrl.po
+++ b/editor/translations/sr_Cyrl.po
@@ -3984,6 +3984,11 @@ msgstr ""
"Ñами."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Ðе могу померити/преименовати корен реÑурÑа."
@@ -4431,6 +4436,10 @@ msgid "Reset to Defaults"
msgstr "Учитај уобичајено"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr " %d Датотеке"
diff --git a/editor/translations/sr_Latn.po b/editor/translations/sr_Latn.po
index 3d979c3fc6..8f79f445d8 100644
--- a/editor/translations/sr_Latn.po
+++ b/editor/translations/sr_Latn.po
@@ -3537,6 +3537,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3930,6 +3935,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/sv.po b/editor/translations/sv.po
index a7bc3d6288..125d4c733e 100644
--- a/editor/translations/sv.po
+++ b/editor/translations/sv.po
@@ -15,18 +15,19 @@
# Anonymous <noreply@weblate.org>, 2020.
# Joakim Lundberg <joakim@joakimlundberg.com>, 2020.
# Kristoffer Grundström <swedishsailfishosuser@tutanota.com>, 2020.
-# Jonas Robertsson <jonas.robertsson@posteo.net>, 2020.
+# Jonas Robertsson <jonas.robertsson@posteo.net>, 2020, 2021.
# André Andersson <andre.eric.andersson@gmail.com>, 2020.
# Andreas Westrell <andreas.westrell@gmail.com>, 2020.
# Gustav Andersson <gustav.andersson96@outlook.com>, 2020.
# Shaggy <anton_christoffersson@hotmail.com>, 2020.
# Marcus Toftedahl <marcus.toftedahl@his.se>, 2020.
+# Alex25820 <Alexander_sjogren@hotmail.se>, 2021.
msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2020-11-04 02:39+0000\n"
-"Last-Translator: Marcus Toftedahl <marcus.toftedahl@his.se>\n"
+"PO-Revision-Date: 2021-03-24 23:44+0000\n"
+"Last-Translator: Jonas Robertsson <jonas.robertsson@posteo.net>\n"
"Language-Team: Swedish <https://hosted.weblate.org/projects/godot-engine/"
"godot/sv/>\n"
"Language: sv\n"
@@ -34,7 +35,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.3.2-dev\n"
+"X-Generator: Weblate 4.5.2-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -43,13 +44,13 @@ msgstr "Ogiltligt typargument till convert(), använd TYPE_* konstanter."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
msgid "Expected a string of length 1 (a character)."
-msgstr "Förväntas en string av längden 1 (en karaktär)."
+msgstr "Förväntade en sträng av längden 1 (ett tecken)."
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/mono/glue/gd_glue.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
msgid "Not enough bytes for decoding bytes, or invalid format."
-msgstr "Inte tillräckligt med bytes för avkodning byte, eller ogiltigt format."
+msgstr "Inte nog med bytes för att avkoda, eller ogiltigt format."
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
@@ -579,7 +580,7 @@ msgstr "Fördubbla val"
#: editor/animation_track_editor.cpp
msgid "Duplicate Transposed"
-msgstr "Fördubbla Transponerade"
+msgstr "Duplicera Transponerade"
#: editor/animation_track_editor.cpp
msgid "Delete Selection"
@@ -599,7 +600,7 @@ msgstr "Optimera Animation"
#: editor/animation_track_editor.cpp
msgid "Clean-Up Animation"
-msgstr "Rensa Animation"
+msgstr "Städa-upp Animation"
#: editor/animation_track_editor.cpp
msgid "Pick the node that will be animated:"
@@ -844,6 +845,7 @@ msgstr ""
"vilotid."
#: editor/connections_dialog.cpp
+#, fuzzy
msgid "Oneshot"
msgstr "Oneshot"
@@ -1044,14 +1046,14 @@ msgid "Owners Of:"
msgstr "Ägare av:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Ta bort valda filer från projektet? (Kan ej återställas)"
+msgstr ""
+"Ta bort valda filer från projektet? (Kan ej återställas)\n"
+"Du kan hitta de borttagna filerna i systemets papperskorg."
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"The files being removed are required by other resources in order for them to "
"work.\n"
@@ -1059,7 +1061,8 @@ msgid ""
"You can find the removed files in the system trash to restore them."
msgstr ""
"Filerna som tas bort krävs av andra resurser för att de ska fungera.\n"
-"Ta bort dem ändå? (går inte ångra)"
+"Ta bort dem ändå? (går inte ångra)\n"
+"Du kan hitta de borttagna filerna i systemets papperskorg."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1070,9 +1073,8 @@ msgid "Error loading:"
msgstr "Fel vid laddning:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid "Load failed due to missing dependencies:"
-msgstr "Scenen misslyckades att ladda på grund av att beroenden saknas:"
+msgstr "Inladdning misslyckades på grund av att beroenden saknas:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
@@ -1239,7 +1241,7 @@ msgstr "Dekomprimerar Tillgångar"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr "Följande filer gick inte att packa upp från tillägget:"
+msgstr "Följande filer misslyckades att packas upp från paketet:"
#: editor/editor_asset_installer.cpp
msgid "And %s more files."
@@ -1256,7 +1258,7 @@ msgstr "Klart!"
#: editor/editor_asset_installer.cpp
msgid "Package Contents:"
-msgstr "Packet Innehåll:"
+msgstr "Paketets Innehåll:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1280,7 +1282,7 @@ msgstr "Byt namn på Ljud-Buss"
#: editor/editor_audio_buses.cpp
msgid "Change Audio Bus Volume"
-msgstr "Växla Ljud-Buss Volum"
+msgstr "Växla Ljud-Buss Volym"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
@@ -1405,7 +1407,7 @@ msgstr "Lägg till Buss"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
-msgstr "Lägg till en ny Audio-Buss för detta layout"
+msgstr "Lägg till en ny Audio-Buss för denna layout."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1446,21 +1448,16 @@ msgid "Valid characters:"
msgstr "Giltiga tecken:"
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing engine class name."
-msgstr ""
-"Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt engine class-namn."
+msgstr "FÃ¥r inte vara samma som ett befintligt engine class-namn."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing built-in type name."
-msgstr "Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt inbyggt typnamn."
+msgstr "FÃ¥r inte vara samma som ett befintligt inbyggt typ-namn."
#: editor/editor_autoload_settings.cpp
-#, fuzzy
msgid "Must not collide with an existing global constant name."
-msgstr ""
-"Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt global constant-namn."
+msgstr "FÃ¥r inte vara samma som ett befintligt globalt konstant-namn."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
@@ -1532,7 +1529,6 @@ msgid "Updating Scene"
msgstr "Uppdaterar Scen"
#: editor/editor_data.cpp
-#, fuzzy
msgid "Storing local changes..."
msgstr "Lagrar lokala ändringar..."
@@ -1541,18 +1537,16 @@ msgid "Updating scene..."
msgstr "Uppdaterar scen..."
#: editor/editor_data.cpp editor/editor_properties.cpp
-#, fuzzy
msgid "[empty]"
-msgstr "(tom)"
+msgstr "[tom]"
#: editor/editor_data.cpp
msgid "[unsaved]"
msgstr "[inte sparad]"
#: editor/editor_dir_dialog.cpp
-#, fuzzy
msgid "Please select a base directory first."
-msgstr "Vänligen välj en baskatalog först"
+msgstr "Vänligen välj en baskatalog först."
#: editor/editor_dir_dialog.cpp
msgid "Choose a Directory"
@@ -1639,21 +1633,20 @@ msgstr ""
"Etc 2' i Projektinställningarna."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for the driver fallback "
"to GLES2.\n"
"Enable 'Import Pvrtc' in Project Settings, or disable 'Driver Fallback "
"Enabled'."
msgstr ""
-"Målplattformen kräver 'ETC' texturkomprimering för GLES2. Aktivera 'Import "
-"Etc' i Projektinställningarna."
+"Målplattformen kräver 'ETC' texturkomprimering för GLES2.\n"
+"Aktivera 'Import Etc' i Projektinställningarna."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
msgid "Custom debug template not found."
-msgstr "Mallfil hittades inte:"
+msgstr "Mallfil hittades inte."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
@@ -1684,14 +1677,12 @@ msgid "Asset Library"
msgstr "Tillgångsbibliotek"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Scene Tree Editing"
-msgstr "Scenträd (Noder):"
+msgstr "Scenträd Redigering"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Node Dock"
-msgstr "Node Namn:"
+msgstr "Nod Docka"
#: editor/editor_feature_profile.cpp
#, fuzzy
@@ -1741,22 +1732,20 @@ msgid "Enable Contextual Editor"
msgstr "Aktivera kontextuell redigerare"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Properties:"
-msgstr "Egenskaper"
+msgstr "Egenskaper:"
#: editor/editor_feature_profile.cpp
msgid "Enabled Features:"
msgstr "Aktivera funktioner:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Enabled Classes:"
-msgstr "Sök Klasser"
+msgstr "Aktiverade Klasser:"
#: editor/editor_feature_profile.cpp
msgid "File '%s' format is invalid, import aborted."
-msgstr "Fil '%s''s format är ogiltig, import avbruten"
+msgstr "Fil '%s''s format är ogiltig, import avbruten."
#: editor/editor_feature_profile.cpp
msgid ""
@@ -1767,9 +1756,8 @@ msgstr ""
"avbruten."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Error saving profile to path: '%s'."
-msgstr "Fel vid laddning av mall '%s'"
+msgstr "Fel vid laddning av mall '%s'."
#: editor/editor_feature_profile.cpp
msgid "Unset"
@@ -1781,9 +1769,8 @@ msgid "Current Profile:"
msgstr "Nuvarande Version:"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Make Current"
-msgstr "Nuvarande:"
+msgstr "Gör till Nuvarande"
#: editor/editor_feature_profile.cpp
#: editor/plugins/animation_player_editor_plugin.cpp
@@ -1836,7 +1823,7 @@ msgstr "Exportera Projekt"
#: editor/editor_feature_profile.cpp
msgid "Manage Editor Feature Profiles"
-msgstr ""
+msgstr "Hantera Redigerarens Funktions Profiler"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Select Current Folder"
@@ -1852,7 +1839,7 @@ msgstr "Välj Denna Mapp"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "Copy Path"
-msgstr "Kopiera Sökvägen"
+msgstr "Kopiera Sökväg"
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
#, fuzzy
@@ -1946,33 +1933,28 @@ msgid "Move Favorite Down"
msgstr "Flytta Favorit Ner"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "Gå till överordnad mapp"
+msgstr "Gå till föregående mapp."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "Gå till överordnad mapp"
+msgstr "Gå till nästa mapp."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
msgstr "Gå till överordnad mapp."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "Sök Klasser"
+msgstr "Uppdatera filer."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "(Un)favorite current folder."
-msgstr "Kunde inte skapa mapp."
+msgstr "Ta bort nuvarande mapp från favoriter."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Toggle the visibility of hidden files."
-msgstr "Växla Dolda Filer"
+msgstr "Växla synligheten av dolda filer."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1998,13 +1980,15 @@ msgstr "Fil:"
#: editor/editor_file_system.cpp
msgid "ScanSources"
-msgstr "ScanSources"
+msgstr "ScanKällor"
#: editor/editor_file_system.cpp
msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Det finns flera importörer för olika typer som pekar på filen %s, import "
+"avbruten"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
@@ -2028,9 +2012,8 @@ msgid "Inherited by:"
msgstr "Ärvd av:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Beskrivning:"
+msgstr "Beskrivning"
#: editor/editor_help.cpp
#, fuzzy
@@ -2043,12 +2026,11 @@ msgstr "Egenskaper"
#: editor/editor_help.cpp
msgid "override:"
-msgstr ""
+msgstr "skriv över:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "Standard"
+msgstr "standard:"
#: editor/editor_help.cpp
msgid "Methods"
@@ -2068,9 +2050,8 @@ msgid "Constants"
msgstr "Konstanter"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "Egenskapsbeskrivning:"
+msgstr "Egenskapsbeskrivningar"
#: editor/editor_help.cpp
#, fuzzy
@@ -2086,9 +2067,8 @@ msgstr ""
"oss genom att [color=$color][url=$url]bidra med en[/url][/color]!"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Method Descriptions"
-msgstr "Metodbeskrivning:"
+msgstr "Metodbeskrivningar"
#: editor/editor_help.cpp
msgid ""
@@ -2183,15 +2163,15 @@ msgstr "Egenskaper"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
-msgstr ""
+msgstr "Egenskap:"
#: editor/editor_inspector.cpp
msgid "Set"
-msgstr ""
+msgstr "Sätt"
#: editor/editor_inspector.cpp
msgid "Set Multiple:"
-msgstr ""
+msgstr "Sätt Flera:"
#: editor/editor_log.cpp
msgid "Output:"
@@ -2213,9 +2193,8 @@ msgid "Clear"
msgstr "Rensa"
#: editor/editor_log.cpp
-#, fuzzy
msgid "Clear Output"
-msgstr "Output:"
+msgstr "Rensa Utdata"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
#: editor/editor_profiler.cpp
@@ -2225,11 +2204,11 @@ msgstr "Stanna"
#: editor/editor_network_profiler.cpp editor/editor_profiler.cpp
#: editor/plugins/animation_state_machine_editor.cpp editor/rename_dialog.cpp
msgid "Start"
-msgstr ""
+msgstr "Starta"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
#, fuzzy
@@ -2238,7 +2217,7 @@ msgstr "Ladda ner"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "Upp"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2246,27 +2225,27 @@ msgstr "Nod"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "Inkommande RPC"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "Inkommande RSET"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "Utgående RPC"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "Utgående RSET"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "Nytt Fönster"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
-msgstr ""
+msgstr "Importerade resurser kan inte sparas."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
@@ -2282,6 +2261,8 @@ msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
msgstr ""
+"Resursen kan inte sparas för att den inte hör inte till den redigerade "
+"scenen. Gör den unik först."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -2301,7 +2282,7 @@ msgstr "Fel vid sparande."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
msgid "Can't open '%s'. The file could have been moved or deleted."
-msgstr ""
+msgstr "Kan inte öppna '%s'. Filen kan ha flyttats eller tagits bort."
#: editor/editor_node.cpp
msgid "Error while parsing '%s'."
@@ -2340,6 +2321,8 @@ msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
+"Scenen kan inte sparas för att det finns en cyklisk instansnings inkusion.\n"
+"Försök lösa det och pröva sedan att spara igen."
#: editor/editor_node.cpp
#, fuzzy
@@ -2352,7 +2335,7 @@ msgstr ""
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "Can't overwrite scene that is still open!"
-msgstr ""
+msgstr "Kan inte skriva över en scen som fortfarande är öppen!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
@@ -2375,6 +2358,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Ett fel uppstod medans editor layouten sparades.\n"
+"Se till att editorns användardata sökväg är skriv tillgänglig."
#: editor/editor_node.cpp
msgid ""
@@ -2382,6 +2367,9 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Standard editor layouten överskriven.\n"
+"För att återställa Standard layouten till sina bas inställningar, använd "
+"Radera Layout valet och radera Standard Layouten."
#: editor/editor_node.cpp
msgid "Layout name not found!"
@@ -2389,7 +2377,7 @@ msgstr "Layoutnamn hittades inte!"
#: editor/editor_node.cpp
msgid "Restored the Default layout to its base settings."
-msgstr ""
+msgstr "Återställde Standard layouten till sina bas inställningar."
#: editor/editor_node.cpp
msgid ""
@@ -2448,7 +2436,7 @@ msgstr "Det finns ingen definierad scen att köra."
#: editor/editor_node.cpp
msgid "Save scene before running..."
-msgstr ""
+msgstr "Spara scenen innan du kör..."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
@@ -2492,7 +2480,7 @@ msgstr "Misslyckades att ladda resurs."
#: editor/editor_node.cpp
msgid "A root node is required to save the scene."
-msgstr ""
+msgstr "En root nod krävs för att spara scenen."
#: editor/editor_node.cpp
msgid "Save Scene As..."
@@ -2536,6 +2524,8 @@ msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"Den aktiva scenen har osparade ändringar.\n"
+"Vill du ladda om den ändå? Detta kan inte ångras."
#: editor/editor_node.cpp
#, fuzzy
@@ -2721,7 +2711,7 @@ msgstr "Stänga Övriga Flikar"
#: editor/editor_node.cpp
msgid "Close Tabs to the Right"
-msgstr ""
+msgstr "Stäng flikar till höger"
#: editor/editor_node.cpp
#, fuzzy
@@ -2746,7 +2736,7 @@ msgstr "%d fler filer"
#: editor/editor_node.cpp
msgid "Dock Position"
-msgstr ""
+msgstr "Dockposition"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
@@ -2836,7 +2826,7 @@ msgstr "Ã…ngra"
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
msgid "Redo"
-msgstr "Ã…ngra"
+msgstr "Återställ"
#: editor/editor_node.cpp
msgid "Miscellaneous project or scene-wide tools."
@@ -2848,45 +2838,40 @@ msgid "Project"
msgstr "Projekt"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Project Settings..."
-msgstr "Projektinställningar"
+msgstr "Projektinställningar..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
-#, fuzzy
msgid "Version Control"
-msgstr "Version:"
+msgstr "Versionshantering"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Ställ In Versionshantering"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Stäng Ner Versionshantering"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "Exportera"
+msgstr "Exportera..."
#: editor/editor_node.cpp
msgid "Install Android Build Template..."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Open Project Data Folder"
-msgstr "Öppna Projekthanteraren?"
+msgstr "Öppna Projekthanteraren"
#: editor/editor_node.cpp editor/plugins/tile_set_editor_plugin.cpp
msgid "Tools"
msgstr "Verktyg"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Orphan Resource Explorer..."
-msgstr "Föräldralös Resursutforskare"
+msgstr "Föräldralös Resursutforskare..."
#: editor/editor_node.cpp
msgid "Quit to Project List"
@@ -2895,7 +2880,7 @@ msgstr "Avsluta till Projektlistan"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/project_export.cpp
msgid "Debug"
-msgstr "Debugga"
+msgstr "Felsök"
#: editor/editor_node.cpp
msgid "Deploy with Remote Debug"
@@ -2927,7 +2912,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "Synliga Kollisionsformer"
#: editor/editor_node.cpp
msgid ""
@@ -2976,9 +2961,8 @@ msgid "Editor"
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Övergångar"
+msgstr "Redigerarinställningar..."
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2994,7 +2978,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
-msgstr "Fullskärm"
+msgstr "Växla Fullskärm"
#: editor/editor_node.cpp
#, fuzzy
@@ -3018,9 +3002,8 @@ msgid "Manage Editor Features..."
msgstr ""
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Export Templates..."
-msgstr "Mallar"
+msgstr "Hantera exportmallar..."
#: editor/editor_node.cpp editor/plugins/shader_editor_plugin.cpp
msgid "Help"
@@ -3186,11 +3169,12 @@ msgid "Open & Run a Script"
msgstr "Öppna & Kör ett Skript"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?"
-msgstr "Följande filer gick inte att packa upp från tillägget:"
+msgstr ""
+"Följande filer är nyare på disken.\n"
+"Vilka åtgärder ska vidtas?"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -3243,9 +3227,8 @@ msgid "Warning!"
msgstr "Varning!"
#: editor/editor_path.cpp
-#, fuzzy
msgid "No sub-resources found."
-msgstr "Resurser"
+msgstr "Inga underresurser hittades."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
@@ -3257,9 +3240,8 @@ msgid "Thumbnail..."
msgstr "Miniatyr..."
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Main Script:"
-msgstr "Öppna Skript"
+msgstr "Huvud Skript:"
#: editor/editor_plugin_settings.cpp
#, fuzzy
@@ -3288,9 +3270,8 @@ msgid "Status:"
msgstr "Status:"
#: editor/editor_plugin_settings.cpp
-#, fuzzy
msgid "Edit:"
-msgstr "Redigera"
+msgstr "Redigera:"
#: editor/editor_profiler.cpp
msgid "Measure:"
@@ -3325,18 +3306,16 @@ msgid "Frame #:"
msgstr ""
#: editor/editor_profiler.cpp
-#, fuzzy
msgid "Time"
-msgstr "Tid:"
+msgstr "Tid"
#: editor/editor_profiler.cpp
msgid "Calls"
msgstr ""
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "Redigera tema..."
+msgstr "Redigera Text:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
@@ -3355,9 +3334,8 @@ msgid "[Empty]"
msgstr ""
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Assign..."
-msgstr "Tilldela"
+msgstr "Tilldela..."
#: editor/editor_properties.cpp
#, fuzzy
@@ -3556,9 +3534,8 @@ msgid "No version.txt found inside templates."
msgstr ""
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error creating path for templates:"
-msgstr "Fel vid laddning av mall '%s'"
+msgstr "Fel vid skapande av sökväg för mallar:"
#: editor/export_template_manager.cpp
msgid "Extracting Export Templates"
@@ -3722,15 +3699,19 @@ msgid "Select mirror from list: (Shift+Click: Open in Browser)"
msgstr ""
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Favorites"
-msgstr "Favoriter:"
+msgstr "Favoriter"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3788,9 +3769,8 @@ msgid "Renaming folder:"
msgstr "Byter namn på mappen:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Duplicating file:"
-msgstr "Duplicera"
+msgstr "Duplicerar fil:"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3798,9 +3778,8 @@ msgid "Duplicating folder:"
msgstr "Byter namn på mappen:"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Inherited Scene"
-msgstr "Ny Ärvd Scen..."
+msgstr "Ny Ärvd Scen"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3817,9 +3796,8 @@ msgid "Instance"
msgstr "Instans"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Add to Favorites"
-msgstr "Favoriter:"
+msgstr "Lägg till i Favoriter"
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3841,14 +3819,12 @@ msgid "Move To..."
msgstr "Flytta Till..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Scene..."
-msgstr "Ny Scen"
+msgstr "Ny Scen..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "New Script..."
-msgstr "Nytt Skript"
+msgstr "Nytt Skript..."
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3868,9 +3844,8 @@ msgid "Collapse All"
msgstr "Stäng Alla"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Duplicate..."
-msgstr "Duplicera"
+msgstr "Duplicera..."
#: editor/filesystem_dock.cpp
#, fuzzy
@@ -3942,19 +3917,16 @@ msgid "Find in Files"
msgstr "%d fler filer"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Find:"
-msgstr "Hitta"
+msgstr "Hitta:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Folder:"
-msgstr "Skapa Mapp"
+msgstr "Mapp:"
#: editor/find_in_files.cpp
-#, fuzzy
msgid "Filters:"
-msgstr "Filtrera noder"
+msgstr "Filter:"
#: editor/find_in_files.cpp
msgid ""
@@ -3979,11 +3951,11 @@ msgstr "Avbryt"
#: editor/find_in_files.cpp
msgid "Find: "
-msgstr "Hitta:"
+msgstr "Hitta: "
#: editor/find_in_files.cpp
msgid "Replace: "
-msgstr "Ersätt:"
+msgstr "Ersätt: "
#: editor/find_in_files.cpp
#, fuzzy
@@ -4158,9 +4130,8 @@ msgid "Select Importer"
msgstr "Välj Node"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Importera"
+msgstr "Importör:"
#: editor/import_defaults_editor.cpp
#, fuzzy
@@ -4168,6 +4139,10 @@ msgid "Reset to Defaults"
msgstr "Ladda Standard"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Filer"
@@ -4258,9 +4233,8 @@ msgid "Load an existing resource from disk and edit it."
msgstr ""
#: editor/inspector_dock.cpp
-#, fuzzy
msgid "Save the currently edited resource."
-msgstr "Spara den nuvarande animationen"
+msgstr "Spara den nuvarande redigerade resursen."
#: editor/inspector_dock.cpp
msgid "Go to the previous edited object in history."
@@ -4315,14 +4289,12 @@ msgid "Subfolder:"
msgstr ""
#: editor/plugin_config_dialog.cpp editor/script_create_dialog.cpp
-#, fuzzy
msgid "Language:"
-msgstr "Språk"
+msgstr "Språk:"
#: editor/plugin_config_dialog.cpp
-#, fuzzy
msgid "Script Name:"
-msgstr "Skript giltigt"
+msgstr "Skript Namn:"
#: editor/plugin_config_dialog.cpp
msgid "Activate now?"
@@ -4337,9 +4309,8 @@ msgstr "Skapa Prenumeration"
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
-#, fuzzy
msgid "Create points."
-msgstr "Radera punkter"
+msgstr "Skapa punkter."
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid ""
@@ -4350,9 +4321,8 @@ msgstr ""
#: editor/plugins/abstract_polygon_2d_editor.cpp
#: editor/plugins/animation_blend_space_1d_editor.cpp
-#, fuzzy
msgid "Erase points."
-msgstr "Radera punkter"
+msgstr "Radera punkter."
#: editor/plugins/abstract_polygon_2d_editor.cpp
#, fuzzy
@@ -4385,9 +4355,8 @@ msgstr "Lägg till Animation"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Load..."
-msgstr "Ladda"
+msgstr "Ladda..."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4550,9 +4519,8 @@ msgid "Add Node to BlendTree"
msgstr ""
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Node Moved"
-msgstr "Node Namn:"
+msgstr "Nod Flyttad"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Unable to connect, port may be in use or connection may be invalid."
@@ -4587,9 +4555,8 @@ msgid "Delete Node(s)"
msgstr "Ta bort Nod(er)"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Toggle Filter On/Off"
-msgstr "Växla distraktionsfritt läge."
+msgstr "Växla Filter På/Av"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#, fuzzy
@@ -4617,9 +4584,8 @@ msgid "Anim Clips"
msgstr "Animklipp:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Ljudklipp:"
+msgstr "Ljudklipp"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Functions"
@@ -4627,21 +4593,18 @@ msgstr "Funktioner"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Node Renamed"
-msgstr "Node Namn:"
+msgstr "Nod har bytt Namn"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Node..."
-msgstr "Lägg Till Node"
+msgstr "Lägg Till Node..."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/root_motion_editor_plugin.cpp
-#, fuzzy
msgid "Edit Filtered Tracks:"
-msgstr "Redigera Filter"
+msgstr "Redigera Filtrerade Spår:"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#, fuzzy
@@ -4762,9 +4725,8 @@ msgid "Animation"
msgstr "Animation"
#: editor/plugins/animation_player_editor_plugin.cpp
-#, fuzzy
msgid "Edit Transitions..."
-msgstr "Övergångar"
+msgstr "Ändra Övergångar..."
#: editor/plugins/animation_player_editor_plugin.cpp
#, fuzzy
@@ -4932,14 +4894,12 @@ msgid ""
msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Create new nodes."
-msgstr "Skapa Ny"
+msgstr "Skapa nya noder."
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Connect nodes."
-msgstr "Anslut Noder"
+msgstr "Anslut noder."
#: editor/plugins/animation_state_machine_editor.cpp
#, fuzzy
@@ -4956,12 +4916,11 @@ msgstr ""
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Transition: "
-msgstr "Övergång:"
+msgstr "Övergång: "
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Play Mode:"
-msgstr "Raw-Läge"
+msgstr "Spel Läge:"
#: editor/plugins/animation_tree_editor_plugin.cpp
#: editor/plugins/animation_tree_player_editor_plugin.cpp
@@ -5549,9 +5508,8 @@ msgid "Full Rect"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Keep Ratio"
-msgstr "Skalnings förhållande:"
+msgstr "Behåll Förhållande"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
@@ -5865,9 +5823,8 @@ msgid "Scale mask for inserting keys."
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Insert keys (based on mask)."
-msgstr "Anim Infoga Nyckel"
+msgstr "Infoga nycklar (baserat på mask)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -6314,16 +6271,16 @@ msgid "Remove item %d?"
msgstr ""
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid ""
"Update from existing scene?:\n"
"%s"
-msgstr "Uppdatera från scen"
+msgstr ""
+"Uppdatera från existerande scen?:\n"
+"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
-#, fuzzy
msgid "Mesh Library"
-msgstr "MeshLibrary..."
+msgstr "MeshLibrary"
#: editor/plugins/mesh_library_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
@@ -6930,21 +6887,16 @@ msgid "Clear Recent Files"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Close and save changes?"
-msgstr ""
-"Stäng och spara ändringar?\n"
-"\""
+msgstr "Stäng och spara ändringar?"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error writing TextFile:"
-msgstr "Fel vid sparande av TileSet!"
+msgstr "Fel vid sparande av TextFil:"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Could not load file at:"
-msgstr "Fel - Kunde inte skapa Skript i filsystemet."
+msgstr "Kunde inte ladda filen vid:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6967,9 +6919,8 @@ msgid "Error importing theme."
msgstr "Fel vid sparande av scenen."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
-msgstr "Fel vid laddning:"
+msgstr "Fel vid Importering"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7077,9 +7028,8 @@ msgid "File"
msgstr "Fil"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "Öppen"
+msgstr "Öppna..."
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -7114,9 +7064,8 @@ msgid "Theme"
msgstr "Tema"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Import Theme..."
-msgstr "Importera Tema"
+msgstr "Importera Tema..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Reload Theme"
@@ -7172,9 +7121,8 @@ msgid "Debug with External Editor"
msgstr ""
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open Godot online documentation."
-msgstr "Öppna Senaste"
+msgstr "Öppna Godot online dokumentation."
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
@@ -7218,33 +7166,30 @@ msgid "Connections to method:"
msgstr "Anslut Till Node:"
#: editor/plugins/script_text_editor.cpp editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source"
-msgstr "Källa:"
+msgstr "Källa"
#: editor/plugins/script_text_editor.cpp
msgid "Target"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid ""
"Missing connected method '%s' for signal '%s' from node '%s' to node '%s'."
-msgstr "Anslut '%s' till '%s'"
+msgstr ""
+"Saknar ansluten metod '%s' för signalen '%s' från noden '%s' till noden '%s'."
#: editor/plugins/script_text_editor.cpp
msgid "[Ignore]"
msgstr ""
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Line"
-msgstr "Rad:"
+msgstr "Rad"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function"
-msgstr "Funktion:"
+msgstr "GÃ¥ till Funktion"
#: editor/plugins/script_text_editor.cpp
msgid "Only resources from filesystem can be dropped."
@@ -7397,14 +7342,12 @@ msgid "Remove All Bookmarks"
msgstr "Ta bort Alla"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function..."
-msgstr "Ta bort Funktion"
+msgstr "GÃ¥ till Funktion..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Line..."
-msgstr "GÃ¥ till Rad"
+msgstr "GÃ¥ till Rad..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
@@ -7862,9 +7805,8 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
-#, fuzzy
msgid "Settings..."
-msgstr "Inställningar"
+msgstr "Inställningar..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
@@ -8034,9 +7976,8 @@ msgid "Update Preview"
msgstr "Förhandsgranska"
#: editor/plugins/sprite_editor_plugin.cpp
-#, fuzzy
msgid "Settings:"
-msgstr "Inställningar"
+msgstr "Inställningar:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -8052,9 +7993,8 @@ msgid "Add Frame"
msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Unable to load images"
-msgstr "Misslyckades att ladda resurs."
+msgstr "Det gick inte att läsa in bilder"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
@@ -8086,9 +8026,8 @@ msgid "Move Frame"
msgstr "Flytta Nod(er)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "Animationer"
+msgstr "Animationer:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -8109,9 +8048,8 @@ msgid "Animation Frames:"
msgstr "Nytt Animationsnamn:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Add a Texture from File"
-msgstr "Flytta nuvarande spår upp."
+msgstr "Lägg till en Textur från en Fil"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frames from a Sprite Sheet"
@@ -8222,9 +8160,8 @@ msgid "Remove All"
msgstr "Ta bort Alla"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "Redigera tema..."
+msgstr "Redigera Tema"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
@@ -8371,9 +8308,8 @@ msgid "Erase Selection"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Fix Invalid Tiles"
-msgstr "Ogiltigt namn."
+msgstr "Fixa Ogiltiga Tiles"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -8595,19 +8531,16 @@ msgid "Copy bitmask."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste bitmask."
-msgstr "Klistra in Animation"
+msgstr "Klistra in bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Erase bitmask."
-msgstr "Radera punkter"
+msgstr "Radera bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new rectangle."
-msgstr "Skapa Ny"
+msgstr "Skapa en ny rektangel."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8615,9 +8548,8 @@ msgid "New Rectangle"
msgstr "Ny Scen"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "Skapa Prenumeration"
+msgstr "Skapa en ny polygon."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8684,25 +8616,28 @@ msgid "Delete selected Rect."
msgstr "Ta bort valda filer?"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select current edited sub-tile.\n"
"Click on another Tile to edit it."
-msgstr "Skapa Mapp"
+msgstr ""
+"Markera nuvarande redigerad sub-tile.\n"
+"Klicka på en annan Tile för att redigera den."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "Radera punkter"
+msgstr "Radera polygon."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"LMB: Set bit on.\n"
"RMB: Set bit off.\n"
"Shift+LMB: Set wildcard bit.\n"
"Click on another Tile to edit it."
-msgstr "Skapa Mapp"
+msgstr ""
+"LMB: Aktivera bit.\n"
+"RMB: Avaktivera bit.\n"
+"Shift+LMB: Aktivera vildkorts bit.\n"
+"Klicka på en annan Tile för att redigera den."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8718,11 +8653,12 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid ""
"Select sub-tile to change its z index.\n"
"Click on another Tile to edit it."
-msgstr "Skapa Mapp"
+msgstr ""
+"Välj sub-tile för att ändra dess z-index.\n"
+"Klicka på en annan Tile för att redigera den."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Set Tile Region"
@@ -8829,9 +8765,8 @@ msgid "This property can't be changed."
msgstr "Åtgärden kan inte göras utan en scen."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "TileSet"
-msgstr "TileSet..."
+msgstr "TileSet"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No VCS addons are available."
@@ -8932,14 +8867,12 @@ msgid "(GLES3 only)"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add Output"
-msgstr "Output:"
+msgstr "Lägg till Utdata"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "Skala:"
+msgstr "Skalär"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector"
@@ -8954,9 +8887,8 @@ msgid "Sampler"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Add input port"
-msgstr "Favoriter:"
+msgstr "Lägg till inmatningsport"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
@@ -8972,9 +8904,8 @@ msgid "Change output port type"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Change input port name"
-msgstr "Ändra Animationsnamn:"
+msgstr "Ändra inmatningsport namn"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Change output port name"
@@ -8991,9 +8922,8 @@ msgid "Remove output port"
msgstr "Ta Bort Mall"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Set expression"
-msgstr "Nuvarande Version:"
+msgstr "Ställ in uttryck"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Resize VisualShader node"
@@ -9012,9 +8942,8 @@ msgid "Add Node to Visual Shader"
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Node(s) Moved"
-msgstr "Node Namn:"
+msgstr "Nod(er) Flyttade"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9054,9 +8983,8 @@ msgid "Light"
msgstr "Höger"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Show resulted shader code."
-msgstr "Skapa Node"
+msgstr "Visa den resulterande skuggningskoden."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9064,18 +8992,16 @@ msgid "Create Shader Node"
msgstr "Skapa Node"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color function."
-msgstr "Funktion:"
+msgstr "Färg funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Color operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Grayscale function."
-msgstr "Skapa Funktion"
+msgstr "Gråskala funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
@@ -9086,9 +9012,8 @@ msgid "Converts RGB vector to HSV equivalent."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Byt namn på funktion"
+msgstr "Sepia funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
@@ -9127,14 +9052,12 @@ msgid "SoftLight operator."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color constant."
-msgstr "Konstant"
+msgstr "Färg konstant."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Color uniform."
-msgstr "Transformera"
+msgstr "Färg enhetlig."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
@@ -9243,9 +9166,8 @@ msgid "'%s' input parameter for vertex and fragment shader mode."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar function."
-msgstr "Skala urval"
+msgstr "Skalär funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar operator."
@@ -9478,9 +9400,8 @@ msgid "Scalar constant."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar uniform."
-msgstr "Transformera"
+msgstr "Skalär uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Perform the cubic texture lookup."
@@ -9503,9 +9424,8 @@ msgid "2D texture uniform lookup with triplanar."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform function."
-msgstr "Transformera"
+msgstr "Transformera funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9547,19 +9467,16 @@ msgid "Multiplies vector by transform."
msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform constant."
-msgstr "Transformera"
+msgstr "Transformera konstant."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Transform uniform."
-msgstr "Transformera"
+msgstr "Transformera uniform."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Ta bort Funktion"
+msgstr "Vektor funktion."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
@@ -9800,9 +9717,8 @@ msgid "Exporting All"
msgstr "Exportera"
#: editor/project_export.cpp
-#, fuzzy
msgid "The given export path doesn't exist:"
-msgstr "Sökvägen finns inte."
+msgstr "Den angivna export vägen finns inte:"
#: editor/project_export.cpp
msgid "Export templates for this platform are missing/corrupted:"
@@ -9881,9 +9797,8 @@ msgid "Script"
msgstr "Nytt Skript"
#: editor/project_export.cpp
-#, fuzzy
msgid "Script Export Mode:"
-msgstr "Exportera Projekt"
+msgstr "Skript Exporterings Läge:"
#: editor/project_export.cpp
msgid "Text"
@@ -9980,9 +9895,8 @@ msgid "Imported Project"
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "Invalid Project Name."
-msgstr "Projektnamn:"
+msgstr "Ogiltigt projektnamn."
#: editor/project_manager.cpp
#, fuzzy
@@ -10115,9 +10029,8 @@ msgid "Error: Project is missing on the filesystem."
msgstr ""
#: editor/project_manager.cpp
-#, fuzzy
msgid "Can't open project at '%s'."
-msgstr "Kan inte öppna projekt"
+msgstr "Kan inte öppna projekt vid '%s'."
#: editor/project_manager.cpp
msgid "Are you sure to open more than one project?"
@@ -10299,9 +10212,8 @@ msgid "Rename Input Action Event"
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Change Action deadzone"
-msgstr "Ändra Animationsnamn:"
+msgstr "Ändra Åtgärdens Dödzon"
#: editor/project_settings_editor.cpp
msgid "Add Input Action Event"
@@ -10670,9 +10582,8 @@ msgid "Suffix:"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "Nuvarande Version:"
+msgstr "Använd Vanliga Uttryck"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10684,18 +10595,16 @@ msgid "Substitute"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node name"
-msgstr "Node Namn:"
+msgstr "Nod namn"
#: editor/rename_dialog.cpp
msgid "Node's parent name, if available"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Node type"
-msgstr "Node Namn:"
+msgstr "Nod typ"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10726,9 +10635,8 @@ msgid "Initial value for the counter"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Step"
-msgstr "Steg (s):"
+msgstr "Steg"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
@@ -10785,9 +10693,8 @@ msgid "Regular Expression Error:"
msgstr "Nuvarande Version:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "At character %s"
-msgstr "Giltiga tecken:"
+msgstr "Vid tecken %s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
@@ -10898,14 +10805,12 @@ msgid "Make node as Root"
msgstr "Gör nod som Rot"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes and any children?"
-msgstr "Ta bort Nod(er)"
+msgstr "Ta bort %d noder och alla barn?"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete %d nodes?"
-msgstr "Ta bort Nod(er)"
+msgstr "Ta bort %d noder?"
#: editor/scene_tree_dock.cpp
msgid "Delete the root node \"%s\"?"
@@ -10916,9 +10821,8 @@ msgid "Delete node \"%s\" and its children?"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Delete node \"%s\"?"
-msgstr "Ta bort Nod(er)"
+msgstr "Ta bort nod \"%s\"?"
#: editor/scene_tree_dock.cpp
msgid "Can not perform with the root node."
@@ -10955,9 +10859,8 @@ msgid "New Scene Root"
msgstr "Ny Scenrot"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Create Root Node:"
-msgstr "Skapa Node"
+msgstr "Skapa Rot Nod:"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -11049,7 +10952,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Add Child Node"
-msgstr "Lägg till Barn-Node"
+msgstr "Lägg till Barn-Nod"
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -11079,16 +10982,15 @@ msgstr ""
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Copy Node Path"
-msgstr "Kopiera Node-Sökväg"
+msgstr "Kopiera Nod-Sökväg"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
msgstr ""
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Add/Create a New Node."
-msgstr "Lägga till/Skapa en Ny Node"
+msgstr "Lägg till/Skapa en Ny Node."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -11161,9 +11063,8 @@ msgid ""
msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Öppna Skript"
+msgstr "Öppna Skript:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -11172,13 +11073,12 @@ msgid ""
msgstr ""
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid ""
"Children are not selectable.\n"
"Click to make selectable."
msgstr ""
"Barn är inte valbara.\n"
-"Klicka för att göra valbara"
+"Klicka för att göra valbara."
#: editor/scene_tree_editor.cpp
msgid "Toggle Visibility"
@@ -11211,14 +11111,12 @@ msgid "Select a Node"
msgstr "Välj en Node"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Path is empty."
-msgstr "Sökvägen är tom"
+msgstr "Sökvägen är tom."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Filename is empty."
-msgstr "Sökvägen är tom"
+msgstr "Filnamn är tom."
#: editor/script_create_dialog.cpp
msgid "Path is not local."
@@ -11230,9 +11128,8 @@ msgid "Invalid base path."
msgstr "Ogiltig Sökväg."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "A directory with the same name exists."
-msgstr "Katalog med samma namn finns redan"
+msgstr "Katalog med samma namn finns redan."
#: editor/script_create_dialog.cpp
msgid "File does not exist."
@@ -11296,14 +11193,12 @@ msgid "Invalid inherited parent name or path."
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Script path/name is valid."
-msgstr "Skript giltigt"
+msgstr "Skript väg/namn är ogiltigt."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
-msgstr "Tillåtna: a-z, a-Z, 0-9 och _"
+msgstr "Tillåtna: a-z, A-Z, 0-9, _ och ."
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11311,14 +11206,12 @@ msgid "Built-in script (into scene file)."
msgstr "Åtgärder med scenfiler."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will create a new script file."
-msgstr "Skapa ny Skript-fil"
+msgstr "Kommer att skapa ny skript-fil."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Will load an existing script file."
-msgstr "Ladda in befintlig Skript-fil"
+msgstr "Kommer att ladda en befintlig Skript-fil."
#: editor/script_create_dialog.cpp
msgid "Script file already exists."
@@ -11331,19 +11224,16 @@ msgid ""
msgstr ""
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "Klassnamn"
+msgstr "Klassnamn:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Template:"
-msgstr "Mall"
+msgstr "Mall:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in Script:"
-msgstr "Öppna Skript"
+msgstr "Inbyggd Skript:"
#: editor/script_create_dialog.cpp
msgid "Attach Node Script"
@@ -11358,9 +11248,8 @@ msgid "Bytes:"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Warning:"
-msgstr "Varning"
+msgstr "Varning:"
#: editor/script_editor_debugger.cpp
msgid "Error:"
@@ -11377,9 +11266,8 @@ msgid "C++ Error:"
msgstr "Fel:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Source"
-msgstr "Källa:"
+msgstr "C++ Källa"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11400,9 +11288,8 @@ msgid "Errors"
msgstr "Fel"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Child process connected."
-msgstr "Barnprocess Ansluten"
+msgstr "Barnprocess ansluten."
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11615,9 +11502,8 @@ msgid "Select dependencies of the library for this entry"
msgstr ""
#: modules/gdnative/gdnative_library_editor_plugin.cpp
-#, fuzzy
msgid "Remove current entry"
-msgstr "Flytta nuvarande spår upp."
+msgstr "Ta bort aktuell post"
#: modules/gdnative/gdnative_library_editor_plugin.cpp
msgid "Double click to create a new entry"
@@ -11849,18 +11735,16 @@ msgid "Generate buffers"
msgstr ""
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Direct lighting"
-msgstr "Sektioner:"
+msgstr "Direkt ljus"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Indirect lighting"
msgstr ""
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
-msgstr "Nuvarande Version:"
+msgstr "Efterbehandling"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
#, fuzzy
@@ -11986,14 +11870,12 @@ msgid "Set Variable Type"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "Favoriter:"
+msgstr "Lägg till Ingångsport"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "Favoriter:"
+msgstr "Lägg till Utgångsport"
#: modules/visual_script/visual_script_editor.cpp
#, fuzzy
@@ -12001,27 +11883,24 @@ msgid "Override an existing built-in function."
msgstr "Ogiltigt namn. FÃ¥r inte vara samma som ett befintligt inbyggt typnamn."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new function."
-msgstr "Skapa Ny"
+msgstr "Skapa en ny funktion."
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
msgstr "Variabler:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new variable."
-msgstr "Skapa Ny"
+msgstr "Skapa en ny variabel."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "Signaler:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "Skapa Prenumeration"
+msgstr "Skapa en ny signal."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
@@ -12226,33 +12105,28 @@ msgid "Editing Signal:"
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Tool:"
-msgstr "Gör Patch"
+msgstr "Skapa Verktyg:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Members:"
msgstr "Medlemmar:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "Ändra Typ"
+msgstr "Ändra Bas Typ:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Nodes..."
-msgstr "Lägg Till Node"
+msgstr "Lägg Till Noder..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "Lägg till Funktion"
+msgstr "Lägg till Funktion..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "Funktioner:"
+msgstr "funktions_namn"
#: modules/visual_script/visual_script_editor.cpp
msgid "Select or create a function to edit its graph."
@@ -12436,9 +12310,8 @@ msgid "Invalid public key for APK expansion."
msgstr ""
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "Ogiltigt namn."
+msgstr "Ogiltigt paket namn:"
#: platform/android/export/export.cpp
msgid ""
@@ -12529,9 +12402,8 @@ msgid "App Store Team ID not specified - cannot configure the project."
msgstr ""
#: platform/iphone/export/export.cpp
-#, fuzzy
msgid "Invalid Identifier:"
-msgstr "Ogiltig teckenstorlek."
+msgstr "Ogiltig identifierare:"
#: platform/iphone/export/export.cpp
msgid "Required icon is not specified in the preset."
@@ -12554,9 +12426,8 @@ msgid "Could not write file:"
msgstr "Kunde inte skriva till filen:"
#: platform/javascript/export/export.cpp
-#, fuzzy
msgid "Could not open template for export:"
-msgstr "Kunde inte skapa mapp."
+msgstr "Kunde inte öppna mall för export:"
#: platform/javascript/export/export.cpp
msgid "Invalid export template:"
@@ -12590,14 +12461,12 @@ msgid "Invalid package publisher display name."
msgstr "Ogiltigt namn."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid product GUID."
-msgstr "Projektnamn:"
+msgstr "Ogiltig produkt GUID."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid publisher GUID."
-msgstr "Ogiltig Sökväg"
+msgstr "Ogiltigt GUID utgivare."
#: platform/uwp/export/export.cpp
#, fuzzy
@@ -12848,9 +12717,8 @@ msgid ""
msgstr ""
#: scene/3d/arvr_nodes.cpp
-#, fuzzy
msgid "ARVROrigin requires an ARVRCamera child node."
-msgstr "ARVROrigin kräver en ARVRCamera Barn-Node"
+msgstr "ARVROrigin kräver en ARVRCamera Barn-Node."
#: scene/3d/baked_lightmap.cpp
msgid "Finding meshes and lights"
@@ -12875,9 +12743,8 @@ msgid "Saving lightmaps"
msgstr "Genererar Lightmaps"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Done"
-msgstr "Klar!"
+msgstr "Klar"
#: scene/3d/collision_object.cpp
msgid ""
@@ -13088,9 +12955,8 @@ msgid "Invalid animation: '%s'."
msgstr "Ogiltig animation: '%s'."
#: scene/animation/animation_tree.cpp
-#, fuzzy
msgid "Nothing connected to input '%s' of node '%s'."
-msgstr "Anslut '%s' till '%s'"
+msgstr "Inget anslutet till inmatning '%s' av nod '%s'."
#: scene/animation/animation_tree.cpp
msgid "No root AnimationNode for the graph is set."
@@ -13137,9 +13003,8 @@ msgid "Switch between hexadecimal and code values."
msgstr ""
#: scene/gui/color_picker.cpp
-#, fuzzy
msgid "Add current color as a preset."
-msgstr "Lägg till nuvarande färg som en förinställning"
+msgstr "Lägg till nuvarande färg som en förinställning."
#: scene/gui/container.cpp
msgid ""
diff --git a/editor/translations/ta.po b/editor/translations/ta.po
index 9f9f40b54b..0fbcb5c3eb 100644
--- a/editor/translations/ta.po
+++ b/editor/translations/ta.po
@@ -3527,6 +3527,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3921,6 +3926,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/te.po b/editor/translations/te.po
index 50c0fb5a4b..de9f84e3a4 100644
--- a/editor/translations/te.po
+++ b/editor/translations/te.po
@@ -3497,6 +3497,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3887,6 +3892,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 76a2d3c125..4ac8875aa6 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -4,7 +4,7 @@
# This file is distributed under the same license as the Godot source code.
# Kaveeta Vivatchai <goodytong@gmail.com>, 2017.
# Poommetee Ketson (Noshyaar) <poommetee@protonmail.com>, 2017-2018.
-# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020.
+# Thanachart Monpassorn <nunf_2539@hotmail.com>, 2020, 2021.
# Anonymous <noreply@weblate.org>, 2020.
# Lon3r <mptube.p@gmail.com>, 2020.
# Kongfa Warorot <gongpha@hotmail.com>, 2020, 2021.
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-02-15 10:51+0000\n"
-"Last-Translator: Kongfa Warorot <gongpha@hotmail.com>\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
+"Last-Translator: Thanachart Monpassorn <nunf_2539@hotmail.com>\n"
"Language-Team: Thai <https://hosted.weblate.org/projects/godot-engine/godot/"
"th/>\n"
"Language: th\n"
@@ -21,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2489,9 +2489,8 @@ msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
msgstr "ไม่สามารถเปิดใช้งานปลั๊à¸à¸­à¸´à¸™: '%s'"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Unable to find script field for addon plugin at: '%s'."
-msgstr "ไม่พบชื่อสคริปต์ในปลั๊à¸à¸­à¸´à¸™: 'res://addons/%s'"
+msgstr "ไม่พบไฟล์สคริปต์สำหรับปลั๊à¸à¸­à¸´à¸™à¸—ี่: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -3069,13 +3068,12 @@ msgid "Open & Run a Script"
msgstr "เปิดà¹à¸¥à¸°à¸£à¸±à¸™à¸ªà¸„ริปต์"
#: editor/editor_node.cpp
-#, fuzzy
msgid ""
"The following files are newer on disk.\n"
"What action should be taken?"
msgstr ""
-"ไฟล์ต่อไปนี้ในดิสà¸à¹Œà¹ƒà¸«à¸¡à¹ˆà¸à¸§à¹ˆà¸²\n"
-"จะทำอย่างไรต่อไป?:"
+"ไฟล์เหล่านี้มีความใหม่à¸à¸§à¹ˆà¸²à¸šà¸™à¸”ิสà¸à¹Œ\n"
+"ต้องจะทำอย่างไรต่อไป?"
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: editor/plugins/shader_editor_plugin.cpp
@@ -3603,6 +3601,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "สถานะ: นำเข้าไฟล์ล้มเหลว à¸à¸£à¸¸à¸“าà¹à¸à¹‰à¹„ขไฟล์à¹à¸¥à¸°à¸™à¸³à¹€à¸‚้าใหม่"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr "à¸à¸²à¸£à¸™à¸³à¹€à¸‚้าไฟล์นี้ถูà¸à¸›à¸´à¸”, ดังนั้นจึงไม่สามารถเปิดเพื่อà¹à¸à¹‰à¹„ขใดๆได้"
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "ไม่สามารถย้าย/เปลี่ยนชื่อโฟลเดอร์ราà¸"
@@ -3988,19 +3991,20 @@ msgid "Saving..."
msgstr "à¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึà¸..."
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Select Importer"
-msgstr "โหมดเลือà¸"
+msgstr "เลือà¸à¸•ัวนำเข้า"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "นำเข้า"
+msgstr "ตัวนำเข้า:"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Reset to Defaults"
-msgstr "โหลดค่าเริ่มต้น"
+msgstr "รีเซ็ตเป็นค่าเริ่มต้น"
+
+#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "เà¸à¹‡à¸šà¹„ฟล์ (ไม่นำเข้า)"
#: editor/import_dock.cpp
msgid "%d Files"
@@ -4957,9 +4961,8 @@ msgid "Got:"
msgstr "ที่ได้รับ:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Failed SHA-256 hash check"
-msgstr "ผิดพลาดในà¸à¸²à¸£à¸•รวจสอบà¹à¸®à¸Š SHA256"
+msgstr "ผิดพลาดในà¸à¸²à¸£à¸•รวจสอบà¹à¸®à¸Š SHA-256"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5090,13 +5093,12 @@ msgid "Assets ZIP File"
msgstr "ทรัพยาà¸à¸£à¹„ฟล์ ZIP"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid ""
"Can't determine a save path for lightmap images.\n"
"Save your scene and try again."
msgstr ""
-"ไม่สามารถเลือà¸à¸•ำà¹à¸«à¸™à¹ˆà¸‡à¸—ี่จะบันทึà¸à¸ à¸²à¸ž lightmap\n"
-"à¸à¸£à¸¸à¸“าบันทึà¸à¸‰à¸²à¸ (เพื่อบันทึà¸à¸ à¸²à¸žà¹ƒà¸™à¹‚ฟลเดอร์เดียวà¸à¸±à¸™) หรือระบุตำà¹à¸«à¸™à¹ˆà¸‡à¹ƒà¸™à¸„ุณสมบัติของ BakedLightmap"
+"ไม่สามารถà¸à¸³à¸«à¸™à¸”ตำà¹à¸«à¸™à¹ˆà¸‡à¸à¸²à¸£à¸šà¸±à¸™à¸—ึà¸à¸ªà¸³à¸«à¸£à¸±à¸šà¸ à¸²à¸ž lightmap\n"
+"ลองบันทึà¸à¸‰à¸²à¸à¸‚องคุณà¹à¸¥à¹‰à¸§à¸¥à¸­à¸‡à¸­à¸µà¸à¸„รั้ง"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
@@ -5111,27 +5113,28 @@ msgstr "ผิดพลาดขณะสร้างภาพ lightmap à¸à¸£à¸
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Failed determining lightmap size. Maximum lightmap size too small?"
-msgstr ""
+msgstr "à¸à¸²à¸£à¸à¸³à¸«à¸™à¸”ขนาด lightmap ล้มเหลว ขนาด lightmap สูงสุดเล็à¸à¹€à¸à¸´à¸™à¹„ป?"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Some mesh is invalid. Make sure the UV2 channel values are contained within "
"the [0.0,1.0] square region."
-msgstr ""
+msgstr "mesh บางส่วนไม่ถูà¸à¸•้อง ตรวจสอบให้à¹à¸™à¹ˆà¹ƒà¸ˆà¸§à¹ˆà¸²à¸„่า UV2 อยู่ในพื้นที่สี่เหลี่ยม [0.0,1.0]"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid ""
"Godot editor was built without ray tracing support, lightmaps can't be baked."
msgstr ""
+"เอดิเตอร์ Godot ถูà¸à¸ªà¸£à¹‰à¸²à¸‡à¹‚ดยไม่ได้สนับสนุน ray tracing ดังนั้นจึงไม่สามารถ bake lightmaps "
+"ได้"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
msgid "Bake Lightmaps"
msgstr "สร้าง Lightmaps"
#: editor/plugins/baked_lightmap_editor_plugin.cpp
-#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "เลือà¸à¹„ฟล์เทมเพลต"
+msgstr "เลือà¸à¹„ฟล์ bake ของ lightmap :"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -6211,9 +6214,8 @@ msgid "Can only set point into a ParticlesMaterial process material"
msgstr "สามารถà¸à¸³à¸«à¸™à¸”จุดให้à¹à¸à¹ˆ ParticlesMaterial เท่านั้น"
#: editor/plugins/particles_2d_editor_plugin.cpp
-#, fuzzy
msgid "Convert to CPUParticles2D"
-msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles"
+msgstr "à¹à¸›à¸¥à¸‡à¹€à¸›à¹‡à¸™ CPUParticles2D"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
@@ -7238,9 +7240,8 @@ msgid "Yaw"
msgstr "Yaw"
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Size"
-msgstr "ขนาด: "
+msgstr "ขนาด"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -9876,9 +9877,8 @@ msgid "Projects"
msgstr "โปรเจà¸à¸•์"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Loading, please wait..."
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸£à¸µà¸¢à¸à¸‚้อมูล โปรดรอ..."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹‚หลด โปรดรอ..."
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -10246,9 +10246,8 @@ msgid "Plugins"
msgstr "ปลั๊à¸à¸­à¸´à¸™"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Import Defaults"
-msgstr "โหลดค่าเริ่มต้น"
+msgstr "นำเข้าค่าเริ่มต้น"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -10497,12 +10496,10 @@ msgid "Instance Child Scene"
msgstr "อินสà¹à¸•นซ์ฉาà¸à¸¥à¸¹à¸"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't paste root node into the same scene."
-msgstr "ทำà¸à¸±à¸šà¹‚หนดของฉาà¸à¸­à¸·à¹ˆà¸™à¹„ม่ได้!"
+msgstr "ไม่สามารถวางโหนดราà¸à¹ƒà¸™à¸‰à¸²à¸à¹€à¸”ียวà¸à¸±à¸™"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Paste Node(s)"
msgstr "วางโหนด"
@@ -10632,7 +10629,6 @@ msgid "Attach Script"
msgstr "à¹à¸™à¸šà¸ªà¸„ริปต์"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Cut Node(s)"
msgstr "ตัดโหนด"
@@ -11437,36 +11433,31 @@ msgstr "มอบทรัพยาà¸à¸£ MeshLibrary ให้à¸à¸±à¸š GridMap
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Begin Bake"
-msgstr ""
+msgstr "เริ่มต้น Bake"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Preparing data structures"
-msgstr ""
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸•รียมโครงสร้างข้อมูล"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Generate buffers"
-msgstr "สร้าง AABB"
+msgstr "สร้างบัฟเฟอร์"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Direct lighting"
-msgstr "ทิศทาง"
+msgstr "lighting à¹à¸šà¸šà¸•รง"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Indirect lighting"
-msgstr "ย่อหน้าขวา"
+msgstr "lighting à¹à¸šà¸šà¸­à¹‰à¸­à¸¡"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
msgstr "หลังประมวลผล"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Plotting lightmaps"
-msgstr "วางà¹à¸™à¸§à¹à¸ªà¸‡:"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸žà¸¥à¹‡à¸­à¸• lightmaps"
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
@@ -11966,9 +11957,8 @@ msgid "Select device from the list"
msgstr "เลือà¸à¸­à¸¸à¸›à¸à¸£à¸“์จาà¸à¸£à¸²à¸¢à¸Šà¸·à¹ˆà¸­"
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Unable to find the 'apksigner' tool."
-msgstr "ไม่สามารถหา zipalign tool"
+msgstr "ไม่สามารถหาเครื่องมือ 'apksigner'"
#: platform/android/export/export.cpp
msgid ""
@@ -11985,14 +11975,12 @@ msgid "Release keystore incorrectly configured in the export preset."
msgstr "Release keystore à¸à¸³à¸«à¸™à¸”ค่าไว้อย่างไม่ถูà¸à¸•้องในพรีเซ็ตสำหรับà¸à¸²à¸£à¸ªà¹ˆà¸‡à¸­à¸­à¸"
#: platform/android/export/export.cpp
-#, fuzzy
msgid "A valid Android SDK path is required in Editor Settings."
-msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+msgstr "ต้องà¸à¸²à¸£à¸—ี่อยู่ของ Android SDK ที่ถูà¸à¸•้อง ในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid Android SDK path in Editor Settings."
-msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+msgstr "ที่อยู่ Android SDK ไม่ถูà¸à¸•้องในตั้งค่าของเอดิเตอร์"
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
@@ -12000,12 +11988,11 @@ msgstr "ไดเร็à¸à¸—อรี 'platform-tools' หายไป!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK platform-tools' adb command."
-msgstr ""
+msgstr "ไม่พบคำสั่ง adb ของ Android SDK platform-tools"
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Please check in the Android SDK directory specified in Editor Settings."
-msgstr "ที่อยู่ Android SDK ผิดพลาดสำหรับà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸šà¸à¸³à¸«à¸™à¸”เองในà¸à¸²à¸£à¸•ั้งค่าเอดิเตอร์"
+msgstr "โปรดตรวจสอบในไดเร็à¸à¸—อรี Android SDK ที่ระบุใตัวตั้งค่าของเอดิเตอร์"
#: platform/android/export/export.cpp
msgid "Missing 'build-tools' directory!"
@@ -12013,7 +12000,7 @@ msgstr "ไดเร็à¸à¸—อรี 'build-tools' หายไป!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK build-tools' apksigner command."
-msgstr ""
+msgstr "ไม่พบคำสั่ง apksigner ของ Android SDK build-tools"
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
@@ -12261,11 +12248,11 @@ msgstr "CollisionPolygon2D ที่ว่างเปล่าจะไม่à¸
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
-msgstr ""
+msgstr "โพลีà¸à¸­à¸™à¹„ม่ถูà¸à¸•้อง ต้องมีอย่างน้อย 3 จุด ในโหมดà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸š 'Solids'"
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
-msgstr ""
+msgstr "โพลีà¸à¸­à¸™à¹„ม่ถูà¸à¸•้อง ต้องมีอย่างน้อย 2 จุด ในโหมดà¸à¸²à¸£à¸ªà¸£à¹‰à¸²à¸‡à¹à¸šà¸š 'Segments'"
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12454,27 +12441,23 @@ msgstr "ARVROrigin จำเป็นต้องมี ARVRCamera เป็นà
#: scene/3d/baked_lightmap.cpp
msgid "Finding meshes and lights"
-msgstr ""
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸«à¸² meshes à¹à¸¥à¸° lights"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing geometry (%d/%d)"
-msgstr "วิเคราะห์พื้นผิว..."
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸•รียมรูปเรขาคณิต (%d/%d)"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Preparing environment"
-msgstr "à¹à¸ªà¸”งสภาพà¹à¸§à¸”ล้อม"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¹€à¸•รียมสภาพà¹à¸§à¸”ล้อม"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Generating capture"
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ capture"
#: scene/3d/baked_lightmap.cpp
-#, fuzzy
msgid "Saving lightmaps"
-msgstr "à¸à¸³à¸¥à¸±à¸‡à¸ªà¸£à¹‰à¸²à¸‡ Lightmaps"
+msgstr "à¸à¸³à¸¥à¸±à¸‡à¸šà¸±à¸™à¸—ึภlightmaps"
#: scene/3d/baked_lightmap.cpp
msgid "Done"
@@ -12846,7 +12829,7 @@ msgstr "ขนาดวิวพอร์ตจะต้องมาà¸à¸à¸§à¹ˆ
msgid ""
"The sampler port is connected but not used. Consider changing the source to "
"'SamplerPort'."
-msgstr ""
+msgstr "พอร์ตตัวอย่างเชื่อมต่ออยู่à¹à¸•่ไม่ได้ใช้ ควรที่จะเปลี่ยนเป็น \"SamplerPort\""
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 9a815d3f25..619bd94bb1 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -61,8 +61,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-16 10:40+0000\n"
-"Last-Translator: furkan atalar <fatalar55@gmail.com>\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
+"Last-Translator: OÄŸuz Ersen <oguzersen@protonmail.com>\n"
"Language-Team: Turkish <https://hosted.weblate.org/projects/godot-engine/"
"godot/tr/>\n"
"Language: tr\n"
@@ -70,7 +70,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -2579,9 +2579,8 @@ msgstr ""
"başarısız oldu."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Unable to find script field for addon plugin at: '%s'."
-msgstr "Eklentideki betik alanı bulunamıyor: 'res://addons/%s'."
+msgstr "Eklentide için betik alanı bulunamıyor: '%s'."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
@@ -3722,6 +3721,13 @@ msgstr ""
"aktarın."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"İçe aktarma bu dosya için devre dışı bırakıldı, bu nedenle düzenleme için "
+"açılamıyor."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Kaynakların kökü taşınamaz/yeniden adlandırılamaz."
@@ -4124,6 +4130,10 @@ msgid "Reset to Defaults"
msgstr "Varsayılanlara dön"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Dosyayı Koru (İçeri Aktarma Yok)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d Dosya"
@@ -10450,9 +10460,8 @@ msgid "Plugins"
msgstr "Eklentiler"
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "Import Defaults"
-msgstr "Varsayılanları İçe Aktar"
+msgstr "Öntanımlı İçe Aktarma Ayarları"
#: editor/property_editor.cpp
msgid "Preset..."
@@ -12494,11 +12503,12 @@ msgstr "Boş bir CollisionPolygon2D'nin çarpışmaya hiçbir etkisi yoktur."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
-msgstr ""
+msgstr "Geçersiz çokgen. 'Solids' oluşturma modunda en az 3 nokta gereklidir."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
msgstr ""
+"Geçersiz çokgen. 'Segments' oluşturma modunda en az 2 nokta gereklidir."
#: scene/2d/collision_shape_2d.cpp
msgid ""
diff --git a/editor/translations/tzm.po b/editor/translations/tzm.po
index c4614c7eb3..893d4134db 100644
--- a/editor/translations/tzm.po
+++ b/editor/translations/tzm.po
@@ -3495,6 +3495,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3885,6 +3890,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr ""
diff --git a/editor/translations/uk.po b/editor/translations/uk.po
index 6a8af58119..3dd58a87f4 100644
--- a/editor/translations/uk.po
+++ b/editor/translations/uk.po
@@ -20,8 +20,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Ukrainian (Godot Engine)\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-10 22:14+0000\n"
-"Last-Translator: Tymofij Lytvynenko <till.svit@gmail.com>\n"
+"PO-Revision-Date: 2021-03-31 03:53+0000\n"
+"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <https://hosted.weblate.org/projects/godot-engine/"
"godot/uk/>\n"
"Language: uk\n"
@@ -30,7 +30,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -3695,6 +3695,13 @@ msgstr ""
"імпортуйте вручну."
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+"Ð†Ð¼Ð¿Ð¾Ñ€Ñ‚ÑƒÐ²Ð°Ð½Ð½Ñ Ð´Ð»Ñ Ñ†ÑŒÐ¾Ð³Ð¾ файла вимкнено, тому його не можна відкрити Ð´Ð»Ñ "
+"редагуваннÑ."
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "Ðеможливо переміÑтити/перейменувати корінь реÑурÑів."
@@ -4095,6 +4102,10 @@ msgid "Reset to Defaults"
msgstr "Відновити типові параметри"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "Зберегти файл (не імпортувати)"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d файлів"
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index a2e1decab6..78698e90ba 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -3561,6 +3561,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr ""
@@ -3965,6 +3970,10 @@ msgid "Reset to Defaults"
msgstr ""
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "Ø§Ø«Ø§Ø«Û Ú©ÛŒ زپ ÙØ§Ø¦Ù„"
diff --git a/editor/translations/vi.po b/editor/translations/vi.po
index 94692dc9b2..fa600ca176 100644
--- a/editor/translations/vi.po
+++ b/editor/translations/vi.po
@@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Godot Engine editor\n"
"POT-Creation-Date: \n"
-"PO-Revision-Date: 2021-03-08 15:33+0000\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
"Last-Translator: Rev <revolnoom7801@gmail.com>\n"
"Language-Team: Vietnamese <https://hosted.weblate.org/projects/godot-engine/"
"godot/vi/>\n"
@@ -31,7 +31,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5.1\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -51,11 +51,11 @@ msgstr "Không đủ byte để giải mã, hoặc định dạng không hợp l
#: core/math/expression.cpp
msgid "Invalid input %i (not passed) in expression"
-msgstr "Dữ liệu vào không hợp lệ %i (không được thông qua)"
+msgstr "Äầu vào %i không hợp lệ (không được thông qua) trong biểu thức"
#: core/math/expression.cpp
msgid "self can't be used because instance is null (not passed)"
-msgstr "self không thể sử dụng vì instance là null (không thông qua)"
+msgstr "Không thể sử dụng self vì instance là null (không thông qua)"
#: core/math/expression.cpp
msgid "Invalid operands to operator %s, %s and %s."
@@ -75,7 +75,7 @@ msgstr "Äối số không hợp lệ để dá»±ng '%s'"
#: core/math/expression.cpp
msgid "On call to '%s':"
-msgstr "Khi cuá»™c gá»i đến '%s':"
+msgstr "Khi gá»i đến '%s':"
#: core/ustring.cpp
msgid "B"
@@ -175,27 +175,23 @@ msgstr "Äổi Function Gá»i Animation"
#: editor/animation_track_editor.cpp
msgid "Anim Multi Change Keyframe Time"
-msgstr "Äổi nhiá»u thá»i gian khung hình"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transition"
-msgstr "Äổi Transition Animation"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Transform"
-msgstr "Äổi Transform Animation"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Keyframe Value"
-msgstr "Äổi giá trị khung hình"
+msgstr ""
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Anim Multi Change Call"
-msgstr "Äổi Function Gá»i Animation"
+msgstr ""
#: editor/animation_track_editor.cpp
msgid "Change Animation Length"
@@ -224,11 +220,11 @@ msgstr "Theo dõi đưá»ng cong Bezier"
#: editor/animation_track_editor.cpp
msgid "Audio Playback Track"
-msgstr "Bản nhạc phát lại âm thanh"
+msgstr "Kênh Âm Thanh"
#: editor/animation_track_editor.cpp
msgid "Animation Playback Track"
-msgstr "Ngưng chạy animation. (S)"
+msgstr "Kênh Hoạt Ảnh"
#: editor/animation_track_editor.cpp
msgid "Animation length (frames)"
@@ -265,7 +261,7 @@ msgstr "Thay đổi đưá»ng dẫn Track"
#: editor/animation_track_editor.cpp
msgid "Toggle this track on/off."
-msgstr "Bật hoặc tắt track này, on/off"
+msgstr "Bật/tắt kênh này."
#: editor/animation_track_editor.cpp
msgid "Update Mode (How this property is set)"
@@ -285,7 +281,7 @@ msgstr "BỠtrack này."
#: editor/animation_track_editor.cpp
msgid "Time (s): "
-msgstr "Bước: "
+msgstr "Thá»i gian (s): "
#: editor/animation_track_editor.cpp
msgid "Toggle Track Enabled"
@@ -407,7 +403,7 @@ msgstr "Sắp xếp lại Tracks"
#: editor/animation_track_editor.cpp
msgid "Transform tracks only apply to Spatial-based nodes."
-msgstr "Các chuyển đổi chỉ có thể áp dụng cho các node Spatial"
+msgstr "Các chuyển đổi chỉ có thể áp dụng cho các nút dựa trên kiểu Spatial."
#: editor/animation_track_editor.cpp
msgid ""
@@ -432,7 +428,7 @@ msgstr ""
#: editor/animation_track_editor.cpp
msgid "Not possible to add a new track without a root"
-msgstr "Không thể thêm track mới mà không có root."
+msgstr "Không thể thêm track mới mà không có root"
#: editor/animation_track_editor.cpp
msgid "Invalid track for Bezier (no suitable sub-properties)"
@@ -444,7 +440,7 @@ msgstr "Thêm Bezier Track"
#: editor/animation_track_editor.cpp
msgid "Track path is invalid, so can't add a key."
-msgstr "ÄÆ°á»ng dẫn không hợp lệ, không thể thêm khoá."
+msgstr "ÄÆ°á»ng dẫn không hợp lệ, nên không thể thêm khóa."
#: editor/animation_track_editor.cpp
msgid "Track is not of type Spatial, can't insert key"
@@ -503,25 +499,21 @@ msgid ""
"Alternatively, use an import preset that imports animations to separate "
"files."
msgstr ""
-"Cáianimation này thuộc vỠmột cảnh đã nhập, vì vậy những thay đổi đối với "
-"các bản nhạc đã nhập sẽ không được lưu.\n"
+"Hoạt ảnh này thuộc vỠmột Cảnh được Nhập, nên các thay đổi lên track được "
+"Nhập sẽ không được lưu lại.\n"
"\n"
-"Äể bật khả năng thêm các bản nhạc tùy chỉnh, hãy Ä‘iá»u hướng đến cài đặt nhập "
-"của cảnh và đặt\n"
-"\"animation > Lưu trữ\" thành \"Tệp\", bật \"Hoạt hình> Giữ các bản nhạc tùy "
-"chỉnh\", sau đó nhập lại.(vn)\n"
-"\"Animation > Storage\" to \"Files\", enable \"Animation > Keep Custom Tracks"
-"\", sau đó nhập lại (english).\n"
-"Hoặc, sử dụng cài đặt trước nhập khẩu nhập hình ảnh động để tách các tệp."
+"Äể bật khả năng thêm track tùy ý, Ä‘i đến cài đặt cá»§a Cảnh được Nhập rồi đặt\n"
+"\"Hoạt Ảnh > Lưu trữ\" thành \"Tệp\", bật \"Hoạt ảnh > Giữ các track tùy "
+"chỉnh\", sau đó Nhập lại.\n"
+"Hoặc, dùng một Cài đặt trước nhập để Nhập hoạt ảnh ra các tệp khác nhau."
#: editor/animation_track_editor.cpp
msgid "Warning: Editing imported animation"
msgstr "Cảnh bảo: Chỉnh sửa hoạt ảnh đã nhập"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select an AnimationPlayer node to create and edit animations."
-msgstr "Chá»n má»™t AnimationPlayer từ Scene Tree để chỉnh sá»­a animation."
+msgstr "Chá»n má»™t AnimationPlayer để tạo và chỉnh sá»­a Hoạt Ảnh."
#: editor/animation_track_editor.cpp
msgid "Only show tracks from nodes selected in tree."
@@ -533,7 +525,7 @@ msgstr "Nhóm các track bởi nút hoặc hiển thị chúng dạng danh sách
#: editor/animation_track_editor.cpp
msgid "Snap:"
-msgstr "Chụp:"
+msgstr "Dính:"
#: editor/animation_track_editor.cpp
msgid "Animation step value."
@@ -652,12 +644,11 @@ msgstr "Dá»n dẹp"
#: editor/animation_track_editor.cpp
msgid "Scale Ratio:"
-msgstr "Tỉ lệ Scale:"
+msgstr "Tỉ lệ phóng đại:"
#: editor/animation_track_editor.cpp
-#, fuzzy
msgid "Select Tracks to Copy"
-msgstr "Chá»n các Track để sao chép:"
+msgstr "Chá»n các Track để sao chép"
#: editor/animation_track_editor.cpp editor/editor_log.cpp
#: editor/editor_properties.cpp
@@ -670,7 +661,7 @@ msgstr "Sao chép"
#: editor/animation_track_editor.cpp
msgid "Select All/None"
-msgstr "Chá»n tất cả/ hoặc không"
+msgstr "Chá»n/Bá» tất cả"
#: editor/animation_track_editor_plugins.cpp
msgid "Add Audio Track Clip"
@@ -678,7 +669,7 @@ msgstr "Thêm Track Âm thanh"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip Start Offset"
-msgstr "Thay đổi thá»i Ä‘iểm bắt đầu phát track âm thanh."
+msgstr "Thay đổi thá»i Ä‘iểm bắt đầu phát track âm thanh"
#: editor/animation_track_editor_plugins.cpp
msgid "Change Audio Track Clip End Offset"
@@ -705,19 +696,16 @@ msgid "Line Number:"
msgstr "Dòng số:"
#: editor/code_editor.cpp
-#, fuzzy
msgid "%d replaced."
-msgstr "Thay thế ..."
+msgstr "Äã thay %d."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d match."
-msgstr "Tìm thấy %d khớp."
+msgstr "%d khá»›p."
#: editor/code_editor.cpp editor/editor_help.cpp
-#, fuzzy
msgid "%d matches."
-msgstr "Tìm thấy %d khớp."
+msgstr "%d khá»›p."
#: editor/code_editor.cpp editor/find_in_files.cpp
msgid "Match Case"
@@ -737,7 +725,7 @@ msgstr "Thay thế tất cả"
#: editor/code_editor.cpp
msgid "Selection Only"
-msgstr "Chỉ lá»±a chá»n"
+msgstr "Chỉ chá»n"
#: editor/code_editor.cpp editor/plugins/script_text_editor.cpp
#: editor/plugins/text_editor.cpp
@@ -746,7 +734,7 @@ msgstr "Chuẩn"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr ""
+msgstr "Hiện/Ẩn bảng Tệp lệnh"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -762,7 +750,7 @@ msgstr "Thu nhá»"
#: editor/code_editor.cpp
msgid "Reset Zoom"
-msgstr "Äặt lại phóng"
+msgstr "Äặt lại độ phóng"
#: editor/code_editor.cpp
msgid "Warnings"
@@ -827,7 +815,7 @@ msgstr "Thêm đối số mở rộng:"
#: editor/connections_dialog.cpp
msgid "Extra Call Arguments:"
-msgstr "Mở rá»™ng Äối số được gá»i:"
+msgstr "Äối số mở rá»™ng được gá»i:"
#: editor/connections_dialog.cpp
msgid "Receiver Method:"
@@ -845,7 +833,7 @@ msgstr "Trì hoãn"
msgid ""
"Defers the signal, storing it in a queue and only firing it at idle time."
msgstr ""
-"Trì hoãn tín hiệu, lưu vào má»™t hàng chá» và chỉ kích nó vào thá»i gian rãnh."
+"Trì hoãn tín hiệu, lưu vào má»™t hàng chá» và chỉ kích nó vào thá»i gian rảnh."
#: editor/connections_dialog.cpp
msgid "Oneshot"
@@ -1048,11 +1036,12 @@ msgid "Owners Of:"
msgstr "Sở hữu của:"
#: editor/dependency_editor.cpp
-#, fuzzy
msgid ""
"Remove selected files from the project? (no undo)\n"
"You can find the removed files in the system trash to restore them."
-msgstr "Gỡ bá» các tệp đã chá»n trong dá»± án? (Không thể khôi phục)"
+msgstr ""
+"Gỡ bá» các tệp đã chá»n trong dá»± án? (Không thể khôi phục)\n"
+"Bạn có thể khôi phục chúng trong thùng rác của hệ thống."
#: editor/dependency_editor.cpp
msgid ""
@@ -1061,6 +1050,9 @@ msgid ""
"Remove them anyway? (no undo)\n"
"You can find the removed files in the system trash to restore them."
msgstr ""
+"Các tài nguyên khác cần những tệp bị xóa này mới hoạt động được.\n"
+"Vẫn xóa hả? (không hồi được đâu)\n"
+"Bạn có thể khôi phục chúng trong thùng rác hệ thống."
#: editor/dependency_editor.cpp
msgid "Cannot remove:"
@@ -1072,11 +1064,11 @@ msgstr "Lỗi tải nạp:"
#: editor/dependency_editor.cpp
msgid "Load failed due to missing dependencies:"
-msgstr ""
+msgstr "Tải thất bại do thiếu phần phụ thuộc:"
#: editor/dependency_editor.cpp editor/editor_node.cpp
msgid "Open Anyway"
-msgstr "Luôn mở"
+msgstr "Cứ mở thôi"
#: editor/dependency_editor.cpp
msgid "Which action should be taken?"
@@ -1092,7 +1084,7 @@ msgstr "Lỗi tải nạp!"
#: editor/dependency_editor.cpp
msgid "Permanently delete %d item(s)? (No undo!)"
-msgstr "Xoá vĩnh viễn các đối tượng %d? (Không thể hoàn lại!)"
+msgstr "Xoá vĩnh viễn %d đối tượng? (Không thể hoàn lại!)"
#: editor/dependency_editor.cpp
msgid "Show Dependencies"
@@ -1116,7 +1108,7 @@ msgstr "Sở hữu"
#: editor/dependency_editor.cpp
msgid "Resources Without Explicit Ownership:"
-msgstr ""
+msgstr "Tài nguyên không có quyá»n sở hữu rõ ràng:"
#: editor/dictionary_property_edit.cpp
msgid "Change Dictionary Key"
@@ -1166,14 +1158,12 @@ msgid "Gold Sponsors"
msgstr "Nhà tài trợ Vàng"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Silver Sponsors"
-msgstr "Ngưá»i á»§ng há»™ Bạc"
+msgstr "Nhà tài trợ Bạc"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Bronze Sponsors"
-msgstr "Ngưá»i á»§ng há»™ Äồng"
+msgstr "Nhà tài trợ Äồng"
#: editor/editor_about.cpp
msgid "Mini Sponsors"
@@ -1197,15 +1187,13 @@ msgstr "Ngưá»i á»§ng há»™"
#: editor/editor_about.cpp
msgid "License"
-msgstr "Cấp phép"
+msgstr "Giấy phép"
#: editor/editor_about.cpp
-#, fuzzy
msgid "Third-party Licenses"
-msgstr "Cấp phép nhóm thứ ba"
+msgstr "Giấy phép bên thứ ba"
#: editor/editor_about.cpp
-#, fuzzy
msgid ""
"Godot Engine relies on a number of third-party free and open source "
"libraries, all compatible with the terms of its MIT license. The following "
@@ -1230,27 +1218,24 @@ msgid "Licenses"
msgstr "Các giấy phép"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
-#, fuzzy
msgid "Error opening package file, not in ZIP format."
-msgstr "Lỗi không thể mở gói, không phải dạng nén."
+msgstr "Lỗi không thể mở gói, không phải dạng nén ZIP."
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "%s (Already Exists)"
-msgstr "Tam giác đã tồn tại."
+msgstr "%s (Äã tồn tại)"
#: editor/editor_asset_installer.cpp
msgid "Uncompressing Assets"
-msgstr "Giải nén Assets"
+msgstr "Giải nén tài nguyên"
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "The following files failed extraction from package:"
-msgstr ""
+msgstr "Không thể lấy các tệp sau khá»i gói:"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "And %s more files."
-msgstr "%d thêm các tệp tin"
+msgstr "Và %s tệp nữa."
#: editor/editor_asset_installer.cpp editor/project_manager.cpp
msgid "Package installed successfully!"
@@ -1262,9 +1247,8 @@ msgid "Success!"
msgstr "Thành công!"
#: editor/editor_asset_installer.cpp
-#, fuzzy
msgid "Package Contents:"
-msgstr "Ná»™i dung:"
+msgstr "Trong Gói có:"
#: editor/editor_asset_installer.cpp editor/editor_node.cpp
msgid "Install"
@@ -1284,11 +1268,11 @@ msgstr "Thêm hiệu ứng"
#: editor/editor_audio_buses.cpp
msgid "Rename Audio Bus"
-msgstr ""
+msgstr "Äổi tên Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Change Audio Bus Volume"
-msgstr ""
+msgstr "Thay đổi âm lượng Bus"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Solo"
@@ -1296,7 +1280,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Mute"
-msgstr ""
+msgstr "Bật/Tắt Âm Thanh của Bus"
#: editor/editor_audio_buses.cpp
msgid "Toggle Audio Bus Bypass Effects"
@@ -1308,19 +1292,19 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus Effect"
-msgstr ""
+msgstr "Thêm hiệu ứng vào Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Move Bus Effect"
-msgstr ""
+msgstr "Di chuyển hiệu ứng Bus"
#: editor/editor_audio_buses.cpp
msgid "Delete Bus Effect"
-msgstr ""
+msgstr "Xóa hiệu ứng của Bus"
#: editor/editor_audio_buses.cpp
msgid "Drag & drop to rearrange."
-msgstr ""
+msgstr "Kéo & thả để sắp xếp lại."
#: editor/editor_audio_buses.cpp
msgid "Solo"
@@ -1336,12 +1320,12 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Bus options"
-msgstr ""
+msgstr "Tùy chá»n Bus"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr "Nhân bản"
+msgstr "Nhân đôi"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -1357,23 +1341,23 @@ msgstr "Âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Add Audio Bus"
-msgstr ""
+msgstr "Thêm Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Master bus can't be deleted!"
-msgstr ""
+msgstr "Không thể xóa Bus âm thanh chủ!"
#: editor/editor_audio_buses.cpp
msgid "Delete Audio Bus"
-msgstr ""
+msgstr "Xóa Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Duplicate Audio Bus"
-msgstr ""
+msgstr "Nhân bản Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "Reset Bus Volume"
-msgstr ""
+msgstr "Äặt lại âm lượng Bus"
#: editor/editor_audio_buses.cpp
msgid "Move Audio Bus"
@@ -1381,7 +1365,7 @@ msgstr ""
#: editor/editor_audio_buses.cpp
msgid "Save Audio Bus Layout As..."
-msgstr ""
+msgstr "Lưu bố cục Bus âm thanh thành..."
#: editor/editor_audio_buses.cpp
msgid "Location for New Layout..."
@@ -1389,7 +1373,7 @@ msgstr "Vị trí cho Bố cục mới..."
#: editor/editor_audio_buses.cpp
msgid "Open Audio Bus Layout"
-msgstr ""
+msgstr "Mở bố cục Bus âm thanh"
#: editor/editor_audio_buses.cpp
msgid "There is no '%s' file."
@@ -1401,20 +1385,19 @@ msgstr "Bố trí"
#: editor/editor_audio_buses.cpp
msgid "Invalid file, not an audio bus layout."
-msgstr ""
+msgstr "Sai kiểu tệp, không phải bố cục bus âm thanh."
#: editor/editor_audio_buses.cpp
-#, fuzzy
msgid "Error saving file: %s"
-msgstr "Lỗi tải font."
+msgstr "Lỗi lưu tệp: %s"
#: editor/editor_audio_buses.cpp
msgid "Add Bus"
-msgstr ""
+msgstr "Thêm Bus"
#: editor/editor_audio_buses.cpp
msgid "Add a new Audio Bus to this layout."
-msgstr ""
+msgstr "Thêm Bus âm thanh mới cho bố cục."
#: editor/editor_audio_buses.cpp editor/editor_properties.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/property_editor.cpp
@@ -1424,7 +1407,7 @@ msgstr "Nạp"
#: editor/editor_audio_buses.cpp
msgid "Load an existing Bus Layout."
-msgstr ""
+msgstr "Nạp một bố cục Bus có sẵn."
#: editor/editor_audio_buses.cpp
msgid "Save As"
@@ -1432,7 +1415,7 @@ msgstr "Lưu thành"
#: editor/editor_audio_buses.cpp
msgid "Save this Bus Layout to a file."
-msgstr ""
+msgstr "Lưu bố cục Bus này vào tệp."
#: editor/editor_audio_buses.cpp editor/import_dock.cpp
msgid "Load Default"
@@ -1440,11 +1423,11 @@ msgstr "Nạp mặc định"
#: editor/editor_audio_buses.cpp
msgid "Load the default Bus Layout."
-msgstr ""
+msgstr "Nạp bố cục Bus mặc định."
#: editor/editor_audio_buses.cpp
msgid "Create a new Bus Layout."
-msgstr ""
+msgstr "Tạo bố cục Bus mới."
#: editor/editor_autoload_settings.cpp
msgid "Invalid name."
@@ -1456,15 +1439,15 @@ msgstr "Ký tự hợp lệ:"
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing engine class name."
-msgstr ""
+msgstr "Không được trùng tên với một lớp có sẵn của công cụ lập trình."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing built-in type name."
-msgstr ""
+msgstr "Không được trùng với tên một kiểu có sẵn đã tồn tại."
#: editor/editor_autoload_settings.cpp
msgid "Must not collide with an existing global constant name."
-msgstr ""
+msgstr "Không được trùng với tên một hằng số toàn cục đã tồn tại."
#: editor/editor_autoload_settings.cpp
msgid "Keyword cannot be used as an autoload name."
@@ -1476,7 +1459,7 @@ msgstr "Nạp tự động '%s' đã tồn tại!"
#: editor/editor_autoload_settings.cpp
msgid "Rename Autoload"
-msgstr "Äổi tên"
+msgstr "Äổi tên Nạp tá»± động"
#: editor/editor_autoload_settings.cpp
msgid "Toggle AutoLoad Globals"
@@ -1488,7 +1471,7 @@ msgstr ""
#: editor/editor_autoload_settings.cpp
msgid "Remove Autoload"
-msgstr ""
+msgstr "Xóa Nạp tự động"
#: editor/editor_autoload_settings.cpp editor/editor_plugin_settings.cpp
msgid "Enable"
@@ -1500,7 +1483,7 @@ msgstr "Sắp xếp lại Autoloads"
#: editor/editor_autoload_settings.cpp
msgid "Can't add autoload:"
-msgstr ""
+msgstr "Không thể thêm nạp tự động:"
#: editor/editor_autoload_settings.cpp
msgid "Add AutoLoad"
@@ -1549,7 +1532,7 @@ msgstr "[rá»—ng]"
#: editor/editor_data.cpp
msgid "[unsaved]"
-msgstr "[chưa save]"
+msgstr "[chưa lưu]"
#: editor/editor_dir_dialog.cpp
msgid "Please select a base directory first."
@@ -1587,7 +1570,7 @@ msgstr "Lưu trữ tệp tin:"
#: editor/editor_export.cpp
msgid "No export template found at the expected path:"
-msgstr ""
+msgstr "Không thấy mẫu xuất nào ở đưá»ng dẫn mong đợi:"
#: editor/editor_export.cpp
msgid "Packing"
@@ -1621,22 +1604,20 @@ msgstr ""
"Trình Ä‘iá»u khiển Dá»± phòng'."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'PVRTC' texture compression for GLES2. Enable "
"'Import Pvrtc' in Project Settings."
msgstr ""
-"Ná»n tảng yêu cầu dùng kiểu nén 'ETC' cho GLES2. Bật 'Nhập ETC' trong Cài đặt "
-"Dự án."
+"Ná»n tảng yêu cầu dùng kiểu nén 'PVRTC' cho GLES2. Hãy bật 'Nhập Pvrtc' trong "
+"Cài đặt Dự án."
#: editor/editor_export.cpp
-#, fuzzy
msgid ""
"Target platform requires 'ETC2' or 'PVRTC' texture compression for GLES3. "
"Enable 'Import Etc 2' or 'Import Pvrtc' in Project Settings."
msgstr ""
-"Ná»n tảng yêu cầu dùng kiểu nén 'ETC2' cho GLES3. Bật 'Nhập ETC2' trong Cài "
-"đặt Dự án."
+"Ná»n tảng yêu cầu dùng kiểu nén 'ETC2' hoặc 'PVRTC' cho GLES3. Hãy bật 'Nhập "
+"ETC2' hoặc 'Nhập Pvrtc' trong Cài đặt Dự án."
#: editor/editor_export.cpp
#, fuzzy
@@ -1659,8 +1640,9 @@ msgstr "Không tìm thấy mẫu gỡ lỗi tuỳ chỉnh."
#: editor/editor_export.cpp platform/android/export/export.cpp
#: platform/iphone/export/export.cpp platform/javascript/export/export.cpp
#: platform/osx/export/export.cpp platform/uwp/export/export.cpp
+#, fuzzy
msgid "Custom release template not found."
-msgstr ""
+msgstr "Không tìm thấy mẫu phát hành tùy chỉnh."
#: editor/editor_export.cpp platform/javascript/export/export.cpp
msgid "Template file not found:"
@@ -1725,7 +1707,7 @@ msgstr "(Äã tắt trình chỉnh sá»­a)"
#: editor/editor_feature_profile.cpp
msgid "Class Options:"
-msgstr "Tuỳ chá»n lá»›p:"
+msgstr "Tuỳ chá»n Lá»›p:"
#: editor/editor_feature_profile.cpp
msgid "Enable Contextual Editor"
@@ -1748,11 +1730,10 @@ msgid "File '%s' format is invalid, import aborted."
msgstr "Tệp '%s' định dạng không hợp lệ, huỷ nhập vào."
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid ""
"Profile '%s' already exists. Remove it first before importing, import "
"aborted."
-msgstr "Hồ sơ '%s' đã tồn tại. Di chuyển hồ sơ trước khi nhập, huỷ nhập."
+msgstr "Hồ sơ '%s' đã tồn tại. Hãy xóa hồ sơ đấy trước khi nhập, đã dừng nhập."
#: editor/editor_feature_profile.cpp
msgid "Error saving profile to path: '%s'."
@@ -1763,9 +1744,8 @@ msgid "Unset"
msgstr "BỠđặt"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Current Profile:"
-msgstr "Hồ sơ hiện tại"
+msgstr "Hồ sơ hiện tại:"
#: editor/editor_feature_profile.cpp
msgid "Make Current"
@@ -1780,16 +1760,15 @@ msgstr "Má»›i"
#: editor/editor_feature_profile.cpp editor/editor_node.cpp
#: editor/project_manager.cpp
msgid "Import"
-msgstr "Nhập vào"
+msgstr "Nhập"
#: editor/editor_feature_profile.cpp editor/project_export.cpp
msgid "Export"
msgstr "Xuất ra"
#: editor/editor_feature_profile.cpp
-#, fuzzy
msgid "Available Profiles:"
-msgstr "Hồ sơ khả dụng"
+msgstr "Hồ sơ khả dụng:"
#: editor/editor_feature_profile.cpp
msgid "Class Options"
@@ -1856,7 +1835,7 @@ msgstr "Làm mới"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Recognized"
-msgstr ""
+msgstr "Äã nhận diện hết"
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "All Files (*)"
@@ -1919,39 +1898,35 @@ msgstr "Tập trung ÄÆ°á»ng dẫn"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Up"
-msgstr "Di chuyển Ưa thích lên"
+msgstr "Di chuyển mục Ưa thích lên"
#: editor/editor_file_dialog.cpp
msgid "Move Favorite Down"
-msgstr "Di chuyển Ưa thích xuống"
+msgstr "Di chuyển mục Ưa thích xuống"
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to previous folder."
-msgstr "Äến thư mục cha"
+msgstr "Quay lại thư mục trước."
#: editor/editor_file_dialog.cpp
-#, fuzzy
msgid "Go to next folder."
-msgstr "Äến thư mục cha"
+msgstr "Äến thư mục tiếp theo."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
msgid "Go to parent folder."
-msgstr "Äến thư mục cha"
+msgstr "Äến thư mục mẹ."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Refresh files."
-msgstr "Tìm kiếm tệp tin"
+msgstr "Làm mới các tệp."
#: editor/editor_file_dialog.cpp
msgid "(Un)favorite current folder."
msgstr "BỠyêu thích thư mục hiện tại."
#: editor/editor_file_dialog.cpp scene/gui/file_dialog.cpp
-#, fuzzy
msgid "Toggle the visibility of hidden files."
-msgstr "Bật tắt hiện các tệp tin ẩn."
+msgstr "Hiện/ẩn các tệp ẩn."
#: editor/editor_file_dialog.cpp editor/filesystem_dock.cpp
msgid "View items as a grid of thumbnails."
@@ -1984,10 +1959,12 @@ msgid ""
"There are multiple importers for different types pointing to file %s, import "
"aborted"
msgstr ""
+"Có nhiá»u trình nhập cho nhiá»u loại khác nhau cùng chỉ đến tệp %s, đã ngừng "
+"nhập"
#: editor/editor_file_system.cpp
msgid "(Re)Importing Assets"
-msgstr ""
+msgstr "Nhập lại tài nguyên"
#: editor/editor_help.cpp editor/plugins/spatial_editor_plugin.cpp
msgid "Top"
@@ -2007,28 +1984,24 @@ msgid "Inherited by:"
msgstr "ÄÆ°á»£c thừa kế bởi:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Description"
-msgstr "Mô tả:"
+msgstr "Mô tả"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Online Tutorials"
-msgstr "Hướng dẫn trực tuyến:"
+msgstr "Hướng dẫn trực tuyến"
#: editor/editor_help.cpp
msgid "Properties"
msgstr "Thuộc tính"
#: editor/editor_help.cpp
-#, fuzzy
msgid "override:"
-msgstr "Ghi đè"
+msgstr "Ghi đè:"
#: editor/editor_help.cpp
-#, fuzzy
msgid "default:"
-msgstr "Mặc định"
+msgstr "mặc định:"
#: editor/editor_help.cpp
msgid "Methods"
@@ -2036,7 +2009,7 @@ msgstr "Hàm"
#: editor/editor_help.cpp
msgid "Theme Properties"
-msgstr ""
+msgstr "Cài đặt Tông màu"
#: editor/editor_help.cpp
msgid "Enumerations"
@@ -2044,23 +2017,23 @@ msgstr ""
#: editor/editor_help.cpp
msgid "Constants"
-msgstr ""
+msgstr "Hằng số"
#: editor/editor_help.cpp
-#, fuzzy
msgid "Property Descriptions"
-msgstr "Mô tả ngắn gá»n:"
+msgstr "Mô tả thuộc tính"
#: editor/editor_help.cpp
-#, fuzzy
msgid "(value)"
-msgstr "Giá trị:"
+msgstr "(giá trị)"
#: editor/editor_help.cpp
msgid ""
"There is currently no description for this property. Please help us by "
"[color=$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"Hiện thuộc tính này chưa được mô tả. Các bạn [color=$color][url=$url]đóng "
+"góp[/url][/color] giúp chúng mình nha!"
#: editor/editor_help.cpp
msgid "Method Descriptions"
@@ -2071,21 +2044,21 @@ msgid ""
"There is currently no description for this method. Please help us by [color="
"$color][url=$url]contributing one[/url][/color]!"
msgstr ""
+"Hiện phương thức này chưa được mô tả. Các bạn [color=$color][url=$url]đóng "
+"góp[/url][/color] giúp chúng mình nha!"
#: editor/editor_help_search.cpp editor/editor_node.cpp
#: editor/plugins/script_editor_plugin.cpp
msgid "Search Help"
-msgstr "Tìm sự giúp đỡ"
+msgstr "Tìm trợ giúp"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Case Sensitive"
-msgstr "Äóng Cảnh"
+msgstr "Phân biệt hoa thưá»ng"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Show Hierarchy"
-msgstr "Tìm kiếm"
+msgstr "Hiện cấp bậc"
#: editor/editor_help_search.cpp
msgid "Display All"
@@ -2093,27 +2066,28 @@ msgstr "Hiển thị tất cả"
#: editor/editor_help_search.cpp
msgid "Classes Only"
-msgstr "Chỉ các Lớp"
+msgstr "Chỉ tìm Lớp"
#: editor/editor_help_search.cpp
msgid "Methods Only"
-msgstr "Chỉ các Hàm"
+msgstr "Chỉ tìm Hàm"
#: editor/editor_help_search.cpp
msgid "Signals Only"
-msgstr "Chỉ các Tín hiệu"
+msgstr "Chỉ tìm Tín hiệu"
#: editor/editor_help_search.cpp
msgid "Constants Only"
-msgstr "Chỉ các Äịnh nghÄ©a"
+msgstr "Chỉ tìm Hằng số"
#: editor/editor_help_search.cpp
msgid "Properties Only"
-msgstr "Chỉ các Thuộc tính"
+msgstr "Chỉ tìm Thuộc tính"
#: editor/editor_help_search.cpp
+#, fuzzy
msgid "Theme Properties Only"
-msgstr ""
+msgstr "Chỉ tìm thuộc tính Tông màu"
#: editor/editor_help_search.cpp
msgid "Member Type"
@@ -2124,28 +2098,25 @@ msgid "Class"
msgstr "Lá»›p"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Method"
msgstr "Hàm"
#: editor/editor_help_search.cpp editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Signal"
msgstr "Tín hiệu"
#: editor/editor_help_search.cpp editor/plugins/theme_editor_plugin.cpp
msgid "Constant"
-msgstr "Cố định"
+msgstr "Hằng số"
#: editor/editor_help_search.cpp
-#, fuzzy
msgid "Property"
-msgstr "Thuộc tính:"
+msgstr "Thuộc tính"
#: editor/editor_help_search.cpp
#, fuzzy
msgid "Theme Property"
-msgstr "Thuộc tính:"
+msgstr "Thuộc tính Tông màu"
#: editor/editor_inspector.cpp editor/project_settings_editor.cpp
msgid "Property:"
@@ -2193,16 +2164,15 @@ msgstr "Bắt đầu"
#: editor/editor_network_profiler.cpp
msgid "%s/s"
-msgstr ""
+msgstr "%s/s"
#: editor/editor_network_profiler.cpp
-#, fuzzy
msgid "Down"
-msgstr "Tải"
+msgstr "Xuống"
#: editor/editor_network_profiler.cpp
msgid "Up"
-msgstr ""
+msgstr "Lên"
#: editor/editor_network_profiler.cpp editor/editor_node.cpp
msgid "Node"
@@ -2210,23 +2180,23 @@ msgstr "Nút"
#: editor/editor_network_profiler.cpp
msgid "Incoming RPC"
-msgstr ""
+msgstr "RPC đến"
#: editor/editor_network_profiler.cpp
msgid "Incoming RSET"
-msgstr ""
+msgstr "RSET đến"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RPC"
-msgstr ""
+msgstr "RPC đi"
#: editor/editor_network_profiler.cpp
msgid "Outgoing RSET"
-msgstr ""
+msgstr "RSET đi"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "New Window"
-msgstr ""
+msgstr "Cửa sổ mới"
#: editor/editor_node.cpp
msgid "Imported resources can't be saved."
@@ -2235,19 +2205,19 @@ msgstr "Tài nguyên đã nhập không thể lưu."
#: editor/editor_node.cpp editor/plugins/script_editor_plugin.cpp
#: scene/gui/dialogs.cpp
msgid "OK"
-msgstr ""
+msgstr "OK"
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Error saving resource!"
-msgstr ""
+msgstr "Lỗi lưu tài nguyên!"
#: editor/editor_node.cpp
msgid ""
"This resource can't be saved because it does not belong to the edited scene. "
"Make it unique first."
msgstr ""
-"Tài nguyên này không thể lưu vì nó không thuộc cảnh đã chỉnh sửa. Tạo nó là "
-"duy nhất."
+"Không thể lưu tài nguyên này vì nó không thuộc cảnh đã chỉnh sửa. Làm nó độc "
+"nhất đã."
#: editor/editor_node.cpp editor/plugins/animation_player_editor_plugin.cpp
msgid "Save Resource As..."
@@ -2275,11 +2245,11 @@ msgstr "Lỗi khi đang phân tích '%s'."
#: editor/editor_node.cpp
msgid "Unexpected end of file '%s'."
-msgstr ""
+msgstr "Tệp kết thúc bất ngỠ'%s'."
#: editor/editor_node.cpp
msgid "Missing '%s' or its dependencies."
-msgstr ""
+msgstr "Thiếu '%s' hoặc các phần phụ thuộc."
#: editor/editor_node.cpp
msgid "Error while loading '%s'."
@@ -2299,15 +2269,15 @@ msgstr "Tạo hình thu nhá»"
#: editor/editor_node.cpp
msgid "This operation can't be done without a tree root."
-msgstr "Hoạt động không thể hoàn tất khi không có nút gốc."
+msgstr "Hành động không thể hoàn thành mà không có nút gốc."
#: editor/editor_node.cpp
msgid ""
"This scene can't be saved because there is a cyclic instancing inclusion.\n"
"Please resolve it and then attempt to save again."
msgstr ""
-"Cảnh này không thể lưu vì đây bao má»™t trưá»ng hợp theo chu kỳ.\n"
-"Giải quyết nó và cố gắng lưu lại."
+"Không thể lưu cảnh này vì bạn đang instancing chồng chéo nối vòng nhau.\n"
+"Giải quyết vòng nối đã rồi hãy thử lưu lại sau."
#: editor/editor_node.cpp
msgid ""
@@ -2323,15 +2293,15 @@ msgstr "Không thể ghi đè cảnh vẫn đang mở!"
#: editor/editor_node.cpp
msgid "Can't load MeshLibrary for merging!"
-msgstr ""
+msgstr "Không thể nạp MeshLibrary để sáp nhập!"
#: editor/editor_node.cpp
msgid "Error saving MeshLibrary!"
-msgstr ""
+msgstr "Lỗi lưu MeshLibrary!"
#: editor/editor_node.cpp
msgid "Can't load TileSet for merging!"
-msgstr ""
+msgstr "Không thể tải TileSet để sáp nhập!"
#: editor/editor_node.cpp
msgid "Error saving TileSet!"
@@ -2342,6 +2312,8 @@ msgid ""
"An error occurred while trying to save the editor layout.\n"
"Make sure the editor's user data path is writable."
msgstr ""
+"Có lỗi khi đang lưu bố cục trình chỉnh sửa.\n"
+"Hãy thá»­ kiểm tra quyá»n ghi lên đưá»ng dẫn dữ liệu cá»§a ngưá»i dùng xem."
#: editor/editor_node.cpp
msgid ""
@@ -2349,15 +2321,17 @@ msgid ""
"To restore the Default layout to its base settings, use the Delete Layout "
"option and delete the Default layout."
msgstr ""
+"Bố cục mặc định của trình chỉnh sửa đã bị ghi đè.\n"
+"Äể hồi lại bố cục mặc định vá» cài đặt gốc, sá»­ dụng tùy chá»n \"Xóa bố cục\" "
+"rồi xóa bố cục \"Mặc định\"."
#: editor/editor_node.cpp
msgid "Layout name not found!"
-msgstr "Tên bố cục không tìm thấy!"
+msgstr "Không tìm thấy tên bố cục!"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Restored the Default layout to its base settings."
-msgstr "Äã khôi phục bố cục mặc định cho các thiết lập."
+msgstr "Äã khôi phục bố cục mặc định vá» thiết lập gốc."
#: editor/editor_node.cpp
msgid ""
@@ -2365,8 +2339,8 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
-"Tài nguyên thuộc vỠcảnh đã nhập, nó không thể chỉnh sửa.\n"
-"Äá»c tài liệu liên quan để cách nhập Cảnh để hiểu rõ quy trình việc này."
+"Tài nguyên thuộc vỠcảnh đã nhập, nên không thể sửa được.\n"
+"Hãy Ä‘á»c hướng dẫn vá» cách nhập Cảnh để hiểu thêm vá» quy trình này."
#: editor/editor_node.cpp
msgid ""
@@ -2381,8 +2355,8 @@ msgid ""
"This resource was imported, so it's not editable. Change its settings in the "
"import panel and then re-import."
msgstr ""
-"Tài nguyên đã được nhập vào, không thể chỉnh sửa. Thay đổi cài đặt của nó "
-"trong bảng Nhập vào, sau đó nhập vào lại."
+"Tài nguyên này được nhập, nên không thể chỉnh sửa. Thay đổi cài đặt của nó "
+"trong bảng Nhập, sau đó Nhập lại."
#: editor/editor_node.cpp
msgid ""
@@ -2391,10 +2365,9 @@ msgid ""
"Please read the documentation relevant to importing scenes to better "
"understand this workflow."
msgstr ""
-"Cảnh này đã được nhập vào, những thay đổi sẽ không được giữ lại.\n"
-"Tạo thực thể nó hoặc kế thừa sẽ cho phép thực hiện các thay đổi.\n"
-"Äá»c tài liệu tài liệu liên quan đến nhập Cảnh để hiểu rõ vá» quy trình việc "
-"này."
+"Do Cảnh này được nhập, nên những thay đổi sẽ không được giữ lại.\n"
+"Thực hiện khởi tạo đối tượng hoặc kế thừa sẽ cho phép việc chỉnh sửa.\n"
+"Hãy Ä‘á»c hướng dẫn liên quan đến nhập Cảnh để hiểu thêm vá» quy trình này."
#: editor/editor_node.cpp
msgid ""
@@ -2411,19 +2384,19 @@ msgstr "Không có cảnh được xác định để chạy."
#: editor/editor_node.cpp
msgid "Save scene before running..."
-msgstr ""
+msgstr "Lưu cảnh trước khi chạy..."
#: editor/editor_node.cpp
msgid "Could not start subprocess!"
-msgstr "Không thể bắt đầu quá trình nhá»!"
+msgstr "Không thể bắt đầu quá trình phụ!"
#: editor/editor_node.cpp editor/filesystem_dock.cpp
msgid "Open Scene"
-msgstr "Mở Scene"
+msgstr "Mở Cảnh"
#: editor/editor_node.cpp
msgid "Open Base Scene"
-msgstr "Mở Scene Mẫu"
+msgstr "Mở Cảnh cơ sở"
#: editor/editor_node.cpp
msgid "Quick Open..."
@@ -2431,11 +2404,11 @@ msgstr "Mở nhanh ..."
#: editor/editor_node.cpp
msgid "Quick Open Scene..."
-msgstr "Mở Scene nhanh..."
+msgstr "Mở Nhanh Cảnh..."
#: editor/editor_node.cpp
msgid "Quick Open Script..."
-msgstr "Mở Script nhanh..."
+msgstr "Mở Nhanh Tệp lệnh..."
#: editor/editor_node.cpp
msgid "Save & Close"
@@ -2455,11 +2428,11 @@ msgstr "Yêu cầu một nút gốc khi lưu cảnh."
#: editor/editor_node.cpp
msgid "Save Scene As..."
-msgstr "Lưu Scene với tên..."
+msgstr "Lưu Cảnh thành..."
#: editor/editor_node.cpp editor/scene_tree_dock.cpp
msgid "This operation can't be done without a scene."
-msgstr "Thao tác này phải có scene mới làm được."
+msgstr "Thao tác này phải có Cảnh mới làm được."
#: editor/editor_node.cpp
msgid "Export Mesh Library"
@@ -2479,26 +2452,27 @@ msgstr "Thao tác này phải có node được chá»n má»›i làm được."
#: editor/editor_node.cpp
msgid "Current scene not saved. Open anyway?"
-msgstr "Scene hiện tại chưa save. Kệ mở luôn?"
+msgstr "Cảnh hiện tại chưa lưu. Kệ mở luôn?"
#: editor/editor_node.cpp
msgid "Can't reload a scene that was never saved."
-msgstr "Không thể nạp má»™t cảnh mà chưa lưu bao giá»."
+msgstr "Không thể nạp má»™t cảnh chưa lưu bao giá»."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reload Saved Scene"
-msgstr "Lưu Cảnh"
+msgstr "Tải lại Cảnh đã lưu"
#: editor/editor_node.cpp
msgid ""
"The current scene has unsaved changes.\n"
"Reload the saved scene anyway? This action cannot be undone."
msgstr ""
+"Cảnh hiện tại có thay đổi chưa được lưu.\n"
+"Vẫn tải lại à? Không hoàn tác được đâu."
#: editor/editor_node.cpp
msgid "Quick Run Scene..."
-msgstr "Chạy Scene nhanh..."
+msgstr "Chạy nhanh Cảnh..."
#: editor/editor_node.cpp
msgid "Quit"
@@ -2545,9 +2519,8 @@ msgid "Close Scene"
msgstr "Äóng Cảnh"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Reopen Closed Scene"
-msgstr "Äóng Cảnh"
+msgstr "Mở lại Cảnh đã đóng"
#: editor/editor_node.cpp
msgid "Unable to enable addon plugin at: '%s' parsing of config failed."
@@ -2559,18 +2532,22 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s'."
-msgstr ""
+msgstr "Không thể nạp tệp lệnh bổ trợ từ đưá»ng dẫn: '%s'."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' There seems to be an error in "
"the code, please check the syntax."
msgstr ""
+"Không thể nạp tệp lệnh bổ trợ từ đưá»ng dẫn: '%s' Có vẻ có lá»—i trong mã "
+"nguồn, hãy kiểm tra lại cú pháp."
#: editor/editor_node.cpp
msgid ""
"Unable to load addon script from path: '%s' Base type is not EditorPlugin."
msgstr ""
+"Không thể tải script addon từ đưá»ng dẫn: '%s' Kiểu gốc không phải "
+"EditorPlugin."
#: editor/editor_node.cpp
msgid "Unable to load addon script from path: '%s' Script is not in tool mode."
@@ -2676,7 +2653,7 @@ msgstr "Chuyển Tab cảnh"
#: editor/editor_node.cpp
msgid "%d more files or folders"
-msgstr "%d thêm các tệp hoặc thư mục."
+msgstr "%d tệp hoặc thư mục nữa"
#: editor/editor_node.cpp
msgid "%d more folders"
@@ -2692,11 +2669,11 @@ msgstr "Vị trí Dock"
#: editor/editor_node.cpp
msgid "Distraction Free Mode"
-msgstr ""
+msgstr "Chế độ tập trung"
#: editor/editor_node.cpp
msgid "Toggle distraction-free mode."
-msgstr ""
+msgstr "Bật tắt chế độ tập trung."
#: editor/editor_node.cpp
msgid "Add a new scene."
@@ -2753,7 +2730,7 @@ msgstr "Lưu Cảnh"
#: editor/editor_node.cpp
msgid "Save All Scenes"
-msgstr "Lưu tất cả Cảnh"
+msgstr "Lưu hết các Cảnh"
#: editor/editor_node.cpp
msgid "Convert To..."
@@ -2761,11 +2738,11 @@ msgstr "Chuyển đổi ..."
#: editor/editor_node.cpp
msgid "MeshLibrary..."
-msgstr ""
+msgstr "MeshLibrary..."
#: editor/editor_node.cpp
msgid "TileSet..."
-msgstr ""
+msgstr "TileSet..."
#: editor/editor_node.cpp editor/plugins/script_text_editor.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -2788,7 +2765,7 @@ msgstr "Dá»± Ãn"
#: editor/editor_node.cpp
msgid "Project Settings..."
-msgstr "Cài đặt Dá»± Ãn"
+msgstr "Cài đặt Dá»± Ãn..."
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control"
@@ -2796,21 +2773,19 @@ msgstr "Theo dõi phiên bản"
#: editor/editor_node.cpp editor/plugins/version_control_editor_plugin.cpp
msgid "Set Up Version Control"
-msgstr ""
+msgstr "Cài đặt trình Ä‘iá»u khiển phiên bản"
#: editor/editor_node.cpp
msgid "Shut Down Version Control"
-msgstr ""
+msgstr "Tắt trình Ä‘iá»u khiển phiên bản"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Export..."
-msgstr "Xuất ra"
+msgstr "Xuất..."
#: editor/editor_node.cpp
-#, fuzzy
msgid "Install Android Build Template..."
-msgstr "Cài đặt mẫu xây dựng Android"
+msgstr "Cài đặt mẫu xây dựng Android..."
#: editor/editor_node.cpp
msgid "Open Project Data Folder"
@@ -2870,13 +2845,15 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Visible Collision Shapes"
-msgstr ""
+msgstr "Các khối va chạm thấy được"
#: editor/editor_node.cpp
msgid ""
"When this option is enabled, collision shapes and raycast nodes (for 2D and "
"3D) will be visible in the running project."
msgstr ""
+"Khi bật tùy chá»n này, các khối va chạm và nút chiếu tia (2D và 3D) sẽ được "
+"hiển thị trong dự án đang chạy."
#: editor/editor_node.cpp
msgid "Visible Navigation"
@@ -2887,10 +2864,12 @@ msgid ""
"When this option is enabled, navigation meshes and polygons will be visible "
"in the running project."
msgstr ""
+"Khi bật tùy chá»n này, các lưới/Ä‘a giác Ä‘iá»u hướng sẽ hiển thị trong dá»± án "
+"đang chạy."
#: editor/editor_node.cpp
msgid "Synchronize Scene Changes"
-msgstr ""
+msgstr "Äồng bá»™ hóa các thay đổi lên Cảnh"
#: editor/editor_node.cpp
msgid ""
@@ -2902,7 +2881,7 @@ msgstr ""
#: editor/editor_node.cpp
msgid "Synchronize Script Changes"
-msgstr ""
+msgstr "Äồng bá»™ hóa thay đổi trong Tệp lệnh"
#: editor/editor_node.cpp
msgid ""
@@ -2917,9 +2896,8 @@ msgid "Editor"
msgstr "Editor (trình biên tập)"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Editor Settings..."
-msgstr "Cài đặt Trình biên tập"
+msgstr "Cài đặt Trình biên tập..."
#: editor/editor_node.cpp
msgid "Editor Layout"
@@ -2927,12 +2905,12 @@ msgstr "Cài đặt Bố cục"
#: editor/editor_node.cpp
msgid "Take Screenshot"
-msgstr ""
+msgstr "Chụp màn hình"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Screenshots are stored in the Editor Data/Settings Folder."
-msgstr "Mở thư mục dữ liệu Trình biên tập"
+msgstr ""
+"Ảnh chụp màn hình được lưu ở thư mục Dữ liệu/Cài đặt của trình biên tập."
#: editor/editor_node.cpp
msgid "Toggle Fullscreen"
@@ -2949,16 +2927,15 @@ msgstr "Mở thư mục dữ liệu Trình biên tập"
#: editor/editor_node.cpp
msgid "Open Editor Data Folder"
-msgstr ""
+msgstr "Mở thư mục dữ liệu Trình biên tập"
#: editor/editor_node.cpp
msgid "Open Editor Settings Folder"
-msgstr ""
+msgstr "Mở thư mục Thiết lập Trình biên tập"
#: editor/editor_node.cpp
-#, fuzzy
msgid "Manage Editor Features..."
-msgstr "Quản lý tính năng Trình biên tập"
+msgstr "Quản lý tính năng Trình biên tập..."
#: editor/editor_node.cpp
msgid "Manage Export Templates..."
@@ -2983,7 +2960,7 @@ msgstr "Báo lỗi"
#: editor/editor_node.cpp
msgid "Send Docs Feedback"
-msgstr ""
+msgstr "Gửi ý kiến phản hồi vỠhướng dẫn"
#: editor/editor_node.cpp editor/plugins/asset_library_editor_plugin.cpp
msgid "Community"
@@ -3040,7 +3017,7 @@ msgstr "Lưu & Khởi động lại"
#: editor/editor_node.cpp
msgid "Spins when the editor window redraws."
-msgstr ""
+msgstr "Xoay khi cửa sổ trình biên soạn được vẽ lại."
#: editor/editor_node.cpp
msgid "Update Continuously"
@@ -3052,11 +3029,11 @@ msgstr "Cập nhật khi có thay đổi"
#: editor/editor_node.cpp
msgid "Hide Update Spinner"
-msgstr ""
+msgstr "Ẩn cái xoay xoay cập nhật"
#: editor/editor_node.cpp
msgid "FileSystem"
-msgstr ""
+msgstr "Hệ thống tệp tin"
#: editor/editor_node.cpp
msgid "Inspector"
@@ -3125,7 +3102,7 @@ msgstr "Xuất thư viện ra"
#: editor/editor_node.cpp
msgid "Merge With Existing"
-msgstr ""
+msgstr "Hợp nhất với Hiện có"
#: editor/editor_node.cpp
msgid "Open & Run a Script"
@@ -3171,7 +3148,7 @@ msgstr "Mở Trình biên tập 3D"
#: editor/editor_node.cpp
msgid "Open Script Editor"
-msgstr "Mở Trình biên tập Mã lệnh"
+msgstr "Mở Trình biên soạn Mã lệnh"
#: editor/editor_node.cpp editor/project_manager.cpp
msgid "Open Asset Library"
@@ -3179,11 +3156,11 @@ msgstr "Mở Thư viện Nguyên liệu"
#: editor/editor_node.cpp
msgid "Open the next Editor"
-msgstr ""
+msgstr "Mở Trình biên soạn tiếp theo"
#: editor/editor_node.cpp
msgid "Open the previous Editor"
-msgstr ""
+msgstr "Mở Trình biên soạn trước đó"
#: editor/editor_node.h
msgid "Warning!"
@@ -3191,15 +3168,15 @@ msgstr "Cảnh báo!"
#: editor/editor_path.cpp
msgid "No sub-resources found."
-msgstr ""
+msgstr "Không tìm thấy tài nguyên phụ."
#: editor/editor_plugin.cpp
msgid "Creating Mesh Previews"
-msgstr ""
+msgstr "Tạo bản xem trước lưới"
#: editor/editor_plugin.cpp
msgid "Thumbnail..."
-msgstr ""
+msgstr "Ảnh thu nhá»..."
#: editor/editor_plugin_settings.cpp
msgid "Main Script:"
@@ -3207,11 +3184,11 @@ msgstr "Mã lệnh chính:"
#: editor/editor_plugin_settings.cpp
msgid "Edit Plugin"
-msgstr ""
+msgstr "Chỉnh phần má»m bổ trợ"
#: editor/editor_plugin_settings.cpp
msgid "Installed Plugins:"
-msgstr ""
+msgstr "Các phần má»m bổ trợ đã cài:"
#: editor/editor_plugin_settings.cpp editor/plugin_config_dialog.cpp
msgid "Update"
@@ -3240,7 +3217,7 @@ msgstr "Äo đạc:"
#: editor/editor_profiler.cpp
msgid "Frame Time (sec)"
-msgstr ""
+msgstr "Thá»i gian khung hình (giây)"
#: editor/editor_profiler.cpp
msgid "Average Time (sec)"
@@ -3248,15 +3225,15 @@ msgstr "Thá»i gian trung bình (giây)"
#: editor/editor_profiler.cpp
msgid "Frame %"
-msgstr ""
+msgstr "Khung hình %"
#: editor/editor_profiler.cpp
msgid "Physics Frame %"
-msgstr ""
+msgstr "Khung hình Vật lý %"
#: editor/editor_profiler.cpp
msgid "Inclusive"
-msgstr ""
+msgstr "Bao gồm"
#: editor/editor_profiler.cpp
msgid "Self"
@@ -3264,28 +3241,27 @@ msgstr ""
#: editor/editor_profiler.cpp
msgid "Frame #:"
-msgstr ""
+msgstr "Khung hình #:"
#: editor/editor_profiler.cpp
msgid "Time"
-msgstr ""
+msgstr "Thá»i gian"
#: editor/editor_profiler.cpp
msgid "Calls"
msgstr ""
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Edit Text:"
-msgstr "Lưu Theme"
+msgstr "Sửa văn bản:"
#: editor/editor_properties.cpp editor/script_create_dialog.cpp
msgid "On"
-msgstr ""
+msgstr "Bật"
#: editor/editor_properties.cpp
msgid "Layer"
-msgstr ""
+msgstr "Lá»›p"
#: editor/editor_properties.cpp
msgid "Bit %d, value %d"
@@ -3297,24 +3273,26 @@ msgstr "[Rá»—ng]"
#: editor/editor_properties.cpp editor/plugins/root_motion_editor_plugin.cpp
msgid "Assign..."
-msgstr ""
+msgstr "Gán..."
#: editor/editor_properties.cpp
-#, fuzzy
msgid "Invalid RID"
-msgstr "ÄÆ°á»ng dẫn sai."
+msgstr "Số RID không hợp lệ"
#: editor/editor_properties.cpp
msgid ""
"The selected resource (%s) does not match any type expected for this "
"property (%s)."
msgstr ""
+"Kiểu cá»§a tài nguyên đã chá»n (%s) không dùng được cho thuá»™c tính này (%s)."
#: editor/editor_properties.cpp
msgid ""
"Can't create a ViewportTexture on resources saved as a file.\n"
"Resource needs to belong to a scene."
msgstr ""
+"Không thể tạo ViewportTexture trên các tài nguyên được lưu dưới dạng tệp.\n"
+"Tài nguyên phải thuộc vỠmột cảnh."
#: editor/editor_properties.cpp
msgid ""
@@ -3326,7 +3304,7 @@ msgstr ""
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Pick a Viewport"
-msgstr ""
+msgstr "Chá»n cổng xem"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "New Script"
@@ -3361,11 +3339,11 @@ msgstr "Dán"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Convert To %s"
-msgstr ""
+msgstr "Chuyển thành %s"
#: editor/editor_properties.cpp editor/property_editor.cpp
msgid "Selected node is not a Viewport!"
-msgstr ""
+msgstr "Nút được chá»n không phải Cổng xem!"
#: editor/editor_properties_array_dict.cpp
msgid "Size: "
@@ -3405,27 +3383,27 @@ msgstr "Ghi logic của bạn trong hàm _run()."
#: editor/editor_run_script.cpp
msgid "There is an edited scene already."
-msgstr ""
+msgstr "Äã có má»™t cảnh được chỉnh sá»­a."
#: editor/editor_run_script.cpp
msgid "Couldn't instance script:"
-msgstr ""
+msgstr "Không thể tạo tệp lệnh:"
#: editor/editor_run_script.cpp
msgid "Did you forget the 'tool' keyword?"
-msgstr ""
+msgstr "Bạn quên từ khóa 'tool' à?"
#: editor/editor_run_script.cpp
msgid "Couldn't run script:"
-msgstr ""
+msgstr "Không thể chạy tệp lệnh:"
#: editor/editor_run_script.cpp
msgid "Did you forget the '_run' method?"
-msgstr ""
+msgstr "Bạn quên phương thức '_run' à?"
#: editor/editor_spin_slider.cpp
msgid "Hold Ctrl to round to integers. Hold Shift for more precise changes."
-msgstr ""
+msgstr "Giữ Ctrl để làm tròn vỠsố nguyên. Giữ Shift để sửa tỉ mỉ hơn."
#: editor/editor_sub_scene.cpp
msgid "Select Node(s) to Import"
@@ -3474,8 +3452,9 @@ msgid "(Current)"
msgstr "(Hiện tại)"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Retrieving mirrors, please wait..."
-msgstr ""
+msgstr "Äang tìm các trang mirror, đợi xíu..."
#: editor/export_template_manager.cpp
msgid "Remove template version '%s'?"
@@ -3503,21 +3482,24 @@ msgstr "Trích xuất các Mẫu xuất bản"
#: editor/export_template_manager.cpp
msgid "Importing:"
-msgstr ""
+msgstr "Äang Nhập:"
#: editor/export_template_manager.cpp
msgid "Error getting the list of mirrors."
-msgstr ""
+msgstr "Có lỗi khi lấy các trang mirror."
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Error parsing JSON of mirror list. Please report this issue!"
-msgstr ""
+msgstr "Có lỗi khi phân tích JSON của danh sách trang mirror. Hãy báo cáo lỗi!"
#: editor/export_template_manager.cpp
msgid ""
"No download links found for this version. Direct download is only available "
"for official releases."
msgstr ""
+"Không tìm thấy liên kết để tải phiên bản này. Chỉ có thể tải trực tiếp các "
+"bản chính thức."
#: editor/export_template_manager.cpp
#: editor/plugins/asset_library_editor_plugin.cpp
@@ -3565,13 +3547,12 @@ msgstr ""
"Các lưu trữ mẫu xuất bản có vấn đỠcó thể được tìm thấy tại '%s'."
#: editor/export_template_manager.cpp
-#, fuzzy
msgid "Error requesting URL:"
-msgstr "Lá»—i khi yêu cầu đưá»ng dẫn: "
+msgstr "Lá»—i khi yêu cầu đưá»ng dẫn:"
#: editor/export_template_manager.cpp
msgid "Connecting to Mirror..."
-msgstr ""
+msgstr "Äang kết nối tá»›i trang Mirror..."
#: editor/export_template_manager.cpp
msgid "Disconnected"
@@ -3617,7 +3598,7 @@ msgstr "Lá»—i SSL Handshake"
#: editor/export_template_manager.cpp
msgid "Uncompressing Android Build Sources"
-msgstr ""
+msgstr "Giải nén nguồn xây dựng Android"
#: editor/export_template_manager.cpp
msgid "Current Version:"
@@ -3646,24 +3627,30 @@ msgstr "Các mẫu xuất bản Godot"
#: editor/export_template_manager.cpp
msgid "Export Template Manager"
-msgstr ""
+msgstr "Trình quản lý Mẫu Xuất"
#: editor/export_template_manager.cpp
msgid "Download Templates"
msgstr "Tải Xuống Các Mẫu Xuất Bản"
#: editor/export_template_manager.cpp
+#, fuzzy
msgid "Select mirror from list: (Shift+Click: Open in Browser)"
-msgstr ""
+msgstr "Chá»n trang mirror từ danh sách: (Shift+Nhấp: Mở trong trình duyệt)"
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "Favorites"
-msgstr "Ưa thích:"
+msgstr "Ưa thích"
#: editor/filesystem_dock.cpp
msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr ""
+"Trạng thái: Nhập tệp thất bại. Hãy sửa tệp rồi nhập lại theo cách thủ công."
+
+#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
@@ -3710,6 +3697,11 @@ msgid ""
"\n"
"Do you wish to overwrite them?"
msgstr ""
+"Các tệp hoặc thư mục sau xung đột với các mục ở vị trí đích '%s':\n"
+"\n"
+"%s\n"
+"\n"
+"Bạn có muốn ghi đè không?"
#: editor/filesystem_dock.cpp
msgid "Renaming file:"
@@ -3765,9 +3757,8 @@ msgid "Move To..."
msgstr "Di chuyển đến..."
#: editor/filesystem_dock.cpp
-#, fuzzy
msgid "New Scene..."
-msgstr "Tạo Cảnh Mới"
+msgstr "Tạo Cảnh Mới..."
#: editor/filesystem_dock.cpp editor/plugins/script_editor_plugin.cpp
msgid "New Script..."
@@ -3965,7 +3956,7 @@ msgstr "Các nút trong Nhóm"
#: editor/groups_editor.cpp
msgid "Empty groups will be automatically removed."
-msgstr ""
+msgstr "Các nhóm trống sẽ tự động bị xóa."
#: editor/groups_editor.cpp
#, fuzzy
@@ -4019,11 +4010,11 @@ msgstr ""
#: editor/import/resource_importer_scene.cpp
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Import Scene"
-msgstr ""
+msgstr "Nhập cảnh"
#: editor/import/resource_importer_scene.cpp
msgid "Importing Scene..."
-msgstr ""
+msgstr "Äang nhập cảnh ..."
#: editor/import/resource_importer_scene.cpp
msgid "Generating Lightmaps"
@@ -4031,27 +4022,28 @@ msgstr ""
#: editor/import/resource_importer_scene.cpp
msgid "Generating for Mesh: "
-msgstr ""
+msgstr "Tạo cho lưới: "
#: editor/import/resource_importer_scene.cpp
msgid "Running Custom Script..."
-msgstr ""
+msgstr "Chạy Tệp lệnh Tá»± chá»n ..."
#: editor/import/resource_importer_scene.cpp
msgid "Couldn't load post-import script:"
-msgstr ""
+msgstr "Không thể tải tệp lệnh sau nhập:"
#: editor/import/resource_importer_scene.cpp
msgid "Invalid/broken script for post-import (check console):"
-msgstr ""
+msgstr "Tập lệnh sau nhập không hợp lệ/há»ng (hãy xem bảng Ä‘iá»u khiển):"
#: editor/import/resource_importer_scene.cpp
msgid "Error running post-import script:"
-msgstr ""
+msgstr "Lỗi khi chạy tập lệnh sau nhập:"
#: editor/import/resource_importer_scene.cpp
msgid "Did you return a Node-derived object in the `post_import()` method?"
msgstr ""
+"Bạn có trả vỠmột vật kế thừa Nút trong phương thức 'post_import' không đấy?"
#: editor/import/resource_importer_scene.cpp
msgid "Saving..."
@@ -4063,9 +4055,8 @@ msgid "Select Importer"
msgstr "Chế độ chá»n"
#: editor/import_defaults_editor.cpp
-#, fuzzy
msgid "Importer:"
-msgstr "Nhập vào"
+msgstr "Công cụ nhập:"
#: editor/import_defaults_editor.cpp
#, fuzzy
@@ -4073,9 +4064,12 @@ msgid "Reset to Defaults"
msgstr "Nạp mặc định"
#: editor/import_dock.cpp
-#, fuzzy
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
-msgstr " Tệp tin"
+msgstr "%d Tệp"
#: editor/import_dock.cpp
msgid "Set as Default for '%s'"
@@ -4090,9 +4084,8 @@ msgid "Import As:"
msgstr "Nhập vào với:"
#: editor/import_dock.cpp
-#, fuzzy
msgid "Preset"
-msgstr "Cài sẵn ..."
+msgstr "Cài sẵn"
#: editor/import_dock.cpp
msgid "Reimport"
@@ -4105,16 +4098,18 @@ msgstr "Lưu các cảnh, nhập vào lại và khởi động lại"
#: editor/import_dock.cpp
msgid "Changing the type of an imported file requires editor restart."
-msgstr ""
+msgstr "Sửa kiểu của tệp đã nhập yêu cầu khởi động lại trình biên soạn."
#: editor/import_dock.cpp
msgid ""
"WARNING: Assets exist that use this resource, they may stop loading properly."
msgstr ""
+"CẢNH BÃO: Có tài nguyên khác sá»­ dụng tài nguyên này, chúng có thể gặp trục "
+"trặc khi nạp đấy."
#: editor/inspector_dock.cpp
msgid "Failed to load resource."
-msgstr ""
+msgstr "Nạp tài nguyên thất bại."
#: editor/inspector_dock.cpp
msgid "Expand All Properties"
@@ -4147,7 +4142,7 @@ msgstr ""
#: editor/inspector_dock.cpp
msgid "Make Sub-Resources Unique"
-msgstr ""
+msgstr "Biến tài nguyên phụ thành độc nhất"
#: editor/inspector_dock.cpp
msgid "Open in Help"
@@ -4155,11 +4150,11 @@ msgstr "Mở trong Trợ giúp"
#: editor/inspector_dock.cpp
msgid "Create a new resource in memory and edit it."
-msgstr ""
+msgstr "Tạo tài nguyên mới trong bộ nhớ rồi chỉnh sửa."
#: editor/inspector_dock.cpp
msgid "Load an existing resource from disk and edit it."
-msgstr ""
+msgstr "Tải tài nguyên có sẵn trong đĩa rồi chỉnh sửa."
#: editor/inspector_dock.cpp
msgid "Save the currently edited resource."
@@ -4167,15 +4162,15 @@ msgstr "Lưu tài nguyên đã chỉnh sửa hiện tại."
#: editor/inspector_dock.cpp
msgid "Go to the previous edited object in history."
-msgstr ""
+msgstr "Äi tá»›i đối tượng má»›i chỉnh sá»­a trước đó trong lịch sá»­."
#: editor/inspector_dock.cpp
msgid "Go to the next edited object in history."
-msgstr ""
+msgstr "Äi đến đối tượng được chỉnh sá»­a liá»n sau trong lịch sá»­."
#: editor/inspector_dock.cpp
msgid "History of recently edited objects."
-msgstr ""
+msgstr "Lịch sử các đối tượng được chỉnh sửa gần đây."
#: editor/inspector_dock.cpp
msgid "Object properties."
@@ -4199,7 +4194,7 @@ msgstr "Chá»n nút duy nhất để chỉnh sá»­a tính hiệu và nhóm cá»§a
#: editor/plugin_config_dialog.cpp
msgid "Edit a Plugin"
-msgstr ""
+msgstr "Chỉnh phần má»m bổ trợ"
#: editor/plugin_config_dialog.cpp
#, fuzzy
@@ -4208,7 +4203,7 @@ msgstr "Tạo & Sửa"
#: editor/plugin_config_dialog.cpp
msgid "Plugin Name:"
-msgstr ""
+msgstr "Tên phần má»m bổ trợ:"
#: editor/plugin_config_dialog.cpp
msgid "Subfolder:"
@@ -4266,7 +4261,7 @@ msgstr "Sửa Polygon (Gỡ điểm)"
#: editor/plugins/abstract_polygon_2d_editor.cpp
msgid "Remove Polygon And Point"
-msgstr ""
+msgstr "Xóa đa giác và điểm"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4316,7 +4311,7 @@ msgstr "Thêm điểm Hoạt ảnh"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Remove BlendSpace1D Point"
-msgstr ""
+msgstr "Xóa điểm BlendSpace1D"
#: editor/plugins/animation_blend_space_1d_editor.cpp
msgid "Move BlendSpace1D Node Point"
@@ -4344,7 +4339,7 @@ msgstr ""
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp scene/gui/graph_edit.cpp
msgid "Enable snap and show grid."
-msgstr "Kích hoạt Snap và hiện Grid."
+msgstr "Bật Dính và hiện lưới."
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4355,7 +4350,7 @@ msgstr "Äiểm"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
msgid "Open Editor"
-msgstr ""
+msgstr "Mở Trình biên soạn"
#: editor/plugins/animation_blend_space_1d_editor.cpp
#: editor/plugins/animation_blend_space_2d_editor.cpp
@@ -4384,7 +4379,7 @@ msgstr "Äổi Thá»i gian Chuyển Animation"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Remove BlendSpace2D Point"
-msgstr ""
+msgstr "Xóa điểm BlendSpace2D"
#: editor/plugins/animation_blend_space_2d_editor.cpp
#, fuzzy
@@ -4406,11 +4401,11 @@ msgstr "Bật tắt Ưa thích"
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Create triangles by connecting points."
-msgstr ""
+msgstr "Nối các điểm để tạo tam giác."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Erase points and triangles."
-msgstr ""
+msgstr "Xóa tam giác và các điểm."
#: editor/plugins/animation_blend_space_2d_editor.cpp
msgid "Generate blend triangles automatically (instead of manually)"
@@ -4496,19 +4491,16 @@ msgstr ""
"Trính phát hoạt ảnh không có đưá»ng dẫn nút Gốc, không thể truy xuất tên."
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Anim Clips"
-msgstr "Âm thanh:"
+msgstr "Các đoạn hoạt ảnh"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Audio Clips"
-msgstr "Âm thanh:"
+msgstr "Các đoạn âm thanh"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
-#, fuzzy
msgid "Functions"
-msgstr "Hàm:"
+msgstr "Hàm"
#: editor/plugins/animation_blend_tree_editor_plugin.cpp
#: editor/plugins/animation_state_machine_editor.cpp
@@ -4646,7 +4638,7 @@ msgstr "Chỉnh sửa Chuyển tiếp ..."
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Open in Inspector"
-msgstr ""
+msgstr "Mở trong Trình kiểm tra"
#: editor/plugins/animation_player_editor_plugin.cpp
msgid "Display list of animations in player."
@@ -4741,9 +4733,8 @@ msgid "Move Node"
msgstr "Di chuyển Nút"
#: editor/plugins/animation_state_machine_editor.cpp
-#, fuzzy
msgid "Transition exists!"
-msgstr "Chuyển tiếp: "
+msgstr "Chuyển tiếp đã tồn tại!"
#: editor/plugins/animation_state_machine_editor.cpp
msgid "Add Transition"
@@ -5004,23 +4995,20 @@ msgid "Request failed, return code:"
msgstr "Yêu cầu thất bại, trả lại code:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed."
msgstr "Yêu cầu thất bại."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Cannot save response to:"
-msgstr "Không thể gỡ bá»:"
+msgstr "Không thể lưu phản hồi tới:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Write error."
-msgstr ""
+msgstr "Ghi bị lỗi."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed, too many redirects"
-msgstr "Yêu cầu thất bại, gá»­i lại quá nhiá»u"
+msgstr "Yêu cầu thất bại, chuyển hướng quá nhiá»u"
#: editor/plugins/asset_library_editor_plugin.cpp
#, fuzzy
@@ -5028,14 +5016,12 @@ msgid "Redirect loop."
msgstr "Chuyển hướng vòng lặp."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Request failed, timeout"
-msgstr "Yêu cầu thất bại, trả lại code:"
+msgstr "Yêu cầu thất bại, quá thá»i gian chá»"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Timeout."
-msgstr "Thá»i gian:"
+msgstr "Quá giá»."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Bad download hash, assuming file has been tampered with."
@@ -5051,7 +5037,7 @@ msgstr "Nhận được:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Failed SHA-256 hash check"
-msgstr ""
+msgstr "Kiểm tra băm SHA-256 thất bại"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Asset Download Error:"
@@ -5078,9 +5064,8 @@ msgid "Idle"
msgstr "Chạy không"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Install..."
-msgstr "Cài đặt"
+msgstr "Cài đặt..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Retry"
@@ -5096,29 +5081,27 @@ msgstr "Tải xuống nguyên liệu này đã được tiến hành!"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Recently Updated"
-msgstr ""
+msgstr "Cập nhật gần đây"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Least Recently Updated"
-msgstr ""
+msgstr "Lâu chưa cập nhật nhất"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (A-Z)"
-msgstr ""
+msgstr "Tên (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Name (Z-A)"
-msgstr ""
+msgstr "Tên (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (A-Z)"
-msgstr "Cấp phép"
+msgstr "Giấy phép (A-Z)"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "License (Z-A)"
-msgstr "Cấp phép"
+msgstr "Giấy phép (Z-A)"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "First"
@@ -5142,16 +5125,15 @@ msgstr "Tất cả"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "No results for \"%s\"."
-msgstr ""
+msgstr "Không tìm thấy kết quả cho \"%s\"."
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Import..."
-msgstr "Nhập vào"
+msgstr "Nhập..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Plugins..."
-msgstr ""
+msgstr "Các phần má»m bổ trợ..."
#: editor/plugins/asset_library_editor_plugin.cpp editor/project_manager.cpp
msgid "Sort:"
@@ -5163,12 +5145,11 @@ msgstr "Danh mục:"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Site:"
-msgstr ""
+msgstr "Trang:"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Support"
-msgstr "Hỗ trợ ..."
+msgstr "Hỗ trợ"
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Official"
@@ -5179,9 +5160,8 @@ msgid "Testing"
msgstr "Kiểm tra"
#: editor/plugins/asset_library_editor_plugin.cpp
-#, fuzzy
msgid "Loading..."
-msgstr "Nạp ..."
+msgstr "Äang tải..."
#: editor/plugins/asset_library_editor_plugin.cpp
msgid "Assets ZIP File"
@@ -5225,7 +5205,7 @@ msgstr ""
#: editor/plugins/baked_lightmap_editor_plugin.cpp
#, fuzzy
msgid "Select lightmap bake file:"
-msgstr "Chá»n file template"
+msgstr "Chá»n tệp bake lightmap:"
#: editor/plugins/camera_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5234,24 +5214,23 @@ msgstr "Xem thá»­"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Configure Snap"
-msgstr "Cấu hình Snap"
+msgstr "Cài đặt Dính"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr ""
+msgstr "Äá»™ lệch lưới:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
-msgstr ""
+msgstr "Bước lưới:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Primary Line Every:"
-msgstr ""
+msgstr "ÄÆ°á»ng kẻ chính Má»—i:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "steps"
-msgstr "2 bước"
+msgstr "bước"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
@@ -5259,98 +5238,85 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
-msgstr ""
+msgstr "Bước xoay:"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale Step:"
-msgstr "Tỷ lệ:"
+msgstr "Bước thu phóng:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Vertical Guide"
-msgstr ""
+msgstr "Di chuyển đưá»ng căn dá»c"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Create Vertical Guide"
-msgstr "Tạo Folder"
+msgstr "Tạo đưá»ng căn dá»c"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Vertical Guide"
-msgstr "Xoá Variable"
+msgstr "Xoá đưá»ng căn dá»c"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Move Horizontal Guide"
-msgstr ""
+msgstr "Di chuyển đưá»ng căn ngang"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Horizontal Guide"
-msgstr "Tạo đưá»ng Guide ngang"
+msgstr "Tạo đưá»ng căn ngang"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Remove Horizontal Guide"
-msgstr "Hủy key không đúng chuẩn"
+msgstr "Xóa đưá»ng căn ngang"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Horizontal and Vertical Guides"
-msgstr ""
+msgstr "Tạo đưá»ng căn ngang và dá»c"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Set CanvasItem \"%s\" Pivot Offset to (%d, %d)"
-msgstr ""
+msgstr "Äặt độ dá»i cá»§a CanvasItem \"%s\" tá»›i (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate %d CanvasItems"
-msgstr "Xoay CanvasItem"
+msgstr "Xoay %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Rotate CanvasItem \"%s\" to %d degrees"
-msgstr "Xoay CanvasItem"
+msgstr "Xoay CanvasItem \"%s\" thành %d độ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" Anchor"
-msgstr "Di chuyển CanvasItem"
+msgstr "Di chuyển neo CanvasItem \"%s\""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Scale Node2D \"%s\" to (%s, %s)"
-msgstr ""
+msgstr "Thu phóng Node2D \"%s\" thành (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Resize Control \"%s\" to (%d, %d)"
-msgstr ""
+msgstr "Chỉnh kích cỡ Nút Äiá»u khiển \"%s\" thành (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale %d CanvasItems"
-msgstr "Tỉ lệ CanvasItem"
+msgstr "Thu phóng %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Scale CanvasItem \"%s\" to (%s, %s)"
-msgstr "Tỉ lệ CanvasItem"
+msgstr "Thu phóng CanvasItem \"%s\" thành (%s, %s)"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move %d CanvasItems"
-msgstr "Di chuyển CanvasItem"
+msgstr "Di chuyển %d CanvasItem"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Move CanvasItem \"%s\" to (%d, %d)"
-msgstr "Di chuyển CanvasItem"
+msgstr "Di chuyển CanvasItem \"%s\" tới (%d, %d)"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
"Children of containers have their anchors and margins values overridden by "
"their parent."
-msgstr ""
-"Mục con trong thùng chứa có giá trị neo và lỠcủa chúng được ghi đè bởi cha "
-"chúng."
+msgstr "Các nút Container sẽ ép các nút con theo neo và lỠmà nó xác định."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Presets for the anchors and margins values of a Control node."
@@ -5361,28 +5327,28 @@ msgid ""
"When active, moving Control nodes changes their anchors instead of their "
"margins."
msgstr ""
-"Khi hoạt động, các nút Control di chuyển thay đổi các neo thay vì lỠcủa "
-"chúng."
+"Khi bật, di chuyển các nút Control sẽ thay đổi neo thay vì lỠcủa chúng."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Left"
-msgstr ""
+msgstr "Góc trên trái"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Top Right"
-msgstr ""
+msgstr "Góc trên phải"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Right"
-msgstr ""
+msgstr "Góc dưới phải"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Bottom Left"
-msgstr ""
+msgstr "Góc dưới trái"
#: editor/plugins/canvas_item_editor_plugin.cpp
+#, fuzzy
msgid "Center Left"
-msgstr ""
+msgstr "Trung tâm Bên trái"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Top"
@@ -5428,16 +5394,15 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Full Rect"
-msgstr ""
+msgstr "Rộng hết cỡ"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Keep Ratio"
-msgstr "Tỉ lệ Scale:"
+msgstr "Giữ Tỉ lệ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Anchors only"
-msgstr "Chỉ các neo"
+msgstr "Chỉ neo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Anchors and Margins"
@@ -5486,9 +5451,8 @@ msgid "Paste Pose"
msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Clear Guides"
-msgstr "Xoá khung xương"
+msgstr "Xóa hết đưá»ng căn"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Create Custom Bone(s) from Node(s)"
@@ -5511,6 +5475,8 @@ msgid ""
"Warning: Children of a container get their position and size determined only "
"by their parent."
msgstr ""
+"Cảnh báo: Nút Container đã xác định kích cỡ và vị trí cho các nút con của nó "
+"rồi."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -5537,7 +5503,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Alt+RMB: Depth list selection"
-msgstr ""
+msgstr "Alt+chuá»™t phải: Chá»n theo tầng"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5552,7 +5518,7 @@ msgstr "Chế độ Xoay"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Mode"
-msgstr "Chế độ Tỉ lệ"
+msgstr "Chế độ căn Tỉ lệ"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
@@ -5569,7 +5535,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan Mode"
-msgstr ""
+msgstr "Chế độ Xoay"
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
@@ -5578,95 +5544,92 @@ msgstr "Chế độ Tỉ lệ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle smart snapping."
-msgstr ""
+msgstr "Bật tắt Dính thông minh."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Smart Snap"
-msgstr "Sử dụng Snap"
+msgstr "Sử dụng Dính thông minh"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Toggle grid snapping."
-msgstr ""
+msgstr "Bật tắt Dính lưới."
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Grid Snap"
-msgstr "Sử dụng Snap"
+msgstr "Sử dụng Dính lưới"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snapping Options"
-msgstr ""
+msgstr "Tùy chá»n Dính"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Rotation Snap"
-msgstr ""
+msgstr "Dùng Dính ở chế độ Xoay"
#: editor/plugins/canvas_item_editor_plugin.cpp
-#, fuzzy
msgid "Use Scale Snap"
-msgstr "Sử dụng Snap"
+msgstr "Dính theo bước tỉ lệ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap Relative"
-msgstr ""
+msgstr "Dính tương đối"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Use Pixel Snap"
-msgstr ""
+msgstr "Dính điểm ảnh"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Smart Snapping"
-msgstr ""
+msgstr "Dính thông minh"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Configure Snap..."
-msgstr ""
+msgstr "Cài đặt Dính..."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Parent"
-msgstr ""
+msgstr "Dính vỠnút Mẹ"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Anchor"
-msgstr "Snap đến neo của Nút"
+msgstr "Dính nút vào điểm neo"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Sides"
-msgstr "Snap sang hai bên nút"
+msgstr "Dính vào các cạnh của Nút"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Node Center"
-msgstr "Snap đến chính giữa nút"
+msgstr "Dính vào tâm Nút"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Other Nodes"
-msgstr "Snap đế các nút khác"
+msgstr "Dính vào các Nút khác"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Snap to Guides"
-msgstr ""
+msgstr "Dính vào ÄÆ°á»ng căn"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock the selected object in place (can't be moved)."
-msgstr ""
+msgstr "Khóa vị trí vật (không cho dịch chuyển)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Unlock the selected object (can be moved)."
-msgstr ""
+msgstr "Thôi khóa vị trí vật (cho phép di chuyển)."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Makes sure the object's children are not selectable."
-msgstr ""
+msgstr "Hãy chắc rằng nút con cá»§a vật ở trạng thái Không thể chá»n."
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Restores the object's children's ability to be selected."
-msgstr ""
+msgstr "Khôi phục khả năng được chá»n nút con cá»§a vật."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Skeleton Options"
@@ -5674,7 +5637,7 @@ msgstr "Cài đặt Khung xương"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Bones"
-msgstr ""
+msgstr "Hiển thị Xương"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Make Custom Bone(s) from Node(s)"
@@ -5696,7 +5659,7 @@ msgstr "Hiện lưới"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Helpers"
-msgstr ""
+msgstr "Hiển thị trợ giúp"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Rulers"
@@ -5704,19 +5667,19 @@ msgstr "Hiện thước"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Guides"
-msgstr ""
+msgstr "Hiện đưá»ng căn"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Origin"
-msgstr ""
+msgstr "Hiện Gốc"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Viewport"
-msgstr ""
+msgstr "Hiện Cổng xem"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Show Group And Lock Icons"
-msgstr ""
+msgstr "Hiện biểu tượng Nhóm và Khóa"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Center Selection"
@@ -5724,7 +5687,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Frame Selection"
-msgstr ""
+msgstr "Lá»±a chá»n khung hình"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Preview Canvas Scale"
@@ -5745,7 +5708,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
#, fuzzy
msgid "Insert keys (based on mask)."
-msgstr "Chèn Key Anim"
+msgstr "Chèn Khóa (dựa trên mask)."
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid ""
@@ -5771,7 +5734,7 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Copy Pose"
-msgstr ""
+msgstr "Sao chép Tư thế"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Clear Pose"
@@ -5779,11 +5742,11 @@ msgstr ""
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Multiply grid step by 2"
-msgstr ""
+msgstr "Gấp đôi bước lưới"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Divide grid step by 2"
-msgstr ""
+msgstr "Chia đôi bước lưới"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Pan View"
@@ -5809,7 +5772,7 @@ msgstr "Tạo Nút"
#: editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Error instancing scene from %s"
-msgstr ""
+msgstr "Lỗi khởi tạo cảnh từ %s"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Change Default Type"
@@ -5837,7 +5800,7 @@ msgstr "Sửa Poly (Xoá điểm)"
#: editor/plugins/collision_shape_2d_editor_plugin.cpp
msgid "Set Handle"
-msgstr ""
+msgstr "Äặt tay nắm"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5848,9 +5811,8 @@ msgstr ""
#: editor/plugins/cpu_particles_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
-#, fuzzy
msgid "Restart"
-msgstr "Restart ngay"
+msgstr "Khởi động lại"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5861,7 +5823,7 @@ msgstr ""
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Particles"
-msgstr ""
+msgstr "Hạt"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5876,12 +5838,12 @@ msgstr ""
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Solid Pixels"
-msgstr ""
+msgstr "Äiểm ảnh rắn"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
msgid "Border Pixels"
-msgstr ""
+msgstr "Äiểm ảnh viá»n"
#: editor/plugins/cpu_particles_2d_editor_plugin.cpp
#: editor/plugins/particles_2d_editor_plugin.cpp
@@ -5922,12 +5884,13 @@ msgid "Flat 1"
msgstr ""
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
+#, fuzzy
msgid "Ease In"
-msgstr ""
+msgstr "Trưá»n vào"
#: editor/plugins/curve_editor_plugin.cpp editor/property_editor.cpp
msgid "Ease Out"
-msgstr ""
+msgstr "Trưá»n ra"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Smoothstep"
@@ -5935,11 +5898,11 @@ msgstr ""
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Point"
-msgstr ""
+msgstr "Sửa điểm uốn"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Modify Curve Tangent"
-msgstr ""
+msgstr "Sửa tiếp tuyến điểm uốn"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Load Curve Preset"
@@ -5965,11 +5928,11 @@ msgstr "Tịnh tuyến"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Load Preset"
-msgstr ""
+msgstr "Nạp cài đặt trước"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Remove Curve Point"
-msgstr ""
+msgstr "Xóa điểm uốn"
#: editor/plugins/curve_editor_plugin.cpp
msgid "Toggle Curve Linear Tangent"
@@ -5977,7 +5940,7 @@ msgstr ""
#: editor/plugins/curve_editor_plugin.cpp
msgid "Hold Shift to edit tangents individually"
-msgstr ""
+msgstr "Giữ Shift để sửa từng tiếp tuyến một"
#: editor/plugins/curve_editor_plugin.cpp
#, fuzzy
@@ -5994,11 +5957,11 @@ msgstr ""
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item %d"
-msgstr ""
+msgstr "Mục %d"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Items"
-msgstr ""
+msgstr "Mục"
#: editor/plugins/item_list_editor_plugin.cpp
msgid "Item List Editor"
@@ -6010,7 +5973,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh is empty!"
-msgstr ""
+msgstr "Lưới trống!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Couldn't create a Trimesh collision shape."
@@ -6022,7 +5985,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "This doesn't work on scene root!"
-msgstr ""
+msgstr "Không thể áp dụng lên Cảnh gốc!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Shape"
@@ -6057,7 +6020,7 @@ msgstr "Tạo hình dạng lồi"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Navigation Mesh"
-msgstr ""
+msgstr "Tạo lưới Ä‘iá»u hướng"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Contained Mesh is not of type ArrayMesh."
@@ -6069,7 +6032,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "No mesh to debug."
-msgstr ""
+msgstr "Không có lưới để gỡ lỗi."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Model has no UV in this layer"
@@ -6077,7 +6040,7 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "MeshInstance lacks a Mesh!"
-msgstr ""
+msgstr "MeshInstance thiếu lưới!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh has not surface to create outlines from!"
@@ -6089,15 +6052,15 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Could not create outline!"
-msgstr ""
+msgstr "Không thể tạo đưá»ng viá»n!"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline"
-msgstr ""
+msgstr "Tạo đưá»ng viá»n"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Mesh"
-msgstr ""
+msgstr "Lưới"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Static Body"
@@ -6109,6 +6072,8 @@ msgid ""
"automatically.\n"
"This is the most accurate (but slowest) option for collision detection."
msgstr ""
+"Tạo một StaticBody rồi tự động gắn một khối va chạm hình đa giác.\n"
+"Äây là tùy chá»n phát hiện va chạm chính xác (nhưng chậm) nhất."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Trimesh Collision Sibling"
@@ -6119,6 +6084,8 @@ msgid ""
"Creates a polygon-based collision shape.\n"
"This is the most accurate (but slowest) option for collision detection."
msgstr ""
+"Tạo một khối va chạm đa giác.\n"
+"Äây là cách phát hiện va chạm chính xác (nhưng chậm) nhất."
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -6130,6 +6097,8 @@ msgid ""
"Creates a single convex collision shape.\n"
"This is the fastest (but least accurate) option for collision detection."
msgstr ""
+"Tạo một khối va chạm lồi.\n"
+"Äây là cách phát hiện va chạm nhanh (nhưng ẩu) nhất."
#: editor/plugins/mesh_instance_editor_plugin.cpp
#, fuzzy
@@ -6141,10 +6110,12 @@ msgid ""
"Creates a polygon-based collision shape.\n"
"This is a performance middle-ground between the two above options."
msgstr ""
+"Tạo một khối va chạm đa giác.\n"
+"Äây là tùy chá»n có hiệu suất cân bằng so vá»›i hai tùy chá»n trên."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh..."
-msgstr ""
+msgstr "Tạo lưới viá»n..."
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid ""
@@ -6168,11 +6139,11 @@ msgstr ""
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Create Outline Mesh"
-msgstr ""
+msgstr "Tạo lưới viá»n"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "Outline Size:"
-msgstr ""
+msgstr "Kích cỡ viá»n:"
#: editor/plugins/mesh_instance_editor_plugin.cpp
msgid "UV Channel Debug"
@@ -6180,13 +6151,15 @@ msgstr ""
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Remove item %d?"
-msgstr ""
+msgstr "Xóa mục %d?"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid ""
"Update from existing scene?:\n"
"%s"
msgstr ""
+"Cập nhật từ cảnh hiện có?:\n"
+"%s"
#: editor/plugins/mesh_library_editor_plugin.cpp
#, fuzzy
@@ -6196,19 +6169,19 @@ msgstr "Xuất Mesh Library"
#: editor/plugins/mesh_library_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Item"
-msgstr ""
+msgstr "Thêm mục"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Remove Selected Item"
-msgstr ""
+msgstr "Xóa mục đã chá»n"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Import from Scene"
-msgstr ""
+msgstr "Nhập từ Cảnh"
#: editor/plugins/mesh_library_editor_plugin.cpp
msgid "Update from Scene"
-msgstr ""
+msgstr "Cập nhật từ Cảnh"
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No mesh source specified (and no MultiMesh set in node)."
@@ -6221,15 +6194,15 @@ msgstr ""
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (invalid path)."
-msgstr ""
+msgstr "Nguồn lưới không hợp lệ (đưá»ng dẫn không hợp lệ)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (not a MeshInstance)."
-msgstr ""
+msgstr "Nguồn lưới không hợp lệ (không phải MeshInstance)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "Mesh source is invalid (contains no Mesh resource)."
-msgstr ""
+msgstr "Nguồn lưới không hợp lệ (không chứa tài nguyên Lưới)."
#: editor/plugins/multimesh_editor_plugin.cpp
msgid "No surface source specified."
@@ -6333,7 +6306,7 @@ msgstr "Xóa Animation"
#: editor/plugins/particles_2d_editor_plugin.cpp
#: editor/plugins/particles_editor_plugin.cpp
msgid "Generation Time (sec):"
-msgstr ""
+msgstr "Thá»i gian tạo (giây):"
#: editor/plugins/particles_editor_plugin.cpp
msgid "The geometry's faces don't contain any area."
@@ -6346,7 +6319,7 @@ msgstr "Cảnh không chứa tệp lệnh."
#: editor/plugins/particles_editor_plugin.cpp
msgid "\"%s\" doesn't inherit from Spatial."
-msgstr ""
+msgstr "\"%s\" không kế thừa từ Spatial."
#: editor/plugins/particles_editor_plugin.cpp
msgid "\"%s\" doesn't contain geometry."
@@ -6394,7 +6367,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Point from Curve"
-msgstr ""
+msgstr "Xóa Ä‘iểm khá»i đưá»ng cong"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Remove Out-Control from Curve"
@@ -6407,7 +6380,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Add Point to Curve"
-msgstr ""
+msgstr "Thêm Äiểm vào ÄÆ°á»ng cong"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Split Curve"
@@ -6415,7 +6388,7 @@ msgstr "Chia đưá»ng Curve"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move Point in Curve"
-msgstr ""
+msgstr "Di chuyển Äiểm trên ÄÆ°á»ng cong"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Move In-Control in Curve"
@@ -6442,7 +6415,7 @@ msgstr "Nhấp: Tạo Point"
#: editor/plugins/path_2d_editor_plugin.cpp
msgid "Left Click: Split Segment (in curve)"
-msgstr ""
+msgstr "Chuá»™t trái: Phân tách các Ä‘oạn (trong đưá»ng cong)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -6456,7 +6429,7 @@ msgstr ""
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Add Point (in empty space)"
-msgstr ""
+msgstr "Thêm điểm (trong không gian trống)"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
@@ -6466,31 +6439,33 @@ msgstr "Xóa Point"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
msgid "Close Curve"
-msgstr ""
+msgstr "Äóng đưá»ng cong"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp editor/project_export.cpp
msgid "Options"
-msgstr ""
+msgstr "Tùy chá»n"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
+#, fuzzy
msgid "Mirror Handle Angles"
-msgstr ""
+msgstr "Äối xứng góc tay cầm"
#: editor/plugins/path_2d_editor_plugin.cpp
#: editor/plugins/path_editor_plugin.cpp
+#, fuzzy
msgid "Mirror Handle Lengths"
-msgstr ""
+msgstr "Äối xứng độ dài tay cầm"
#: editor/plugins/path_editor_plugin.cpp
msgid "Curve Point #"
-msgstr ""
+msgstr "Äiểm uốn #"
#: editor/plugins/path_editor_plugin.cpp
msgid "Set Curve Point Position"
-msgstr ""
+msgstr "Äặt vị trí Ä‘iểm uốn"
#: editor/plugins/path_editor_plugin.cpp
msgid "Set Curve In Position"
@@ -6502,7 +6477,7 @@ msgstr ""
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Path"
-msgstr ""
+msgstr "Tách đưá»ng"
#: editor/plugins/path_editor_plugin.cpp
msgid "Remove Path Point"
@@ -6518,12 +6493,11 @@ msgstr ""
#: editor/plugins/path_editor_plugin.cpp
msgid "Split Segment (in curve)"
-msgstr ""
+msgstr "Phân tách Ä‘oạn (trong đưá»ng cong)"
#: editor/plugins/physical_bone_plugin.cpp
-#, fuzzy
msgid "Move Joint"
-msgstr "Di chuyển đến..."
+msgstr "Di chuyển Khớp"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
@@ -6532,7 +6506,7 @@ msgstr "Thuộc tính xương của nút Polygon2D không trỠđến nút Skel
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones"
-msgstr ""
+msgstr "Äồng bá»™ Xương"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid ""
@@ -6564,7 +6538,7 @@ msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Invalid Polygon (need 3 different vertices)"
-msgstr ""
+msgstr "Äa giác không hợp lệ (cần 3 đỉnh khác nhau)"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6602,9 +6576,8 @@ msgid "UV"
msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Points"
-msgstr "Di chuyển đến..."
+msgstr "Các Äiểm"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6613,12 +6586,11 @@ msgstr "Tạo"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Bones"
-msgstr ""
+msgstr "Xương"
#: editor/plugins/polygon_2d_editor_plugin.cpp
-#, fuzzy
msgid "Move Points"
-msgstr "Di chuyển đến..."
+msgstr "Di chuyển các điểm"
#: editor/plugins/polygon_2d_editor_plugin.cpp
#, fuzzy
@@ -6627,31 +6599,31 @@ msgstr "Kéo: Xoay"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift: Move All"
-msgstr ""
+msgstr "Shift: Di chuyển tất"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift+Command: Scale"
-msgstr ""
+msgstr "Shift+Command: Thu phóng"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Ctrl: Rotate"
-msgstr ""
+msgstr "Ctrl: Xoay"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Shift+Ctrl: Scale"
-msgstr ""
+msgstr "Shift+Ctrl: Thu phóng"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Move Polygon"
-msgstr ""
+msgstr "Di chuyển đa g"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Rotate Polygon"
-msgstr ""
+msgstr "Xoay đa giác"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Scale Polygon"
-msgstr ""
+msgstr "Thu phóng đa giác"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Create a custom polygon. Enables custom polygon rendering."
@@ -6673,7 +6645,7 @@ msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Radius:"
-msgstr ""
+msgstr "Bán kính:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Copy Polygon to UV"
@@ -6690,19 +6662,19 @@ msgstr ""
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Settings"
-msgstr ""
+msgstr "Thiết lập lưới"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Snap"
-msgstr ""
+msgstr "Dính"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Enable Snap"
-msgstr ""
+msgstr "Bật Dính"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid"
-msgstr ""
+msgstr "Lưới"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Show Grid"
@@ -6710,44 +6682,44 @@ msgstr "Hiện lưới"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Configure Grid:"
-msgstr ""
+msgstr "Cài đặt Lưới:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset X:"
-msgstr ""
+msgstr "Äá»™ lệch X cá»§a Lưới:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Offset Y:"
-msgstr ""
+msgstr "Äá»™ lệch Y cá»§a Lưới:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step X:"
-msgstr ""
+msgstr "Bước Lưới trục X:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Grid Step Y:"
-msgstr ""
+msgstr "Bước Lưới trục Y:"
#: editor/plugins/polygon_2d_editor_plugin.cpp
msgid "Sync Bones to Polygon"
-msgstr ""
+msgstr "Äồng bá»™ Xương vá»›i Äa giác"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ERROR: Couldn't load resource!"
-msgstr ""
+msgstr "LỖI: Không thể nạp tài nguyên!"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Add Resource"
-msgstr ""
+msgstr "Thêm tài nguyên"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Rename Resource"
-msgstr ""
+msgstr "Äổi tên tài nguyên"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Delete Resource"
-msgstr ""
+msgstr "Xóa tài nguyên"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Resource clipboard is empty!"
@@ -6755,7 +6727,7 @@ msgstr ""
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Paste Resource"
-msgstr ""
+msgstr "Dán tài nguyên"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_editor.cpp
@@ -6767,16 +6739,16 @@ msgstr ""
#: editor/scene_tree_editor.cpp editor/script_editor_debugger.cpp
#: modules/visual_script/visual_script_editor.cpp
msgid "Type:"
-msgstr ""
+msgstr "Kiểu:"
#: editor/plugins/resource_preloader_editor_plugin.cpp
#: editor/scene_tree_dock.cpp editor/scene_tree_editor.cpp
msgid "Open in Editor"
-msgstr ""
+msgstr "Mở trong Trình biên soạn"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "Load Resource"
-msgstr ""
+msgstr "Nạp tài nguyên"
#: editor/plugins/resource_preloader_editor_plugin.cpp
msgid "ResourcePreloader"
@@ -6784,11 +6756,11 @@ msgstr ""
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "AnimationTree has no path set to an AnimationPlayer"
-msgstr ""
+msgstr "AnimationTree chưa đặt đưá»ng dẫn đến AnimationPlayer nào"
#: editor/plugins/root_motion_editor_plugin.cpp
msgid "Path to AnimationPlayer is invalid"
-msgstr ""
+msgstr "ÄÆ°á»ng dẫn tá»›i AnimationPlayer không hợp lệ"
#: editor/plugins/script_editor_plugin.cpp
msgid "Clear Recent Files"
@@ -6796,11 +6768,11 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Close and save changes?"
-msgstr ""
+msgstr "Äóng và lưu thay đổi?"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error writing TextFile:"
-msgstr ""
+msgstr "Lỗi viết TextFile:"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6808,29 +6780,24 @@ msgid "Could not load file at:"
msgstr "Không viết được file:"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error saving file!"
-msgstr "Lỗi tải font."
+msgstr "Lỗi lưu tệp!"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error while saving theme."
-msgstr "Lỗi khi lưu scene."
+msgstr "Lỗi khi lưu Tông màu."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Saving"
-msgstr "Lỗi di chuyển:"
+msgstr "Lỗi Khi Lưu"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error importing theme."
-msgstr "Lỗi khi lưu scene."
+msgstr "Lỗi khi nhập Tông màu."
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Error Importing"
-msgstr "Lỗi di chuyển:"
+msgstr "Lỗi Khi Nhập"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6849,7 +6816,7 @@ msgstr "Lưu Scene với tên..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Can't obtain the script for running."
-msgstr ""
+msgstr "Không thể lấy tệp lệnh để chạy."
#: editor/plugins/script_editor_plugin.cpp
msgid "Script failed reloading, check console for errors."
@@ -6866,33 +6833,33 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme"
-msgstr ""
+msgstr "Nhập Tông màu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error while saving theme"
-msgstr ""
+msgstr "Lỗi khi lưu Tông màu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Error saving"
-msgstr ""
+msgstr "Lỗi khi lưu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme As..."
-msgstr ""
+msgstr "Lưu Tông màu thành..."
#: editor/plugins/script_editor_plugin.cpp
msgid "%s Class Reference"
-msgstr ""
+msgstr "Tham khảo Lớp %s"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Next"
-msgstr "Tìm tiếp theo"
+msgstr "Tìm tiếp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp
msgid "Find Previous"
-msgstr ""
+msgstr "Tìm trước đó"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6901,7 +6868,7 @@ msgstr "Lá»c các thuá»™c tính"
#: editor/plugins/script_editor_plugin.cpp
msgid "Toggle alphabetical sorting of the method list."
-msgstr ""
+msgstr "Bật/tắt sắp xếp danh sách phương thức theo bảng chữ cái."
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6910,7 +6877,7 @@ msgstr "Lá»c các nút"
#: editor/plugins/script_editor_plugin.cpp
msgid "Sort"
-msgstr ""
+msgstr "Sắp xếp"
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
@@ -6926,20 +6893,19 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Next script"
-msgstr ""
+msgstr "Tệp lệnh tiếp theo"
#: editor/plugins/script_editor_plugin.cpp
msgid "Previous script"
-msgstr ""
+msgstr "Tệp lệnh trước đó"
#: editor/plugins/script_editor_plugin.cpp
msgid "File"
-msgstr ""
+msgstr "Tệp"
#: editor/plugins/script_editor_plugin.cpp
-#, fuzzy
msgid "Open..."
-msgstr "Mở"
+msgstr "Mở..."
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6948,7 +6914,7 @@ msgstr "Tạo Script"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save All"
-msgstr ""
+msgstr "Lưu tất cả"
#: editor/plugins/script_editor_plugin.cpp
msgid "Soft Reload Script"
@@ -6956,7 +6922,7 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Copy Script Path"
-msgstr ""
+msgstr "Sao chép đưá»ng dẫn tệp lệnh"
#: editor/plugins/script_editor_plugin.cpp
#, fuzzy
@@ -6970,19 +6936,19 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme"
-msgstr ""
+msgstr "Tông màu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Import Theme..."
-msgstr ""
+msgstr "Nhập Tông màu..."
#: editor/plugins/script_editor_plugin.cpp
msgid "Reload Theme"
-msgstr ""
+msgstr "Tải lại Tông màu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Save Theme"
-msgstr "Lưu Theme"
+msgstr "Lưu Tông màu"
#: editor/plugins/script_editor_plugin.cpp
msgid "Close All"
@@ -7031,11 +6997,11 @@ msgstr ""
#: editor/plugins/script_editor_plugin.cpp
msgid "Open Godot online documentation."
-msgstr ""
+msgstr "Mở tài liệu Godot trực tuyến."
#: editor/plugins/script_editor_plugin.cpp
msgid "Search the reference documentation."
-msgstr ""
+msgstr "Tìm tài liệu tham khảo."
#: editor/plugins/script_editor_plugin.cpp
msgid "Go to previous edited document."
@@ -7089,12 +7055,11 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp
msgid "[Ignore]"
-msgstr ""
+msgstr "[Bá» qua]"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Line"
-msgstr "Dòng:"
+msgstr "Dòng"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7120,15 +7085,15 @@ msgstr "Chá»n màu"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Convert Case"
-msgstr ""
+msgstr "Chuyển đổi Hoa thưá»ng"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Uppercase"
-msgstr ""
+msgstr "Chữ hoa"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Lowercase"
-msgstr ""
+msgstr "Chữ thưá»ng"
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Capitalize"
@@ -7136,22 +7101,21 @@ msgstr ""
#: editor/plugins/script_text_editor.cpp editor/plugins/text_editor.cpp
msgid "Syntax Highlighter"
-msgstr ""
+msgstr "Nổi màu cú pháp"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Bookmarks"
-msgstr ""
+msgstr "Dấu trang"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Breakpoints"
-msgstr "Tạo các điểm."
+msgstr "Äiểm dừng"
#: editor/plugins/script_text_editor.cpp
#: editor/plugins/shader_editor_plugin.cpp editor/plugins/text_editor.cpp
msgid "Go To"
-msgstr ""
+msgstr "Äi tá»›i"
#: editor/plugins/script_text_editor.cpp editor/scene_tree_dock.cpp
#: scene/gui/line_edit.cpp scene/gui/text_edit.cpp
@@ -7165,31 +7129,31 @@ msgstr "Chá»n Toàn Bá»™"
#: editor/plugins/script_text_editor.cpp
msgid "Delete Line"
-msgstr ""
+msgstr "Xóa dòng"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Left"
-msgstr ""
+msgstr "Thụt lỠTrái"
#: editor/plugins/script_text_editor.cpp
msgid "Indent Right"
-msgstr ""
+msgstr "Thụt lỠphải"
#: editor/plugins/script_text_editor.cpp
msgid "Toggle Comment"
-msgstr ""
+msgstr "Bật/tắt chú thích"
#: editor/plugins/script_text_editor.cpp
msgid "Fold/Unfold Line"
-msgstr ""
+msgstr "Cuộn/Trải dòng"
#: editor/plugins/script_text_editor.cpp
msgid "Fold All Lines"
-msgstr ""
+msgstr "Cuộn tất cả các dòng"
#: editor/plugins/script_text_editor.cpp
msgid "Unfold All Lines"
-msgstr ""
+msgstr "Trải tất cả các dòng"
#: editor/plugins/script_text_editor.cpp
msgid "Clone Down"
@@ -7206,19 +7170,19 @@ msgstr "Chá»n Scale"
#: editor/plugins/script_text_editor.cpp
msgid "Trim Trailing Whitespace"
-msgstr ""
+msgstr "Xóa khoảng trắng cuối dòng"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Spaces"
-msgstr ""
+msgstr "Chuyển thụt lỠthành Dấu cách"
#: editor/plugins/script_text_editor.cpp
msgid "Convert Indent to Tabs"
-msgstr ""
+msgstr "Chuyển thụt lỠthành Tab"
#: editor/plugins/script_text_editor.cpp
msgid "Auto Indent"
-msgstr ""
+msgstr "Thụt lỠTự động"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7246,26 +7210,25 @@ msgstr "Äến Step trước đó"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Bookmarks"
-msgstr ""
+msgstr "Xóa hết má»i dấu trang"
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Function..."
-msgstr "Xoá Function"
+msgstr "Äi tá»›i Hàm..."
#: editor/plugins/script_text_editor.cpp
-#, fuzzy
msgid "Go to Line..."
-msgstr "Äến Dòng"
+msgstr "Äến Dòng..."
#: editor/plugins/script_text_editor.cpp
#: modules/visual_script/visual_script_editor.cpp
+#, fuzzy
msgid "Toggle Breakpoint"
-msgstr ""
+msgstr "Tạo điểm dừng"
#: editor/plugins/script_text_editor.cpp
msgid "Remove All Breakpoints"
-msgstr ""
+msgstr "Xóa hết má»i Ä‘iểm dừng"
#: editor/plugins/script_text_editor.cpp
#, fuzzy
@@ -7302,19 +7265,19 @@ msgstr ""
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Skeleton2D"
-msgstr ""
+msgstr "Skeleton2D"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Make Rest Pose (From Bones)"
-msgstr ""
+msgstr "Tạo tư thế nghỉ (Từ Xương)"
#: editor/plugins/skeleton_2d_editor_plugin.cpp
msgid "Set Bones to Rest Pose"
-msgstr ""
+msgstr "Äặt Xương thành Tư thế Nghỉ"
#: editor/plugins/skeleton_editor_plugin.cpp
msgid "Create physical bones"
-msgstr ""
+msgstr "Tạo xương vật lý"
#: editor/plugins/skeleton_editor_plugin.cpp
#, fuzzy
@@ -7322,8 +7285,9 @@ msgid "Skeleton"
msgstr "Xóa Point"
#: editor/plugins/skeleton_editor_plugin.cpp
+#, fuzzy
msgid "Create physical skeleton"
-msgstr ""
+msgstr "Tạo bộ xương vật lý"
#: editor/plugins/skeleton_ik_editor_plugin.cpp
msgid "Play IK"
@@ -7386,9 +7350,8 @@ msgid "Yaw"
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
-#, fuzzy
msgid "Size"
-msgstr "Kích thước: "
+msgstr "Kích cỡ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Objects Drawn"
@@ -7468,7 +7431,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "No parent to instance a child at."
-msgstr ""
+msgstr "Không có nút mẹ để khởi tạo nút con."
#: editor/plugins/spatial_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "This operation requires a single selected node."
@@ -7480,7 +7443,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Lock View Rotation"
-msgstr ""
+msgstr "Khóa xoay ở chế độ xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Display Normal"
@@ -7508,19 +7471,20 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Information"
-msgstr ""
+msgstr "Xem thông tin"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View FPS"
-msgstr ""
+msgstr "Xem tốc độ khung hình"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Half Resolution"
-msgstr ""
+msgstr "Nửa độ phân giải"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Audio Listener"
-msgstr ""
+msgstr "Trình nghe âm thanh"
#: editor/plugins/spatial_editor_plugin.cpp
#, fuzzy
@@ -7533,7 +7497,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Not available when using the GLES2 renderer."
-msgstr ""
+msgstr "Không khả dụng khi sử dụng trình kết xuất GLES2."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Freelook Left"
@@ -7569,13 +7533,15 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Rotation Locked"
-msgstr ""
+msgstr "Äã khóa xoay ở chế độ xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid ""
"Note: The FPS value displayed is the editor's framerate.\n"
"It cannot be used as a reliable indication of in-game performance."
msgstr ""
+"Lưu ý: Tốc độ khung hình được hiển thị là của trình biên soạn.\n"
+"Äừng lấy đó làm mốc để đánh giá hiệu suất."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "XForm Dialog"
@@ -7591,8 +7557,9 @@ msgid ""
msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Snap Nodes To Floor"
-msgstr "Snap các nút đến Floor"
+msgstr "Dính Nút lên Sàn"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Couldn't find a solid floor to snap the selection to."
@@ -7604,38 +7571,41 @@ msgid ""
"Alt+Drag: Move\n"
"Alt+RMB: Depth list selection"
msgstr ""
+"Kéo: Xoay\n"
+"Alt+Kéo: Di chuyển\n"
+"Alt+Chuá»™t phải: Chá»n theo tầng"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Local Space"
-msgstr ""
+msgstr "Sử dụng Không gian Cục bộ"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Use Snap"
-msgstr "Sử dụng Snap"
+msgstr "Sử dụng Dính"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Bottom View"
-msgstr ""
+msgstr "Góc nhìn đáy"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Top View"
-msgstr ""
+msgstr "Góc nhìn đỉnh"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rear View"
-msgstr ""
+msgstr "Góc nhìn lưng"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Front View"
-msgstr ""
+msgstr "Góc nhìn trực diện"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Left View"
-msgstr ""
+msgstr "Góc nhìn trái"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Right View"
-msgstr ""
+msgstr "Góc nhìn phải"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Switch Perspective/Orthogonal View"
@@ -7643,7 +7613,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Insert Animation Key"
-msgstr ""
+msgstr "Chèn khóa Hoạt ảnh"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Focus Origin"
@@ -7659,24 +7629,26 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
#: editor/plugins/visual_shader_editor_plugin.cpp
+#, fuzzy
msgid "Transform"
-msgstr ""
+msgstr "Biến đổi"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Object to Floor"
-msgstr ""
+msgstr "Dính Vật lên Sàn"
#: editor/plugins/spatial_editor_plugin.cpp
+#, fuzzy
msgid "Transform Dialog..."
-msgstr ""
+msgstr "Hộp thoại Biến đổi ..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "1 Viewport"
-msgstr ""
+msgstr "1 Cổng xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports"
-msgstr ""
+msgstr "2 Cổng xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "2 Viewports (Alt)"
@@ -7684,7 +7656,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports"
-msgstr ""
+msgstr "3 Cổng xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "3 Viewports (Alt)"
@@ -7692,7 +7664,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "4 Viewports"
-msgstr ""
+msgstr "4 Cổng xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Gizmos"
@@ -7704,7 +7676,7 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "View Grid"
-msgstr ""
+msgstr "Xem Lưới"
#: editor/plugins/spatial_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -7714,7 +7686,7 @@ msgstr "Äang kết nối..."
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Settings"
-msgstr ""
+msgstr "Thiết lập Dính"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Translate Snap:"
@@ -7722,15 +7694,15 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate Snap (deg.):"
-msgstr ""
+msgstr "Dính theo Bước xoay (độ):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale Snap (%):"
-msgstr ""
+msgstr "Thu Phóng Dính (%):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Viewport Settings"
-msgstr ""
+msgstr "Cài đặt Cổng xem"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Perspective FOV (deg.):"
@@ -7754,11 +7726,11 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Rotate (deg.):"
-msgstr ""
+msgstr "Xoay (theo độ):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Scale (ratio):"
-msgstr ""
+msgstr "Thu phóng (theo tỉ lệ):"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Transform Type"
@@ -7766,11 +7738,11 @@ msgstr ""
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Pre"
-msgstr ""
+msgstr "Trước"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Post"
-msgstr ""
+msgstr "Sau"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Nameless gizmo"
@@ -7793,7 +7765,7 @@ msgstr "Tạo"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Polygon2D Preview"
-msgstr ""
+msgstr "Xem trước Polygon2D"
#: editor/plugins/sprite_editor_plugin.cpp
#, fuzzy
@@ -7816,8 +7788,9 @@ msgid "LightOccluder2D Preview"
msgstr "Tạo Folder"
#: editor/plugins/sprite_editor_plugin.cpp
+#, fuzzy
msgid "Sprite is empty!"
-msgstr ""
+msgstr "Sprite trống!"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Can't convert a sprite using animation frames to mesh."
@@ -7829,7 +7802,7 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Convert to Mesh2D"
-msgstr ""
+msgstr "Chuyển thành Mesh2D"
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Invalid geometry, can't create polygon."
@@ -7863,11 +7836,11 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Simplification: "
-msgstr ""
+msgstr "ÄÆ¡n giản hóa: "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Shrink (Pixels): "
-msgstr ""
+msgstr "Thu nhá» (Äiểm ảnh): "
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Grow (Pixels): "
@@ -7879,7 +7852,7 @@ msgstr ""
#: editor/plugins/sprite_editor_plugin.cpp
msgid "Settings:"
-msgstr ""
+msgstr "Cài đặt:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7888,15 +7861,15 @@ msgstr "Xoá lá»±a chá»n"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add %d Frame(s)"
-msgstr ""
+msgstr "Thêm %d Khung hình"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Frame"
-msgstr ""
+msgstr "Thêm Khung hình"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Unable to load images"
-msgstr ""
+msgstr "Không tải được hình ảnh"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "ERROR: Couldn't load frame resource!"
@@ -7912,15 +7885,15 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Add Empty"
-msgstr ""
+msgstr "Thêm Rỗng"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Change Animation FPS"
-msgstr ""
+msgstr "Thay đổi tốc độ hoạt ảnh"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "(empty)"
-msgstr ""
+msgstr "(trống)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7928,9 +7901,8 @@ msgid "Move Frame"
msgstr "Di chuyển Nút"
#: editor/plugins/sprite_frames_editor_plugin.cpp
-#, fuzzy
msgid "Animations:"
-msgstr "Các Công cụ Animation"
+msgstr "Các hoạt ảnh:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7939,11 +7911,11 @@ msgstr "Tạo Animation mới"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Speed:"
-msgstr ""
+msgstr "Tốc độ:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Loop"
-msgstr ""
+msgstr "Lặp"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7961,19 +7933,19 @@ msgstr ""
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (Before)"
-msgstr ""
+msgstr "Chèn Rỗng (Trước)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Insert Empty (After)"
-msgstr ""
+msgstr "Chèn Rỗng (Sau)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (Before)"
-msgstr ""
+msgstr "Di chuyển (Trước)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Move (After)"
-msgstr ""
+msgstr "Di chuyển (Sau)"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7982,15 +7954,15 @@ msgstr "Chá»n Points"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Horizontal:"
-msgstr ""
+msgstr "Ngang:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Vertical:"
-msgstr ""
+msgstr "Dá»c:"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "Select/Clear All Frames"
-msgstr ""
+msgstr "Chá»n/Xóa Tất cả Khung hình"
#: editor/plugins/sprite_frames_editor_plugin.cpp
#, fuzzy
@@ -7999,7 +7971,7 @@ msgstr "Tạo từ Scene"
#: editor/plugins/sprite_frames_editor_plugin.cpp
msgid "SpriteFrames"
-msgstr ""
+msgstr "SpriteFrames"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Region Rect"
@@ -8007,11 +7979,11 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Set Margin"
-msgstr ""
+msgstr "Äặt Lá»"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Snap Mode:"
-msgstr ""
+msgstr "Chế độ Dính:"
#: editor/plugins/texture_region_editor_plugin.cpp
#: scene/resources/visual_shader.cpp
@@ -8020,11 +7992,11 @@ msgstr "Không có"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Pixel Snap"
-msgstr ""
+msgstr "Dính Äiểm ảnh"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Grid Snap"
-msgstr ""
+msgstr "Dính lưới"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Auto Slice"
@@ -8036,7 +8008,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
-msgstr ""
+msgstr "Bước:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Sep.:"
@@ -8044,7 +8016,7 @@ msgstr ""
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "TextureRegion"
-msgstr ""
+msgstr "TextureRegion"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All Items"
@@ -8052,24 +8024,23 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add All"
-msgstr ""
+msgstr "Thêm Tất cả"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Remove All Items"
-msgstr ""
+msgstr "Xóa tất cả các mục"
#: editor/plugins/theme_editor_plugin.cpp editor/project_manager.cpp
msgid "Remove All"
-msgstr ""
+msgstr "Xoá tất cả"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Edit Theme"
-msgstr "Lưu Theme"
+msgstr "Chỉnh Tông màu"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Theme editing menu."
-msgstr ""
+msgstr "Menu chỉnh Tông màu."
#: editor/plugins/theme_editor_plugin.cpp
msgid "Add Class Items"
@@ -8081,7 +8052,7 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Template"
-msgstr ""
+msgstr "Tạo Mẫu Trống"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create Empty Editor Template"
@@ -8089,7 +8060,7 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Create From Current Editor Theme"
-msgstr ""
+msgstr "Tạo từ Tông màu Trình biên soạn hiện tại"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8103,7 +8074,7 @@ msgstr "Tắt"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Item"
-msgstr ""
+msgstr "Mục"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8112,11 +8083,11 @@ msgstr "Tắt"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Check Item"
-msgstr ""
+msgstr "Äánh dấu mục"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Checked Item"
-msgstr ""
+msgstr "Mục đã đánh dấu"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Radio Item"
@@ -8132,23 +8103,23 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Submenu"
-msgstr ""
+msgstr "Menu phụ"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subitem 1"
-msgstr ""
+msgstr "Mục phụ 1"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subitem 2"
-msgstr ""
+msgstr "Mục phụ 2"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has"
-msgstr ""
+msgstr "Có"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Many"
-msgstr ""
+msgstr "Nhiá»u"
#: editor/plugins/theme_editor_plugin.cpp
#, fuzzy
@@ -8174,7 +8145,7 @@ msgstr "Chỉnh Thá»i gian Chuyển Animation"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Subtree"
-msgstr ""
+msgstr "Cây con"
#: editor/plugins/theme_editor_plugin.cpp
msgid "Has,Many,Options"
@@ -8182,12 +8153,12 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Data Type:"
-msgstr ""
+msgstr "Kiểu Dữ liệu:"
#: editor/plugins/theme_editor_plugin.cpp
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Icon"
-msgstr ""
+msgstr "Biểu tượng"
#: editor/plugins/theme_editor_plugin.cpp editor/rename_dialog.cpp
msgid "Style"
@@ -8199,20 +8170,19 @@ msgstr ""
#: editor/plugins/theme_editor_plugin.cpp
msgid "Color"
-msgstr ""
+msgstr "Màu"
#: editor/plugins/theme_editor_plugin.cpp
-#, fuzzy
msgid "Theme File"
-msgstr "Mở"
+msgstr "Tệp Tông màu"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase Selection"
-msgstr ""
+msgstr "Xóa Lá»±a chá»n"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Fix Invalid Tiles"
-msgstr ""
+msgstr "Sửa các ô không hợp lệ"
#: editor/plugins/tile_map_editor_plugin.cpp
#: modules/gridmap/grid_map_editor_plugin.cpp
@@ -8222,11 +8192,11 @@ msgstr "Nhân đôi lá»±a chá»n"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint TileMap"
-msgstr ""
+msgstr "Tô TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Line Draw"
-msgstr ""
+msgstr "Vẽ đưá»ng"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rectangle Paint"
@@ -8238,7 +8208,7 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Erase TileMap"
-msgstr ""
+msgstr "Xóa TileMap"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8247,7 +8217,7 @@ msgstr "Tìm tiếp theo"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Transpose"
-msgstr ""
+msgstr "Chuyển vị"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Disable Autotile"
@@ -8258,17 +8228,17 @@ msgid "Enable Priority"
msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
-#, fuzzy
msgid "Filter tiles"
-msgstr "Lá»c tệp tin ..."
+msgstr "Lá»c ô"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Give a TileSet resource to this TileMap to use its tiles."
msgstr ""
+"Hãy cung cấp tài nguyên TileSet cho TileMap này để sử dụng các ô của nó."
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Paint Tile"
-msgstr ""
+msgstr "Tô ô"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid ""
@@ -8284,23 +8254,23 @@ msgstr ""
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Pick Tile"
-msgstr ""
+msgstr "Chá»n ô"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Left"
-msgstr ""
+msgstr "Xoay Trái"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Rotate Right"
-msgstr ""
+msgstr "Xoay Phải"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Horizontally"
-msgstr ""
+msgstr "Lật Ngang"
#: editor/plugins/tile_map_editor_plugin.cpp
msgid "Flip Vertically"
-msgstr ""
+msgstr "Lật Dá»c"
#: editor/plugins/tile_map_editor_plugin.cpp
#, fuzzy
@@ -8308,14 +8278,12 @@ msgid "Clear Transform"
msgstr "Äổi Transform Animation"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Add Texture(s) to TileSet."
-msgstr "Chèn Texture(s) vào TileSet"
+msgstr "Thêm Há»a tiết vào TileSet."
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected Texture from TileSet."
-msgstr "Xóa Texture hiện tại từ TileSet"
+msgstr "Xóa Há»a tiết hiện tại khá»i TileSet."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from Scene"
@@ -8341,7 +8309,7 @@ msgstr "Má»›i %s"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Next Coordinate"
-msgstr ""
+msgstr "Tá»a độ tiếp theo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Select the next shape, subtile, or Tile."
@@ -8372,7 +8340,7 @@ msgstr "Tạo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Navigation"
-msgstr ""
+msgstr "Äiá»u hướng"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Bitmask"
@@ -8402,7 +8370,7 @@ msgstr "Tạo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Navigation Mode"
-msgstr "Chế độ Navigation"
+msgstr "Chế độ di chuyển"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Bitmask Mode"
@@ -8426,9 +8394,8 @@ msgid "Copy bitmask."
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Paste bitmask."
-msgstr "Dán Animation"
+msgstr "Dán bitmask."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Erase bitmask."
@@ -8444,9 +8411,8 @@ msgid "New Rectangle"
msgstr "Tạo Cảnh Mới"
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Create a new polygon."
-msgstr "Tạo"
+msgstr "Tạo đa giác mới."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8464,11 +8430,11 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Enable snap and show grid (configurable via the Inspector)."
-msgstr ""
+msgstr "Bật Dính và hiện lưới (có thể cài đặt thông qua Trình kiểm tra)."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Display Tile Names (Hold Alt Key)"
-msgstr ""
+msgstr "Hiển thị tên ô (Giữ phím Alt)"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8476,21 +8442,20 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Remove selected texture? This will remove all tiles which use it."
-msgstr "Xóa Texture hiện tại từ TileSet"
+msgstr "Xóa Há»a tiết đã chá»n? Các ô dùng há»a tiết này cÅ©ng bốc hÆ¡i luôn đó."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "You haven't selected a texture to remove."
-msgstr ""
+msgstr "Bạn chưa chá»n há»a tiết để xóa."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Create from scene? This will overwrite all current tiles."
-msgstr ""
+msgstr "Tạo từ Cảnh? Việc này sẽ ghi đè lên tất cả các ô hiện tại."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Merge from scene?"
-msgstr ""
+msgstr "Hợp nhất từ cảnh?"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8499,7 +8464,7 @@ msgstr "Xóa Template"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "%s file(s) were not added because was already on the list."
-msgstr ""
+msgstr "%s tệp không được thêm vào vì đã có trong danh sách."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8519,9 +8484,8 @@ msgid ""
msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
-#, fuzzy
msgid "Delete polygon."
-msgstr "Tạo"
+msgstr "Xóa đa giác."
#: editor/plugins/tile_set_editor_plugin.cpp
msgid ""
@@ -8594,7 +8558,7 @@ msgstr ""
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Make Polygon Concave"
-msgstr ""
+msgstr "Biến thành đa giác lõm"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8608,7 +8572,7 @@ msgstr "Xóa Template"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Collision Polygon"
-msgstr ""
+msgstr "Xóa khối va chạm đa giác"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Remove Occlusion Polygon"
@@ -8621,11 +8585,11 @@ msgstr "Xóa Animation"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Priority"
-msgstr ""
+msgstr "Chỉnh độ ưu tiên của ô"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "Edit Tile Z Index"
-msgstr ""
+msgstr "Sá»­a chiá»u sâu (Z) cá»§a ô"
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8649,7 +8613,7 @@ msgstr "Tạo"
#: editor/plugins/tile_set_editor_plugin.cpp
msgid "This property can't be changed."
-msgstr ""
+msgstr "Không thể thay đổi thuộc tính này."
#: editor/plugins/tile_set_editor_plugin.cpp
#, fuzzy
@@ -8658,11 +8622,11 @@ msgstr "Xuất Tile Set"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No VCS addons are available."
-msgstr ""
+msgstr "Không có phần má»m kiểm soát phiên bản khả dụng."
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Error"
-msgstr ""
+msgstr "Lá»—i"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "No files added to stage"
@@ -8679,11 +8643,11 @@ msgstr ""
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Version Control System"
-msgstr ""
+msgstr "Phần má»m kiểm soát phiên bản"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Initialize"
-msgstr ""
+msgstr "Khởi tạo"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "Staging area"
@@ -8735,7 +8699,7 @@ msgstr "Äổi"
#: editor/plugins/version_control_editor_plugin.cpp
#: modules/gdnative/gdnative_library_singleton_editor.cpp
msgid "Status"
-msgstr ""
+msgstr "Trạng thái"
#: editor/plugins/version_control_editor_plugin.cpp
msgid "View file diffs before committing them to the latest version"
@@ -8751,7 +8715,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "(GLES3 only)"
-msgstr ""
+msgstr "(Chỉ dành cho GLES3)"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8759,17 +8723,16 @@ msgid "Add Output"
msgstr "Thêm Input"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Scalar"
-msgstr "Tỷ lệ:"
+msgstr "Tỷ lệ"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector"
-msgstr ""
+msgstr "Vector"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean"
-msgstr ""
+msgstr "Boolean"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sampler"
@@ -8782,7 +8745,7 @@ msgstr "Thêm Input"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add output port"
-msgstr ""
+msgstr "Thêm cổng đầu ra"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8796,11 +8759,11 @@ msgstr "Äổi dạng mặc định"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Change input port name"
-msgstr ""
+msgstr "Äổi tên cổng đầu vào"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Change output port name"
-msgstr ""
+msgstr "Äổi tên cổng đầu ra"
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -8827,7 +8790,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Set Input Default Port"
-msgstr ""
+msgstr "Äặt cổng đầu vào mặc định"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Add Node to Visual Shader"
@@ -8862,11 +8825,11 @@ msgstr "Äối số đã thay đổi"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vertex"
-msgstr ""
+msgstr "Äỉnh"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Fragment"
-msgstr ""
+msgstr "Mảnh"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Light"
@@ -8896,16 +8859,15 @@ msgstr "Tạo Function"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts HSV vector to RGB equivalent."
-msgstr ""
+msgstr "Chuyển đổi vector HSV sang RGB tương đương."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts RGB vector to HSV equivalent."
-msgstr ""
+msgstr "Chuyển đổi vector RGB sang HSV tương đương."
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Sepia function."
-msgstr "Äổi tên Hàm"
+msgstr "Hàm Sepia."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Burn operator."
@@ -8956,19 +8918,19 @@ msgstr "Äổi Transform Animation"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the %s comparison between two parameters."
-msgstr ""
+msgstr "Trả vỠkết quả boolean của phép so sánh %s giữa hai tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Equal (==)"
-msgstr ""
+msgstr "Bằng (==)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than (>)"
-msgstr ""
+msgstr "Lớn hơn (>)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Greater Than or Equal (>=)"
-msgstr ""
+msgstr "Lớn hơn hoặc Bằng (>=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -8981,24 +8943,28 @@ msgid ""
"Returns the boolean result of the comparison between INF and a scalar "
"parameter."
msgstr ""
+"Trả vỠkết quả boolean của phép so sánh giữa Vô cùng (INF) và một tham số vô "
+"hướng."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between NaN and a scalar "
"parameter."
msgstr ""
+"Trả vỠkết quả boolean so sánh giữa NaN (Không phải số) và một tham số vô "
+"hướng."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than (<)"
-msgstr ""
+msgstr "NhỠhơn (<)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Less Than or Equal (<=)"
-msgstr ""
+msgstr "NhỠhơn hoặc Bằng (<=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Not Equal (!=)"
-msgstr ""
+msgstr "Không bằng (!=)"
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9012,17 +8978,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the boolean result of the comparison between two parameters."
-msgstr ""
+msgstr "Trả vỠkết quả boolean so sánh giữa hai tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the boolean result of the comparison between INF (or NaN) and a "
"scalar parameter."
msgstr ""
+"Trả vỠkết quả boolean của phép so sánh giữa INF (hoặc NaN) và một tham số "
+"vô hướng."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean constant."
-msgstr ""
+msgstr "Hằng số Boolean."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Boolean uniform."
@@ -9034,7 +9002,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Input parameter."
-msgstr ""
+msgstr "Tham số đầu vào."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "'%s' input parameter for vertex and fragment shader modes."
@@ -9071,43 +9039,43 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "E constant (2.718282). Represents the base of the natural logarithm."
-msgstr ""
+msgstr "Hằng số E (2,718282). Cơ số của logarit tự nhiên."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Epsilon constant (0.00001). Smallest possible scalar number."
-msgstr ""
+msgstr "Hằng số Epsilon (0,00001). Số vô hướng nhỠnhất có thể."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Phi constant (1.618034). Golden ratio."
-msgstr ""
+msgstr "Hằng số Phi (1.618034). Tỷ lệ vàng."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/4 constant (0.785398) or 45 degrees."
-msgstr ""
+msgstr "Hằng số Pi/4 (0,785398) hay còn là 45 độ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi/2 constant (1.570796) or 90 degrees."
-msgstr ""
+msgstr "Hằng số Pi/2 (1.570796) hay còn là 90 độ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Pi constant (3.141593) or 180 degrees."
-msgstr ""
+msgstr "Hằng số Pi (3,141593) hay còn là 180 độ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Tau constant (6.283185) or 360 degrees."
-msgstr ""
+msgstr "Hằng số Tau (6,283185) hay còn là 360 độ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Sqrt2 constant (1.414214). Square root of 2."
-msgstr ""
+msgstr "Hằng số Sqrt2 (1,414214). Căn bậc hai của 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the absolute value of the parameter."
-msgstr ""
+msgstr "Trả vỠgiá trị tuyệt đối của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-cosine of the parameter."
-msgstr ""
+msgstr "Trả vỠarc-cosine của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic cosine of the parameter."
@@ -9115,7 +9083,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-sine of the parameter."
-msgstr ""
+msgstr "Trả vỠarc-sin của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic sine of the parameter."
@@ -9123,11 +9091,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameter."
-msgstr ""
+msgstr "Trả vỠarc-tan của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the arc-tangent of the parameters."
-msgstr ""
+msgstr "Trả vỠarc-tan của các tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse hyperbolic tangent of the parameter."
@@ -9136,7 +9104,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Finds the nearest integer that is greater than or equal to the parameter."
-msgstr ""
+msgstr "Tìm số nguyên gần nhất lớn hơn hoặc bằng tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Constrains a value to lie between two further values."
@@ -9144,7 +9112,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the cosine of the parameter."
-msgstr ""
+msgstr "Trả vỠcosine của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic cosine of the parameter."
@@ -9152,23 +9120,23 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in radians to degrees."
-msgstr ""
+msgstr "Äổi radian vỠđộ."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-e Exponential."
-msgstr ""
+msgstr "Lũy thừa cơ số e."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 Exponential."
-msgstr ""
+msgstr "Lũy thừa cơ số 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer less than or equal to the parameter."
-msgstr ""
+msgstr "Tìm số nguyên gần nhất nhỠhơn hoặc bằng tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Computes the fractional part of the argument."
-msgstr ""
+msgstr "Tính phần phân số của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the inverse of the square root of the parameter."
@@ -9176,19 +9144,19 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Natural logarithm."
-msgstr ""
+msgstr "Logarit tự nhiên."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Base-2 logarithm."
-msgstr ""
+msgstr "Logarit cơ số 2."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the greater of two values."
-msgstr ""
+msgstr "Trả vỠgiá trị lớn hơn trong hai giá trị."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the lesser of two values."
-msgstr ""
+msgstr "Trả vỠgiá trị nhỠhơn trong hai giá trị."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Linear interpolation between two scalars."
@@ -9196,7 +9164,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the opposite value of the parameter."
-msgstr ""
+msgstr "Trả vỠgiá trị đối của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 - scalar"
@@ -9205,11 +9173,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
"Returns the value of the first parameter raised to the power of the second."
-msgstr ""
+msgstr "Trả vỠlũy thừa cơ số tham số đầu tiên có số mũ tham số thứ hai."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Converts a quantity in degrees to radians."
-msgstr ""
+msgstr "Äổi từ độ vá» radian."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "1.0 / scalar"
@@ -9217,23 +9185,23 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest integer to the parameter."
-msgstr ""
+msgstr "Tìm số nguyên gần tham số nhất."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Finds the nearest even integer to the parameter."
-msgstr ""
+msgstr "Tìm số nguyên chẵn gần tham số nhất."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Clamps the value between 0.0 and 1.0."
-msgstr ""
+msgstr "Kẹp giá trị trong khoảng từ 0.0 đến 1.0."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Extracts the sign of the parameter."
-msgstr ""
+msgstr "Lấy tính âm/dương của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the sine of the parameter."
-msgstr ""
+msgstr "Trả vỠsin của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic sine of the parameter."
@@ -9241,7 +9209,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the square root of the parameter."
-msgstr ""
+msgstr "Trả vỠcăn bậc hai của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9261,7 +9229,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the tangent of the parameter."
-msgstr ""
+msgstr "Trả vỠtan của tham số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the hyperbolic tangent of the parameter."
@@ -9273,15 +9241,15 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Adds scalar to scalar."
-msgstr ""
+msgstr "Cộng hai số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Divides scalar by scalar."
-msgstr ""
+msgstr "Chia hai số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Multiplies scalar by scalar."
-msgstr ""
+msgstr "Nhân hai số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Returns the remainder of the two scalars."
@@ -9289,11 +9257,11 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Subtracts scalar from scalar."
-msgstr ""
+msgstr "Trừ hai số."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Scalar constant."
-msgstr ""
+msgstr "Hằng số vô hướng."
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
@@ -9323,7 +9291,7 @@ msgstr ""
#: editor/plugins/visual_shader_editor_plugin.cpp
#, fuzzy
msgid "Transform function."
-msgstr "Tạo"
+msgstr "Hàm biến hóa."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid ""
@@ -9375,9 +9343,8 @@ msgid "Transform uniform."
msgstr "Tạo"
#: editor/plugins/visual_shader_editor_plugin.cpp
-#, fuzzy
msgid "Vector function."
-msgstr "Xoá Function"
+msgstr "Hàm Vector."
#: editor/plugins/visual_shader_editor_plugin.cpp
msgid "Vector operator."
@@ -9744,9 +9711,8 @@ msgid "Export All"
msgstr "Xuất Tile Set"
#: editor/project_export.cpp editor/project_manager.cpp
-#, fuzzy
msgid "ZIP File"
-msgstr " Tệp tin"
+msgstr "Tệp ZIP"
#: editor/project_export.cpp
msgid "Godot Game Pack"
@@ -10051,11 +10017,8 @@ msgid "Projects"
msgstr "Dự án"
#: editor/project_manager.cpp
-#, fuzzy
msgid "Loading, please wait..."
-msgstr ""
-"Äang quét các tệp tin,\n"
-"ChỠmột chút ..."
+msgstr "Äang tải, đợi xíu..."
#: editor/project_manager.cpp
msgid "Last Modified"
@@ -10131,9 +10094,8 @@ msgid ""
msgstr ""
#: editor/project_settings_editor.cpp
-#, fuzzy
msgid "An action with the name '%s' already exists."
-msgstr "LỖI: Tên animation trùng lặp!"
+msgstr "Hành động với tên '%s' đã tồn tại."
#: editor/project_settings_editor.cpp
msgid "Rename Input Action Event"
@@ -10451,15 +10413,15 @@ msgstr ""
#: editor/property_editor.cpp
msgid "File..."
-msgstr ""
+msgstr "Tệp tin..."
#: editor/property_editor.cpp
msgid "Dir..."
-msgstr ""
+msgstr "Thư mục..."
#: editor/property_editor.cpp
msgid "Assign"
-msgstr ""
+msgstr "Gán"
#: editor/property_editor.cpp
msgid "Select Node"
@@ -10467,7 +10429,7 @@ msgstr "Chá»n nút"
#: editor/property_editor.cpp
msgid "Error loading file: Not a resource!"
-msgstr ""
+msgstr "Lỗi tải tệp: Không phải tài nguyên!"
#: editor/property_editor.cpp
msgid "Pick a Node"
@@ -10475,11 +10437,11 @@ msgstr "Lấy một nút"
#: editor/property_editor.cpp
msgid "Bit %d, val %d."
-msgstr ""
+msgstr "Bit %d, giá trị %d."
#: editor/property_selector.cpp
msgid "Select Property"
-msgstr ""
+msgstr "Chá»n Thuá»™c tính"
#: editor/property_selector.cpp
msgid "Select Virtual Method"
@@ -10487,7 +10449,7 @@ msgstr ""
#: editor/property_selector.cpp
msgid "Select Method"
-msgstr ""
+msgstr "Chá»n Phương thức"
#: editor/rename_dialog.cpp editor/scene_tree_dock.cpp
#, fuzzy
@@ -10495,30 +10457,28 @@ msgid "Batch Rename"
msgstr "Äổi tên"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Replace:"
-msgstr "Thay thế: "
+msgstr "Thay thế:"
#: editor/rename_dialog.cpp
msgid "Prefix:"
-msgstr ""
+msgstr "Tiá»n tố:"
#: editor/rename_dialog.cpp
msgid "Suffix:"
-msgstr ""
+msgstr "Hậu tố:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Use Regular Expressions"
-msgstr "Phiên bản hiện tại:"
+msgstr "Dùng Regular Expression"
#: editor/rename_dialog.cpp
msgid "Advanced Options"
-msgstr ""
+msgstr "Tùy chá»n Nâng cao"
#: editor/rename_dialog.cpp
msgid "Substitute"
-msgstr ""
+msgstr "Thay thế"
#: editor/rename_dialog.cpp
msgid "Node name"
@@ -10534,7 +10494,7 @@ msgstr "Loại nút"
#: editor/rename_dialog.cpp
msgid "Current scene name"
-msgstr ""
+msgstr "Tên Cảnh hiện tại"
#: editor/rename_dialog.cpp
msgid "Root node name"
@@ -10551,18 +10511,16 @@ msgid "Per-level Counter"
msgstr ""
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "If set, the counter restarts for each group of child nodes."
-msgstr "Nếu đặt bộ đếm khởi động lại cho từng nhóm nút con"
+msgstr "Nếu được đặt, bộ đếm sẽ khởi động lại với từng nhóm nút con."
#: editor/rename_dialog.cpp
msgid "Initial value for the counter"
-msgstr ""
+msgstr "Giá trị đếm ban đầu"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "Step"
-msgstr "Bước (s):"
+msgstr "Bước"
#: editor/rename_dialog.cpp
msgid "Amount by which counter is incremented for each node"
@@ -10570,21 +10528,23 @@ msgstr "Giá trị mà bộ đếm tăng lên cho mỗi nút"
#: editor/rename_dialog.cpp
msgid "Padding"
-msgstr ""
+msgstr "Äệm"
#: editor/rename_dialog.cpp
msgid ""
"Minimum number of digits for the counter.\n"
"Missing digits are padded with leading zeros."
msgstr ""
+"Số chữ số tối thiểu cho bộ đếm.\n"
+"Äệm thêm 0 ở đầu nếu thiếu chữ số."
#: editor/rename_dialog.cpp
msgid "Post-Process"
-msgstr ""
+msgstr "Hậu xử lý"
#: editor/rename_dialog.cpp
msgid "Keep"
-msgstr ""
+msgstr "Giữ"
#: editor/rename_dialog.cpp
msgid "PascalCase to snake_case"
@@ -10600,11 +10560,11 @@ msgstr ""
#: editor/rename_dialog.cpp
msgid "To Lowercase"
-msgstr ""
+msgstr "Hoa thành Thưá»ng"
#: editor/rename_dialog.cpp
msgid "To Uppercase"
-msgstr ""
+msgstr "Thưá»ng thành Hoa"
#: editor/rename_dialog.cpp
#, fuzzy
@@ -10617,9 +10577,8 @@ msgid "Regular Expression Error:"
msgstr "Phiên bản hiện tại:"
#: editor/rename_dialog.cpp
-#, fuzzy
msgid "At character %s"
-msgstr "Ký tự hợp lệ:"
+msgstr "Tại kí tự %s"
#: editor/reparent_dialog.cpp editor/scene_tree_dock.cpp
msgid "Reparent Node"
@@ -10643,19 +10602,19 @@ msgstr ""
#: editor/run_settings_dialog.cpp
msgid "Current Scene"
-msgstr ""
+msgstr "Cảnh Hiện tại"
#: editor/run_settings_dialog.cpp
msgid "Main Scene"
-msgstr ""
+msgstr "Cảnh chính"
#: editor/run_settings_dialog.cpp
msgid "Main Scene Arguments:"
-msgstr ""
+msgstr "Tham số Cảnh chính:"
#: editor/run_settings_dialog.cpp
msgid "Scene Run Settings"
-msgstr ""
+msgstr "Cài đặt chạy Cảnh"
#: editor/scene_tree_dock.cpp
msgid "No parent to instance the scenes at."
@@ -10663,7 +10622,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Error loading scene from %s"
-msgstr ""
+msgstr "Lỗi tải cảnh từ %s"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10675,7 +10634,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Instance Scene(s)"
-msgstr ""
+msgstr "Khởi tạo Cảnh"
#: editor/scene_tree_dock.cpp
msgid "Replace with Branch Scene"
@@ -10683,12 +10642,11 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Instance Child Scene"
-msgstr ""
+msgstr "Khởi tạo Cảnh con"
#: editor/scene_tree_dock.cpp
-#, fuzzy
msgid "Can't paste root node into the same scene."
-msgstr "Không thể hoạt động trên các nút từ ngoại cảnh!"
+msgstr "Không thể dán Nút Gốc vào cùng một Cảnh."
#: editor/scene_tree_dock.cpp
#, fuzzy
@@ -10702,7 +10660,7 @@ msgstr "Äính kèm Script"
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on the tree root."
-msgstr ""
+msgstr "Thao tác này không thể áp dụng lên gốc của cây."
#: editor/scene_tree_dock.cpp
msgid "Move Node In Parent"
@@ -10728,7 +10686,7 @@ msgstr "Nút phải thuộc cảnh đã chỉnh sửa để trở thành gốc."
#: editor/scene_tree_dock.cpp
msgid "Instantiated scenes can't become root"
-msgstr ""
+msgstr "Cảnh khởi tạo không thể thành gốc"
#: editor/scene_tree_dock.cpp
msgid "Make node as Root"
@@ -10761,11 +10719,11 @@ msgstr "Không thể thực hiện với nút gốc."
#: editor/scene_tree_dock.cpp
msgid "This operation can't be done on instanced scenes."
-msgstr ""
+msgstr "Không thể thực hiện thao tác này trên Cảnh được khởi tạo."
#: editor/scene_tree_dock.cpp
msgid "Save New Scene As..."
-msgstr ""
+msgstr "Lưu Cảnh Mới Thành..."
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10797,11 +10755,11 @@ msgstr "Tạo Nút Gốc:"
#: editor/scene_tree_dock.cpp
msgid "2D Scene"
-msgstr "2D Scene"
+msgstr "Cảnh 2D"
#: editor/scene_tree_dock.cpp
msgid "3D Scene"
-msgstr "3D Scene"
+msgstr "Cảnh 3D"
#: editor/scene_tree_dock.cpp
msgid "User Interface"
@@ -10841,6 +10799,7 @@ msgid ""
"Couldn't save new scene. Likely dependencies (instances) couldn't be "
"satisfied."
msgstr ""
+"Không thể lưu cảnh má»›i. Có vẻ là do không thá»a mãn được các phần phụ thuá»™c."
#: editor/scene_tree_dock.cpp
msgid "Error saving scene."
@@ -10848,19 +10807,19 @@ msgstr "Lỗi khi lưu scene."
#: editor/scene_tree_dock.cpp
msgid "Error duplicating scene to save it."
-msgstr ""
+msgstr "Lỗi khi nhân bản cảnh để lưu."
#: editor/scene_tree_dock.cpp
msgid "Sub-Resources"
-msgstr ""
+msgstr "Tài nguyên phụ"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance"
-msgstr ""
+msgstr "Xóa Kế thừa"
#: editor/scene_tree_dock.cpp
msgid "Editable Children"
-msgstr ""
+msgstr "Các nút Con có thể sửa"
#: editor/scene_tree_dock.cpp
msgid "Load As Placeholder"
@@ -10868,7 +10827,7 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Open Documentation"
-msgstr ""
+msgstr "Mở Hướng dẫn"
#: editor/scene_tree_dock.cpp
msgid ""
@@ -10888,7 +10847,7 @@ msgstr "Thu gá»n Tất cả"
#: editor/scene_tree_dock.cpp
msgid "Change Type"
-msgstr ""
+msgstr "Äổi Kiểu"
#: editor/scene_tree_dock.cpp
msgid "Reparent to New Node"
@@ -10896,15 +10855,15 @@ msgstr "Reparent đến nút mới"
#: editor/scene_tree_dock.cpp
msgid "Make Scene Root"
-msgstr ""
+msgstr "Biến Cảnh thành Gốc"
#: editor/scene_tree_dock.cpp
msgid "Merge From Scene"
-msgstr ""
+msgstr "Hợp nhất từ Cảnh"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Save Branch as Scene"
-msgstr ""
+msgstr "Lưu Nhánh thành Cảnh"
#: editor/scene_tree_dock.cpp editor/script_editor_debugger.cpp
msgid "Copy Node Path"
@@ -10912,7 +10871,7 @@ msgstr "Sao chép đưá»ng dẫn nút"
#: editor/scene_tree_dock.cpp
msgid "Delete (No Confirm)"
-msgstr ""
+msgstr "Xóa (Không há»i lại)"
#: editor/scene_tree_dock.cpp
msgid "Add/Create a New Node."
@@ -10941,11 +10900,11 @@ msgstr ""
#: editor/scene_tree_dock.cpp
msgid "Local"
-msgstr ""
+msgstr "Cục bộ"
#: editor/scene_tree_dock.cpp
msgid "Clear Inheritance? (No Undo!)"
-msgstr ""
+msgstr "Xóa Kế thừa? (Mất tăm luôn đấy!)"
#: editor/scene_tree_editor.cpp
msgid "Toggle Visible"
@@ -10994,9 +10953,8 @@ msgstr ""
"Nhấp để hiện khung nhóm."
#: editor/scene_tree_editor.cpp
-#, fuzzy
msgid "Open Script:"
-msgstr "Tạo Script"
+msgstr "Mở Tệp lệnh:"
#: editor/scene_tree_editor.cpp
msgid ""
@@ -11011,6 +10969,8 @@ msgid ""
"Children are not selectable.\n"
"Click to make selectable."
msgstr ""
+"Không thể chá»n Con cá»§a nút này.\n"
+"Bấm vào đây để có thể chá»n chúng."
#: editor/scene_tree_editor.cpp
msgid "Toggle Visibility"
@@ -11021,6 +10981,8 @@ msgid ""
"AnimationPlayer is pinned.\n"
"Click to unpin."
msgstr ""
+"AnimationPlayer đã được ghim.\n"
+"Bấm để bỠghim."
#: editor/scene_tree_editor.cpp
msgid "Invalid node name, the following characters are not allowed:"
@@ -11044,11 +11006,11 @@ msgstr "Chá»n má»™t Nút"
#: editor/script_create_dialog.cpp
msgid "Path is empty."
-msgstr ""
+msgstr "ÄÆ°á»ng dẫn trống."
#: editor/script_create_dialog.cpp
msgid "Filename is empty."
-msgstr ""
+msgstr "Tên tệp trống."
#: editor/script_create_dialog.cpp
msgid "Path is not local."
@@ -11069,17 +11031,16 @@ msgid "File does not exist."
msgstr "Tệp không tồn tại."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid extension."
-msgstr "Phải sử dụng extension có hiệu lực"
+msgstr "Tên đuôi không hợp lệ."
#: editor/script_create_dialog.cpp
msgid "Wrong extension chosen."
-msgstr ""
+msgstr "Sai đuôi mở rộng."
#: editor/script_create_dialog.cpp
msgid "Error loading template '%s'"
-msgstr ""
+msgstr "Lỗi nạp mẫu '%s'"
#: editor/script_create_dialog.cpp
msgid "Error - Could not create script in filesystem."
@@ -11087,7 +11048,7 @@ msgstr ""
#: editor/script_create_dialog.cpp
msgid "Error loading script from %s"
-msgstr ""
+msgstr "Lỗi nạp tệp lệnh từ %s"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11095,12 +11056,13 @@ msgid "Overrides"
msgstr "Ghi đè"
#: editor/script_create_dialog.cpp
+#, fuzzy
msgid "N/A"
-msgstr ""
+msgstr "Không có"
#: editor/script_create_dialog.cpp
msgid "Open Script / Choose Location"
-msgstr ""
+msgstr "Mở tệp lệnh / Chá»n vị trí"
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11108,8 +11070,9 @@ msgid "Open Script"
msgstr "Tạo Script"
#: editor/script_create_dialog.cpp
+#, fuzzy
msgid "File exists, it will be reused."
-msgstr ""
+msgstr "Tệp tồn tại, và sẽ được dùng lại."
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11117,9 +11080,8 @@ msgid "Invalid path."
msgstr "ÄÆ°á»ng dẫn sai."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Invalid class name."
-msgstr "Kích thước font không hợp lệ."
+msgstr "Tên Lớp không hợp lệ."
#: editor/script_create_dialog.cpp
msgid "Invalid inherited parent name or path."
@@ -11132,11 +11094,11 @@ msgstr "Animation tree khả dụng."
#: editor/script_create_dialog.cpp
msgid "Allowed: a-z, A-Z, 0-9, _ and ."
-msgstr ""
+msgstr "ÄÆ°á»£c dùng: a-z, A-Z, 0-9, _ và ."
#: editor/script_create_dialog.cpp
msgid "Built-in script (into scene file)."
-msgstr ""
+msgstr "Tệp lệnh tích hợp (vào tệp cảnh)."
#: editor/script_create_dialog.cpp
msgid "Will create a new script file."
@@ -11144,7 +11106,7 @@ msgstr "Sẽ tạo một tệp lệnh mới."
#: editor/script_create_dialog.cpp
msgid "Will load an existing script file."
-msgstr ""
+msgstr "Sẽ nạp một tệp lệnh đã tồn tại."
#: editor/script_create_dialog.cpp
#, fuzzy
@@ -11156,20 +11118,20 @@ msgid ""
"Note: Built-in scripts have some limitations and can't be edited using an "
"external editor."
msgstr ""
+"Lưu ý: Tệp lệnh tích hợp có một số hạn chế và không thể chỉnh sửa bằng trình "
+"biên soạn bên ngoài."
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Class Name:"
-msgstr "Lá»›p:"
+msgstr "Tên Lớp:"
#: editor/script_create_dialog.cpp
msgid "Template:"
msgstr "Bản mẫu:"
#: editor/script_create_dialog.cpp
-#, fuzzy
msgid "Built-in Script:"
-msgstr "Tạo Script"
+msgstr "Tệp lệnh có sẵn:"
#: editor/script_create_dialog.cpp
msgid "Attach Node Script"
@@ -11181,27 +11143,23 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Bytes:"
-msgstr ""
+msgstr "Bytes:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Warning:"
-msgstr "Cảnh báo"
+msgstr "Cảnh báo:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Error:"
-msgstr "Lá»—i!"
+msgstr "Lá»—i:"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error"
-msgstr "Lá»—i!"
+msgstr "Lá»—i C++"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "C++ Error:"
-msgstr "Lá»—i!"
+msgstr "Lá»—i C++:"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11209,13 +11167,13 @@ msgid "C++ Source"
msgstr "Sao chép Tài nguyên"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Source:"
-msgstr "Quét nguồn"
+msgstr "Nguồn:"
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "C++ Source:"
-msgstr ""
+msgstr "Tệp nguồn C++:"
#: editor/script_editor_debugger.cpp
msgid "Stack Trace"
@@ -11223,25 +11181,23 @@ msgstr ""
#: editor/script_editor_debugger.cpp
msgid "Errors"
-msgstr ""
+msgstr "Lá»—i"
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Child process connected."
-msgstr "Các Nút đã ngắt Kết nối"
+msgstr "Äã kết nối tiến trình con."
#: editor/script_editor_debugger.cpp
msgid "Copy Error"
-msgstr ""
+msgstr "Sao chép lỗi"
#: editor/script_editor_debugger.cpp
msgid "Video RAM"
msgstr ""
#: editor/script_editor_debugger.cpp
-#, fuzzy
msgid "Skip Breakpoints"
-msgstr "Tạo các điểm."
+msgstr "LỠđi điểm dừng"
#: editor/script_editor_debugger.cpp
msgid "Inspect Previous Instance"
@@ -11265,28 +11221,31 @@ msgid "Network Profiler"
msgstr "Xuất hồ sơ"
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Monitor"
-msgstr ""
+msgstr "Màn hình"
#: editor/script_editor_debugger.cpp
msgid "Value"
-msgstr ""
+msgstr "Giá trị"
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Monitors"
-msgstr ""
+msgstr "Màn hình"
#: editor/script_editor_debugger.cpp
msgid "Pick one or more items from the list to display the graph."
-msgstr ""
+msgstr "Chá»n má»™t hoặc nhiá»u mục từ danh sách để hiển thị biểu đồ."
#: editor/script_editor_debugger.cpp
msgid "List of Video Memory Usage by Resource:"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Total:"
-msgstr ""
+msgstr "Tổng:"
#: editor/script_editor_debugger.cpp
#, fuzzy
@@ -11295,23 +11254,24 @@ msgstr "Xuất hồ sơ"
#: editor/script_editor_debugger.cpp
msgid "Resource Path"
-msgstr ""
+msgstr "ÄÆ°á»ng dẫn Tài nguyên"
#: editor/script_editor_debugger.cpp
msgid "Type"
-msgstr ""
+msgstr "Kiểu"
#: editor/script_editor_debugger.cpp
msgid "Format"
-msgstr ""
+msgstr "Äịnh dạng"
#: editor/script_editor_debugger.cpp
msgid "Usage"
msgstr ""
#: editor/script_editor_debugger.cpp
+#, fuzzy
msgid "Misc"
-msgstr ""
+msgstr "Khác"
#: editor/script_editor_debugger.cpp
msgid "Clicked Control:"
@@ -11335,15 +11295,15 @@ msgstr ""
#: editor/settings_config_dialog.cpp
msgid "Erase Shortcut"
-msgstr ""
+msgstr "Xóa lối tắt"
#: editor/settings_config_dialog.cpp
msgid "Restore Shortcut"
-msgstr ""
+msgstr "Khôi phục lối tắt"
#: editor/settings_config_dialog.cpp
msgid "Change Shortcut"
-msgstr ""
+msgstr "Thay đổi Lối tắt"
#: editor/settings_config_dialog.cpp
msgid "Editor Settings"
@@ -11351,7 +11311,7 @@ msgstr "Cài đặt Trình biên tập"
#: editor/settings_config_dialog.cpp
msgid "Shortcuts"
-msgstr ""
+msgstr "Lối tắt"
#: editor/settings_config_dialog.cpp
msgid "Binding"
@@ -11359,7 +11319,7 @@ msgstr ""
#: editor/spatial_editor_gizmos.cpp
msgid "Change Light Radius"
-msgstr ""
+msgstr "Thay đổi bán kính ánh sáng"
#: editor/spatial_editor_gizmos.cpp
msgid "Change AudioStreamPlayer3D Emission Angle"
@@ -11386,8 +11346,9 @@ msgid "Change Probe Extents"
msgstr ""
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
+#, fuzzy
msgid "Change Sphere Shape Radius"
-msgstr ""
+msgstr "Thay đổi bán kính hình cầu"
#: editor/spatial_editor_gizmos.cpp modules/csg/csg_gizmos.cpp
msgid "Change Box Shape Extents"
@@ -11517,7 +11478,7 @@ msgstr ""
#: modules/gdscript/gdscript_functions.cpp
msgid "Invalid instance dictionary (invalid subclasses)"
-msgstr ""
+msgstr "Từ điển không hợp lệ (Lớp con không hợp lệ)"
#: modules/gdscript/gdscript_functions.cpp
msgid "Object can't provide a length."
@@ -11679,9 +11640,8 @@ msgid "Indirect lighting"
msgstr ""
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
-#, fuzzy
msgid "Post processing"
-msgstr "Phiên bản hiện tại:"
+msgstr "Hậu xử lí"
#: modules/lightmapper_cpu/lightmapper_cpu.cpp
msgid "Plotting lightmaps"
@@ -11689,7 +11649,7 @@ msgstr ""
#: modules/mono/csharp_script.cpp
msgid "Class name can't be a reserved keyword"
-msgstr ""
+msgstr "Tên Lớp không được trùng với từ khóa"
#: modules/mono/mono_gd/gd_mono_utils.cpp
msgid "End of inner exception stack trace"
@@ -11701,15 +11661,15 @@ msgstr ""
#: modules/recast/navigation_mesh_editor_plugin.cpp
msgid "Clear the navigation mesh."
-msgstr ""
+msgstr "Xóa lưới Ä‘iá»u hướng."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Setting up Configuration..."
-msgstr ""
+msgstr "Thiết lập cấu hình ..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Calculating grid size..."
-msgstr ""
+msgstr "Tính kích thước lưới ..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating heightfield..."
@@ -11729,11 +11689,11 @@ msgstr ""
#: modules/recast/navigation_mesh_generator.cpp
msgid "Partitioning..."
-msgstr ""
+msgstr "Phân vùng ..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating contours..."
-msgstr ""
+msgstr "Tạo đưá»ng viá»n ..."
#: modules/recast/navigation_mesh_generator.cpp
msgid "Creating polymesh..."
@@ -11745,7 +11705,7 @@ msgstr ""
#: modules/recast/navigation_mesh_generator.cpp
msgid "Navigation Mesh Generator Setup:"
-msgstr ""
+msgstr "Thiết lập trình tạo lưới Ä‘iá»u hướng:"
#: modules/recast/navigation_mesh_generator.cpp
msgid "Parsing Geometry..."
@@ -11753,7 +11713,7 @@ msgstr ""
#: modules/recast/navigation_mesh_generator.cpp
msgid "Done!"
-msgstr ""
+msgstr "Xong!"
#: modules/visual_script/visual_script.cpp
msgid ""
@@ -11780,45 +11740,44 @@ msgstr ""
#: modules/visual_script/visual_script.cpp
msgid "Node returned an invalid sequence output: "
-msgstr "Nút trả vỠđầu ra là chuỗi không hợp lệ: "
+msgstr "Nút trả vỠchuỗi không hợp lệ: "
#: modules/visual_script/visual_script.cpp
msgid "Found sequence bit but not the node in the stack, report bug!"
-msgstr "Tìm ra chuỗi bit nhưng không phải nút trong ngăn xếp, báo cáo lỗi!"
+msgstr ""
+"Tìm thấy chuỗi bit nhưng không phải là nút trong ngăn xếp, báo cáo lỗi!"
#: modules/visual_script/visual_script.cpp
msgid "Stack overflow with stack depth: "
-msgstr ""
+msgstr "Tràn ngăn xếp ở ngăn xếp tầng: "
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Signal Arguments"
-msgstr ""
+msgstr "Thay đổi đối số tín hiệu"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Argument Type"
-msgstr ""
+msgstr "Thay đổi loại đối số"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Argument name"
-msgstr ""
+msgstr "Thay đổi tên đối số"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Default Value"
-msgstr ""
+msgstr "Äặt giá trị mặc định cho biến"
#: modules/visual_script/visual_script_editor.cpp
msgid "Set Variable Type"
-msgstr ""
+msgstr "Äặt loại biến"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Input Port"
-msgstr "Thêm Input"
+msgstr "Thêm cổng vào"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Output Port"
-msgstr "Thêm Input"
+msgstr "Thêm cổng ra"
#: modules/visual_script/visual_script_editor.cpp
msgid "Override an existing built-in function."
@@ -11826,24 +11785,23 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Create a new function."
-msgstr "Tạo một hàm mới."
+msgstr "Tạo hàm mới."
#: modules/visual_script/visual_script_editor.cpp
msgid "Variables:"
-msgstr ""
+msgstr "Biến:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Create a new variable."
-msgstr "Tạo một biến mới."
+msgstr "Tạo biến mới."
#: modules/visual_script/visual_script_editor.cpp
msgid "Signals:"
msgstr "Tín hiệu:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create a new signal."
-msgstr "Tạo"
+msgstr "Tạo tín hiệu mới."
#: modules/visual_script/visual_script_editor.cpp
msgid "Name is not a valid identifier:"
@@ -11851,7 +11809,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Name already in use by another func/var/signal:"
-msgstr ""
+msgstr "Tên đã được sử dụng bởi func/var/singal khác:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Rename Function"
@@ -11870,9 +11828,8 @@ msgid "Add Function"
msgstr "Thêm Hàm"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Delete input port"
-msgstr "Xoá Function"
+msgstr "Xoá cổng vào"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Variable"
@@ -11883,22 +11840,20 @@ msgid "Add Signal"
msgstr "Thêm Tín hiệu"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Input Port"
-msgstr "Xoá Function"
+msgstr "Xóa cổng vào"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Remove Output Port"
-msgstr "Xóa Template"
+msgstr "Xóa cổng ra"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Expression"
-msgstr ""
+msgstr "Thay đổi biểu thức"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove VisualScript Nodes"
-msgstr "Gỡ bỠcác nút VisualScript"
+msgstr "Xóa các nút VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Duplicate VisualScript Nodes"
@@ -11914,11 +11869,11 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a simple reference to the node."
-msgstr "Giữ %s và thả để tham chiếu đơn giản đế nút."
+msgstr "Giữ %s để thả một tham chiếu đơn giản lên nút."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold Ctrl to drop a simple reference to the node."
-msgstr "Giữ Ctrl và thả để tham chiếu đơn giản đến nút."
+msgstr "Giữ Ctrl để thả một tài liệu tham khảo đơn giản đến nút."
#: modules/visual_script/visual_script_editor.cpp
msgid "Hold %s to drop a Variable Setter."
@@ -11930,11 +11885,11 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Preload Node"
-msgstr "Thêm nút Preload"
+msgstr "Thêm nút tải trước"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Node(s) From Tree"
-msgstr "Thêm các nút từ cây"
+msgstr "Thêm nút từ cây"
#: modules/visual_script/visual_script_editor.cpp
msgid ""
@@ -11952,7 +11907,7 @@ msgstr ""
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Base Type"
-msgstr ""
+msgstr "Thay đổi loại cơ sở"
#: modules/visual_script/visual_script_editor.cpp
msgid "Move Node(s)"
@@ -11964,7 +11919,7 @@ msgstr "Gỡ bỠnút VisualScript"
#: modules/visual_script/visual_script_editor.cpp
msgid "Connect Nodes"
-msgstr "Kết nối các nút"
+msgstr "Kết nối nút"
#: modules/visual_script/visual_script_editor.cpp
msgid "Disconnect Nodes"
@@ -11980,15 +11935,15 @@ msgstr "Kết nối trình tự nút"
#: modules/visual_script/visual_script_editor.cpp
msgid "Script already has function '%s'"
-msgstr ""
+msgstr "Tệp lệnh đã có hàm '%s'"
#: modules/visual_script/visual_script_editor.cpp
msgid "Change Input Value"
-msgstr ""
+msgstr "Thay đổi giá trị đầu vào"
#: modules/visual_script/visual_script_editor.cpp
msgid "Resize Comment"
-msgstr ""
+msgstr "Thay đổi kích thước Nhận xét"
#: modules/visual_script/visual_script_editor.cpp
msgid "Can't copy the function node."
@@ -11996,7 +11951,7 @@ msgstr "Không thể sao chép nút chức năng."
#: modules/visual_script/visual_script_editor.cpp
msgid "Clipboard is empty!"
-msgstr ""
+msgstr "Clipboard trống!"
#: modules/visual_script/visual_script_editor.cpp
msgid "Paste VisualScript Nodes"
@@ -12019,17 +11974,16 @@ msgid "Try to only have one sequence input in selection."
msgstr ""
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Create Function"
-msgstr "Äổi tên Hàm"
+msgstr "Tạo Hàm"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Function"
-msgstr "Xoá Function"
+msgstr "Xoá Hàm"
#: modules/visual_script/visual_script_editor.cpp
msgid "Remove Variable"
-msgstr "Xoá Variable"
+msgstr "Xoá Biến"
#: modules/visual_script/visual_script_editor.cpp
msgid "Editing Variable:"
@@ -12052,27 +12006,24 @@ msgid "Members:"
msgstr "Những Thành viên:"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Change Base Type:"
-msgstr "Äổi %s Loại"
+msgstr "Äổi Kiểu Gốc:"
#: modules/visual_script/visual_script_editor.cpp
msgid "Add Nodes..."
msgstr "Thêm các nút..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Add Function..."
-msgstr "Thêm Hàm"
+msgstr "Thêm Hàm..."
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "function_name"
-msgstr "Hàm:"
+msgstr "ten_ham"
#: modules/visual_script/visual_script_editor.cpp
msgid "Select or create a function to edit its graph."
-msgstr ""
+msgstr "Chá»n hoặc tạo má»™t hàm để chỉnh đồ thị."
#: modules/visual_script/visual_script_editor.cpp
msgid "Delete Selected"
@@ -12084,21 +12035,19 @@ msgstr "Tìm loại Node"
#: modules/visual_script/visual_script_editor.cpp
msgid "Copy Nodes"
-msgstr "Sao chép các nút"
+msgstr "Sao chép nút"
#: modules/visual_script/visual_script_editor.cpp
msgid "Cut Nodes"
msgstr "Cắt các nút"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Make Function"
-msgstr "Äổi tên Hàm"
+msgstr "Tạo Hàm"
#: modules/visual_script/visual_script_editor.cpp
-#, fuzzy
msgid "Refresh Graph"
-msgstr "Làm mới"
+msgstr "Làm mới đồ thị"
#: modules/visual_script/visual_script_editor.cpp
msgid "Edit Member"
@@ -12106,19 +12055,19 @@ msgstr ""
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Input type not iterable: "
-msgstr ""
+msgstr "Kiểu đầu vào không lặp được: "
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid"
-msgstr ""
+msgstr "TrỠlặp không còn hợp lệ"
#: modules/visual_script/visual_script_flow_control.cpp
msgid "Iterator became invalid: "
-msgstr ""
+msgstr "TrỠlặp không còn hợp lệ: "
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name."
-msgstr ""
+msgstr "Tên thuộc tính chỉ mục không hợp lệ."
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Base object is not a Node!"
@@ -12126,37 +12075,41 @@ msgstr "Äối tượng cÆ¡ sở không phải má»™t nút!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Path does not lead Node!"
-msgstr "Path không chỉ đến Node!"
+msgstr "ÄÆ°á»ng dẫn không chỉ đến Nút!"
#: modules/visual_script/visual_script_func_nodes.cpp
msgid "Invalid index property name '%s' in node %s."
-msgstr ""
+msgstr "Tên thuộc tính chỉ mục '%s' ở nút '%s' không hợp lệ."
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid argument of type: "
-msgstr ""
+msgstr ": Tham số có loại không hợp lệ: "
#: modules/visual_script/visual_script_nodes.cpp
msgid ": Invalid arguments: "
-msgstr ""
+msgstr ": Tham số không hợp lệ: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "VariableGet not found in script: "
-msgstr ""
+msgstr "Không tìm thấy VariableGet trong tệp lệnh: "
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
msgid "VariableSet not found in script: "
-msgstr ""
+msgstr "Không tìm thấy VariableSet trong tệp lệnh: "
#: modules/visual_script/visual_script_nodes.cpp
msgid "Custom node has no _step() method, can't process graph."
-msgstr ""
+msgstr "Nút tùy chá»n không có phương thức _step(), không thể xá»­ lí đồ thị."
#: modules/visual_script/visual_script_nodes.cpp
+#, fuzzy
msgid ""
"Invalid return value from _step(), must be integer (seq out), or string "
"(error)."
msgstr ""
+"_step() trả giá trị không hợp lệ, phải là số nguyên (seq out), hoặc xâu "
+"(lá»—i)."
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Search VisualScript"
@@ -12164,15 +12117,15 @@ msgstr "Tìm VisualScript"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Get %s"
-msgstr ""
+msgstr "Lấy %s"
#: modules/visual_script/visual_script_property_selector.cpp
msgid "Set %s"
-msgstr ""
+msgstr "Gán %s"
#: platform/android/export/export.cpp
msgid "Package name is missing."
-msgstr ""
+msgstr "Thiếu tên gói."
#: platform/android/export/export.cpp
msgid "Package segments must be of non-zero length."
@@ -12180,11 +12133,11 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "The character '%s' is not allowed in Android application package names."
-msgstr ""
+msgstr "Không được phép cho kí tá»± '%s' vào tên gói phần má»m Android."
#: platform/android/export/export.cpp
msgid "A digit cannot be the first character in a package segment."
-msgstr ""
+msgstr "Không thể có chữ số làm kí tự đầu tiên trong một phần của gói."
#: platform/android/export/export.cpp
msgid "The character '%s' cannot be the first character in a package segment."
@@ -12192,15 +12145,15 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "The package must have at least one '.' separator."
-msgstr ""
+msgstr "Kí tự phân cách '.' phải xuất hiện ít nhất một lần trong tên gói."
#: platform/android/export/export.cpp
msgid "Select device from the list"
-msgstr ""
+msgstr "Chá»n thiết bị trong danh sách"
#: platform/android/export/export.cpp
msgid "Unable to find the 'apksigner' tool."
-msgstr ""
+msgstr "Không tìm thấy công cụ 'apksigner'."
#: platform/android/export/export.cpp
msgid ""
@@ -12228,11 +12181,11 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Missing 'platform-tools' directory!"
-msgstr ""
+msgstr "Thiếu thư mục 'platform-tools'!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK platform-tools' adb command."
-msgstr ""
+msgstr "Không tìm thấy lệnh adb trong bộ Android SDK platform-tools."
#: platform/android/export/export.cpp
msgid "Please check in the Android SDK directory specified in Editor Settings."
@@ -12240,26 +12193,27 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Missing 'build-tools' directory!"
-msgstr ""
+msgstr "Thiếu thư mục 'build-tools'!"
#: platform/android/export/export.cpp
msgid "Unable to find Android SDK build-tools' apksigner command."
-msgstr ""
+msgstr "Không tìm thấy lệnh apksigner của bộ Android SDK build-tools."
#: platform/android/export/export.cpp
msgid "Invalid public key for APK expansion."
-msgstr ""
+msgstr "Khóa công khai của bộ APK mở rộng không hợp lệ."
#: platform/android/export/export.cpp
-#, fuzzy
msgid "Invalid package name:"
-msgstr "Kích thước font không hợp lệ."
+msgstr "Tên gói không hợp lệ:"
#: platform/android/export/export.cpp
msgid ""
"Invalid \"GodotPaymentV3\" module included in the \"android/modules\" "
"project setting (changed in Godot 3.2.2).\n"
msgstr ""
+"Cài đặt dự án chứa module không hợp lệ \"GodotPaymentV3\" ở mục \"android/"
+"modules\" (đã thay đổi từ Godot 3.2.2).\n"
#: platform/android/export/export.cpp
msgid "\"Use Custom Build\" must be enabled to use the plugins."
@@ -12269,12 +12223,14 @@ msgstr ""
msgid ""
"\"Degrees Of Freedom\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR"
"\"."
-msgstr ""
+msgstr "\"Bậc tự do\" chỉ dùng được khi \"Xr Mode\" là \"Oculus Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
"\"Hand Tracking\" is only valid when \"Xr Mode\" is \"Oculus Mobile VR\"."
msgstr ""
+"\"Theo dõi chuyển động tay\" chỉ dùng được khi \"Xr Mode\" là \"Oculus "
+"Mobile VR\"."
#: platform/android/export/export.cpp
msgid ""
@@ -12284,10 +12240,11 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."
msgstr ""
+"\"Xuất AAB\" chỉ dùng được khi \"Sử dụng Bản dựng tùy chỉnh\" được bật."
#: platform/android/export/export.cpp
msgid "Invalid filename! Android App Bundle requires the *.aab extension."
-msgstr ""
+msgstr "Tên tệp không hợp lệ! Android App Bundle cần đuôi *.aab ở cuối."
#: platform/android/export/export.cpp
msgid "APK Expansion not compatible with Android App Bundle."
@@ -12295,7 +12252,7 @@ msgstr ""
#: platform/android/export/export.cpp
msgid "Invalid filename! Android APK requires the *.apk extension."
-msgstr ""
+msgstr "Tên tệp không hợp lệ! Android APK cần đuôi *.apk ở cuối."
#: platform/android/export/export.cpp
msgid ""
@@ -12326,8 +12283,8 @@ msgid ""
"Building of Android project failed, check output for the error.\n"
"Alternatively visit docs.godotengine.org for Android build documentation."
msgstr ""
-"Xây dựng dự án Android không thành công, kiểm tra lỗi đầu ra.\n"
-"Hoặc truy cập 'docs.godotengine.org' xem tài liệu xây dựng Android."
+"Xây dựng dự án Android thất bại, hãy kiểm tra đầu ra để biết lỗi.\n"
+"Hoặc truy cập 'docs.godotengine.org' để xem cách xây dựng Android."
#: platform/android/export/export.cpp
msgid "Moving output"
@@ -12362,7 +12319,7 @@ msgstr ""
#: platform/javascript/export/export.cpp
msgid "Stop HTTP Server"
-msgstr ""
+msgstr "Dừng Máy chủ HTTP"
#: platform/javascript/export/export.cpp
msgid "Run in Browser"
@@ -12378,11 +12335,11 @@ msgstr "Không viết được file:"
#: platform/javascript/export/export.cpp
msgid "Could not open template for export:"
-msgstr ""
+msgstr "Không thể mở bản mẫu để xuất:"
#: platform/javascript/export/export.cpp
msgid "Invalid export template:"
-msgstr ""
+msgstr "Bản xuất mẫu không hợp lệ:"
#: platform/javascript/export/export.cpp
msgid "Could not read custom HTML shell:"
@@ -12422,49 +12379,52 @@ msgid "Invalid publisher GUID."
msgstr "Kích thước font không hợp lệ."
#: platform/uwp/export/export.cpp
-#, fuzzy
msgid "Invalid background color."
-msgstr "Kích thước font không hợp lệ."
+msgstr "Màu ná»n không hợp lệ."
#: platform/uwp/export/export.cpp
msgid "Invalid Store Logo image dimensions (should be 50x50)."
-msgstr ""
+msgstr "Kích thước ảnh Logo Store không hợp lệ (phải là 50x50)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 44x44 logo image dimensions (should be 44x44)."
-msgstr ""
+msgstr "Kích thước ảnh logo vuông 44x44 không hợp lệ (phải là 44x44)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 71x71 logo image dimensions (should be 71x71)."
-msgstr ""
+msgstr "Kích thước ảnh logo vuông 71x71 không hợp lệ (phải là 71x71)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 150x150 logo image dimensions (should be 150x150)."
-msgstr ""
+msgstr "Kích thước ảnh logo vuông 150x150 không hợp lệ (phải là 150x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid square 310x310 logo image dimensions (should be 310x310)."
-msgstr ""
+msgstr "Kích thước ảnh logo vuông 310x310 không hợp lệ (phải là 310x310)."
#: platform/uwp/export/export.cpp
msgid "Invalid wide 310x150 logo image dimensions (should be 310x150)."
-msgstr ""
+msgstr "Kích thước ảnh logo 310x150 không hợp lệ (phải là 310x150)."
#: platform/uwp/export/export.cpp
msgid "Invalid splash screen image dimensions (should be 620x300)."
-msgstr ""
+msgstr "Ảnh mở màn có kích thước không hợp lệ (phải là 620x300)."
#: scene/2d/animated_sprite.cpp
msgid ""
"A SpriteFrames resource must be created or set in the \"Frames\" property in "
"order for AnimatedSprite to display frames."
msgstr ""
+"Tài nguyên SpriteFrames phải được tạo hoặc đặt trong thuộc tính \"Khung hình"
+"\" thì AnimatedSprite mới hiển thị các khung hình được."
#: scene/2d/canvas_modulate.cpp
msgid ""
"Only one visible CanvasModulate is allowed per scene (or set of instanced "
"scenes). The first created one will work, while the rest will be ignored."
msgstr ""
+"Chỉ cho phép một CanvasModulate (không ẩn) ứng với một Cảnh (hoặc một tập "
+"Cảnh đã được tạo). Cái đầu tiên sẽ chạy, những cái sau sẽ bị lỠđi."
#: scene/2d/collision_object_2d.cpp
msgid ""
@@ -12472,6 +12432,10 @@ msgid ""
"Consider adding a CollisionShape2D or CollisionPolygon2D as a child to "
"define its shape."
msgstr ""
+"Nút này không có hình thù, nên không thể va chạm hoặc tương tác với các vật "
+"khác.\n"
+"Hãy thêm nút con CollisionShape2D hoặc CollisionPolygon2D để định dạng cho "
+"nút này."
#: scene/2d/collision_polygon_2d.cpp
msgid ""
@@ -12479,18 +12443,21 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
+"CollisionPolygon2D nhằm mục đích tạo khối va chạm cho những nút kế thừa từ "
+"CollisionObject2D. Vậy nên hãy cho nút ấy làm con của Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, ... để tạo khối va chạm."
#: scene/2d/collision_polygon_2d.cpp
msgid "An empty CollisionPolygon2D has no effect on collision."
-msgstr ""
+msgstr "ColiisionPolygon2D rỗng sẽ không phản ứng gì khi có va chạm."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 3 points are needed in 'Solids' build mode."
-msgstr ""
+msgstr "Äa giác không hợp lệ. Cần ít nhất 3 Ä‘iểm trong chế độ dá»±ng \"Solids\"."
#: scene/2d/collision_polygon_2d.cpp
msgid "Invalid polygon. At least 2 points are needed in 'Segments' build mode."
-msgstr ""
+msgstr "Äa giác không hợp lệ. Cần ít nhất 2 Ä‘iểm trong chế độ dá»±ng 'Segments'."
#: scene/2d/collision_shape_2d.cpp
msgid ""
@@ -12498,44 +12465,52 @@ msgid ""
"CollisionObject2D derived node. Please only use it as a child of Area2D, "
"StaticBody2D, RigidBody2D, KinematicBody2D, etc. to give them a shape."
msgstr ""
+"CollisionShape2D nhằm mục đích tạo khối va chạm cho những nút kế thừa từ "
+"CollisionObject2D. Vậy nên hãy cho nút ấy làm con của Area2D, StaticBody2D, "
+"RigidBody2D, KinematicBody2D, ... để tạo khối va chạm."
#: scene/2d/collision_shape_2d.cpp
msgid ""
"A shape must be provided for CollisionShape2D to function. Please create a "
"shape resource for it!"
msgstr ""
+"CollisionShape2D cần một khối hình mới hoạt động được. Hãy tạo một tài "
+"nguyên khối hình cho nó!"
#: scene/2d/collision_shape_2d.cpp
msgid ""
"Polygon-based shapes are not meant be used nor edited directly through the "
"CollisionShape2D node. Please use the CollisionPolygon2D node instead."
msgstr ""
+"Khối hình đa giác không được nhằm để dùng hoặc chỉnh sửa thông qua nút "
+"CollisionShape2D. Hãy chuyển qua dùng nút CollisionPolygon2D."
#: scene/2d/cpu_particles_2d.cpp
msgid ""
"CPUParticles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"Hoạt ảnh CPUParticles2D cần CanvasItemMaterial bật \"Particles Animation\"."
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be PhysicsBody2Ds"
-msgstr ""
+msgstr "Nút A và Nút B phải là PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nút A phải là PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node B must be a PhysicsBody2D"
-msgstr ""
+msgstr "Nút B phải là PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Joint is not connected to two PhysicsBody2Ds"
-msgstr ""
+msgstr "Khớp nối chưa kết nối tới hai PhysicsBody2D"
#: scene/2d/joints_2d.cpp
msgid "Node A and Node B must be different PhysicsBody2Ds"
-msgstr ""
+msgstr "Nút A và Nút B phải là 2 PhysicsBody2D khác nhau"
#: scene/2d/light_2d.cpp
msgid ""
@@ -12568,6 +12543,7 @@ msgstr ""
msgid ""
"ParallaxLayer node only works when set as child of a ParallaxBackground node."
msgstr ""
+"Nút ParallaxLayer chỉ hoạt động khi là con của một nút ParallaxBackground."
#: scene/2d/particles_2d.cpp
msgid ""
@@ -12587,10 +12563,11 @@ msgid ""
"Particles2D animation requires the usage of a CanvasItemMaterial with "
"\"Particles Animation\" enabled."
msgstr ""
+"Hoạt ảnh Particles2D cần CanvasItemMaterial bật \"Particles Animation\"."
#: scene/2d/path_2d.cpp
msgid "PathFollow2D only works when set as a child of a Path2D node."
-msgstr ""
+msgstr "PathFollow2D chỉ hoạt động khi được đặt làm con của một nút Path2D."
#: scene/2d/physics_body_2d.cpp
msgid ""
@@ -12602,6 +12579,8 @@ msgstr ""
#: scene/2d/remote_transform_2d.cpp
msgid "Path property must point to a valid Node2D node to work."
msgstr ""
+"Thuá»™c tính ÄÆ°á»ng dẫn phải chỉ đến má»™t nút Node2D hợp lệ thì má»›i hoạt động "
+"được."
#: scene/2d/skeleton_2d.cpp
msgid "This Bone2D chain should end at a Skeleton2D node."
@@ -12610,11 +12589,12 @@ msgstr ""
#: scene/2d/skeleton_2d.cpp
msgid "A Bone2D only works with a Skeleton2D or another Bone2D as parent node."
msgstr ""
+"Bone2D chỉ hoạt động khi là con một nút Skeleton2D hoặc một Bone2D khác ."
#: scene/2d/skeleton_2d.cpp
msgid ""
"This bone lacks a proper REST pose. Go to the Skeleton2D node and set one."
-msgstr ""
+msgstr "Thanh xương này thiếu dáng NGHỈ. Hãy đặt một dáng tại nút Skeleton2D."
#: scene/2d/tile_map.cpp
msgid ""
@@ -12645,13 +12625,15 @@ msgstr ""
#: scene/3d/arvr_nodes.cpp
msgid "ARVRAnchor must have an ARVROrigin node as its parent."
-msgstr ""
+msgstr "ARVRAnchor phải là con của nút ARVROrigin."
#: scene/3d/arvr_nodes.cpp
msgid ""
"The anchor ID must not be 0 or this anchor won't be bound to an actual "
"anchor."
msgstr ""
+"ID của neo phải là 0, nếu không thì neo này sẽ không bị ràng buộc với neo "
+"thá»±c."
#: scene/3d/arvr_nodes.cpp
msgid "ARVROrigin requires an ARVRCamera child node."
@@ -12913,7 +12895,7 @@ msgstr ""
#: scene/gui/color_picker.cpp
msgid "Pick a color from the editor window."
-msgstr "Chá»n má»™t màu từ cá»­a sổ biên tập"
+msgstr "Chá»n má»™t màu từ cá»­a sổ biên tập."
#: scene/gui/color_picker.cpp
msgid "HSV"
@@ -13014,7 +12996,7 @@ msgstr ""
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for preview."
-msgstr "nguồn vô hiệu cho xem trước"
+msgstr "Nguồn vô hiệu cho xem trước."
#: scene/resources/visual_shader_nodes.cpp
msgid "Invalid source for shader."
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index deca89e9ea..e043d0f05a 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -81,7 +81,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Chinese (Simplified) (Godot Engine)\n"
"POT-Creation-Date: 2018-01-20 12:15+0200\n"
-"PO-Revision-Date: 2021-03-16 10:40+0000\n"
+"PO-Revision-Date: 2021-04-05 14:28+0000\n"
"Last-Translator: Haoyu Qiu <timothyqiu32@gmail.com>\n"
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
"godot-engine/godot/zh_Hans/>\n"
@@ -90,7 +90,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Weblate 4.5.2-dev\n"
+"X-Generator: Weblate 4.6-dev\n"
#: core/math/expression.cpp modules/gdscript/gdscript_functions.cpp
#: modules/visual_script/visual_script_builtin_funcs.cpp
@@ -790,7 +790,7 @@ msgstr "标准"
#: editor/code_editor.cpp editor/plugins/script_editor_plugin.cpp
msgid "Toggle Scripts Panel"
-msgstr "å¼€å¯ï¼å…³é—­è„šæœ¬é¢æ¿"
+msgstr "切æ¢è„šæœ¬é¢æ¿"
#: editor/code_editor.cpp editor/plugins/canvas_item_editor_plugin.cpp
#: editor/plugins/texture_region_editor_plugin.cpp
@@ -1376,7 +1376,7 @@ msgstr "总线选项"
#: editor/editor_audio_buses.cpp editor/filesystem_dock.cpp
#: editor/plugins/animation_player_editor_plugin.cpp editor/scene_tree_dock.cpp
msgid "Duplicate"
-msgstr "æ‹·è´"
+msgstr "å¤åˆ¶"
#: editor/editor_audio_buses.cpp
msgid "Reset Volume"
@@ -3660,6 +3660,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "状æ€ï¼šå¯¼å…¥æ–‡ä»¶å¤±è´¥ã€‚è¯·æ‰‹åŠ¨ä¿®å¤æ–‡ä»¶åŽé‡æ–°å¯¼å…¥ã€‚"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr "该文件的导入已被ç¦ç”¨ï¼Œå› æ­¤ä¸èƒ½æ‰“开进行编辑。"
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "无法移动或é‡å‘½å根资æºã€‚"
@@ -4057,6 +4062,10 @@ msgid "Reset to Defaults"
msgstr "é‡ç½®ä¸ºé»˜è®¤å€¼"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr "ä¿ç•™æ–‡ä»¶ï¼ˆä¸å¯¼å…¥ï¼‰"
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d 个文件"
@@ -5195,7 +5204,7 @@ msgstr "设置å¸é™„"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Offset:"
-msgstr "网格åç§»é‡:"
+msgstr "网格å移:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Grid Step:"
@@ -5211,7 +5220,7 @@ msgstr "æ­¥"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Offset:"
-msgstr "旋转åç§»é‡:"
+msgstr "旋转å移:"
#: editor/plugins/canvas_item_editor_plugin.cpp
msgid "Rotation Step:"
@@ -7493,7 +7502,7 @@ msgstr ""
"\n"
"ç眼:Gizmo å¯è§ã€‚\n"
"闭眼:Gizmo éšè—。\n"
-"åŠç眼:Gizmo 也å¯ç©¿è¿‡ä¸é€æ˜Žçš„表é¢å¯è§ï¼ˆâ€œX-Ray - X å…‰â€ï¼‰ã€‚"
+"åŠç眼:Gizmo 也å¯ç©¿è¿‡ä¸é€æ˜Žçš„表é¢å¯è§ï¼ˆâ€œX å…‰â€ï¼‰ã€‚"
#: editor/plugins/spatial_editor_plugin.cpp
msgid "Snap Nodes To Floor"
@@ -7922,7 +7931,7 @@ msgstr "自动è£å‰ª"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Offset:"
-msgstr "åç§»é‡ï¼š"
+msgstr "å移:"
#: editor/plugins/texture_region_editor_plugin.cpp
msgid "Step:"
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index 2009ba8f20..030f678592 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -3764,6 +3764,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "ç‹€æ…‹ï¼šå°Žå…¥æª”æ¡ˆå¤±æ•—ã€‚è«‹ä¿®æ­£æª”æ¡ˆä¸¦å†æ‰‹å‹•導入。"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
#, fuzzy
msgid "Cannot move/rename resources root."
msgstr "ä¸èƒ½ç§»å‹•ï¼é‡æ–°å‘½å resources root."
@@ -4189,6 +4194,10 @@ msgid "Reset to Defaults"
msgstr "é è¨­"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
#, fuzzy
msgid "%d Files"
msgstr "檔案"
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 62ef5a616c..2c60984b36 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -3610,6 +3610,11 @@ msgid "Status: Import of file failed. Please fix file and reimport manually."
msgstr "ç‹€æ…‹ï¼šæª”æ¡ˆåŒ¯å…¥å¤±æ•—ã€‚è«‹ä¿®æ­£æª”æ¡ˆä¸¦æ‰‹å‹•é‡æ–°åŒ¯å…¥ã€‚"
#: editor/filesystem_dock.cpp
+msgid ""
+"Importing has been disabled for this file, so it can't be opened for editing."
+msgstr ""
+
+#: editor/filesystem_dock.cpp
msgid "Cannot move/rename resources root."
msgstr "ç„¡æ³•ç§»å‹•æˆ–é‡æ–°å‘½å根資æºã€‚"
@@ -4007,6 +4012,10 @@ msgid "Reset to Defaults"
msgstr "é‡è¨­ç‚ºé è¨­"
#: editor/import_dock.cpp
+msgid "Keep File (No Import)"
+msgstr ""
+
+#: editor/import_dock.cpp
msgid "%d Files"
msgstr "%d 個檔案"
diff --git a/main/main.cpp b/main/main.cpp
index aa925c508c..4103fad17c 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -365,7 +365,7 @@ void Main::print_help(const char *p_binary) {
OS::get_singleton()->print(" <path> should be absolute or relative to the project directory, and include the filename for the binary (e.g. 'builds/game.exe'). The target directory should exist.\n");
OS::get_singleton()->print(" --export-debug <preset> <path> Same as --export, but using the debug template.\n");
OS::get_singleton()->print(" --export-pack <preset> <path> Same as --export, but only export the game pack for the given preset. The <path> extension determines whether it will be in PCK or ZIP format.\n");
- OS::get_singleton()->print(" --doctool <path> Dump the engine API reference to the given <path> in XML format, merging if existing files are found.\n");
+ OS::get_singleton()->print(" --doctool [<path>] Dump the engine API reference to the given <path> (defaults to current dir) in XML format, merging if existing files are found.\n");
OS::get_singleton()->print(" --no-docbase Disallow dumping the base types (used with --doctool).\n");
OS::get_singleton()->print(" --build-solutions Build the scripting solutions (e.g. for C# projects). Implies --editor and requires a valid project to edit.\n");
#ifdef DEBUG_METHODS_ENABLED
@@ -1826,8 +1826,7 @@ bool Main::start() {
ERR_FAIL_COND_V(!_start_success, false);
bool hasicon = false;
- String doc_tool;
- List<String> removal_docs;
+ String doc_tool_path;
String positional_arg;
String game_path;
String script;
@@ -1881,9 +1880,11 @@ bool Main::start() {
script = args[i + 1];
#ifdef TOOLS_ENABLED
} else if (args[i] == "--doctool") {
- doc_tool = args[i + 1];
- for (int j = i + 2; j < args.size(); j++) {
- removal_docs.push_back(args[j]);
+ doc_tool_path = args[i + 1];
+ if (doc_tool_path.begins_with("-")) {
+ // Assuming other command line arg, so default to cwd.
+ doc_tool_path = ".";
+ parsed_pair = false;
}
} else if (args[i] == "--export") {
editor = true; //needs editor
@@ -1904,16 +1905,19 @@ bool Main::start() {
if (parsed_pair) {
i++;
}
+ } else if (args[i] == "--doctool") {
+ // Handle case where no path is given to --doctool.
+ doc_tool_path = ".";
}
}
#ifdef TOOLS_ENABLED
- if (doc_tool != "") {
+ if (doc_tool_path != "") {
Engine::get_singleton()->set_editor_hint(
true); // Needed to instance editor-only classes for their default values
{
- DirAccessRef da = DirAccess::open(doc_tool);
+ DirAccessRef da = DirAccess::open(doc_tool_path);
ERR_FAIL_COND_V_MSG(!da, false, "Argument supplied to --doctool must be a valid directory path.");
}
@@ -1943,7 +1947,7 @@ bool Main::start() {
// Custom modules are always located by absolute path.
String path = _doc_data_class_paths[i].path;
if (path.is_rel_path()) {
- path = doc_tool.plus_file(path);
+ path = doc_tool_path.plus_file(path);
}
String name = _doc_data_class_paths[i].name;
doc_data_classes[name] = path;
@@ -1960,7 +1964,7 @@ bool Main::start() {
}
}
- String index_path = doc_tool.plus_file("doc/classes");
+ String index_path = doc_tool_path.plus_file("doc/classes");
// Create the main documentation directory if it doesn't exist
DirAccess *da = DirAccess::create_for_path(index_path);
da->make_dir_recursive(index_path);
@@ -2533,10 +2537,10 @@ bool Main::iteration() {
if (frame > 1000000) {
if (editor || project_manager) {
if (print_fps) {
- print_line("Editor FPS: " + itos(frames));
+ print_line(vformat("Editor FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(1)));
}
} else if (GLOBAL_GET("debug/settings/stdout/print_fps") || print_fps) {
- print_line("Game FPS: " + itos(frames));
+ print_line(vformat("Project FPS: %d (%s mspf)", frames, rtos(1000.0 / frames).pad_decimals(1)));
}
Engine::get_singleton()->_fps = frames;
diff --git a/modules/bullet/space_bullet.cpp b/modules/bullet/space_bullet.cpp
index ceae3be8bc..bdaec4a09e 100644
--- a/modules/bullet/space_bullet.cpp
+++ b/modules/bullet/space_bullet.cpp
@@ -1235,6 +1235,10 @@ bool SpaceBullet::recover_from_penetration(RigidBodyBullet *p_body, const btTran
continue;
}
+ if (kin_shape.shape->getShapeType() == EMPTY_SHAPE_PROXYTYPE) {
+ continue;
+ }
+
btTransform shape_transform = p_body_position * kin_shape.transform;
shape_transform.getOrigin() += r_delta_recover_movement;
diff --git a/modules/csg/csg.cpp b/modules/csg/csg.cpp
index 8b46447f04..7387842259 100644
--- a/modules/csg/csg.cpp
+++ b/modules/csg/csg.cpp
@@ -931,7 +931,7 @@ void CSGBrushOperation::Build2DFaces::_merge_faces(const Vector<int> &p_segment_
// Delete the old faces in reverse index order.
merge_faces_idx.sort();
- merge_faces_idx.invert();
+ merge_faces_idx.reverse();
for (int i = 0; i < merge_faces_idx.size(); ++i) {
faces.remove(merge_faces_idx[i]);
}
diff --git a/modules/csg/csg_shape.cpp b/modules/csg/csg_shape.cpp
index b97ee6ce4c..77be493be9 100644
--- a/modules/csg/csg_shape.cpp
+++ b/modules/csg/csg_shape.cpp
@@ -1679,7 +1679,7 @@ CSGBrush *CSGPolygon3D::_build_brush() {
Vector<Point2> final_polygon = polygon;
if (Triangulate::get_area(final_polygon) > 0) {
- final_polygon.invert();
+ final_polygon.reverse();
}
Vector<int> triangles = Geometry2D::triangulate_polygon(final_polygon);
diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp
index 622b589feb..1ac4922acf 100644
--- a/modules/fbx/data/fbx_skeleton.cpp
+++ b/modules/fbx/data/fbx_skeleton.cpp
@@ -69,7 +69,7 @@ void FBXSkeleton::init_skeleton(const ImportState &state) {
// Make sure the bone name is unique.
const String bone_name = bone->bone_name;
int same_name_count = 0;
- for (int y = x; y < skeleton_bone_count; y++) {
+ for (int y = x + 1; y < skeleton_bone_count; y++) {
Ref<FBXBone> other_bone = skeleton_bones[y];
if (other_bone.is_valid()) {
if (other_bone->bone_name == bone_name) {
diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp
index e18ebe3930..55d524883f 100644
--- a/modules/fbx/editor_scene_importer_fbx.cpp
+++ b/modules/fbx/editor_scene_importer_fbx.cpp
@@ -94,7 +94,7 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl
Error err;
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err);
- ERR_FAIL_COND_V(!f, NULL);
+ ERR_FAIL_COND_V(!f, nullptr);
{
PackedByteArray data;
@@ -104,6 +104,9 @@ Node3D *EditorSceneImporterFBX::import_scene(const String &p_path, uint32_t p_fl
bool is_binary = false;
data.resize(f->get_len());
+
+ ERR_FAIL_COND_V(data.size() < 64, NULL);
+
f->get_buffer(data.ptrw(), data.size());
PackedByteArray fbx_header;
fbx_header.resize(64);
@@ -260,8 +263,9 @@ T EditorSceneImporterFBX::_interpolate_track(const Vector<float> &p_times, const
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
- if (p_times[i] > p_time)
+ if (p_times[i] > p_time) {
break;
+ }
idx++;
}
@@ -334,7 +338,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
ImportState state;
state.is_blender_fbx = p_is_blender_fbx;
state.path = p_path;
- state.animation_player = NULL;
+ state.animation_player = nullptr;
// create new root node for scene
Node3D *scene_root = memnew(Node3D);
@@ -610,8 +614,9 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
for (const FBXDocParser::Geometry *mesh : geometry) {
print_verbose("[doc] [" + itos(mesh->ID()) + "] mesh: " + fbx_node->node_name);
- if (mesh == nullptr)
+ if (mesh == nullptr) {
continue;
+ }
const FBXDocParser::MeshGeometry *mesh_geometry = dynamic_cast<const FBXDocParser::MeshGeometry *>(mesh);
if (mesh_geometry) {
@@ -628,7 +633,7 @@ Node3D *EditorSceneImporterFBX::_generate_scene(
mesh_data_precached->mesh_node = fbx_node;
// mesh node, mesh id
- mesh_node = mesh_data_precached->create_fbx_mesh(state, mesh_geometry, fbx_node->fbx_model, 0);
+ mesh_node = mesh_data_precached->create_fbx_mesh(state, mesh_geometry, fbx_node->fbx_model, false);
if (!state.MeshNodes.has(mesh_id)) {
state.MeshNodes.insert(mesh_id, fbx_node);
}
diff --git a/modules/fbx/editor_scene_importer_fbx.h b/modules/fbx/editor_scene_importer_fbx.h
index 39f8648b0f..4bb2c9d21b 100644
--- a/modules/fbx/editor_scene_importer_fbx.h
+++ b/modules/fbx/editor_scene_importer_fbx.h
@@ -128,7 +128,7 @@ public:
virtual void get_extensions(List<String> *r_extensions) const override;
virtual uint32_t get_import_flags() const override;
- virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL) override;
+ virtual Node3D *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr) override;
};
#endif // TOOLS_ENABLED
diff --git a/modules/fbx/fbx_parser/ByteSwapper.h b/modules/fbx/fbx_parser/ByteSwapper.h
index f759c9117c..5c16383974 100644
--- a/modules/fbx/fbx_parser/ByteSwapper.h
+++ b/modules/fbx/fbx_parser/ByteSwapper.h
@@ -264,8 +264,9 @@ struct Getter {
le = !le;
if (le) {
ByteSwapper<T, (sizeof(T) > 1 ? true : false)>()(inout);
- } else
+ } else {
ByteSwapper<T, false>()(inout);
+ }
}
};
diff --git a/modules/fbx/fbx_parser/FBXAnimation.cpp b/modules/fbx/fbx_parser/FBXAnimation.cpp
index b11e2c7f55..4ab5edebb1 100644
--- a/modules/fbx/fbx_parser/FBXAnimation.cpp
+++ b/modules/fbx/fbx_parser/FBXAnimation.cpp
@@ -130,7 +130,7 @@ AnimationCurve::~AnimationCurve() {
AnimationCurveNode::AnimationCurveNode(uint64_t id, const ElementPtr element, const std::string &name,
const Document &doc, const char *const *target_prop_whitelist /*= NULL*/,
size_t whitelist_size /*= 0*/) :
- Object(id, element, name), target(), doc(doc) {
+ Object(id, element, name), doc(doc) {
const ScopePtr sc = GetRequiredScope(element);
// find target node
diff --git a/modules/fbx/fbx_parser/FBXDocument.cpp b/modules/fbx/fbx_parser/FBXDocument.cpp
index bcf7fa1565..d156db201b 100644
--- a/modules/fbx/fbx_parser/FBXDocument.cpp
+++ b/modules/fbx/fbx_parser/FBXDocument.cpp
@@ -93,7 +93,7 @@ using namespace Util;
// ------------------------------------------------------------------------------------------------
LazyObject::LazyObject(uint64_t id, const ElementPtr element, const Document &doc) :
- doc(doc), element(element), id(id), flags() {
+ doc(doc), element(element), id(id) {
// empty
}
@@ -252,7 +252,7 @@ FileGlobalSettings::~FileGlobalSettings() {
// ------------------------------------------------------------------------------------------------
Document::Document(const Parser &parser, const ImportSettings &settings) :
- settings(settings), parser(parser), SafeToImport(false) {
+ settings(settings), parser(parser) {
// Cannot use array default initialization syntax because vc8 fails on it
for (unsigned int &timeStamp : creationTimeStamp) {
timeStamp = 0;
diff --git a/modules/fbx/fbx_parser/FBXDocument.h b/modules/fbx/fbx_parser/FBXDocument.h
index b810197d7e..20e635a6a4 100644
--- a/modules/fbx/fbx_parser/FBXDocument.h
+++ b/modules/fbx/fbx_parser/FBXDocument.h
@@ -670,7 +670,7 @@ public:
uint8_t *RelinquishContent() {
uint8_t *ptr = content;
- content = 0;
+ content = nullptr;
return ptr;
}
diff --git a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
index 835b66ab23..df50a32c39 100644
--- a/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
+++ b/modules/fbx/fbx_parser/FBXDocumentUtil.cpp
@@ -160,7 +160,7 @@ const PropertyTable *GetPropertyTable(const Document &doc,
DOMWarning("property table (Properties70) not found", element);
}
if (templateProps) {
- return templateProps;
+ return new const PropertyTable(templateProps);
} else {
return new const PropertyTable();
}
diff --git a/modules/fbx/fbx_parser/FBXImportSettings.h b/modules/fbx/fbx_parser/FBXImportSettings.h
index 97ce496eaf..b016db174b 100644
--- a/modules/fbx/fbx_parser/FBXImportSettings.h
+++ b/modules/fbx/fbx_parser/FBXImportSettings.h
@@ -80,60 +80,52 @@ namespace FBXDocParser {
/** FBX import settings, parts of which are publicly accessible via their corresponding AI_CONFIG constants */
struct ImportSettings {
- ImportSettings() :
- strictMode(true), readAllLayers(true), readAllMaterials(true), readMaterials(true), readTextures(true), readCameras(true), readLights(true), readAnimations(true), readWeights(true), preservePivots(true), optimizeEmptyAnimationCurves(true), useLegacyEmbeddedTextureNaming(false), removeEmptyBones(true), convertToMeters(false) {
- // empty
- }
-
/** enable strict mode:
* - only accept fbx 2012, 2013 files
* - on the slightest error, give up.
*
* Basically, strict mode means that the fbx file will actually
- * be validated. Strict mode is off by default. */
- bool strictMode;
+ * be validated.*/
+ bool strictMode = true;
/** specifies whether all geometry layers are read and scanned for
* usable data channels. The FBX spec indicates that many readers
* will only read the first channel and that this is in some way
* the recommended way- in reality, however, it happens a lot that
- * vertex data is spread among multiple layers. The default
- * value for this option is true.*/
- bool readAllLayers;
+ * vertex data is spread among multiple layers.*/
+ bool readAllLayers = true;
/** specifies whether all materials are read, or only those that
* are referenced by at least one mesh. Reading all materials
* may make FBX reading a lot slower since all objects
- * need to be processed .
- * This bit is ignored unless readMaterials=true*/
- bool readAllMaterials;
+ * need to be processed.
+ * This bit is ignored unless readMaterials=true.*/
+ bool readAllMaterials = true;
/** import materials (true) or skip them and assign a default
- * material. The default value is true.*/
- bool readMaterials;
+ * material.*/
+ bool readMaterials = true;
- /** import embedded textures? Default value is true.*/
- bool readTextures;
+ /** import embedded textures?*/
+ bool readTextures = true;
- /** import cameras? Default value is true.*/
- bool readCameras;
+ /** import cameras?*/
+ bool readCameras = true;
- /** import light sources? Default value is true.*/
- bool readLights;
+ /** import light sources?*/
+ bool readLights = true;
/** import animations (i.e. animation curves, the node
- * skeleton is always imported). Default value is true. */
- bool readAnimations;
+ * skeleton is always imported).*/
+ bool readAnimations = true;
- /** read bones (vertex weights and deform info).
- * Default value is true. */
- bool readWeights;
+ /** read bones (vertex weights and deform info).*/
+ bool readWeights = true;
/** preserve transformation pivots and offsets. Since these can
* not directly be represented in assimp, additional dummy
* nodes will be generated. Note that settings this to false
- * can make animation import a lot slower. The default value
- * is true.
+ * can make animation import a lot slower.
*
* The naming scheme for the generated nodes is:
* <OriginalName>_$AssimpFbx$_<TransformName>
@@ -149,24 +141,21 @@ struct ImportSettings {
* Scaling
* Rotation
**/
- bool preservePivots;
+ bool preservePivots = true;
/** do not import animation curves that specify a constant
- * values matching the corresponding node transformation.
- * The default value is true. */
- bool optimizeEmptyAnimationCurves;
+ * values matching the corresponding node transformation.*/
+ bool optimizeEmptyAnimationCurves = true;
- /** use legacy naming for embedded textures eg: (*0, *1, *2)
- */
- bool useLegacyEmbeddedTextureNaming;
+ /** use legacy naming for embedded textures eg: (*0, *1, *2).*/
+ bool useLegacyEmbeddedTextureNaming = false;
- /** Empty bones shall be removed
- */
- bool removeEmptyBones;
+ /** Empty bones shall be removed.*/
+ bool removeEmptyBones = true;
- /** Set to true to perform a conversion from cm to meter after the import
- */
- bool convertToMeters;
+ /** Set to true to perform a conversion from cm to meter after
+ * the import.*/
+ bool convertToMeters = false;
};
} // namespace FBXDocParser
diff --git a/modules/fbx/fbx_parser/FBXMaterial.cpp b/modules/fbx/fbx_parser/FBXMaterial.cpp
index 9970a2b0b1..219da1b2f4 100644
--- a/modules/fbx/fbx_parser/FBXMaterial.cpp
+++ b/modules/fbx/fbx_parser/FBXMaterial.cpp
@@ -171,7 +171,7 @@ Material::~Material() {
// ------------------------------------------------------------------------------------------------
Texture::Texture(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name) :
- Object(id, element, name), uvScaling(1.0f, 1.0f), media(nullptr) {
+ Object(id, element, name), uvScaling(1.0f, 1.0f) {
const ScopePtr sc = GetRequiredScope(element);
const ElementPtr Type = sc->GetElement("Type");
@@ -267,10 +267,10 @@ LayeredTexture::LayeredTexture(uint64_t id, const ElementPtr element, const Docu
ElementPtr BlendModes = sc->GetElement("BlendModes");
ElementPtr Alphas = sc->GetElement("Alphas");
- if (BlendModes != 0) {
+ if (BlendModes != nullptr) {
blendMode = (BlendMode)ParseTokenAsInt(GetRequiredToken(BlendModes, 0));
}
- if (Alphas != 0) {
+ if (Alphas != nullptr) {
alpha = ParseTokenAsFloat(GetRequiredToken(Alphas, 0));
}
}
@@ -297,7 +297,7 @@ void LayeredTexture::fillTexture(const Document &doc) {
// ------------------------------------------------------------------------------------------------
Video::Video(uint64_t id, const ElementPtr element, const Document &doc, const std::string &name) :
- Object(id, element, name), contentLength(0), content(0) {
+ Object(id, element, name) {
const ScopePtr sc = GetRequiredScope(element);
const ElementPtr Type = sc->GetElement("Type");
diff --git a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
index ccc06550fe..a28e7565c6 100644
--- a/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
+++ b/modules/fbx/fbx_parser/FBXMeshGeometry.cpp
@@ -88,7 +88,7 @@ using namespace Util;
// ------------------------------------------------------------------------------------------------
Geometry::Geometry(uint64_t id, const ElementPtr element, const std::string &name, const Document &doc) :
- Object(id, element, name), skin() {
+ Object(id, element, name) {
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "Deformer");
for (const Connection *con : conns) {
const Skin *sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
diff --git a/modules/fbx/fbx_parser/FBXParseTools.h b/modules/fbx/fbx_parser/FBXParseTools.h
index 21472f5b7b..b4003bbec5 100644
--- a/modules/fbx/fbx_parser/FBXParseTools.h
+++ b/modules/fbx/fbx_parser/FBXParseTools.h
@@ -61,7 +61,7 @@ inline bool IsLineEnd(char_t c) {
// Special version of the function, providing higher accuracy and safety
// It is mainly used by fast_atof to prevent ugly and unwanted integer overflows.
// ------------------------------------------------------------------------------------
-inline uint64_t strtoul10_64(const char *in, bool &errored, const char **out = 0, unsigned int *max_inout = 0) {
+inline uint64_t strtoul10_64(const char *in, bool &errored, const char **out = nullptr, unsigned int *max_inout = nullptr) {
unsigned int cur = 0;
uint64_t value = 0;
diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp
index 44c24ff926..166d98bb8c 100644
--- a/modules/fbx/fbx_parser/FBXParser.cpp
+++ b/modules/fbx/fbx_parser/FBXParser.cpp
@@ -216,7 +216,7 @@ Scope::~Scope() {
// ------------------------------------------------------------------------------------------------
Parser::Parser(const TokenList &tokens, bool is_binary) :
- tokens(tokens), last(), current(), cursor(tokens.begin()), is_binary(is_binary) {
+ tokens(tokens), cursor(tokens.begin()), is_binary(is_binary) {
root = new_Scope(*this, true);
scopes.push_back(root);
}
diff --git a/modules/fbx/fbx_parser/FBXProperties.cpp b/modules/fbx/fbx_parser/FBXProperties.cpp
index 8ab94e1ef4..84e71512d6 100644
--- a/modules/fbx/fbx_parser/FBXProperties.cpp
+++ b/modules/fbx/fbx_parser/FBXProperties.cpp
@@ -145,8 +145,12 @@ std::string PeekPropertyName(const Element &element) {
} // namespace
// ------------------------------------------------------------------------------------------------
-PropertyTable::PropertyTable() :
- templateProps(), element() {
+PropertyTable::PropertyTable() {
+}
+
+// ------------------------------------------------------------------------------------------------
+PropertyTable::PropertyTable(const PropertyTable *templateProps) :
+ templateProps(templateProps), element() {
}
// ------------------------------------------------------------------------------------------------
@@ -216,8 +220,9 @@ DirectPropertyMap PropertyTable::GetUnparsedProperties() const {
// Loop through all the lazy properties (which is all the properties)
for (const LazyPropertyMap::value_type &element : lazyProps) {
// Skip parsed properties
- if (props.end() != props.find(element.first))
+ if (props.end() != props.find(element.first)) {
continue;
+ }
// Read the element's value.
// Wrap the naked pointer (since the call site is required to acquire ownership)
@@ -225,8 +230,9 @@ DirectPropertyMap PropertyTable::GetUnparsedProperties() const {
Property *prop = ReadTypedProperty(element.second);
// Element could not be read. Skip it.
- if (!prop)
+ if (!prop) {
continue;
+ }
// Add to result
result[element.first] = prop;
diff --git a/modules/fbx/fbx_parser/FBXProperties.h b/modules/fbx/fbx_parser/FBXProperties.h
index 27cacfaf76..0595b25fa7 100644
--- a/modules/fbx/fbx_parser/FBXProperties.h
+++ b/modules/fbx/fbx_parser/FBXProperties.h
@@ -137,6 +137,7 @@ class PropertyTable {
public:
// in-memory property table with no source element
PropertyTable();
+ PropertyTable(const PropertyTable *templateProps);
PropertyTable(const ElementPtr element, const PropertyTable *templateProps);
~PropertyTable();
diff --git a/modules/fbx/fbx_parser/FBXUtil.cpp b/modules/fbx/fbx_parser/FBXUtil.cpp
index 80ea5fab4c..4295cb6f5e 100644
--- a/modules/fbx/fbx_parser/FBXUtil.cpp
+++ b/modules/fbx/fbx_parser/FBXUtil.cpp
@@ -122,8 +122,9 @@ static const uint8_t base64DecodeTable[128] = {
uint8_t DecodeBase64(char ch) {
const auto idx = static_cast<uint8_t>(ch);
- if (idx > 127)
+ if (idx > 127) {
return 255;
+ }
return base64DecodeTable[idx];
}
@@ -211,8 +212,9 @@ std::string EncodeBase64(const char *data, size_t length) {
EncodeByteBlock(&finalBytes[0], encoded_string, iEncodedByte);
// add '=' at the end
- for (size_t i = 0; i < 4 * extraBytes / 3; i++)
+ for (size_t i = 0; i < 4 * extraBytes / 3; i++) {
encoded_string[encodedBytes - i - 1] = '=';
+ }
}
return encoded_string;
}
diff --git a/modules/fbx/tools/import_utils.h b/modules/fbx/tools/import_utils.h
index 6261138812..bea28ffeda 100644
--- a/modules/fbx/tools/import_utils.h
+++ b/modules/fbx/tools/import_utils.h
@@ -339,7 +339,7 @@ public:
// } else {
// Ref<Texture> texture = ResourceLoader::load(p_path);
// ERR_FAIL_COND_V(texture.is_null(), Ref<Image>());
- // Ref<Image> image = texture->get_data();
+ // Ref<Image> image = texture->get_image();
// ERR_FAIL_COND_V(image.is_null(), Ref<Image>());
// state.path_to_image_cache.insert(p_path, image);
// return image;
diff --git a/modules/fbx/tools/validation_tools.h b/modules/fbx/tools/validation_tools.h
index ced100aed2..fe0c92b22f 100644
--- a/modules/fbx/tools/validation_tools.h
+++ b/modules/fbx/tools/validation_tools.h
@@ -65,8 +65,9 @@ protected:
Error err;
FileAccess *file = FileAccess::open(path, FileAccess::WRITE, &err);
if (!file || err) {
- if (file)
+ if (file) {
memdelete(file);
+ }
print_error("ValidationTracker Error - failed to create file - path: %s\n" + path);
return;
}
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 86bd8b820d..0de6b27d27 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -159,6 +159,8 @@ void GDNativeLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
}
void GDNativeLibrary::set_config_file(Ref<ConfigFile> p_config_file) {
+ ERR_FAIL_COND(p_config_file.is_null());
+
set_singleton(p_config_file->get_value("general", "singleton", default_singleton));
set_load_once(p_config_file->get_value("general", "load_once", default_load_once));
set_symbol_prefix(p_config_file->get_value("general", "symbol_prefix", default_symbol_prefix));
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 59b078f2b6..489083e795 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -5716,7 +5716,7 @@
]
},
{
- "name": "godot_packed_glyph_array_invert",
+ "name": "godot_packed_glyph_array_reverse",
"return_type": "void",
"arguments": [
[
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
index cbd65e3772..b76f89cc99 100644
--- a/modules/gdnative/include/pluginscript/godot_pluginscript.h
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -56,6 +56,7 @@ typedef struct {
int p_argcount, godot_variant_call_error *r_error);
void (*notification)(godot_pluginscript_instance_data *p_data, int p_notification);
+ godot_string (*to_string)(godot_pluginscript_instance_data *p_data, godot_bool *r_valid);
//this is used by script languages that keep a reference counter of their own
//you can make make Ref<> not die when it reaches zero, so deleting the reference
diff --git a/modules/gdnative/include/text/godot_text.h b/modules/gdnative/include/text/godot_text.h
index 86fc745134..f3c50e6f87 100644
--- a/modules/gdnative/include/text/godot_text.h
+++ b/modules/gdnative/include/text/godot_text.h
@@ -118,6 +118,7 @@ typedef struct {
godot_vector2 (*font_get_glyph_kerning)(void *, godot_rid *, uint32_t, uint32_t, int);
godot_vector2 (*font_draw_glyph)(void *, godot_rid *, godot_rid *, int, const godot_vector2 *, uint32_t, const godot_color *);
godot_vector2 (*font_draw_glyph_outline)(void *, godot_rid *, godot_rid *, int, int, const godot_vector2 *, uint32_t, const godot_color *);
+ bool (*font_get_glyph_contours)(void *, godot_rid *, int, uint32_t, godot_packed_vector3_array *, godot_packed_int32_array *, bool *);
float (*font_get_oversampling)(void *);
void (*font_set_oversampling)(void *, float);
godot_packed_string_array (*get_system_fonts)(void *);
@@ -213,7 +214,7 @@ godot_bool GDAPI godot_packed_glyph_array_has(godot_packed_glyph_array *p_self,
void GDAPI godot_packed_glyph_array_sort(godot_packed_glyph_array *p_self);
-void GDAPI godot_packed_glyph_array_invert(godot_packed_glyph_array *p_self);
+void GDAPI godot_packed_glyph_array_reverse(godot_packed_glyph_array *p_self);
void GDAPI godot_packed_glyph_array_push_back(godot_packed_glyph_array *p_self, const godot_glyph *p_data);
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index 0025f4bb06..f795bef59f 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -1729,6 +1729,46 @@ void NativeScriptLanguage::unregister_script(NativeScript *script) {
Map<String, Ref<GDNative>>::Element *G = library_gdnatives.find(script->lib_path);
if (G && G->get()->get_library()->is_reloadable()) {
+ // ONLY if the library is marked as reloadable, and no more instances of its scripts exist do we unload the library
+
+ // First remove meta data related to the library
+ Map<String, Map<StringName, NativeScriptDesc>>::Element *L = library_classes.find(script->lib_path);
+ if (L) {
+ Map<StringName, NativeScriptDesc> classes = L->get();
+
+ for (Map<StringName, NativeScriptDesc>::Element *C = classes.front(); C; C = C->next()) {
+ // free property stuff first
+ for (OrderedHashMap<StringName, NativeScriptDesc::Property>::Element P = C->get().properties.front(); P; P = P.next()) {
+ if (P.get().getter.free_func) {
+ P.get().getter.free_func(P.get().getter.method_data);
+ }
+
+ if (P.get().setter.free_func) {
+ P.get().setter.free_func(P.get().setter.method_data);
+ }
+ }
+
+ // free method stuff
+ for (Map<StringName, NativeScriptDesc::Method>::Element *M = C->get().methods.front(); M; M = M->next()) {
+ if (M->get().method.free_func) {
+ M->get().method.free_func(M->get().method.method_data);
+ }
+ }
+
+ // free constructor/destructor
+ if (C->get().create_func.free_func) {
+ C->get().create_func.free_func(C->get().create_func.method_data);
+ }
+
+ if (C->get().destroy_func.free_func) {
+ C->get().destroy_func.free_func(C->get().destroy_func.method_data);
+ }
+ }
+
+ library_classes.erase(script->lib_path);
+ }
+
+ // now unload the library
G->get()->terminate();
library_gdnatives.erase(G);
}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
index 432aa80325..7f8dba0906 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.cpp
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -93,6 +93,13 @@ void PluginScriptInstance::notification(int p_notification) {
_desc->notification(_data, p_notification);
}
+String PluginScriptInstance::to_string(bool *r_valid) {
+ godot_string ret = _desc->to_string(_data, r_valid);
+ String str_ret = *(String *)&ret;
+ godot_string_destroy(&ret);
+ return str_ret;
+}
+
Vector<ScriptNetData> PluginScriptInstance::get_rpc_methods() const {
return _script->get_rpc_methods();
}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
index 536eb550e0..b263c0e62c 100644
--- a/modules/gdnative/pluginscript/pluginscript_instance.h
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -63,6 +63,7 @@ public:
virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error);
virtual void notification(int p_notification);
+ virtual String to_string(bool *r_valid);
virtual Ref<Script> get_script() const;
diff --git a/modules/gdnative/text/text_server_gdnative.cpp b/modules/gdnative/text/text_server_gdnative.cpp
index 7cd8de5f2e..bc4b1ac134 100644
--- a/modules/gdnative/text/text_server_gdnative.cpp
+++ b/modules/gdnative/text/text_server_gdnative.cpp
@@ -359,6 +359,12 @@ Vector2 TextServerGDNative::font_draw_glyph_outline(RID p_font, RID p_canvas, in
return advance;
}
+bool TextServerGDNative::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
+ ERR_FAIL_COND_V(interface == nullptr, false);
+ ERR_FAIL_COND_V(interface->font_get_glyph_contours == nullptr, false);
+ return interface->font_get_glyph_contours(data, (godot_rid *)&p_font, p_size, p_index, (godot_packed_vector3_array *)&r_points, (godot_packed_int32_array *)&r_contours, (bool *)&r_orientation);
+}
+
float TextServerGDNative::font_get_oversampling() const {
ERR_FAIL_COND_V(interface == nullptr, 1.f);
return interface->font_get_oversampling(data);
@@ -841,9 +847,9 @@ void GDAPI godot_packed_glyph_array_sort(godot_packed_glyph_array *p_self) {
self->sort();
}
-void GDAPI godot_packed_glyph_array_invert(godot_packed_glyph_array *p_self) {
+void GDAPI godot_packed_glyph_array_reverse(godot_packed_glyph_array *p_self) {
Vector<TextServer::Glyph> *self = (Vector<TextServer::Glyph> *)p_self;
- self->invert();
+ self->reverse();
}
void GDAPI godot_packed_glyph_array_push_back(godot_packed_glyph_array *p_self, const godot_glyph *p_data) {
diff --git a/modules/gdnative/text/text_server_gdnative.h b/modules/gdnative/text/text_server_gdnative.h
index 931bb44885..7e42b16fe1 100644
--- a/modules/gdnative/text/text_server_gdnative.h
+++ b/modules/gdnative/text/text_server_gdnative.h
@@ -126,6 +126,8 @@ public:
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
+
virtual float font_get_oversampling() const override;
virtual void font_set_oversampling(float p_oversampling) override;
diff --git a/modules/gdnative/xr/xr_interface_gdnative.cpp b/modules/gdnative/xr/xr_interface_gdnative.cpp
index 1d5a9d98f8..122cb5849b 100644
--- a/modules/gdnative/xr/xr_interface_gdnative.cpp
+++ b/modules/gdnative/xr/xr_interface_gdnative.cpp
@@ -301,7 +301,8 @@ godot_int GDAPI godot_xr_add_controller(char *p_device_name, godot_int p_hand, g
Input *input = Input::get_singleton();
ERR_FAIL_NULL_V(input, 0);
- XRPositionalTracker *new_tracker = memnew(XRPositionalTracker);
+ Ref<XRPositionalTracker> new_tracker;
+ new_tracker.instance();
new_tracker->set_tracker_name(p_device_name);
new_tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
if (p_hand == 1) {
@@ -340,8 +341,8 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
- XRPositionalTracker *remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
- if (remove_tracker != nullptr) {
+ Ref<XRPositionalTracker> remove_tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (remove_tracker.is_valid()) {
// unset our joystick if applicable
int joyid = remove_tracker->get_joy_id();
if (joyid != -1) {
@@ -351,7 +352,7 @@ void GDAPI godot_xr_remove_controller(godot_int p_controller_id) {
// remove our tracker from our server
xr_server->remove_tracker(remove_tracker);
- memdelete(remove_tracker);
+ remove_tracker.unref();
}
}
@@ -359,8 +360,8 @@ void GDAPI godot_xr_set_controller_transform(godot_int p_controller_id, godot_tr
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker.is_valid()) {
Transform *transform = (Transform *)p_transform;
if (p_tracks_orientation) {
tracker->set_orientation(transform->basis);
@@ -378,8 +379,8 @@ void GDAPI godot_xr_set_controller_button(godot_int p_controller_id, godot_int p
Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker.is_valid()) {
int joyid = tracker->get_joy_id();
if (joyid != -1) {
input->joy_button(joyid, p_button, p_is_pressed);
@@ -394,8 +395,8 @@ void GDAPI godot_xr_set_controller_axis(godot_int p_controller_id, godot_int p_a
Input *input = Input::get_singleton();
ERR_FAIL_NULL(input);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker.is_valid()) {
int joyid = tracker->get_joy_id();
if (joyid != -1) {
Input::JoyAxisValue jx;
@@ -410,8 +411,8 @@ godot_float GDAPI godot_xr_get_controller_rumble(godot_int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0.0);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
- if (tracker != nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker.is_valid()) {
return tracker->get_rumble();
}
diff --git a/modules/gdnavigation/nav_map.cpp b/modules/gdnavigation/nav_map.cpp
index 80f367f3a6..464082221f 100644
--- a/modules/gdnavigation/nav_map.cpp
+++ b/modules/gdnavigation/nav_map.cpp
@@ -351,7 +351,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
path.push_back(begin_point);
}
- path.invert();
+ path.reverse();
} else {
path.push_back(end_point);
@@ -363,7 +363,7 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p
np_id = navigation_polys[np_id].back_navigation_poly_id;
}
- path.invert();
+ path.reverse();
}
return path;
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp
index a129b73c1a..c9c5d00aa5 100644
--- a/modules/gdscript/gdscript.cpp
+++ b/modules/gdscript/gdscript.cpp
@@ -276,7 +276,7 @@ void GDScript::_get_script_property_list(List<PropertyInfo> *r_list, bool p_incl
}
msort.sort();
- msort.invert();
+ msort.reverse();
for (int i = 0; i < msort.size(); i++) {
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -1310,21 +1310,29 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) {
return true; //function exists, call was successful
}
} else {
- if (!member->data_type.is_type(p_value)) {
- // Try conversion
- Callable::CallError ce;
- const Variant *value = &p_value;
- Variant converted;
- Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- members.write[member->index] = converted;
- return true;
- } else {
- return false;
+ if (member->data_type.has_type) {
+ if (member->data_type.builtin_type == Variant::ARRAY && member->data_type.has_container_element_type()) {
+ // Typed array.
+ if (p_value.get_type() == Variant::ARRAY) {
+ return VariantInternal::get_array(&members.write[member->index])->typed_assign(p_value);
+ } else {
+ return false;
+ }
+ } else if (!member->data_type.is_type(p_value)) {
+ // Try conversion
+ Callable::CallError ce;
+ const Variant *value = &p_value;
+ Variant converted;
+ Variant::construct(member->data_type.builtin_type, converted, &value, 1, ce);
+ if (ce.error == Callable::CallError::CALL_OK) {
+ members.write[member->index] = converted;
+ return true;
+ } else {
+ return false;
+ }
}
- } else {
- members.write[member->index] = p_value;
}
+ members.write[member->index] = p_value;
}
return true;
}
@@ -1494,7 +1502,7 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const
}
msort.sort();
- msort.invert();
+ msort.reverse();
for (int i = 0; i < msort.size(); i++) {
props.push_front(sptr->member_info[msort[i].name]);
}
@@ -2293,7 +2301,7 @@ GDScriptLanguage::~GDScriptLanguage() {
script->unreference();
}
- singleton = NULL;
+ singleton = nullptr;
}
void GDScriptLanguage::add_orphan_subclass(const String &p_qualified_name, const ObjectID &p_subclass) {
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index a6138cc564..bdca64c146 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -39,40 +39,6 @@
#include "gdscript.h"
#include "gdscript_utility_functions.h"
-// TODO: Move this to a central location (maybe core?).
-static HashMap<StringName, StringName> underscore_map;
-static const char *underscore_classes[] = {
- "ClassDB",
- "Directory",
- "Engine",
- "File",
- "Geometry",
- "GodotSharp",
- "JSON",
- "Marshalls",
- "Mutex",
- "OS",
- "ResourceLoader",
- "ResourceSaver",
- "Semaphore",
- "Thread",
- "VisualScriptEditor",
- nullptr,
-};
-static StringName get_real_class_name(const StringName &p_source) {
- if (underscore_map.is_empty()) {
- const char **class_name = underscore_classes;
- while (*class_name != nullptr) {
- underscore_map[*class_name] = String("_") + *class_name;
- class_name++;
- }
- }
- if (underscore_map.has(p_source)) {
- return underscore_map[p_source];
- }
- return p_source;
-}
-
static MethodInfo info_from_utility_func(const StringName &p_function) {
ERR_FAIL_COND_V(!Variant::has_utility_function(p_function), MethodInfo());
@@ -106,10 +72,6 @@ static MethodInfo info_from_utility_func(const StringName &p_function) {
return info;
}
-void GDScriptAnalyzer::cleanup() {
- underscore_map.clear();
-}
-
static GDScriptParser::DataType make_callable_type(const MethodInfo &p_info) {
GDScriptParser::DataType type;
type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
@@ -150,7 +112,7 @@ static GDScriptParser::DataType make_native_enum_type(const StringName &p_native
type.is_meta_type = true;
List<StringName> enum_values;
- StringName real_native_name = get_real_class_name(p_native_class);
+ StringName real_native_name = GDScriptParser::get_real_class_name(p_native_class);
ClassDB::get_enum_constants(real_native_name, p_enum_name, &enum_values);
for (const List<StringName>::Element *E = enum_values.front(); E != nullptr; E = E->next()) {
@@ -267,7 +229,7 @@ Error GDScriptAnalyzer::resolve_inheritance(GDScriptParser::ClassNode *p_class,
push_error(vformat(R"(Could not resolve super class inheritance from "%s".)", name), p_class);
return err;
}
- } else if (class_exists(name) && ClassDB::can_instance(get_real_class_name(name))) {
+ } else if (class_exists(name) && ClassDB::can_instance(GDScriptParser::get_real_class_name(name))) {
base.kind = GDScriptParser::DataType::NATIVE;
base.native_type = name;
} else {
@@ -413,6 +375,14 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
}
result.kind = GDScriptParser::DataType::BUILTIN;
result.builtin_type = GDScriptParser::get_builtin_type(first);
+
+ if (result.builtin_type == Variant::ARRAY) {
+ GDScriptParser::DataType container_type = resolve_datatype(p_type->container_type);
+
+ if (container_type.kind != GDScriptParser::DataType::VARIANT) {
+ result.set_container_element_type(container_type);
+ }
+ }
} else if (class_exists(first)) {
// Native engine classes.
result.kind = GDScriptParser::DataType::NATIVE;
@@ -436,7 +406,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
return GDScriptParser::DataType();
}
result = ref->get_parser()->head->get_datatype();
- } else if (ClassDB::has_enum(get_real_class_name(parser->current_class->base_type.native_type), first)) {
+ } else if (ClassDB::has_enum(GDScriptParser::get_real_class_name(parser->current_class->base_type.native_type), first)) {
// Native enum in current class.
result = make_native_enum_type(parser->current_class->base_type.native_type, first);
} else {
@@ -499,7 +469,7 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
}
} else if (result.kind == GDScriptParser::DataType::NATIVE) {
// Only enums allowed for native.
- if (ClassDB::has_enum(get_real_class_name(result.native_type), p_type->type_chain[1]->name)) {
+ if (ClassDB::has_enum(GDScriptParser::get_real_class_name(result.native_type), p_type->type_chain[1]->name)) {
if (p_type->type_chain.size() > 2) {
push_error(R"(Enums cannot contain nested types.)", p_type->type_chain[2]);
} else {
@@ -513,6 +483,10 @@ GDScriptParser::DataType GDScriptAnalyzer::resolve_datatype(GDScriptParser::Type
}
}
+ if (result.builtin_type != Variant::ARRAY && p_type->container_type != nullptr) {
+ push_error("Only arrays can specify the collection element type.", p_type);
+ }
+
p_type->set_datatype(result);
return result;
}
@@ -535,9 +509,23 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
datatype.kind = GDScriptParser::DataType::VARIANT;
datatype.type_source = GDScriptParser::DataType::UNDETECTED;
+ GDScriptParser::DataType specified_type;
+ if (member.variable->datatype_specifier != nullptr) {
+ specified_type = resolve_datatype(member.variable->datatype_specifier);
+ specified_type.is_meta_type = false;
+ }
+
if (member.variable->initializer != nullptr) {
member.variable->set_datatype(datatype); // Allow recursive usage.
reduce_expression(member.variable->initializer);
+ if ((member.variable->infer_datatype || (member.variable->datatype_specifier != nullptr && specified_type.has_container_element_type())) && member.variable->initializer->type == GDScriptParser::Node::ARRAY) {
+ // Typed array.
+ GDScriptParser::ArrayNode *array = static_cast<GDScriptParser::ArrayNode *>(member.variable->initializer);
+ // Can only infer typed array if it has elements.
+ if ((member.variable->infer_datatype && array->elements.size() > 0) || member.variable->datatype_specifier != nullptr) {
+ update_array_literal_element_type(specified_type, array);
+ }
+ }
datatype = member.variable->initializer->get_datatype();
if (datatype.type_source != GDScriptParser::DataType::UNDETECTED) {
datatype.type_source = GDScriptParser::DataType::INFERRED;
@@ -545,8 +533,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
}
if (member.variable->datatype_specifier != nullptr) {
- datatype = resolve_datatype(member.variable->datatype_specifier);
- datatype.is_meta_type = false;
+ datatype = specified_type;
if (member.variable->initializer != nullptr) {
if (!is_type_compatible(datatype, member.variable->initializer->get_datatype(), true)) {
@@ -582,37 +569,32 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
datatype.is_constant = false;
member.variable->set_datatype(datatype);
- if (!datatype.has_no_type()) {
- // TODO: Move this out into a routine specific to validate annotations.
- if (member.variable->export_info.hint == PROPERTY_HINT_TYPE_STRING) {
- // @export annotation.
- switch (datatype.kind) {
- case GDScriptParser::DataType::BUILTIN:
- member.variable->export_info.hint_string = Variant::get_type_name(datatype.builtin_type);
- break;
- case GDScriptParser::DataType::NATIVE:
- if (ClassDB::is_parent_class(get_real_class_name(datatype.native_type), "Resource")) {
- member.variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE;
- member.variable->export_info.hint_string = get_real_class_name(datatype.native_type);
- } else {
- push_error(R"(Export type can only be built-in or a resource.)", member.variable);
- }
- break;
- default:
- // TODO: Allow custom user resources.
- push_error(R"(Export type can only be built-in or a resource.)", member.variable);
- break;
- }
- }
+
+ // Apply annotations.
+ for (List<GDScriptParser::AnnotationNode *>::Element *E = member.variable->annotations.front(); E; E = E->next()) {
+ E->get()->apply(parser, member.variable);
}
} break;
case GDScriptParser::ClassNode::Member::CONSTANT: {
reduce_expression(member.constant->initializer);
+ GDScriptParser::DataType specified_type;
+
+ if (member.constant->datatype_specifier != nullptr) {
+ specified_type = resolve_datatype(member.constant->datatype_specifier);
+ specified_type.is_meta_type = false;
+ }
+
GDScriptParser::DataType datatype = member.constant->get_datatype();
if (member.constant->initializer) {
if (member.constant->initializer->type == GDScriptParser::Node::ARRAY) {
- const_fold_array(static_cast<GDScriptParser::ArrayNode *>(member.constant->initializer));
+ GDScriptParser::ArrayNode *array = static_cast<GDScriptParser::ArrayNode *>(member.constant->initializer);
+ const_fold_array(array);
+
+ // Can only infer typed array if it has elements.
+ if (array->elements.size() > 0 || (member.constant->datatype_specifier != nullptr && specified_type.has_container_element_type())) {
+ update_array_literal_element_type(specified_type, array);
+ }
} else if (member.constant->initializer->type == GDScriptParser::Node::DICTIONARY) {
const_fold_dictionary(static_cast<GDScriptParser::DictionaryNode *>(member.constant->initializer));
}
@@ -622,8 +604,7 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
}
if (member.constant->datatype_specifier != nullptr) {
- datatype = resolve_datatype(member.constant->datatype_specifier);
- datatype.is_meta_type = false;
+ datatype = specified_type;
if (!is_type_compatible(datatype, member.constant->initializer->get_datatype(), true)) {
push_error(vformat(R"(Value of type "%s" cannot be initialized to constant of type "%s".)", member.constant->initializer->get_datatype().to_string(), datatype.to_string()), member.constant->initializer);
@@ -637,6 +618,11 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
datatype.is_constant = true;
member.constant->set_datatype(datatype);
+
+ // Apply annotations.
+ for (List<GDScriptParser::AnnotationNode *>::Element *E = member.constant->annotations.front(); E; E = E->next()) {
+ E->get()->apply(parser, member.constant);
+ }
} break;
case GDScriptParser::ClassNode::Member::SIGNAL: {
for (int j = 0; j < member.signal->parameters.size(); j++) {
@@ -651,6 +637,11 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
signal_type.builtin_type = Variant::SIGNAL;
member.signal->set_datatype(signal_type);
+
+ // Apply annotations.
+ for (List<GDScriptParser::AnnotationNode *>::Element *E = member.signal->annotations.front(); E; E = E->next()) {
+ E->get()->apply(parser, member.signal);
+ }
} break;
case GDScriptParser::ClassNode::Member::ENUM: {
GDScriptParser::DataType enum_type;
@@ -693,6 +684,11 @@ void GDScriptAnalyzer::resolve_class_interface(GDScriptParser::ClassNode *p_clas
current_enum = nullptr;
member.m_enum->set_datatype(enum_type);
+
+ // Apply annotations.
+ for (List<GDScriptParser::AnnotationNode *>::Element *E = member.m_enum->annotations.front(); E; E = E->next()) {
+ E->get()->apply(parser, member.m_enum);
+ }
} break;
case GDScriptParser::ClassNode::Member::FUNCTION:
resolve_function_signature(member.function);
@@ -761,6 +757,11 @@ void GDScriptAnalyzer::resolve_class_body(GDScriptParser::ClassNode *p_class) {
}
resolve_function_body(member.function);
+
+ // Apply annotations.
+ for (List<GDScriptParser::AnnotationNode *>::Element *E = member.function->annotations.front(); E; E = E->next()) {
+ E->get()->apply(parser, member.function);
+ }
}
parser->current_class = previous_class;
@@ -1092,8 +1093,23 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable
GDScriptParser::DataType type;
type.kind = GDScriptParser::DataType::VARIANT; // By default.
+ GDScriptParser::DataType specified_type;
+ if (p_variable->datatype_specifier != nullptr) {
+ specified_type = resolve_datatype(p_variable->datatype_specifier);
+ specified_type.is_meta_type = false;
+ }
+
if (p_variable->initializer != nullptr) {
reduce_expression(p_variable->initializer);
+ if ((p_variable->infer_datatype || (p_variable->datatype_specifier != nullptr && specified_type.has_container_element_type())) && p_variable->initializer->type == GDScriptParser::Node::ARRAY) {
+ // Typed array.
+ GDScriptParser::ArrayNode *array = static_cast<GDScriptParser::ArrayNode *>(p_variable->initializer);
+ // Can only infer typed array if it has elements.
+ if ((p_variable->infer_datatype && array->elements.size() > 0) || p_variable->datatype_specifier != nullptr) {
+ update_array_literal_element_type(specified_type, array);
+ }
+ }
+
type = p_variable->initializer->get_datatype();
if (p_variable->infer_datatype) {
@@ -1117,7 +1133,7 @@ void GDScriptAnalyzer::resolve_variable(GDScriptParser::VariableNode *p_variable
}
if (p_variable->datatype_specifier != nullptr) {
- type = resolve_datatype(p_variable->datatype_specifier);
+ type = specified_type;
type.is_meta_type = false;
if (p_variable->initializer != nullptr) {
@@ -1362,6 +1378,12 @@ void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) {
if (p_return->return_value != nullptr) {
reduce_expression(p_return->return_value);
+ if (p_return->return_value->type == GDScriptParser::Node::ARRAY) {
+ // Check if assigned value is an array literal, so we can make it a typed array too if appropriate.
+ if (parser->current_function->get_datatype().has_container_element_type() && p_return->return_value->type == GDScriptParser::Node::ARRAY) {
+ update_array_literal_element_type(parser->current_function->get_datatype(), static_cast<GDScriptParser::ArrayNode *>(p_return->return_value));
+ }
+ }
result = p_return->return_value->get_datatype();
} else {
// Return type is null by default.
@@ -1498,6 +1520,52 @@ void GDScriptAnalyzer::reduce_array(GDScriptParser::ArrayNode *p_array) {
p_array->set_datatype(arr_type);
}
+// When an array literal is stored (or passed as function argument) to a typed context, we then assume the array is typed.
+// This function determines which type is that (if any).
+void GDScriptAnalyzer::update_array_literal_element_type(const GDScriptParser::DataType &p_base_type, GDScriptParser::ArrayNode *p_array_literal) {
+ GDScriptParser::DataType array_type = p_array_literal->get_datatype();
+ if (p_array_literal->elements.size() == 0) {
+ // Empty array literal, just make the same type as the storage.
+ array_type.set_container_element_type(p_base_type.get_container_element_type());
+ } else {
+ // Check if elements match.
+ bool all_same_type = true;
+ bool all_have_type = true;
+
+ GDScriptParser::DataType element_type;
+ for (int i = 0; i < p_array_literal->elements.size(); i++) {
+ if (i == 0) {
+ element_type = p_array_literal->elements[0]->get_datatype();
+ } else {
+ GDScriptParser::DataType this_element_type = p_array_literal->elements[i]->get_datatype();
+ if (this_element_type.has_no_type()) {
+ all_same_type = false;
+ all_have_type = false;
+ break;
+ } else if (element_type != this_element_type) {
+ if (!is_type_compatible(element_type, this_element_type, false)) {
+ if (is_type_compatible(this_element_type, element_type, false)) {
+ // This element is a super-type to the previous type, so we use the super-type.
+ element_type = this_element_type;
+ } else {
+ // It's incompatible.
+ all_same_type = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ if (all_same_type) {
+ array_type.set_container_element_type(element_type);
+ } else if (all_have_type) {
+ push_error(vformat(R"(Variant array is not compatible with an array of type "%s".)", p_base_type.get_container_element_type().to_string()), p_array_literal);
+ }
+ }
+ // Update the type on the value itself.
+ p_array_literal->set_datatype(array_type);
+}
+
void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assignment) {
reduce_expression(p_assignment->assignee);
reduce_expression(p_assignment->assigned_value);
@@ -1506,24 +1574,33 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
return;
}
- if (p_assignment->assignee->get_datatype().is_constant) {
+ GDScriptParser::DataType assignee_type = p_assignment->assignee->get_datatype();
+
+ // Check if assigned value is an array literal, so we can make it a typed array too if appropriate.
+ if (assignee_type.has_container_element_type() && p_assignment->assigned_value->type == GDScriptParser::Node::ARRAY) {
+ update_array_literal_element_type(assignee_type, static_cast<GDScriptParser::ArrayNode *>(p_assignment->assigned_value));
+ }
+
+ GDScriptParser::DataType assigned_value_type = p_assignment->assigned_value->get_datatype();
+
+ if (assignee_type.is_constant) {
push_error("Cannot assign a new value to a constant.", p_assignment->assignee);
}
- if (!p_assignment->assignee->get_datatype().is_variant() && !p_assignment->assigned_value->get_datatype().is_variant()) {
+ if (!assignee_type.is_variant() && !assigned_value_type.is_variant()) {
bool compatible = true;
- GDScriptParser::DataType op_type = p_assignment->assigned_value->get_datatype();
+ GDScriptParser::DataType op_type = assigned_value_type;
if (p_assignment->operation != GDScriptParser::AssignmentNode::OP_NONE) {
- op_type = get_operation_type(p_assignment->variant_op, p_assignment->assignee->get_datatype(), p_assignment->assigned_value->get_datatype(), compatible, p_assignment->assigned_value);
+ op_type = get_operation_type(p_assignment->variant_op, assignee_type, assigned_value_type, compatible, p_assignment->assigned_value);
}
if (compatible) {
- compatible = is_type_compatible(p_assignment->assignee->get_datatype(), op_type, true);
+ compatible = is_type_compatible(assignee_type, op_type, true);
if (!compatible) {
- if (p_assignment->assignee->get_datatype().is_hard_type()) {
+ if (assignee_type.is_hard_type()) {
// Try reverse test since it can be a masked subtype.
- if (!is_type_compatible(op_type, p_assignment->assignee->get_datatype(), true)) {
- push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", p_assignment->assigned_value->get_datatype().to_string(), p_assignment->assignee->get_datatype().to_string()), p_assignment->assigned_value);
+ if (!is_type_compatible(op_type, assignee_type, true)) {
+ push_error(vformat(R"(Cannot assign a value of type "%s" to a target of type "%s".)", assigned_value_type.to_string(), assignee_type.to_string()), p_assignment->assigned_value);
} else {
// TODO: Add warning.
mark_node_unsafe(p_assignment);
@@ -1534,11 +1611,11 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
}
}
} else {
- push_error(vformat(R"(Invalid operands "%s" and "%s" for assignment operator.)", p_assignment->assignee->get_datatype().to_string(), p_assignment->assigned_value->get_datatype().to_string()), p_assignment);
+ push_error(vformat(R"(Invalid operands "%s" and "%s" for assignment operator.)", assignee_type.to_string(), assigned_value_type.to_string()), p_assignment);
}
}
- if (p_assignment->assignee->get_datatype().has_no_type() || p_assignment->assigned_value->get_datatype().is_variant()) {
+ if (assignee_type.has_no_type() || assigned_value_type.is_variant()) {
mark_node_unsafe(p_assignment);
}
@@ -1558,7 +1635,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: {
GDScriptParser::DataType id_type = identifier->variable_source->get_datatype();
if (!id_type.is_hard_type()) {
- id_type = p_assignment->assigned_value->get_datatype();
+ id_type = assigned_value_type;
id_type.type_source = GDScriptParser::DataType::INFERRED;
id_type.is_constant = false;
identifier->variable_source->set_datatype(id_type);
@@ -1567,7 +1644,7 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: {
GDScriptParser::DataType id_type = identifier->bind_source->get_datatype();
if (!id_type.is_hard_type()) {
- id_type = p_assignment->assigned_value->get_datatype();
+ id_type = assigned_value_type;
id_type.type_source = GDScriptParser::DataType::INFERRED;
id_type.is_constant = false;
identifier->variable_source->set_datatype(id_type);
@@ -1579,12 +1656,10 @@ void GDScriptAnalyzer::reduce_assignment(GDScriptParser::AssignmentNode *p_assig
}
}
- GDScriptParser::DataType assignee_type = p_assignment->assignee->get_datatype();
- GDScriptParser::DataType assigned_type = p_assignment->assigned_value->get_datatype();
#ifdef DEBUG_ENABLED
- if (p_assignment->assigned_value->type == GDScriptParser::Node::CALL && assigned_type.kind == GDScriptParser::DataType::BUILTIN && assigned_type.builtin_type == Variant::NIL) {
+ if (p_assignment->assigned_value->type == GDScriptParser::Node::CALL && assigned_value_type.kind == GDScriptParser::DataType::BUILTIN && assigned_value_type.builtin_type == Variant::NIL) {
parser->push_warning(p_assignment->assigned_value, GDScriptWarning::VOID_ASSIGNMENT, static_cast<GDScriptParser::CallNode *>(p_assignment->assigned_value)->function_name);
- } else if (assignee_type.is_hard_type() && assignee_type.builtin_type == Variant::INT && assigned_type.builtin_type == Variant::FLOAT) {
+ } else if (assignee_type.is_hard_type() && assignee_type.builtin_type == Variant::INT && assigned_value_type.builtin_type == Variant::FLOAT) {
parser->push_warning(p_assignment->assigned_value, GDScriptWarning::NARROWING_CONVERSION);
}
#endif
@@ -1728,8 +1803,12 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_await) {
bool all_is_constant = true;
+ Map<int, GDScriptParser::ArrayNode *> arrays; // For array literal to potentially type when passing.
for (int i = 0; i < p_call->arguments.size(); i++) {
reduce_expression(p_call->arguments[i]);
+ if (p_call->arguments[i]->type == GDScriptParser::Node::ARRAY) {
+ arrays[i] = static_cast<GDScriptParser::ArrayNode *>(p_call->arguments[i]);
+ }
all_is_constant = all_is_constant && p_call->arguments[i]->is_constant;
}
@@ -2007,6 +2086,13 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
List<GDScriptParser::DataType> par_types;
if (get_function_signature(p_call, base_type, p_call->function_name, return_type, par_types, default_arg_count, is_static, is_vararg)) {
+ // If the function require typed arrays we must make literals be typed.
+ for (Map<int, GDScriptParser::ArrayNode *>::Element *E = arrays.front(); E; E = E->next()) {
+ int index = E->key();
+ if (index < par_types.size() && par_types[index].has_container_element_type()) {
+ update_array_literal_element_type(par_types[index], E->get());
+ }
+ }
validate_call_arg(par_types, default_arg_count, is_vararg, p_call);
if (is_self && parser->current_function != nullptr && parser->current_function->is_static && !is_static) {
@@ -2131,7 +2217,7 @@ void GDScriptAnalyzer::reduce_get_node(GDScriptParser::GetNodeNode *p_get_node)
result.native_type = "Node";
result.builtin_type = Variant::OBJECT;
- if (!ClassDB::is_parent_class(get_real_class_name(parser->current_class->base_type.native_type), result.native_type)) {
+ if (!ClassDB::is_parent_class(GDScriptParser::get_real_class_name(parser->current_class->base_type.native_type), result.native_type)) {
push_error(R"*(Cannot use shorthand "get_node()" notation ("$") on a class that isn't a node.)*", p_get_node);
}
@@ -2297,7 +2383,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
}
// Check native members.
- const StringName &native = get_real_class_name(base.native_type);
+ const StringName &native = GDScriptParser::get_real_class_name(base.native_type);
if (class_exists(native)) {
PropertyInfo prop_info;
@@ -2752,11 +2838,20 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri
case Variant::TRANSFORM:
case Variant::PLANE:
case Variant::COLOR:
- case Variant::ARRAY:
case Variant::DICTIONARY:
result_type.kind = GDScriptParser::DataType::VARIANT;
result_type.type_source = GDScriptParser::DataType::UNDETECTED;
break;
+ // Can have an element type.
+ case Variant::ARRAY:
+ if (base_type.has_container_element_type()) {
+ result_type = base_type.get_container_element_type();
+ result_type.type_source = base_type.type_source;
+ } else {
+ result_type.kind = GDScriptParser::DataType::VARIANT;
+ result_type.type_source = GDScriptParser::DataType::UNDETECTED;
+ }
+ break;
// Here for completeness.
case Variant::OBJECT:
case Variant::VARIANT_MAX:
@@ -2979,6 +3074,34 @@ GDScriptParser::DataType GDScriptAnalyzer::type_from_property(const PropertyInfo
result.native_type = p_property.class_name == StringName() ? "Object" : p_property.class_name;
} else {
result.kind = GDScriptParser::DataType::BUILTIN;
+ result.builtin_type = p_property.type;
+ if (p_property.type == Variant::ARRAY && p_property.hint == PROPERTY_HINT_ARRAY_TYPE) {
+ // Check element type.
+ StringName elem_type_name = p_property.hint_string;
+ GDScriptParser::DataType elem_type;
+ elem_type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
+
+ Variant::Type elem_builtin_type = GDScriptParser::get_builtin_type(elem_type_name);
+ if (elem_builtin_type < Variant::VARIANT_MAX) {
+ // Builtin type.
+ elem_type.kind = GDScriptParser::DataType::BUILTIN;
+ elem_type.builtin_type = elem_builtin_type;
+ } else if (class_exists(elem_type_name)) {
+ elem_type.kind = GDScriptParser::DataType::NATIVE;
+ elem_type.builtin_type = Variant::OBJECT;
+ elem_type.native_type = p_property.hint_string;
+ } else if (ScriptServer::is_global_class(elem_type_name)) {
+ // Just load this as it shouldn't be a GDScript.
+ Ref<Script> script = ResourceLoader::load(ScriptServer::get_global_class_path(elem_type_name));
+ elem_type.kind = GDScriptParser::DataType::SCRIPT;
+ elem_type.builtin_type = Variant::OBJECT;
+ elem_type.native_type = script->get_instance_base_type();
+ elem_type.script_type = script;
+ } else {
+ ERR_FAIL_V_MSG(result, "Could not find element type from property hint of a typed array.");
+ }
+ result.set_container_element_type(elem_type);
+ }
}
return result;
}
@@ -3084,7 +3207,7 @@ bool GDScriptAnalyzer::get_function_signature(GDScriptParser::Node *p_source, GD
return true;
}
- StringName real_native = get_real_class_name(base_native);
+ StringName real_native = GDScriptParser::get_real_class_name(base_native);
MethodInfo info;
if (ClassDB::get_method_info(real_native, function_name, &info)) {
@@ -3179,7 +3302,7 @@ bool GDScriptAnalyzer::is_shadowing(GDScriptParser::IdentifierNode *p_local, con
StringName parent = base_native;
while (parent != StringName()) {
- StringName real_class_name = get_real_class_name(parent);
+ StringName real_class_name = GDScriptParser::get_real_class_name(parent);
if (ClassDB::has_method(real_class_name, name, true)) {
parser->push_warning(p_local, GDScriptWarning::SHADOWED_VARIABLE_BASE_CLASS, p_context, p_local->name, "method", parent);
return true;
@@ -3257,6 +3380,18 @@ bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_targ
// Enum value is also integer.
valid = true;
}
+ if (valid && p_target.builtin_type == Variant::ARRAY && p_source.builtin_type == Variant::ARRAY) {
+ // Check the element type.
+ if (p_target.has_container_element_type()) {
+ if (!p_source.has_container_element_type()) {
+ // TODO: Maybe this is valid but unsafe?
+ // Variant array can't be appended to typed array.
+ valid = false;
+ } else {
+ valid = is_type_compatible(p_target.get_container_element_type(), p_source.get_container_element_type(), false);
+ }
+ }
+ }
return valid;
}
@@ -3329,14 +3464,14 @@ bool GDScriptAnalyzer::is_type_compatible(const GDScriptParser::DataType &p_targ
}
// Get underscore-prefixed version for some classes.
- src_native = get_real_class_name(src_native);
+ src_native = GDScriptParser::get_real_class_name(src_native);
switch (p_target.kind) {
case GDScriptParser::DataType::NATIVE: {
if (p_target.is_meta_type) {
return ClassDB::is_parent_class(src_native, GDScriptNativeClass::get_class_static());
}
- StringName tgt_native = get_real_class_name(p_target.native_type);
+ StringName tgt_native = GDScriptParser::get_real_class_name(p_target.native_type);
return ClassDB::is_parent_class(src_native, tgt_native);
}
case GDScriptParser::DataType::SCRIPT:
@@ -3385,8 +3520,8 @@ void GDScriptAnalyzer::mark_node_unsafe(const GDScriptParser::Node *p_node) {
#endif
}
-bool GDScriptAnalyzer::class_exists(const StringName &p_class) {
- StringName real_name = get_real_class_name(p_class);
+bool GDScriptAnalyzer::class_exists(const StringName &p_class) const {
+ StringName real_name = GDScriptParser::get_real_class_name(p_class);
return ClassDB::class_exists(real_name) && ClassDB::is_class_exposed(real_name);
}
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index dab5b032a3..8430d3f4a5 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -103,10 +103,11 @@ class GDScriptAnalyzer {
bool validate_call_arg(const MethodInfo &p_method, const GDScriptParser::CallNode *p_call);
GDScriptParser::DataType get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, const GDScriptParser::DataType &p_b, bool &r_valid, const GDScriptParser::Node *p_source);
GDScriptParser::DataType get_operation_type(Variant::Operator p_operation, const GDScriptParser::DataType &p_a, bool &r_valid, const GDScriptParser::Node *p_source);
+ void update_array_literal_element_type(const GDScriptParser::DataType &p_base_type, GDScriptParser::ArrayNode *p_array_literal);
bool is_type_compatible(const GDScriptParser::DataType &p_target, const GDScriptParser::DataType &p_source, bool p_allow_implicit_conversion = false) const;
void push_error(const String &p_message, const GDScriptParser::Node *p_origin);
void mark_node_unsafe(const GDScriptParser::Node *p_node);
- bool class_exists(const StringName &p_class);
+ bool class_exists(const StringName &p_class) const;
Ref<GDScriptParserRef> get_parser_for(const String &p_path);
#ifdef DEBUG_ENABLED
bool is_shadowing(GDScriptParser::IdentifierNode *p_local, const String &p_context);
@@ -119,8 +120,6 @@ public:
Error analyze();
GDScriptAnalyzer(GDScriptParser *p_parser);
-
- static void cleanup();
};
#endif // GDSCRIPT_ANALYZER_H
diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp
index 58c6b31a77..b553dcede3 100644
--- a/modules/gdscript/gdscript_byte_codegen.cpp
+++ b/modules/gdscript/gdscript_byte_codegen.cpp
@@ -59,12 +59,7 @@ uint32_t GDScriptByteCodeGenerator::add_local_constant(const StringName &p_name,
}
uint32_t GDScriptByteCodeGenerator::add_or_get_constant(const Variant &p_constant) {
- if (constant_map.has(p_constant)) {
- return constant_map[p_constant];
- }
- int index = constant_map.size();
- constant_map[p_constant] = index;
- return index;
+ return get_constant_pos(p_constant);
}
uint32_t GDScriptByteCodeGenerator::add_or_get_name(const StringName &p_name) {
@@ -100,7 +95,7 @@ void GDScriptByteCodeGenerator::start_parameters() {
}
void GDScriptByteCodeGenerator::end_parameters() {
- function->default_arguments.invert();
+ function->default_arguments.reverse();
}
void GDScriptByteCodeGenerator::write_start(GDScript *p_script, const StringName &p_function_name, bool p_static, MultiplayerAPI::RPCMode p_rpc_mode, const GDScriptDataType &p_return_type) {
@@ -599,14 +594,21 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
// Typed assignment.
switch (p_target.type.kind) {
case GDScriptDataType::BUILTIN: {
- append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
- append(p_target);
- append(p_source);
- append(p_target.type.builtin_type);
+ if (p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
+ append(p_target);
+ append(p_source);
+ } else {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
+ append(p_target);
+ append(p_source);
+ append(p_target.type.builtin_type);
+ }
} break;
case GDScriptDataType::NATIVE: {
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_target.type.native_type];
- class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
+ Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
+ class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_NATIVE, 3);
append(p_target);
append(p_source);
@@ -615,8 +617,7 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
Variant script = p_target.type.script_type;
- int idx = get_constant_pos(script);
- idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
+ int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_SCRIPT, 3);
append(p_target);
@@ -633,7 +634,11 @@ void GDScriptByteCodeGenerator::write_assign(const Address &p_target, const Addr
}
}
} else {
- if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
+ if (p_target.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type == Variant::ARRAY && p_target.type.has_container_element_type()) {
+ append(GDScriptFunction::OPCODE_ASSIGN_TYPED_ARRAY, 2);
+ append(p_target);
+ append(p_source);
+ } else if (p_target.type.kind == GDScriptDataType::BUILTIN && p_source.type.kind == GDScriptDataType::BUILTIN && p_target.type.builtin_type != p_source.type.builtin_type) {
// Need conversion..
append(GDScriptFunction::OPCODE_ASSIGN_TYPED_BUILTIN, 2);
append(p_target);
@@ -663,6 +668,12 @@ void GDScriptByteCodeGenerator::write_assign_default_parameter(const Address &p_
function->default_arguments.push_back(opcodes.size());
}
+void GDScriptByteCodeGenerator::write_store_named_global(const Address &p_dst, const StringName &p_global) {
+ append(GDScriptFunction::OPCODE_STORE_NAMED_GLOBAL, 1);
+ append(p_dst);
+ append(p_global);
+}
+
void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) {
int index = 0;
@@ -673,16 +684,14 @@ void GDScriptByteCodeGenerator::write_cast(const Address &p_target, const Addres
} break;
case GDScriptDataType::NATIVE: {
int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[p_type.native_type];
- class_idx |= (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
+ Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
append(GDScriptFunction::OPCODE_CAST_TO_NATIVE, 3);
- index = class_idx;
+ index = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
} break;
case GDScriptDataType::SCRIPT:
case GDScriptDataType::GDSCRIPT: {
Variant script = p_type.script_type;
- int idx = get_constant_pos(script);
- idx |= (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
-
+ int idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
append(GDScriptFunction::OPCODE_CAST_TO_SCRIPT, 3);
index = idx;
} break;
@@ -893,7 +902,7 @@ void GDScriptByteCodeGenerator::write_call_self(const Address &p_target, const S
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
- append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ append(GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
append(p_target);
append(p_arguments.size());
append(p_function_name);
@@ -904,7 +913,7 @@ void GDScriptByteCodeGenerator::write_call_self_async(const Address &p_target, c
for (int i = 0; i < p_arguments.size(); i++) {
append(p_arguments[i]);
}
- append(GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS);
+ append(GDScriptFunction::ADDR_SELF);
append(p_target);
append(p_arguments.size());
append(p_function_name);
@@ -980,6 +989,25 @@ void GDScriptByteCodeGenerator::write_construct_array(const Address &p_target, c
append(p_arguments.size());
}
+void GDScriptByteCodeGenerator::write_construct_typed_array(const Address &p_target, const GDScriptDataType &p_element_type, const Vector<Address> &p_arguments) {
+ append(GDScriptFunction::OPCODE_CONSTRUCT_TYPED_ARRAY, 2 + p_arguments.size());
+ for (int i = 0; i < p_arguments.size(); i++) {
+ append(p_arguments[i]);
+ }
+ append(p_target);
+ if (p_element_type.script_type) {
+ Variant script_type = Ref<Script>(p_element_type.script_type);
+ int addr = get_constant_pos(script_type);
+ addr |= GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS;
+ append(addr);
+ } else {
+ append(Address()); // null.
+ }
+ append(p_arguments.size());
+ append(p_element_type.builtin_type);
+ append(p_element_type.native_type);
+}
+
void GDScriptByteCodeGenerator::write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) {
append(GDScriptFunction::OPCODE_CONSTRUCT_DICTIONARY, 1 + p_arguments.size());
for (int i = 0; i < p_arguments.size(); i++) {
@@ -1257,8 +1285,84 @@ void GDScriptByteCodeGenerator::write_newline(int p_line) {
}
void GDScriptByteCodeGenerator::write_return(const Address &p_return_value) {
- append(GDScriptFunction::OPCODE_RETURN, 1);
- append(p_return_value);
+ if (!function->return_type.has_type || p_return_value.type.has_type) {
+ // Either the function is untyped or the return value is also typed.
+
+ // If this is a typed function, then we need to check for potential conversions.
+ if (function->return_type.has_type) {
+ if (function->return_type.kind == GDScriptDataType::BUILTIN && function->return_type.builtin_type == Variant::ARRAY && function->return_type.has_container_element_type()) {
+ // Typed array.
+ const GDScriptDataType &element_type = function->return_type.get_container_element_type();
+
+ Variant script = function->return_type.script_type;
+ int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2);
+ append(p_return_value);
+ append(script_idx);
+ append(element_type.kind == GDScriptDataType::BUILTIN ? element_type.builtin_type : Variant::OBJECT);
+ append(element_type.native_type);
+ } else if (function->return_type.kind == GDScriptDataType::BUILTIN && p_return_value.type.kind == GDScriptDataType::BUILTIN && function->return_type.builtin_type != p_return_value.type.builtin_type) {
+ // Add conversion.
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_BUILTIN, 1);
+ append(p_return_value);
+ append(function->return_type.builtin_type);
+ } else {
+ // Just assign.
+ append(GDScriptFunction::OPCODE_RETURN, 1);
+ append(p_return_value);
+ }
+ } else {
+ append(GDScriptFunction::OPCODE_RETURN, 1);
+ append(p_return_value);
+ }
+ } else {
+ switch (function->return_type.kind) {
+ case GDScriptDataType::BUILTIN: {
+ if (function->return_type.builtin_type == Variant::ARRAY && function->return_type.has_container_element_type()) {
+ const GDScriptDataType &element_type = function->return_type.get_container_element_type();
+
+ Variant script = function->return_type.script_type;
+ int script_idx = get_constant_pos(script);
+ script_idx |= (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_ARRAY, 2);
+ append(p_return_value);
+ append(script_idx);
+ append(element_type.kind == GDScriptDataType::BUILTIN ? element_type.builtin_type : Variant::OBJECT);
+ append(element_type.native_type);
+ } else {
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_BUILTIN, 1);
+ append(p_return_value);
+ append(function->return_type.builtin_type);
+ }
+ } break;
+ case GDScriptDataType::NATIVE: {
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_NATIVE, 2);
+ append(p_return_value);
+ int class_idx = GDScriptLanguage::get_singleton()->get_global_map()[function->return_type.native_type];
+ Variant nc = GDScriptLanguage::get_singleton()->get_global_array()[class_idx];
+ class_idx = get_constant_pos(nc) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+ append(class_idx);
+ } break;
+ case GDScriptDataType::GDSCRIPT:
+ case GDScriptDataType::SCRIPT: {
+ Variant script = function->return_type.script_type;
+ int script_idx = get_constant_pos(script) | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
+
+ append(GDScriptFunction::OPCODE_RETURN_TYPED_SCRIPT, 2);
+ append(p_return_value);
+ append(script_idx);
+ } break;
+ default: {
+ ERR_PRINT("Compiler bug: unresolved return.");
+
+ // Shouldn't get here, but fail-safe to a regular return;
+ append(GDScriptFunction::OPCODE_RETURN, 1);
+ append(p_return_value);
+ } break;
+ }
+ }
}
void GDScriptByteCodeGenerator::write_assert(const Address &p_test, const Address &p_message) {
diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h
index 1e66af269a..4b196ed420 100644
--- a/modules/gdscript/gdscript_byte_codegen.h
+++ b/modules/gdscript/gdscript_byte_codegen.h
@@ -51,11 +51,11 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
List<Map<StringName, int>> block_identifier_stack;
Map<StringName, int> block_identifiers;
- int current_stack_size = 0;
+ int current_stack_size = 3; // First 3 spots are reserved for self, class, and nil.
int current_temporaries = 0;
int current_locals = 0;
int current_line = 0;
- int stack_max = 0;
+ int stack_max = 3;
int instr_args_max = 0;
int ptrcall_max = 0;
@@ -135,7 +135,7 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
ERR_PRINT("Leaving block with non-zero temporary variables: " + itos(current_temporaries));
}
#endif
- current_stack_size = current_locals;
+ current_stack_size = current_locals + 3; // Keep the 3 reserved slots for self, class, and nil.
if (debug_stack) {
for (Map<StringName, int>::Element *E = block_identifiers.front(); E; E = E->next()) {
@@ -163,64 +163,72 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
}
int get_constant_pos(const Variant &p_constant) {
- if (constant_map.has(p_constant))
+ if (constant_map.has(p_constant)) {
return constant_map[p_constant];
+ }
int pos = constant_map.size();
constant_map[p_constant] = pos;
return pos;
}
int get_operation_pos(const Variant::ValidatedOperatorEvaluator p_operation) {
- if (operator_func_map.has(p_operation))
+ if (operator_func_map.has(p_operation)) {
return operator_func_map[p_operation];
+ }
int pos = operator_func_map.size();
operator_func_map[p_operation] = pos;
return pos;
}
int get_setter_pos(const Variant::ValidatedSetter p_setter) {
- if (setters_map.has(p_setter))
+ if (setters_map.has(p_setter)) {
return setters_map[p_setter];
+ }
int pos = setters_map.size();
setters_map[p_setter] = pos;
return pos;
}
int get_getter_pos(const Variant::ValidatedGetter p_getter) {
- if (getters_map.has(p_getter))
+ if (getters_map.has(p_getter)) {
return getters_map[p_getter];
+ }
int pos = getters_map.size();
getters_map[p_getter] = pos;
return pos;
}
int get_keyed_setter_pos(const Variant::ValidatedKeyedSetter p_keyed_setter) {
- if (keyed_setters_map.has(p_keyed_setter))
+ if (keyed_setters_map.has(p_keyed_setter)) {
return keyed_setters_map[p_keyed_setter];
+ }
int pos = keyed_setters_map.size();
keyed_setters_map[p_keyed_setter] = pos;
return pos;
}
int get_keyed_getter_pos(const Variant::ValidatedKeyedGetter p_keyed_getter) {
- if (keyed_getters_map.has(p_keyed_getter))
+ if (keyed_getters_map.has(p_keyed_getter)) {
return keyed_getters_map[p_keyed_getter];
+ }
int pos = keyed_getters_map.size();
keyed_getters_map[p_keyed_getter] = pos;
return pos;
}
int get_indexed_setter_pos(const Variant::ValidatedIndexedSetter p_indexed_setter) {
- if (indexed_setters_map.has(p_indexed_setter))
+ if (indexed_setters_map.has(p_indexed_setter)) {
return indexed_setters_map[p_indexed_setter];
+ }
int pos = indexed_setters_map.size();
indexed_setters_map[p_indexed_setter] = pos;
return pos;
}
int get_indexed_getter_pos(const Variant::ValidatedIndexedGetter p_indexed_getter) {
- if (indexed_getters_map.has(p_indexed_getter))
+ if (indexed_getters_map.has(p_indexed_getter)) {
return indexed_getters_map[p_indexed_getter];
+ }
int pos = indexed_getters_map.size();
indexed_getters_map[p_indexed_getter] = pos;
return pos;
@@ -272,8 +280,9 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
}
void alloc_stack(int p_level) {
- if (p_level >= stack_max)
+ if (p_level >= stack_max) {
stack_max = p_level + 1;
+ }
}
int increase_stack() {
@@ -283,33 +292,27 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
}
void alloc_ptrcall(int p_params) {
- if (p_params >= ptrcall_max)
+ if (p_params >= ptrcall_max) {
ptrcall_max = p_params;
+ }
}
int address_of(const Address &p_address) {
switch (p_address.mode) {
case Address::SELF:
- return GDScriptFunction::ADDR_TYPE_SELF << GDScriptFunction::ADDR_BITS;
+ return GDScriptFunction::ADDR_SELF;
case Address::CLASS:
- return GDScriptFunction::ADDR_TYPE_CLASS << GDScriptFunction::ADDR_BITS;
+ return GDScriptFunction::ADDR_CLASS;
case Address::MEMBER:
return p_address.address | (GDScriptFunction::ADDR_TYPE_MEMBER << GDScriptFunction::ADDR_BITS);
- case Address::CLASS_CONSTANT:
- return p_address.address | (GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT << GDScriptFunction::ADDR_BITS);
- case Address::LOCAL_CONSTANT:
case Address::CONSTANT:
- return p_address.address | (GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT << GDScriptFunction::ADDR_BITS);
+ return p_address.address | (GDScriptFunction::ADDR_TYPE_CONSTANT << GDScriptFunction::ADDR_BITS);
case Address::LOCAL_VARIABLE:
case Address::TEMPORARY:
case Address::FUNCTION_PARAMETER:
return p_address.address | (GDScriptFunction::ADDR_TYPE_STACK << GDScriptFunction::ADDR_BITS);
- case Address::GLOBAL:
- return p_address.address | (GDScriptFunction::ADDR_TYPE_GLOBAL << GDScriptFunction::ADDR_BITS);
- case Address::NAMED_GLOBAL:
- return p_address.address | (GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL << GDScriptFunction::ADDR_BITS);
case Address::NIL:
- return GDScriptFunction::ADDR_TYPE_NIL << GDScriptFunction::ADDR_BITS;
+ return GDScriptFunction::ADDR_NIL;
}
return -1; // Unreachable.
}
@@ -431,6 +434,7 @@ public:
virtual void write_assign_true(const Address &p_target) override;
virtual void write_assign_false(const Address &p_target) override;
virtual void write_assign_default_parameter(const Address &p_dst, const Address &p_src) override;
+ virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) override;
virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) override;
virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
@@ -445,6 +449,7 @@ public:
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) override;
virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) override;
+ virtual void write_construct_typed_array(const Address &p_target, const GDScriptDataType &p_element_type, const Vector<Address> &p_arguments) override;
virtual void write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) override;
virtual void write_await(const Address &p_target, const Address &p_operand) override;
virtual void write_if(const Address &p_condition) override;
diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h
index d72bd12033..cce4e856c7 100644
--- a/modules/gdscript/gdscript_codegen.h
+++ b/modules/gdscript/gdscript_codegen.h
@@ -45,13 +45,9 @@ public:
CLASS,
MEMBER,
CONSTANT,
- CLASS_CONSTANT,
- LOCAL_CONSTANT,
LOCAL_VARIABLE,
FUNCTION_PARAMETER,
TEMPORARY,
- GLOBAL,
- NAMED_GLOBAL,
NIL,
};
AddressMode mode = NIL;
@@ -123,6 +119,7 @@ public:
virtual void write_assign_true(const Address &p_target) = 0;
virtual void write_assign_false(const Address &p_target) = 0;
virtual void write_assign_default_parameter(const Address &dst, const Address &src) = 0;
+ virtual void write_store_named_global(const Address &p_dst, const StringName &p_global) = 0;
virtual void write_cast(const Address &p_target, const Address &p_source, const GDScriptDataType &p_type) = 0;
virtual void write_call(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
@@ -137,6 +134,7 @@ public:
virtual void write_call_script_function(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
virtual void write_construct(const Address &p_target, Variant::Type p_type, const Vector<Address> &p_arguments) = 0;
virtual void write_construct_array(const Address &p_target, const Vector<Address> &p_arguments) = 0;
+ virtual void write_construct_typed_array(const Address &p_target, const GDScriptDataType &p_element_type, const Vector<Address> &p_arguments) = 0;
virtual void write_construct_dictionary(const Address &p_target, const Vector<Address> &p_arguments) = 0;
virtual void write_await(const Address &p_target, const Address &p_operand) = 0;
virtual void write_if(const Address &p_condition) = 0;
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 63ca34fc24..abbca899bd 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -137,22 +137,22 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
}
}
} break;
+ case GDScriptParser::DataType::ENUM:
case GDScriptParser::DataType::ENUM_VALUE:
result.has_type = true;
result.kind = GDScriptDataType::BUILTIN;
result.builtin_type = Variant::INT;
break;
- case GDScriptParser::DataType::ENUM:
- result.has_type = true;
- result.kind = GDScriptDataType::BUILTIN;
- result.builtin_type = Variant::DICTIONARY;
- break;
case GDScriptParser::DataType::UNRESOLVED: {
ERR_PRINT("Parser bug: converting unresolved type.");
return GDScriptDataType();
}
}
+ if (p_datatype.has_container_element_type()) {
+ result.set_container_element_type(_gdtype_from_datatype(p_datatype.get_container_element_type()));
+ }
+
// Only hold strong reference to the script if it's not the owner of the
// element qualified with this type, to avoid cyclic references (leaks).
if (result.script_type && result.script_type == p_owner) {
@@ -262,7 +262,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
GDScriptNativeClass *nc = nullptr;
while (scr) {
if (scr->constants.has(identifier)) {
- return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CLASS_CONSTANT, gen->add_or_get_name(identifier)); // TODO: Get type here.
+ return codegen.add_constant(scr->constants[identifier]); // TODO: Get type here.
}
if (scr->native.is_valid()) {
nc = scr->native.ptr();
@@ -319,7 +319,8 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (GDScriptLanguage::get_singleton()->get_global_map().has(identifier)) {
int idx = GDScriptLanguage::get_singleton()->get_global_map()[identifier];
- return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::GLOBAL, idx); // TODO: Get type.
+ Variant global = GDScriptLanguage::get_singleton()->get_global_array()[idx];
+ return codegen.add_constant(global); // TODO: Get type.
}
// Try global classes.
@@ -347,7 +348,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
#ifdef TOOLS_ENABLED
if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(identifier)) {
- return GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NAMED_GLOBAL, gen->add_or_get_name(identifier)); // TODO: Get type.
+ GDScriptCodeGenerator::Address global = codegen.add_temporary(); // TODO: Get type.
+ gen->write_store_named_global(global, identifier);
+ return global;
}
#endif
@@ -376,10 +379,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
Vector<GDScriptCodeGenerator::Address> values;
// Create the result temporary first since it's the last to be killed.
- GDScriptDataType array_type;
- array_type.has_type = true;
- array_type.kind = GDScriptDataType::BUILTIN;
- array_type.builtin_type = Variant::ARRAY;
+ GDScriptDataType array_type = _gdtype_from_datatype(an->get_datatype());
GDScriptCodeGenerator::Address result = codegen.add_temporary(array_type);
for (int i = 0; i < an->elements.size(); i++) {
@@ -390,7 +390,11 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
values.push_back(val);
}
- gen->write_construct_array(result, values);
+ if (array_type.has_container_element_type()) {
+ gen->write_construct_typed_array(result, array_type.get_container_element_type(), values);
+ } else {
+ gen->write_construct_array(result, values);
+ }
for (int i = 0; i < values.size(); i++) {
if (values[i].mode == GDScriptCodeGenerator::Address::TEMPORARY) {
@@ -777,6 +781,10 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
gen->pop_temporary();
}
}
+
+ if (operand.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
+ gen->pop_temporary();
+ }
} break;
default: {
GDScriptCodeGenerator::Address left_operand = _parse_expression(codegen, r_error, binary->left_operand);
@@ -1733,8 +1741,17 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
const GDScriptParser::VariableNode *lv = static_cast<const GDScriptParser::VariableNode *>(s);
// Should be already in stack when the block began.
GDScriptCodeGenerator::Address local = codegen.locals[lv->identifier->name];
+ GDScriptParser::DataType local_type = lv->get_datatype();
if (lv->initializer != nullptr) {
+ // For typed arrays we need to make sure this is already initialized correctly so typed assignment work.
+ if (local_type.is_hard_type() && local_type.builtin_type == Variant::ARRAY) {
+ if (local_type.has_container_element_type()) {
+ codegen.generator->write_construct_typed_array(local, _gdtype_from_datatype(local_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>());
+ } else {
+ codegen.generator->write_construct_array(local, Vector<GDScriptCodeGenerator::Address>());
+ }
+ }
GDScriptCodeGenerator::Address src_address = _parse_expression(codegen, error, lv->initializer);
if (error) {
return error;
@@ -1743,6 +1760,14 @@ Error GDScriptCompiler::_parse_block(CodeGen &codegen, const GDScriptParser::Sui
if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
+ } else if (lv->get_datatype().is_hard_type()) {
+ // Initialize with default for type.
+ if (local_type.has_container_element_type()) {
+ codegen.generator->write_construct_typed_array(local, _gdtype_from_datatype(local_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>());
+ } else if (local_type.kind == GDScriptParser::DataType::BUILTIN) {
+ codegen.generator->write_construct(local, local_type.builtin_type, Vector<GDScriptCodeGenerator::Address>());
+ }
+ // The `else` branch is for objects, in such case we leave it as `null`.
}
} break;
case GDScriptParser::Node::CONSTANT: {
@@ -1844,21 +1869,41 @@ Error GDScriptCompiler::_parse_function(GDScript *p_script, const GDScriptParser
continue;
}
+ GDScriptParser::DataType field_type = field->get_datatype();
+
+ GDScriptCodeGenerator::Address dst_address(GDScriptCodeGenerator::Address::MEMBER, codegen.script->member_indices[field->identifier->name].index, _gdtype_from_datatype(field->get_datatype()));
if (field->initializer) {
// Emit proper line change.
codegen.generator->write_newline(field->initializer->start_line);
+ // For typed arrays we need to make sure this is already initialized correctly so typed assignment work.
+ if (field_type.is_hard_type() && field_type.builtin_type == Variant::ARRAY && field_type.has_container_element_type()) {
+ if (field_type.has_container_element_type()) {
+ codegen.generator->write_construct_typed_array(dst_address, _gdtype_from_datatype(field_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>());
+ } else {
+ codegen.generator->write_construct_array(dst_address, Vector<GDScriptCodeGenerator::Address>());
+ }
+ }
GDScriptCodeGenerator::Address src_address = _parse_expression(codegen, error, field->initializer, false, true);
if (error) {
memdelete(codegen.generator);
return error;
}
- GDScriptCodeGenerator::Address dst_address(GDScriptCodeGenerator::Address::MEMBER, codegen.script->member_indices[field->identifier->name].index, _gdtype_from_datatype(field->get_datatype()));
codegen.generator->write_assign(dst_address, src_address);
if (src_address.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
codegen.generator->pop_temporary();
}
+ } else if (field->get_datatype().is_hard_type()) {
+ codegen.generator->write_newline(field->start_line);
+
+ // Initialize with default for type.
+ if (field_type.has_container_element_type()) {
+ codegen.generator->write_construct_typed_array(dst_address, _gdtype_from_datatype(field_type.get_container_element_type(), codegen.script), Vector<GDScriptCodeGenerator::Address>());
+ } else if (field_type.kind == GDScriptParser::DataType::BUILTIN) {
+ codegen.generator->write_construct(dst_address, field_type.builtin_type, Vector<GDScriptCodeGenerator::Address>());
+ }
+ // The `else` branch is for objects, in such case we leave it as `null`.
}
}
}
@@ -1972,6 +2017,8 @@ Error GDScriptCompiler::_parse_setter_getter(GDScript *p_script, const GDScriptP
func_name = "@" + p_variable->identifier->name + "_getter";
}
+ codegen.function_name = func_name;
+
GDScriptDataType return_type;
if (p_is_setter) {
return_type.has_type = true;
@@ -2176,9 +2223,8 @@ Error GDScriptCompiler::_parse_class_level(GDScript *p_script, const GDScriptPar
prop_info.hint = export_info.hint;
prop_info.hint_string = export_info.hint_string;
prop_info.usage = export_info.usage;
- } else {
- prop_info.usage = PROPERTY_USAGE_SCRIPT_VARIABLE;
}
+ prop_info.usage |= PROPERTY_USAGE_SCRIPT_VARIABLE;
#ifdef TOOLS_ENABLED
p_script->doc_variables[name] = variable->doc_description;
#endif
diff --git a/modules/gdscript/gdscript_compiler.h b/modules/gdscript/gdscript_compiler.h
index 651391f972..1b0beec0d4 100644
--- a/modules/gdscript/gdscript_compiler.h
+++ b/modules/gdscript/gdscript_compiler.h
@@ -61,7 +61,7 @@ class GDScriptCompiler {
GDScriptCodeGenerator::Address add_local_constant(const StringName &p_name, const Variant &p_value) {
uint32_t addr = generator->add_local_constant(p_name, p_value);
- locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::LOCAL_CONSTANT, addr);
+ locals[p_name] = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::CONSTANT, addr);
return locals[p_name];
}
diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp
index 17cb5e3c96..74da0ee232 100644
--- a/modules/gdscript/gdscript_disassembler.cpp
+++ b/modules/gdscript/gdscript_disassembler.cpp
@@ -69,35 +69,23 @@ static String _disassemble_address(const GDScript *p_script, const GDScriptFunct
int addr = p_address & GDScriptFunction::ADDR_MASK;
switch (p_address >> GDScriptFunction::ADDR_BITS) {
- case GDScriptFunction::ADDR_TYPE_SELF: {
- return "self";
- } break;
- case GDScriptFunction::ADDR_TYPE_CLASS: {
- return "class";
- } break;
case GDScriptFunction::ADDR_TYPE_MEMBER: {
return "member(" + p_script->debug_get_member_by_index(addr) + ")";
} break;
- case GDScriptFunction::ADDR_TYPE_CLASS_CONSTANT: {
- return "class_const(" + p_function.get_global_name(addr) + ")";
- } break;
- case GDScriptFunction::ADDR_TYPE_LOCAL_CONSTANT: {
+ case GDScriptFunction::ADDR_TYPE_CONSTANT: {
return "const(" + _get_variant_string(p_function.get_constant(addr)) + ")";
} break;
case GDScriptFunction::ADDR_TYPE_STACK: {
- return "stack(" + itos(addr) + ")";
- } break;
- case GDScriptFunction::ADDR_TYPE_STACK_VARIABLE: {
- return "var_stack(" + itos(addr) + ")";
- } break;
- case GDScriptFunction::ADDR_TYPE_GLOBAL: {
- return "global(" + _get_variant_string(GDScriptLanguage::get_singleton()->get_global_array()[addr]) + ")";
- } break;
- case GDScriptFunction::ADDR_TYPE_NAMED_GLOBAL: {
- return "named_global(" + p_function.get_global_name(addr) + ")";
- } break;
- case GDScriptFunction::ADDR_TYPE_NIL: {
- return "nil";
+ switch (addr) {
+ case GDScriptFunction::ADDR_STACK_SELF:
+ return "self";
+ case GDScriptFunction::ADDR_STACK_CLASS:
+ return "class";
+ case GDScriptFunction::ADDR_STACK_NIL:
+ return "nil";
+ default:
+ return "stack(" + itos(addr) + ")";
+ }
} break;
}
@@ -322,6 +310,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
incr += 4;
} break;
+ case OPCODE_ASSIGN_TYPED_ARRAY: {
+ text += "assign typed array ";
+ text += DADDR(1);
+ text += " = ";
+ text += DADDR(2);
+
+ incr += 3;
+ } break;
case OPCODE_ASSIGN_TYPED_NATIVE: {
text += "assign typed native (";
text += DADDR(3);
@@ -385,8 +381,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += Variant::get_type_name(t) + "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(i + 1);
}
text += ")";
@@ -402,8 +399,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "<unkown type>(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(i + 1);
}
text += ")";
@@ -417,8 +415,43 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += " = [";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
+ text += ", ";
+ }
+ text += DADDR(1 + i);
+ }
+
+ text += "]";
+
+ incr += 3 + argc;
+ } break;
+ case OPCODE_CONSTRUCT_TYPED_ARRAY: {
+ int argc = _code_ptr[ip + 1 + instr_var_args];
+
+ Ref<Script> script_type = get_constant(_code_ptr[ip + argc + 2]);
+ Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + argc + 4];
+ StringName native_type = get_global_name(_code_ptr[ip + argc + 5]);
+
+ String type_name;
+ if (script_type.is_valid() && script_type->is_valid()) {
+ type_name = script_type->get_path();
+ } else if (native_type != StringName()) {
+ type_name = native_type;
+ } else {
+ type_name = Variant::get_type_name(builtin_type);
+ }
+
+ text += " make_typed_array (";
+ text += type_name;
+ text += ") ";
+
+ text += DADDR(1 + argc);
+ text += " = [";
+
+ for (int i = 0; i < argc; i++) {
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
@@ -433,8 +466,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += " = {";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i * 2 + 0);
text += ": ";
text += DADDR(1 + i * 2 + 1);
@@ -468,8 +502,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -498,8 +533,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -518,8 +554,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -595,8 +632,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -613,8 +651,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -631,8 +670,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -649,8 +689,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -667,8 +708,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
text += "(";
for (int i = 0; i < argc; i++) {
- if (i > 0)
+ if (i > 0) {
text += ", ";
+ }
text += DADDR(1 + i);
}
text += ")";
@@ -720,6 +762,39 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
incr = 2;
} break;
+ case OPCODE_RETURN_TYPED_BUILTIN: {
+ text += "return typed builtin (";
+ text += Variant::get_type_name((Variant::Type)_code_ptr[ip + 2]);
+ text += ") ";
+ text += DADDR(1);
+
+ incr += 3;
+ } break;
+ case OPCODE_RETURN_TYPED_ARRAY: {
+ text += "return typed array ";
+ text += DADDR(1);
+
+ incr += 5;
+ } break;
+ case OPCODE_RETURN_TYPED_NATIVE: {
+ text += "return typed native (";
+ text += DADDR(2);
+ text += ") ";
+ text += DADDR(1);
+
+ incr += 3;
+ } break;
+ case OPCODE_RETURN_TYPED_SCRIPT: {
+ Variant script = _constants_ptr[_code_ptr[ip + 2]];
+ Script *sc = Object::cast_to<Script>(script.operator Object *());
+
+ text += "return typed script (";
+ text += sc->get_path();
+ text += ") ";
+ text += DADDR(1);
+
+ incr += 3;
+ } break;
#define DISASSEMBLE_ITERATE(m_type) \
case OPCODE_ITERATE_##m_type: { \
@@ -798,6 +873,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
incr += 5;
} break;
DISASSEMBLE_ITERATE_TYPES(DISASSEMBLE_ITERATE);
+ case OPCODE_STORE_NAMED_GLOBAL: {
+ text += "store named global ";
+ text += DADDR(1);
+ text += " = ";
+ text += String(_global_names_ptr[_code_ptr[ip + 2]]);
+
+ incr += 3;
+ } break;
case OPCODE_LINE: {
int line = _code_ptr[ip + 1] - 1;
if (line >= 0 && line < p_code_lines.size()) {
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index a9975c8602..ae3b16a9d7 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -500,36 +500,6 @@ struct GDScriptCompletionIdentifier {
const GDScriptParser::ExpressionNode *assigned_expression = nullptr;
};
-// TODO: Move this to a central location (maybe core?).
-static const char *underscore_classes[] = {
- "ClassDB",
- "Directory",
- "Engine",
- "File",
- "Geometry",
- "GodotSharp",
- "JSON",
- "Marshalls",
- "Mutex",
- "OS",
- "ResourceLoader",
- "ResourceSaver",
- "Semaphore",
- "Thread",
- "VisualScriptEditor",
- nullptr,
-};
-static StringName _get_real_class_name(const StringName &p_source) {
- const char **class_name = underscore_classes;
- while (*class_name != nullptr) {
- if (p_source == *class_name) {
- return String("_") + p_source;
- }
- class_name++;
- }
- return p_source;
-}
-
static String _get_visual_datatype(const PropertyInfo &p_info, bool p_is_arg = true) {
if (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
String enum_name = p_info.class_name;
@@ -930,7 +900,7 @@ static void _find_identifiers_in_base(const GDScriptCompletionIdentifier &p_base
}
} break;
case GDScriptParser::DataType::NATIVE: {
- StringName type = _get_real_class_name(base_type.native_type);
+ StringName type = GDScriptParser::get_real_class_name(base_type.native_type);
if (!ClassDB::class_exists(type)) {
return;
}
@@ -1067,7 +1037,7 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool
static const char *_keywords[] = {
"false", "PI", "TAU", "INF", "NAN", "self", "true", "breakpoint", "tool", "super",
"break", "continue", "pass", "return",
- 0
+ nullptr
};
const char **kw = _keywords;
@@ -1080,7 +1050,7 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool
static const char *_keywords_with_space[] = {
"and", "in", "not", "or", "as", "class", "extends", "is", "func", "signal", "await",
"const", "enum", "static", "var", "if", "elif", "else", "for", "match", "while",
- 0
+ nullptr
};
const char **kws = _keywords_with_space;
@@ -1093,7 +1063,7 @@ static void _find_identifiers(GDScriptParser::CompletionContext &p_context, bool
static const char *_keywords_with_args[] = {
"assert", "preload",
- 0
+ nullptr
};
const char **kwa = _keywords_with_args;
@@ -1775,15 +1745,15 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
return true;
}
}
- base_type = base_type.class_type->base_type;
}
+ base_type = base_type.class_type->base_type;
break;
case GDScriptParser::DataType::NATIVE: {
if (id_type.is_set() && !id_type.is_variant()) {
base_type = GDScriptParser::DataType();
break;
}
- StringName real_native = _get_real_class_name(base_type.native_type);
+ StringName real_native = GDScriptParser::get_real_class_name(base_type.native_type);
MethodInfo info;
if (ClassDB::get_method_info(real_native, p_context.current_function->identifier->name, &info)) {
for (const List<PropertyInfo>::Element *E = info.arguments.front(); E; E = E->next()) {
@@ -1854,7 +1824,7 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
}
// Check ClassDB.
- StringName class_name = _get_real_class_name(p_identifier);
+ StringName class_name = GDScriptParser::get_real_class_name(p_identifier);
if (ClassDB::class_exists(class_name) && ClassDB::is_class_exposed(class_name)) {
r_type.type.type_source = GDScriptParser::DataType::ANNOTATED_EXPLICIT;
r_type.type.kind = GDScriptParser::DataType::NATIVE;
@@ -1970,7 +1940,7 @@ static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &
}
} break;
case GDScriptParser::DataType::NATIVE: {
- StringName class_name = _get_real_class_name(base_type.native_type);
+ StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type);
if (!ClassDB::class_exists(class_name)) {
return false;
}
@@ -2133,7 +2103,7 @@ static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContex
}
} break;
case GDScriptParser::DataType::NATIVE: {
- StringName native = _get_real_class_name(base_type.native_type);
+ StringName native = GDScriptParser::get_real_class_name(base_type.native_type);
if (!ClassDB::class_exists(native)) {
return false;
}
@@ -2230,7 +2200,7 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c
base_type = base_type.class_type->base_type;
} break;
case GDScriptParser::DataType::NATIVE: {
- StringName class_name = _get_real_class_name(base_type.native_type);
+ StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type);
if (!ClassDB::class_exists(class_name)) {
base_type.kind = GDScriptParser::DataType::UNRESOLVED;
break;
@@ -2615,7 +2585,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path
break;
}
- StringName class_name = _get_real_class_name(native_type.native_type);
+ StringName class_name = GDScriptParser::get_real_class_name(native_type.native_type);
if (!ClassDB::class_exists(class_name)) {
break;
}
@@ -2844,7 +2814,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
}
} break;
case GDScriptParser::DataType::NATIVE: {
- StringName class_name = _get_real_class_name(base_type.native_type);
+ StringName class_name = GDScriptParser::get_real_class_name(base_type.native_type);
if (!ClassDB::class_exists(class_name)) {
base_type.kind = GDScriptParser::DataType::UNRESOLVED;
break;
@@ -2922,7 +2892,7 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co
v = v_ref;
} else {
Callable::CallError err;
- Variant::construct(base_type.builtin_type, v, NULL, 0, err);
+ Variant::construct(base_type.builtin_type, v, nullptr, 0, err);
if (err.error != Callable::CallError::CALL_OK) {
break;
}
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index e64630a743..414dfab2e7 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -43,7 +43,11 @@
class GDScriptInstance;
class GDScript;
-struct GDScriptDataType {
+class GDScriptDataType {
+private:
+ GDScriptDataType *container_element_type = nullptr;
+
+public:
enum Kind {
UNINITIALIZED,
BUILTIN,
@@ -71,7 +75,24 @@ struct GDScriptDataType {
case BUILTIN: {
Variant::Type var_type = p_variant.get_type();
bool valid = builtin_type == var_type;
- if (!valid && p_allow_implicit_conversion) {
+ if (valid && builtin_type == Variant::ARRAY && has_container_element_type()) {
+ Array array = p_variant;
+ if (array.is_typed()) {
+ Variant::Type array_builtin_type = (Variant::Type)array.get_typed_builtin();
+ StringName array_native_type = array.get_typed_class_name();
+ Ref<Script> array_script_type_ref = array.get_typed_script();
+
+ if (array_script_type_ref.is_valid()) {
+ valid = (container_element_type->kind == SCRIPT || container_element_type->kind == GDSCRIPT) && container_element_type->script_type == array_script_type_ref.ptr();
+ } else if (array_native_type != StringName()) {
+ valid = container_element_type->kind == NATIVE && container_element_type->native_type == array_native_type;
+ } else {
+ valid = container_element_type->kind == BUILTIN && container_element_type->builtin_type == array_builtin_type;
+ }
+ } else {
+ valid = false;
+ }
+ } else if (!valid && p_allow_implicit_conversion) {
valid = Variant::can_convert_strict(var_type, builtin_type);
}
return valid;
@@ -153,7 +174,49 @@ struct GDScriptDataType {
return info;
}
- GDScriptDataType() {}
+ void set_container_element_type(const GDScriptDataType &p_element_type) {
+ container_element_type = memnew(GDScriptDataType(p_element_type));
+ }
+
+ GDScriptDataType get_container_element_type() const {
+ ERR_FAIL_COND_V(container_element_type == nullptr, GDScriptDataType());
+ return *container_element_type;
+ }
+
+ bool has_container_element_type() const {
+ return container_element_type != nullptr;
+ }
+
+ void unset_container_element_type() {
+ if (container_element_type) {
+ memdelete(container_element_type);
+ }
+ container_element_type = nullptr;
+ }
+
+ GDScriptDataType() = default;
+
+ GDScriptDataType &operator=(const GDScriptDataType &p_other) {
+ kind = p_other.kind;
+ has_type = p_other.has_type;
+ builtin_type = p_other.builtin_type;
+ native_type = p_other.native_type;
+ script_type = p_other.script_type;
+ script_type_ref = p_other.script_type_ref;
+ unset_container_element_type();
+ if (p_other.has_container_element_type()) {
+ set_container_element_type(p_other.get_container_element_type());
+ }
+ return *this;
+ }
+
+ GDScriptDataType(const GDScriptDataType &p_other) {
+ *this = p_other;
+ }
+
+ ~GDScriptDataType() {
+ unset_container_element_type();
+ }
};
class GDScriptFunction {
@@ -179,6 +242,7 @@ public:
OPCODE_ASSIGN_TRUE,
OPCODE_ASSIGN_FALSE,
OPCODE_ASSIGN_TYPED_BUILTIN,
+ OPCODE_ASSIGN_TYPED_ARRAY,
OPCODE_ASSIGN_TYPED_NATIVE,
OPCODE_ASSIGN_TYPED_SCRIPT,
OPCODE_CAST_TO_BUILTIN,
@@ -187,6 +251,7 @@ public:
OPCODE_CONSTRUCT, // Only for basic types!
OPCODE_CONSTRUCT_VALIDATED, // Only for basic types!
OPCODE_CONSTRUCT_ARRAY,
+ OPCODE_CONSTRUCT_TYPED_ARRAY,
OPCODE_CONSTRUCT_DICTIONARY,
OPCODE_CALL,
OPCODE_CALL_RETURN,
@@ -241,6 +306,10 @@ public:
OPCODE_JUMP_IF_NOT,
OPCODE_JUMP_TO_DEF_ARGUMENT,
OPCODE_RETURN,
+ OPCODE_RETURN_TYPED_BUILTIN,
+ OPCODE_RETURN_TYPED_ARRAY,
+ OPCODE_RETURN_TYPED_NATIVE,
+ OPCODE_RETURN_TYPED_SCRIPT,
OPCODE_ITERATE_BEGIN,
OPCODE_ITERATE_BEGIN_INT,
OPCODE_ITERATE_BEGIN_FLOAT,
@@ -281,6 +350,7 @@ public:
OPCODE_ITERATE_PACKED_VECTOR3_ARRAY,
OPCODE_ITERATE_PACKED_COLOR_ARRAY,
OPCODE_ITERATE_OBJECT,
+ OPCODE_STORE_NAMED_GLOBAL,
OPCODE_ASSERT,
OPCODE_BREAKPOINT,
OPCODE_LINE,
@@ -291,16 +361,18 @@ public:
ADDR_BITS = 24,
ADDR_MASK = ((1 << ADDR_BITS) - 1),
ADDR_TYPE_MASK = ~ADDR_MASK,
- ADDR_TYPE_SELF = 0,
- ADDR_TYPE_CLASS = 1,
+ ADDR_TYPE_STACK = 0,
+ ADDR_TYPE_CONSTANT = 1,
ADDR_TYPE_MEMBER = 2,
- ADDR_TYPE_CLASS_CONSTANT = 3,
- ADDR_TYPE_LOCAL_CONSTANT = 4,
- ADDR_TYPE_STACK = 5,
- ADDR_TYPE_STACK_VARIABLE = 6,
- ADDR_TYPE_GLOBAL = 7,
- ADDR_TYPE_NAMED_GLOBAL = 8,
- ADDR_TYPE_NIL = 9
+ };
+
+ enum FixedAddresses {
+ ADDR_STACK_SELF = 0,
+ ADDR_STACK_CLASS = 1,
+ ADDR_STACK_NIL = 2,
+ ADDR_SELF = ADDR_STACK_SELF | (ADDR_TYPE_STACK << ADDR_BITS),
+ ADDR_CLASS = ADDR_STACK_CLASS | (ADDR_TYPE_STACK << ADDR_BITS),
+ ADDR_NIL = ADDR_STACK_NIL | (ADDR_TYPE_STACK << ADDR_BITS),
};
enum Instruction {
@@ -393,7 +465,7 @@ private:
List<StackDebug> stack_debug;
- _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const;
+ _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const;
_FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const;
friend class GDScriptLanguage;
@@ -428,7 +500,6 @@ public:
#endif
Vector<uint8_t> stack;
int stack_size = 0;
- Variant self;
uint32_t alloca_size = 0;
int ip = 0;
int line = 0;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 7f3dd6b2e5..695154e9a9 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -94,8 +94,43 @@ Variant::Type GDScriptParser::get_builtin_type(const StringName &p_type) {
return Variant::VARIANT_MAX;
}
+// TODO: Move this to a central location (maybe core?).
+static HashMap<StringName, StringName> underscore_map;
+static const char *underscore_classes[] = {
+ "ClassDB",
+ "Directory",
+ "Engine",
+ "File",
+ "Geometry",
+ "GodotSharp",
+ "JSON",
+ "Marshalls",
+ "Mutex",
+ "OS",
+ "ResourceLoader",
+ "ResourceSaver",
+ "Semaphore",
+ "Thread",
+ "VisualScriptEditor",
+ nullptr,
+};
+StringName GDScriptParser::get_real_class_name(const StringName &p_source) {
+ if (underscore_map.is_empty()) {
+ const char **class_name = underscore_classes;
+ while (*class_name != nullptr) {
+ underscore_map[*class_name] = String("_") + *class_name;
+ class_name++;
+ }
+ }
+ if (underscore_map.has(p_source)) {
+ return underscore_map[p_source];
+ }
+ return p_source;
+}
+
void GDScriptParser::cleanup() {
builtin_types.clear();
+ underscore_map.clear();
}
void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const {
@@ -109,12 +144,11 @@ void GDScriptParser::get_annotation_list(List<MethodInfo> *r_annotations) const
GDScriptParser::GDScriptParser() {
// Register valid annotations.
// TODO: Should this be static?
- // TODO: Validate applicable types (e.g. a VARIABLE annotation that only applies to string variables).
register_annotation(MethodInfo("@tool"), AnnotationInfo::SCRIPT, &GDScriptParser::tool_annotation);
register_annotation(MethodInfo("@icon", { Variant::STRING, "icon_path" }), AnnotationInfo::SCRIPT, &GDScriptParser::icon_annotation);
register_annotation(MethodInfo("@onready"), AnnotationInfo::VARIABLE, &GDScriptParser::onready_annotation);
// Export annotations.
- register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_TYPE_STRING, Variant::NIL>);
+ register_annotation(MethodInfo("@export"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_NONE, Variant::NIL>);
register_annotation(MethodInfo("@export_enum", { Variant::STRING, "names" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_ENUM, Variant::INT>, 0, true);
register_annotation(MethodInfo("@export_file", { Variant::STRING, "filter" }), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_FILE, Variant::STRING>, 1, true);
register_annotation(MethodInfo("@export_dir"), AnnotationInfo::VARIABLE, &GDScriptParser::export_annotations<PROPERTY_HINT_DIR, Variant::STRING>);
@@ -680,7 +714,6 @@ void GDScriptParser::parse_class_member(T *(GDScriptParser::*p_parse_function)()
while (!annotation_stack.is_empty()) {
AnnotationNode *last_annotation = annotation_stack.back()->get();
if (last_annotation->applies_to(p_target)) {
- last_annotation->apply(this, member);
member->annotations.push_front(last_annotation);
annotation_stack.pop_back();
} else {
@@ -811,6 +844,9 @@ GDScriptParser::VariableNode *GDScriptParser::parse_variable(bool p_allow_proper
if (match(GDScriptTokenizer::Token::EQUAL)) {
// Initializer.
variable->initializer = parse_expression(false);
+ if (variable->initializer == nullptr) {
+ push_error(R"(Expected expression for variable initial value after "=".)");
+ }
variable->assignments++;
}
@@ -2674,6 +2710,19 @@ GDScriptParser::TypeNode *GDScriptParser::parse_type(bool p_allow_void) {
type->type_chain.push_back(type_element);
+ if (match(GDScriptTokenizer::Token::BRACKET_OPEN)) {
+ // Typed collection (like Array[int]).
+ type->container_type = parse_type(false); // Don't allow void for array element type.
+ if (type->container_type == nullptr) {
+ push_error(R"(Expected type for collection after "[".)");
+ type = nullptr;
+ } else if (type->container_type->container_type != nullptr) {
+ push_error("Nested typed collections are not supported.");
+ }
+ consume(GDScriptTokenizer::Token::BRACKET_CLOSE, R"(Expected closing "]" after collection type.)");
+ return type;
+ }
+
int chain_index = 1;
while (match(GDScriptTokenizer::Token::PERIOD)) {
make_completion_context(COMPLETION_TYPE_ATTRIBUTE, type, chain_index++);
@@ -3160,29 +3209,10 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
}
variable->exported = true;
- // TODO: Improving setting type, especially for range hints, which can be int or float.
+
variable->export_info.type = t_type;
variable->export_info.hint = t_hint;
- if (p_annotation->name == "@export") {
- if (variable->datatype_specifier == nullptr) {
- if (variable->initializer == nullptr) {
- push_error(R"(Cannot use "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation);
- return false;
- }
- if (variable->initializer->type == Node::LITERAL) {
- variable->export_info.type = static_cast<LiteralNode *>(variable->initializer)->value.get_type();
- } else if (variable->initializer->type == Node::ARRAY) {
- variable->export_info.type = Variant::ARRAY;
- } else if (variable->initializer->type == Node::DICTIONARY) {
- variable->export_info.type = Variant::DICTIONARY;
- } else {
- push_error(R"(To use "@export" annotation with type-less variable, the default value must be a literal.)", p_annotation);
- return false;
- }
- } // else: Actual type will be set by the analyzer, which can infer the proper type.
- }
-
String hint_string;
for (int i = 0; i < p_annotation->resolved_arguments.size(); i++) {
if (i > 0) {
@@ -3193,6 +3223,86 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node
variable->export_info.hint_string = hint_string;
+ // This is called after tne analyzer is done finding the type, so this should be set here.
+ DataType export_type = variable->get_datatype();
+
+ if (p_annotation->name == "@export") {
+ if (variable->datatype_specifier == nullptr && variable->initializer == nullptr) {
+ push_error(R"(Cannot use simple "@export" annotation with variable without type or initializer, since type can't be inferred.)", p_annotation);
+ return false;
+ }
+
+ bool is_array = false;
+
+ if (export_type.builtin_type == Variant::ARRAY && export_type.has_container_element_type()) {
+ export_type = export_type.get_container_element_type(); // Use inner type for.
+ is_array = true;
+ }
+
+ if (export_type.is_variant() || export_type.has_no_type()) {
+ push_error(R"(Cannot use simple "@export" annotation because the type of the initialized value can't be inferred.)", p_annotation);
+ return false;
+ }
+
+ switch (export_type.kind) {
+ case GDScriptParser::DataType::BUILTIN:
+ variable->export_info.type = export_type.builtin_type;
+ variable->export_info.hint = PROPERTY_HINT_NONE;
+ variable->export_info.hint_string = Variant::get_type_name(export_type.builtin_type);
+ break;
+ case GDScriptParser::DataType::NATIVE:
+ if (ClassDB::is_parent_class(get_real_class_name(export_type.native_type), "Resource")) {
+ variable->export_info.type = Variant::OBJECT;
+ variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE;
+ variable->export_info.hint_string = get_real_class_name(export_type.native_type);
+ } else {
+ push_error(R"(Export type can only be built-in, a resource, or an enum.)", variable);
+ return false;
+ }
+ break;
+ case GDScriptParser::DataType::ENUM: {
+ variable->export_info.type = Variant::INT;
+ variable->export_info.hint = PROPERTY_HINT_ENUM;
+
+ String enum_hint_string;
+ for (const Map<StringName, int>::Element *E = export_type.enum_values.front(); E; E = E->next()) {
+ enum_hint_string += E->key().operator String().camelcase_to_underscore(true).capitalize().xml_escape();
+ enum_hint_string += ":";
+ enum_hint_string += String::num_int64(E->get()).xml_escape();
+
+ if (E->next()) {
+ enum_hint_string += ",";
+ }
+ }
+
+ variable->export_info.hint_string = enum_hint_string;
+ } break;
+ default:
+ // TODO: Allow custom user resources.
+ push_error(R"(Export type can only be built-in, a resource, or an enum.)", variable);
+ break;
+ }
+
+ if (is_array) {
+ String hint_prefix = itos(variable->export_info.type);
+ if (variable->export_info.hint) {
+ hint_prefix += "/" + itos(variable->export_info.hint);
+ }
+ variable->export_info.hint = PROPERTY_HINT_TYPE_STRING;
+ variable->export_info.hint_string = hint_prefix + ":" + variable->export_info.hint_string;
+ variable->export_info.type = Variant::ARRAY;
+ }
+ } else {
+ // Validate variable type with export.
+ if (!export_type.is_variant() && (export_type.kind != DataType::BUILTIN || export_type.builtin_type != t_type)) {
+ // Allow float/int conversion.
+ if ((t_type != Variant::FLOAT || export_type.builtin_type != Variant::INT) && (t_type != Variant::INT || export_type.builtin_type != Variant::FLOAT)) {
+ push_error(vformat(R"("%s" annotation requires a variable of type "%s" but type "%s" was given instead.)", p_annotation->name.operator String(), Variant::get_type_name(t_type), export_type.to_string()), variable);
+ return false;
+ }
+ }
+ }
+
return true;
}
@@ -3278,6 +3388,9 @@ String GDScriptParser::DataType::to_string() const {
if (builtin_type == Variant::NIL) {
return "null";
}
+ if (builtin_type == Variant::ARRAY && has_container_element_type()) {
+ return vformat("Array[%s]", container_element_type->to_string());
+ }
return Variant::get_type_name(builtin_type);
case NATIVE:
if (is_meta_type) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index a4b1d4c866..272d21ffce 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -94,7 +94,12 @@ public:
struct VariableNode;
struct WhileNode;
- struct DataType {
+ class DataType {
+ private:
+ // Private access so we can control memory management.
+ DataType *container_element_type = nullptr;
+
+ public:
enum Kind {
BUILTIN,
NATIVE,
@@ -104,7 +109,6 @@ public:
ENUM_VALUE, // Value from enumeration.
VARIANT, // Can be any type.
UNRESOLVED,
- // TODO: Enum
};
Kind kind = UNRESOLVED;
@@ -128,7 +132,7 @@ public:
ClassNode *class_type = nullptr;
MethodInfo method_info; // For callable/signals.
- HashMap<StringName, int> enum_values; // For enums.
+ Map<StringName, int> enum_values; // For enums.
_FORCE_INLINE_ bool is_set() const { return kind != UNRESOLVED; }
_FORCE_INLINE_ bool has_no_type() const { return type_source == UNDETECTED; }
@@ -136,6 +140,26 @@ public:
_FORCE_INLINE_ bool is_hard_type() const { return type_source > INFERRED; }
String to_string() const;
+ _FORCE_INLINE_ void set_container_element_type(const DataType &p_type) {
+ container_element_type = memnew(DataType(p_type));
+ }
+
+ _FORCE_INLINE_ DataType get_container_element_type() const {
+ ERR_FAIL_COND_V(container_element_type == nullptr, DataType());
+ return *container_element_type;
+ }
+
+ _FORCE_INLINE_ bool has_container_element_type() const {
+ return container_element_type != nullptr;
+ }
+
+ _FORCE_INLINE_ void unset_container_element_type() {
+ if (container_element_type) {
+ memdelete(container_element_type);
+ };
+ container_element_type = nullptr;
+ }
+
bool operator==(const DataType &p_other) const {
if (type_source == UNDETECTED || p_other.type_source == UNDETECTED) {
return true; // Can be consireded equal for parsing purposes.
@@ -173,6 +197,37 @@ public:
bool operator!=(const DataType &p_other) const {
return !(this->operator==(p_other));
}
+
+ DataType &operator=(const DataType &p_other) {
+ kind = p_other.kind;
+ type_source = p_other.type_source;
+ is_constant = p_other.is_constant;
+ is_meta_type = p_other.is_meta_type;
+ is_coroutine = p_other.is_coroutine;
+ builtin_type = p_other.builtin_type;
+ native_type = p_other.native_type;
+ enum_type = p_other.enum_type;
+ script_type = p_other.script_type;
+ script_path = p_other.script_path;
+ class_type = p_other.class_type;
+ method_info = p_other.method_info;
+ enum_values = p_other.enum_values;
+ unset_container_element_type();
+ if (p_other.has_container_element_type()) {
+ set_container_element_type(p_other.get_container_element_type());
+ }
+ return *this;
+ }
+
+ DataType() = default;
+
+ DataType(const DataType &p_other) {
+ *this = p_other;
+ }
+
+ ~DataType() {
+ unset_container_element_type();
+ }
};
struct ParserError {
@@ -987,6 +1042,7 @@ public:
struct TypeNode : public Node {
Vector<IdentifierNode *> type_chain;
+ TypeNode *container_type = nullptr;
TypeNode() {
type = TYPE;
@@ -1313,6 +1369,7 @@ public:
ClassNode *get_tree() const { return head; }
bool is_tool() const { return _is_tool; }
static Variant::Type get_builtin_type(const StringName &p_type);
+ static StringName get_real_class_name(const StringName &p_source);
CompletionContext get_completion_context() const { return completion_context; }
CompletionCall get_completion_call() const { return completion_call; }
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index 348d221352..64c629662c 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -298,7 +298,7 @@ struct GDScriptUtilityFunctionsDefinitions {
sname.push_back(p->name);
p = p->_owner;
}
- sname.invert();
+ sname.reverse();
if (!p->path.is_resource_file()) {
r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 2216fcab2d..8bf6a8b08b 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -34,22 +34,22 @@
#include "core/os/os.h"
#include "gdscript.h"
-Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const {
+Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, Variant *p_stack, String &r_error) const {
int address = p_address & ADDR_MASK;
//sequential table (jump table generated by compiler)
switch ((p_address & ADDR_TYPE_MASK) >> ADDR_BITS) {
- case ADDR_TYPE_SELF: {
+ case ADDR_TYPE_STACK: {
#ifdef DEBUG_ENABLED
- if (unlikely(!p_instance)) {
- r_error = "Cannot access self without instance.";
- return nullptr;
- }
+ ERR_FAIL_INDEX_V(address, _stack_size, nullptr);
#endif
- return &self;
+ return &p_stack[address];
} break;
- case ADDR_TYPE_CLASS: {
- return &static_ref;
+ case ADDR_TYPE_CONSTANT: {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(address, _constant_count, nullptr);
+#endif
+ return &_constants_ptr[address];
} break;
case ADDR_TYPE_MEMBER: {
#ifdef DEBUG_ENABLED
@@ -61,65 +61,6 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
//member indexing is O(1)
return &p_instance->members.write[address];
} break;
- case ADDR_TYPE_CLASS_CONSTANT: {
- //todo change to index!
- GDScript *s = p_script;
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
-#endif
- const StringName *sn = &_global_names_ptr[address];
-
- while (s) {
- GDScript *o = s;
- while (o) {
- Map<StringName, Variant>::Element *E = o->constants.find(*sn);
- if (E) {
- return &E->get();
- }
- o = o->_owner;
- }
- s = s->_base;
- }
-
- ERR_FAIL_V_MSG(nullptr, "GDScriptCompiler bug.");
- } break;
- case ADDR_TYPE_LOCAL_CONSTANT: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _constant_count, nullptr);
-#endif
- return &_constants_ptr[address];
- } break;
- case ADDR_TYPE_STACK:
- case ADDR_TYPE_STACK_VARIABLE: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _stack_size, nullptr);
-#endif
- return &p_stack[address];
- } break;
- case ADDR_TYPE_GLOBAL: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, GDScriptLanguage::get_singleton()->get_global_array_size(), nullptr);
-#endif
- return &GDScriptLanguage::get_singleton()->get_global_array()[address];
- } break;
-#ifdef TOOLS_ENABLED
- case ADDR_TYPE_NAMED_GLOBAL: {
-#ifdef DEBUG_ENABLED
- ERR_FAIL_INDEX_V(address, _global_names_count, nullptr);
-#endif
- StringName id = _global_names_ptr[address];
-
- if (GDScriptLanguage::get_singleton()->get_named_globals_map().has(id)) {
- return (Variant *)&GDScriptLanguage::get_singleton()->get_named_globals_map()[id];
- } else {
- r_error = "Autoload singleton '" + String(id) + "' has been removed.";
- return nullptr;
- }
- } break;
-#endif
- case ADDR_TYPE_NIL: {
- return &nil;
- } break;
}
ERR_FAIL_V_MSG(nullptr, "Bad code! (unknown addressing mode).");
@@ -127,6 +68,17 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta
}
#ifdef DEBUG_ENABLED
+static String _get_script_name(const Ref<Script> p_script) {
+ Ref<GDScript> gdscript = p_script;
+ if (gdscript.is_valid()) {
+ return gdscript->get_script_class_name();
+ } else if (p_script->get_name().is_empty()) {
+ return p_script->get_path().get_file();
+ } else {
+ return p_script->get_name();
+ }
+}
+
static String _get_var_type(const Variant *p_var) {
String basestr;
@@ -140,15 +92,30 @@ static String _get_var_type(const Variant *p_var) {
basestr = "previously freed";
}
} else {
+ basestr = bobj->get_class();
if (bobj->get_script_instance()) {
- basestr = bobj->get_class() + " (" + bobj->get_script_instance()->get_script()->get_path().get_file() + ")";
- } else {
- basestr = bobj->get_class();
+ basestr += " (" + _get_script_name(bobj->get_script_instance()->get_script()) + ")";
}
}
} else {
- basestr = Variant::get_type_name(p_var->get_type());
+ if (p_var->get_type() == Variant::ARRAY) {
+ basestr = "Array";
+ const Array *p_array = VariantInternal::get_array(p_var);
+ Variant::Type builtin_type = (Variant::Type)p_array->get_typed_builtin();
+ StringName native_type = p_array->get_typed_class_name();
+ Ref<Script> script_type = p_array->get_typed_script();
+
+ if (script_type.is_valid() && script_type->is_valid()) {
+ basestr += "[" + _get_script_name(script_type) + "]";
+ } else if (native_type != StringName()) {
+ basestr += "[" + native_type.operator String() + "]";
+ } else if (builtin_type != Variant::NIL) {
+ basestr += "[" + Variant::get_type_name(builtin_type) + "]";
+ }
+ } else {
+ basestr = Variant::get_type_name(p_var->get_type());
+ }
}
return basestr;
@@ -207,6 +174,7 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_ASSIGN_TRUE, \
&&OPCODE_ASSIGN_FALSE, \
&&OPCODE_ASSIGN_TYPED_BUILTIN, \
+ &&OPCODE_ASSIGN_TYPED_ARRAY, \
&&OPCODE_ASSIGN_TYPED_NATIVE, \
&&OPCODE_ASSIGN_TYPED_SCRIPT, \
&&OPCODE_CAST_TO_BUILTIN, \
@@ -215,6 +183,7 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_CONSTRUCT, \
&&OPCODE_CONSTRUCT_VALIDATED, \
&&OPCODE_CONSTRUCT_ARRAY, \
+ &&OPCODE_CONSTRUCT_TYPED_ARRAY, \
&&OPCODE_CONSTRUCT_DICTIONARY, \
&&OPCODE_CALL, \
&&OPCODE_CALL_RETURN, \
@@ -268,6 +237,10 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_JUMP_IF_NOT, \
&&OPCODE_JUMP_TO_DEF_ARGUMENT, \
&&OPCODE_RETURN, \
+ &&OPCODE_RETURN_TYPED_BUILTIN, \
+ &&OPCODE_RETURN_TYPED_ARRAY, \
+ &&OPCODE_RETURN_TYPED_NATIVE, \
+ &&OPCODE_RETURN_TYPED_SCRIPT, \
&&OPCODE_ITERATE_BEGIN, \
&&OPCODE_ITERATE_BEGIN_INT, \
&&OPCODE_ITERATE_BEGIN_FLOAT, \
@@ -308,6 +281,7 @@ String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const
&&OPCODE_ITERATE_PACKED_VECTOR3_ARRAY, \
&&OPCODE_ITERATE_PACKED_COLOR_ARRAY, \
&&OPCODE_ITERATE_OBJECT, \
+ &&OPCODE_STORE_NAMED_GLOBAL, \
&&OPCODE_ASSERT, \
&&OPCODE_BREAKPOINT, \
&&OPCODE_LINE, \
@@ -383,11 +357,9 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
r_err.error = Callable::CallError::CALL_OK;
- Variant self;
- Variant static_ref;
Variant retvalue;
Variant *stack = nullptr;
- Variant **instruction_args;
+ Variant **instruction_args = nullptr;
const void **call_args_ptr = nullptr;
int defarg = 0;
@@ -412,7 +384,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
script = p_state->script;
p_instance = p_state->instance;
defarg = p_state->defarg;
- self = p_state->self;
} else {
if (p_argcount != _argument_count) {
@@ -430,55 +401,49 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
}
- alloca_size = sizeof(Variant *) * _instruction_args_size + sizeof(Variant) * _stack_size;
+ // Add 3 here for self, class, and nil.
+ alloca_size = sizeof(Variant *) * 3 + sizeof(Variant *) * _instruction_args_size + sizeof(Variant) * _stack_size;
- if (alloca_size) {
- uint8_t *aptr = (uint8_t *)alloca(alloca_size);
+ uint8_t *aptr = (uint8_t *)alloca(alloca_size);
+ stack = (Variant *)aptr;
- if (_stack_size) {
- stack = (Variant *)aptr;
- for (int i = 0; i < p_argcount; i++) {
- if (!argument_types[i].has_type) {
- memnew_placement(&stack[i], Variant(*p_args[i]));
- continue;
- }
-
- if (!argument_types[i].is_type(*p_args[i], true)) {
- r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_err.argument = i;
- r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
- return Variant();
- }
- if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
- Variant arg;
- Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err);
- memnew_placement(&stack[i], Variant(arg));
- } else {
- memnew_placement(&stack[i], Variant(*p_args[i]));
- }
- }
- for (int i = p_argcount; i < _stack_size; i++) {
- memnew_placement(&stack[i], Variant);
- }
- } else {
- stack = nullptr;
+ for (int i = 0; i < p_argcount; i++) {
+ if (!argument_types[i].has_type) {
+ memnew_placement(&stack[i + 3], Variant(*p_args[i]));
+ continue;
}
- if (_instruction_args_size) {
- instruction_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
+ if (!argument_types[i].is_type(*p_args[i], true)) {
+ r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_err.argument = i;
+ r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT;
+ return Variant();
+ }
+ if (argument_types[i].kind == GDScriptDataType::BUILTIN) {
+ Variant arg;
+ Variant::construct(argument_types[i].builtin_type, arg, &p_args[i], 1, r_err);
+ memnew_placement(&stack[i + 3], Variant(arg));
} else {
- instruction_args = nullptr;
+ memnew_placement(&stack[i + 3], Variant(*p_args[i]));
}
+ }
+ for (int i = p_argcount + 3; i < _stack_size; i++) {
+ memnew_placement(&stack[i], Variant);
+ }
+ memnew_placement(&stack[ADDR_STACK_NIL], Variant);
+
+ if (_instruction_args_size) {
+ instruction_args = (Variant **)&aptr[sizeof(Variant) * _stack_size];
} else {
- stack = nullptr;
instruction_args = nullptr;
}
if (p_instance) {
- self = p_instance->owner;
+ memnew_placement(&stack[ADDR_STACK_SELF], Variant(p_instance->owner));
script = p_instance->script.ptr();
} else {
+ memnew_placement(&stack[ADDR_STACK_SELF], Variant);
script = _script;
}
}
@@ -488,7 +453,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
call_args_ptr = nullptr;
}
- static_ref = script;
+ memnew_placement(&stack[ADDR_STACK_CLASS], Variant(script));
String err_text;
@@ -509,10 +474,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space) \
GD_ERR_BREAK((ip + m_space) > _code_size)
-#define GET_VARIANT_PTR(m_v, m_code_ofs) \
- Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); \
- if (unlikely(!m_v)) \
+#define GET_VARIANT_PTR(m_v, m_code_ofs) \
+ Variant *m_v; \
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text); \
+ if (unlikely(!m_v)) \
OPCODE_BREAK;
#else
@@ -520,7 +485,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#define CHECK_SPACE(m_space)
#define GET_VARIANT_PTR(m_v, m_code_ofs) \
Variant *m_v; \
- m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text);
+ m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, stack, err_text);
#endif
@@ -544,7 +509,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
#ifdef DEBUG_ENABLED
OPCODE_WHILE(ip < _code_size) {
- int last_opcode = _code_ptr[ip];
+ int last_opcode = _code_ptr[ip] & INSTR_MASK;
#else
OPCODE_WHILE(true) {
#endif
@@ -1077,6 +1042,31 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_ASSIGN_TYPED_ARRAY) {
+ CHECK_SPACE(3);
+ GET_INSTRUCTION_ARG(dst, 0);
+ GET_INSTRUCTION_ARG(src, 1);
+
+ Array *dst_arr = VariantInternal::get_array(dst);
+
+ if (src->get_type() != Variant::ARRAY) {
+#ifdef DEBUG_ENABLED
+ err_text = "Trying to assign value of type '" + Variant::get_type_name(src->get_type()) +
+ "' to a variable of type '" + +"'.";
+#endif
+ OPCODE_BREAK;
+ }
+ if (!dst_arr->typed_assign(*src)) {
+#ifdef DEBUG_ENABLED
+ err_text = "Trying to assign a typed array with an array of different type.'";
+#endif
+ OPCODE_BREAK;
+ }
+
+ ip += 3;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSIGN_TYPED_NATIVE) {
CHECK_SPACE(4);
GET_INSTRUCTION_ARG(dst, 0);
@@ -1308,6 +1298,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
GET_INSTRUCTION_ARG(dst, argc);
+ *dst = Variant(); // Clear potential previous typed array.
*dst = array;
@@ -1315,6 +1306,35 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_CONSTRUCT_TYPED_ARRAY) {
+ CHECK_SPACE(3 + instr_arg_count);
+ ip += instr_arg_count;
+
+ int argc = _code_ptr[ip + 1];
+
+ GET_INSTRUCTION_ARG(script_type, argc + 1);
+ Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 2];
+ int native_type_idx = _code_ptr[ip + 3];
+ GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
+ const StringName native_type = _global_names_ptr[native_type_idx];
+
+ Array array;
+ array.set_typed(builtin_type, native_type, script_type);
+ array.resize(argc);
+
+ for (int i = 0; i < argc; i++) {
+ array[i] = *(instruction_args[i]);
+ }
+
+ GET_INSTRUCTION_ARG(dst, argc);
+ *dst = Variant(); // Clear potential previous typed array.
+
+ *dst = array;
+
+ ip += 4;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_CONSTRUCT_DICTIONARY) {
CHECK_SPACE(2 + instr_arg_count);
@@ -1951,7 +1971,6 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
memnew_placement(&gdfs->state.stack.write[sizeof(Variant) * i], Variant(stack[i]));
}
gdfs->state.stack_size = _stack_size;
- gdfs->state.self = self;
gdfs->state.alloca_size = alloca_size;
gdfs->state.ip = ip + 2;
gdfs->state.line = line;
@@ -2063,6 +2082,183 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
OPCODE_BREAK;
}
+ OPCODE(OPCODE_RETURN_TYPED_BUILTIN) {
+ CHECK_SPACE(3);
+ GET_INSTRUCTION_ARG(r, 0);
+
+ Variant::Type ret_type = (Variant::Type)_code_ptr[ip + 2];
+ GD_ERR_BREAK(ret_type < 0 || ret_type >= Variant::VARIANT_MAX);
+
+ if (r->get_type() != ret_type) {
+ if (Variant::can_convert_strict(r->get_type(), ret_type)) {
+ Callable::CallError ce;
+ Variant::construct(ret_type, retvalue, const_cast<const Variant **>(&r), 1, ce);
+ } else {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ Variant::get_type_name(r->get_type()), Variant::get_type_name(ret_type));
+#endif // DEBUG_ENABLED
+
+ // Construct a base type anyway so type constraints are met.
+ Callable::CallError ce;
+ Variant::construct(ret_type, retvalue, nullptr, 0, ce);
+ OPCODE_BREAK;
+ }
+ } else {
+ retvalue = *r;
+ }
+#ifdef DEBUG_ENABLED
+ exit_ok = true;
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
+ OPCODE(OPCODE_RETURN_TYPED_ARRAY) {
+ CHECK_SPACE(5);
+ GET_INSTRUCTION_ARG(r, 0);
+
+ GET_INSTRUCTION_ARG(script_type, 1);
+ Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 3];
+ int native_type_idx = _code_ptr[ip + 4];
+ GD_ERR_BREAK(native_type_idx < 0 || native_type_idx >= _global_names_count);
+ const StringName native_type = _global_names_ptr[native_type_idx];
+
+ if (r->get_type() != Variant::ARRAY) {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "Array[%s]".)",
+ Variant::get_type_name(r->get_type()), Variant::get_type_name(builtin_type));
+#endif
+ OPCODE_BREAK;
+ }
+
+ Array array;
+ array.set_typed(builtin_type, native_type, script_type);
+
+#ifdef DEBUG_ENABLED
+ bool valid = array.typed_assign(*VariantInternal::get_array(r));
+#else
+ array.typed_assign(*VariantInternal::get_array(r));
+#endif // DEBUG_ENABLED
+
+ // Assign the return value anyway since we want it to be the valid type.
+ retvalue = array;
+
+#ifdef DEBUG_ENABLED
+ if (!valid) {
+ err_text = "Trying to return a typed array with an array of different type.'";
+ OPCODE_BREAK;
+ }
+
+ exit_ok = true;
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
+ OPCODE(OPCODE_RETURN_TYPED_NATIVE) {
+ CHECK_SPACE(3);
+ GET_INSTRUCTION_ARG(r, 0);
+
+ GET_INSTRUCTION_ARG(type, 1);
+ GDScriptNativeClass *nc = Object::cast_to<GDScriptNativeClass>(type->operator Object *());
+ GD_ERR_BREAK(!nc);
+
+ if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ Variant::get_type_name(r->get_type()), nc->get_name());
+ OPCODE_BREAK;
+ }
+
+#ifdef DEBUG_ENABLED
+ bool freed = false;
+ Object *ret_obj = r->get_validated_object_with_check(freed);
+
+ if (freed) {
+ err_text = "Trying to return a previously freed instance.";
+ OPCODE_BREAK;
+ }
+#else
+ Object *ret_obj = r->operator Object *();
+#endif // DEBUG_ENABLED
+ if (ret_obj && !ClassDB::is_parent_class(ret_obj->get_class_name(), nc->get_name())) {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ ret_obj->get_class_name(), nc->get_name());
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+ retvalue = *r;
+
+#ifdef DEBUG_ENABLED
+ exit_ok = true;
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
+ OPCODE(OPCODE_RETURN_TYPED_SCRIPT) {
+ CHECK_SPACE(3);
+ GET_INSTRUCTION_ARG(r, 0);
+
+ GET_INSTRUCTION_ARG(type, 1);
+ Script *base_type = Object::cast_to<Script>(type->operator Object *());
+ GD_ERR_BREAK(!base_type);
+
+ if (r->get_type() != Variant::OBJECT && r->get_type() != Variant::NIL) {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ Variant::get_type_name(r->get_type()), _get_script_name(Ref<Script>(base_type)));
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
+#ifdef DEBUG_ENABLED
+ bool freed = false;
+ Object *ret_obj = r->get_validated_object_with_check(freed);
+
+ if (freed) {
+ err_text = "Trying to return a previously freed instance.";
+ OPCODE_BREAK;
+ }
+#else
+ Object *ret_obj = r->operator Object *();
+#endif // DEBUG_ENABLED
+
+ if (ret_obj) {
+ ScriptInstance *ret_inst = ret_obj->get_script_instance();
+ if (!ret_inst) {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ ret_obj->get_class_name(), _get_script_name(Ref<GDScript>(base_type)));
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
+ Script *ret_type = ret_obj->get_script_instance()->get_script().ptr();
+ bool valid = false;
+
+ while (ret_type) {
+ if (ret_type == base_type) {
+ valid = true;
+ break;
+ }
+ ret_type = ret_type->get_base_script().ptr();
+ }
+
+ if (!valid) {
+#ifdef DEBUG_ENABLED
+ err_text = vformat(R"(Trying to return value of type "%s" from a function which the return type is "%s".)",
+ _get_script_name(ret_obj->get_script_instance()->get_script()), _get_script_name(Ref<GDScript>(base_type)));
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+ }
+ retvalue = *r;
+
+#ifdef DEBUG_ENABLED
+ exit_ok = true;
+#endif // DEBUG_ENABLED
+ OPCODE_BREAK;
+ }
+
OPCODE(OPCODE_ITERATE_BEGIN) {
CHECK_SPACE(8); // Space for this and a regular iterate.
@@ -2764,6 +2960,19 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
DISPATCH_OPCODE;
+ OPCODE(OPCODE_STORE_NAMED_GLOBAL) {
+ CHECK_SPACE(3);
+ int globalname_idx = _code_ptr[ip + 2];
+ GD_ERR_BREAK(globalname_idx < 0 || globalname_idx >= _global_names_count);
+ const StringName *globalname = &_global_names_ptr[globalname_idx];
+
+ GET_INSTRUCTION_ARG(dst, 0);
+ *dst = GDScriptLanguage::get_singleton()->get_named_globals_map()[*globalname];
+
+ ip += 3;
+ }
+ DISPATCH_OPCODE;
+
OPCODE(OPCODE_ASSERT) {
CHECK_SPACE(3);
diff --git a/modules/gdscript/register_types.cpp b/modules/gdscript/register_types.cpp
index 93b709a613..19fd3daf20 100644
--- a/modules/gdscript/register_types.cpp
+++ b/modules/gdscript/register_types.cpp
@@ -158,7 +158,6 @@ void unregister_gdscript_types() {
#endif // TOOLS_ENABLED
GDScriptParser::cleanup();
- GDScriptAnalyzer::cleanup();
GDScriptUtilityFunctions::unregister_functions();
}
diff --git a/modules/glslang/register_types.cpp b/modules/glslang/register_types.cpp
index 545aa68747..14135265b9 100644
--- a/modules/glslang/register_types.cpp
+++ b/modules/glslang/register_types.cpp
@@ -37,7 +37,7 @@
#include <glslang/Include/Types.h>
#include <glslang/Public/ShaderLang.h>
-static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error) {
+static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage, const String &p_source_code, RenderingDevice::ShaderLanguage p_language, String *r_error, const RenderingDevice::Capabilities *p_capabilities) {
Vector<uint8_t> ret;
ERR_FAIL_COND_V(p_language == RenderingDevice::SHADER_LANGUAGE_HLSL, ret);
@@ -51,20 +51,75 @@ static Vector<uint8_t> _compile_shader_glsl(RenderingDevice::ShaderStage p_stage
};
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
+ bool check_subgroup_support = true; // assume we support subgroups
- glslang::EShTargetClientVersion VulkanClientVersion = glslang::EShTargetVulkan_1_0;
- glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_3;
+ glslang::EShTargetClientVersion ClientVersion = glslang::EShTargetVulkan_1_2;
+ glslang::EShTargetLanguageVersion TargetVersion = glslang::EShTargetSpv_1_5;
glslang::TShader::ForbidIncluder includer;
+ if (p_capabilities->device_family == RenderingDevice::DeviceFamily::DEVICE_VULKAN) {
+ if (p_capabilities->version_major == 1 && p_capabilities->version_minor == 0) {
+ ClientVersion = glslang::EShTargetVulkan_1_0;
+ TargetVersion = glslang::EShTargetSpv_1_0;
+ check_subgroup_support = false; // subgroups are not supported in Vulkan 1.0
+ } else if (p_capabilities->version_major == 1 && p_capabilities->version_minor == 1) {
+ ClientVersion = glslang::EShTargetVulkan_1_1;
+ TargetVersion = glslang::EShTargetSpv_1_3;
+ } else {
+ // use defaults
+ }
+ } else {
+ // once we support other backends we'll need to do something here
+ if (r_error) {
+ (*r_error) = "GLSLANG - Unsupported device family";
+ }
+ return ret;
+ }
+
glslang::TShader shader(stages[p_stage]);
CharString cs = p_source_code.ascii();
const char *cs_strings = cs.get_data();
+ std::string preamble = "";
shader.setStrings(&cs_strings, 1);
shader.setEnvInput(glslang::EShSourceGlsl, stages[p_stage], glslang::EShClientVulkan, ClientInputSemanticsVersion);
- shader.setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
+ shader.setEnvClient(glslang::EShClientVulkan, ClientVersion);
shader.setEnvTarget(glslang::EShTargetSpv, TargetVersion);
+ if (check_subgroup_support) {
+ uint32_t stage_bit = 1 << p_stage;
+
+ if ((p_capabilities->subgroup_in_shaders & stage_bit) == stage_bit) {
+ // stage supports subgroups
+ preamble += "#define has_GL_KHR_shader_subgroup_basic 1\n";
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_VOTE_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_vote 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_ARITHMETIC_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_arithmetic 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_BALLOT_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_ballot 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_shuffle 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_SHUFFLE_RELATIVE_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_shuffle_relative 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_CLUSTERED_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_clustered 1\n";
+ }
+ if (p_capabilities->subgroup_operations & RenderingDevice::SUBGROUP_QUAD_BIT) {
+ preamble += "#define has_GL_KHR_shader_subgroup_quad 1\n";
+ }
+ }
+ }
+
+ if (preamble != "") {
+ shader.setPreamble(preamble.c_str());
+ }
+
EShMessages messages = (EShMessages)(EShMsgSpvRules | EShMsgVulkanRules);
const int DefaultVersion = 100;
std::string pre_processed_code;
diff --git a/modules/gltf/editor_scene_importer_gltf.h b/modules/gltf/editor_scene_importer_gltf.h
index db961e591d..af1a885f2b 100644
--- a/modules/gltf/editor_scene_importer_gltf.h
+++ b/modules/gltf/editor_scene_importer_gltf.h
@@ -64,8 +64,8 @@ public:
virtual void get_extensions(List<String> *r_extensions) const override;
virtual Node *import_scene(const String &p_path, uint32_t p_flags,
int p_bake_fps,
- List<String> *r_missing_deps = NULL,
- Error *r_err = NULL) override;
+ List<String> *r_missing_deps = nullptr,
+ Error *r_err = nullptr) override;
virtual Ref<Animation> import_animation(const String &p_path,
uint32_t p_flags, int p_bake_fps) override;
};
@@ -80,7 +80,7 @@ protected:
public:
virtual void save_scene(Node *p_node, const String &p_path, const String &p_src_path,
uint32_t p_flags, int p_bake_fps,
- List<String> *r_missing_deps, Error *r_err = NULL);
+ List<String> *r_missing_deps, Error *r_err = nullptr);
virtual void _build_parent_hierachy(Ref<GLTFState> state);
virtual Error export_gltf(Node *p_root, String p_path, int32_t p_flags = 0,
real_t p_bake_fps = 1000.0f);
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index d6e67a78d7..0b70175a24 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -940,22 +940,29 @@ String GLTFDocument::_get_accessor_type_name(const GLTFDocument::GLTFType p_type
}
GLTFDocument::GLTFType GLTFDocument::_get_type_from_str(const String &p_string) {
- if (p_string == "SCALAR")
+ if (p_string == "SCALAR") {
return GLTFDocument::TYPE_SCALAR;
+ }
- if (p_string == "VEC2")
+ if (p_string == "VEC2") {
return GLTFDocument::TYPE_VEC2;
- if (p_string == "VEC3")
+ }
+ if (p_string == "VEC3") {
return GLTFDocument::TYPE_VEC3;
- if (p_string == "VEC4")
+ }
+ if (p_string == "VEC4") {
return GLTFDocument::TYPE_VEC4;
+ }
- if (p_string == "MAT2")
+ if (p_string == "MAT2") {
return GLTFDocument::TYPE_MAT2;
- if (p_string == "MAT3")
+ }
+ if (p_string == "MAT3") {
return GLTFDocument::TYPE_MAT3;
- if (p_string == "MAT4")
+ }
+ if (p_string == "MAT4") {
return GLTFDocument::TYPE_MAT4;
+ }
ERR_FAIL_V(GLTFDocument::TYPE_SCALAR);
}
@@ -1434,8 +1441,9 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> state, const GLTFAc
ERR_FAIL_INDEX_V(a->buffer_view, state->buffer_views.size(), Vector<double>());
const Error err = _decode_buffer_view(state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
} else {
//fill with zeros, as bufferview is not defined.
for (int i = 0; i < (a->count * component_count); i++) {
@@ -1450,14 +1458,16 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> state, const GLTFAc
const int indices_component_size = _get_component_type_size(a->sparse_indices_component_type);
Error err = _decode_buffer_view(state, indices.ptrw(), a->sparse_indices_buffer_view, 0, 0, indices_component_size, a->sparse_count, TYPE_SCALAR, 1, a->sparse_indices_component_type, indices_component_size, false, a->sparse_indices_byte_offset, false);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
Vector<double> data;
data.resize(component_count * a->sparse_count);
err = _decode_buffer_view(state, data.ptrw(), a->sparse_values_buffer_view, skip_every, skip_bytes, element_size, a->sparse_count, a->type, component_count, a->component_type, component_size, a->normalized, a->sparse_values_byte_offset, p_for_vertex);
- if (err != OK)
+ if (err != OK) {
return Vector<double>();
+ }
for (int i = 0; i < indices.size(); i++) {
const int write_offset = int(indices[i]) * component_count;
@@ -1528,8 +1538,9 @@ Vector<int> GLTFDocument::_decode_accessor_as_ints(Ref<GLTFState> state, const G
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<int> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const double *attribs_ptr = attribs.ptr();
const int ret_size = attribs.size();
@@ -1546,8 +1557,9 @@ Vector<float> GLTFDocument::_decode_accessor_as_floats(Ref<GLTFState> state, con
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<float> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const double *attribs_ptr = attribs.ptr();
const int ret_size = attribs.size();
@@ -1820,8 +1832,9 @@ Vector<Vector2> GLTFDocument::_decode_accessor_as_vec2(Ref<GLTFState> state, con
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector2> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 2 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -1998,8 +2011,9 @@ Vector<Vector3> GLTFDocument::_decode_accessor_as_vec3(Ref<GLTFState> state, con
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Vector3> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 3 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -2017,8 +2031,9 @@ Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> state, cons
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Color> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
const int type = state->accessors[p_accessor]->type;
ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret);
@@ -2042,8 +2057,9 @@ Vector<Quat> GLTFDocument::_decode_accessor_as_quat(Ref<GLTFState> state, const
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Quat> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
const double *attribs_ptr = attribs.ptr();
@@ -2060,8 +2076,9 @@ Vector<Transform2D> GLTFDocument::_decode_accessor_as_xform2d(Ref<GLTFState> sta
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform2D> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 4 != 0, ret);
ret.resize(attribs.size() / 4);
@@ -2076,8 +2093,9 @@ Vector<Basis> GLTFDocument::_decode_accessor_as_basis(Ref<GLTFState> state, cons
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Basis> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 9 != 0, ret);
ret.resize(attribs.size() / 9);
@@ -2093,8 +2111,9 @@ Vector<Transform> GLTFDocument::_decode_accessor_as_xform(Ref<GLTFState> state,
const Vector<double> attribs = _decode_accessor(state, p_accessor, p_for_vertex);
Vector<Transform> ret;
- if (attribs.size() == 0)
+ if (attribs.size() == 0) {
return ret;
+ }
ERR_FAIL_COND_V(attribs.size() % 16 != 0, ret);
ret.resize(attribs.size() / 16);
@@ -2821,7 +2840,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path
ERR_CONTINUE(state->images[i].is_null());
- Ref<Image> image = state->images[i]->get_data();
+ Ref<Image> image = state->images[i]->get_image();
ERR_CONTINUE(image.is_null());
if (p_path.to_lower().ends_with("glb")) {
@@ -2838,7 +2857,7 @@ Error GLTFDocument::_serialize_images(Ref<GLTFState> state, const String &p_path
Vector<uint8_t> buffer;
Ref<ImageTexture> img_tex = image;
if (img_tex.is_valid()) {
- image = img_tex->get_data();
+ image = img_tex->get_image();
}
Error err = PNGDriverCommon::image_to_png(image, buffer);
ERR_FAIL_COND_V_MSG(err, err, "Can't convert image to PNG.");
@@ -3046,8 +3065,9 @@ Error GLTFDocument::_serialize_textures(Ref<GLTFState> state) {
}
Error GLTFDocument::_parse_textures(Ref<GLTFState> state) {
- if (!state->json.has("textures"))
+ if (!state->json.has("textures")) {
return OK;
+ }
const Array &textures = state->json["textures"];
for (GLTFTextureIndex i = 0; i < textures.size(); i++) {
@@ -3068,7 +3088,7 @@ GLTFTextureIndex GLTFDocument::_set_texture(Ref<GLTFState> state, Ref<Texture2D>
ERR_FAIL_COND_V(p_texture.is_null(), -1);
Ref<GLTFTexture> gltf_texture;
gltf_texture.instance();
- ERR_FAIL_COND_V(p_texture->get_data().is_null(), -1);
+ ERR_FAIL_COND_V(p_texture->get_image().is_null(), -1);
GLTFImageIndex gltf_src_image_i = state->images.size();
state->images.push_back(p_texture);
gltf_texture->set_src_image(gltf_src_image_i);
@@ -3115,7 +3135,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
Ref<Texture2D> albedo_texture = material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
GLTFTextureIndex gltf_texture_index = -1;
- if (albedo_texture.is_valid() && albedo_texture->get_data().is_valid()) {
+ if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
albedo_texture->set_name(material->get_name() + "_albedo");
gltf_texture_index = _set_texture(state, albedo_texture);
}
@@ -3128,9 +3148,9 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
mr["metallicFactor"] = material->get_metallic();
mr["roughnessFactor"] = material->get_roughness();
- bool has_roughness = material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_data().is_valid();
+ bool has_roughness = material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
bool has_ao = material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
- bool has_metalness = material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_data().is_valid();
+ bool has_metalness = material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
if (has_ao || has_roughness || has_metalness) {
Dictionary mrt;
Ref<Texture2D> roughness_texture = material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
@@ -3149,10 +3169,10 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
if (has_ao) {
height = ao_texture->get_height();
width = ao_texture->get_width();
- ao_image = ao_texture->get_data();
+ ao_image = ao_texture->get_image();
Ref<ImageTexture> img_tex = ao_image;
if (img_tex.is_valid()) {
- ao_image = img_tex->get_data();
+ ao_image = img_tex->get_image();
}
if (ao_image->is_compressed()) {
ao_image->decompress();
@@ -3162,10 +3182,10 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
if (has_roughness) {
height = roughness_texture->get_height();
width = roughness_texture->get_width();
- roughness_image = roughness_texture->get_data();
+ roughness_image = roughness_texture->get_image();
Ref<ImageTexture> img_tex = roughness_image;
if (img_tex.is_valid()) {
- roughness_image = img_tex->get_data();
+ roughness_image = img_tex->get_image();
}
if (roughness_image->is_compressed()) {
roughness_image->decompress();
@@ -3175,17 +3195,17 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
if (has_metalness) {
height = metallic_texture->get_height();
width = metallic_texture->get_width();
- metallness_image = metallic_texture->get_data();
+ metallness_image = metallic_texture->get_image();
Ref<ImageTexture> img_tex = metallness_image;
if (img_tex.is_valid()) {
- metallness_image = img_tex->get_data();
+ metallness_image = img_tex->get_image();
}
if (metallness_image->is_compressed()) {
metallness_image->decompress();
}
}
Ref<Texture2D> albedo_texture = material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
- if (albedo_texture.is_valid() && albedo_texture->get_data().is_valid()) {
+ if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
height = albedo_texture->get_height();
width = albedo_texture->get_width();
}
@@ -3266,10 +3286,10 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
{
Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
// Code for uncompressing RG normal maps
- Ref<Image> img = normal_texture->get_data();
+ Ref<Image> img = normal_texture->get_image();
Ref<ImageTexture> img_tex = img;
if (img_tex.is_valid()) {
- img = img_tex->get_data();
+ img = img_tex->get_image();
}
img->decompress();
img->convert(Image::FORMAT_RGBA8);
@@ -3288,7 +3308,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
GLTFTextureIndex gltf_texture_index = -1;
- if (tex.is_valid() && tex->get_data().is_valid()) {
+ if (tex.is_valid() && tex->get_image().is_valid()) {
tex->set_name(material->get_name() + "_normal");
gltf_texture_index = _set_texture(state, tex);
}
@@ -3311,7 +3331,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
Dictionary et;
Ref<Texture2D> emission_texture = material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
GLTFTextureIndex gltf_texture_index = -1;
- if (emission_texture.is_valid() && emission_texture->get_data().is_valid()) {
+ if (emission_texture.is_valid() && emission_texture->get_image().is_valid()) {
emission_texture->set_name(material->get_name() + "_emission");
gltf_texture_index = _set_texture(state, emission_texture);
}
@@ -3340,8 +3360,9 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
}
Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
- if (!state->json.has("materials"))
+ if (!state->json.has("materials")) {
return OK;
+ }
const Array &materials = state->json["materials"];
for (GLTFMaterialIndex i = 0; i < materials.size(); i++) {
@@ -3370,7 +3391,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (diffuse_texture_dict.has("index")) {
Ref<Texture2D> diffuse_texture = _get_texture(state, diffuse_texture_dict["index"]);
if (diffuse_texture.is_valid()) {
- spec_gloss->diffuse_img = diffuse_texture->get_data();
+ spec_gloss->diffuse_img = diffuse_texture->get_image();
material->set_texture(BaseMaterial3D::TEXTURE_ALBEDO, diffuse_texture);
}
}
@@ -3398,7 +3419,7 @@ Error GLTFDocument::_parse_materials(Ref<GLTFState> state) {
if (spec_gloss_texture.has("index")) {
const Ref<Texture2D> orig_texture = _get_texture(state, spec_gloss_texture["index"]);
if (orig_texture.is_valid()) {
- spec_gloss->spec_gloss_img = orig_texture->get_data();
+ spec_gloss->spec_gloss_img = orig_texture->get_image();
}
}
}
@@ -3858,8 +3879,9 @@ Error GLTFDocument::_verify_skin(Ref<GLTFState> state, Ref<GLTFSkin> skin) {
}
Error GLTFDocument::_parse_skins(Ref<GLTFState> state) {
- if (!state->json.has("skins"))
+ if (!state->json.has("skins")) {
return OK;
+ }
const Array &skins = state->json["skins"];
@@ -4108,8 +4130,9 @@ Error GLTFDocument::_reparent_to_fake_joint(Ref<GLTFState> state, Ref<GLTFSkelet
state->nodes.push_back(fake_joint);
// We better not be a joint, or we messed up in our logic
- if (node->joint)
+ if (node->joint) {
return FAILED;
+ }
fake_joint->translation = node->translation;
fake_joint->rotation = node->rotation;
@@ -4528,8 +4551,9 @@ Error GLTFDocument::_parse_lights(Ref<GLTFState> state) {
}
Error GLTFDocument::_parse_cameras(Ref<GLTFState> state) {
- if (!state->json.has("cameras"))
+ if (!state->json.has("cameras")) {
return OK;
+ }
const Array cameras = state->json["cameras"];
@@ -4730,8 +4754,9 @@ Error GLTFDocument::_serialize_animations(Ref<GLTFState> state) {
}
Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
- if (!state->json.has("animations"))
+ if (!state->json.has("animations")) {
return OK;
+ }
const Array &animations = state->json["animations"];
@@ -4741,8 +4766,9 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
Ref<GLTFAnimation> animation;
animation.instance();
- if (!d.has("channels") || !d.has("samplers"))
+ if (!d.has("channels") || !d.has("samplers")) {
continue;
+ }
Array channels = d["channels"];
Array samplers = d["samplers"];
@@ -4757,8 +4783,9 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) {
for (int j = 0; j < channels.size(); j++) {
const Dictionary &c = channels[j];
- if (!c.has("target"))
+ if (!c.has("target")) {
continue;
+ }
const Dictionary &t = c["target"];
if (!t.has("node") || !t.has("path")) {
@@ -4868,8 +4895,9 @@ void GLTFDocument::_assign_scene_names(Ref<GLTFState> state) {
Ref<GLTFNode> n = state->nodes[i];
// Any joints get unique names generated when the skeleton is made, unique to the skeleton
- if (n->skeleton >= 0)
+ if (n->skeleton >= 0) {
continue;
+ }
if (n->get_name().is_empty()) {
if (n->mesh >= 0) {
@@ -5515,8 +5543,9 @@ T GLTFDocument::_interpolate_track(const Vector<float> &p_times, const Vector<T>
//could use binary search, worth it?
int idx = -1;
for (int i = 0; i < p_times.size(); i++) {
- if (p_times[i] > p_time)
+ if (p_times[i] > p_time) {
break;
+ }
idx++;
}
@@ -6356,13 +6385,15 @@ Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binar
//binary file
//text file
err = _parse_glb(p_path, state);
- if (err)
+ if (err) {
return FAILED;
+ }
} else {
//text file
err = _parse_json(p_path, state);
- if (err)
+ if (err) {
return FAILED;
+ }
}
f->close();
@@ -6382,68 +6413,81 @@ Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binar
/* STEP 0 PARSE SCENE */
err = _parse_scenes(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 1 PARSE NODES */
err = _parse_nodes(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 2 PARSE BUFFERS */
err = _parse_buffers(state, p_path.get_base_dir());
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 3 PARSE BUFFER VIEWS */
err = _parse_buffer_views(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 4 PARSE ACCESSORS */
err = _parse_accessors(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 5 PARSE IMAGES */
err = _parse_images(state, p_path.get_base_dir());
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 6 PARSE TEXTURES */
err = _parse_textures(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 7 PARSE TEXTURES */
err = _parse_materials(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 9 PARSE SKINS */
err = _parse_skins(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 10 DETERMINE SKELETONS */
err = _determine_skeletons(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 11 CREATE SKELETONS */
err = _create_skeletons(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 12 CREATE SKINS */
err = _create_skins(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 13 PARSE MESHES (we have enough info now) */
err = _parse_meshes(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 14 PARSE LIGHTS */
err = _parse_lights(state);
@@ -6453,13 +6497,15 @@ Error GLTFDocument::parse(Ref<GLTFState> state, String p_path, bool p_read_binar
/* STEP 15 PARSE CAMERAS */
err = _parse_cameras(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 16 PARSE ANIMATIONS */
err = _parse_animations(state);
- if (err != OK)
+ if (err != OK) {
return Error::FAILED;
+ }
/* STEP 17 ASSIGN SCENE NAMES */
_assign_scene_names(state);
diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp
index b128b81000..aaa05a910c 100644
--- a/modules/minimp3/audio_stream_mp3.cpp
+++ b/modules/minimp3/audio_stream_mp3.cpp
@@ -99,8 +99,9 @@ float AudioStreamPlaybackMP3::get_playback_position() const {
}
void AudioStreamPlaybackMP3::seek(float p_time) {
- if (!active)
+ if (!active) {
return;
+ }
if (p_time >= mp3_stream->get_length()) {
p_time = 0;
diff --git a/modules/opensimplex/doc_classes/NoiseTexture.xml b/modules/opensimplex/doc_classes/NoiseTexture.xml
index 86e7f9cc08..38c5138482 100644
--- a/modules/opensimplex/doc_classes/NoiseTexture.xml
+++ b/modules/opensimplex/doc_classes/NoiseTexture.xml
@@ -6,11 +6,12 @@
<description>
Uses an [OpenSimplexNoise] to fill the texture data. You can specify the texture size but keep in mind that larger textures will take longer to generate and seamless noise only works with square sized textures.
NoiseTexture can also generate normal map textures.
- The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_data] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the data:
+ The class uses [Thread]s to generate the texture data internally, so [method Texture2D.get_image] may return [code]null[/code] if the generation process has not completed yet. In that case, you need to wait for the texture to be generated before accessing the image and the generated byte data:
[codeblock]
var texture = preload("res://noise.tres")
yield(texture, "changed")
- var image = texture.get_data()
+ var image = texture.get_image()
+ var data = image.get_data()
[/codeblock]
</description>
<tutorials>
diff --git a/modules/opensimplex/noise_texture.cpp b/modules/opensimplex/noise_texture.cpp
index f5d401b058..7272d32fac 100644
--- a/modules/opensimplex/noise_texture.cpp
+++ b/modules/opensimplex/noise_texture.cpp
@@ -81,9 +81,9 @@ void NoiseTexture::_validate_property(PropertyInfo &property) const {
}
}
-void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
- data = p_image;
- if (data.is_valid()) {
+void NoiseTexture::_set_texture_image(const Ref<Image> &p_image) {
+ image = p_image;
+ if (image.is_valid()) {
if (texture.is_valid()) {
RID new_texture = RS::get_singleton()->texture_2d_create(p_image);
RS::get_singleton()->texture_replace(texture, new_texture);
@@ -95,7 +95,7 @@ void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
}
void NoiseTexture::_thread_done(const Ref<Image> &p_image) {
- _set_texture_data(p_image);
+ _set_texture_image(p_image);
noise_thread.wait_to_finish();
if (regen_queued) {
noise_thread.start(_thread_function, this);
@@ -159,7 +159,7 @@ void NoiseTexture::_update_texture() {
} else {
Ref<Image> image = _generate_texture();
- _set_texture_data(image);
+ _set_texture_image(image);
}
update_queued = false;
}
@@ -253,6 +253,6 @@ RID NoiseTexture::get_rid() const {
return texture;
}
-Ref<Image> NoiseTexture::get_data() const {
- return data;
+Ref<Image> NoiseTexture::get_image() const {
+ return image;
}
diff --git a/modules/opensimplex/noise_texture.h b/modules/opensimplex/noise_texture.h
index e89479d962..6983ae18fe 100644
--- a/modules/opensimplex/noise_texture.h
+++ b/modules/opensimplex/noise_texture.h
@@ -43,7 +43,7 @@ class NoiseTexture : public Texture2D {
GDCLASS(NoiseTexture, Texture2D);
private:
- Ref<Image> data;
+ Ref<Image> image;
Thread noise_thread;
@@ -66,7 +66,7 @@ private:
void _queue_update();
Ref<Image> _generate_texture();
void _update_texture();
- void _set_texture_data(const Ref<Image> &p_image);
+ void _set_texture_image(const Ref<Image> &p_image);
protected:
static void _bind_methods();
@@ -94,7 +94,7 @@ public:
virtual RID get_rid() const override;
virtual bool has_alpha() const override { return false; }
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
NoiseTexture();
virtual ~NoiseTexture();
diff --git a/modules/text_server_adv/dynamic_font_adv.cpp b/modules/text_server_adv/dynamic_font_adv.cpp
index 2521e68dda..326af7f0ee 100644
--- a/modules/text_server_adv/dynamic_font_adv.cpp
+++ b/modules/text_server_adv/dynamic_font_adv.cpp
@@ -231,7 +231,7 @@ Dictionary DynamicFontDataAdvanced::get_feature_list() const {
Dictionary out;
// Read feature flags.
- unsigned int count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, NULL, NULL);
+ unsigned int count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *feature_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, &count, feature_tags);
@@ -240,7 +240,7 @@ Dictionary DynamicFontDataAdvanced::get_feature_list() const {
}
memfree(feature_tags);
}
- count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, NULL, NULL);
+ count = hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *feature_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
hb_ot_layout_table_get_feature_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, &count, feature_tags);
@@ -639,7 +639,7 @@ bool DynamicFontDataAdvanced::is_script_supported(uint32_t p_script) const {
DataAtSize *fds = const_cast<DynamicFontDataAdvanced *>(this)->get_data_for_size(base_size);
ERR_FAIL_COND_V(fds == nullptr, false);
- unsigned int count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, NULL, NULL);
+ unsigned int count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *script_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GSUB, 0, &count, script_tags);
@@ -651,7 +651,7 @@ bool DynamicFontDataAdvanced::is_script_supported(uint32_t p_script) const {
}
memfree(script_tags);
}
- count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, NULL, NULL);
+ count = hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, nullptr, nullptr);
if (count != 0) {
hb_tag_t *script_tags = (hb_tag_t *)memalloc(count * sizeof(hb_tag_t));
hb_ot_layout_table_get_script_tags(hb_font_get_face(fds->hb_handle), HB_OT_TAG_GPOS, 0, &count, script_tags);
@@ -997,6 +997,29 @@ Vector2 DynamicFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, in
return advance;
}
+bool DynamicFontDataAdvanced::get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
+ _THREAD_SAFE_METHOD_
+ DataAtSize *fds = const_cast<DynamicFontDataAdvanced *>(this)->get_data_for_size(p_size);
+ ERR_FAIL_COND_V(fds == nullptr, false);
+
+ int error = FT_Load_Glyph(fds->face, p_index, FT_LOAD_NO_BITMAP | (force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
+ ERR_FAIL_COND_V(error, false);
+
+ r_points.clear();
+ r_contours.clear();
+
+ float h = fds->ascent;
+ float scale = (1.0 / 64.0) / oversampling * fds->scale_color_font;
+ for (short i = 0; i < fds->face->glyph->outline.n_points; i++) {
+ r_points.push_back(Vector3(fds->face->glyph->outline.points[i].x * scale, h - fds->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fds->face->glyph->outline.tags[i])));
+ }
+ for (short i = 0; i < fds->face->glyph->outline.n_contours; i++) {
+ r_contours.push_back(fds->face->glyph->outline.contours[i]);
+ }
+ r_orientation = (FT_Outline_Get_Orientation(&fds->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
+ return true;
+}
+
DynamicFontDataAdvanced::~DynamicFontDataAdvanced() {
clear_cache();
if (library != nullptr) {
diff --git a/modules/text_server_adv/dynamic_font_adv.h b/modules/text_server_adv/dynamic_font_adv.h
index d69a30b321..1292966f0c 100644
--- a/modules/text_server_adv/dynamic_font_adv.h
+++ b/modules/text_server_adv/dynamic_font_adv.h
@@ -186,6 +186,8 @@ public:
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
+ virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
+
virtual ~DynamicFontDataAdvanced() override;
};
diff --git a/modules/text_server_adv/font_adv.h b/modules/text_server_adv/font_adv.h
index 2b6d977451..4fadefc569 100644
--- a/modules/text_server_adv/font_adv.h
+++ b/modules/text_server_adv/font_adv.h
@@ -92,8 +92,8 @@ struct FontDataAdvanced {
virtual bool has_outline() const = 0;
virtual float get_base_size() const = 0;
- virtual bool is_lang_supported(const String &p_lang) const { return false; };
- virtual bool is_script_supported(uint32_t p_script) const { return false; };
+ virtual bool is_lang_supported(const String &p_lang) const { return true; };
+ virtual bool is_script_supported(uint32_t p_script) const { return true; };
virtual bool has_char(char32_t p_char) const = 0;
virtual String get_supported_chars() const = 0;
@@ -107,6 +107,8 @@ struct FontDataAdvanced {
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
+ virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { return false; };
+
virtual ~FontDataAdvanced(){};
};
diff --git a/modules/text_server_adv/script_iterator.cpp b/modules/text_server_adv/script_iterator.cpp
index 8f23bb9e02..f9bbd25a5f 100644
--- a/modules/text_server_adv/script_iterator.cpp
+++ b/modules/text_server_adv/script_iterator.cpp
@@ -75,10 +75,12 @@ ScriptIterator::ScriptIterator(const String &p_string, int p_start, int p_length
while (paren_sp >= 0 && paren_stack[paren_sp].pair_index != paired_ch) {
paren_sp -= 1;
}
- if (paren_sp < start_sp)
+ if (paren_sp < start_sp) {
start_sp = paren_sp;
- if (paren_sp >= 0)
+ }
+ if (paren_sp >= 0) {
sc = paren_stack[paren_sp].script_code;
+ }
}
}
diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp
index 43b8f18101..8b8b6b7cd3 100644
--- a/modules/text_server_adv/text_server_adv.cpp
+++ b/modules/text_server_adv/text_server_adv.cpp
@@ -906,6 +906,13 @@ Vector2 TextServerAdvanced::font_draw_glyph_outline(RID p_font, RID p_canvas, in
return fd->draw_glyph_outline(p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
}
+bool TextServerAdvanced::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataAdvanced *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, false);
+ return fd->get_glyph_contours(p_size, p_index, r_points, r_contours, r_orientation);
+}
+
float TextServerAdvanced::font_get_oversampling() const {
return oversampling;
}
@@ -1825,8 +1832,9 @@ _FORCE_INLINE_ int _generate_kashida_justification_opportunies(const String &p_d
}
}
}
- if (!is_transparent(c))
+ if (!is_transparent(c)) {
pc = c;
+ }
i++;
}
diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h
index b53b5716e5..4ad23ca059 100644
--- a/modules/text_server_adv/text_server_adv.h
+++ b/modules/text_server_adv/text_server_adv.h
@@ -188,6 +188,8 @@ public:
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
+
virtual float font_get_oversampling() const override;
virtual void font_set_oversampling(float p_oversampling) override;
diff --git a/modules/text_server_fb/dynamic_font_fb.cpp b/modules/text_server_fb/dynamic_font_fb.cpp
index 66d36bc885..dec1d6f83f 100644
--- a/modules/text_server_fb/dynamic_font_fb.cpp
+++ b/modules/text_server_fb/dynamic_font_fb.cpp
@@ -680,6 +680,29 @@ Vector2 DynamicFontDataFallback::draw_glyph_outline(RID p_canvas, int p_size, in
return advance;
}
+bool DynamicFontDataFallback::get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
+ _THREAD_SAFE_METHOD_
+ DataAtSize *fds = const_cast<DynamicFontDataFallback *>(this)->get_data_for_size(p_size);
+ ERR_FAIL_COND_V(fds == nullptr, false);
+
+ int error = FT_Load_Glyph(fds->face, p_index, FT_LOAD_NO_BITMAP | (force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0));
+ ERR_FAIL_COND_V(error, false);
+
+ r_points.clear();
+ r_contours.clear();
+
+ float h = fds->ascent;
+ float scale = (1.0 / 64.0) / oversampling * fds->scale_color_font;
+ for (short i = 0; i < fds->face->glyph->outline.n_points; i++) {
+ r_points.push_back(Vector3(fds->face->glyph->outline.points[i].x * scale, h - fds->face->glyph->outline.points[i].y * scale, FT_CURVE_TAG(fds->face->glyph->outline.tags[i])));
+ }
+ for (short i = 0; i < fds->face->glyph->outline.n_contours; i++) {
+ r_contours.push_back(fds->face->glyph->outline.contours[i]);
+ }
+ r_orientation = (FT_Outline_Get_Orientation(&fds->face->glyph->outline) == FT_ORIENTATION_FILL_RIGHT);
+ return true;
+}
+
DynamicFontDataFallback::~DynamicFontDataFallback() {
clear_cache();
if (library != nullptr) {
diff --git a/modules/text_server_fb/dynamic_font_fb.h b/modules/text_server_fb/dynamic_font_fb.h
index eb70f46666..b34c8cbed5 100644
--- a/modules/text_server_fb/dynamic_font_fb.h
+++ b/modules/text_server_fb/dynamic_font_fb.h
@@ -164,6 +164,8 @@ public:
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const override;
+ virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
+
virtual ~DynamicFontDataFallback() override;
};
diff --git a/modules/text_server_fb/font_fb.h b/modules/text_server_fb/font_fb.h
index 218f3df03a..fe9888b7f4 100644
--- a/modules/text_server_fb/font_fb.h
+++ b/modules/text_server_fb/font_fb.h
@@ -93,6 +93,8 @@ struct FontDataFallback {
virtual Vector2 draw_glyph(RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
virtual Vector2 draw_glyph_outline(RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color) const = 0;
+ virtual bool get_glyph_contours(int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const { return false; };
+
virtual ~FontDataFallback(){};
};
diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp
index f46f96d30d..98a67ef309 100644
--- a/modules/text_server_fb/text_server_fb.cpp
+++ b/modules/text_server_fb/text_server_fb.cpp
@@ -452,6 +452,13 @@ Vector2 TextServerFallback::font_draw_glyph_outline(RID p_font, RID p_canvas, in
return fd->draw_glyph_outline(p_canvas, p_size, p_outline_size, p_pos, p_index, p_color);
}
+bool TextServerFallback::font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const {
+ _THREAD_SAFE_METHOD_
+ const FontDataFallback *fd = font_owner.getornull(p_font);
+ ERR_FAIL_COND_V(!fd, false);
+ return fd->get_glyph_contours(p_size, p_index, r_points, r_contours, r_orientation);
+}
+
float TextServerFallback::font_get_oversampling() const {
return oversampling;
}
diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h
index b10369d172..8f5eb1d315 100644
--- a/modules/text_server_fb/text_server_fb.h
+++ b/modules/text_server_fb/text_server_fb.h
@@ -137,6 +137,8 @@ public:
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const override;
+ virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const override;
+
virtual float font_get_oversampling() const override;
virtual void font_set_oversampling(float p_oversampling) override;
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index e91ae46a57..6d5fff88d9 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -784,8 +784,9 @@ ScriptInstance *VisualScript::instance_create(Object *p_this) {
variables.get_key_list(&keys);
for (const List<StringName>::Element *E = keys.front(); E; E = E->next()) {
- if (!variables[E->get()]._export)
+ if (!variables[E->get()]._export) {
continue;
+ }
PropertyInfo p = variables[E->get()].info;
p.name = String(E->get());
@@ -2050,12 +2051,12 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
instance->id = F->get();
instance->input_port_count = node->get_input_value_port_count();
- instance->input_ports = NULL;
+ instance->input_ports = nullptr;
instance->output_port_count = node->get_output_value_port_count();
- instance->output_ports = NULL;
+ instance->output_ports = nullptr;
instance->sequence_output_count = node->get_output_sequence_port_count();
instance->sequence_index = function.node_count++;
- instance->sequence_outputs = NULL;
+ instance->sequence_outputs = nullptr;
instance->pass_idx = -1;
if (instance->input_port_count) {
@@ -2075,7 +2076,7 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
if (instance->sequence_output_count) {
instance->sequence_outputs = memnew_arr(VisualScriptNodeInstance *, instance->sequence_output_count);
for (int i = 0; i < instance->sequence_output_count; i++) {
- instance->sequence_outputs[i] = NULL; // If it remains null, flow ends here.
+ instance->sequence_outputs[i] = nullptr; // If it remains null, flow ends here.
}
}
@@ -2085,10 +2086,11 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
StringName var_name;
- if (Object::cast_to<VisualScriptLocalVar>(*node))
+ if (Object::cast_to<VisualScriptLocalVar>(*node)) {
var_name = String(Object::cast_to<VisualScriptLocalVar>(*node)->get_var_name()).strip_edges();
- else
+ } else {
var_name = String(Object::cast_to<VisualScriptLocalVarSet>(*node)->get_var_name()).strip_edges();
+ }
if (!local_var_indices.has(var_name)) {
local_var_indices[var_name] = function.max_stack;
@@ -2252,6 +2254,7 @@ Variant VisualScriptFunctionState::_signal_callback(const Variant **p_args, int
}
void VisualScriptFunctionState::connect_to_signal(Object *p_obj, const String &p_signal, Array p_binds) {
+ ERR_FAIL_NULL(p_obj);
Vector<Variant> binds;
for (int i = 0; i < p_binds.size(); i++) {
binds.push_back(p_binds[i]);
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index d520837d43..3cdf60708b 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1826,6 +1826,8 @@ void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool n
}
void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
// GUI input for VS Editor Plugin
Ref<InputEventMouseButton> key = p_event;
@@ -3015,9 +3017,9 @@ void VisualScriptEditor::_graph_connect_to_empty(const String &p_from, int p_fro
if (!vsn.is_valid()) {
return;
}
- if (vsn->get_output_value_port_count())
-
+ if (vsn->get_output_value_port_count()) {
port_action_pos = p_release_pos;
+ }
if (p_from_slot < vsn->get_output_sequence_port_count()) {
port_action_node = p_from.to_int();
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml
index 45db49c913..d362bcc10f 100644
--- a/modules/websocket/doc_classes/WebSocketClient.xml
+++ b/modules/websocket/doc_classes/WebSocketClient.xml
@@ -28,6 +28,7 @@
If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI], connections to non-Godot servers will not work, and [signal data_received] will not be emitted.
If [code]false[/code] is passed instead (default), you must call [PacketPeer] functions ([code]put_packet[/code], [code]get_packet[/code], etc.) on the [WebSocketPeer] returned via [code]get_peer(1)[/code] and not on this object directly (e.g. [code]get_peer(1).put_packet(data)[/code]).
You can optionally pass a list of [code]custom_headers[/code] to be added to the handshake HTTP request.
+ [b]Note:[/b] To avoid mixed content warnings or errors in HTML5, you may have to use a [code]url[/code] that starts with [code]wss://[/code] (secure) instead of [code]ws://[/code]. When doing so, make sure to use the fully qualified domain name that matches the one defined in the server's SSL certificate. Do not connect directly via the IP address for [code]wss://[/code] connections, as it won't match with the SSL certificate.
[b]Note:[/b] Specifying [code]custom_headers[/code] is not supported in HTML5 exports due to browsers restrictions.
</description>
</method>
diff --git a/modules/webxr/webxr_interface.h b/modules/webxr/webxr_interface.h
index c5b2dc8d73..366235fcd5 100644
--- a/modules/webxr/webxr_interface.h
+++ b/modules/webxr/webxr_interface.h
@@ -57,7 +57,7 @@ public:
virtual void set_requested_reference_space_types(String p_requested_reference_space_types) = 0;
virtual String get_requested_reference_space_types() const = 0;
virtual String get_reference_space_type() const = 0;
- virtual XRPositionalTracker *get_controller(int p_controller_id) const = 0;
+ virtual Ref<XRPositionalTracker> get_controller(int p_controller_id) const = 0;
virtual String get_visibility_state() const = 0;
virtual PackedVector3Array get_bounds_geometry() const = 0;
};
diff --git a/modules/webxr/webxr_interface_js.cpp b/modules/webxr/webxr_interface_js.cpp
index 10076327e2..4dce2c2b23 100644
--- a/modules/webxr/webxr_interface_js.cpp
+++ b/modules/webxr/webxr_interface_js.cpp
@@ -160,7 +160,7 @@ String WebXRInterfaceJS::get_reference_space_type() const {
return reference_space_type;
}
-XRPositionalTracker *WebXRInterfaceJS::get_controller(int p_controller_id) const {
+Ref<XRPositionalTracker> WebXRInterfaceJS::get_controller(int p_controller_id) const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, nullptr);
@@ -380,10 +380,10 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1);
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, p_controller_id + 1);
if (godot_webxr_is_controller_connected(p_controller_id)) {
- if (tracker == nullptr) {
- tracker = memnew(XRPositionalTracker);
+ if (tracker.is_null()) {
+ tracker.instance();
tracker->set_tracker_type(XRServer::TRACKER_CONTROLLER);
// Controller id's 0 and 1 are always the left and right hands.
if (p_controller_id < 2) {
@@ -423,7 +423,7 @@ void WebXRInterfaceJS::_update_tracker(int p_controller_id) {
}
free(axes);
}
- } else if (tracker) {
+ } else if (tracker.is_valid()) {
xr_server->remove_tracker(tracker);
}
}
diff --git a/modules/webxr/webxr_interface_js.h b/modules/webxr/webxr_interface_js.h
index 49299b252f..7c841c1911 100644
--- a/modules/webxr/webxr_interface_js.h
+++ b/modules/webxr/webxr_interface_js.h
@@ -71,7 +71,7 @@ public:
virtual String get_requested_reference_space_types() const override;
void _set_reference_space_type(String p_reference_space_type);
virtual String get_reference_space_type() const override;
- virtual XRPositionalTracker *get_controller(int p_controller_id) const override;
+ virtual Ref<XRPositionalTracker> get_controller(int p_controller_id) const override;
virtual String get_visibility_state() const override;
virtual PackedVector3Array get_bounds_geometry() const override;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 326e513261..5f9f420b59 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -2262,8 +2262,9 @@ public:
CharString command_line_argument = command_line_strings[i].utf8();
int base = r_command_line_flags.size();
int length = command_line_argument.length();
- if (length == 0)
+ if (length == 0) {
continue;
+ }
r_command_line_flags.resize(base + 4 + length);
encode_uint32(length, &r_command_line_flags.write[base]);
copymem(&r_command_line_flags.write[base + 4], command_line_argument.ptr(), length);
@@ -2484,7 +2485,7 @@ public:
_clear_assets_directory();
if (!apk_expansion) {
print_verbose("Exporting project files..");
- err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, NULL, ignore_so_file);
+ err = export_project_files(p_preset, rename_and_store_file_in_gradle_project, nullptr, ignore_so_file);
if (err != OK) {
EditorNode::add_io_error("Could not export project files to gradle project\n");
return err;
@@ -2615,10 +2616,11 @@ public:
}
// This is the start of the Legacy build system
print_verbose("Starting legacy build system..");
- if (p_debug)
+ if (p_debug) {
src_apk = p_preset->get("custom_template/debug");
- else
+ } else {
src_apk = p_preset->get("custom_template/release");
+ }
src_apk = src_apk.strip_edges();
if (src_apk == "") {
if (p_debug) {
@@ -2813,11 +2815,11 @@ public:
zipOpenNewFileInZip(unaligned_apk,
"assets/_cl_",
&zipfi,
- NULL,
+ nullptr,
0,
- NULL,
+ nullptr,
0,
- NULL,
+ nullptr,
0, // No compress (little size gain and potentially slower startup)
Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(unaligned_apk, command_line_flags.ptr(), command_line_flags.size());
diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h
index 097a2391ee..40b8e90c6f 100644
--- a/platform/android/export/gradle_export_util.h
+++ b/platform/android/export/gradle_export_util.h
@@ -47,20 +47,21 @@ const String godot_project_name_xml_string = R"(<?xml version="1.0" encoding="ut
DisplayServer::ScreenOrientation _get_screen_orientation() {
String orientation_settings = ProjectSettings::get_singleton()->get("display/window/handheld/orientation");
DisplayServer::ScreenOrientation screen_orientation;
- if (orientation_settings == "portrait")
+ if (orientation_settings == "portrait") {
screen_orientation = DisplayServer::SCREEN_PORTRAIT;
- else if (orientation_settings == "reverse_landscape")
+ } else if (orientation_settings == "reverse_landscape") {
screen_orientation = DisplayServer::SCREEN_REVERSE_LANDSCAPE;
- else if (orientation_settings == "reverse_portrait")
+ } else if (orientation_settings == "reverse_portrait") {
screen_orientation = DisplayServer::SCREEN_REVERSE_PORTRAIT;
- else if (orientation_settings == "sensor_landscape")
+ } else if (orientation_settings == "sensor_landscape") {
screen_orientation = DisplayServer::SCREEN_SENSOR_LANDSCAPE;
- else if (orientation_settings == "sensor_portrait")
+ } else if (orientation_settings == "sensor_portrait") {
screen_orientation = DisplayServer::SCREEN_SENSOR_PORTRAIT;
- else if (orientation_settings == "sensor")
+ } else if (orientation_settings == "sensor") {
screen_orientation = DisplayServer::SCREEN_SENSOR;
- else
+ } else {
screen_orientation = DisplayServer::SCREEN_LANDSCAPE;
+ }
return screen_orientation;
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
index ec2ace4821..4eac2d08d1 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java
@@ -34,7 +34,6 @@ import android.content.Intent;
import android.os.Bundle;
import android.view.KeyEvent;
-import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.FragmentActivity;
@@ -63,30 +62,9 @@ public abstract class FullScreenGodotApp extends FragmentActivity implements God
@Override
public void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
if (godotFragment != null) {
godotFragment.onNewIntent(intent);
- } else {
- super.onNewIntent(intent);
- }
- }
-
- @CallSuper
- @Override
- public void onActivityResult(int requestCode, int resultCode, Intent data) {
- if (godotFragment != null) {
- godotFragment.onActivityResult(requestCode, resultCode, data);
- } else {
- super.onActivityResult(requestCode, resultCode, data);
- }
- }
-
- @CallSuper
- @Override
- public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
- if (godotFragment != null) {
- godotFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
- } else {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
diff --git a/platform/javascript/display_server_javascript.cpp b/platform/javascript/display_server_javascript.cpp
index c10fb40ecb..fa6f5c1e9e 100644
--- a/platform/javascript/display_server_javascript.cpp
+++ b/platform/javascript/display_server_javascript.cpp
@@ -341,7 +341,7 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso
Rect2 atlas_rect;
if (texture.is_valid()) {
- image = texture->get_data();
+ image = texture->get_image();
}
if (!image.is_valid() && atlas_texture.is_valid()) {
@@ -364,7 +364,7 @@ void DisplayServerJavaScript::cursor_set_custom_image(const RES &p_cursor, Curso
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
- image = texture->get_data();
+ image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 1e89e144cc..3f04bedea2 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -550,7 +550,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese
if (f) {
file_sizes[pck_path.get_file()] = (uint64_t)f->get_len();
memdelete(f);
- f = NULL;
+ f = nullptr;
}
_fix_html(html, p_preset, p_path.get_file().get_basename(), p_debug, p_flags, shared_objects, file_sizes);
f = FileAccess::open(p_path, FileAccess::WRITE);
diff --git a/platform/javascript/godot_js.h b/platform/javascript/godot_js.h
index 4448a35670..8927a83cb3 100644
--- a/platform/javascript/godot_js.h
+++ b/platform/javascript/godot_js.h
@@ -71,6 +71,7 @@ extern int godot_js_display_fullscreen_exit();
extern void godot_js_display_compute_position(int p_x, int p_y, int32_t *r_x, int32_t *r_y);
extern void godot_js_display_window_title_set(const char *p_text);
extern void godot_js_display_window_icon_set(const uint8_t *p_ptr, int p_len);
+extern int godot_js_display_has_webgl(int p_version);
// Display clipboard
extern int godot_js_display_clipboard_set(const char *p_text);
diff --git a/platform/javascript/js/engine/engine.js b/platform/javascript/js/engine/engine.js
index 7211ebbfd8..17a8df9e29 100644
--- a/platform/javascript/js/engine/engine.js
+++ b/platform/javascript/js/engine/engine.js
@@ -101,19 +101,23 @@ const Engine = (function () {
}
const me = this;
function doInit(promise) {
- return promise.then(function (response) {
- return Godot(me.config.getModuleConfig(loadPath, new Response(response.clone().body, { 'headers': [['content-type', 'application/wasm']] })));
- }).then(function (module) {
- const paths = me.config.persistentPaths;
- return module['initFS'](paths).then(function (err) {
- return Promise.resolve(module);
+ // Care! Promise chaining is bogus with old emscripten versions.
+ // This caused a regression with the Mono build (which uses an older emscripten version).
+ // Make sure to test that when refactoring.
+ return new Promise(function (resolve, reject) {
+ promise.then(function (response) {
+ const cloned = new Response(response.clone().body, { 'headers': [['content-type', 'application/wasm']] });
+ Godot(me.config.getModuleConfig(loadPath, cloned)).then(function (module) {
+ const paths = me.config.persistentPaths;
+ module['initFS'](paths).then(function (err) {
+ me.rtenv = module;
+ if (me.config.unloadAfterInit) {
+ Engine.unload();
+ }
+ resolve();
+ });
+ });
});
- }).then(function (module) {
- me.rtenv = module;
- if (me.config.unloadAfterInit) {
- Engine.unload();
- }
- return Promise.resolve();
});
}
preloader.setProgressFunc(this.config.onProgress);
diff --git a/platform/javascript/js/engine/preloader.js b/platform/javascript/js/engine/preloader.js
index 3535fdb361..564c68d264 100644
--- a/platform/javascript/js/engine/preloader.js
+++ b/platform/javascript/js/engine/preloader.js
@@ -1,22 +1,5 @@
const Preloader = /** @constructor */ function () { // eslint-disable-line no-unused-vars
function getTrackedResponse(response, load_status) {
- let clen = 0;
- let compressed = false;
- response.headers.forEach(function (value, header) {
- const h = header.toLowerCase().trim();
- // We can't accurately compute compressed stream length.
- if (h === 'content-encoding') {
- compressed = true;
- } else if (h === 'content-length') {
- const length = parseInt(value, 10);
- if (!Number.isNaN(length) && length > 0) {
- clen = length;
- }
- }
- });
- if (!compressed && clen) {
- load_status.total = clen;
- }
function onloadprogress(reader, controller) {
return reader.read().then(function (result) {
if (load_status.done) {
diff --git a/platform/javascript/js/libs/library_godot_display.js b/platform/javascript/js/libs/library_godot_display.js
index 99aa4793d9..91cab5eacc 100644
--- a/platform/javascript/js/libs/library_godot_display.js
+++ b/platform/javascript/js/libs/library_godot_display.js
@@ -719,6 +719,17 @@ const GodotDisplay = {
GodotRuntime.setHeapValue(r_y, (y - rect.y) * rh, 'i32');
},
+ godot_js_display_has_webgl__sig: 'ii',
+ godot_js_display_has_webgl: function (p_version) {
+ if (p_version !== 1 && p_version !== 2) {
+ return false;
+ }
+ try {
+ return !!document.createElement('canvas').getContext(p_version === 2 ? 'webgl2' : 'webgl');
+ } catch (e) { /* Not available */ }
+ return false;
+ },
+
/*
* Canvas
*/
@@ -858,7 +869,7 @@ const GodotDisplay = {
const notif = [p_enter, p_exit, p_in, p_out];
['mouseover', 'mouseleave', 'focus', 'blur'].forEach(function (evt_name, idx) {
GodotDisplayListeners.add(canvas, evt_name, function () {
- func.bind(null, notif[idx]);
+ func(notif[idx]);
}, true);
});
},
diff --git a/platform/javascript/js/libs/library_godot_fetch.js b/platform/javascript/js/libs/library_godot_fetch.js
index 4ae6a23593..de5ae2b1ae 100644
--- a/platform/javascript/js/libs/library_godot_fetch.js
+++ b/platform/javascript/js/libs/library_godot_fetch.js
@@ -49,25 +49,14 @@ const GodotFetch = {
if (!obj) {
return;
}
- let size = -1;
- let compressed = false;
let chunked = false;
response.headers.forEach(function (value, header) {
const v = value.toLowerCase().trim();
const h = header.toLowerCase().trim();
- if (h === 'content-encoding') {
- compressed = true;
- size = -1;
- } else if (h === 'content-length') {
- const len = Number.parseInt(value, 10);
- if (!Number.isNaN(len) && !compressed) {
- size = len;
- }
- } else if (h === 'transfer-encoding' && v === 'chunked') {
+ if (h === 'transfer-encoding' && v === 'chunked') {
chunked = true;
}
});
- obj.bodySize = size;
obj.status = response.status;
obj.response = response;
obj.reader = response.body.getReader();
diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp
index 27b9d9485a..8dc1b41702 100644
--- a/platform/linuxbsd/display_server_x11.cpp
+++ b/platform/linuxbsd/display_server_x11.cpp
@@ -1917,7 +1917,7 @@ void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape
Rect2i atlas_rect;
if (texture.is_valid()) {
- image = texture->get_data();
+ image = texture->get_image();
}
if (!image.is_valid() && atlas_texture.is_valid()) {
@@ -1940,7 +1940,7 @@ void DisplayServerX11::cursor_set_custom_image(const RES &p_cursor, CursorShape
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
- image = texture->get_data();
+ image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
@@ -2012,7 +2012,7 @@ int DisplayServerX11::keyboard_get_layout_count() const {
XkbGetNames(x11_display, XkbSymbolsNameMask, kbd);
const Atom *groups = kbd->names->groups;
- if (kbd->ctrls != NULL) {
+ if (kbd->ctrls != nullptr) {
_group_count = kbd->ctrls->num_groups;
} else {
while (_group_count < XkbNumKbdGroups && groups[_group_count] != None) {
@@ -2046,7 +2046,7 @@ String DisplayServerX11::keyboard_get_layout_language(int p_index) const {
int _group_count = 0;
const Atom *groups = kbd->names->groups;
- if (kbd->ctrls != NULL) {
+ if (kbd->ctrls != nullptr) {
_group_count = kbd->ctrls->num_groups;
} else {
while (_group_count < XkbNumKbdGroups && groups[_group_count] != None) {
@@ -2085,7 +2085,7 @@ String DisplayServerX11::keyboard_get_layout_name(int p_index) const {
int _group_count = 0;
const Atom *groups = kbd->names->groups;
- if (kbd->ctrls != NULL) {
+ if (kbd->ctrls != nullptr) {
_group_count = kbd->ctrls->num_groups;
} else {
while (_group_count < XkbNumKbdGroups && groups[_group_count] != None) {
@@ -2684,7 +2684,7 @@ bool DisplayServerX11::_wait_for_events() const {
tv.tv_sec = 1;
// Wait for next event or timeout.
- int num_ready_fds = select(x11_fd + 1, &in_fds, NULL, NULL, &tv);
+ int num_ready_fds = select(x11_fd + 1, &in_fds, nullptr, nullptr, &tv);
if (num_ready_fds > 0) {
// Event received.
diff --git a/platform/linuxbsd/joypad_linux.cpp b/platform/linuxbsd/joypad_linux.cpp
index 8ea0f6c246..e8f4352dff 100644
--- a/platform/linuxbsd/joypad_linux.cpp
+++ b/platform/linuxbsd/joypad_linux.cpp
@@ -178,17 +178,18 @@ void JoypadLinux::monitor_joypads(udev *p_udev) {
select() ensured that this will not block. */
dev = udev_monitor_receive_device(mon);
- if (dev && udev_device_get_devnode(dev) != 0) {
+ if (dev && udev_device_get_devnode(dev) != nullptr) {
MutexLock lock(joy_mutex);
String action = udev_device_get_action(dev);
const char *devnode = udev_device_get_devnode(dev);
if (devnode) {
String devnode_str = devnode;
if (devnode_str.find(ignore_str) == -1) {
- if (action == "add")
+ if (action == "add") {
open_joypad(devnode);
- else if (String(action) == "remove")
+ } else if (String(action) == "remove") {
close_joypad(get_joy_from_path(devnode));
+ }
}
}
@@ -212,7 +213,7 @@ void JoypadLinux::monitor_joypads() {
struct dirent *current;
char fname[64];
- while ((current = readdir(input_directory)) != NULL) {
+ while ((current = readdir(input_directory)) != nullptr) {
if (strncmp(current->d_name, "event", 5) != 0) {
continue;
}
diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm
index 412dd59f56..6b838b6d14 100644
--- a/platform/osx/display_server_osx.mm
+++ b/platform/osx/display_server_osx.mm
@@ -3117,7 +3117,7 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape
Rect2 atlas_rect;
if (texture.is_valid()) {
- image = texture->get_data();
+ image = texture->get_image();
}
if (!image.is_valid() && atlas_texture.is_valid()) {
@@ -3140,7 +3140,7 @@ void DisplayServerOSX::cursor_set_custom_image(const RES &p_cursor, CursorShape
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
- image = texture->get_data();
+ image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 6ac98cae9c..aca9471849 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -155,7 +155,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), ""));
#ifdef OSX_ENABLED
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_PLACEHOLDER_TEXT, "Type: Name (ID)"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/hardened_runtime"), true));
@@ -487,7 +487,11 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
}
args.push_back("-s");
- args.push_back(p_preset->get("codesign/identity"));
+ if (p_preset->get("codesign/identity") == "") {
+ args.push_back("-");
+ } else {
+ args.push_back(p_preset->get("codesign/identity"));
+ }
args.push_back("-v"); /* provide some more feedback */
@@ -1060,12 +1064,6 @@ bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset
}
bool sign_enabled = p_preset->get("codesign/enable");
- if (sign_enabled) {
- if (p_preset->get("codesign/identity") == "") {
- err += TTR("Codesign: identity not specified.") + "\n";
- valid = false;
- }
- }
bool noto_enabled = p_preset->get("notarization/enable");
if (noto_enabled) {
if (!sign_enabled) {
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index 1aad2bfa1a..2a0bc78440 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -855,33 +855,33 @@ class EditorExportPlatformUWP : public EditorExportPlatform {
Vector<uint8_t> _get_image_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
Vector<uint8_t> data;
- StreamTexture2D *image = nullptr;
+ StreamTexture2D *texture = nullptr;
if (p_path.find("StoreLogo") != -1) {
- image = p_preset->get("images/store_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/store_logo")));
+ texture = p_preset->get("images/store_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/store_logo")));
} else if (p_path.find("Square44x44Logo") != -1) {
- image = p_preset->get("images/square44x44_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square44x44_logo")));
+ texture = p_preset->get("images/square44x44_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square44x44_logo")));
} else if (p_path.find("Square71x71Logo") != -1) {
- image = p_preset->get("images/square71x71_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square71x71_logo")));
+ texture = p_preset->get("images/square71x71_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square71x71_logo")));
} else if (p_path.find("Square150x150Logo") != -1) {
- image = p_preset->get("images/square150x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square150x150_logo")));
+ texture = p_preset->get("images/square150x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square150x150_logo")));
} else if (p_path.find("Square310x310Logo") != -1) {
- image = p_preset->get("images/square310x310_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square310x310_logo")));
+ texture = p_preset->get("images/square310x310_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/square310x310_logo")));
} else if (p_path.find("Wide310x150Logo") != -1) {
- image = p_preset->get("images/wide310x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/wide310x150_logo")));
+ texture = p_preset->get("images/wide310x150_logo").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/wide310x150_logo")));
} else if (p_path.find("SplashScreen") != -1) {
- image = p_preset->get("images/splash_screen").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/splash_screen")));
+ texture = p_preset->get("images/splash_screen").is_zero() ? nullptr : Object::cast_to<StreamTexture2D>(((Object *)p_preset->get("images/splash_screen")));
} else {
ERR_PRINT("Unable to load logo");
}
- if (!image) {
+ if (!texture) {
return data;
}
String tmp_path = EditorSettings::get_singleton()->get_cache_dir().plus_file("uwp_tmp_logo.png");
- Error err = image->get_data()->save_png(tmp_path);
+ Error err = texture->get_image()->save_png(tmp_path);
if (err != OK) {
String err_string = "Couldn't save temp logo file.";
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index 4d81afc5dd..86f20f1dd7 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -1299,7 +1299,7 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh
Rect2 atlas_rect;
if (texture.is_valid()) {
- image = texture->get_data();
+ image = texture->get_image();
}
if (!image.is_valid() && atlas_texture.is_valid()) {
@@ -1322,7 +1322,7 @@ void DisplayServerWindows::cursor_set_custom_image(const RES &p_cursor, CursorSh
ERR_FAIL_COND(texture_size.width > 256 || texture_size.height > 256);
ERR_FAIL_COND(p_hotspot.x > texture_size.width || p_hotspot.y > texture_size.height);
- image = texture->get_data();
+ image = texture->get_image();
ERR_FAIL_COND(!image.is_valid());
@@ -2566,6 +2566,8 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
windows[window_id].preserve_window_size = false;
window_set_size(Size2(windows[window_id].width, windows[window_id].height), window_id);
}
+ } else {
+ windows[window_id].preserve_window_size = true;
}
if (!windows[window_id].rect_changed_callback.is_null()) {
diff --git a/scene/2d/animated_sprite_2d.cpp b/scene/2d/animated_sprite_2d.cpp
index dfc08583f2..4aa079b013 100644
--- a/scene/2d/animated_sprite_2d.cpp
+++ b/scene/2d/animated_sprite_2d.cpp
@@ -382,12 +382,11 @@ bool AnimatedSprite2D::_is_playing() const {
}
void AnimatedSprite2D::play(const StringName &p_animation, const bool p_backwards) {
- ERR_FAIL_NULL_MSG(frames, "Can't play AnimatedSprite2D without a valid SpriteFrames resource.");
backwards = p_backwards;
if (p_animation) {
set_animation(p_animation);
- if (backwards && get_frame() == 0) {
+ if (frames.is_valid() && backwards && get_frame() == 0) {
set_frame(frames->get_frame_count(p_animation) - 1);
}
}
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 9d6868a1b2..4e58984b37 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -189,6 +189,8 @@ String TouchScreenButton::get_action() const {
}
void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!get_tree()) {
return;
}
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index be62fe801f..db5fc7593e 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -439,6 +439,17 @@ String Skeleton3D::get_bone_name(int p_bone) const {
return bones[p_bone].name;
}
+void Skeleton3D::set_bone_name(int p_bone, const String &p_name) {
+ ERR_FAIL_INDEX(p_bone, bones.size());
+
+ for (int i = 0; i < bones.size(); i++) {
+ if (i != p_bone) {
+ ERR_FAIL_COND(bones[i].name == p_name);
+ }
+ }
+
+ bones.write[p_bone].name = p_name;
+}
bool Skeleton3D::is_bone_parent_of(int p_bone, int p_parent_bone_id) const {
int parent_of_bone = get_bone_parent(p_bone);
@@ -869,6 +880,7 @@ void Skeleton3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_bone", "name"), &Skeleton3D::add_bone);
ClassDB::bind_method(D_METHOD("find_bone", "name"), &Skeleton3D::find_bone);
ClassDB::bind_method(D_METHOD("get_bone_name", "bone_idx"), &Skeleton3D::get_bone_name);
+ ClassDB::bind_method(D_METHOD("set_bone_name", "bone_idx", "name"), &Skeleton3D::set_bone_name);
ClassDB::bind_method(D_METHOD("get_bone_parent", "bone_idx"), &Skeleton3D::get_bone_parent);
ClassDB::bind_method(D_METHOD("set_bone_parent", "bone_idx", "parent_idx"), &Skeleton3D::set_bone_parent);
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 9772bfcc95..2941ac2c45 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -143,6 +143,7 @@ public:
void add_bone(const String &p_name);
int find_bone(const String &p_name) const;
String get_bone_name(int p_bone) const;
+ void set_bone_name(int p_bone, const String &p_name);
bool is_bone_parent_of(int p_bone_id, int p_parent_bone_id) const;
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index 85da546430..6cde6a9b17 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -255,9 +255,22 @@ void FabrikInverseKinematic::make_goal(Task *p_task, const Transform &p_inverse_
void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position) {
if (blending_delta <= 0.01f) {
+ // Before skipping, make sure we undo the global pose overrides
+ ChainItem *ci(&p_task->chain.chain_root);
+ while (ci) {
+ p_task->skeleton->set_bone_global_pose_override(ci->bone, ci->initial_transform, 0.0, false);
+
+ if (!ci->children.is_empty()) {
+ ci = &ci->children.write[0];
+ } else {
+ ci = nullptr;
+ }
+ }
+
return; // Skip solving
}
+ // This line below is part of the problem - removing it fixes the issue with BoneAttachment nodes...
p_task->skeleton->set_bone_global_pose_override(p_task->chain.chain_root.bone, Transform(), 0.0, true);
if (p_task->chain.middle_chain_item) {
@@ -268,9 +281,9 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
p_task->skeleton->set_bone_global_pose_override(p_task->chain.tips[i].chain_item->bone, Transform(), 0.0, true);
}
- // Update the initial root transform
- p_task->chain.chain_root.initial_transform = p_task->skeleton->get_bone_global_pose(p_task->chain.chain_root.bone);
- p_task->chain.chain_root.current_pos = p_task->chain.chain_root.initial_transform.origin;
+ // Update the transforms to their global poses
+ // (Needed to sync IK with animation)
+ _update_chain(p_task->skeleton, &p_task->chain.chain_root);
make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse(), blending_delta);
@@ -286,22 +299,48 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
Transform new_bone_pose(ci->initial_transform);
new_bone_pose.origin = ci->current_pos;
- if (!ci->children.is_empty()) {
- /// Rotate basis
- const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
- const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
-
- if (rot_axis[0] != 0 && rot_axis[1] != 0 && rot_axis[2] != 0) {
- const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1)));
- new_bone_pose.basis.rotate(rot_axis, rot_angle);
+ // The root bone needs to be rotated differently so it isn't frozen in place.
+ if (ci == &p_task->chain.chain_root && !ci->children.is_empty()) {
+ new_bone_pose = new_bone_pose.looking_at(ci->children[0].current_pos);
+ const Vector3 bone_rest_dir = p_task->skeleton->get_bone_rest(ci->children[0].bone).origin.normalized().abs();
+ const Vector3 bone_rest_dir_abs = bone_rest_dir.abs();
+ if (bone_rest_dir_abs.x > bone_rest_dir_abs.y && bone_rest_dir_abs.x > bone_rest_dir_abs.z) {
+ if (bone_rest_dir.x < 0) {
+ new_bone_pose.basis.rotate_local(Vector3(0, 1, 0), -Math_PI / 2.0f);
+ } else {
+ new_bone_pose.basis.rotate_local(Vector3(0, 1, 0), Math_PI / 2.0f);
+ }
+ } else if (bone_rest_dir_abs.y > bone_rest_dir_abs.x && bone_rest_dir_abs.y > bone_rest_dir_abs.z) {
+ if (bone_rest_dir.y < 0) {
+ new_bone_pose.basis.rotate_local(Vector3(1, 0, 0), Math_PI / 2.0f);
+ } else {
+ new_bone_pose.basis.rotate_local(Vector3(1, 0, 0), -Math_PI / 2.0f);
+ }
+ } else {
+ if (bone_rest_dir.z < 0) {
+ // Do nothing!
+ } else {
+ new_bone_pose.basis.rotate_local(Vector3(0, 0, 1), Math_PI);
+ }
}
-
} else {
- // Set target orientation to tip
- if (override_tip_basis) {
- new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis;
+ if (!ci->children.is_empty()) {
+ /// Rotate basis
+ const Vector3 initial_ori((ci->children[0].initial_transform.origin - ci->initial_transform.origin).normalized());
+ const Vector3 rot_axis(initial_ori.cross(ci->current_ori).normalized());
+
+ if (rot_axis[0] != 0 && rot_axis[1] != 0 && rot_axis[2] != 0) {
+ const real_t rot_angle(Math::acos(CLAMP(initial_ori.dot(ci->current_ori), -1, 1)));
+ new_bone_pose.basis.rotate(rot_axis, rot_angle);
+ }
+
} else {
- new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
+ // Set target orientation to tip
+ if (override_tip_basis) {
+ new_bone_pose.basis = p_task->chain.tips[0].end_effector->goal_transform.basis;
+ } else {
+ new_bone_pose.basis = new_bone_pose.basis * p_task->chain.tips[0].end_effector->goal_transform.basis;
+ }
}
}
@@ -319,6 +358,20 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
}
}
+void FabrikInverseKinematic::_update_chain(const Skeleton3D *p_sk, ChainItem *p_chain_item) {
+ if (!p_chain_item) {
+ return;
+ }
+
+ p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
+ p_chain_item->current_pos = p_chain_item->initial_transform.origin;
+
+ ChainItem *items = p_chain_item->children.ptrw();
+ for (int i = 0; i < p_chain_item->children.size(); i += 1) {
+ _update_chain(p_sk, items + i);
+ }
+}
+
void SkeletonIK3D::_validate_property(PropertyInfo &property) const {
if (property.name == "root_bone" || property.name == "tip_bone") {
if (skeleton) {
diff --git a/scene/3d/skeleton_ik_3d.h b/scene/3d/skeleton_ik_3d.h
index c98f55804c..9255e18b72 100644
--- a/scene/3d/skeleton_ik_3d.h
+++ b/scene/3d/skeleton_ik_3d.h
@@ -118,6 +118,8 @@ public:
static void set_goal(Task *p_task, const Transform &p_goal);
static void make_goal(Task *p_task, const Transform &p_inverse_transf, real_t blending_delta);
static void solve(Task *p_task, real_t blending_delta, bool override_tip_basis, bool p_use_magnet, const Vector3 &p_magnet_position);
+
+ static void _update_chain(const Skeleton3D *p_skeleton, ChainItem *p_chain_item);
};
class SkeletonIK3D : public Node {
diff --git a/scene/3d/sprite_3d.h b/scene/3d/sprite_3d.h
index b48660eb2d..d1bc8dc737 100644
--- a/scene/3d/sprite_3d.h
+++ b/scene/3d/sprite_3d.h
@@ -203,8 +203,8 @@ class AnimatedSprite3D : public SpriteBase3D {
float timeout = 0.0;
- bool hflip = 1;
- bool vflip = 1;
+ bool hflip = true;
+ bool vflip = true;
Color modulate;
diff --git a/scene/3d/voxelizer.cpp b/scene/3d/voxelizer.cpp
index 16718b956f..1b9ce0201f 100644
--- a/scene/3d/voxelizer.cpp
+++ b/scene/3d/voxelizer.cpp
@@ -344,7 +344,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
Ref<Image> img_albedo;
if (albedo_tex.is_valid()) {
- img_albedo = albedo_tex->get_data();
+ img_albedo = albedo_tex->get_image();
mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo(), Color(0, 0, 0)); // albedo texture, color is multiplicative
} else {
mc.albedo = _get_bake_texture(img_albedo, Color(1, 1, 1), mat->get_albedo()); // no albedo texture, color is additive
@@ -358,7 +358,7 @@ Voxelizer::MaterialCache Voxelizer::_get_material_cache(Ref<Material> p_material
Ref<Image> img_emission;
if (emission_tex.is_valid()) {
- img_emission = emission_tex->get_data();
+ img_emission = emission_tex->get_image();
}
if (mat->get_emission_operator() == StandardMaterial3D::EMISSION_OP_ADD) {
diff --git a/scene/3d/xr_nodes.cpp b/scene/3d/xr_nodes.cpp
index 7fed34c7c6..63be4352d5 100644
--- a/scene/3d/xr_nodes.cpp
+++ b/scene/3d/xr_nodes.cpp
@@ -190,8 +190,8 @@ void XRController3D::_notification(int p_what) {
ERR_FAIL_NULL(xr_server);
// find the tracker for our controller
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (!tracker.is_valid()) {
// this controller is currently turned off
is_active = false;
button_states = 0;
@@ -277,8 +277,8 @@ String XRController3D::get_controller_name() const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String());
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (!tracker.is_valid()) {
return String("Not connected");
};
@@ -290,8 +290,8 @@ int XRController3D::get_joystick_id() const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (!tracker.is_valid()) {
// No tracker? no joystick id... (0 is our first joystick)
return -1;
};
@@ -322,8 +322,8 @@ real_t XRController3D::get_rumble() const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, 0.0);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (!tracker.is_valid()) {
return 0.0;
};
@@ -335,8 +335,8 @@ void XRController3D::set_rumble(real_t p_rumble) {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL(xr_server);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker != nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (tracker.is_valid()) {
tracker->set_rumble(p_rumble);
};
};
@@ -354,8 +354,8 @@ XRPositionalTracker::TrackerHand XRController3D::get_tracker_hand() const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, XRPositionalTracker::TRACKER_HAND_UNKNOWN);
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_CONTROLLER, controller_id);
+ if (!tracker.is_valid()) {
return XRPositionalTracker::TRACKER_HAND_UNKNOWN;
};
@@ -404,8 +404,8 @@ void XRAnchor3D::_notification(int p_what) {
ERR_FAIL_NULL(xr_server);
// find the tracker for our anchor
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
+ if (!tracker.is_valid()) {
// this anchor is currently not available
is_active = false;
} else {
@@ -475,8 +475,8 @@ String XRAnchor3D::get_anchor_name() const {
XRServer *xr_server = XRServer::get_singleton();
ERR_FAIL_NULL_V(xr_server, String());
- XRPositionalTracker *tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
- if (tracker == nullptr) {
+ Ref<XRPositionalTracker> tracker = xr_server->find_by_type_and_id(XRServer::TRACKER_ANCHOR, anchor_id);
+ if (!tracker.is_valid()) {
return String("Not connected");
};
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index d46f24752e..246fff6d57 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -281,7 +281,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
at = cost_map[at].prev;
}
- path.invert();
+ path.reverse();
return true;
}
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index db13b9b11f..826fd0189b 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -53,6 +53,8 @@ void BaseButton::_unpress_group() {
}
void BaseButton::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (status.disabled) { // no interaction with disabled button
return;
}
@@ -323,6 +325,8 @@ Ref<Shortcut> BaseButton::get_shortcut() const {
}
void BaseButton::_unhandled_key_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!_is_focus_owner_in_shorcut_context()) {
return;
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 5822119b46..b78f9cad24 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -115,19 +115,22 @@ void ColorPicker::_update_controls() {
if (raw_mode_enabled) {
for (int i = 0; i < 3; i++) {
- scroll[i]->add_theme_icon_override("grabber", Ref<Texture2D>());
- scroll[i]->add_theme_icon_override("grabber_highlight", Ref<Texture2D>());
- scroll[i]->add_theme_style_override("slider", Ref<StyleBox>());
- scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBox>());
- scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBox>());
+ scroll[i]->remove_theme_icon_override("grabber");
+ scroll[i]->remove_theme_icon_override("grabber_highlight");
+ scroll[i]->remove_theme_style_override("slider");
+ scroll[i]->remove_theme_style_override("grabber_area");
+ scroll[i]->remove_theme_style_override("grabber_area_highlight");
}
} else {
- for (int i = 0; i < 3; i++) {
- scroll[i]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
- scroll[i]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
- scroll[i]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
- scroll[i]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
- scroll[i]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
+ Ref<StyleBoxEmpty> style_box_empty(memnew(StyleBoxEmpty));
+ Ref<Texture2D> bar_arrow = get_theme_icon("bar_arrow");
+
+ for (int i = 0; i < 4; i++) {
+ scroll[i]->add_theme_icon_override("grabber", bar_arrow);
+ scroll[i]->add_theme_icon_override("grabber_highlight", bar_arrow);
+ scroll[i]->add_theme_style_override("slider", style_box_empty);
+ scroll[i]->add_theme_style_override("grabber_area", style_box_empty);
+ scroll[i]->add_theme_style_override("grabber_area_highlight", style_box_empty);
}
}
@@ -140,6 +143,30 @@ void ColorPicker::_update_controls() {
scroll[3]->hide();
labels[3]->hide();
}
+
+ switch (picker_type) {
+ case SHAPE_HSV_RECTANGLE:
+ wheel_edit->hide();
+ w_edit->show();
+ uv_edit->show();
+ break;
+ case SHAPE_HSV_WHEEL:
+ wheel_edit->show();
+ w_edit->hide();
+ uv_edit->hide();
+
+ wheel->set_material(wheel_mat);
+ break;
+ case SHAPE_VHS_CIRCLE:
+ wheel_edit->show();
+ w_edit->show();
+ uv_edit->hide();
+
+ wheel->set_material(circle_mat);
+ break;
+ default: {
+ }
+ }
}
void ColorPicker::_set_pick_color(const Color &p_color, bool p_update_sliders) {
@@ -264,6 +291,8 @@ void ColorPicker::_update_color(bool p_update_sliders) {
for (int i = 0; i < 4; i++) {
scroll[i]->update();
}
+ wheel->update();
+ wheel_uv->update();
updating = false;
}
@@ -306,6 +335,18 @@ Color ColorPicker::get_pick_color() const {
return color;
}
+void ColorPicker::set_picker_shape(PickerShapeType p_picker_type) {
+ ERR_FAIL_INDEX(p_picker_type, SHAPE_MAX);
+ picker_type = p_picker_type;
+
+ _update_controls();
+ _update_color();
+}
+
+ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
+ return picker_type;
+}
+
void ColorPicker::add_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
@@ -418,7 +459,7 @@ void ColorPicker::_update_text_value() {
}
void ColorPicker::_sample_draw() {
- const Rect2 r = Rect2(Point2(), Size2(uv_edit->get_size().width, sample->get_size().height * 0.95));
+ const Rect2 r = Rect2(Point2(), Size2(sample->get_size().width, sample->get_size().height * 0.95));
if (color.a < 1.0) {
sample->draw_texture_rect(get_theme_icon("preset_bg", "ColorPicker"), r, true);
@@ -438,42 +479,131 @@ void ColorPicker::_hsv_draw(int p_which, Control *c) {
}
if (p_which == 0) {
Vector<Point2> points;
- points.push_back(Vector2());
- points.push_back(Vector2(c->get_size().x, 0));
- points.push_back(c->get_size());
- points.push_back(Vector2(0, c->get_size().y));
Vector<Color> colors;
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(1, 1, 1, 1));
- colors.push_back(Color(0, 0, 0, 1));
- colors.push_back(Color(0, 0, 0, 1));
- c->draw_polygon(points, colors);
Vector<Color> colors2;
Color col = color;
+ Vector2 center = c->get_size() / 2.0;
+
+ switch (picker_type) {
+ case SHAPE_HSV_WHEEL: {
+ points.resize(4);
+ colors.resize(4);
+ colors2.resize(4);
+ real_t ring_radius_x = Math_SQRT12 * c->get_size().width * 0.42;
+ real_t ring_radius_y = Math_SQRT12 * c->get_size().height * 0.42;
+
+ points.set(0, center - Vector2(ring_radius_x, ring_radius_y));
+ points.set(1, center + Vector2(ring_radius_x, -ring_radius_y));
+ points.set(2, center + Vector2(ring_radius_x, ring_radius_y));
+ points.set(3, center + Vector2(-ring_radius_x, ring_radius_y));
+ colors.set(0, Color(1, 1, 1, 1));
+ colors.set(1, Color(1, 1, 1, 1));
+ colors.set(2, Color(0, 0, 0, 1));
+ colors.set(3, Color(0, 0, 0, 1));
+ c->draw_polygon(points, colors);
+
+ col.set_hsv(h, 1, 1);
+ col.a = 0;
+ colors2.set(0, col);
+ col.a = 1;
+ colors2.set(1, col);
+ col.set_hsv(h, 1, 0);
+ colors2.set(2, col);
+ col.a = 0;
+ colors2.set(3, col);
+ c->draw_polygon(points, colors2);
+ break;
+ }
+ case SHAPE_HSV_RECTANGLE: {
+ points.resize(4);
+ colors.resize(4);
+ colors2.resize(4);
+ points.set(0, Vector2());
+ points.set(1, Vector2(c->get_size().x, 0));
+ points.set(2, c->get_size());
+ points.set(3, Vector2(0, c->get_size().y));
+ colors.set(0, Color(1, 1, 1, 1));
+ colors.set(1, Color(1, 1, 1, 1));
+ colors.set(2, Color(0, 0, 0, 1));
+ colors.set(3, Color(0, 0, 0, 1));
+ c->draw_polygon(points, colors);
+ col = color;
+ col.set_hsv(h, 1, 1);
+ col.a = 0;
+ colors2.set(0, col);
+ col.a = 1;
+ colors2.set(1, col);
+ col.set_hsv(h, 1, 0);
+ colors2.set(2, col);
+ col.a = 0;
+ colors2.set(3, col);
+ c->draw_polygon(points, colors2);
+ break;
+ }
+ default: {
+ }
+ }
+ Ref<Texture2D> cursor = get_theme_icon("picker_cursor", "ColorPicker");
+ int x;
+ int y;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ x = center.x + (center.x * Math::cos(h * Math_TAU) * s) - (cursor->get_width() / 2);
+ y = center.y + (center.y * Math::sin(h * Math_TAU) * s) - (cursor->get_height() / 2);
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+ x = CLAMP(real_size.x * s, 0, real_size.x) + corner_x - (cursor->get_width() / 2);
+ y = CLAMP(real_size.y - real_size.y * v, 0, real_size.y) + corner_y - (cursor->get_height() / 2);
+ }
+ c->draw_texture(cursor, Point2(x, y));
+
col.set_hsv(h, 1, 1);
- col.a = 0;
- colors2.push_back(col);
- col.a = 1;
- colors2.push_back(col);
- col.set_hsv(h, 1, 0);
- colors2.push_back(col);
- col.a = 0;
- colors2.push_back(col);
- c->draw_polygon(points, colors2);
- int x = CLAMP(c->get_size().x * s, 0, c->get_size().x);
- int y = CLAMP(c->get_size().y - c->get_size().y * v, 0, c->get_size().y);
- col = color;
- col.a = 1;
- c->draw_line(Point2(x, 0), Point2(x, c->get_size().y), col.inverted());
- c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
- c->draw_line(Point2(x, y), Point2(x, y), Color(1, 1, 1), 2);
+ if (picker_type == SHAPE_HSV_WHEEL) {
+ points.resize(4);
+ double h1 = h - (0.5 / 360);
+ double h2 = h + (0.5 / 360);
+ points.set(0, Point2(center.x + (center.x * Math::cos(h1 * Math_TAU)), center.y + (center.y * Math::sin(h1 * Math_TAU))));
+ points.set(1, Point2(center.x + (center.x * Math::cos(h1 * Math_TAU) * 0.84), center.y + (center.y * Math::sin(h1 * Math_TAU) * 0.84)));
+ points.set(2, Point2(center.x + (center.x * Math::cos(h2 * Math_TAU)), center.y + (center.y * Math::sin(h2 * Math_TAU))));
+ points.set(3, Point2(center.x + (center.x * Math::cos(h2 * Math_TAU) * 0.84), center.y + (center.y * Math::sin(h2 * Math_TAU) * 0.84)));
+ c->draw_multiline(points, col.inverted());
+ }
+
} else if (p_which == 1) {
- Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
- c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
- int y = c->get_size().y - c->get_size().y * (1.0 - h);
- Color col = Color();
- col.set_hsv(h, 1, 1);
- c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ if (picker_type == SHAPE_HSV_RECTANGLE) {
+ Ref<Texture2D> hue = get_theme_icon("color_hue", "ColorPicker");
+ c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
+ int y = c->get_size().y - c->get_size().y * (1.0 - h);
+ Color col;
+ col.set_hsv(h, 1, 1);
+ c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ } else if (picker_type == SHAPE_VHS_CIRCLE) {
+ Vector<Point2> points;
+ Vector<Color> colors;
+ Color col;
+ col.set_hsv(h, s, 1);
+ points.resize(4);
+ colors.resize(4);
+ points.set(0, Vector2());
+ points.set(1, Vector2(c->get_size().x, 0));
+ points.set(2, c->get_size());
+ points.set(3, Vector2(0, c->get_size().y));
+ colors.set(0, col);
+ colors.set(1, col);
+ colors.set(2, Color(0, 0, 0));
+ colors.set(3, Color(0, 0, 0));
+ c->draw_polygon(points, colors);
+ int y = c->get_size().y - c->get_size().y * CLAMP(v, 0, 1);
+ col.set_hsv(h, 1, v);
+ c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
+ }
+ } else if (p_which == 2) {
+ c->draw_rect(Rect2(Point2(), c->get_size()), Color(1, 1, 1));
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ circle_mat->set_shader_param("v", v);
+ }
}
}
@@ -540,16 +670,51 @@ void ColorPicker::_slider_draw(int p_which) {
scroll[p_which]->draw_polygon(pos, col);
}
-void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
+void ColorPicker::_uv_input(const Ref<InputEvent> &p_event, Control *c) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
+ Vector2 center = c->get_size() / 2.0;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ real_t dist = center.distance_to(bev->get_position());
+
+ if (dist <= center.x) {
+ real_t rad = Math::atan2(bev->get_position().y - center.y, bev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ s = CLAMP(dist / center.x, 0, 1);
+ } else {
+ return;
+ }
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+
+ if (bev->get_position().x < corner_x || bev->get_position().x > c->get_size().x - corner_x ||
+ bev->get_position().y < corner_y || bev->get_position().y > c->get_size().y - corner_y) {
+ {
+ real_t dist = center.distance_to(bev->get_position());
+
+ if (dist >= center.x * 0.84 && dist <= center.x) {
+ real_t rad = Math::atan2(bev->get_position().y - center.y, bev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ spinning = true;
+ } else {
+ return;
+ }
+ }
+ }
+
+ if (!spinning) {
+ real_t x = CLAMP(bev->get_position().x, corner_x, c->get_size().x - corner_x);
+ real_t y = CLAMP(bev->get_position().y, corner_x, c->get_size().y - corner_y);
+
+ s = (x - c->get_position().x - corner_x) / real_size.x;
+ v = 1.0 - (y - c->get_position().y - corner_y) / real_size.y;
+ }
+ }
changing_color = true;
- float x = CLAMP((float)bev->get_position().x, 0, uv_edit->get_size().width);
- float y = CLAMP((float)bev->get_position().y, 0, uv_edit->get_size().height);
- s = x / uv_edit->get_size().width;
- v = 1.0 - y / uv_edit->get_size().height;
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -560,8 +725,10 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
} else if (deferred_mode_enabled && !bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
emit_signal("color_changed", color);
changing_color = false;
+ spinning = false;
} else {
changing_color = false;
+ spinning = false;
}
}
@@ -571,10 +738,30 @@ void ColorPicker::_uv_input(const Ref<InputEvent> &p_event) {
if (!changing_color) {
return;
}
- float x = CLAMP((float)mev->get_position().x, 0, uv_edit->get_size().width);
- float y = CLAMP((float)mev->get_position().y, 0, uv_edit->get_size().height);
- s = x / uv_edit->get_size().width;
- v = 1.0 - y / uv_edit->get_size().height;
+
+ Vector2 center = c->get_size() / 2.0;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ real_t dist = center.distance_to(mev->get_position());
+ real_t rad = Math::atan2(mev->get_position().y - center.y, mev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ s = CLAMP(dist / center.x, 0, 1);
+ } else {
+ if (spinning) {
+ real_t rad = Math::atan2(mev->get_position().y - center.y, mev->get_position().x - center.x);
+ h = ((rad >= 0) ? rad : (Math_TAU + rad)) / Math_TAU;
+ } else {
+ real_t corner_x = (c == wheel_uv) ? center.x - Math_SQRT12 * c->get_size().width * 0.42 : 0;
+ real_t corner_y = (c == wheel_uv) ? center.y - Math_SQRT12 * c->get_size().height * 0.42 : 0;
+ Size2 real_size(c->get_size().x - corner_x * 2, c->get_size().y - corner_y * 2);
+
+ real_t x = CLAMP(mev->get_position().x, corner_x, c->get_size().x - corner_x);
+ real_t y = CLAMP(mev->get_position().y, corner_x, c->get_size().y - corner_y);
+
+ s = (x - corner_x) / real_size.x;
+ v = 1.0 - (y - corner_y) / real_size.y;
+ }
+ }
+
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -592,7 +779,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
changing_color = true;
float y = CLAMP((float)bev->get_position().y, 0, w_edit->get_size().height);
- h = y / w_edit->get_size().height;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ v = 1.0 - (y / w_edit->get_size().height);
+ } else {
+ h = y / w_edit->get_size().height;
+ }
} else {
changing_color = false;
}
@@ -614,7 +805,11 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
return;
}
float y = CLAMP((float)mev->get_position().y, 0, w_edit->get_size().height);
- h = y / w_edit->get_size().height;
+ if (picker_type == SHAPE_VHS_CIRCLE) {
+ v = 1.0 - (y / w_edit->get_size().height);
+ } else {
+ h = y / w_edit->get_size().height;
+ }
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -682,7 +877,7 @@ void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
return;
}
- Ref<Image> img = r->get_texture()->get_data();
+ Ref<Image> img = r->get_texture()->get_image();
if (img.is_valid() && !img->is_empty()) {
Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y);
@@ -798,18 +993,25 @@ void ColorPicker::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_preset", "color"), &ColorPicker::add_preset);
ClassDB::bind_method(D_METHOD("erase_preset", "color"), &ColorPicker::erase_preset);
ClassDB::bind_method(D_METHOD("get_presets"), &ColorPicker::get_presets);
+ ClassDB::bind_method(D_METHOD("set_picker_shape", "picker"), &ColorPicker::set_picker_shape);
+ ClassDB::bind_method(D_METHOD("get_picker_shape"), &ColorPicker::get_picker_shape);
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_pick_color", "get_pick_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "edit_alpha"), "set_edit_alpha", "is_editing_alpha");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hsv_mode"), "set_hsv_mode", "is_hsv_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "raw_mode"), "set_raw_mode", "is_raw_mode");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "deferred_mode"), "set_deferred_mode", "is_deferred_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "picker_shape", PROPERTY_HINT_ENUM, "HSV Rectangle,HSV Rectangle Wheel,VHS Circle"), "set_picker_shape", "get_picker_shape");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_enabled"), "set_presets_enabled", "are_presets_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "presets_visible"), "set_presets_visible", "are_presets_visible");
ADD_SIGNAL(MethodInfo("color_changed", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_added", PropertyInfo(Variant::COLOR, "color")));
ADD_SIGNAL(MethodInfo("preset_removed", PropertyInfo(Variant::COLOR, "color")));
+
+ BIND_ENUM_CONSTANT(SHAPE_HSV_RECTANGLE);
+ BIND_ENUM_CONSTANT(SHAPE_HSV_WHEEL);
+ BIND_ENUM_CONSTANT(SHAPE_VHS_CIRCLE);
}
ColorPicker::ColorPicker() :
@@ -818,36 +1020,25 @@ ColorPicker::ColorPicker() :
add_child(hb_edit);
hb_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- uv_edit = memnew(Control);
hb_edit->add_child(uv_edit);
- uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input));
+ uv_edit->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(uv_edit));
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_custom_minimum_size(Size2(get_theme_constant("sv_width"), get_theme_constant("sv_height")));
uv_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, uv_edit));
- w_edit = memnew(Control);
- hb_edit->add_child(w_edit);
- w_edit->set_custom_minimum_size(Size2(get_theme_constant("h_width"), 0));
- w_edit->set_h_size_flags(SIZE_FILL);
- w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
- w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
-
HBoxContainer *hb_smpl = memnew(HBoxContainer);
add_child(hb_smpl);
- sample = memnew(TextureRect);
hb_smpl->add_child(sample);
sample->set_h_size_flags(SIZE_EXPAND_FILL);
sample->connect("draw", callable_mp(this, &ColorPicker::_sample_draw));
- btn_pick = memnew(Button);
btn_pick->set_flat(true);
hb_smpl->add_child(btn_pick);
btn_pick->set_toggle_mode(true);
- btn_pick->set_tooltip(TTR("Pick a color from the editor window."));
+ btn_pick->set_tooltip(RTR("Pick a color from the editor window."));
btn_pick->connect("pressed", callable_mp(this, &ColorPicker::_screen_pick_pressed));
VBoxContainer *vbl = memnew(VBoxContainer);
@@ -887,27 +1078,20 @@ ColorPicker::ColorPicker() :
vbr->add_child(hbc);
}
+
labels[3]->set_text("A");
- scroll[3]->add_theme_icon_override("grabber", get_theme_icon("bar_arrow"));
- scroll[3]->add_theme_icon_override("grabber_highlight", get_theme_icon("bar_arrow"));
- scroll[3]->add_theme_style_override("slider", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
- scroll[3]->add_theme_style_override("grabber_area", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
- scroll[3]->add_theme_style_override("grabber_area_highlight", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty)));
HBoxContainer *hhb = memnew(HBoxContainer);
vbr->add_child(hhb);
- btn_hsv = memnew(CheckButton);
hhb->add_child(btn_hsv);
- btn_hsv->set_text(TTR("HSV"));
+ btn_hsv->set_text(RTR("HSV"));
btn_hsv->connect("toggled", callable_mp(this, &ColorPicker::set_hsv_mode));
- btn_raw = memnew(CheckButton);
hhb->add_child(btn_raw);
- btn_raw->set_text(TTR("Raw"));
+ btn_raw->set_text(RTR("Raw"));
btn_raw->connect("toggled", callable_mp(this, &ColorPicker::set_raw_mode));
- text_type = memnew(Button);
hhb->add_child(text_type);
text_type->set_text("#");
text_type->set_tooltip(TTR("Switch between hexadecimal and code values."));
@@ -921,36 +1105,70 @@ ColorPicker::ColorPicker() :
text_type->set_mouse_filter(MOUSE_FILTER_IGNORE);
}
- c_text = memnew(LineEdit);
hhb->add_child(c_text);
c_text->set_h_size_flags(SIZE_EXPAND_FILL);
c_text->connect("text_entered", callable_mp(this, &ColorPicker::_html_entered));
c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter));
c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit));
+ wheel_edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ wheel_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ wheel_edit->set_custom_minimum_size(Size2(get_theme_constant("sv_width"), get_theme_constant("sv_height")));
+ hb_edit->add_child(wheel_edit);
+
+ wheel_mat.instance();
+ circle_mat.instance();
+
+ Ref<Shader> wheel_shader(memnew(Shader));
+ wheel_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5)*float(sqrt(x*x+y*y)>0.42);COLOR=vec4(clamp((abs(fract(((a-TAU)/TAU)+vec3(3.0,2.0,1.0)/3.0)*6.0-3.0)-1.0),0.0,1.0),(b+b2+b3+b4)/4.00);}");
+ wheel_mat->set_shader(wheel_shader);
+
+ Ref<Shader> circle_shader(memnew(Shader));
+ circle_shader->set_code("shader_type canvas_item;const float TAU=6.28318530718;uniform float v=1.0;void fragment(){float x=UV.x-0.5;float y=UV.y-0.5;float a=atan(y,x);x+=0.001;y+=0.001;float b=float(sqrt(x*x+y*y)<0.5);x-=0.002;float b2=float(sqrt(x*x+y*y)<0.5);y-=0.002;float b3=float(sqrt(x*x+y*y)<0.5);x+=0.002;float b4=float(sqrt(x*x+y*y)<0.5);COLOR=vec4(mix(vec3(1.0),clamp(abs(fract(vec3((a-TAU)/TAU)+vec3(1.0,2.0/3.0,1.0/3.0))*6.0-vec3(3.0))-vec3(1.0),0.0,1.0),((float(sqrt(x*x+y*y))*2.0))/1.0)*vec3(v),(b+b2+b3+b4)/4.00);}");
+ circle_mat->set_shader(circle_shader);
+
+ MarginContainer *wheel_margin(memnew(MarginContainer));
+#ifdef TOOLS_ENABLED
+ wheel_margin->add_theme_constant_override("margin_bottom", 8 * EDSCALE);
+#else
+ wheel_margin->add_theme_constant_override("margin_bottom", 8);
+#endif
+ wheel_edit->add_child(wheel_margin);
+
+ wheel_margin->add_child(wheel);
+ wheel->set_mouse_filter(MOUSE_FILTER_PASS);
+ wheel->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(2, wheel));
+
+ wheel_margin->add_child(wheel_uv);
+ wheel_uv->connect("gui_input", callable_mp(this, &ColorPicker::_uv_input), make_binds(wheel_uv));
+ wheel_uv->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(0, wheel_uv));
+
+ hb_edit->add_child(w_edit);
+ w_edit->set_custom_minimum_size(Size2(get_theme_constant("h_width"), 0));
+ w_edit->set_h_size_flags(SIZE_FILL);
+ w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
+ w_edit->connect("gui_input", callable_mp(this, &ColorPicker::_w_input));
+ w_edit->connect("draw", callable_mp(this, &ColorPicker::_hsv_draw), make_binds(1, w_edit));
+
+ picker_type = SHAPE_HSV_RECTANGLE;
_update_controls();
updating = false;
set_pick_color(Color(1, 1, 1));
- preset_separator = memnew(HSeparator);
add_child(preset_separator);
- preset_container = memnew(HBoxContainer);
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(preset_container);
- preset = memnew(TextureRect);
preset_container->add_child(preset);
preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input));
preset->connect("draw", callable_mp(this, &ColorPicker::_update_presets));
- preset_container2 = memnew(HBoxContainer);
preset_container2->set_h_size_flags(SIZE_EXPAND_FILL);
add_child(preset_container2);
- bt_add_preset = memnew(Button);
preset_container2->add_child(bt_add_preset);
- bt_add_preset->set_tooltip(TTR("Add current color as a preset."));
+ bt_add_preset->set_tooltip(RTR("Add current color as a preset."));
bt_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 24e1746c41..a0d2aa95ca 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -31,6 +31,7 @@
#ifndef COLOR_PICKER_H
#define COLOR_PICKER_H
+#include "scene/gui/aspect_ratio_container.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/check_button.h"
@@ -45,29 +46,44 @@
class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
+public:
+ enum PickerShapeType {
+ SHAPE_HSV_RECTANGLE,
+ SHAPE_HSV_WHEEL,
+ SHAPE_VHS_CIRCLE,
+
+ SHAPE_MAX
+ };
+
private:
Control *screen = nullptr;
- Control *uv_edit;
- Control *w_edit;
- TextureRect *sample;
- TextureRect *preset;
- HBoxContainer *preset_container;
- HBoxContainer *preset_container2;
- HSeparator *preset_separator;
- Button *bt_add_preset;
+ Control *uv_edit = memnew(Control);
+ Control *w_edit = memnew(Control);
+ AspectRatioContainer *wheel_edit = memnew(AspectRatioContainer);
+ Ref<ShaderMaterial> wheel_mat;
+ Ref<ShaderMaterial> circle_mat;
+ Control *wheel = memnew(Control);
+ Control *wheel_uv = memnew(Control);
+ TextureRect *sample = memnew(TextureRect);
+ TextureRect *preset = memnew(TextureRect);
+ HBoxContainer *preset_container = memnew(HBoxContainer);
+ HBoxContainer *preset_container2 = memnew(HBoxContainer);
+ HSeparator *preset_separator = memnew(HSeparator);
+ Button *bt_add_preset = memnew(Button);
List<Color> presets;
- Button *btn_pick;
- CheckButton *btn_hsv;
- CheckButton *btn_raw;
+ Button *btn_pick = memnew(Button);
+ CheckButton *btn_hsv = memnew(CheckButton);
+ CheckButton *btn_raw = memnew(CheckButton);
HSlider *scroll[4];
SpinBox *values[4];
Label *labels[4];
- Button *text_type;
- LineEdit *c_text;
+ Button *text_type = memnew(Button);
+ LineEdit *c_text = memnew(LineEdit);
bool edit_alpha = true;
Size2i ms;
bool text_is_constructor = false;
int presets_per_row = 0;
+ PickerShapeType picker_type = SHAPE_HSV_WHEEL;
Color color;
bool raw_mode_enabled = false;
@@ -75,6 +91,7 @@ private:
bool deferred_mode_enabled = false;
bool updating = true;
bool changing_color = false;
+ bool spinning = false;
bool presets_enabled = true;
bool presets_visible = true;
float h = 0.0;
@@ -93,7 +110,7 @@ private:
void _hsv_draw(int p_which, Control *c);
void _slider_draw(int p_which);
- void _uv_input(const Ref<InputEvent> &p_event);
+ void _uv_input(const Ref<InputEvent> &p_event, Control *c);
void _w_input(const Ref<InputEvent> &p_event);
void _preset_input(const Ref<InputEvent> &p_event);
void _screen_input(const Ref<InputEvent> &p_event);
@@ -115,6 +132,9 @@ public:
void set_pick_color(const Color &p_color);
Color get_pick_color() const;
+ void set_picker_shape(PickerShapeType p_picker_type);
+ PickerShapeType get_picker_shape() const;
+
void add_preset(const Color &p_color);
void erase_preset(const Color &p_color);
PackedColorArray get_presets() const;
@@ -175,4 +195,5 @@ public:
ColorPickerButton();
};
+VARIANT_ENUM_CAST(ColorPicker::PickerShapeType);
#endif // COLOR_PICKER_H
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 2e391adf2c..300201c0db 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -290,15 +290,11 @@ void Control::_update_minimum_size() {
}
Size2 minsize = get_combined_minimum_size();
- if (minsize.x > data.size_cache.x ||
- minsize.y > data.size_cache.y) {
- _size_changed();
- }
-
data.updating_last_minimum_size = false;
if (minsize != data.last_minimum_size) {
data.last_minimum_size = minsize;
+ _size_changed();
emit_signal(SceneStringNames::get_singleton()->minimum_size_changed);
}
}
@@ -327,7 +323,6 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = data.color_override.has(name) ? Variant(data.color_override[name]) : Variant();
} else if (sname.begins_with("custom_constants/")) {
String name = sname.get_slicec('/', 1);
-
r_ret = data.constant_override.has(name) ? Variant(data.constant_override[name]) : Variant();
} else {
return false;
@@ -1780,53 +1775,38 @@ Rect2 Control::get_anchorable_rect() const {
}
void Control::add_theme_icon_override(const StringName &p_name, const Ref<Texture2D> &p_icon) {
+ ERR_FAIL_COND(!p_icon.is_valid());
+
if (data.icon_override.has(p_name)) {
data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of an icon
- if (p_icon.is_null()) {
- data.icon_override.erase(p_name);
- } else {
- data.icon_override[p_name] = p_icon;
- if (data.icon_override[p_name].is_valid()) {
- data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ data.icon_override[p_name] = p_icon;
+ data.icon_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
notification(NOTIFICATION_THEME_CHANGED);
}
void Control::add_theme_style_override(const StringName &p_name, const Ref<StyleBox> &p_style) {
+ ERR_FAIL_COND(!p_style.is_valid());
+
if (data.style_override.has(p_name)) {
data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of a style
- if (p_style.is_null()) {
- data.style_override.erase(p_name);
- } else {
- data.style_override[p_name] = p_style;
- if (data.style_override[p_name].is_valid()) {
- data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ data.style_override[p_name] = p_style;
+ data.style_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
notification(NOTIFICATION_THEME_CHANGED);
}
void Control::add_theme_font_override(const StringName &p_name, const Ref<Font> &p_font) {
+ ERR_FAIL_COND(!p_font.is_valid());
+
if (data.font_override.has(p_name)) {
data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
}
- // clear if "null" is passed instead of a font
- if (p_font.is_null()) {
- data.font_override.erase(p_name);
- } else {
- data.font_override[p_name] = p_font;
- if (data.font_override[p_name].is_valid()) {
- data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
- }
- }
+ data.font_override[p_name] = p_font;
+ data.font_override[p_name]->connect("changed", callable_mp(this, &Control::_override_changed), Vector<Variant>(), CONNECT_REFERENCE_COUNTED);
notification(NOTIFICATION_THEME_CHANGED);
}
@@ -1845,6 +1825,48 @@ void Control::add_theme_constant_override(const StringName &p_name, int p_consta
notification(NOTIFICATION_THEME_CHANGED);
}
+void Control::remove_theme_icon_override(const StringName &p_name) {
+ if (data.icon_override.has(p_name)) {
+ data.icon_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.icon_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_style_override(const StringName &p_name) {
+ if (data.style_override.has(p_name)) {
+ data.style_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.style_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_font_override(const StringName &p_name) {
+ if (data.font_override.has(p_name)) {
+ data.font_override[p_name]->disconnect("changed", callable_mp(this, &Control::_override_changed));
+ }
+
+ data.font_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_font_size_override(const StringName &p_name) {
+ data.font_size_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_color_override(const StringName &p_name) {
+ data.color_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
+void Control::remove_theme_constant_override(const StringName &p_name) {
+ data.constant_override.erase(p_name);
+ notification(NOTIFICATION_THEME_CHANGED);
+}
+
void Control::set_focus_mode(FocusMode p_focus_mode) {
ERR_FAIL_INDEX((int)p_focus_mode, 3);
@@ -2799,6 +2821,13 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_theme_color_override", "name", "color"), &Control::add_theme_color_override);
ClassDB::bind_method(D_METHOD("add_theme_constant_override", "name", "constant"), &Control::add_theme_constant_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_icon_override", "name"), &Control::remove_theme_icon_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_stylebox_override", "name"), &Control::remove_theme_style_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_font_override", "name"), &Control::remove_theme_font_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_font_size_override", "name"), &Control::remove_theme_font_size_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_color_override", "name"), &Control::remove_theme_color_override);
+ ClassDB::bind_method(D_METHOD("remove_theme_constant_override", "name"), &Control::remove_theme_constant_override);
+
ClassDB::bind_method(D_METHOD("get_theme_icon", "name", "node_type"), &Control::get_theme_icon, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_stylebox", "name", "node_type"), &Control::get_theme_stylebox, DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_theme_font", "name", "node_type"), &Control::get_theme_font, DEFVAL(""));
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a911d69c3f..184b2df6d3 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -459,6 +459,13 @@ public:
void add_theme_color_override(const StringName &p_name, const Color &p_color);
void add_theme_constant_override(const StringName &p_name, int p_constant);
+ void remove_theme_icon_override(const StringName &p_name);
+ void remove_theme_style_override(const StringName &p_name);
+ void remove_theme_font_override(const StringName &p_name);
+ void remove_theme_font_size_override(const StringName &p_name);
+ void remove_theme_color_override(const StringName &p_name);
+ void remove_theme_constant_override(const StringName &p_name);
+
Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_node_type = StringName()) const;
Ref<StyleBox> get_theme_stylebox(const StringName &p_name, const StringName &p_node_type = StringName()) const;
Ref<Font> get_theme_font(const StringName &p_name, const StringName &p_node_type = StringName()) const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 7ac8dbccca..5409b44b9e 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -96,6 +96,8 @@ void FileDialog::_notification(int p_what) {
}
void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (k.is_valid() && has_focus()) {
if (k->is_pressed()) {
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 36b383f16c..e72709e847 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -92,6 +92,8 @@ GradientEdit::~GradientEdit() {
}
void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
if (k.is_valid() && k->is_pressed() && k->get_keycode() == KEY_DELETE && grabbed != -1) {
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 315bef38e8..06c9cf1b63 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -154,6 +154,8 @@ Vector2 GraphEditMinimap::_convert_to_graph_position(const Vector2 &p_position)
}
void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
if (!ge->is_minimap_enabled()) {
return;
}
@@ -1066,6 +1068,8 @@ void GraphEdit::set_selected(Node *p_child) {
}
void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid() && (mm->get_button_mask() & MOUSE_BUTTON_MASK_MIDDLE || (mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
@@ -1123,7 +1127,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
}
gn->set_selected(box_selection_mode_additive);
} else {
- bool select = (previus_selected.find(gn) != nullptr);
+ bool select = (previous_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
@@ -1148,7 +1152,7 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
continue;
}
- bool select = (previus_selected.find(gn) != nullptr);
+ bool select = (previous_selected.find(gn) != nullptr);
if (gn->is_selected() && !select) {
emit_signal("node_deselected", gn);
} else if (!gn->is_selected() && select) {
@@ -1273,29 +1277,29 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
box_selecting_from = b->get_position();
if (b->get_control()) {
box_selection_mode_additive = true;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2 || !gn2->is_selected()) {
continue;
}
- previus_selected.push_back(gn2);
+ previous_selected.push_back(gn2);
}
} else if (b->get_shift()) {
box_selection_mode_additive = false;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2 || !gn2->is_selected()) {
continue;
}
- previus_selected.push_back(gn2);
+ previous_selected.push_back(gn2);
}
} else {
box_selection_mode_additive = true;
- previus_selected.clear();
+ previous_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn2 = Object::cast_to<GraphNode>(get_child(i));
if (!gn2) {
@@ -1312,15 +1316,16 @@ void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
if (b->get_button_index() == MOUSE_BUTTON_LEFT && !b->is_pressed() && box_selecting) {
box_selecting = false;
- previus_selected.clear();
+ box_selecting_rect = Rect2();
+ previous_selected.clear();
top_layer->update();
minimap->update();
}
if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
- set_zoom(zoom * ZOOM_SCALE);
+ set_zoom_custom(zoom * ZOOM_SCALE, b->get_position());
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
- set_zoom(zoom / ZOOM_SCALE);
+ set_zoom_custom(zoom / ZOOM_SCALE, b->get_position());
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_UP && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
} else if (b->get_button_index() == MOUSE_BUTTON_WHEEL_DOWN && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 8fdf975319..fa3b113705 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -150,7 +150,7 @@ private:
Point2 box_selecting_from;
Point2 box_selecting_to;
Rect2 box_selecting_rect;
- List<GraphNode *> previus_selected;
+ List<GraphNode *> previous_selected;
bool setting_scroll_ofs = false;
bool right_disconnects = false;
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index 8eba473d57..7d5c53effe 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -804,6 +804,8 @@ Color GraphNode::get_connection_output_color(int p_idx) {
}
void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
+ ERR_FAIL_COND(p_ev.is_null());
+
Ref<InputEventMouseButton> mb = p_ev;
if (mb.is_valid()) {
ERR_FAIL_COND_MSG(get_parent_control() == nullptr, "GraphNode must be the child of a GraphEdit node.");
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 482560d29d..86d070f9b1 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -530,6 +530,8 @@ Size2 ItemList::Item::get_icon_size() const {
}
void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
double prev_scroll = scroll_bar->get_value();
Ref<InputEventMouseMotion> mm = p_event;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index d1cd73c803..2d8eb3191c 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -215,6 +215,8 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
}
void LineEdit::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index 5acc7e808a..1e9baa77fc 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -34,6 +34,8 @@
#include "scene/main/window.h"
void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!_is_focus_owner_in_shorcut_context()) {
return;
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index bfbd46a9f0..44df8eafdc 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -252,6 +252,8 @@ void PopupMenu::_submenu_timeout() {
}
void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (p_event->is_action("ui_down") && p_event->is_pressed()) {
int search_from = mouse_over + 1;
if (search_from >= items.size()) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 13b57ece6c..c763ae6bd6 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -760,7 +760,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
//draw_rect(Rect2(p_ofs + off, TS->shaped_text_get_size(rid)), Color(1,0,0), false, 2); //DEBUG_RECTS
- off.y += TS->shaped_text_get_ascent(rid);
+ off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
// Draw inlined objects.
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1079,7 +1079,7 @@ int RichTextLabel::_draw_line(ItemFrame *p_frame, int p_line, const Vector2 &p_o
off.x += glyphs[i].advance;
}
}
- off.y += TS->shaped_text_get_descent(rid);
+ off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
}
return line_count;
@@ -1174,7 +1174,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
} break;
}
- off.y += TS->shaped_text_get_ascent(rid);
+ off.y += TS->shaped_text_get_ascent(rid) + l.text_buf->get_spacing_top();
Array objects = TS->shaped_text_get_objects(rid);
for (int i = 0; i < objects.size(); i++) {
@@ -1238,7 +1238,7 @@ float RichTextLabel::_find_click_in_line(ItemFrame *p_frame, int p_line, const V
if (rect.has_point(p_click) && !table_hit) {
char_pos = TS->shaped_text_hit_test_position(rid, p_click.x - rect.position.x);
}
- off.y += TS->shaped_text_get_descent(rid);
+ off.y += TS->shaped_text_get_descent(rid) + l.text_buf->get_spacing_bottom();
}
if (char_pos >= 0) {
@@ -1469,6 +1469,8 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
}
void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> b = p_event;
if (b.is_valid()) {
@@ -3756,7 +3758,9 @@ void RichTextLabel::set_effects(const Vector<Variant> &effects) {
custom_effects.push_back(effect);
}
- parse_bbcode(bbcode);
+ if ((bbcode != "") && use_bbcode) {
+ parse_bbcode(bbcode);
+ }
}
Vector<Variant> RichTextLabel::get_effects() {
@@ -3773,7 +3777,9 @@ void RichTextLabel::install_effect(const Variant effect) {
if (rteffect.is_valid()) {
custom_effects.push_back(effect);
- parse_bbcode(bbcode);
+ if ((bbcode != "") && use_bbcode) {
+ parse_bbcode(bbcode);
+ }
}
}
@@ -3999,14 +4005,16 @@ void RichTextLabel::set_fixed_size_to_width(int p_width) {
}
Size2 RichTextLabel::get_minimum_size() const {
- Size2 size(0, 0);
+ Ref<StyleBox> style = get_theme_stylebox("normal");
+ Size2 size = style->get_minimum_size();
+
if (fixed_width != -1) {
- size.x = fixed_width;
+ size.x += fixed_width;
}
if (fixed_width != -1 || fit_content_height) {
const_cast<RichTextLabel *>(this)->_validate_line_caches(main);
- size.y = get_content_height();
+ size.y += get_content_height();
}
return size;
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index a56bf15507..62276e3af0 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -42,6 +42,8 @@ void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
}
void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseMotion> m = p_event;
if (!m.is_valid() || drag.active) {
emit_signal("scrolling");
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 90a528482f..757a0841ea 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -88,6 +88,8 @@ void ScrollContainer::_cancel_drag() {
}
void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
+ ERR_FAIL_COND(p_gui_input.is_null());
+
double prev_v_scroll = v_scroll->get_value();
double prev_h_scroll = h_scroll->get_value();
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 7f1d19a87a..a407ef21cb 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -46,6 +46,8 @@ Size2 Slider::get_minimum_size() const {
}
void Slider::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!editable) {
return;
}
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 50b25fa7b4..9dc2afdb2d 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -100,6 +100,8 @@ void SpinBox::_release_mouse() {
}
void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (!is_editable()) {
return;
}
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index c80120f87d..13ff2c5b86 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -207,6 +207,8 @@ void SplitContainer::_notification(int p_what) {
}
void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility != DRAGGER_VISIBLE) {
return;
}
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 8ffdd269a4..bfc7e29f9c 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -140,6 +140,8 @@ void SubViewportContainer::_notification(int p_what) {
}
void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
@@ -165,6 +167,8 @@ void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
}
void SubViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
if (Engine::get_singleton()->is_editor_hint()) {
return;
}
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 1e31f9e206..ff9dafa0f9 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -72,6 +72,8 @@ int TabContainer::_get_top_margin() const {
}
void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseButton> mb = p_event;
Popup *popup = get_popup();
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 4a7285a154..6cbc5890ce 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -83,11 +83,16 @@ Size2 Tabs::get_minimum_size() const {
}
}
- ms.width = 0; //TODO: should make this optional
+ if (clip_tabs) {
+ ms.width = 0;
+ }
+
return ms;
}
void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid()) {
@@ -105,10 +110,10 @@ void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
highlight_arrow = 0;
}
} else {
- int limit = get_size().width - incr->get_width() - decr->get_width();
- if (pos.x > limit + decr->get_width()) {
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
+ if (pos.x > limit_minus_buttons + decr->get_width()) {
highlight_arrow = 1;
- } else if (pos.x > limit) {
+ } else if (pos.x > limit_minus_buttons) {
highlight_arrow = 0;
}
}
@@ -305,7 +310,8 @@ void Tabs::_notification(int p_what) {
Ref<Texture2D> incr_hl = get_theme_icon("increment_highlight");
Ref<Texture2D> decr_hl = get_theme_icon("decrement_highlight");
- int limit = get_size().width - incr->get_size().width - decr->get_size().width;
+ int limit = get_size().width;
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
missing_right = false;
@@ -328,7 +334,8 @@ void Tabs::_notification(int p_what) {
col = font_unselected_color;
}
- if (w + lsize > limit) {
+ int new_width = w + lsize;
+ if (new_width > limit || (i < tabs.size() - 1 && new_width > limit_minus_buttons)) { // For the last tab, we accept if the tab covers the buttons.
max_drawn_tab = i - 1;
missing_right = true;
break;
@@ -459,15 +466,15 @@ void Tabs::_notification(int p_what) {
}
} else {
if (offset > 0) {
- draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit, vofs));
+ draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit_minus_buttons, vofs));
} else {
- draw_texture(decr, Point2(limit, vofs), Color(1, 1, 1, 0.5));
+ draw_texture(decr, Point2(limit_minus_buttons, vofs), Color(1, 1, 1, 0.5));
}
if (missing_right) {
- draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs));
+ draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit_minus_buttons + decr->get_size().width, vofs));
} else {
- draw_texture(incr, Point2(limit + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
+ draw_texture(incr, Point2(limit_minus_buttons + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
}
}
@@ -666,7 +673,7 @@ void Tabs::_update_cache() {
Ref<StyleBox> tab_selected = get_theme_stylebox("tab_selected");
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
int w = 0;
int mw = 0;
@@ -686,7 +693,7 @@ void Tabs::_update_cache() {
}
int m_width = min_width;
if (count_resize > 0) {
- m_width = MAX((limit - size_fixed) / count_resize, min_width);
+ m_width = MAX((limit_minus_buttons - size_fixed) / count_resize, min_width);
}
for (int i = offset; i < tabs.size(); i++) {
Ref<StyleBox> sb;
@@ -699,7 +706,7 @@ void Tabs::_update_cache() {
}
int lsize = tabs[i].size_cache;
int slen = tabs[i].size_text;
- if (min_width > 0 && mw > limit && i != current) {
+ if (min_width > 0 && mw > limit_minus_buttons && i != current) {
if (lsize > m_width) {
slen = m_width - (sb->get_margin(SIDE_LEFT) + sb->get_margin(SIDE_RIGHT));
if (tabs[i].icon.is_valid()) {
@@ -909,6 +916,19 @@ Tabs::TabAlign Tabs::get_tab_align() const {
return tab_align;
}
+void Tabs::set_clip_tabs(bool p_clip_tabs) {
+ if (clip_tabs == p_clip_tabs) {
+ return;
+ }
+ clip_tabs = p_clip_tabs;
+ update();
+ minimum_size_changed();
+}
+
+bool Tabs::get_clip_tabs() const {
+ return clip_tabs;
+}
+
void Tabs::move_tab(int from, int to) {
if (from == to) {
return;
@@ -975,7 +995,8 @@ void Tabs::_ensure_no_over_offset() {
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ int limit = get_size().width;
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
while (offset > 0) {
int total_w = 0;
@@ -983,7 +1004,7 @@ void Tabs::_ensure_no_over_offset() {
total_w += tabs[i].size_cache;
}
- if (total_w < limit) {
+ if ((buttons_visible && total_w < limit_minus_buttons) || total_w < limit) { // For the last tab, we accept if the tab covers the buttons.
offset--;
update();
} else {
@@ -1014,9 +1035,12 @@ void Tabs::ensure_tab_visible(int p_idx) {
int prev_offset = offset;
Ref<Texture2D> incr = get_theme_icon("increment");
Ref<Texture2D> decr = get_theme_icon("decrement");
- int limit = get_size().width - incr->get_width() - decr->get_width();
+ int limit = get_size().width;
+ int limit_minus_buttons = get_size().width - incr->get_width() - decr->get_width();
+
for (int i = offset; i <= p_idx; i++) {
- if (tabs[i].ofs_cache + tabs[i].size_cache > limit) {
+ int total_w = tabs[i].ofs_cache + tabs[i].size_cache;
+ if (total_w > limit || (buttons_visible && total_w > limit_minus_buttons)) {
offset++;
}
}
@@ -1105,6 +1129,8 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_tab", "title", "icon"), &Tabs::add_tab, DEFVAL(""), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align);
+ ClassDB::bind_method(D_METHOD("set_clip_tabs", "clip_tabs"), &Tabs::set_clip_tabs);
+ ClassDB::bind_method(D_METHOD("get_clip_tabs"), &Tabs::get_clip_tabs);
ClassDB::bind_method(D_METHOD("get_tab_offset"), &Tabs::get_tab_offset);
ClassDB::bind_method(D_METHOD("get_offset_buttons_visible"), &Tabs::get_offset_buttons_visible);
ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &Tabs::ensure_tab_visible);
@@ -1131,6 +1157,7 @@ void Tabs::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_align", PROPERTY_HINT_ENUM, "Left,Center,Right"), "set_tab_align", "get_tab_align");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_tabs"), "set_clip_tabs", "get_clip_tabs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "tab_close_display_policy", PROPERTY_HINT_ENUM, "Show Never,Show Active Only,Show Always"), "set_tab_close_display_policy", "get_tab_close_display_policy");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scrolling_enabled"), "set_scrolling_enabled", "get_scrolling_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "drag_to_rearrange_enabled"), "set_drag_to_rearrange_enabled", "get_drag_to_rearrange_enabled");
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 86877f4d80..61c9a5d96a 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -85,6 +85,7 @@ private:
int previous = 0;
int _get_top_margin() const;
TabAlign tab_align = ALIGN_CENTER;
+ bool clip_tabs = true;
int rb_hover = -1;
bool rb_pressing = false;
@@ -148,6 +149,9 @@ public:
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
+ void set_clip_tabs(bool p_clip_tabs);
+ bool get_clip_tabs() const;
+
void move_tab(int from, int to);
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy);
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 74c530f1b0..f54ab004c6 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2854,6 +2854,8 @@ void TextEdit::_get_minimap_mouse_row(const Point2i &p_mouse, int &r_row) const
}
void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
+ ERR_FAIL_COND(p_gui_input.is_null());
+
double prev_v_scroll = v_scroll->get_value();
double prev_h_scroll = h_scroll->get_value();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index abfea241f3..73fd9dbcd7 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2402,6 +2402,8 @@ void Tree::_go_down() {
}
void Tree::_gui_input(Ref<InputEvent> p_event) {
+ ERR_FAIL_COND(p_event.is_null());
+
Ref<InputEventKey> k = p_event;
bool is_command = k.is_valid() && k->get_command();
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index b18b2afb6d..55529517f1 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -1511,9 +1511,9 @@ bool CanvasTexture::has_alpha() const {
}
}
-Ref<Image> CanvasTexture::get_data() const {
+Ref<Image> CanvasTexture::get_image() const {
if (diffuse_texture.is_valid()) {
- return diffuse_texture->get_data();
+ return diffuse_texture->get_image();
} else {
return Ref<Image>();
}
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index 0f86f2e0f8..1c64cafab8 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -475,7 +475,7 @@ public:
virtual bool is_pixel_opaque(int p_x, int p_y) const override;
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
virtual RID get_rid() const override;
diff --git a/scene/main/http_request.cpp b/scene/main/http_request.cpp
index e4ed5c6e6c..64df37654b 100644
--- a/scene/main/http_request.cpp
+++ b/scene/main/http_request.cpp
@@ -454,7 +454,7 @@ void HTTPRequest::_request_done(int p_status, int p_code, const PackedStringArra
is_compressed = false;
}
- const PackedByteArray *data = NULL;
+ const PackedByteArray *data = nullptr;
if (accept_gzip && is_compressed && p_data.size() > 0) {
// Decompress request body
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 933f67db68..27712242d1 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -1690,7 +1690,7 @@ NodePath Node::get_path_to(const Node *p_node) const {
n = n->data.parent;
}
- path.invert();
+ path.reverse();
return NodePath(path, false);
}
@@ -1711,7 +1711,7 @@ NodePath Node::get_path() const {
n = n->data.parent;
}
- path.invert();
+ path.reverse();
data.path_cache = memnew(NodePath(path, true));
@@ -1968,8 +1968,9 @@ Node *Node::get_deepest_editable_node(Node *p_start_node) const {
Node *node = p_start_node;
while (iterated_item->get_owner() && iterated_item->get_owner() != this) {
- if (!is_editable_instance(iterated_item->get_owner()))
+ if (!is_editable_instance(iterated_item->get_owner())) {
node = iterated_item->get_owner();
+ }
iterated_item = iterated_item->get_owner();
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index c6fe1117d1..a3effef99a 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -131,7 +131,7 @@ bool ViewportTexture::has_alpha() const {
return false;
}
-Ref<Image> ViewportTexture::get_data() const {
+Ref<Image> ViewportTexture::get_image() const {
ERR_FAIL_COND_V_MSG(!vp, Ref<Image>(), "Viewport Texture must be set to use it.");
return RS::get_singleton()->texture_2d_get(vp->texture_rid);
}
@@ -2399,29 +2399,27 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (from && p_event->is_pressed()) {
Control *next = nullptr;
- Input *input = Input::get_singleton();
-
- if (p_event->is_action_pressed("ui_focus_next") && input->is_action_just_pressed("ui_focus_next")) {
+ if (p_event->is_action_pressed("ui_focus_next", true)) {
next = from->find_next_valid_focus();
}
- if (p_event->is_action_pressed("ui_focus_prev") && input->is_action_just_pressed("ui_focus_prev")) {
+ if (p_event->is_action_pressed("ui_focus_prev", true)) {
next = from->find_prev_valid_focus();
}
- if (!mods && p_event->is_action_pressed("ui_up") && input->is_action_just_pressed("ui_up")) {
+ if (!mods && p_event->is_action_pressed("ui_up", true)) {
next = from->_get_focus_neighbor(SIDE_TOP);
}
- if (!mods && p_event->is_action_pressed("ui_left") && input->is_action_just_pressed("ui_left")) {
+ if (!mods && p_event->is_action_pressed("ui_left", true)) {
next = from->_get_focus_neighbor(SIDE_LEFT);
}
- if (!mods && p_event->is_action_pressed("ui_right") && input->is_action_just_pressed("ui_right")) {
+ if (!mods && p_event->is_action_pressed("ui_right", true)) {
next = from->_get_focus_neighbor(SIDE_RIGHT);
}
- if (!mods && p_event->is_action_pressed("ui_down") && input->is_action_just_pressed("ui_down")) {
+ if (!mods && p_event->is_action_pressed("ui_down", true)) {
next = from->_get_focus_neighbor(SIDE_BOTTOM);
}
@@ -3067,6 +3065,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
}
void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
+ ERR_FAIL_COND(p_event.is_null());
ERR_FAIL_COND(!is_inside_tree());
if (disable_input || !_can_consume_input_events()) {
@@ -3227,8 +3226,9 @@ Viewport::ScreenSpaceAA Viewport::get_screen_space_aa() const {
}
void Viewport::set_use_debanding(bool p_use_debanding) {
- if (use_debanding == p_use_debanding)
+ if (use_debanding == p_use_debanding) {
return;
+ }
use_debanding = p_use_debanding;
RS::get_singleton()->viewport_set_use_debanding(viewport, p_use_debanding);
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 0f11e6fb19..8e79b50385 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -77,7 +77,7 @@ public:
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
ViewportTexture();
~ViewportTexture();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index fe8591e3d9..232ad278dd 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -532,6 +532,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<VisualShaderNodeResizableBase>();
ClassDB::register_virtual_class<VisualShaderNodeGroupBase>();
ClassDB::register_virtual_class<VisualShaderNodeConstant>();
+ ClassDB::register_class<VisualShaderNodeComment>();
ClassDB::register_class<VisualShaderNodeFloatConstant>();
ClassDB::register_class<VisualShaderNodeIntConstant>();
ClassDB::register_class<VisualShaderNodeBooleanConstant>();
@@ -955,9 +956,9 @@ void register_scene_types() {
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/use_hidpi", PropertyInfo(Variant::BOOL, "gui/theme/use_hidpi", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
- String theme_path = GLOBAL_DEF("gui/theme/custom", "");
+ String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
- String font_path = GLOBAL_DEF("gui/theme/custom_font", "");
+ String font_path = GLOBAL_DEF_RST("gui/theme/custom_font", "");
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
Ref<Font> font;
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index 6e56f6e7fc..ac31315858 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -41,7 +41,7 @@ bool ConvexPolygonShape2D::_edit_is_selected_on_click(const Point2 &p_point, dou
void ConvexPolygonShape2D::_update_shape() {
Vector<Vector2> final_points = points;
if (Geometry2D::is_polygon_clockwise(final_points)) { //needs to be counter clockwise
- final_points.invert();
+ final_points.reverse();
}
PhysicsServer2D::get_singleton()->shape_set_data(get_rid(), final_points);
emit_changed();
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 854001f397..f05b43377f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -114,7 +114,7 @@ static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false,
}
Ref<ImageTexture> texture(memnew(ImageTexture));
- Ref<Image> img = p_texture->get_data();
+ Ref<Image> img = p_texture->get_image();
img = img->duplicate();
if (p_flip_y) {
@@ -891,6 +891,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("preset_bg", "ColorPicker", make_icon(mini_checkerboard_png));
theme->set_icon("overbright_indicator", "ColorPicker", make_icon(overbright_indicator_png));
theme->set_icon("bar_arrow", "ColorPicker", make_icon(bar_arrow_png));
+ theme->set_icon("picker_cursor", "ColorPicker", make_icon(picker_cursor_png));
theme->set_icon("bg", "ColorPickerButton", make_icon(mini_checkerboard_png));
diff --git a/scene/resources/default_theme/picker_cursor.png b/scene/resources/default_theme/picker_cursor.png
new file mode 100644
index 0000000000..2f403492d2
--- /dev/null
+++ b/scene/resources/default_theme/picker_cursor.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 5d4dbd0758..190f2a03d9 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -266,6 +266,10 @@ static const unsigned char panel_bg_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x25, 0x2a, 0x35, 0x32, 0x3b, 0x4a, 0x73, 0x58, 0x4a, 0x0, 0x0, 0x0, 0xa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x40, 0x3, 0x0, 0x0, 0x10, 0x0, 0x1, 0xb3, 0xac, 0xe2, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char picker_cursor_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xb9, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0x8f, 0x3d, 0x8a, 0xc2, 0x50, 0x18, 0x45, 0xcf, 0x6b, 0x92, 0x2a, 0x19, 0xd4, 0xa4, 0x72, 0x47, 0x3, 0x42, 0xc0, 0x9f, 0x55, 0x44, 0x17, 0x24, 0x88, 0xee, 0x24, 0x53, 0x4d, 0x7e, 0xa, 0xbf, 0x94, 0xd6, 0x71, 0x5, 0xf2, 0x5e, 0x7f, 0x2d, 0xa2, 0xa2, 0xe0, 0x29, 0xef, 0xb9, 0xcd, 0x1, 0x40, 0xb1, 0x76, 0x6a, 0x14, 0x14, 0xd4, 0x68, 0xab, 0x98, 0x11, 0xcd, 0xd5, 0xef, 0x9b, 0xac, 0x27, 0x10, 0x32, 0x3b, 0xb4, 0x32, 0xcd, 0xc7, 0x77, 0xff, 0xfb, 0xc7, 0xc0, 0x92, 0x84, 0x84, 0x82, 0xcb, 0xa2, 0x92, 0x29, 0x46, 0xbb, 0x7d, 0xc3, 0xc0, 0x94, 0x27, 0x13, 0x86, 0x63, 0xa7, 0x12, 0xb5, 0x59, 0xcf, 0x8a, 0x77, 0xd6, 0xb9, 0xa9, 0x46, 0xde, 0x5, 0x92, 0xf, 0x91, 0x3a, 0x2f, 0xff, 0x4d, 0xfc, 0x38, 0xaf, 0x1b, 0x6a, 0x33, 0xa3, 0xf8, 0x10, 0x9b, 0xfc, 0xac, 0x1a, 0x6d, 0xf, 0x2d, 0x17, 0x26, 0xaf, 0x79, 0xc6, 0xf5, 0xd4, 0xa9, 0x44, 0xb1, 0x6c, 0x51, 0x31, 0xb0, 0x26, 0x25, 0x65, 0xc3, 0xb5, 0xa8, 0x64, 0x8a, 0xc6, 0x40, 0x3b, 0x76, 0xb9, 0xb9, 0xe0, 0x42, 0x7e, 0x3e, 0x75, 0x8f, 0x40, 0x0, 0x45, 0x2a, 0x55, 0xcb, 0xcb, 0xeb, 0x5f, 0xa5, 0x22, 0x80, 0x3b, 0xa0, 0x2c, 0x6c, 0xa1, 0x40, 0x2f, 0xda, 0xfc, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char popup_bg_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xa2, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x3b, 0x43, 0x42, 0x42, 0x4b, 0x3e, 0x3e, 0x47, 0x3e, 0x3e, 0x46, 0x41, 0x41, 0x4a, 0x0, 0x0, 0x0, 0x3d, 0x3d, 0x45, 0x3b, 0x3b, 0x43, 0x3a, 0x3a, 0x42, 0x38, 0x38, 0x41, 0x37, 0x37, 0x3e, 0x36, 0x36, 0x3d, 0x35, 0x35, 0x3c, 0x0, 0x0, 0x0, 0x38, 0x38, 0x40, 0x38, 0x38, 0x40, 0x31, 0x31, 0x38, 0x34, 0x34, 0x3b, 0x34, 0x34, 0x3b, 0x39, 0x39, 0x3f, 0x31, 0x31, 0x38, 0x2f, 0x2f, 0x36, 0x2d, 0x2d, 0x33, 0x2c, 0x2c, 0x32, 0x2b, 0x2b, 0x31, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x29, 0x29, 0x30, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x28, 0x28, 0x2d, 0x27, 0x27, 0x2d, 0x27, 0x27, 0x2c, 0x29, 0x29, 0x2e, 0x26, 0x26, 0x2c, 0x36, 0xc6, 0xc8, 0x93, 0x0, 0x0, 0x0, 0x28, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0x4, 0x13, 0x19, 0x1f, 0x22, 0x23, 0x16, 0x27, 0x35, 0x3f, 0x45, 0x46, 0x94, 0xf5, 0xfa, 0xfb, 0xf5, 0x40, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0x1a, 0xf5, 0xf6, 0x95, 0xfa, 0xfb, 0xf4, 0x94, 0x71, 0xda, 0xac, 0x92, 0x0, 0x0, 0x0, 0x7f, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x65, 0x8f, 0x35, 0x82, 0xc3, 0x0, 0xc, 0x4, 0x77, 0x24, 0x85, 0xba, 0xe3, 0xff, 0xff, 0xee, 0xca, 0x74, 0x41, 0xdb, 0x32, 0xf3, 0x94, 0x82, 0x85, 0x10, 0x1d, 0x92, 0xb2, 0x3, 0x8e, 0x95, 0x77, 0x93, 0x6c, 0x28, 0xed, 0x15, 0x54, 0x67, 0xa6, 0x41, 0x3e, 0x8, 0x9c, 0xc3, 0xf4, 0xf2, 0xf6, 0x2a, 0x80, 0xf8, 0x44, 0x2d, 0x79, 0x2d, 0x20, 0xe0, 0x2, 0xa8, 0xc3, 0x2e, 0x6f, 0xc, 0x9e, 0x4c, 0x3c, 0x21, 0x4, 0xd8, 0xf0, 0x2, 0x28, 0x24, 0xcd, 0x3, 0xa9, 0x19, 0x64, 0xce, 0x83, 0x4c, 0x45, 0xe6, 0x69, 0x1a, 0xd8, 0xe9, 0x99, 0x96, 0x7f, 0x77, 0x37, 0x59, 0x83, 0xcc, 0xef, 0x7f, 0x89, 0x1f, 0x8e, 0xbf, 0x95, 0xd3, 0x1d, 0xf0, 0xff, 0x7a, 0x63, 0x7e, 0x86, 0xcb, 0x73, 0x8c, 0x5e, 0xee, 0xca, 0xb1, 0xad, 0x5f, 0x3, 0xaf, 0xdb, 0x49, 0x94, 0x4b, 0x90, 0x40, 0xdf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 0d02bde90d..5647856736 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -829,16 +829,26 @@ void BaseMaterial3D::_update_shader() {
}
if (flags[FLAG_UV1_USE_TRIPLANAR]) {
- code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
+ if (flags[FLAG_UV1_USE_WORLD_TRIPLANAR]) {
+ code += "\tuv1_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL),vec3(uv1_blend_sharpness));\n";
+ code += "\tuv1_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv1_scale + uv1_offset;\n";
+ } else {
+ code += "\tuv1_power_normal=pow(abs(NORMAL),vec3(uv1_blend_sharpness));\n";
+ code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
+ }
code += "\tuv1_power_normal/=dot(uv1_power_normal,vec3(1.0));\n";
- code += "\tuv1_triplanar_pos = VERTEX * uv1_scale + uv1_offset;\n";
code += "\tuv1_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
}
if (flags[FLAG_UV2_USE_TRIPLANAR]) {
- code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
+ if (flags[FLAG_UV2_USE_WORLD_TRIPLANAR]) {
+ code += "\tuv2_power_normal=pow(abs(mat3(WORLD_MATRIX) * NORMAL), vec3(uv2_blend_sharpness));\n";
+ code += "\tuv2_triplanar_pos = (WORLD_MATRIX * vec4(VERTEX, 1.0f)).xyz * uv2_scale + uv2_offset;\n";
+ } else {
+ code += "\tuv2_power_normal=pow(abs(NORMAL), vec3(uv2_blend_sharpness));\n";
+ code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
+ }
code += "\tuv2_power_normal/=dot(uv2_power_normal,vec3(1.0));\n";
- code += "\tuv2_triplanar_pos = VERTEX * uv2_scale + uv2_offset;\n";
code += "\tuv2_triplanar_pos *= vec3(1.0,-1.0, 1.0);\n";
}
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 1a2b21299a..f8e1ce6a61 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -1238,6 +1238,22 @@ StringName ArrayMesh::get_blend_shape_name(int p_index) const {
return blend_shapes[p_index];
}
+void ArrayMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
+ ERR_FAIL_INDEX(p_index, blend_shapes.size());
+
+ StringName name = p_name;
+ int found = blend_shapes.find(name);
+ if (found != -1 && found != p_index) {
+ int count = 2;
+ do {
+ name = String(p_name) + " " + itos(count);
+ count++;
+ } while (blend_shapes.find(name) != -1);
+ }
+
+ blend_shapes.write[p_index] = name;
+}
+
void ArrayMesh::clear_blend_shapes() {
ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created.");
@@ -1590,6 +1606,7 @@ void ArrayMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
+ ClassDB::bind_method(D_METHOD("set_blend_shape_name", "index", "name"), &ArrayMesh::set_blend_shape_name);
ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes);
ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index 2ce519e644..9a462d5719 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -141,6 +141,7 @@ public:
virtual Ref<Material> surface_get_material(int p_idx) const = 0;
virtual int get_blend_shape_count() const = 0;
virtual StringName get_blend_shape_name(int p_index) const = 0;
+ virtual void set_blend_shape_name(int p_index, const StringName &p_name) = 0;
Vector<Face3> get_faces() const;
Ref<TriangleMesh> generate_triangle_mesh() const;
@@ -223,6 +224,7 @@ public:
void add_blend_shape(const StringName &p_name);
int get_blend_shape_count() const override;
StringName get_blend_shape_name(int p_index) const override;
+ void set_blend_shape_name(int p_index, const StringName &p_name) override;
void clear_blend_shapes();
void set_blend_shape_mode(BlendShapeMode p_mode);
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index 536318ed16..a08684a506 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -368,7 +368,7 @@ Vector<Vector2> PolygonPathFinder::find_path(const Vector2 &p_from, const Vector
path.push_back(points[at].pos);
} while (at != aidx);
- path.invert();
+ path.reverse();
}
for (int i = 0; i < points.size() - 2; i++) {
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index ba6c4591c9..1be511e8f1 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -175,6 +175,9 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const {
return StringName();
}
+void PrimitiveMesh::set_blend_shape_name(int p_index, const StringName &p_name) {
+}
+
AABB PrimitiveMesh::get_aabb() const {
if (pending_request) {
_update();
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
index bb3df9d10e..65ecdfc19d 100644
--- a/scene/resources/primitive_meshes.h
+++ b/scene/resources/primitive_meshes.h
@@ -81,6 +81,7 @@ public:
virtual Ref<Material> surface_get_material(int p_idx) const override;
virtual int get_blend_shape_count() const override;
virtual StringName get_blend_shape_name(int p_index) const override;
+ virtual void set_blend_shape_name(int p_index, const StringName &p_name) override;
virtual AABB get_aabb() const override;
virtual RID get_rid() const override;
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 444a4bb22a..341f5abd80 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -98,6 +98,9 @@ void TextParagraph::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_line_underline_position", "line"), &TextParagraph::get_line_underline_position);
ClassDB::bind_method(D_METHOD("get_line_underline_thickness", "line"), &TextParagraph::get_line_underline_thickness);
+ ClassDB::bind_method(D_METHOD("get_spacing_top"), &TextParagraph::get_spacing_top);
+ ClassDB::bind_method(D_METHOD("get_spacing_bottom"), &TextParagraph::get_spacing_bottom);
+
ClassDB::bind_method(D_METHOD("get_dropcap_size"), &TextParagraph::get_dropcap_size);
ClassDB::bind_method(D_METHOD("get_dropcap_lines"), &TextParagraph::get_dropcap_lines);
@@ -266,6 +269,14 @@ bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, i
return res;
}
+int TextParagraph::get_spacing_top() const {
+ return spacing_top;
+}
+
+int TextParagraph::get_spacing_bottom() const {
+ return spacing_bottom;
+}
+
void TextParagraph::_set_bidi_override(const Array &p_override) {
Vector<Vector2i> overrides;
for (int i = 0; i < p_override.size(); i++) {
@@ -609,11 +620,13 @@ int TextParagraph::hit_test(const Point2 &p_coords) const {
const_cast<TextParagraph *>(this)->_shape_lines();
Vector2 ofs;
if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) {
- if (ofs.y < 0)
+ if (ofs.y < 0) {
return 0;
+ }
} else {
- if (ofs.x < 0)
+ if (ofs.x < 0) {
return 0;
+ }
}
for (int i = 0; i < lines.size(); i++) {
if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) {
diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h
index a16fa8c3c4..4396b07130 100644
--- a/scene/resources/text_paragraph.h
+++ b/scene/resources/text_paragraph.h
@@ -116,6 +116,9 @@ public:
float get_line_underline_position(int p_line) const;
float get_line_underline_thickness(int p_line) const;
+ int get_spacing_top() const;
+ int get_spacing_bottom() const;
+
Size2 get_dropcap_size() const;
int get_dropcap_lines() const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index d2bb1338d8..b6a2f24b8b 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -71,7 +71,7 @@ void Texture2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw", "canvas_item", "position", "modulate", "transpose"), &Texture2D::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture2D::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "clip_uv"), &Texture2D::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(true));
- ClassDB::bind_method(D_METHOD("get_data"), &Texture2D::get_data);
+ ClassDB::bind_method(D_METHOD("get_image"), &Texture2D::get_image);
ADD_GROUP("", "");
}
@@ -116,7 +116,7 @@ bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
bool ImageTexture::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name == "image") {
- r_ret = get_data();
+ r_ret = get_image();
} else if (p_name == "size") {
r_ret = Size2(w, h);
} else {
@@ -200,7 +200,7 @@ void ImageTexture::_resource_path_changed() {
String path = get_path();
}
-Ref<Image> ImageTexture::get_data() const {
+Ref<Image> ImageTexture::get_image() const {
if (image_stored) {
return RenderingServer::get_singleton()->texture_2d_get(texture);
} else {
@@ -251,7 +251,7 @@ void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
bool ImageTexture::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
- Ref<Image> img = get_data();
+ Ref<Image> img = get_image();
if (img.is_valid()) {
if (img->is_compressed()) { //must decompress, if compressed
Ref<Image> decom = img->duplicate();
@@ -661,7 +661,7 @@ bool StreamTexture2D::has_alpha() const {
return false;
}
-Ref<Image> StreamTexture2D::get_data() const {
+Ref<Image> StreamTexture2D::get_image() const {
if (texture.is_valid()) {
return RS::get_singleton()->texture_2d_get(texture);
} else {
@@ -671,7 +671,7 @@ Ref<Image> StreamTexture2D::get_data() const {
bool StreamTexture2D::is_pixel_opaque(int p_x, int p_y) const {
if (!alpha_cache.is_valid()) {
- Ref<Image> img = get_data();
+ Ref<Image> img = get_image();
if (img.is_valid()) {
if (img->is_compressed()) { //must decompress, if compressed
Ref<Image> decom = img->duplicate();
@@ -1495,7 +1495,7 @@ Ref<Texture2D> LargeTexture::get_piece_texture(int p_idx) const {
Ref<Image> LargeTexture::to_image() const {
Ref<Image> img = memnew(Image(this->get_width(), this->get_height(), false, Image::FORMAT_RGBA8));
for (int i = 0; i < pieces.size(); i++) {
- Ref<Image> src_img = pieces[i].texture->get_data();
+ Ref<Image> src_img = pieces[i].texture->get_image();
img->blit_rect(src_img, Rect2(0, 0, src_img->get_width(), src_img->get_height()), pieces[i].offset);
}
@@ -1782,7 +1782,7 @@ int GradientTexture::get_width() const {
return width;
}
-Ref<Image> GradientTexture::get_data() const {
+Ref<Image> GradientTexture::get_image() const {
if (!texture.is_valid()) {
return Ref<Image>();
}
@@ -2031,14 +2031,14 @@ bool AnimatedTexture::has_alpha() const {
return frames[current_frame].texture->has_alpha();
}
-Ref<Image> AnimatedTexture::get_data() const {
+Ref<Image> AnimatedTexture::get_image() const {
RWLockRead r(rw_lock);
if (!frames[current_frame].texture.is_valid()) {
return Ref<Image>();
}
- return frames[current_frame].texture->get_data();
+ return frames[current_frame].texture->get_image();
}
bool AnimatedTexture::is_pixel_opaque(int p_x, int p_y) const {
@@ -2543,7 +2543,7 @@ uint32_t CameraTexture::get_flags() const {
return 0;
}
-Ref<Image> CameraTexture::get_data() const {
+Ref<Image> CameraTexture::get_image() const {
// not (yet) supported
return Ref<Image>();
}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index a0d917fd86..16c98f2891 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -71,7 +71,7 @@ public:
virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
- virtual Ref<Image> get_data() const { return Ref<Image>(); }
+ virtual Ref<Image> get_image() const { return Ref<Image>(); }
Texture2D();
};
@@ -108,7 +108,7 @@ public:
Image::Format get_format() const;
void update(const Ref<Image> &p_image, bool p_immediate = false);
- Ref<Image> get_data() const override;
+ Ref<Image> get_image() const override;
int get_width() const override;
int get_height() const override;
@@ -203,7 +203,7 @@ public:
virtual bool has_alpha() const override;
bool is_pixel_opaque(int p_x, int p_y) const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
StreamTexture2D();
~StreamTexture2D();
@@ -716,7 +716,7 @@ public:
virtual int get_height() const override { return 1; }
virtual bool has_alpha() const override { return true; }
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
GradientTexture();
virtual ~GradientTexture();
@@ -812,7 +812,7 @@ public:
virtual bool has_alpha() const override;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
bool is_pixel_opaque(int p_x, int p_y) const override;
@@ -839,7 +839,7 @@ public:
virtual void set_flags(uint32_t p_flags);
virtual uint32_t get_flags() const;
- virtual Ref<Image> get_data() const override;
+ virtual Ref<Image> get_image() const override;
void set_camera_feed_id(int p_new_id);
int get_camera_feed_id() const;
diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp
index 2b173add38..036d11574c 100644
--- a/scene/resources/theme.cpp
+++ b/scene/resources/theme.cpp
@@ -1371,12 +1371,12 @@ void Theme::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "default_font", PROPERTY_HINT_RESOURCE_TYPE, "Font"), "set_default_font", "get_default_font");
ADD_PROPERTY(PropertyInfo(Variant::INT, "default_font_size"), "set_default_font_size", "get_default_font_size");
- BIND_ENUM_CONSTANT(DATA_TYPE_ICON);
- BIND_ENUM_CONSTANT(DATA_TYPE_STYLEBOX);
- BIND_ENUM_CONSTANT(DATA_TYPE_FONT);
- BIND_ENUM_CONSTANT(DATA_TYPE_FONT_SIZE);
BIND_ENUM_CONSTANT(DATA_TYPE_COLOR);
BIND_ENUM_CONSTANT(DATA_TYPE_CONSTANT);
+ BIND_ENUM_CONSTANT(DATA_TYPE_FONT);
+ BIND_ENUM_CONSTANT(DATA_TYPE_FONT_SIZE);
+ BIND_ENUM_CONSTANT(DATA_TYPE_ICON);
+ BIND_ENUM_CONSTANT(DATA_TYPE_STYLEBOX);
BIND_ENUM_CONSTANT(DATA_TYPE_MAX);
}
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 859546694f..e1e24ddab2 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -2667,6 +2667,70 @@ VisualShaderNodeResizableBase::VisualShaderNodeResizableBase() {
set_allow_v_resize(true);
}
+////////////// Comment
+
+String VisualShaderNodeComment::get_caption() const {
+ return title;
+}
+
+int VisualShaderNodeComment::get_input_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeComment::PortType VisualShaderNodeComment::get_input_port_type(int p_port) const {
+ return PortType::PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeComment::get_input_port_name(int p_port) const {
+ return String();
+}
+
+int VisualShaderNodeComment::get_output_port_count() const {
+ return 0;
+}
+
+VisualShaderNodeComment::PortType VisualShaderNodeComment::get_output_port_type(int p_port) const {
+ return PortType::PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeComment::get_output_port_name(int p_port) const {
+ return String();
+}
+
+void VisualShaderNodeComment::set_title(const String &p_title) {
+ title = p_title;
+}
+
+String VisualShaderNodeComment::get_title() const {
+ return title;
+}
+
+void VisualShaderNodeComment::set_description(const String &p_description) {
+ description = p_description;
+}
+
+String VisualShaderNodeComment::get_description() const {
+ return description;
+}
+
+String VisualShaderNodeComment::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+ return String();
+}
+
+void VisualShaderNodeComment::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_title", "title"), &VisualShaderNodeComment::set_title);
+ ClassDB::bind_method(D_METHOD("get_title"), &VisualShaderNodeComment::get_title);
+
+ ClassDB::bind_method(D_METHOD("set_description", "description"), &VisualShaderNodeComment::set_description);
+ ClassDB::bind_method(D_METHOD("get_description"), &VisualShaderNodeComment::get_description);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "description"), "set_description", "get_description");
+}
+
+VisualShaderNodeComment::VisualShaderNodeComment() {
+}
+
////////////// GroupBase
void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) {
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index ef724c7650..54a5c19049 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -421,6 +421,7 @@ public:
bool is_global_code_generated() const;
virtual bool is_qualifier_supported(Qualifier p_qual) const = 0;
+ virtual bool is_convertible_to_constant() const = 0;
virtual Vector<StringName> get_editable_properties() const override;
virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const override;
@@ -510,6 +511,38 @@ public:
VisualShaderNodeResizableBase();
};
+class VisualShaderNodeComment : public VisualShaderNodeResizableBase {
+ GDCLASS(VisualShaderNodeComment, VisualShaderNodeResizableBase);
+
+protected:
+ String title = "Comment";
+ String description = "";
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual String get_caption() const override;
+
+ virtual int get_input_port_count() const override;
+ virtual PortType get_input_port_type(int p_port) const override;
+ virtual String get_input_port_name(int p_port) const override;
+
+ virtual int get_output_port_count() const override;
+ virtual PortType get_output_port_type(int p_port) const override;
+ virtual String get_output_port_name(int p_port) const override;
+
+ virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+ void set_title(const String &p_title);
+ String get_title() const;
+
+ void set_description(const String &p_description);
+ String get_description() const;
+
+ VisualShaderNodeComment();
+};
+
class VisualShaderNodeGroupBase : public VisualShaderNodeResizableBase {
GDCLASS(VisualShaderNodeGroupBase, VisualShaderNodeResizableBase);
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index a99c09e89c..7943b95177 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -3744,6 +3744,10 @@ bool VisualShaderNodeFloatUniform::is_qualifier_supported(Qualifier p_qual) cons
return true; // all qualifiers are supported
}
+bool VisualShaderNodeFloatUniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("hint");
@@ -3911,6 +3915,10 @@ bool VisualShaderNodeIntUniform::is_qualifier_supported(Qualifier p_qual) const
return true; // all qualifiers are supported
}
+bool VisualShaderNodeIntUniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("hint");
@@ -4019,6 +4027,10 @@ bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) co
return true; // all qualifiers are supported
}
+bool VisualShaderNodeBooleanUniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("default_value_enabled");
@@ -4113,6 +4125,10 @@ bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) cons
return true; // all qualifiers are supported
}
+bool VisualShaderNodeColorUniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("default_value_enabled");
@@ -4209,6 +4225,10 @@ bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const
return true; // all qualifiers are supported
}
+bool VisualShaderNodeVec3Uniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("default_value_enabled");
@@ -4309,6 +4329,10 @@ bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual)
return true; // all qualifiers are supported
}
+bool VisualShaderNodeTransformUniform::is_convertible_to_constant() const {
+ return true; // conversion is allowed
+}
+
Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const {
Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties();
props.push_back("default_value_enabled");
@@ -4494,6 +4518,10 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co
return false;
}
+bool VisualShaderNodeTextureUniform::is_convertible_to_constant() const {
+ return false; // conversion is not allowed
+}
+
VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() {
simple_decl = false;
}
@@ -4632,16 +4660,18 @@ String VisualShaderNodeTexture2DArrayUniform::generate_global(Shader::Mode p_mod
switch (texture_type) {
case TYPE_DATA:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black;\n";
- else
+ } else {
code += ";\n";
+ }
break;
case TYPE_COLOR:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black_albedo;\n";
- else
+ } else {
code += " : hint_albedo;\n";
+ }
break;
case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
@@ -4700,16 +4730,18 @@ String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, Vi
switch (texture_type) {
case TYPE_DATA:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black;\n";
- else
+ } else {
code += ";\n";
+ }
break;
case TYPE_COLOR:
- if (color_default == COLOR_DEFAULT_BLACK)
+ if (color_default == COLOR_DEFAULT_BLACK) {
code += " : hint_black_albedo;\n";
- else
+ } else {
code += " : hint_albedo;\n";
+ }
break;
case TYPE_NORMAL_MAP:
code += " : hint_normal;\n";
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index a5d0fe4649..594a494cf1 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1574,6 +1574,7 @@ public:
float get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1639,6 +1640,7 @@ public:
int get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1683,6 +1685,7 @@ public:
bool get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1724,6 +1727,7 @@ public:
Color get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1766,6 +1770,7 @@ public:
Vector3 get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1808,6 +1813,7 @@ public:
Transform get_default_value() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
virtual Vector<StringName> get_editable_properties() const override;
@@ -1865,6 +1871,7 @@ public:
ColorDefault get_color_default() const;
bool is_qualifier_supported(Qualifier p_qual) const override;
+ bool is_convertible_to_constant() const override;
VisualShaderNodeTextureUniform();
};
diff --git a/servers/camera_server.cpp b/servers/camera_server.cpp
index b06f32417c..ee4a2e148b 100644
--- a/servers/camera_server.cpp
+++ b/servers/camera_server.cpp
@@ -99,6 +99,8 @@ Ref<CameraFeed> CameraServer::get_feed_by_id(int p_id) {
};
void CameraServer::add_feed(const Ref<CameraFeed> &p_feed) {
+ ERR_FAIL_COND(p_feed.is_null());
+
// add our feed
feeds.push_back(p_feed);
diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp
index 6485c8d1e9..532cb259b3 100644
--- a/servers/physics_2d/area_2d_sw.cpp
+++ b/servers/physics_2d/area_2d_sw.cpp
@@ -215,7 +215,9 @@ void Area2DSW::call_queries() {
for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
if (E->get().state == 0) { // Nothing happened
- E = E->next();
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
continue;
}
@@ -250,7 +252,9 @@ void Area2DSW::call_queries() {
for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
if (E->get().state == 0) { // Nothing happened
- E = E->next();
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
continue;
}
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 6e7e802a8b..6cc086b9b7 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -502,6 +502,7 @@ Variant CapsuleShape2DSW::get_data() const {
void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_supports, int &r_amount) const {
int support_idx = -1;
real_t d = -1e10;
+ r_amount = 0;
for (int i = 0; i < point_count; i++) {
//test point
@@ -520,7 +521,7 @@ void ConvexPolygonShape2DSW::get_supports(const Vector2 &p_normal, Vector2 *r_su
}
}
- ERR_FAIL_COND(support_idx == -1);
+ ERR_FAIL_COND_MSG(support_idx == -1, "Convex polygon shape support not found.");
r_amount = 1;
r_supports[0] = points[support_idx].pos;
@@ -580,6 +581,7 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
}
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
+ ERR_FAIL_COND_V_MSG(point_count == 0, 0, "Convex polygon shape has no points.");
Rect2 aabb;
aabb.position = points[0].pos * p_scale;
for (int i = 0; i < point_count; i++) {
@@ -691,6 +693,10 @@ bool ConcavePolygonShape2DSW::contains_point(const Vector2 &p_point) const {
}
bool ConcavePolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vector2 &p_end, Vector2 &r_point, Vector2 &r_normal) const {
+ if (segments.size() == 0 || points.size() == 0) {
+ return false;
+ }
+
uint32_t *stack = (uint32_t *)alloca(sizeof(int) * bvh_depth);
enum {
diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp
index b6c5b3003c..bb4e0ed752 100644
--- a/servers/physics_3d/area_3d_sw.cpp
+++ b/servers/physics_3d/area_3d_sw.cpp
@@ -215,7 +215,9 @@ void Area3DSW::call_queries() {
for (Map<BodyKey, BodyState>::Element *E = monitored_bodies.front(); E;) {
if (E->get().state == 0) { // Nothing happened
- E = E->next();
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_bodies.erase(E);
+ E = next;
continue;
}
@@ -250,7 +252,9 @@ void Area3DSW::call_queries() {
for (Map<BodyKey, BodyState>::Element *E = monitored_areas.front(); E;) {
if (E->get().state == 0) { // Nothing happened
- E = E->next();
+ Map<BodyKey, BodyState>::Element *next = E->next();
+ monitored_areas.erase(E);
+ E = next;
continue;
}
diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp
index bf0946a0e2..4c14cb3162 100644
--- a/servers/physics_3d/shape_3d_sw.cpp
+++ b/servers/physics_3d/shape_3d_sw.cpp
@@ -891,6 +891,9 @@ void ConvexPolygonShape3DSW::get_supports(const Vector3 &p_normal, int p_max, Ve
const Vector3 *vertices = mesh.vertices.ptr();
int vc = mesh.vertices.size();
+ r_amount = 0;
+ ERR_FAIL_COND_MSG(vc == 0, "Convex polygon shape has no vertices.");
+
//find vertex first
real_t max = 0;
int vtx = 0;
diff --git a/servers/physics_3d/step_3d_sw.cpp b/servers/physics_3d/step_3d_sw.cpp
index 9a73e11562..2133a38670 100644
--- a/servers/physics_3d/step_3d_sw.cpp
+++ b/servers/physics_3d/step_3d_sw.cpp
@@ -229,10 +229,11 @@ void Step3DSW::step(Space3DSW *p_space, real_t p_delta, int p_iterations) {
while (sb) {
for (const Set<Constraint3DSW *>::Element *E = sb->self()->get_constraints().front(); E; E = E->next()) {
Constraint3DSW *c = E->get();
- if (c->get_island_step() == _step)
+ if (c->get_island_step() == _step) {
continue;
+ }
c->set_island_step(_step);
- c->set_island_next(NULL);
+ c->set_island_next(nullptr);
c->set_island_list_next(constraint_island_list);
constraint_island_list = c;
}
diff --git a/servers/rendering/renderer_rd/SCsub b/servers/rendering/renderer_rd/SCsub
index 6a2e682c67..9c95f538ac 100644
--- a/servers/rendering/renderer_rd/SCsub
+++ b/servers/rendering/renderer_rd/SCsub
@@ -4,4 +4,5 @@ Import("env")
env.add_source_files(env.servers_sources, "*.cpp")
+SConscript("forward_clustered/SCsub")
SConscript("shaders/SCsub")
diff --git a/servers/rendering/renderer_rd/forward_clustered/SCsub b/servers/rendering/renderer_rd/forward_clustered/SCsub
new file mode 100644
index 0000000000..86681f9c74
--- /dev/null
+++ b/servers/rendering/renderer_rd/forward_clustered/SCsub
@@ -0,0 +1,5 @@
+#!/usr/bin/env python
+
+Import("env")
+
+env.add_source_files(env.servers_sources, "*.cpp")
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 7a19495f48..bcdefea567 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_scene_render_forward_clustered.cpp */
+/* render_forward_clustered.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,508 +28,18 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "renderer_scene_render_forward_clustered.h"
+#include "render_forward_clustered.h"
#include "core/config/project_settings.h"
#include "servers/rendering/rendering_device.h"
#include "servers/rendering/rendering_server_default.h"
-/* SCENE SHADER */
-void RendererSceneRenderForwardClustered::ShaderData::set_code(const String &p_code) {
- //compile
+using namespace RendererSceneRenderImplementation;
- code = p_code;
- valid = false;
- ubo_size = 0;
- uniforms.clear();
- uses_screen_texture = false;
-
- if (code == String()) {
- return; //just invalid, but no error
- }
-
- ShaderCompilerRD::GeneratedCode gen_code;
-
- int blend_mode = BLEND_MODE_MIX;
- int depth_testi = DEPTH_TEST_ENABLED;
- int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
- int cull = CULL_BACK;
-
- uses_point_size = false;
- uses_alpha = false;
- uses_blend_alpha = false;
- uses_depth_pre_pass = false;
- uses_discard = false;
- uses_roughness = false;
- uses_normal = false;
- bool wireframe = false;
-
- unshaded = false;
- uses_vertex = false;
- uses_sss = false;
- uses_transmittance = false;
- uses_screen_texture = false;
- uses_depth_texture = false;
- uses_normal_texture = false;
- uses_time = false;
- writes_modelview_or_projection = false;
- uses_world_coordinates = false;
-
- int depth_drawi = DEPTH_DRAW_OPAQUE;
-
- ShaderCompilerRD::IdentifierActions actions;
-
- actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
- actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
- actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_mode, BLEND_MODE_SUB);
- actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MUL);
-
- actions.render_mode_values["alpha_to_coverage"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE);
- actions.render_mode_values["alpha_to_coverage_and_one"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE);
-
- actions.render_mode_values["depth_draw_never"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_DISABLED);
- actions.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_OPAQUE);
- actions.render_mode_values["depth_draw_always"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_ALWAYS);
-
- actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
-
- actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull, CULL_DISABLED);
- actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull, CULL_FRONT);
- actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull, CULL_BACK);
-
- actions.render_mode_flags["unshaded"] = &unshaded;
- actions.render_mode_flags["wireframe"] = &wireframe;
-
- actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
- actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
-
- actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
- actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
-
- actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
- actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
- actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
- actions.usage_flag_pointers["DISCARD"] = &uses_discard;
- actions.usage_flag_pointers["TIME"] = &uses_time;
- actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
- actions.usage_flag_pointers["NORMAL"] = &uses_normal;
- actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal;
-
- actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size;
- actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size;
-
- actions.write_flag_pointers["MODELVIEW_MATRIX"] = &writes_modelview_or_projection;
- actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection;
- actions.write_flag_pointers["VERTEX"] = &uses_vertex;
-
- actions.uniforms = &uniforms;
-
- RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
-
- Error err = scene_singleton->shader.compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
-
- ERR_FAIL_COND(err != OK);
-
- if (version.is_null()) {
- version = scene_singleton->shader.scene_shader.version_create();
- }
-
- depth_draw = DepthDraw(depth_drawi);
- depth_test = DepthTest(depth_testi);
-
-#if 0
- print_line("**compiling shader:");
- print_line("**defines:\n");
- for (int i = 0; i < gen_code.defines.size(); i++) {
- print_line(gen_code.defines[i]);
- }
- print_line("\n**uniforms:\n" + gen_code.uniforms);
- print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
- print_line("\n**vertex_code:\n" + gen_code.vertex);
- print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
- print_line("\n**fragment_code:\n" + gen_code.fragment);
- print_line("\n**light_code:\n" + gen_code.light);
-#endif
- scene_singleton->shader.scene_shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
- ERR_FAIL_COND(!scene_singleton->shader.scene_shader.version_is_valid(version));
-
- ubo_size = gen_code.uniform_total_size;
- ubo_offsets = gen_code.uniform_offsets;
- texture_uniforms = gen_code.texture_uniforms;
-
- //blend modes
-
- // if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage
- if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) {
- blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE;
- }
-
- RD::PipelineColorBlendState::Attachment blend_attachment;
-
- switch (blend_mode) {
- case BLEND_MODE_MIX: {
- blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
-
- } break;
- case BLEND_MODE_ADD: {
- blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
- blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- uses_blend_alpha = true; //force alpha used because of blend
-
- } break;
- case BLEND_MODE_SUB: {
- blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
- blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
- blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
- blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- uses_blend_alpha = true; //force alpha used because of blend
-
- } break;
- case BLEND_MODE_MUL: {
- blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_DST_COLOR;
- blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ZERO;
- blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_DST_ALPHA;
- blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
- uses_blend_alpha = true; //force alpha used because of blend
- } break;
- case BLEND_MODE_ALPHA_TO_COVERAGE: {
- blend_attachment.enable_blend = true;
- blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
- blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
- blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
- blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
- blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
- }
- }
-
- RD::PipelineColorBlendState blend_state_blend;
- blend_state_blend.attachments.push_back(blend_attachment);
- RD::PipelineColorBlendState blend_state_opaque = RD::PipelineColorBlendState::create_disabled(1);
- RD::PipelineColorBlendState blend_state_opaque_specular = RD::PipelineColorBlendState::create_disabled(2);
- RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
- RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
-
- //update pipelines
-
- RD::PipelineDepthStencilState depth_stencil_state;
-
- if (depth_test != DEPTH_TEST_DISABLED) {
- depth_stencil_state.enable_depth_test = true;
- depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
- depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
- }
-
- for (int i = 0; i < CULL_VARIANT_MAX; i++) {
- RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
- { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK },
- { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT },
- { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED }
- };
-
- RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull];
-
- for (int j = 0; j < RS::PRIMITIVE_MAX; j++) {
- RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
- RD::RENDER_PRIMITIVE_POINTS,
- RD::RENDER_PRIMITIVE_LINES,
- RD::RENDER_PRIMITIVE_LINESTRIPS,
- RD::RENDER_PRIMITIVE_TRIANGLES,
- RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
- };
-
- RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
-
- for (int k = 0; k < SHADER_VERSION_MAX; k++) {
- if (!static_cast<RendererSceneRenderForwardClustered *>(singleton)->shader.scene_shader.is_variant_enabled(k)) {
- continue;
- }
- RD::PipelineRasterizationState raster_state;
- raster_state.cull_mode = cull_mode_rd;
- raster_state.wireframe = wireframe;
-
- RD::PipelineColorBlendState blend_state;
- RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
- RD::PipelineMultisampleState multisample_state;
-
- if (uses_alpha || uses_blend_alpha) {
- // only allow these flags to go through if we have some form of msaa
- if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
- multisample_state.enable_alpha_to_coverage = true;
- } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
- multisample_state.enable_alpha_to_coverage = true;
- multisample_state.enable_alpha_to_one = true;
- }
-
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
- blend_state = blend_state_blend;
- if (depth_draw == DEPTH_DRAW_OPAQUE) {
- depth_stencil.enable_depth_write = false; //alpha does not draw depth
- }
- } else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL)) {
- if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
- //none, blend state contains nothing
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
- blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
- } else {
- blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
- }
- } else {
- pipelines[i][j][k].clear();
- continue; // do not use this version (will error if using it is attempted)
- }
- } else {
- if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
- blend_state = blend_state_opaque;
- } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
- //none, leave empty
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
- blend_state = blend_state_depth_normal_roughness;
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) {
- blend_state = blend_state_depth_normal_roughness_giprobe;
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
- blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
- } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_SDF) {
- blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
- } else {
- //specular write
- blend_state = blend_state_opaque_specular;
- depth_stencil.enable_depth_test = false;
- depth_stencil.enable_depth_write = false;
- }
- }
-
- RID shader_variant = scene_singleton->shader.scene_shader.version_get_shader(version, k);
- pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0);
- }
- }
- }
-
- valid = true;
-}
-
-void RendererSceneRenderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
- if (!p_texture.is_valid()) {
- default_texture_params.erase(p_name);
- } else {
- default_texture_params[p_name] = p_texture;
- }
-}
-
-void RendererSceneRenderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
- Map<int, StringName> order;
-
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
- if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
- continue;
- }
-
- if (E->get().texture_order >= 0) {
- order[E->get().texture_order + 100000] = E->key();
- } else {
- order[E->get().order] = E->key();
- }
- }
-
- for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
- PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
- pi.name = E->get();
- p_param_list->push_back(pi);
- }
-}
-
-void RendererSceneRenderForwardClustered::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
- for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
- if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
- continue;
- }
-
- RendererStorage::InstanceShaderParam p;
- p.info = ShaderLanguage::uniform_to_property_info(E->get());
- p.info.name = E->key(); //supply name
- p.index = E->get().instance_index;
- p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
- p_param_list->push_back(p);
- }
-}
-
-bool RendererSceneRenderForwardClustered::ShaderData::is_param_texture(const StringName &p_param) const {
- if (!uniforms.has(p_param)) {
- return false;
- }
-
- return uniforms[p_param].texture_order >= 0;
-}
-
-bool RendererSceneRenderForwardClustered::ShaderData::is_animated() const {
- return false;
-}
-
-bool RendererSceneRenderForwardClustered::ShaderData::casts_shadows() const {
- return false;
-}
-
-Variant RendererSceneRenderForwardClustered::ShaderData::get_default_parameter(const StringName &p_parameter) const {
- if (uniforms.has(p_parameter)) {
- ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
- Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
- return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
- }
- return Variant();
-}
-
-RS::ShaderNativeSourceCode RendererSceneRenderForwardClustered::ShaderData::get_native_source_code() const {
- RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
-
- return scene_singleton->shader.scene_shader.version_get_native_source_code(version);
-}
-
-RendererSceneRenderForwardClustered::ShaderData::ShaderData() {
- valid = false;
- uses_screen_texture = false;
-}
-
-RendererSceneRenderForwardClustered::ShaderData::~ShaderData() {
- RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
- ERR_FAIL_COND(!scene_singleton);
- //pipeline variants will clear themselves if shader is gone
- if (version.is_valid()) {
- scene_singleton->shader.scene_shader.version_free(version);
- }
-}
-
-RendererStorageRD::ShaderData *RendererSceneRenderForwardClustered::_create_shader_func() {
- ShaderData *shader_data = memnew(ShaderData);
- return shader_data;
-}
-
-void RendererSceneRenderForwardClustered::MaterialData::set_render_priority(int p_priority) {
- priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
-}
-
-void RendererSceneRenderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
- next_pass = p_pass;
-}
-
-void RendererSceneRenderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
- RendererSceneRenderForwardClustered *scene_singleton = (RendererSceneRenderForwardClustered *)RendererSceneRenderForwardClustered::singleton;
-
- if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
- p_uniform_dirty = true;
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- uniform_buffer = RID();
- }
-
- ubo_data.resize(shader_data->ubo_size);
- if (ubo_data.size()) {
- uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
- memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
- }
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- //check whether buffer changed
- if (p_uniform_dirty && ubo_data.size()) {
- update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
- RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
- }
-
- uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
-
- if ((uint32_t)texture_cache.size() != tex_uniform_count) {
- texture_cache.resize(tex_uniform_count);
- p_textures_dirty = true;
-
- //clear previous uniform set
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- uniform_set = RID();
- }
- }
-
- if (p_textures_dirty && tex_uniform_count) {
- update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
- }
-
- if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
- // This material does not require an uniform set, so don't create it.
- return;
- }
-
- if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- //no reason to update uniform set, only UBO (or nothing) was needed to update
- return;
- }
-
- Vector<RD::Uniform> uniforms;
-
- {
- if (shader_data->ubo_size) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
- u.binding = 0;
- u.ids.push_back(uniform_buffer);
- uniforms.push_back(u);
- }
-
- const RID *textures = texture_cache.ptrw();
- for (uint32_t i = 0; i < tex_uniform_count; i++) {
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
- u.binding = 1 + i;
- u.ids.push_back(textures[i]);
- uniforms.push_back(u);
- }
- }
-
- uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_singleton->shader.scene_shader.version_get_shader(shader_data->version, 0), MATERIAL_UNIFORM_SET);
-}
-
-RendererSceneRenderForwardClustered::MaterialData::~MaterialData() {
- if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
- RD::get_singleton()->free(uniform_set);
- }
-
- if (uniform_buffer.is_valid()) {
- RD::get_singleton()->free(uniform_buffer);
- }
-}
-
-RendererStorageRD::MaterialData *RendererSceneRenderForwardClustered::_create_material_func(ShaderData *p_shader) {
- MaterialData *material_data = memnew(MaterialData);
- material_data->shader_data = p_shader;
- material_data->last_frame = false;
- //update will happen later anyway so do nothing.
- return material_data;
-}
-
-RendererSceneRenderForwardClustered::RenderBufferDataForward::~RenderBufferDataForward() {
+RenderForwardClustered::RenderBufferDataForwardClustered::~RenderBufferDataForwardClustered() {
clear();
}
-void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_specular() {
+void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_specular() {
if (!specular.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
@@ -583,7 +93,7 @@ void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_specul
}
}
-void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_giprobe() {
+void RenderForwardClustered::RenderBufferDataForwardClustered::ensure_giprobe() {
if (!giprobe_buffer.is_valid()) {
RD::TextureFormat tf;
tf.format = RD::DATA_FORMAT_R8G8_UINT;
@@ -619,7 +129,7 @@ void RendererSceneRenderForwardClustered::RenderBufferDataForward::ensure_giprob
}
}
-void RendererSceneRenderForwardClustered::RenderBufferDataForward::clear() {
+void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
if (giprobe_buffer != RID()) {
RD::get_singleton()->free(giprobe_buffer);
giprobe_buffer = RID();
@@ -673,7 +183,7 @@ void RendererSceneRenderForwardClustered::RenderBufferDataForward::clear() {
}
}
-void RendererSceneRenderForwardClustered::RenderBufferDataForward::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
+void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa) {
clear();
msaa = p_msaa;
@@ -740,7 +250,7 @@ void RendererSceneRenderForwardClustered::RenderBufferDataForward::configure(RID
}
}
-void RendererSceneRenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForward *rb) {
+void RenderForwardClustered::_allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb) {
if (rb->normal_roughness_buffer.is_valid()) {
return;
}
@@ -778,11 +288,11 @@ void RendererSceneRenderForwardClustered::_allocate_normal_roughness_texture(Ren
_render_buffers_clear_uniform_set(rb);
}
-RendererSceneRenderRD::RenderBufferData *RendererSceneRenderForwardClustered::_create_render_buffer_data() {
- return memnew(RenderBufferDataForward);
+RendererSceneRenderRD::RenderBufferData *RenderForwardClustered::_create_render_buffer_data() {
+ return memnew(RenderBufferDataForwardClustered);
}
-bool RendererSceneRenderForwardClustered::free(RID p_rid) {
+bool RenderForwardClustered::free(RID p_rid) {
if (RendererSceneRenderRD::free(p_rid)) {
return true;
}
@@ -791,15 +301,15 @@ bool RendererSceneRenderForwardClustered::free(RID p_rid) {
/// RENDERING ///
-template <RendererSceneRenderForwardClustered::PassMode p_pass_mode>
-void RendererSceneRenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
+template <RenderForwardClustered::PassMode p_pass_mode>
+void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
RD::DrawListID draw_list = p_draw_list;
RD::FramebufferFormatID framebuffer_format = p_framebuffer_Format;
//global scope bindings
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, render_base_uniform_set, SCENE_UNIFORM_SET);
RD::get_singleton()->draw_list_bind_uniform_set(draw_list, p_params->render_pass_uniform_set, RENDER_PASS_UNIFORM_SET);
- RD::get_singleton()->draw_list_bind_uniform_set(draw_list, default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET);
+ RD::get_singleton()->draw_list_bind_uniform_set(draw_list, scene_shader.default_vec4_xform_uniform_set, TRANSFORMS_UNIFORM_SET);
RID prev_material_uniform_set;
@@ -826,7 +336,7 @@ void RendererSceneRenderForwardClustered::_render_list_template(RenderingDevice:
push_constant.base_index = i + p_params->element_offset;
RID material_uniform_set;
- ShaderData *shader;
+ SceneShaderForwardClustered::ShaderData *shader;
void *mesh_surface;
if (shadow_pass || p_params->pass_mode == PASS_MODE_DEPTH) { //regular depth pass can use these too
@@ -845,59 +355,59 @@ void RendererSceneRenderForwardClustered::_render_list_template(RenderingDevice:
}
//find cull variant
- ShaderData::CullVariant cull_variant;
+ SceneShaderForwardClustered::ShaderData::CullVariant cull_variant;
if (p_params->pass_mode == PASS_MODE_DEPTH_MATERIAL || p_params->pass_mode == PASS_MODE_SDF || ((p_params->pass_mode == PASS_MODE_SHADOW || p_params->pass_mode == PASS_MODE_SHADOW_DP) && surf->flags & GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
- cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
+ cull_variant = SceneShaderForwardClustered::ShaderData::CULL_VARIANT_DOUBLE_SIDED;
} else {
bool mirror = surf->owner->mirror;
if (p_params->reverse_cull) {
mirror = !mirror;
}
- cull_variant = mirror ? ShaderData::CULL_VARIANT_REVERSED : ShaderData::CULL_VARIANT_NORMAL;
+ cull_variant = mirror ? SceneShaderForwardClustered::ShaderData::CULL_VARIANT_REVERSED : SceneShaderForwardClustered::ShaderData::CULL_VARIANT_NORMAL;
}
RS::PrimitiveType primitive = surf->primitive;
RID xforms_uniform_set = surf->owner->transforms_uniform_set;
- ShaderVersion shader_version = SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
+ SceneShaderForwardClustered::ShaderVersion shader_version = SceneShaderForwardClustered::SHADER_VERSION_MAX; // Assigned to silence wrong -Wmaybe-initialized.
switch (p_params->pass_mode) {
case PASS_MODE_COLOR:
case PASS_MODE_COLOR_TRANSPARENT: {
if (element_info.uses_lightmap) {
- shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_LIGHTMAP_COLOR_PASS;
} else if (element_info.uses_forward_gi) {
- shader_version = SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI;
} else {
- shader_version = SHADER_VERSION_COLOR_PASS;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS;
}
} break;
case PASS_MODE_COLOR_SPECULAR: {
if (element_info.uses_lightmap) {
- shader_version = SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR;
} else {
- shader_version = SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR;
}
} break;
case PASS_MODE_SHADOW:
case PASS_MODE_DEPTH: {
- shader_version = SHADER_VERSION_DEPTH_PASS;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS;
} break;
case PASS_MODE_SHADOW_DP: {
- shader_version = SHADER_VERSION_DEPTH_PASS_DP;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_DP;
} break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
- shader_version = SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
} break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_GIPROBE: {
- shader_version = SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE;
} break;
case PASS_MODE_DEPTH_MATERIAL: {
- shader_version = SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL;
} break;
case PASS_MODE_SDF: {
- shader_version = SHADER_VERSION_DEPTH_PASS_WITH_SDF;
+ shader_version = SceneShaderForwardClustered::SHADER_VERSION_DEPTH_PASS_WITH_SDF;
} break;
}
@@ -961,7 +471,7 @@ void RendererSceneRenderForwardClustered::_render_list_template(RenderingDevice:
}
}
-void RendererSceneRenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
+void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
//use template for faster performance (pass mode comparisons are inlined)
switch (p_params->pass_mode) {
@@ -998,7 +508,7 @@ void RendererSceneRenderForwardClustered::_render_list(RenderingDevice::DrawList
}
}
-void RendererSceneRenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
+void RenderForwardClustered::_render_list_thread_function(uint32_t p_thread, RenderListParameters *p_params) {
uint32_t render_total = p_params->element_count;
uint32_t total_threads = RendererThreadPool::singleton->thread_work_pool.get_thread_count();
uint32_t render_from = p_thread * render_total / total_threads;
@@ -1006,7 +516,7 @@ void RendererSceneRenderForwardClustered::_render_list_thread_function(uint32_t
_render_list(thread_draw_lists[p_thread], p_params->framebuffer_format, p_params, render_from, render_to);
}
-void RendererSceneRenderForwardClustered::_render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
+void RenderForwardClustered::_render_list_with_threads(RenderListParameters *p_params, RID p_framebuffer, RD::InitialAction p_initial_color_action, RD::FinalAction p_final_color_action, RD::InitialAction p_initial_depth_action, RD::FinalAction p_final_depth_action, const Vector<Color> &p_clear_color_values, float p_clear_depth, uint32_t p_clear_stencil, const Rect2 &p_region, const Vector<RID> &p_storage_textures) {
RD::FramebufferFormatID fb_format = RD::get_singleton()->framebuffer_get_format(p_framebuffer);
p_params->framebuffer_format = fb_format;
@@ -1014,7 +524,7 @@ void RendererSceneRenderForwardClustered::_render_list_with_threads(RenderListPa
//multi threaded
thread_draw_lists.resize(RendererThreadPool::singleton->thread_work_pool.get_thread_count());
RD::get_singleton()->draw_list_begin_split(p_framebuffer, thread_draw_lists.size(), thread_draw_lists.ptr(), p_initial_color_action, p_final_color_action, p_initial_depth_action, p_final_depth_action, p_clear_color_values, p_clear_depth, p_clear_stencil, p_region, p_storage_textures);
- RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RendererSceneRenderForwardClustered::_render_list_thread_function, p_params);
+ RendererThreadPool::singleton->thread_work_pool.do_work(thread_draw_lists.size(), this, &RenderForwardClustered::_render_list_thread_function, p_params);
RD::get_singleton()->draw_list_end(p_params->barrier);
} else {
//single threaded
@@ -1024,7 +534,7 @@ void RendererSceneRenderForwardClustered::_render_list_with_threads(RenderListPa
}
}
-void RendererSceneRenderForwardClustered::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
+void RenderForwardClustered::_setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
//CameraMatrix projection = p_cam_projection;
//projection.flip_y(); // Vulkan and modern APIs use Y-Down
CameraMatrix correction;
@@ -1083,7 +593,7 @@ void RendererSceneRenderForwardClustered::_setup_environment(RID p_environment,
scene_state.ubo.fog_enabled = false;
if (p_render_buffers.is_valid()) {
- RenderBufferDataForward *render_buffers = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+ RenderBufferDataForwardClustered *render_buffers = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
if (render_buffers->msaa != RS::VIEWPORT_MSAA_DISABLED) {
scene_state.ubo.gi_upscale_for_msaa = true;
}
@@ -1274,7 +784,7 @@ void RendererSceneRenderForwardClustered::_setup_environment(RID p_environment,
RD::get_singleton()->buffer_update(scene_state.uniform_buffers[p_index], 0, sizeof(SceneState::UBO), &scene_state.ubo, RD::BARRIER_MASK_RASTER);
}
-void RendererSceneRenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) {
+void RenderForwardClustered::_update_instance_data_buffer(RenderListType p_render_list) {
if (scene_state.instance_data[p_render_list].size() > 0) {
if (scene_state.instance_buffer[p_render_list] == RID() || scene_state.instance_buffer_size[p_render_list] < scene_state.instance_data[p_render_list].size()) {
if (scene_state.instance_buffer[p_render_list] != RID()) {
@@ -1287,7 +797,7 @@ void RendererSceneRenderForwardClustered::_update_instance_data_buffer(RenderLis
RD::get_singleton()->buffer_update(scene_state.instance_buffer[p_render_list], 0, sizeof(SceneState::InstanceData) * scene_state.instance_data[p_render_list].size(), scene_state.instance_data[p_render_list].ptr(), RD::BARRIER_MASK_RASTER);
}
}
-void RendererSceneRenderForwardClustered::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
+void RenderForwardClustered::_fill_instance_data(RenderListType p_render_list, uint32_t p_offset, int32_t p_max_elements, bool p_update_buffer) {
RenderList *rl = &render_list[p_render_list];
uint32_t element_total = p_max_elements >= 0 ? uint32_t(p_max_elements) : rl->elements.size();
@@ -1355,7 +865,7 @@ void RendererSceneRenderForwardClustered::_fill_instance_data(RenderListType p_r
}
}
-void RendererSceneRenderForwardClustered::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) {
+void RenderForwardClustered::_fill_render_list(RenderListType p_render_list, const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi, bool p_using_opaque_gi, const Plane &p_lod_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, bool p_append) {
if (p_render_list == RENDER_LIST_OPAQUE) {
scene_state.used_sss = false;
scene_state.used_screen_texture = false;
@@ -1431,7 +941,7 @@ void RendererSceneRenderForwardClustered::_fill_render_list(RenderListType p_ren
uses_lightmap = true;
}
- } else if (!low_end) {
+ } else {
if (p_using_opaque_gi) {
flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
@@ -1549,14 +1059,14 @@ void RendererSceneRenderForwardClustered::_fill_render_list(RenderListType p_ren
}
}
-void RendererSceneRenderForwardClustered::_setup_giprobes(const PagedArray<RID> &p_giprobes) {
+void RenderForwardClustered::_setup_giprobes(const PagedArray<RID> &p_giprobes) {
scene_state.giprobes_used = MIN(p_giprobes.size(), uint32_t(MAX_GI_PROBES));
for (uint32_t i = 0; i < scene_state.giprobes_used; i++) {
scene_state.giprobe_ids[i] = p_giprobes[i];
}
}
-void RendererSceneRenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
+void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
scene_state.lightmaps_used = 0;
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
if (i >= (int)scene_state.max_lightmaps) {
@@ -1578,10 +1088,10 @@ void RendererSceneRenderForwardClustered::_setup_lightmaps(const PagedArray<RID>
}
}
-void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
- RenderBufferDataForward *render_buffer = nullptr;
+void RenderForwardClustered::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_cluster_buffer, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
+ RenderBufferDataForwardClustered *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
- render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
+ render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffer);
}
RendererSceneEnvironmentRD *env = get_environment(p_environment);
@@ -1623,7 +1133,7 @@ void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, con
opaque_framebuffer = render_buffer->color_fb;
- if (!low_end && p_gi_probes.size() > 0) {
+ if (p_gi_probes.size() > 0) {
using_giprobe = true;
}
@@ -1702,7 +1212,7 @@ void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, con
RD::get_singleton()->draw_command_end_label();
- bool using_sss = !low_end && render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
+ bool using_sss = render_buffer && scene_state.used_sss && sub_surface_scattering_get_quality() != RS::SUB_SURFACE_SCATTERING_QUALITY_DISABLED;
if (using_sss) {
using_separate_specular = true;
@@ -1786,7 +1296,7 @@ void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, con
bool debug_giprobes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_ALBEDO || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_LIGHTING || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_GI_PROBE_EMISSION;
bool debug_sdfgi_probes = get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_SDFGI_PROBES;
- bool depth_pre_pass = !low_end && depth_framebuffer.is_valid();
+ bool depth_pre_pass = depth_framebuffer.is_valid();
bool using_ssao = depth_pre_pass && p_render_buffer.is_valid() && p_environment.is_valid() && environment_is_ssao_enabled(p_environment);
bool continue_depth = false;
@@ -1981,7 +1491,7 @@ void RendererSceneRenderForwardClustered::_render_scene(RID p_render_buffer, con
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_shadow_begin() {
+void RenderForwardClustered::_render_shadow_begin() {
scene_state.shadow_passes.clear();
RD::get_singleton()->draw_command_begin_label("Shadow Setup");
_update_render_base_uniform_set();
@@ -1989,7 +1499,7 @@ void RendererSceneRenderForwardClustered::_render_shadow_begin() {
render_list[RENDER_LIST_SECONDARY].clear();
scene_state.instance_data[RENDER_LIST_SECONDARY].clear();
}
-void RendererSceneRenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
+void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold, const Rect2i &p_rect, bool p_flip_y, bool p_clear_region, bool p_begin, bool p_end) {
uint32_t shadow_pass_index = scene_state.shadow_passes.size();
SceneState::ShadowPass shadow_pass;
@@ -2036,7 +1546,7 @@ void RendererSceneRenderForwardClustered::_render_shadow_append(RID p_framebuffe
}
}
-void RendererSceneRenderForwardClustered::_render_shadow_process() {
+void RenderForwardClustered::_render_shadow_process() {
_update_instance_data_buffer(RENDER_LIST_SECONDARY);
//render shadows one after the other, so this can be done un-barriered and the driver can optimize (as well as allow us to run compute at the same time)
@@ -2048,7 +1558,7 @@ void RendererSceneRenderForwardClustered::_render_shadow_process() {
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
+void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
RD::get_singleton()->draw_command_begin_label("Shadow Render");
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
@@ -2063,7 +1573,7 @@ void RendererSceneRenderForwardClustered::_render_shadow_end(uint32_t p_barrier)
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
+void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
RD::get_singleton()->draw_command_begin_label("Render Collider Heightfield");
@@ -2091,7 +1601,7 @@ void RendererSceneRenderForwardClustered::_render_particle_collider_heightfield(
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RenderForwardClustered::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
RD::get_singleton()->draw_command_begin_label("Render Material");
@@ -2129,7 +1639,7 @@ void RendererSceneRenderForwardClustered::_render_material(const Transform &p_ca
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
+void RenderForwardClustered::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering UV2");
RD::get_singleton()->draw_command_begin_label("Render UV2");
@@ -2191,14 +1701,14 @@ void RendererSceneRenderForwardClustered::_render_uv2(const PagedArray<GeometryI
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
+void RenderForwardClustered::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
RENDER_TIMESTAMP("Render SDFGI");
RD::get_singleton()->draw_command_begin_label("Render SDFGI Voxel");
_update_render_base_uniform_set();
- RenderBufferDataForward *render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+ RenderBufferDataForwardClustered *render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
ERR_FAIL_COND(!render_buffer);
PassMode pass_mode = PASS_MODE_SDF;
@@ -2272,14 +1782,14 @@ void RendererSceneRenderForwardClustered::_render_sdfgi(RID p_render_buffers, co
RD::get_singleton()->draw_command_end_label();
}
-void RendererSceneRenderForwardClustered::_base_uniforms_changed() {
+void RenderForwardClustered::_base_uniforms_changed() {
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
}
render_base_uniform_set = RID();
}
-void RendererSceneRenderForwardClustered::_update_render_base_uniform_set() {
+void RenderForwardClustered::_update_render_base_uniform_set() {
if (render_base_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set) || (lightmap_texture_array_version != storage->lightmap_array_get_version())) {
if (render_base_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
RD::get_singleton()->free(render_base_uniform_set);
@@ -2314,7 +1824,7 @@ void RendererSceneRenderForwardClustered::_update_render_base_uniform_set() {
RD::Uniform u;
u.binding = 2;
u.uniform_type = RD::UNIFORM_TYPE_SAMPLER;
- u.ids.push_back(shadow_sampler);
+ u.ids.push_back(scene_shader.shadow_sampler);
uniforms.push_back(u);
}
@@ -2393,7 +1903,7 @@ void RendererSceneRenderForwardClustered::_update_render_base_uniform_set() {
uniforms.push_back(u);
}
- if (!low_end) {
+ {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 13;
@@ -2401,17 +1911,17 @@ void RendererSceneRenderForwardClustered::_update_render_base_uniform_set() {
uniforms.push_back(u);
}
- render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, SCENE_UNIFORM_SET);
+ render_base_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, SCENE_UNIFORM_SET);
}
}
-RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) {
+RID RenderForwardClustered::_setup_render_pass_uniform_set(RenderListType p_render_list, RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, RID p_cluster_buffer, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, bool p_use_directional_shadow_atlas, int p_index) {
//there should always be enough uniform buffers for render passes, otherwise bugs
ERR_FAIL_INDEX_V(p_index, (int)scene_state.uniform_buffers.size(), RID());
- RenderBufferDataForward *rb = nullptr;
+ RenderBufferDataForwardClustered *rb = nullptr;
if (p_render_buffers.is_valid()) {
- rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+ rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
}
//default render buffer and scene state uniform set
@@ -2431,7 +1941,7 @@ RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderLi
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
RID instance_buffer = scene_state.instance_buffer[p_render_list];
if (instance_buffer == RID()) {
- instance_buffer = default_vec4_xform_buffer; // any buffer will do since its not used
+ instance_buffer = scene_shader.default_vec4_xform_buffer; // any buffer will do since its not used
}
u.ids.push_back(instance_buffer);
uniforms.push_back(u);
@@ -2532,7 +2042,7 @@ RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderLi
RD::Uniform u;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : default_vec4_xform_buffer;
+ RID cb = p_cluster_buffer.is_valid() ? p_cluster_buffer : scene_shader.default_vec4_xform_buffer;
u.ids.push_back(cb);
uniforms.push_back(u);
}
@@ -2555,7 +2065,7 @@ RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderLi
uniforms.push_back(u);
}
- if (!low_end) {
+ {
{
RD::Uniform u;
u.binding = 11;
@@ -2651,11 +2161,11 @@ RID RendererSceneRenderForwardClustered::_setup_render_pass_uniform_set(RenderLi
RD::get_singleton()->free(render_pass_uniform_sets[p_index]);
}
- render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RENDER_PASS_UNIFORM_SET);
+ render_pass_uniform_sets[p_index] = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_rd, RENDER_PASS_UNIFORM_SET);
return render_pass_uniform_sets[p_index];
}
-RID RendererSceneRenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
+RID RenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture) {
if (sdfgi_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(sdfgi_pass_uniform_set)) {
RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
@@ -2748,7 +2258,7 @@ RID RendererSceneRenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RI
RD::Uniform u;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- RID cb = default_vec4_xform_buffer;
+ RID cb = scene_shader.default_vec4_xform_buffer;
u.ids.push_back(cb);
uniforms.push_back(u);
}
@@ -2784,28 +2294,28 @@ RID RendererSceneRenderForwardClustered::_setup_sdfgi_render_pass_uniform_set(RI
uniforms.push_back(u);
}
- sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET);
+ sdfgi_pass_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, scene_shader.default_shader_sdfgi_rd, RENDER_PASS_UNIFORM_SET);
return sdfgi_pass_uniform_set;
}
-void RendererSceneRenderForwardClustered::_render_buffers_clear_uniform_set(RenderBufferDataForward *rb) {
+void RenderForwardClustered::_render_buffers_clear_uniform_set(RenderBufferDataForwardClustered *rb) {
}
-void RendererSceneRenderForwardClustered::_render_buffers_uniform_set_changed(RID p_render_buffers) {
- RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+void RenderForwardClustered::_render_buffers_uniform_set_changed(RID p_render_buffers) {
+ RenderBufferDataForwardClustered *rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
_render_buffers_clear_uniform_set(rb);
}
-RID RendererSceneRenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) {
- RenderBufferDataForward *rb = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffers);
+RID RenderForwardClustered::_render_buffers_get_normal_texture(RID p_render_buffers) {
+ RenderBufferDataForwardClustered *rb = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_buffers);
return rb->normal_roughness_buffer;
}
-RendererSceneRenderForwardClustered *RendererSceneRenderForwardClustered::singleton = nullptr;
+RenderForwardClustered *RenderForwardClustered::singleton = nullptr;
-void RendererSceneRenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
+void RenderForwardClustered::_geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
if (ginstance->dirty_list_element.in_list()) {
return;
@@ -2825,7 +2335,7 @@ void RendererSceneRenderForwardClustered::_geometry_instance_mark_dirty(Geometry
geometry_instance_dirty_list.add(&ginstance->dirty_list_element);
}
-void RendererSceneRenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
+void RenderForwardClustered::_geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh) {
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
@@ -2853,10 +2363,10 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface_with_ma
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_DOUBLE_SIDED_SHADOWS;
}
- if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) {
+ if (has_alpha || has_read_screen_alpha || p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED) {
//material is only meant for alpha pass
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_ALPHA;
- if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED)) {
+ if (p_material->shader_data->uses_depth_pre_pass && !(p_material->shader_data->depth_draw == SceneShaderForwardClustered::ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == SceneShaderForwardClustered::ShaderData::DEPTH_TEST_DISABLED)) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_DEPTH;
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
}
@@ -2866,11 +2376,11 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface_with_ma
flags |= GeometryInstanceSurfaceDataCache::FLAG_PASS_SHADOW;
}
- MaterialData *material_shadow = nullptr;
+ SceneShaderForwardClustered::MaterialData *material_shadow = nullptr;
void *surface_shadow = nullptr;
if (!p_material->shader_data->writes_modelview_or_projection && !p_material->shader_data->uses_vertex && !p_material->shader_data->uses_discard && !p_material->shader_data->uses_depth_pre_pass) {
flags |= GeometryInstanceSurfaceDataCache::FLAG_USES_SHARED_SHADOW_MATERIAL;
- material_shadow = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
+ material_shadow = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
RID shadow_mesh = storage->mesh_get_shadow_mesh(p_mesh);
@@ -2921,15 +2431,15 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface_with_ma
sdcache->sort.priority = p_material->priority;
}
-void RendererSceneRenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
+void RenderForwardClustered::_geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh) {
RID m_src;
m_src = ginstance->data->material_override.is_valid() ? ginstance->data->material_override : p_material;
- MaterialData *material = nullptr;
+ SceneShaderForwardClustered::MaterialData *material = nullptr;
if (m_src.is_valid()) {
- material = (MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
+ material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(m_src, RendererStorageRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
material = nullptr;
}
@@ -2940,8 +2450,8 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface(Geometr
storage->material_update_dependency(m_src, &ginstance->data->dependency_tracker);
}
} else {
- material = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- m_src = default_material;
+ material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(scene_shader.default_material, RendererStorageRD::SHADER_TYPE_3D);
+ m_src = scene_shader.default_material;
}
ERR_FAIL_COND(!material);
@@ -2950,7 +2460,7 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface(Geometr
while (material->next_pass.is_valid()) {
RID next_pass = material->next_pass;
- material = (MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
+ material = (SceneShaderForwardClustered::MaterialData *)storage->material_get_data(next_pass, RendererStorageRD::SHADER_TYPE_3D);
if (!material || !material->shader_data->valid) {
break;
}
@@ -2961,7 +2471,7 @@ void RendererSceneRenderForwardClustered::_geometry_instance_add_surface(Geometr
}
}
-void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) {
+void RenderForwardClustered::_geometry_instance_update(GeometryInstance *p_geometry_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
if (ginstance->data->dirty_dependencies) {
@@ -3022,8 +2532,9 @@ void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInst
for (int j = 0; j < draw_passes; j++) {
RID mesh = storage->particles_get_draw_pass_mesh(ginstance->data->base, j);
- if (!mesh.is_valid())
+ if (!mesh.is_valid()) {
continue;
+ }
const RID *materials = nullptr;
uint32_t surface_count;
@@ -3067,7 +2578,7 @@ void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInst
}
ginstance->base_flags |= (stride << INSTANCE_DATA_FLAGS_MULTIMESH_STRIDE_SHIFT);
- ginstance->transforms_uniform_set = storage->multimesh_get_3d_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ ginstance->transforms_uniform_set = storage->multimesh_get_3d_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
} else if (ginstance->data->base_type == RS::INSTANCE_PARTICLES) {
ginstance->base_flags |= INSTANCE_DATA_FLAG_MULTIMESH;
@@ -3090,12 +2601,12 @@ void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInst
if (!storage->particles_is_using_local_coords(ginstance->data->base)) {
store_transform = false;
}
- ginstance->transforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ ginstance->transforms_uniform_set = storage->particles_get_instance_buffer_uniform_set(ginstance->data->base, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
} else if (ginstance->data->base_type == RS::INSTANCE_MESH) {
if (storage->skeleton_is_valid(ginstance->data->skeleton)) {
ginstance->base_flags |= INSTANCE_DATA_FLAG_SKELETON;
- ginstance->transforms_uniform_set = storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, default_shader_rd, TRANSFORMS_UNIFORM_SET);
+ ginstance->transforms_uniform_set = storage->skeleton_get_3d_uniform_set(ginstance->data->skeleton, scene_shader.default_shader_rd, TRANSFORMS_UNIFORM_SET);
if (ginstance->data->dirty_dependencies) {
storage->skeleton_update_dependency(ginstance->data->skeleton, &ginstance->data->dependency_tracker);
}
@@ -3105,7 +2616,7 @@ void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInst
ginstance->store_transform_cache = store_transform;
ginstance->can_sdfgi = false;
- if (!lightmap_instance_is_valid(ginstance->lightmap_instance) && !low_end) {
+ if (!lightmap_instance_is_valid(ginstance->lightmap_instance)) {
if (ginstance->gi_probes[0].is_null() && (ginstance->data->use_baked_light || ginstance->data->use_dynamic_gi)) {
ginstance->can_sdfgi = true;
}
@@ -3119,24 +2630,24 @@ void RendererSceneRenderForwardClustered::_geometry_instance_update(GeometryInst
ginstance->dirty_list_element.remove_from_list();
}
-void RendererSceneRenderForwardClustered::_update_dirty_geometry_instances() {
+void RenderForwardClustered::_update_dirty_geometry_instances() {
while (geometry_instance_dirty_list.first()) {
_geometry_instance_update(geometry_instance_dirty_list.first()->self());
}
}
-void RendererSceneRenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
+void RenderForwardClustered::_geometry_instance_dependency_changed(RendererStorage::DependencyChangedNotification p_notification, RendererStorage::DependencyTracker *p_tracker) {
switch (p_notification) {
case RendererStorage::DEPENDENCY_CHANGED_MATERIAL:
case RendererStorage::DEPENDENCY_CHANGED_MESH:
case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH:
case RendererStorage::DEPENDENCY_CHANGED_SKELETON_DATA: {
- static_cast<RendererSceneRenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+ static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
} break;
case RendererStorage::DEPENDENCY_CHANGED_MULTIMESH_VISIBLE_INSTANCES: {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_tracker->userdata);
if (ginstance->data->base_type == RS::INSTANCE_MULTIMESH) {
- ginstance->instance_count = static_cast<RendererSceneRenderForwardClustered *>(singleton)->storage->multimesh_get_instances_to_draw(ginstance->data->base);
+ ginstance->instance_count = static_cast<RenderForwardClustered *>(singleton)->storage->multimesh_get_instances_to_draw(ginstance->data->base);
}
} break;
default: {
@@ -3144,11 +2655,11 @@ void RendererSceneRenderForwardClustered::_geometry_instance_dependency_changed(
} break;
}
}
-void RendererSceneRenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
- static_cast<RendererSceneRenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
+void RenderForwardClustered::_geometry_instance_dependency_deleted(const RID &p_dependency, RendererStorage::DependencyTracker *p_tracker) {
+ static_cast<RenderForwardClustered *>(singleton)->_geometry_instance_mark_dirty(static_cast<GeometryInstance *>(p_tracker->userdata));
}
-RendererSceneRender::GeometryInstance *RendererSceneRenderForwardClustered::geometry_instance_create(RID p_base) {
+RendererSceneRender::GeometryInstance *RenderForwardClustered::geometry_instance_create(RID p_base) {
RS::InstanceType type = storage->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
@@ -3165,34 +2676,34 @@ RendererSceneRender::GeometryInstance *RendererSceneRenderForwardClustered::geom
return ginstance;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
+void RenderForwardClustered::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->data->skeleton = p_skeleton;
_geometry_instance_mark_dirty(ginstance);
ginstance->data->dirty_dependencies = true;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
+void RenderForwardClustered::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->data->material_override = p_override;
_geometry_instance_mark_dirty(ginstance);
ginstance->data->dirty_dependencies = true;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
+void RenderForwardClustered::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->data->surface_materials = p_materials;
_geometry_instance_mark_dirty(ginstance);
ginstance->data->dirty_dependencies = true;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
+void RenderForwardClustered::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->mesh_instance = p_mesh_instance;
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
+void RenderForwardClustered::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->transform = p_transform;
@@ -3209,24 +2720,24 @@ void RendererSceneRenderForwardClustered::geometry_instance_set_transform(Geomet
ginstance->lod_model_scale = max_scale;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
+void RenderForwardClustered::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->lod_bias = p_lod_bias;
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
+void RenderForwardClustered::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->data->use_baked_light = p_enable;
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
+void RenderForwardClustered::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->data->use_dynamic_gi = p_enable;
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
+void RenderForwardClustered::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->lightmap_instance = p_lightmap_instance;
@@ -3234,7 +2745,7 @@ void RendererSceneRenderForwardClustered::geometry_instance_set_use_lightmap(Geo
ginstance->lightmap_slice_index = p_lightmap_slice_index;
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
+void RenderForwardClustered::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
if (p_sh9) {
@@ -3251,13 +2762,13 @@ void RendererSceneRenderForwardClustered::geometry_instance_set_lightmap_capture
}
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
+void RenderForwardClustered::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->shader_parameters_offset = p_offset;
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
+void RenderForwardClustered::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
@@ -3265,13 +2776,13 @@ void RendererSceneRenderForwardClustered::geometry_instance_set_cast_double_side
_geometry_instance_mark_dirty(ginstance);
}
-void RendererSceneRenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
+void RenderForwardClustered::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->layer_mask = p_layer_mask;
}
-void RendererSceneRenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) {
+void RenderForwardClustered::geometry_instance_free(GeometryInstance *p_geometry_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
if (ginstance->lightmap_sh != nullptr) {
@@ -3287,28 +2798,28 @@ void RendererSceneRenderForwardClustered::geometry_instance_free(GeometryInstanc
geometry_instance_alloc.free(ginstance);
}
-uint32_t RendererSceneRenderForwardClustered::geometry_instance_get_pair_mask() {
+uint32_t RenderForwardClustered::geometry_instance_get_pair_mask() {
return (1 << RS::INSTANCE_GI_PROBE);
}
-void RendererSceneRenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
+void RenderForwardClustered::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
}
-void RendererSceneRenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
+void RenderForwardClustered::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
}
-void RendererSceneRenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
+void RenderForwardClustered::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
}
-Transform RendererSceneRenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) {
+Transform RenderForwardClustered::geometry_instance_get_transform(GeometryInstance *p_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
ERR_FAIL_COND_V(!ginstance, Transform());
return ginstance->transform;
}
-AABB RendererSceneRenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) {
+AABB RenderForwardClustered::geometry_instance_get_aabb(GeometryInstance *p_instance) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_instance);
ERR_FAIL_COND_V(!ginstance, AABB());
return ginstance->data->aabb;
}
-void RendererSceneRenderForwardClustered::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
+void RenderForwardClustered::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
GeometryInstanceForwardClustered *ginstance = static_cast<GeometryInstanceForwardClustered *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
if (p_gi_probe_instance_count > 0) {
@@ -3324,19 +2835,14 @@ void RendererSceneRenderForwardClustered::geometry_instance_pair_gi_probe_instan
}
}
-RendererSceneRenderForwardClustered::RendererSceneRenderForwardClustered(RendererStorageRD *p_storage) :
+RenderForwardClustered::RenderForwardClustered(RendererStorageRD *p_storage) :
RendererSceneRenderRD(p_storage) {
singleton = this;
- low_end = is_low_end();
/* SCENE SHADER */
{
String defines;
- if (low_end) {
- defines += "\n#define LOW_END_MODE \n";
- }
-
defines += "\n#define MAX_ROUGHNESS_LOD " + itos(get_roughness_layers() - 1) + ".0\n";
if (is_using_radiance_cubemap_array()) {
defines += "\n#define USE_RADIANCE_CUBEMAP_ARRAY \n";
@@ -3346,7 +2852,7 @@ RendererSceneRenderForwardClustered::RendererSceneRenderForwardClustered(Rendere
{
//lightmaps
- scene_state.max_lightmaps = low_end ? 2 : MAX_LIGHTMAPS;
+ scene_state.max_lightmaps = MAX_LIGHTMAPS;
defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n";
defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n";
@@ -3362,267 +2868,13 @@ RendererSceneRenderForwardClustered::RendererSceneRenderForwardClustered(Rendere
defines += "\n#define MATERIAL_UNIFORM_SET " + itos(MATERIAL_UNIFORM_SET) + "\n";
}
- Vector<String> shader_versions;
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_GIPROBE\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n");
- shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n");
- shader_versions.push_back("");
- shader_versions.push_back("\n#define USE_FORWARD_GI\n");
- shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n");
- shader_versions.push_back("\n#define USE_LIGHTMAP\n");
- shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n");
- shader.scene_shader.initialize(shader_versions, defines);
-
- if (is_low_end()) {
- //disable the high end versions
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS, false);
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE, false);
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_SDF, false);
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI, false);
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
- shader.scene_shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
- }
- }
-
- storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
- storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs);
-
- {
- //shader compiler
- ShaderCompilerRD::DefaultIdentifierActions actions;
-
- actions.renames["WORLD_MATRIX"] = "world_matrix";
- actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
- actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
- actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
- actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
- actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
- actions.renames["MODELVIEW_MATRIX"] = "modelview";
- actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
-
- actions.renames["VERTEX"] = "vertex";
- actions.renames["NORMAL"] = "normal";
- actions.renames["TANGENT"] = "tangent";
- actions.renames["BINORMAL"] = "binormal";
- actions.renames["POSITION"] = "position";
- actions.renames["UV"] = "uv_interp";
- actions.renames["UV2"] = "uv2_interp";
- actions.renames["COLOR"] = "color_interp";
- actions.renames["POINT_SIZE"] = "gl_PointSize";
- actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
-
- actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
- actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
- actions.renames["ALPHA_ANTIALIASING_EDGE"] = "alpha_antialiasing_edge";
- actions.renames["ALPHA_TEXTURE_COORDINATE"] = "alpha_texture_coordinate";
-
- //builtins
-
- actions.renames["TIME"] = "scene_data.time";
- actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size";
-
- actions.renames["FRAGCOORD"] = "gl_FragCoord";
- actions.renames["FRONT_FACING"] = "gl_FrontFacing";
- actions.renames["NORMAL_MAP"] = "normal_map";
- actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
- actions.renames["ALBEDO"] = "albedo";
- actions.renames["ALPHA"] = "alpha";
- actions.renames["METALLIC"] = "metallic";
- actions.renames["SPECULAR"] = "specular";
- actions.renames["ROUGHNESS"] = "roughness";
- actions.renames["RIM"] = "rim";
- actions.renames["RIM_TINT"] = "rim_tint";
- actions.renames["CLEARCOAT"] = "clearcoat";
- actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
- actions.renames["ANISOTROPY"] = "anisotropy";
- actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
- actions.renames["SSS_STRENGTH"] = "sss_strength";
- actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
- actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
- actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
- actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
- actions.renames["BACKLIGHT"] = "backlight";
- actions.renames["AO"] = "ao";
- actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
- actions.renames["EMISSION"] = "emission";
- actions.renames["POINT_COORD"] = "gl_PointCoord";
- actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
- actions.renames["SCREEN_UV"] = "screen_uv";
- actions.renames["SCREEN_TEXTURE"] = "color_buffer";
- actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
- actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
- actions.renames["DEPTH"] = "gl_FragDepth";
- actions.renames["OUTPUT_IS_SRGB"] = "true";
- actions.renames["FOG"] = "custom_fog";
- actions.renames["RADIANCE"] = "custom_radiance";
- actions.renames["IRRADIANCE"] = "custom_irradiance";
- actions.renames["BONE_INDICES"] = "bone_attrib";
- actions.renames["BONE_WEIGHTS"] = "weight_attrib";
- actions.renames["CUSTOM0"] = "custom0_attrib";
- actions.renames["CUSTOM1"] = "custom1_attrib";
- actions.renames["CUSTOM2"] = "custom2_attrib";
- actions.renames["CUSTOM3"] = "custom3_attrib";
-
- //for light
- actions.renames["VIEW"] = "view";
- actions.renames["LIGHT_COLOR"] = "light_color";
- actions.renames["LIGHT"] = "light";
- actions.renames["ATTENUATION"] = "attenuation";
- actions.renames["SHADOW_ATTENUATION"] = "shadow_attenuation";
- actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
- actions.renames["SPECULAR_LIGHT"] = "specular_light";
-
- actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
- actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
- actions.usage_defines["BINORMAL"] = "@TANGENT";
- actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n";
- actions.usage_defines["RIM_TINT"] = "@RIM";
- actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n";
- actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT";
- actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n";
- actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
- actions.usage_defines["AO"] = "#define AO_USED\n";
- actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
- actions.usage_defines["UV"] = "#define UV_USED\n";
- actions.usage_defines["UV2"] = "#define UV2_USED\n";
- actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
- actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
- actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
- actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
- actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
- actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
- actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
- actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
- actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
- actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
- actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
-
- actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n";
- actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n";
- actions.usage_defines["ALPHA_ANTIALIASING_EDGE"] = "#define ALPHA_ANTIALIASING_EDGE_USED\n";
- actions.usage_defines["ALPHA_TEXTURE_COORDINATE"] = "@ALPHA_ANTIALIASING_EDGE";
-
- actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
- actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
- actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
- actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
- actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
-
- actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
- actions.usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
-
- actions.usage_defines["FOG"] = "#define CUSTOM_FOG_USED\n";
- actions.usage_defines["RADIANCE"] = "#define CUSTOM_RADIANCE_USED\n";
- actions.usage_defines["IRRADIANCE"] = "#define CUSTOM_IRRADIANCE_USED\n";
-
- actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
- actions.render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
- actions.render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n";
- actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
- actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
-
- bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");
-
- if (!force_lambert) {
- actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
- }
-
- actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
- actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
- actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
-
- actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n";
-
- bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx");
-
- if (!force_blinn) {
- actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
- } else {
- actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n";
- }
-
- actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
- actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
- actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
- actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
- actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
- actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
- actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
- actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
-
- actions.sampler_array_name = "material_samplers";
- actions.base_texture_binding_index = 1;
- actions.texture_layout_set = MATERIAL_UNIFORM_SET;
- actions.base_uniform_string = "material.";
- actions.base_varying_index = 10;
-
- actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
- actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
- actions.global_buffer_array_variable = "global_variables.data";
- actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
-
- shader.compiler.initialize(actions);
- }
-
- {
- //default material and shader
- default_shader = storage->shader_allocate();
- storage->shader_initialize(default_shader);
- storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
- default_material = storage->material_allocate();
- storage->material_initialize(default_material);
- storage->material_set_shader(default_material, default_shader);
-
- MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
- default_shader_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
- if (!low_end) {
- default_shader_sdfgi_rd = shader.scene_shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
- }
- }
-
- {
- overdraw_material_shader = storage->shader_allocate();
- storage->shader_initialize(overdraw_material_shader);
- storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
- overdraw_material = storage->material_allocate();
- storage->material_initialize(overdraw_material);
- storage->material_set_shader(overdraw_material, overdraw_material_shader);
-
- wireframe_material_shader = storage->shader_allocate();
- storage->shader_initialize(wireframe_material_shader);
- storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }");
- wireframe_material = storage->material_allocate();
- storage->material_initialize(wireframe_material);
- storage->material_set_shader(wireframe_material, wireframe_material_shader);
- }
-
- {
- default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
- Vector<RD::Uniform> uniforms;
- RD::Uniform u;
- u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
- u.ids.push_back(default_vec4_xform_buffer);
- u.binding = 0;
- uniforms.push_back(u);
-
- default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, TRANSFORMS_UNIFORM_SET);
- }
- {
- RD::SamplerState sampler;
- sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
- sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
- sampler.enable_compare = true;
- sampler.compare_op = RD::COMPARE_OP_LESS;
- shadow_sampler = RD::get_singleton()->sampler_create(sampler);
+ scene_shader.init(p_storage, defines);
}
render_list_thread_threshold = GLOBAL_GET("rendering/limits/forward_renderer/threaded_render_minimum_instances");
}
-RendererSceneRenderForwardClustered::~RendererSceneRenderForwardClustered() {
+RenderForwardClustered::~RenderForwardClustered() {
directional_shadow_atlas_set_size(0);
//clear base uniform set if still valid
@@ -3636,17 +2888,6 @@ RendererSceneRenderForwardClustered::~RendererSceneRenderForwardClustered() {
RD::get_singleton()->free(sdfgi_pass_uniform_set);
}
- RD::get_singleton()->free(default_vec4_xform_buffer);
- RD::get_singleton()->free(shadow_sampler);
-
- storage->free(wireframe_material_shader);
- storage->free(overdraw_material_shader);
- storage->free(default_shader);
-
- storage->free(wireframe_material);
- storage->free(overdraw_material);
- storage->free(default_material);
-
{
for (uint32_t i = 0; i < scene_state.uniform_buffers.size(); i++) {
RD::get_singleton()->free(scene_state.uniform_buffers[i]);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
index 98e2a7efcc..72e84a6f24 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* renderer_scene_render_forward_clustered.h */
+/* render_forward_clustered.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -32,12 +32,17 @@
#define RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
#include "core/templates/paged_allocator.h"
+#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
-class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
+namespace RendererSceneRenderImplementation {
+
+class RenderForwardClustered : public RendererSceneRenderRD {
+ friend SceneShaderForwardClustered;
+
enum {
SCENE_UNIFORM_SET = 0,
RENDER_PASS_UNIFORM_SET = 1,
@@ -63,155 +68,11 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
/* Scene Shader */
- enum ShaderVersion {
- SHADER_VERSION_DEPTH_PASS,
- SHADER_VERSION_DEPTH_PASS_DP,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
- SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
- SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
- SHADER_VERSION_DEPTH_PASS_WITH_SDF,
- SHADER_VERSION_COLOR_PASS,
- SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
- SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS,
- SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
- SHADER_VERSION_MAX
- };
-
- struct {
- SceneForwardClusteredShaderRD scene_shader;
- ShaderCompilerRD compiler;
- } shader;
-
- /* Material */
-
- struct ShaderData : public RendererStorageRD::ShaderData {
- enum BlendMode { //used internally
- BLEND_MODE_MIX,
- BLEND_MODE_ADD,
- BLEND_MODE_SUB,
- BLEND_MODE_MUL,
- BLEND_MODE_ALPHA_TO_COVERAGE
- };
-
- enum DepthDraw {
- DEPTH_DRAW_DISABLED,
- DEPTH_DRAW_OPAQUE,
- DEPTH_DRAW_ALWAYS
- };
-
- enum DepthTest {
- DEPTH_TEST_DISABLED,
- DEPTH_TEST_ENABLED
- };
-
- enum Cull {
- CULL_DISABLED,
- CULL_FRONT,
- CULL_BACK
- };
-
- enum CullVariant {
- CULL_VARIANT_NORMAL,
- CULL_VARIANT_REVERSED,
- CULL_VARIANT_DOUBLE_SIDED,
- CULL_VARIANT_MAX
-
- };
-
- enum AlphaAntiAliasing {
- ALPHA_ANTIALIASING_OFF,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
- ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
- };
-
- bool valid;
- RID version;
- uint32_t vertex_input_mask;
- PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
-
- String path;
-
- Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
- Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
-
- Vector<uint32_t> ubo_offsets;
- uint32_t ubo_size;
-
- String code;
- Map<StringName, RID> default_texture_params;
-
- DepthDraw depth_draw;
- DepthTest depth_test;
-
- bool uses_point_size;
- bool uses_alpha;
- bool uses_blend_alpha;
- bool uses_alpha_clip;
- bool uses_depth_pre_pass;
- bool uses_discard;
- bool uses_roughness;
- bool uses_normal;
-
- bool unshaded;
- bool uses_vertex;
- bool uses_sss;
- bool uses_transmittance;
- bool uses_screen_texture;
- bool uses_depth_texture;
- bool uses_normal_texture;
- bool uses_time;
- bool writes_modelview_or_projection;
- bool uses_world_coordinates;
-
- uint64_t last_pass = 0;
- uint32_t index = 0;
-
- virtual void set_code(const String &p_Code);
- virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
- virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
- void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
-
- virtual bool is_param_texture(const StringName &p_param) const;
- virtual bool is_animated() const;
- virtual bool casts_shadows() const;
- virtual Variant get_default_parameter(const StringName &p_parameter) const;
- virtual RS::ShaderNativeSourceCode get_native_source_code() const;
-
- ShaderData();
- virtual ~ShaderData();
- };
-
- RendererStorageRD::ShaderData *_create_shader_func();
- static RendererStorageRD::ShaderData *_create_shader_funcs() {
- return static_cast<RendererSceneRenderForwardClustered *>(singleton)->_create_shader_func();
- }
-
- struct MaterialData : public RendererStorageRD::MaterialData {
- uint64_t last_frame;
- ShaderData *shader_data;
- RID uniform_buffer;
- RID uniform_set;
- Vector<RID> texture_cache;
- Vector<uint8_t> ubo_data;
- uint64_t last_pass = 0;
- uint32_t index = 0;
- RID next_pass;
- uint8_t priority;
- virtual void set_render_priority(int p_priority);
- virtual void set_next_pass(RID p_pass);
- virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
- virtual ~MaterialData();
- };
-
- RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
- static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
- return static_cast<RendererSceneRenderForwardClustered *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
- }
+ SceneShaderForwardClustered scene_shader;
/* Framebuffer */
- struct RenderBufferDataForward : public RenderBufferData {
+ struct RenderBufferDataForwardClustered : public RenderBufferData {
//for rendering, may be MSAAd
RID color;
@@ -244,13 +105,12 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
void clear();
virtual void configure(RID p_color_buffer, RID p_depth_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa);
- ~RenderBufferDataForward();
+ ~RenderBufferDataForwardClustered();
};
virtual RenderBufferData *_create_render_buffer_data();
- void _allocate_normal_roughness_texture(RenderBufferDataForward *rb);
+ void _allocate_normal_roughness_texture(RenderBufferDataForwardClustered *rb);
- RID shadow_sampler;
RID render_base_uniform_set;
LocalVector<RID> render_pass_uniform_sets;
RID sdfgi_pass_uniform_set;
@@ -258,7 +118,7 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
virtual void _base_uniforms_changed();
- void _render_buffers_clear_uniform_set(RenderBufferDataForward *rb);
+ void _render_buffers_clear_uniform_set(RenderBufferDataForwardClustered *rb);
virtual void _render_buffers_uniform_set_changed(RID p_render_buffers);
virtual RID _render_buffers_get_normal_texture(RID p_render_buffers);
@@ -488,19 +348,7 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
} scene_state;
- static RendererSceneRenderForwardClustered *singleton;
-
- RID default_shader;
- RID default_material;
- RID overdraw_material_shader;
- RID overdraw_material;
- RID wireframe_material_shader;
- RID wireframe_material;
- RID default_shader_rd;
- RID default_shader_sdfgi_rd;
-
- RID default_vec4_xform_buffer;
- RID default_vec4_xform_uniform_set;
+ static RenderForwardClustered *singleton;
void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2i &p_screen_size, uint32_t p_cluster_size, uint32_t p_max_cluster_elements, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
void _setup_giprobes(const PagedArray<RID> &p_giprobes);
@@ -578,11 +426,11 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
void *surface = nullptr;
RID material_uniform_set;
- ShaderData *shader = nullptr;
+ SceneShaderForwardClustered::ShaderData *shader = nullptr;
void *surface_shadow = nullptr;
RID material_uniform_set_shadow;
- ShaderData *shader_shadow = nullptr;
+ SceneShaderForwardClustered::ShaderData *shader_shadow = nullptr;
GeometryInstanceSurfaceDataCache *next = nullptr;
GeometryInstanceForwardClustered *owner = nullptr;
@@ -650,14 +498,12 @@ class RendererSceneRenderForwardClustered : public RendererSceneRenderRD {
PagedAllocator<GeometryInstanceSurfaceDataCache> geometry_instance_surface_alloc;
PagedAllocator<GeometryInstanceLightmapSH> geometry_instance_lightmap_sh;
- void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
+ void _geometry_instance_add_surface_with_material(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, SceneShaderForwardClustered::MaterialData *p_material, uint32_t p_material_id, uint32_t p_shader_id, RID p_mesh);
void _geometry_instance_add_surface(GeometryInstanceForwardClustered *ginstance, uint32_t p_surface, RID p_material, RID p_mesh);
void _geometry_instance_mark_dirty(GeometryInstance *p_geometry_instance);
void _geometry_instance_update(GeometryInstance *p_geometry_instance);
void _update_dirty_geometry_instances();
- bool low_end = false;
-
/* Render List */
struct RenderList {
@@ -760,7 +606,8 @@ public:
virtual bool free(RID p_rid);
- RendererSceneRenderForwardClustered(RendererStorageRD *p_storage);
- ~RendererSceneRenderForwardClustered();
+ RenderForwardClustered(RendererStorageRD *p_storage);
+ ~RenderForwardClustered();
};
+} // namespace RendererSceneRenderImplementation
#endif // !RENDERING_SERVER_SCENE_RENDER_FORWARD_CLUSTERED_H
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
new file mode 100644
index 0000000000..45f6384b5e
--- /dev/null
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -0,0 +1,807 @@
+/*************************************************************************/
+/* scene_shader_forward_clustered.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "scene_shader_forward_clustered.h"
+#include "core/config/project_settings.h"
+#include "render_forward_clustered.h"
+
+using namespace RendererSceneRenderImplementation;
+
+void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
+ //compile
+
+ code = p_code;
+ valid = false;
+ ubo_size = 0;
+ uniforms.clear();
+ uses_screen_texture = false;
+
+ if (code == String()) {
+ return; //just invalid, but no error
+ }
+
+ ShaderCompilerRD::GeneratedCode gen_code;
+
+ int blend_mode = BLEND_MODE_MIX;
+ int depth_testi = DEPTH_TEST_ENABLED;
+ int alpha_antialiasing_mode = ALPHA_ANTIALIASING_OFF;
+ int cull = CULL_BACK;
+
+ uses_point_size = false;
+ uses_alpha = false;
+ uses_blend_alpha = false;
+ uses_depth_pre_pass = false;
+ uses_discard = false;
+ uses_roughness = false;
+ uses_normal = false;
+ bool wireframe = false;
+
+ unshaded = false;
+ uses_vertex = false;
+ uses_sss = false;
+ uses_transmittance = false;
+ uses_screen_texture = false;
+ uses_depth_texture = false;
+ uses_normal_texture = false;
+ uses_time = false;
+ writes_modelview_or_projection = false;
+ uses_world_coordinates = false;
+
+ int depth_drawi = DEPTH_DRAW_OPAQUE;
+
+ ShaderCompilerRD::IdentifierActions actions;
+
+ actions.render_mode_values["blend_add"] = Pair<int *, int>(&blend_mode, BLEND_MODE_ADD);
+ actions.render_mode_values["blend_mix"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MIX);
+ actions.render_mode_values["blend_sub"] = Pair<int *, int>(&blend_mode, BLEND_MODE_SUB);
+ actions.render_mode_values["blend_mul"] = Pair<int *, int>(&blend_mode, BLEND_MODE_MUL);
+
+ actions.render_mode_values["alpha_to_coverage"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE);
+ actions.render_mode_values["alpha_to_coverage_and_one"] = Pair<int *, int>(&alpha_antialiasing_mode, ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE);
+
+ actions.render_mode_values["depth_draw_never"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_DISABLED);
+ actions.render_mode_values["depth_draw_opaque"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_OPAQUE);
+ actions.render_mode_values["depth_draw_always"] = Pair<int *, int>(&depth_drawi, DEPTH_DRAW_ALWAYS);
+
+ actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
+
+ actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull, CULL_DISABLED);
+ actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull, CULL_FRONT);
+ actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull, CULL_BACK);
+
+ actions.render_mode_flags["unshaded"] = &unshaded;
+ actions.render_mode_flags["wireframe"] = &wireframe;
+
+ actions.usage_flag_pointers["ALPHA"] = &uses_alpha;
+ actions.render_mode_flags["depth_prepass_alpha"] = &uses_depth_pre_pass;
+
+ actions.usage_flag_pointers["SSS_STRENGTH"] = &uses_sss;
+ actions.usage_flag_pointers["SSS_TRANSMITTANCE_DEPTH"] = &uses_transmittance;
+
+ actions.usage_flag_pointers["SCREEN_TEXTURE"] = &uses_screen_texture;
+ actions.usage_flag_pointers["DEPTH_TEXTURE"] = &uses_depth_texture;
+ actions.usage_flag_pointers["NORMAL_TEXTURE"] = &uses_normal_texture;
+ actions.usage_flag_pointers["DISCARD"] = &uses_discard;
+ actions.usage_flag_pointers["TIME"] = &uses_time;
+ actions.usage_flag_pointers["ROUGHNESS"] = &uses_roughness;
+ actions.usage_flag_pointers["NORMAL"] = &uses_normal;
+ actions.usage_flag_pointers["NORMAL_MAP"] = &uses_normal;
+
+ actions.usage_flag_pointers["POINT_SIZE"] = &uses_point_size;
+ actions.usage_flag_pointers["POINT_COORD"] = &uses_point_size;
+
+ actions.write_flag_pointers["MODELVIEW_MATRIX"] = &writes_modelview_or_projection;
+ actions.write_flag_pointers["PROJECTION_MATRIX"] = &writes_modelview_or_projection;
+ actions.write_flag_pointers["VERTEX"] = &uses_vertex;
+
+ actions.uniforms = &uniforms;
+
+ SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
+ Error err = shader_singleton->compiler.compile(RS::SHADER_SPATIAL, code, &actions, path, gen_code);
+
+ ERR_FAIL_COND(err != OK);
+
+ if (version.is_null()) {
+ version = shader_singleton->shader.version_create();
+ }
+
+ depth_draw = DepthDraw(depth_drawi);
+ depth_test = DepthTest(depth_testi);
+
+#if 0
+ print_line("**compiling shader:");
+ print_line("**defines:\n");
+ for (int i = 0; i < gen_code.defines.size(); i++) {
+ print_line(gen_code.defines[i]);
+ }
+ print_line("\n**uniforms:\n" + gen_code.uniforms);
+ print_line("\n**vertex_globals:\n" + gen_code.vertex_global);
+ print_line("\n**vertex_code:\n" + gen_code.vertex);
+ print_line("\n**fragment_globals:\n" + gen_code.fragment_global);
+ print_line("\n**fragment_code:\n" + gen_code.fragment);
+ print_line("\n**light_code:\n" + gen_code.light);
+#endif
+ shader_singleton->shader.version_set_code(version, gen_code.uniforms, gen_code.vertex_global, gen_code.vertex, gen_code.fragment_global, gen_code.light, gen_code.fragment, gen_code.defines);
+ ERR_FAIL_COND(!shader_singleton->shader.version_is_valid(version));
+
+ ubo_size = gen_code.uniform_total_size;
+ ubo_offsets = gen_code.uniform_offsets;
+ texture_uniforms = gen_code.texture_uniforms;
+
+ //blend modes
+
+ // if any form of Alpha Antialiasing is enabled, set the blend mode to alpha to coverage
+ if (alpha_antialiasing_mode != ALPHA_ANTIALIASING_OFF) {
+ blend_mode = BLEND_MODE_ALPHA_TO_COVERAGE;
+ }
+
+ RD::PipelineColorBlendState::Attachment blend_attachment;
+
+ switch (blend_mode) {
+ case BLEND_MODE_MIX: {
+ blend_attachment.enable_blend = true;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+
+ } break;
+ case BLEND_MODE_ADD: {
+ blend_attachment.enable_blend = true;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
+ blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ uses_blend_alpha = true; //force alpha used because of blend
+
+ } break;
+ case BLEND_MODE_SUB: {
+ blend_attachment.enable_blend = true;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_SUBTRACT;
+ blend_attachment.color_blend_op = RD::BLEND_OP_SUBTRACT;
+ blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE;
+ blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ uses_blend_alpha = true; //force alpha used because of blend
+
+ } break;
+ case BLEND_MODE_MUL: {
+ blend_attachment.enable_blend = true;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_DST_COLOR;
+ blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ZERO;
+ blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_DST_ALPHA;
+ blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
+ uses_blend_alpha = true; //force alpha used because of blend
+ } break;
+ case BLEND_MODE_ALPHA_TO_COVERAGE: {
+ blend_attachment.enable_blend = true;
+ blend_attachment.alpha_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.color_blend_op = RD::BLEND_OP_ADD;
+ blend_attachment.src_color_blend_factor = RD::BLEND_FACTOR_SRC_ALPHA;
+ blend_attachment.dst_color_blend_factor = RD::BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
+ blend_attachment.src_alpha_blend_factor = RD::BLEND_FACTOR_ONE;
+ blend_attachment.dst_alpha_blend_factor = RD::BLEND_FACTOR_ZERO;
+ }
+ }
+
+ RD::PipelineColorBlendState blend_state_blend;
+ blend_state_blend.attachments.push_back(blend_attachment);
+ RD::PipelineColorBlendState blend_state_opaque = RD::PipelineColorBlendState::create_disabled(1);
+ RD::PipelineColorBlendState blend_state_opaque_specular = RD::PipelineColorBlendState::create_disabled(2);
+ RD::PipelineColorBlendState blend_state_depth_normal_roughness = RD::PipelineColorBlendState::create_disabled(1);
+ RD::PipelineColorBlendState blend_state_depth_normal_roughness_giprobe = RD::PipelineColorBlendState::create_disabled(2);
+
+ //update pipelines
+
+ RD::PipelineDepthStencilState depth_stencil_state;
+
+ if (depth_test != DEPTH_TEST_DISABLED) {
+ depth_stencil_state.enable_depth_test = true;
+ depth_stencil_state.depth_compare_operator = RD::COMPARE_OP_LESS_OR_EQUAL;
+ depth_stencil_state.enable_depth_write = depth_draw != DEPTH_DRAW_DISABLED ? true : false;
+ }
+
+ for (int i = 0; i < CULL_VARIANT_MAX; i++) {
+ RD::PolygonCullMode cull_mode_rd_table[CULL_VARIANT_MAX][3] = {
+ { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_FRONT, RD::POLYGON_CULL_BACK },
+ { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_BACK, RD::POLYGON_CULL_FRONT },
+ { RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED, RD::POLYGON_CULL_DISABLED }
+ };
+
+ RD::PolygonCullMode cull_mode_rd = cull_mode_rd_table[i][cull];
+
+ for (int j = 0; j < RS::PRIMITIVE_MAX; j++) {
+ RD::RenderPrimitive primitive_rd_table[RS::PRIMITIVE_MAX] = {
+ RD::RENDER_PRIMITIVE_POINTS,
+ RD::RENDER_PRIMITIVE_LINES,
+ RD::RENDER_PRIMITIVE_LINESTRIPS,
+ RD::RENDER_PRIMITIVE_TRIANGLES,
+ RD::RENDER_PRIMITIVE_TRIANGLE_STRIPS,
+ };
+
+ RD::RenderPrimitive primitive_rd = uses_point_size ? RD::RENDER_PRIMITIVE_POINTS : primitive_rd_table[j];
+
+ for (int k = 0; k < SHADER_VERSION_MAX; k++) {
+ if (!static_cast<SceneShaderForwardClustered *>(singleton)->shader.is_variant_enabled(k)) {
+ continue;
+ }
+ RD::PipelineRasterizationState raster_state;
+ raster_state.cull_mode = cull_mode_rd;
+ raster_state.wireframe = wireframe;
+
+ RD::PipelineColorBlendState blend_state;
+ RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
+ RD::PipelineMultisampleState multisample_state;
+
+ if (uses_alpha || uses_blend_alpha) {
+ // only allow these flags to go through if we have some form of msaa
+ if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
+ multisample_state.enable_alpha_to_coverage = true;
+ } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
+ multisample_state.enable_alpha_to_coverage = true;
+ multisample_state.enable_alpha_to_one = true;
+ }
+
+ if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
+ blend_state = blend_state_blend;
+ if (depth_draw == DEPTH_DRAW_OPAQUE) {
+ depth_stencil.enable_depth_write = false; //alpha does not draw depth
+ }
+ } else if (uses_depth_pre_pass && (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP || k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS || k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL)) {
+ if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
+ //none, blend state contains nothing
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
+ blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
+ } else {
+ blend_state = blend_state_opaque; //writes to normal and roughness in opaque way
+ }
+ } else {
+ pipelines[i][j][k].clear();
+ continue; // do not use this version (will error if using it is attempted)
+ }
+ } else {
+ if (k == SHADER_VERSION_COLOR_PASS || k == SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI || k == SHADER_VERSION_LIGHTMAP_COLOR_PASS) {
+ blend_state = blend_state_opaque;
+ } else if (k == SHADER_VERSION_DEPTH_PASS || k == SHADER_VERSION_DEPTH_PASS_DP) {
+ //none, leave empty
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
+ blend_state = blend_state_depth_normal_roughness;
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE) {
+ blend_state = blend_state_depth_normal_roughness_giprobe;
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL) {
+ blend_state = RD::PipelineColorBlendState::create_disabled(5); //writes to normal and roughness in opaque way
+ } else if (k == SHADER_VERSION_DEPTH_PASS_WITH_SDF) {
+ blend_state = RD::PipelineColorBlendState(); //no color targets for SDF
+ } else {
+ //specular write
+ blend_state = blend_state_opaque_specular;
+ depth_stencil.enable_depth_test = false;
+ depth_stencil.enable_depth_write = false;
+ }
+ }
+
+ RID shader_variant = shader_singleton->shader.version_get_shader(version, k);
+ pipelines[i][j][k].setup(shader_variant, primitive_rd, raster_state, multisample_state, depth_stencil, blend_state, 0);
+ }
+ }
+ }
+
+ valid = true;
+}
+
+void SceneShaderForwardClustered::ShaderData::set_default_texture_param(const StringName &p_name, RID p_texture) {
+ if (!p_texture.is_valid()) {
+ default_texture_params.erase(p_name);
+ } else {
+ default_texture_params[p_name] = p_texture;
+ }
+}
+
+void SceneShaderForwardClustered::ShaderData::get_param_list(List<PropertyInfo> *p_param_list) const {
+ Map<int, StringName> order;
+
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_LOCAL) {
+ continue;
+ }
+
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
+ }
+
+ for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
+ PropertyInfo pi = ShaderLanguage::uniform_to_property_info(uniforms[E->get()]);
+ pi.name = E->get();
+ p_param_list->push_back(pi);
+ }
+}
+
+void SceneShaderForwardClustered::ShaderData::get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const {
+ for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = uniforms.front(); E; E = E->next()) {
+ if (E->get().scope != ShaderLanguage::ShaderNode::Uniform::SCOPE_INSTANCE) {
+ continue;
+ }
+
+ RendererStorage::InstanceShaderParam p;
+ p.info = ShaderLanguage::uniform_to_property_info(E->get());
+ p.info.name = E->key(); //supply name
+ p.index = E->get().instance_index;
+ p.default_value = ShaderLanguage::constant_value_to_variant(E->get().default_value, E->get().type, E->get().hint);
+ p_param_list->push_back(p);
+ }
+}
+
+bool SceneShaderForwardClustered::ShaderData::is_param_texture(const StringName &p_param) const {
+ if (!uniforms.has(p_param)) {
+ return false;
+ }
+
+ return uniforms[p_param].texture_order >= 0;
+}
+
+bool SceneShaderForwardClustered::ShaderData::is_animated() const {
+ return false;
+}
+
+bool SceneShaderForwardClustered::ShaderData::casts_shadows() const {
+ return false;
+}
+
+Variant SceneShaderForwardClustered::ShaderData::get_default_parameter(const StringName &p_parameter) const {
+ if (uniforms.has(p_parameter)) {
+ ShaderLanguage::ShaderNode::Uniform uniform = uniforms[p_parameter];
+ Vector<ShaderLanguage::ConstantNode::Value> default_value = uniform.default_value;
+ return ShaderLanguage::constant_value_to_variant(default_value, uniform.type, uniform.hint);
+ }
+ return Variant();
+}
+
+RS::ShaderNativeSourceCode SceneShaderForwardClustered::ShaderData::get_native_source_code() const {
+ SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
+
+ return shader_singleton->shader.version_get_native_source_code(version);
+}
+
+SceneShaderForwardClustered::ShaderData::ShaderData() {
+ valid = false;
+ uses_screen_texture = false;
+}
+
+SceneShaderForwardClustered::ShaderData::~ShaderData() {
+ SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
+ ERR_FAIL_COND(!shader_singleton);
+ //pipeline variants will clear themselves if shader is gone
+ if (version.is_valid()) {
+ shader_singleton->shader.version_free(version);
+ }
+}
+
+RendererStorageRD::ShaderData *SceneShaderForwardClustered::_create_shader_func() {
+ ShaderData *shader_data = memnew(ShaderData);
+ return shader_data;
+}
+
+void SceneShaderForwardClustered::MaterialData::set_render_priority(int p_priority) {
+ priority = p_priority - RS::MATERIAL_RENDER_PRIORITY_MIN; //8 bits
+}
+
+void SceneShaderForwardClustered::MaterialData::set_next_pass(RID p_pass) {
+ next_pass = p_pass;
+}
+
+void SceneShaderForwardClustered::MaterialData::update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty) {
+ SceneShaderForwardClustered *shader_singleton = (SceneShaderForwardClustered *)SceneShaderForwardClustered::singleton;
+
+ if ((uint32_t)ubo_data.size() != shader_data->ubo_size) {
+ p_uniform_dirty = true;
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ uniform_buffer = RID();
+ }
+
+ ubo_data.resize(shader_data->ubo_size);
+ if (ubo_data.size()) {
+ uniform_buffer = RD::get_singleton()->uniform_buffer_create(ubo_data.size());
+ memset(ubo_data.ptrw(), 0, ubo_data.size()); //clear
+ }
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ //check whether buffer changed
+ if (p_uniform_dirty && ubo_data.size()) {
+ update_uniform_buffer(shader_data->uniforms, shader_data->ubo_offsets.ptr(), p_parameters, ubo_data.ptrw(), ubo_data.size(), false);
+ RD::get_singleton()->buffer_update(uniform_buffer, 0, ubo_data.size(), ubo_data.ptrw(), RD::BARRIER_MASK_RASTER);
+ }
+
+ uint32_t tex_uniform_count = shader_data->texture_uniforms.size();
+
+ if ((uint32_t)texture_cache.size() != tex_uniform_count) {
+ texture_cache.resize(tex_uniform_count);
+ p_textures_dirty = true;
+
+ //clear previous uniform set
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ uniform_set = RID();
+ }
+ }
+
+ if (p_textures_dirty && tex_uniform_count) {
+ update_textures(p_parameters, shader_data->default_texture_params, shader_data->texture_uniforms, texture_cache.ptrw(), true);
+ }
+
+ if (shader_data->ubo_size == 0 && shader_data->texture_uniforms.size() == 0) {
+ // This material does not require an uniform set, so don't create it.
+ return;
+ }
+
+ if (!p_textures_dirty && uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ //no reason to update uniform set, only UBO (or nothing) was needed to update
+ return;
+ }
+
+ Vector<RD::Uniform> uniforms;
+
+ {
+ if (shader_data->ubo_size) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
+ u.binding = 0;
+ u.ids.push_back(uniform_buffer);
+ uniforms.push_back(u);
+ }
+
+ const RID *textures = texture_cache.ptrw();
+ for (uint32_t i = 0; i < tex_uniform_count; i++) {
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
+ u.binding = 1 + i;
+ u.ids.push_back(textures[i]);
+ uniforms.push_back(u);
+ }
+ }
+
+ uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader_singleton->shader.version_get_shader(shader_data->version, 0), RenderForwardClustered::MATERIAL_UNIFORM_SET);
+}
+
+SceneShaderForwardClustered::MaterialData::~MaterialData() {
+ if (uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(uniform_set)) {
+ RD::get_singleton()->free(uniform_set);
+ }
+
+ if (uniform_buffer.is_valid()) {
+ RD::get_singleton()->free(uniform_buffer);
+ }
+}
+
+RendererStorageRD::MaterialData *SceneShaderForwardClustered::_create_material_func(ShaderData *p_shader) {
+ MaterialData *material_data = memnew(MaterialData);
+ material_data->shader_data = p_shader;
+ material_data->last_frame = false;
+ //update will happen later anyway so do nothing.
+ return material_data;
+}
+
+SceneShaderForwardClustered *SceneShaderForwardClustered::singleton = nullptr;
+
+SceneShaderForwardClustered::SceneShaderForwardClustered() {
+ // there should be only one of these, contained within our RenderFM singleton.
+ singleton = this;
+}
+
+SceneShaderForwardClustered::~SceneShaderForwardClustered() {
+ RD::get_singleton()->free(default_vec4_xform_buffer);
+ RD::get_singleton()->free(shadow_sampler);
+
+ storage->free(wireframe_material_shader);
+ storage->free(overdraw_material_shader);
+ storage->free(default_shader);
+
+ storage->free(wireframe_material);
+ storage->free(overdraw_material);
+ storage->free(default_material);
+}
+
+void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const String p_defines) {
+ storage = p_storage;
+
+ {
+ Vector<String> shader_versions;
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_DUAL_PARABOLOID\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_NORMAL_ROUGHNESS\n#define MODE_RENDER_GIPROBE\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_MATERIAL\n");
+ shader_versions.push_back("\n#define MODE_RENDER_DEPTH\n#define MODE_RENDER_SDF\n");
+ shader_versions.push_back("");
+ shader_versions.push_back("\n#define USE_FORWARD_GI\n");
+ shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n");
+ shader_versions.push_back("\n#define USE_LIGHTMAP\n");
+ shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n");
+ shader.initialize(shader_versions, p_defines);
+
+ /*
+ if (p_is_low_end) {
+ //disable the high end versions
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS, false);
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE, false);
+ shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_WITH_SDF, false);
+ shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI, false);
+ shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
+ shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, false);
+ }
+ */
+ }
+
+ storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
+ storage->material_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_material_funcs);
+
+ {
+ //shader compiler
+ ShaderCompilerRD::DefaultIdentifierActions actions;
+
+ actions.renames["WORLD_MATRIX"] = "world_matrix";
+ actions.renames["WORLD_NORMAL_MATRIX"] = "world_normal_matrix";
+ actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
+ actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
+ actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
+ actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix";
+ actions.renames["MODELVIEW_MATRIX"] = "modelview";
+ actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
+
+ actions.renames["VERTEX"] = "vertex";
+ actions.renames["NORMAL"] = "normal";
+ actions.renames["TANGENT"] = "tangent";
+ actions.renames["BINORMAL"] = "binormal";
+ actions.renames["POSITION"] = "position";
+ actions.renames["UV"] = "uv_interp";
+ actions.renames["UV2"] = "uv2_interp";
+ actions.renames["COLOR"] = "color_interp";
+ actions.renames["POINT_SIZE"] = "gl_PointSize";
+ actions.renames["INSTANCE_ID"] = "gl_InstanceIndex";
+
+ actions.renames["ALPHA_SCISSOR_THRESHOLD"] = "alpha_scissor_threshold";
+ actions.renames["ALPHA_HASH_SCALE"] = "alpha_hash_scale";
+ actions.renames["ALPHA_ANTIALIASING_EDGE"] = "alpha_antialiasing_edge";
+ actions.renames["ALPHA_TEXTURE_COORDINATE"] = "alpha_texture_coordinate";
+
+ //builtins
+
+ actions.renames["TIME"] = "scene_data.time";
+ actions.renames["VIEWPORT_SIZE"] = "scene_data.viewport_size";
+
+ actions.renames["FRAGCOORD"] = "gl_FragCoord";
+ actions.renames["FRONT_FACING"] = "gl_FrontFacing";
+ actions.renames["NORMAL_MAP"] = "normal_map";
+ actions.renames["NORMAL_MAP_DEPTH"] = "normal_map_depth";
+ actions.renames["ALBEDO"] = "albedo";
+ actions.renames["ALPHA"] = "alpha";
+ actions.renames["METALLIC"] = "metallic";
+ actions.renames["SPECULAR"] = "specular";
+ actions.renames["ROUGHNESS"] = "roughness";
+ actions.renames["RIM"] = "rim";
+ actions.renames["RIM_TINT"] = "rim_tint";
+ actions.renames["CLEARCOAT"] = "clearcoat";
+ actions.renames["CLEARCOAT_GLOSS"] = "clearcoat_gloss";
+ actions.renames["ANISOTROPY"] = "anisotropy";
+ actions.renames["ANISOTROPY_FLOW"] = "anisotropy_flow";
+ actions.renames["SSS_STRENGTH"] = "sss_strength";
+ actions.renames["SSS_TRANSMITTANCE_COLOR"] = "transmittance_color";
+ actions.renames["SSS_TRANSMITTANCE_DEPTH"] = "transmittance_depth";
+ actions.renames["SSS_TRANSMITTANCE_CURVE"] = "transmittance_curve";
+ actions.renames["SSS_TRANSMITTANCE_BOOST"] = "transmittance_boost";
+ actions.renames["BACKLIGHT"] = "backlight";
+ actions.renames["AO"] = "ao";
+ actions.renames["AO_LIGHT_AFFECT"] = "ao_light_affect";
+ actions.renames["EMISSION"] = "emission";
+ actions.renames["POINT_COORD"] = "gl_PointCoord";
+ actions.renames["INSTANCE_CUSTOM"] = "instance_custom";
+ actions.renames["SCREEN_UV"] = "screen_uv";
+ actions.renames["SCREEN_TEXTURE"] = "color_buffer";
+ actions.renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions.renames["NORMAL_ROUGHNESS_TEXTURE"] = "normal_roughness_buffer";
+ actions.renames["DEPTH"] = "gl_FragDepth";
+ actions.renames["OUTPUT_IS_SRGB"] = "true";
+ actions.renames["FOG"] = "custom_fog";
+ actions.renames["RADIANCE"] = "custom_radiance";
+ actions.renames["IRRADIANCE"] = "custom_irradiance";
+ actions.renames["BONE_INDICES"] = "bone_attrib";
+ actions.renames["BONE_WEIGHTS"] = "weight_attrib";
+ actions.renames["CUSTOM0"] = "custom0_attrib";
+ actions.renames["CUSTOM1"] = "custom1_attrib";
+ actions.renames["CUSTOM2"] = "custom2_attrib";
+ actions.renames["CUSTOM3"] = "custom3_attrib";
+
+ //for light
+ actions.renames["VIEW"] = "view";
+ actions.renames["LIGHT_COLOR"] = "light_color";
+ actions.renames["LIGHT"] = "light";
+ actions.renames["ATTENUATION"] = "attenuation";
+ actions.renames["SHADOW_ATTENUATION"] = "shadow_attenuation";
+ actions.renames["DIFFUSE_LIGHT"] = "diffuse_light";
+ actions.renames["SPECULAR_LIGHT"] = "specular_light";
+
+ actions.usage_defines["NORMAL"] = "#define NORMAL_USED\n";
+ actions.usage_defines["TANGENT"] = "#define TANGENT_USED\n";
+ actions.usage_defines["BINORMAL"] = "@TANGENT";
+ actions.usage_defines["RIM"] = "#define LIGHT_RIM_USED\n";
+ actions.usage_defines["RIM_TINT"] = "@RIM";
+ actions.usage_defines["CLEARCOAT"] = "#define LIGHT_CLEARCOAT_USED\n";
+ actions.usage_defines["CLEARCOAT_GLOSS"] = "@CLEARCOAT";
+ actions.usage_defines["ANISOTROPY"] = "#define LIGHT_ANISOTROPY_USED\n";
+ actions.usage_defines["ANISOTROPY_FLOW"] = "@ANISOTROPY";
+ actions.usage_defines["AO"] = "#define AO_USED\n";
+ actions.usage_defines["AO_LIGHT_AFFECT"] = "#define AO_USED\n";
+ actions.usage_defines["UV"] = "#define UV_USED\n";
+ actions.usage_defines["UV2"] = "#define UV2_USED\n";
+ actions.usage_defines["BONE_INDICES"] = "#define BONES_USED\n";
+ actions.usage_defines["BONE_WEIGHTS"] = "#define WEIGHTS_USED\n";
+ actions.usage_defines["CUSTOM0"] = "#define CUSTOM0\n";
+ actions.usage_defines["CUSTOM1"] = "#define CUSTOM1\n";
+ actions.usage_defines["CUSTOM2"] = "#define CUSTOM2\n";
+ actions.usage_defines["CUSTOM3"] = "#define CUSTOM3\n";
+ actions.usage_defines["NORMAL_MAP"] = "#define NORMAL_MAP_USED\n";
+ actions.usage_defines["NORMAL_MAP_DEPTH"] = "@NORMAL_MAP";
+ actions.usage_defines["COLOR"] = "#define COLOR_USED\n";
+ actions.usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
+ actions.usage_defines["POSITION"] = "#define OVERRIDE_POSITION\n";
+
+ actions.usage_defines["ALPHA_SCISSOR_THRESHOLD"] = "#define ALPHA_SCISSOR_USED\n";
+ actions.usage_defines["ALPHA_HASH_SCALE"] = "#define ALPHA_HASH_USED\n";
+ actions.usage_defines["ALPHA_ANTIALIASING_EDGE"] = "#define ALPHA_ANTIALIASING_EDGE_USED\n";
+ actions.usage_defines["ALPHA_TEXTURE_COORDINATE"] = "@ALPHA_ANTIALIASING_EDGE";
+
+ actions.usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
+ actions.usage_defines["SSS_TRANSMITTANCE_DEPTH"] = "#define ENABLE_TRANSMITTANCE\n";
+ actions.usage_defines["BACKLIGHT"] = "#define LIGHT_BACKLIGHT_USED\n";
+ actions.usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
+ actions.usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
+
+ actions.usage_defines["DIFFUSE_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+ actions.usage_defines["SPECULAR_LIGHT"] = "#define USE_LIGHT_SHADER_CODE\n";
+
+ actions.usage_defines["FOG"] = "#define CUSTOM_FOG_USED\n";
+ actions.usage_defines["RADIANCE"] = "#define CUSTOM_RADIANCE_USED\n";
+ actions.usage_defines["IRRADIANCE"] = "#define CUSTOM_IRRADIANCE_USED\n";
+
+ actions.render_mode_defines["skip_vertex_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions.render_mode_defines["world_vertex_coords"] = "#define VERTEX_WORLD_COORDS_USED\n";
+ actions.render_mode_defines["ensure_correct_normals"] = "#define ENSURE_CORRECT_NORMALS\n";
+ actions.render_mode_defines["cull_front"] = "#define DO_SIDE_CHECK\n";
+ actions.render_mode_defines["cull_disabled"] = "#define DO_SIDE_CHECK\n";
+
+ bool force_lambert = GLOBAL_GET("rendering/shading/overrides/force_lambert_over_burley");
+
+ if (!force_lambert) {
+ actions.render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
+ }
+
+ actions.render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
+ actions.render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
+ actions.render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
+
+ actions.render_mode_defines["sss_mode_skin"] = "#define SSS_MODE_SKIN\n";
+
+ bool force_blinn = GLOBAL_GET("rendering/shading/overrides/force_blinn_over_ggx");
+
+ if (!force_blinn) {
+ actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
+ } else {
+ actions.render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_BLINN\n";
+ }
+
+ actions.render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
+ actions.render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
+ actions.render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
+ actions.render_mode_defines["specular_disabled"] = "#define SPECULAR_DISABLED\n";
+ actions.render_mode_defines["shadows_disabled"] = "#define SHADOWS_DISABLED\n";
+ actions.render_mode_defines["ambient_light_disabled"] = "#define AMBIENT_LIGHT_DISABLED\n";
+ actions.render_mode_defines["shadow_to_opacity"] = "#define USE_SHADOW_TO_OPACITY\n";
+ actions.render_mode_defines["unshaded"] = "#define MODE_UNSHADED\n";
+
+ actions.sampler_array_name = "material_samplers";
+ actions.base_texture_binding_index = 1;
+ actions.texture_layout_set = RenderForwardClustered::MATERIAL_UNIFORM_SET;
+ actions.base_uniform_string = "material.";
+ actions.base_varying_index = 10;
+
+ actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
+ actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
+ actions.global_buffer_array_variable = "global_variables.data";
+ actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
+
+ compiler.initialize(actions);
+ }
+
+ {
+ //default material and shader
+ default_shader = storage->shader_allocate();
+ storage->shader_initialize(default_shader);
+ storage->shader_set_code(default_shader, "shader_type spatial; void vertex() { ROUGHNESS = 0.8; } void fragment() { ALBEDO=vec3(0.6); ROUGHNESS=0.8; METALLIC=0.2; } \n");
+ default_material = storage->material_allocate();
+ storage->material_initialize(default_material);
+ storage->material_set_shader(default_material, default_shader);
+
+ MaterialData *md = (MaterialData *)storage->material_get_data(default_material, RendererStorageRD::SHADER_TYPE_3D);
+ default_shader_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_COLOR_PASS);
+ default_shader_sdfgi_rd = shader.version_get_shader(md->shader_data->version, SHADER_VERSION_DEPTH_PASS_WITH_SDF);
+ }
+
+ {
+ overdraw_material_shader = storage->shader_allocate();
+ storage->shader_initialize(overdraw_material_shader);
+ storage->shader_set_code(overdraw_material_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
+ overdraw_material = storage->material_allocate();
+ storage->material_initialize(overdraw_material);
+ storage->material_set_shader(overdraw_material, overdraw_material_shader);
+
+ wireframe_material_shader = storage->shader_allocate();
+ storage->shader_initialize(wireframe_material_shader);
+ storage->shader_set_code(wireframe_material_shader, "shader_type spatial;\nrender_mode wireframe,unshaded;\n void fragment() { ALBEDO=vec3(0.0,0.0,0.0); }");
+ wireframe_material = storage->material_allocate();
+ storage->material_initialize(wireframe_material);
+ storage->material_set_shader(wireframe_material, wireframe_material_shader);
+ }
+
+ {
+ default_vec4_xform_buffer = RD::get_singleton()->storage_buffer_create(256);
+ Vector<RD::Uniform> uniforms;
+ RD::Uniform u;
+ u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
+ u.ids.push_back(default_vec4_xform_buffer);
+ u.binding = 0;
+ uniforms.push_back(u);
+
+ default_vec4_xform_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, default_shader_rd, RenderForwardClustered::TRANSFORMS_UNIFORM_SET);
+ }
+ {
+ RD::SamplerState sampler;
+ sampler.mag_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler.min_filter = RD::SAMPLER_FILTER_LINEAR;
+ sampler.enable_compare = true;
+ sampler.compare_op = RD::COMPARE_OP_LESS;
+ shadow_sampler = RD::get_singleton()->sampler_create(sampler);
+ }
+}
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
new file mode 100644
index 0000000000..953a5291c8
--- /dev/null
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h
@@ -0,0 +1,210 @@
+/*************************************************************************/
+/* scene_shader_forward_clustered.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef RSSR_SCENE_SHADER_FC_H
+#define RSSR_SCENE_SHADER_FC_H
+
+#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
+#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
+#include "servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl.gen.h"
+
+namespace RendererSceneRenderImplementation {
+
+class SceneShaderForwardClustered {
+private:
+ static SceneShaderForwardClustered *singleton;
+
+public:
+ RendererStorageRD *storage;
+
+ enum ShaderVersion {
+ SHADER_VERSION_DEPTH_PASS,
+ SHADER_VERSION_DEPTH_PASS_DP,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS,
+ SHADER_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_GIPROBE,
+ SHADER_VERSION_DEPTH_PASS_WITH_MATERIAL,
+ SHADER_VERSION_DEPTH_PASS_WITH_SDF,
+ SHADER_VERSION_COLOR_PASS,
+ SHADER_VERSION_COLOR_PASS_WITH_FORWARD_GI,
+ SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS,
+ SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
+ SHADER_VERSION_MAX
+ };
+
+ struct ShaderData : public RendererStorageRD::ShaderData {
+ enum BlendMode { //used internally
+ BLEND_MODE_MIX,
+ BLEND_MODE_ADD,
+ BLEND_MODE_SUB,
+ BLEND_MODE_MUL,
+ BLEND_MODE_ALPHA_TO_COVERAGE
+ };
+
+ enum DepthDraw {
+ DEPTH_DRAW_DISABLED,
+ DEPTH_DRAW_OPAQUE,
+ DEPTH_DRAW_ALWAYS
+ };
+
+ enum DepthTest {
+ DEPTH_TEST_DISABLED,
+ DEPTH_TEST_ENABLED
+ };
+
+ enum Cull {
+ CULL_DISABLED,
+ CULL_FRONT,
+ CULL_BACK
+ };
+
+ enum CullVariant {
+ CULL_VARIANT_NORMAL,
+ CULL_VARIANT_REVERSED,
+ CULL_VARIANT_DOUBLE_SIDED,
+ CULL_VARIANT_MAX
+
+ };
+
+ enum AlphaAntiAliasing {
+ ALPHA_ANTIALIASING_OFF,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
+ ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE
+ };
+
+ bool valid;
+ RID version;
+ uint32_t vertex_input_mask;
+ PipelineCacheRD pipelines[CULL_VARIANT_MAX][RS::PRIMITIVE_MAX][SHADER_VERSION_MAX];
+
+ String path;
+
+ Map<StringName, ShaderLanguage::ShaderNode::Uniform> uniforms;
+ Vector<ShaderCompilerRD::GeneratedCode::Texture> texture_uniforms;
+
+ Vector<uint32_t> ubo_offsets;
+ uint32_t ubo_size;
+
+ String code;
+ Map<StringName, RID> default_texture_params;
+
+ DepthDraw depth_draw;
+ DepthTest depth_test;
+
+ bool uses_point_size;
+ bool uses_alpha;
+ bool uses_blend_alpha;
+ bool uses_alpha_clip;
+ bool uses_depth_pre_pass;
+ bool uses_discard;
+ bool uses_roughness;
+ bool uses_normal;
+
+ bool unshaded;
+ bool uses_vertex;
+ bool uses_sss;
+ bool uses_transmittance;
+ bool uses_screen_texture;
+ bool uses_depth_texture;
+ bool uses_normal_texture;
+ bool uses_time;
+ bool writes_modelview_or_projection;
+ bool uses_world_coordinates;
+
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+
+ virtual void set_code(const String &p_Code);
+ virtual void set_default_texture_param(const StringName &p_name, RID p_texture);
+ virtual void get_param_list(List<PropertyInfo> *p_param_list) const;
+ void get_instance_param_list(List<RendererStorage::InstanceShaderParam> *p_param_list) const;
+
+ virtual bool is_param_texture(const StringName &p_param) const;
+ virtual bool is_animated() const;
+ virtual bool casts_shadows() const;
+ virtual Variant get_default_parameter(const StringName &p_parameter) const;
+ virtual RS::ShaderNativeSourceCode get_native_source_code() const;
+
+ ShaderData();
+ virtual ~ShaderData();
+ };
+
+ RendererStorageRD::ShaderData *_create_shader_func();
+ static RendererStorageRD::ShaderData *_create_shader_funcs() {
+ return static_cast<SceneShaderForwardClustered *>(singleton)->_create_shader_func();
+ }
+
+ struct MaterialData : public RendererStorageRD::MaterialData {
+ uint64_t last_frame;
+ ShaderData *shader_data;
+ RID uniform_buffer;
+ RID uniform_set;
+ Vector<RID> texture_cache;
+ Vector<uint8_t> ubo_data;
+ uint64_t last_pass = 0;
+ uint32_t index = 0;
+ RID next_pass;
+ uint8_t priority;
+ virtual void set_render_priority(int p_priority);
+ virtual void set_next_pass(RID p_pass);
+ virtual void update_parameters(const Map<StringName, Variant> &p_parameters, bool p_uniform_dirty, bool p_textures_dirty);
+ virtual ~MaterialData();
+ };
+
+ RendererStorageRD::MaterialData *_create_material_func(ShaderData *p_shader);
+ static RendererStorageRD::MaterialData *_create_material_funcs(RendererStorageRD::ShaderData *p_shader) {
+ return static_cast<SceneShaderForwardClustered *>(singleton)->_create_material_func(static_cast<ShaderData *>(p_shader));
+ }
+
+ SceneForwardClusteredShaderRD shader;
+ ShaderCompilerRD compiler;
+
+ RID default_shader;
+ RID default_material;
+ RID overdraw_material_shader;
+ RID overdraw_material;
+ RID wireframe_material_shader;
+ RID wireframe_material;
+ RID default_shader_rd;
+ RID default_shader_sdfgi_rd;
+
+ RID default_vec4_xform_buffer;
+ RID default_vec4_xform_uniform_set;
+
+ RID shadow_sampler;
+
+ SceneShaderForwardClustered();
+ ~SceneShaderForwardClustered();
+
+ void init(RendererStorageRD *p_storage, const String p_defines);
+};
+
+} // namespace RendererSceneRenderImplementation
+#endif // !RSSR_SCENE_SHADER_FM_H
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
index d5ac05d1d1..2247b841c9 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.cpp
@@ -175,5 +175,5 @@ RendererCompositorRD::RendererCompositorRD() {
storage = memnew(RendererStorageRD);
canvas = memnew(RendererCanvasRenderRD(storage));
- scene = memnew(RendererSceneRenderForwardClustered(storage));
+ scene = memnew(RendererSceneRenderImplementation::RenderForwardClustered(storage));
}
diff --git a/servers/rendering/renderer_rd/renderer_compositor_rd.h b/servers/rendering/renderer_rd/renderer_compositor_rd.h
index 67a843452b..5b5f3ad0cb 100644
--- a/servers/rendering/renderer_rd/renderer_compositor_rd.h
+++ b/servers/rendering/renderer_rd/renderer_compositor_rd.h
@@ -34,8 +34,8 @@
#include "core/os/os.h"
#include "core/templates/thread_work_pool.h"
#include "servers/rendering/renderer_compositor.h"
+#include "servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.h"
#include "servers/rendering/renderer_rd/renderer_canvas_render_rd.h"
-#include "servers/rendering/renderer_rd/renderer_scene_render_forward_clustered.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
class RendererCompositorRD : public RendererCompositor {
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
index 4e4e553605..3856f38457 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.cpp
@@ -2992,6 +2992,7 @@ void RendererSceneGIRD::init(RendererStorageRD *p_storage, RendererSceneSkyRD *p
}
}
default_giprobe_buffer = RD::get_singleton()->uniform_buffer_create(sizeof(GIProbeData) * MAX_GIPROBES);
+ half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");
}
void RendererSceneGIRD::free() {
@@ -3097,10 +3098,10 @@ void RendererSceneGIRD::setup_giprobes(RID p_render_buffers, const Transform &p_
}
if (giprobes_changed) {
- if (RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
- RD::get_singleton()->free(rb->gi_uniform_set);
+ if (RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) {
+ RD::get_singleton()->free(rb->gi.uniform_set);
}
- rb->gi_uniform_set = RID();
+ rb->gi.uniform_set = RID();
if (rb->volumetric_fog) {
if (RD::get_singleton()->uniform_set_is_valid(rb->volumetric_fog->uniform_set)) {
RD::get_singleton()->free(rb->volumetric_fog->uniform_set);
@@ -3125,7 +3126,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
ERR_FAIL_COND(rb == nullptr);
RendererSceneEnvironmentRD *env = p_scene_render->environment_owner.getornull(p_environment);
- if (rb->ambient_buffer.is_null() || rb->using_half_size_gi != half_resolution) {
+ if (rb->ambient_buffer.is_null() || rb->gi.using_half_size_gi != half_resolution) {
if (rb->ambient_buffer.is_valid()) {
RD::get_singleton()->free(rb->ambient_buffer);
RD::get_singleton()->free(rb->reflection_buffer);
@@ -3142,7 +3143,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
tf.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_STORAGE_BIT;
rb->reflection_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
rb->ambient_buffer = RD::get_singleton()->texture_create(tf, RD::TextureView());
- rb->using_half_size_gi = half_resolution;
+ rb->gi.using_half_size_gi = half_resolution;
p_scene_render->_render_buffers_uniform_set_changed(p_render_buffers);
}
@@ -3187,7 +3188,7 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
push_constant.cam_rotation[10] = p_transform.basis[2][2];
push_constant.cam_rotation[11] = 0;
- if (rb->gi_uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi_uniform_set)) {
+ if (rb->gi.uniform_set.is_null() || !RD::get_singleton()->uniform_set_is_valid(rb->gi.uniform_set)) {
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
@@ -3340,22 +3341,22 @@ void RendererSceneGIRD::process_gi(RID p_render_buffers, RID p_normal_roughness_
uniforms.push_back(u);
}
- rb->gi_uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
+ rb->gi.uniform_set = RD::get_singleton()->uniform_set_create(uniforms, shader.version_get_shader(shader_version, 0), 0);
}
Mode mode;
- if (rb->using_half_size_gi) {
+ if (rb->gi.using_half_size_gi) {
mode = (use_sdfgi && use_giprobes) ? MODE_HALF_RES_COMBINED : (use_sdfgi ? MODE_HALF_RES_SDFGI : MODE_HALF_RES_GIPROBE);
} else {
mode = (use_sdfgi && use_giprobes) ? MODE_COMBINED : (use_sdfgi ? MODE_SDFGI : MODE_GIPROBE);
}
RD::ComputeListID compute_list = RD::get_singleton()->compute_list_begin(true);
RD::get_singleton()->compute_list_bind_compute_pipeline(compute_list, pipelines[mode]);
- RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi_uniform_set, 0);
+ RD::get_singleton()->compute_list_bind_uniform_set(compute_list, rb->gi.uniform_set, 0);
RD::get_singleton()->compute_list_set_push_constant(compute_list, &push_constant, sizeof(PushConstant));
- if (rb->using_half_size_gi) {
+ if (rb->gi.using_half_size_gi) {
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width >> 1, rb->height >> 1, 1);
} else {
RD::get_singleton()->compute_list_dispatch_threads(compute_list, rb->width, rb->height, 1);
diff --git a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
index c0f3318538..df20011b23 100644
--- a/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_gi_rd.h
@@ -561,6 +561,9 @@ public:
RID full_buffer;
RID full_dispatch;
RID full_mask;
+
+ RID uniform_set;
+ bool using_half_size_gi = false;
};
struct SDFGIData {
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
index 4cf296f0db..ca9e014c95 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.cpp
@@ -317,7 +317,7 @@ void RendererSceneRenderRD::environment_set_sdfgi(RID p_env, bool p_enable, RS::
RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- if (low_end) {
+ if (!is_dynamic_gi_supported()) {
return;
}
@@ -379,7 +379,7 @@ void RendererSceneRenderRD::environment_set_volumetric_fog(RID p_env, bool p_ena
RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- if (low_end) {
+ if (!is_volumetric_supported()) {
return;
}
@@ -410,10 +410,6 @@ void RendererSceneRenderRD::environment_set_ssr(RID p_env, bool p_enable, int p_
RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- if (low_end) {
- return;
- }
-
env->set_ssr(p_enable, p_max_steps, p_fade_int, p_fade_out, p_depth_tolerance);
}
@@ -429,10 +425,6 @@ void RendererSceneRenderRD::environment_set_ssao(RID p_env, bool p_enable, float
RendererSceneEnvironmentRD *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- if (low_end) {
- return;
- }
-
env->set_ssao(p_enable, p_radius, p_intensity, p_power, p_detail, p_horizon, p_sharpness, p_light_affect, p_ao_channel_affect);
}
@@ -522,9 +514,13 @@ RID RendererSceneRenderRD::reflection_atlas_create() {
ra.count = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_count");
ra.size = GLOBAL_GET("rendering/reflections/reflection_atlas/reflection_size");
- ra.cluster_builder = memnew(ClusterBuilderRD);
- ra.cluster_builder->set_shared(&cluster_builder_shared);
- ra.cluster_builder->setup(Size2i(ra.size, ra.size), max_cluster_elements, RID(), RID(), RID());
+ if (is_clustered_enabled()) {
+ ra.cluster_builder = memnew(ClusterBuilderRD);
+ ra.cluster_builder->set_shared(&cluster_builder_shared);
+ ra.cluster_builder->setup(Size2i(ra.size, ra.size), max_cluster_elements, RID(), RID(), RID());
+ } else {
+ ra.cluster_builder = nullptr;
+ }
return reflection_atlas_owner.make_rid(ra);
}
@@ -537,7 +533,10 @@ void RendererSceneRenderRD::reflection_atlas_set_size(RID p_ref_atlas, int p_ref
return; //no changes
}
- ra->cluster_builder->setup(Size2i(ra->size, ra->size), max_cluster_elements, RID(), RID(), RID());
+ if (ra->cluster_builder) {
+ // only if we're using our cluster
+ ra->cluster_builder->setup(Size2i(ra->size, ra->size), max_cluster_elements, RID(), RID(), RID());
+ }
ra->size = p_reflection_size;
ra->count = p_reflection_count;
@@ -1340,7 +1339,7 @@ void RendererSceneRenderRD::gi_probe_instance_set_transform_to_data(RID p_probe,
}
bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
- if (low_end) {
+ if (!is_dynamic_gi_supported()) {
return false;
}
@@ -1348,7 +1347,7 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
}
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
- if (low_end) {
+ if (!is_dynamic_gi_supported()) {
return;
}
@@ -2124,10 +2123,13 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->msaa = p_msaa;
rb->screen_space_aa = p_screen_space_aa;
rb->use_debanding = p_use_debanding;
- if (rb->cluster_builder == nullptr) {
- rb->cluster_builder = memnew(ClusterBuilderRD);
+
+ if (is_clustered_enabled()) {
+ if (rb->cluster_builder == nullptr) {
+ rb->cluster_builder = memnew(ClusterBuilderRD);
+ }
+ rb->cluster_builder->set_shared(&cluster_builder_shared);
}
- rb->cluster_builder->set_shared(&cluster_builder_shared);
_free_render_buffer_data(rb);
@@ -2170,7 +2172,9 @@ void RendererSceneRenderRD::render_buffers_configure(RID p_render_buffers, RID p
rb->data->configure(rb->texture, rb->depth_texture, p_width, p_height, p_msaa);
_render_buffers_uniform_set_changed(p_render_buffers);
- rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
+ if (is_clustered_enabled()) {
+ rb->cluster_builder->setup(Size2i(p_width, p_height), max_cluster_elements, rb->depth_texture, storage->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED), rb->texture);
+ }
}
void RendererSceneRenderRD::gi_set_use_half_resolution(bool p_enable) {
@@ -2943,6 +2947,7 @@ void RendererSceneRenderRD::_volumetric_fog_erase(RenderBuffers *rb) {
}
void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_environment, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_gi_probe_count) {
+ ERR_FAIL_COND(!is_clustered_enabled()); // can't use volumetric fog without clustered
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
RendererSceneEnvironmentRD *env = environment_owner.getornull(p_environment);
@@ -3505,7 +3510,9 @@ void RendererSceneRenderRD::_pre_opaque_render(bool p_use_ssao, bool p_use_gi, R
break;
}
}
- _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count);
+ if (is_volumetric_supported()) {
+ _update_volumetric_fog(render_state.render_buffers, render_state.environment, render_state.cam_projection, render_state.cam_transform, render_state.shadow_atlas, directional_light_count, directional_shadows, positional_light_count, render_state.gi_probe_count);
+ }
}
}
@@ -3578,8 +3585,8 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
}
if (render_buffers_owner.owns(render_state.render_buffers)) {
- RenderBuffers *rs_rb = render_buffers_owner.getornull(render_state.render_buffers);
- current_cluster_builder = rs_rb->cluster_builder;
+ // render_state.render_buffers == p_render_buffers so we can use our already retrieved rb
+ current_cluster_builder = rb->cluster_builder;
} else if (reflection_probe_instance_owner.owns(render_state.reflection_probe)) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.getornull(render_state.reflection_probe);
ReflectionAtlas *ra = reflection_atlas_owner.getornull(rpi->atlas);
@@ -3590,7 +3597,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
current_cluster_builder = ra->cluster_builder;
}
} else {
- ERR_PRINT("No cluster builder, bug"); //should never happen, will crash
+ ERR_PRINT("No render buffer nor reflection atlas, bug"); //should never happen, will crash
current_cluster_builder = nullptr;
}
@@ -4076,8 +4083,19 @@ int RendererSceneRenderRD::get_max_directional_lights() const {
return cluster.max_directional_lights;
}
-bool RendererSceneRenderRD::is_low_end() const {
- return low_end;
+bool RendererSceneRenderRD::is_dynamic_gi_supported() const {
+ // usable by default (unless low end = true)
+ return true;
+}
+
+bool RendererSceneRenderRD::is_clustered_enabled() const {
+ // used by default.
+ return true;
+}
+
+bool RendererSceneRenderRD::is_volumetric_supported() const {
+ // usable by default (unless low end = true)
+ return true;
}
RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
@@ -4089,21 +4107,13 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
directional_shadow.size = GLOBAL_GET("rendering/shadows/directional_shadow/size");
directional_shadow.use_16_bits = GLOBAL_GET("rendering/shadows/directional_shadow/16_bits");
- uint32_t textures_per_stage = RD::get_singleton()->limit_get(RD::LIMIT_MAX_TEXTURES_PER_SHADER_STAGE);
-
- low_end = GLOBAL_GET("rendering/driver/rd_renderer/use_low_end_renderer");
-
- if (textures_per_stage < 48) {
- low_end = true;
- }
-
/* SKY SHADER */
sky.init(storage);
/* GI */
- if (!low_end) {
+ if (is_dynamic_gi_supported()) {
gi.init(storage, &sky);
}
@@ -4141,7 +4151,7 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
cluster.directional_light_buffer = RD::get_singleton()->uniform_buffer_create(directional_light_buffer_size);
}
- if (!low_end) {
+ if (is_volumetric_supported()) {
String defines = "\n#define MAX_DIRECTIONAL_LIGHT_DATA_STRUCTS " + itos(cluster.max_directional_lights) + "\n";
Vector<String> volumetric_fog_modes;
volumetric_fog_modes.push_back("\n#define MODE_DENSITY\n");
@@ -4188,8 +4198,6 @@ RendererSceneRenderRD::RendererSceneRenderRD(RendererStorageRD *p_storage) {
environment_set_volumetric_fog_filter_active(GLOBAL_GET("rendering/environment/volumetric_fog/use_filter"));
cull_argument.set_page_pool(&cull_argument_pool);
-
- gi.half_resolution = GLOBAL_GET("rendering/global_illumination/gi/use_half_resolution");
}
RendererSceneRenderRD::~RendererSceneRenderRD() {
@@ -4201,7 +4209,7 @@ RendererSceneRenderRD::~RendererSceneRenderRD() {
RD::get_singleton()->free(sky.sky_scene_state.uniform_set);
}
- if (!low_end) {
+ if (is_dynamic_gi_supported()) {
gi.free();
volumetric_fog.shader.version_free(volumetric_fog.shader_version);
diff --git a/servers/rendering/renderer_rd/renderer_scene_render_rd.h b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
index 001cfeb74d..884bf2a744 100644
--- a/servers/rendering/renderer_rd/renderer_scene_render_rd.h
+++ b/servers/rendering/renderer_rd/renderer_scene_render_rd.h
@@ -383,9 +383,9 @@ private:
RID texture; //main texture for rendering to, must be filled after done rendering
RID depth_texture; //main depth texture
- RID gi_uniform_set;
RendererSceneGIRD::SDFGI *sdfgi = nullptr;
VolumetricFog *volumetric_fog = nullptr;
+ RendererSceneGIRD::RenderBuffersGI gi;
ClusterBuilderRD *cluster_builder = nullptr;
@@ -428,9 +428,6 @@ private:
RID ambient_buffer;
RID reflection_buffer;
- bool using_half_size_gi = false;
-
- RendererSceneGIRD::RenderBuffersGI gi;
};
/* GI */
@@ -719,7 +716,6 @@ private:
*/
uint32_t max_cluster_elements = 512;
- bool low_end = false;
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true);
@@ -1193,7 +1189,9 @@ public:
void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir);
- bool is_low_end() const;
+ virtual bool is_dynamic_gi_supported() const;
+ virtual bool is_clustered_enabled() const;
+ virtual bool is_volumetric_supported() const;
RendererSceneRenderRD(RendererStorageRD *p_storage);
~RendererSceneRenderRD();
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index ba5ace8f31..b984f850a0 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -4692,10 +4692,11 @@ void RendererStorageRD::update_particles() {
if (particles->clear && particles->pre_process_time > 0.0) {
float frame_time;
- if (particles->fixed_fps > 0)
+ if (particles->fixed_fps > 0) {
frame_time = 1.0 / particles->fixed_fps;
- else
+ } else {
frame_time = 1.0 / 30.0;
+ }
float todo = particles->pre_process_time;
@@ -4731,10 +4732,11 @@ void RendererStorageRD::update_particles() {
particles->frame_remainder = todo;
} else {
- if (zero_time_scale)
+ if (zero_time_scale) {
_particles_process(particles, 0.0);
- else
+ } else {
_particles_process(particles, RendererCompositorRD::singleton->get_frame_delta_time());
+ }
}
//copy particles to instance buffer
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.h b/servers/rendering/renderer_rd/renderer_storage_rd.h
index cd3d4604eb..6405bb75b0 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.h
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.h
@@ -691,21 +691,21 @@ private:
};
struct Particles {
- bool inactive;
- float inactive_time;
- bool emitting;
- bool one_shot;
- int amount;
- float lifetime;
- float pre_process_time;
- float explosiveness;
- float randomness;
- bool restart_request;
- AABB custom_aabb;
- bool use_local_coords;
+ bool inactive = true;
+ float inactive_time = 0.0;
+ bool emitting = false;
+ bool one_shot = false;
+ int amount = 0;
+ float lifetime = 1.0;
+ float pre_process_time = 0.0;
+ float explosiveness = 0.0;
+ float randomness = 0.0;
+ bool restart_request = false;
+ AABB custom_aabb = AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8));
+ bool use_local_coords = true;
RID process_material;
- RS::ParticlesDrawOrder draw_order;
+ RS::ParticlesDrawOrder draw_order = RS::PARTICLES_DRAW_ORDER_INDEX;
Vector<RID> draw_passes;
@@ -730,21 +730,21 @@ private:
RID sub_emitter;
- float phase;
- float prev_phase;
- uint64_t prev_ticks;
- uint32_t random_seed;
+ float phase = 0.0;
+ float prev_phase = 0.0;
+ uint64_t prev_ticks = 0;
+ uint32_t random_seed = 0;
- uint32_t cycle_number;
+ uint32_t cycle_number = 0;
- float speed_scale;
+ float speed_scale = 1.0;
- int fixed_fps;
- bool fractional_delta;
- float frame_remainder;
- float collision_base_size;
+ int fixed_fps = 0;
+ bool fractional_delta = false;
+ float frame_remainder = 0;
+ float collision_base_size = 0.01;
- bool clear;
+ bool clear = true;
bool force_sub_emit = false;
@@ -757,31 +757,6 @@ private:
Set<RID> collisions;
- Particles() :
- inactive(true),
- inactive_time(0.0),
- emitting(false),
- one_shot(false),
- amount(0),
- lifetime(1.0),
- pre_process_time(0.0),
- explosiveness(0.0),
- randomness(0.0),
- restart_request(false),
- custom_aabb(AABB(Vector3(-4, -4, -4), Vector3(8, 8, 8))),
- use_local_coords(true),
- draw_order(RS::PARTICLES_DRAW_ORDER_INDEX),
- prev_ticks(0),
- random_seed(0),
- cycle_number(0),
- speed_scale(1.0),
- fixed_fps(0),
- fractional_delta(false),
- frame_remainder(0),
- collision_base_size(0.01),
- clear(true) {
- }
-
Dependency dependency;
ParticlesFrameParams frame_params;
diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
index 8723ea78e4..ca92d2104e 100644
--- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl
+++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
@@ -65,7 +65,7 @@ void main() {
VERSION_DEFINES
-#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic) && defined(GL_KHR_shader_subgroup_vote)
+#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) && defined(has_GL_KHR_shader_subgroup_vote)
#extension GL_KHR_shader_subgroup_ballot : enable
#extension GL_KHR_shader_subgroup_arithmetic : enable
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index 7b86dac143..76edec1cb6 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -1735,8 +1735,6 @@ void sdfgi_process(uint cascade, vec3 cascade_pos, vec3 cam_pos, vec3 cam_normal
#ifndef MODE_RENDER_DEPTH
-#ifndef LOW_END_MODE
-
vec4 volumetric_fog_process(vec2 screen_uv, float z) {
vec3 fog_pos = vec3(screen_uv, z * scene_data.volumetric_fog_inv_length);
if (fog_pos.z < 0.0) {
@@ -1747,7 +1745,6 @@ vec4 volumetric_fog_process(vec2 screen_uv, float z) {
return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
}
-#endif
vec4 fog_process(vec3 vertex) {
vec3 fog_color = scene_data.fog_light_color;
@@ -2019,7 +2016,6 @@ FRAGMENT_SHADER_CODE
fog = fog_process(vertex);
}
-#ifndef LOW_END_MODE
if (scene_data.volumetric_fog_enabled) {
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
if (scene_data.fog_enabled) {
@@ -2037,7 +2033,6 @@ FRAGMENT_SHADER_CODE
fog = volumetric_fog;
}
}
-#endif //!LOW_END_MODE
#endif //!CUSTOM_FOG_USED
uint fog_rg = packHalf2x16(fog.rg);
@@ -2377,7 +2372,7 @@ FRAGMENT_SHADER_CODE
specular_light = spec_accum.rgb;
ambient_light = amb_accum.rgb;
}
-#elif !defined(LOW_END_MODE)
+#else
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_GI_BUFFERS)) { //use GI buffers
@@ -2412,13 +2407,11 @@ FRAGMENT_SHADER_CODE
}
#endif
-#ifndef LOW_END_MODE
if (scene_data.ssao_enabled) {
float ssao = texture(sampler2D(ao_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv).r;
ao = min(ao, ssao);
ao_light_affect = mix(ao_light_affect, max(ao_light_affect, scene_data.ssao_light_affect), scene_data.ssao_ao_affect);
}
-#endif //LOW_END_MODE
{ // process reflections
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
index d78890fa9e..e064a90ae0 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered_inc.glsl
@@ -3,7 +3,7 @@
#define MAX_GI_PROBES 8
-#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic)
+#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
#extension GL_KHR_shader_subgroup_ballot : enable
#extension GL_KHR_shader_subgroup_arithmetic : enable
@@ -122,8 +122,6 @@ layout(set = 0, binding = 12, std430) restrict readonly buffer GlobalVariableDat
}
global_variables;
-#ifndef LOW_END_MODE
-
struct SDFGIProbeCascadeData {
vec3 position;
float to_probe;
@@ -159,8 +157,6 @@ layout(set = 0, binding = 13, std140) uniform SDFGI {
}
sdfgi;
-#endif //LOW_END_MODE
-
/* Set 2: Render Pass (changes per render pass) */
layout(set = 1, binding = 0, std140) uniform SceneData {
@@ -280,9 +276,7 @@ layout(set = 1, binding = 5) uniform texture2D directional_shadow_atlas;
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
-#ifndef LOW_END_MOD
layout(set = 1, binding = 7) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
-#endif
layout(set = 1, binding = 8, std430) buffer restrict readonly ClusterBuffer {
uint data[];
@@ -306,8 +300,6 @@ layout(r32ui, set = 1, binding = 12) uniform restrict uimage3D geom_facing_grid;
layout(set = 1, binding = 9) uniform texture2D depth_buffer;
layout(set = 1, binding = 10) uniform texture2D color_buffer;
-#ifndef LOW_END_MODE
-
layout(set = 1, binding = 11) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 12) uniform texture2D ao_buffer;
layout(set = 1, binding = 13) uniform texture2D ambient_buffer;
@@ -338,8 +330,6 @@ gi_probes;
layout(set = 1, binding = 18) uniform texture3D volumetric_fog_texture;
-#endif // LOW_END_MODE
-
#endif
/* Set 2 Skeleton & Instancing (can change per item) */
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index e7ba8feb80..ce8a459b24 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -5,10 +5,10 @@
VERSION_DEFINES
/* Do not use subgroups here, seems there is not much advantage and causes glitches
+#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
#extension GL_KHR_shader_subgroup_ballot: enable
#extension GL_KHR_shader_subgroup_arithmetic: enable
-#if defined(GL_KHR_shader_subgroup_ballot) && defined(GL_KHR_shader_subgroup_arithmetic)
#define USE_SUBGROUPS
#endif
*/
diff --git a/servers/rendering/renderer_scene_render.h b/servers/rendering/renderer_scene_render.h
index 1dea3580b6..9ca9574f6f 100644
--- a/servers/rendering/renderer_scene_render.h
+++ b/servers/rendering/renderer_scene_render.h
@@ -241,8 +241,6 @@ public:
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) = 0;
- virtual bool is_low_end() const = 0;
-
virtual void update() = 0;
virtual ~RendererSceneRender() {}
};
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index 27a9353e4e..e6ad001807 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -59,7 +59,7 @@ Vector<uint8_t> RenderingDevice::shader_compile_from_source(ShaderStage p_stage,
ERR_FAIL_COND_V(!compile_function, Vector<uint8_t>());
- return compile_function(p_stage, p_source_code, p_language, r_error);
+ return compile_function(p_stage, p_source_code, p_language, r_error, &device_capabilities);
}
RID RenderingDevice::_texture_create(const Ref<RDTextureFormat> &p_format, const Ref<RDTextureView> &p_view, const TypedArray<PackedByteArray> &p_data) {
diff --git a/servers/rendering/rendering_device.h b/servers/rendering/rendering_device.h
index 9fbf58d131..2de0549e8d 100644
--- a/servers/rendering/rendering_device.h
+++ b/servers/rendering/rendering_device.h
@@ -51,6 +51,13 @@ class RDPipelineColorBlendState;
class RenderingDevice : public Object {
GDCLASS(RenderingDevice, Object)
public:
+ enum DeviceFamily {
+ DEVICE_UNKNOWN,
+ DEVICE_OPENGL,
+ DEVICE_VULKAN,
+ DEVICE_DIRECTX
+ };
+
enum ShaderStage {
SHADER_STAGE_VERTEX,
SHADER_STAGE_FRAGMENT,
@@ -70,7 +77,29 @@ public:
SHADER_LANGUAGE_HLSL
};
- typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error);
+ enum SubgroupOperations {
+ SUBGROUP_BASIC_BIT = 1,
+ SUBGROUP_VOTE_BIT = 2,
+ SUBGROUP_ARITHMETIC_BIT = 4,
+ SUBGROUP_BALLOT_BIT = 8,
+ SUBGROUP_SHUFFLE_BIT = 16,
+ SUBGROUP_SHUFFLE_RELATIVE_BIT = 32,
+ SUBGROUP_CLUSTERED_BIT = 64,
+ SUBGROUP_QUAD_BIT = 128,
+ };
+
+ struct Capabilities {
+ // main device info
+ DeviceFamily device_family = DEVICE_UNKNOWN;
+ uint32_t version_major = 1.0;
+ uint32_t version_minor = 0.0;
+ // subgroup capabilities
+ uint32_t subgroup_size = 0;
+ uint32_t subgroup_in_shaders = 0; // Set flags using SHADER_STAGE_VERTEX_BIT, SHADER_STAGE_FRAGMENT_BIT, etc.
+ uint32_t subgroup_operations = 0; // Set flags, using SubgroupOperations
+ };
+
+ typedef Vector<uint8_t> (*ShaderCompileFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language, String *r_error, const Capabilities *p_capabilities);
typedef Vector<uint8_t> (*ShaderCacheFunction)(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language);
private:
@@ -82,6 +111,8 @@ private:
protected:
static void _bind_methods();
+ Capabilities device_capabilities;
+
public:
//base numeric ID for all types
enum {
@@ -597,6 +628,8 @@ public:
/**** SHADER ****/
/****************/
+ const Capabilities *get_device_capabilities() const { return &device_capabilities; };
+
virtual Vector<uint8_t> shader_compile_from_source(ShaderStage p_stage, const String &p_source_code, ShaderLanguage p_language = SHADER_LANGUAGE_GLSL, String *r_error = nullptr, bool p_allow_cache = true);
static void shader_set_compile_function(ShaderCompileFunction p_function);
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index df1a7d58d0..4ae0eda232 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -6825,7 +6825,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(pos2);
- Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -6906,7 +6906,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(NULL, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -6932,10 +6932,11 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
decl.initializer.push_back(n);
break;
} else {
- if (curly)
+ if (curly) {
_set_error("Expected '}' or ','");
- else
+ } else {
_set_error("Expected ')' or ','");
+ }
return ERR_PARSE_ERROR;
}
}
@@ -6961,9 +6962,10 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(NULL, FunctionInfo());
- if (!expr)
+ Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ if (!expr) {
return ERR_PARSE_ERROR;
+ }
if (expr->type == Node::TYPE_OPERATOR && ((OperatorNode *)expr)->op == OP_CALL) {
_set_error("Expected constant expression after '='");
return ERR_PARSE_ERROR;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index d6d3c11cfb..8b03565291 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -291,6 +291,8 @@ void TextServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_hex_code_box_size", "size", "index"), &TextServer::get_hex_code_box_size);
ClassDB::bind_method(D_METHOD("draw_hex_code_box", "canvas", "size", "pos", "index", "color"), &TextServer::draw_hex_code_box);
+ ClassDB::bind_method(D_METHOD("font_get_glyph_contours", "font", "size", "index"), &TextServer::_font_get_glyph_contours);
+
/* Shaped text buffer interface */
ClassDB::bind_method(D_METHOD("create_shaped_text", "direction", "orientation"), &TextServer::create_shaped_text, DEFVAL(DIRECTION_AUTO), DEFVAL(ORIENTATION_HORIZONTAL));
@@ -403,6 +405,11 @@ void TextServer::_bind_methods() {
BIND_ENUM_CONSTANT(FEATURE_FONT_SYSTEM);
BIND_ENUM_CONSTANT(FEATURE_FONT_VARIABLE);
BIND_ENUM_CONSTANT(FEATURE_USE_SUPPORT_DATA);
+
+ /* FT Contour Point Types */
+ BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_ON);
+ BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_OFF_CONIC);
+ BIND_ENUM_CONSTANT(CONTOUR_CURVE_TAG_OFF_CUBIC);
}
Vector3 TextServer::hex_code_box_font_size[2] = { Vector3(5, 5, 1), Vector3(10, 10, 2) };
@@ -1212,6 +1219,21 @@ RID TextServer::_create_font_memory(const PackedByteArray &p_data, const String
return create_font_memory(p_data.ptr(), p_data.size(), p_type, p_base_size);
}
+Dictionary TextServer::_font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index) const {
+ Vector<Vector3> points;
+ Vector<int32_t> contours;
+ bool orientation;
+ bool ok = font_get_glyph_contours(p_font, p_size, p_index, points, contours, orientation);
+ Dictionary out;
+
+ if (ok) {
+ out["points"] = points;
+ out["contours"] = contours;
+ out["orientation"] = orientation;
+ }
+ return out;
+}
+
void TextServer::_shaped_text_set_bidi_override(RID p_shaped, const Array &p_override) {
Vector<Vector2i> overrides;
for (int i = 0; i < p_override.size(); i++) {
diff --git a/servers/text_server.h b/servers/text_server.h
index e1429da1d1..7fcfb91151 100644
--- a/servers/text_server.h
+++ b/servers/text_server.h
@@ -99,6 +99,12 @@ public:
FEATURE_USE_SUPPORT_DATA = 1 << 7
};
+ enum ContourPointTag {
+ CONTOUR_CURVE_TAG_ON = 0x01,
+ CONTOUR_CURVE_TAG_OFF_CONIC = 0x00,
+ CONTOUR_CURVE_TAG_OFF_CUBIC = 0x02
+ };
+
struct Glyph {
int start = -1; // Start offset in the source string.
int end = -1; // End offset in the source string.
@@ -286,6 +292,8 @@ public:
virtual Vector2 font_draw_glyph(RID p_font, RID p_canvas, int p_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
virtual Vector2 font_draw_glyph_outline(RID p_font, RID p_canvas, int p_size, int p_outline_size, const Vector2 &p_pos, uint32_t p_index, const Color &p_color = Color(1, 1, 1)) const = 0;
+ virtual bool font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index, Vector<Vector3> &r_points, Vector<int32_t> &r_contours, bool &r_orientation) const = 0;
+
virtual float font_get_oversampling() const = 0;
virtual void font_set_oversampling(float p_oversampling) = 0;
@@ -372,6 +380,8 @@ public:
/* GDScript wrappers */
RID _create_font_memory(const PackedByteArray &p_data, const String &p_type, int p_base_size = 16);
+ Dictionary _font_get_glyph_contours(RID p_font, int p_size, uint32_t p_index) const;
+
Array _shaped_text_get_glyphs(RID p_shaped) const;
Dictionary _shaped_text_get_carets(RID p_shaped, int p_position) const;
@@ -454,5 +464,6 @@ VARIANT_ENUM_CAST(TextServer::LineBreakFlag);
VARIANT_ENUM_CAST(TextServer::GraphemeFlag);
VARIANT_ENUM_CAST(TextServer::Hinting);
VARIANT_ENUM_CAST(TextServer::Feature);
+VARIANT_ENUM_CAST(TextServer::ContourPointTag);
#endif // TEXT_SERVER_H
diff --git a/servers/xr/xr_positional_tracker.h b/servers/xr/xr_positional_tracker.h
index 420d818342..a5c6459471 100644
--- a/servers/xr/xr_positional_tracker.h
+++ b/servers/xr/xr_positional_tracker.h
@@ -43,8 +43,8 @@
This is where potentially additional AR/VR interfaces may be active as there are AR/VR SDKs that solely deal with positional tracking.
*/
-class XRPositionalTracker : public Object {
- GDCLASS(XRPositionalTracker, Object);
+class XRPositionalTracker : public Reference {
+ GDCLASS(XRPositionalTracker, Reference);
_THREAD_SAFE_CLASS_
public:
diff --git a/servers/xr_server.cpp b/servers/xr_server.cpp
index 7087ae4947..5678071857 100644
--- a/servers/xr_server.cpp
+++ b/servers/xr_server.cpp
@@ -48,12 +48,17 @@ void XRServer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "world_scale"), "set_world_scale", "get_world_scale");
+ ClassDB::bind_method(D_METHOD("add_interface", "interface"), &XRServer::add_interface);
+ ClassDB::bind_method(D_METHOD("clear_primary_interface_if", "interface"), &XRServer::clear_primary_interface_if);
ClassDB::bind_method(D_METHOD("get_interface_count"), &XRServer::get_interface_count);
+ ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &XRServer::remove_interface);
ClassDB::bind_method(D_METHOD("get_interface", "idx"), &XRServer::get_interface);
ClassDB::bind_method(D_METHOD("get_interfaces"), &XRServer::get_interfaces);
ClassDB::bind_method(D_METHOD("find_interface", "name"), &XRServer::find_interface);
ClassDB::bind_method(D_METHOD("get_tracker_count"), &XRServer::get_tracker_count);
ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &XRServer::get_tracker);
+ ClassDB::bind_method(D_METHOD("add_tracker", "tracker"), &XRServer::add_tracker);
+ ClassDB::bind_method(D_METHOD("remove_tracker", "tracker"), &XRServer::remove_tracker);
ClassDB::bind_method(D_METHOD("get_primary_interface"), &XRServer::get_primary_interface);
ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &XRServer::set_primary_interface);
@@ -260,15 +265,15 @@ int XRServer::get_free_tracker_id_for_type(TrackerType p_tracker_type) {
return tracker_id;
};
-void XRServer::add_tracker(XRPositionalTracker *p_tracker) {
- ERR_FAIL_NULL(p_tracker);
+void XRServer::add_tracker(Ref<XRPositionalTracker> p_tracker) {
+ ERR_FAIL_COND(p_tracker.is_null());
trackers.push_back(p_tracker);
emit_signal("tracker_added", p_tracker->get_tracker_name(), p_tracker->get_tracker_type(), p_tracker->get_tracker_id());
};
-void XRServer::remove_tracker(XRPositionalTracker *p_tracker) {
- ERR_FAIL_NULL(p_tracker);
+void XRServer::remove_tracker(Ref<XRPositionalTracker> p_tracker) {
+ ERR_FAIL_COND(p_tracker.is_null());
int idx = -1;
for (int i = 0; i < trackers.size(); i++) {
@@ -288,14 +293,14 @@ int XRServer::get_tracker_count() const {
return trackers.size();
};
-XRPositionalTracker *XRServer::get_tracker(int p_index) const {
- ERR_FAIL_INDEX_V(p_index, trackers.size(), nullptr);
+Ref<XRPositionalTracker> XRServer::get_tracker(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, trackers.size(), Ref<XRPositionalTracker>());
return trackers[p_index];
};
-XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
- ERR_FAIL_COND_V(p_tracker_id == 0, nullptr);
+Ref<XRPositionalTracker> XRServer::find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const {
+ ERR_FAIL_COND_V(p_tracker_id == 0, Ref<XRPositionalTracker>());
for (int i = 0; i < trackers.size(); i++) {
if (trackers[i]->get_tracker_type() == p_tracker_type && trackers[i]->get_tracker_id() == p_tracker_id) {
@@ -303,7 +308,7 @@ XRPositionalTracker *XRServer::find_by_type_and_id(TrackerType p_tracker_type, i
};
};
- return nullptr;
+ return Ref<XRPositionalTracker>();
};
Ref<XRInterface> XRServer::get_primary_interface() const {
diff --git a/servers/xr_server.h b/servers/xr_server.h
index d3972be838..46243d7fd0 100644
--- a/servers/xr_server.h
+++ b/servers/xr_server.h
@@ -77,7 +77,7 @@ public:
private:
Vector<Ref<XRInterface>> interfaces;
- Vector<XRPositionalTracker *> trackers;
+ Vector<Ref<XRPositionalTracker>> trackers;
Ref<XRInterface> primary_interface; /* we'll identify one interface as primary, this will be used by our viewports */
@@ -167,11 +167,11 @@ public:
*/
bool is_tracker_id_in_use_for_type(TrackerType p_tracker_type, int p_tracker_id) const;
int get_free_tracker_id_for_type(TrackerType p_tracker_type);
- void add_tracker(XRPositionalTracker *p_tracker);
- void remove_tracker(XRPositionalTracker *p_tracker);
+ void add_tracker(Ref<XRPositionalTracker> p_tracker);
+ void remove_tracker(Ref<XRPositionalTracker> p_tracker);
int get_tracker_count() const;
- XRPositionalTracker *get_tracker(int p_index) const;
- XRPositionalTracker *find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
+ Ref<XRPositionalTracker> get_tracker(int p_index) const;
+ Ref<XRPositionalTracker> find_by_type_and_id(TrackerType p_tracker_type, int p_tracker_id) const;
uint64_t get_last_process_usec();
uint64_t get_last_commit_usec();
diff --git a/tests/test_dictionary.h b/tests/test_dictionary.h
new file mode 100644
index 0000000000..b94cf36109
--- /dev/null
+++ b/tests/test_dictionary.h
@@ -0,0 +1,159 @@
+/*************************************************************************/
+/* test_dictionary.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_DICTIONARY_H
+#define TEST_DICTIONARY_H
+
+#include "core/templates/ordered_hash_map.h"
+#include "core/templates/safe_refcount.h"
+#include "core/variant/dictionary.h"
+#include "core/variant/variant.h"
+#include "tests/test_macros.h"
+
+namespace TestDictionary {
+
+TEST_CASE("[Dictionary] Assignment using bracket notation ([])") {
+ Dictionary map;
+ map["Hello"] = 0;
+ CHECK(int(map["Hello"]) == 0);
+ map["Hello"] = 3;
+ CHECK(int(map["Hello"]) == 3);
+ map["World!"] = 4;
+ CHECK(int(map["World!"]) == 4);
+
+ // Test non-string keys, since keys can be of any Variant type.
+ map[12345] = -5;
+ CHECK(int(map[12345]) == -5);
+ map[false] = 128;
+ CHECK(int(map[false]) == 128);
+ map[Vector2(10, 20)] = 30;
+ CHECK(int(map[Vector2(10, 20)]) == 30);
+ map[0] = 400;
+ CHECK(int(map[0]) == 400);
+ // Check that assigning 0 doesn't overwrite the value for `false`.
+ CHECK(int(map[false]) == 128);
+}
+
+TEST_CASE("[Dictionary] == and != operators") {
+ Dictionary map1;
+ Dictionary map2;
+ CHECK(map1 != map2);
+ map1[1] = 3;
+ map2 = map1;
+ CHECK(map1 == map2);
+}
+
+TEST_CASE("[Dictionary] get_key_lists()") {
+ Dictionary map;
+ List<Variant> keys;
+ List<Variant> *ptr = &keys;
+ map.get_key_list(ptr);
+ CHECK(keys.is_empty());
+ map[1] = 3;
+ map.get_key_list(ptr);
+ CHECK(keys.size() == 1);
+ CHECK(int(keys[0]) == 1);
+ map[2] = 4;
+ map.get_key_list(ptr);
+ CHECK(keys.size() == 3);
+}
+
+TEST_CASE("[Dictionary] get_key_at_index()") {
+ Dictionary map;
+ map[4] = 3;
+ Variant val = map.get_key_at_index(0);
+ CHECK(int(val) == 4);
+ map[3] = 1;
+ val = map.get_key_at_index(0);
+ CHECK(int(val) == 4);
+ val = map.get_key_at_index(1);
+ CHECK(int(val) == 3);
+}
+
+TEST_CASE("[Dictionary] getptr()") {
+ Dictionary map;
+ map[1] = 3;
+ Variant *key = map.getptr(1);
+ CHECK(int(*key) == 3);
+ key = map.getptr(2);
+ CHECK(key == nullptr);
+}
+
+TEST_CASE("[Dictionary] get_valid()") {
+ Dictionary map;
+ map[1] = 3;
+ Variant val = map.get_valid(1);
+ CHECK(int(val) == 3);
+}
+TEST_CASE("[Dictionary] get()") {
+ Dictionary map;
+ map[1] = 3;
+ Variant val = map.get(1, -1);
+ CHECK(int(val) == 3);
+}
+
+TEST_CASE("[Dictionary] size(), empty() and clear()") {
+ Dictionary map;
+ CHECK(map.size() == 0);
+ CHECK(map.is_empty());
+ map[1] = 3;
+ CHECK(map.size() == 1);
+ CHECK(!map.is_empty());
+ map.clear();
+ CHECK(map.size() == 0);
+ CHECK(map.is_empty());
+}
+
+TEST_CASE("[Dictionary] has() and has_all()") {
+ Dictionary map;
+ CHECK(map.has(1) == false);
+ map[1] = 3;
+ CHECK(map.has(1));
+ Array keys;
+ keys.push_back(1);
+ CHECK(map.has_all(keys));
+ keys.push_back(2);
+ CHECK(map.has_all(keys) == false);
+}
+
+TEST_CASE("[Dictionary] keys() and values()") {
+ Dictionary map;
+ Array keys = map.keys();
+ Array values = map.values();
+ CHECK(keys.is_empty());
+ CHECK(values.is_empty());
+ map[1] = 3;
+ keys = map.keys();
+ values = map.values();
+ CHECK(int(keys[0]) == 1);
+ CHECK(int(values[0]) == 3);
+}
+} // namespace TestDictionary
+#endif // TEST_DICTIONARY_H
diff --git a/tests/test_geometry_2d.h b/tests/test_geometry_2d.h
index ea02d1114f..c9313f3625 100644
--- a/tests/test_geometry_2d.h
+++ b/tests/test_geometry_2d.h
@@ -113,7 +113,7 @@ TEST_CASE("[Geometry2D] Polygon clockwise") {
p.push_back(Vector2(1, 5));
CHECK(Geometry2D::is_polygon_clockwise(p));
- p.invert();
+ p.reverse();
CHECK_FALSE(Geometry2D::is_polygon_clockwise(p));
}
diff --git a/tests/test_list.h b/tests/test_list.h
index 1c70b6e961..52d5edff70 100644
--- a/tests/test_list.h
+++ b/tests/test_list.h
@@ -260,7 +260,7 @@ TEST_CASE("[List] Invert") {
List<int>::Element *n[4];
populate_integers(list, n, 4);
- list.invert();
+ list.reverse();
CHECK(list.front()->get() == 3);
CHECK(list.front()->next()->get() == 2);
diff --git a/tests/test_main.cpp b/tests/test_main.cpp
index f2a546de9b..d06d604532 100644
--- a/tests/test_main.cpp
+++ b/tests/test_main.cpp
@@ -42,6 +42,7 @@
#include "test_config_file.h"
#include "test_crypto.h"
#include "test_curve.h"
+#include "test_dictionary.h"
#include "test_expression.h"
#include "test_file_access.h"
#include "test_geometry_2d.h"
@@ -62,6 +63,7 @@
#include "test_object.h"
#include "test_ordered_hash_map.h"
#include "test_paged_array.h"
+#include "test_path_3d.h"
#include "test_pck_packer.h"
#include "test_physics_2d.h"
#include "test_physics_3d.h"
diff --git a/tests/test_path_3d.h b/tests/test_path_3d.h
new file mode 100644
index 0000000000..9961ae6e97
--- /dev/null
+++ b/tests/test_path_3d.h
@@ -0,0 +1,85 @@
+/*************************************************************************/
+/* test_path_3d.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef TEST_PATH_3D_H
+#define TEST_PATH_3D_H
+
+#include "scene/3d/path_3d.h"
+#include "scene/resources/curve.h"
+
+#include "tests/test_macros.h"
+
+namespace TestPath3D {
+
+TEST_CASE("[Path3D] Initialization") {
+ SUBCASE("Path should be empty right after initialization") {
+ Path3D *test_path = memnew(Path3D);
+ CHECK(test_path->get_curve() == nullptr);
+ memdelete(test_path);
+ }
+}
+
+TEST_CASE("[Path3D] Curve setter and getter") {
+ SUBCASE("Curve passed to the class should remain the same") {
+ Path3D *test_path = memnew(Path3D);
+ const Ref<Curve3D> &curve = memnew(Curve3D);
+
+ test_path->set_curve(curve);
+ CHECK(test_path->get_curve() == curve);
+ memdelete(test_path);
+ }
+ SUBCASE("Curve passed many times to the class should remain the same") {
+ Path3D *test_path = memnew(Path3D);
+ const Ref<Curve3D> &curve = memnew(Curve3D);
+
+ test_path->set_curve(curve);
+ test_path->set_curve(curve);
+ test_path->set_curve(curve);
+ CHECK(test_path->get_curve() == curve);
+ memdelete(test_path);
+ }
+ SUBCASE("Curve rewrite testing") {
+ Path3D *test_path = memnew(Path3D);
+ const Ref<Curve3D> &curve1 = memnew(Curve3D);
+ const Ref<Curve3D> &curve2 = memnew(Curve3D);
+
+ test_path->set_curve(curve1);
+ test_path->set_curve(curve2);
+ CHECK_MESSAGE(test_path->get_curve() != curve1,
+ "After rewrite, second curve should be in class");
+ CHECK_MESSAGE(test_path->get_curve() == curve2,
+ "After rewrite, second curve should be in class");
+ memdelete(test_path);
+ }
+}
+
+} // namespace TestPath3D
+
+#endif // TEST_PATH_3D