summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/android_builds.yml4
-rw-r--r--.github/workflows/ios_builds.yml4
-rw-r--r--.github/workflows/javascript_builds.yml4
-rw-r--r--.github/workflows/linux_builds.yml4
-rw-r--r--.github/workflows/macos_builds.yml4
-rw-r--r--.github/workflows/static_checks.yml4
-rw-r--r--.github/workflows/windows_builds.yml4
-rw-r--r--.gitignore2
-rw-r--r--COPYRIGHT.txt4
-rw-r--r--SConstruct4
-rw-r--r--core/core_constants.cpp2
-rw-r--r--core/doc_data.cpp18
-rw-r--r--core/error/error_list.cpp98
-rw-r--r--core/error/error_list.h5
-rw-r--r--core/extension/extension_api_dump.cpp23
-rw-r--r--core/input/input.cpp20
-rw-r--r--core/input/input_event.cpp9
-rw-r--r--core/input/input_event.h3
-rw-r--r--core/input/input_map.cpp18
-rw-r--r--core/input/input_map.h3
-rw-r--r--core/input/shortcut.cpp (renamed from scene/gui/shortcut.cpp)0
-rw-r--r--core/input/shortcut.h (renamed from scene/gui/shortcut.h)0
-rw-r--r--core/io/resource.cpp9
-rw-r--r--core/io/resource_loader.cpp88
-rw-r--r--core/io/resource_loader.h12
-rw-r--r--core/io/resource_saver.cpp35
-rw-r--r--core/io/resource_saver.h6
-rw-r--r--core/math/a_star.cpp28
-rw-r--r--core/math/a_star.h8
-rw-r--r--core/math/camera_matrix.cpp4
-rw-r--r--core/math/convex_hull.h2
-rw-r--r--core/math/dynamic_bvh.h2
-rw-r--r--core/math/transform_3d.h2
-rw-r--r--core/math/triangulate.h2
-rw-r--r--core/object/class_db.cpp15
-rw-r--r--core/object/class_db.h13
-rw-r--r--core/object/make_virtuals.py19
-rw-r--r--core/object/method_bind.h1
-rw-r--r--core/object/object.cpp15
-rw-r--r--core/object/object.h10
-rw-r--r--core/object/ref_counted.h4
-rw-r--r--core/os/main_loop.cpp29
-rw-r--r--core/os/main_loop.h6
-rw-r--r--core/register_core_types.cpp3
-rw-r--r--core/templates/map.h2
-rw-r--r--core/templates/rid_owner.h10
-rw-r--r--core/templates/set.h2
-rw-r--r--core/variant/method_ptrcall.h7
-rw-r--r--core/variant/native_ptr.h130
-rw-r--r--core/variant/typed_array.h10
-rw-r--r--core/variant/variant_call.cpp1
-rw-r--r--core/variant/variant_utility.cpp12
-rw-r--r--doc/Doxyfile38
-rw-r--r--doc/classes/@GlobalScope.xml23
-rw-r--r--doc/classes/AStar.xml4
-rw-r--r--doc/classes/AStar2D.xml4
-rw-r--r--doc/classes/AnimationNode.xml22
-rw-r--r--doc/classes/Area3D.xml9
-rw-r--r--doc/classes/ArrayMesh.xml1
-rw-r--r--doc/classes/AudioStream.xml15
-rw-r--r--doc/classes/AudioStreamPlayback.xml40
-rw-r--r--doc/classes/BaseMaterial3D.xml2
-rw-r--r--doc/classes/CPUParticles2D.xml148
-rw-r--r--doc/classes/CPUParticles3D.xml183
-rw-r--r--doc/classes/CanvasItemMaterial.xml2
-rw-r--r--doc/classes/CodeEdit.xml4
-rw-r--r--doc/classes/CollisionObject2D.xml2
-rw-r--r--doc/classes/CollisionObject3D.xml2
-rw-r--r--doc/classes/ColorPicker.xml2
-rw-r--r--doc/classes/Control.xml22
-rw-r--r--doc/classes/DisplayServer.xml2
-rw-r--r--doc/classes/EditorImportPlugin.xml32
-rw-r--r--doc/classes/EditorInspectorPlugin.xml20
-rw-r--r--doc/classes/EditorNode3DGizmo.xml20
-rw-r--r--doc/classes/EditorNode3DGizmoPlugin.xml54
-rw-r--r--doc/classes/EditorPlugin.xml110
-rw-r--r--doc/classes/EditorProperty.xml5
-rw-r--r--doc/classes/EditorResourceConversionPlugin.xml10
-rw-r--r--doc/classes/EditorResourcePreviewGenerator.xml16
-rw-r--r--doc/classes/EditorSceneImporter.xml8
-rw-r--r--doc/classes/EditorSceneImporterMesh.xml45
-rw-r--r--doc/classes/EditorScenePostImport.xml2
-rw-r--r--doc/classes/EditorSyntaxHighlighter.xml12
-rw-r--r--doc/classes/EditorTranslationParserPlugin.xml4
-rw-r--r--doc/classes/File.xml2
-rw-r--r--doc/classes/GradientTexture.xml3
-rw-r--r--doc/classes/GraphEdit.xml16
-rw-r--r--doc/classes/HTTPClient.xml4
-rw-r--r--doc/classes/InputEventShortcut.xml17
-rw-r--r--doc/classes/ItemList.xml3
-rw-r--r--doc/classes/Line2D.xml1
-rw-r--r--doc/classes/Node.xml27
-rw-r--r--doc/classes/ParticlesMaterial.xml160
-rw-r--r--doc/classes/PhysicsServer3D.xml12
-rw-r--r--doc/classes/RandomNumberGenerator.xml2
-rw-r--r--doc/classes/Resource.xml12
-rw-r--r--doc/classes/ResourceFormatLoader.xml32
-rw-r--r--doc/classes/ResourceFormatSaver.xml4
-rw-r--r--doc/classes/RichTextEffect.xml2
-rw-r--r--doc/classes/ScriptEditorBase.xml7
-rw-r--r--doc/classes/String.xml10
-rw-r--r--doc/classes/SyntaxHighlighter.xml2
-rw-r--r--doc/classes/TextEdit.xml2
-rw-r--r--doc/classes/Viewport.xml32
-rw-r--r--doc/classes/VisualScriptCustomNodes.xml (renamed from modules/visual_script/doc_classes/VisualScriptEditor.xml)4
-rw-r--r--doc/classes/VisualShaderNodeCustom.xml34
-rwxr-xr-xdoc/tools/makerst.py2
-rw-r--r--drivers/vulkan/rendering_device_vulkan.cpp4
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp146
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h3
-rw-r--r--editor/animation_bezier_editor.cpp4
-rw-r--r--editor/animation_bezier_editor.h2
-rw-r--r--editor/animation_track_editor.cpp10
-rw-r--r--editor/animation_track_editor.h4
-rw-r--r--editor/animation_track_editor_plugins.cpp4
-rw-r--r--editor/animation_track_editor_plugins.h2
-rw-r--r--editor/code_editor.cpp7
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/create_dialog.cpp2
-rw-r--r--editor/doc_tools.cpp57
-rw-r--r--editor/editor_audio_buses.cpp4
-rw-r--r--editor/editor_audio_buses.h2
-rw-r--r--editor/editor_command_palette.cpp6
-rw-r--r--editor/editor_command_palette.h2
-rw-r--r--editor/editor_export.cpp18
-rw-r--r--editor/editor_export.h4
-rw-r--r--editor/editor_file_dialog.cpp6
-rw-r--r--editor/editor_file_dialog.h2
-rw-r--r--editor/editor_help.cpp10
-rw-r--r--editor/editor_help.h2
-rw-r--r--editor/editor_help_search.cpp2
-rw-r--r--editor/editor_inspector.cpp56
-rw-r--r--editor/editor_inspector.h11
-rw-r--r--editor/editor_node.cpp15
-rw-r--r--editor/editor_node.h2
-rw-r--r--editor/editor_plugin.cpp155
-rw-r--r--editor/editor_plugin.h26
-rw-r--r--editor/editor_properties.cpp3
-rw-r--r--editor/editor_resource_preview.cpp35
-rw-r--r--editor/editor_resource_preview.h6
-rw-r--r--editor/editor_run_script.cpp16
-rw-r--r--editor/editor_run_script.h1
-rw-r--r--editor/editor_settings.cpp4
-rw-r--r--editor/editor_settings.h2
-rw-r--r--editor/editor_spin_slider.cpp4
-rw-r--r--editor/editor_spin_slider.h2
-rw-r--r--editor/editor_themes.cpp9
-rw-r--r--editor/editor_translation_parser.cpp23
-rw-r--r--editor/editor_translation_parser.h5
-rw-r--r--editor/import/editor_import_plugin.cpp170
-rw-r--r--editor/import/editor_import_plugin.h13
-rw-r--r--editor/import/resource_importer_scene.cpp39
-rw-r--r--editor/import/resource_importer_scene.h7
-rw-r--r--editor/import/scene_importer_mesh.cpp14
-rw-r--r--editor/import/scene_importer_mesh.h3
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp8
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp78
-rw-r--r--editor/plugins/animation_player_editor_plugin.h6
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp4
-rw-r--r--editor/plugins/asset_library_editor_plugin.h2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h2
-rw-r--r--editor/plugins/collision_polygon_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/curve_editor_plugin.cpp6
-rw-r--r--editor/plugins/curve_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp6
-rw-r--r--editor/plugins/mesh_editor_plugin.h3
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp238
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h37
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp23
-rw-r--r--editor/plugins/node_3d_editor_plugin.h8
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp4
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h2
-rw-r--r--editor/plugins/script_editor_plugin.cpp25
-rw-r--r--editor/plugins/script_editor_plugin.h7
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h2
-rw-r--r--editor/plugins/texture_3d_editor_plugin.cpp6
-rw-r--r--editor/plugins/texture_3d_editor_plugin.h1
-rw-r--r--editor/plugins/texture_layered_editor_plugin.cpp9
-rw-r--r--editor/plugins/texture_layered_editor_plugin.h2
-rw-r--r--editor/plugins/tiles/tile_atlas_view.cpp6
-rw-r--r--editor/plugins/tiles/tile_atlas_view.h2
-rw-r--r--editor/plugins/tiles/tile_data_editors.cpp8
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp9
-rw-r--r--editor/plugins/visual_shader_editor_plugin.h2
-rw-r--r--editor/project_manager.cpp3
-rw-r--r--editor/project_manager.h2
-rw-r--r--editor/property_editor.cpp33
-rw-r--r--editor/property_editor.h4
-rw-r--r--editor/property_selector.cpp2
-rw-r--r--editor/quick_open.cpp8
-rw-r--r--editor/scene_tree_dock.cpp7
-rw-r--r--editor/scene_tree_dock.h4
-rw-r--r--editor/settings_config_dialog.cpp3
-rw-r--r--editor/settings_config_dialog.h2
-rw-r--r--editor/translations/el.po2
-rw-r--r--main/main.cpp10
-rw-r--r--misc/dist/html/editor.html2
-rw-r--r--misc/dist/html/full-size.html2
-rw-r--r--misc/dist/linux/org.godotengine.Godot.xml2
-rw-r--r--misc/dist/windows/modpath.pas4
-rwxr-xr-xmisc/hooks/canonicalize_filename.sh2
-rwxr-xr-xmisc/scripts/black_format.sh2
-rwxr-xr-xmisc/scripts/clang_format.sh2
-rwxr-xr-xmisc/scripts/file_format.sh2
-rwxr-xr-xmisc/scripts/make_icons.sh2
-rw-r--r--modules/bullet/rigid_body_bullet.h2
-rw-r--r--modules/enet/doc_classes/ENetConnection.xml3
-rw-r--r--modules/fbx/fbx_parser/FBXParser.cpp2
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp2
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.h2
-rw-r--r--modules/gdscript/gdscript_parser.cpp3
-rw-r--r--modules/gltf/gltf_document.h4
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs15
-rw-r--r--modules/mono/glue/string_glue.cpp6
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp6
-rw-r--r--modules/text_server_adv/SCsub2
-rw-r--r--modules/text_server_adv/bitmap_font_adv.cpp2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptCustomNode.xml54
-rw-r--r--modules/visual_script/doc_classes/VisualScriptSubCall.xml7
-rw-r--r--modules/visual_script/register_types.cpp12
-rw-r--r--modules/visual_script/visual_script.cpp20
-rw-r--r--modules/visual_script/visual_script_editor.cpp30
-rw-r--r--modules/visual_script/visual_script_editor.h20
-rw-r--r--modules/visual_script/visual_script_nodes.cpp164
-rw-r--r--modules/visual_script/visual_script_nodes.h26
-rw-r--r--modules/visual_script/visual_script_property_selector.cpp2
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/android/export/export.cpp2
-rw-r--r--platform/android/export/export_plugin.cpp4
-rw-r--r--platform/android/java/app/gradle.properties4
-rw-r--r--platform/android/java/gradle.properties4
-rw-r--r--platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java2
-rw-r--r--platform/linuxbsd/crash_handler_linuxbsd.cpp10
-rw-r--r--platform/osx/crash_handler_osx.mm10
-rw-r--r--platform/osx/export/export_plugin.cpp4
-rw-r--r--platform/windows/crash_handler_windows.cpp10
-rw-r--r--platform/windows/detect.py2
-rw-r--r--platform/windows/display_server_windows.cpp33
-rw-r--r--scene/2d/audio_stream_player_2d.cpp6
-rw-r--r--scene/2d/collision_object_2d.cpp8
-rw-r--r--scene/2d/collision_object_2d.h4
-rw-r--r--scene/2d/cpu_particles_2d.cpp254
-rw-r--r--scene/2d/cpu_particles_2d.h22
-rw-r--r--scene/2d/gpu_particles_2d.cpp2
-rw-r--r--scene/2d/physics_body_2d.cpp8
-rw-r--r--scene/2d/physics_body_2d.h2
-rw-r--r--scene/2d/tile_map.cpp12
-rw-r--r--scene/2d/touch_screen_button.cpp8
-rw-r--r--scene/2d/touch_screen_button.h2
-rw-r--r--scene/3d/area_3d.cpp69
-rw-r--r--scene/3d/area_3d.h14
-rw-r--r--scene/3d/audio_stream_player_3d.cpp6
-rw-r--r--scene/3d/collision_object_3d.cpp8
-rw-r--r--scene/3d/collision_object_3d.h4
-rw-r--r--scene/3d/cpu_particles_3d.cpp260
-rw-r--r--scene/3d/cpu_particles_3d.h25
-rw-r--r--scene/3d/gpu_particles_3d.cpp2
-rw-r--r--scene/3d/physics_body_3d.cpp67
-rw-r--r--scene/3d/physics_body_3d.h2
-rw-r--r--scene/animation/animation_tree.cpp52
-rw-r--r--scene/animation/animation_tree.h8
-rw-r--r--scene/audio/audio_stream_player.cpp6
-rw-r--r--scene/gui/base_button.cpp18
-rw-r--r--scene/gui/base_button.h7
-rw-r--r--scene/gui/code_edit.cpp41
-rw-r--r--scene/gui/code_edit.h12
-rw-r--r--scene/gui/color_picker.cpp202
-rw-r--r--scene/gui/color_picker.h39
-rw-r--r--scene/gui/control.cpp103
-rw-r--r--scene/gui/control.h18
-rw-r--r--scene/gui/file_dialog.cpp4
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/gradient_edit.cpp3
-rw-r--r--scene/gui/gradient_edit.h2
-rw-r--r--scene/gui/graph_edit.cpp115
-rw-r--r--scene/gui/graph_edit.h13
-rw-r--r--scene/gui/graph_node.cpp4
-rw-r--r--scene/gui/graph_node.h2
-rw-r--r--scene/gui/item_list.cpp42
-rw-r--r--scene/gui/item_list.h7
-rw-r--r--scene/gui/line_edit.cpp3
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/menu_button.cpp6
-rw-r--r--scene/gui/menu_button.h4
-rw-r--r--scene/gui/popup_menu.cpp6
-rw-r--r--scene/gui/popup_menu.h4
-rw-r--r--scene/gui/rich_text_effect.cpp29
-rw-r--r--scene/gui/rich_text_effect.h32
-rw-r--r--scene/gui/rich_text_label.cpp11
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/scroll_bar.cpp3
-rw-r--r--scene/gui/scroll_bar.h2
-rw-r--r--scene/gui/scroll_container.cpp3
-rw-r--r--scene/gui/scroll_container.h2
-rw-r--r--scene/gui/slider.cpp3
-rw-r--r--scene/gui/slider.h2
-rw-r--r--scene/gui/spin_box.cpp4
-rw-r--r--scene/gui/spin_box.h2
-rw-r--r--scene/gui/split_container.cpp4
-rw-r--r--scene/gui/split_container.h2
-rw-r--r--scene/gui/subviewport_container.cpp10
-rw-r--r--scene/gui/subviewport_container.h4
-rw-r--r--scene/gui/tab_container.cpp3
-rw-r--r--scene/gui/tab_container.h2
-rw-r--r--scene/gui/tabs.cpp3
-rw-r--r--scene/gui/tabs.h2
-rw-r--r--scene/gui/text_edit.cpp56
-rw-r--r--scene/gui/text_edit.h20
-rw-r--r--scene/gui/tree.cpp4
-rw-r--r--scene/gui/tree.h3
-rw-r--r--scene/main/canvas_item.cpp6
-rw-r--r--scene/main/canvas_item.h1
-rw-r--r--scene/main/node.cpp95
-rw-r--r--scene/main/node.h21
-rw-r--r--scene/main/scene_tree.cpp23
-rw-r--r--scene/main/scene_tree.h8
-rw-r--r--scene/main/viewport.cpp59
-rw-r--r--scene/main/viewport.h6
-rw-r--r--scene/main/window.cpp6
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/animation.cpp13
-rw-r--r--scene/resources/animation.h3
-rw-r--r--scene/resources/curve.cpp97
-rw-r--r--scene/resources/curve.h2
-rw-r--r--scene/resources/default_theme/default_theme.cpp50
-rw-r--r--scene/resources/particles_material.cpp344
-rw-r--r--scene/resources/particles_material.h62
-rw-r--r--scene/resources/primitive_meshes.cpp7
-rw-r--r--scene/resources/skeleton_modification_2d.cpp12
-rw-r--r--scene/resources/skeleton_modification_2d.h4
-rw-r--r--scene/resources/skeleton_modification_3d.cpp16
-rw-r--r--scene/resources/skeleton_modification_3d.h3
-rw-r--r--scene/resources/syntax_highlighter.cpp24
-rw-r--r--scene/resources/syntax_highlighter.h9
-rw-r--r--scene/resources/text_paragraph.cpp17
-rw-r--r--scene/resources/texture.cpp71
-rw-r--r--scene/resources/texture.h4
-rw-r--r--scene/resources/visual_shader.cpp109
-rw-r--r--scene/resources/visual_shader.h14
-rw-r--r--servers/audio/audio_stream.cpp84
-rw-r--r--servers/audio/audio_stream.h37
-rw-r--r--servers/audio/effects/audio_effect_pitch_shift.cpp2
-rw-r--r--servers/physics_3d/area_3d_sw.cpp22
-rw-r--r--servers/physics_3d/area_3d_sw.h16
-rw-r--r--servers/physics_3d/gjk_epa.cpp2
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp2
-rw-r--r--servers/physics_3d/joints/generic_6dof_joint_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.cpp2
-rw-r--r--servers/physics_3d/joints/hinge_joint_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/jacobian_entry_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.cpp2
-rw-r--r--servers/physics_3d/joints/pin_joint_3d_sw.h2
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.cpp2
-rw-r--r--servers/physics_3d/joints/slider_joint_3d_sw.h2
-rw-r--r--servers/physics_3d/shape_3d_sw.cpp2
-rw-r--r--servers/physics_3d/soft_body_3d_sw.cpp87
-rw-r--r--servers/physics_3d/soft_body_3d_sw.h6
-rw-r--r--servers/physics_server_3d.cpp4
-rw-r--r--servers/physics_server_3d.h6
-rw-r--r--servers/register_server_types.cpp4
-rw-r--r--servers/rendering/renderer_rd/effects_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp4
-rw-r--r--servers/rendering/renderer_rd/renderer_storage_rd.cpp2
-rw-r--r--servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cluster_render.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl4
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/tonemap.glsl10
-rw-r--r--servers/text_server.cpp6
-rw-r--r--tests/test_curve.h35
381 files changed, 4335 insertions, 2853 deletions
diff --git a/.github/workflows/android_builds.yml b/.github/workflows/android_builds.yml
index a618b69e30..5efeba4b5f 100644
--- a/.github/workflows/android_builds.yml
+++ b/.github/workflows/android_builds.yml
@@ -7,6 +7,10 @@ env:
SCONSFLAGS: platform=android verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-android
+ cancel-in-progress: true
+
jobs:
android-template:
runs-on: "ubuntu-20.04"
diff --git a/.github/workflows/ios_builds.yml b/.github/workflows/ios_builds.yml
index 6f5ffcf42f..69809c6cb6 100644
--- a/.github/workflows/ios_builds.yml
+++ b/.github/workflows/ios_builds.yml
@@ -7,6 +7,10 @@ env:
SCONSFLAGS: platform=iphone verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-ios
+ cancel-in-progress: true
+
jobs:
ios-template:
runs-on: "macos-latest"
diff --git a/.github/workflows/javascript_builds.yml b/.github/workflows/javascript_builds.yml
index 5124197d3d..25a063c3b2 100644
--- a/.github/workflows/javascript_builds.yml
+++ b/.github/workflows/javascript_builds.yml
@@ -9,6 +9,10 @@ env:
EM_VERSION: 2.0.27
EM_CACHE_FOLDER: 'emsdk-cache'
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-javascript
+ cancel-in-progress: true
+
jobs:
javascript-template:
runs-on: "ubuntu-20.04"
diff --git a/.github/workflows/linux_builds.yml b/.github/workflows/linux_builds.yml
index e2b9fa8a7b..6fe76345f3 100644
--- a/.github/workflows/linux_builds.yml
+++ b/.github/workflows/linux_builds.yml
@@ -7,6 +7,10 @@ env:
SCONSFLAGS: platform=linuxbsd verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-linux
+ cancel-in-progress: true
+
jobs:
linux-editor:
runs-on: "ubuntu-20.04"
diff --git a/.github/workflows/macos_builds.yml b/.github/workflows/macos_builds.yml
index abc561eaa9..2c9e0fa1a0 100644
--- a/.github/workflows/macos_builds.yml
+++ b/.github/workflows/macos_builds.yml
@@ -7,6 +7,10 @@ env:
SCONSFLAGS: platform=osx verbose=yes warnings=extra werror=yes debug_symbols=no --jobs=2 module_text_server_fb_enabled=yes
SCONS_CACHE_LIMIT: 4096
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-macos
+ cancel-in-progress: true
+
jobs:
macos-editor:
runs-on: "macos-latest"
diff --git a/.github/workflows/static_checks.yml b/.github/workflows/static_checks.yml
index 30468034ff..fd2e748076 100644
--- a/.github/workflows/static_checks.yml
+++ b/.github/workflows/static_checks.yml
@@ -1,6 +1,10 @@
name: 📊 Static Checks
on: [push, pull_request]
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-static
+ cancel-in-progress: true
+
jobs:
static-checks:
name: Static Checks (clang-format, black format, file format, documentation checks)
diff --git a/.github/workflows/windows_builds.yml b/.github/workflows/windows_builds.yml
index 1f9e3ac5e3..53febd353b 100644
--- a/.github/workflows/windows_builds.yml
+++ b/.github/workflows/windows_builds.yml
@@ -9,6 +9,10 @@ env:
SCONS_CACHE_MSVC_CONFIG: true
SCONS_CACHE_LIMIT: 3072
+concurrency:
+ group: ci-${{github.actor}}-${{github.head_ref || github.run_number}}-${{github.ref}}-windows
+ cancel-in-progress: true
+
jobs:
windows-editor:
# Windows 10 with latest image
diff --git a/.gitignore b/.gitignore
index c1c2374bc3..00d87b6bf6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,7 +83,7 @@ gmon.out
__MACOSX
logs/
-# for projects that use SCons for building: http://http://www.scons.org/
+# for projects that use SCons for building: https://www.scons.org/
.sconf_temp
.sconsign*.dblite
*.pyc
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index ef444721b2..035e680fe1 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -1135,7 +1135,7 @@ License: glslang
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
.
As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -1761,7 +1761,7 @@ License: MPL-2.0
.
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ file, You can obtain one at https://mozilla.org/MPL/2.0/.
.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
diff --git a/SConstruct b/SConstruct
index 1ab42b6b90..0ae7442e35 100644
--- a/SConstruct
+++ b/SConstruct
@@ -316,10 +316,10 @@ if env_base["target"] == "debug":
# will properly be rebuilt. As such, we only enable them for debug (dev) builds, not release.
# To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
- # http://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
+ # https://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
env_base.Decider("MD5-timestamp")
# Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
- # http://scons.org/doc/production/HTML/scons-user/ch06s04.html
+ # https://scons.org/doc/production/HTML/scons-user/ch06s04.html
env_base.SetOption("implicit_cache", 1)
if env_base["no_editor_splash"]:
diff --git a/core/core_constants.cpp b/core/core_constants.cpp
index 5791f79053..4f3f1fd16e 100644
--- a/core/core_constants.cpp
+++ b/core/core_constants.cpp
@@ -558,6 +558,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_NODE_PATH_VALID_TYPES);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_SAVE_FILE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_OBJECTID);
+ BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_INT_IS_POINTER);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_ARRAY_TYPE);
BIND_CORE_ENUM_CONSTANT(PROPERTY_HINT_MAX);
@@ -605,6 +606,7 @@ void register_global_constants() {
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_VIRTUAL);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_FROM_SCRIPT);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_STATIC);
+ BIND_CORE_ENUM_CONSTANT(METHOD_FLAG_OBJECT_CORE);
BIND_CORE_ENUM_CONSTANT(METHOD_FLAGS_DEFAULT);
BIND_CORE_ENUM_CONSTANT_CUSTOM("TYPE_NIL", Variant::NIL);
diff --git a/core/doc_data.cpp b/core/doc_data.cpp
index 45450bf97a..4b284a30aa 100644
--- a/core/doc_data.cpp
+++ b/core/doc_data.cpp
@@ -31,7 +31,14 @@
#include "doc_data.h"
void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const PropertyInfo &p_retinfo) {
- if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_retinfo.type == Variant::INT && p_retinfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
+ p_method.return_type = p_retinfo.hint_string;
+ if (p_method.return_type == "") {
+ p_method.return_type = "void*";
+ } else {
+ p_method.return_type += "*";
+ }
+ } else if (p_retinfo.type == Variant::INT && p_retinfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_method.return_enum = p_retinfo.class_name;
if (p_method.return_enum.begins_with("_")) { //proxy class
p_method.return_enum = p_method.return_enum.substr(1, p_method.return_enum.length());
@@ -55,7 +62,14 @@ void DocData::return_doc_from_retinfo(DocData::MethodDoc &p_method, const Proper
void DocData::argument_doc_from_arginfo(DocData::ArgumentDoc &p_argument, const PropertyInfo &p_arginfo) {
p_argument.name = p_arginfo.name;
- if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
+ if (p_arginfo.type == Variant::INT && p_arginfo.hint == PROPERTY_HINT_INT_IS_POINTER) {
+ p_argument.type = p_arginfo.hint_string;
+ if (p_argument.type == "") {
+ p_argument.type = "void*";
+ } else {
+ p_argument.type += "*";
+ }
+ } else if (p_arginfo.type == Variant::INT && p_arginfo.usage & PROPERTY_USAGE_CLASS_IS_ENUM) {
p_argument.enumeration = p_arginfo.class_name;
if (p_argument.enumeration.begins_with("_")) { //proxy class
p_argument.enumeration = p_argument.enumeration.substr(1, p_argument.enumeration.length());
diff --git a/core/error/error_list.cpp b/core/error/error_list.cpp
index a8355065fe..e1e94dd65d 100644
--- a/core/error/error_list.cpp
+++ b/core/error/error_list.cpp
@@ -31,55 +31,55 @@
#include "error_list.h"
const char *error_names[] = {
- "No error",
- "Generic error",
- "Requested operation is unsupported/unavailable",
- "The object hasn't been set up properly",
- "Missing credentials for requested resource",
- "Parameter out of range",
- "Out of memory",
- "File not found",
- "Bad drive",
- "Bad path",
- "Permission denied",
- "Already in use",
- "Can't open file",
- "Can't write file",
- "Can't read file",
- "File unrecognized",
- "File corrupt",
- "Missing dependencies for file",
- "Unexpected eof",
- "Can't open resource/socket/file", // File too? What's the difference to ERR_FILE_CANT_OPEN
- "Can't create", // What can't be created,
- "Query failed", // What query,
- "Already in use",
- "Resource is locked",
- "Timeout",
- "Can't connect",
- "Can't resolve hostname", // I guessed it's the hostname here.
- "Connection error",
- "Can't acquire resource",
- "Can't fork",
- "Invalid data",
- "Invalid parameter",
- "Item already exists",
- "Item does not exist",
- "Can't read from database", // Comments say, it's full? Is that correct?
- "Can't write to database", // Is the database always full when this is raised?
- "Compilation failed",
- "Method not found",
- "Link failed",
- "Script failed",
- "Cyclic link detected",
- "Invalid declaration",
- "Duplicate symbol",
- "Parse error",
- "Resource is busy",
- "Skip error", // ???? What's this? String taken from the docs
- "Help error", // More specific?
- "Bug",
- "Printer on fire",
+ "OK", // OK
+ "Failed", // FAILED
+ "Unavailable", // ERR_UNAVAILABLE
+ "Unconfigured", // ERR_UNCONFIGURED
+ "Unauthorized", // ERR_UNAUTHORIZED
+ "Parameter out of range", // ERR_PARAMETER_RANGE_ERROR
+ "Out of memory", // ERR_OUT_OF_MEMORY
+ "File not found", // ERR_FILE_NOT_FOUND
+ "File: Bad drive", // ERR_FILE_BAD_DRIVE
+ "File: Bad path", // ERR_FILE_BAD_PATH
+ "File: Permission denied", // ERR_FILE_NO_PERMISSION
+ "File already in use", // ERR_FILE_ALREADY_IN_USE
+ "Can't open file", // ERR_FILE_CANT_OPEN
+ "Can't write file", // ERR_FILE_CANT_WRITE
+ "Can't read file", // ERR_FILE_CANT_READ
+ "File unrecognized", // ERR_FILE_UNRECOGNIZED
+ "File corrupt", // ERR_FILE_CORRUPT
+ "Missing dependencies for file", // ERR_FILE_MISSING_DEPENDENCIES
+ "End of file", // ERR_FILE_EOF
+ "Can't open", // ERR_CANT_OPEN
+ "Can't create", // ERR_CANT_CREATE
+ "Query failed", // ERR_QUERY_FAILED
+ "Already in use", // ERR_ALREADY_IN_USE
+ "Locked", // ERR_LOCKED
+ "Timeout", // ERR_TIMEOUT
+ "Can't connect", // ERR_CANT_CONNECT
+ "Can't resolve", // ERR_CANT_RESOLVE
+ "Connection error", // ERR_CONNECTION_ERROR
+ "Can't acquire resource", // ERR_CANT_ACQUIRE_RESOURCE
+ "Can't fork", // ERR_CANT_FORK
+ "Invalid data", // ERR_INVALID_DATA
+ "Invalid parameter", // ERR_INVALID_PARAMETER
+ "Already exists", // ERR_ALREADY_EXISTS
+ "Does not exist", // ERR_DOES_NOT_EXIST
+ "Can't read database", // ERR_DATABASE_CANT_READ
+ "Can't write database", // ERR_DATABASE_CANT_WRITE
+ "Compilation failed", // ERR_COMPILATION_FAILED
+ "Method not found", // ERR_METHOD_NOT_FOUND
+ "Link failed", // ERR_LINK_FAILED
+ "Script failed", // ERR_SCRIPT_FAILED
+ "Cyclic link detected", // ERR_CYCLIC_LINK
+ "Invalid declaration", // ERR_INVALID_DECLARATION
+ "Duplicate symbol", // ERR_DUPLICATE_SYMBOL
+ "Parse error", // ERR_PARSE_ERROR
+ "Busy", // ERR_BUSY
+ "Skip", // ERR_SKIP
+ "Help", // ERR_HELP
+ "Bug", // ERR_BUG
+ "Printer on fire", // ERR_PRINTER_ON_FIRE
};
static_assert(sizeof(error_names) / sizeof(*error_names) == ERR_MAX);
diff --git a/core/error/error_list.h b/core/error/error_list.h
index e7c7f10265..852825dda5 100644
--- a/core/error/error_list.h
+++ b/core/error/error_list.h
@@ -36,6 +36,11 @@
* values can be more detailed in the future.
*
* This is a generic error list, mainly for organizing a language of returning errors.
+ *
+ * Errors:
+ * - Are added to the Error enum in core/error/error_list.h
+ * - Have a description added to error_names in core/error/error_list.cpp
+ * - Are bound with BIND_CORE_ENUM_CONSTANT() in core/core_constants.cpp
*/
enum Error {
diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp
index 49570cd1c1..a8547a0090 100644
--- a/core/extension/extension_api_dump.cpp
+++ b/core/extension/extension_api_dump.cpp
@@ -39,6 +39,13 @@
#ifdef TOOLS_ENABLED
static String get_type_name(const PropertyInfo &p_info) {
+ if (p_info.type == Variant::INT && (p_info.hint == PROPERTY_HINT_INT_IS_POINTER)) {
+ if (p_info.hint_string == "") {
+ return "void*";
+ } else {
+ return p_info.hint_string + "*";
+ }
+ }
if (p_info.type == Variant::INT && (p_info.usage & PROPERTY_USAGE_CLASS_IS_ENUM)) {
return String("enum::") + String(p_info.class_name);
}
@@ -653,7 +660,7 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
ClassDB::get_method_list(class_name, &method_list, true);
for (const MethodInfo &F : method_list) {
StringName method_name = F.name;
- if (F.flags & METHOD_FLAG_VIRTUAL) {
+ if ((F.flags & METHOD_FLAG_VIRTUAL) && !(F.flags & METHOD_FLAG_OBJECT_CORE)) {
//virtual method
const MethodInfo &mi = F;
Dictionary d2;
@@ -831,6 +838,20 @@ Dictionary NativeExtensionAPIDump::generate_extension_api() {
}
}
+ {
+ Array native_structures;
+
+ {
+ Dictionary d;
+ d["name"] = "AudioFrame";
+ d["format"] = "float left,float right";
+
+ native_structures.push_back(d);
+ }
+
+ api_dump["native_structures"] = native_structures;
+ }
+
return api_dump;
}
diff --git a/core/input/input.cpp b/core/input/input.cpp
index 72563cc40a..9195f7d8b5 100644
--- a/core/input/input.cpp
+++ b/core/input/input.cpp
@@ -240,18 +240,12 @@ bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const {
}
bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
return action_state.has(p_action) && action_state[p_action].pressed && (p_exact ? action_state[p_action].exact : true);
}
bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
@@ -269,10 +263,7 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con
}
bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return false;
@@ -290,10 +281,7 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co
}
float Input::get_action_strength(const StringName &p_action, bool p_exact) const {
-#ifdef DEBUG_ENABLED
- bool has_action = InputMap::get_singleton()->has_action(p_action);
- ERR_FAIL_COND_V_MSG(!has_action, false, "Request for nonexistent InputMap action '" + String(p_action) + "'.");
-#endif
+ ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action));
const Map<StringName, Action>::Element *E = action_state.find(p_action);
if (!E) {
return 0.0f;
diff --git a/core/input/input_event.cpp b/core/input/input_event.cpp
index 325cdf2127..50b2099236 100644
--- a/core/input/input_event.cpp
+++ b/core/input/input_event.cpp
@@ -31,8 +31,8 @@
#include "input_event.h"
#include "core/input/input_map.h"
+#include "core/input/shortcut.h"
#include "core/os/keyboard.h"
-#include "scene/gui/shortcut.h"
const int InputEvent::DEVICE_ID_TOUCH_MOUSE = -1;
const int InputEvent::DEVICE_ID_INTERNAL = -2;
@@ -1545,6 +1545,13 @@ Ref<Shortcut> InputEventShortcut::get_shortcut() {
return shortcut;
}
+void InputEventShortcut::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_shortcut", "shortcut"), &InputEventShortcut::set_shortcut);
+ ClassDB::bind_method(D_METHOD("get_shortcut"), &InputEventShortcut::get_shortcut);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "Shortcut"), "set_shortcut", "get_shortcut");
+}
+
bool InputEventShortcut::is_pressed() const {
return true;
}
diff --git a/core/input/input_event.h b/core/input/input_event.h
index 517d63eb40..3fc8078a09 100644
--- a/core/input/input_event.h
+++ b/core/input/input_event.h
@@ -548,6 +548,9 @@ class InputEventShortcut : public InputEvent {
Ref<Shortcut> shortcut;
+protected:
+ static void _bind_methods();
+
public:
void set_shortcut(Ref<Shortcut> p_shortcut);
Ref<Shortcut> get_shortcut();
diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp
index 83ec70757e..c7ca65f61a 100644
--- a/core/input/input_map.cpp
+++ b/core/input/input_map.cpp
@@ -59,7 +59,7 @@ void InputMap::_bind_methods() {
* Returns an nonexistent action error message with a suggestion of the closest
* matching action name (if possible).
*/
-String InputMap::_suggest_actions(const StringName &p_action) const {
+String InputMap::suggest_actions(const StringName &p_action) const {
List<StringName> actions = get_actions();
StringName closest_action;
float closest_similarity = 0.0;
@@ -93,7 +93,7 @@ void InputMap::add_action(const StringName &p_action, float p_deadzone) {
}
void InputMap::erase_action(const StringName &p_action) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map.erase(p_action);
}
@@ -147,20 +147,20 @@ bool InputMap::has_action(const StringName &p_action) const {
}
float InputMap::action_get_deadzone(const StringName &p_action) {
- ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!input_map.has(p_action), 0.0f, suggest_actions(p_action));
return input_map[p_action].deadzone;
}
void InputMap::action_set_deadzone(const StringName &p_action, float p_deadzone) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map[p_action].deadzone = p_deadzone;
}
void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_MSG(p_event.is_null(), "It's not a reference to a valid InputEvent object.");
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
if (_find_event(input_map[p_action], p_event, true)) {
return; // Already added.
}
@@ -169,12 +169,12 @@ void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent
}
bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!input_map.has(p_action), false, suggest_actions(p_action));
return (_find_event(input_map[p_action], p_event, true) != nullptr);
}
void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
List<Ref<InputEvent>>::Element *E = _find_event(input_map[p_action], p_event, true);
if (E) {
@@ -186,7 +186,7 @@ void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEve
}
void InputMap::action_erase_events(const StringName &p_action) {
- ERR_FAIL_COND_MSG(!input_map.has(p_action), _suggest_actions(p_action));
+ ERR_FAIL_COND_MSG(!input_map.has(p_action), suggest_actions(p_action));
input_map[p_action].inputs.clear();
}
@@ -218,7 +218,7 @@ bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName
bool InputMap::event_get_action_status(const Ref<InputEvent> &p_event, const StringName &p_action, bool p_exact_match, bool *p_pressed, float *p_strength, float *p_raw_strength) const {
OrderedHashMap<StringName, Action>::Element E = input_map.find(p_action);
- ERR_FAIL_COND_V_MSG(!E, false, _suggest_actions(p_action));
+ ERR_FAIL_COND_V_MSG(!E, false, suggest_actions(p_action));
Ref<InputEventAction> input_event_action = p_event;
if (input_event_action.is_valid()) {
diff --git a/core/input/input_map.h b/core/input/input_map.h
index 0e0567464a..a2d3952f94 100644
--- a/core/input/input_map.h
+++ b/core/input/input_map.h
@@ -61,7 +61,6 @@ private:
Array _action_get_events(const StringName &p_action);
Array _get_actions();
- String _suggest_actions(const StringName &p_action) const;
protected:
static void _bind_methods();
@@ -89,6 +88,8 @@ public:
void load_from_project_settings();
void load_default();
+ String suggest_actions(const StringName &p_action) const;
+
String get_builtin_display_name(const String &p_name) const;
// Use an Ordered Map so insertion order is preserved. We want the elements to be 'grouped' somewhat.
const OrderedHashMap<String, List<Ref<InputEvent>>> &get_builtins();
diff --git a/scene/gui/shortcut.cpp b/core/input/shortcut.cpp
index d0cb08724e..d0cb08724e 100644
--- a/scene/gui/shortcut.cpp
+++ b/core/input/shortcut.cpp
diff --git a/scene/gui/shortcut.h b/core/input/shortcut.h
index 249dd1971f..249dd1971f 100644
--- a/scene/gui/shortcut.h
+++ b/core/input/shortcut.h
diff --git a/core/io/resource.cpp b/core/io/resource.cpp
index 0262655927..87b4d7195d 100644
--- a/core/io/resource.cpp
+++ b/core/io/resource.cpp
@@ -352,9 +352,8 @@ Node *Resource::get_local_scene() const {
}
void Resource::setup_local_to_scene() {
- if (get_script_instance()) {
- get_script_instance()->call("_setup_local_to_scene");
- }
+ // Can't use GDVIRTUAL in Resource, so this will have to be done with a signal
+ emit_signal(SNAME("setup_local_to_scene_requested"));
}
Node *(*Resource::_get_local_scene_func)() = nullptr;
@@ -422,12 +421,12 @@ void Resource::_bind_methods() {
ClassDB::bind_method(D_METHOD("duplicate", "subresources"), &Resource::duplicate, DEFVAL(false));
ADD_SIGNAL(MethodInfo("changed"));
+ ADD_SIGNAL(MethodInfo("setup_local_to_scene_requested"));
+
ADD_GROUP("Resource", "resource_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "resource_local_to_scene"), "set_local_to_scene", "is_local_to_scene");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "resource_path", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_path", "get_path");
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "resource_name"), "set_name", "get_name");
-
- BIND_VMETHOD(MethodInfo("_setup_local_to_scene"));
}
Resource::Resource() :
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index d02d827443..64237f3b15 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -68,25 +68,28 @@ bool ResourceFormatLoader::recognize_path(const String &p_path, const String &p_
}
bool ResourceFormatLoader::handles_type(const String &p_type) const {
- if (get_script_instance() && get_script_instance()->has_method("_handles_type")) {
- // I guess custom loaders for custom resources should use "Resource"
- return get_script_instance()->call("_handles_type", p_type);
+ bool success;
+ if (GDVIRTUAL_CALL(_handles_type, p_type, success)) {
+ return success;
}
return false;
}
String ResourceFormatLoader::get_resource_type(const String &p_path) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_resource_type")) {
- return get_script_instance()->call("_get_resource_type", p_path);
+ String ret;
+
+ if (GDVIRTUAL_CALL(_get_resource_type, p_path, ret)) {
+ return ret;
}
return "";
}
ResourceUID::ID ResourceFormatLoader::get_resource_uid(const String &p_path) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_resource_uid")) {
- return get_script_instance()->call("_get_resource_uid", p_path);
+ int64_t uid;
+ if (GDVIRTUAL_CALL(_get_resource_uid, p_path, uid)) {
+ return uid;
}
return ResourceUID::INVALID_ID;
@@ -105,27 +108,26 @@ void ResourceLoader::get_recognized_extensions_for_type(const String &p_type, Li
}
bool ResourceFormatLoader::exists(const String &p_path) const {
+ bool success;
+ if (GDVIRTUAL_CALL(_exists, p_path, success)) {
+ return success;
+ }
return FileAccess::exists(p_path); //by default just check file
}
void ResourceFormatLoader::get_recognized_extensions(List<String> *p_extensions) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_recognized_extensions")) {
- PackedStringArray exts = get_script_instance()->call("_get_recognized_extensions");
-
- {
- const String *r = exts.ptr();
- for (int i = 0; i < exts.size(); ++i) {
- p_extensions->push_back(r[i]);
- }
+ PackedStringArray exts;
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, exts)) {
+ const String *r = exts.ptr();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
}
}
}
RES ResourceFormatLoader::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, CacheMode p_cache_mode) {
- // Check user-defined loader if there's any. Hard fail if it returns an error.
- if (get_script_instance() && get_script_instance()->has_method("_load")) {
- Variant res = get_script_instance()->call("_load", p_path, p_original_path, p_use_sub_threads, p_cache_mode);
-
+ Variant res;
+ if (GDVIRTUAL_CALL(_load, p_path, p_original_path, p_use_sub_threads, p_cache_mode, res)) {
if (res.get_type() == Variant::INT) { // Error code, abort.
if (r_error) {
*r_error = (Error)res.operator int64_t();
@@ -143,48 +145,42 @@ RES ResourceFormatLoader::load(const String &p_path, const String &p_original_pa
}
void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) {
- if (get_script_instance() && get_script_instance()->has_method("_get_dependencies")) {
- PackedStringArray deps = get_script_instance()->call("_get_dependencies", p_path, p_add_types);
-
- {
- const String *r = deps.ptr();
- for (int i = 0; i < deps.size(); ++i) {
- p_dependencies->push_back(r[i]);
- }
+ PackedStringArray deps;
+ if (GDVIRTUAL_CALL(_get_dependencies, p_path, p_add_types, deps)) {
+ const String *r = deps.ptr();
+ for (int i = 0; i < deps.size(); ++i) {
+ p_dependencies->push_back(r[i]);
}
}
}
Error ResourceFormatLoader::rename_dependencies(const String &p_path, const Map<String, String> &p_map) {
- if (get_script_instance() && get_script_instance()->has_method("_rename_dependencies")) {
- Dictionary deps_dict;
- for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
- deps_dict[E->key()] = E->value();
- }
+ Dictionary deps_dict;
+ for (Map<String, String>::Element *E = p_map.front(); E; E = E->next()) {
+ deps_dict[E->key()] = E->value();
+ }
- int64_t res = get_script_instance()->call("_rename_dependencies", deps_dict);
- return (Error)res;
+ int64_t err;
+ if (GDVIRTUAL_CALL(_rename_dependencies, p_path, deps_dict, err)) {
+ return (Error)err;
}
return OK;
}
void ResourceFormatLoader::_bind_methods() {
- {
- MethodInfo info = MethodInfo(Variant::NIL, "_load", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "original_path"), PropertyInfo(Variant::BOOL, "use_sub_threads"), PropertyInfo(Variant::INT, "cache_mode"));
- info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(info);
- }
-
- BIND_VMETHOD(MethodInfo(Variant::PACKED_STRING_ARRAY, "_get_recognized_extensions"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_handles_type", PropertyInfo(Variant::STRING_NAME, "typename")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_resource_type", PropertyInfo(Variant::STRING, "path")));
- BIND_VMETHOD(MethodInfo("_get_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "add_types")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_rename_dependencies", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "renames")));
-
BIND_ENUM_CONSTANT(CACHE_MODE_IGNORE);
BIND_ENUM_CONSTANT(CACHE_MODE_REUSE);
BIND_ENUM_CONSTANT(CACHE_MODE_REPLACE);
+
+ GDVIRTUAL_BIND(_get_recognized_extensions);
+ GDVIRTUAL_BIND(_handles_type, "type");
+ GDVIRTUAL_BIND(_get_resource_type, "path");
+ GDVIRTUAL_BIND(_get_resource_uid, "path");
+ GDVIRTUAL_BIND(_get_dependencies, "path", "add_types");
+ GDVIRTUAL_BIND(_rename_dependencies, "path", "renames");
+ GDVIRTUAL_BIND(_exists, "path");
+ GDVIRTUAL_BIND(_load, "path", "original_path", "use_sub_threads", "cache_mode");
}
///////////////////////////////////
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index e525e80a9d..f1d9815635 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -32,6 +32,8 @@
#define RESOURCE_LOADER_H
#include "core/io/resource.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
#include "core/os/semaphore.h"
#include "core/os/thread.h"
@@ -48,6 +50,16 @@ public:
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions)
+ GDVIRTUAL1RC(bool, _handles_type, StringName)
+ GDVIRTUAL1RC(String, _get_resource_type, String)
+ GDVIRTUAL1RC(ResourceUID::ID, _get_resource_uid, String)
+ GDVIRTUAL2RC(Vector<String>, _get_dependencies, String, bool)
+ GDVIRTUAL2RC(int64_t, _rename_dependencies, String, Dictionary)
+ GDVIRTUAL1RC(bool, _exists, String)
+
+ GDVIRTUAL4RC(Variant, _load, String, String, bool, int)
+
public:
virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
virtual bool exists(const String &p_path) const;
diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp
index 564de5ee69..823b5f75b1 100644
--- a/core/io/resource_saver.cpp
+++ b/core/io/resource_saver.cpp
@@ -42,44 +42,37 @@ ResourceSavedCallback ResourceSaver::save_callback = nullptr;
ResourceSaverGetResourceIDForPath ResourceSaver::save_get_id_for_path = nullptr;
Error ResourceFormatSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
- if (get_script_instance() && get_script_instance()->has_method("_save")) {
- return (Error)get_script_instance()->call("_save", p_path, p_resource, p_flags).operator int64_t();
+ int64_t res;
+ if (GDVIRTUAL_CALL(_save, p_path, p_resource, p_flags, res)) {
+ return (Error)res;
}
return ERR_METHOD_NOT_FOUND;
}
bool ResourceFormatSaver::recognize(const RES &p_resource) const {
- if (get_script_instance() && get_script_instance()->has_method("_recognize")) {
- return get_script_instance()->call("_recognize", p_resource);
+ bool success;
+ if (GDVIRTUAL_CALL(_recognize, p_resource, success)) {
+ return success;
}
return false;
}
void ResourceFormatSaver::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_recognized_extensions")) {
- PackedStringArray exts = get_script_instance()->call("_get_recognized_extensions", p_resource);
-
- {
- const String *r = exts.ptr();
- for (int i = 0; i < exts.size(); ++i) {
- p_extensions->push_back(r[i]);
- }
+ PackedStringArray exts;
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, p_resource, exts)) {
+ const String *r = exts.ptr();
+ for (int i = 0; i < exts.size(); ++i) {
+ p_extensions->push_back(r[i]);
}
}
}
void ResourceFormatSaver::_bind_methods() {
- {
- PropertyInfo arg0 = PropertyInfo(Variant::STRING, "path");
- PropertyInfo arg1 = PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource");
- PropertyInfo arg2 = PropertyInfo(Variant::INT, "flags");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_save", arg0, arg1, arg2));
- }
-
- BIND_VMETHOD(MethodInfo(Variant::PACKED_STRING_ARRAY, "_get_recognized_extensions", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_recognize", PropertyInfo(Variant::OBJECT, "resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource")));
+ GDVIRTUAL_BIND(_save, "path", "resource", "flags");
+ GDVIRTUAL_BIND(_recognize, "resource");
+ GDVIRTUAL_BIND(_get_recognized_extensions, "resource");
}
Error ResourceSaver::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
diff --git a/core/io/resource_saver.h b/core/io/resource_saver.h
index 2fc8d32126..fcde835dab 100644
--- a/core/io/resource_saver.h
+++ b/core/io/resource_saver.h
@@ -32,6 +32,8 @@
#define RESOURCE_SAVER_H
#include "core/io/resource.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
class ResourceFormatSaver : public RefCounted {
GDCLASS(ResourceFormatSaver, RefCounted);
@@ -39,6 +41,10 @@ class ResourceFormatSaver : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL3R(int64_t, _save, String, RES, uint32_t)
+ GDVIRTUAL1RC(bool, _recognize, RES)
+ GDVIRTUAL1RC(Vector<String>, _get_recognized_extensions, RES)
+
public:
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 322eb7ac61..b380860522 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -382,8 +382,9 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
}
real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
Point *from_point;
@@ -398,8 +399,9 @@ real_t AStar::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar::_compute_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
Point *from_point;
@@ -557,8 +559,8 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id")
+ GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
}
AStar::~AStar() {
@@ -654,8 +656,9 @@ Vector2 AStar2D::get_closest_position_in_segment(const Vector2 &p_point) const {
}
real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_estimate_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_estimate_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_estimate_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
AStar::Point *from_point;
@@ -670,8 +673,9 @@ real_t AStar2D::_estimate_cost(int p_from_id, int p_to_id) {
}
real_t AStar2D::_compute_cost(int p_from_id, int p_to_id) {
- if (get_script_instance() && get_script_instance()->has_method(SceneStringNames::get_singleton()->_compute_cost)) {
- return get_script_instance()->call(SceneStringNames::get_singleton()->_compute_cost, p_from_id, p_to_id);
+ real_t scost;
+ if (GDVIRTUAL_CALL(_compute_cost, p_from_id, p_to_id, scost)) {
+ return scost;
}
AStar::Point *from_point;
@@ -875,6 +879,6 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_path", "from_id", "to_id"), &AStar2D::get_point_path);
ClassDB::bind_method(D_METHOD("get_id_path", "from_id", "to_id"), &AStar2D::get_id_path);
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_estimate_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_compute_cost", PropertyInfo(Variant::INT, "from_id"), PropertyInfo(Variant::INT, "to_id")));
+ GDVIRTUAL_BIND(_estimate_cost, "from_id", "to_id")
+ GDVIRTUAL_BIND(_compute_cost, "from_id", "to_id")
}
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 44758cb046..64fa32a325 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -31,7 +31,9 @@
#ifndef A_STAR_H
#define A_STAR_H
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
+#include "core/object/script_language.h"
#include "core/templates/oa_hash_map.h"
/**
@@ -122,6 +124,9 @@ protected:
virtual real_t _estimate_cost(int p_from_id, int p_to_id);
virtual real_t _compute_cost(int p_from_id, int p_to_id);
+ GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
+ GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
+
public:
int get_available_point_id() const;
@@ -169,6 +174,9 @@ protected:
virtual real_t _estimate_cost(int p_from_id, int p_to_id);
virtual real_t _compute_cost(int p_from_id, int p_to_id);
+ GDVIRTUAL2RC(real_t, _estimate_cost, int64_t, int64_t)
+ GDVIRTUAL2RC(real_t, _compute_cost, int64_t, int64_t)
+
public:
int get_available_point_id() const;
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 66c18f7b3c..8066a59281 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -341,8 +341,8 @@ bool CameraMatrix::get_endpoints(const Transform3D &p_transform, Vector3 *p_8poi
Vector<Plane> CameraMatrix::get_projection_planes(const Transform3D &p_transform) const {
/** Fast Plane Extraction from combined modelview/projection matrices.
* References:
- * https://web.archive.org/web/20011221205252/http://www.markmorley.com/opengl/frustumculling.html
- * https://web.archive.org/web/20061020020112/http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
+ * https://web.archive.org/web/20011221205252/https://www.markmorley.com/opengl/frustumculling.html
+ * https://web.archive.org/web/20061020020112/https://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
*/
Vector<Plane> planes;
diff --git a/core/math/convex_hull.h b/core/math/convex_hull.h
index ba7be9c5e8..a860d60b02 100644
--- a/core/math/convex_hull.h
+++ b/core/math/convex_hull.h
@@ -49,7 +49,7 @@ subject to the following restrictions:
#include "core/templates/vector.h"
/// Convex hull implementation based on Preparata and Hong
-/// See http://code.google.com/p/bullet/issues/detail?id=275
+/// See https://code.google.com/p/bullet/issues/detail?id=275
/// Ole Kniemeyer, MAXON Computer GmbH
class ConvexHullComputer {
public:
diff --git a/core/math/dynamic_bvh.h b/core/math/dynamic_bvh.h
index 0b6286cd9d..d63132b4da 100644
--- a/core/math/dynamic_bvh.h
+++ b/core/math/dynamic_bvh.h
@@ -41,7 +41,7 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org
+Copyright (c) 2003-2013 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/core/math/transform_3d.h b/core/math/transform_3d.h
index cadfdc13d1..345e0fade0 100644
--- a/core/math/transform_3d.h
+++ b/core/math/transform_3d.h
@@ -155,7 +155,7 @@ _FORCE_INLINE_ Plane Transform3D::xform_inv(const Plane &p_plane) const {
}
_FORCE_INLINE_ AABB Transform3D::xform(const AABB &p_aabb) const {
- /* http://dev.theomader.com/transform-bounding-boxes/ */
+ /* https://dev.theomader.com/transform-bounding-boxes/ */
Vector3 min = p_aabb.position;
Vector3 max = p_aabb.position + p_aabb.size;
Vector3 tmin, tmax;
diff --git a/core/math/triangulate.h b/core/math/triangulate.h
index 55dc4e8e7d..249ca6238f 100644
--- a/core/math/triangulate.h
+++ b/core/math/triangulate.h
@@ -34,7 +34,7 @@
#include "core/math/vector2.h"
/*
-http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
+https://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
*/
class Triangulate {
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 75145e1b65..b29b2bd421 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -1421,7 +1421,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, const c
return p_bind;
}
-void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual) {
+void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector<String> &p_arg_names, bool p_object_core) {
ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'.");
OBJTYPE_WLOCK;
@@ -1431,6 +1431,19 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
if (p_virtual) {
mi.flags |= METHOD_FLAG_VIRTUAL;
}
+ if (p_object_core) {
+ mi.flags |= METHOD_FLAG_OBJECT_CORE;
+ }
+ if (p_arg_names.size()) {
+ if (p_arg_names.size() != mi.arguments.size()) {
+ WARN_PRINT("Mismatch argument name count for virtual function: " + String(p_class) + "::" + p_method.name);
+ } else {
+ for (int i = 0; i < p_arg_names.size(); i++) {
+ mi.arguments[i].name = p_arg_names[i];
+ }
+ }
+ }
+
classes[p_class].virtual_methods.push_back(mi);
classes[p_class].virtual_methods_map[p_method.name] = mi;
diff --git a/core/object/class_db.h b/core/object/class_db.h
index 8add0285f7..45572517be 100644
--- a/core/object/class_db.h
+++ b/core/object/class_db.h
@@ -372,7 +372,7 @@ public:
static bool get_method_info(const StringName &p_class, const StringName &p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static MethodBind *get_method(const StringName &p_class, const StringName &p_name);
- static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
+ static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true, const Vector<String> &p_arg_names = Vector<String>(), bool p_object_core = false);
static void get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false);
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
@@ -425,17 +425,6 @@ public:
#endif
-#ifdef TOOLS_ENABLED
-
-#define BIND_VMETHOD(m_method) \
- ::ClassDB::add_virtual_method(get_class_static(), m_method);
-
-#else
-
-#define BIND_VMETHOD(m_method)
-
-#endif
-
#define GDREGISTER_CLASS(m_class) \
if (!GD_IS_DEFINED(ClassDB_Disable_##m_class)) { \
::ClassDB::register_class<m_class>(); \
diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py
index 9948620c73..65a421cfb2 100644
--- a/core/object/make_virtuals.py
+++ b/core/object/make_virtuals.py
@@ -1,8 +1,8 @@
proto = """
#define GDVIRTUAL$VER($RET m_name $ARG) \\
StringName _gdvirtual_##m_name##_sn = #m_name;\\
-bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
- GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\
+_FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
if (script_instance) {\\
Callable::CallError ce; \\
@@ -23,6 +23,16 @@ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\
\\
return false;\\
}\\
+_FORCE_INLINE_ bool _gdvirtual_##m_name##_overriden() const { \\
+ ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\
+ if (script_instance) {\\
+ return script_instance->has_method(_gdvirtual_##m_name##_sn);\\
+ }\\
+ if (_gdvirtual_##m_name) {\\
+ return true;\\
+ }\\
+ return false;\\
+}\\
\\
_FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() { \\
MethodInfo method_info;\\
@@ -32,7 +42,6 @@ _FORCE_INLINE_ static MethodInfo _gdvirtual_##m_name##_get_method_info() { \\
return method_info;\\
}
-
"""
@@ -77,7 +86,7 @@ def generate_version(argcount, const=False, returns=False):
callptrargs += "\t\t"
callptrargsptr += ", "
argtext += "m_type" + str(i + 1)
- callargtext += "const m_type" + str(i + 1) + "& arg" + str(i + 1)
+ callargtext += "m_type" + str(i + 1) + " arg" + str(i + 1)
callsiargs += "Variant(arg" + str(i + 1) + ")"
callsiargptrs += "&vargs[" + str(i) + "]"
callptrargs += (
@@ -103,7 +112,7 @@ def generate_version(argcount, const=False, returns=False):
if returns:
if argcount > 0:
callargtext += ","
- callargtext += " m_ret& r_ret"
+ callargtext += " m_ret& r_ret"
s = s.replace("$CALLSIBEGIN", "Variant ret = ")
s = s.replace("$CALLSIRET", "r_ret = ret;")
s = s.replace("$CALLPTRRETPASS", "&ret")
diff --git a/core/object/method_bind.h b/core/object/method_bind.h
index 92b964772a..b0b379873e 100644
--- a/core/object/method_bind.h
+++ b/core/object/method_bind.h
@@ -43,6 +43,7 @@ enum MethodFlags {
METHOD_FLAG_FROM_SCRIPT = 64,
METHOD_FLAG_VARARG = 128,
METHOD_FLAG_STATIC = 256,
+ METHOD_FLAG_OBJECT_CORE = 512,
METHOD_FLAGS_DEFAULT = METHOD_FLAG_NORMAL,
};
diff --git a/core/object/object.cpp b/core/object/object.cpp
index 2bb4b981b9..3335942fb3 100644
--- a/core/object/object.cpp
+++ b/core/object/object.cpp
@@ -1619,22 +1619,25 @@ void Object::_bind_methods() {
ADD_SIGNAL(MethodInfo("script_changed"));
ADD_SIGNAL(MethodInfo("property_list_changed"));
- BIND_VMETHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
+#define BIND_OBJ_CORE_METHOD(m_method) \
+ ::ClassDB::add_virtual_method(get_class_static(), m_method, true, Vector<String>(), true);
+
+ BIND_OBJ_CORE_METHOD(MethodInfo("_notification", PropertyInfo(Variant::INT, "what")));
+ BIND_OBJ_CORE_METHOD(MethodInfo(Variant::BOOL, "_set", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::NIL, "value")));
#ifdef TOOLS_ENABLED
MethodInfo miget("_get", PropertyInfo(Variant::STRING_NAME, "property"));
miget.return_val.name = "Variant";
miget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(miget);
+ BIND_OBJ_CORE_METHOD(miget);
MethodInfo plget("_get_property_list");
plget.return_val.type = Variant::ARRAY;
- BIND_VMETHOD(plget);
+ BIND_OBJ_CORE_METHOD(plget);
#endif
- BIND_VMETHOD(MethodInfo("_init"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_to_string"));
+ BIND_OBJ_CORE_METHOD(MethodInfo("_init"));
+ BIND_OBJ_CORE_METHOD(MethodInfo(Variant::STRING, "_to_string"));
BIND_CONSTANT(NOTIFICATION_POSTINITIALIZE);
BIND_CONSTANT(NOTIFICATION_PREDELETE);
diff --git a/core/object/object.h b/core/object/object.h
index 94531f1cd0..a53143158b 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -97,6 +97,7 @@ enum PropertyHint {
PROPERTY_HINT_SAVE_FILE, ///< a file path must be passed, hint_text (optionally) is a filter "*.png,*.wav,*.doc,". This opens a save dialog
PROPERTY_HINT_INT_IS_OBJECTID,
PROPERTY_HINT_ARRAY_TYPE,
+ PROPERTY_HINT_INT_IS_POINTER,
PROPERTY_HINT_MAX,
// When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit
};
@@ -282,7 +283,14 @@ struct ObjectNativeExtension {
};
#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__)
-#define GDVIRTUAL_BIND(m_name) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info());
+#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__)
+#ifdef DEBUG_METHODS_ENABLED
+#define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__));
+#else
+#define GDVIRTUAL_BIND(m_name, ...)
+#endif
+#define GDVIRTUAL_IS_OVERRIDEN(m_name) _gdvirtual_##m_name##_overriden()
+#define GDVIRTUAL_IS_OVERRIDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overriden()
/*
the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model.
diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h
index e0af2c18bb..f2dd2aa324 100644
--- a/core/object/ref_counted.h
+++ b/core/object/ref_counted.h
@@ -274,8 +274,6 @@ struct PtrToArg<const Ref<T> &> {
}
};
-#ifdef DEBUG_METHODS_ENABLED
-
template <class T>
struct GetTypeInfo<Ref<T>> {
static const Variant::Type VARIANT_TYPE = Variant::OBJECT;
@@ -296,6 +294,4 @@ struct GetTypeInfo<const Ref<T> &> {
}
};
-#endif // DEBUG_METHODS_ENABLED
-
#endif // REF_COUNTED_H
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 3c0e56f5a8..0ba69a8d47 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -33,11 +33,6 @@
#include "core/object/script_language.h"
void MainLoop::_bind_methods() {
- BIND_VMETHOD(MethodInfo("_initialize"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_finalize"));
-
BIND_CONSTANT(NOTIFICATION_OS_MEMORY_WARNING);
BIND_CONSTANT(NOTIFICATION_TRANSLATION_CHANGED);
BIND_CONSTANT(NOTIFICATION_WM_ABOUT);
@@ -50,7 +45,12 @@ void MainLoop::_bind_methods() {
BIND_CONSTANT(NOTIFICATION_TEXT_SERVER_CHANGED);
ADD_SIGNAL(MethodInfo("on_request_permissions_result", PropertyInfo(Variant::STRING, "permission"), PropertyInfo(Variant::BOOL, "granted")));
-};
+
+ GDVIRTUAL_BIND(_initialize);
+ GDVIRTUAL_BIND(_physics_process, "delta");
+ GDVIRTUAL_BIND(_process, "delta");
+ GDVIRTUAL_BIND(_finalize);
+}
void MainLoop::set_initialize_script(const Ref<Script> &p_initialize_script) {
initialize_script = p_initialize_script;
@@ -61,30 +61,31 @@ void MainLoop::initialize() {
set_script(initialize_script);
}
- if (get_script_instance()) {
- get_script_instance()->call("_initialize");
- }
+ GDVIRTUAL_CALL(_initialize);
}
bool MainLoop::physics_process(double p_time) {
- if (get_script_instance()) {
- return get_script_instance()->call("_physics_process", p_time);
+ bool quit;
+ if (GDVIRTUAL_CALL(_physics_process, p_time, quit)) {
+ return quit;
}
return false;
}
bool MainLoop::process(double p_time) {
- if (get_script_instance()) {
- return get_script_instance()->call("_process", p_time);
+ bool quit;
+ if (GDVIRTUAL_CALL(_process, p_time, quit)) {
+ return quit;
}
return false;
}
void MainLoop::finalize() {
+ GDVIRTUAL_CALL(_finalize);
+
if (get_script_instance()) {
- get_script_instance()->call("_finalize");
set_script(Variant()); //clear script
}
}
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index b42e9b18ff..4da01d767e 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -32,6 +32,7 @@
#define MAIN_LOOP_H
#include "core/input/input_event.h"
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
#include "core/object/script_language.h"
@@ -44,6 +45,11 @@ class MainLoop : public Object {
protected:
static void _bind_methods();
+ GDVIRTUAL0(_initialize)
+ GDVIRTUAL1R(bool, _physics_process, double)
+ GDVIRTUAL1R(bool, _process, double)
+ GDVIRTUAL0(_finalize)
+
public:
enum {
//make sure these are replicated in Node
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index e2a097f883..35f4532abb 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -41,6 +41,7 @@
#include "core/extension/native_extension_manager.h"
#include "core/input/input.h"
#include "core/input/input_map.h"
+#include "core/input/shortcut.h"
#include "core/io/config_file.h"
#include "core/io/dtls_server.h"
#include "core/io/http_client.h"
@@ -145,10 +146,12 @@ void register_core_types() {
GDREGISTER_CLASS(Resource);
GDREGISTER_CLASS(Image);
+ GDREGISTER_CLASS(Shortcut);
GDREGISTER_VIRTUAL_CLASS(InputEvent);
GDREGISTER_VIRTUAL_CLASS(InputEventWithModifiers);
GDREGISTER_VIRTUAL_CLASS(InputEventFromWindow);
GDREGISTER_CLASS(InputEventKey);
+ GDREGISTER_CLASS(InputEventShortcut);
GDREGISTER_VIRTUAL_CLASS(InputEventMouse);
GDREGISTER_CLASS(InputEventMouseButton);
GDREGISTER_CLASS(InputEventMouseMotion);
diff --git a/core/templates/map.h b/core/templates/map.h
index a47547d355..badb407e5d 100644
--- a/core/templates/map.h
+++ b/core/templates/map.h
@@ -36,7 +36,7 @@
#include "core/templates/pair.h"
// based on the very nice implementation of rb-trees by:
-// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class K, class V, class C = Comparator<K>, class A = DefaultAllocator>
class Map {
diff --git a/core/templates/rid_owner.h b/core/templates/rid_owner.h
index 8d139551ef..e947d2211c 100644
--- a/core/templates/rid_owner.h
+++ b/core/templates/rid_owner.h
@@ -53,14 +53,16 @@ protected:
return rid;
}
- static uint64_t _gen_id() {
- return base_id.increment();
- }
-
static RID _gen_rid() {
return _make_from_id(_gen_id());
}
+ friend struct VariantUtilityFunctions;
+
+ static uint64_t _gen_id() {
+ return base_id.increment();
+ }
+
public:
virtual ~RID_AllocBase() {}
};
diff --git a/core/templates/set.h b/core/templates/set.h
index 9261d2d3d2..0a80ceefb5 100644
--- a/core/templates/set.h
+++ b/core/templates/set.h
@@ -35,7 +35,7 @@
#include "core/typedefs.h"
// based on the very nice implementation of rb-trees by:
-// https://web.archive.org/web/20120507164830/http://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
+// https://web.archive.org/web/20120507164830/https://web.mit.edu/~emin/www/source_code/red_black_tree/index.html
template <class T, class C = Comparator<T>, class A = DefaultAllocator>
class Set {
diff --git a/core/variant/method_ptrcall.h b/core/variant/method_ptrcall.h
index 8836e257a9..98304621f2 100644
--- a/core/variant/method_ptrcall.h
+++ b/core/variant/method_ptrcall.h
@@ -191,6 +191,7 @@ struct PtrToArg<ObjectID> {
// This is for the special cases used by Variant.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARG(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -236,6 +237,7 @@ struct PtrToArg<ObjectID> {
} \
}
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARG_ALT(m_type, m_type_alt) \
template <> \
struct PtrToArg<Vector<m_type_alt>> { \
@@ -285,6 +287,7 @@ MAKE_VECARG_ALT(String, StringName);
// For stuff that gets converted to Array vectors.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_VECARR(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -325,6 +328,7 @@ MAKE_VECARR(Variant);
MAKE_VECARR(RID);
MAKE_VECARR(Plane);
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_DVECARR(m_type) \
template <> \
struct PtrToArg<Vector<m_type>> { \
@@ -372,6 +376,7 @@ MAKE_VECARR(Plane);
// Special case for IPAddress.
+// No EncodeT because direct pointer conversion not possible.
#define MAKE_STRINGCONV_BY_REFERENCE(m_type) \
template <> \
struct PtrToArg<m_type> { \
@@ -395,6 +400,7 @@ MAKE_VECARR(Plane);
MAKE_STRINGCONV_BY_REFERENCE(IPAddress);
+// No EncodeT because direct pointer conversion not possible.
template <>
struct PtrToArg<Vector<Face3>> {
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
@@ -429,6 +435,7 @@ struct PtrToArg<Vector<Face3>> {
}
};
+// No EncodeT because direct pointer conversion not possible.
template <>
struct PtrToArg<const Vector<Face3> &> {
_FORCE_INLINE_ static Vector<Face3> convert(const void *p_ptr) {
diff --git a/core/variant/native_ptr.h b/core/variant/native_ptr.h
new file mode 100644
index 0000000000..b4ec0df7d6
--- /dev/null
+++ b/core/variant/native_ptr.h
@@ -0,0 +1,130 @@
+/*************************************************************************/
+/* native_ptr.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 NATIVE_PTR_H
+#define NATIVE_PTR_H
+
+#include "core/math/audio_frame.h"
+#include "core/variant/method_ptrcall.h"
+#include "core/variant/type_info.h"
+
+template <class T>
+struct GDNativeConstPtr {
+ const T *data = nullptr;
+ GDNativeConstPtr(const T *p_assign) { data = p_assign; }
+ static const char *get_name() { return "const void"; }
+ operator const T *() const { return data; }
+ operator Variant() const { return uint64_t(data); }
+};
+
+template <class T>
+struct GDNativePtr {
+ T *data = nullptr;
+ GDNativePtr(T *p_assign) { data = p_assign; }
+ static const char *get_name() { return "void"; }
+ operator T *() const { return data; }
+ operator Variant() const { return uint64_t(data); }
+};
+
+#define GDVIRTUAL_NATIVE_PTR(m_type) \
+ template <> \
+ struct GDNativeConstPtr<m_type> { \
+ const m_type *data = nullptr; \
+ GDNativeConstPtr(const m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return "const " #m_type; } \
+ operator const m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ }; \
+ template <> \
+ struct GDNativePtr<m_type> { \
+ m_type *data = nullptr; \
+ GDNativePtr(m_type *p_assign) { data = p_assign; } \
+ static const char *get_name() { return #m_type; } \
+ operator m_type *() const { return data; } \
+ operator Variant() const { return uint64_t(data); } \
+ };
+
+template <class T>
+struct GetTypeInfo<GDNativeConstPtr<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativeConstPtr<T>::get_name());
+ }
+};
+
+template <class T>
+struct GetTypeInfo<GDNativePtr<T>> {
+ static const Variant::Type VARIANT_TYPE = Variant::NIL;
+ static const GodotTypeInfo::Metadata METADATA = GodotTypeInfo::METADATA_NONE;
+ static inline PropertyInfo get_class_info() {
+ return PropertyInfo(Variant::INT, String(), PROPERTY_HINT_INT_IS_POINTER, GDNativePtr<T>::get_name());
+ }
+};
+
+template <class T>
+struct PtrToArg<GDNativeConstPtr<T>> {
+ _FORCE_INLINE_ static GDNativeConstPtr<T> convert(const void *p_ptr) {
+ return GDNativeConstPtr<T>(reinterpret_cast<const T *>(p_ptr));
+ }
+ typedef const T *EncodeT;
+ _FORCE_INLINE_ static void encode(GDNativeConstPtr<T> p_val, void *p_ptr) {
+ *((const T **)p_ptr) = p_val.data;
+ }
+};
+template <class T>
+struct PtrToArg<GDNativePtr<T>> {
+ _FORCE_INLINE_ static GDNativePtr<T> convert(const void *p_ptr) {
+ return GDNativePtr<T>(reinterpret_cast<const T *>(p_ptr));
+ }
+ typedef T *EncodeT;
+ _FORCE_INLINE_ static void encode(GDNativePtr<T> p_val, void *p_ptr) {
+ *((T **)p_ptr) = p_val.data;
+ }
+};
+
+GDVIRTUAL_NATIVE_PTR(AudioFrame)
+GDVIRTUAL_NATIVE_PTR(bool)
+GDVIRTUAL_NATIVE_PTR(char)
+GDVIRTUAL_NATIVE_PTR(char16_t)
+GDVIRTUAL_NATIVE_PTR(char32_t)
+GDVIRTUAL_NATIVE_PTR(wchar_t)
+GDVIRTUAL_NATIVE_PTR(uint8_t)
+GDVIRTUAL_NATIVE_PTR(int8_t)
+GDVIRTUAL_NATIVE_PTR(uint16_t)
+GDVIRTUAL_NATIVE_PTR(int16_t)
+GDVIRTUAL_NATIVE_PTR(uint32_t)
+GDVIRTUAL_NATIVE_PTR(int32_t)
+GDVIRTUAL_NATIVE_PTR(int64_t)
+GDVIRTUAL_NATIVE_PTR(uint64_t)
+GDVIRTUAL_NATIVE_PTR(float)
+GDVIRTUAL_NATIVE_PTR(double)
+
+#endif // NATIVE_PTR_H
diff --git a/core/variant/typed_array.h b/core/variant/typed_array.h
index 900dcf7689..2e96f4e445 100644
--- a/core/variant/typed_array.h
+++ b/core/variant/typed_array.h
@@ -125,7 +125,7 @@ struct PtrToArg<TypedArray<T>> {
_FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
}
-
+ typedef Array EncodeT;
_FORCE_INLINE_ static void encode(TypedArray<T> p_val, void *p_ptr) {
*(Array *)p_ptr = p_val;
}
@@ -133,13 +133,13 @@ struct PtrToArg<TypedArray<T>> {
template <class T>
struct PtrToArg<const TypedArray<T> &> {
- _FORCE_INLINE_ static TypedArray<T> convert(const void *p_ptr) {
+ typedef Array EncodeT;
+ _FORCE_INLINE_ static TypedArray<T>
+ convert(const void *p_ptr) {
return TypedArray<T>(*reinterpret_cast<const Array *>(p_ptr));
}
};
-#ifdef DEBUG_METHODS_ENABLED
-
template <class T>
struct GetTypeInfo<TypedArray<T>> {
static const Variant::Type VARIANT_TYPE = Variant::ARRAY;
@@ -218,6 +218,4 @@ MAKE_TYPED_ARRAY_INFO(Vector<Vector2>, Variant::PACKED_VECTOR2_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Vector3>, Variant::PACKED_VECTOR3_ARRAY)
MAKE_TYPED_ARRAY_INFO(Vector<Color>, Variant::PACKED_COLOR_ARRAY)
-#endif
-
#endif // TYPED_ARRAY_H
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index c3481d4896..a4817eb7d2 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1422,6 +1422,7 @@ static void _register_variant_builtin_methods() {
bind_method(String, is_absolute_path, sarray(), varray());
bind_method(String, is_rel_path, sarray(), varray());
+ bind_method(String, simplify_path, sarray(), varray());
bind_method(String, get_base_dir, sarray(), varray());
bind_method(String, get_file, sarray(), varray());
bind_method(String, xml_escape, sarray("escape_quotes"), varray(false));
diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp
index 6c57d1de10..f5cb2d40d6 100644
--- a/core/variant/variant_utility.cpp
+++ b/core/variant/variant_utility.cpp
@@ -35,6 +35,8 @@
#include "core/object/ref_counted.h"
#include "core/os/os.h"
#include "core/templates/oa_hash_map.h"
+#include "core/templates/rid.h"
+#include "core/templates/rid_owner.h"
#include "core/variant/binder_common.h"
#include "core/variant/variant_parser.h"
@@ -728,6 +730,13 @@ struct VariantUtilityFunctions {
}
return p_instance.get_validated_object() != nullptr;
}
+
+ static inline uint64_t rid_allocate_id() {
+ return RID_AllocBase::_gen_id();
+ }
+ static inline RID rid_from_int64(uint64_t p_base) {
+ return RID::from_uint64(p_base);
+ }
};
#ifdef DEBUG_METHODS_ENABLED
@@ -1265,6 +1274,9 @@ void Variant::_register_variant_utility_functions() {
FUNCBINDR(instance_from_id, sarray("instance_id"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(is_instance_id_valid, sarray("id"), Variant::UTILITY_FUNC_TYPE_GENERAL);
FUNCBINDR(is_instance_valid, sarray("instance"), Variant::UTILITY_FUNC_TYPE_GENERAL);
+
+ FUNCBINDR(rid_allocate_id, Vector<String>(), Variant::UTILITY_FUNC_TYPE_GENERAL);
+ FUNCBINDR(rid_from_int64, sarray("base"), Variant::UTILITY_FUNC_TYPE_GENERAL);
}
void Variant::_unregister_variant_utility_functions() {
diff --git a/doc/Doxyfile b/doc/Doxyfile
index a7aa204741..26d86cb127 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -20,7 +20,7 @@
# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all text
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
-# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# built into libc) for the transcoding. See https://www.gnu.org/software/libiconv
# for the list of possible encodings.
# The default value is: UTF-8.
@@ -295,7 +295,7 @@ EXTENSION_MAPPING =
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
-# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# documentation. See https://daringfireball.net/projects/markdown/ for details.
# The output of markdown processing is further processed by doxygen, so you can
# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
# case of backward compatibilities issues.
@@ -692,7 +692,7 @@ LAYOUT_FILE =
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
# the reference definitions. This must be a list of .bib files. The .bib
# extension is automatically appended if omitted. This requires the bibtex tool
-# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info.
# For LaTeX the style of the bibliography can be controlled using
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
# search path. See also \cite for info how to create references.
@@ -773,7 +773,7 @@ INPUT = ../core/ ../main/ ../scene/
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
-# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# documentation (see: https://www.gnu.org/software/libiconv) for the list of
# possible encodings.
# The default value is: UTF-8.
@@ -1006,7 +1006,7 @@ SOURCE_TOOLTIPS = YES
# If the USE_HTAGS tag is set to YES then the references to source code will
# point to the HTML generated by the htags(1) tool instead of doxygen built-in
# source browser. The htags tool is part of GNU's global source tagging system
-# (see http://www.gnu.org/software/global/global.html). You will need version
+# (see https://www.gnu.org/software/global/global.html). You will need version
# 4.8.6 or higher.
#
# To use it do the following:
@@ -1034,7 +1034,7 @@ USE_HTAGS = NO
VERBATIM_HEADERS = YES
# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the
-# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# clang parser (see: https://clang.llvm.org/) for more accurate parsing at the
# cost of reduced performance. This can be particularly helpful with template
# rich C++ code for which doxygen's built-in parser lacks the necessary type
# information.
@@ -1170,7 +1170,7 @@ HTML_EXTRA_FILES =
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a colorwheel, see
-# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# https://en.wikipedia.org/wiki/Hue for more information. For instance the value
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
# purple, and 360 is red again.
# Minimum value: 0, maximum value: 359, default value: 220.
@@ -1349,7 +1349,7 @@ QCH_FILE =
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
# Project output. For more information please see Qt Help Project / Namespace
-# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# (see: https://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
# The default value is: org.doxygen.Project.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1357,7 +1357,7 @@ QHP_NAMESPACE = org.doxygen.Project
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
# Help Project output. For more information please see Qt Help Project / Virtual
-# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# Folders (see: https://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
# folders).
# The default value is: doc.
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1366,7 +1366,7 @@ QHP_VIRTUAL_FOLDER = doc
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
# filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: https://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1374,7 +1374,7 @@ QHP_CUST_FILTER_NAME =
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
# custom filter to add. For more information please see Qt Help Project / Custom
-# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# Filters (see: https://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
# filters).
# This tag requires that the tag GENERATE_QHP is set to YES.
@@ -1382,7 +1382,7 @@ QHP_CUST_FILTER_ATTRS =
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
# project's filter section matches. Qt Help Project / Filter Attributes (see:
-# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# https://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
# This tag requires that the tag GENERATE_QHP is set to YES.
QHP_SECT_FILTER_ATTRS =
@@ -1487,7 +1487,7 @@ FORMULA_FONTSIZE = 10
FORMULA_TRANSPARENT = YES
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
-# http://www.mathjax.org) which uses client side Javascript for the rendering
+# https://www.mathjax.org) which uses client side Javascript for the rendering
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
# installed or if you want to formulas look prettier in the HTML output. When
# enabled you may also need to install MathJax separately and configure the path
@@ -1514,7 +1514,7 @@ MATHJAX_FORMAT = HTML-CSS
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
# Content Delivery Network so you can quickly see the result without installing
# MathJax. However, it is strongly recommended to install a local copy of
-# MathJax from http://www.mathjax.org before deployment.
+# MathJax from https://www.mathjax.org before deployment.
# The default value is: http://cdn.mathjax.org/mathjax/latest.
# This tag requires that the tag USE_MATHJAX is set to YES.
@@ -1576,7 +1576,7 @@ SERVER_BASED_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/).
+# Xapian (see: https://xapian.org/).
#
# See the section "External Indexing and Searching" for details.
# The default value is: NO.
@@ -1589,7 +1589,7 @@ EXTERNAL_SEARCH = NO
#
# Doxygen ships with an example indexer (doxyindexer) and search engine
# (doxysearch.cgi) which are based on the open source search engine library
-# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Xapian (see: https://xapian.org/). See the section "External Indexing and
# Searching" for details.
# This tag requires that the tag SEARCHENGINE is set to YES.
@@ -1773,7 +1773,7 @@ LATEX_SOURCE_CODE = NO
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
# bibliography, e.g. plainnat, or ieeetr. See
-# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# https://en.wikipedia.org/wiki/BibTeX and \cite for more info.
# The default value is: plain.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -2138,7 +2138,7 @@ CLASS_DIAGRAMS = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. Doxygen will then run the mscgen tool (see:
-# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# https://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
# documentation. The MSCGEN_PATH tag allows you to specify the directory where
# the mscgen tool resides. If left empty the tool is assumed to be found in the
# default search path.
@@ -2160,7 +2160,7 @@ HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
-# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: NO.
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index d4680d1836..585b94a522 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -711,6 +711,19 @@
<description>
</description>
</method>
+ <method name="rid_allocate_id">
+ <return type="int" />
+ <description>
+ Allocate a unique ID which can be used by the implementation to construct a RID. This is used mainly from native extensions to implement servers.
+ </description>
+ </method>
+ <method name="rid_from_int64">
+ <return type="RID" />
+ <argument index="0" name="base" type="int" />
+ <description>
+ Create a RID from an int64. This is used mainly from native extensions to build servers.
+ </description>
+ </method>
<method name="round">
<return type="float" />
<argument index="0" name="x" type="float" />
@@ -1072,8 +1085,8 @@
<member name="TranslationServer" type="TranslationServer" setter="" getter="">
The [TranslationServer] singleton.
</member>
- <member name="VisualScriptEditor" type="VisualScriptEditor" setter="" getter="">
- The [VisualScriptEditor] singleton.
+ <member name="VisualScriptEditor" type="VisualScriptCustomNodes" setter="" getter="">
+ The [VisualScriptCustomNodes] singleton.
</member>
<member name="XRServer" type="XRServer" setter="" getter="">
The [XRServer] singleton.
@@ -2351,9 +2364,11 @@
</constant>
<constant name="PROPERTY_HINT_INT_IS_OBJECTID" value="38" enum="PropertyHint">
</constant>
+ <constant name="PROPERTY_HINT_INT_IS_POINTER" value="40" enum="PropertyHint">
+ </constant>
<constant name="PROPERTY_HINT_ARRAY_TYPE" value="39" enum="PropertyHint">
</constant>
- <constant name="PROPERTY_HINT_MAX" value="40" enum="PropertyHint">
+ <constant name="PROPERTY_HINT_MAX" value="41" enum="PropertyHint">
</constant>
<constant name="PROPERTY_USAGE_NONE" value="0" enum="PropertyUsageFlags">
</constant>
@@ -2458,6 +2473,8 @@
</constant>
<constant name="METHOD_FLAG_STATIC" value="256" enum="MethodFlags">
</constant>
+ <constant name="METHOD_FLAG_OBJECT_CORE" value="512" enum="MethodFlags">
+ </constant>
<constant name="METHOD_FLAGS_DEFAULT" value="1" enum="MethodFlags">
Default method flags.
</constant>
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index 63dd250dbc..3e91184a65 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -38,7 +38,7 @@
<tutorials>
</tutorials>
<methods>
- <method name="_compute_cost" qualifiers="virtual">
+ <method name="_compute_cost" qualifiers="virtual const">
<return type="float" />
<argument index="0" name="from_id" type="int" />
<argument index="1" name="to_id" type="int" />
@@ -47,7 +47,7 @@
Note that this function is hidden in the default [code]AStar[/code] class.
</description>
</method>
- <method name="_estimate_cost" qualifiers="virtual">
+ <method name="_estimate_cost" qualifiers="virtual const">
<return type="float" />
<argument index="0" name="from_id" type="int" />
<argument index="1" name="to_id" type="int" />
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 31d695b051..453e8b6315 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -9,7 +9,7 @@
<tutorials>
</tutorials>
<methods>
- <method name="_compute_cost" qualifiers="virtual">
+ <method name="_compute_cost" qualifiers="virtual const">
<return type="float" />
<argument index="0" name="from_id" type="int" />
<argument index="1" name="to_id" type="int" />
@@ -18,7 +18,7 @@
Note that this function is hidden in the default [code]AStar2D[/code] class.
</description>
</method>
- <method name="_estimate_cost" qualifiers="virtual">
+ <method name="_estimate_cost" qualifiers="virtual const">
<return type="float" />
<argument index="0" name="from_id" type="int" />
<argument index="1" name="to_id" type="int" />
diff --git a/doc/classes/AnimationNode.xml b/doc/classes/AnimationNode.xml
index a9a08efcf1..173ff43d2a 100644
--- a/doc/classes/AnimationNode.xml
+++ b/doc/classes/AnimationNode.xml
@@ -11,46 +11,46 @@
<link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>
</tutorials>
<methods>
- <method name="_get_caption" qualifiers="virtual">
+ <method name="_get_caption" qualifiers="virtual const">
<return type="String" />
<description>
Gets the text caption for this node (used by some editors).
</description>
</method>
- <method name="_get_child_by_name" qualifiers="virtual">
- <return type="Object" />
- <argument index="0" name="name" type="String" />
+ <method name="_get_child_by_name" qualifiers="virtual const">
+ <return type="AnimationNode" />
+ <argument index="0" name="name" type="StringName" />
<description>
Gets a child node by index (used by editors inheriting from [AnimationRootNode]).
</description>
</method>
- <method name="_get_child_nodes" qualifiers="virtual">
+ <method name="_get_child_nodes" qualifiers="virtual const">
<return type="Dictionary" />
<description>
Gets all children nodes in order as a [code]name: node[/code] dictionary. Only useful when inheriting [AnimationRootNode].
</description>
</method>
- <method name="_get_parameter_default_value" qualifiers="virtual">
+ <method name="_get_parameter_default_value" qualifiers="virtual const">
<return type="Variant" />
- <argument index="0" name="name" type="StringName" />
+ <argument index="0" name="parameter" type="StringName" />
<description>
Gets the default value of a parameter. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees.
</description>
</method>
- <method name="_get_parameter_list" qualifiers="virtual">
+ <method name="_get_parameter_list" qualifiers="virtual const">
<return type="Array" />
<description>
Gets the property information for parameter. Parameters are custom local memory used for your nodes, given a resource can be reused in multiple trees. Format is similar to [method Object.get_property_list].
</description>
</method>
- <method name="_has_filter" qualifiers="virtual">
+ <method name="_has_filter" qualifiers="virtual const">
<return type="bool" />
<description>
Returns [code]true[/code] whether you want the blend tree editor to display filter editing on this node.
</description>
</method>
- <method name="_process" qualifiers="virtual">
- <return type="void" />
+ <method name="_process" qualifiers="virtual const">
+ <return type="float" />
<argument index="0" name="time" type="float" />
<argument index="1" name="seek" type="bool" />
<description>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index 2180196bb5..e91cfd79a1 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -92,6 +92,15 @@
<member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" enum="Area3D.SpaceOverride" default="0">
Override mode for gravity and damping calculations within this area. See [enum SpaceOverride] for possible values.
</member>
+ <member name="wind_attenuation_factor" type="float" setter="set_wind_attenuation_factor" getter="get_wind_attenuation_factor" default="0.0">
+ The exponential rate at which wind force decreases with distance from its origin.
+ </member>
+ <member name="wind_force_magnitude" type="float" setter="set_wind_force_magnitude" getter="get_wind_force_magnitude" default="0.0">
+ The magnitude of area-specific wind force.
+ </member>
+ <member name="wind_source_path" type="NodePath" setter="set_wind_source_path" getter="get_wind_source_path" default="NodePath(&quot;&quot;)">
+ The [Node3D] which is used to specify the the direction and origin of an area-specific wind force. The direction is opposite to the z-axis of the [Node3D]'s local transform, and its origin is the origin of the [Node3D]'s local transform.
+ </member>
</members>
<signals>
<signal name="area_entered">
diff --git a/doc/classes/ArrayMesh.xml b/doc/classes/ArrayMesh.xml
index 637b9a9f16..670a25ab83 100644
--- a/doc/classes/ArrayMesh.xml
+++ b/doc/classes/ArrayMesh.xml
@@ -115,6 +115,7 @@
<argument index="0" name="index" type="int" />
<argument index="1" name="name" type="StringName" />
<description>
+ Sets the name of the blend shape at this index.
</description>
</method>
<method name="surface_find_by_name" qualifiers="const">
diff --git a/doc/classes/AudioStream.xml b/doc/classes/AudioStream.xml
index 8a58b178d8..a954a06117 100644
--- a/doc/classes/AudioStream.xml
+++ b/doc/classes/AudioStream.xml
@@ -13,6 +13,21 @@
<link title="Audio Spectrum Demo">https://godotengine.org/asset-library/asset/528</link>
</tutorials>
<methods>
+ <method name="_get_length" qualifiers="virtual const">
+ <return type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="_get_stream_name" qualifiers="virtual const">
+ <return type="String" />
+ <description>
+ </description>
+ </method>
+ <method name="_instance_playback" qualifiers="virtual const">
+ <return type="AudioStreamPlayback" />
+ <description>
+ </description>
+ </method>
<method name="get_length" qualifiers="const">
<return type="float" />
<description>
diff --git a/doc/classes/AudioStreamPlayback.xml b/doc/classes/AudioStreamPlayback.xml
index cb01aa75e8..09d063ed3b 100644
--- a/doc/classes/AudioStreamPlayback.xml
+++ b/doc/classes/AudioStreamPlayback.xml
@@ -10,6 +10,46 @@
<link title="Audio Generator Demo">https://godotengine.org/asset-library/asset/526</link>
</tutorials>
<methods>
+ <method name="_get_loop_count" qualifiers="virtual const">
+ <return type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="_get_playback_position" qualifiers="virtual const">
+ <return type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="_is_playing" qualifiers="virtual const">
+ <return type="bool" />
+ <description>
+ </description>
+ </method>
+ <method name="_mix" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="buffer" type="AudioFrame*" />
+ <argument index="1" name="rate_scale" type="float" />
+ <argument index="2" name="frames" type="int" />
+ <description>
+ </description>
+ </method>
+ <method name="_seek" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="position" type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="_start" qualifiers="virtual">
+ <return type="void" />
+ <argument index="0" name="from_pos" type="float" />
+ <description>
+ </description>
+ </method>
+ <method name="_stop" qualifiers="virtual">
+ <return type="void" />
+ <description>
+ </description>
+ </method>
</methods>
<constants>
</constants>
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index bbf7c5eb6d..a5516636aa 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -683,7 +683,7 @@
</constant>
<constant name="BILLBOARD_PARTICLES" value="3" enum="BillboardMode">
Used for particle systems when assigned to [GPUParticles3D] and [CPUParticles3D] nodes. Enables [code]particles_anim_*[/code] properties.
- The [member ParticlesMaterial.anim_speed] or [member CPUParticles3D.anim_speed] should also be set to a positive value for the animation to play.
+ The [member ParticlesMaterial.anim_speed_min] or [member CPUParticles3D.anim_speed_min] should also be set to a value bigger than zero for the animation to play.
</constant>
<constant name="TEXTURE_CHANNEL_RED" value="0" enum="TextureChannel">
Used to read from the red channel of a texture.
diff --git a/doc/classes/CPUParticles2D.xml b/doc/classes/CPUParticles2D.xml
index ab6897ca1d..9226140c1a 100644
--- a/doc/classes/CPUParticles2D.xml
+++ b/doc/classes/CPUParticles2D.xml
@@ -18,25 +18,23 @@
Sets this node's properties to match a given [GPUParticles2D] node with an assigned [ParticlesMaterial].
</description>
</method>
- <method name="get_param" qualifiers="const">
- <return type="float" />
+ <method name="get_param_curve" qualifiers="const">
+ <return type="Curve" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
<description>
- Returns the base value of the parameter specified by [enum Parameter].
+ Returns the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="get_param_curve" qualifiers="const">
- <return type="Curve" />
+ <method name="get_param_max" qualifiers="const">
+ <return type="float" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
<description>
- Returns the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="get_param_randomness" qualifiers="const">
+ <method name="get_param_min" qualifiers="const">
<return type="float" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
<description>
- Returns the randomness factor of the parameter specified by [enum Parameter].
</description>
</method>
<method name="get_particle_flag" qualifiers="const">
@@ -52,28 +50,26 @@
Restarts the particle emitter.
</description>
</method>
- <method name="set_param">
+ <method name="set_param_curve">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
- <argument index="1" name="value" type="float" />
+ <argument index="1" name="curve" type="Curve" />
<description>
- Sets the base value of the parameter specified by [enum Parameter].
+ Sets the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="set_param_curve">
+ <method name="set_param_max">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
- <argument index="1" name="curve" type="Curve" />
+ <argument index="1" name="value" type="float" />
<description>
- Sets the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="set_param_randomness">
+ <method name="set_param_min">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles2D.Parameter" />
- <argument index="1" name="randomness" type="float" />
+ <argument index="1" name="value" type="float" />
<description>
- Sets the randomness factor of the parameter specified by [enum Parameter].
</description>
</method>
<method name="set_particle_flag">
@@ -89,41 +85,33 @@
<member name="amount" type="int" setter="set_amount" getter="get_amount" default="8">
Number of particles emitted in one emission cycle.
</member>
- <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial rotation applied to each particle, in degrees.
- </member>
<member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's rotation will be animated along this [Curve].
</member>
- <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Rotation randomness ratio.
+ <member name="angle_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
</member>
- <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial angular velocity applied to each particle. Sets the speed of rotation of the particle.
+ <member name="angle_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's angular velocity will vary along this [Curve].
</member>
- <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Angular velocity randomness ratio.
+ <member name="angular_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
</member>
- <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation offset.
+ <member name="angular_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's animation offset will vary along this [Curve].
</member>
- <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation offset randomness ratio.
+ <member name="anim_offset_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
</member>
- <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation speed.
+ <member name="anim_offset_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's animation speed will vary along this [Curve].
</member>
- <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation speed randomness ratio.
+ <member name="anim_speed_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="anim_speed_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
Each particle's initial color. If [member texture] is defined, it will be multiplied by this color.
@@ -131,14 +119,12 @@
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
Each particle's color will vary along this [Gradient] (multiplied with [member color]).
</member>
- <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0">
- The rate at which particles lose velocity.
- </member>
<member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Damping will vary along this [Curve].
</member>
- <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Damping randomness ratio.
+ <member name="damping_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="damping_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="direction" type="Vector2" setter="set_direction" getter="get_direction" default="Vector2(1, 0)">
Unit vector specifying the particles' emission direction.
@@ -179,20 +165,16 @@
<member name="gravity" type="Vector2" setter="set_gravity" getter="get_gravity" default="Vector2(0, 980)">
Gravity applied to every particle.
</member>
- <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial hue variation applied to each particle.
- </member>
<member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's hue will vary along this [Curve].
</member>
- <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Hue variation randomness ratio.
+ <member name="hue_variation_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="hue_variation_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
- <member name="initial_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial velocity magnitude for each particle. Direction comes from [member spread] and the node's orientation.
+ <member name="initial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
</member>
- <member name="initial_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Initial velocity randomness ratio.
+ <member name="initial_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0">
Amount of time each particle will exist.
@@ -200,14 +182,12 @@
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
Particle lifetime randomness ratio.
</member>
- <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Linear acceleration applied to each particle in the direction of motion.
- </member>
<member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's linear acceleration will vary along this [Curve].
</member>
- <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Linear acceleration randomness ratio.
+ <member name="linear_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true">
If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates.
@@ -215,14 +195,12 @@
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false">
If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end.
</member>
- <member name="orbit_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second.
- </member>
<member name="orbit_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's orbital velocity will vary along this [Curve].
</member>
- <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Orbital velocity randomness ratio.
+ <member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Align Y axis of particle with the direction of its velocity.
@@ -230,41 +208,41 @@
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0">
Particle system starts as if it had already run for this many seconds.
</member>
- <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Radial acceleration applied to each particle. Makes particle accelerate away from origin.
- </member>
<member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's radial acceleration will vary along this [Curve].
</member>
- <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Radial acceleration randomness ratio.
+ <member name="radial_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="radial_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" default="0.0">
Emission lifetime randomness ratio.
</member>
- <member name="scale_amount" type="float" setter="set_param" getter="get_param" default="1.0">
- Initial scale applied to each particle.
- </member>
<member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's scale will vary along this [Curve].
</member>
- <member name="scale_amount_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Scale randomness ratio.
+ <member name="scale_amount_max" type="float" setter="set_param_max" getter="get_param_max" default="1.0">
+ </member>
+ <member name="scale_amount_min" type="float" setter="set_param_min" getter="get_param_min" default="1.0">
+ </member>
+ <member name="scale_curve_x" type="Curve" setter="set_scale_curve_x" getter="get_scale_curve_x">
+ </member>
+ <member name="scale_curve_y" type="Curve" setter="set_scale_curve_y" getter="get_scale_curve_y">
</member>
<member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0">
Particle system's running speed scaling ratio. A value of [code]0[/code] can be used to pause the particles.
</member>
+ <member name="split_scale" type="bool" setter="set_split_scale" getter="get_split_scale" default="false">
+ </member>
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees.
</member>
- <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion.
- </member>
<member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's tangential acceleration will vary along this [Curve].
</member>
- <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Tangential acceleration randomness ratio.
+ <member name="tangential_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="tangential_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
Particle texture. If [code]null[/code], particles will be squares.
@@ -278,40 +256,40 @@
Particles are drawn in order of remaining lifetime.
</constant>
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set initial velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set initial velocity properties.
</constant>
<constant name="PARAM_ANGULAR_VELOCITY" value="1" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angular velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set angular velocity properties.
</constant>
<constant name="PARAM_ORBIT_VELOCITY" value="2" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set orbital velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set orbital velocity properties.
</constant>
<constant name="PARAM_LINEAR_ACCEL" value="3" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set linear acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set linear acceleration properties.
</constant>
<constant name="PARAM_RADIAL_ACCEL" value="4" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set radial acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set radial acceleration properties.
</constant>
<constant name="PARAM_TANGENTIAL_ACCEL" value="5" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set tangential acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set tangential acceleration properties.
</constant>
<constant name="PARAM_DAMPING" value="6" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set damping properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set damping properties.
</constant>
<constant name="PARAM_ANGLE" value="7" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angle properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set angle properties.
</constant>
<constant name="PARAM_SCALE" value="8" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set scale properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set scale properties.
</constant>
<constant name="PARAM_HUE_VARIATION" value="9" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set hue variation properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set hue variation properties.
</constant>
<constant name="PARAM_ANIM_SPEED" value="10" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation speed properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set animation speed properties.
</constant>
<constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation offset properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set animation offset properties.
</constant>
<constant name="PARAM_MAX" value="12" enum="Parameter">
Represents the size of the [enum Parameter] enum.
diff --git a/doc/classes/CPUParticles3D.xml b/doc/classes/CPUParticles3D.xml
index 8aa3573996..fe8c354427 100644
--- a/doc/classes/CPUParticles3D.xml
+++ b/doc/classes/CPUParticles3D.xml
@@ -17,25 +17,23 @@
Sets this node's properties to match a given [GPUParticles3D] node with an assigned [ParticlesMaterial].
</description>
</method>
- <method name="get_param" qualifiers="const">
- <return type="float" />
+ <method name="get_param_curve" qualifiers="const">
+ <return type="Curve" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
<description>
- Returns the base value of the parameter specified by [enum Parameter].
+ Returns the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="get_param_curve" qualifiers="const">
- <return type="Curve" />
+ <method name="get_param_max" qualifiers="const">
+ <return type="float" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
<description>
- Returns the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="get_param_randomness" qualifiers="const">
+ <method name="get_param_min" qualifiers="const">
<return type="float" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
<description>
- Returns the randomness factor of the parameter specified by [enum Parameter].
</description>
</method>
<method name="get_particle_flag" qualifiers="const">
@@ -51,28 +49,28 @@
Restarts the particle emitter.
</description>
</method>
- <method name="set_param">
+ <method name="set_param_curve">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
- <argument index="1" name="value" type="float" />
+ <argument index="1" name="curve" type="Curve" />
<description>
- Sets the base value of the parameter specified by [enum Parameter].
+ Sets the [Curve] of the parameter specified by [enum Parameter].
</description>
</method>
- <method name="set_param_curve">
+ <method name="set_param_max">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
- <argument index="1" name="curve" type="Curve" />
+ <argument index="1" name="value" type="float" />
<description>
- Sets the [Curve] of the parameter specified by [enum Parameter].
+ Sets the maximum value for the given parameter
</description>
</method>
- <method name="set_param_randomness">
+ <method name="set_param_min">
<return type="void" />
<argument index="0" name="param" type="int" enum="CPUParticles3D.Parameter" />
- <argument index="1" name="randomness" type="float" />
+ <argument index="1" name="value" type="float" />
<description>
- Sets the randomness factor of the parameter specified by [enum Parameter].
+ Sets the minimum value for the given parameter
</description>
</method>
<method name="set_particle_flag">
@@ -88,41 +86,41 @@
<member name="amount" type="int" setter="set_amount" getter="get_amount" default="8">
Number of particles emitted in one emission cycle.
</member>
- <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial rotation applied to each particle, in degrees.
- </member>
<member name="angle_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's rotation will be animated along this [Curve].
</member>
- <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Rotation randomness ratio.
+ <member name="angle_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum angle.
</member>
- <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial angular velocity applied to each particle. Sets the speed of rotation of the particle.
+ <member name="angle_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum angle.
</member>
<member name="angular_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's angular velocity will vary along this [Curve].
</member>
- <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Angular velocity randomness ratio.
+ <member name="angular_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum angular velocity.
</member>
- <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation offset.
+ <member name="angular_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum angular velocity.
</member>
<member name="anim_offset_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's animation offset will vary along this [Curve].
</member>
- <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation offset randomness ratio.
+ <member name="anim_offset_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum animation offset.
</member>
- <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation speed.
+ <member name="anim_offset_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum animation offset.
</member>
<member name="anim_speed_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's animation speed will vary along this [Curve].
</member>
- <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation speed randomness ratio.
+ <member name="anim_speed_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum particle animation speed.
+ </member>
+ <member name="anim_speed_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum particle animation speed.
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
Each particle's initial color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code].
@@ -130,14 +128,14 @@
<member name="color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp">
Each particle's color will vary along this [GradientTexture] over its lifetime (multiplied with [member color]).
</member>
- <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0">
- The rate at which particles lose velocity.
- </member>
<member name="damping_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Damping will vary along this [Curve].
</member>
- <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Damping randomness ratio.
+ <member name="damping_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum damping.
+ </member>
+ <member name="damping_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum damping
</member>
<member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3(1, 0, 0)">
Unit vector specifying the particles' emission direction.
@@ -193,20 +191,20 @@
<member name="gravity" type="Vector3" setter="set_gravity" getter="get_gravity" default="Vector3(0, -9.8, 0)">
Gravity applied to every particle.
</member>
- <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial hue variation applied to each particle.
- </member>
<member name="hue_variation_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's hue will vary along this [Curve].
</member>
- <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Hue variation randomness ratio.
+ <member name="hue_variation_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum hue variation.
</member>
- <member name="initial_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial velocity magnitude for each particle. Direction comes from [member spread] and the node's orientation.
+ <member name="hue_variation_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum hue variation.
</member>
- <member name="initial_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Initial velocity randomness ratio.
+ <member name="initial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum value of the initial velocity.
+ </member>
+ <member name="initial_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum value of the initial velocity.
</member>
<member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" default="1.0">
Amount of time each particle will exist.
@@ -214,14 +212,14 @@
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
Particle lifetime randomness ratio.
</member>
- <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Linear acceleration applied to each particle in the direction of motion.
- </member>
<member name="linear_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's linear acceleration will vary along this [Curve].
</member>
- <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Linear acceleration randomness ratio.
+ <member name="linear_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum linear acceleration.
+ </member>
+ <member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum linear acceleration.
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" default="true">
If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates.
@@ -232,15 +230,14 @@
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" default="false">
If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end.
</member>
- <member name="orbit_velocity" type="float" setter="set_param" getter="get_param">
- Orbital velocity applied to each particle. Makes the particles circle around origin in the local XY plane. Specified in number of full rotations around origin per second.
- This property is only available when [member particle_flag_disable_z] is [code]true[/code].
- </member>
<member name="orbit_velocity_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's orbital velocity will vary along this [Curve].
</member>
- <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness">
- Orbital velocity randomness ratio.
+ <member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max">
+ Maximum orbit velocity.
+ </member>
+ <member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min">
+ Minimum orbit velocity.
</member>
<member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Align Y axis of particle with the direction of its velocity.
@@ -249,46 +246,58 @@
If [code]true[/code], particles will not move on the Z axis.
</member>
<member name="particle_flag_rotate_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
- If [code]true[/code], particles rotate around Y axis by [member angle].
+ If [code]true[/code], particles rotate around Y axis by [member angle_min].
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" default="0.0">
Particle system starts as if it had already run for this many seconds.
</member>
- <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Radial acceleration applied to each particle. Makes particle accelerate away from origin.
- </member>
<member name="radial_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's radial acceleration will vary along this [Curve].
</member>
- <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Radial acceleration randomness ratio.
+ <member name="radial_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum radial acceleration.
+ </member>
+ <member name="radial_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum radial acceleration.
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" default="0.0">
Emission lifetime randomness ratio.
</member>
- <member name="scale_amount" type="float" setter="set_param" getter="get_param" default="1.0">
- Initial scale applied to each particle.
- </member>
<member name="scale_amount_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's scale will vary along this [Curve].
</member>
- <member name="scale_amount_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Scale randomness ratio.
+ <member name="scale_amount_max" type="float" setter="set_param_max" getter="get_param_max" default="1.0">
+ Maximum scale.
+ </member>
+ <member name="scale_amount_min" type="float" setter="set_param_min" getter="get_param_min" default="1.0">
+ Minimum scale.
+ </member>
+ <member name="scale_curve_x" type="Curve" setter="set_scale_curve_x" getter="get_scale_curve_x">
+ Curve for the scale over life, along the x axis.
+ </member>
+ <member name="scale_curve_y" type="Curve" setter="set_scale_curve_y" getter="get_scale_curve_y">
+ Curve for the scale over life, along the y axis.
+ </member>
+ <member name="scale_curve_z" type="Curve" setter="set_scale_curve_z" getter="get_scale_curve_z">
+ Curve for the scale over life, along the z axis.
</member>
<member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" default="1.0">
Particle system's running speed scaling ratio. A value of [code]0[/code] can be used to pause the particles.
</member>
+ <member name="split_scale" type="bool" setter="set_split_scale" getter="get_split_scale" default="false">
+ If set to true, three different scale curves can be specified, one per scale axis.
+ </member>
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees. Applied to X/Z plane and Y/Z planes.
</member>
- <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion.
- </member>
<member name="tangential_accel_curve" type="Curve" setter="set_param_curve" getter="get_param_curve">
Each particle's tangential acceleration will vary along this [Curve].
</member>
- <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Tangential acceleration randomness ratio.
+ <member name="tangential_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum tangent acceleration.
+ </member>
+ <member name="tangential_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum tangent acceleration.
</member>
</members>
<constants>
@@ -302,40 +311,40 @@
Particles are drawn in order of depth.
</constant>
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set initial velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set initial velocity properties.
</constant>
<constant name="PARAM_ANGULAR_VELOCITY" value="1" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angular velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set angular velocity properties.
</constant>
<constant name="PARAM_ORBIT_VELOCITY" value="2" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set orbital velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set orbital velocity properties.
</constant>
<constant name="PARAM_LINEAR_ACCEL" value="3" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set linear acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set linear acceleration properties.
</constant>
<constant name="PARAM_RADIAL_ACCEL" value="4" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set radial acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set radial acceleration properties.
</constant>
<constant name="PARAM_TANGENTIAL_ACCEL" value="5" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set tangential acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set tangential acceleration properties.
</constant>
<constant name="PARAM_DAMPING" value="6" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set damping properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set damping properties.
</constant>
<constant name="PARAM_ANGLE" value="7" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set angle properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set angle properties.
</constant>
<constant name="PARAM_SCALE" value="8" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set scale properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set scale properties.
</constant>
<constant name="PARAM_HUE_VARIATION" value="9" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set hue variation properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set hue variation properties.
</constant>
<constant name="PARAM_ANIM_SPEED" value="10" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation speed properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set animation speed properties.
</constant>
<constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_curve] to set animation offset properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_curve] to set animation offset properties.
</constant>
<constant name="PARAM_MAX" value="12" enum="Parameter">
Represents the size of the [enum Parameter] enum.
diff --git a/doc/classes/CanvasItemMaterial.xml b/doc/classes/CanvasItemMaterial.xml
index c2d44c1d17..780899bff7 100644
--- a/doc/classes/CanvasItemMaterial.xml
+++ b/doc/classes/CanvasItemMaterial.xml
@@ -30,7 +30,7 @@
[b]Note:[/b] This property is only used and visible in the editor if [member particles_animation] is [code]true[/code].
</member>
<member name="particles_animation" type="bool" setter="set_particles_animation" getter="get_particles_animation" default="false">
- If [code]true[/code], enable spritesheet-based animation features when assigned to [GPUParticles2D] and [CPUParticles2D] nodes. The [member ParticlesMaterial.anim_speed] or [member CPUParticles2D.anim_speed] should also be set to a positive value for the animation to play.
+ If [code]true[/code], enable spritesheet-based animation features when assigned to [GPUParticles2D] and [CPUParticles2D] nodes. The [member ParticlesMaterial.anim_speed_max] or [member CPUParticles2D.anim_speed_max] should also be set to a positive value for the animation to play.
This property (and other [code]particles_anim_*[/code] properties that depend on it) has no effect on other types of nodes.
</member>
</members>
diff --git a/doc/classes/CodeEdit.xml b/doc/classes/CodeEdit.xml
index 47078330f3..93f72d45ae 100644
--- a/doc/classes/CodeEdit.xml
+++ b/doc/classes/CodeEdit.xml
@@ -17,9 +17,9 @@
Override this method to define how the selected entry should be inserted. If [code]replace[/code] is true, any existing text should be replaced.
</description>
</method>
- <method name="_filter_code_completion_candidates" qualifiers="virtual">
+ <method name="_filter_code_completion_candidates" qualifiers="virtual const">
<return type="Array" />
- <argument index="0" name="candidates" type="Array" />
+ <argument index="0" name="candidates" type="Dictionary[]" />
<description>
Override this method to define what items in [code]candidates[/code] should be displayed.
Both [code]candidates[/code] and the return is a [Array] of [Dictionary], see [method get_code_completion_option] for [Dictionary] content.
diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml
index 7129c72e7c..ba1ee3909d 100644
--- a/doc/classes/CollisionObject2D.xml
+++ b/doc/classes/CollisionObject2D.xml
@@ -11,7 +11,7 @@
<methods>
<method name="_input_event" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="viewport" type="Object" />
+ <argument index="0" name="viewport" type="Viewport" />
<argument index="1" name="event" type="InputEvent" />
<argument index="2" name="shape_idx" type="int" />
<description>
diff --git a/doc/classes/CollisionObject3D.xml b/doc/classes/CollisionObject3D.xml
index f9151a2c2f..19bcdcbb27 100644
--- a/doc/classes/CollisionObject3D.xml
+++ b/doc/classes/CollisionObject3D.xml
@@ -11,7 +11,7 @@
<methods>
<method name="_input_event" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="camera" type="Object" />
+ <argument index="0" name="camera" type="Camera3D" />
<argument index="1" name="event" type="InputEvent" />
<argument index="2" name="position" type="Vector3" />
<argument index="3" name="normal" type="Vector3" />
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index 99e121de75..571ffd592a 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -116,7 +116,7 @@
</theme_item>
<theme_item name="picker_cursor" data_type="icon" type="Texture2D">
</theme_item>
- <theme_item name="preset_bg" data_type="icon" type="Texture2D">
+ <theme_item name="sample_bg" data_type="icon" type="Texture2D">
</theme_item>
<theme_item name="screen_picker" data_type="icon" type="Texture2D">
The icon for the screen color picker button.
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 0834521c91..5392189f6a 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -22,9 +22,9 @@
<link title="All GUI Demos">https://github.com/godotengine/godot-demo-projects/tree/master/gui</link>
</tutorials>
<methods>
- <method name="_can_drop_data" qualifiers="virtual">
+ <method name="_can_drop_data" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="position" type="Vector2" />
+ <argument index="0" name="at_position" type="Vector2" />
<argument index="1" name="data" type="Variant" />
<description>
Godot calls this method to test if [code]data[/code] from a control's [method _get_drag_data] can be dropped at [code]position[/code]. [code]position[/code] is local to this control.
@@ -49,7 +49,7 @@
</method>
<method name="_drop_data" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="position" type="Vector2" />
+ <argument index="0" name="at_position" type="Vector2" />
<argument index="1" name="data" type="Variant" />
<description>
Godot calls this method to pass you the [code]data[/code] from a control's [method _get_drag_data] result. Godot first calls [method _can_drop_data] to test if [code]data[/code] is allowed to drop at [code]position[/code] where [code]position[/code] is local to this control.
@@ -73,9 +73,9 @@
[/codeblocks]
</description>
</method>
- <method name="_get_drag_data" qualifiers="virtual">
+ <method name="_get_drag_data" qualifiers="virtual const">
<return type="Variant" />
- <argument index="0" name="position" type="Vector2" />
+ <argument index="0" name="at_position" type="Vector2" />
<description>
Godot calls this method to get data that can be dragged and dropped onto controls that expect drop data. Returns [code]null[/code] if there is no data to drag. Controls that want to receive drop data should implement [method _can_drop_data] and [method _drop_data]. [code]position[/code] is local to this control. Drag may be forced with [method force_drag].
A preview that will follow the mouse that should represent the data can be set with [method set_drag_preview]. A good time to set the preview is in this method.
@@ -97,7 +97,7 @@
[/codeblocks]
</description>
</method>
- <method name="_get_minimum_size" qualifiers="virtual">
+ <method name="_get_minimum_size" qualifiers="virtual const">
<return type="Vector2" />
<description>
Virtual method to be implemented by the user. Returns the minimum size for this control. Alternative to [member rect_min_size] for controlling minimum size via code. The actual minimum size will be the max value of these two (in each axis separately).
@@ -141,15 +141,15 @@
</method>
<method name="_has_point" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="" type="Vector2" />
+ <argument index="0" name="position" type="Vector2" />
<description>
Virtual method to be implemented by the user. Returns whether the given [code]point[/code] is inside this control.
If not overridden, default behavior is checking if the point is within control's Rect.
[b]Note:[/b] If you want to check if a point is inside the control, you can use [code]get_rect().has_point(point)[/code].
</description>
</method>
- <method name="_make_custom_tooltip" qualifiers="virtual">
- <return type="Control" />
+ <method name="_make_custom_tooltip" qualifiers="virtual const">
+ <return type="Object" />
<argument index="0" name="for_text" type="String" />
<description>
Virtual method to be implemented by the user. Returns a [Control] node that should be used as a tooltip instead of the default one. The [code]for_text[/code] includes the contents of the [member hint_tooltip] property.
@@ -193,8 +193,8 @@
[/codeblocks]
</description>
</method>
- <method name="_structured_text_parser" qualifiers="virtual">
- <return type="void" />
+ <method name="_structured_text_parser" qualifiers="virtual const">
+ <return type="Array" />
<argument index="0" name="args" type="Array" />
<argument index="1" name="text" type="String" />
<description>
diff --git a/doc/classes/DisplayServer.xml b/doc/classes/DisplayServer.xml
index abb715b34e..4f495eaec9 100644
--- a/doc/classes/DisplayServer.xml
+++ b/doc/classes/DisplayServer.xml
@@ -649,6 +649,8 @@
<argument index="0" name="min_size" type="Vector2i" />
<argument index="1" name="window_id" type="int" default="0" />
<description>
+ Sets the minimum size for the given window to [code]min_size[/code] (in pixels).
+ [b]Note:[/b] By default, the main window has a minimum size of [code]Vector2i(64, 64)[/code]. This prevents issues that can arise when the window is resized to a near-zero size.
</description>
</method>
<method name="window_set_mode">
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index b379ccc8c6..da6738d6b7 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -113,28 +113,28 @@
<link title="Import plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/import_plugins.html</link>
</tutorials>
<methods>
- <method name="_get_import_options" qualifiers="virtual">
+ <method name="_get_import_options" qualifiers="virtual const">
<return type="Array" />
- <argument index="0" name="preset" type="int" />
+ <argument index="0" name="preset_index" type="int" />
<description>
Gets the options and default values for the preset at this index. Returns an Array of Dictionaries with the following keys: [code]name[/code], [code]default_value[/code], [code]property_hint[/code] (optional), [code]hint_string[/code] (optional), [code]usage[/code] (optional).
</description>
</method>
- <method name="_get_import_order" qualifiers="virtual">
+ <method name="_get_import_order" qualifiers="virtual const">
<return type="int" />
<description>
Gets the order of this importer to be run when importing resources. Importers with [i]lower[/i] import orders will be called first, and higher values will be called later. Use this to ensure the importer runs after the dependencies are already imported. The default import order is [code]0[/code] unless overridden by a specific importer. See [enum ResourceImporter.ImportOrder] for some predefined values.
</description>
</method>
- <method name="_get_importer_name" qualifiers="virtual">
+ <method name="_get_importer_name" qualifiers="virtual const">
<return type="String" />
<description>
Gets the unique name of the importer.
</description>
</method>
- <method name="_get_option_visibility" qualifiers="virtual">
+ <method name="_get_option_visibility" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="option" type="String" />
+ <argument index="0" name="option_name" type="StringName" />
<argument index="1" name="options" type="Dictionary" />
<description>
This method can be overridden to hide specific import options if conditions are met. This is mainly useful for hiding options that depend on others if one of them is disabled. For example:
@@ -163,50 +163,50 @@
Return [code]true[/code] to make all options always visible.
</description>
</method>
- <method name="_get_preset_count" qualifiers="virtual">
+ <method name="_get_preset_count" qualifiers="virtual const">
<return type="int" />
<description>
Gets the number of initial presets defined by the plugin. Use [method _get_import_options] to get the default options for the preset and [method _get_preset_name] to get the name of the preset.
</description>
</method>
- <method name="_get_preset_name" qualifiers="virtual">
+ <method name="_get_preset_name" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="preset" type="int" />
+ <argument index="0" name="preset_index" type="int" />
<description>
Gets the name of the options preset at this index.
</description>
</method>
- <method name="_get_priority" qualifiers="virtual">
+ <method name="_get_priority" qualifiers="virtual const">
<return type="float" />
<description>
Gets the priority of this plugin for the recognized extension. Higher priority plugins will be preferred. The default priority is [code]1.0[/code].
</description>
</method>
- <method name="_get_recognized_extensions" qualifiers="virtual">
- <return type="Array" />
+ <method name="_get_recognized_extensions" qualifiers="virtual const">
+ <return type="PackedStringArray" />
<description>
Gets the list of file extensions to associate with this loader (case-insensitive). e.g. [code]["obj"][/code].
</description>
</method>
- <method name="_get_resource_type" qualifiers="virtual">
+ <method name="_get_resource_type" qualifiers="virtual const">
<return type="String" />
<description>
Gets the Godot resource type associated with this loader. e.g. [code]"Mesh"[/code] or [code]"Animation"[/code].
</description>
</method>
- <method name="_get_save_extension" qualifiers="virtual">
+ <method name="_get_save_extension" qualifiers="virtual const">
<return type="String" />
<description>
Gets the extension used to save this resource in the [code].godot/imported[/code] directory.
</description>
</method>
- <method name="_get_visible_name" qualifiers="virtual">
+ <method name="_get_visible_name" qualifiers="virtual const">
<return type="String" />
<description>
Gets the name to display in the import window. You should choose this name as a continuation to "Import as", e.g. "Import as Special Mesh".
</description>
</method>
- <method name="_import" qualifiers="virtual">
+ <method name="_import" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="source_file" type="String" />
<argument index="1" name="save_path" type="String" />
diff --git a/doc/classes/EditorInspectorPlugin.xml b/doc/classes/EditorInspectorPlugin.xml
index 62fd7a1d6e..ee93379210 100644
--- a/doc/classes/EditorInspectorPlugin.xml
+++ b/doc/classes/EditorInspectorPlugin.xml
@@ -16,9 +16,9 @@
<link title="Inspector plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/inspector_plugins.html</link>
</tutorials>
<methods>
- <method name="_can_handle" qualifiers="virtual">
+ <method name="_can_handle" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="object" type="Object" />
+ <argument index="0" name="object" type="Variant" />
<description>
Returns [code]true[/code] if this object can be handled by this plugin.
</description>
@@ -31,9 +31,9 @@
</method>
<method name="_parse_category" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="category" type="String" />
+ <argument index="0" name="object" type="Object" />
+ <argument index="1" name="category" type="String" />
<description>
- Called to allow adding controls at the beginning of the category.
</description>
</method>
<method name="_parse_end" qualifiers="virtual">
@@ -44,11 +44,13 @@
</method>
<method name="_parse_property" qualifiers="virtual">
<return type="bool" />
- <argument index="0" name="type" type="int" />
- <argument index="1" name="path" type="String" />
- <argument index="2" name="hint" type="int" />
- <argument index="3" name="hint_text" type="String" />
- <argument index="4" name="usage" type="int" />
+ <argument index="0" name="object" type="Object" />
+ <argument index="1" name="type" type="int" />
+ <argument index="2" name="name" type="String" />
+ <argument index="3" name="hint_type" type="int" />
+ <argument index="4" name="hint_string" type="String" />
+ <argument index="5" name="usage_flags" type="int" />
+ <argument index="6" name="wide" type="bool" />
<description>
Called to allow adding property specific editors to the inspector. Usually these inherit [EditorProperty]. Returning [code]true[/code] removes the built-in editor for this property, otherwise allows to insert a custom editor before the built-in one.
</description>
diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml
index 39f6805254..91e024cc1c 100644
--- a/doc/classes/EditorNode3DGizmo.xml
+++ b/doc/classes/EditorNode3DGizmo.xml
@@ -13,7 +13,7 @@
<return type="void" />
<argument index="0" name="id" type="int" />
<argument index="1" name="restore" type="Variant" />
- <argument index="2" name="cancel" type="bool" default="false" />
+ <argument index="2" name="cancel" type="bool" />
<description>
Override this method to commit a handle being edited (handles must have been previously added by [method add_handles]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action.
@@ -22,14 +22,14 @@
<method name="_commit_subgizmos" qualifiers="virtual">
<return type="void" />
<argument index="0" name="ids" type="PackedInt32Array" />
- <argument index="1" name="restore" type="Array" />
- <argument index="2" name="cancel" type="bool" default="false" />
+ <argument index="1" name="restores" type="Transform3D[]" />
+ <argument index="2" name="cancel" type="bool" />
<description>
Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action.
</description>
</method>
- <method name="_get_handle_name" qualifiers="virtual">
+ <method name="_get_handle_name" qualifiers="virtual const">
<return type="String" />
<argument index="0" name="id" type="int" />
<description>
@@ -37,21 +37,21 @@
Handles can be named for reference to the user when editing.
</description>
</method>
- <method name="_get_handle_value" qualifiers="virtual">
+ <method name="_get_handle_value" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="id" type="int" />
<description>
Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle].
</description>
</method>
- <method name="_get_subgizmo_transform" qualifiers="virtual">
+ <method name="_get_subgizmo_transform" qualifiers="virtual const">
<return type="Transform3D" />
<argument index="0" name="id" type="int" />
<description>
Override this method to return the current transform of a subgizmo. This transform will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_subgizmos].
</description>
</method>
- <method name="_is_handle_highlighted" qualifiers="virtual">
+ <method name="_is_handle_highlighted" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="id" type="int" />
<description>
@@ -81,15 +81,15 @@
Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system.
</description>
</method>
- <method name="_subgizmos_intersect_frustum" qualifiers="virtual">
+ <method name="_subgizmos_intersect_frustum" qualifiers="virtual const">
<return type="PackedInt32Array" />
<argument index="0" name="camera" type="Camera3D" />
- <argument index="1" name="frustum" type="Array" />
+ <argument index="1" name="frustum" type="Plane[]" />
<description>
Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos].
</description>
</method>
- <method name="_subgizmos_intersect_ray" qualifiers="virtual">
+ <method name="_subgizmos_intersect_ray" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="camera" type="Camera3D" />
<argument index="1" name="point" type="Vector2" />
diff --git a/doc/classes/EditorNode3DGizmoPlugin.xml b/doc/classes/EditorNode3DGizmoPlugin.xml
index fb72427a7a..4ba455a336 100644
--- a/doc/classes/EditorNode3DGizmoPlugin.xml
+++ b/doc/classes/EditorNode3DGizmoPlugin.xml
@@ -10,7 +10,7 @@
<link title="Spatial gizmo plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/spatial_gizmos.html</link>
</tutorials>
<methods>
- <method name="_can_be_hidden" qualifiers="virtual">
+ <method name="_can_be_hidden" qualifiers="virtual const">
<return type="bool" />
<description>
Override this method to define whether the gizmos handled by this plugin can be hidden or not. Returns [code]true[/code] if not overridden.
@@ -19,9 +19,9 @@
<method name="_commit_handle" qualifiers="virtual">
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="handle_id" type="int" />
<argument index="2" name="restore" type="Variant" />
- <argument index="3" name="cancel" type="bool" default="false" />
+ <argument index="3" name="cancel" type="bool" />
<description>
Override this method to commit a handle being edited (handles must have been previously added by [method EditorNode3DGizmo.add_handles] during [method _redraw]). This usually means creating an [UndoRedo] action for the change, using the current handle value as "do" and the [code]restore[/code] argument as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] value should be directly set, without any [UndoRedo] action. Called for this plugin's active gizmos.
@@ -31,73 +31,73 @@
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="ids" type="PackedInt32Array" />
- <argument index="2" name="restore" type="Array" />
- <argument index="3" name="cancel" type="bool" default="false" />
+ <argument index="2" name="restores" type="Transform3D[]" />
+ <argument index="3" name="cancel" type="bool" />
<description>
Override this method to commit a group of subgizmos being edited (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). This usually means creating an [UndoRedo] action for the change, using the current transforms as "do" and the [code]restore[/code] transforms as "undo".
If the [code]cancel[/code] argument is [code]true[/code], the [code]restore[/code] transforms should be directly set, without any [UndoRedo] action. As with all subgizmo methods, transforms are given in local space respect to the gizmo's Node3D. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_create_gizmo" qualifiers="virtual">
+ <method name="_create_gizmo" qualifiers="virtual const">
<return type="EditorNode3DGizmo" />
- <argument index="0" name="spatial" type="Node3D" />
+ <argument index="0" name="for_node_3d" type="Node3D" />
<description>
Override this method to return a custom [EditorNode3DGizmo] for the spatial nodes of your choice, return [code]null[/code] for the rest of nodes. See also [method _has_gizmo].
</description>
</method>
- <method name="_get_gizmo_name" qualifiers="virtual">
+ <method name="_get_gizmo_name" qualifiers="virtual const">
<return type="String" />
<description>
Override this method to provide the name that will appear in the gizmo visibility menu.
</description>
</method>
- <method name="_get_handle_name" qualifiers="virtual">
+ <method name="_get_handle_name" qualifiers="virtual const">
<return type="String" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="handle_id" type="int" />
<description>
Override this method to provide gizmo's handle names. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_get_handle_value" qualifiers="virtual">
+ <method name="_get_handle_value" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="handle_id" type="int" />
<description>
Override this method to return the current value of a handle. This value will be requested at the start of an edit and used as the [code]restore[/code] argument in [method _commit_handle]. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_get_priority" qualifiers="virtual">
+ <method name="_get_priority" qualifiers="virtual const">
<return type="int" />
<description>
Override this method to set the gizmo's priority. Gizmos with higher priority will have precedence when processing inputs like handles or subgizmos selection.
All built-in editor gizmos return a priority of [code]-1[/code]. If not overridden, this method will return [code]0[/code], which means custom gizmos will automatically get higher priority than built-in gizmos.
</description>
</method>
- <method name="_get_subgizmo_transform" qualifiers="virtual">
+ <method name="_get_subgizmo_transform" qualifiers="virtual const">
<return type="Transform3D" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="subgizmo_id" type="int" />
<description>
Override this method to return the current transform of a subgizmo. As with all subgizmo methods, the transform should be in local space respect to the gizmo's Node3D. This transform will be requested at the start of an edit and used in the [code]restore[/code] argument in [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_has_gizmo" qualifiers="virtual">
+ <method name="_has_gizmo" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="spatial" type="Node3D" />
+ <argument index="0" name="for_node_3d" type="Node3D" />
<description>
Override this method to define which Node3D nodes have a gizmo from this plugin. Whenever a [Node3D] node is added to a scene this method is called, if it returns [code]true[/code] the node gets a generic [EditorNode3DGizmo] assigned and is added to this plugin's list of active gizmos.
</description>
</method>
- <method name="_is_handle_highlighted" qualifiers="virtual">
+ <method name="_is_handle_highlighted" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="handle_id" type="int" />
<description>
Override this method to return [code]true[/code] whenever to given handle should be highlighted in the editor. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_is_selectable_when_hidden" qualifiers="virtual">
+ <method name="_is_selectable_when_hidden" qualifiers="virtual const">
<return type="bool" />
<description>
Override this method to define whether Node3D with this gizmo should be selectable even when the gizmo is hidden.
@@ -113,9 +113,9 @@
<method name="_set_handle" qualifiers="virtual">
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="handle_id" type="int" />
<argument index="2" name="camera" type="Camera3D" />
- <argument index="3" name="point" type="Vector2" />
+ <argument index="3" name="screen_pos" type="Vector2" />
<description>
Override this method to update the node's properties when the user drags a gizmo handle (previously added with [method EditorNode3DGizmo.add_handles]). The provided [code]point[/code] is the mouse position in screen coordinates and the [code]camera[/code] can be used to convert it to raycasts. Called for this plugin's active gizmos.
</description>
@@ -123,26 +123,26 @@
<method name="_set_subgizmo_transform" qualifiers="virtual">
<return type="void" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
- <argument index="1" name="id" type="int" />
+ <argument index="1" name="subgizmo_id" type="int" />
<argument index="2" name="transform" type="Transform3D" />
<description>
Override this method to update the node properties during subgizmo editing (see [method _subgizmos_intersect_ray] and [method _subgizmos_intersect_frustum]). The [code]transform[/code] is given in the Node3D's local coordinate system. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_subgizmos_intersect_frustum" qualifiers="virtual">
+ <method name="_subgizmos_intersect_frustum" qualifiers="virtual const">
<return type="PackedInt32Array" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="camera" type="Camera3D" />
- <argument index="2" name="frustum" type="Array" />
+ <argument index="2" name="frustum_planes" type="Plane[]" />
<description>
Override this method to allow selecting subgizmos using mouse drag box selection. Given a [code]camera[/code] and a [code]frustum[/code], this method should return which subgizmos are contained within the frustum. The [code]frustum[/code] argument consists of an [code]Array[/code] with all the [code]Plane[/code]s that make up the selection frustum. The returned value should contain a list of unique subgizmo identifiers, these identifiers can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
</method>
- <method name="_subgizmos_intersect_ray" qualifiers="virtual">
+ <method name="_subgizmos_intersect_ray" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="gizmo" type="EditorNode3DGizmo" />
<argument index="1" name="camera" type="Camera3D" />
- <argument index="2" name="point" type="Vector2" />
+ <argument index="2" name="screen_pos" type="Vector2" />
<description>
Override this method to allow selecting subgizmos using mouse clicks. Given a [code]camera[/code] and a [code]point[/code] in screen coordinates, this method should return which subgizmo should be selected. The returned value should be a unique subgizmo identifier, which can have any non-negative value and will be used in other virtual methods like [method _get_subgizmo_transform] or [method _commit_subgizmos]. Called for this plugin's active gizmos.
</description>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index 37efca7f48..e564e8045c 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -38,7 +38,7 @@
</method>
<method name="_edit" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="object" type="Object" />
+ <argument index="0" name="object" type="Variant" />
<description>
This function is used for plugins that edit specific object types (nodes or resources). It requests the editor to edit the given object.
</description>
@@ -49,18 +49,18 @@
Called by the engine when the user enables the [EditorPlugin] in the Plugin tab of the project settings window.
</description>
</method>
- <method name="_forward_canvas_draw_over_viewport" qualifiers="virtual">
+ <method name="_forward_3d_draw_over_viewport" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="overlay" type="Control" />
+ <argument index="0" name="viewport_control" type="Control" />
<description>
- Called by the engine when the 2D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
+ Called by the engine when the 3D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
[codeblocks]
[gdscript]
- func _forward_canvas_draw_over_viewport(overlay):
+ func _forward_spatial_3d_over_viewport(overlay):
# Draw a circle at cursor position.
- overlay.draw_circle(overlay.get_local_mouse_position(), 64, Color.white)
+ overlay.draw_circle(overlay.get_local_mouse_position(), 64)
- func _forward_canvas_gui_input(event):
+ func _forward_spatial_gui_input(camera, event):
if event is InputEventMouseMotion:
# Redraw viewport when cursor is moved.
update_overlays()
@@ -68,13 +68,13 @@
return false
[/gdscript]
[csharp]
- public override void ForwardCanvasDrawOverViewport(Godot.Control overlay)
+ public override void ForwardSpatialDrawOverViewport(Godot.Control overlay)
{
// Draw a circle at cursor position.
overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
}
- public override bool ForwardCanvasGuiInput(InputEvent @event)
+ public override bool ForwardSpatialGuiInput(Godot.Camera3D camera, InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
@@ -87,28 +87,29 @@
[/codeblocks]
</description>
</method>
- <method name="_forward_canvas_force_draw_over_viewport" qualifiers="virtual">
+ <method name="_forward_3d_force_draw_over_viewport" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="overlay" type="Control" />
+ <argument index="0" name="viewport_control" type="Control" />
<description>
- This method is the same as [method _forward_canvas_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
+ This method is the same as [method _forward_3d_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled].
</description>
</method>
- <method name="_forward_canvas_gui_input" qualifiers="virtual">
+ <method name="_forward_3d_gui_input" qualifiers="virtual">
<return type="bool" />
- <argument index="0" name="event" type="InputEvent" />
+ <argument index="0" name="viewport_camera" type="Camera3D" />
+ <argument index="1" name="event" type="InputEvent" />
<description>
- Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
+ Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
[codeblocks]
[gdscript]
- # Prevents the InputEvent to reach other Editor classes
- func _forward_canvas_gui_input(event):
+ # Prevents the InputEvent to reach other Editor classes.
+ func _forward_spatial_gui_input(camera, event):
return true
[/gdscript]
[csharp]
- // Prevents the InputEvent to reach other Editor classes
- public override bool ForwardCanvasGuiInput(InputEvent @event)
+ // Prevents the InputEvent to reach other Editor classes.
+ public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
{
return true;
}
@@ -118,12 +119,12 @@
[codeblocks]
[gdscript]
# Consumes InputEventMouseMotion and forwards other InputEvent types.
- func _forward_canvas_gui_input(event):
+ func _forward_spatial_gui_input(camera, event):
return event is InputEventMouseMotion
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
- public override bool ForwardCanvasGuiInput(InputEvent @event)
+ public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
{
return @event is InputEventMouseMotion;
}
@@ -131,18 +132,18 @@
[/codeblocks]
</description>
</method>
- <method name="_forward_spatial_draw_over_viewport" qualifiers="virtual">
+ <method name="_forward_canvas_draw_over_viewport" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="overlay" type="Control" />
+ <argument index="0" name="viewport_control" type="Control" />
<description>
- Called by the engine when the 3D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
+ Called by the engine when the 2D editor's viewport is updated. Use the [code]overlay[/code] [Control] for drawing. You can update the viewport manually by calling [method update_overlays].
[codeblocks]
[gdscript]
- func _forward_spatial_draw_over_viewport(overlay):
+ 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_spatial_gui_input(camera, event):
+ func _forward_canvas_gui_input(event):
if event is InputEventMouseMotion:
# Redraw viewport when cursor is moved.
update_overlays()
@@ -150,13 +151,13 @@
return false
[/gdscript]
[csharp]
- public override void ForwardSpatialDrawOverViewport(Godot.Control overlay)
+ public override void ForwardCanvasDrawOverViewport(Godot.Control overlay)
{
// Draw a circle at cursor position.
overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
}
- public override bool ForwardSpatialGuiInput(Godot.Camera3D camera, InputEvent @event)
+ public override bool ForwardCanvasGuiInput(InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
@@ -169,29 +170,28 @@
[/codeblocks]
</description>
</method>
- <method name="_forward_spatial_force_draw_over_viewport" qualifiers="virtual">
+ <method name="_forward_canvas_force_draw_over_viewport" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="overlay" type="Control" />
+ <argument index="0" name="viewport_control" type="Control" />
<description>
- This method is the same as [method _forward_spatial_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
+ This method is the same as [method _forward_canvas_draw_over_viewport], except it draws on top of everything. Useful when you need an extra layer that shows over anything else.
You need to enable calling of this method by using [method set_force_draw_over_forwarding_enabled].
</description>
</method>
- <method name="_forward_spatial_gui_input" qualifiers="virtual">
+ <method name="_forward_canvas_gui_input" qualifiers="virtual">
<return type="bool" />
- <argument index="0" name="camera" type="Camera3D" />
- <argument index="1" name="event" type="InputEvent" />
+ <argument index="0" name="event" type="InputEvent" />
<description>
- Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 3D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
+ Called when there is a root node in the current edited scene, [method _handles] is implemented and an [InputEvent] happens in the 2D viewport. Intercepts the [InputEvent], if [code]return true[/code] [EditorPlugin] consumes the [code]event[/code], otherwise forwards [code]event[/code] to other Editor classes. Example:
[codeblocks]
[gdscript]
- # Prevents the InputEvent to reach other Editor classes.
- func _forward_spatial_gui_input(camera, event):
+ # Prevents the InputEvent to reach other Editor classes
+ func _forward_canvas_gui_input(event):
return true
[/gdscript]
[csharp]
- // Prevents the InputEvent to reach other Editor classes.
- public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
+ // Prevents the InputEvent to reach other Editor classes
+ public override bool ForwardCanvasGuiInput(InputEvent @event)
{
return true;
}
@@ -201,12 +201,12 @@
[codeblocks]
[gdscript]
# Consumes InputEventMouseMotion and forwards other InputEvent types.
- func _forward_spatial_gui_input(camera, event):
+ func _forward_canvas_gui_input(event):
return event is InputEventMouseMotion
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
- public override bool ForwardSpatialGuiInput(Camera3D camera, InputEvent @event)
+ public override bool ForwardCanvasGuiInput(InputEvent @event)
{
return @event is InputEventMouseMotion;
}
@@ -214,13 +214,13 @@
[/codeblocks]
</description>
</method>
- <method name="_get_breakpoints" qualifiers="virtual">
+ <method name="_get_breakpoints" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
This is for editors that edit script-based objects. You can return a list of breakpoints in the format ([code]script:line[/code]), for example: [code]res://path_to_script.gd:25[/code].
</description>
</method>
- <method name="_get_plugin_icon" qualifiers="virtual">
+ <method name="_get_plugin_icon" qualifiers="virtual const">
<return type="Texture2D" />
<description>
Override this method in your plugin to return a [Texture2D] in order to give it an icon.
@@ -246,14 +246,14 @@
[/codeblocks]
</description>
</method>
- <method name="_get_plugin_name" qualifiers="virtual">
+ <method name="_get_plugin_name" qualifiers="virtual const">
<return type="String" />
<description>
Override this method in your plugin to provide the name of the plugin when displayed in the Godot editor.
For main screen plugins, this appears at the top of the screen, to the right of the "2D", "3D", "Script", and "AssetLib" buttons.
</description>
</method>
- <method name="_get_state" qualifiers="virtual">
+ <method name="_get_state" qualifiers="virtual const">
<return type="Dictionary" />
<description>
Gets the state of your plugin editor. This is used when saving the scene (so state is kept when opening it again) and for switching tabs (so state can be restored when the tab returns).
@@ -261,19 +261,19 @@
</method>
<method name="_get_window_layout" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="layout" type="ConfigFile" />
+ <argument index="0" name="configuration" type="ConfigFile" />
<description>
Gets the GUI layout of the plugin. This is used to save the project's editor layout when [method queue_save_layout] is called or the editor layout was changed(For example changing the position of a dock).
</description>
</method>
- <method name="_handles" qualifiers="virtual">
+ <method name="_handles" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="object" type="Object" />
+ <argument index="0" name="object" type="Variant" />
<description>
- Implement this function if your plugin edits a specific type of object (Resource or Node). If you return [code]true[/code], then you will get the functions [method _edit] and [method _make_visible] called when the editor requests them. If you have declared the methods [method _forward_canvas_gui_input] and [method _forward_spatial_gui_input] these will be called too.
+ Implement this function if your plugin edits a specific type of object (Resource or Node). If you return [code]true[/code], then you will get the functions [method _edit] and [method _make_visible] called when the editor requests them. If you have declared the methods [method _forward_canvas_gui_input] and [method _forward_3d_gui_input] these will be called too.
</description>
</method>
- <method name="_has_main_screen" qualifiers="virtual">
+ <method name="_has_main_screen" qualifiers="virtual const">
<return type="bool" />
<description>
Returns [code]true[/code] if this is a main screen editor plugin (it goes in the workspace selector together with [b]2D[/b], [b]3D[/b], [b]Script[/b] and [b]AssetLib[/b]).
@@ -302,7 +302,7 @@
</method>
<method name="_set_window_layout" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="layout" type="ConfigFile" />
+ <argument index="0" name="configuration" type="ConfigFile" />
<description>
Restore the plugin GUI layout saved by [method _get_window_layout].
</description>
@@ -586,19 +586,19 @@
<method name="set_force_draw_over_forwarding_enabled">
<return type="void" />
<description>
- Enables calling of [method _forward_canvas_force_draw_over_viewport] for the 2D editor and [method _forward_spatial_force_draw_over_viewport] for the 3D editor when their viewports are updated. You need to call this method only once and it will work permanently for this plugin.
+ Enables calling of [method _forward_canvas_force_draw_over_viewport] for the 2D editor and [method _forward_3d_force_draw_over_viewport] for the 3D editor when their viewports are updated. You need to call this method only once and it will work permanently for this plugin.
</description>
</method>
<method name="set_input_event_forwarding_always_enabled">
<return type="void" />
<description>
- Use this method if you always want to receive inputs from 3D view screen inside [method _forward_spatial_gui_input]. It might be especially usable if your plugin will want to use raycast in the scene.
+ Use this method if you always want to receive inputs from 3D view screen inside [method _forward_3d_gui_input]. It might be especially usable if your plugin will want to use raycast in the scene.
</description>
</method>
<method name="update_overlays" qualifiers="const">
<return type="int" />
<description>
- Updates the overlays of the 2D and 3D editor viewport. Causes methods [method _forward_canvas_draw_over_viewport], [method _forward_canvas_force_draw_over_viewport], [method _forward_spatial_draw_over_viewport] and [method _forward_spatial_force_draw_over_viewport] to be called.
+ Updates the overlays of the 2D and 3D editor viewport. Causes methods [method _forward_canvas_draw_over_viewport], [method _forward_canvas_force_draw_over_viewport], [method _forward_3d_draw_over_viewport] and [method _forward_3d_force_draw_over_viewport] to be called.
</description>
</method>
</methods>
diff --git a/doc/classes/EditorProperty.xml b/doc/classes/EditorProperty.xml
index 725b0ba8ff..822bcfd255 100644
--- a/doc/classes/EditorProperty.xml
+++ b/doc/classes/EditorProperty.xml
@@ -57,6 +57,11 @@
Puts the [code]editor[/code] control below the property label. The control must be previously added using [method Node.add_child].
</description>
</method>
+ <method name="update_property">
+ <return type="void" />
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="checkable" type="bool" setter="set_checkable" getter="is_checkable" default="false">
diff --git a/doc/classes/EditorResourceConversionPlugin.xml b/doc/classes/EditorResourceConversionPlugin.xml
index 3de508c88d..8543afa4ae 100644
--- a/doc/classes/EditorResourceConversionPlugin.xml
+++ b/doc/classes/EditorResourceConversionPlugin.xml
@@ -7,17 +7,23 @@
<tutorials>
</tutorials>
<methods>
- <method name="_convert" qualifiers="virtual">
+ <method name="_convert" qualifiers="virtual const">
<return type="Resource" />
<argument index="0" name="resource" type="Resource" />
<description>
</description>
</method>
- <method name="_converts_to" qualifiers="virtual">
+ <method name="_converts_to" qualifiers="virtual const">
<return type="String" />
<description>
</description>
</method>
+ <method name="_handles" qualifiers="virtual const">
+ <return type="bool" />
+ <argument index="0" name="resource" type="Resource" />
+ <description>
+ </description>
+ </method>
</methods>
<constants>
</constants>
diff --git a/doc/classes/EditorResourcePreviewGenerator.xml b/doc/classes/EditorResourcePreviewGenerator.xml
index 7054b1f4d0..033e03c5b5 100644
--- a/doc/classes/EditorResourcePreviewGenerator.xml
+++ b/doc/classes/EditorResourcePreviewGenerator.xml
@@ -9,41 +9,41 @@
<tutorials>
</tutorials>
<methods>
- <method name="_can_generate_small_preview" qualifiers="virtual">
+ <method name="_can_generate_small_preview" qualifiers="virtual const">
<return type="bool" />
<description>
If this function returns [code]true[/code], the generator will call [method _generate] or [method _generate_from_path] for small previews as well.
By default, it returns [code]false[/code].
</description>
</method>
- <method name="_generate" qualifiers="virtual">
+ <method name="_generate" qualifiers="virtual const">
<return type="Texture2D" />
- <argument index="0" name="from" type="Resource" />
- <argument index="1" name="size" type="Vector2" />
+ <argument index="0" name="resource" type="Resource" />
+ <argument index="1" name="size" type="Vector2i" />
<description>
Generate a preview from a given resource with the specified size. This must always be implemented.
Returning an empty texture is an OK way to fail and let another generator take care.
Care must be taken because this function is always called from a thread (not the main thread).
</description>
</method>
- <method name="_generate_from_path" qualifiers="virtual">
+ <method name="_generate_from_path" qualifiers="virtual const">
<return type="Texture2D" />
<argument index="0" name="path" type="String" />
- <argument index="1" name="size" type="Vector2" />
+ <argument index="1" name="size" type="Vector2i" />
<description>
Generate a preview directly from a path with the specified size. Implementing this is optional, as default code will load and call [method _generate].
Returning an empty texture is an OK way to fail and let another generator take care.
Care must be taken because this function is always called from a thread (not the main thread).
</description>
</method>
- <method name="_generate_small_preview_automatically" qualifiers="virtual">
+ <method name="_generate_small_preview_automatically" qualifiers="virtual const">
<return type="bool" />
<description>
If this function returns [code]true[/code], the generator will automatically generate the small previews from the normal preview texture generated by the methods [method _generate] or [method _generate_from_path].
By default, it returns [code]false[/code].
</description>
</method>
- <method name="_handles" qualifiers="virtual">
+ <method name="_handles" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="type" type="String" />
<description>
diff --git a/doc/classes/EditorSceneImporter.xml b/doc/classes/EditorSceneImporter.xml
index 2e9d6a43d8..a400db551f 100644
--- a/doc/classes/EditorSceneImporter.xml
+++ b/doc/classes/EditorSceneImporter.xml
@@ -8,12 +8,12 @@
<tutorials>
</tutorials>
<methods>
- <method name="_get_extensions" qualifiers="virtual">
- <return type="Array" />
+ <method name="_get_extensions" qualifiers="virtual const">
+ <return type="PackedStringArray" />
<description>
</description>
</method>
- <method name="_get_import_flags" qualifiers="virtual">
+ <method name="_get_import_flags" qualifiers="virtual const">
<return type="int" />
<description>
</description>
@@ -27,7 +27,7 @@
</description>
</method>
<method name="_import_scene" qualifiers="virtual">
- <return type="Node" />
+ <return type="Object" />
<argument index="0" name="path" type="String" />
<argument index="1" name="flags" type="int" />
<argument index="2" name="bake_fps" type="int" />
diff --git a/doc/classes/EditorSceneImporterMesh.xml b/doc/classes/EditorSceneImporterMesh.xml
index 3a9eea87bb..b0f233da2f 100644
--- a/doc/classes/EditorSceneImporterMesh.xml
+++ b/doc/classes/EditorSceneImporterMesh.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorSceneImporterMesh" inherits="Resource" version="4.0">
<brief_description>
+ A [Resource] that contains vertex array-based geometry during the import process.
</brief_description>
<description>
+ EditorSceneImporterMesh is a type of [Resource] analogous to [ArrayMesh]. It contains vertex array-based geometry, divided in [i]surfaces[/i]. Each surface contains a completely separate array and a material used to draw it. Design wise, a mesh with multiple surfaces is preferred to a single surface, because objects created in 3D editing software commonly contain multiple materials.
+
+ Unlike its runtime counterpart, [EditorSceneImporterMesh] contains mesh data before various import steps, such as lod and shadow mesh generation, have taken place. Modify surface data by calling [method clear], followed by [method add_surface] for each surface.
</description>
<tutorials>
</tutorials>
@@ -11,6 +15,7 @@
<return type="void" />
<argument index="0" name="name" type="String" />
<description>
+ Adds name for a blend shape that will be added with [method add_surface]. Must be called before surface is added.
</description>
</method>
<method name="add_surface">
@@ -23,44 +28,56 @@
<argument index="4" name="material" type="Material" default="null" />
<argument index="5" name="name" type="String" default="&quot;&quot;" />
<description>
+ Creates a new surface, analogous to [method ArrayMesh.add_surface_from_arrays].
+ Surfaces are created to be rendered using a [code]primitive[/code], which may be any of the types defined in [enum Mesh.PrimitiveType]. (As a note, when using indices, it is recommended to only use points, lines, or triangles.) [method Mesh.get_surface_count] will become the [code]surf_idx[/code] for this new surface.
+ The [code]arrays[/code] argument is an array of arrays. See [enum Mesh.ArrayType] for the values used in this array. For example, [code]arrays[0][/code] is the array of vertices. That first vertex sub-array is always required; the others are optional. Adding an index array puts this function into "index mode" where the vertex and other arrays become the sources of data and the index array defines the vertex order. All sub-arrays must have the same length as the vertex array or be empty, except for [constant Mesh.ARRAY_INDEX] if it is used.
</description>
</method>
<method name="clear">
<return type="void" />
<description>
+ Removes all surfaces and blend shapes from this [EditorSceneImporterMesh].
</description>
</method>
<method name="get_blend_shape_count" qualifiers="const">
<return type="int" />
<description>
+ Returns the number of blend shapes that the mesh holds.
</description>
</method>
<method name="get_blend_shape_mode" qualifiers="const">
<return type="int" enum="Mesh.BlendShapeMode" />
<description>
+ Returns the blend shape mode for this Mesh.
</description>
</method>
<method name="get_blend_shape_name" qualifiers="const">
<return type="String" />
<argument index="0" name="blend_shape_idx" type="int" />
<description>
+ Returns the name of the blend shape at this index.
</description>
</method>
<method name="get_lightmap_size_hint" qualifiers="const">
<return type="Vector2i" />
<description>
+ Returns the size hint of this mesh for lightmap-unwrapping in UV-space.
</description>
</method>
<method name="get_mesh">
<return type="ArrayMesh" />
- <argument index="0" name="arg0" type="Mesh" />
+ <argument index="0" name="base_mesh" type="ArrayMesh" default="null" />
<description>
+ Returns the mesh data represented by this [EditorSceneImporterMesh] as a usable [ArrayMesh].
+ This method caches the returned mesh, and subsequent calls will return the cached data until [method clear] is called.
+ If not yet cached and [code]base_mesh[/code] is provided, [code]base_mesh[/code] will be used and mutated.
</description>
</method>
<method name="get_surface_arrays" qualifiers="const">
<return type="Array" />
<argument index="0" name="surface_idx" type="int" />
<description>
+ Returns the arrays for the vertices, normals, uvs, etc. that make up the requested surface. See [method add_surface].
</description>
</method>
<method name="get_surface_blend_shape_arrays" qualifiers="const">
@@ -68,17 +85,20 @@
<argument index="0" name="surface_idx" type="int" />
<argument index="1" name="blend_shape_idx" type="int" />
<description>
+ Returns a single set of blend shape arrays for the requested blend shape index for a surface.
</description>
</method>
<method name="get_surface_count" qualifiers="const">
<return type="int" />
<description>
+ Returns the amount of surfaces that the mesh holds.
</description>
</method>
<method name="get_surface_lod_count" qualifiers="const">
<return type="int" />
<argument index="0" name="surface_idx" type="int" />
<description>
+ Returns the amount of lods that the mesh holds on a given surface.
</description>
</method>
<method name="get_surface_lod_indices" qualifiers="const">
@@ -86,6 +106,7 @@
<argument index="0" name="surface_idx" type="int" />
<argument index="1" name="lod_idx" type="int" />
<description>
+ Returns the index buffer of a lod for a surface.
</description>
</method>
<method name="get_surface_lod_size" qualifiers="const">
@@ -93,36 +114,58 @@
<argument index="0" name="surface_idx" type="int" />
<argument index="1" name="lod_idx" type="int" />
<description>
+ Returns the screen ratio which activates a lod for a surface.
</description>
</method>
<method name="get_surface_material" qualifiers="const">
<return type="Material" />
<argument index="0" name="surface_idx" type="int" />
<description>
+ Returns a [Material] in a given surface. Surface is rendered using this material.
</description>
</method>
<method name="get_surface_name" qualifiers="const">
<return type="String" />
<argument index="0" name="surface_idx" type="int" />
<description>
+ Gets the name assigned to this surface.
</description>
</method>
<method name="get_surface_primitive_type">
<return type="int" enum="Mesh.PrimitiveType" />
<argument index="0" name="surface_idx" type="int" />
<description>
+ Returns the primitive type of the requested surface (see [method add_surface]).
</description>
</method>
<method name="set_blend_shape_mode">
<return type="void" />
<argument index="0" name="mode" type="int" enum="Mesh.BlendShapeMode" />
<description>
+ Sets the blend shape mode to one of [enum Mesh.BlendShapeMode].
</description>
</method>
<method name="set_lightmap_size_hint">
<return type="void" />
<argument index="0" name="size" type="Vector2i" />
<description>
+ Sets the size hint of this mesh for lightmap-unwrapping in UV-space.
+ </description>
+ </method>
+ <method name="set_surface_material">
+ <return type="void" />
+ <argument index="0" name="surface_idx" type="int" />
+ <argument index="1" name="material" type="Material" />
+ <description>
+ Sets a [Material] for a given surface. Surface will be rendered using this material.
+ </description>
+ </method>
+ <method name="set_surface_name">
+ <return type="void" />
+ <argument index="0" name="surface_idx" type="int" />
+ <argument index="1" name="name" type="String" />
+ <description>
+ Sets a name for a given surface.
</description>
</method>
</methods>
diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml
index 95b0b42d9f..43ca3db5fa 100644
--- a/doc/classes/EditorScenePostImport.xml
+++ b/doc/classes/EditorScenePostImport.xml
@@ -57,7 +57,7 @@
<methods>
<method name="_post_import" qualifiers="virtual">
<return type="Object" />
- <argument index="0" name="scene" type="Object" />
+ <argument index="0" name="scene" type="Node" />
<description>
Called after the scene was imported. This method must return the modified version of the scene.
</description>
diff --git a/doc/classes/EditorSyntaxHighlighter.xml b/doc/classes/EditorSyntaxHighlighter.xml
index 37644a8595..394a4ada46 100644
--- a/doc/classes/EditorSyntaxHighlighter.xml
+++ b/doc/classes/EditorSyntaxHighlighter.xml
@@ -5,24 +5,18 @@
</brief_description>
<description>
Base syntax highlighter resource all editor syntax highlighters extend from, it is used in the [ScriptEditor].
- Add a syntax highlighter to an individual script by calling [method ScriptEditorBase._add_syntax_highlighter]. To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter]
+ Add a syntax highlighter to an individual script by calling ScriptEditorBase._add_syntax_highlighter (currently not working). To apply to all scripts on open, call [method ScriptEditor.register_syntax_highlighter]
</description>
<tutorials>
</tutorials>
<methods>
- <method name="_get_name" qualifiers="virtual">
+ <method name="_get_name" qualifiers="virtual const">
<return type="String" />
<description>
Virtual method which can be overridden to return the syntax highlighter name.
</description>
</method>
- <method name="_get_supported_extentions" qualifiers="virtual">
- <return type="Array" />
- <description>
- Virtual method which can be overridden to return the supported file extensions.
- </description>
- </method>
- <method name="_get_supported_languages" qualifiers="virtual">
+ <method name="_get_supported_languages" qualifiers="virtual const">
<return type="Array" />
<description>
Virtual method which can be overridden to return the supported language names.
diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml
index 47da8ec37b..94e96e985f 100644
--- a/doc/classes/EditorTranslationParserPlugin.xml
+++ b/doc/classes/EditorTranslationParserPlugin.xml
@@ -102,8 +102,8 @@
<tutorials>
</tutorials>
<methods>
- <method name="_get_recognized_extensions" qualifiers="virtual">
- <return type="Array" />
+ <method name="_get_recognized_extensions" qualifiers="virtual const">
+ <return type="PackedStringArray" />
<description>
Gets the list of file extensions to associate with this parser, e.g. [code]["csv"][/code].
</description>
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index 6622619fb3..8ecdc8b220 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -438,7 +438,7 @@
Opens the file for read and write operations. The file is created if it does not exist, and truncated if it does. The cursor is positioned at the beginning of the file.
</constant>
<constant name="COMPRESSION_FASTLZ" value="0" enum="CompressionMode">
- Uses the [url=http://fastlz.org/]FastLZ[/url] compression method.
+ Uses the [url=https://fastlz.org/]FastLZ[/url] compression method.
</constant>
<constant name="COMPRESSION_DEFLATE" value="1" enum="CompressionMode">
Uses the [url=https://en.wikipedia.org/wiki/DEFLATE]DEFLATE[/url] compression method.
diff --git a/doc/classes/GradientTexture.xml b/doc/classes/GradientTexture.xml
index 242a78b2e4..44da042dd4 100644
--- a/doc/classes/GradientTexture.xml
+++ b/doc/classes/GradientTexture.xml
@@ -14,6 +14,9 @@
<member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient">
The [Gradient] that will be used to fill the texture.
</member>
+ <member name="use_hdr" type="bool" setter="set_use_hdr" getter="is_using_hdr" default="false">
+ If [code]true[/code], the generated texture will support high dynamic range ([constant Image.FORMAT_RGBAF] format). This allows for glow effects to work if [member Environment.glow_enabled] is [code]true[/code]. If [code]false[/code], the generated texture will use low dynamic range; overbright colors will be clamped ([constant Image.FORMAT_RGBA8] format).
+ </member>
<member name="width" type="int" setter="set_width" getter="get_width" default="2048">
The number of color samples that will be obtained from the [Gradient].
</member>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 907cf8587d..c870026d58 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -10,6 +10,14 @@
<tutorials>
</tutorials>
<methods>
+ <method name="_get_connection_line" qualifiers="virtual const">
+ <return type="PackedVector2Array" />
+ <argument index="0" name="from" type="Vector2" />
+ <argument index="1" name="to" type="Vector2" />
+ <description>
+ Virtual method which can be overridden to customize how connections are drawn.
+ </description>
+ </method>
<method name="add_valid_connection_type">
<return type="void" />
<argument index="0" name="from_type" type="int" />
@@ -64,6 +72,14 @@
Removes the connection between the [code]from_port[/code] slot of the [code]from[/code] GraphNode and the [code]to_port[/code] slot of the [code]to[/code] GraphNode. If the connection does not exist, no connection is removed.
</description>
</method>
+ <method name="get_connection_line">
+ <return type="PackedVector2Array" />
+ <argument index="0" name="from" type="Vector2" />
+ <argument index="1" name="to" type="Vector2" />
+ <description>
+ Returns the points which would make up a connection between [code]from[/code] and [code]to[/code].
+ </description>
+ </method>
<method name="get_connection_list" qualifiers="const">
<return type="Array" />
<description>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index 22398cc3ce..861627b526 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -138,7 +138,7 @@
<argument index="3" name="body" type="String" default="&quot;&quot;" />
<description>
Sends a request to the connected host.
- The URL parameter is usually just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
+ The URL parameter is usually just the part after the host, so for [code]https://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
Headers are HTTP request headers. For available HTTP methods, see [enum Method].
To create a POST request with query strings to push to the server, do:
[codeblocks]
@@ -166,7 +166,7 @@
<argument index="3" name="body" type="PackedByteArray" />
<description>
Sends a raw request to the connected host.
- The URL parameter is usually just the part after the host, so for [code]http://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
+ The URL parameter is usually just the part after the host, so for [code]https://somehost.com/index.php[/code], it is [code]/index.php[/code]. When sending requests to an HTTP proxy server, it should be an absolute URL. For [constant HTTPClient.METHOD_OPTIONS] requests, [code]*[/code] is also allowed. For [constant HTTPClient.METHOD_CONNECT] requests, it should be the authority component ([code]host:port[/code]).
Headers are HTTP request headers. For available HTTP methods, see [enum Method].
Sends the body data raw, as a byte array and does not encode it in any way.
</description>
diff --git a/doc/classes/InputEventShortcut.xml b/doc/classes/InputEventShortcut.xml
new file mode 100644
index 0000000000..35cca02cf7
--- /dev/null
+++ b/doc/classes/InputEventShortcut.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="InputEventShortcut" inherits="InputEvent" version="4.0">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <methods>
+ </methods>
+ <members>
+ <member name="shortcut" type="Shortcut" setter="set_shortcut" getter="get_shortcut">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index 06e98f7e57..e3e4a9fa7d 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -403,6 +403,9 @@
<member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" enum="ItemList.SelectMode" default="0">
Allows single or multiple item selection. See the [enum SelectMode] constants.
</member>
+ <member name="text_overrun_behavior" type="int" setter="set_text_overrun_behavior" getter="get_text_overrun_behavior" enum="TextParagraph.OverrunBehavior" default="0">
+ Sets the clipping behavior when the text exceeds an item's bounding rectangle. See [enum TextParagraph.OverrunBehavior] for a description of all modes.
+ </member>
</members>
<signals>
<signal name="item_activated">
diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml
index 093ba51755..4d9abbbb19 100644
--- a/doc/classes/Line2D.xml
+++ b/doc/classes/Line2D.xml
@@ -58,6 +58,7 @@
<members>
<member name="antialiased" type="bool" setter="set_antialiased" getter="get_antialiased" default="false">
If [code]true[/code], the line's border will be anti-aliased.
+ [b]Note:[/b] Line2D is not accelerated by batching when being anti-aliased.
</member>
<member name="begin_cap_mode" type="int" setter="set_begin_cap_mode" getter="get_begin_cap_mode" enum="Line2D.LineCapMode" default="0">
Controls the style of the line's first point. Use [enum LineCapMode] constants.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index 096fbbf2c0..f5bc705ecb 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -35,8 +35,8 @@
Corresponds to the [constant NOTIFICATION_EXIT_TREE] notification in [method Object._notification] and signal [signal tree_exiting]. To get notified when the node has already left the active tree, connect to the [signal tree_exited].
</description>
</method>
- <method name="_get_configuration_warnings" qualifiers="virtual">
- <return type="String[]" />
+ <method name="_get_configuration_warnings" qualifiers="virtual const">
+ <return type="PackedStringArray" />
<description>
The elements in the array returned from this method are displayed as warnings in the Scene Dock if the script that overrides it is a [code]tool[/code] script.
Returning an empty array produces no warnings.
@@ -96,9 +96,9 @@
</method>
<method name="_unhandled_key_input" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="event" type="InputEventKey" />
+ <argument index="0" name="event" type="InputEvent" />
<description>
- Called when an [InputEventKey] hasn't been consumed by [method _input] or any GUI. The input event propagates up through the node tree until a node consumes it.
+ Called when an [InputEventKey] or [InputEventShortcut] hasn't been consumed by [method _input] or any GUI. The input event propagates up through the node tree until a node consumes it.
It is only called if unhandled key input processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_unhandled_key_input].
To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called.
For gameplay input, this and [method _unhandled_input] are usually a better fit than [method _input] as they allow the GUI to intercept the events first.
@@ -376,7 +376,14 @@
<method name="is_displayed_folded" qualifiers="const">
<return type="bool" />
<description>
- Returns [code]true[/code] if the node is folded (collapsed) in the Scene dock.
+ Returns [code]true[/code] if the node is folded (collapsed) in the Scene dock. This method is only intended for use with editor tooling.
+ </description>
+ </method>
+ <method name="is_editable_instance" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="node" type="Node" />
+ <description>
+ Returns [code]true[/code] if [code]node[/code] has editable children enabled relative to this node. This method is only intended for use with editor tooling.
</description>
</method>
<method name="is_greater_than" qualifiers="const">
@@ -584,7 +591,15 @@
<return type="void" />
<argument index="0" name="fold" type="bool" />
<description>
- Sets the folded state of the node in the Scene dock.
+ Sets the folded state of the node in the Scene dock. This method is only intended for use with editor tooling.
+ </description>
+ </method>
+ <method name="set_editable_instance">
+ <return type="void" />
+ <argument index="0" name="node" type="Node" />
+ <argument index="1" name="is_editable" type="bool" />
+ <description>
+ Sets the editable children state of [code]node[/code] relative to this node. This method is only intended for use with editor tooling.
</description>
</method>
<method name="set_editor_description">
diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml
index 3520d3b966..3b583f5c89 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -11,18 +11,18 @@
<tutorials>
</tutorials>
<methods>
- <method name="get_param" qualifiers="const">
+ <method name="get_param_max" qualifiers="const">
<return type="float" />
<argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter" />
<description>
- Returns the value of the specified parameter.
+ Return the maximum value range for the given prameter.
</description>
</method>
- <method name="get_param_randomness" qualifiers="const">
+ <method name="get_param_min" qualifiers="const">
<return type="float" />
<argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter" />
<description>
- Returns the randomness ratio associated with the specified parameter.
+ Return the minimum value range for the given parameter.
</description>
</method>
<method name="get_param_texture" qualifiers="const">
@@ -39,20 +39,20 @@
Returns [code]true[/code] if the specified particle flag is enabled. See [enum ParticleFlags] for options.
</description>
</method>
- <method name="set_param">
+ <method name="set_param_max">
<return type="void" />
<argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter" />
<argument index="1" name="value" type="float" />
<description>
- Sets the specified [enum Parameter].
+ Sets the maximum value range for the given parameter.
</description>
</method>
- <method name="set_param_randomness">
+ <method name="set_param_min">
<return type="void" />
<argument index="0" name="param" type="int" enum="ParticlesMaterial.Parameter" />
- <argument index="1" name="randomness" type="float" />
+ <argument index="1" name="value" type="float" />
<description>
- Sets the randomness ratio for the specified [enum Parameter].
+ Sets the minimum value range for the given parameter.
</description>
</method>
<method name="set_param_texture">
@@ -73,53 +73,56 @@
</method>
</methods>
<members>
- <member name="angle" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial rotation applied to each particle, in degrees.
- Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES].
- </member>
<member name="angle_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's rotation will be animated along this [CurveTexture].
</member>
- <member name="angle_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Rotation randomness ratio.
+ <member name="angle_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum angle.
</member>
- <member name="angular_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial angular velocity applied to each particle. Sets the speed of rotation of the particle.
- Only applied when [member particle_flag_disable_z] or [member particle_flag_rotate_y] are [code]true[/code] or the [BaseMaterial3D] being used to draw the particle is using [constant BaseMaterial3D.BILLBOARD_PARTICLES].
+ <member name="angle_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum angle.
</member>
<member name="angular_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's angular velocity will vary along this [CurveTexture].
</member>
- <member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Angular velocity randomness ratio.
+ <member name="angular_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum angular velocity.
</member>
- <member name="anim_offset" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation offset.
+ <member name="angular_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum angular velocity.
</member>
<member name="anim_offset_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's animation offset will vary along this [CurveTexture].
</member>
- <member name="anim_offset_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation offset randomness ratio.
+ <member name="anim_offset_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum animation offset.
</member>
- <member name="anim_speed" type="float" setter="set_param" getter="get_param" default="0.0">
- Particle animation speed.
+ <member name="anim_offset_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum animation offset.
</member>
<member name="anim_speed_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's animation speed will vary along this [CurveTexture].
</member>
- <member name="anim_speed_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Animation speed randomness ratio.
+ <member name="anim_speed_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum particle animation speed.
+ </member>
+ <member name="anim_speed_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum particle animation speed.
</member>
<member name="attractor_interaction_enabled" type="bool" setter="set_attractor_interaction_enabled" getter="is_attractor_interaction_enabled" default="true">
+ True if the interaction with particle attractors is enabled.
</member>
<member name="collision_bounce" type="float" setter="set_collision_bounce" getter="get_collision_bounce" default="0.0">
+ Collision bouncyness.
</member>
<member name="collision_enabled" type="bool" setter="set_collision_enabled" getter="is_collision_enabled" default="false">
+ True if collisions are enabled for this particle system.
</member>
<member name="collision_friction" type="float" setter="set_collision_friction" getter="get_collision_friction" default="0.0">
+ Collision friction.
</member>
<member name="collision_use_scale" type="bool" setter="set_collision_use_scale" getter="is_collision_using_scale" default="false">
+ Should collision take scale into account.
</member>
<member name="color" type="Color" setter="set_color" getter="get_color" default="Color(1, 1, 1, 1)">
Each particle's initial color. If the [GPUParticles2D]'s [code]texture[/code] is defined, it will be multiplied by this color. To have particle display color in a [BaseMaterial3D] make sure to set [member BaseMaterial3D.vertex_color_use_as_albedo] to [code]true[/code].
@@ -127,14 +130,12 @@
<member name="color_ramp" type="Texture2D" setter="set_color_ramp" getter="get_color_ramp">
Each particle's color will vary along this [GradientTexture] over its lifetime (multiplied with [member color]).
</member>
- <member name="damping" type="float" setter="set_param" getter="get_param" default="0.0">
- The rate at which particles lose velocity.
- </member>
<member name="damping_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Damping will vary along this [CurveTexture].
</member>
- <member name="damping_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Damping randomness ratio.
+ <member name="damping_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ </member>
+ <member name="damping_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
</member>
<member name="direction" type="Vector3" setter="set_direction" getter="get_direction" default="Vector3(1, 0, 0)">
Unit vector specifying the particles' emission direction.
@@ -178,42 +179,41 @@
<member name="gravity" type="Vector3" setter="set_gravity" getter="get_gravity" default="Vector3(0, -9.8, 0)">
Gravity applied to every particle.
</member>
- <member name="hue_variation" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial hue variation applied to each particle.
- </member>
<member name="hue_variation_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's hue will vary along this [CurveTexture].
</member>
- <member name="hue_variation_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Hue variation randomness ratio.
+ <member name="hue_variation_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum hue variation.
+ </member>
+ <member name="hue_variation_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum hue variation.
</member>
- <member name="initial_velocity" type="float" setter="set_param" getter="get_param" default="0.0">
- Initial velocity magnitude for each particle. Direction comes from [member spread] and the node's orientation.
+ <member name="initial_velocity_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum initial velocity.
</member>
- <member name="initial_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Initial velocity randomness ratio.
+ <member name="initial_velocity_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum initial velocity.
</member>
<member name="lifetime_randomness" type="float" setter="set_lifetime_randomness" getter="get_lifetime_randomness" default="0.0">
Particle lifetime randomness ratio.
</member>
- <member name="linear_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Linear acceleration applied to each particle in the direction of motion.
- </member>
<member name="linear_accel_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's linear acceleration will vary along this [CurveTexture].
</member>
- <member name="linear_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Linear acceleration randomness ratio.
+ <member name="linear_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum linear acceleration.
</member>
- <member name="orbit_velocity" type="float" setter="set_param" getter="get_param">
- Orbital velocity applied to each particle. Makes the particles circle around origin. Specified in number of full rotations around origin per second.
- Only available when [member particle_flag_disable_z] is [code]true[/code].
+ <member name="linear_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum linear acceleration.
</member>
<member name="orbit_velocity_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's orbital velocity will vary along this [CurveTexture].
</member>
- <member name="orbit_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness">
- Orbital velocity randomness ratio.
+ <member name="orbit_velocity_max" type="float" setter="set_param_max" getter="get_param_max">
+ Maximum orbit velocity.
+ </member>
+ <member name="orbit_velocity_min" type="float" setter="set_param_min" getter="get_param_min">
+ Minimum orbit velocity.
</member>
<member name="particle_flag_align_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
Align Y axis of particle with the direction of its velocity.
@@ -222,25 +222,25 @@
If [code]true[/code], particles will not move on the z axis.
</member>
<member name="particle_flag_rotate_y" type="bool" setter="set_particle_flag" getter="get_particle_flag" default="false">
- If [code]true[/code], particles rotate around Y axis by [member angle].
- </member>
- <member name="radial_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Radial acceleration applied to each particle. Makes particle accelerate away from origin.
+ If [code]true[/code], particles rotate around Y axis by [member angle_min].
</member>
<member name="radial_accel_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's radial acceleration will vary along this [CurveTexture].
</member>
- <member name="radial_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Radial acceleration randomness ratio.
+ <member name="radial_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum radial acceleration.
</member>
- <member name="scale" type="float" setter="set_param" getter="get_param" default="1.0">
- Initial scale applied to each particle.
+ <member name="radial_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum radial acceleration.
</member>
<member name="scale_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
- Each particle's scale will vary along this [CurveTexture].
+ Each particle's scale will vary along this [CurveTexture]. If a [CurveXYZTexture] is supplied instead, the scale will be separated per-axis.
</member>
- <member name="scale_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Scale randomness ratio.
+ <member name="scale_max" type="float" setter="set_param_max" getter="get_param_max" default="1.0">
+ Maximum scale.
+ </member>
+ <member name="scale_min" type="float" setter="set_param_min" getter="get_param_min" default="1.0">
+ Minimum scale.
</member>
<member name="spread" type="float" setter="set_spread" getter="get_spread" default="45.0">
Each particle's initial direction range from [code]+spread[/code] to [code]-spread[/code] degrees.
@@ -253,52 +253,52 @@
</member>
<member name="sub_emitter_mode" type="int" setter="set_sub_emitter_mode" getter="get_sub_emitter_mode" enum="ParticlesMaterial.SubEmitterMode" default="0">
</member>
- <member name="tangential_accel" type="float" setter="set_param" getter="get_param" default="0.0">
- Tangential acceleration applied to each particle. Tangential acceleration is perpendicular to the particle's velocity giving the particles a swirling motion.
- </member>
<member name="tangential_accel_curve" type="Texture2D" setter="set_param_texture" getter="get_param_texture">
Each particle's tangential acceleration will vary along this [CurveTexture].
</member>
- <member name="tangential_accel_random" type="float" setter="set_param_randomness" getter="get_param_randomness" default="0.0">
- Tangential acceleration randomness ratio.
+ <member name="tangential_accel_max" type="float" setter="set_param_max" getter="get_param_max" default="0.0">
+ Maximum tangential acceleration.
+ </member>
+ <member name="tangential_accel_min" type="float" setter="set_param_min" getter="get_param_min" default="0.0">
+ Minimum tangential acceleration.
</member>
</members>
<constants>
<constant name="PARAM_INITIAL_LINEAR_VELOCITY" value="0" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set initial velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set initial velocity properties.
</constant>
<constant name="PARAM_ANGULAR_VELOCITY" value="1" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angular velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set angular velocity properties.
</constant>
<constant name="PARAM_ORBIT_VELOCITY" value="2" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set orbital velocity properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set orbital velocity properties.
</constant>
<constant name="PARAM_LINEAR_ACCEL" value="3" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set linear acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set linear acceleration properties.
</constant>
<constant name="PARAM_RADIAL_ACCEL" value="4" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set radial acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set radial acceleration properties.
</constant>
<constant name="PARAM_TANGENTIAL_ACCEL" value="5" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set tangential acceleration properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set tangential acceleration properties.
</constant>
<constant name="PARAM_DAMPING" value="6" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set damping properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set damping properties.
</constant>
<constant name="PARAM_ANGLE" value="7" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set angle properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set angle properties.
</constant>
<constant name="PARAM_SCALE" value="8" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set scale properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set scale properties.
</constant>
<constant name="PARAM_HUE_VARIATION" value="9" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set hue variation properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set hue variation properties.
</constant>
<constant name="PARAM_ANIM_SPEED" value="10" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation speed properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set animation speed properties.
</constant>
<constant name="PARAM_ANIM_OFFSET" value="11" enum="Parameter">
- Use with [method set_param], [method set_param_randomness], and [method set_param_texture] to set animation offset properties.
+ Use with [method set_param_min], [method set_param_max], and [method set_param_texture] to set animation offset properties.
</constant>
<constant name="PARAM_MAX" value="12" enum="Parameter">
Represents the size of the [enum Parameter] enum.
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index d46e38ac5f..33eb0de698 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -1222,6 +1222,18 @@
<constant name="AREA_PARAM_PRIORITY" value="7" enum="AreaParameter">
Constant to set/get the priority (order of processing) of an area.
</constant>
+ <constant name="AREA_PARAM_WIND_FORCE_MAGNITUDE" value="8" enum="AreaParameter">
+ Constant to set/get the magnitude of area-specific wind force.
+ </constant>
+ <constant name="AREA_PARAM_WIND_SOURCE" value="9" enum="AreaParameter">
+ Constant to set/get the 3D vector that specifies the origin from which an area-specific wind blows.
+ </constant>
+ <constant name="AREA_PARAM_WIND_DIRECTION" value="10" enum="AreaParameter">
+ Constant to set/get the 3D vector that specifies the direction in which an area-specific wind blows.
+ </constant>
+ <constant name="AREA_PARAM_WIND_ATTENUATION_FACTOR" value="11" enum="AreaParameter">
+ Constant to set/get the exponential rate at which wind force decreases with distance from its origin.
+ </constant>
<constant name="AREA_SPACE_OVERRIDE_DISABLED" value="0" enum="AreaSpaceOverrideMode">
This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them.
</constant>
diff --git a/doc/classes/RandomNumberGenerator.xml b/doc/classes/RandomNumberGenerator.xml
index 2cf3cbb83d..fed6568d22 100644
--- a/doc/classes/RandomNumberGenerator.xml
+++ b/doc/classes/RandomNumberGenerator.xml
@@ -4,7 +4,7 @@
A class for generating pseudo-random numbers.
</brief_description>
<description>
- RandomNumberGenerator is a class for generating pseudo-random numbers. It currently uses [url=http://www.pcg-random.org/]PCG32[/url].
+ RandomNumberGenerator is a class for generating pseudo-random numbers. It currently uses [url=https://www.pcg-random.org/]PCG32[/url].
[b]Note:[/b] The underlying algorithm is an implementation detail. As a result, it should not be depended upon for reproducible random streams across Godot versions.
To generate a random float number (within a given range) based on a time-dependant seed:
[codeblock]
diff --git a/doc/classes/Resource.xml b/doc/classes/Resource.xml
index 701ecf815c..65dedf5280 100644
--- a/doc/classes/Resource.xml
+++ b/doc/classes/Resource.xml
@@ -12,12 +12,6 @@
<link title="When and how to avoid using nodes for everything">https://docs.godotengine.org/en/latest/getting_started/workflow/best_practices/node_alternatives.html</link>
</tutorials>
<methods>
- <method name="_setup_local_to_scene" qualifiers="virtual">
- <return type="void" />
- <description>
- Virtual function which can be overridden to customize the behavior value of [method setup_local_to_scene].
- </description>
- </method>
<method name="duplicate" qualifiers="const">
<return type="Resource" />
<argument index="0" name="subresources" type="bool" default="false" />
@@ -54,7 +48,7 @@
<method name="setup_local_to_scene">
<return type="void" />
<description>
- This method is called when a resource with [member resource_local_to_scene] enabled is loaded from a [PackedScene] instantiation. Its behavior can be customized by overriding [method _setup_local_to_scene] from script.
+ This method is called when a resource with [member resource_local_to_scene] enabled is loaded from a [PackedScene] instantiation. Its behavior can be customized by connecting [signal setup_local_to_scene_requested] from script.
For most resources, this method performs no base logic. [ViewportTexture] performs custom logic to properly set the proxy texture and flags in the local viewport.
</description>
</method>
@@ -84,6 +78,10 @@
[b]Note:[/b] This signal is not emitted automatically for custom resources, which means that you need to create a setter and emit the signal yourself.
</description>
</signal>
+ <signal name="setup_local_to_scene_requested">
+ <description>
+ </description>
+ </signal>
</signals>
<constants>
</constants>
diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml
index bce5785cc1..0c2bb26c02 100644
--- a/doc/classes/ResourceFormatLoader.xml
+++ b/doc/classes/ResourceFormatLoader.xml
@@ -11,22 +11,28 @@
<tutorials>
</tutorials>
<methods>
- <method name="_get_dependencies" qualifiers="virtual">
- <return type="void" />
+ <method name="_exists" qualifiers="virtual const">
+ <return type="bool" />
+ <argument index="0" name="path" type="String" />
+ <description>
+ </description>
+ </method>
+ <method name="_get_dependencies" qualifiers="virtual const">
+ <return type="PackedStringArray" />
<argument index="0" name="path" type="String" />
- <argument index="1" name="add_types" type="String" />
+ <argument index="1" name="add_types" type="bool" />
<description>
If implemented, gets the dependencies of a given resource. If [code]add_types[/code] is [code]true[/code], paths should be appended [code]::TypeName[/code], where [code]TypeName[/code] is the class name of the dependency.
[b]Note:[/b] Custom resource types defined by scripts aren't known by the [ClassDB], so you might just return [code]"Resource"[/code] for them.
</description>
</method>
- <method name="_get_recognized_extensions" qualifiers="virtual">
+ <method name="_get_recognized_extensions" qualifiers="virtual const">
<return type="PackedStringArray" />
<description>
Gets the list of extensions for files this loader is able to read.
</description>
</method>
- <method name="_get_resource_type" qualifiers="virtual">
+ <method name="_get_resource_type" qualifiers="virtual const">
<return type="String" />
<argument index="0" name="path" type="String" />
<description>
@@ -34,15 +40,21 @@
[b]Note:[/b] Custom resource types defined by scripts aren't known by the [ClassDB], so you might just return [code]"Resource"[/code] for them.
</description>
</method>
- <method name="_handles_type" qualifiers="virtual">
+ <method name="_get_resource_uid" qualifiers="virtual const">
+ <return type="int" />
+ <argument index="0" name="path" type="String" />
+ <description>
+ </description>
+ </method>
+ <method name="_handles_type" qualifiers="virtual const">
<return type="bool" />
- <argument index="0" name="typename" type="StringName" />
+ <argument index="0" name="type" type="StringName" />
<description>
Tells which resource class this loader can load.
[b]Note:[/b] Custom resource types defined by scripts aren't known by the [ClassDB], so you might just handle [code]"Resource"[/code] for them.
</description>
</method>
- <method name="_load" qualifiers="virtual">
+ <method name="_load" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="path" type="String" />
<argument index="1" name="original_path" type="String" />
@@ -53,10 +65,10 @@
The [code]cache_mode[/code] property defines whether and how the cache should be used or updated when loading the resource. See [enum CacheMode] for details.
</description>
</method>
- <method name="_rename_dependencies" qualifiers="virtual">
+ <method name="_rename_dependencies" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="path" type="String" />
- <argument index="1" name="renames" type="String" />
+ <argument index="1" name="renames" type="Dictionary" />
<description>
If implemented, renames dependencies within the given resource and saves it. [code]renames[/code] is a dictionary [code]{ String =&gt; String }[/code] mapping old dependency paths to new paths.
Returns [constant OK] on success, or an [enum Error] constant in case of failure.
diff --git a/doc/classes/ResourceFormatSaver.xml b/doc/classes/ResourceFormatSaver.xml
index ef9eebc953..7ee8875321 100644
--- a/doc/classes/ResourceFormatSaver.xml
+++ b/doc/classes/ResourceFormatSaver.xml
@@ -10,14 +10,14 @@
<tutorials>
</tutorials>
<methods>
- <method name="_get_recognized_extensions" qualifiers="virtual">
+ <method name="_get_recognized_extensions" qualifiers="virtual const">
<return type="PackedStringArray" />
<argument index="0" name="resource" type="Resource" />
<description>
Returns the list of extensions available for saving the resource object, provided it is recognized (see [method _recognize]).
</description>
</method>
- <method name="_recognize" qualifiers="virtual">
+ <method name="_recognize" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="resource" type="Resource" />
<description>
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index 142afbb860..fd93f6be56 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -23,7 +23,7 @@
<link title="RichTextEffect test project (third-party)">https://github.com/Eoin-ONeill-Yokai/Godot-Rich-Text-Effect-Test-Project</link>
</tutorials>
<methods>
- <method name="_process_custom_fx" qualifiers="virtual">
+ <method name="_process_custom_fx" qualifiers="virtual const">
<return type="bool" />
<argument index="0" name="char_fx" type="CharFXTransform" />
<description>
diff --git a/doc/classes/ScriptEditorBase.xml b/doc/classes/ScriptEditorBase.xml
index 0efcde5638..08baa705e8 100644
--- a/doc/classes/ScriptEditorBase.xml
+++ b/doc/classes/ScriptEditorBase.xml
@@ -9,13 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="_add_syntax_highlighter" qualifiers="virtual">
- <return type="void" />
- <argument index="0" name="highlighter" type="Object" />
- <description>
- Adds a [EditorSyntaxHighlighter] to the open script.
- </description>
- </method>
<method name="get_base_editor" qualifiers="const">
<return type="Control" />
<description>
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 97efc24bd1..de9eb518c6 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -239,7 +239,7 @@
<method name="is_absolute_path" qualifiers="const">
<return type="bool" />
<description>
- If the string is a path to a file or directory, returns [code]true[/code] if the path is absolute.
+ Returns [code]true[/code] if the string is a path to a file or directory and its starting point is explicitly defined. This includes [code]res://[/code], [code]user://[/code], [code]C:\[/code], [code]/[/code], etc.
</description>
</method>
<method name="is_empty" qualifiers="const">
@@ -251,7 +251,7 @@
<method name="is_rel_path" qualifiers="const">
<return type="bool" />
<description>
- If the string is a path to a file or directory, returns [code]true[/code] if the path is relative.
+ Returns [code]true[/code] if the string is a path to a file or directory and its starting point is implicitly defined within the context it is being used. The starting point may refer to the current directory ([code]./[/code]), or the current [Node].
</description>
</method>
<method name="is_subsequence_of" qualifiers="const">
@@ -646,6 +646,12 @@
Returns the similarity index of the text compared to this string. 1 means totally similar and 0 means totally dissimilar.
</description>
</method>
+ <method name="simplify_path" qualifiers="const">
+ <return type="String" />
+ <description>
+ Returns a simplified canonical path.
+ </description>
+ </method>
<method name="split" qualifiers="const">
<return type="PackedStringArray" />
<argument index="0" name="delimiter" type="String" />
diff --git a/doc/classes/SyntaxHighlighter.xml b/doc/classes/SyntaxHighlighter.xml
index ea0d1c27a3..c478cb0eb6 100644
--- a/doc/classes/SyntaxHighlighter.xml
+++ b/doc/classes/SyntaxHighlighter.xml
@@ -17,7 +17,7 @@
Virtual method which can be overridden to clear any local caches.
</description>
</method>
- <method name="_get_line_syntax_highlighting" qualifiers="virtual">
+ <method name="_get_line_syntax_highlighting" qualifiers="virtual const">
<return type="Dictionary" />
<argument index="0" name="line" type="int" />
<description>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 7aa627b7d0..abb4119584 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -30,7 +30,7 @@
</method>
<method name="_handle_unicode_input" qualifiers="virtual">
<return type="void" />
- <argument index="0" name="unicode" type="int" />
+ <argument index="0" name="unicode_char" type="int" />
<description>
Override this method to define what happens when the types in the provided key [code]unicode[/code].
</description>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 4a62d3ec7b..2478b71b6a 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -113,26 +113,33 @@
Returns [code]true[/code] if the viewport is currently performing a drag operation.
</description>
</method>
- <method name="input">
+ <method name="is_embedding_subwindows" qualifiers="const">
+ <return type="bool" />
+ <description>
+ </description>
+ </method>
+ <method name="is_input_handled" qualifiers="const">
+ <return type="bool" />
+ <description>
+ </description>
+ </method>
+ <method name="push_input">
<return type="void" />
<argument index="0" name="event" type="InputEvent" />
<argument index="1" name="in_local_coords" type="bool" default="false" />
<description>
</description>
</method>
- <method name="input_text">
+ <method name="push_text_input">
<return type="void" />
<argument index="0" name="text" type="String" />
<description>
</description>
</method>
- <method name="is_embedding_subwindows" qualifiers="const">
- <return type="bool" />
- <description>
- </description>
- </method>
- <method name="is_input_handled" qualifiers="const">
- <return type="bool" />
+ <method name="push_unhandled_input">
+ <return type="void" />
+ <argument index="0" name="event" type="InputEvent" />
+ <argument index="1" name="in_local_coords" type="bool" default="false" />
<description>
</description>
</method>
@@ -150,13 +157,6 @@
Sets the number of subdivisions to use in the specified quadrant. A higher number of subdivisions allows you to have more shadows in the scene at once, but reduces the quality of the shadows. A good practice is to have quadrants with a varying number of subdivisions and to have as few subdivisions as possible.
</description>
</method>
- <method name="unhandled_input">
- <return type="void" />
- <argument index="0" name="event" type="InputEvent" />
- <argument index="1" name="in_local_coords" type="bool" default="false" />
- <description>
- </description>
- </method>
<method name="warp_mouse">
<return type="void" />
<argument index="0" name="to_position" type="Vector2" />
diff --git a/modules/visual_script/doc_classes/VisualScriptEditor.xml b/doc/classes/VisualScriptCustomNodes.xml
index 9ea889c77b..3ef8022f5e 100644
--- a/modules/visual_script/doc_classes/VisualScriptEditor.xml
+++ b/doc/classes/VisualScriptCustomNodes.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="VisualScriptEditor" inherits="Object" version="4.0">
+<class name="VisualScriptCustomNodes" inherits="Object" version="4.0">
<brief_description>
+ Manages custom nodes for the Visual Script editor.
</brief_description>
<description>
+ This singleton can be used to manage (i.e., add or remove) custom nodes for the Visual Script editor.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
index f6dbd2ad43..3a489419c1 100644
--- a/doc/classes/VisualShaderNodeCustom.xml
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -16,17 +16,17 @@
<link title="Visual Shader plugins">https://docs.godotengine.org/en/latest/tutorials/plugins/editor/visual_shader_plugins.html</link>
</tutorials>
<methods>
- <method name="_get_category" qualifiers="virtual">
+ <method name="_get_category" qualifiers="virtual const">
<return type="String" />
<description>
Override this method to define the path to the associated custom node in the Visual Shader Editor's members dialog. The path may look like [code]"MyGame/MyFunctions/Noise"[/code].
Defining this method is [b]optional[/b]. If not overridden, the node will be filed under the "Addons" category.
</description>
</method>
- <method name="_get_code" qualifiers="virtual">
+ <method name="_get_code" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="input_vars" type="Array" />
- <argument index="1" name="output_vars" type="Array" />
+ <argument index="0" name="input_vars" type="PackedStringArray" />
+ <argument index="1" name="output_vars" type="String[]" />
<argument index="2" name="mode" type="int" />
<argument index="3" name="type" type="int" />
<description>
@@ -37,14 +37,14 @@
Defining this method is [b]required[/b].
</description>
</method>
- <method name="_get_description" qualifiers="virtual">
+ <method name="_get_description" qualifiers="virtual const">
<return type="String" />
<description>
Override this method to define the description of the associated custom node in the Visual Shader Editor's members dialog.
Defining this method is [b]optional[/b].
</description>
</method>
- <method name="_get_global_code" qualifiers="virtual">
+ <method name="_get_global_code" qualifiers="virtual const">
<return type="String" />
<argument index="0" name="mode" type="int" />
<description>
@@ -54,22 +54,22 @@
Defining this method is [b]optional[/b].
</description>
</method>
- <method name="_get_input_port_count" qualifiers="virtual">
+ <method name="_get_input_port_count" qualifiers="virtual const">
<return type="int" />
<description>
Override this method to define the amount of input ports of the associated custom node.
Defining this method is [b]required[/b]. If not overridden, the node has no input ports.
</description>
</method>
- <method name="_get_input_port_name" qualifiers="virtual">
- <return type="StringName" />
+ <method name="_get_input_port_name" qualifiers="virtual const">
+ <return type="String" />
<argument index="0" name="port" type="int" />
<description>
Override this method to define the names of input ports of the associated custom node. The names are used both for the input slots in the editor and as identifiers in the shader code, and are passed in the [code]input_vars[/code] array in [method _get_code].
Defining this method is [b]optional[/b], but recommended. If not overridden, input ports are named as [code]"in" + str(port)[/code].
</description>
</method>
- <method name="_get_input_port_type" qualifiers="virtual">
+ <method name="_get_input_port_type" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="port" type="int" />
<description>
@@ -77,29 +77,29 @@
Defining this method is [b]optional[/b], but recommended. If not overridden, input ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
</description>
</method>
- <method name="_get_name" qualifiers="virtual">
+ <method name="_get_name" qualifiers="virtual const">
<return type="String" />
<description>
Override this method to define the name of the associated custom node in the Visual Shader Editor's members dialog and graph.
Defining this method is [b]optional[/b], but recommended. If not overridden, the node will be named as "Unnamed".
</description>
</method>
- <method name="_get_output_port_count" qualifiers="virtual">
+ <method name="_get_output_port_count" qualifiers="virtual const">
<return type="int" />
<description>
Override this method to define the amount of output ports of the associated custom node.
Defining this method is [b]required[/b]. If not overridden, the node has no output ports.
</description>
</method>
- <method name="_get_output_port_name" qualifiers="virtual">
- <return type="StringName" />
+ <method name="_get_output_port_name" qualifiers="virtual const">
+ <return type="String" />
<argument index="0" name="port" type="int" />
<description>
Override this method to define the names of output ports of the associated custom node. The names are used both for the output slots in the editor and as identifiers in the shader code, and are passed in the [code]output_vars[/code] array in [method _get_code].
Defining this method is [b]optional[/b], but recommended. If not overridden, output ports are named as [code]"out" + str(port)[/code].
</description>
</method>
- <method name="_get_output_port_type" qualifiers="virtual">
+ <method name="_get_output_port_type" qualifiers="virtual const">
<return type="int" />
<argument index="0" name="port" type="int" />
<description>
@@ -107,14 +107,14 @@
Defining this method is [b]optional[/b], but recommended. If not overridden, output ports will return the [constant VisualShaderNode.PORT_TYPE_SCALAR] type.
</description>
</method>
- <method name="_get_return_icon_type" qualifiers="virtual">
+ <method name="_get_return_icon_type" qualifiers="virtual const">
<return type="int" />
<description>
Override this method to define the return icon of the associated custom node in the Visual Shader Editor's members dialog.
Defining this method is [b]optional[/b]. If not overridden, no return icon is shown.
</description>
</method>
- <method name="_is_highend" qualifiers="virtual">
+ <method name="_is_highend" qualifiers="virtual const">
<return type="bool" />
<description>
Override this method to enable high-end mark in the Visual Shader Editor's members dialog.
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 4691b61e1b..a23324fd24 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -1007,6 +1007,8 @@ def format_table(f, data, remove_empty_columns=False): # type: (TextIO, Iterabl
def make_type(klass, state): # type: (str, State) -> str
+ if klass.find("*") != -1: # Pointer, ignore
+ return klass
link_type = klass
if link_type.endswith("[]"): # Typed array, strip [] to link to contained type.
link_type = link_type[:-2]
diff --git a/drivers/vulkan/rendering_device_vulkan.cpp b/drivers/vulkan/rendering_device_vulkan.cpp
index 63510d261a..2de8b9025c 100644
--- a/drivers/vulkan/rendering_device_vulkan.cpp
+++ b/drivers/vulkan/rendering_device_vulkan.cpp
@@ -7957,13 +7957,13 @@ void RenderingDeviceVulkan::compute_list_bind_uniform_set(ComputeListID p_list,
textures_to_storage[i]->used_in_compute = false;
textures_to_storage[i]->used_in_raster = false;
- textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_transfer = false;
} else {
src_access_flags = 0;
textures_to_storage[i]->used_in_compute = false;
textures_to_storage[i]->used_in_raster = false;
- textures_to_storage[i]->used_in_compute = false;
+ textures_to_storage[i]->used_in_transfer = false;
textures_to_storage[i]->used_in_frame = frames_drawn;
}
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 43c8722b06..0b5cfceadc 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -35,8 +35,60 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+#include <stdint.h> // INT32_MAX
+
#include <functiondiscoverykeys.h>
+// Define IAudioClient3 if not already defined by MinGW headers
+#if defined __MINGW32__ || defined __MINGW64__
+
+#ifndef __IAudioClient3_FWD_DEFINED__
+#define __IAudioClient3_FWD_DEFINED__
+
+typedef interface IAudioClient3 IAudioClient3;
+
+#endif // __IAudioClient3_FWD_DEFINED__
+
+#ifndef __IAudioClient3_INTERFACE_DEFINED__
+#define __IAudioClient3_INTERFACE_DEFINED__
+
+MIDL_INTERFACE("7ED4EE07-8E67-4CD4-8C1A-2B7A5987AD42")
+IAudioClient3 : public IAudioClient2 {
+public:
+ virtual HRESULT STDMETHODCALLTYPE GetSharedModeEnginePeriod(
+ /* [annotation][in] */
+ _In_ const WAVEFORMATEX *pFormat,
+ /* [annotation][out] */
+ _Out_ UINT32 *pDefaultPeriodInFrames,
+ /* [annotation][out] */
+ _Out_ UINT32 *pFundamentalPeriodInFrames,
+ /* [annotation][out] */
+ _Out_ UINT32 *pMinPeriodInFrames,
+ /* [annotation][out] */
+ _Out_ UINT32 *pMaxPeriodInFrames) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE GetCurrentSharedModeEnginePeriod(
+ /* [unique][annotation][out] */
+ _Out_ WAVEFORMATEX * *ppFormat,
+ /* [annotation][out] */
+ _Out_ UINT32 * pCurrentPeriodInFrames) = 0;
+
+ virtual HRESULT STDMETHODCALLTYPE InitializeSharedAudioStream(
+ /* [annotation][in] */
+ _In_ DWORD StreamFlags,
+ /* [annotation][in] */
+ _In_ UINT32 PeriodInFrames,
+ /* [annotation][in] */
+ _In_ const WAVEFORMATEX *pFormat,
+ /* [annotation][in] */
+ _In_opt_ LPCGUID AudioSessionGuid) = 0;
+};
+__CRT_UUID_DECL(IAudioClient3, 0x7ED4EE07, 0x8E67, 0x4CD4, 0x8C, 0x1A, 0x2B, 0x7A, 0x59, 0x87, 0xAD, 0x42)
+
+#endif // __IAudioClient3_INTERFACE_DEFINED__
+
+#endif // __MINGW32__ || __MINGW64__
+
#ifndef PKEY_Device_FriendlyName
#undef DEFINE_PROPERTYKEY
@@ -51,6 +103,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0
const CLSID CLSID_MMDeviceEnumerator = __uuidof(MMDeviceEnumerator);
const IID IID_IMMDeviceEnumerator = __uuidof(IMMDeviceEnumerator);
const IID IID_IAudioClient = __uuidof(IAudioClient);
+const IID IID_IAudioClient3 = __uuidof(IAudioClient3);
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
const IID IID_IAudioCaptureClient = __uuidof(IAudioCaptureClient);
@@ -221,7 +274,22 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
ERR_PRINT("WASAPI: RegisterEndpointNotificationCallback error");
}
- hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
+ bool using_audio_client_3 = !p_capture; // IID_IAudioClient3 is only used for adjustable output latency (not input)
+ if (using_audio_client_3) {
+ hr = device->Activate(IID_IAudioClient3, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
+ if (hr != S_OK) {
+ // IID_IAudioClient3 will never activate on OS versions before Windows 10.
+ // Older Windows versions should fall back gracefully.
+ using_audio_client_3 = false;
+ print_verbose("WASAPI: Couldn't activate device with IAudioClient3 interface, falling back to IAudioClient interface");
+ } else {
+ print_verbose("WASAPI: Activated device using IAudioClient3 interface");
+ }
+ }
+ if (!using_audio_client_3) {
+ hr = device->Activate(IID_IAudioClient, CLSCTX_ALL, nullptr, (void **)&p_device->audio_client);
+ }
+
SAFE_RELEASE(device)
if (reinit) {
@@ -232,6 +300,16 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
}
+ if (using_audio_client_3) {
+ AudioClientProperties audioProps;
+ audioProps.cbSize = sizeof(AudioClientProperties);
+ audioProps.bIsOffload = FALSE;
+ audioProps.eCategory = AudioCategory_GameEffects;
+
+ hr = ((IAudioClient3 *)p_device->audio_client)->SetClientProperties(&audioProps);
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: SetClientProperties failed with error 0x" + String::num_uint64(hr, 16) + ".");
+ }
+
hr = p_device->audio_client->GetMixFormat(&pwfex);
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
@@ -285,15 +363,55 @@ Error AudioDriverWASAPI::audio_device_init(AudioDeviceWASAPI *p_device, bool p_c
}
}
- DWORD streamflags = 0;
- if ((DWORD)mix_rate != pwfex->nSamplesPerSec) {
- streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST;
- pwfex->nSamplesPerSec = mix_rate;
- pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8);
- }
+ if (!using_audio_client_3) {
+ DWORD streamflags = 0;
+ if ((DWORD)mix_rate != pwfex->nSamplesPerSec) {
+ streamflags |= AUDCLNT_STREAMFLAGS_RATEADJUST;
+ pwfex->nSamplesPerSec = mix_rate;
+ pwfex->nAvgBytesPerSec = pwfex->nSamplesPerSec * pwfex->nChannels * (pwfex->wBitsPerSample / 8);
+ }
+ hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, nullptr);
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16) + ".");
+ UINT32 max_frames;
+ HRESULT hr = p_device->audio_client->GetBufferSize(&max_frames);
+ ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
- hr = p_device->audio_client->Initialize(AUDCLNT_SHAREMODE_SHARED, streamflags, p_capture ? REFTIMES_PER_SEC : 0, 0, pwfex, nullptr);
- ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: Initialize failed with error 0x" + String::num_uint64(hr, 16) + ".");
+ // Due to WASAPI Shared Mode we have no control of the buffer size
+ buffer_frames = max_frames;
+ } else {
+ IAudioClient3 *device_audio_client_3 = (IAudioClient3 *)p_device->audio_client;
+
+ // AUDCLNT_STREAMFLAGS_RATEADJUST is an invalid flag with IAudioClient3, therefore we have to use
+ // the closest supported mix rate supported by the audio driver.
+ mix_rate = pwfex->nSamplesPerSec;
+ print_verbose("WASAPI: mix_rate = " + itos(mix_rate));
+
+ UINT32 default_period_frames, fundamental_period_frames, min_period_frames, max_period_frames;
+ hr = device_audio_client_3->GetSharedModeEnginePeriod(
+ pwfex,
+ &default_period_frames,
+ &fundamental_period_frames,
+ &min_period_frames,
+ &max_period_frames);
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: GetSharedModeEnginePeriod failed with error 0x" + String::num_uint64(hr, 16) + ".");
+
+ // Period frames must be an integral multiple of fundamental_period_frames or IAudioClient3 initialization will fail,
+ // so we need to select the closest multiple to the user-specified latency.
+ UINT32 desired_period_frames = target_latency_ms * mix_rate / 1000;
+ UINT32 period_frames = (desired_period_frames / fundamental_period_frames) * fundamental_period_frames;
+ if (ABS((int64_t)period_frames - (int64_t)desired_period_frames) > ABS((int64_t)(period_frames + fundamental_period_frames) - (int64_t)desired_period_frames)) {
+ period_frames = period_frames + fundamental_period_frames;
+ }
+ period_frames = CLAMP(period_frames, min_period_frames, max_period_frames);
+ print_verbose("WASAPI: fundamental_period_frames = " + itos(fundamental_period_frames));
+ print_verbose("WASAPI: min_period_frames = " + itos(min_period_frames));
+ print_verbose("WASAPI: max_period_frames = " + itos(max_period_frames));
+ print_verbose("WASAPI: selected a period frame size of " + itos(period_frames));
+ buffer_frames = period_frames;
+
+ hr = device_audio_client_3->InitializeSharedAudioStream(0, period_frames, pwfex, nullptr);
+ ERR_FAIL_COND_V_MSG(hr != S_OK, ERR_CANT_OPEN, "WASAPI: InitializeSharedAudioStream failed with error 0x" + String::num_uint64(hr, 16) + ".");
+ }
if (p_capture) {
hr = p_device->audio_client->GetService(IID_IAudioCaptureClient, (void **)&p_device->capture_client);
@@ -328,13 +446,6 @@ Error AudioDriverWASAPI::init_render_device(bool reinit) {
break;
}
- UINT32 max_frames;
- HRESULT hr = audio_output.audio_client->GetBufferSize(&max_frames);
- ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
-
- // Due to WASAPI Shared Mode we have no control of the buffer size
- buffer_frames = max_frames;
-
// Sample rate is independent of channels (ref: https://stackoverflow.com/questions/11048825/audio-sample-frequency-rely-on-channels)
samples_in.resize(buffer_frames * channels);
@@ -367,7 +478,6 @@ Error AudioDriverWASAPI::audio_device_finish(AudioDeviceWASAPI *p_device) {
if (p_device->audio_client) {
p_device->audio_client->Stop();
}
-
p_device->active = false;
}
@@ -389,6 +499,8 @@ Error AudioDriverWASAPI::finish_capture_device() {
Error AudioDriverWASAPI::init() {
mix_rate = GLOBAL_GET("audio/driver/mix_rate");
+ target_latency_ms = GLOBAL_GET("audio/output_latency");
+
Error err = init_render_device();
if (err != OK) {
ERR_PRINT("WASAPI: init_render_device error");
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index b9b325f0fb..312b6a6781 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -71,6 +71,7 @@ class AudioDriverWASAPI : public AudioDriver {
unsigned int channels = 0;
int mix_rate = 0;
int buffer_frames = 0;
+ int target_latency_ms = 0;
bool thread_exited = false;
mutable bool exit_thread = false;
@@ -114,5 +115,5 @@ public:
AudioDriverWASAPI();
};
+#endif // WASAPI_ENABLED
#endif // AUDIO_DRIVER_WASAPI_H
-#endif
diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp
index ea2ae53e82..bf7d808d50 100644
--- a/editor/animation_bezier_editor.cpp
+++ b/editor/animation_bezier_editor.cpp
@@ -606,7 +606,7 @@ void AnimationBezierTrackEdit::_select_at_anim(const Ref<Animation> &p_anim, int
update();
}
-void AnimationBezierTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
+void AnimationBezierTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (p_event->is_pressed()) {
@@ -1131,8 +1131,6 @@ void AnimationBezierTrackEdit::set_block_animation_update_ptr(bool *p_block_ptr)
}
void AnimationBezierTrackEdit::_bind_methods() {
- ClassDB::bind_method("_gui_input", &AnimationBezierTrackEdit::_gui_input);
-
ClassDB::bind_method("_clear_selection", &AnimationBezierTrackEdit::_clear_selection);
ClassDB::bind_method("_clear_selection_for_anim", &AnimationBezierTrackEdit::_clear_selection_for_anim);
ClassDB::bind_method("_select_at_anim", &AnimationBezierTrackEdit::_select_at_anim);
diff --git a/editor/animation_bezier_editor.h b/editor/animation_bezier_editor.h
index b082cae3ea..a4a662ebcb 100644
--- a/editor/animation_bezier_editor.h
+++ b/editor/animation_bezier_editor.h
@@ -77,7 +77,7 @@ class AnimationBezierTrackEdit : public Control {
void _zoom_changed();
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _menu_selected(int p_index);
bool *block_animation_update_ptr; //used to block all tracks re-gen (speed up)
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp
index ff2818f027..324237ff82 100644
--- a/editor/animation_track_editor.cpp
+++ b/editor/animation_track_editor.cpp
@@ -1642,7 +1642,7 @@ void AnimationTimelineEdit::_play_position_draw() {
}
}
-void AnimationTimelineEdit::_gui_input(const Ref<InputEvent> &p_event) {
+void AnimationTimelineEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
const Ref<InputEventMouseButton> mb = p_event;
@@ -1754,8 +1754,6 @@ void AnimationTimelineEdit::_track_added(int p_track) {
}
void AnimationTimelineEdit::_bind_methods() {
- ClassDB::bind_method("_gui_input", &AnimationTimelineEdit::_gui_input);
-
ADD_SIGNAL(MethodInfo("zoom_changed"));
ADD_SIGNAL(MethodInfo("name_limit_changed"));
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag")));
@@ -2551,7 +2549,7 @@ String AnimationTrackEdit::get_tooltip(const Point2 &p_pos) const {
return Control::get_tooltip(p_pos);
}
-void AnimationTrackEdit::_gui_input(const Ref<InputEvent> &p_event) {
+void AnimationTrackEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (p_event->is_pressed()) {
@@ -2965,8 +2963,6 @@ void AnimationTrackEdit::append_to_selection(const Rect2 &p_box, bool p_deselect
}
void AnimationTrackEdit::_bind_methods() {
- ClassDB::bind_method("_gui_input", &AnimationTrackEdit::_gui_input);
-
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::FLOAT, "position"), PropertyInfo(Variant::BOOL, "drag")));
ADD_SIGNAL(MethodInfo("remove_request", PropertyInfo(Variant::INT, "track")));
ADD_SIGNAL(MethodInfo("dropped", PropertyInfo(Variant::INT, "from_track"), PropertyInfo(Variant::INT, "to_track")));
@@ -5761,7 +5757,7 @@ void AnimationTrackEditor::_pick_track_filter_input(const Ref<InputEvent> &p_ie)
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- pick_track->get_scene_tree()->get_scene_tree()->call("_gui_input", k);
+ pick_track->get_scene_tree()->get_scene_tree()->gui_input(k);
pick_track->get_filter_line_edit()->accept_event();
} break;
default:
diff --git a/editor/animation_track_editor.h b/editor/animation_track_editor.h
index 6d977e5a3f..4da708dd1c 100644
--- a/editor/animation_track_editor.h
+++ b/editor/animation_track_editor.h
@@ -89,7 +89,7 @@ class AnimationTimelineEdit : public Range {
float dragging_hsize_from;
float dragging_hsize_at;
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _track_added(int p_track);
protected:
@@ -195,7 +195,7 @@ protected:
static void _bind_methods();
void _notification(int p_what);
- virtual void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
public:
virtual Variant get_drag_data(const Point2 &p_point) override;
diff --git a/editor/animation_track_editor_plugins.cpp b/editor/animation_track_editor_plugins.cpp
index 0caed1e8e3..4ee8b991e4 100644
--- a/editor/animation_track_editor_plugins.cpp
+++ b/editor/animation_track_editor_plugins.cpp
@@ -1035,7 +1035,7 @@ void AnimationTrackEditTypeAudio::drop_data(const Point2 &p_point, const Variant
AnimationTrackEdit::drop_data(p_point, p_data);
}
-void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
+void AnimationTrackEditTypeAudio::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event;
@@ -1132,7 +1132,7 @@ void AnimationTrackEditTypeAudio::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
- AnimationTrackEdit::_gui_input(p_event);
+ AnimationTrackEdit::gui_input(p_event);
}
////////////////////
diff --git a/editor/animation_track_editor_plugins.h b/editor/animation_track_editor_plugins.h
index 66229c3012..a362422c2b 100644
--- a/editor/animation_track_editor_plugins.h
+++ b/editor/animation_track_editor_plugins.h
@@ -124,7 +124,7 @@ protected:
static void _bind_methods();
public:
- virtual void _gui_input(const Ref<InputEvent> &p_event) override;
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 39095c42a4..89c2e49814 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -114,7 +114,7 @@ void FindReplaceBar::_notification(int p_what) {
}
}
-void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
+void FindReplaceBar::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -611,7 +611,6 @@ void FindReplaceBar::set_text_edit(CodeTextEditor *p_text_editor) {
}
void FindReplaceBar::_bind_methods() {
- ClassDB::bind_method("_unhandled_input", &FindReplaceBar::_unhandled_input);
ClassDB::bind_method("_search_current", &FindReplaceBar::search_current);
ADD_SIGNAL(MethodInfo("search"));
@@ -712,7 +711,7 @@ 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) {
+void CodeTextEditor::input(const Ref<InputEvent> &event) {
ERR_FAIL_COND(event.is_null());
const Ref<InputEventKey> key_event = event;
@@ -1753,8 +1752,6 @@ void CodeTextEditor::remove_all_bookmarks() {
}
void CodeTextEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_input"), &CodeTextEditor::_input);
-
ADD_SIGNAL(MethodInfo("validate_script"));
ADD_SIGNAL(MethodInfo("load_theme_settings"));
ADD_SIGNAL(MethodInfo("show_errors_panel"));
diff --git a/editor/code_editor.h b/editor/code_editor.h
index ee8f4366dd..dfe6561f13 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -105,7 +105,7 @@ class FindReplaceBar : public HBoxContainer {
protected:
void _notification(int p_what);
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
bool _search(uint32_t p_flags, int p_from_line, int p_from_col);
@@ -173,7 +173,7 @@ class CodeTextEditor : public VBoxContainer {
void _font_resize_timeout();
bool _add_font_size(int p_delta);
- void _input(const Ref<InputEvent> &event);
+ virtual void input(const Ref<InputEvent> &event) override;
void _text_editor_gui_input(const Ref<InputEvent> &p_event);
void _zoom_in();
void _zoom_out();
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index eeab0fc2f5..f0b27702e7 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -356,7 +356,7 @@ void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
search_box->accept_event();
} break;
default:
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 8d1c22dabd..fb5f7448c4 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -64,35 +64,42 @@ void DocTools::merge_from(const DocTools &p_data) {
if (cf.methods[j].name != m.name) {
continue;
}
- if (cf.methods[j].arguments.size() != m.arguments.size()) {
- continue;
- }
- // since polymorphic functions are allowed we need to check the type of
- // the arguments so we make sure they are different.
- int arg_count = cf.methods[j].arguments.size();
- Vector<bool> arg_used;
- arg_used.resize(arg_count);
- for (int l = 0; l < arg_count; ++l) {
- arg_used.write[l] = false;
- }
- // also there is no guarantee that argument ordering will match, so we
- // have to check one by one so we make sure we have an exact match
- for (int k = 0; k < arg_count; ++k) {
+
+ const char *operator_prefix = "operator "; // Operators use a space at the end, making this prefix an invalid identifier (and differentiating from methods).
+
+ if (cf.methods[j].name == c.name || cf.methods[j].name.begins_with(operator_prefix)) {
+ // Since constructors and operators can repeat, we need to check the type of
+ // the arguments so we make sure they are different.
+
+ if (cf.methods[j].arguments.size() != m.arguments.size()) {
+ continue;
+ }
+
+ int arg_count = cf.methods[j].arguments.size();
+ Vector<bool> arg_used;
+ arg_used.resize(arg_count);
for (int l = 0; l < arg_count; ++l) {
- if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
- arg_used.write[l] = true;
- break;
+ arg_used.write[l] = false;
+ }
+ // also there is no guarantee that argument ordering will match, so we
+ // have to check one by one so we make sure we have an exact match
+ for (int k = 0; k < arg_count; ++k) {
+ for (int l = 0; l < arg_count; ++l) {
+ if (cf.methods[j].arguments[k].type == m.arguments[l].type && !arg_used[l]) {
+ arg_used.write[l] = true;
+ break;
+ }
}
}
- }
- bool not_the_same = false;
- for (int l = 0; l < arg_count; ++l) {
- if (!arg_used[l]) { // at least one of the arguments was different
- not_the_same = true;
+ bool not_the_same = false;
+ for (int l = 0; l < arg_count; ++l) {
+ if (!arg_used[l]) { // at least one of the arguments was different
+ not_the_same = true;
+ }
+ }
+ if (not_the_same) {
+ continue;
}
- }
- if (not_the_same) {
- continue;
}
const DocData::MethodDoc &mf = cf.methods[j];
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 5209ee06c6..88087664d7 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -530,7 +530,7 @@ void EditorAudioBus::_effect_add(int p_which) {
ur->commit_action();
}
-void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorAudioBus::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> mb = p_event;
@@ -744,7 +744,7 @@ void EditorAudioBus::_effect_rmb(const Vector2 &p_pos) {
void EditorAudioBus::_bind_methods() {
ClassDB::bind_method("update_bus", &EditorAudioBus::update_bus);
ClassDB::bind_method("update_send", &EditorAudioBus::update_send);
- ClassDB::bind_method("_gui_input", &EditorAudioBus::_gui_input);
+
ClassDB::bind_method("_get_drag_data_fw", &EditorAudioBus::get_drag_data_fw);
ClassDB::bind_method("_can_drop_data_fw", &EditorAudioBus::can_drop_data_fw);
ClassDB::bind_method("_drop_data_fw", &EditorAudioBus::drop_data_fw);
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index 0fbda8ece9..e1aaa060c6 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -90,7 +90,7 @@ class EditorAudioBus : public PanelContainer {
bool is_master;
mutable bool hovering_drop;
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _effects_gui_input(Ref<InputEvent> p_event);
void _bus_popup_pressed(int p_option);
diff --git a/editor/editor_command_palette.cpp b/editor/editor_command_palette.cpp
index cf6ede2277..25250e231e 100644
--- a/editor/editor_command_palette.cpp
+++ b/editor/editor_command_palette.cpp
@@ -149,7 +149,7 @@ void EditorCommandPalette::_sbox_input(const Ref<InputEvent> &p_ie) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
} break;
default:
break;
@@ -226,7 +226,7 @@ void EditorCommandPalette::register_shortcuts_as_command() {
ev.instantiate();
ev->set_shortcut(shortcut);
String shortcut_text = String(shortcut->get_as_text());
- add_command(command_name, *key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::unhandled_input), varray(ev, false), shortcut_text);
+ add_command(command_name, *key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::push_unhandled_input), varray(ev, false), shortcut_text);
key = unregistered_shortcuts.next(key);
}
unregistered_shortcuts.clear();
@@ -238,7 +238,7 @@ Ref<Shortcut> EditorCommandPalette::add_shortcut_command(const String &p_command
ev.instantiate();
ev->set_shortcut(p_shortcut);
String shortcut_text = String(p_shortcut->get_as_text());
- add_command(p_command, p_key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::unhandled_input), varray(ev, false), shortcut_text);
+ add_command(p_command, p_key, callable_mp(EditorNode::get_singleton()->get_viewport(), &Viewport::push_unhandled_input), varray(ev, false), shortcut_text);
} else {
const String key_name = String(p_key);
const String command_name = String(p_command);
diff --git a/editor/editor_command_palette.h b/editor/editor_command_palette.h
index cfd8b964c8..093f4b797d 100644
--- a/editor/editor_command_palette.h
+++ b/editor/editor_command_palette.h
@@ -31,9 +31,9 @@
#ifndef EDITOR_COMMAND_PALETTE_H
#define EDITOR_COMMAND_PALETTE_H
+#include "core/input/shortcut.h"
#include "core/os/thread_safe.h"
#include "scene/gui/dialogs.h"
-#include "scene/gui/shortcut.h"
#include "scene/gui/tree.h"
class EditorCommandPalette : public ConfirmationDialog {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index b374f56f6d..91c3c51c4d 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -624,21 +624,15 @@ Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
}
void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) {
- if (get_script_instance()) {
- get_script_instance()->call("_export_file", p_path, p_type, p_features);
- }
+ GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features);
}
void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) {
- if (get_script_instance()) {
- get_script_instance()->call("_export_begin", p_features, p_debug, p_path, p_flags);
- }
+ GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags);
}
void EditorExportPlugin::_export_end_script() {
- if (get_script_instance()) {
- get_script_instance()->call("_export_end");
- }
+ GDVIRTUAL_CALL(_export_end);
}
void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const Set<String> &p_features) {
@@ -663,9 +657,9 @@ void EditorExportPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
- BIND_VMETHOD(MethodInfo("_export_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::STRING, "type"), PropertyInfo(Variant::PACKED_STRING_ARRAY, "features")));
- BIND_VMETHOD(MethodInfo("_export_begin", PropertyInfo(Variant::PACKED_STRING_ARRAY, "features"), PropertyInfo(Variant::BOOL, "is_debug"), PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags")));
- BIND_VMETHOD(MethodInfo("_export_end"));
+ GDVIRTUAL_BIND(_export_file, "path", "type", "features");
+ GDVIRTUAL_BIND(_export_begin, "features", "is_debug", "path", "flags");
+ GDVIRTUAL_BIND(_export_end);
}
EditorExportPlugin::EditorExportPlugin() {
diff --git a/editor/editor_export.h b/editor/editor_export.h
index c9401df9c2..b681f52330 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -349,6 +349,10 @@ protected:
static void _bind_methods();
+ GDVIRTUAL3(_export_file, String, String, Vector<String>)
+ GDVIRTUAL4(_export_begin, Vector<String>, bool, String, uint32_t)
+ GDVIRTUAL0(_export_end)
+
public:
Vector<String> get_ios_frameworks() const;
Vector<String> get_ios_embedded_frameworks() const;
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 5ccbed1b49..1e9d579708 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -124,7 +124,7 @@ void EditorFileDialog::_notification(int p_what) {
}
}
-void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+void EditorFileDialog::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -728,6 +728,7 @@ void EditorFileDialog::update_file_list() {
item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
item_list->set_fixed_column_width(thumbnail_size * 3 / 2);
item_list->set_max_text_lines(2);
+ item_list->set_text_overrun_behavior(TextParagraph::OVERRUN_TRIM_ELLIPSIS);
item_list->set_fixed_icon_size(Size2(thumbnail_size, thumbnail_size));
if (thumbnail_size < 64) {
@@ -1354,8 +1355,6 @@ EditorFileDialog::DisplayMode EditorFileDialog::get_display_mode() const {
}
void EditorFileDialog::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorFileDialog::_unhandled_input);
-
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &EditorFileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &EditorFileDialog::clear_filters);
@@ -1645,6 +1644,7 @@ EditorFileDialog::EditorFileDialog() {
item_list->connect("item_rmb_selected", callable_mp(this, &EditorFileDialog::_item_list_item_rmb_selected));
item_list->connect("rmb_clicked", callable_mp(this, &EditorFileDialog::_item_list_rmb_clicked));
item_list->set_allow_rmb_select(true);
+
list_vb->add_child(item_list);
item_menu = memnew(PopupMenu);
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index d789956a3e..ed427dc76e 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -193,7 +193,7 @@ private:
void _thumbnail_done(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, const Variant &p_udata);
void _request_single_thumbnail(const String &p_path);
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
bool _is_open_should_be_disabled();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index f92b9ac8ba..16151e36de 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -170,7 +170,7 @@ void EditorHelp::_add_type(const String &p_type, const String &p_enum) {
if (t.is_empty()) {
t = "void";
}
- bool can_ref = (t != "void") || !p_enum.is_empty();
+ bool can_ref = (t != "void" && t.find("*") == -1) || !p_enum.is_empty();
if (!p_enum.is_empty()) {
if (p_enum.get_slice_count(".") > 1) {
@@ -632,8 +632,8 @@ void EditorHelp::_update_doc() {
continue;
}
}
- // Ignore undocumented private.
- if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.is_empty()) {
+ // Ignore undocumented non virtual private.
+ if (cd.methods[i].name.begins_with("_") && cd.methods[i].description.is_empty() && cd.methods[i].qualifiers.find("virtual") == -1) {
continue;
}
methods.push_back(cd.methods[i]);
@@ -1825,8 +1825,6 @@ void FindBar::_notification(int p_what) {
}
void FindBar::_bind_methods() {
- ClassDB::bind_method("_unhandled_input", &FindBar::_unhandled_input);
-
ADD_SIGNAL(MethodInfo("search"));
}
@@ -1902,7 +1900,7 @@ void FindBar::_hide_bar() {
hide();
}
-void FindBar::_unhandled_input(const Ref<InputEvent> &p_event) {
+void FindBar::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
diff --git a/editor/editor_help.h b/editor/editor_help.h
index 69bb72c52d..0b0821a7f4 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -70,7 +70,7 @@ class FindBar : public HBoxContainer {
protected:
void _notification(int p_what);
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
bool _search(bool p_search_previous = false);
diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp
index 2b5eee4c1f..e56b10720d 100644
--- a/editor/editor_help_search.cpp
+++ b/editor/editor_help_search.cpp
@@ -71,7 +71,7 @@ void EditorHelpSearch::_search_box_gui_input(const Ref<InputEvent> &p_event) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- results_tree->call("_gui_input", key);
+ results_tree->gui_input(key);
search_box->accept_event();
} break;
default:
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index b3ce11028b..97cb9b6f85 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -379,9 +379,7 @@ StringName EditorProperty::get_edited_property() {
}
void EditorProperty::update_property() {
- if (get_script_instance()) {
- get_script_instance()->call("_update_property");
- }
+ GDVIRTUAL_CALL(_update_property);
}
void EditorProperty::set_read_only(bool p_read_only) {
@@ -694,7 +692,7 @@ bool EditorProperty::is_selected() const {
return selected;
}
-void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorProperty::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (property == StringName()) {
@@ -766,7 +764,7 @@ void EditorProperty::_gui_input(const Ref<InputEvent> &p_event) {
call_deferred(SNAME("emit_changed"), property, object->get(property).operator int64_t() + 1, "", false);
}
- call_deferred(SNAME("_update_property"));
+ call_deferred(SNAME("update_property"));
}
}
if (delete_rect.has_point(mpos)) {
@@ -922,9 +920,8 @@ void EditorProperty::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_edited_property"), &EditorProperty::get_edited_property);
ClassDB::bind_method(D_METHOD("get_edited_object"), &EditorProperty::get_edited_object);
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorProperty::_gui_input);
-
ClassDB::bind_method(D_METHOD("get_tooltip_text"), &EditorProperty::get_tooltip_text);
+ ClassDB::bind_method(D_METHOD("update_property"), &EditorProperty::update_property);
ClassDB::bind_method(D_METHOD("add_focusable", "control"), &EditorProperty::add_focusable);
ClassDB::bind_method(D_METHOD("set_bottom_editor", "editor"), &EditorProperty::set_bottom_editor);
@@ -948,7 +945,7 @@ void EditorProperty::_bind_methods() {
ADD_SIGNAL(MethodInfo("object_id_selected", PropertyInfo(Variant::STRING_NAME, "property"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("selected", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "focusable_idx")));
- BIND_VMETHOD(MethodInfo("_update_property"));
+ GDVIRTUAL_BIND(_update_property)
}
EditorProperty::EditorProperty() {
@@ -1003,43 +1000,31 @@ void EditorInspectorPlugin::add_property_editor_for_multiple_properties(const St
}
bool EditorInspectorPlugin::can_handle(Object *p_object) {
- if (get_script_instance()) {
- return get_script_instance()->call("_can_handle", p_object);
+ bool success;
+ if (GDVIRTUAL_CALL(_can_handle, p_object, success)) {
+ return success;
}
return false;
}
void EditorInspectorPlugin::parse_begin(Object *p_object) {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_begin", p_object);
- }
+ GDVIRTUAL_CALL(_parse_begin);
}
void EditorInspectorPlugin::parse_category(Object *p_object, const String &p_parse_category) {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_category", p_object, p_parse_category);
- }
+ GDVIRTUAL_CALL(_parse_category, p_object, p_parse_category);
}
bool EditorInspectorPlugin::parse_property(Object *p_object, const Variant::Type p_type, const String &p_path, const PropertyHint p_hint, const String &p_hint_text, const uint32_t p_usage, const bool p_wide) {
- if (get_script_instance()) {
- Variant arg[6] = {
- p_object, p_type, p_path, p_hint, p_hint_text, p_usage
- };
- const Variant *argptr[6] = {
- &arg[0], &arg[1], &arg[2], &arg[3], &arg[4], &arg[5]
- };
-
- Callable::CallError err;
- return get_script_instance()->call("_parse_property", (const Variant **)&argptr, 6, err);
+ bool ret;
+ if (GDVIRTUAL_CALL(_parse_property, p_object, p_type, p_path, p_hint, p_hint_text, p_usage, p_wide, ret)) {
+ return ret;
}
return false;
}
void EditorInspectorPlugin::parse_end() {
- if (get_script_instance()) {
- get_script_instance()->call("_parse_end");
- }
+ GDVIRTUAL_CALL(_parse_end);
}
void EditorInspectorPlugin::_bind_methods() {
@@ -1047,11 +1032,11 @@ void EditorInspectorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_property_editor", "property", "editor"), &EditorInspectorPlugin::add_property_editor);
ClassDB::bind_method(D_METHOD("add_property_editor_for_multiple_properties", "label", "properties", "editor"), &EditorInspectorPlugin::add_property_editor_for_multiple_properties);
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_handle", PropertyInfo(Variant::OBJECT, "object")));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_begin"));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_category", PropertyInfo(Variant::STRING, "category")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_parse_property", PropertyInfo(Variant::INT, "type"), PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "hint"), PropertyInfo(Variant::STRING, "hint_text"), PropertyInfo(Variant::INT, "usage")));
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_end"));
+ GDVIRTUAL_BIND(_can_handle, "object")
+ GDVIRTUAL_BIND(_parse_begin)
+ GDVIRTUAL_BIND(_parse_category, "object", "category")
+ GDVIRTUAL_BIND(_parse_property, "object", "type", "name", "hint_type", "hint_string", "usage_flags", "wide");
+ GDVIRTUAL_BIND(_parse_end)
}
////////////////////////////////////////////////
@@ -1332,7 +1317,7 @@ void EditorInspectorSection::setup(const String &p_section, const String &p_labe
}
}
-void EditorInspectorSection::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorInspectorSection::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!foldable) {
@@ -1391,7 +1376,6 @@ void EditorInspectorSection::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_vbox"), &EditorInspectorSection::get_vbox);
ClassDB::bind_method(D_METHOD("unfold"), &EditorInspectorSection::unfold);
ClassDB::bind_method(D_METHOD("fold"), &EditorInspectorSection::fold);
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorInspectorSection::_gui_input);
}
EditorInspectorSection::EditorInspectorSection() {
diff --git a/editor/editor_inspector.h b/editor/editor_inspector.h
index 3c9ba9f39d..71e31dd711 100644
--- a/editor/editor_inspector.h
+++ b/editor/editor_inspector.h
@@ -102,11 +102,12 @@ private:
Map<StringName, Variant> cache;
+ GDVIRTUAL0(_update_property)
protected:
void _notification(int p_what);
static void _bind_methods();
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
public:
void emit_changed(const StringName &p_property, const Variant &p_value, const StringName &p_field = StringName(), bool p_changing = false);
@@ -192,6 +193,12 @@ class EditorInspectorPlugin : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL1RC(bool, _can_handle, Variant)
+ GDVIRTUAL0(_parse_begin)
+ GDVIRTUAL2(_parse_category, Object *, String)
+ GDVIRTUAL7R(bool, _parse_property, Object *, int, String, int, String, int, bool)
+ GDVIRTUAL0(_parse_end)
+
public:
void add_custom_control(Control *control);
void add_property_editor(const String &p_for_property, Control *p_prop);
@@ -245,7 +252,7 @@ class EditorInspectorSection : public Container {
protected:
void _notification(int p_what);
static void _bind_methods();
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
public:
virtual Size2 get_minimum_size() const override;
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 3adb7688b0..1c2b449449 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -388,20 +388,22 @@ void EditorNode::_version_control_menu_option(int p_idx) {
}
void EditorNode::_update_title() {
- String appname = ProjectSettings::get_singleton()->get("application/config/name");
- String title = appname.is_empty() ? String(VERSION_FULL_NAME) : String(VERSION_NAME + String(" - ") + appname);
- String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
+ const String appname = ProjectSettings::get_singleton()->get("application/config/name");
+ String title = (appname.is_empty() ? "Unnamed Project" : appname) + String(" - ") + VERSION_NAME;
+ const String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
if (!edited.is_empty()) {
- title += " - " + String(edited.get_file());
+ // Display the edited scene name before the program name so that it can be seen in the OS task bar.
+ title = vformat("%s - %s", edited.get_file(), title);
}
if (unsaved_cache) {
- title += " (*)";
+ // Display the "modified" mark before anything else so that it can always be seen in the OS task bar.
+ title = vformat("(*) %s", title);
}
DisplayServer::get_singleton()->window_set_title(title);
}
-void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
+void EditorNode::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -5586,7 +5588,6 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_editor_select", &EditorNode::_editor_select);
ClassDB::bind_method("_node_renamed", &EditorNode::_node_renamed);
ClassDB::bind_method("edit_node", &EditorNode::edit_node);
- ClassDB::bind_method("_unhandled_input", &EditorNode::_unhandled_input);
ClassDB::bind_method(D_METHOD("push_item", "object", "property", "inspector_only"), &EditorNode::push_item, DEFVAL(""), DEFVAL(false));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 911139f470..5ff28f322a 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -530,7 +530,7 @@ private:
bool convert_old;
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
static void _load_error_notify(void *p_ud, const String &p_text);
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 98b5ec7d56..73ea4fb5ef 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -558,22 +558,19 @@ void EditorPlugin::notify_resource_saved(const Ref<Resource> &p_resource) {
}
bool EditorPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_canvas_gui_input")) {
- return get_script_instance()->call("_forward_canvas_gui_input", p_event);
+ bool success;
+ if (GDVIRTUAL_CALL(_forward_canvas_gui_input, p_event, success)) {
+ return success;
}
return false;
}
void EditorPlugin::forward_canvas_draw_over_viewport(Control *p_overlay) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_canvas_draw_over_viewport")) {
- get_script_instance()->call("_forward_canvas_draw_over_viewport", p_overlay);
- }
+ GDVIRTUAL_CALL(_forward_canvas_draw_over_viewport, p_overlay);
}
void EditorPlugin::forward_canvas_force_draw_over_viewport(Control *p_overlay) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_canvas_force_draw_over_viewport")) {
- get_script_instance()->call("_forward_canvas_force_draw_over_viewport", p_overlay);
- }
+ GDVIRTUAL_CALL(_forward_canvas_force_draw_over_viewport, p_overlay);
}
// Updates the overlays of the 2D viewport or, if in 3D mode, of every 3D viewport.
@@ -596,110 +593,101 @@ int EditorPlugin::update_overlays() const {
}
bool EditorPlugin::forward_spatial_gui_input(Camera3D *p_camera, const Ref<InputEvent> &p_event) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_spatial_gui_input")) {
- return get_script_instance()->call("_forward_spatial_gui_input", p_camera, p_event);
+ bool success;
+
+ if (GDVIRTUAL_CALL(_forward_3d_gui_input, p_camera, p_event, success)) {
+ return success;
}
return false;
}
void EditorPlugin::forward_spatial_draw_over_viewport(Control *p_overlay) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_spatial_draw_over_viewport")) {
- get_script_instance()->call("_forward_spatial_draw_over_viewport", p_overlay);
- }
+ GDVIRTUAL_CALL(_forward_3d_draw_over_viewport, p_overlay);
}
void EditorPlugin::forward_spatial_force_draw_over_viewport(Control *p_overlay) {
- if (get_script_instance() && get_script_instance()->has_method("_forward_spatial_force_draw_over_viewport")) {
- get_script_instance()->call("_forward_spatial_force_draw_over_viewport", p_overlay);
- }
+ GDVIRTUAL_CALL(_forward_3d_force_draw_over_viewport, p_overlay);
}
String EditorPlugin::get_name() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_plugin_name")) {
- return get_script_instance()->call("_get_plugin_name");
+ String name;
+ if (GDVIRTUAL_CALL(_get_plugin_name, name)) {
+ return name;
}
return String();
}
const Ref<Texture2D> EditorPlugin::get_icon() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_plugin_icon")) {
- return get_script_instance()->call("_get_plugin_icon");
+ Ref<Texture2D> icon;
+ if (GDVIRTUAL_CALL(_get_plugin_icon, icon)) {
+ return icon;
}
return Ref<Texture2D>();
}
bool EditorPlugin::has_main_screen() const {
- if (get_script_instance() && get_script_instance()->has_method("_has_main_screen")) {
- return get_script_instance()->call("_has_main_screen");
+ bool success;
+ if (GDVIRTUAL_CALL(_has_main_screen, success)) {
+ return success;
}
return false;
}
void EditorPlugin::make_visible(bool p_visible) {
- if (get_script_instance() && get_script_instance()->has_method("_make_visible")) {
- get_script_instance()->call("_make_visible", p_visible);
- }
+ GDVIRTUAL_CALL(_make_visible, p_visible);
}
void EditorPlugin::edit(Object *p_object) {
- if (get_script_instance() && get_script_instance()->has_method("_edit")) {
- if (p_object->is_class("Resource")) {
- get_script_instance()->call("_edit", Ref<Resource>(Object::cast_to<Resource>(p_object)));
- } else {
- get_script_instance()->call("_edit", p_object);
- }
+ if (p_object->is_class("Resource")) {
+ GDVIRTUAL_CALL(_edit, Ref<Resource>(Object::cast_to<Resource>(p_object)));
+ } else {
+ GDVIRTUAL_CALL(_edit, p_object);
}
}
bool EditorPlugin::handles(Object *p_object) const {
- if (get_script_instance() && get_script_instance()->has_method("_handles")) {
- return get_script_instance()->call("_handles", p_object);
+ bool success;
+ if (GDVIRTUAL_CALL(_handles, p_object, success)) {
+ return success;
}
return false;
}
Dictionary EditorPlugin::get_state() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_state")) {
- return get_script_instance()->call("_get_state");
+ Dictionary state;
+ if (GDVIRTUAL_CALL(_get_state, state)) {
+ return state;
}
return Dictionary();
}
void EditorPlugin::set_state(const Dictionary &p_state) {
- if (get_script_instance() && get_script_instance()->has_method("_set_state")) {
- get_script_instance()->call("_set_state", p_state);
- }
+ GDVIRTUAL_CALL(_set_state, p_state);
}
void EditorPlugin::clear() {
- if (get_script_instance() && get_script_instance()->has_method("_clear")) {
- get_script_instance()->call("_clear");
- }
+ GDVIRTUAL_CALL(_clear);
}
// if editor references external resources/scenes, save them
void EditorPlugin::save_external_data() {
- if (get_script_instance() && get_script_instance()->has_method("_save_external_data")) {
- get_script_instance()->call("_save_external_data");
- }
+ GDVIRTUAL_CALL(_save_external_data);
}
// if changes are pending in editor, apply them
void EditorPlugin::apply_changes() {
- if (get_script_instance() && get_script_instance()->has_method("_apply_changes")) {
- get_script_instance()->call("_apply_changes");
- }
+ GDVIRTUAL_CALL(_apply_changes);
}
void EditorPlugin::get_breakpoints(List<String> *p_breakpoints) {
- if (get_script_instance() && get_script_instance()->has_method("_get_breakpoints")) {
- PackedStringArray arr = get_script_instance()->call("_get_breakpoints");
+ PackedStringArray arr;
+ if (GDVIRTUAL_CALL(_get_breakpoints, arr)) {
for (int i = 0; i < arr.size(); i++) {
p_breakpoints->push_back(arr[i]);
}
@@ -796,37 +784,28 @@ int find(const PackedStringArray &a, const String &v) {
void EditorPlugin::enable_plugin() {
// Called when the plugin gets enabled in project settings, after it's added to the tree.
// You can implement it to register autoloads.
- if (get_script_instance() && get_script_instance()->has_method("_enable_plugin")) {
- get_script_instance()->call("_enable_plugin");
- }
+ GDVIRTUAL_CALL(_enable_plugin);
}
void EditorPlugin::disable_plugin() {
// Last function called when the plugin gets disabled in project settings.
// Implement it to cleanup things from the project, such as unregister autoloads.
-
- if (get_script_instance() && get_script_instance()->has_method("_disable_plugin")) {
- get_script_instance()->call("_disable_plugin");
- }
+ GDVIRTUAL_CALL(_disable_plugin);
}
void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
- if (get_script_instance() && get_script_instance()->has_method("_set_window_layout")) {
- get_script_instance()->call("_set_window_layout", p_layout);
- }
+ GDVIRTUAL_CALL(_set_window_layout, p_layout);
}
void EditorPlugin::get_window_layout(Ref<ConfigFile> p_layout) {
- if (get_script_instance() && get_script_instance()->has_method("_get_window_layout")) {
- get_script_instance()->call("_get_window_layout", p_layout);
- }
+ GDVIRTUAL_CALL(_get_window_layout, p_layout);
}
bool EditorPlugin::build() {
- if (get_script_instance() && get_script_instance()->has_method("_build")) {
- return get_script_instance()->call("_build");
+ bool success;
+ if (GDVIRTUAL_CALL(_build, success)) {
+ return success;
}
-
return true;
}
@@ -915,29 +894,29 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_debugger_plugin", "script"), &EditorPlugin::add_debugger_plugin);
ClassDB::bind_method(D_METHOD("remove_debugger_plugin", "script"), &EditorPlugin::remove_debugger_plugin);
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_forward_canvas_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- BIND_VMETHOD(MethodInfo("_forward_canvas_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
- BIND_VMETHOD(MethodInfo("_forward_canvas_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- BIND_VMETHOD(MethodInfo("_forward_spatial_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
- BIND_VMETHOD(MethodInfo("_forward_spatial_force_draw_over_viewport", PropertyInfo(Variant::OBJECT, "overlay", PROPERTY_HINT_RESOURCE_TYPE, "Control")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_plugin_name"));
- BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::OBJECT, "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "_get_plugin_icon"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_main_screen"));
- BIND_VMETHOD(MethodInfo("_make_visible", PropertyInfo(Variant::BOOL, "visible")));
- BIND_VMETHOD(MethodInfo("_edit", PropertyInfo(Variant::OBJECT, "object")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_handles", PropertyInfo(Variant::OBJECT, "object")));
- BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_state"));
- BIND_VMETHOD(MethodInfo("_set_state", PropertyInfo(Variant::DICTIONARY, "state")));
- BIND_VMETHOD(MethodInfo("_clear"));
- BIND_VMETHOD(MethodInfo("_save_external_data"));
- BIND_VMETHOD(MethodInfo("_apply_changes"));
- BIND_VMETHOD(MethodInfo(Variant::PACKED_STRING_ARRAY, "_get_breakpoints"));
- BIND_VMETHOD(MethodInfo("_set_window_layout", PropertyInfo(Variant::OBJECT, "layout", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile")));
- BIND_VMETHOD(MethodInfo("_get_window_layout", PropertyInfo(Variant::OBJECT, "layout", PROPERTY_HINT_RESOURCE_TYPE, "ConfigFile")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_build"));
- BIND_VMETHOD(MethodInfo("_enable_plugin"));
- BIND_VMETHOD(MethodInfo("_disable_plugin"));
+ GDVIRTUAL_BIND(_forward_canvas_gui_input, "event");
+ GDVIRTUAL_BIND(_forward_canvas_draw_over_viewport, "viewport_control");
+ GDVIRTUAL_BIND(_forward_canvas_force_draw_over_viewport, "viewport_control");
+ GDVIRTUAL_BIND(_forward_3d_gui_input, "viewport_camera", "event");
+ GDVIRTUAL_BIND(_forward_3d_draw_over_viewport, "viewport_control");
+ GDVIRTUAL_BIND(_forward_3d_force_draw_over_viewport, "viewport_control");
+ GDVIRTUAL_BIND(_get_plugin_name);
+ GDVIRTUAL_BIND(_get_plugin_icon);
+ GDVIRTUAL_BIND(_has_main_screen);
+ GDVIRTUAL_BIND(_make_visible, "visible");
+ GDVIRTUAL_BIND(_edit, "object");
+ GDVIRTUAL_BIND(_handles, "object");
+ GDVIRTUAL_BIND(_get_state);
+ GDVIRTUAL_BIND(_set_state, "state");
+ GDVIRTUAL_BIND(_clear);
+ GDVIRTUAL_BIND(_save_external_data);
+ GDVIRTUAL_BIND(_apply_changes);
+ GDVIRTUAL_BIND(_get_breakpoints);
+ GDVIRTUAL_BIND(_set_window_layout, "configuration");
+ GDVIRTUAL_BIND(_get_window_layout, "configuration");
+ GDVIRTUAL_BIND(_build);
+ GDVIRTUAL_BIND(_enable_plugin);
+ GDVIRTUAL_BIND(_disable_plugin);
ADD_SIGNAL(MethodInfo("scene_changed", PropertyInfo(Variant::OBJECT, "scene_root", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("scene_closed", PropertyInfo(Variant::STRING, "filepath")));
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index d665278144..169106d901 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -39,9 +39,9 @@
#include "editor/import/editor_import_plugin.h"
#include "editor/import/resource_importer_scene.h"
#include "editor/script_create_dialog.h"
+#include "scene/3d/camera_3d.h"
#include "scene/main/node.h"
#include "scene/resources/texture.h"
-
class EditorNode;
class Node3D;
class Camera3D;
@@ -148,6 +148,30 @@ protected:
void add_custom_type(const String &p_type, const String &p_base, const Ref<Script> &p_script, const Ref<Texture2D> &p_icon);
void remove_custom_type(const String &p_type);
+ GDVIRTUAL1R(bool, _forward_canvas_gui_input, Ref<InputEvent>)
+ GDVIRTUAL1(_forward_canvas_draw_over_viewport, Control *)
+ GDVIRTUAL1(_forward_canvas_force_draw_over_viewport, Control *)
+ GDVIRTUAL2R(bool, _forward_3d_gui_input, Camera3D *, Ref<InputEvent>)
+ GDVIRTUAL1(_forward_3d_draw_over_viewport, Control *)
+ GDVIRTUAL1(_forward_3d_force_draw_over_viewport, Control *)
+ GDVIRTUAL0RC(String, _get_plugin_name)
+ GDVIRTUAL0RC(Ref<Texture2D>, _get_plugin_icon)
+ GDVIRTUAL0RC(bool, _has_main_screen)
+ GDVIRTUAL1(_make_visible, bool)
+ GDVIRTUAL1(_edit, Variant)
+ GDVIRTUAL1RC(bool, _handles, Variant)
+ GDVIRTUAL0RC(Dictionary, _get_state)
+ GDVIRTUAL1(_set_state, Dictionary)
+ GDVIRTUAL0(_clear)
+ GDVIRTUAL0(_save_external_data)
+ GDVIRTUAL0(_apply_changes)
+ GDVIRTUAL0RC(Vector<String>, _get_breakpoints)
+ GDVIRTUAL1(_set_window_layout, Ref<ConfigFile>)
+ GDVIRTUAL1(_get_window_layout, Ref<ConfigFile>)
+ GDVIRTUAL0R(bool, _build)
+ GDVIRTUAL0(_enable_plugin)
+ GDVIRTUAL0(_disable_plugin)
+
public:
enum CustomControlContainer {
CONTAINER_TOOLBAR,
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 99619cfc40..cb7fffe592 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -735,7 +735,7 @@ public:
return String();
}
- void _gui_input(const Ref<InputEvent> &p_ev) {
+ void gui_input(const Ref<InputEvent> &p_ev) override {
const Ref<InputEventMouseMotion> mm = p_ev;
if (mm.is_valid()) {
bool expand_was_hovered = expand_hovered;
@@ -931,7 +931,6 @@ public:
}
static void _bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorPropertyLayersGrid::_gui_input);
ADD_SIGNAL(MethodInfo("flag_changed", PropertyInfo(Variant::INT, "flag")));
}
};
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 7f4ee7848f..8fc1345f3e 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -40,22 +40,25 @@
#include "editor_settings.h"
bool EditorResourcePreviewGenerator::handles(const String &p_type) const {
- if (get_script_instance() && get_script_instance()->has_method("_handles")) {
- return get_script_instance()->call("_handles", p_type);
+ bool success;
+ if (GDVIRTUAL_CALL(_handles, p_type, success)) {
+ return success;
}
ERR_FAIL_V_MSG(false, "EditorResourcePreviewGenerator::_handles needs to be overridden.");
}
Ref<Texture2D> EditorResourcePreviewGenerator::generate(const RES &p_from, const Size2 &p_size) const {
- if (get_script_instance() && get_script_instance()->has_method("_generate")) {
- return get_script_instance()->call("_generate", p_from, p_size);
+ Ref<Texture2D> preview;
+ if (GDVIRTUAL_CALL(_generate, p_from, p_size, preview)) {
+ return preview;
}
ERR_FAIL_V_MSG(Ref<Texture2D>(), "EditorResourcePreviewGenerator::_generate needs to be overridden.");
}
Ref<Texture2D> EditorResourcePreviewGenerator::generate_from_path(const String &p_path, const Size2 &p_size) const {
- if (get_script_instance() && get_script_instance()->has_method("_generate_from_path")) {
- return get_script_instance()->call("_generate_from_path", p_path, p_size);
+ Ref<Texture2D> preview;
+ if (GDVIRTUAL_CALL(_generate_from_path, p_path, p_size, preview)) {
+ return preview;
}
RES res = ResourceLoader::load(p_path);
@@ -66,27 +69,29 @@ Ref<Texture2D> EditorResourcePreviewGenerator::generate_from_path(const String &
}
bool EditorResourcePreviewGenerator::generate_small_preview_automatically() const {
- if (get_script_instance() && get_script_instance()->has_method("_generate_small_preview_automatically")) {
- return get_script_instance()->call("_generate_small_preview_automatically");
+ bool success;
+ if (GDVIRTUAL_CALL(_generate_small_preview_automatically, success)) {
+ return success;
}
return false;
}
bool EditorResourcePreviewGenerator::can_generate_small_preview() const {
- if (get_script_instance() && get_script_instance()->has_method("_can_generate_small_preview")) {
- return get_script_instance()->call("_can_generate_small_preview");
+ bool success;
+ if (GDVIRTUAL_CALL(_can_generate_small_preview, success)) {
+ return success;
}
return false;
}
void EditorResourcePreviewGenerator::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_handles", PropertyInfo(Variant::STRING, "type")));
- BIND_VMETHOD(MethodInfo(CLASS_INFO(Texture2D), "_generate", PropertyInfo(Variant::OBJECT, "from", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::VECTOR2, "size")));
- BIND_VMETHOD(MethodInfo(CLASS_INFO(Texture2D), "_generate_from_path", PropertyInfo(Variant::STRING, "path", PROPERTY_HINT_FILE), PropertyInfo(Variant::VECTOR2, "size")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_generate_small_preview_automatically"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_generate_small_preview"));
+ GDVIRTUAL_BIND(_handles, "type");
+ GDVIRTUAL_BIND(_generate, "resource", "size");
+ GDVIRTUAL_BIND(_generate_from_path, "path", "size");
+ GDVIRTUAL_BIND(_generate_small_preview_automatically);
+ GDVIRTUAL_BIND(_can_generate_small_preview);
}
EditorResourcePreviewGenerator::EditorResourcePreviewGenerator() {
diff --git a/editor/editor_resource_preview.h b/editor/editor_resource_preview.h
index 67f83220d0..ea16c8fde0 100644
--- a/editor/editor_resource_preview.h
+++ b/editor/editor_resource_preview.h
@@ -43,6 +43,12 @@ class EditorResourcePreviewGenerator : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL1RC(bool, _handles, String)
+ GDVIRTUAL2RC(Ref<Texture2D>, _generate, RES, Vector2i)
+ GDVIRTUAL2RC(Ref<Texture2D>, _generate_from_path, String, Vector2i)
+ GDVIRTUAL0RC(bool, _generate_small_preview_automatically)
+ GDVIRTUAL0RC(bool, _can_generate_small_preview)
+
public:
virtual bool handles(const String &p_type) const;
virtual Ref<Texture2D> generate(const RES &p_from, const Size2 &p_size) const;
diff --git a/editor/editor_run_script.cpp b/editor/editor_run_script.cpp
index 83ce50a9f9..27923ef413 100644
--- a/editor/editor_run_script.cpp
+++ b/editor/editor_run_script.cpp
@@ -60,18 +60,8 @@ Node *EditorScript::get_scene() {
}
void EditorScript::_run() {
- Ref<Script> s = get_script();
- ERR_FAIL_COND(!s.is_valid());
- if (!get_script_instance()) {
- EditorNode::add_io_error(TTR("Couldn't instance script:") + "\n " + s->get_path() + "\n" + TTR("Did you forget the 'tool' keyword?"));
- return;
- }
-
- Callable::CallError ce;
- ce.error = Callable::CallError::CALL_OK;
- get_script_instance()->call("_run", nullptr, 0, ce);
- if (ce.error != Callable::CallError::CALL_OK) {
- EditorNode::add_io_error(TTR("Couldn't run script:") + "\n " + s->get_path() + "\n" + TTR("Did you forget the '_run' method?"));
+ if (!GDVIRTUAL_CALL(_run)) {
+ EditorNode::add_io_error(TTR("Couldn't run editor script, did you forget to override the '_run' method?"));
}
}
@@ -83,7 +73,7 @@ void EditorScript::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_root_node", "node"), &EditorScript::add_root_node);
ClassDB::bind_method(D_METHOD("get_scene"), &EditorScript::get_scene);
ClassDB::bind_method(D_METHOD("get_editor_interface"), &EditorScript::get_editor_interface);
- BIND_VMETHOD(MethodInfo("_run"));
+ GDVIRTUAL_BIND(_run);
}
EditorScript::EditorScript() {
diff --git a/editor/editor_run_script.h b/editor/editor_run_script.h
index c8412c3c92..6c7e37774d 100644
--- a/editor/editor_run_script.h
+++ b/editor/editor_run_script.h
@@ -41,6 +41,7 @@ class EditorScript : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL0(_run)
public:
void add_root_node(Node *p_node);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 3fc010c701..8d579753c2 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -704,8 +704,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("editors/tiles_editor/grid_color", Color(1.0, 0.5, 0.2, 0.5));
// Polygon editor
- _initial_set("editors/poly_editor/point_grab_radius", 8);
- _initial_set("editors/poly_editor/show_previous_outline", true);
+ _initial_set("editors/polygon_editor/point_grab_radius", 8);
+ _initial_set("editors/polygon_editor/show_previous_outline", true);
// Animation
_initial_set("editors/animation/autorename_animation_tracks", true);
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index 6d28b26623..86e15f5ff5 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -31,13 +31,13 @@
#ifndef EDITOR_SETTINGS_H
#define EDITOR_SETTINGS_H
+#include "core/input/shortcut.h"
#include "core/io/config_file.h"
#include "core/io/resource.h"
#include "core/object/class_db.h"
#include "core/os/thread_safe.h"
#include "core/string/translation.h"
#include "editor/editor_paths.h"
-#include "scene/gui/shortcut.h"
class EditorPlugin;
diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp
index 91f00deeaa..3f65b101f7 100644
--- a/editor/editor_spin_slider.cpp
+++ b/editor/editor_spin_slider.cpp
@@ -52,7 +52,7 @@ String EditorSpinSlider::get_text_value() const {
return TS->format_number(String::num(get_value(), Math::range_step_decimals(get_step())));
}
-void EditorSpinSlider::_gui_input(const Ref<InputEvent> &p_event) {
+void EditorSpinSlider::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (read_only) {
@@ -564,8 +564,6 @@ void EditorSpinSlider::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flat", "flat"), &EditorSpinSlider::set_flat);
ClassDB::bind_method(D_METHOD("is_flat"), &EditorSpinSlider::is_flat);
- ClassDB::bind_method(D_METHOD("_gui_input"), &EditorSpinSlider::_gui_input);
-
ADD_PROPERTY(PropertyInfo(Variant::STRING, "label"), "set_label", "get_label");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "read_only"), "set_read_only", "is_read_only");
diff --git a/editor/editor_spin_slider.h b/editor/editor_spin_slider.h
index c09d084e88..1bf8e8eef9 100644
--- a/editor/editor_spin_slider.h
+++ b/editor/editor_spin_slider.h
@@ -85,7 +85,7 @@ class EditorSpinSlider : public Range {
protected:
void _notification(int p_what);
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
static void _bind_methods();
void _grabber_mouse_entered();
void _grabber_mouse_exited();
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 4496180ddd..8c348731d6 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -1361,7 +1361,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_constant("label_width", "ColorPicker", 10 * EDSCALE);
theme->set_icon("screen_picker", "ColorPicker", theme->get_icon("ColorPick", "EditorIcons"));
theme->set_icon("add_preset", "ColorPicker", theme->get_icon("Add", "EditorIcons"));
- theme->set_icon("preset_bg", "ColorPicker", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
+ theme->set_icon("sample_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"));
@@ -1369,6 +1369,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
// ColorPickerButton
theme->set_icon("bg", "ColorPickerButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
+ // ColorPresetButton
+ Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2);
+ preset_sb->set_anti_aliased(false);
+ theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb);
+ theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon("GuiMiniCheckerboard", "EditorIcons"));
+ theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon("OverbrightIndicator", "EditorIcons"));
+
// Information on 3D viewport
Ref<StyleBoxFlat> style_info_3d_viewport = style_default->duplicate();
style_info_3d_viewport->set_bg_color(style_info_3d_viewport->get_bg_color() * Color(1, 1, 1, 0.5));
diff --git a/editor/editor_translation_parser.cpp b/editor/editor_translation_parser.cpp
index 27d428e682..df47b2d988 100644
--- a/editor/editor_translation_parser.cpp
+++ b/editor/editor_translation_parser.cpp
@@ -38,15 +38,10 @@
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()) {
- return ERR_UNAVAILABLE;
- }
-
- if (get_script_instance()->has_method("_parse_file")) {
- Array ids;
- Array ids_ctx_plural;
- get_script_instance()->call("_parse_file", p_path, ids, ids_ctx_plural);
+ Array ids;
+ Array ids_ctx_plural;
+ if (GDVIRTUAL_CALL(_parse_file, p_path, ids, ids_ctx_plural)) {
// Add user's extracted translatable messages.
for (int i = 0; i < ids.size(); i++) {
r_ids->append(ids[i]);
@@ -71,12 +66,8 @@ Error EditorTranslationParserPlugin::parse_file(const String &p_path, Vector<Str
}
void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_extensions) const {
- if (!get_script_instance()) {
- return;
- }
-
- if (get_script_instance()->has_method("_get_recognized_extensions")) {
- Array extensions = get_script_instance()->call("_get_recognized_extensions");
+ Vector<String> extensions;
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, extensions)) {
for (int i = 0; i < extensions.size(); i++) {
r_extensions->push_back(extensions[i]);
}
@@ -86,8 +77,8 @@ void EditorTranslationParserPlugin::get_recognized_extensions(List<String> *r_ex
}
void EditorTranslationParserPlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::NIL, "_parse_file", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::ARRAY, "msgids"), PropertyInfo(Variant::ARRAY, "msgids_context_plural")));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_recognized_extensions"));
+ GDVIRTUAL_BIND(_parse_file, "path", "msgids", "msgids_context_plural");
+ GDVIRTUAL_BIND(_get_recognized_extensions);
}
/////////////////////////
diff --git a/editor/editor_translation_parser.h b/editor/editor_translation_parser.h
index 7013bbb8c4..242ba33b55 100644
--- a/editor/editor_translation_parser.h
+++ b/editor/editor_translation_parser.h
@@ -32,7 +32,9 @@
#define EDITOR_TRANSLATION_PARSER_H
#include "core/error/error_list.h"
+#include "core/object/gdvirtual.gen.inc"
#include "core/object/ref_counted.h"
+#include "core/object/script_language.h"
class EditorTranslationParserPlugin : public RefCounted {
GDCLASS(EditorTranslationParserPlugin, RefCounted);
@@ -40,6 +42,9 @@ class EditorTranslationParserPlugin : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL3(_parse_file, String, Array, Array)
+ GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions)
+
public:
virtual Error parse_file(const String &p_path, Vector<String> *r_ids, Vector<Vector<String>> *r_ids_ctx_plural);
virtual void get_recognized_extensions(List<String> *r_extensions) const;
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index 8660289c40..d219f6e325 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -35,102 +35,131 @@ EditorImportPlugin::EditorImportPlugin() {
}
String EditorImportPlugin::get_importer_name() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_importer_name")), "");
- return get_script_instance()->call("_get_importer_name");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_importer_name, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(String(), "Unimplemented _get_importer_name in add-on.");
}
String EditorImportPlugin::get_visible_name() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_visible_name")), "");
- return get_script_instance()->call("_get_visible_name");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_visible_name, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(String(), "Unimplemented _get_visible_name in add-on.");
}
void EditorImportPlugin::get_recognized_extensions(List<String> *p_extensions) const {
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("_get_recognized_extensions")));
- Array extensions = get_script_instance()->call("_get_recognized_extensions");
- for (int i = 0; i < extensions.size(); i++) {
- p_extensions->push_back(extensions[i]);
+ Vector<String> extensions;
+
+ if (GDVIRTUAL_CALL(_get_recognized_extensions, extensions)) {
+ for (int i = 0; i < extensions.size(); i++) {
+ p_extensions->push_back(extensions[i]);
+ }
}
+ ERR_FAIL_MSG("Unimplemented _get_recognized_extensions in add-on.");
}
String EditorImportPlugin::get_preset_name(int p_idx) const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_preset_name")), "");
- return get_script_instance()->call("_get_preset_name", p_idx);
+ String ret;
+ if (GDVIRTUAL_CALL(_get_preset_name, p_idx, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(String(), "Unimplemented _get_preset_name in add-on.");
}
int EditorImportPlugin::get_preset_count() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_preset_count")), 0);
- return get_script_instance()->call("_get_preset_count");
+ int ret;
+ if (GDVIRTUAL_CALL(_get_preset_count, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(-1, "Unimplemented _get_preset_count in add-on.");
}
String EditorImportPlugin::get_save_extension() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_save_extension")), "");
- return get_script_instance()->call("_get_save_extension");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_save_extension, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(String(), "Unimplemented _get_save_extension in add-on.");
}
String EditorImportPlugin::get_resource_type() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_resource_type")), "");
- return get_script_instance()->call("_get_resource_type");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_resource_type, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(String(), "Unimplemented _get_resource_type in add-on.");
}
float EditorImportPlugin::get_priority() const {
- if (!(get_script_instance() && get_script_instance()->has_method("_get_priority"))) {
- return ResourceImporter::get_priority();
+ float ret;
+ if (GDVIRTUAL_CALL(_get_priority, ret)) {
+ return ret;
}
- return get_script_instance()->call("_get_priority");
+ ERR_FAIL_V_MSG(-1, "Unimplemented _get_priority in add-on.");
}
int EditorImportPlugin::get_import_order() const {
- if (!(get_script_instance() && get_script_instance()->has_method("_get_import_order"))) {
- return ResourceImporter::get_import_order();
+ int ret;
+ if (GDVIRTUAL_CALL(_get_import_order, ret)) {
+ return ret;
}
- return get_script_instance()->call("_get_import_order");
+ ERR_FAIL_V_MSG(-1, "Unimplemented _get_import_order in add-on.");
}
void EditorImportPlugin::get_import_options(List<ResourceImporter::ImportOption> *r_options, int p_preset) const {
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("_get_import_options")));
Array needed;
needed.push_back("name");
needed.push_back("default_value");
- Array options = get_script_instance()->call("_get_import_options", p_preset);
- for (int i = 0; i < options.size(); i++) {
- Dictionary d = options[i];
- ERR_FAIL_COND(!d.has_all(needed));
- String name = d["name"];
- Variant default_value = d["default_value"];
-
- PropertyHint hint = PROPERTY_HINT_NONE;
- if (d.has("property_hint")) {
- hint = (PropertyHint)d["property_hint"].operator int64_t();
- }
-
- String hint_string;
- if (d.has("hint_string")) {
- hint_string = d["hint_string"];
+ Array options;
+ if (GDVIRTUAL_CALL(_get_import_options, p_preset, options)) {
+ for (int i = 0; i < options.size(); i++) {
+ Dictionary d = options[i];
+ ERR_FAIL_COND(!d.has_all(needed));
+ String name = d["name"];
+ Variant default_value = d["default_value"];
+
+ PropertyHint hint = PROPERTY_HINT_NONE;
+ if (d.has("property_hint")) {
+ hint = (PropertyHint)d["property_hint"].operator int64_t();
+ }
+
+ String hint_string;
+ if (d.has("hint_string")) {
+ hint_string = d["hint_string"];
+ }
+
+ uint32_t usage = PROPERTY_USAGE_DEFAULT;
+ if (d.has("usage")) {
+ usage = d["usage"];
+ }
+
+ ImportOption option(PropertyInfo(default_value.get_type(), name, hint, hint_string, usage), default_value);
+ r_options->push_back(option);
}
-
- uint32_t usage = PROPERTY_USAGE_DEFAULT;
- if (d.has("usage")) {
- usage = d["usage"];
- }
-
- ImportOption option(PropertyInfo(default_value.get_type(), name, hint, hint_string, usage), default_value);
- r_options->push_back(option);
}
+
+ ERR_FAIL_MSG("Unimplemented _get_import_options in add-on.");
}
bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_option_visibility")), true);
Dictionary d;
Map<StringName, Variant>::Element *E = p_options.front();
while (E) {
d[E->key()] = E->get();
E = E->next();
}
- return get_script_instance()->call("_get_option_visibility", p_option, d);
+ bool visible;
+ if (GDVIRTUAL_CALL(_get_option_visibility, p_option, d, visible)) {
+ return visible;
+ }
+
+ ERR_FAIL_V_MSG(false, "Unimplemented _get_option_visibility in add-on.");
}
Error EditorImportPlugin::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_import")), ERR_UNAVAILABLE);
Dictionary options;
Array platform_variants, gen_files;
@@ -139,28 +168,33 @@ Error EditorImportPlugin::import(const String &p_source_file, const String &p_sa
options[E->key()] = E->get();
E = E->next();
}
- Error err = (Error)get_script_instance()->call("_import", p_source_file, p_save_path, options, platform_variants, gen_files).operator int64_t();
- for (int i = 0; i < platform_variants.size(); i++) {
- r_platform_variants->push_back(platform_variants[i]);
- }
- for (int i = 0; i < gen_files.size(); i++) {
- r_gen_files->push_back(gen_files[i]);
+ int err;
+ if (GDVIRTUAL_CALL(_import, p_source_file, p_save_path, options, platform_variants, gen_files, err)) {
+ Error ret_err = Error(err);
+
+ for (int i = 0; i < platform_variants.size(); i++) {
+ r_platform_variants->push_back(platform_variants[i]);
+ }
+ for (int i = 0; i < gen_files.size(); i++) {
+ r_gen_files->push_back(gen_files[i]);
+ }
+ return ret_err;
}
- return err;
+ ERR_FAIL_V_MSG(ERR_METHOD_NOT_FOUND, "Unimplemented _import in add-on.");
}
void EditorImportPlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_importer_name"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_visible_name"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_preset_count"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_preset_name", PropertyInfo(Variant::INT, "preset")));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_recognized_extensions"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_import_options", PropertyInfo(Variant::INT, "preset")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_save_extension"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_resource_type"));
- BIND_VMETHOD(MethodInfo(Variant::FLOAT, "_get_priority"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_import_order"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_get_option_visibility", PropertyInfo(Variant::STRING, "option"), PropertyInfo(Variant::DICTIONARY, "options")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_import", PropertyInfo(Variant::STRING, "source_file"), PropertyInfo(Variant::STRING, "save_path"), PropertyInfo(Variant::DICTIONARY, "options"), PropertyInfo(Variant::ARRAY, "platform_variants"), PropertyInfo(Variant::ARRAY, "gen_files")));
+ GDVIRTUAL_BIND(_get_importer_name)
+ GDVIRTUAL_BIND(_get_visible_name)
+ GDVIRTUAL_BIND(_get_preset_count)
+ GDVIRTUAL_BIND(_get_preset_name, "preset_index")
+ GDVIRTUAL_BIND(_get_recognized_extensions)
+ GDVIRTUAL_BIND(_get_import_options, "preset_index")
+ GDVIRTUAL_BIND(_get_save_extension)
+ GDVIRTUAL_BIND(_get_resource_type)
+ GDVIRTUAL_BIND(_get_priority)
+ GDVIRTUAL_BIND(_get_import_order)
+ GDVIRTUAL_BIND(_get_option_visibility, "option_name", "options")
+ GDVIRTUAL_BIND(_import, "source_file", "save_path", "options", "platform_variants", "gen_files");
}
diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h
index 345a40e96d..49c959ab44 100644
--- a/editor/import/editor_import_plugin.h
+++ b/editor/import/editor_import_plugin.h
@@ -39,6 +39,19 @@ class EditorImportPlugin : public ResourceImporter {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(String, _get_importer_name)
+ GDVIRTUAL0RC(String, _get_visible_name)
+ GDVIRTUAL0RC(int, _get_preset_count)
+ GDVIRTUAL1RC(String, _get_preset_name, int)
+ GDVIRTUAL0RC(Vector<String>, _get_recognized_extensions)
+ GDVIRTUAL1RC(Array, _get_import_options, int)
+ GDVIRTUAL0RC(String, _get_save_extension)
+ GDVIRTUAL0RC(String, _get_resource_type)
+ GDVIRTUAL0RC(float, _get_priority)
+ GDVIRTUAL0RC(int, _get_import_order)
+ GDVIRTUAL2RC(bool, _get_option_visibility, StringName, Dictionary)
+ GDVIRTUAL5RC(int, _import, String, String, Dictionary, Array, Array)
+
public:
EditorImportPlugin();
virtual String get_importer_name() const override;
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 492fa3f965..2b03ad928c 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -51,16 +51,17 @@
#include "scene/resources/world_margin_shape_3d.h"
uint32_t EditorSceneImporter::get_import_flags() const {
- if (get_script_instance()) {
- return get_script_instance()->call("_get_import_flags");
+ int ret;
+ if (GDVIRTUAL_CALL(_get_import_flags, ret)) {
+ return ret;
}
ERR_FAIL_V(0);
}
void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
- if (get_script_instance()) {
- Array arr = get_script_instance()->call("_get_extensions");
+ Vector<String> arr;
+ if (GDVIRTUAL_CALL(_get_extensions, arr)) {
for (int i = 0; i < arr.size(); i++) {
r_extensions->push_back(arr[i]);
}
@@ -71,16 +72,18 @@ void EditorSceneImporter::get_extensions(List<String> *r_extensions) const {
}
Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
- if (get_script_instance()) {
- return get_script_instance()->call("_import_scene", p_path, p_flags, p_bake_fps);
+ Object *ret;
+ if (GDVIRTUAL_CALL(_import_scene, p_path, p_flags, p_bake_fps, ret)) {
+ return Object::cast_to<Node>(ret);
}
ERR_FAIL_V(nullptr);
}
Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
- if (get_script_instance()) {
- return get_script_instance()->call("_import_animation", p_path, p_flags);
+ Ref<Animation> ret;
+ if (GDVIRTUAL_CALL(_import_animation, p_path, p_flags, p_bake_fps, ret)) {
+ return ret;
}
ERR_FAIL_V(nullptr);
@@ -101,15 +104,10 @@ void EditorSceneImporter::_bind_methods() {
ClassDB::bind_method(D_METHOD("import_scene_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_scene_from_other_importer);
ClassDB::bind_method(D_METHOD("import_animation_from_other_importer", "path", "flags", "bake_fps"), &EditorSceneImporter::import_animation_from_other_importer);
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_import_flags"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_extensions"));
-
- MethodInfo mi = MethodInfo(Variant::OBJECT, "_import_scene", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps"));
- mi.return_val.class_name = "Node";
- BIND_VMETHOD(mi);
- mi = MethodInfo(Variant::OBJECT, "_import_animation", PropertyInfo(Variant::STRING, "path"), PropertyInfo(Variant::INT, "flags"), PropertyInfo(Variant::INT, "bake_fps"));
- mi.return_val.class_name = "Animation";
- BIND_VMETHOD(mi);
+ GDVIRTUAL_BIND(_get_import_flags);
+ GDVIRTUAL_BIND(_get_extensions);
+ GDVIRTUAL_BIND(_import_scene, "path", "flags", "bake_fps");
+ GDVIRTUAL_BIND(_import_animation, "path", "flags", "bake_fps");
BIND_CONSTANT(IMPORT_SCENE);
BIND_CONSTANT(IMPORT_ANIMATION);
@@ -120,13 +118,14 @@ void EditorSceneImporter::_bind_methods() {
/////////////////////////////////
void EditorScenePostImport::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_post_import", PropertyInfo(Variant::OBJECT, "scene")));
+ GDVIRTUAL_BIND(_post_import, "scene")
ClassDB::bind_method(D_METHOD("get_source_file"), &EditorScenePostImport::get_source_file);
}
Node *EditorScenePostImport::post_import(Node *p_scene) {
- if (get_script_instance()) {
- return get_script_instance()->call("_post_import", p_scene);
+ Object *ret;
+ if (GDVIRTUAL_CALL(_post_import, p_scene, ret)) {
+ return Object::cast_to<Node>(ret);
}
return p_scene;
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 781beff689..542959be02 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -51,6 +51,11 @@ protected:
Node *import_scene_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
Ref<Animation> import_animation_from_other_importer(const String &p_path, uint32_t p_flags, int p_bake_fps);
+ GDVIRTUAL0RC(int, _get_import_flags)
+ GDVIRTUAL0RC(Vector<String>, _get_extensions)
+ GDVIRTUAL3R(Object *, _import_scene, String, uint32_t, uint32_t)
+ GDVIRTUAL3R(Ref<Animation>, _import_animation, String, uint32_t, uint32_t)
+
public:
enum ImportFlags {
IMPORT_SCENE = 1,
@@ -77,6 +82,8 @@ class EditorScenePostImport : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL1R(Object *, _post_import, Node *)
+
public:
String get_source_file() const;
virtual Node *post_import(Node *p_scene);
diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp
index 0d14347225..06f373c54f 100644
--- a/editor/import/scene_importer_mesh.cpp
+++ b/editor/import/scene_importer_mesh.cpp
@@ -110,6 +110,12 @@ String EditorSceneImporterMesh::get_surface_name(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), String());
return surfaces[p_surface].name;
}
+void EditorSceneImporterMesh::set_surface_name(int p_surface, const String &p_name) {
+ ERR_FAIL_INDEX(p_surface, surfaces.size());
+ surfaces.write[p_surface].name = p_name;
+ mesh.unref();
+}
+
Array EditorSceneImporterMesh::get_surface_blend_shape_arrays(int p_surface, int p_blend_shape) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
ERR_FAIL_INDEX_V(p_blend_shape, surfaces[p_surface].blend_shape_data.size(), Array());
@@ -140,6 +146,7 @@ Ref<Material> EditorSceneImporterMesh::get_surface_material(int p_surface) const
void EditorSceneImporterMesh::set_surface_material(int p_surface, const Ref<Material> &p_material) {
ERR_FAIL_INDEX(p_surface, surfaces.size());
surfaces.write[p_surface].material = p_material;
+ mesh.unref();
}
Basis EditorSceneImporterMesh::compute_rotation_matrix_from_ortho_6d(Vector3 p_x_raw, Vector3 p_y_raw) {
@@ -244,7 +251,7 @@ bool EditorSceneImporterMesh::has_mesh() const {
return mesh.is_valid();
}
-Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh(const Ref<Mesh> &p_base) {
+Ref<ArrayMesh> EditorSceneImporterMesh::get_mesh(const Ref<ArrayMesh> &p_base) {
ERR_FAIL_COND_V(surfaces.size() == 0, Ref<ArrayMesh>());
if (mesh.is_null()) {
@@ -838,7 +845,10 @@ void EditorSceneImporterMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_surface_lod_indices", "surface_idx", "lod_idx"), &EditorSceneImporterMesh::get_surface_lod_indices);
ClassDB::bind_method(D_METHOD("get_surface_material", "surface_idx"), &EditorSceneImporterMesh::get_surface_material);
- ClassDB::bind_method(D_METHOD("get_mesh"), &EditorSceneImporterMesh::get_mesh);
+ ClassDB::bind_method(D_METHOD("set_surface_name", "surface_idx", "name"), &EditorSceneImporterMesh::set_surface_name);
+ ClassDB::bind_method(D_METHOD("set_surface_material", "surface_idx", "material"), &EditorSceneImporterMesh::set_surface_material);
+
+ ClassDB::bind_method(D_METHOD("get_mesh", "base_mesh"), &EditorSceneImporterMesh::get_mesh, DEFVAL(Ref<ArrayMesh>()));
ClassDB::bind_method(D_METHOD("clear"), &EditorSceneImporterMesh::clear);
ClassDB::bind_method(D_METHOD("_set_data", "data"), &EditorSceneImporterMesh::_set_data);
diff --git a/editor/import/scene_importer_mesh.h b/editor/import/scene_importer_mesh.h
index 2488de7ed0..e57e479d8e 100644
--- a/editor/import/scene_importer_mesh.h
+++ b/editor/import/scene_importer_mesh.h
@@ -88,6 +88,7 @@ public:
Mesh::PrimitiveType get_surface_primitive_type(int p_surface);
String get_surface_name(int p_surface) const;
+ void set_surface_name(int p_surface, const String &p_name);
Array get_surface_arrays(int p_surface) const;
Array get_surface_blend_shape_arrays(int p_surface, int p_blend_shape) const;
int get_surface_lod_count(int p_surface) const;
@@ -112,7 +113,7 @@ public:
Size2i get_lightmap_size_hint() const;
bool has_mesh() const;
- Ref<ArrayMesh> get_mesh(const Ref<Mesh> &p_base = Ref<Mesh>());
+ Ref<ArrayMesh> get_mesh(const Ref<ArrayMesh> &p_base = Ref<ArrayMesh>());
void clear();
};
#endif // EDITOR_SCENE_IMPORTER_MESH_H
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index ef3b0588b8..36a814c30a 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -367,7 +367,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
edge_point = PosVertex();
return true;
} else {
- const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
if (!_is_line() && wip.size() > 1 && xform.xform(wip[0]).distance_to(xform.xform(cpoint)) < grab_threshold) {
//wip closed
@@ -502,7 +502,7 @@ void AbstractPolygon2DEditor::forward_canvas_draw_over_viewport(Control *p_overl
offset = _get_offset(j);
}
- if (!wip_active && j == edited_point.polygon && EDITOR_GET("editors/poly_editor/show_previous_outline")) {
+ if (!wip_active && j == edited_point.polygon && EDITOR_GET("editors/polygon_editor/show_previous_outline")) {
const Color col = Color(0.5, 0.5, 0.5); // FIXME polygon->get_outline_color();
const int n = pre_move_edit.size();
for (int i = 0; i < n - (is_closed ? 0 : 1); i++) {
@@ -625,7 +625,7 @@ AbstractPolygon2DEditor::Vertex AbstractPolygon2DEditor::get_active_point() cons
}
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const Vector2 &p_pos) const {
- const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
const int n_polygons = _get_polygon_count();
const Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
@@ -653,7 +653,7 @@ AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_point(const
}
AbstractPolygon2DEditor::PosVertex AbstractPolygon2DEditor::closest_edge_point(const Vector2 &p_pos) const {
- const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
const real_t eps = grab_threshold * 2;
const real_t eps2 = eps * eps;
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index b4e9f468de..830b010d01 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -345,7 +345,7 @@ void AnimationPlayerEditor::_animation_rename() {
void AnimationPlayerEditor::_animation_load() {
ERR_FAIL_COND(!player);
- file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILE);
+ file->set_file_mode(EditorFileDialog::FILE_MODE_OPEN_FILES);
file->clear_filters();
List<String> extensions;
@@ -355,7 +355,6 @@ void AnimationPlayerEditor::_animation_load() {
}
file->popup_file_dialog();
- current_option = RESOURCE_LOAD;
}
void AnimationPlayerEditor::_animation_save_in_path(const Ref<Resource> &p_resource, const String &p_path) {
@@ -416,7 +415,6 @@ void AnimationPlayerEditor::_animation_save_as(const Ref<Resource> &p_resource)
file->set_current_path(path);
file->set_title(TTR("Save Resource As..."));
file->popup_file_dialog();
- current_option = RESOURCE_SAVE;
}
void AnimationPlayerEditor::_animation_remove() {
@@ -718,44 +716,48 @@ void AnimationPlayerEditor::_animation_edit() {
}
}
-void AnimationPlayerEditor::_dialog_action(String p_path) {
- switch (current_option) {
- case RESOURCE_LOAD: {
- ERR_FAIL_COND(!player);
+void AnimationPlayerEditor::_save_animation(String p_file) {
+ String current = animation->get_item_text(animation->get_selected());
+ if (current != "") {
+ Ref<Animation> anim = player->get_animation(current);
- Ref<Resource> res = ResourceLoader::load(p_path, "Animation");
- ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + p_path + "'.");
- ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + p_path + "' is not Animation.");
+ ERR_FAIL_COND(!Object::cast_to<Resource>(*anim));
- String anim_name = p_path.get_file();
- int ext_pos = anim_name.rfind(".");
- if (ext_pos != -1) {
- anim_name = anim_name.substr(0, ext_pos);
- }
+ RES current_res = RES(Object::cast_to<Resource>(*anim));
- undo_redo->create_action(TTR("Load Animation"));
- undo_redo->add_do_method(player, "add_animation", anim_name, res);
- undo_redo->add_undo_method(player, "remove_animation", anim_name);
- if (player->has_animation(anim_name)) {
- undo_redo->add_undo_method(player, "add_animation", anim_name, player->get_animation(anim_name));
- }
- undo_redo->add_do_method(this, "_animation_player_changed", player);
- undo_redo->add_undo_method(this, "_animation_player_changed", player);
- undo_redo->commit_action();
- break;
- }
- case RESOURCE_SAVE: {
- String current = animation->get_item_text(animation->get_selected());
- if (current != "") {
- Ref<Animation> anim = player->get_animation(current);
+ _animation_save_in_path(current_res, p_file);
+ }
+}
- ERR_FAIL_COND(!Object::cast_to<Resource>(*anim));
+void AnimationPlayerEditor::_load_animations(Vector<String> p_files) {
+ ERR_FAIL_COND(!player);
- RES current_res = RES(Object::cast_to<Resource>(*anim));
+ for (int i = 0; i < p_files.size(); i++) {
+ String file = p_files[i];
- _animation_save_in_path(current_res, p_path);
- }
+ Ref<Resource> res = ResourceLoader::load(file, "Animation");
+ ERR_FAIL_COND_MSG(res.is_null(), "Cannot load Animation from file '" + file + "'.");
+ ERR_FAIL_COND_MSG(!res->is_class("Animation"), "Loaded resource from file '" + file + "' is not Animation.");
+ if (file.rfind("/") != -1) {
+ file = file.substr(file.rfind("/") + 1, file.length());
+ }
+ if (file.rfind("\\") != -1) {
+ file = file.substr(file.rfind("\\") + 1, file.length());
}
+
+ if (file.find(".") != -1) {
+ file = file.substr(0, file.find("."));
+ }
+
+ undo_redo->create_action(TTR("Load Animation"));
+ undo_redo->add_do_method(player, "add_animation", file, res);
+ undo_redo->add_undo_method(player, "remove_animation", file);
+ if (player->has_animation(file)) {
+ undo_redo->add_undo_method(player, "add_animation", file, player->get_animation(file));
+ }
+ undo_redo->add_do_method(this, "_animation_player_changed", player);
+ undo_redo->add_undo_method(this, "_animation_player_changed", player);
+ undo_redo->commit_action();
}
}
@@ -1220,7 +1222,7 @@ void AnimationPlayerEditor::_onion_skinning_menu(int p_option) {
}
}
-void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+void AnimationPlayerEditor::unhandled_key_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventKey> k = p_ev;
@@ -1497,7 +1499,6 @@ void AnimationPlayerEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_animation_player_changed"), &AnimationPlayerEditor::_animation_player_changed);
ClassDB::bind_method(D_METHOD("_list_changed"), &AnimationPlayerEditor::_list_changed);
ClassDB::bind_method(D_METHOD("_animation_duplicate"), &AnimationPlayerEditor::_animation_duplicate);
- ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &AnimationPlayerEditor::_unhandled_key_input);
ClassDB::bind_method(D_METHOD("_prepare_onion_layers_1"), &AnimationPlayerEditor::_prepare_onion_layers_1);
ClassDB::bind_method(D_METHOD("_prepare_onion_layers_2"), &AnimationPlayerEditor::_prepare_onion_layers_2);
@@ -1696,7 +1697,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
animation->connect("item_selected", callable_mp(this, &AnimationPlayerEditor::_animation_selected));
- file->connect("file_selected", callable_mp(this, &AnimationPlayerEditor::_dialog_action));
+ file->connect("file_selected", callable_mp(this, &AnimationPlayerEditor::_save_animation));
+ file->connect("files_selected", callable_mp(this, &AnimationPlayerEditor::_load_animations));
frame->connect("value_changed", callable_mp(this, &AnimationPlayerEditor::_seek_value_changed), make_binds(true, false));
scale->connect("text_submitted", callable_mp(this, &AnimationPlayerEditor::_scale_changed));
@@ -1736,6 +1738,8 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor, AnimationPlay
onion.capture.shader = Ref<Shader>(memnew(Shader));
onion.capture.shader->set_code(R"(
+// Animation editor onion skinning shader.
+
shader_type canvas_item;
uniform vec4 bkg_color;
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index 5c2348f86b..be80b7f4e3 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -112,7 +112,6 @@ class AnimationPlayerEditor : public VBoxContainer {
EditorFileDialog *file;
ConfirmationDialog *delete_dialog;
- int current_option;
struct BlendEditor {
AcceptDialog *dialog = nullptr;
@@ -185,7 +184,8 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_duplicate();
void _animation_resource_edit();
void _scale_changed(const String &p_scale);
- void _dialog_action(String p_file);
+ void _save_animation(String p_file);
+ void _load_animations(Vector<String> p_files);
void _seek_frame_changed(const String &p_frame);
void _seek_value_changed(float p_value, bool p_set = false, bool p_timeline_only = false);
void _blend_editor_next_changed(const int p_idx);
@@ -200,7 +200,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_key_editor_seek(float p_pos, bool p_drag, bool p_timeline_only = false);
void _animation_key_editor_anim_len_changed(float p_len);
- void _unhandled_key_input(const Ref<InputEvent> &p_ev);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_ev) override;
void _animation_tool_menu(int p_option);
void _onion_skinning_menu(int p_option);
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 785bab42cf..5405723d10 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -614,7 +614,7 @@ void EditorAssetLibrary::_update_repository_options() {
}
}
-void EditorAssetLibrary::_unhandled_key_input(const Ref<InputEvent> &p_event) {
+void EditorAssetLibrary::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
const Ref<InputEventKey> key = p_event;
@@ -1322,8 +1322,6 @@ void EditorAssetLibrary::disable_community_support() {
}
void EditorAssetLibrary::_bind_methods() {
- ClassDB::bind_method("_unhandled_key_input", &EditorAssetLibrary::_unhandled_key_input);
-
ADD_SIGNAL(MethodInfo("install_asset", PropertyInfo(Variant::STRING, "zip_path"), PropertyInfo(Variant::STRING, "name")));
}
diff --git a/editor/plugins/asset_library_editor_plugin.h b/editor/plugins/asset_library_editor_plugin.h
index c6ca1ecd4f..286546f962 100644
--- a/editor/plugins/asset_library_editor_plugin.h
+++ b/editor/plugins/asset_library_editor_plugin.h
@@ -299,7 +299,7 @@ class EditorAssetLibrary : public PanelContainer {
protected:
static void _bind_methods();
void _notification(int p_what);
- void _unhandled_key_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
public:
void disable_community_support();
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 477e066e87..ec3f899e78 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -472,7 +472,7 @@ real_t CanvasItemEditor::snap_angle(real_t p_target, real_t p_start) const {
}
}
-void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+void CanvasItemEditor::unhandled_key_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventKey> k = p_ev;
@@ -590,7 +590,7 @@ void CanvasItemEditor::_find_canvas_items_at_pos(const Point2 &p_pos, Node *p_no
return;
}
- const real_t grab_distance = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_distance = EDITOR_GET("editors/polygon_editor/point_grab_radius");
CanvasItem *canvas_item = Object::cast_to<CanvasItem>(p_node);
for (int i = p_node->get_child_count() - 1; i >= 0; i--) {
@@ -4918,7 +4918,7 @@ void CanvasItemEditor::_focus_selection(int p_op) {
void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_update_override_camera_button", "game_running"), &CanvasItemEditor::_update_override_camera_button);
ClassDB::bind_method("_get_editor_data", &CanvasItemEditor::_get_editor_data);
- ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
+
ClassDB::bind_method(D_METHOD("set_state"), &CanvasItemEditor::set_state);
ClassDB::bind_method(D_METHOD("update_viewport"), &CanvasItemEditor::update_viewport);
ClassDB::bind_method(D_METHOD("_zoom_on_position"), &CanvasItemEditor::_zoom_on_position);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index bff580315e..1965efbf30 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -455,7 +455,7 @@ private:
void _keying_changed();
- void _unhandled_key_input(const Ref<InputEvent> &p_ev);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_ev) override;
void _draw_text_at_position(Point2 p_position, String p_string, Side p_side);
void _draw_margin_at_position(int p_value, Point2 p_position, Side p_side);
diff --git a/editor/plugins/collision_polygon_3d_editor_plugin.cpp b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
index 5d5f78e0dc..8b354c33a1 100644
--- a/editor/plugins/collision_polygon_3d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_3d_editor_plugin.cpp
@@ -138,7 +138,7 @@ bool CollisionPolygon3DEditor::forward_spatial_gui_input(Camera3D *p_camera, con
Vector<Vector2> poly = node->call("get_polygon");
//first check if a point is to be added (segment split)
- real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
switch (mode) {
case MODE_CREATE: {
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index 07ff0eb346..4a22dc5b62 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -101,7 +101,7 @@ void CurveEditor::_notification(int p_what) {
}
}
-void CurveEditor::on_gui_input(const Ref<InputEvent> &p_event) {
+void CurveEditor::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb_ref = p_event;
if (mb_ref.is_valid()) {
const InputEventMouseButton &mb = **mb_ref;
@@ -757,10 +757,6 @@ void CurveEditor::_draw() {
}
}
-void CurveEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &CurveEditor::on_gui_input);
-}
-
//---------------
bool EditorInspectorPluginCurve::can_handle(Object *p_object) {
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index 2e8dd43d7e..c351f6ebe9 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -74,10 +74,8 @@ public:
protected:
void _notification(int p_what);
- static void _bind_methods();
-
private:
- void on_gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void on_preset_item_selected(int preset_id);
void _curve_changed();
void on_context_menu_item_selected(int action_id);
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 39ab3215ff..768f29e15a 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -32,7 +32,7 @@
#include "editor/editor_scale.h"
-void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
+void MeshEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event;
@@ -103,10 +103,6 @@ void MeshEditor::_button_pressed(Node *p_button) {
}
}
-void MeshEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &MeshEditor::_gui_input);
-}
-
MeshEditor::MeshEditor() {
viewport = memnew(SubViewport);
Ref<World3D> world_3d;
diff --git a/editor/plugins/mesh_editor_plugin.h b/editor/plugins/mesh_editor_plugin.h
index 455fcb5fe9..1e88b70202 100644
--- a/editor/plugins/mesh_editor_plugin.h
+++ b/editor/plugins/mesh_editor_plugin.h
@@ -64,8 +64,7 @@ class MeshEditor : public SubViewportContainer {
protected:
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
- static void _bind_methods();
+ void gui_input(const Ref<InputEvent> &p_event) override;
public:
void edit(Ref<Mesh> p_mesh);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index a42f94ed3d..5d1b4d8ead 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -105,9 +105,7 @@ void EditorNode3DGizmo::clear() {
}
void EditorNode3DGizmo::redraw() {
- if (get_script_instance() && get_script_instance()->has_method("_redraw")) {
- get_script_instance()->call("_redraw");
- } else {
+ if (!GDVIRTUAL_CALL(_redraw)) {
ERR_FAIL_COND(!gizmo_plugin);
gizmo_plugin->redraw(this);
}
@@ -118,8 +116,9 @@ void EditorNode3DGizmo::redraw() {
}
String EditorNode3DGizmo::get_handle_name(int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_handle_name")) {
- return get_script_instance()->call("_get_handle_name", p_id);
+ String ret;
+ if (GDVIRTUAL_CALL(_get_handle_name, p_id, ret)) {
+ return ret;
}
ERR_FAIL_COND_V(!gizmo_plugin, "");
@@ -127,8 +126,9 @@ String EditorNode3DGizmo::get_handle_name(int p_id) const {
}
bool EditorNode3DGizmo::is_handle_highlighted(int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_is_handle_highlighted")) {
- return get_script_instance()->call("_is_handle_highlighted", p_id);
+ bool success;
+ if (GDVIRTUAL_CALL(_is_handle_highlighted, p_id, success)) {
+ return success;
}
ERR_FAIL_COND_V(!gizmo_plugin, false);
@@ -136,8 +136,9 @@ bool EditorNode3DGizmo::is_handle_highlighted(int p_id) const {
}
Variant EditorNode3DGizmo::get_handle_value(int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_handle_value")) {
- return get_script_instance()->call("_get_handle_value", p_id);
+ Variant value;
+ if (GDVIRTUAL_CALL(_get_handle_value, p_id, value)) {
+ return value;
}
ERR_FAIL_COND_V(!gizmo_plugin, Variant());
@@ -145,8 +146,7 @@ Variant EditorNode3DGizmo::get_handle_value(int p_id) const {
}
void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p_point) {
- if (get_script_instance() && get_script_instance()->has_method("_set_handle")) {
- get_script_instance()->call("_set_handle", p_id, p_camera, p_point);
+ if (GDVIRTUAL_CALL(_set_handle, p_id, p_camera, p_point)) {
return;
}
@@ -155,8 +155,7 @@ void EditorNode3DGizmo::set_handle(int p_id, Camera3D *p_camera, const Point2 &p
}
void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p_cancel) {
- if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) {
- get_script_instance()->call("_commit_handle", p_id, p_restore, p_cancel);
+ if (GDVIRTUAL_CALL(_commit_handle, p_id, p_restore, p_cancel)) {
return;
}
@@ -165,8 +164,9 @@ void EditorNode3DGizmo::commit_handle(int p_id, const Variant &p_restore, bool p
}
int EditorNode3DGizmo::subgizmos_intersect_ray(Camera3D *p_camera, const Vector2 &p_point) const {
- if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_ray")) {
- return get_script_instance()->call("_subgizmos_intersect_ray", p_camera, p_point);
+ int id;
+ if (GDVIRTUAL_CALL(_subgizmos_intersect_ray, p_camera, p_point, id)) {
+ return id;
}
ERR_FAIL_COND_V(!gizmo_plugin, -1);
@@ -174,12 +174,14 @@ int EditorNode3DGizmo::subgizmos_intersect_ray(Camera3D *p_camera, const Vector2
}
Vector<int> EditorNode3DGizmo::subgizmos_intersect_frustum(const Camera3D *p_camera, const Vector<Plane> &p_frustum) const {
- if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_frustum")) {
- Array frustum;
- for (int i = 0; i < p_frustum.size(); i++) {
- frustum[i] = p_frustum[i];
- }
- return get_script_instance()->call("_subgizmos_intersect_frustum", p_camera, frustum);
+ TypedArray<Plane> frustum;
+ frustum.resize(p_frustum.size());
+ for (int i = 0; i < p_frustum.size(); i++) {
+ frustum[i] = p_frustum[i];
+ }
+ Vector<int> ret;
+ if (GDVIRTUAL_CALL(_subgizmos_intersect_frustum, p_camera, frustum, ret)) {
+ return ret;
}
ERR_FAIL_COND_V(!gizmo_plugin, Vector<int>());
@@ -187,8 +189,9 @@ Vector<int> EditorNode3DGizmo::subgizmos_intersect_frustum(const Camera3D *p_cam
}
Transform3D EditorNode3DGizmo::get_subgizmo_transform(int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_subgizmo_transform")) {
- return get_script_instance()->call("_get_subgizmo_transform", p_id);
+ Transform3D ret;
+ if (GDVIRTUAL_CALL(_get_subgizmo_transform, p_id, ret)) {
+ return ret;
}
ERR_FAIL_COND_V(!gizmo_plugin, Transform3D());
@@ -196,8 +199,7 @@ Transform3D EditorNode3DGizmo::get_subgizmo_transform(int p_id) const {
}
void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform) {
- if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) {
- get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform);
+ if (GDVIRTUAL_CALL(_set_subgizmo_transform, p_id, p_transform)) {
return;
}
@@ -206,18 +208,13 @@ void EditorNode3DGizmo::set_subgizmo_transform(int p_id, Transform3D p_transform
}
void EditorNode3DGizmo::commit_subgizmos(const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) {
- if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) {
- Array ids;
- for (int i = 0; i < p_ids.size(); i++) {
- ids[i] = p_ids[i];
- }
-
- Array restore;
- for (int i = 0; i < p_restore.size(); i++) {
- restore[i] = p_restore[i];
- }
+ TypedArray<Transform3D> restore;
+ restore.resize(p_restore.size());
+ for (int i = 0; i < p_restore.size(); i++) {
+ restore[i] = p_restore[i];
+ }
- get_script_instance()->call("_commit_subgizmos", ids, restore, p_cancel);
+ if (GDVIRTUAL_CALL(_commit_subgizmos, p_ids, restore, p_cancel)) {
return;
}
@@ -837,26 +834,19 @@ void EditorNode3DGizmo::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_subgizmo_selected"), &EditorNode3DGizmo::is_subgizmo_selected);
ClassDB::bind_method(D_METHOD("get_subgizmo_selection"), &EditorNode3DGizmo::get_subgizmo_selection);
- BIND_VMETHOD(MethodInfo("_redraw"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", PropertyInfo(Variant::INT, "id")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", PropertyInfo(Variant::INT, "id")));
-
- MethodInfo hvget(Variant::NIL, "_get_handle_value", PropertyInfo(Variant::INT, "id"));
- hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(hvget);
+ GDVIRTUAL_BIND(_redraw);
+ GDVIRTUAL_BIND(_get_handle_name, "id");
+ GDVIRTUAL_BIND(_is_handle_highlighted, "id");
- BIND_VMETHOD(MethodInfo("_set_handle", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point")));
- MethodInfo cm = MethodInfo("_commit_handle", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
- cm.default_arguments.push_back(false);
- BIND_VMETHOD(cm);
+ GDVIRTUAL_BIND(_get_handle_value, "id");
+ GDVIRTUAL_BIND(_set_handle, "id", "camera", "point");
+ GDVIRTUAL_BIND(_commit_handle, "id", "restore", "cancel");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_subgizmos_intersect_ray", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point")));
- BIND_VMETHOD(MethodInfo(Variant::PACKED_INT32_ARRAY, "_subgizmos_intersect_frustum", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::ARRAY, "frustum")));
- BIND_VMETHOD(MethodInfo(Variant::TRANSFORM3D, "_get_subgizmo_transform", PropertyInfo(Variant::INT, "id")));
- BIND_VMETHOD(MethodInfo("_set_subgizmo_transform", PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::TRANSFORM3D, "transform")));
- MethodInfo cs = MethodInfo("_commit_subgizmos", PropertyInfo(Variant::PACKED_INT32_ARRAY, "ids"), PropertyInfo(Variant::ARRAY, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
- cs.default_arguments.push_back(false);
- BIND_VMETHOD(cs);
+ GDVIRTUAL_BIND(_subgizmos_intersect_ray, "camera", "point");
+ GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "camera", "frustum");
+ GDVIRTUAL_BIND(_set_subgizmo_transform, "id", "transform");
+ GDVIRTUAL_BIND(_get_subgizmo_transform, "id");
+ GDVIRTUAL_BIND(_commit_subgizmos, "ids", "restores", "cancel");
}
EditorNode3DGizmo::EditorNode3DGizmo() {
@@ -1042,11 +1032,6 @@ Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::get_gizmo(Node3D *p_spatial) {
}
void EditorNode3DGizmoPlugin::_bind_methods() {
-#define GIZMO_REF PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "EditorNode3DGizmo")
-
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
- BIND_VMETHOD(MethodInfo(GIZMO_REF, "_create_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
-
ClassDB::bind_method(D_METHOD("create_material", "name", "color", "billboard", "on_top", "use_vertex_color"), &EditorNode3DGizmoPlugin::create_material, DEFVAL(false), DEFVAL(false), DEFVAL(false));
ClassDB::bind_method(D_METHOD("create_icon_material", "name", "texture", "on_top", "color"), &EditorNode3DGizmoPlugin::create_icon_material, DEFVAL(false), DEFVAL(Color(1, 1, 1, 1)));
ClassDB::bind_method(D_METHOD("create_handle_material", "name", "billboard", "texture"), &EditorNode3DGizmoPlugin::create_handle_material, DEFVAL(false), DEFVAL(Variant()));
@@ -1054,45 +1039,42 @@ void EditorNode3DGizmoPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorNode3DGizmoPlugin::get_material, DEFVAL(Ref<EditorNode3DGizmo>()));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_gizmo_name"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_priority"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_be_hidden"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_selectable_when_hidden"));
-
- BIND_VMETHOD(MethodInfo("_redraw", GIZMO_REF));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_handle_name", GIZMO_REF, PropertyInfo(Variant::INT, "id")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "id")));
+ GDVIRTUAL_BIND(_has_gizmo, "for_node_3d");
+ GDVIRTUAL_BIND(_create_gizmo, "for_node_3d");
- MethodInfo hvget(Variant::NIL, "_get_handle_value", GIZMO_REF, PropertyInfo(Variant::INT, "id"));
- hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(hvget);
+ GDVIRTUAL_BIND(_get_gizmo_name);
+ GDVIRTUAL_BIND(_get_priority);
+ GDVIRTUAL_BIND(_can_be_hidden);
+ GDVIRTUAL_BIND(_is_selectable_when_hidden);
- BIND_VMETHOD(MethodInfo("_set_handle", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point")));
- MethodInfo cm = MethodInfo("_commit_handle", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
- cm.default_arguments.push_back(false);
- BIND_VMETHOD(cm);
+ GDVIRTUAL_BIND(_redraw, "gizmo");
+ GDVIRTUAL_BIND(_get_handle_name, "gizmo", "handle_id");
+ GDVIRTUAL_BIND(_is_handle_highlighted, "gizmo", "handle_id");
+ GDVIRTUAL_BIND(_get_handle_value, "gizmo", "handle_id");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_subgizmos_intersect_ray", GIZMO_REF, PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::VECTOR2, "point")));
- BIND_VMETHOD(MethodInfo(Variant::PACKED_INT32_ARRAY, "_subgizmos_intersect_frustum", GIZMO_REF, PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera3D"), PropertyInfo(Variant::ARRAY, "frustum")));
- BIND_VMETHOD(MethodInfo(Variant::TRANSFORM3D, "_get_subgizmo_transform", GIZMO_REF, PropertyInfo(Variant::INT, "id")));
- BIND_VMETHOD(MethodInfo("_set_subgizmo_transform", GIZMO_REF, PropertyInfo(Variant::INT, "id"), PropertyInfo(Variant::TRANSFORM3D, "transform")));
- MethodInfo cs = MethodInfo("_commit_subgizmos", GIZMO_REF, PropertyInfo(Variant::PACKED_INT32_ARRAY, "ids"), PropertyInfo(Variant::ARRAY, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
- cs.default_arguments.push_back(false);
- BIND_VMETHOD(cs);
+ GDVIRTUAL_BIND(_set_handle, "gizmo", "handle_id", "camera", "screen_pos");
+ GDVIRTUAL_BIND(_commit_handle, "gizmo", "handle_id", "restore", "cancel");
-#undef GIZMO_REF
+ GDVIRTUAL_BIND(_subgizmos_intersect_ray, "gizmo", "camera", "screen_pos");
+ GDVIRTUAL_BIND(_subgizmos_intersect_frustum, "gizmo", "camera", "frustum_planes");
+ GDVIRTUAL_BIND(_get_subgizmo_transform, "gizmo", "subgizmo_id");
+ GDVIRTUAL_BIND(_set_subgizmo_transform, "gizmo", "subgizmo_id", "transform");
+ GDVIRTUAL_BIND(_commit_subgizmos, "gizmo", "ids", "restores", "cancel");
+ ;
}
bool EditorNode3DGizmoPlugin::has_gizmo(Node3D *p_spatial) {
- if (get_script_instance() && get_script_instance()->has_method("_has_gizmo")) {
- return get_script_instance()->call("_has_gizmo", p_spatial);
+ bool success;
+ if (GDVIRTUAL_CALL(_has_gizmo, p_spatial, success)) {
+ return success;
}
return false;
}
Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial) {
- if (get_script_instance() && get_script_instance()->has_method("_create_gizmo")) {
- return get_script_instance()->call("_create_gizmo", p_spatial);
+ Ref<EditorNode3DGizmo> ret;
+ if (GDVIRTUAL_CALL(_create_gizmo, p_spatial, ret)) {
+ return ret;
}
Ref<EditorNode3DGizmo> ref;
@@ -1103,106 +1085,100 @@ Ref<EditorNode3DGizmo> EditorNode3DGizmoPlugin::create_gizmo(Node3D *p_spatial)
}
bool EditorNode3DGizmoPlugin::can_be_hidden() const {
- if (get_script_instance() && get_script_instance()->has_method("_can_be_hidden")) {
- return get_script_instance()->call("_can_be_hidden");
+ bool ret;
+ if (GDVIRTUAL_CALL(_can_be_hidden, ret)) {
+ return ret;
}
return true;
}
bool EditorNode3DGizmoPlugin::is_selectable_when_hidden() const {
- if (get_script_instance() && get_script_instance()->has_method("_is_selectable_when_hidden")) {
- return get_script_instance()->call("_is_selectable_when_hidden");
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_selectable_when_hidden, ret)) {
+ return ret;
}
return false;
}
void EditorNode3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {
- if (get_script_instance() && get_script_instance()->has_method("_redraw")) {
- Ref<EditorNode3DGizmo> ref(p_gizmo);
- get_script_instance()->call("_redraw", ref);
- }
+ GDVIRTUAL_CALL(_redraw, p_gizmo);
}
bool EditorNode3DGizmoPlugin::is_handle_highlighted(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_is_handle_highlighted")) {
- return get_script_instance()->call("_is_handle_highlighted", p_gizmo, p_id);
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_handle_highlighted, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ return ret;
}
return false;
}
String EditorNode3DGizmoPlugin::get_handle_name(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_handle_name")) {
- return get_script_instance()->call("_get_handle_name", p_gizmo, p_id);
+ String ret;
+ if (GDVIRTUAL_CALL(_get_handle_name, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ return ret;
}
return "";
}
Variant EditorNode3DGizmoPlugin::get_handle_value(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_handle_value")) {
- return get_script_instance()->call("_get_handle_value", p_gizmo, p_id);
+ Variant ret;
+ if (GDVIRTUAL_CALL(_get_handle_value, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ return ret;
}
return Variant();
}
void EditorNode3DGizmoPlugin::set_handle(const EditorNode3DGizmo *p_gizmo, int p_id, Camera3D *p_camera, const Point2 &p_point) {
- if (get_script_instance() && get_script_instance()->has_method("_set_handle")) {
- get_script_instance()->call("_set_handle", p_gizmo, p_id, p_camera, p_point);
- }
+ GDVIRTUAL_CALL(_set_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_camera, p_point);
}
void EditorNode3DGizmoPlugin::commit_handle(const EditorNode3DGizmo *p_gizmo, int p_id, const Variant &p_restore, bool p_cancel) {
- if (get_script_instance() && get_script_instance()->has_method("_commit_handle")) {
- get_script_instance()->call("_commit_handle", p_gizmo, p_id, p_restore, p_cancel);
- }
+ GDVIRTUAL_CALL(_commit_handle, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_restore, p_cancel);
}
int EditorNode3DGizmoPlugin::subgizmos_intersect_ray(const EditorNode3DGizmo *p_gizmo, Camera3D *p_camera, const Vector2 &p_point) const {
- if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_ray")) {
- return get_script_instance()->call("_subgizmos_intersect_ray", p_camera, p_point);
+ int ret;
+ if (GDVIRTUAL_CALL(_subgizmos_intersect_ray, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, p_point, ret)) {
+ return ret;
}
return -1;
}
Vector<int> EditorNode3DGizmoPlugin::subgizmos_intersect_frustum(const EditorNode3DGizmo *p_gizmo, const Camera3D *p_camera, const Vector<Plane> &p_frustum) const {
- if (get_script_instance() && get_script_instance()->has_method("_subgizmos_intersect_frustum")) {
- Array frustum;
- for (int i = 0; i < p_frustum.size(); i++) {
- frustum[i] = p_frustum[i];
- }
- return get_script_instance()->call("_subgizmos_intersect_frustum", p_camera, frustum);
+ TypedArray<Transform3D> frustum;
+ frustum.resize(p_frustum.size());
+ for (int i = 0; i < p_frustum.size(); i++) {
+ frustum[i] = p_frustum[i];
+ }
+ Vector<int> ret;
+ if (GDVIRTUAL_CALL(_subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>(p_gizmo), p_camera, frustum, ret)) {
+ return ret;
}
return Vector<int>();
}
Transform3D EditorNode3DGizmoPlugin::get_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_subgizmo_transform")) {
- return get_script_instance()->call("_get_subgizmo_transform", p_id);
+ Transform3D ret;
+ if (GDVIRTUAL_CALL(_get_subgizmo_transform, Ref<EditorNode3DGizmo>(p_gizmo), p_id, ret)) {
+ return ret;
}
return Transform3D();
}
void EditorNode3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gizmo, int p_id, Transform3D p_transform) {
- if (get_script_instance() && get_script_instance()->has_method("_set_subgizmo_transform")) {
- get_script_instance()->call("_set_subgizmo_transform", p_id, p_transform);
- }
+ GDVIRTUAL_CALL(_set_subgizmo_transform, Ref<EditorNode3DGizmo>(p_gizmo), p_id, p_transform);
}
void EditorNode3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, const Vector<int> &p_ids, const Vector<Transform3D> &p_restore, bool p_cancel) {
- if (get_script_instance() && get_script_instance()->has_method("_commit_subgizmos")) {
- Array ids;
- for (int i = 0; i < p_ids.size(); i++) {
- ids[i] = p_ids[i];
- }
-
- Array restore;
- for (int i = 0; i < p_restore.size(); i++) {
- restore[i] = p_restore[i];
- }
-
- get_script_instance()->call("_commit_subgizmos", ids, restore, p_cancel);
+ TypedArray<Transform3D> restore;
+ restore.resize(p_restore.size());
+ for (int i = 0; i < p_restore.size(); i++) {
+ restore[i] = p_restore[i];
}
+
+ GDVIRTUAL_CALL(_commit_subgizmos, Ref<EditorNode3DGizmo>(p_gizmo), p_ids, restore, p_cancel);
}
void EditorNode3DGizmoPlugin::set_state(int p_state) {
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index 2cc0951557..415ed5da5c 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -33,10 +33,10 @@
#include "core/templates/local_vector.h"
#include "core/templates/ordered_hash_map.h"
+#include "scene/3d/camera_3d.h"
#include "scene/3d/node_3d.h"
#include "scene/3d/skeleton_3d.h"
-class Camera3D;
class Timer;
class EditorNode3DGizmoPlugin;
@@ -79,6 +79,19 @@ protected:
EditorNode3DGizmoPlugin *gizmo_plugin;
+ GDVIRTUAL0(_redraw)
+ GDVIRTUAL1RC(String, _get_handle_name, int)
+ GDVIRTUAL1RC(bool, _is_handle_highlighted, int)
+
+ GDVIRTUAL1RC(Variant, _get_handle_value, int)
+ GDVIRTUAL3(_set_handle, int, const Camera3D *, Vector2)
+ GDVIRTUAL3(_commit_handle, int, Variant, bool)
+
+ GDVIRTUAL2RC(int, _subgizmos_intersect_ray, const Camera3D *, Vector2)
+ GDVIRTUAL2RC(Vector<int>, _subgizmos_intersect_frustum, const Camera3D *, TypedArray<Plane>)
+ GDVIRTUAL1RC(Transform3D, _get_subgizmo_transform, int)
+ GDVIRTUAL2(_set_subgizmo_transform, int, Transform3D)
+ GDVIRTUAL3(_commit_subgizmos, Vector<int>, TypedArray<Transform3D>, bool)
public:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
@@ -145,6 +158,28 @@ protected:
virtual bool has_gizmo(Node3D *p_spatial);
virtual Ref<EditorNode3DGizmo> create_gizmo(Node3D *p_spatial);
+ GDVIRTUAL1RC(bool, _has_gizmo, Node3D *)
+ GDVIRTUAL1RC(Ref<EditorNode3DGizmo>, _create_gizmo, Node3D *)
+
+ GDVIRTUAL0RC(String, _get_gizmo_name)
+ GDVIRTUAL0RC(int, _get_priority)
+ GDVIRTUAL0RC(bool, _can_be_hidden)
+ GDVIRTUAL0RC(bool, _is_selectable_when_hidden)
+
+ GDVIRTUAL1(_redraw, Ref<EditorNode3DGizmo>)
+ GDVIRTUAL2RC(String, _get_handle_name, Ref<EditorNode3DGizmo>, int)
+ GDVIRTUAL2RC(bool, _is_handle_highlighted, Ref<EditorNode3DGizmo>, int)
+ GDVIRTUAL2RC(Variant, _get_handle_value, Ref<EditorNode3DGizmo>, int)
+
+ GDVIRTUAL4(_set_handle, Ref<EditorNode3DGizmo>, int, const Camera3D *, Vector2)
+ GDVIRTUAL4(_commit_handle, Ref<EditorNode3DGizmo>, int, Variant, bool)
+
+ GDVIRTUAL3RC(int, _subgizmos_intersect_ray, Ref<EditorNode3DGizmo>, const Camera3D *, Vector2)
+ GDVIRTUAL3RC(Vector<int>, _subgizmos_intersect_frustum, Ref<EditorNode3DGizmo>, const Camera3D *, TypedArray<Plane>)
+ GDVIRTUAL2RC(Transform3D, _get_subgizmo_transform, Ref<EditorNode3DGizmo>, int)
+ GDVIRTUAL3(_set_subgizmo_transform, Ref<EditorNode3DGizmo>, int, Transform3D)
+ GDVIRTUAL4(_commit_subgizmos, Ref<EditorNode3DGizmo>, Vector<int>, TypedArray<Transform3D>, bool)
+
public:
void create_material(const String &p_name, const Color &p_color, bool p_billboard = false, bool p_on_top = false, bool p_use_vertex_color = false);
void create_icon_material(const String &p_name, const Ref<Texture2D> &p_texture, bool p_on_top = false, const Color &p_albedo = Color(1, 1, 1, 1));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 4300a56ef0..291cafab2b 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -181,7 +181,7 @@ void ViewportRotationControl::_get_sorted_axis(Vector<Axis2D> &r_axis) {
r_axis.sort_custom<Axis2DCompare>();
}
-void ViewportRotationControl::_gui_input(Ref<InputEvent> p_event) {
+void ViewportRotationControl::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
const Ref<InputEventMouseButton> mb = p_event;
@@ -252,10 +252,6 @@ void ViewportRotationControl::set_viewport(Node3DEditorViewport *p_viewport) {
viewport = p_viewport;
}
-void ViewportRotationControl::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ViewportRotationControl::_gui_input);
-}
-
void Node3DEditorViewport::_update_camera(real_t p_interp_delta) {
bool is_orthogonal = camera->get_projection() == Camera3D::PROJECTION_ORTHOGONAL;
@@ -4428,7 +4424,7 @@ Node3DEditorViewport::~Node3DEditorViewport() {
//////////////////////////////////////////////////////////////
-void Node3DEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
+void Node3DEditorViewportContainer::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> mb = p_event;
@@ -4720,10 +4716,6 @@ Node3DEditorViewportContainer::View Node3DEditorViewportContainer::get_view() {
return view;
}
-void Node3DEditorViewportContainer::_bind_methods() {
- ClassDB::bind_method("_gui_input", &Node3DEditorViewportContainer::_gui_input);
-}
-
Node3DEditorViewportContainer::Node3DEditorViewportContainer() {
set_clip_contents(true);
view = VIEW_USE_1_VIEWPORT;
@@ -5606,6 +5598,8 @@ void Node3DEditor::_init_indicators() {
Ref<Shader> grid_shader = memnew(Shader);
grid_shader->set_code(R"(
+// 3D editor grid shader.
+
shader_type spatial;
render_mode unshaded;
@@ -5847,6 +5841,8 @@ void fragment() {
Ref<Shader> rotate_shader = memnew(Shader);
rotate_shader->set_code(R"(
+// 3D editor rotation manipulator gizmo shader.
+
shader_type spatial;
render_mode unshaded, depth_test_disabled;
@@ -5895,6 +5891,8 @@ void fragment() {
Ref<Shader> border_shader = memnew(Shader);
border_shader->set_code(R"(
+// 3D editor rotation manipulator gizmo shader (white outline).
+
shader_type spatial;
render_mode unshaded, depth_test_disabled;
@@ -6512,7 +6510,7 @@ void Node3DEditor::snap_selected_nodes_to_floor() {
}
}
-void Node3DEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
+void Node3DEditor::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!is_visible_in_tree()) {
@@ -6890,7 +6888,6 @@ void Node3DEditor::_register_all_gizmos() {
}
void Node3DEditor::_bind_methods() {
- ClassDB::bind_method("_unhandled_key_input", &Node3DEditor::_unhandled_key_input);
ClassDB::bind_method("_get_editor_data", &Node3DEditor::_get_editor_data);
ClassDB::bind_method("_request_gizmo", &Node3DEditor::_request_gizmo);
ClassDB::bind_method("_clear_subgizmo_selection", &Node3DEditor::_clear_subgizmo_selection);
@@ -7515,6 +7512,8 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) {
sun_direction_shader.instantiate();
sun_direction_shader->set_code(R"(
+// 3D editor Preview Sun direction shader.
+
shader_type canvas_item;
uniform vec3 sun_direction;
diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h
index 868b834993..59f3ec6fcd 100644
--- a/editor/plugins/node_3d_editor_plugin.h
+++ b/editor/plugins/node_3d_editor_plugin.h
@@ -74,9 +74,8 @@ class ViewportRotationControl : public Control {
const float AXIS_CIRCLE_RADIUS = 8.0f * EDSCALE;
protected:
- static void _bind_methods();
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _draw();
void _draw_axis(const Axis2D &p_axis);
void _get_sorted_axis(Vector<Axis2D> &r_axis);
@@ -470,11 +469,10 @@ private:
Vector2 drag_begin_pos;
Vector2 drag_begin_ratio;
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
protected:
void _notification(int p_what);
- static void _bind_methods();
public:
void set_view(View p_view);
@@ -744,7 +742,7 @@ private:
protected:
void _notification(int p_what);
//void _gui_input(InputEvent p_event);
- void _unhandled_key_input(Ref<InputEvent> p_event);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
static void _bind_methods();
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index 584eb84ecd..119ecddf63 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -70,7 +70,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
- real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 9377395418..782152b002 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -1041,7 +1041,7 @@ void Polygon2DEditor::_uv_draw() {
for (int i = 0; i < uvs.size(); i++) {
int next = uv_draw_max > 0 ? (i + 1) % uv_draw_max : 0;
- if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_DEF("editors/poly_editor/show_previous_outline", true)) {
+ if (i < uv_draw_max && uv_drag && uv_move_current == UV_MODE_EDIT_POINT && EDITOR_DEF("editors/polygon_editor/show_previous_outline", true)) {
uv_edit_draw->draw_line(mtx.xform(points_prev[i]), mtx.xform(points_prev[next]), prev_color, Math::round(EDSCALE));
}
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index cbea2405b8..eae6916a92 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -35,9 +35,6 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
-}
-
void ResourcePreloaderEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
load->set_icon(get_theme_icon(SNAME("Folder"), SNAME("EditorIcons")));
@@ -335,7 +332,6 @@ void ResourcePreloaderEditor::drop_data_fw(const Point2 &p_point, const Variant
}
void ResourcePreloaderEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ResourcePreloaderEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_update_library"), &ResourcePreloaderEditor::_update_library);
ClassDB::bind_method(D_METHOD("_remove_resource", "to_remove"), &ResourcePreloaderEditor::_remove_resource);
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index bc10b48a16..04ab458eb5 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -75,7 +75,7 @@ class ResourcePreloaderEditor : public PanelContainer {
protected:
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
+
static void _bind_methods();
public:
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 5c1e557286..3d2b3f4478 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -54,17 +54,17 @@
/*** SYNTAX HIGHLIGHTER ****/
String EditorSyntaxHighlighter::_get_name() const {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_get_name")) {
- return si->call("_get_name");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_name, ret)) {
+ return ret;
}
return "Unnamed";
}
Array EditorSyntaxHighlighter::_get_supported_languages() const {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_get_supported_languages")) {
- return si->call("_get_supported_languages");
+ Array ret;
+ if (GDVIRTUAL_CALL(_get_supported_languages, ret)) {
+ return ret;
}
return Array();
}
@@ -81,9 +81,8 @@ Ref<EditorSyntaxHighlighter> EditorSyntaxHighlighter::_create() const {
void EditorSyntaxHighlighter::_bind_methods() {
ClassDB::bind_method(D_METHOD("_get_edited_resource"), &EditorSyntaxHighlighter::_get_edited_resource);
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_supported_languages"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_supported_extentions"));
+ GDVIRTUAL_BIND(_get_name)
+ GDVIRTUAL_BIND(_get_supported_languages)
}
////
@@ -223,8 +222,6 @@ void ScriptEditorBase::_bind_methods() {
// TODO: This signal is no use for VisualScript.
ADD_SIGNAL(MethodInfo("search_in_files_requested", PropertyInfo(Variant::STRING, "text")));
ADD_SIGNAL(MethodInfo("replace_in_files_requested", PropertyInfo(Variant::STRING, "text")));
-
- BIND_VMETHOD(MethodInfo("_add_syntax_highlighter", PropertyInfo(Variant::OBJECT, "highlighter")));
}
static bool _is_built_in_script(Script *p_script) {
@@ -319,7 +316,7 @@ void ScriptEditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
k->get_keycode() == KEY_DOWN ||
k->get_keycode() == KEY_PAGEUP ||
k->get_keycode() == KEY_PAGEDOWN)) {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
search_box->accept_event();
}
}
@@ -2731,7 +2728,7 @@ void ScriptEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data, Co
}
}
-void ScriptEditor::_unhandled_key_input(const Ref<InputEvent> &p_event) {
+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()) {
@@ -3275,7 +3272,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_update_script_connections", &ScriptEditor::_update_script_connections);
ClassDB::bind_method("_help_class_open", &ScriptEditor::_help_class_open);
ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts);
- ClassDB::bind_method("_unhandled_key_input", &ScriptEditor::_unhandled_key_input);
+
ClassDB::bind_method("_update_members_overview", &ScriptEditor::_update_members_overview);
ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index e322828b6c..a57aeea5c0 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -56,6 +56,9 @@ private:
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(String, _get_name)
+ GDVIRTUAL0RC(Array, _get_supported_languages)
+
public:
virtual String _get_name() const;
virtual Array _get_supported_languages() const;
@@ -74,7 +77,7 @@ private:
public:
virtual void _update_cache() override;
- virtual Dictionary _get_line_syntax_highlighting(int p_line) override { return highlighter->get_line_syntax_highlighting(p_line); }
+ virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override { return highlighter->get_line_syntax_highlighting(p_line); }
virtual String _get_name() const override { return TTR("Standard"); }
@@ -408,7 +411,7 @@ class ScriptEditor : public PanelContainer {
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
- void _unhandled_key_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
void _script_list_gui_input(const Ref<InputEvent> &ev);
void _make_script_list_context_menu();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 2883dbbc81..400f9f560f 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -40,7 +40,7 @@
#include "scene/gui/margin_container.h"
#include "scene/gui/panel_container.h"
-void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
+void SpriteFramesEditor::gui_input(const Ref<InputEvent> &p_event) {
}
void SpriteFramesEditor::_open_sprite_sheet() {
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index e6c59e3533..17e30f0cab 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -147,7 +147,7 @@ class SpriteFramesEditor : public HSplitContainer {
protected:
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_3d_editor_plugin.cpp b/editor/plugins/texture_3d_editor_plugin.cpp
index 3987cdd6a0..bd1923f4ab 100644
--- a/editor/plugins/texture_3d_editor_plugin.cpp
+++ b/editor/plugins/texture_3d_editor_plugin.cpp
@@ -34,9 +34,6 @@
#include "core/io/resource_loader.h"
#include "editor/editor_settings.h"
-void Texture3DEditor::_gui_input(Ref<InputEvent> p_event) {
-}
-
void Texture3DEditor::_texture_rect_draw() {
texture_rect->draw_rect(Rect2(Point2(), texture_rect->get_size()), Color(1, 1, 1, 1));
}
@@ -79,6 +76,8 @@ void Texture3DEditor::_update_material() {
void Texture3DEditor::_make_shaders() {
shader.instantiate();
shader->set_code(R"(
+// Texture3DEditor preview shader.
+
shader_type canvas_item;
uniform sampler3D tex;
@@ -145,7 +144,6 @@ void Texture3DEditor::edit(Ref<Texture3D> p_texture) {
}
void Texture3DEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &Texture3DEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_layer_changed"), &Texture3DEditor::_layer_changed);
}
diff --git a/editor/plugins/texture_3d_editor_plugin.h b/editor/plugins/texture_3d_editor_plugin.h
index 9d90d3653f..855194e644 100644
--- a/editor/plugins/texture_3d_editor_plugin.h
+++ b/editor/plugins/texture_3d_editor_plugin.h
@@ -65,7 +65,6 @@ class Texture3DEditor : public Control {
protected:
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
diff --git a/editor/plugins/texture_layered_editor_plugin.cpp b/editor/plugins/texture_layered_editor_plugin.cpp
index 80359452ac..424e018a47 100644
--- a/editor/plugins/texture_layered_editor_plugin.cpp
+++ b/editor/plugins/texture_layered_editor_plugin.cpp
@@ -34,7 +34,7 @@
#include "core/io/resource_loader.h"
#include "editor/editor_settings.h"
-void TextureLayeredEditor::_gui_input(Ref<InputEvent> p_event) {
+void TextureLayeredEditor::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event;
@@ -106,6 +106,8 @@ void TextureLayeredEditor::_update_material() {
void TextureLayeredEditor::_make_shaders() {
shaders[0].instantiate();
shaders[0]->set_code(R"(
+// TextureLayeredEditor preview shader (2D array).
+
shader_type canvas_item;
uniform sampler2DArray tex;
@@ -118,6 +120,8 @@ void fragment() {
shaders[1].instantiate();
shaders[1]->set_code(R"(
+// TextureLayeredEditor preview shader (cubemap).
+
shader_type canvas_item;
uniform samplerCube tex;
@@ -132,6 +136,8 @@ void fragment() {
shaders[2].instantiate();
shaders[2]->set_code(R"(
+// TextureLayeredEditor preview shader (cubemap array).
+
shader_type canvas_item;
uniform samplerCubeArray tex;
@@ -214,7 +220,6 @@ void TextureLayeredEditor::edit(Ref<TextureLayered> p_texture) {
}
void TextureLayeredEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &TextureLayeredEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_layer_changed"), &TextureLayeredEditor::_layer_changed);
}
diff --git a/editor/plugins/texture_layered_editor_plugin.h b/editor/plugins/texture_layered_editor_plugin.h
index c4ced62fb9..a7fe4b94e9 100644
--- a/editor/plugins/texture_layered_editor_plugin.h
+++ b/editor/plugins/texture_layered_editor_plugin.h
@@ -67,7 +67,7 @@ class TextureLayeredEditor : public Control {
protected:
void _notification(int p_what);
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
static void _bind_methods();
public:
diff --git a/editor/plugins/tiles/tile_atlas_view.cpp b/editor/plugins/tiles/tile_atlas_view.cpp
index 13f04cb804..0add83f64d 100644
--- a/editor/plugins/tiles/tile_atlas_view.cpp
+++ b/editor/plugins/tiles/tile_atlas_view.cpp
@@ -41,7 +41,7 @@
#include "editor/editor_scale.h"
#include "editor/editor_settings.h"
-void TileAtlasView::_gui_input(const Ref<InputEvent> &p_event) {
+void TileAtlasView::gui_input(const Ref<InputEvent> &p_event) {
Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
drag_type = DRAG_TYPE_NONE;
@@ -548,8 +548,6 @@ void TileAtlasView::_notification(int p_what) {
}
void TileAtlasView::_bind_methods() {
- ClassDB::bind_method("_gui_input", &TileAtlasView::_gui_input);
-
ADD_SIGNAL(MethodInfo("transform_changed", PropertyInfo(Variant::FLOAT, "zoom"), PropertyInfo(Variant::VECTOR2, "scroll")));
}
@@ -582,7 +580,7 @@ TileAtlasView::TileAtlasView() {
center_container = memnew(CenterContainer);
center_container->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
center_container->set_anchors_preset(Control::PRESET_CENTER);
- center_container->connect("gui_input", callable_mp(this, &TileAtlasView::_gui_input));
+ center_container->connect("gui_input", callable_mp(this, &TileAtlasView::gui_input));
panel->add_child(center_container);
missing_source_label = memnew(Label);
diff --git a/editor/plugins/tiles/tile_atlas_view.h b/editor/plugins/tiles/tile_atlas_view.h
index b2046f4322..5b0df366ae 100644
--- a/editor/plugins/tiles/tile_atlas_view.h
+++ b/editor/plugins/tiles/tile_atlas_view.h
@@ -62,7 +62,7 @@ private:
void _update_zoom_and_panning(bool p_zoom_on_mouse_pos = false);
void _zoom_widget_changed();
void _center_view();
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
Map<Vector2, Map<int, Rect2i>> alternative_tiles_rect_cache;
void _update_alternative_tiles_rect_cache();
diff --git a/editor/plugins/tiles/tile_data_editors.cpp b/editor/plugins/tiles/tile_data_editors.cpp
index bab55df65a..d406c2514c 100644
--- a/editor/plugins/tiles/tile_data_editors.cpp
+++ b/editor/plugins/tiles/tile_data_editors.cpp
@@ -110,7 +110,7 @@ void DummyObject::clear_dummy_properties() {
void GenericTilePolygonEditor::_base_control_draw() {
ERR_FAIL_COND(!tile_set.is_valid());
- real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
Color grid_color = EditorSettings::get_singleton()->get("editors/tiles_editor/grid_color");
const Ref<Texture2D> handle = get_theme_icon(SNAME("EditorPathSharpHandle"), SNAME("EditorIcons"));
@@ -262,7 +262,7 @@ void GenericTilePolygonEditor::_advanced_menu_item_pressed(int p_item_pressed) {
}
void GenericTilePolygonEditor::_grab_polygon_point(Vector2 p_pos, const Transform2D &p_polygon_xform, int &r_polygon_index, int &r_point_index) {
- const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
r_polygon_index = -1;
r_point_index = -1;
float closest_distance = grab_threshold + 1.0;
@@ -280,7 +280,7 @@ void GenericTilePolygonEditor::_grab_polygon_point(Vector2 p_pos, const Transfor
}
void GenericTilePolygonEditor::_grab_polygon_segment_point(Vector2 p_pos, const Transform2D &p_polygon_xform, int &r_polygon_index, int &r_segment_index, Vector2 &r_point) {
- const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ const real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
Point2 point = p_polygon_xform.affine_inverse().xform(p_pos);
r_polygon_index = -1;
@@ -340,7 +340,7 @@ void GenericTilePolygonEditor::_snap_to_half_pixel(Point2 &r_point) {
}
void GenericTilePolygonEditor::_base_control_gui_input(Ref<InputEvent> p_event) {
- real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
+ real_t grab_threshold = EDITOR_GET("editors/polygon_editor/point_grab_radius");
hovered_polygon_index = -1;
hovered_point_index = -1;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index d84ed4828c..5b1da11f12 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -70,14 +70,15 @@ const int MAX_FLOAT_CONST_DEFS = sizeof(float_constant_defs) / sizeof(FloatConst
///////////////////
Control *VisualShaderNodePlugin::create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node) {
- if (get_script_instance()) {
- return get_script_instance()->call("_create_editor", p_parent_resource, p_node);
+ Object *ret;
+ if (GDVIRTUAL_CALL(_create_editor, p_parent_resource, p_node, ret)) {
+ return Object::cast_to<Control>(ret);
}
return nullptr;
}
void VisualShaderNodePlugin::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_create_editor", PropertyInfo(Variant::OBJECT, "parent_resource", PROPERTY_HINT_RESOURCE_TYPE, "Resource"), PropertyInfo(Variant::OBJECT, "for_node", PROPERTY_HINT_RESOURCE_TYPE, "VisualShaderNode")));
+ GDVIRTUAL_BIND(_create_editor, "parent_resource", "visual_shader_node");
}
///////////////////
@@ -3170,7 +3171,7 @@ void VisualShaderEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
ie->get_keycode() == KEY_DOWN ||
ie->get_keycode() == KEY_ENTER ||
ie->get_keycode() == KEY_KP_ENTER)) {
- members->call("_gui_input", ie);
+ members->gui_input(ie);
node_filter->accept_event();
}
}
diff --git a/editor/plugins/visual_shader_editor_plugin.h b/editor/plugins/visual_shader_editor_plugin.h
index fbfe1197a3..9f24c5af72 100644
--- a/editor/plugins/visual_shader_editor_plugin.h
+++ b/editor/plugins/visual_shader_editor_plugin.h
@@ -47,6 +47,8 @@ class VisualShaderNodePlugin : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL2RC(Object *, _create_editor, RES, Ref<VisualShaderNode>)
+
public:
virtual Control *create_editor(const Ref<Resource> &p_parent_resource, const Ref<VisualShaderNode> &p_node);
};
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 8d425a1e51..05cf3791f4 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -1887,7 +1887,7 @@ void ProjectManager::_update_project_buttons() {
erase_missing_btn->set_disabled(!_project_list->is_any_project_missing());
}
-void ProjectManager::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+void ProjectManager::unhandled_key_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventKey> k = p_ev;
@@ -2364,7 +2364,6 @@ void ProjectManager::_on_search_term_changed(const String &p_term) {
}
void ProjectManager::_bind_methods() {
- ClassDB::bind_method("_unhandled_key_input", &ProjectManager::_unhandled_key_input);
ClassDB::bind_method("_update_project_buttons", &ProjectManager::_update_project_buttons);
ClassDB::bind_method("_version_button_pressed", &ProjectManager::_version_button_pressed);
}
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 0fc69bd313..f45d34d461 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -121,7 +121,7 @@ class ProjectManager : public Control {
void _install_project(const String &p_zip_path, const String &p_title);
void _dim_window();
- void _unhandled_key_input(const Ref<InputEvent> &p_ev);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_ev) override;
void _files_dropped(PackedStringArray p_files, int p_screen);
void _version_button_pressed();
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 7338588d56..6ea9b9dfae 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -59,42 +59,33 @@
#include "scene/scene_string_names.h"
void EditorResourceConversionPlugin::_bind_methods() {
- MethodInfo mi;
- mi.name = "_convert";
- mi.return_val.type = Variant::OBJECT;
- mi.return_val.class_name = "Resource";
- mi.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE;
- mi.return_val.hint_string = "Resource";
- mi.arguments.push_back(mi.return_val);
- mi.arguments[0].name = "resource";
-
- BIND_VMETHOD(mi)
-
- mi.name = "_handles";
- mi.return_val = PropertyInfo(Variant::BOOL, "");
-
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_converts_to"));
+ GDVIRTUAL_BIND(_converts_to);
+ GDVIRTUAL_BIND(_handles, "resource");
+ GDVIRTUAL_BIND(_convert, "resource");
}
String EditorResourceConversionPlugin::converts_to() const {
- if (get_script_instance()) {
- return get_script_instance()->call("_converts_to");
+ String ret;
+ if (GDVIRTUAL_CALL(_converts_to, ret)) {
+ return ret;
}
return "";
}
bool EditorResourceConversionPlugin::handles(const Ref<Resource> &p_resource) const {
- if (get_script_instance()) {
- return get_script_instance()->call("_handles", p_resource);
+ bool ret;
+ if (GDVIRTUAL_CALL(_handles, p_resource, ret)) {
+ return ret;
}
return false;
}
Ref<Resource> EditorResourceConversionPlugin::convert(const Ref<Resource> &p_resource) const {
- if (get_script_instance()) {
- return get_script_instance()->call("_convert", p_resource);
+ RES ret;
+ if (GDVIRTUAL_CALL(_convert, p_resource, ret)) {
+ return ret;
}
return Ref<Resource>();
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 8a587b50b0..23771b7494 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -56,6 +56,10 @@ class EditorResourceConversionPlugin : public RefCounted {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(String, _converts_to)
+ GDVIRTUAL1RC(bool, _handles, RES)
+ GDVIRTUAL1RC(RES, _convert, RES)
+
public:
virtual String converts_to() const;
virtual bool handles(const Ref<Resource> &p_resource) const;
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 1272d064a0..f167ded4e7 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -48,7 +48,7 @@ void PropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index f8af3e8f36..fc3abbb87e 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -130,12 +130,6 @@ float EditorQuickOpen::_score_path(const String &p_search, const String &p_path)
return score * (1.0f - 0.1f * (float(pos) / file.length()));
}
- // Positive bias for matches close to the end of the path.
- pos = p_path.rfindn(p_search);
- if (pos != -1) {
- return 1.1f + 0.09 / (p_path.length() - pos + 1);
- }
-
// Similarity
return p_path.to_lower().similarity(p_search.to_lower());
}
@@ -170,7 +164,7 @@ void EditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
search_box->accept_event();
if (allow_multi_select) {
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 0b228c2695..2ec4a088a2 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -62,7 +62,7 @@ void SceneTreeDock::_quick_open() {
instantiate_scenes(quick_open->get_selected_files(), scene_tree->get_selected());
}
-void SceneTreeDock::_input(Ref<InputEvent> p_event) {
+void SceneTreeDock::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> mb = p_event;
@@ -72,7 +72,7 @@ void SceneTreeDock::_input(Ref<InputEvent> p_event) {
}
}
-void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
+void SceneTreeDock::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (get_focus_owner() && get_focus_owner()->is_text_field()) {
@@ -3163,8 +3163,7 @@ void SceneTreeDock::_create_remap_for_resource(RES p_resource, Map<RES, RES> &r_
void SceneTreeDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_owners"), &SceneTreeDock::_set_owners);
- ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &SceneTreeDock::_unhandled_key_input);
- ClassDB::bind_method(D_METHOD("_input"), &SceneTreeDock::_input);
+
ClassDB::bind_method(D_METHOD("_update_script_button"), &SceneTreeDock::_update_script_button);
ClassDB::bind_method(D_METHOD("instantiate"), &SceneTreeDock::instantiate);
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index ccdc0a3786..387a35acbb 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -210,8 +210,8 @@ class SceneTreeDock : public VBoxContainer {
void _node_prerenamed(Node *p_node, const String &p_new_name);
void _nodes_drag_begin();
- void _input(Ref<InputEvent> p_event);
- void _unhandled_key_input(Ref<InputEvent> p_event);
+ virtual void input(const Ref<InputEvent> &p_event) override;
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
void _import_subscene();
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 71802d1737..649caf5373 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -138,7 +138,7 @@ void EditorSettingsDialog::_notification(int p_what) {
}
}
-void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+void EditorSettingsDialog::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
const Ref<InputEventKey> k = p_event;
@@ -542,7 +542,6 @@ void EditorSettingsDialog::_editor_restart_close() {
}
void EditorSettingsDialog::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_update_shortcuts"), &EditorSettingsDialog::_update_shortcuts);
ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed);
}
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index c38fceedf1..2b6c9b3e1d 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -83,7 +83,7 @@ class EditorSettingsDialog : public AcceptDialog {
void _settings_property_edited(const String &p_name);
void _settings_save();
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
void _update_icons();
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 93b5941f64..e773b011a4 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -6,7 +6,7 @@
# Georgios Katsanakis <geo.elgeo@gmail.com>, 2019.
# Overloaded <manoschool@yahoo.gr>, 2019.
# Eternal Death <eternaldeath0001@gmail.com>, 2019.
-# Overloaded @ Orama Interactive http://orama-interactive.com/ <manoschool@yahoo.gr>, 2020.
+# Overloaded @ Orama Interactive https://orama-interactive.com/ <manoschool@yahoo.gr>, 2020.
# pandektis <pandektis@gmail.com>, 2020.
# KostasMSC <kargyris@athtech.gr>, 2020.
# lawfulRobot <czavantias@gmail.com>, 2020, 2021.
diff --git a/main/main.cpp b/main/main.cpp
index 6764332f16..a90dc121f3 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -571,8 +571,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
List<String>::Element *I = args.front();
- I = args.front();
-
while (I) {
I->get() = unescape_cmdline(I->get().strip_edges());
I = I->next();
@@ -2203,7 +2201,7 @@ bool Main::start() {
//standard helpers that can be changed from main config
String stretch_mode = GLOBAL_DEF_BASIC("display/window/stretch/mode", "disabled");
- String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore");
+ String stretch_aspect = GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep");
Size2i stretch_size = Size2i(GLOBAL_DEF_BASIC("display/window/size/width", 0),
GLOBAL_DEF_BASIC("display/window/size/height", 0));
@@ -2242,6 +2240,10 @@ bool Main::start() {
DisplayServer::get_singleton()->window_set_title(appname);
#endif
+ // Define a very small minimum window size to prevent bugs such as GH-37242.
+ // It can still be overridden by the user in a script.
+ DisplayServer::get_singleton()->window_set_min_size(Size2i(64, 64));
+
bool snap_controls = GLOBAL_DEF("gui/common/snap_controls_to_pixels", true);
sml->get_root()->set_snap_controls_to_pixels(snap_controls);
@@ -2262,7 +2264,7 @@ bool Main::start() {
"display/window/stretch/mode",
PROPERTY_HINT_ENUM,
"disabled,canvas_items,viewport"));
- GLOBAL_DEF_BASIC("display/window/stretch/aspect", "ignore");
+ GLOBAL_DEF_BASIC("display/window/stretch/aspect", "keep");
ProjectSettings::get_singleton()->set_custom_property_info("display/window/stretch/aspect",
PropertyInfo(Variant::STRING,
"display/window/stretch/aspect",
diff --git a/misc/dist/html/editor.html b/misc/dist/html/editor.html
index 347c22adf8..2cae215951 100644
--- a/misc/dist/html/editor.html
+++ b/misc/dist/html/editor.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
+<html xmlns="https://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no" />
diff --git a/misc/dist/html/full-size.html b/misc/dist/html/full-size.html
index 7afb6fdb6b..90e8167369 100644
--- a/misc/dist/html/full-size.html
+++ b/misc/dist/html/full-size.html
@@ -1,5 +1,5 @@
<!DOCTYPE html>
-<html xmlns='http://www.w3.org/1999/xhtml' lang='' xml:lang=''>
+<html xmlns='https://www.w3.org/1999/xhtml' lang='' xml:lang=''>
<head>
<meta charset='utf-8' />
<meta name='viewport' content='width=device-width, user-scalable=no' />
diff --git a/misc/dist/linux/org.godotengine.Godot.xml b/misc/dist/linux/org.godotengine.Godot.xml
index d4452018c4..2f06bb3639 100644
--- a/misc/dist/linux/org.godotengine.Godot.xml
+++ b/misc/dist/linux/org.godotengine.Godot.xml
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
-<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+<mime-info xmlns="https://specifications.freedesktop.org/shared-mime-info-spec">
<mime-type type="application/x-godot-project">
<comment>Godot Engine project</comment>
<sub-class-of type="text/plain"/>
diff --git a/misc/dist/windows/modpath.pas b/misc/dist/windows/modpath.pas
index ab09f18254..6d80d4201e 100644
--- a/misc/dist/windows/modpath.pas
+++ b/misc/dist/windows/modpath.pas
@@ -3,9 +3,9 @@
// Inno Setup Ver: 5.4.2
// Script Version: 1.4.2
// Author: Jared Breland <jbreland@legroom.net>
-// Homepage: http://www.legroom.net/software
+// Homepage: https://www.legroom.net/software
// License: GNU Lesser General Public License (LGPL), version 3
-// http://www.gnu.org/licenses/lgpl.html
+// https://www.gnu.org/licenses/lgpl.html
//
// Script Function:
// Allow modification of environmental path directly from Inno Setup installers
diff --git a/misc/hooks/canonicalize_filename.sh b/misc/hooks/canonicalize_filename.sh
index 5fcae6ee70..fe66999d8c 100755
--- a/misc/hooks/canonicalize_filename.sh
+++ b/misc/hooks/canonicalize_filename.sh
@@ -16,7 +16,7 @@
# specified filename. This should reproduce the results of the GNU version of
# readlink with the -f option.
#
-# Reference: http://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac
+# Reference: https://stackoverflow.com/questions/1055671/how-can-i-get-the-behavior-of-gnus-readlink-f-on-a-mac
canonicalize_filename () {
local target_file="$1"
local physical_directory=""
diff --git a/misc/scripts/black_format.sh b/misc/scripts/black_format.sh
index f93e8cbc2a..2ad9a23832 100755
--- a/misc/scripts/black_format.sh
+++ b/misc/scripts/black_format.sh
@@ -15,7 +15,7 @@ PY_FILES=$(find \( -path "./.git" \
\) -print)
black -l 120 $PY_FILES
-git diff > patch.patch
+git diff --color > patch.patch
# If no patch has been generated all is OK, clean up, and exit.
if [ ! -s patch.patch ] ; then
diff --git a/misc/scripts/clang_format.sh b/misc/scripts/clang_format.sh
index 63c66d41c3..bcd63aa73b 100755
--- a/misc/scripts/clang_format.sh
+++ b/misc/scripts/clang_format.sh
@@ -40,7 +40,7 @@ while IFS= read -rd '' f; do
done
done
-git diff > patch.patch
+git diff --color > patch.patch
# If no patch has been generated all is OK, clean up, and exit.
if [ ! -s patch.patch ] ; then
diff --git a/misc/scripts/file_format.sh b/misc/scripts/file_format.sh
index 795431cd28..0b49b175f2 100755
--- a/misc/scripts/file_format.sh
+++ b/misc/scripts/file_format.sh
@@ -42,7 +42,7 @@ while IFS= read -rd '' f; do
perl -i -ple 's/\s*$//g' "$f"
done
-git diff > patch.patch
+git diff --color > patch.patch
# If no patch has been generated all is OK, clean up, and exit.
if [ ! -s patch.patch ] ; then
diff --git a/misc/scripts/make_icons.sh b/misc/scripts/make_icons.sh
index b590f03d38..cbb9266055 100755
--- a/misc/scripts/make_icons.sh
+++ b/misc/scripts/make_icons.sh
@@ -20,7 +20,7 @@ zip godot-icons.zip icon*.png
icotool -c -o godot-icon.ico icon{16,24,32,48,64,128,256}.png
# icns for macOS
-# Only some sizes: http://iconhandbook.co.uk/reference/chart/osx/
+# Only some sizes: https://iconhandbook.co.uk/reference/chart/osx/
png2icns godot-icon.icns icon{16,32,128,256,512,1024}.png
rm -f icon*.png
diff --git a/modules/bullet/rigid_body_bullet.h b/modules/bullet/rigid_body_bullet.h
index 5e102d8b05..01ac1e4836 100644
--- a/modules/bullet/rigid_body_bullet.h
+++ b/modules/bullet/rigid_body_bullet.h
@@ -301,7 +301,7 @@ public:
void reload_axis_lock();
/// Doc:
- /// https://web.archive.org/web/20180404091446/http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
+ /// https://web.archive.org/web/20180404091446/https://www.bulletphysics.org/mediawiki-1.5.8/index.php/Anti_tunneling_by_Motion_Clamping
void set_continuous_collision_detection(bool p_enable);
bool is_continuous_collision_detection_enabled() const;
diff --git a/modules/enet/doc_classes/ENetConnection.xml b/modules/enet/doc_classes/ENetConnection.xml
index c2a85ffdf8..00469ab44c 100644
--- a/modules/enet/doc_classes/ENetConnection.xml
+++ b/modules/enet/doc_classes/ENetConnection.xml
@@ -40,6 +40,7 @@
<description>
Sets the compression method used for network packets. These have different tradeoffs of compression speed versus bandwidth, you may need to test which one works best for your use case if you use compression at all.
[b]Note:[/b] Most games' network design involve sending many small packets frequently (smaller than 4 KB each). If in doubt, it is recommended to keep the default compression algorithm as it works best on these small packets.
+ [b]Note:[/b] The compression mode must be set to the same value on both the server and all its clients. Clients will fail to connect if the compression mode set on the client differs from the one set on the server.
</description>
</method>
<method name="connect_to_host">
@@ -155,7 +156,7 @@
ENet's built-in range encoding. Works well on small packets, but is not the most efficient algorithm on packets larger than 4 KB.
</constant>
<constant name="COMPRESS_FASTLZ" value="2" enum="CompressionMode">
- [url=http://fastlz.org/]FastLZ[/url] compression. This option uses less CPU resources compared to [constant COMPRESS_ZLIB], at the expense of using more bandwidth.
+ [url=https://fastlz.org/]FastLZ[/url] compression. This option uses less CPU resources compared to [constant COMPRESS_ZLIB], at the expense of using more bandwidth.
</constant>
<constant name="COMPRESS_ZLIB" value="3" enum="CompressionMode">
[url=https://www.zlib.net/]Zlib[/url] compression. This option uses less bandwidth compared to [constant COMPRESS_FASTLZ], at the expense of using more CPU resources.
diff --git a/modules/fbx/fbx_parser/FBXParser.cpp b/modules/fbx/fbx_parser/FBXParser.cpp
index a92b23f4ee..d9ef025a16 100644
--- a/modules/fbx/fbx_parser/FBXParser.cpp
+++ b/modules/fbx/fbx_parser/FBXParser.cpp
@@ -575,7 +575,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char *&data, const cha
std::copy(data, end, buff.begin());
} else if (encmode == 1) {
// zlib/deflate, next comes ZIP head (0x78 0x01)
- // see http://www.ietf.org/rfc/rfc1950.txt
+ // see https://www.ietf.org/rfc/rfc1950.txt
z_stream zstream;
zstream.opaque = Z_NULL;
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 0b1cb5d502..8b9bd2659d 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -45,7 +45,7 @@ static bool _is_bin_symbol(char32_t c) {
return (c == '0' || c == '1');
}
-Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting(int p_line) {
+Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
Dictionary color_map;
Type next_type = NONE;
diff --git a/modules/gdscript/editor/gdscript_highlighter.h b/modules/gdscript/editor/gdscript_highlighter.h
index d07c182aa6..fabd64dab8 100644
--- a/modules/gdscript/editor/gdscript_highlighter.h
+++ b/modules/gdscript/editor/gdscript_highlighter.h
@@ -80,7 +80,7 @@ private:
public:
virtual void _update_cache() override;
- virtual Dictionary _get_line_syntax_highlighting(int p_line) override;
+ virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override;
virtual String _get_name() const override;
virtual Array _get_supported_languages() const override;
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index d21caf4389..af872e49e2 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -1117,7 +1117,6 @@ GDScriptParser::EnumNode *GDScriptParser::parse_enum() {
}
item.custom_value = value;
}
- item.rightmost_column = previous.rightmost_column;
item.index = enum_node->values.size();
enum_node->values.push_back(item);
@@ -2951,7 +2950,7 @@ void GDScriptParser::get_class_doc_comment(int p_line, String &p_brief, String &
} else {
/* Syntax:
- @tutorial ( The Title Here ) : http://the.url/
+ @tutorial ( The Title Here ) : https://the.url/
^ open ^ close ^ colon ^ url
*/
int open_bracket_pos = begin_scan, close_bracket_pos = 0;
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 3e8ea19045..7a826897a9 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -346,8 +346,8 @@ private:
Error _serialize_extensions(Ref<GLTFState> state) const;
public:
- // http://www.itu.int/rec/R-REC-BT.601
- // http://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.601-7-201103-I!!PDF-E.pdf
+ // https://www.itu.int/rec/R-REC-BT.601
+ // https://www.itu.int/dms_pubrec/itu-r/rec/bt/R-REC-BT.601-7-201103-I!!PDF-E.pdf
static constexpr float R_BRIGHTNESS_COEFF = 0.299f;
static constexpr float G_BRIGHTNESS_COEFF = 0.587f;
static constexpr float B_BRIGHTNESS_COEFF = 0.114f;
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index f101c43e89..2331a12d0f 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -790,7 +790,7 @@ void GridMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
if (k.is_valid() && (k->get_keycode() == KEY_UP || k->get_keycode() == KEY_DOWN || k->get_keycode() == KEY_PAGEUP || k->get_keycode() == KEY_PAGEDOWN)) {
// Forward the key input to the ItemList so it can be scrolled
- mesh_library_palette->call("_gui_input", k);
+ mesh_library_palette->gui_input(k);
search_box->accept_event();
}
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
index 6ce148d51e..e619ad74e9 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/StringExtensions.cs
@@ -575,7 +575,7 @@ namespace Godot
/// <summary>
/// If the string is a path to a file or directory, return <see langword="true"/> if the path is absolute.
/// </summary>
- public static bool IsAbsPath(this string instance)
+ public static bool IsAbsolutePath(this string instance)
{
if (string.IsNullOrEmpty(instance))
return false;
@@ -590,7 +590,7 @@ namespace Godot
/// </summary>
public static bool IsRelPath(this string instance)
{
- return !IsAbsPath(instance);
+ return !IsAbsolutePath(instance);
}
/// <summary>
@@ -1103,6 +1103,17 @@ namespace Godot
}
/// <summary>
+ /// Returns a simplified canonical path.
+ /// </summary>
+ public static string SimplifyPath(this string instance)
+ {
+ return godot_icall_String_simplify_path(instance);
+ }
+
+ [MethodImpl(MethodImplOptions.InternalCall)]
+ internal extern static string godot_icall_String_simplify_path(string str);
+
+ /// <summary>
/// Split the string by a divisor string, return an array of the substrings.
/// Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
/// </summary>
diff --git a/modules/mono/glue/string_glue.cpp b/modules/mono/glue/string_glue.cpp
index 18a9221f89..bb80a836ad 100644
--- a/modules/mono/glue/string_glue.cpp
+++ b/modules/mono/glue/string_glue.cpp
@@ -67,6 +67,11 @@ MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
return GDMonoMarshal::mono_string_from_godot(ret);
}
+MonoString *godot_icall_String_simplify_path(MonoString *p_str) {
+ String ret = GDMonoMarshal::mono_string_to_godot(p_str).simplify_path();
+ return GDMonoMarshal::mono_string_from_godot(ret);
+}
+
void godot_register_string_icalls() {
GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", godot_icall_String_md5_buffer);
GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", godot_icall_String_md5_text);
@@ -74,6 +79,7 @@ void godot_register_string_icalls() {
GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", godot_icall_String_rfindn);
GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", godot_icall_String_sha256_buffer);
GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", godot_icall_String_sha256_text);
+ GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_simplify_path", godot_icall_String_simplify_path);
}
#endif // MONO_GLUE_ENABLED
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 60047545c4..cf76c23926 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -91,7 +91,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
// The object was just created, no script instance binding should have been attached
CRASH_COND(CSharpLanguage::has_instance_binding(unmanaged));
- void *data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
+ void *data;
+ {
+ MutexLock lock(CSharpLanguage::get_singleton()->get_language_bind_mutex());
+ data = (void *)CSharpLanguage::get_singleton()->insert_script_binding(unmanaged, script_binding);
+ }
// Should be thread safe because the object was just created and nothing else should be referencing it
CSharpLanguage::set_instance_binding(unmanaged, data);
diff --git a/modules/text_server_adv/SCsub b/modules/text_server_adv/SCsub
index d06c5c2f14..1fcbb7aaca 100644
--- a/modules/text_server_adv/SCsub
+++ b/modules/text_server_adv/SCsub
@@ -15,7 +15,7 @@ def make_icu_data(target, source, env):
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("/* (C) 2016 and later: Unicode, Inc. and others. */\n")
- g.write("/* License & terms of use: http://www.unicode.org/copyright.html */\n")
+ g.write("/* License & terms of use: https://www.unicode.org/copyright.html */\n")
g.write("#ifndef _ICU_DATA_H\n")
g.write("#define _ICU_DATA_H\n")
g.write('#include "unicode/utypes.h"\n')
diff --git a/modules/text_server_adv/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp
index df7b42eac6..1731fb6223 100644
--- a/modules/text_server_adv/bitmap_font_adv.cpp
+++ b/modules/text_server_adv/bitmap_font_adv.cpp
@@ -225,7 +225,7 @@ hb_font_t *hb_bmp_font_create(BitmapFontDataAdvanced *p_face, int p_size, hb_des
Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_base_size) {
_THREAD_SAFE_METHOD_
//fnt format used by angelcode bmfont
- //http://www.angelcode.com/products/bmfont/
+ //https://www.angelcode.com/products/bmfont/
FileAccess *f = FileAccess::open(p_filename, FileAccess::READ);
ERR_FAIL_COND_V_MSG(!f, ERR_FILE_NOT_FOUND, "Can't open font: " + p_filename + ".");
diff --git a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml
index 8aa34f8cae..b574576856 100644
--- a/modules/visual_script/doc_classes/VisualScriptCustomNode.xml
+++ b/modules/visual_script/doc_classes/VisualScriptCustomNode.xml
@@ -9,118 +9,118 @@
<tutorials>
</tutorials>
<methods>
- <method name="_get_caption" qualifiers="virtual">
+ <method name="_get_caption" qualifiers="virtual const">
<return type="String" />
<description>
Return the node's title.
</description>
</method>
- <method name="_get_category" qualifiers="virtual">
+ <method name="_get_category" qualifiers="virtual const">
<return type="String" />
<description>
Return the node's category.
</description>
</method>
- <method name="_get_input_value_port_count" qualifiers="virtual">
+ <method name="_get_input_value_port_count" qualifiers="virtual const">
<return type="int" />
<description>
Return the count of input value ports.
</description>
</method>
- <method name="_get_input_value_port_hint" qualifiers="virtual">
+ <method name="_get_input_value_port_hint" qualifiers="virtual const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="input_idx" type="int" />
<description>
Return the specified input port's hint. See the [enum @GlobalScope.PropertyHint] hints.
</description>
</method>
- <method name="_get_input_value_port_hint_string" qualifiers="virtual">
+ <method name="_get_input_value_port_hint_string" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="input_idx" type="int" />
<description>
Return the specified input port's hint string.
</description>
</method>
- <method name="_get_input_value_port_name" qualifiers="virtual">
+ <method name="_get_input_value_port_name" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="input_idx" type="int" />
<description>
Return the specified input port's name.
</description>
</method>
- <method name="_get_input_value_port_type" qualifiers="virtual">
+ <method name="_get_input_value_port_type" qualifiers="virtual const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="input_idx" type="int" />
<description>
Return the specified input port's type. See the [enum Variant.Type] values.
</description>
</method>
- <method name="_get_output_sequence_port_count" qualifiers="virtual">
+ <method name="_get_output_sequence_port_count" qualifiers="virtual const">
<return type="int" />
<description>
Return the amount of output [b]sequence[/b] ports.
</description>
</method>
- <method name="_get_output_sequence_port_text" qualifiers="virtual">
+ <method name="_get_output_sequence_port_text" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="seq_idx" type="int" />
<description>
Return the specified [b]sequence[/b] output's name.
</description>
</method>
- <method name="_get_output_value_port_count" qualifiers="virtual">
+ <method name="_get_output_value_port_count" qualifiers="virtual const">
<return type="int" />
<description>
Return the amount of output value ports.
</description>
</method>
- <method name="_get_output_value_port_hint" qualifiers="virtual">
+ <method name="_get_output_value_port_hint" qualifiers="virtual const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="output_idx" type="int" />
<description>
Return the specified output port's hint. See the [enum @GlobalScope.PropertyHint] hints.
</description>
</method>
- <method name="_get_output_value_port_hint_string" qualifiers="virtual">
+ <method name="_get_output_value_port_hint_string" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="output_idx" type="int" />
<description>
Return the specified output port's hint string.
</description>
</method>
- <method name="_get_output_value_port_name" qualifiers="virtual">
+ <method name="_get_output_value_port_name" qualifiers="virtual const">
<return type="String" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="output_idx" type="int" />
<description>
Return the specified output port's name.
</description>
</method>
- <method name="_get_output_value_port_type" qualifiers="virtual">
+ <method name="_get_output_value_port_type" qualifiers="virtual const">
<return type="int" />
- <argument index="0" name="idx" type="int" />
+ <argument index="0" name="output_idx" type="int" />
<description>
Return the specified output port's type. See the [enum Variant.Type] values.
</description>
</method>
- <method name="_get_text" qualifiers="virtual">
+ <method name="_get_text" qualifiers="virtual const">
<return type="String" />
<description>
Return the custom node's text, which is shown right next to the input [b]sequence[/b] port (if there is none, on the place that is usually taken by it).
</description>
</method>
- <method name="_get_working_memory_size" qualifiers="virtual">
+ <method name="_get_working_memory_size" qualifiers="virtual const">
<return type="int" />
<description>
Return the size of the custom node's working memory. See [method _step] for more details.
</description>
</method>
- <method name="_has_input_sequence_port" qualifiers="virtual">
+ <method name="_has_input_sequence_port" qualifiers="virtual const">
<return type="bool" />
<description>
Return whether the custom node has an input [b]sequence[/b] port.
</description>
</method>
- <method name="_step" qualifiers="virtual">
+ <method name="_step" qualifiers="virtual const">
<return type="Variant" />
<argument index="0" name="inputs" type="Array" />
<argument index="1" name="outputs" type="Array" />
diff --git a/modules/visual_script/doc_classes/VisualScriptSubCall.xml b/modules/visual_script/doc_classes/VisualScriptSubCall.xml
index 374e7d0f35..f54887b09c 100644
--- a/modules/visual_script/doc_classes/VisualScriptSubCall.xml
+++ b/modules/visual_script/doc_classes/VisualScriptSubCall.xml
@@ -9,13 +9,6 @@
<tutorials>
</tutorials>
<methods>
- <method name="_subcall" qualifiers="virtual">
- <return type="Variant" />
- <argument index="0" name="arguments" type="Variant" />
- <description>
- Called by this node.
- </description>
- </method>
</methods>
<constants>
</constants>
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index fce98eb8a0..7fb9707fce 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -43,7 +43,7 @@
VisualScriptLanguage *visual_script_language = nullptr;
#ifdef TOOLS_ENABLED
-static vs_bind::VisualScriptEditor *vs_editor_singleton = nullptr;
+static VisualScriptCustomNodes *vs_custom_nodes_singleton = nullptr;
#endif
void register_visual_script_types() {
@@ -114,10 +114,10 @@ void register_visual_script_types() {
#ifdef TOOLS_ENABLED
ClassDB::set_current_api(ClassDB::API_EDITOR);
- GDREGISTER_CLASS(vs_bind::VisualScriptEditor);
+ GDREGISTER_CLASS(VisualScriptCustomNodes);
ClassDB::set_current_api(ClassDB::API_CORE);
- vs_editor_singleton = memnew(vs_bind::VisualScriptEditor);
- Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", vs_bind::VisualScriptEditor::get_singleton()));
+ vs_custom_nodes_singleton = memnew(VisualScriptCustomNodes);
+ Engine::get_singleton()->add_singleton(Engine::Singleton("VisualScriptEditor", VisualScriptCustomNodes::get_singleton()));
VisualScriptEditor::register_editor();
#endif
@@ -130,8 +130,8 @@ void unregister_visual_script_types() {
#ifdef TOOLS_ENABLED
VisualScriptEditor::free_clipboard();
- if (vs_editor_singleton) {
- memdelete(vs_editor_singleton);
+ if (vs_custom_nodes_singleton) {
+ memdelete(vs_custom_nodes_singleton);
}
#endif
if (visual_script_language) {
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index 86793af77f..142419f90a 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -1845,26 +1845,6 @@ void VisualScriptInstance::create(const Ref<VisualScript> &p_script, Object *p_o
max_input_args = 0;
max_output_args = 0;
- if (Object::cast_to<Node>(p_owner)) {
- // Turn on these if they exist and base is a node.
- Node *node = Object::cast_to<Node>(p_owner);
- if (p_script->functions.has("_process")) {
- node->set_process(true);
- }
- if (p_script->functions.has("_physics_process")) {
- node->set_physics_process(true);
- }
- if (p_script->functions.has("_input")) {
- node->set_process_input(true);
- }
- if (p_script->functions.has("_unhandled_input")) {
- node->set_process_unhandled_input(true);
- }
- if (p_script->functions.has("_unhandled_key_input")) {
- node->set_process_unhandled_key_input(true);
- }
- }
-
// Setup variables.
{
List<StringName> keys;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 9d813e3d77..eee9e8f32b 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -1816,7 +1816,7 @@ void VisualScriptEditor::_generic_search(String p_base_type, Vector2 pos, bool n
}
}
-void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
+void VisualScriptEditor::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
// GUI input for VS Editor Plugin
@@ -4246,8 +4246,6 @@ void VisualScriptEditor::_bind_methods() {
ClassDB::bind_method("_can_drop_data_fw", &VisualScriptEditor::can_drop_data_fw);
ClassDB::bind_method("_drop_data_fw", &VisualScriptEditor::drop_data_fw);
- ClassDB::bind_method("_input", &VisualScriptEditor::_input);
-
ClassDB::bind_method("_update_graph_connections", &VisualScriptEditor::_update_graph_connections);
ClassDB::bind_method("_update_members", &VisualScriptEditor::_update_members);
@@ -4524,46 +4522,44 @@ void VisualScriptEditor::register_editor() {
void VisualScriptEditor::validate() {
}
-namespace vs_bind {
+// VisualScriptCustomNodes
-Ref<VisualScriptNode> VisualScriptEditor::create_node_custom(const String &p_name) {
+Ref<VisualScriptNode> VisualScriptCustomNodes::create_node_custom(const String &p_name) {
Ref<VisualScriptCustomNode> node;
node.instantiate();
node->set_script(singleton->custom_nodes[p_name]);
return node;
}
-VisualScriptEditor *VisualScriptEditor::singleton = nullptr;
-Map<String, REF> VisualScriptEditor::custom_nodes;
+VisualScriptCustomNodes *VisualScriptCustomNodes::singleton = nullptr;
+Map<String, REF> VisualScriptCustomNodes::custom_nodes;
-VisualScriptEditor::VisualScriptEditor() {
+VisualScriptCustomNodes::VisualScriptCustomNodes() {
singleton = this;
}
-VisualScriptEditor::~VisualScriptEditor() {
+VisualScriptCustomNodes::~VisualScriptCustomNodes() {
custom_nodes.clear();
}
-void VisualScriptEditor::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
+void VisualScriptCustomNodes::add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script) {
String node_name = "custom/" + p_category + "/" + p_name;
custom_nodes.insert(node_name, p_script);
- VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptEditor::create_node_custom);
+ VisualScriptLanguage::singleton->add_register_func(node_name, &VisualScriptCustomNodes::create_node_custom);
emit_signal(SNAME("custom_nodes_updated"));
}
-void VisualScriptEditor::remove_custom_node(const String &p_name, const String &p_category) {
+void VisualScriptCustomNodes::remove_custom_node(const String &p_name, const String &p_category) {
String node_name = "custom/" + p_category + "/" + p_name;
custom_nodes.erase(node_name);
VisualScriptLanguage::singleton->remove_register_func(node_name);
emit_signal(SNAME("custom_nodes_updated"));
}
-void VisualScriptEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptEditor::add_custom_node);
- ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptEditor::remove_custom_node);
+void VisualScriptCustomNodes::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("add_custom_node", "name", "category", "script"), &VisualScriptCustomNodes::add_custom_node);
+ ClassDB::bind_method(D_METHOD("remove_custom_node", "name", "category"), &VisualScriptCustomNodes::remove_custom_node);
ADD_SIGNAL(MethodInfo("custom_nodes_updated"));
}
-} // namespace vs_bind
-
#endif
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 0c4ea880c8..7dfb4fa270 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -46,6 +46,8 @@ class VisualScriptEditorVariableEdit;
// TODO: Maybe this class should be refactored.
// See https://github.com/godotengine/godot/issues/51913
class VisualScriptEditor : public ScriptEditorBase {
+ GDCLASS(VisualScriptEditor, ScriptEditorBase);
+
enum {
TYPE_SEQUENCE = 1000,
INDEX_BASE_SEQUENCE = 1024
@@ -234,7 +236,7 @@ class VisualScriptEditor : public ScriptEditorBase {
void _generic_search(String p_base_type = "", Vector2 pos = Vector2(), bool node_centered = false);
- void _input(const Ref<InputEvent> &p_event);
+ virtual void input(const Ref<InputEvent> &p_event) override;
void _graph_gui_input(const Ref<InputEvent> &p_event);
void _members_gui_input(const Ref<InputEvent> &p_event);
void _fn_name_box_input(const Ref<InputEvent> &p_event);
@@ -330,33 +332,29 @@ public:
~VisualScriptEditor();
};
-namespace vs_bind {
-
// Singleton
-class VisualScriptEditor : public Object {
- GDCLASS(VisualScriptEditor, Object);
+class VisualScriptCustomNodes : public Object {
+ GDCLASS(VisualScriptCustomNodes, Object);
friend class VisualScriptLanguage;
protected:
static void _bind_methods();
- static VisualScriptEditor *singleton;
+ static VisualScriptCustomNodes *singleton;
static Map<String, REF> custom_nodes;
static Ref<VisualScriptNode> create_node_custom(const String &p_name);
public:
- static VisualScriptEditor *get_singleton() { return singleton; }
+ static VisualScriptCustomNodes *get_singleton() { return singleton; }
void add_custom_node(const String &p_name, const String &p_category, const Ref<Script> &p_script);
void remove_custom_node(const String &p_name, const String &p_category);
- VisualScriptEditor();
- ~VisualScriptEditor();
+ VisualScriptCustomNodes();
+ ~VisualScriptCustomNodes();
};
-} // namespace vs_bind
-
#endif
#endif // VISUALSCRIPT_EDITOR_H
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index c517d89aa5..c9e426fa6c 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -2825,36 +2825,41 @@ VisualScriptSelf::VisualScriptSelf() {
//////////////////////////////////////////
int VisualScriptCustomNode::get_output_sequence_port_count() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_count")) {
- return get_script_instance()->call("_get_output_sequence_port_count");
+ int ret;
+ if (GDVIRTUAL_CALL(_get_output_sequence_port_count, ret)) {
+ return ret;
}
return 0;
}
bool VisualScriptCustomNode::has_input_sequence_port() const {
- if (get_script_instance() && get_script_instance()->has_method("_has_input_sequence_port")) {
- return get_script_instance()->call("_has_input_sequence_port");
+ bool ret;
+ if (GDVIRTUAL_CALL(_has_input_sequence_port, ret)) {
+ return ret;
}
return false;
}
int VisualScriptCustomNode::get_input_value_port_count() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_count")) {
- return get_script_instance()->call("_get_input_value_port_count");
+ int ret;
+ if (GDVIRTUAL_CALL(_get_input_value_port_count, ret)) {
+ return ret;
}
return 0;
}
int VisualScriptCustomNode::get_output_value_port_count() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_count")) {
- return get_script_instance()->call("_get_output_value_port_count");
+ int ret;
+ if (GDVIRTUAL_CALL(_get_output_value_port_count, ret)) {
+ return ret;
}
return 0;
}
String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
- if (get_script_instance() && get_script_instance()->has_method("_get_output_sequence_port_text")) {
- return get_script_instance()->call("_get_output_sequence_port_text", p_port);
+ String ret;
+ if (GDVIRTUAL_CALL(_get_output_sequence_port_text, p_port, ret)) {
+ return ret;
}
return String();
@@ -2862,34 +2867,61 @@ String VisualScriptCustomNode::get_output_sequence_port_text(int p_port) const {
PropertyInfo VisualScriptCustomNode::get_input_value_port_info(int p_idx) const {
PropertyInfo info;
- if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_type")) {
- info.type = Variant::Type(int(get_script_instance()->call("_get_input_value_port_type", p_idx)));
+ {
+ int type;
+ if (GDVIRTUAL_CALL(_get_input_value_port_type, p_idx, type)) {
+ info.type = Variant::Type(type);
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_name")) {
- info.name = get_script_instance()->call("_get_input_value_port_name", p_idx);
+ {
+ String name;
+ if (GDVIRTUAL_CALL(_get_input_value_port_name, p_idx, name)) {
+ info.name = name;
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_hint")) {
- info.hint = PropertyHint(int(get_script_instance()->call("_get_input_value_port_hint", p_idx)));
+ {
+ int hint;
+ if (GDVIRTUAL_CALL(_get_input_value_port_hint, p_idx, hint)) {
+ info.hint = PropertyHint(hint);
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_input_value_port_hint_string")) {
- info.hint_string = get_script_instance()->call("_get_input_value_port_hint_string", p_idx);
+
+ {
+ String hint_string;
+ if (GDVIRTUAL_CALL(_get_input_value_port_hint_string, p_idx, hint_string)) {
+ info.hint_string = hint_string;
+ }
}
+
return info;
}
PropertyInfo VisualScriptCustomNode::get_output_value_port_info(int p_idx) const {
PropertyInfo info;
- if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_type")) {
- info.type = Variant::Type(int(get_script_instance()->call("_get_output_value_port_type", p_idx)));
+ {
+ int type;
+ if (GDVIRTUAL_CALL(_get_output_value_port_type, p_idx, type)) {
+ info.type = Variant::Type(type);
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_name")) {
- info.name = get_script_instance()->call("_get_output_value_port_name", p_idx);
+ {
+ String name;
+ if (GDVIRTUAL_CALL(_get_output_value_port_name, p_idx, name)) {
+ info.name = name;
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_hint")) {
- info.hint = PropertyHint(int(get_script_instance()->call("_get_output_value_port_hint", p_idx)));
+ {
+ int hint;
+ if (GDVIRTUAL_CALL(_get_output_value_port_hint, p_idx, hint)) {
+ info.hint = PropertyHint(hint);
+ }
}
- if (get_script_instance() && get_script_instance()->has_method("_get_output_value_port_hint_string")) {
- info.hint_string = get_script_instance()->call("_get_output_value_port_hint_string", p_idx);
+
+ {
+ String hint_string;
+ if (GDVIRTUAL_CALL(_get_output_value_port_hint_string, p_idx, hint_string)) {
+ info.hint_string = hint_string;
+ }
}
return info;
}
@@ -2911,22 +2943,25 @@ VisualScriptCustomNode::TypeGuess VisualScriptCustomNode::guess_output_type(Type
}
String VisualScriptCustomNode::get_caption() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_caption")) {
- return get_script_instance()->call("_get_caption");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_caption, ret)) {
+ return ret;
}
return "CustomNode";
}
String VisualScriptCustomNode::get_text() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_text")) {
- return get_script_instance()->call("_get_text");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_text, ret)) {
+ return ret;
}
return "";
}
String VisualScriptCustomNode::get_category() const {
- if (get_script_instance() && get_script_instance()->has_method("_get_category")) {
- return get_script_instance()->call("_get_category");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_category, ret)) {
+ return ret;
}
return "Custom";
}
@@ -2941,14 +2976,7 @@ public:
virtual int get_working_memory_size() const { return work_mem_size; }
virtual int step(const Variant **p_inputs, Variant **p_outputs, StartMode p_start_mode, Variant *p_working_mem, Callable::CallError &r_error, String &r_error_str) {
- if (node->get_script_instance()) {
-#ifdef DEBUG_ENABLED
- if (!node->get_script_instance()->has_method(VisualScriptLanguage::singleton->_step)) {
- r_error_str = RTR("Custom node has no _step() method, can't process graph.");
- r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
- return 0;
- }
-#endif
+ if (GDVIRTUAL_IS_OVERRIDEN_PTR(node, _step)) {
Array in_values;
Array out_values;
Array work_mem;
@@ -2969,7 +2997,8 @@ public:
int ret_out;
- Variant ret = node->get_script_instance()->call(VisualScriptLanguage::singleton->_step, in_values, out_values, p_start_mode, work_mem);
+ Variant ret;
+ GDVIRTUAL_CALL_PTR(node, _step, in_values, out_values, p_start_mode, work_mem, ret);
if (ret.get_type() == Variant::STRING) {
r_error_str = ret;
r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
@@ -2995,6 +3024,9 @@ public:
}
return ret_out;
+ } else {
+ r_error_str = RTR("Custom node has no _step() method, can't process graph.");
+ r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD;
}
return 0;
@@ -3008,11 +3040,8 @@ VisualScriptNodeInstance *VisualScriptCustomNode::instantiate(VisualScriptInstan
instance->in_count = get_input_value_port_count();
instance->out_count = get_output_value_port_count();
- if (get_script_instance() && get_script_instance()->has_method("_get_working_memory_size")) {
- instance->work_mem_size = get_script_instance()->call("_get_working_memory_size");
- } else {
- instance->work_mem_size = 0;
- }
+ instance->work_mem_size = 0;
+ GDVIRTUAL_CALL(_get_working_memory_size, instance->work_mem_size);
return instance;
}
@@ -3022,32 +3051,29 @@ void VisualScriptCustomNode::_script_changed() {
}
void VisualScriptCustomNode::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_sequence_port_count"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_input_sequence_port"));
-
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_sequence_port_text", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_count"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_count"));
+ GDVIRTUAL_BIND(_get_output_sequence_port_count);
+ GDVIRTUAL_BIND(_has_input_sequence_port);
+ GDVIRTUAL_BIND(_get_output_sequence_port_text, "seq_idx");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_type", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_value_port_name", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_value_port_hint", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_value_port_hint_string", PropertyInfo(Variant::INT, "idx")));
+ GDVIRTUAL_BIND(_get_input_value_port_count);
+ GDVIRTUAL_BIND(_get_input_value_port_type, "input_idx");
+ GDVIRTUAL_BIND(_get_input_value_port_name, "input_idx");
+ GDVIRTUAL_BIND(_get_input_value_port_hint, "input_idx");
+ GDVIRTUAL_BIND(_get_input_value_port_hint_string, "input_idx");
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_type", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_value_port_name", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_value_port_hint", PropertyInfo(Variant::INT, "idx")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_value_port_hint_string", PropertyInfo(Variant::INT, "idx")));
+ GDVIRTUAL_BIND(_get_output_value_port_count);
+ GDVIRTUAL_BIND(_get_output_value_port_type, "output_idx");
+ GDVIRTUAL_BIND(_get_output_value_port_name, "output_idx");
+ GDVIRTUAL_BIND(_get_output_value_port_hint, "output_idx");
+ GDVIRTUAL_BIND(_get_output_value_port_hint_string, "output_idx");
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_caption"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_text"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
+ GDVIRTUAL_BIND(_get_caption);
+ GDVIRTUAL_BIND(_get_text);
+ GDVIRTUAL_BIND(_get_category);
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_working_memory_size"));
+ GDVIRTUAL_BIND(_get_working_memory_size);
- MethodInfo stepmi(Variant::NIL, "_step", PropertyInfo(Variant::ARRAY, "inputs"), PropertyInfo(Variant::ARRAY, "outputs"), PropertyInfo(Variant::INT, "start_mode"), PropertyInfo(Variant::ARRAY, "working_mem"));
- stepmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(stepmi);
+ GDVIRTUAL_BIND(_step, "inputs", "outputs", "start_mode", "working_mem");
BIND_ENUM_CONSTANT(START_MODE_BEGIN_SEQUENCE);
BIND_ENUM_CONSTANT(START_MODE_CONTINUE_SEQUENCE);
@@ -3170,9 +3196,7 @@ VisualScriptNodeInstance *VisualScriptSubCall::instantiate(VisualScriptInstance
}
void VisualScriptSubCall::_bind_methods() {
- MethodInfo scmi(Variant::NIL, "_subcall", PropertyInfo(Variant::NIL, "arguments"));
- scmi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(scmi);
+ // Since this is script only, registering virtual function is no longer valid. Will have to go in docs.
}
VisualScriptSubCall::VisualScriptSubCall() {
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index 2390e5c7bc..35d9b0b4fe 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -31,6 +31,8 @@
#ifndef VISUAL_SCRIPT_NODES_H
#define VISUAL_SCRIPT_NODES_H
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
#include "visual_script.h"
class VisualScriptFunction : public VisualScriptNode {
@@ -757,6 +759,30 @@ class VisualScriptCustomNode : public VisualScriptNode {
protected:
static void _bind_methods();
+ friend class VisualScriptNodeInstanceCustomNode;
+ GDVIRTUAL0RC(int, _get_output_sequence_port_count)
+ GDVIRTUAL0RC(bool, _has_input_sequence_port)
+ GDVIRTUAL1RC(String, _get_output_sequence_port_text, int)
+
+ GDVIRTUAL0RC(int, _get_input_value_port_count)
+ GDVIRTUAL1RC(int, _get_input_value_port_type, int)
+ GDVIRTUAL1RC(String, _get_input_value_port_name, int)
+ GDVIRTUAL1RC(int, _get_input_value_port_hint, int)
+ GDVIRTUAL1RC(String, _get_input_value_port_hint_string, int)
+
+ GDVIRTUAL0RC(int, _get_output_value_port_count)
+ GDVIRTUAL1RC(int, _get_output_value_port_type, int)
+ GDVIRTUAL1RC(String, _get_output_value_port_name, int)
+ GDVIRTUAL1RC(int, _get_output_value_port_hint, int)
+ GDVIRTUAL1RC(String, _get_output_value_port_hint_string, int)
+
+ GDVIRTUAL0RC(String, _get_caption)
+ GDVIRTUAL0RC(String, _get_text)
+ GDVIRTUAL0RC(String, _get_category)
+
+ GDVIRTUAL0RC(int, _get_working_memory_size)
+
+ GDVIRTUAL4RC(Variant, _step, Array, Array, int, Array)
public:
enum StartMode { //replicated for step
diff --git a/modules/visual_script/visual_script_property_selector.cpp b/modules/visual_script/visual_script_property_selector.cpp
index bacb1947be..d8b88d6cd3 100644
--- a/modules/visual_script/visual_script_property_selector.cpp
+++ b/modules/visual_script/visual_script_property_selector.cpp
@@ -55,7 +55,7 @@ void VisualScriptPropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", k);
+ search_options->gui_input(k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 7a993e9ca6..61ccad9ac3 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -93,7 +93,7 @@ def configure(env):
install_ndk_if_needed(env)
# Workaround for MinGW. See:
- # http://www.scons.org/wiki/LongCmdLinesOnWin32
+ # https://www.scons.org/wiki/LongCmdLinesOnWin32
if os.name == "nt":
import subprocess
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index fc86abb6f1..8df61831c2 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -48,6 +48,8 @@ void register_android_exporter() {
EDITOR_DEF("export/android/shutdown_adb_on_exit", true);
+ EDITOR_DEF("export/android/one_click_deploy_clear_previous_install", false);
+
Ref<EditorExportPlatformAndroid> exporter = Ref<EditorExportPlatformAndroid>(memnew(EditorExportPlatformAndroid));
EditorExport::get_singleton()->add_export_platform(exporter);
}
diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp
index 8ed2d4e60a..bdf12b6c50 100644
--- a/platform/android/export/export_plugin.cpp
+++ b/platform/android/export/export_plugin.cpp
@@ -1646,8 +1646,6 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
- r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false));
-
r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,4096,1,or_greater"), 1));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0"));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname"));
@@ -1794,7 +1792,7 @@ Error EditorExportPlatformAndroid::run(const Ref<EditorExportPreset> &p_preset,
int rv;
String output;
- bool remove_prev = p_preset->get("one_click_deploy/clear_previous_install");
+ bool remove_prev = EDITOR_GET("export/android/one_click_deploy_clear_previous_install");
String version_name = p_preset->get("version/name");
String package_name = p_preset->get("package/unique_name");
diff --git a/platform/android/java/app/gradle.properties b/platform/android/java/app/gradle.properties
index 19587bd81f..0ad8e611ca 100644
--- a/platform/android/java/app/gradle.properties
+++ b/platform/android/java/app/gradle.properties
@@ -4,7 +4,7 @@
# where otherwise specified.
# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
+# https://www.gradle.org/docs/current/userguide/build_environment.html
android.enableJetifier=true
android.useAndroidX=true
@@ -15,7 +15,7 @@ org.gradle.jvmargs=-Xmx4536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.warning.mode=all
diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties
index b51a19a005..5cd94e85d9 100644
--- a/platform/android/java/gradle.properties
+++ b/platform/android/java/gradle.properties
@@ -7,7 +7,7 @@
# any settings specified in this file.
# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
+# https://www.gradle.org/docs/current/userguide/build_environment.html
android.enableJetifier=true
android.useAndroidX=true
@@ -18,7 +18,7 @@ org.gradle.jvmargs=-Xmx4536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# https://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
org.gradle.warning.mode=all
diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
index 2a72c9818d..9aa65fd786 100644
--- a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
+++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/Helpers.java
@@ -54,7 +54,7 @@ public class Helpers {
/*
* Parse the Content-Disposition HTTP Header. The format of the header is defined here:
- * http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
+ * https://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html This header provides a filename for
* content that is going to be downloaded to the file system. We only support the attachment
* type.
*/
diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp
index ea0222cb19..0e98af71fa 100644
--- a/platform/linuxbsd/crash_handler_linuxbsd.cpp
+++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp
@@ -32,6 +32,8 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+#include "core/version.h"
+#include "core/version_hash.gen.h"
#include "main/main.h"
#ifdef DEBUG_ENABLED
@@ -61,12 +63,19 @@ static void handle_crash(int sig) {
}
// Dump the backtrace to stderr with a message to the user
+ fprintf(stderr, "\n================================================================\n");
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
}
+ // Print the engine version just before, so that people are reminded to include the version in backtrace reports.
+ if (String(VERSION_HASH).length() != 0) {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n");
+ } else {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n");
+ }
fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
@@ -115,6 +124,7 @@ static void handle_crash(int sig) {
free(strings);
}
fprintf(stderr, "-- END OF BACKTRACE --\n");
+ fprintf(stderr, "================================================================\n");
// Abort to pass the error to the OS
abort();
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 0f128d504f..31228b10b4 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -32,6 +32,8 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+#include "core/version.h"
+#include "core/version_hash.gen.h"
#include "main/main.h"
#include <string.h>
@@ -85,11 +87,18 @@ static void handle_crash(int sig) {
}
// Dump the backtrace to stderr with a message to the user
+ fprintf(stderr, "\n================================================================\n");
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
if (OS::get_singleton()->get_main_loop())
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
+ // Print the engine version just before, so that people are reminded to include the version in backtrace reports.
+ if (String(VERSION_HASH).length() != 0) {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n");
+ } else {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n");
+ }
fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
@@ -148,6 +157,7 @@ static void handle_crash(int sig) {
free(strings);
}
fprintf(stderr, "-- END OF BACKTRACE --\n");
+ fprintf(stderr, "================================================================\n");
// Abort to pass the error to the OS
abort();
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 5b959d6da4..54a3104482 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -931,7 +931,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
zipfi.tmz_date.tm_hour = time.hour;
zipfi.tmz_date.tm_mday = date.day;
zipfi.tmz_date.tm_min = time.minute;
- zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, http://www.cplusplus.com/reference/ctime/tm/
+ zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
zipfi.tmz_date.tm_sec = time.second;
zipfi.tmz_date.tm_year = date.year;
zipfi.dosDate = 0;
@@ -976,7 +976,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
zipfi.tmz_date.tm_hour = time.hour;
zipfi.tmz_date.tm_mday = date.day;
zipfi.tmz_date.tm_min = time.minute;
- zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, http://www.cplusplus.com/reference/ctime/tm/
+ zipfi.tmz_date.tm_mon = date.month - 1; // Note: "tm" month range - 0..11, Godot month range - 1..12, https://www.cplusplus.com/reference/ctime/tm/
zipfi.tmz_date.tm_sec = time.second;
zipfi.tmz_date.tm_year = date.year;
zipfi.dosDate = 0;
diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp
index e2d507eddd..1b4dae207f 100644
--- a/platform/windows/crash_handler_windows.cpp
+++ b/platform/windows/crash_handler_windows.cpp
@@ -32,6 +32,8 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+#include "core/version.h"
+#include "core/version_hash.gen.h"
#include "main/main.h"
#ifdef CRASH_HANDLER_EXCEPTION
@@ -127,6 +129,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
return EXCEPTION_CONTINUE_SEARCH;
}
+ fprintf(stderr, "\n================================================================\n");
fprintf(stderr, "%s: Program crashed\n", __FUNCTION__);
if (OS::get_singleton()->get_main_loop())
@@ -175,6 +178,12 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
msg = proj_settings->get("debug/settings/crash_handler/message");
}
+ // Print the engine version just before, so that people are reminded to include the version in backtrace reports.
+ if (String(VERSION_HASH).length() != 0) {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n");
+ } else {
+ fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n");
+ }
fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data());
int n = 0;
@@ -200,6 +209,7 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
} while (frame.AddrReturn.Offset != 0 && n < 256);
fprintf(stderr, "-- END OF BACKTRACE --\n");
+ fprintf(stderr, "================================================================\n");
SymCleanup(process);
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 9154f7749e..3961480d23 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -321,7 +321,7 @@ def configure_msvc(env, manual_msvc_config):
def configure_mingw(env):
# Workaround for MinGW. See:
- # http://www.scons.org/wiki/LongCmdLinesOnWin32
+ # https://www.scons.org/wiki/LongCmdLinesOnWin32
env.use_windows_spawn_fix()
## Build type
diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp
index b6489e7a95..c6ed30a0fe 100644
--- a/platform/windows/display_server_windows.cpp
+++ b/platform/windows/display_server_windows.cpp
@@ -854,12 +854,13 @@ Size2i DisplayServerWindows::window_get_size(WindowID p_window) const {
ERR_FAIL_COND_V(!windows.has(p_window), Size2i());
const WindowData &wd = windows[p_window];
+ // GetClientRect() returns a zero rect for a minimized window, so we need to get the size in another way.
if (wd.minimized) {
return Size2(wd.width, wd.height);
}
RECT r;
- if (GetClientRect(wd.hWnd, &r)) { // Only area inside of window border
+ if (GetClientRect(wd.hWnd, &r)) { // Retrieves area inside of window border.
return Size2(r.right - r.left, r.bottom - r.top);
}
return Size2();
@@ -1900,7 +1901,9 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
case WM_GETMINMAXINFO: {
if (windows[window_id].resizable && !windows[window_id].fullscreen) {
- Size2 decor = window_get_size(window_id) - window_get_real_size(window_id); // Size of window decorations
+ // Size of window decorations.
+ Size2 decor = window_get_real_size(window_id) - window_get_size(window_id);
+
MINMAXINFO *min_max_info = (MINMAXINFO *)lParam;
if (windows[window_id].min_size != Size2()) {
min_max_info->ptMinTrackSize.x = windows[window_id].min_size.x + decor.x;
@@ -2563,10 +2566,13 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
} break;
case WM_SIZE: {
- // Ignore size when a SIZE_MINIMIZED event is triggered
+ // Ignore window size change when a SIZE_MINIMIZED event is triggered.
if (wParam != SIZE_MINIMIZED) {
+ // The new width and height of the client area.
int window_w = LOWORD(lParam);
int window_h = HIWORD(lParam);
+
+ // Set new value to the size if it isn't preserved.
if (window_w > 0 && window_h > 0 && !windows[window_id].preserve_window_size) {
windows[window_id].width = window_w;
windows[window_id].height = window_h;
@@ -2577,29 +2583,37 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
}
#endif
- } else {
+ } else { // If the size is preserved.
windows[window_id].preserve_window_size = false;
+
+ // Restore the old size.
window_set_size(Size2(windows[window_id].width, windows[window_id].height), window_id);
}
- } else {
+ } else { // When the window has been minimized, preserve its size.
windows[window_id].preserve_window_size = true;
}
+ // Call windows rect change callback.
if (!windows[window_id].rect_changed_callback.is_null()) {
Variant size = Rect2i(windows[window_id].last_pos.x, windows[window_id].last_pos.y, windows[window_id].width, windows[window_id].height);
- Variant *sizep = &size;
+ Variant *size_ptr = &size;
Variant ret;
Callable::CallError ce;
- windows[window_id].rect_changed_callback.call((const Variant **)&sizep, 1, ret, ce);
+ windows[window_id].rect_changed_callback.call((const Variant **)&size_ptr, 1, ret, ce);
}
+ // The window has been maximized.
if (wParam == SIZE_MAXIMIZED) {
windows[window_id].maximized = true;
windows[window_id].minimized = false;
- } else if (wParam == SIZE_MINIMIZED) {
+ }
+ // The window has been minimized.
+ else if (wParam == SIZE_MINIMIZED) {
windows[window_id].maximized = false;
windows[window_id].minimized = true;
- } else if (wParam == SIZE_RESTORED) {
+ }
+ // The window has been resized, but neither the SIZE_MINIMIZED nor SIZE_MAXIMIZED value applies.
+ else if (wParam == SIZE_RESTORED) {
windows[window_id].maximized = false;
windows[window_id].minimized = false;
}
@@ -2626,7 +2640,6 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
ZeroMemory(dib_data, dib_size.x * dib_size.y * 4);
}
#endif
- //return 0; // Jump Back
} break;
case WM_ENTERSIZEMOVE: {
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
index e0b994f27d..8a4d42fd1f 100644
--- a/scene/2d/audio_stream_player_2d.cpp
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -272,8 +272,12 @@ void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
}
if (p_stream.is_valid()) {
- stream = p_stream;
stream_playback = p_stream->instance_playback();
+ if (stream_playback.is_valid()) {
+ stream = p_stream;
+ } else {
+ stream.unref();
+ }
}
AudioServer::get_singleton()->unlock();
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index 60f29ca163..5d3a538f60 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -481,10 +481,8 @@ bool CollisionObject2D::is_pickable() const {
return pickable;
}
-void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_viewport, p_input_event, p_shape);
- }
+void CollisionObject2D::_input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
+ GDVIRTUAL_CALL(_input_event, p_viewport, p_input_event, p_shape);
emit_signal(SceneStringNames::get_singleton()->input_event, p_viewport, p_input_event, p_shape);
}
@@ -597,7 +595,7 @@ void CollisionObject2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject2D::shape_owner_clear_shapes);
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject2D::shape_find_owner);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "viewport"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx")));
+ GDVIRTUAL_BIND(_input_event, "viewport", "event", "shape_idx");
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "viewport", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("mouse_entered"));
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index 11e11d1382..19abacb201 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -32,6 +32,7 @@
#define COLLISION_OBJECT_2D_H
#include "scene/2d/node_2d.h"
+#include "scene/main/viewport.h"
#include "scene/resources/shape_2d.h"
#include "servers/physics_server_2d.h"
@@ -88,7 +89,7 @@ protected:
void _update_pickable();
friend class Viewport;
- void _input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape);
+ void _input_event_call(Viewport *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape);
void _mouse_enter();
void _mouse_exit();
@@ -100,6 +101,7 @@ protected:
void set_body_mode(PhysicsServer2D::BodyMode p_mode);
+ GDVIRTUAL3(_input_event, Viewport *, Ref<InputEvent>, int)
public:
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 559bd2fd16..b836497627 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -248,7 +248,7 @@ TypedArray<String> CPUParticles2D::get_configuration_warnings() const {
CanvasItemMaterial *mat = Object::cast_to<CanvasItemMaterial>(get_material().ptr());
if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
- if (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
+ if (get_param_max(PARAM_ANIM_SPEED) != 0.0 || get_param_max(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid()) {
warnings.push_back(TTR("CPUParticles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."));
}
@@ -292,28 +292,34 @@ real_t CPUParticles2D::get_spread() const {
return spread;
}
-void CPUParticles2D::set_param(Parameter p_param, real_t p_value) {
+void CPUParticles2D::set_param_min(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
- parameters[p_param] = p_value;
+ parameters_min[p_param] = p_value;
+ if (parameters_min[p_param] > parameters_max[p_param]) {
+ set_param_max(p_param, p_value);
+ }
}
-real_t CPUParticles2D::get_param(Parameter p_param) const {
+real_t CPUParticles2D::get_param_min(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return parameters[p_param];
+ return parameters_min[p_param];
}
-void CPUParticles2D::set_param_randomness(Parameter p_param, real_t p_value) {
+void CPUParticles2D::set_param_max(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
- randomness[p_param] = p_value;
+ parameters_max[p_param] = p_value;
+ if (parameters_min[p_param] > parameters_max[p_param]) {
+ set_param_min(p_param, p_value);
+ }
}
-real_t CPUParticles2D::get_param_randomness(Parameter p_param) const {
+real_t CPUParticles2D::get_param_max(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return randomness[p_param];
+ return parameters_max[p_param];
}
static void _adjust_curve_range(const Ref<Curve> &p_curve, real_t p_min, real_t p_max) {
@@ -460,6 +466,31 @@ Vector2 CPUParticles2D::get_gravity() const {
return gravity;
}
+void CPUParticles2D::set_scale_curve_x(Ref<Curve> p_scale_curve) {
+ scale_curve_x = p_scale_curve;
+}
+
+void CPUParticles2D::set_scale_curve_y(Ref<Curve> p_scale_curve) {
+ scale_curve_y = p_scale_curve;
+}
+
+void CPUParticles2D::set_split_scale(bool p_split_scale) {
+ split_scale = p_split_scale;
+ notify_property_list_changed();
+}
+
+Ref<Curve> CPUParticles2D::get_scale_curve_x() const {
+ return scale_curve_x;
+}
+
+Ref<Curve> CPUParticles2D::get_scale_curve_y() const {
+ return scale_curve_y;
+}
+
+bool CPUParticles2D::get_split_scale() {
+ return split_scale;
+}
+
void CPUParticles2D::_validate_property(PropertyInfo &property) const {
if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
property.usage = PROPERTY_USAGE_NONE;
@@ -484,6 +515,9 @@ void CPUParticles2D::_validate_property(PropertyInfo &property) const {
if (property.name == "emission_colors" && emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) {
property.usage = PROPERTY_USAGE_NONE;
}
+ if (property.name.begins_with("scale_curve_") && !split_scale) {
+ property.usage = PROPERTY_USAGE_NONE;
+ }
}
static uint32_t idhash(uint32_t x) {
@@ -695,14 +729,14 @@ void CPUParticles2D::_particles_process(double p_delta) {
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector2 rot = Vector2(Math::cos(angle1_rad), Math::sin(angle1_rad));
- p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
+ p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf());
- real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
+ real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
p.rotation = Math::deg2rad(base_angle);
p.custom[0] = 0.0; // unused
p.custom[1] = 0.0; // phase [0..1]
- p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation phase [0..1]
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand);
p.custom[3] = 0.0;
p.transform = Transform2D();
p.time = 0;
@@ -766,51 +800,51 @@ void CPUParticles2D::_particles_process(double p_delta) {
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;
- real_t tex_linear_velocity = 0.0;
+ real_t tex_linear_velocity = 1.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
- real_t tex_orbit_velocity = 0.0;
+ real_t tex_orbit_velocity = 1.0;
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
- real_t tex_angular_velocity = 0.0;
+ real_t tex_angular_velocity = 1.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
- real_t tex_linear_accel = 0.0;
+ real_t tex_linear_accel = 1.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
- real_t tex_tangential_accel = 0.0;
+ real_t tex_tangential_accel = 1.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
- real_t tex_radial_accel = 0.0;
+ real_t tex_radial_accel = 1.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
- real_t tex_damping = 0.0;
+ real_t tex_damping = 1.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
- real_t tex_angle = 0.0;
+ real_t tex_angle = 1.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
- real_t tex_anim_speed = 0.0;
+ real_t tex_anim_speed = 1.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
- real_t tex_anim_offset = 0.0;
+ real_t tex_anim_offset = 1.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
@@ -819,18 +853,18 @@ void CPUParticles2D::_particles_process(double p_delta) {
Vector2 pos = p.transform[2];
//apply linear acceleration
- force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector2();
+ force += p.velocity.length() > 0.0 ? p.velocity.normalized() * tex_linear_accel * Math::lerp(parameters_min[PARAM_LINEAR_ACCEL], parameters_max[PARAM_LINEAR_ACCEL], rand_from_seed(alt_seed)) : Vector2();
//apply radial acceleration
Vector2 org = emission_xform[2];
Vector2 diff = pos - org;
- force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector2();
+ force += diff.length() > 0.0 ? diff.normalized() * (tex_radial_accel)*Math::lerp(parameters_min[PARAM_RADIAL_ACCEL], parameters_max[PARAM_RADIAL_ACCEL], rand_from_seed(alt_seed)) : Vector2();
//apply tangential acceleration;
Vector2 yx = Vector2(diff.y, diff.x);
- force += yx.length() > 0.0 ? (yx * Vector2(-1.0, 1.0)).normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector2();
+ force += yx.length() > 0.0 ? yx.normalized() * (tex_tangential_accel * Math::lerp(parameters_min[PARAM_TANGENTIAL_ACCEL], parameters_max[PARAM_TANGENTIAL_ACCEL], rand_from_seed(alt_seed))) : Vector2();
//apply attractor forces
p.velocity += force * local_delta;
//orbit velocity
- real_t orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
+ real_t orbit_amount = tex_orbit_velocity * Math::lerp(parameters_min[PARAM_ORBIT_VELOCITY], parameters_max[PARAM_ORBIT_VELOCITY], rand_from_seed(alt_seed));
if (orbit_amount != 0.0) {
real_t ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
@@ -843,9 +877,9 @@ void CPUParticles2D::_particles_process(double p_delta) {
p.velocity = p.velocity.normalized() * tex_linear_velocity;
}
- if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
+ if (parameters_max[PARAM_DAMPING] + tex_damping > 0.0) {
real_t v = p.velocity.length();
- real_t damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
+ real_t damp = tex_damping * Math::lerp(parameters_min[PARAM_DAMPING], parameters_max[PARAM_DAMPING], rand_from_seed(alt_seed));
v -= damp * local_delta;
if (v < 0.0) {
p.velocity = Vector2();
@@ -853,18 +887,32 @@ void CPUParticles2D::_particles_process(double p_delta) {
p.velocity = p.velocity.normalized() * v;
}
}
- real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
- base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
+ real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
+ base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.rotation = Math::deg2rad(base_angle); //angle
- real_t animation_phase = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]);
- p.custom[2] = animation_phase;
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed));
}
//apply color
//apply hue rotation
- real_t tex_scale = 1.0;
- if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
+ Vector2 tex_scale = Vector2(1.0, 1.0);
+ if (split_scale) {
+ if (scale_curve_x.is_valid()) {
+ tex_scale.x = scale_curve_x->interpolate(tv);
+ } else {
+ tex_scale.x = 1.0;
+ }
+ if (scale_curve_y.is_valid()) {
+ tex_scale.y = scale_curve_y->interpolate(tv);
+ } else {
+ tex_scale.y = 1.0;
+ }
+ } else {
+ if (curve_parameters[PARAM_SCALE].is_valid()) {
+ real_t tmp_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
+ tex_scale.x = tmp_scale;
+ tex_scale.y = tmp_scale;
+ }
}
real_t tex_hue_variation = 0.0;
@@ -872,7 +920,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- real_t hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ real_t hue_rot_angle = (tex_hue_variation)*Math_TAU * Math::lerp(parameters_min[PARAM_HUE_VARIATION], parameters_max[PARAM_HUE_VARIATION], p.hue_rot_rand);
real_t hue_rot_c = Math::cos(hue_rot_angle);
real_t hue_rot_s = Math::sin(hue_rot_angle);
@@ -912,13 +960,15 @@ void CPUParticles2D::_particles_process(double p_delta) {
}
//scale by scale
- real_t base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], (real_t)1.0, p.scale_rand * randomness[PARAM_SCALE]);
- if (base_scale < 0.000001) {
- base_scale = 0.000001;
+ Vector2 base_scale = tex_scale * Math::lerp(parameters_min[PARAM_SCALE], parameters_max[PARAM_SCALE], p.scale_rand);
+ if (base_scale.x < 0.00001) {
+ base_scale.x = 0.00001;
}
-
- p.transform.elements[0] *= base_scale;
- p.transform.elements[1] *= base_scale;
+ if (base_scale.y < 0.00001) {
+ base_scale.y = 0.00001;
+ }
+ p.transform.elements[0] *= base_scale.x;
+ p.transform.elements[1] *= base_scale.y;
p.transform[2] += p.velocity * local_delta;
}
@@ -1130,18 +1180,24 @@ void CPUParticles2D::convert_from_particles(Node *p_particles) {
Vector2 rect_extents = Vector2(material->get_emission_box_extents().x, material->get_emission_box_extents().y);
set_emission_rect_extents(rect_extents);
+ Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticlesMaterial::PARAM_SCALE);
+ if (scale3D.is_valid()) {
+ split_scale = true;
+ scale_curve_x = scale3D->get_curve_x();
+ scale_curve_y = scale3D->get_curve_y();
+ }
Vector2 gravity = Vector2(material->get_gravity().x, material->get_gravity().y);
set_gravity(gravity);
set_lifetime_randomness(material->get_lifetime_randomness());
#define CONVERT_PARAM(m_param) \
- set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
+ set_param_min(m_param, material->get_param_min(ParticlesMaterial::m_param)); \
{ \
Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \
if (ctex.is_valid()) \
set_param_curve(m_param, ctex->get_curve()); \
} \
- set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param));
+ set_param_max(m_param, material->get_param_max(ParticlesMaterial::m_param));
CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY);
CONVERT_PARAM(PARAM_ANGULAR_VELOCITY);
@@ -1224,11 +1280,11 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &CPUParticles2D::set_spread);
ClassDB::bind_method(D_METHOD("get_spread"), &CPUParticles2D::get_spread);
- ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &CPUParticles2D::set_param);
- ClassDB::bind_method(D_METHOD("get_param", "param"), &CPUParticles2D::get_param);
+ ClassDB::bind_method(D_METHOD("set_param_min", "param", "value"), &CPUParticles2D::set_param_min);
+ ClassDB::bind_method(D_METHOD("get_param_min", "param"), &CPUParticles2D::get_param_min);
- ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &CPUParticles2D::set_param_randomness);
- ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &CPUParticles2D::get_param_randomness);
+ ClassDB::bind_method(D_METHOD("set_param_max", "param", "value"), &CPUParticles2D::set_param_max);
+ ClassDB::bind_method(D_METHOD("get_param_max", "param"), &CPUParticles2D::get_param_max);
ClassDB::bind_method(D_METHOD("set_param_curve", "param", "curve"), &CPUParticles2D::set_param_curve);
ClassDB::bind_method(D_METHOD("get_param_curve", "param"), &CPUParticles2D::get_param_curve);
@@ -1263,6 +1319,15 @@ void CPUParticles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles2D::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles2D::set_gravity);
+ ClassDB::bind_method(D_METHOD("get_split_scale"), &CPUParticles2D::get_split_scale);
+ ClassDB::bind_method(D_METHOD("set_split_scale", "split_scale"), &CPUParticles2D::set_split_scale);
+
+ ClassDB::bind_method(D_METHOD("get_scale_curve_x"), &CPUParticles2D::get_scale_curve_x);
+ ClassDB::bind_method(D_METHOD("set_scale_curve_x", "scale_curve"), &CPUParticles2D::set_scale_curve_x);
+
+ ClassDB::bind_method(D_METHOD("get_scale_curve_y"), &CPUParticles2D::get_scale_curve_y);
+ ClassDB::bind_method(D_METHOD("set_scale_curve_y", "scale_curve"), &CPUParticles2D::set_scale_curve_y);
+
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles2D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
@@ -1280,54 +1345,58 @@ void CPUParticles2D::_bind_methods() {
ADD_GROUP("Gravity", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "gravity"), "set_gravity", "get_gravity");
ADD_GROUP("Initial Velocity", "initial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY);
ADD_GROUP("Angular Velocity", "angular_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY);
ADD_GROUP("Orbit Velocity", "orbit_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY);
ADD_GROUP("Linear Accel", "linear_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL);
ADD_GROUP("Radial Accel", "radial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL);
ADD_GROUP("Tangential Accel", "tangential_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param", "get_param", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE);
ADD_GROUP("Scale", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_SCALE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "split_scale"), "set_split_scale", "get_split_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scale_curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_scale_curve_x", "get_scale_curve_x");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scale_curve_y", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_scale_curve_y", "get_scale_curve_y");
+
ADD_GROUP("Color", "");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
ADD_GROUP("Hue Variation", "hue_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION);
ADD_GROUP("Animation", "anim_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET);
BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
@@ -1366,22 +1435,31 @@ CPUParticles2D::CPUParticles2D() {
set_amount(8);
set_use_local_coordinates(true);
- set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
- set_param(PARAM_ANGULAR_VELOCITY, 0);
- set_param(PARAM_ORBIT_VELOCITY, 0);
- set_param(PARAM_LINEAR_ACCEL, 0);
- set_param(PARAM_RADIAL_ACCEL, 0);
- set_param(PARAM_TANGENTIAL_ACCEL, 0);
- set_param(PARAM_DAMPING, 0);
- set_param(PARAM_ANGLE, 0);
- set_param(PARAM_SCALE, 1);
- set_param(PARAM_HUE_VARIATION, 0);
- set_param(PARAM_ANIM_SPEED, 0);
- set_param(PARAM_ANIM_OFFSET, 0);
-
- for (int i = 0; i < PARAM_MAX; i++) {
- set_param_randomness(Parameter(i), 0);
- }
+ set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_min(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_min(PARAM_ORBIT_VELOCITY, 0);
+ set_param_min(PARAM_LINEAR_ACCEL, 0);
+ set_param_min(PARAM_RADIAL_ACCEL, 0);
+ set_param_min(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_min(PARAM_DAMPING, 0);
+ set_param_min(PARAM_ANGLE, 0);
+ set_param_min(PARAM_SCALE, 1);
+ set_param_min(PARAM_HUE_VARIATION, 0);
+ set_param_min(PARAM_ANIM_SPEED, 0);
+ set_param_min(PARAM_ANIM_OFFSET, 0);
+
+ set_param_max(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_max(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_max(PARAM_ORBIT_VELOCITY, 0);
+ set_param_max(PARAM_LINEAR_ACCEL, 0);
+ set_param_max(PARAM_RADIAL_ACCEL, 0);
+ set_param_max(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_max(PARAM_DAMPING, 0);
+ set_param_max(PARAM_ANGLE, 0);
+ set_param_max(PARAM_SCALE, 1);
+ set_param_max(PARAM_HUE_VARIATION, 0);
+ set_param_max(PARAM_ANIM_SPEED, 0);
+ set_param_max(PARAM_ANIM_OFFSET, 0);
for (int i = 0; i < PARTICLE_FLAG_MAX; i++) {
particle_flags[i] = false;
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 0f8950375f..4990d443e3 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -150,8 +150,8 @@ private:
Vector2 direction = Vector2(1, 0);
real_t spread = 45.0;
- real_t parameters[PARAM_MAX];
- real_t randomness[PARAM_MAX];
+ real_t parameters_min[PARAM_MAX];
+ real_t parameters_max[PARAM_MAX];
Ref<Curve> curve_parameters[PARAM_MAX];
Color color;
@@ -167,6 +167,10 @@ private:
Vector<Color> emission_colors;
int emission_point_count = 0;
+ Ref<Curve> scale_curve_x;
+ Ref<Curve> scale_curve_y;
+ bool split_scale = false;
+
Vector2 gravity = Vector2(0, 980);
void _update_internal();
@@ -236,11 +240,11 @@ public:
void set_spread(real_t p_spread);
real_t get_spread() const;
- void set_param(Parameter p_param, real_t p_value);
- real_t get_param(Parameter p_param) const;
+ void set_param_min(Parameter p_param, real_t p_value);
+ real_t get_param_min(Parameter p_param) const;
- void set_param_randomness(Parameter p_param, real_t p_value);
- real_t get_param_randomness(Parameter p_param) const;
+ void set_param_max(Parameter p_param, real_t p_value);
+ real_t get_param_max(Parameter p_param) const;
void set_param_curve(Parameter p_param, const Ref<Curve> &p_curve);
Ref<Curve> get_param_curve(Parameter p_param) const;
@@ -261,6 +265,9 @@ public:
void set_emission_normals(const Vector<Vector2> &p_normals);
void set_emission_colors(const Vector<Color> &p_colors);
void set_emission_point_count(int p_count);
+ void set_scale_curve_x(Ref<Curve> p_scale_curve);
+ void set_scale_curve_y(Ref<Curve> p_scale_curve);
+ void set_split_scale(bool p_split_scale);
EmissionShape get_emission_shape() const;
real_t get_emission_sphere_radius() const;
@@ -269,6 +276,9 @@ public:
Vector<Vector2> get_emission_normals() const;
Vector<Color> get_emission_colors() const;
int get_emission_point_count() const;
+ Ref<Curve> get_scale_curve_x() const;
+ Ref<Curve> get_scale_curve_y() const;
+ bool get_split_scale();
void set_gravity(const Vector2 &p_gravity);
Vector2 get_gravity() const;
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index 47bf1bc77c..5bce705dd5 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -295,7 +295,7 @@ TypedArray<String> GPUParticles2D::get_configuration_warnings() const {
if (get_material().is_null() || (mat && !mat->get_particles_animation())) {
const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr());
if (process &&
- (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
+ (process->get_param_max(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
warnings.push_back(TTR("Particles2D animation requires the usage of a CanvasItemMaterial with \"Particles Animation\" enabled."));
}
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 13ed4af04e..a9d4877cbb 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -529,9 +529,9 @@ void RigidBody2D::_direct_state_changed(Object *p_state) {
sleeping = state->is_sleeping();
emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
}
- if (get_script_instance()) {
- get_script_instance()->call("_integrate_forces", state);
- }
+
+ GDVIRTUAL_CALL(_integrate_forces, state);
+
set_block_transform_notify(false); // want it back
if (contact_monitor) {
@@ -978,7 +978,7 @@ void RigidBody2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody2D::get_colliding_bodies);
- BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState2D")));
+ GDVIRTUAL_BIND(_integrate_forces, "state");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,65535,0.01,exp"), "set_mass", "get_mass");
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index 302a2148be..a999317953 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -189,6 +189,8 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ GDVIRTUAL1(_integrate_forces, PhysicsDirectBodyState2D *)
+
public:
void set_mode(Mode p_mode);
Mode get_mode() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 12aa1afc45..13f1d258a8 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1051,9 +1051,13 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
Vector2 quadrant_pos = map_to_world(q.coords * get_effective_quadrant_size(q.layer));
+ LocalVector<int> body_shape_count;
+ body_shape_count.resize(q.bodies.size());
+
// Clear shapes.
for (int body_index = 0; body_index < q.bodies.size(); body_index++) {
ps->body_clear_shapes(q.bodies[body_index]);
+ body_shape_count[body_index] = 0;
// Position the bodies.
Transform2D xform;
@@ -1078,6 +1082,8 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
TileData *tile_data = Object::cast_to<TileData>(atlas_source->get_tile_data(c.get_atlas_coords(), c.alternative_tile));
for (int body_index = 0; body_index < q.bodies.size(); body_index++) {
+ int &body_shape_index = body_shape_count[body_index];
+
// Add the shapes again.
for (int polygon_index = 0; polygon_index < tile_data->get_collision_polygons_count(body_index); polygon_index++) {
bool one_way_collision = tile_data->is_collision_polygon_one_way(body_index, polygon_index);
@@ -1091,8 +1097,10 @@ void TileMap::_physics_update_dirty_quadrants(SelfList<TileMapQuadrant>::List &r
// Add decomposed convex shapes.
Ref<ConvexPolygonShape2D> shape = tile_data->get_collision_polygon_shape(body_index, polygon_index, shape_index);
ps->body_add_shape(q.bodies[body_index], shape->get_rid(), xform);
- ps->body_set_shape_metadata(q.bodies[body_index], shape_index, E_cell->get());
- ps->body_set_shape_as_one_way_collision(q.bodies[body_index], shape_index, one_way_collision, one_way_collision_margin);
+ ps->body_set_shape_metadata(q.bodies[body_index], body_shape_index, E_cell->get());
+ ps->body_set_shape_as_one_way_collision(q.bodies[body_index], body_shape_index, one_way_collision, one_way_collision_margin);
+
+ ++body_shape_index;
}
}
}
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index 00e4e1dc62..8bd7b696f2 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -185,7 +185,7 @@ String TouchScreenButton::get_action() const {
return action;
}
-void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
+void TouchScreenButton::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!get_tree()) {
@@ -288,7 +288,7 @@ void TouchScreenButton::_press(int p_finger_pressed) {
iea.instantiate();
iea->set_action(action);
iea->set_pressed(true);
- get_viewport()->input(iea, true);
+ get_viewport()->push_input(iea, true);
}
emit_signal(SNAME("pressed"));
@@ -305,7 +305,7 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
iea.instantiate();
iea->set_action(action);
iea->set_pressed(false);
- get_viewport()->input(iea, true);
+ get_viewport()->push_input(iea, true);
}
}
@@ -384,8 +384,6 @@ void TouchScreenButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_pressed"), &TouchScreenButton::is_pressed);
- ClassDB::bind_method(D_METHOD("_input"), &TouchScreenButton::_input);
-
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "pressed", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture_pressed", "get_texture_pressed");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "bitmask", PROPERTY_HINT_RESOURCE_TYPE, "BitMap"), "set_bitmask", "get_bitmask");
diff --git a/scene/2d/touch_screen_button.h b/scene/2d/touch_screen_button.h
index 10820ad059..1c515149d4 100644
--- a/scene/2d/touch_screen_button.h
+++ b/scene/2d/touch_screen_button.h
@@ -61,7 +61,7 @@ private:
VisibilityMode visibility = VISIBILITY_ALWAYS;
- void _input(const Ref<InputEvent> &p_event);
+ virtual void input(const Ref<InputEvent> &p_event) override;
bool _is_point_inside(const Point2 &p_point);
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 2e917c4a42..943586f43c 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -105,6 +105,61 @@ real_t Area3D::get_priority() const {
return priority;
}
+void Area3D::set_wind_force_magnitude(real_t p_wind_force_magnitude) {
+ wind_force_magnitude = p_wind_force_magnitude;
+ if (is_inside_tree()) {
+ _initialize_wind();
+ }
+}
+
+real_t Area3D::get_wind_force_magnitude() const {
+ return wind_force_magnitude;
+}
+
+void Area3D::set_wind_attenuation_factor(real_t p_wind_force_attenuation_factor) {
+ wind_attenuation_factor = p_wind_force_attenuation_factor;
+ if (is_inside_tree()) {
+ _initialize_wind();
+ }
+}
+
+real_t Area3D::get_wind_attenuation_factor() const {
+ return wind_attenuation_factor;
+}
+
+void Area3D::set_wind_source_path(const NodePath &p_wind_source_path) {
+ wind_source_path = p_wind_source_path;
+ if (is_inside_tree()) {
+ _initialize_wind();
+ }
+}
+
+const NodePath &Area3D::get_wind_source_path() const {
+ return wind_source_path;
+}
+
+void Area3D::_initialize_wind() {
+ real_t temp_magnitude = 0.0;
+ Vector3 wind_direction(0., 0., 0.);
+ Vector3 wind_source(0., 0., 0.);
+
+ // Overwrite with area-specified info if available
+ if (!wind_source_path.is_empty()) {
+ Node3D *p_wind_source = Object::cast_to<Node3D>(get_node(wind_source_path));
+ ERR_FAIL_NULL(p_wind_source);
+ Transform3D global_transform = p_wind_source->get_transform();
+ wind_direction = -global_transform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ wind_source = global_transform.origin;
+ temp_magnitude = wind_force_magnitude;
+ }
+
+ // Set force, source and direction in the physics server.
+ PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_WIND_ATTENUATION_FACTOR, wind_attenuation_factor);
+ PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_WIND_SOURCE, wind_source);
+ PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_WIND_DIRECTION, wind_direction);
+ PhysicsServer3D::get_singleton()->area_set_param(get_rid(), PhysicsServer3D::AREA_PARAM_WIND_FORCE_MAGNITUDE, temp_magnitude);
+}
+
void Area3D::_body_enter_tree(ObjectID p_id) {
Object *obj = ObjectDB::get_instance(p_id);
Node *node = Object::cast_to<Node>(obj);
@@ -264,6 +319,8 @@ void Area3D::_clear_monitoring() {
void Area3D::_notification(int p_what) {
if (p_what == NOTIFICATION_EXIT_TREE) {
_clear_monitoring();
+ } else if (p_what == NOTIFICATION_ENTER_TREE) {
+ _initialize_wind();
}
}
@@ -550,6 +607,15 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_priority", "priority"), &Area3D::set_priority);
ClassDB::bind_method(D_METHOD("get_priority"), &Area3D::get_priority);
+ ClassDB::bind_method(D_METHOD("set_wind_force_magnitude", "wind_force_magnitude"), &Area3D::set_wind_force_magnitude);
+ ClassDB::bind_method(D_METHOD("get_wind_force_magnitude"), &Area3D::get_wind_force_magnitude);
+
+ ClassDB::bind_method(D_METHOD("set_wind_attenuation_factor", "wind_attenuation_factor"), &Area3D::set_wind_attenuation_factor);
+ ClassDB::bind_method(D_METHOD("get_wind_attenuation_factor"), &Area3D::get_wind_attenuation_factor);
+
+ ClassDB::bind_method(D_METHOD("set_wind_source_path", "wind_source_path"), &Area3D::set_wind_source_path);
+ ClassDB::bind_method(D_METHOD("get_wind_source_path"), &Area3D::get_wind_source_path);
+
ClassDB::bind_method(D_METHOD("set_monitorable", "enable"), &Area3D::set_monitorable);
ClassDB::bind_method(D_METHOD("is_monitorable"), &Area3D::is_monitorable);
@@ -605,6 +671,9 @@ void Area3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "gravity", PROPERTY_HINT_RANGE, "-32,32,0.001,or_lesser,or_greater"), "set_gravity", "get_gravity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "linear_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_linear_damp", "get_linear_damp");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "0,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wind_force_magnitude", PROPERTY_HINT_RANGE, "0,10,0.001,or_greater"), "set_wind_force_magnitude", "get_wind_force_magnitude");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "wind_attenuation_factor", PROPERTY_HINT_RANGE, "0.0,3.0,0.001,or_greater"), "set_wind_attenuation_factor", "get_wind_attenuation_factor");
+ ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "wind_source_path", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node3D"), "set_wind_source_path", "get_wind_source_path");
ADD_GROUP("Audio Bus", "audio_bus_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus");
diff --git a/scene/3d/area_3d.h b/scene/3d/area_3d.h
index 5b8d612717..847d1c5966 100644
--- a/scene/3d/area_3d.h
+++ b/scene/3d/area_3d.h
@@ -55,6 +55,9 @@ private:
real_t angular_damp = 0.1;
real_t linear_damp = 0.1;
int priority = 0;
+ real_t wind_force_magnitude = 0.0;
+ real_t wind_attenuation_factor = 0.0;
+ NodePath wind_source_path;
bool monitoring = false;
bool monitorable = false;
bool locked = false;
@@ -134,6 +137,8 @@ private:
void _validate_property(PropertyInfo &property) const override;
+ void _initialize_wind();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -163,6 +168,15 @@ public:
void set_priority(real_t p_priority);
real_t get_priority() const;
+ void set_wind_force_magnitude(real_t p_wind_force_magnitude);
+ real_t get_wind_force_magnitude() const;
+
+ void set_wind_attenuation_factor(real_t p_wind_attenuation_factor);
+ real_t get_wind_attenuation_factor() const;
+
+ void set_wind_source_path(const NodePath &p_wind_source_path);
+ const NodePath &get_wind_source_path() const;
+
void set_monitoring(bool p_enable);
bool is_monitoring() const;
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
index d2424c9a3b..3b44580264 100644
--- a/scene/3d/audio_stream_player_3d.cpp
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -624,8 +624,12 @@ void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
}
if (p_stream.is_valid()) {
- stream = p_stream;
stream_playback = p_stream->instance_playback();
+ if (stream_playback.is_valid()) {
+ stream = p_stream;
+ } else {
+ stream.unref();
+ }
}
AudioServer::get_singleton()->unlock();
diff --git a/scene/3d/collision_object_3d.cpp b/scene/3d/collision_object_3d.cpp
index 36d9bfba82..e2f953974a 100644
--- a/scene/3d/collision_object_3d.cpp
+++ b/scene/3d/collision_object_3d.cpp
@@ -254,10 +254,8 @@ void CollisionObject3D::_apply_enabled() {
}
}
-void CollisionObject3D::_input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
- }
+void CollisionObject3D::_input_event_call(Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
+ GDVIRTUAL_CALL(_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
emit_signal(SceneStringNames::get_singleton()->input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
}
@@ -453,7 +451,7 @@ void CollisionObject3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("shape_owner_clear_shapes", "owner_id"), &CollisionObject3D::shape_owner_clear_shapes);
ClassDB::bind_method(D_METHOD("shape_find_owner", "shape_index"), &CollisionObject3D::shape_find_owner);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "position"), PropertyInfo(Variant::VECTOR3, "normal"), PropertyInfo(Variant::INT, "shape_idx")));
+ GDVIRTUAL_BIND(_input_event, "camera", "event", "position", "normal", "shape_idx");
ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "position"), PropertyInfo(Variant::VECTOR3, "normal"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("mouse_entered"));
diff --git a/scene/3d/collision_object_3d.h b/scene/3d/collision_object_3d.h
index c066960eb4..1c7e205888 100644
--- a/scene/3d/collision_object_3d.h
+++ b/scene/3d/collision_object_3d.h
@@ -31,6 +31,7 @@
#ifndef COLLISION_OBJECT_3D_H
#define COLLISION_OBJECT_3D_H
+#include "scene/3d/camera_3d.h"
#include "scene/3d/node_3d.h"
class CollisionObject3D : public Node3D {
@@ -101,7 +102,7 @@ protected:
void _on_transform_changed();
friend class Viewport;
- virtual void _input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
+ virtual void _input_event_call(Camera3D *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
virtual void _mouse_enter();
virtual void _mouse_exit();
@@ -110,6 +111,7 @@ protected:
void set_only_update_transform_changes(bool p_enable);
bool is_only_update_transform_changes_enabled() const;
+ GDVIRTUAL5(_input_event, Camera3D *, Ref<InputEvent>, Vector3, Vector3, int)
public:
void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index e2095940ff..48ef41e015 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -212,7 +212,7 @@ TypedArray<String> CPUParticles3D::get_configuration_warnings() const {
warnings.push_back(TTR("Nothing is visible because no mesh has been assigned."));
}
- if (!anim_material_found && (get_param(PARAM_ANIM_SPEED) != 0.0 || get_param(PARAM_ANIM_OFFSET) != 0.0 ||
+ if (!anim_material_found && (get_param_max(PARAM_ANIM_SPEED) != 0.0 || get_param_max(PARAM_ANIM_OFFSET) != 0.0 ||
get_param_curve(PARAM_ANIM_SPEED).is_valid() || get_param_curve(PARAM_ANIM_OFFSET).is_valid())) {
warnings.push_back(TTR("CPUParticles3D animation requires the usage of a StandardMaterial3D whose Billboard Mode is set to \"Particle Billboard\"."));
}
@@ -263,28 +263,33 @@ real_t CPUParticles3D::get_flatness() const {
return flatness;
}
-void CPUParticles3D::set_param(Parameter p_param, real_t p_value) {
+void CPUParticles3D::set_param_min(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
- parameters[p_param] = p_value;
+ parameters_min[p_param] = p_value;
+ if (parameters_min[p_param] > parameters_max[p_param]) {
+ set_param_max(p_param, p_value);
+ }
}
-real_t CPUParticles3D::get_param(Parameter p_param) const {
+real_t CPUParticles3D::get_param_min(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return parameters[p_param];
+ return parameters_min[p_param];
}
-void CPUParticles3D::set_param_randomness(Parameter p_param, real_t p_value) {
+void CPUParticles3D::set_param_max(Parameter p_param, real_t p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
-
- randomness[p_param] = p_value;
+ parameters_max[p_param] = p_value;
+ if (parameters_min[p_param] > parameters_max[p_param]) {
+ set_param_min(p_param, p_value);
+ }
}
-real_t CPUParticles3D::get_param_randomness(Parameter p_param) const {
+real_t CPUParticles3D::get_param_max(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return randomness[p_param];
+ return parameters_max[p_param];
}
static void _adjust_curve_range(const Ref<Curve> &p_curve, real_t p_min, real_t p_max) {
@@ -417,6 +422,23 @@ void CPUParticles3D::set_emission_ring_inner_radius(real_t p_radius) {
emission_ring_inner_radius = p_radius;
}
+void CPUParticles3D::set_scale_curve_x(Ref<Curve> p_scale_curve) {
+ scale_curve_x = p_scale_curve;
+}
+
+void CPUParticles3D::set_scale_curve_y(Ref<Curve> p_scale_curve) {
+ scale_curve_y = p_scale_curve;
+}
+
+void CPUParticles3D::set_scale_curve_z(Ref<Curve> p_scale_curve) {
+ scale_curve_z = p_scale_curve;
+}
+
+void CPUParticles3D::set_split_scale(bool p_split_scale) {
+ split_scale = p_split_scale;
+ notify_property_list_changed();
+}
+
real_t CPUParticles3D::get_emission_sphere_radius() const {
return emission_sphere_radius;
}
@@ -465,6 +487,22 @@ Vector3 CPUParticles3D::get_gravity() const {
return gravity;
}
+Ref<Curve> CPUParticles3D::get_scale_curve_x() const {
+ return scale_curve_x;
+}
+
+Ref<Curve> CPUParticles3D::get_scale_curve_y() const {
+ return scale_curve_y;
+}
+
+Ref<Curve> CPUParticles3D::get_scale_curve_z() const {
+ return scale_curve_z;
+}
+
+bool CPUParticles3D::get_split_scale() {
+ return split_scale;
+}
+
void CPUParticles3D::_validate_property(PropertyInfo &property) const {
if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) {
property.usage = PROPERTY_USAGE_NONE;
@@ -489,6 +527,10 @@ void CPUParticles3D::_validate_property(PropertyInfo &property) const {
if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
property.usage = PROPERTY_USAGE_NONE;
}
+
+ if (property.name.begins_with("scale_curve_") && !split_scale) {
+ property.usage = PROPERTY_USAGE_NONE;
+ }
}
static uint32_t idhash(uint32_t x) {
@@ -707,7 +749,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
real_t angle1_rad = Math::atan2(direction.y, direction.x) + Math::deg2rad((Math::randf() * 2.0 - 1.0) * spread);
Vector3 rot = Vector3(Math::cos(angle1_rad), Math::sin(angle1_rad), 0.0);
- p.velocity = rot * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
+ p.velocity = rot * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], Math::randf());
} else {
//initiate velocity spread in 3D
real_t angle1_rad = Math::deg2rad((Math::randf() * (real_t)2.0 - (real_t)1.0) * spread);
@@ -731,13 +773,13 @@ void CPUParticles3D::_particles_process(double p_delta) {
binormal.normalize();
Vector3 normal = binormal.cross(direction_nrm);
spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;
- p.velocity = spread_direction * parameters[PARAM_INITIAL_LINEAR_VELOCITY] * Math::lerp((real_t)1.0, real_t(Math::randf()), randomness[PARAM_INITIAL_LINEAR_VELOCITY]);
+ p.velocity = spread_direction * Math::lerp(parameters_min[PARAM_INITIAL_LINEAR_VELOCITY], parameters_max[PARAM_INITIAL_LINEAR_VELOCITY], float(Math::randf()));
}
- real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
+ real_t base_angle = tex_angle * Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
p.custom[0] = Math::deg2rad(base_angle); //angle
p.custom[1] = 0.0; //phase
- p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]); //animation offset (0-1)
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand); //animation offset (0-1)
p.transform = Transform3D();
p.time = 0;
p.lifetime = lifetime * (1.0 - Math::randf() * lifetime_randomness);
@@ -894,26 +936,25 @@ void CPUParticles3D::_particles_process(double p_delta) {
position.z = 0.0;
}
//apply linear acceleration
- force += p.velocity.length() > 0.0 ? p.velocity.normalized() * (parameters[PARAM_LINEAR_ACCEL] + tex_linear_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_LINEAR_ACCEL]) : Vector3();
+ force += p.velocity.length() > 0.0 ? p.velocity.normalized() * tex_linear_accel * Math::lerp(parameters_min[PARAM_LINEAR_ACCEL], parameters_max[PARAM_LINEAR_ACCEL], rand_from_seed(alt_seed)) : Vector3();
//apply radial acceleration
Vector3 org = emission_xform.origin;
Vector3 diff = position - org;
- force += diff.length() > 0.0 ? diff.normalized() * (parameters[PARAM_RADIAL_ACCEL] + tex_radial_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_RADIAL_ACCEL]) : Vector3();
- //apply tangential acceleration;
+ force += diff.length() > 0.0 ? diff.normalized() * (tex_radial_accel)*Math::lerp(parameters_min[PARAM_RADIAL_ACCEL], parameters_max[PARAM_RADIAL_ACCEL], rand_from_seed(alt_seed)) : Vector3();
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
Vector2 yx = Vector2(diff.y, diff.x);
Vector2 yx2 = (yx * Vector2(-1.0, 1.0)).normalized();
- force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
+ force += yx.length() > 0.0 ? Vector3(yx2.x, yx2.y, 0.0) * (tex_tangential_accel * Math::lerp(parameters_min[PARAM_TANGENTIAL_ACCEL], parameters_max[PARAM_TANGENTIAL_ACCEL], rand_from_seed(alt_seed))) : Vector3();
} else {
Vector3 crossDiff = diff.normalized().cross(gravity.normalized());
- force += crossDiff.length() > 0.0 ? crossDiff.normalized() * ((parameters[PARAM_TANGENTIAL_ACCEL] + tex_tangential_accel) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_TANGENTIAL_ACCEL])) : Vector3();
+ force += crossDiff.length() > 0.0 ? crossDiff.normalized() * (tex_tangential_accel * Math::lerp(parameters_min[PARAM_TANGENTIAL_ACCEL], parameters_max[PARAM_TANGENTIAL_ACCEL], rand_from_seed(alt_seed))) : Vector3();
}
//apply attractor forces
p.velocity += force * local_delta;
//orbit velocity
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
- real_t orbit_amount = (parameters[PARAM_ORBIT_VELOCITY] + tex_orbit_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ORBIT_VELOCITY]);
+ real_t orbit_amount = tex_orbit_velocity * Math::lerp(parameters_min[PARAM_ORBIT_VELOCITY], parameters_max[PARAM_ORBIT_VELOCITY], rand_from_seed(alt_seed));
if (orbit_amount != 0.0) {
real_t ang = orbit_amount * local_delta * Math_TAU;
// Not sure why the ParticlesMaterial code uses a clockwise rotation matrix,
@@ -927,9 +968,10 @@ void CPUParticles3D::_particles_process(double p_delta) {
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
p.velocity = p.velocity.normalized() * tex_linear_velocity;
}
- if (parameters[PARAM_DAMPING] + tex_damping > 0.0) {
+
+ if (parameters_max[PARAM_DAMPING] + tex_damping > 0.0) {
real_t v = p.velocity.length();
- real_t damp = (parameters[PARAM_DAMPING] + tex_damping) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_DAMPING]);
+ real_t damp = tex_damping * Math::lerp(parameters_min[PARAM_DAMPING], parameters_max[PARAM_DAMPING], rand_from_seed(alt_seed));
v -= damp * local_delta;
if (v < 0.0) {
p.velocity = Vector3();
@@ -937,17 +979,38 @@ void CPUParticles3D::_particles_process(double p_delta) {
p.velocity = p.velocity.normalized() * v;
}
}
- real_t base_angle = (parameters[PARAM_ANGLE] + tex_angle) * Math::lerp((real_t)1.0, p.angle_rand, randomness[PARAM_ANGLE]);
- base_angle += p.custom[1] * lifetime * (parameters[PARAM_ANGULAR_VELOCITY] + tex_angular_velocity) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed) * 2.0f - 1.0f, randomness[PARAM_ANGULAR_VELOCITY]);
+ real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
+ base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.custom[0] = Math::deg2rad(base_angle); //angle
- p.custom[2] = (parameters[PARAM_ANIM_OFFSET] + tex_anim_offset) * Math::lerp((real_t)1.0, p.anim_offset_rand, randomness[PARAM_ANIM_OFFSET]) + p.custom[1] * (parameters[PARAM_ANIM_SPEED] + tex_anim_speed) * Math::lerp((real_t)1.0, rand_from_seed(alt_seed), randomness[PARAM_ANIM_SPEED]); //angle
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle
}
//apply color
//apply hue rotation
- real_t tex_scale = 1.0;
- if (curve_parameters[PARAM_SCALE].is_valid()) {
- tex_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
+ Vector3 tex_scale = Vector3(1.0, 1.0, 1.0);
+ if (split_scale) {
+ if (scale_curve_x.is_valid()) {
+ tex_scale.x = scale_curve_x->interpolate(tv);
+ } else {
+ tex_scale.x = 1.0;
+ }
+ if (scale_curve_y.is_valid()) {
+ tex_scale.y = scale_curve_y->interpolate(tv);
+ } else {
+ tex_scale.y = 1.0;
+ }
+ if (scale_curve_z.is_valid()) {
+ tex_scale.z = scale_curve_z->interpolate(tv);
+ } else {
+ tex_scale.z = 1.0;
+ }
+ } else {
+ if (curve_parameters[PARAM_SCALE].is_valid()) {
+ float tmp_scale = curve_parameters[PARAM_SCALE]->interpolate(tv);
+ tex_scale.x = tmp_scale;
+ tex_scale.y = tmp_scale;
+ tex_scale.z = tmp_scale;
+ }
}
real_t tex_hue_variation = 0.0;
@@ -955,7 +1018,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
tex_hue_variation = curve_parameters[PARAM_HUE_VARIATION]->interpolate(tv);
}
- real_t hue_rot_angle = (parameters[PARAM_HUE_VARIATION] + tex_hue_variation) * Math_TAU * Math::lerp(1, p.hue_rot_rand * 2.0f - 1.0f, randomness[PARAM_HUE_VARIATION]);
+ real_t hue_rot_angle = (tex_hue_variation)*Math_TAU * Math::lerp(parameters_min[PARAM_HUE_VARIATION], parameters_max[PARAM_HUE_VARIATION], p.hue_rot_rand);
real_t hue_rot_c = Math::cos(hue_rot_angle);
real_t hue_rot_s = Math::sin(hue_rot_angle);
@@ -1025,13 +1088,21 @@ void CPUParticles3D::_particles_process(double p_delta) {
}
}
+ p.transform.basis = p.transform.basis.orthonormalized();
//scale by scale
- real_t base_scale = tex_scale * Math::lerp(parameters[PARAM_SCALE], (real_t)1.0, p.scale_rand * randomness[PARAM_SCALE]);
- if (base_scale < CMP_EPSILON) {
- base_scale = CMP_EPSILON;
+
+ Vector3 base_scale = tex_scale * Math::lerp(parameters_min[PARAM_SCALE], parameters_max[PARAM_SCALE], p.scale_rand);
+ if (base_scale.x < CMP_EPSILON) {
+ base_scale.x = CMP_EPSILON;
+ }
+ if (base_scale.y < CMP_EPSILON) {
+ base_scale.y = CMP_EPSILON;
+ }
+ if (base_scale.z < CMP_EPSILON) {
+ base_scale.z = CMP_EPSILON;
}
- p.transform.basis.scale(Vector3(1, 1, 1) * base_scale);
+ p.transform.basis.scale(base_scale);
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
p.velocity.z = 0.0;
@@ -1267,18 +1338,25 @@ void CPUParticles3D::convert_from_particles(Node *p_particles) {
set_emission_shape(EmissionShape(material->get_emission_shape()));
set_emission_sphere_radius(material->get_emission_sphere_radius());
set_emission_box_extents(material->get_emission_box_extents());
+ Ref<CurveXYZTexture> scale3D = material->get_param_texture(ParticlesMaterial::PARAM_SCALE);
+ if (scale3D.is_valid()) {
+ split_scale = true;
+ scale_curve_x = scale3D->get_curve_x();
+ scale_curve_y = scale3D->get_curve_y();
+ scale_curve_z = scale3D->get_curve_z();
+ }
set_gravity(material->get_gravity());
set_lifetime_randomness(material->get_lifetime_randomness());
#define CONVERT_PARAM(m_param) \
- set_param(m_param, material->get_param(ParticlesMaterial::m_param)); \
+ set_param_min(m_param, material->get_param_min(ParticlesMaterial::m_param)); \
{ \
Ref<CurveTexture> ctex = material->get_param_texture(ParticlesMaterial::m_param); \
if (ctex.is_valid()) \
set_param_curve(m_param, ctex->get_curve()); \
} \
- set_param_randomness(m_param, material->get_param_randomness(ParticlesMaterial::m_param));
+ set_param_max(m_param, material->get_param_max(ParticlesMaterial::m_param));
CONVERT_PARAM(PARAM_INITIAL_LINEAR_VELOCITY);
CONVERT_PARAM(PARAM_ANGULAR_VELOCITY);
@@ -1364,11 +1442,11 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &CPUParticles3D::set_flatness);
ClassDB::bind_method(D_METHOD("get_flatness"), &CPUParticles3D::get_flatness);
- ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &CPUParticles3D::set_param);
- ClassDB::bind_method(D_METHOD("get_param", "param"), &CPUParticles3D::get_param);
+ ClassDB::bind_method(D_METHOD("set_param_min", "param", "value"), &CPUParticles3D::set_param_min);
+ ClassDB::bind_method(D_METHOD("get_param_min", "param"), &CPUParticles3D::get_param_min);
- ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &CPUParticles3D::set_param_randomness);
- ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &CPUParticles3D::get_param_randomness);
+ ClassDB::bind_method(D_METHOD("set_param_max", "param", "value"), &CPUParticles3D::set_param_max);
+ ClassDB::bind_method(D_METHOD("get_param_max", "param"), &CPUParticles3D::get_param_max);
ClassDB::bind_method(D_METHOD("set_param_curve", "param", "curve"), &CPUParticles3D::set_param_curve);
ClassDB::bind_method(D_METHOD("get_param_curve", "param"), &CPUParticles3D::get_param_curve);
@@ -1415,6 +1493,18 @@ void CPUParticles3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_gravity"), &CPUParticles3D::get_gravity);
ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &CPUParticles3D::set_gravity);
+ ClassDB::bind_method(D_METHOD("get_split_scale"), &CPUParticles3D::get_split_scale);
+ ClassDB::bind_method(D_METHOD("set_split_scale", "split_scale"), &CPUParticles3D::set_split_scale);
+
+ ClassDB::bind_method(D_METHOD("get_scale_curve_x"), &CPUParticles3D::get_scale_curve_x);
+ ClassDB::bind_method(D_METHOD("set_scale_curve_x", "scale_curve"), &CPUParticles3D::set_scale_curve_x);
+
+ ClassDB::bind_method(D_METHOD("get_scale_curve_y"), &CPUParticles3D::get_scale_curve_y);
+ ClassDB::bind_method(D_METHOD("set_scale_curve_y", "scale_curve"), &CPUParticles3D::set_scale_curve_y);
+
+ ClassDB::bind_method(D_METHOD("get_scale_curve_z"), &CPUParticles3D::get_scale_curve_z);
+ ClassDB::bind_method(D_METHOD("set_scale_curve_z", "scale_curve"), &CPUParticles3D::set_scale_curve_z);
+
ClassDB::bind_method(D_METHOD("convert_from_particles", "particles"), &CPUParticles3D::convert_from_particles);
ADD_GROUP("Emission Shape", "emission_");
@@ -1439,54 +1529,58 @@ void CPUParticles3D::_bind_methods() {
ADD_GROUP("Gravity", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity");
ADD_GROUP("Initial Velocity", "initial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY);
ADD_GROUP("Angular Velocity", "angular_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGULAR_VELOCITY);
ADD_GROUP("Orbit Velocity", "orbit_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ORBIT_VELOCITY);
ADD_GROUP("Linear Accel", "linear_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_LINEAR_ACCEL);
ADD_GROUP("Radial Accel", "radial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_RADIAL_ACCEL);
ADD_GROUP("Tangential Accel", "tangential_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param", "get_param", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_min", "get_param_min", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01"), "set_param_max", "get_param_max", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_DAMPING);
ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param", "get_param", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANGLE);
ADD_GROUP("Scale", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_amount_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_SCALE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_amount_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_SCALE);
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "split_scale"), "set_split_scale", "get_split_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scale_curve_x", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_scale_curve_x", "get_scale_curve_x");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scale_curve_y", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_scale_curve_y", "get_scale_curve_y");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "scale_curve_z", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_scale_curve_z", "get_scale_curve_z");
ADD_GROUP("Color", "");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_color_ramp", "get_color_ramp");
ADD_GROUP("Hue Variation", "hue_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_HUE_VARIATION);
ADD_GROUP("Animation", "anim_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater,or_lesser"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_param_curve", "get_param_curve", PARAM_ANIM_OFFSET);
BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY);
@@ -1527,18 +1621,30 @@ CPUParticles3D::CPUParticles3D() {
set_emitting(true);
set_amount(8);
- set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
- set_param(PARAM_ANGULAR_VELOCITY, 0);
- set_param(PARAM_ORBIT_VELOCITY, 0);
- set_param(PARAM_LINEAR_ACCEL, 0);
- set_param(PARAM_RADIAL_ACCEL, 0);
- set_param(PARAM_TANGENTIAL_ACCEL, 0);
- set_param(PARAM_DAMPING, 0);
- set_param(PARAM_ANGLE, 0);
- set_param(PARAM_SCALE, 1);
- set_param(PARAM_HUE_VARIATION, 0);
- set_param(PARAM_ANIM_SPEED, 0);
- set_param(PARAM_ANIM_OFFSET, 0);
+ set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_min(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_min(PARAM_ORBIT_VELOCITY, 0);
+ set_param_min(PARAM_LINEAR_ACCEL, 0);
+ set_param_min(PARAM_RADIAL_ACCEL, 0);
+ set_param_min(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_min(PARAM_DAMPING, 0);
+ set_param_min(PARAM_ANGLE, 0);
+ set_param_min(PARAM_SCALE, 1);
+ set_param_min(PARAM_HUE_VARIATION, 0);
+ set_param_min(PARAM_ANIM_SPEED, 0);
+ set_param_min(PARAM_ANIM_OFFSET, 0);
+ set_param_max(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_max(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_max(PARAM_ORBIT_VELOCITY, 0);
+ set_param_max(PARAM_LINEAR_ACCEL, 0);
+ set_param_max(PARAM_RADIAL_ACCEL, 0);
+ set_param_max(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_max(PARAM_DAMPING, 0);
+ set_param_max(PARAM_ANGLE, 0);
+ set_param_max(PARAM_SCALE, 1);
+ set_param_max(PARAM_HUE_VARIATION, 0);
+ set_param_max(PARAM_ANIM_SPEED, 0);
+ set_param_max(PARAM_ANIM_OFFSET, 0);
set_emission_shape(EMISSION_SHAPE_POINT);
set_emission_sphere_radius(1);
set_emission_box_extents(Vector3(1, 1, 1));
@@ -1549,10 +1655,6 @@ CPUParticles3D::CPUParticles3D() {
set_gravity(Vector3(0, -9.8, 0));
- for (int i = 0; i < PARAM_MAX; i++) {
- set_param_randomness(Parameter(i), 0);
- }
-
for (int i = 0; i < PARTICLE_FLAG_MAX; i++) {
particle_flags[i] = false;
}
diff --git a/scene/3d/cpu_particles_3d.h b/scene/3d/cpu_particles_3d.h
index 5b60322f05..160814ead4 100644
--- a/scene/3d/cpu_particles_3d.h
+++ b/scene/3d/cpu_particles_3d.h
@@ -154,8 +154,8 @@ private:
real_t spread = 45.0;
real_t flatness = 0.0;
- real_t parameters[PARAM_MAX];
- real_t randomness[PARAM_MAX] = {};
+ real_t parameters_min[PARAM_MAX];
+ real_t parameters_max[PARAM_MAX] = {};
Ref<Curve> curve_parameters[PARAM_MAX];
Color color = Color(1, 1, 1, 1);
@@ -175,6 +175,11 @@ private:
real_t emission_ring_radius;
real_t emission_ring_inner_radius;
+ Ref<Curve> scale_curve_x;
+ Ref<Curve> scale_curve_y;
+ Ref<Curve> scale_curve_z;
+ bool split_scale = false;
+
Vector3 gravity = Vector3(0, -9.8, 0);
void _update_internal();
@@ -246,11 +251,11 @@ public:
void set_flatness(real_t p_flatness);
real_t get_flatness() const;
- void set_param(Parameter p_param, real_t p_value);
- real_t get_param(Parameter p_param) const;
+ void set_param_min(Parameter p_param, real_t p_value);
+ real_t get_param_min(Parameter p_param) const;
- void set_param_randomness(Parameter p_param, real_t p_value);
- real_t get_param_randomness(Parameter p_param) const;
+ void set_param_max(Parameter p_param, real_t p_value);
+ real_t get_param_max(Parameter p_param) const;
void set_param_curve(Parameter p_param, const Ref<Curve> &p_curve);
Ref<Curve> get_param_curve(Parameter p_param) const;
@@ -275,6 +280,10 @@ public:
void set_emission_ring_height(real_t p_height);
void set_emission_ring_radius(real_t p_radius);
void set_emission_ring_inner_radius(real_t p_radius);
+ void set_scale_curve_x(Ref<Curve> p_scale_curve);
+ void set_scale_curve_y(Ref<Curve> p_scale_curve);
+ void set_scale_curve_z(Ref<Curve> p_scale_curve);
+ void set_split_scale(bool p_split_scale);
EmissionShape get_emission_shape() const;
real_t get_emission_sphere_radius() const;
@@ -287,6 +296,10 @@ public:
real_t get_emission_ring_height() const;
real_t get_emission_ring_radius() const;
real_t get_emission_ring_inner_radius() const;
+ Ref<Curve> get_scale_curve_x() const;
+ Ref<Curve> get_scale_curve_y() const;
+ Ref<Curve> get_scale_curve_z() const;
+ bool get_split_scale();
void set_gravity(const Vector3 &p_gravity);
Vector3 get_gravity() const;
diff --git a/scene/3d/gpu_particles_3d.cpp b/scene/3d/gpu_particles_3d.cpp
index d56228df66..baf28ae102 100644
--- a/scene/3d/gpu_particles_3d.cpp
+++ b/scene/3d/gpu_particles_3d.cpp
@@ -312,7 +312,7 @@ TypedArray<String> GPUParticles3D::get_configuration_warnings() const {
} else {
const ParticlesMaterial *process = Object::cast_to<ParticlesMaterial>(process_material.ptr());
if (!anim_material_found && process &&
- (process->get_param(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
+ (process->get_param_max(ParticlesMaterial::PARAM_ANIM_SPEED) != 0.0 || process->get_param_max(ParticlesMaterial::PARAM_ANIM_OFFSET) != 0.0 ||
process->get_param_texture(ParticlesMaterial::PARAM_ANIM_SPEED).is_valid() || process->get_param_texture(ParticlesMaterial::PARAM_ANIM_OFFSET).is_valid())) {
warnings.push_back(TTR("Particles animation requires the usage of a BaseMaterial3D whose Billboard Mode is set to \"Particle Billboard\"."));
}
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 092efc55d7..d34331e1d8 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -599,9 +599,9 @@ void RigidBody3D::_direct_state_changed(Object *p_state) {
sleeping = state->is_sleeping();
emit_signal(SceneStringNames::get_singleton()->sleeping_state_changed);
}
- if (get_script_instance()) {
- get_script_instance()->call("_integrate_forces", state);
- }
+
+ GDVIRTUAL_CALL(_integrate_forces, state);
+
set_ignore_transform_notification(false);
_on_transform_changed();
@@ -1022,7 +1022,7 @@ void RigidBody3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_colliding_bodies"), &RigidBody3D::get_colliding_bodies);
- BIND_VMETHOD(MethodInfo("_integrate_forces", PropertyInfo(Variant::OBJECT, "state", PROPERTY_HINT_RESOURCE_TYPE, "PhysicsDirectBodyState3D")));
+ GDVIRTUAL_BIND(_integrate_forces, "state");
ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Dynamic,Static,DynamicLocked,Kinematic"), "set_mode", "get_mode");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "mass", PROPERTY_HINT_RANGE, "0.01,65535,0.01,exp"), "set_mass", "get_mass");
@@ -1080,8 +1080,6 @@ void RigidBody3D::_reload_physics_characteristics() {
#define FLOOR_ANGLE_THRESHOLD 0.01
bool CharacterBody3D::move_and_slide() {
- Vector3 body_velocity_normal = linear_velocity.normalized();
-
bool was_on_floor = on_floor;
// Hack in order to work with calling from _process as well as from _physics_process; calling from thread is risky
@@ -1111,7 +1109,7 @@ bool CharacterBody3D::move_and_slide() {
floor_normal = Vector3();
floor_velocity = Vector3();
- if (current_floor_velocity != Vector3() && on_floor_body.is_valid()) {
+ if (!current_floor_velocity.is_equal_approx(Vector3()) && on_floor_body.is_valid()) {
PhysicsServer3D::MotionResult floor_result;
Set<RID> exclude;
exclude.insert(on_floor_body);
@@ -1130,39 +1128,35 @@ bool CharacterBody3D::move_and_slide() {
for (int iteration = 0; iteration < max_slides; ++iteration) {
PhysicsServer3D::MotionResult result;
- bool found_collision = false;
-
bool collided = move_and_collide(motion, result, margin, false, !sliding_enabled);
- if (!collided) {
- motion = Vector3(); //clear because no collision happened and motion completed
- } else {
- found_collision = true;
-
+ if (collided) {
motion_results.push_back(result);
_set_collision_direction(result);
- if (on_floor && floor_stop_on_slope) {
- if ((body_velocity_normal + up_direction).length() < 0.01) {
- Transform3D gt = get_global_transform();
- if (result.travel.length() > margin) {
- gt.origin -= result.travel.slide(up_direction);
- } else {
- gt.origin -= result.travel;
- }
- set_global_transform(gt);
- linear_velocity = Vector3();
- return true;
+ if (on_floor && floor_stop_on_slope && (linear_velocity.normalized() + up_direction).length() < 0.01) {
+ Transform3D gt = get_global_transform();
+ if (result.travel.length() > margin) {
+ gt.origin -= result.travel.slide(up_direction);
+ } else {
+ gt.origin -= result.travel;
}
+ set_global_transform(gt);
+ linear_velocity = Vector3();
+ motion = Vector3();
+ break;
}
- if (sliding_enabled || !on_floor) {
- motion = result.remainder.slide(result.collision_normal);
- linear_velocity = linear_velocity.slide(result.collision_normal);
+ if (result.remainder.is_equal_approx(Vector3())) {
+ motion = Vector3();
+ break;
+ }
- for (int j = 0; j < 3; j++) {
- if (locked_axis & (1 << j)) {
- linear_velocity[j] = 0.0;
- }
+ if (sliding_enabled || !on_floor) {
+ Vector3 slide_motion = result.remainder.slide(result.collision_normal);
+ if (slide_motion.dot(linear_velocity) > 0.0) {
+ motion = slide_motion;
+ } else {
+ motion = Vector3();
}
} else {
motion = result.remainder;
@@ -1171,12 +1165,12 @@ bool CharacterBody3D::move_and_slide() {
sliding_enabled = true;
- if (!found_collision || motion == Vector3()) {
+ if (!collided || motion.is_equal_approx(Vector3())) {
break;
}
}
- if (was_on_floor && snap != Vector3()) {
+ if (was_on_floor && !on_floor && !snap.is_equal_approx(Vector3())) {
// Apply snap.
Transform3D gt = get_global_transform();
PhysicsServer3D::MotionResult result;
@@ -1213,6 +1207,11 @@ bool CharacterBody3D::move_and_slide() {
linear_velocity += current_floor_velocity;
}
+ // Reset the gravity accumulation when touching the ground.
+ if (on_floor && linear_velocity.dot(up_direction) <= 0) {
+ linear_velocity = linear_velocity.slide(up_direction);
+ }
+
return motion_results.size() > 0;
}
diff --git a/scene/3d/physics_body_3d.h b/scene/3d/physics_body_3d.h
index 9c40f92f06..26b9a39047 100644
--- a/scene/3d/physics_body_3d.h
+++ b/scene/3d/physics_body_3d.h
@@ -132,6 +132,8 @@ public:
MODE_KINEMATIC,
};
+ GDVIRTUAL1(_integrate_forces, PhysicsDirectBodyState3D *)
+
protected:
bool can_sleep = true;
PhysicsDirectBodyState3D *state = nullptr;
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index 543545b90f..88fb960164 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -36,8 +36,9 @@
#include "servers/audio/audio_stream.h"
void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
- if (get_script_instance()) {
- Array parameters = get_script_instance()->call("_get_parameter_list");
+ Array parameters;
+
+ if (GDVIRTUAL_CALL(_get_parameter_list, parameters)) {
for (int i = 0; i < parameters.size(); i++) {
Dictionary d = parameters[i];
ERR_CONTINUE(d.is_empty());
@@ -47,8 +48,9 @@ void AnimationNode::get_parameter_list(List<PropertyInfo> *r_list) const {
}
Variant AnimationNode::get_parameter_default_value(const StringName &p_parameter) const {
- if (get_script_instance()) {
- return get_script_instance()->call("_get_parameter_default_value", p_parameter);
+ Variant ret;
+ if (GDVIRTUAL_CALL(_get_parameter_default_value, p_parameter, ret)) {
+ return ret;
}
return Variant();
}
@@ -72,8 +74,8 @@ Variant AnimationNode::get_parameter(const StringName &p_name) const {
}
void AnimationNode::get_child_nodes(List<ChildNode> *r_child_nodes) {
- if (get_script_instance()) {
- Dictionary cn = get_script_instance()->call("_get_child_nodes");
+ Dictionary cn;
+ if (GDVIRTUAL_CALL(_get_child_nodes, cn)) {
List<Variant> keys;
cn.get_key_list(&keys);
for (const Variant &E : keys) {
@@ -298,8 +300,9 @@ String AnimationNode::get_input_name(int p_input) {
}
String AnimationNode::get_caption() const {
- if (get_script_instance()) {
- return get_script_instance()->call("_get_caption");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_caption, ret)) {
+ return ret;
}
return "Node";
@@ -329,8 +332,9 @@ void AnimationNode::remove_input(int p_index) {
}
double AnimationNode::process(double p_time, bool p_seek) {
- if (get_script_instance()) {
- return get_script_instance()->call("_process", p_time, p_seek);
+ double ret;
+ if (GDVIRTUAL_CALL(_process, p_time, p_seek, ret)) {
+ return ret;
}
return 0;
@@ -357,8 +361,9 @@ bool AnimationNode::is_path_filtered(const NodePath &p_path) const {
}
bool AnimationNode::has_filter() const {
- if (get_script_instance()) {
- return get_script_instance()->call("_has_filter");
+ bool ret;
+ if (GDVIRTUAL_CALL(_has_filter, ret)) {
+ return ret;
}
return false;
@@ -390,8 +395,9 @@ void AnimationNode::_validate_property(PropertyInfo &property) const {
}
Ref<AnimationNode> AnimationNode::get_child_by_name(const StringName &p_name) {
- if (get_script_instance()) {
- return get_script_instance()->call("_get_child_by_name", p_name);
+ Ref<AnimationNode> ret;
+ if (GDVIRTUAL_CALL(_get_child_by_name, p_name, ret)) {
+ return ret;
}
return Ref<AnimationNode>();
}
@@ -422,17 +428,13 @@ void AnimationNode::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "filter_enabled", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_filter_enabled", "is_filter_enabled");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "filters", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_filters", "_get_filters");
- BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_child_nodes"));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_get_parameter_list"));
- BIND_VMETHOD(MethodInfo(Variant::OBJECT, "_get_child_by_name", PropertyInfo(Variant::STRING, "name")));
- {
- MethodInfo mi = MethodInfo(Variant::NIL, "_get_parameter_default_value", PropertyInfo(Variant::STRING_NAME, "name"));
- mi.return_val.usage = PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(mi);
- }
- BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "time"), PropertyInfo(Variant::BOOL, "seek")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_caption"));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_has_filter"));
+ GDVIRTUAL_BIND(_get_child_nodes);
+ GDVIRTUAL_BIND(_get_parameter_list);
+ GDVIRTUAL_BIND(_get_child_by_name, "name");
+ GDVIRTUAL_BIND(_get_parameter_default_value, "parameter");
+ GDVIRTUAL_BIND(_process, "time", "seek");
+ GDVIRTUAL_BIND(_get_caption);
+ GDVIRTUAL_BIND(_has_filter);
ADD_SIGNAL(MethodInfo("removed_from_graph"));
diff --git a/scene/animation/animation_tree.h b/scene/animation/animation_tree.h
index 59bbc5b4da..1e0267682e 100644
--- a/scene/animation/animation_tree.h
+++ b/scene/animation/animation_tree.h
@@ -112,6 +112,14 @@ protected:
void _set_parent(Object *p_parent);
+ GDVIRTUAL0RC(Dictionary, _get_child_nodes)
+ GDVIRTUAL0RC(Array, _get_parameter_list)
+ GDVIRTUAL1RC(Ref<AnimationNode>, _get_child_by_name, StringName)
+ GDVIRTUAL1RC(Variant, _get_parameter_default_value, StringName)
+ GDVIRTUAL2RC(double, _process, double, bool)
+ GDVIRTUAL0RC(String, _get_caption)
+ GDVIRTUAL0RC(bool, _has_filter)
+
public:
virtual void get_parameter_list(List<PropertyInfo> *r_list) const;
virtual Variant get_parameter_default_value(const StringName &p_parameter) const;
diff --git a/scene/audio/audio_stream_player.cpp b/scene/audio/audio_stream_player.cpp
index 298d75b668..9383355292 100644
--- a/scene/audio/audio_stream_player.cpp
+++ b/scene/audio/audio_stream_player.cpp
@@ -202,8 +202,12 @@ void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
}
if (p_stream.is_valid()) {
- stream = p_stream;
stream_playback = p_stream->instance_playback();
+ if (stream_playback.is_valid()) {
+ stream = p_stream;
+ } else {
+ stream.unref();
+ }
}
AudioServer::get_singleton()->unlock();
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index d252a4507c..bef1011364 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -52,7 +52,7 @@ void BaseButton::_unpress_group() {
}
}
-void BaseButton::_gui_input(Ref<InputEvent> p_event) {
+void BaseButton::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (status.disabled) { // no interaction with disabled button
@@ -121,17 +121,13 @@ void BaseButton::_notification(int p_what) {
}
void BaseButton::_pressed() {
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_pressed);
- }
+ GDVIRTUAL_CALL(_pressed);
pressed();
emit_signal(SNAME("pressed"));
}
void BaseButton::_toggled(bool p_pressed) {
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, p_pressed);
- }
+ GDVIRTUAL_CALL(_toggled, p_pressed);
toggled(p_pressed);
emit_signal(SNAME("toggled"), p_pressed);
}
@@ -342,7 +338,7 @@ Ref<Shortcut> BaseButton::get_shortcut() const {
return shortcut;
}
-void BaseButton::_unhandled_key_input(Ref<InputEvent> p_event) {
+void BaseButton::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!_is_focus_owner_in_shorcut_context()) {
@@ -411,8 +407,6 @@ bool BaseButton::_is_focus_owner_in_shorcut_context() const {
}
void BaseButton::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &BaseButton::_gui_input);
- ClassDB::bind_method(D_METHOD("_unhandled_key_input"), &BaseButton::_unhandled_key_input);
ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &BaseButton::set_pressed);
ClassDB::bind_method(D_METHOD("is_pressed"), &BaseButton::is_pressed);
ClassDB::bind_method(D_METHOD("set_pressed_no_signal", "pressed"), &BaseButton::set_pressed_no_signal);
@@ -440,8 +434,8 @@ void BaseButton::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shortcut_context", "node"), &BaseButton::set_shortcut_context);
ClassDB::bind_method(D_METHOD("get_shortcut_context"), &BaseButton::get_shortcut_context);
- BIND_VMETHOD(MethodInfo("_pressed"));
- BIND_VMETHOD(MethodInfo("_toggled", PropertyInfo(Variant::BOOL, "button_pressed")));
+ GDVIRTUAL_BIND(_pressed);
+ GDVIRTUAL_BIND(_toggled, "button_pressed");
ADD_SIGNAL(MethodInfo("pressed"));
ADD_SIGNAL(MethodInfo("button_up"));
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index d86b35daf0..cd6e78464f 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -75,12 +75,15 @@ protected:
virtual void pressed();
virtual void toggled(bool p_pressed);
static void _bind_methods();
- virtual void _gui_input(Ref<InputEvent> p_event);
- virtual void _unhandled_key_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
bool _is_focus_owner_in_shorcut_context() const;
+ GDVIRTUAL0(_pressed)
+ GDVIRTUAL1(_toggled, bool)
+
public:
enum DrawMode {
DRAW_NORMAL,
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 08dd7f28eb..27cac73aef 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -248,7 +248,7 @@ void CodeEdit::_notification(int p_what) {
}
}
-void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
+void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventMouseButton> mb = p_gui_input;
if (mb.is_valid()) {
@@ -354,7 +354,7 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
Ref<InputEventKey> k = p_gui_input;
bool update_code_completion = false;
if (!k.is_valid()) {
- TextEdit::_gui_input(p_gui_input);
+ TextEdit::gui_input(p_gui_input);
return;
}
@@ -450,7 +450,7 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
if (k->is_action("ui_text_backspace", true)) {
backspace();
- _filter_code_completion_candidates();
+ _filter_code_completion_candidates_impl();
accept_event();
return;
}
@@ -519,10 +519,10 @@ void CodeEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
set_code_hint("");
}
- TextEdit::_gui_input(p_gui_input);
+ TextEdit::gui_input(p_gui_input);
if (update_code_completion) {
- _filter_code_completion_candidates();
+ _filter_code_completion_candidates_impl();
}
}
@@ -557,7 +557,7 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
/* Text manipulation */
// Overridable actions
-void CodeEdit::_handle_unicode_input(const uint32_t p_unicode) {
+void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
bool had_selection = has_selection();
if (had_selection) {
begin_complex_operation();
@@ -609,7 +609,7 @@ void CodeEdit::_handle_unicode_input(const uint32_t p_unicode) {
}
}
-void CodeEdit::_backspace() {
+void CodeEdit::_backspace_internal() {
if (!is_editable()) {
return;
}
@@ -1739,9 +1739,7 @@ String CodeEdit::get_text_for_code_completion() const {
}
void CodeEdit::request_code_completion(bool p_force) {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_request_code_completion")) {
- si->call("_request_code_completion", p_force);
+ if (GDVIRTUAL_CALL(_request_code_completion, p_force)) {
return;
}
@@ -1798,7 +1796,7 @@ void CodeEdit::update_code_completion_options(bool p_forced) {
code_completion_forced = p_forced;
code_completion_option_sources = code_completion_option_submitted;
code_completion_option_submitted.clear();
- _filter_code_completion_candidates();
+ _filter_code_completion_candidates_impl();
}
TypedArray<Dictionary> CodeEdit::get_code_completion_options() const {
@@ -1855,11 +1853,10 @@ void CodeEdit::confirm_code_completion(bool p_replace) {
return;
}
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_confirm_code_completion")) {
- si->call("_confirm_code_completion", p_replace);
+ if (GDVIRTUAL_CALL(_confirm_code_completion, p_replace)) {
return;
}
+
begin_complex_operation();
int caret_line = get_caret_line();
@@ -2179,9 +2176,10 @@ void CodeEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_code_comletion_prefixes"), &CodeEdit::get_code_completion_prefixes);
// Overridable
- BIND_VMETHOD(MethodInfo("_confirm_code_completion", PropertyInfo(Variant::BOOL, "replace")));
- BIND_VMETHOD(MethodInfo("_request_code_completion", PropertyInfo(Variant::BOOL, "force")));
- BIND_VMETHOD(MethodInfo(Variant::ARRAY, "_filter_code_completion_candidates", PropertyInfo(Variant::ARRAY, "candidates")));
+
+ GDVIRTUAL_BIND(_confirm_code_completion, "replace")
+ GDVIRTUAL_BIND(_request_code_completion, "force")
+ GDVIRTUAL_BIND(_filter_code_completion_candidates, "candidates")
/* Line length guidelines */
ClassDB::bind_method(D_METHOD("set_line_length_guidelines", "guideline_columns"), &CodeEdit::set_line_length_guidelines);
@@ -2650,11 +2648,10 @@ TypedArray<String> CodeEdit::_get_delimiters(DelimiterType p_type) const {
}
/* Code Completion */
-void CodeEdit::_filter_code_completion_candidates() {
- ScriptInstance *si = get_script_instance();
+void CodeEdit::_filter_code_completion_candidates_impl() {
int line_height = get_line_height();
- if (si && si->has_method("_filter_code_completion_candidates")) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_filter_code_completion_candidates)) {
code_completion_options.clear();
code_completion_base = "";
@@ -2674,7 +2671,9 @@ void CodeEdit::_filter_code_completion_candidates() {
i++;
}
- TypedArray<Dictionary> completion_options = si->call("_filter_code_completion_candidates", completion_options_sources);
+ Array completion_options;
+
+ GDVIRTUAL_CALL(_filter_code_completion_candidates, completion_options_sources, completion_options);
/* No options to complete, cancel. */
if (completion_options.size() == 0) {
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 76ac15f553..4fbb5194e6 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -219,7 +219,7 @@ private:
List<ScriptCodeCompletionOption> code_completion_option_sources;
String code_completion_base;
- void _filter_code_completion_candidates();
+ void _filter_code_completion_candidates_impl();
/* Line length guidelines */
TypedArray<int> line_length_guideline_columns;
@@ -248,7 +248,7 @@ private:
void _text_changed();
protected:
- void _gui_input(const Ref<InputEvent> &p_gui_input) override;
+ void gui_input(const Ref<InputEvent> &p_gui_input) override;
void _notification(int p_what);
static void _bind_methods();
@@ -256,8 +256,12 @@ protected:
/* Text manipulation */
// Overridable actions
- virtual void _handle_unicode_input(const uint32_t p_unicode) override;
- virtual void _backspace() override;
+ virtual void _handle_unicode_input_internal(const uint32_t p_unicode) override;
+ virtual void _backspace_internal() override;
+
+ GDVIRTUAL1(_confirm_code_completion, bool)
+ GDVIRTUAL1(_request_code_completion, bool)
+ GDVIRTUAL1RC(Array, _filter_code_completion_candidates, TypedArray<Dictionary>)
public:
/* General overrides */
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 261480bcdd..0dddb2b09a 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -46,13 +46,13 @@ void ColorPicker::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker")));
- bt_add_preset->set_icon(get_theme_icon(SNAME("add_preset")));
-
+ btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset")));
+ _update_presets();
_update_controls();
} break;
case NOTIFICATION_ENTER_TREE: {
btn_pick->set_icon(get_theme_icon(SNAME("screen_picker"), SNAME("ColorPicker")));
- bt_add_preset->set_icon(get_theme_icon(SNAME("add_preset")));
+ btn_add_preset->set_icon(get_theme_icon(SNAME("add_preset")));
_update_controls();
_update_color();
@@ -69,7 +69,6 @@ void ColorPicker::_notification(int p_what) {
for (int i = 0; i < preset_cache.size(); i++) {
presets.push_back(preset_cache[i]);
}
- preset->update();
}
#endif
} break;
@@ -98,6 +97,8 @@ Ref<Shader> ColorPicker::circle_shader;
void ColorPicker::init_shaders() {
wheel_shader.instantiate();
wheel_shader->set_code(R"(
+// ColorPicker wheel shader.
+
shader_type canvas_item;
void fragment() {
@@ -120,6 +121,8 @@ void fragment() {
circle_shader.instantiate();
circle_shader->set_code(R"(
+// ColorPicker circle shader.
+
shader_type canvas_item;
uniform float v = 1.0;
@@ -372,22 +375,23 @@ void ColorPicker::_update_color(bool p_update_sliders) {
}
void ColorPicker::_update_presets() {
- return;
- //presets should be shown using buttons or something else, this method is not a good idea
-
- presets_per_row = 10;
- Size2 size = bt_add_preset->get_size();
- Size2 preset_size = Size2(MIN(size.width * presets.size(), presets_per_row * size.width), size.height * (Math::ceil((float)presets.size() / presets_per_row)));
- preset->set_custom_minimum_size(preset_size);
- preset_container->set_custom_minimum_size(preset_size);
- preset->draw_rect(Rect2(Point2(), preset_size), Color(1, 1, 1, 0));
-
- for (int i = 0; i < presets.size(); i++) {
- int x = (i % presets_per_row) * size.width;
- int y = (Math::floor((float)i / presets_per_row)) * size.height;
- preset->draw_rect(Rect2(Point2(x, y), size), presets[i]);
+ int preset_size = _get_preset_size();
+ // Only update the preset button size if it has changed.
+ if (preset_size != prev_preset_size) {
+ prev_preset_size = preset_size;
+ btn_add_preset->set_custom_minimum_size(Size2(preset_size, preset_size));
+ for (int i = 1; i < preset_container->get_child_count(); i++) {
+ ColorPresetButton *cpb = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
+ cpb->set_custom_minimum_size(Size2(preset_size, preset_size));
+ }
+ }
+ // Only load preset buttons when the only child is the add-preset button.
+ if (preset_container->get_child_count() == 1) {
+ for (int i = 0; i < preset_cache.size(); i++) {
+ _add_preset_button(preset_size, preset_cache[i]);
+ }
+ _notification(NOTIFICATION_VISIBILITY_CHANGED);
}
- _notification(NOTIFICATION_VISIBILITY_CHANGED);
}
void ColorPicker::_text_type_toggled() {
@@ -422,14 +426,37 @@ ColorPicker::PickerShapeType ColorPicker::get_picker_shape() const {
return picker_type;
}
+inline int ColorPicker::_get_preset_size() {
+ return (int(get_minimum_size().width) - (preset_container->get_theme_constant(SNAME("hseparation")) * (preset_column_count - 1))) / preset_column_count;
+}
+
+void ColorPicker::_add_preset_button(int p_size, const Color &p_color) {
+ ColorPresetButton *btn_preset = memnew(ColorPresetButton(p_color));
+ btn_preset->set_preset_color(p_color);
+ btn_preset->set_custom_minimum_size(Size2(p_size, p_size));
+ btn_preset->connect("gui_input", callable_mp(this, &ColorPicker::_preset_input), varray(p_color));
+ btn_preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Apply color\nRMB: Remove preset"), p_color.to_html(p_color.a < 1)));
+ preset_container->add_child(btn_preset);
+}
+
void ColorPicker::add_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.move_to_back(presets.find(p_color));
+
+ // Find button to move to the end.
+ for (int i = 1; i < preset_container->get_child_count(); i++) {
+ ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
+ if (current_btn && p_color == current_btn->get_preset_color()) {
+ preset_container->move_child(current_btn, preset_container->get_child_count() - 1);
+ break;
+ }
+ }
} else {
presets.push_back(p_color);
preset_cache.push_back(p_color);
+
+ _add_preset_button(_get_preset_size(), p_color);
}
- preset->update();
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
@@ -443,7 +470,15 @@ void ColorPicker::erase_preset(const Color &p_color) {
if (presets.find(p_color)) {
presets.erase(presets.find(p_color));
preset_cache.erase(preset_cache.find(p_color));
- preset->update();
+
+ // Find preset button to remove.
+ for (int i = 1; i < preset_container->get_child_count(); i++) {
+ ColorPresetButton *current_btn = Object::cast_to<ColorPresetButton>(preset_container->get_child(i));
+ if (current_btn && p_color == current_btn->get_preset_color()) {
+ current_btn->queue_delete();
+ break;
+ }
+ }
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
@@ -560,7 +595,7 @@ void ColorPicker::_sample_draw() {
const Rect2 rect_old = Rect2(Point2(), Size2(sample->get_size().width * 0.5, sample->get_size().height * 0.95));
if (display_old_color && old_color.a < 1.0) {
- sample->draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPicker")), rect_old, true);
+ sample->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), rect_old, true);
}
sample->draw_rect(rect_old, old_color);
@@ -574,7 +609,7 @@ void ColorPicker::_sample_draw() {
}
if (color.a < 1.0) {
- sample->draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPicker")), rect_new, true);
+ sample->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), rect_new, true);
}
sample->draw_rect(rect_new, color);
@@ -734,7 +769,7 @@ void ColorPicker::_slider_draw(int p_which) {
#endif
if (p_which == 3) {
- scroll[p_which]->draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
+ scroll[p_which]->draw_texture_rect(get_theme_icon(SNAME("sample_bg"), SNAME("ColorPicker")), Rect2(Point2(0, margin), Size2(size.x, margin)), true);
left_color = color;
left_color.a = 0;
@@ -932,43 +967,19 @@ void ColorPicker::_w_input(const Ref<InputEvent> &p_event) {
}
}
-void ColorPicker::_preset_input(const Ref<InputEvent> &p_event) {
+void ColorPicker::_preset_input(const Ref<InputEvent> &p_event, const Color &p_color) {
Ref<InputEventMouseButton> bev = p_event;
if (bev.is_valid()) {
- int index = 0;
if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_LEFT) {
- for (int i = 0; i < presets.size(); i++) {
- int x = (i % presets_per_row) * bt_add_preset->get_size().x;
- int y = (Math::floor((float)i / presets_per_row)) * bt_add_preset->get_size().y;
- if (bev->get_position().x > x && bev->get_position().x < x + preset->get_size().x && bev->get_position().y > y && bev->get_position().y < y + preset->get_size().y) {
- index = i;
- }
- }
- set_pick_color(presets[index]);
+ set_pick_color(p_color);
_update_color();
- emit_signal(SNAME("color_changed"), color);
+ emit_signal(SNAME("color_changed"), p_color);
} else if (bev->is_pressed() && bev->get_button_index() == MOUSE_BUTTON_RIGHT && presets_enabled) {
- index = bev->get_position().x / (preset->get_size().x / presets.size());
- Color clicked_preset = presets[index];
- erase_preset(clicked_preset);
- emit_signal(SNAME("preset_removed"), clicked_preset);
- bt_add_preset->show();
+ erase_preset(p_color);
+ emit_signal(SNAME("preset_removed"), p_color);
}
}
-
- Ref<InputEventMouseMotion> mev = p_event;
-
- if (mev.is_valid()) {
- int index = mev->get_position().x * presets.size();
- if (preset->get_size().x != 0) {
- index /= preset->get_size().x;
- }
- if (index < 0 || index >= presets.size()) {
- return;
- }
- preset->set_tooltip(vformat(RTR("Color: #%s\nLMB: Set color\nRMB: Remove preset"), presets[index].to_html(presets[index].a < 1)));
- }
}
void ColorPicker::_screen_input(const Ref<InputEvent> &p_event) {
@@ -1064,11 +1075,11 @@ void ColorPicker::_html_focus_exit() {
void ColorPicker::set_presets_enabled(bool p_enabled) {
presets_enabled = p_enabled;
if (!p_enabled) {
- bt_add_preset->set_disabled(true);
- bt_add_preset->set_focus_mode(FOCUS_NONE);
+ btn_add_preset->set_disabled(true);
+ btn_add_preset->set_focus_mode(FOCUS_NONE);
} else {
- bt_add_preset->set_disabled(false);
- bt_add_preset->set_focus_mode(FOCUS_ALL);
+ btn_add_preset->set_disabled(false);
+ btn_add_preset->set_focus_mode(FOCUS_ALL);
}
}
@@ -1080,7 +1091,6 @@ void ColorPicker::set_presets_visible(bool p_visible) {
presets_visible = p_visible;
preset_separator->set_visible(p_visible);
preset_container->set_visible(p_visible);
- preset_container2->set_visible(p_visible);
}
bool ColorPicker::are_presets_visible() const {
@@ -1266,17 +1276,13 @@ ColorPicker::ColorPicker() :
add_child(preset_separator);
preset_container->set_h_size_flags(SIZE_EXPAND_FILL);
+ preset_container->set_columns(preset_column_count);
add_child(preset_container);
- 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->set_h_size_flags(SIZE_EXPAND_FILL);
- add_child(preset_container2);
- preset_container2->add_child(bt_add_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));
+ btn_add_preset->set_icon_align(Button::ALIGN_CENTER);
+ btn_add_preset->set_tooltip(RTR("Add current color as a preset."));
+ btn_add_preset->connect("pressed", callable_mp(this, &ColorPicker::_add_preset_pressed));
+ preset_container->add_child(btn_add_preset);
}
/////////////////
@@ -1303,6 +1309,7 @@ void ColorPickerButton::pressed() {
_update_picker();
popup->set_as_minsize();
+ picker->_update_presets();
Rect2i usable_rect = popup->get_usable_parent_rect();
//let's try different positions to see which one we can use
@@ -1428,3 +1435,64 @@ void ColorPickerButton::_bind_methods() {
ColorPickerButton::ColorPickerButton() {
set_toggle_mode(true);
}
+
+/////////////////
+
+void ColorPresetButton::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_DRAW: {
+ const Rect2 r = Rect2(Point2(0, 0), get_size());
+ Ref<StyleBox> sb_raw = get_theme_stylebox(SNAME("preset_fg"), SNAME("ColorPresetButton"))->duplicate();
+ Ref<StyleBoxFlat> sb_flat = sb_raw;
+ Ref<StyleBoxTexture> sb_texture = sb_raw;
+
+ if (sb_flat.is_valid()) {
+ if (preset_color.a < 1) {
+ // Draw a background pattern when the color is transparent.
+ sb_flat->set_bg_color(Color(1, 1, 1));
+ sb_flat->draw(get_canvas_item(), r);
+
+ Rect2 bg_texture_rect = r.grow_side(SIDE_LEFT, -sb_flat->get_margin(SIDE_LEFT));
+ bg_texture_rect = bg_texture_rect.grow_side(SIDE_RIGHT, -sb_flat->get_margin(SIDE_RIGHT));
+ bg_texture_rect = bg_texture_rect.grow_side(SIDE_TOP, -sb_flat->get_margin(SIDE_TOP));
+ bg_texture_rect = bg_texture_rect.grow_side(SIDE_BOTTOM, -sb_flat->get_margin(SIDE_BOTTOM));
+
+ draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPresetButton")), bg_texture_rect, true);
+ sb_flat->set_bg_color(preset_color);
+ }
+ sb_flat->set_bg_color(preset_color);
+ sb_flat->draw(get_canvas_item(), r);
+ } else if (sb_texture.is_valid()) {
+ if (preset_color.a < 1) {
+ // Draw a background pattern when the color is transparent.
+ bool use_tile_texture = (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE) || (sb_texture->get_h_axis_stretch_mode() == StyleBoxTexture::AxisStretchMode::AXIS_STRETCH_MODE_TILE_FIT);
+ draw_texture_rect(get_theme_icon(SNAME("preset_bg"), SNAME("ColorPresetButton")), r, use_tile_texture);
+ }
+ sb_texture->set_modulate(preset_color);
+ sb_texture->draw(get_canvas_item(), r);
+ } else {
+ WARN_PRINT("Unsupported StyleBox used for ColorPresetButton. Use StyleBoxFlat or StyleBoxTexture instead.");
+ }
+ if (preset_color.r > 1 || preset_color.g > 1 || preset_color.b > 1) {
+ // Draw an indicator to denote that the color is "overbright" and can't be displayed accurately in the preview
+ draw_texture(Control::get_theme_icon(SNAME("overbright_indicator"), SNAME("ColorPresetButton")), Vector2(0, 0));
+ }
+
+ } break;
+ }
+}
+
+void ColorPresetButton::set_preset_color(const Color &p_color) {
+ preset_color = p_color;
+}
+
+Color ColorPresetButton::get_preset_color() const {
+ return preset_color;
+}
+
+ColorPresetButton::ColorPresetButton(Color p_color) {
+ preset_color = p_color;
+}
+
+ColorPresetButton::~ColorPresetButton() {
+}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index 60da3957aa..67ca007eb5 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -35,6 +35,7 @@
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/check_button.h"
+#include "scene/gui/grid_container.h"
#include "scene/gui/label.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/popup.h"
@@ -43,6 +44,22 @@
#include "scene/gui/spin_box.h"
#include "scene/gui/texture_rect.h"
+class ColorPresetButton : public BaseButton {
+ GDCLASS(ColorPresetButton, BaseButton);
+
+ Color preset_color;
+
+protected:
+ void _notification(int);
+
+public:
+ void set_preset_color(const Color &p_color);
+ Color get_preset_color() const;
+
+ ColorPresetButton(Color p_color);
+ ~ColorPresetButton();
+};
+
class ColorPicker : public BoxContainer {
GDCLASS(ColorPicker, BoxContainer);
@@ -69,12 +86,9 @@ private:
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);
+ GridContainer *preset_container = memnew(GridContainer);
HSeparator *preset_separator = memnew(HSeparator);
- Button *bt_add_preset = memnew(Button);
- List<Color> presets;
+ Button *btn_add_preset = memnew(Button);
Button *btn_pick = memnew(Button);
CheckButton *btn_hsv = memnew(CheckButton);
CheckButton *btn_raw = memnew(CheckButton);
@@ -83,14 +97,19 @@ private:
Label *labels[4];
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;
+ const int preset_column_count = 9;
+ int prev_preset_size = 0;
+ List<Color> presets;
+
Color color;
Color old_color;
+
bool display_old_color = false;
bool raw_mode_enabled = false;
bool hsv_mode_enabled = false;
@@ -100,6 +119,7 @@ private:
bool spinning = false;
bool presets_enabled = true;
bool presets_visible = true;
+
float h = 0.0;
float s = 0.0;
float v = 0.0;
@@ -109,7 +129,6 @@ private:
void _value_changed(double);
void _update_controls();
void _update_color(bool p_update_sliders = true);
- void _update_presets();
void _update_text_value();
void _text_type_toggled();
void _sample_input(const Ref<InputEvent> &p_event);
@@ -119,7 +138,7 @@ private:
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 _preset_input(const Ref<InputEvent> &p_event, const Color &p_color);
void _screen_input(const Ref<InputEvent> &p_event);
void _add_preset_pressed();
void _screen_pick_pressed();
@@ -127,6 +146,9 @@ private:
void _focus_exit();
void _html_focus_exit();
+ inline int _get_preset_size();
+ void _add_preset_button(int p_size, const Color &p_color);
+
protected:
void _notification(int);
static void _bind_methods();
@@ -152,6 +174,7 @@ public:
void add_preset(const Color &p_color);
void erase_preset(const Color &p_color);
PackedColorArray get_presets() const;
+ void _update_presets();
void set_hsv_mode(bool p_enabled);
bool is_hsv_mode() const;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index f114e06c75..4ac6a58d36 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -730,14 +730,9 @@ Variant Control::get_drag_data(const Point2 &p_point) {
}
}
- if (get_script_instance()) {
- Variant v = p_point;
- const Variant *p = &v;
- Callable::CallError ce;
- Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->_get_drag_data, &p, 1, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- return ret;
- }
+ Variant dd;
+ if (GDVIRTUAL_CALL(_get_drag_data, p_point, dd)) {
+ return dd;
}
return Variant();
@@ -752,16 +747,10 @@ bool Control::can_drop_data(const Point2 &p_point, const Variant &p_data) const
}
}
- if (get_script_instance()) {
- Variant v = p_point;
- const Variant *p[2] = { &v, &p_data };
- Callable::CallError ce;
- Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->_can_drop_data, p, 2, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- return ret;
- }
+ bool ret;
+ if (GDVIRTUAL_CALL(_can_drop_data, p_point, p_data, ret)) {
+ return ret;
}
-
return false;
}
@@ -775,15 +764,7 @@ void Control::drop_data(const Point2 &p_point, const Variant &p_data) {
}
}
- if (get_script_instance()) {
- Variant v = p_point;
- const Variant *p[2] = { &v, &p_data };
- Callable::CallError ce;
- Variant ret = get_script_instance()->call(SceneStringNames::get_singleton()->_drop_data, p, 2, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- return;
- }
- }
+ GDVIRTUAL_CALL(_drop_data, p_point, p_data);
}
void Control::force_drag(const Variant &p_data, Control *p_control) {
@@ -799,16 +780,26 @@ void Control::set_drag_preview(Control *p_control) {
get_viewport()->_gui_set_drag_preview(this, p_control);
}
+void Control::_call_gui_input(const Ref<InputEvent> &p_event) {
+ emit_signal(SceneStringNames::get_singleton()->gui_input, p_event); //signal should be first, so it's possible to override an event (and then accept it)
+ if (!is_inside_tree() || get_viewport()->is_input_handled()) {
+ return; //input was handled, abort
+ }
+ GDVIRTUAL_CALL(_gui_input, p_event);
+ if (!is_inside_tree() || get_viewport()->is_input_handled()) {
+ return; //input was handled, abort
+ }
+ gui_input(p_event);
+}
+void Control::gui_input(const Ref<InputEvent> &p_event) {
+}
+
Size2 Control::get_minimum_size() const {
- ScriptInstance *si = const_cast<Control *>(this)->get_script_instance();
- if (si) {
- Callable::CallError ce;
- Variant s = si->call(SceneStringNames::get_singleton()->_get_minimum_size, nullptr, 0, ce);
- if (ce.error == Callable::CallError::CALL_OK) {
- return s;
- }
+ Vector2 ms;
+ if (GDVIRTUAL_CALL(_get_minimum_size, ms)) {
+ return ms;
}
- return Size2();
+ return Vector2();
}
template <class T>
@@ -2123,8 +2114,9 @@ String Control::get_tooltip(const Point2 &p_pos) const {
}
Control *Control::make_custom_tooltip(const String &p_text) const {
- if (get_script_instance()) {
- return const_cast<Control *>(this)->call("_make_custom_tooltip", p_text);
+ Object *ret = nullptr;
+ if (GDVIRTUAL_CALL(_make_custom_tooltip, p_text, ret)) {
+ return Object::cast_to<Control>(ret);
}
return nullptr;
}
@@ -2499,14 +2491,11 @@ Vector<Vector2i> Control::structured_text_parser(StructuredTextParser p_theme_ty
}
} break;
case STRUCTURED_TEXT_CUSTOM: {
- if (get_script_instance()) {
- Variant data = get_script_instance()->call(SceneStringNames::get_singleton()->_structured_text_parser, p_args, p_text);
- if (data.get_type() == Variant::ARRAY) {
- Array _data = data;
- for (int i = 0; i < _data.size(); i++) {
- if (_data[i].get_type() == Variant::VECTOR2I) {
- ret.push_back(Vector2i(_data[i]));
- }
+ Array r;
+ if (GDVIRTUAL_CALL(_structured_text_parser, p_args, p_text, r)) {
+ for (int i = 0; i < r.size(); i++) {
+ if (r[i].get_type() == Variant::VECTOR2I) {
+ ret.push_back(Vector2i(r[i]));
}
}
}
@@ -2823,21 +2812,6 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Control::set_auto_translate);
ClassDB::bind_method(D_METHOD("is_auto_translating"), &Control::is_auto_translating);
- BIND_VMETHOD(MethodInfo("_structured_text_parser", PropertyInfo(Variant::ARRAY, "args"), PropertyInfo(Variant::STRING, "text")));
-
- BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size"));
-
- MethodInfo get_drag_data = MethodInfo("_get_drag_data", PropertyInfo(Variant::VECTOR2, "position"));
- get_drag_data.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
- BIND_VMETHOD(get_drag_data);
-
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_can_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
- BIND_VMETHOD(MethodInfo("_drop_data", PropertyInfo(Variant::VECTOR2, "position"), PropertyInfo(Variant::NIL, "data")));
- BIND_VMETHOD(MethodInfo(
- PropertyInfo(Variant::OBJECT, "control", PROPERTY_HINT_RESOURCE_TYPE, "Control"),
- "_make_custom_tooltip", PropertyInfo(Variant::STRING, "for_text")));
-
ADD_GROUP("Anchor", "anchor_");
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_left", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_LEFT);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anchor_top", PROPERTY_HINT_RANGE, "0,1,0.001,or_lesser,or_greater"), "_set_anchor", "get_anchor", SIDE_TOP);
@@ -2994,5 +2968,14 @@ void Control::_bind_methods() {
ADD_SIGNAL(MethodInfo("minimum_size_changed"));
ADD_SIGNAL(MethodInfo("theme_changed"));
- GDVIRTUAL_BIND(_has_point);
+ GDVIRTUAL_BIND(_has_point, "position");
+ GDVIRTUAL_BIND(_structured_text_parser, "args", "text");
+ GDVIRTUAL_BIND(_get_minimum_size);
+
+ GDVIRTUAL_BIND(_get_drag_data, "at_position");
+ GDVIRTUAL_BIND(_can_drop_data, "at_position", "data");
+ GDVIRTUAL_BIND(_drop_data, "at_position", "data");
+ GDVIRTUAL_BIND(_make_custom_tooltip, "for_text");
+
+ GDVIRTUAL_BIND(_gui_input, "event");
}
diff --git a/scene/gui/control.h b/scene/gui/control.h
index a871a8e9fb..0faa617f8d 100644
--- a/scene/gui/control.h
+++ b/scene/gui/control.h
@@ -31,10 +31,10 @@
#ifndef CONTROL_H
#define CONTROL_H
+#include "core/input/shortcut.h"
#include "core/math/transform_2d.h"
#include "core/object/gdvirtual.gen.inc"
#include "core/templates/rid.h"
-#include "scene/gui/shortcut.h"
#include "scene/main/canvas_item.h"
#include "scene/main/node.h"
#include "scene/main/timer.h"
@@ -263,6 +263,8 @@ private:
friend class Viewport;
+ void _call_gui_input(const Ref<InputEvent> &p_event);
+
void _update_minimum_size_cache();
friend class Window;
static void _propagate_theme_changed(Node *p_at, Control *p_owner, Window *p_owner_window, bool p_assign = true);
@@ -272,7 +274,6 @@ private:
static bool has_theme_item_in_types(Control *p_theme_owner, Window *p_theme_owner_window, Theme::DataType p_data_type, const StringName &p_name, List<StringName> p_theme_types);
_FORCE_INLINE_ void _get_theme_type_dependencies(const StringName &p_theme_type, List<StringName> *p_list) const;
- GDVIRTUAL1RC(bool, _has_point, Vector2)
protected:
virtual void add_child_notify(Node *p_child) override;
virtual void remove_child_notify(Node *p_child) override;
@@ -291,6 +292,17 @@ protected:
//bind helpers
+ GDVIRTUAL1RC(bool, _has_point, Vector2)
+ GDVIRTUAL2RC(Array, _structured_text_parser, Array, String)
+ GDVIRTUAL0RC(Vector2, _get_minimum_size)
+
+ GDVIRTUAL1RC(Variant, _get_drag_data, Vector2)
+ GDVIRTUAL2RC(bool, _can_drop_data, Vector2, Variant)
+ GDVIRTUAL2(_drop_data, Vector2, Variant)
+ GDVIRTUAL1RC(Object *, _make_custom_tooltip, String)
+
+ GDVIRTUAL1(_gui_input, Ref<InputEvent>)
+
public:
enum {
/* NOTIFICATION_DRAW=30,
@@ -333,6 +345,8 @@ public:
virtual Size2 _edit_get_minimum_size() const override;
#endif
+ virtual void gui_input(const Ref<InputEvent> &p_event);
+
void accept_event();
virtual Size2 get_minimum_size() const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 2e4204e171..2512b24623 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -95,7 +95,7 @@ void FileDialog::_notification(int p_what) {
}
}
-void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+void FileDialog::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -854,8 +854,6 @@ void FileDialog::_update_drives() {
bool FileDialog::default_show_hidden_files = false;
void FileDialog::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_unhandled_input"), &FileDialog::_unhandled_input);
-
ClassDB::bind_method(D_METHOD("_cancel_pressed"), &FileDialog::_cancel_pressed);
ClassDB::bind_method(D_METHOD("clear_filters"), &FileDialog::clear_filters);
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 7fbafc4bb4..b5190bdab1 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -132,7 +132,7 @@ private:
void _update_drives();
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
bool _is_open_should_be_disabled();
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 635f3c51b9..bbab3008e2 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -88,7 +88,7 @@ void GradientEdit::_show_color_picker() {
GradientEdit::~GradientEdit() {
}
-void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
+void GradientEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -458,6 +458,5 @@ Vector<Gradient::Point> &GradientEdit::get_points() {
}
void GradientEdit::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &GradientEdit::_gui_input);
ADD_SIGNAL(MethodInfo("ramp_changed"));
}
diff --git a/scene/gui/gradient_edit.h b/scene/gui/gradient_edit.h
index b0ee2c4abb..a173631963 100644
--- a/scene/gui/gradient_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -52,7 +52,7 @@ class GradientEdit : public Control {
void _show_color_picker();
protected:
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index fcecbb5fca..0281bc7efb 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -51,10 +51,6 @@ GraphEditFilter::GraphEditFilter(GraphEdit *p_edit) {
ge = p_edit;
}
-void GraphEditMinimap::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &GraphEditMinimap::_gui_input);
-}
-
GraphEditMinimap::GraphEditMinimap(GraphEdit *p_edit) {
ge = p_edit;
@@ -148,7 +144,7 @@ Vector2 GraphEditMinimap::_convert_to_graph_position(const Vector2 &p_position)
return graph_position;
}
-void GraphEditMinimap::_gui_input(const Ref<InputEvent> &p_ev) {
+void GraphEditMinimap::gui_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
if (!ge->is_minimap_enabled()) {
@@ -805,68 +801,36 @@ bool GraphEdit::is_in_hot_zone(const Vector2 &pos, const Vector2 &p_mouse_pos, c
return true;
}
-template <class Vector2>
-static _FORCE_INLINE_ Vector2 _bezier_interp(real_t t, Vector2 start, Vector2 control_1, Vector2 control_2, Vector2 end) {
- /* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - t);
- real_t omt2 = omt * omt;
- real_t omt3 = omt2 * omt;
- real_t t2 = t * t;
- real_t t3 = t2 * t;
-
- return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
-}
-
-void GraphEdit::_bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const {
- float mp = p_begin + (p_end - p_begin) * 0.5;
- Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
- Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
- Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);
-
- Vector2 na = (mid - beg).normalized();
- Vector2 nb = (end - mid).normalized();
- float dp = Math::rad2deg(Math::acos(na.dot(nb)));
-
- if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) {
- points.push_back((beg + end) * 0.5);
- colors.push_back(p_color.lerp(p_to_color, mp));
- lines++;
- } else {
- _bake_segment2d(points, colors, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
- _bake_segment2d(points, colors, mp, p_end, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
+PackedVector2Array GraphEdit::get_connection_line(const Vector2 &p_from, const Vector2 &p_to) {
+ Vector<Vector2> ret;
+ if (GDVIRTUAL_CALL(_get_connection_line, p_from, p_to, ret)) {
+ return ret;
}
-}
-void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_bezier_ratio) {
- //cubic bezier code
- float diff = p_to.x - p_from.x;
- float cp_offset;
- int cp_len = get_theme_constant(SNAME("bezier_len_pos")) * p_bezier_ratio;
- int cp_neg_len = get_theme_constant(SNAME("bezier_len_neg")) * p_bezier_ratio;
-
- if (diff > 0) {
- cp_offset = MIN(cp_len, diff * 0.5);
- } else {
- cp_offset = MAX(MIN(cp_len - diff, cp_neg_len), -diff * 0.5);
- }
-
- Vector2 c1 = Vector2(cp_offset * zoom, 0);
- Vector2 c2 = Vector2(-cp_offset * zoom, 0);
-
- int lines = 0;
+ Curve2D curve;
+ Vector<Color> colors;
+ curve.add_point(p_from);
+ curve.set_point_out(0, Vector2(60, 0));
+ curve.add_point(p_to);
+ curve.set_point_in(1, Vector2(-60, 0));
+ return curve.tessellate();
+}
- Vector<Point2> points;
+void GraphEdit::_draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom) {
+ Vector<Vector2> points = get_connection_line(p_from / p_zoom, p_to / p_zoom);
+ Vector<Vector2> scaled_points;
Vector<Color> colors;
- points.push_back(p_from);
- colors.push_back(p_color);
- _bake_segment2d(points, colors, 0, 1, p_from, c1, p_to, c2, 0, 3, 9, 3, p_color, p_to_color, lines);
- points.push_back(p_to);
- colors.push_back(p_to_color);
+ float length = (p_from / p_zoom).distance_to(p_to / p_zoom);
+ for (int i = 0; i < points.size(); i++) {
+ float d = (p_from / p_zoom).distance_to(points[i]) / length;
+ colors.push_back(p_color.lerp(p_to_color, d));
+ scaled_points.push_back(points[i] * p_zoom);
+ }
#ifdef TOOLS_ENABLED
- p_where->draw_polyline_colors(points, colors, Math::floor(p_width * EDSCALE), lines_antialiased);
+ p_where->draw_polyline_colors(scaled_points, colors, Math::floor(p_width * EDSCALE), lines_antialiased);
#else
- p_where->draw_polyline_colors(points, colors, p_width, lines_antialiased);
+ p_where->draw_polyline_colors(scaled_points, colors, p_width, lines_antialiased);
#endif
}
@@ -913,7 +877,7 @@ void GraphEdit::_connections_layer_draw() {
color = color.lerp(activity_color, E->get().activity);
tocolor = tocolor.lerp(activity_color, E->get().activity);
}
- _draw_cos_line(connections_layer, frompos, topos, color, tocolor, lines_thickness);
+ _draw_connection_line(connections_layer, frompos, topos, color, tocolor, lines_thickness, zoom);
}
while (to_erase.size()) {
@@ -952,7 +916,7 @@ void GraphEdit::_top_layer_draw() {
if (!connecting_out) {
SWAP(pos, topos);
}
- _draw_cos_line(top_layer, pos, topos, col, col, lines_thickness);
+ _draw_connection_line(top_layer, pos, topos, col, col, lines_thickness, zoom);
}
if (box_selecting) {
@@ -1056,7 +1020,7 @@ void GraphEdit::_minimap_draw() {
from_color = from_color.lerp(activity_color, E.activity);
to_color = to_color.lerp(activity_color, E.activity);
}
- _draw_cos_line(minimap, from_position, to_position, from_color, to_color, 1.0, 0.5);
+ _draw_connection_line(minimap, from_position, to_position, from_color, to_color, 0.1, minimap->_convert_from_graph_position(Vector2(zoom, zoom)).length());
}
// Draw the "camera" viewport.
@@ -1080,7 +1044,7 @@ void GraphEdit::set_selected(Node *p_child) {
}
}
-void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
+void GraphEdit::gui_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventMouseMotion> mm = p_ev;
@@ -2048,7 +2012,6 @@ void GraphEdit::arrange_nodes() {
if (gn->is_selected()) {
selected_nodes.insert(gn->get_name());
- origin = origin < gn->get_position_offset() ? origin : gn->get_position_offset();
Set<StringName> s;
for (List<Connection>::Element *E = connections.front(); E; E = E->next()) {
GraphNode *p_from = Object::cast_to<GraphNode>(node_names[E->get().from]);
@@ -2072,6 +2035,11 @@ void GraphEdit::arrange_nodes() {
}
}
+ if (!selected_nodes.size()) {
+ arranging_graph = false;
+ return;
+ }
+
HashMap<int, Vector<StringName>> layers = _layering(selected_nodes, upper_neighbours);
_crossing_minimisation(layers, upper_neighbours);
@@ -2098,16 +2066,16 @@ void GraphEdit::arrange_nodes() {
for (const Set<StringName>::Element *E = block_heads.front(); E; E = E->next()) {
_place_block(E->get(), gap_v, layers, root, align, node_names, inner_shift, sink, shift, new_positions);
}
+ origin.y = Object::cast_to<GraphNode>(node_names[layers[0][0]])->get_position_offset().y - (new_positions[layers[0][0]].y + (float)inner_shift[layers[0][0]]);
+ origin.x = Object::cast_to<GraphNode>(node_names[layers[0][0]])->get_position_offset().x;
for (const Set<StringName>::Element *E = block_heads.front(); E; E = E->next()) {
StringName u = E->get();
- StringName prev = u;
float start_from = origin.y + new_positions[E->get()].y;
do {
Vector2 cal_pos;
cal_pos.y = start_from + (real_t)inner_shift[u];
new_positions.set(u, cal_pos);
- prev = u;
u = align[u];
} while (u != E->get());
}
@@ -2130,10 +2098,11 @@ void GraphEdit::arrange_nodes() {
if (current_node_size == largest_node_size) {
cal_pos.x = start_from;
} else {
- float current_node_start_pos;
- if (current_node_size >= largest_node_size / 2) {
- current_node_start_pos = start_from;
- } else {
+ float current_node_start_pos = start_from;
+ if (current_node_size < largest_node_size / 2) {
+ if (!(i || j)) {
+ start_from -= (largest_node_size - current_node_size);
+ }
current_node_start_pos = start_from + largest_node_size - current_node_size;
}
cal_pos.x = current_node_start_pos;
@@ -2179,6 +2148,7 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_valid_connection_type", "from_type", "to_type"), &GraphEdit::add_valid_connection_type);
ClassDB::bind_method(D_METHOD("remove_valid_connection_type", "from_type", "to_type"), &GraphEdit::remove_valid_connection_type);
ClassDB::bind_method(D_METHOD("is_valid_connection_type", "from_type", "to_type"), &GraphEdit::is_valid_connection_type);
+ ClassDB::bind_method(D_METHOD("get_connection_line", "from", "to"), &GraphEdit::get_connection_line);
ClassDB::bind_method(D_METHOD("set_zoom", "zoom"), &GraphEdit::set_zoom);
ClassDB::bind_method(D_METHOD("get_zoom"), &GraphEdit::get_zoom);
@@ -2218,7 +2188,6 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_right_disconnects", "enable"), &GraphEdit::set_right_disconnects);
ClassDB::bind_method(D_METHOD("is_right_disconnects_enabled"), &GraphEdit::is_right_disconnects_enabled);
- ClassDB::bind_method(D_METHOD("_gui_input"), &GraphEdit::_gui_input);
ClassDB::bind_method(D_METHOD("_update_scroll_offset"), &GraphEdit::_update_scroll_offset);
ClassDB::bind_method(D_METHOD("get_zoom_hbox"), &GraphEdit::get_zoom_hbox);
@@ -2227,6 +2196,8 @@ void GraphEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_selected", "node"), &GraphEdit::set_selected);
+ GDVIRTUAL_BIND(_get_connection_line, "from", "to")
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "right_disconnects"), "set_right_disconnects", "is_right_disconnects_enabled");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "scroll_offset"), "set_scroll_ofs", "get_scroll_ofs");
ADD_PROPERTY(PropertyInfo(Variant::INT, "snap_distance"), "set_snap", "get_snap");
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index 9fd7cbef22..44e50aa3c2 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -62,8 +62,6 @@ class GraphEditMinimap : public Control {
GraphEdit *ge;
protected:
- static void _bind_methods();
-
public:
GraphEditMinimap(GraphEdit *p_edit);
@@ -88,7 +86,7 @@ private:
Vector2 _convert_from_graph_position(const Vector2 &p_position);
Vector2 _convert_to_graph_position(const Vector2 &p_position);
- void _gui_input(const Ref<InputEvent> &p_ev);
+ virtual void gui_input(const Ref<InputEvent> &p_ev) override;
void _adjust_graph_scroll(const Vector2 &p_offset);
};
@@ -169,9 +167,8 @@ private:
float lines_thickness = 2.0f;
bool lines_antialiased = true;
- void _bake_segment2d(Vector<Vector2> &points, Vector<Color> &colors, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_min_depth, int p_max_depth, float p_tol, const Color &p_color, const Color &p_to_color, int &lines) const;
-
- void _draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_bezier_ratio = 1.0);
+ PackedVector2Array get_connection_line(const Vector2 &p_from, const Vector2 &p_to);
+ void _draw_connection_line(CanvasItem *p_where, const Vector2 &p_from, const Vector2 &p_to, const Color &p_color, const Color &p_to_color, float p_width, float p_zoom);
void _graph_node_raised(Node *p_gn);
void _graph_node_moved(Node *p_gn);
@@ -179,7 +176,7 @@ private:
void _update_scroll();
void _scroll_moved(double);
- void _gui_input(const Ref<InputEvent> &p_ev);
+ virtual void gui_input(const Ref<InputEvent> &p_ev) override;
Control *connections_layer;
GraphEditFilter *top_layer;
@@ -256,6 +253,8 @@ protected:
virtual void remove_child_notify(Node *p_child) override;
void _notification(int p_what);
+ GDVIRTUAL2RC(Vector<Vector2>, _get_connection_line, Vector2, Vector2)
+
public:
Error connect_node(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
bool is_node_connected(const StringName &p_from, int p_from_port, const StringName &p_to, int p_to_port);
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index e85cefcb7b..08c8c60d7a 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -863,7 +863,7 @@ Color GraphNode::get_connection_output_color(int p_idx) {
return conn_output_cache[p_idx].color;
}
-void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
+void GraphNode::gui_input(const Ref<InputEvent> &p_ev) {
ERR_FAIL_COND(p_ev.is_null());
Ref<InputEventMouseButton> mb = p_ev;
@@ -946,8 +946,6 @@ void GraphNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_language", "language"), &GraphNode::set_language);
ClassDB::bind_method(D_METHOD("get_language"), &GraphNode::get_language);
- ClassDB::bind_method(D_METHOD("_gui_input"), &GraphNode::_gui_input);
-
ClassDB::bind_method(D_METHOD("set_slot", "idx", "enable_left", "type_left", "color_left", "enable_right", "type_right", "color_right", "custom_left", "custom_right"), &GraphNode::set_slot, DEFVAL(Ref<Texture2D>()), DEFVAL(Ref<Texture2D>()));
ClassDB::bind_method(D_METHOD("clear_slot", "idx"), &GraphNode::clear_slot);
ClassDB::bind_method(D_METHOD("clear_all_slots"), &GraphNode::clear_all_slots);
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index c70f616b47..c7c7006bfc 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -99,7 +99,7 @@ private:
Overlay overlay = OVERLAY_DISABLED;
protected:
- void _gui_input(const Ref<InputEvent> &p_ev);
+ virtual void gui_input(const Ref<InputEvent> &p_ev) override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 258d65112a..8297de9f30 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -48,6 +48,8 @@ void ItemList::_shape(int p_idx) {
} else {
item.text_buf->set_flags(TextServer::BREAK_NONE);
}
+ item.text_buf->set_text_overrun_behavior(text_overrun_behavior);
+ item.text_buf->set_max_lines_visible(max_text_lines);
}
int ItemList::add_item(const String &p_item, const Ref<Texture2D> &p_texture, bool p_selectable) {
@@ -453,6 +455,7 @@ void ItemList::set_max_text_lines(int p_lines) {
for (int i = 0; i < items.size(); i++) {
if (icon_mode == ICON_MODE_TOP && max_text_lines > 0) {
items.write[i].text_buf->set_flags(TextServer::BREAK_MANDATORY | TextServer::BREAK_WORD_BOUND | TextServer::BREAK_GRAPHEME_BOUND);
+ items.write[i].text_buf->set_max_lines_visible(p_lines);
} else {
items.write[i].text_buf->set_flags(TextServer::BREAK_NONE);
}
@@ -534,7 +537,7 @@ Size2 ItemList::Item::get_icon_size() const {
return size_result;
}
-void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
+void ItemList::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
double prev_scroll = scroll_bar->get_value();
@@ -930,8 +933,14 @@ void ItemList::_notification(int p_what) {
}
if (items[i].text != "") {
+ int max_width = -1;
+ if (fixed_column_width) {
+ max_width = fixed_column_width;
+ } else if (same_column_width) {
+ max_width = items[i].rect_cache.size.x;
+ }
+ items.write[i].text_buf->set_width(max_width);
Size2 s = items[i].text_buf->get_size();
- //s.width=MIN(s.width,fixed_column_width);
if (icon_mode == ICON_MODE_TOP) {
minsize.x = MAX(minsize.x, s.width);
@@ -1139,11 +1148,8 @@ void ItemList::_notification(int p_what) {
if (icon_mode == ICON_MODE_TOP) {
pos.x += Math::floor((items[i].rect_cache.size.width - icon_size.width) / 2);
- pos.y += MIN(
- Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2),
- items[i].rect_cache.size.height - items[i].min_rect_cache.size.height);
- text_ofs.y = icon_size.height + icon_margin;
- text_ofs.y += items[i].rect_cache.size.height - items[i].min_rect_cache.size.height;
+ pos.y += icon_margin;
+ text_ofs.y = icon_size.height + icon_margin * 2;
} else {
pos.y += Math::floor((items[i].rect_cache.size.height - icon_size.height) / 2);
text_ofs.x = icon_size.width + icon_margin;
@@ -1210,7 +1216,6 @@ void ItemList::_notification(int p_what) {
text_ofs.x = size.width - text_ofs.x - max_len;
}
- items.write[i].text_buf->set_width(max_len);
items.write[i].text_buf->set_align(HALIGN_CENTER);
if (outline_size > 0 && font_outline_color.a > 0) {
@@ -1488,6 +1493,21 @@ bool ItemList::has_auto_height() const {
return auto_height;
}
+void ItemList::set_text_overrun_behavior(TextParagraph::OverrunBehavior p_behavior) {
+ if (text_overrun_behavior != p_behavior) {
+ text_overrun_behavior = p_behavior;
+ for (int i = 0; i < items.size(); i++) {
+ items.write[i].text_buf->set_text_overrun_behavior(p_behavior);
+ }
+ shape_changed = true;
+ update();
+ }
+}
+
+TextParagraph::OverrunBehavior ItemList::get_text_overrun_behavior() const {
+ return text_overrun_behavior;
+}
+
void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_item", "text", "icon", "selectable"), &ItemList::add_item, DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("add_icon_item", "icon", "selectable"), &ItemList::add_icon_item, DEFVAL(true));
@@ -1594,11 +1614,12 @@ void ItemList::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_v_scroll"), &ItemList::get_v_scroll);
- ClassDB::bind_method(D_METHOD("_gui_input"), &ItemList::_gui_input);
-
ClassDB::bind_method(D_METHOD("_set_items"), &ItemList::_set_items);
ClassDB::bind_method(D_METHOD("_get_items"), &ItemList::_get_items);
+ ClassDB::bind_method(D_METHOD("set_text_overrun_behavior", "overrun_behavior"), &ItemList::set_text_overrun_behavior);
+ ClassDB::bind_method(D_METHOD("get_text_overrun_behavior"), &ItemList::get_text_overrun_behavior);
+
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "items", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_items", "_get_items");
ADD_PROPERTY(PropertyInfo(Variant::INT, "select_mode", PROPERTY_HINT_ENUM, "Single,Multi"), "set_select_mode", "get_select_mode");
@@ -1606,6 +1627,7 @@ void ItemList::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_rmb_select"), "set_allow_rmb_select", "get_allow_rmb_select");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_text_lines", PROPERTY_HINT_RANGE, "1,10,1,or_greater"), "set_max_text_lines", "get_max_text_lines");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_height"), "set_auto_height", "has_auto_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "text_overrun_behavior", PROPERTY_HINT_ENUM, "Trim Nothing,Trim Characters,Trim Words,Ellipsis,Word Ellipsis"), "set_text_overrun_behavior", "get_text_overrun_behavior");
ADD_GROUP("Columns", "");
ADD_PROPERTY(PropertyInfo(Variant::INT, "max_columns", PROPERTY_HINT_RANGE, "0,10,1,or_greater"), "set_max_columns", "get_max_columns");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "same_column_width"), "set_same_column_width", "is_same_column_width");
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 86a0174a20..148fa7ba9f 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -95,6 +95,7 @@ private:
SelectMode select_mode = SELECT_SINGLE;
IconMode icon_mode = ICON_MODE_LEFT;
VScrollBar *scroll_bar;
+ TextParagraph::OverrunBehavior text_overrun_behavior = TextParagraph::OVERRUN_NO_TRIMMING;
uint64_t search_time_msec = 0;
String search_string;
@@ -122,7 +123,6 @@ private:
void _set_items(const Array &p_items);
void _scroll_changed(double);
- void _gui_input(const Ref<InputEvent> &p_event);
void _shape(int p_idx);
protected:
@@ -130,6 +130,8 @@ protected:
static void _bind_methods();
public:
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
+
int add_item(const String &p_item, const Ref<Texture2D> &p_texture = Ref<Texture2D>(), bool p_selectable = true);
int add_icon_item(const Ref<Texture2D> &p_item, bool p_selectable = true);
@@ -182,6 +184,9 @@ public:
void set_item_custom_fg_color(int p_idx, const Color &p_custom_fg_color);
Color get_item_custom_fg_color(int p_idx) const;
+ void set_text_overrun_behavior(TextParagraph::OverrunBehavior p_behavior);
+ TextParagraph::OverrunBehavior get_text_overrun_behavior() const;
+
void select(int p_idx, bool p_single = true);
void deselect(int p_idx);
void deselect_all();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 11e08b231e..5e9c2d891f 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -216,7 +216,7 @@ void LineEdit::_delete(bool p_word, bool p_all_to_right) {
}
}
-void LineEdit::_gui_input(Ref<InputEvent> p_event) {
+void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> b = p_event;
@@ -2084,7 +2084,6 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_align", "align"), &LineEdit::set_align);
ClassDB::bind_method(D_METHOD("get_align"), &LineEdit::get_align);
- ClassDB::bind_method(D_METHOD("_gui_input"), &LineEdit::_gui_input);
ClassDB::bind_method(D_METHOD("clear"), &LineEdit::clear);
ClassDB::bind_method(D_METHOD("select", "from", "to"), &LineEdit::select, DEFVAL(0), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("select_all"), &LineEdit::select_all);
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 0e9c032e88..e364a79c83 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -202,7 +202,7 @@ private:
protected:
void _notification(int p_what);
static void _bind_methods();
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index dc6c7fec28..e312aaed57 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -33,7 +33,7 @@
#include "core/os/keyboard.h"
#include "scene/main/window.h"
-void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) {
+void MenuButton::unhandled_key_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!_is_focus_owner_in_shorcut_context()) {
@@ -100,8 +100,8 @@ void MenuButton::pressed() {
popup->popup();
}
-void MenuButton::_gui_input(Ref<InputEvent> p_event) {
- BaseButton::_gui_input(p_event);
+void MenuButton::gui_input(const Ref<InputEvent> &p_event) {
+ BaseButton::gui_input(p_event);
}
PopupMenu *MenuButton::get_popup() const {
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index cc2ca117c4..730495b65d 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -47,14 +47,14 @@ class MenuButton : public Button {
Array _get_items() const;
void _set_items(const Array &p_items);
- void _gui_input(Ref<InputEvent> p_event) override;
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _popup_visibility_changed(bool p_visible);
protected:
void _notification(int p_what);
static void _bind_methods();
- virtual void _unhandled_key_input(Ref<InputEvent> p_event) override;
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_event) override;
public:
virtual void pressed() override;
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index aff367e398..f75d6755a8 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -251,7 +251,7 @@ void PopupMenu::_submenu_timeout() {
submenu_over = -1;
}
-void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
+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()) {
@@ -1581,8 +1581,6 @@ void PopupMenu::take_mouse_focus() {
}
void PopupMenu::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &PopupMenu::_gui_input);
-
ClassDB::bind_method(D_METHOD("add_item", "label", "id", "accel"), &PopupMenu::add_item, DEFVAL(-1), DEFVAL(0));
ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_item, DEFVAL(-1), DEFVAL(0));
ClassDB::bind_method(D_METHOD("add_check_item", "label", "id", "accel"), &PopupMenu::add_check_item, DEFVAL(-1), DEFVAL(0));
@@ -1708,7 +1706,7 @@ PopupMenu::PopupMenu() {
scroll_container->add_child(control);
control->connect("draw", callable_mp(this, &PopupMenu::_draw_items));
- connect("window_input", callable_mp(this, &PopupMenu::_gui_input));
+ connect("window_input", callable_mp(this, &PopupMenu::gui_input));
submenu_timer = memnew(Timer);
submenu_timer->set_wait_time(0.3);
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index aedc5d0155..5c427e43bc 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -31,10 +31,10 @@
#ifndef POPUP_MENU_H
#define POPUP_MENU_H
+#include "core/input/shortcut.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/popup.h"
#include "scene/gui/scroll_container.h"
-#include "scene/gui/shortcut.h"
#include "scene/resources/text_line.h"
class PopupMenu : public Popup {
@@ -107,7 +107,7 @@ class PopupMenu : public Popup {
void _shape_item(int p_item);
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event);
void _activate_submenu(int p_over);
void _submenu_timeout();
diff --git a/scene/gui/rich_text_effect.cpp b/scene/gui/rich_text_effect.cpp
index 39718a269a..236d106af8 100644
--- a/scene/gui/rich_text_effect.cpp
+++ b/scene/gui/rich_text_effect.cpp
@@ -32,8 +32,15 @@
#include "core/object/script_language.h"
-void RichTextEffect::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_process_custom_fx", PropertyInfo(Variant::OBJECT, "char_fx", PROPERTY_HINT_RESOURCE_TYPE, "CharFXTransform")));
+CharFXTransform::CharFXTransform() {
+}
+
+CharFXTransform::~CharFXTransform() {
+ environment.clear();
+}
+
+void RichTextEffect::_bind_methods(){
+ GDVIRTUAL_BIND(_process_custom_fx, "char_fx")
}
Variant RichTextEffect::get_bbcode() const {
@@ -49,15 +56,10 @@ Variant RichTextEffect::get_bbcode() const {
bool RichTextEffect::_process_effect_impl(Ref<CharFXTransform> p_cfx) {
bool return_value = false;
- if (get_script_instance()) {
- Variant v = get_script_instance()->call("_process_custom_fx", p_cfx);
- if (v.get_type() != Variant::BOOL) {
- return_value = false;
- } else {
- return_value = (bool)v;
- }
+ if (GDVIRTUAL_CALL(_process_custom_fx, p_cfx, return_value)) {
+ return return_value;
}
- return return_value;
+ return false;
}
RichTextEffect::RichTextEffect() {
@@ -101,10 +103,3 @@ void CharFXTransform::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "glyph_index"), "set_glyph_index", "get_glyph_index");
ADD_PROPERTY(PropertyInfo(Variant::RID, "font"), "set_font", "get_font");
}
-
-CharFXTransform::CharFXTransform() {
-}
-
-CharFXTransform::~CharFXTransform() {
- environment.clear();
-}
diff --git a/scene/gui/rich_text_effect.h b/scene/gui/rich_text_effect.h
index 67323e7f93..e674b2f62f 100644
--- a/scene/gui/rich_text_effect.h
+++ b/scene/gui/rich_text_effect.h
@@ -32,20 +32,8 @@
#define RICH_TEXT_EFFECT_H
#include "core/io/resource.h"
-
-class RichTextEffect : public Resource {
- GDCLASS(RichTextEffect, Resource);
- OBJ_SAVE_TYPE(RichTextEffect);
-
-protected:
- static void _bind_methods();
-
-public:
- Variant get_bbcode() const;
- bool _process_effect_impl(Ref<class CharFXTransform> p_cfx);
-
- RichTextEffect();
-};
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
class CharFXTransform : public RefCounted {
GDCLASS(CharFXTransform, RefCounted);
@@ -89,4 +77,20 @@ public:
void set_environment(Dictionary p_environment) { environment = p_environment; }
};
+class RichTextEffect : public Resource {
+ GDCLASS(RichTextEffect, Resource);
+ OBJ_SAVE_TYPE(RichTextEffect);
+
+protected:
+ static void _bind_methods();
+
+ GDVIRTUAL1RC(bool, _process_custom_fx, Ref<CharFXTransform>)
+
+public:
+ Variant get_bbcode() const;
+ bool _process_effect_impl(Ref<class CharFXTransform> p_cfx);
+
+ RichTextEffect();
+};
+
#endif // RICH_TEXT_EFFECT_H
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 75c2da7ef9..21a87d4e76 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -1451,7 +1451,7 @@ void RichTextLabel::_notification(int p_what) {
Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const {
if (!underline_meta) {
- return CURSOR_ARROW;
+ return get_default_cursor_shape();
}
if (selection.click_item) {
@@ -1459,11 +1459,11 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
}
if (main->first_invalid_line < main->lines.size()) {
- return CURSOR_ARROW; //invalid
+ return get_default_cursor_shape(); //invalid
}
if (main->first_resized_line < main->lines.size()) {
- return CURSOR_ARROW; //invalid
+ return get_default_cursor_shape(); //invalid
}
Item *item = nullptr;
@@ -1474,10 +1474,10 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
return CURSOR_POINTING_HAND;
}
- return CURSOR_ARROW;
+ return get_default_cursor_shape();
}
-void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
+void RichTextLabel::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> b = p_event;
@@ -3993,7 +3993,6 @@ void RichTextLabel::_validate_property(PropertyInfo &property) const {
}
void RichTextLabel::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &RichTextLabel::_gui_input);
ClassDB::bind_method(D_METHOD("get_text"), &RichTextLabel::get_text);
ClassDB::bind_method(D_METHOD("add_text", "text"), &RichTextLabel::add_text);
ClassDB::bind_method(D_METHOD("set_text", "text"), &RichTextLabel::set_text);
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 28dfe74b08..ae04a7e684 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -443,7 +443,7 @@ private:
void _update_fx(ItemFrame *p_frame, double p_delta_time);
void _scroll_changed(double);
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
Item *_get_next_item(Item *p_item, bool p_free = false) const;
Item *_get_prev_item(Item *p_item, bool p_free = false) const;
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index ce04a0204b..08bcb0bdda 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -41,7 +41,7 @@ void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
focus_by_default = p_can_focus;
}
-void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
+void ScrollBar::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> m = p_event;
@@ -597,7 +597,6 @@ bool ScrollBar::is_smooth_scroll_enabled() const {
}
void ScrollBar::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollBar::_gui_input);
ClassDB::bind_method(D_METHOD("set_custom_step", "step"), &ScrollBar::set_custom_step);
ClassDB::bind_method(D_METHOD("get_custom_step"), &ScrollBar::get_custom_step);
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 24b3b33e82..fbc035397f 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -86,7 +86,7 @@ class ScrollBar : public Range {
void _drag_node_exit();
void _drag_node_input(const Ref<InputEvent> &p_input);
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
protected:
void _notification(int p_what);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index eb5fc924da..b5daa8b3f1 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -83,7 +83,7 @@ void ScrollContainer::_cancel_drag() {
}
}
-void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
+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();
@@ -568,7 +568,6 @@ VScrollBar *ScrollContainer::get_v_scrollbar() {
}
void ScrollContainer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ScrollContainer::_gui_input);
ClassDB::bind_method(D_METHOD("_update_scrollbar_position"), &ScrollContainer::_update_scrollbar_position);
ClassDB::bind_method(D_METHOD("set_h_scroll", "value"), &ScrollContainer::set_h_scroll);
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 4733fdabca..9f4ec558dc 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -68,7 +68,7 @@ class ScrollContainer : public Container {
protected:
Size2 get_minimum_size() const override;
- void _gui_input(const Ref<InputEvent> &p_gui_input);
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
void _gui_focus_changed(Control *p_control);
void _update_dimensions();
void _notification(int p_what);
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 61b5325175..352f87954e 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -45,7 +45,7 @@ Size2 Slider::get_minimum_size() const {
}
}
-void Slider::_gui_input(Ref<InputEvent> p_event) {
+void Slider::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!editable) {
@@ -253,7 +253,6 @@ bool Slider::is_scrollable() const {
}
void Slider::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &Slider::_gui_input);
ClassDB::bind_method(D_METHOD("set_ticks", "count"), &Slider::set_ticks);
ClassDB::bind_method(D_METHOD("get_ticks"), &Slider::get_ticks);
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index 65a4036cd1..46fa08bbf0 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -50,7 +50,7 @@ class Slider : public Range {
bool scrollable = true;
protected:
- void _gui_input(Ref<InputEvent> p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
static void _bind_methods();
bool ticks_on_borders = false;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 3f0368a4e2..65a3eb3adf 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -99,7 +99,7 @@ void SpinBox::_release_mouse() {
}
}
-void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
+void SpinBox::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (!is_editable()) {
@@ -258,7 +258,7 @@ void SpinBox::apply() {
void SpinBox::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_value_changed"),&SpinBox::_value_changed);
- ClassDB::bind_method(D_METHOD("_gui_input"), &SpinBox::_gui_input);
+
ClassDB::bind_method(D_METHOD("set_align", "align"), &SpinBox::set_align);
ClassDB::bind_method(D_METHOD("get_align"), &SpinBox::get_align);
ClassDB::bind_method(D_METHOD("set_suffix", "suffix"), &SpinBox::set_suffix);
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index fb10379296..9ec3885f1f 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -65,7 +65,7 @@ class SpinBox : public Range {
inline void _adjust_width_for_icon(const Ref<Texture2D> &icon);
protected:
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index 3114e5b7c0..4736a1ad37 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -206,7 +206,7 @@ void SplitContainer::_notification(int p_what) {
}
}
-void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
+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) {
@@ -337,8 +337,6 @@ bool SplitContainer::is_collapsed() const {
}
void SplitContainer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &SplitContainer::_gui_input);
-
ClassDB::bind_method(D_METHOD("set_split_offset", "offset"), &SplitContainer::set_split_offset);
ClassDB::bind_method(D_METHOD("get_split_offset"), &SplitContainer::get_split_offset);
ClassDB::bind_method(D_METHOD("clamp_split_offset"), &SplitContainer::clamp_split_offset);
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index 6cb94d6ecf..47fd30a122 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -60,7 +60,7 @@ private:
void _resort();
protected:
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index bfc7e29f9c..53ea32e1b7 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -139,7 +139,7 @@ void SubViewportContainer::_notification(int p_what) {
}
}
-void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
+void SubViewportContainer::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
if (Engine::get_singleton()->is_editor_hint()) {
@@ -162,11 +162,11 @@ void SubViewportContainer::_input(const Ref<InputEvent> &p_event) {
continue;
}
- c->input(ev);
+ c->push_input(ev);
}
}
-void SubViewportContainer::_unhandled_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()) {
@@ -189,13 +189,11 @@ void SubViewportContainer::_unhandled_input(const Ref<InputEvent> &p_event) {
continue;
}
- c->unhandled_input(ev);
+ c->push_unhandled_input(ev);
}
}
void SubViewportContainer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_unhandled_input", "event"), &SubViewportContainer::_unhandled_input);
- ClassDB::bind_method(D_METHOD("_input", "event"), &SubViewportContainer::_input);
ClassDB::bind_method(D_METHOD("set_stretch", "enable"), &SubViewportContainer::set_stretch);
ClassDB::bind_method(D_METHOD("is_stretch_enabled"), &SubViewportContainer::is_stretch_enabled);
diff --git a/scene/gui/subviewport_container.h b/scene/gui/subviewport_container.h
index 77cf4c16b3..7853f1590e 100644
--- a/scene/gui/subviewport_container.h
+++ b/scene/gui/subviewport_container.h
@@ -47,8 +47,8 @@ public:
void set_stretch(bool p_enable);
bool is_stretch_enabled() const;
- void _input(const Ref<InputEvent> &p_event);
- void _unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void input(const Ref<InputEvent> &p_event) override;
+ virtual void unhandled_input(const Ref<InputEvent> &p_event) override;
void set_stretch_shrink(int p_shrink);
int get_stretch_shrink() const;
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 53a2fe4d93..5884d2a854 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -71,7 +71,7 @@ int TabContainer::_get_top_margin() const {
return tab_height + content_height;
}
-void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
+void TabContainer::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseButton> mb = p_event;
@@ -1193,7 +1193,6 @@ bool TabContainer::get_use_hidden_tabs_for_min_size() const {
}
void TabContainer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &TabContainer::_gui_input);
ClassDB::bind_method(D_METHOD("get_tab_count"), &TabContainer::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &TabContainer::set_current_tab);
ClassDB::bind_method(D_METHOD("get_current_tab"), &TabContainer::get_current_tab);
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 35f18eff8e..fe96df25e8 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -76,7 +76,7 @@ private:
protected:
void _child_renamed_callback();
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
virtual void add_child_notify(Node *p_child) override;
virtual void move_child_notify(Node *p_child) override;
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 103860ad78..3ca2d1c1e9 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -90,7 +90,7 @@ Size2 Tabs::get_minimum_size() const {
return ms;
}
-void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
+void Tabs::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventMouseMotion> mm = p_event;
@@ -1107,7 +1107,6 @@ bool Tabs::get_select_with_rmb() const {
}
void Tabs::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input);
ClassDB::bind_method(D_METHOD("_update_hover"), &Tabs::_update_hover);
ClassDB::bind_method(D_METHOD("get_tab_count"), &Tabs::get_tab_count);
ClassDB::bind_method(D_METHOD("set_current_tab", "tab_idx"), &Tabs::set_current_tab);
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 61c9a5d96a..b044453803 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -112,7 +112,7 @@ private:
void _shape(int p_tab);
protected:
- void _gui_input(const Ref<InputEvent> &p_event);
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 87f06445ac..61dfec6abe 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1305,7 +1305,7 @@ void TextEdit::_notification(int p_what) {
}
}
-void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
+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();
@@ -2150,7 +2150,6 @@ void TextEdit::_delete(bool p_word, bool p_all_to_right) {
next_column = column;
} else {
// Delete one character
- next_column = caret.column < curline_len ? (caret.column + 1) : 0;
if (caret_mid_grapheme_enabled) {
next_column = caret.column < curline_len ? (caret.column + 1) : 0;
} else {
@@ -2768,48 +2767,38 @@ Point2i TextEdit::get_next_visible_line_index_offset_from(int p_line_from, int p
// Overridable actions
void TextEdit::handle_unicode_input(const uint32_t p_unicode) {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_handle_unicode_input")) {
- si->call("_handle_unicode_input", p_unicode);
+ if (GDVIRTUAL_CALL(_handle_unicode_input, p_unicode)) {
return;
}
- _handle_unicode_input(p_unicode);
+ _handle_unicode_input_internal(p_unicode);
}
void TextEdit::backspace() {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_backspace")) {
- si->call("_backspace");
+ if (GDVIRTUAL_CALL(_backspace)) {
return;
}
- _backspace();
+ _backspace_internal();
}
void TextEdit::cut() {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_cut")) {
- si->call("_cut");
+ if (GDVIRTUAL_CALL(_cut)) {
return;
}
- _cut();
+ _cut_internal();
}
void TextEdit::copy() {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_copy")) {
- si->call("_copy");
+ if (GDVIRTUAL_CALL(_copy)) {
return;
}
- _copy();
+ _copy_internal();
}
void TextEdit::paste() {
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_paste")) {
- si->call("_paste");
+ if (GDVIRTUAL_CALL(_paste)) {
return;
}
- _paste();
+ _paste_internal();
}
// Context menu.
@@ -4377,7 +4366,7 @@ bool TextEdit::is_drawing_spaces() const {
void TextEdit::_bind_methods() {
/*Internal. */
- ClassDB::bind_method(D_METHOD("_gui_input"), &TextEdit::_gui_input);
+
ClassDB::bind_method(D_METHOD("_text_changed_emit"), &TextEdit::_text_changed_emit);
/* Text */
@@ -4452,12 +4441,11 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("copy"), &TextEdit::copy);
ClassDB::bind_method(D_METHOD("paste"), &TextEdit::paste);
- BIND_VMETHOD(MethodInfo("_handle_unicode_input", PropertyInfo(Variant::INT, "unicode")))
- BIND_VMETHOD(MethodInfo("_backspace"));
-
- BIND_VMETHOD(MethodInfo("_cut"));
- BIND_VMETHOD(MethodInfo("_copy"));
- BIND_VMETHOD(MethodInfo("_paste"));
+ GDVIRTUAL_BIND(_handle_unicode_input, "unicode_char")
+ GDVIRTUAL_BIND(_backspace)
+ GDVIRTUAL_BIND(_cut)
+ GDVIRTUAL_BIND(_copy)
+ GDVIRTUAL_BIND(_paste)
// Context Menu
BIND_ENUM_CONSTANT(MENU_CUT);
@@ -4884,7 +4872,7 @@ void TextEdit::_set_symbol_lookup_word(const String &p_symbol) {
/* Text manipulation */
// Overridable actions
-void TextEdit::_handle_unicode_input(const uint32_t p_unicode) {
+void TextEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
if (!editable) {
return;
}
@@ -4915,7 +4903,7 @@ void TextEdit::_handle_unicode_input(const uint32_t p_unicode) {
}
}
-void TextEdit::_backspace() {
+void TextEdit::_backspace_internal() {
if (!editable) {
return;
}
@@ -4946,7 +4934,7 @@ void TextEdit::_backspace() {
set_caret_column(prev_column);
}
-void TextEdit::_cut() {
+void TextEdit::_cut_internal() {
if (!editable) {
return;
}
@@ -4976,7 +4964,7 @@ void TextEdit::_cut() {
cut_copy_line = clipboard;
}
-void TextEdit::_copy() {
+void TextEdit::_copy_internal() {
if (has_selection()) {
DisplayServer::get_singleton()->clipboard_set(get_selected_text());
cut_copy_line = "";
@@ -4991,7 +4979,7 @@ void TextEdit::_copy() {
}
}
-void TextEdit::_paste() {
+void TextEdit::_paste_internal() {
if (!editable) {
return;
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 69468978ab..ced03e19d0 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -528,7 +528,7 @@ private:
protected:
void _notification(int p_what);
- virtual void _gui_input(const Ref<InputEvent> &p_gui_input);
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
static void _bind_methods();
@@ -562,12 +562,18 @@ protected:
/* Text manipulation */
// Overridable actions
- virtual void _handle_unicode_input(const uint32_t p_unicode);
- virtual void _backspace();
-
- virtual void _cut();
- virtual void _copy();
- virtual void _paste();
+ virtual void _handle_unicode_input_internal(const uint32_t p_unicode);
+ virtual void _backspace_internal();
+
+ virtual void _cut_internal();
+ virtual void _copy_internal();
+ virtual void _paste_internal();
+
+ GDVIRTUAL1(_handle_unicode_input, int)
+ GDVIRTUAL0(_backspace)
+ GDVIRTUAL0(_cut)
+ GDVIRTUAL0(_copy)
+ GDVIRTUAL0(_paste)
public:
/* General overrides. */
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index d9892b53fc..5f07f5216a 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2768,7 +2768,7 @@ void Tree::_go_down() {
accept_event();
}
-void Tree::_gui_input(Ref<InputEvent> p_event) {
+void Tree::gui_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(p_event.is_null());
Ref<InputEventKey> k = p_event;
@@ -4650,8 +4650,6 @@ bool Tree::get_allow_reselect() const {
}
void Tree::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &Tree::_gui_input);
-
ClassDB::bind_method(D_METHOD("clear"), &Tree::clear);
ClassDB::bind_method(D_METHOD("create_item", "parent", "idx"), &Tree::_create_item, DEFVAL(Variant()), DEFVAL(-1));
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index c207737cc0..cce8b527db 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -462,7 +462,6 @@ private:
void popup_select(int p_option);
- void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
void item_edited(int p_column, TreeItem *p_item, bool p_lmb = true);
@@ -626,6 +625,8 @@ protected:
}
public:
+ virtual void gui_input(const Ref<InputEvent> &p_event) override;
+
virtual String get_tooltip(const Point2 &p_pos) const override;
TreeItem *get_item_at_position(const Point2 &p_pos) const;
diff --git a/scene/main/canvas_item.cpp b/scene/main/canvas_item.cpp
index f2415eaf71..f329332725 100644
--- a/scene/main/canvas_item.cpp
+++ b/scene/main/canvas_item.cpp
@@ -151,9 +151,7 @@ void CanvasItem::_update_callback() {
current_item_drawn = this;
notification(NOTIFICATION_DRAW);
emit_signal(SceneStringNames::get_singleton()->draw);
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_draw);
- }
+ GDVIRTUAL_CALL(_draw);
current_item_drawn = nullptr;
drawing = false;
}
@@ -934,7 +932,7 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_clip_children", "enable"), &CanvasItem::set_clip_children);
ClassDB::bind_method(D_METHOD("is_clipping_children"), &CanvasItem::is_clipping_children);
- BIND_VMETHOD(MethodInfo("_draw"));
+ GDVIRTUAL_BIND(_draw);
ADD_GROUP("Visibility", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible");
diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h
index dc7ad2bf5d..a591cab485 100644
--- a/scene/main/canvas_item.h
+++ b/scene/main/canvas_item.h
@@ -142,6 +142,7 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+ GDVIRTUAL0(_draw)
public:
enum {
NOTIFICATION_TRANSFORM_CHANGED = SceneTree::NOTIFICATION_TRANSFORM_CHANGED, //unique
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index 155af30a6d..9fce00be60 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -54,16 +54,11 @@ int Node::orphan_node_count = 0;
void Node::_notification(int p_notification) {
switch (p_notification) {
case NOTIFICATION_PROCESS: {
- if (get_script_instance()) {
- Variant time = get_process_delta_time();
- get_script_instance()->call(SceneStringNames::get_singleton()->_process, time);
- }
+ GDVIRTUAL_CALL(_process, get_process_delta_time());
+
} break;
case NOTIFICATION_PHYSICS_PROCESS: {
- if (get_script_instance()) {
- Variant time = get_physics_process_delta_time();
- get_script_instance()->call(SceneStringNames::get_singleton()->_physics_process, time);
- }
+ GDVIRTUAL_CALL(_physics_process, get_process_delta_time());
} break;
case NOTIFICATION_ENTER_TREE: {
@@ -128,27 +123,26 @@ void Node::_notification(int p_notification) {
} break;
case NOTIFICATION_READY: {
if (get_script_instance()) {
- if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_input)) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_input)) {
set_process_input(true);
}
- if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_unhandled_input)) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_unhandled_input)) {
set_process_unhandled_input(true);
}
- if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_unhandled_key_input)) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_unhandled_key_input)) {
set_process_unhandled_key_input(true);
}
- if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_process)) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_process)) {
set_process(true);
}
-
- if (get_script_instance()->has_method(SceneStringNames::get_singleton()->_physics_process)) {
+ if (GDVIRTUAL_IS_OVERRIDEN(_physics_process)) {
set_physics_process(true);
}
- get_script_instance()->call(SceneStringNames::get_singleton()->_ready);
+ GDVIRTUAL_CALL(_ready);
}
if (data.filename.length()) {
ERR_FAIL_COND(!is_inside_tree());
@@ -221,9 +215,7 @@ void Node::_propagate_enter_tree() {
notification(NOTIFICATION_ENTER_TREE);
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_enter_tree);
- }
+ GDVIRTUAL_CALL(_enter_tree);
emit_signal(SceneStringNames::get_singleton()->tree_entered);
@@ -269,9 +261,8 @@ void Node::_propagate_exit_tree() {
data.blocked--;
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_exit_tree);
- }
+ GDVIRTUAL_CALL(_exit_tree);
+
emit_signal(SceneStringNames::get_singleton()->tree_exiting);
notification(NOTIFICATION_EXIT_TREE, true);
@@ -2496,9 +2487,14 @@ void Node::clear_internal_tree_resource_paths() {
}
TypedArray<String> Node::get_configuration_warnings() const {
- if (get_script_instance() && get_script_instance()->get_script().is_valid() &&
- get_script_instance()->get_script()->is_tool() && get_script_instance()->has_method("_get_configuration_warnings")) {
- return get_script_instance()->call("_get_configuration_warnings");
+ Vector<String> warnings;
+ if (GDVIRTUAL_CALL(_get_configuration_warnings, warnings)) {
+ TypedArray<String> ret;
+ ret.resize(warnings.size());
+ for (int i = 0; i < warnings.size(); i++) {
+ ret[i] = warnings[i];
+ }
+ return ret;
}
return Array();
}
@@ -2544,6 +2540,37 @@ void Node::request_ready() {
data.ready_first = true;
}
+void Node::_call_input(const Ref<InputEvent> &p_event) {
+ GDVIRTUAL_CALL(_input, p_event);
+ if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
+ return;
+ }
+ input(p_event);
+}
+void Node::_call_unhandled_input(const Ref<InputEvent> &p_event) {
+ GDVIRTUAL_CALL(_unhandled_input, p_event);
+ if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
+ return;
+ }
+ unhandled_input(p_event);
+}
+void Node::_call_unhandled_key_input(const Ref<InputEvent> &p_event) {
+ GDVIRTUAL_CALL(_unhandled_key_input, p_event);
+ if (!is_inside_tree() || !get_viewport() || get_viewport()->is_input_handled()) {
+ return;
+ }
+ unhandled_key_input(p_event);
+}
+
+void Node::input(const Ref<InputEvent> &p_event) {
+}
+
+void Node::unhandled_input(const Ref<InputEvent> &p_event) {
+}
+
+void Node::unhandled_key_input(const Ref<InputEvent> &p_key_event) {
+}
+
void Node::_bind_methods() {
GLOBAL_DEF("editor/node_naming/name_num_separator", 0);
ProjectSettings::get_singleton()->set_custom_property_info("editor/node_naming/name_num_separator", PropertyInfo(Variant::INT, "editor/node_naming/name_num_separator", PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
@@ -2625,6 +2652,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder);
ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder);
+ ClassDB::bind_method(D_METHOD("set_editable_instance", "node", "is_editable"), &Node::set_editable_instance);
+ ClassDB::bind_method(D_METHOD("is_editable_instance", "node"), &Node::is_editable_instance);
ClassDB::bind_method(D_METHOD("get_viewport"), &Node::get_viewport);
@@ -2737,15 +2766,15 @@ void Node::_bind_methods() {
ADD_GROUP("Editor Description", "editor_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_INTERNAL), "set_editor_description", "get_editor_description");
- BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_enter_tree"));
- BIND_VMETHOD(MethodInfo("_exit_tree"));
- BIND_VMETHOD(MethodInfo("_ready"));
- BIND_VMETHOD(MethodInfo("_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
- BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEventKey")));
- BIND_VMETHOD(MethodInfo(PropertyInfo(Variant::ARRAY, "", PROPERTY_HINT_ARRAY_TYPE, "String"), "_get_configuration_warnings"));
+ GDVIRTUAL_BIND(_process, "delta");
+ GDVIRTUAL_BIND(_physics_process, "delta");
+ GDVIRTUAL_BIND(_enter_tree);
+ GDVIRTUAL_BIND(_exit_tree);
+ GDVIRTUAL_BIND(_ready);
+ GDVIRTUAL_BIND(_get_configuration_warnings);
+ GDVIRTUAL_BIND(_input, "event");
+ GDVIRTUAL_BIND(_unhandled_input, "event");
+ GDVIRTUAL_BIND(_unhandled_key_input, "event");
}
String Node::_get_name_num_separator() {
diff --git a/scene/main/node.h b/scene/main/node.h
index 6616524866..a07accba2f 100644
--- a/scene/main/node.h
+++ b/scene/main/node.h
@@ -208,6 +208,27 @@ protected:
void _set_owner_nocheck(Node *p_owner);
void _set_name_nocheck(const StringName &p_name);
+ //call from SceneTree
+ void _call_input(const Ref<InputEvent> &p_event);
+ void _call_unhandled_input(const Ref<InputEvent> &p_event);
+ void _call_unhandled_key_input(const Ref<InputEvent> &p_event);
+
+protected:
+ virtual void input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_input(const Ref<InputEvent> &p_event);
+ virtual void unhandled_key_input(const Ref<InputEvent> &p_key_event);
+
+ GDVIRTUAL1(_process, double)
+ GDVIRTUAL1(_physics_process, double)
+ GDVIRTUAL0(_enter_tree)
+ GDVIRTUAL0(_exit_tree)
+ GDVIRTUAL0(_ready)
+ GDVIRTUAL0RC(Vector<String>, _get_configuration_warnings)
+
+ GDVIRTUAL1(_input, Ref<InputEvent>)
+ GDVIRTUAL1(_unhandled_input, Ref<InputEvent>)
+ GDVIRTUAL1(_unhandled_key_input, Ref<InputEvent>)
+
public:
enum {
// you can make your own, but don't use the same numbers as other notifications in other nodes
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 5b707498a7..8260d0dff5 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -867,7 +867,7 @@ void SceneMainLoop::_update_listener_2d() {
*/
-void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport) {
+void SceneTree::_call_input_pause(const StringName &p_group, CallInputType p_call_type, const Ref<InputEvent> &p_input, Viewport *p_viewport) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E) {
return;
@@ -886,9 +886,6 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
int node_count = nodes_copy.size();
Node **nodes = nodes_copy.ptrw();
- Variant arg = p_input;
- const Variant *v[1] = { &arg };
-
call_lock++;
for (int i = node_count - 1; i >= 0; i--) {
@@ -905,14 +902,16 @@ void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p
continue;
}
- Callable::CallError err;
- // Call both script and native method.
- if (n->get_script_instance()) {
- n->get_script_instance()->call(p_method, (const Variant **)v, 1, err);
- }
- MethodBind *method = ClassDB::get_method(n->get_class_name(), p_method);
- if (method) {
- method->call(n, (const Variant **)v, 1, err);
+ switch (p_call_type) {
+ case CALL_INPUT_TYPE_INPUT:
+ n->_call_input(p_input);
+ break;
+ case CALL_INPUT_TYPE_UNHANDLED_INPUT:
+ n->_call_unhandled_input(p_input);
+ break;
+ case CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT:
+ n->_call_unhandled_key_input(p_input);
+ break;
}
}
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index cfb95bd6b5..b1b94ae910 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -204,8 +204,14 @@ private:
void _main_window_close();
void _main_window_go_back();
+ enum CallInputType {
+ CALL_INPUT_TYPE_INPUT,
+ CALL_INPUT_TYPE_UNHANDLED_INPUT,
+ CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT,
+ };
+
//used by viewport
- void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input, Viewport *p_viewport);
+ void _call_input_pause(const StringName &p_group, CallInputType p_call_type, const Ref<InputEvent> &p_input, Viewport *p_viewport);
protected:
void _notification(int p_notification);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 78fa0985a9..ea2323c651 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -32,6 +32,7 @@
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
+#include "core/object/message_queue.h"
#include "core/string/translation.h"
#include "core/templates/pair.h"
#include "scene/2d/camera_2d.h"
@@ -662,7 +663,7 @@ void Viewport::_process_picking() {
}
if (send_event) {
- co->_input_event(this, ev, res[i].shape);
+ co->_input_event_call(this, ev, res[i].shape);
}
}
}
@@ -1234,27 +1235,7 @@ void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_inpu
Control *control = Object::cast_to<Control>(ci);
if (control) {
if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
- control->emit_signal(SceneStringNames::get_singleton()->gui_input, ev); //signal should be first, so it's possible to override an event (and then accept it)
- }
- if (gui.key_event_accepted) {
- break;
- }
- if (!control->is_inside_tree()) {
- break;
- }
-
- if (control->data.mouse_filter != Control::MOUSE_FILTER_IGNORE) {
- // Call both script and native methods.
- Callable::CallError error;
- Variant event = ev;
- const Variant *args[1] = { &event };
- if (control->get_script_instance()) {
- control->get_script_instance()->call(SceneStringNames::get_singleton()->_gui_input, args, 1, error);
- }
- MethodBind *method = ClassDB::get_method(control->get_class_name(), SceneStringNames::get_singleton()->_gui_input);
- if (method) {
- method->call(control, args, 1, error);
- }
+ control->_call_gui_input(ev);
}
if (!control->is_inside_tree() || control->is_set_as_top_level()) {
@@ -1982,10 +1963,7 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
if (gui.key_focus) {
gui.key_event_accepted = false;
if (gui.key_focus->can_process()) {
- gui.key_focus->call(SceneStringNames::get_singleton()->_gui_input, p_event);
- if (gui.key_focus) { //maybe lost it
- gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event);
- }
+ gui.key_focus->_call_gui_input(p_event);
}
if (gui.key_event_accepted) {
@@ -2205,7 +2183,7 @@ void Viewport::_drop_mouse_focus() {
mb->set_global_position(c->get_local_mouse_position());
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
- c->call(SceneStringNames::get_singleton()->_gui_input, mb);
+ c->_call_gui_input(mb);
}
}
}
@@ -2317,7 +2295,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(false);
- gui.mouse_focus->call(SceneStringNames::get_singleton()->_gui_input, mb);
+ gui.mouse_focus->_call_gui_input(mb);
}
}
@@ -2335,7 +2313,7 @@ void Viewport::_post_gui_grab_click_focus() {
mb->set_position(click);
mb->set_button_index(MouseButton(i + 1));
mb->set_pressed(true);
- gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb);
+ MessageQueue::get_singleton()->push_callable(callable_mp(gui.mouse_focus, &Control::_call_gui_input), mb);
}
}
}
@@ -2343,9 +2321,9 @@ void Viewport::_post_gui_grab_click_focus() {
///////////////////////////////
-void Viewport::input_text(const String &p_text) {
+void Viewport::push_text_input(const String &p_text) {
if (gui.subwindow_focused) {
- gui.subwindow_focused->input_text(p_text);
+ gui.subwindow_focused->push_text_input(p_text);
return;
}
@@ -2665,7 +2643,7 @@ bool Viewport::_sub_windows_forward_input(const Ref<InputEvent> &p_event) {
return true;
}
-void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
+void Viewport::push_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
ERR_FAIL_COND(!is_inside_tree());
if (disable_input) {
@@ -2695,7 +2673,7 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
}
if (!is_input_handled()) {
- get_tree()->_call_input_pause(input_group, "_input", ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
+ get_tree()->_call_input_pause(input_group, SceneTree::CALL_INPUT_TYPE_INPUT, ev, this); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
}
if (!is_input_handled()) {
@@ -2703,10 +2681,9 @@ void Viewport::input(const Ref<InputEvent> &p_event, bool p_local_coords) {
}
event_count++;
- //get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",ev); //special one for GUI, as controls use their own process check
}
-void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
+void Viewport::push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords) {
ERR_FAIL_COND(p_event.is_null());
ERR_FAIL_COND(!is_inside_tree());
local_input_handled = false;
@@ -2727,11 +2704,11 @@ void Viewport::unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coor
}
// Unhandled Input
- get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", ev, this);
+ get_tree()->_call_input_pause(unhandled_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_INPUT, ev, this);
// Unhandled key Input - used for performance reasons - This is called a lot less than _unhandled_input since it ignores MouseMotion, etc
if (!is_input_handled() && (Object::cast_to<InputEventKey>(*ev) != nullptr || Object::cast_to<InputEventShortcut>(*ev) != nullptr)) {
- get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", ev, this);
+ get_tree()->_call_input_pause(unhandled_key_input_group, SceneTree::CALL_INPUT_TYPE_UNHANDLED_KEY_INPUT, ev, this);
}
if (physics_object_picking && !is_input_handled()) {
@@ -3159,7 +3136,7 @@ void Viewport::_collision_object_3d_input_event(CollisionObject3D *p_object, Cam
return; //discarded
}
}
- p_object->_input_event(camera_3d, p_input_event, p_pos, p_normal, p_shape);
+ p_object->_input_event_call(camera_3d, p_input_event, p_pos, p_normal, p_shape);
physics_last_object_transform = object_transform;
physics_last_camera_transform = camera_transform;
physics_last_id = id;
@@ -3515,9 +3492,9 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_physics_object_picking"), &Viewport::get_physics_object_picking);
ClassDB::bind_method(D_METHOD("get_viewport_rid"), &Viewport::get_viewport_rid);
- ClassDB::bind_method(D_METHOD("input_text", "text"), &Viewport::input_text);
- ClassDB::bind_method(D_METHOD("input", "event", "in_local_coords"), &Viewport::input, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("unhandled_input", "event", "in_local_coords"), &Viewport::unhandled_input, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("push_text_input", "text"), &Viewport::push_text_input);
+ ClassDB::bind_method(D_METHOD("push_input", "event", "in_local_coords"), &Viewport::push_input, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("push_unhandled_input", "event", "in_local_coords"), &Viewport::push_unhandled_input, DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_camera_2d"), &Viewport::get_camera_2d);
ClassDB::bind_method(D_METHOD("set_as_audio_listener_2d", "enable"), &Viewport::set_as_audio_listener_2d);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 9c51f404d7..b24de77e6b 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -508,9 +508,9 @@ public:
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
- void input_text(const String &p_text);
- void input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
- void unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
+ void push_text_input(const String &p_text);
+ void push_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
+ void push_unhandled_input(const Ref<InputEvent> &p_event, bool p_local_coords = false);
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 73eec73d75..b9c0ae5a4a 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -916,14 +916,14 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
emit_signal(SceneStringNames::get_singleton()->window_input, p_ev);
- input(p_ev);
+ push_input(p_ev);
if (!is_input_handled()) {
- unhandled_input(p_ev);
+ push_unhandled_input(p_ev);
}
}
void Window::_window_input_text(const String &p_text) {
- input_text(p_text);
+ push_text_input(p_text);
}
void Window::_window_drop_files(const Vector<String> &p_files) {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 6f8091c03f..2cea3c2337 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -320,7 +320,6 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- GDREGISTER_CLASS(Shortcut);
GDREGISTER_CLASS(Control);
GDREGISTER_CLASS(Button);
GDREGISTER_CLASS(Label);
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index e6a74e7685..b4eec2530b 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "animation.h"
-#include "scene/scene_string_names.h"
#include "core/math/geometry_3d.h"
+#include "scene/scene_string_names.h"
bool Animation::_set(const StringName &p_name, const Variant &p_value) {
String name = p_name;
@@ -79,15 +79,16 @@ bool Animation::_set(const StringName &p_name, const Variant &p_value) {
TransformTrack *tt = static_cast<TransformTrack *>(tracks[track]);
Vector<real_t> values = p_value;
int vcount = values.size();
- ERR_FAIL_COND_V(vcount % 12, false); // should be multiple of 12
+ ERR_FAIL_COND_V(vcount % TRANSFORM_TRACK_SIZE, false);
const real_t *r = values.ptr();
- tt->transforms.resize(vcount / 12);
+ int64_t count = vcount / TRANSFORM_TRACK_SIZE;
+ tt->transforms.resize(count);
- for (int i = 0; i < (vcount / 12); i++) {
+ for (int i = 0; i < count; i++) {
TKey<TransformKey> &tk = tt->transforms.write[i];
- const real_t *ofs = &r[i * 12];
+ const real_t *ofs = &r[i * TRANSFORM_TRACK_SIZE];
tk.time = ofs[0];
tk.transition = ofs[1];
@@ -354,7 +355,7 @@ bool Animation::_get(const StringName &p_name, Variant &r_ret) const {
if (track_get_type(track) == TYPE_TRANSFORM3D) {
Vector<real_t> keys;
int kk = track_get_key_count(track);
- keys.resize(kk * sizeof(Transform3D));
+ keys.resize(kk * TRANSFORM_TRACK_SIZE);
real_t *w = keys.ptrw();
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index 6227f6967f..9a410bd566 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -92,6 +92,9 @@ private:
Vector3 scale;
};
+ // Not necessarily the same size as Transform3D. The amount of numbers in Animation::Key and TransformKey.
+ const int32_t TRANSFORM_TRACK_SIZE = 12;
+
/* TRANSFORM TRACK */
struct TransformTrack : public Track {
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index 3b666640f8..a364a27e80 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -662,19 +662,27 @@ void Curve2D::_bake() const {
if (points.size() == 0) {
baked_point_cache.resize(0);
+ baked_dist_cache.resize(0);
return;
}
if (points.size() == 1) {
baked_point_cache.resize(1);
baked_point_cache.set(0, points[0].pos);
+
+ baked_dist_cache.resize(1);
+ baked_dist_cache.set(0, 0.0);
return;
}
Vector2 pos = points[0].pos;
+ float dist = 0.0;
+
List<Vector2> pointlist;
+ List<float> distlist;
pointlist.push_back(pos); //start always from origin
+ distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
float step = 0.1; // at least 10 substeps ought to be enough?
@@ -712,7 +720,10 @@ void Curve2D::_bake() const {
pos = npp;
p = mid;
+ dist += d;
+
pointlist.push_back(pos);
+ distlist.push_back(dist);
} else {
p = np;
}
@@ -722,16 +733,20 @@ void Curve2D::_bake() const {
Vector2 lastpos = points[points.size() - 1].pos;
float rem = pos.distance_to(lastpos);
- baked_max_ofs = (pointlist.size() - 1) * bake_interval + rem;
+ dist += rem;
+ baked_max_ofs = dist;
pointlist.push_back(lastpos);
+ distlist.push_back(dist);
baked_point_cache.resize(pointlist.size());
+ baked_dist_cache.resize(distlist.size());
+
Vector2 *w = baked_point_cache.ptrw();
- int idx = 0;
+ float *wd = baked_dist_cache.ptrw();
- for (const Vector2 &E : pointlist) {
- w[idx] = E;
- idx++;
+ for (int i = 0; i < pointlist.size(); i++) {
+ w[i] = pointlist[i];
+ wd[i] = distlist[i];
}
}
@@ -766,19 +781,26 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
return r[bpc - 1];
}
- int idx = Math::floor((double)p_offset / (double)bake_interval);
- float frac = Math::fmod(p_offset, (float)bake_interval);
-
- if (idx >= bpc - 1) {
- return r[bpc - 1];
- } else if (idx == bpc - 2) {
- if (frac > 0) {
- frac /= Math::fmod(baked_max_ofs, bake_interval);
+ int start = 0, end = bpc, idx = (end + start) / 2;
+ // binary search to find baked points
+ while (start < idx) {
+ float offset = baked_dist_cache[idx];
+ if (p_offset <= offset) {
+ end = idx;
+ } else {
+ start = idx;
}
- } else {
- frac /= bake_interval;
+ idx = (end + start) / 2;
}
+ float offset_begin = baked_dist_cache[idx];
+ float offset_end = baked_dist_cache[idx + 1];
+
+ float idx_interval = offset_end - offset_begin;
+ ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector2(), "failed to find baked segment");
+
+ float frac = (p_offset - offset_begin) / idx_interval;
+
if (p_cubic) {
Vector2 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector2 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
@@ -1145,6 +1167,7 @@ void Curve3D::_bake() const {
baked_point_cache.resize(0);
baked_tilt_cache.resize(0);
baked_up_vector_cache.resize(0);
+ baked_dist_cache.resize(0);
return;
}
@@ -1153,6 +1176,8 @@ void Curve3D::_bake() const {
baked_point_cache.set(0, points[0].pos);
baked_tilt_cache.resize(1);
baked_tilt_cache.set(0, points[0].tilt);
+ baked_dist_cache.resize(1);
+ baked_dist_cache.set(0, 0.0);
if (up_vector_enabled) {
baked_up_vector_cache.resize(1);
@@ -1165,8 +1190,12 @@ void Curve3D::_bake() const {
}
Vector3 pos = points[0].pos;
+ float dist = 0.0;
List<Plane> pointlist;
+ List<float> distlist;
+
pointlist.push_back(Plane(pos, points[0].tilt));
+ distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
float step = 0.1; // at least 10 substeps ought to be enough?
@@ -1207,7 +1236,10 @@ void Curve3D::_bake() const {
Plane post;
post.normal = pos;
post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid);
+ dist += d;
+
pointlist.push_back(post);
+ distlist.push_back(dist);
} else {
p = np;
}
@@ -1218,8 +1250,10 @@ void Curve3D::_bake() const {
float lastilt = points[points.size() - 1].tilt;
float rem = pos.distance_to(lastpos);
- baked_max_ofs = (pointlist.size() - 1) * bake_interval + rem;
+ dist += rem;
+ baked_max_ofs = dist;
pointlist.push_back(Plane(lastpos, lastilt));
+ distlist.push_back(dist);
baked_point_cache.resize(pointlist.size());
Vector3 *w = baked_point_cache.ptrw();
@@ -1231,6 +1265,9 @@ void Curve3D::_bake() const {
baked_up_vector_cache.resize(up_vector_enabled ? pointlist.size() : 0);
Vector3 *up_write = baked_up_vector_cache.ptrw();
+ baked_dist_cache.resize(pointlist.size());
+ float *wd = baked_dist_cache.ptrw();
+
Vector3 sideways;
Vector3 up;
Vector3 forward;
@@ -1242,6 +1279,7 @@ void Curve3D::_bake() const {
for (const Plane &E : pointlist) {
w[idx] = E.normal;
wt[idx] = E.d;
+ wd[idx] = distlist[idx];
if (!up_vector_enabled) {
idx++;
@@ -1308,19 +1346,26 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
return r[bpc - 1];
}
- int idx = Math::floor((double)p_offset / (double)bake_interval);
- float frac = Math::fmod(p_offset, bake_interval);
-
- if (idx >= bpc - 1) {
- return r[bpc - 1];
- } else if (idx == bpc - 2) {
- if (frac > 0) {
- frac /= Math::fmod(baked_max_ofs, bake_interval);
+ int start = 0, end = bpc, idx = (end + start) / 2;
+ // binary search to find baked points
+ while (start < idx) {
+ float offset = baked_dist_cache[idx];
+ if (p_offset <= offset) {
+ end = idx;
+ } else {
+ start = idx;
}
- } else {
- frac /= bake_interval;
+ idx = (end + start) / 2;
}
+ float offset_begin = baked_dist_cache[idx];
+ float offset_end = baked_dist_cache[idx + 1];
+
+ float idx_interval = offset_end - offset_begin;
+ ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector3(), "failed to find baked segment");
+
+ float frac = (p_offset - offset_begin) / idx_interval;
+
if (p_cubic) {
Vector3 pre = idx > 0 ? r[idx - 1] : r[idx];
Vector3 post = (idx < (bpc - 2)) ? r[idx + 2] : r[idx + 1];
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index c25d307608..5808fd6508 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -161,6 +161,7 @@ class Curve2D : public Resource {
mutable bool baked_cache_dirty = false;
mutable PackedVector2Array baked_point_cache;
+ mutable PackedFloat32Array baked_dist_cache;
mutable float baked_max_ofs = 0.0;
void _bake() const;
@@ -224,6 +225,7 @@ class Curve3D : public Resource {
mutable PackedVector3Array baked_point_cache;
mutable Vector<real_t> baked_tilt_cache;
mutable PackedVector3Array baked_up_vector_cache;
+ mutable PackedFloat32Array baked_dist_cache;
mutable float baked_max_ofs = 0.0;
void _bake() const;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 4e139adabb..dd7b348498 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -212,26 +212,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_constant("outline_size", "LinkButton", 0);
theme->set_constant("underline_spacing", "LinkButton", 2 * scale);
- // ColorPickerButton
-
- theme->set_stylebox("normal", "ColorPickerButton", sb_button_normal);
- theme->set_stylebox("pressed", "ColorPickerButton", sb_button_pressed);
- theme->set_stylebox("hover", "ColorPickerButton", sb_button_hover);
- theme->set_stylebox("disabled", "ColorPickerButton", sb_button_disabled);
- theme->set_stylebox("focus", "ColorPickerButton", sb_button_focus);
-
- theme->set_font("font", "ColorPickerButton", Ref<Font>());
- theme->set_font_size("font_size", "ColorPickerButton", -1);
-
- theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1));
- theme->set_color("font_pressed_color", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
- theme->set_color("font_hover_color", "ColorPickerButton", Color(1, 1, 1, 1));
- theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
- theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1));
-
- theme->set_constant("hseparation", "ColorPickerButton", 2 * scale);
- theme->set_constant("outline_size", "ColorPickerButton", 0);
-
// OptionButton
Ref<StyleBox> sb_optbutton_focus = sb_expand(make_stylebox(button_focus_png, 4, 4, 4, 4, 6, 2, 6, 2), 2, 2, 2, 2);
@@ -859,7 +839,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("add_preset", "ColorPicker", make_icon(icon_add_png));
theme->set_icon("color_hue", "ColorPicker", make_icon(color_picker_hue_png));
theme->set_icon("color_sample", "ColorPicker", make_icon(color_picker_sample_png));
- theme->set_icon("preset_bg", "ColorPicker", make_icon(mini_checkerboard_png));
+ theme->set_icon("sample_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));
@@ -867,6 +847,34 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// ColorPickerButton
theme->set_icon("bg", "ColorPickerButton", make_icon(mini_checkerboard_png));
+ theme->set_stylebox("normal", "ColorPickerButton", sb_button_normal);
+ theme->set_stylebox("pressed", "ColorPickerButton", sb_button_pressed);
+ theme->set_stylebox("hover", "ColorPickerButton", sb_button_hover);
+ theme->set_stylebox("disabled", "ColorPickerButton", sb_button_disabled);
+ theme->set_stylebox("focus", "ColorPickerButton", sb_button_focus);
+
+ theme->set_font("font", "ColorPickerButton", Ref<Font>());
+ theme->set_font_size("font_size", "ColorPickerButton", -1);
+
+ theme->set_color("font_color", "ColorPickerButton", Color(1, 1, 1, 1));
+ theme->set_color("font_pressed_color", "ColorPickerButton", Color(0.8, 0.8, 0.8, 1));
+ theme->set_color("font_hover_color", "ColorPickerButton", Color(1, 1, 1, 1));
+ theme->set_color("font_disabled_color", "ColorPickerButton", Color(0.9, 0.9, 0.9, 0.3));
+ theme->set_color("font_outline_color", "ColorPickerButton", Color(1, 1, 1));
+
+ theme->set_constant("hseparation", "ColorPickerButton", 2 * scale);
+ theme->set_constant("outline_size", "ColorPickerButton", 0);
+
+ // ColorPresetButton
+
+ Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2);
+ preset_sb->set_corner_radius_all(2);
+ preset_sb->set_corner_detail(2);
+ preset_sb->set_anti_aliased(false);
+
+ theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb);
+ theme->set_icon("preset_bg", "ColorPresetButton", make_icon(mini_checkerboard_png));
+ theme->set_icon("overbright_indicator", "ColorPresetButton", make_icon(overbright_indicator_png));
// TooltipPanel
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index 34f4142a14..0495a9e92c 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -45,31 +45,31 @@ void ParticlesMaterial::init_shaders() {
shader_names->direction = "direction";
shader_names->spread = "spread";
shader_names->flatness = "flatness";
- shader_names->initial_linear_velocity = "initial_linear_velocity";
- shader_names->initial_angle = "initial_angle";
- shader_names->angular_velocity = "angular_velocity";
- shader_names->orbit_velocity = "orbit_velocity";
- shader_names->linear_accel = "linear_accel";
- shader_names->radial_accel = "radial_accel";
- shader_names->tangent_accel = "tangent_accel";
- shader_names->damping = "damping";
- shader_names->scale = "scale";
- shader_names->hue_variation = "hue_variation";
- shader_names->anim_speed = "anim_speed";
- shader_names->anim_offset = "anim_offset";
-
- shader_names->initial_linear_velocity_random = "initial_linear_velocity_random";
- shader_names->initial_angle_random = "initial_angle_random";
- shader_names->angular_velocity_random = "angular_velocity_random";
- shader_names->orbit_velocity_random = "orbit_velocity_random";
- shader_names->linear_accel_random = "linear_accel_random";
- shader_names->radial_accel_random = "radial_accel_random";
- shader_names->tangent_accel_random = "tangent_accel_random";
- shader_names->damping_random = "damping_random";
- shader_names->scale_random = "scale_random";
- shader_names->hue_variation_random = "hue_variation_random";
- shader_names->anim_speed_random = "anim_speed_random";
- shader_names->anim_offset_random = "anim_offset_random";
+ shader_names->initial_linear_velocity_min = "initial_linear_velocity_min";
+ shader_names->initial_angle_min = "initial_angle_min";
+ shader_names->angular_velocity_min = "angular_velocity_min";
+ shader_names->orbit_velocity_min = "orbit_velocity_min";
+ shader_names->linear_accel_min = "linear_accel_min";
+ shader_names->radial_accel_min = "radial_accel_min";
+ shader_names->tangent_accel_min = "tangent_accel_min";
+ shader_names->damping_min = "damping_min";
+ shader_names->scale_min = "scale_min";
+ shader_names->hue_variation_min = "hue_variation_min";
+ shader_names->anim_speed_min = "anim_speed_min";
+ shader_names->anim_offset_min = "anim_offset_min";
+
+ shader_names->initial_linear_velocity_max = "initial_linear_velocity_max";
+ shader_names->initial_angle_max = "initial_angle_max";
+ shader_names->angular_velocity_max = "angular_velocity_max";
+ shader_names->orbit_velocity_max = "orbit_velocity_max";
+ shader_names->linear_accel_max = "linear_accel_max";
+ shader_names->radial_accel_max = "radial_accel_max";
+ shader_names->tangent_accel_max = "tangent_accel_max";
+ shader_names->damping_max = "damping_max";
+ shader_names->scale_max = "scale_max";
+ shader_names->hue_variation_max = "hue_variation_max";
+ shader_names->anim_speed_max = "anim_speed_max";
+ shader_names->anim_offset_max = "anim_offset_max";
shader_names->angle_texture = "angle_texture";
shader_names->angular_velocity_texture = "angular_velocity_texture";
@@ -155,31 +155,31 @@ void ParticlesMaterial::_update_shader() {
code += "uniform vec3 direction;\n";
code += "uniform float spread;\n";
code += "uniform float flatness;\n";
- code += "uniform float initial_linear_velocity;\n";
- code += "uniform float initial_angle;\n";
- code += "uniform float angular_velocity;\n";
- code += "uniform float orbit_velocity;\n";
- code += "uniform float linear_accel;\n";
- code += "uniform float radial_accel;\n";
- code += "uniform float tangent_accel;\n";
- code += "uniform float damping;\n";
- code += "uniform float scale;\n";
- code += "uniform float hue_variation;\n";
- code += "uniform float anim_speed;\n";
- code += "uniform float anim_offset;\n";
-
- code += "uniform float initial_linear_velocity_random;\n";
- code += "uniform float initial_angle_random;\n";
- code += "uniform float angular_velocity_random;\n";
- code += "uniform float orbit_velocity_random;\n";
- code += "uniform float linear_accel_random;\n";
- code += "uniform float radial_accel_random;\n";
- code += "uniform float tangent_accel_random;\n";
- code += "uniform float damping_random;\n";
- code += "uniform float scale_random;\n";
- code += "uniform float hue_variation_random;\n";
- code += "uniform float anim_speed_random;\n";
- code += "uniform float anim_offset_random;\n";
+ code += "uniform float initial_linear_velocity_min;\n";
+ code += "uniform float initial_angle_min;\n";
+ code += "uniform float angular_velocity_min;\n";
+ code += "uniform float orbit_velocity_min;\n";
+ code += "uniform float linear_accel_min;\n";
+ code += "uniform float radial_accel_min;\n";
+ code += "uniform float tangent_accel_min;\n";
+ code += "uniform float damping_min;\n";
+ code += "uniform float scale_min;\n";
+ code += "uniform float hue_variation_min;\n";
+ code += "uniform float anim_speed_min;\n";
+ code += "uniform float anim_offset_min;\n";
+
+ code += "uniform float initial_linear_velocity_max;\n";
+ code += "uniform float initial_angle_max;\n";
+ code += "uniform float angular_velocity_max;\n";
+ code += "uniform float orbit_velocity_max;\n";
+ code += "uniform float linear_accel_max;\n";
+ code += "uniform float radial_accel_max;\n";
+ code += "uniform float tangent_accel_max;\n";
+ code += "uniform float damping_max;\n";
+ code += "uniform float scale_max;\n";
+ code += "uniform float hue_variation_max;\n";
+ code += "uniform float anim_speed_max;\n";
+ code += "uniform float anim_offset_max;\n";
code += "uniform float lifetime_randomness;\n";
switch (emission_shape) {
@@ -329,7 +329,7 @@ void ParticlesMaterial::_update_shader() {
if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(0.0, 0.0), 0.0).r;\n";
} else {
- code += " float tex_anim_offset = 0.0;\n";
+ code += " float tex_anim_offset = 1.0;\n";
}
code += " float spread_rad = spread * degree_to_rad;\n";
@@ -339,7 +339,7 @@ void ParticlesMaterial::_update_shader() {
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n";
} else {
- code += " float tex_linear_velocity = 0.0;\n";
+ code += " float tex_linear_velocity = 1.0;\n";
}
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
@@ -347,7 +347,7 @@ void ParticlesMaterial::_update_shader() {
code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n";
code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n";
code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n";
- code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " VELOCITY = rot * mix(initial_linear_velocity_min,initial_linear_velocity_max, rand_from_seed(alt_seed));\n";
code += " }\n";
} else {
@@ -369,16 +369,16 @@ void ParticlesMaterial::_update_shader() {
code += " binormal = normalize(binormal);\n";
code += " vec3 normal = cross(binormal, direction_nrm);\n";
code += " spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;\n";
- code += " VELOCITY = spread_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n";
+ code += " VELOCITY = spread_direction * mix(initial_linear_velocity_min, initial_linear_velocity_max,rand_from_seed(alt_seed));\n";
code += " }\n";
}
code += " }\n";
- code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n";
+ code += " float base_angle = (tex_angle) * mix(initial_angle_min, initial_angle_max, angle_rand);\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
code += " CUSTOM.y = 0.0;\n"; // phase
code += " CUSTOM.w = (1.0 - lifetime_randomness * rand_from_seed(alt_seed));\n";
- code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);\n"; // animation offset (0-1)
+ code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, anim_offset_rand);\n"; // animation offset (0-1)
code += " if (RESTART_POSITION) {\n";
@@ -471,63 +471,63 @@ void ParticlesMaterial::_update_shader() {
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_linear_velocity = 0.0;\n";
+ code += " float tex_linear_velocity = 1.0;\n";
}
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_orbit_velocity = 0.0;\n";
+ code += " float tex_orbit_velocity = 1.0;\n";
}
}
if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_angular_velocity = 0.0;\n";
+ code += " float tex_angular_velocity = 1.0;\n";
}
if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_linear_accel = 0.0;\n";
+ code += " float tex_linear_accel = 1.0;\n";
}
if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_radial_accel = 0.0;\n";
+ code += " float tex_radial_accel = 1.0;\n";
}
if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_tangent_accel = 0.0;\n";
+ code += " float tex_tangent_accel = 1.0;\n";
}
if (tex_parameters[PARAM_DAMPING].is_valid()) {
code += " float tex_damping = textureLod(damping_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_damping = 0.0;\n";
+ code += " float tex_damping = 1.0;\n";
}
if (tex_parameters[PARAM_ANGLE].is_valid()) {
code += " float tex_angle = textureLod(angle_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_angle = 0.0;\n";
+ code += " float tex_angle = 1.0;\n";
}
if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) {
code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_anim_speed = 0.0;\n";
+ code += " float tex_anim_speed = 1.0;\n";
}
if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) {
code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_anim_offset = 0.0;\n";
+ code += " float tex_anim_offset = 1.0;\n";
}
code += " vec3 force = gravity;\n";
@@ -536,18 +536,19 @@ void ParticlesMaterial::_update_shader() {
code += " pos.z = 0.0;\n";
}
code += " // apply linear acceleration\n";
- code += " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel + tex_linear_accel) * mix(1.0, rand_from_seed(alt_seed), linear_accel_random) : vec3(0.0);\n";
+ code += " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * tex_linear_accel * mix(linear_accel_min, linear_accel_max, rand_from_seed(alt_seed)) : vec3(0.0);\n";
code += " // apply radial acceleration\n";
code += " vec3 org = EMISSION_TRANSFORM[3].xyz;\n";
code += " vec3 diff = pos - org;\n";
- code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);\n";
+ code += " force += length(diff) > 0.0 ? normalize(diff) * tex_radial_accel * mix(radial_accel_min, radial_accel_max, rand_from_seed(alt_seed)) : vec3(0.0);\n";
code += " // apply tangential acceleration;\n";
+ code += " float tangent_accel_val = tex_tangent_accel * mix(tangent_accel_min, tangent_accel_max, rand_from_seed(alt_seed))\n;";
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
- code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n";
+ code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * tangent_accel_val : vec3(0.0);\n";
} else {
code += " vec3 crossDiff = cross(normalize(diff), normalize(gravity));\n";
- code += " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n";
+ code += " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * tangent_accel_val : vec3(0.0);\n";
}
if (attractor_interaction_enabled) {
code += " force += ATTRACTOR_FORCE;\n\n";
@@ -557,7 +558,7 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY += force * DELTA;\n";
code += " // orbit velocity\n";
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
- code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n";
+ code += " float orbit_amount = tex_orbit_velocity * mix(orbit_velocity_min, orbit_velocity_max, rand_from_seed(alt_seed));\n";
code += " if (orbit_amount != 0.0) {\n";
code += " float ang = orbit_amount * DELTA * pi * 2.0;\n";
code += " mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));\n";
@@ -569,9 +570,10 @@ void ParticlesMaterial::_update_shader() {
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n";
}
- code += " if (damping + tex_damping > 0.0) {\n";
+ code += " float dmp = mix(damping_min, damping_max, rand_from_seed(alt_seed));\n";
+ code += " if (dmp * tex_damping > 0.0) {\n";
code += " float v = length(VELOCITY);\n";
- code += " float damp = (damping + tex_damping) * mix(1.0, rand_from_seed(alt_seed), damping_random);\n";
+ code += " float damp = tex_damping * dmp;\n";
code += " v -= damp * DELTA;\n";
code += " if (v < 0.0) {\n";
code += " VELOCITY = vec3(0.0);\n";
@@ -579,26 +581,26 @@ void ParticlesMaterial::_update_shader() {
code += " VELOCITY = normalize(VELOCITY) * v;\n";
code += " }\n";
code += " }\n";
- code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n";
- code += " base_angle += CUSTOM.y * LIFETIME * (angular_velocity + tex_angular_velocity) * mix(1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, angular_velocity_random);\n";
+ code += " float base_angle = (tex_angle) * mix(initial_angle_min, initial_angle_max, rand_from_seed(alt_seed));\n";
+ code += " base_angle += CUSTOM.y * LIFETIME * (tex_angular_velocity) * mix(angular_velocity_min,angular_velocity_max, rand_from_seed(alt_seed));\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
- code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random) + CUSTOM.y * (anim_speed + tex_anim_speed) * mix(1.0, rand_from_seed(alt_seed), anim_speed_random);\n"; // angle
+ code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + CUSTOM.y * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle
// apply color
// apply hue rotation
if (tex_parameters[PARAM_SCALE].is_valid()) {
- code += " float tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).r;\n";
+ code += " vec3 tex_scale = textureLod(scale_texture, vec2(tv, 0.0), 0.0).rgb;\n";
} else {
- code += " float tex_scale = 1.0;\n";
+ code += " vec3 tex_scale = vec3(1.0);\n";
}
if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) {
code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(tv, 0.0), 0.0).r;\n";
} else {
- code += " float tex_hue_variation = 0.0;\n";
+ code += " float tex_hue_variation = 1.0;\n";
}
- code += " float hue_rot_angle = (hue_variation + tex_hue_variation) * pi * 2.0 * mix(1.0, hue_rot_rand * 2.0 - 1.0, hue_variation_random);\n";
+ code += " float hue_rot_angle = (tex_hue_variation) * pi * 2.0 * mix(hue_variation_min, hue_variation_max, rand_from_seed(alt_seed));\n";
code += " float hue_rot_c = cos(hue_rot_angle);\n";
code += " float hue_rot_s = sin(hue_rot_angle);\n";
code += " mat4 hue_rot_mat = mat4(vec4(0.299, 0.587, 0.114, 0.0),\n";
@@ -660,18 +662,18 @@ void ParticlesMaterial::_update_shader() {
}
// turn particle by rotation in Y
if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) {
+ code += " vec4 origin = TRANSFORM[3];\n";
code += " TRANSFORM = mat4(vec4(cos(CUSTOM.x), 0.0, -sin(CUSTOM.x), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(sin(CUSTOM.x), 0.0, cos(CUSTOM.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n";
+ code += " TRANSFORM[3] = origin;\n";
}
}
//scale by scale
- code += " float base_scale = tex_scale * mix(scale, 1.0, scale_random * scale_rand);\n";
- code += " if (base_scale < 0.000001) {\n";
- code += " base_scale = 0.000001;\n";
- code += " }\n";
+ code += " float base_scale = mix(scale_min, scale_max, scale_rand);\n";
+ code += " base_scale = sign(base_scale) * max(abs(base_scale), 0.001);\n";
- code += " TRANSFORM[0].xyz *= base_scale;\n";
- code += " TRANSFORM[1].xyz *= base_scale;\n";
- code += " TRANSFORM[2].xyz *= base_scale;\n";
+ code += " TRANSFORM[0].xyz *= base_scale * sign(tex_scale.r) * max(abs(tex_scale.r), 0.001);\n";
+ code += " TRANSFORM[1].xyz *= base_scale * sign(tex_scale.g) * max(abs(tex_scale.g), 0.001);\n";
+ code += " TRANSFORM[2].xyz *= base_scale * sign(tex_scale.b) * max(abs(tex_scale.b), 0.001);\n";
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
code += " VELOCITY.z = 0.0;\n";
code += " TRANSFORM[3].z = 0.0;\n";
@@ -777,110 +779,116 @@ float ParticlesMaterial::get_flatness() const {
return flatness;
}
-void ParticlesMaterial::set_param(Parameter p_param, float p_value) {
+void ParticlesMaterial::set_param_min(Parameter p_param, float p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
- parameters[p_param] = p_value;
+ params_min[p_param] = p_value;
+ if (params_min[p_param] > params_max[p_param]) {
+ set_param_max(p_param, p_value);
+ }
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_min, p_value);
} break;
case PARAM_ANGULAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_min, p_value);
} break;
case PARAM_ORBIT_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_min, p_value);
} break;
case PARAM_LINEAR_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_min, p_value);
} break;
case PARAM_RADIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_min, p_value);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_min, p_value);
} break;
case PARAM_DAMPING: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_min, p_value);
} break;
case PARAM_ANGLE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_min, p_value);
} break;
case PARAM_SCALE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_min, p_value);
} break;
case PARAM_HUE_VARIATION: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_min, p_value);
} break;
case PARAM_ANIM_SPEED: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_min, p_value);
} break;
case PARAM_ANIM_OFFSET: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_min, p_value);
} break;
case PARAM_MAX:
break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param(Parameter p_param) const {
+float ParticlesMaterial::get_param_min(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return parameters[p_param];
+ return params_min[p_param];
}
-void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) {
+void ParticlesMaterial::set_param_max(Parameter p_param, float p_value) {
ERR_FAIL_INDEX(p_param, PARAM_MAX);
- randomness[p_param] = p_value;
+ params_max[p_param] = p_value;
+ if (params_min[p_param] > params_max[p_param]) {
+ set_param_min(p_param, p_value);
+ }
switch (p_param) {
case PARAM_INITIAL_LINEAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_max, p_value);
} break;
case PARAM_ANGULAR_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_max, p_value);
} break;
case PARAM_ORBIT_VELOCITY: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_max, p_value);
} break;
case PARAM_LINEAR_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_max, p_value);
} break;
case PARAM_RADIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_max, p_value);
} break;
case PARAM_TANGENTIAL_ACCEL: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_max, p_value);
} break;
case PARAM_DAMPING: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_max, p_value);
} break;
case PARAM_ANGLE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_max, p_value);
} break;
case PARAM_SCALE: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_max, p_value);
} break;
case PARAM_HUE_VARIATION: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_max, p_value);
} break;
case PARAM_ANIM_SPEED: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_max, p_value);
} break;
case PARAM_ANIM_OFFSET: {
- RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value);
+ RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_max, p_value);
} break;
case PARAM_MAX:
break; // Can't happen, but silences warning
}
}
-float ParticlesMaterial::get_param_randomness(Parameter p_param) const {
+float ParticlesMaterial::get_param_max(Parameter p_param) const {
ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0);
- return randomness[p_param];
+ return params_max[p_param];
}
static void _adjust_curve_range(const Ref<Texture2D> &p_texture, float p_min, float p_max) {
@@ -1259,11 +1267,11 @@ void ParticlesMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &ParticlesMaterial::set_flatness);
ClassDB::bind_method(D_METHOD("get_flatness"), &ParticlesMaterial::get_flatness);
- ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ParticlesMaterial::set_param);
- ClassDB::bind_method(D_METHOD("get_param", "param"), &ParticlesMaterial::get_param);
+ ClassDB::bind_method(D_METHOD("set_param_min", "param", "value"), &ParticlesMaterial::set_param_min);
+ ClassDB::bind_method(D_METHOD("get_param_min", "param"), &ParticlesMaterial::get_param_min);
- ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &ParticlesMaterial::set_param_randomness);
- ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &ParticlesMaterial::get_param_randomness);
+ ClassDB::bind_method(D_METHOD("set_param_max", "param", "value"), &ParticlesMaterial::set_param_max);
+ ClassDB::bind_method(D_METHOD("get_param_max", "param"), &ParticlesMaterial::get_param_max);
ClassDB::bind_method(D_METHOD("set_param_texture", "param", "texture"), &ParticlesMaterial::set_param_texture);
ClassDB::bind_method(D_METHOD("get_param_texture", "param"), &ParticlesMaterial::get_param_texture);
@@ -1369,54 +1377,54 @@ void ParticlesMaterial::_bind_methods() {
ADD_GROUP("Gravity", "");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity");
ADD_GROUP("Initial Velocity", "initial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_INITIAL_LINEAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "initial_velocity_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_INITIAL_LINEAR_VELOCITY);
ADD_GROUP("Angular Velocity", "angular_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_min", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANGULAR_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angular_velocity_max", PROPERTY_HINT_RANGE, "-720,720,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANGULAR_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY);
ADD_GROUP("Orbit Velocity", "orbit_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_min", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ORBIT_VELOCITY);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "orbit_velocity_max", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ORBIT_VELOCITY);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY);
ADD_GROUP("Linear Accel", "linear_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_LINEAR_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "linear_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_LINEAR_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL);
ADD_GROUP("Radial Accel", "radial_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_RADIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "radial_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_RADIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL);
ADD_GROUP("Tangential Accel", "tangential_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_min", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_TANGENTIAL_ACCEL);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "tangential_accel_max", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_TANGENTIAL_ACCEL);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL);
ADD_GROUP("Damping", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_min", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_DAMPING);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "damping_max", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_DAMPING);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING);
ADD_GROUP("Angle", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param", "get_param", PARAM_ANGLE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_min", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_min", "get_param_min", PARAM_ANGLE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "angle_max", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater,degrees"), "set_param_max", "get_param_max", PARAM_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE);
ADD_GROUP("Scale", "");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE);
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_min", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_min", "get_param_min", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "scale_max", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param_max", "get_param_max", PARAM_SCALE);
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture,CurveXYZTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE);
ADD_GROUP("Color", "");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp");
ADD_GROUP("Hue Variation", "hue_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param", "get_param", PARAM_HUE_VARIATION);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_min", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_min", "get_param_min", PARAM_HUE_VARIATION);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "hue_variation_max", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_param_max", "get_param_max", PARAM_HUE_VARIATION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION);
ADD_GROUP("Animation", "anim_");
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_SPEED);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_speed_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_SPEED);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET);
- ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_min", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_min", "get_param_min", PARAM_ANIM_OFFSET);
+ ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_max", PROPERTY_HINT_RANGE, "0,16,0.01,or_lesser,or_greater"), "set_param_max", "get_param_max", PARAM_ANIM_OFFSET);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET);
ADD_GROUP("Sub Emitter", "sub_emitter_");
@@ -1472,18 +1480,30 @@ ParticlesMaterial::ParticlesMaterial() :
set_direction(Vector3(1, 0, 0));
set_spread(45);
set_flatness(0);
- set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0);
- set_param(PARAM_ANGULAR_VELOCITY, 0);
- set_param(PARAM_ORBIT_VELOCITY, 0);
- set_param(PARAM_LINEAR_ACCEL, 0);
- set_param(PARAM_RADIAL_ACCEL, 0);
- set_param(PARAM_TANGENTIAL_ACCEL, 0);
- set_param(PARAM_DAMPING, 0);
- set_param(PARAM_ANGLE, 0);
- set_param(PARAM_SCALE, 1);
- set_param(PARAM_HUE_VARIATION, 0);
- set_param(PARAM_ANIM_SPEED, 0);
- set_param(PARAM_ANIM_OFFSET, 0);
+ set_param_min(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_min(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_min(PARAM_ORBIT_VELOCITY, 0);
+ set_param_min(PARAM_LINEAR_ACCEL, 0);
+ set_param_min(PARAM_RADIAL_ACCEL, 0);
+ set_param_min(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_min(PARAM_DAMPING, 0);
+ set_param_min(PARAM_ANGLE, 0);
+ set_param_min(PARAM_SCALE, 1);
+ set_param_min(PARAM_HUE_VARIATION, 0);
+ set_param_min(PARAM_ANIM_SPEED, 0);
+ set_param_min(PARAM_ANIM_OFFSET, 0);
+ set_param_max(PARAM_INITIAL_LINEAR_VELOCITY, 0);
+ set_param_max(PARAM_ANGULAR_VELOCITY, 0);
+ set_param_max(PARAM_ORBIT_VELOCITY, 0);
+ set_param_max(PARAM_LINEAR_ACCEL, 0);
+ set_param_max(PARAM_RADIAL_ACCEL, 0);
+ set_param_max(PARAM_TANGENTIAL_ACCEL, 0);
+ set_param_max(PARAM_DAMPING, 0);
+ set_param_max(PARAM_ANGLE, 0);
+ set_param_max(PARAM_SCALE, 1);
+ set_param_max(PARAM_HUE_VARIATION, 0);
+ set_param_max(PARAM_ANIM_SPEED, 0);
+ set_param_max(PARAM_ANIM_OFFSET, 0);
set_emission_shape(EMISSION_SHAPE_POINT);
set_emission_sphere_radius(1);
set_emission_box_extents(Vector3(1, 1, 1));
@@ -1505,10 +1525,6 @@ ParticlesMaterial::ParticlesMaterial() :
set_collision_friction(0.0);
set_collision_use_scale(false);
- for (int i = 0; i < PARAM_MAX; i++) {
- set_param_randomness(Parameter(i), 0);
- }
-
for (int i = 0; i < PARTICLE_FLAG_MAX; i++) {
particle_flags[i] = false;
}
diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h
index 1e1821024e..8ab26aff77 100644
--- a/scene/resources/particles_material.h
+++ b/scene/resources/particles_material.h
@@ -154,31 +154,31 @@ private:
StringName direction;
StringName spread;
StringName flatness;
- StringName initial_linear_velocity;
- StringName initial_angle;
- StringName angular_velocity;
- StringName orbit_velocity;
- StringName linear_accel;
- StringName radial_accel;
- StringName tangent_accel;
- StringName damping;
- StringName scale;
- StringName hue_variation;
- StringName anim_speed;
- StringName anim_offset;
-
- StringName initial_linear_velocity_random;
- StringName initial_angle_random;
- StringName angular_velocity_random;
- StringName orbit_velocity_random;
- StringName linear_accel_random;
- StringName radial_accel_random;
- StringName tangent_accel_random;
- StringName damping_random;
- StringName scale_random;
- StringName hue_variation_random;
- StringName anim_speed_random;
- StringName anim_offset_random;
+ StringName initial_linear_velocity_min;
+ StringName initial_angle_min;
+ StringName angular_velocity_min;
+ StringName orbit_velocity_min;
+ StringName linear_accel_min;
+ StringName radial_accel_min;
+ StringName tangent_accel_min;
+ StringName damping_min;
+ StringName scale_min;
+ StringName hue_variation_min;
+ StringName anim_speed_min;
+ StringName anim_offset_min;
+
+ StringName initial_linear_velocity_max;
+ StringName initial_angle_max;
+ StringName angular_velocity_max;
+ StringName orbit_velocity_max;
+ StringName linear_accel_max;
+ StringName radial_accel_max;
+ StringName tangent_accel_max;
+ StringName damping_max;
+ StringName scale_max;
+ StringName hue_variation_max;
+ StringName anim_speed_max;
+ StringName anim_offset_max;
StringName angle_texture;
StringName angular_velocity_texture;
@@ -230,8 +230,8 @@ private:
float spread;
float flatness;
- float parameters[PARAM_MAX];
- float randomness[PARAM_MAX];
+ float params_min[PARAM_MAX];
+ float params_max[PARAM_MAX];
Ref<Texture2D> tex_parameters[PARAM_MAX];
Color color;
@@ -283,11 +283,11 @@ public:
void set_flatness(float p_flatness);
float get_flatness() const;
- void set_param(Parameter p_param, float p_value);
- float get_param(Parameter p_param) const;
+ void set_param_min(Parameter p_param, float p_value);
+ float get_param_min(Parameter p_param) const;
- void set_param_randomness(Parameter p_param, float p_value);
- float get_param_randomness(Parameter p_param) const;
+ void set_param_max(Parameter p_param, float p_value);
+ float get_param_max(Parameter p_param) const;
void set_param_texture(Parameter p_param, const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_param_texture(Parameter p_param) const;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index ba85ea4a6c..e7da41db9d 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -1420,6 +1420,8 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z;
+ float scale = height * (is_hemisphere ? 1.0 : 0.5);
+
// set our bounding box
Vector<Vector3> points;
@@ -1443,7 +1445,7 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
v /= (rings + 1);
w = sin(Math_PI * v);
- y = height * (is_hemisphere ? 1.0 : 0.5) * cos(Math_PI * v);
+ y = scale * cos(Math_PI * v);
for (i = 0; i <= radial_segments; i++) {
float u = i;
@@ -1458,7 +1460,8 @@ void SphereMesh::_create_mesh_array(Array &p_arr) const {
} else {
Vector3 p = Vector3(x * radius * w, y, z * radius * w);
points.push_back(p);
- normals.push_back(p.normalized());
+ Vector3 normal = Vector3(x * radius * w * scale, y / scale, z * radius * w * scale);
+ normals.push_back(normal.normalized());
};
ADD_TANGENT(z, 0.0, -x, 1.0)
uvs.push_back(Vector2(u, v));
diff --git a/scene/resources/skeleton_modification_2d.cpp b/scene/resources/skeleton_modification_2d.cpp
index 2d5b42ddf4..e533fb054a 100644
--- a/scene/resources/skeleton_modification_2d.cpp
+++ b/scene/resources/skeleton_modification_2d.cpp
@@ -44,7 +44,7 @@
///////////////////////////////////////
void SkeletonModification2D::_execute(float p_delta) {
- call("_execute", p_delta);
+ GDVIRTUAL_CALL(_execute, p_delta);
if (!enabled) {
return;
@@ -59,11 +59,11 @@ void SkeletonModification2D::_setup_modification(SkeletonModificationStack2D *p_
WARN_PRINT("Could not setup modification with name " + get_name());
}
- call("_setup_modification", p_stack);
+ GDVIRTUAL_CALL(_setup_modification, Ref<SkeletonModificationStack2D>(p_stack));
}
void SkeletonModification2D::_draw_editor_gizmo() {
- call("_draw_editor_gizmo");
+ GDVIRTUAL_CALL(_draw_editor_gizmo);
}
void SkeletonModification2D::set_enabled(bool p_enabled) {
@@ -228,9 +228,9 @@ bool SkeletonModification2D::get_editor_draw_gizmo() const {
}
void SkeletonModification2D::_bind_methods() {
- BIND_VMETHOD(MethodInfo("_execute", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_setup_modification", PropertyInfo(Variant::OBJECT, "modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack2D")));
- BIND_VMETHOD(MethodInfo("_draw_editor_gizmo"));
+ GDVIRTUAL_BIND(_execute, "delta");
+ GDVIRTUAL_BIND(_setup_modification, "modification_stack")
+ GDVIRTUAL_BIND(_draw_editor_gizmo)
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &SkeletonModification2D::set_enabled);
ClassDB::bind_method(D_METHOD("get_enabled"), &SkeletonModification2D::get_enabled);
diff --git a/scene/resources/skeleton_modification_2d.h b/scene/resources/skeleton_modification_2d.h
index 18633e55cb..aaddb9136e 100644
--- a/scene/resources/skeleton_modification_2d.h
+++ b/scene/resources/skeleton_modification_2d.h
@@ -57,6 +57,10 @@ protected:
bool _print_execution_error(bool p_condition, String p_message);
+ GDVIRTUAL1(_execute, double)
+ GDVIRTUAL1(_setup_modification, Ref<SkeletonModificationStack2D>)
+ GDVIRTUAL0(_draw_editor_gizmo)
+
public:
virtual void _execute(float _delta);
virtual void _setup_modification(SkeletonModificationStack2D *p_stack);
diff --git a/scene/resources/skeleton_modification_3d.cpp b/scene/resources/skeleton_modification_3d.cpp
index 9306ee14cd..ee02ede2d5 100644
--- a/scene/resources/skeleton_modification_3d.cpp
+++ b/scene/resources/skeleton_modification_3d.cpp
@@ -32,11 +32,7 @@
#include "scene/3d/skeleton_3d.h"
void SkeletonModification3D::_execute(real_t p_delta) {
- if (get_script_instance()) {
- if (get_script_instance()->has_method("execute")) {
- get_script_instance()->call("execute", p_delta);
- }
- }
+ GDVIRTUAL_CALL(_execute, p_delta);
if (!enabled)
return;
@@ -50,11 +46,7 @@ void SkeletonModification3D::_setup_modification(SkeletonModificationStack3D *p_
WARN_PRINT("Could not setup modification with name " + this->get_name());
}
- if (get_script_instance()) {
- if (get_script_instance()->has_method("setup_modification")) {
- get_script_instance()->call("setup_modification", p_stack);
- }
- }
+ GDVIRTUAL_CALL(_setup_modification, Ref<SkeletonModificationStack3D>(p_stack));
}
void SkeletonModification3D::set_enabled(bool p_enabled) {
@@ -148,8 +140,8 @@ int SkeletonModification3D::get_execution_mode() const {
}
void SkeletonModification3D::_bind_methods() {
- BIND_VMETHOD(MethodInfo("_execute", PropertyInfo(Variant::FLOAT, "delta")));
- BIND_VMETHOD(MethodInfo("_setup_modification", PropertyInfo(Variant::OBJECT, "modification_stack", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonModificationStack3D")));
+ GDVIRTUAL_BIND(_execute, "delta");
+ GDVIRTUAL_BIND(_setup_modification, "modification_stack")
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &SkeletonModification3D::set_enabled);
ClassDB::bind_method(D_METHOD("get_enabled"), &SkeletonModification3D::get_enabled);
diff --git a/scene/resources/skeleton_modification_3d.h b/scene/resources/skeleton_modification_3d.h
index 94ab0bf32c..fb1f3d33d1 100644
--- a/scene/resources/skeleton_modification_3d.h
+++ b/scene/resources/skeleton_modification_3d.h
@@ -53,6 +53,9 @@ protected:
bool _print_execution_error(bool p_condition, String p_message);
+ GDVIRTUAL1(_execute, double)
+ GDVIRTUAL1(_setup_modification, Ref<SkeletonModificationStack3D>)
+
public:
virtual void _execute(real_t p_delta);
virtual void _setup_modification(SkeletonModificationStack3D *p_stack);
diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp
index 173ce2adce..52a3abf74d 100644
--- a/scene/resources/syntax_highlighter.cpp
+++ b/scene/resources/syntax_highlighter.cpp
@@ -43,12 +43,10 @@ Dictionary SyntaxHighlighter::get_line_syntax_highlighting(int p_line) {
return color_map;
}
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_get_line_syntax_highlighting")) {
- color_map = si->call("_get_line_syntax_highlighting", p_line);
- } else {
- color_map = _get_line_syntax_highlighting(p_line);
+ if (!GDVIRTUAL_CALL(_get_line_syntax_highlighting, p_line, color_map)) {
+ color_map = _get_line_syntax_highlighting_impl(p_line);
}
+
highlighting_cache[p_line] = color_map;
return color_map;
}
@@ -69,9 +67,7 @@ void SyntaxHighlighter::_lines_edited_from(int p_from_line, int p_to_line) {
void SyntaxHighlighter::clear_highlighting_cache() {
highlighting_cache.clear();
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_clear_highlighting_cache")) {
- si->call("_clear_highlighting_cache");
+ if (GDVIRTUAL_CALL(_clear_highlighting_cache)) {
return;
}
_clear_highlighting_cache();
@@ -83,9 +79,7 @@ void SyntaxHighlighter::update_cache() {
if (text_edit == nullptr) {
return;
}
- ScriptInstance *si = get_script_instance();
- if (si && si->has_method("_update_cache")) {
- si->call("_update_cache");
+ if (GDVIRTUAL_CALL(_update_cache)) {
return;
}
_update_cache();
@@ -115,9 +109,9 @@ void SyntaxHighlighter::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_highlighting_cache"), &SyntaxHighlighter::clear_highlighting_cache);
ClassDB::bind_method(D_METHOD("get_text_edit"), &SyntaxHighlighter::get_text_edit);
- BIND_VMETHOD(MethodInfo(Variant::DICTIONARY, "_get_line_syntax_highlighting", PropertyInfo(Variant::INT, "line")));
- BIND_VMETHOD(MethodInfo("_clear_highlighting_cache"));
- BIND_VMETHOD(MethodInfo("_update_cache"));
+ GDVIRTUAL_BIND(_get_line_syntax_highlighting, "line")
+ GDVIRTUAL_BIND(_clear_highlighting_cache)
+ GDVIRTUAL_BIND(_update_cache)
}
////////////////////////////////////////////////////////////////////////////////
@@ -130,7 +124,7 @@ static bool _is_hex_symbol(char32_t c) {
return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
}
-Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) {
+Dictionary CodeHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
Dictionary color_map;
bool prev_is_char = false;
diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h
index f3964b0c8f..0fe39ccff6 100644
--- a/scene/resources/syntax_highlighter.h
+++ b/scene/resources/syntax_highlighter.h
@@ -32,6 +32,8 @@
#define SYNTAX_HIGHLIGHTER_H
#include "core/io/resource.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
class TextEdit;
@@ -48,9 +50,12 @@ protected:
static void _bind_methods();
+ GDVIRTUAL1RC(Dictionary, _get_line_syntax_highlighting, int)
+ GDVIRTUAL0(_clear_highlighting_cache)
+ GDVIRTUAL0(_update_cache)
public:
Dictionary get_line_syntax_highlighting(int p_line);
- virtual Dictionary _get_line_syntax_highlighting(int p_line) { return Dictionary(); }
+ virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) { return Dictionary(); }
void clear_highlighting_cache();
virtual void _clear_highlighting_cache() {}
@@ -93,7 +98,7 @@ protected:
static void _bind_methods();
public:
- virtual Dictionary _get_line_syntax_highlighting(int p_line) override;
+ virtual Dictionary _get_line_syntax_highlighting_impl(int p_line) override;
virtual void _clear_highlighting_cache() override;
virtual void _update_cache() override;
diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp
index 357411ae04..763033354a 100644
--- a/scene/resources/text_paragraph.cpp
+++ b/scene/resources/text_paragraph.cpp
@@ -437,7 +437,8 @@ Size2 TextParagraph::get_non_wraped_size() const {
Size2 TextParagraph::get_size() const {
const_cast<TextParagraph *>(this)->_shape_lines();
Size2 size;
- for (int i = 0; i < lines_rid.size(); i++) {
+ int visible_lines = (max_lines_visible >= 0) ? MIN(max_lines_visible, lines_rid.size()) : lines_rid.size();
+ for (int i = 0; i < visible_lines; i++) {
Size2 lsize = TS->shaped_text_get_size(lines_rid[i]);
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
size.x = MAX(size.x, lsize.x);
@@ -587,15 +588,15 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
l_width -= h_offset;
}
}
- float length = TS->shaped_text_get_width(lines_rid[i]);
+ float line_width = TS->shaped_text_get_width(lines_rid[i]);
if (width > 0) {
switch (align) {
case HALIGN_FILL:
if (TS->shaped_text_get_direction(lines_rid[i]) == TextServer::DIRECTION_RTL) {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += l_width - length;
+ ofs.x += l_width - line_width;
} else {
- ofs.y += l_width - length;
+ ofs.y += l_width - line_width;
}
}
break;
@@ -603,16 +604,16 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo
break;
case HALIGN_CENTER: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += Math::floor((l_width - length) / 2.0);
+ ofs.x += Math::floor((l_width - line_width) / 2.0);
} else {
- ofs.y += Math::floor((l_width - length) / 2.0);
+ ofs.y += Math::floor((l_width - line_width) / 2.0);
}
} break;
case HALIGN_RIGHT: {
if (TS->shaped_text_get_orientation(lines_rid[i]) == TextServer::ORIENTATION_HORIZONTAL) {
- ofs.x += l_width - length;
+ ofs.x += l_width - line_width;
} else {
- ofs.y += l_width - length;
+ ofs.y += l_width - line_width;
}
} break;
}
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4ad5f2a506..063a13efc0 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1758,11 +1758,16 @@ void GradientTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_gradient"), &GradientTexture::get_gradient);
ClassDB::bind_method(D_METHOD("set_width", "width"), &GradientTexture::set_width);
+ // The `get_width()` method is already exposed by the parent class Texture2D.
+
+ ClassDB::bind_method(D_METHOD("set_use_hdr", "enabled"), &GradientTexture::set_use_hdr);
+ ClassDB::bind_method(D_METHOD("is_using_hdr"), &GradientTexture::is_using_hdr);
ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,4096"), "set_width", "get_width");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_hdr"), "set_use_hdr", "is_using_hdr");
}
void GradientTexture::set_gradient(Ref<Gradient> p_gradient) {
@@ -1800,30 +1805,49 @@ void GradientTexture::_update() {
return;
}
- Vector<uint8_t> data;
- data.resize(width * 4);
- {
- uint8_t *wd8 = data.ptrw();
+ if (use_hdr) {
+ // High dynamic range.
+ Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBAF));
Gradient &g = **gradient;
-
+ // `create()` isn't available for non-uint8_t data, so fill in the data manually.
for (int i = 0; i < width; i++) {
float ofs = float(i) / (width - 1);
- Color color = g.get_color_at_offset(ofs);
+ image->set_pixel(i, 0, g.get_color_at_offset(ofs));
+ }
- wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
- wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
- wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
- wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(image);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_create(image);
+ }
+ } else {
+ // Low dynamic range. "Overbright" colors will be clamped.
+ Vector<uint8_t> data;
+ data.resize(width * 4);
+ {
+ uint8_t *wd8 = data.ptrw();
+ Gradient &g = **gradient;
+
+ for (int i = 0; i < width; i++) {
+ float ofs = float(i) / (width - 1);
+ Color color = g.get_color_at_offset(ofs);
+
+ wd8[i * 4 + 0] = uint8_t(CLAMP(color.r * 255.0, 0, 255));
+ wd8[i * 4 + 1] = uint8_t(CLAMP(color.g * 255.0, 0, 255));
+ wd8[i * 4 + 2] = uint8_t(CLAMP(color.b * 255.0, 0, 255));
+ wd8[i * 4 + 3] = uint8_t(CLAMP(color.a * 255.0, 0, 255));
+ }
}
- }
- Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
+ Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
- if (texture.is_valid()) {
- RID new_texture = RS::get_singleton()->texture_2d_create(image);
- RS::get_singleton()->texture_replace(texture, new_texture);
- } else {
- texture = RS::get_singleton()->texture_2d_create(image);
+ if (texture.is_valid()) {
+ RID new_texture = RS::get_singleton()->texture_2d_create(image);
+ RS::get_singleton()->texture_replace(texture, new_texture);
+ } else {
+ texture = RS::get_singleton()->texture_2d_create(image);
+ }
}
emit_changed();
@@ -1839,6 +1863,19 @@ int GradientTexture::get_width() const {
return width;
}
+void GradientTexture::set_use_hdr(bool p_enabled) {
+ if (p_enabled == use_hdr) {
+ return;
+ }
+
+ use_hdr = p_enabled;
+ _queue_update();
+}
+
+bool GradientTexture::is_using_hdr() const {
+ return use_hdr;
+}
+
Ref<Image> GradientTexture::get_image() const {
if (!texture.is_valid()) {
return Ref<Image>();
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index 2e97c2deb1..f6b991c335 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -686,6 +686,7 @@ private:
bool update_pending = false;
RID texture;
int width = 2048;
+ bool use_hdr = false;
void _queue_update();
void _update();
@@ -700,6 +701,9 @@ public:
void set_width(int p_width);
int get_width() const override;
+ void set_use_hdr(bool p_enabled);
+ bool is_using_hdr() const;
+
virtual RID get_rid() const override { return texture; }
virtual int get_height() const override { return 1; }
virtual bool has_alpha() const override { return true; }
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index b00dcca004..a7f99a2113 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -261,54 +261,47 @@ VisualShaderNode::VisualShaderNode() {
/////////////////////////////////////////////////////////
void VisualShaderNodeCustom::update_ports() {
- ERR_FAIL_COND(!get_script_instance());
+ {
+ input_ports.clear();
+ int input_port_count;
+ if (GDVIRTUAL_CALL(_get_input_port_count, input_port_count)) {
+ for (int i = 0; i < input_port_count; i++) {
+ Port port;
+ if (!GDVIRTUAL_CALL(_get_input_port_name, i, port.name)) {
+ port.name = "in" + itos(i);
+ }
+ if (!GDVIRTUAL_CALL(_get_input_port_type, i, port.type)) {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
- input_ports.clear();
- if (get_script_instance()->has_method("_get_input_port_count")) {
- int input_port_count = (int)get_script_instance()->call("_get_input_port_count");
- bool has_name = get_script_instance()->has_method("_get_input_port_name");
- bool has_type = get_script_instance()->has_method("_get_input_port_type");
- for (int i = 0; i < input_port_count; i++) {
- Port port;
- if (has_name) {
- port.name = (String)get_script_instance()->call("_get_input_port_name", i);
- } else {
- port.name = "in" + itos(i);
+ input_ports.push_back(port);
}
- if (has_type) {
- port.type = (int)get_script_instance()->call("_get_input_port_type", i);
- } else {
- port.type = (int)PortType::PORT_TYPE_SCALAR;
- }
- input_ports.push_back(port);
}
}
- output_ports.clear();
- if (get_script_instance()->has_method("_get_output_port_count")) {
- int output_port_count = (int)get_script_instance()->call("_get_output_port_count");
- bool has_name = get_script_instance()->has_method("_get_output_port_name");
- bool has_type = get_script_instance()->has_method("_get_output_port_type");
- for (int i = 0; i < output_port_count; i++) {
- Port port;
- if (has_name) {
- port.name = (String)get_script_instance()->call("_get_output_port_name", i);
- } else {
- port.name = "out" + itos(i);
- }
- if (has_type) {
- port.type = (int)get_script_instance()->call("_get_output_port_type", i);
- } else {
- port.type = (int)PortType::PORT_TYPE_SCALAR;
+
+ {
+ output_ports.clear();
+ int output_port_count;
+ if (GDVIRTUAL_CALL(_get_output_port_count, output_port_count)) {
+ for (int i = 0; i < output_port_count; i++) {
+ Port port;
+ if (!GDVIRTUAL_CALL(_get_output_port_name, i, port.name)) {
+ port.name = "out" + itos(i);
+ }
+ if (!GDVIRTUAL_CALL(_get_output_port_type, i, port.type)) {
+ port.type = (int)PortType::PORT_TYPE_SCALAR;
+ }
+
+ output_ports.push_back(port);
}
- output_ports.push_back(port);
}
}
}
String VisualShaderNodeCustom::get_caption() const {
- ERR_FAIL_COND_V(!get_script_instance(), "");
- if (get_script_instance()->has_method("_get_name")) {
- return (String)get_script_instance()->call("_get_name");
+ String ret;
+ if (GDVIRTUAL_CALL(_get_name, ret)) {
+ return ret;
}
return "Unnamed";
}
@@ -342,9 +335,8 @@ String VisualShaderNodeCustom::get_output_port_name(int p_port) const {
}
String VisualShaderNodeCustom::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 {
- ERR_FAIL_COND_V(!get_script_instance(), "");
- ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), "");
- Array input_vars;
+ ERR_FAIL_COND_V(!GDVIRTUAL_IS_OVERRIDEN(_get_code), "");
+ Vector<String> input_vars;
for (int i = 0; i < get_input_port_count(); i++) {
input_vars.push_back(p_input_vars[i]);
}
@@ -353,7 +345,8 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::
output_vars.push_back(p_output_vars[i]);
}
String code = " {\n";
- String _code = (String)get_script_instance()->call("_get_code", input_vars, output_vars, (int)p_mode, (int)p_type);
+ String _code;
+ GDVIRTUAL_CALL(_get_code, input_vars, output_vars, (int)p_mode, (int)p_type, _code);
bool nend = _code.ends_with("\n");
_code = _code.insert(0, " ");
_code = _code.replace("\n", "\n ");
@@ -369,10 +362,10 @@ String VisualShaderNodeCustom::generate_code(Shader::Mode p_mode, VisualShader::
}
String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
- ERR_FAIL_COND_V(!get_script_instance(), "");
- if (get_script_instance()->has_method("_get_global_code")) {
+ String ret;
+ if (GDVIRTUAL_CALL(_get_global_code, (int)p_mode, ret)) {
String code = "// " + get_caption() + "\n";
- code += (String)get_script_instance()->call("_get_global_code", (int)p_mode);
+ code += ret;
code += "\n";
return code;
}
@@ -416,19 +409,19 @@ void VisualShaderNodeCustom::_set_initialized(bool p_enabled) {
}
void VisualShaderNodeCustom::_bind_methods() {
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description"));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_input_port_name", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count"));
- BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING_NAME, "_get_output_port_name", PropertyInfo(Variant::INT, "port")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type")));
- BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode")));
- BIND_VMETHOD(MethodInfo(Variant::BOOL, "_is_highend"));
+ GDVIRTUAL_BIND(_get_name);
+ GDVIRTUAL_BIND(_get_description);
+ GDVIRTUAL_BIND(_get_category);
+ GDVIRTUAL_BIND(_get_return_icon_type);
+ GDVIRTUAL_BIND(_get_input_port_count);
+ GDVIRTUAL_BIND(_get_input_port_type, "port");
+ GDVIRTUAL_BIND(_get_input_port_name, "port");
+ GDVIRTUAL_BIND(_get_output_port_count);
+ GDVIRTUAL_BIND(_get_output_port_type, "port");
+ GDVIRTUAL_BIND(_get_output_port_name, "port");
+ GDVIRTUAL_BIND(_get_code, "input_vars", "output_vars", "mode", "type");
+ GDVIRTUAL_BIND(_get_global_code, "mode");
+ GDVIRTUAL_BIND(_is_highend);
ClassDB::bind_method(D_METHOD("_set_initialized", "enabled"), &VisualShaderNodeCustom::_set_initialized);
ClassDB::bind_method(D_METHOD("_is_initialized"), &VisualShaderNodeCustom::_is_initialized);
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 31651318ae..b3efac02aa 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -314,6 +314,20 @@ protected:
virtual void remove_input_port_default_value(int p_port) override;
virtual void clear_default_input_values() override;
+ GDVIRTUAL0RC(String, _get_name)
+ GDVIRTUAL0RC(String, _get_description)
+ GDVIRTUAL0RC(String, _get_category)
+ GDVIRTUAL0RC(int, _get_return_icon_type)
+ GDVIRTUAL0RC(int, _get_input_port_count)
+ GDVIRTUAL1RC(int, _get_input_port_type, int)
+ GDVIRTUAL1RC(String, _get_input_port_name, int)
+ GDVIRTUAL0RC(int, _get_output_port_count)
+ GDVIRTUAL1RC(int, _get_output_port_type, int)
+ GDVIRTUAL1RC(String, _get_output_port_name, int)
+ GDVIRTUAL4RC(String, _get_code, Vector<String>, TypedArray<String>, int, int)
+ GDVIRTUAL1RC(String, _get_global_code, int)
+ GDVIRTUAL0RC(bool, _is_highend)
+
protected:
void _set_input_port_default_value(int p_port, const Variant &p_value);
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index f3fa857682..5544a09ac0 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -33,6 +33,63 @@
#include "core/config/project_settings.h"
#include "core/os/os.h"
+void AudioStreamPlayback::start(float p_from_pos) {
+ if (GDVIRTUAL_CALL(_start, p_from_pos)) {
+ return;
+ }
+ ERR_FAIL_MSG("AudioStreamPlayback::start unimplemented!");
+}
+void AudioStreamPlayback::stop() {
+ if (GDVIRTUAL_CALL(_stop)) {
+ return;
+ }
+ ERR_FAIL_MSG("AudioStreamPlayback::stop unimplemented!");
+}
+bool AudioStreamPlayback::is_playing() const {
+ bool ret;
+ if (GDVIRTUAL_CALL(_is_playing, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(false, "AudioStreamPlayback::is_playing unimplemented!");
+}
+
+int AudioStreamPlayback::get_loop_count() const {
+ int ret;
+ if (GDVIRTUAL_CALL(_get_loop_count, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
+float AudioStreamPlayback::get_playback_position() const {
+ float ret;
+ if (GDVIRTUAL_CALL(_get_playback_position, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(0, "AudioStreamPlayback::get_playback_position unimplemented!");
+}
+void AudioStreamPlayback::seek(float p_time) {
+ if (GDVIRTUAL_CALL(_seek, p_time)) {
+ return;
+ }
+}
+
+void AudioStreamPlayback::mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) {
+ if (GDVIRTUAL_CALL(_mix, p_buffer, p_rate_scale, p_frames)) {
+ return;
+ }
+ WARN_PRINT_ONCE("AudioStreamPlayback::mix unimplemented!");
+}
+
+void AudioStreamPlayback::_bind_methods() {
+ GDVIRTUAL_BIND(_start, "from_pos")
+ GDVIRTUAL_BIND(_stop)
+ GDVIRTUAL_BIND(_is_playing)
+ GDVIRTUAL_BIND(_get_loop_count)
+ GDVIRTUAL_BIND(_get_playback_position)
+ GDVIRTUAL_BIND(_seek, "position")
+ GDVIRTUAL_BIND(_mix, "buffer", "rate_scale", "frames");
+}
//////////////////////////////
void AudioStreamPlaybackResampled::_begin_resample() {
@@ -92,8 +149,34 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
////////////////////////////////
+Ref<AudioStreamPlayback> AudioStream::instance_playback() {
+ Ref<AudioStreamPlayback> ret;
+ if (GDVIRTUAL_CALL(_instance_playback, ret)) {
+ return ret;
+ }
+ ERR_FAIL_V_MSG(Ref<AudioStreamPlayback>(), "Method must be implemented!");
+}
+String AudioStream::get_stream_name() const {
+ String ret;
+ if (GDVIRTUAL_CALL(_get_stream_name, ret)) {
+ return ret;
+ }
+ return String();
+}
+
+float AudioStream::get_length() const {
+ float ret;
+ if (GDVIRTUAL_CALL(_get_length, ret)) {
+ return ret;
+ }
+ return 0;
+}
+
void AudioStream::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_length"), &AudioStream::get_length);
+ GDVIRTUAL_BIND(_instance_playback);
+ GDVIRTUAL_BIND(_get_stream_name);
+ GDVIRTUAL_BIND(_get_length);
}
////////////////////////////////
@@ -358,3 +441,4 @@ void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_buffer, float p_rate_scal
AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
random_pitch->playbacks.erase(this);
}
+/////////////////////////////////////////////
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 0d426f99b2..25f0017211 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -36,20 +36,33 @@
#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
+#include "core/object/gdvirtual.gen.inc"
+#include "core/object/script_language.h"
+#include "core/variant/native_ptr.h"
+
class AudioStreamPlayback : public RefCounted {
GDCLASS(AudioStreamPlayback, RefCounted);
+protected:
+ static void _bind_methods();
+ GDVIRTUAL1(_start, float)
+ GDVIRTUAL0(_stop)
+ GDVIRTUAL0RC(bool, _is_playing)
+ GDVIRTUAL0RC(int, _get_loop_count)
+ GDVIRTUAL0RC(float, _get_playback_position)
+ GDVIRTUAL1(_seek, float)
+ GDVIRTUAL3(_mix, GDNativePtr<AudioFrame>, float, int)
public:
- virtual void start(float p_from_pos = 0.0) = 0;
- virtual void stop() = 0;
- virtual bool is_playing() const = 0;
+ virtual void start(float p_from_pos = 0.0);
+ virtual void stop();
+ virtual bool is_playing() const;
- virtual int get_loop_count() const = 0; //times it looped
+ virtual int get_loop_count() const; //times it looped
- virtual float get_playback_position() const = 0;
- virtual void seek(float p_time) = 0;
+ virtual float get_playback_position() const;
+ virtual void seek(float p_time);
- virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames) = 0;
+ virtual void mix(AudioFrame *p_buffer, float p_rate_scale, int p_frames);
};
class AudioStreamPlaybackResampled : public AudioStreamPlayback {
@@ -84,11 +97,15 @@ class AudioStream : public Resource {
protected:
static void _bind_methods();
+ GDVIRTUAL0RC(Ref<AudioStreamPlayback>, _instance_playback)
+ GDVIRTUAL0RC(String, _get_stream_name)
+ GDVIRTUAL0RC(float, _get_length)
+
public:
- virtual Ref<AudioStreamPlayback> instance_playback() = 0;
- virtual String get_stream_name() const = 0;
+ virtual Ref<AudioStreamPlayback> instance_playback();
+ virtual String get_stream_name() const;
- virtual float get_length() const = 0; //if supported, otherwise return 0
+ virtual float get_length() const;
};
// Microphone
diff --git a/servers/audio/effects/audio_effect_pitch_shift.cpp b/servers/audio/effects/audio_effect_pitch_shift.cpp
index bfbaeee3f3..d6c396e0a5 100644
--- a/servers/audio/effects/audio_effect_pitch_shift.cpp
+++ b/servers/audio/effects/audio_effect_pitch_shift.cpp
@@ -40,7 +40,7 @@
*
* NAME: smbPitchShift.cpp
* VERSION: 1.2
-* HOME URL: http://blogs.zynaptiq.com/bernsee
+* HOME URL: https://blogs.zynaptiq.com/bernsee
* KNOWN BUGS: none
*
* SYNOPSIS: Routine for doing pitch shifting while maintaining
diff --git a/servers/physics_3d/area_3d_sw.cpp b/servers/physics_3d/area_3d_sw.cpp
index 364f63e4ad..c292abad48 100644
--- a/servers/physics_3d/area_3d_sw.cpp
+++ b/servers/physics_3d/area_3d_sw.cpp
@@ -163,6 +163,20 @@ void Area3DSW::set_param(PhysicsServer3D::AreaParameter p_param, const Variant &
case PhysicsServer3D::AREA_PARAM_PRIORITY:
priority = p_value;
break;
+ case PhysicsServer3D::AREA_PARAM_WIND_FORCE_MAGNITUDE:
+ ERR_FAIL_COND_MSG(wind_force_magnitude < 0, "Wind force magnitude must be a non-negative real number, but a negative number was specified.");
+ wind_force_magnitude = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_WIND_SOURCE:
+ wind_source = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_WIND_DIRECTION:
+ wind_direction = p_value;
+ break;
+ case PhysicsServer3D::AREA_PARAM_WIND_ATTENUATION_FACTOR:
+ ERR_FAIL_COND_MSG(wind_attenuation_factor < 0, "Wind attenuation factor must be a non-negative real number, but a negative number was specified.");
+ wind_attenuation_factor = p_value;
+ break;
}
}
@@ -184,6 +198,14 @@ Variant Area3DSW::get_param(PhysicsServer3D::AreaParameter p_param) const {
return angular_damp;
case PhysicsServer3D::AREA_PARAM_PRIORITY:
return priority;
+ case PhysicsServer3D::AREA_PARAM_WIND_FORCE_MAGNITUDE:
+ return wind_force_magnitude;
+ case PhysicsServer3D::AREA_PARAM_WIND_SOURCE:
+ return wind_source;
+ case PhysicsServer3D::AREA_PARAM_WIND_DIRECTION:
+ return wind_direction;
+ case PhysicsServer3D::AREA_PARAM_WIND_ATTENUATION_FACTOR:
+ return wind_attenuation_factor;
}
return Variant();
diff --git a/servers/physics_3d/area_3d_sw.h b/servers/physics_3d/area_3d_sw.h
index 5959ee1e95..814472885c 100644
--- a/servers/physics_3d/area_3d_sw.h
+++ b/servers/physics_3d/area_3d_sw.h
@@ -50,6 +50,10 @@ class Area3DSW : public CollisionObject3DSW {
real_t point_attenuation;
real_t linear_damp;
real_t angular_damp;
+ real_t wind_force_magnitude = 0.0;
+ real_t wind_attenuation_factor = 0.0;
+ Vector3 wind_source;
+ Vector3 wind_direction;
int priority;
bool monitorable;
@@ -154,6 +158,18 @@ public:
_FORCE_INLINE_ void set_priority(int p_priority) { priority = p_priority; }
_FORCE_INLINE_ int get_priority() const { return priority; }
+ _FORCE_INLINE_ void set_wind_force_magnitude(real_t p_wind_force_magnitude) { wind_force_magnitude = p_wind_force_magnitude; }
+ _FORCE_INLINE_ real_t get_wind_force_magnitude() const { return wind_force_magnitude; }
+
+ _FORCE_INLINE_ void set_wind_attenuation_factor(real_t p_wind_attenuation_factor) { wind_attenuation_factor = p_wind_attenuation_factor; }
+ _FORCE_INLINE_ real_t get_wind_attenuation_factor() const { return wind_attenuation_factor; }
+
+ _FORCE_INLINE_ void set_wind_source(const Vector3 &p_wind_source) { wind_source = p_wind_source; }
+ _FORCE_INLINE_ const Vector3 &get_wind_source() const { return wind_source; }
+
+ _FORCE_INLINE_ void set_wind_direction(const Vector3 &p_wind_direction) { wind_direction = p_wind_direction; }
+ _FORCE_INLINE_ const Vector3 &get_wind_direction() const { return wind_direction; }
+
_FORCE_INLINE_ void add_constraint(Constraint3DSW *p_constraint) { constraints.insert(p_constraint); }
_FORCE_INLINE_ void remove_constraint(Constraint3DSW *p_constraint) { constraints.erase(p_constraint); }
_FORCE_INLINE_ const Set<Constraint3DSW *> &get_constraints() const { return constraints; }
diff --git a/servers/physics_3d/gjk_epa.cpp b/servers/physics_3d/gjk_epa.cpp
index 2df991563d..f2f712193a 100644
--- a/servers/physics_3d/gjk_epa.cpp
+++ b/servers/physics_3d/gjk_epa.cpp
@@ -37,7 +37,7 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2008 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
index 56aba24b42..d2b64ce6e3 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.cpp
@@ -34,7 +34,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
index d0f3dbbd35..c2a0443aff 100644
--- a/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
+++ b/servers/physics_3d/joints/generic_6dof_joint_3d_sw.h
@@ -40,7 +40,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
index b928f18231..e2bf2845fe 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.cpp
@@ -34,7 +34,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/hinge_joint_3d_sw.h b/servers/physics_3d/joints/hinge_joint_3d_sw.h
index 22eb2f4660..572c35266f 100644
--- a/servers/physics_3d/joints/hinge_joint_3d_sw.h
+++ b/servers/physics_3d/joints/hinge_joint_3d_sw.h
@@ -40,7 +40,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/jacobian_entry_3d_sw.h b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
index 6afa70c816..30c80db23f 100644
--- a/servers/physics_3d/joints/jacobian_entry_3d_sw.h
+++ b/servers/physics_3d/joints/jacobian_entry_3d_sw.h
@@ -37,7 +37,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.cpp b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
index 8eb84d1c2f..7a713c1161 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.cpp
@@ -34,7 +34,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/pin_joint_3d_sw.h b/servers/physics_3d/joints/pin_joint_3d_sw.h
index 3d91452850..09deefc5c4 100644
--- a/servers/physics_3d/joints/pin_joint_3d_sw.h
+++ b/servers/physics_3d/joints/pin_joint_3d_sw.h
@@ -40,7 +40,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.cpp b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
index 1895fe1e2e..9f01196c30 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.cpp
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.cpp
@@ -34,7 +34,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/joints/slider_joint_3d_sw.h b/servers/physics_3d/joints/slider_joint_3d_sw.h
index f357bbd67a..f09476f570 100644
--- a/servers/physics_3d/joints/slider_joint_3d_sw.h
+++ b/servers/physics_3d/joints/slider_joint_3d_sw.h
@@ -40,7 +40,7 @@ Adapted to Godot from the Bullet library.
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/shape_3d_sw.cpp b/servers/physics_3d/shape_3d_sw.cpp
index a84405de81..664308ed7b 100644
--- a/servers/physics_3d/shape_3d_sw.cpp
+++ b/servers/physics_3d/shape_3d_sw.cpp
@@ -39,7 +39,7 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2009 Erwin Coumans http://bulletphysics.org
+Copyright (c) 2003-2009 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
diff --git a/servers/physics_3d/soft_body_3d_sw.cpp b/servers/physics_3d/soft_body_3d_sw.cpp
index 73b81444e1..ead6497f1f 100644
--- a/servers/physics_3d/soft_body_3d_sw.cpp
+++ b/servers/physics_3d/soft_body_3d_sw.cpp
@@ -38,7 +38,7 @@
/*
Bullet Continuous Collision Detection and Physics Library
-Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+Copyright (c) 2003-2006 Erwin Coumans https://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
@@ -165,7 +165,7 @@ void SoftBody3DSW::update_rendering_server(RenderingServerHandler *p_rendering_s
p_rendering_server_handler->set_aabb(bounds);
}
-void SoftBody3DSW::update_normals() {
+void SoftBody3DSW::update_normals_and_centroids() {
uint32_t i, ni;
for (i = 0, ni = nodes.size(); i < ni; ++i) {
@@ -180,6 +180,7 @@ void SoftBody3DSW::update_normals() {
face.n[2]->n += n;
face.normal = n;
face.normal.normalize();
+ face.centroid = 0.33333333333 * (face.n[0]->x + face.n[1]->x + face.n[2]->x);
}
for (i = 0, ni = nodes.size(); i < ni; ++i) {
@@ -310,7 +311,7 @@ void SoftBody3DSW::apply_nodes_transform(const Transform3D &p_transform) {
face_tree.clear();
- update_normals();
+ update_normals_and_centroids();
update_bounds();
update_constants();
}
@@ -574,7 +575,7 @@ bool SoftBody3DSW::create_from_trimesh(const Vector<int> &p_indices, const Vecto
reoptimize_link_order();
update_constants();
- update_normals();
+ update_normals_and_centroids();
update_bounds();
return true;
@@ -898,32 +899,66 @@ void SoftBody3DSW::add_velocity(const Vector3 &p_velocity) {
}
}
-void SoftBody3DSW::apply_forces() {
- if (pressure_coefficient < CMP_EPSILON) {
- return;
- }
+void SoftBody3DSW::apply_forces(bool p_has_wind_forces) {
+ int ac = areas.size();
if (nodes.is_empty()) {
return;
}
uint32_t i, ni;
+ int32_t j;
- // Calculate volume.
real_t volume = 0.0;
const Vector3 &org = nodes[0].x;
+
+ // Iterate over faces (try not to iterate elsewhere if possible).
for (i = 0, ni = faces.size(); i < ni; ++i) {
+ bool stopped = false;
const Face &face = faces[i];
+
+ Vector3 wind_force(0, 0, 0);
+
+ // Compute volume.
volume += vec3_dot(face.n[0]->x - org, vec3_cross(face.n[1]->x - org, face.n[2]->x - org));
+
+ // Compute nodal forces from area winds.
+ if (ac && p_has_wind_forces) {
+ const AreaCMP *aa = &areas[0];
+ for (j = ac - 1; j >= 0 && !stopped; j--) {
+ PhysicsServer3D::AreaSpaceOverrideMode mode = aa[j].area->get_space_override_mode();
+ switch (mode) {
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: {
+ wind_force += _compute_area_windforce(aa[j].area, &face);
+ stopped = mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE_REPLACE;
+ } break;
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE:
+ case PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: {
+ wind_force = _compute_area_windforce(aa[j].area, &face);
+ stopped = mode == PhysicsServer3D::AREA_SPACE_OVERRIDE_REPLACE;
+ } break;
+ default: {
+ }
+ }
+ }
+
+ for (j = 0; j < 3; j++) {
+ Node *current_node = face.n[j];
+ current_node->f += wind_force;
+ }
+ }
}
volume /= 6.0;
- // Apply per node forces.
- real_t ivolumetp = 1.0 / Math::abs(volume) * pressure_coefficient;
- for (i = 0, ni = nodes.size(); i < ni; ++i) {
- Node &node = nodes[i];
- if (node.im > 0) {
- node.f += node.n * (node.area * ivolumetp);
+ // Apply nodal pressure forces.
+ if (pressure_coefficient > CMP_EPSILON) {
+ real_t ivolumetp = 1.0 / Math::abs(volume) * pressure_coefficient;
+ for (i = 0, ni = nodes.size(); i < ni; ++i) {
+ Node &node = nodes[i];
+ if (node.im > 0) {
+ node.f += node.n * (node.area * ivolumetp);
+ }
}
}
}
@@ -941,6 +976,18 @@ void SoftBody3DSW::_compute_area_gravity(const Area3DSW *p_area) {
}
}
+Vector3 SoftBody3DSW::_compute_area_windforce(const Area3DSW *p_area, const Face *p_face) {
+ real_t wfm = p_area->get_wind_force_magnitude();
+ real_t waf = p_area->get_wind_attenuation_factor();
+ const Vector3 &wd = p_area->get_wind_direction();
+ const Vector3 &ws = p_area->get_wind_source();
+ real_t projection_on_tri_normal = vec3_dot(p_face->normal, wd);
+ real_t projection_toward_centroid = vec3_dot(p_face->centroid - ws, wd);
+ real_t attenuation_over_distance = pow(projection_toward_centroid, -waf);
+ real_t nodal_force_magnitude = wfm * 0.33333333333 * p_face->ra * projection_on_tri_normal * attenuation_over_distance;
+ return nodal_force_magnitude * p_face->normal;
+}
+
void SoftBody3DSW::predict_motion(real_t p_delta) {
const real_t inv_delta = 1.0 / p_delta;
@@ -952,11 +999,15 @@ void SoftBody3DSW::predict_motion(real_t p_delta) {
int ac = areas.size();
bool stopped = false;
+ bool has_wind_forces = false;
if (ac) {
areas.sort();
const AreaCMP *aa = &areas[0];
for (int i = ac - 1; i >= 0 && !stopped; i--) {
+ // Avoids unnecessary loop in apply_forces().
+ has_wind_forces = has_wind_forces || aa[i].area->get_wind_force_magnitude() > CMP_EPSILON;
+
PhysicsServer3D::AreaSpaceOverrideMode mode = aa[i].area->get_space_override_mode();
switch (mode) {
case PhysicsServer3D::AREA_SPACE_OVERRIDE_COMBINE:
@@ -978,7 +1029,9 @@ void SoftBody3DSW::predict_motion(real_t p_delta) {
// Apply forces.
add_velocity(gravity * p_delta);
- apply_forces();
+ if (pressure_coefficient > CMP_EPSILON || has_wind_forces) {
+ apply_forces(has_wind_forces);
+ }
// Avoid soft body from 'exploding' so use some upper threshold of maximum motion
// that a node can travel per frame.
@@ -1057,7 +1110,7 @@ void SoftBody3DSW::solve_constraints(real_t p_delta) {
node.q = node.x;
}
- update_normals();
+ update_normals_and_centroids();
}
void SoftBody3DSW::solve_links(real_t kst, real_t ti) {
diff --git a/servers/physics_3d/soft_body_3d_sw.h b/servers/physics_3d/soft_body_3d_sw.h
index be0620c506..58fd234fde 100644
--- a/servers/physics_3d/soft_body_3d_sw.h
+++ b/servers/physics_3d/soft_body_3d_sw.h
@@ -71,6 +71,7 @@ class SoftBody3DSW : public CollisionObject3DSW {
};
struct Face {
+ Vector3 centroid;
Node *n[3] = { nullptr, nullptr, nullptr }; // Node pointers
Vector3 normal; // Normal
real_t ra = 0.0; // Rest area
@@ -114,6 +115,7 @@ class SoftBody3DSW : public CollisionObject3DSW {
uint64_t island_step = 0;
_FORCE_INLINE_ void _compute_area_gravity(const Area3DSW *p_area);
+ _FORCE_INLINE_ Vector3 _compute_area_windforce(const Area3DSW *p_area, const Face *p_face);
public:
SoftBody3DSW();
@@ -220,7 +222,7 @@ protected:
virtual void _shapes_changed();
private:
- void update_normals();
+ void update_normals_and_centroids();
void update_bounds();
void update_constants();
void update_area();
@@ -231,7 +233,7 @@ private:
void add_velocity(const Vector3 &p_velocity);
- void apply_forces();
+ void apply_forces(bool p_has_wind_forces);
bool create_from_trimesh(const Vector<int> &p_indices, const Vector<Vector3> &p_vertices);
void generate_bending_constraints(int p_distance);
diff --git a/servers/physics_server_3d.cpp b/servers/physics_server_3d.cpp
index 53863cea72..1f46a96b27 100644
--- a/servers/physics_server_3d.cpp
+++ b/servers/physics_server_3d.cpp
@@ -766,6 +766,10 @@ void PhysicsServer3D::_bind_methods() {
BIND_ENUM_CONSTANT(AREA_PARAM_LINEAR_DAMP);
BIND_ENUM_CONSTANT(AREA_PARAM_ANGULAR_DAMP);
BIND_ENUM_CONSTANT(AREA_PARAM_PRIORITY);
+ BIND_ENUM_CONSTANT(AREA_PARAM_WIND_FORCE_MAGNITUDE);
+ BIND_ENUM_CONSTANT(AREA_PARAM_WIND_SOURCE);
+ BIND_ENUM_CONSTANT(AREA_PARAM_WIND_DIRECTION);
+ BIND_ENUM_CONSTANT(AREA_PARAM_WIND_ATTENUATION_FACTOR);
BIND_ENUM_CONSTANT(AREA_SPACE_OVERRIDE_DISABLED);
BIND_ENUM_CONSTANT(AREA_SPACE_OVERRIDE_COMBINE);
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index f806fd55be..5201e76498 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -298,7 +298,11 @@ public:
AREA_PARAM_GRAVITY_POINT_ATTENUATION,
AREA_PARAM_LINEAR_DAMP,
AREA_PARAM_ANGULAR_DAMP,
- AREA_PARAM_PRIORITY
+ AREA_PARAM_PRIORITY,
+ AREA_PARAM_WIND_FORCE_MAGNITUDE,
+ AREA_PARAM_WIND_SOURCE,
+ AREA_PARAM_WIND_DIRECTION,
+ AREA_PARAM_WIND_ATTENUATION_FACTOR,
};
virtual RID area_create() = 0;
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 857f112102..8e86957d9b 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -140,8 +140,8 @@ void register_server_types() {
GDREGISTER_VIRTUAL_CLASS(XRInterface);
GDREGISTER_CLASS(XRPositionalTracker);
- GDREGISTER_VIRTUAL_CLASS(AudioStream);
- GDREGISTER_VIRTUAL_CLASS(AudioStreamPlayback);
+ GDREGISTER_CLASS(AudioStream);
+ GDREGISTER_CLASS(AudioStreamPlayback);
GDREGISTER_VIRTUAL_CLASS(AudioStreamPlaybackResampled);
GDREGISTER_CLASS(AudioStreamMicrophone);
GDREGISTER_CLASS(AudioStreamRandomPitch);
diff --git a/servers/rendering/renderer_rd/effects_rd.cpp b/servers/rendering/renderer_rd/effects_rd.cpp
index 3683622d3e..80d843227b 100644
--- a/servers/rendering/renderer_rd/effects_rd.cpp
+++ b/servers/rendering/renderer_rd/effects_rd.cpp
@@ -2171,10 +2171,8 @@ EffectsRD::EffectsRD(bool p_prefer_raster_effects) {
for (int pass = 0; pass < 4; pass++) {
for (int subPass = 0; subPass < sub_pass_count; subPass++) {
int a = pass;
- int b = subPass;
-
int spmap[5]{ 0, 1, 4, 3, 2 };
- b = spmap[subPass];
+ int b = spmap[subPass];
float ca, sa;
float angle0 = (float(a) + float(b) / float(sub_pass_count)) * Math_PI * 0.5f;
diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
index be18a73989..a24860996c 100644
--- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp
@@ -683,6 +683,8 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
default_shader = storage->shader_allocate();
storage->shader_initialize(default_shader);
storage->shader_set_code(default_shader, R"(
+// Default 3D material shader (clustered).
+
shader_type spatial;
void vertex() {
@@ -712,6 +714,8 @@ void fragment() {
storage->shader_initialize(overdraw_material_shader);
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
storage->shader_set_code(overdraw_material_shader, R"(
+// 3D editor Overdraw debug draw mode shader (clustered).
+
shader_type spatial;
render_mode blend_add, unshaded;
diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
index 735014a2ec..04ad1a2724 100644
--- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp
@@ -673,6 +673,8 @@ void SceneShaderForwardMobile::init(RendererStorageRD *p_storage, const String p
default_shader = storage->shader_allocate();
storage->shader_initialize(default_shader);
storage->shader_set_code(default_shader, R"(
+// Default 3D material shader (mobile).
+
shader_type spatial;
void vertex() {
@@ -701,6 +703,8 @@ void fragment() {
storage->shader_initialize(overdraw_material_shader);
// Use relatively low opacity so that more "layers" of overlapping objects can be distinguished.
storage->shader_set_code(overdraw_material_shader, R"(
+// 3D editor Overdraw debug draw mode shader (mobile).
+
shader_type spatial;
render_mode blend_add, unshaded;
diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
index f8aefdb29c..3af5047854 100644
--- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp
@@ -2575,6 +2575,8 @@ RendererCanvasRenderRD::RendererCanvasRenderRD(RendererStorageRD *p_storage) {
storage->shader_initialize(default_canvas_group_shader);
storage->shader_set_code(default_canvas_group_shader, R"(
+// Default CanvasGroup shader.
+
shader_type canvas_item;
void fragment() {
diff --git a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
index 9e85608f1e..4165c3f7ba 100644
--- a/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_scene_sky_rd.cpp
@@ -855,6 +855,8 @@ void RendererSceneSkyRD::init(RendererStorageRD *p_storage) {
storage->shader_initialize(sky_shader.default_shader);
storage->shader_set_code(sky_shader.default_shader, R"(
+// Default sky shader.
+
shader_type sky;
void sky() {
@@ -942,6 +944,8 @@ void sky() {
storage->shader_initialize(sky_scene_state.fog_shader);
storage->shader_set_code(sky_scene_state.fog_shader, R"(
+// Default clear color sky shader.
+
shader_type sky;
uniform vec4 clear_color;
diff --git a/servers/rendering/renderer_rd/renderer_storage_rd.cpp b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
index 8cc20618fc..14a5a01054 100644
--- a/servers/rendering/renderer_rd/renderer_storage_rd.cpp
+++ b/servers/rendering/renderer_rd/renderer_storage_rd.cpp
@@ -9398,6 +9398,8 @@ RendererStorageRD::RendererStorageRD() {
particles_shader.default_shader = shader_allocate();
shader_initialize(particles_shader.default_shader);
shader_set_code(particles_shader.default_shader, R"(
+// Default particles shader.
+
shader_type particles;
void process() {
diff --git a/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl b/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl
index 43a2a29616..a3b3938ee9 100644
--- a/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl
+++ b/servers/rendering/renderer_rd/shaders/bokeh_dof_raster.glsl
@@ -47,7 +47,7 @@ layout(set = 2, binding = 0) uniform sampler2D original_weight;
#endif
//DOF
-// Bokeh single pass implementation based on http://tuxedolabs.blogspot.com/2018/05/bokeh-depth-of-field-in-single-pass.html
+// Bokeh single pass implementation based on https://tuxedolabs.blogspot.com/2018/05/bokeh-depth-of-field-in-single-pass.html
#ifdef MODE_GEN_BLUR_SIZE
diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
index da7d189281..6d95722a57 100644
--- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl
+++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl
@@ -117,7 +117,7 @@ void main() {
uint cluster_thread_group_index;
if (!gl_HelperInvocation) {
- //http://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf
+ //https://advances.realtimerendering.com/s2017/2017_Sig_Improved_Culling_final.pdf
uvec4 mask;
diff --git a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
index 80c0ac4fb4..be12be5dec 100644
--- a/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/cubemap_roughness_inc.glsl
@@ -69,13 +69,13 @@ vec3 ImportanceSampleGGX(vec2 Xi, float Roughness, vec3 N) {
return TangentX * H.x + TangentY * H.y + N * H.z;
}
-// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float GGX(float NdotV, float a) {
float k = a / 2.0;
return NdotV / (NdotV * (1.0 - k) + k);
}
-// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
+// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
float G_Smith(float a, float nDotV, float nDotL) {
return GGX(nDotL, a * a) * GGX(nDotV, a * a);
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index adf9f20618..7a11f8904e 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -118,7 +118,7 @@ void main() {
mat3 world_normal_matrix;
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
- world_normal_matrix = inverse(mat3(world_matrix));
+ world_normal_matrix = transpose(inverse(mat3(world_matrix)));
} else {
world_normal_matrix = mat3(world_matrix);
}
@@ -881,7 +881,7 @@ void main() {
#ifdef NORMAL_USED
if (scene_data.roughness_limiter_enabled) {
- //http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
+ //https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
vec3 dndu = dFdx(normal), dndv = dFdy(normal);
float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv));
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index ef2fde7516..9fa5d3280d 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -288,7 +288,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#ifndef USE_NO_SHADOWS
// Interleaved Gradient Noise
-// http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
+// https://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare
float quick_hash(vec2 pos) {
const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);
return fract(magic.z * fract(dot(pos, magic.xy)));
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index a2a54a0511..7e2cc8fe01 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -124,7 +124,7 @@ void main() {
mat3 world_normal_matrix;
if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
- world_normal_matrix = inverse(mat3(world_matrix));
+ world_normal_matrix = transpose(inverse(mat3(world_matrix)));
} else {
world_normal_matrix = mat3(world_matrix);
}
@@ -847,7 +847,7 @@ void main() {
#ifdef NORMAL_USED
if (scene_data.roughness_limiter_enabled) {
- //http://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
+ //https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf
float roughness2 = roughness * roughness;
vec3 dndu = dFdx(normal), dndv = dFdy(normal);
float variance = scene_data.roughness_limiter_amount * (dot(dndu, dndu) + dot(dndv, dndv));
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
index 0eacbc5363..4290d5b869 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_debug_probes.glsl
@@ -24,7 +24,7 @@ layout(push_constant, binding = 0, std430) uniform Params {
}
params;
-// http://in4k.untergrund.net/html_articles/hugi_27_-_coding_corner_polaris_sphere_tessellation_101.htm
+// https://in4k.untergrund.net/html_articles/hugi_27_-_coding_corner_polaris_sphere_tessellation_101.htm
vec3 get_sphere_vertex(uint p_vertex_id) {
float x_angle = float(p_vertex_id & 1u) + (p_vertex_id >> params.band_power);
diff --git a/servers/rendering/renderer_rd/shaders/tonemap.glsl b/servers/rendering/renderer_rd/shaders/tonemap.glsl
index 3c685c25b9..f997101183 100644
--- a/servers/rendering/renderer_rd/shaders/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/tonemap.glsl
@@ -37,15 +37,15 @@ layout(location = 0) in vec2 uv_interp;
#ifdef SUBPASS
layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput input_color;
-#else
-#if MULTIVIEW
+#elif defined(MULTIVIEW)
layout(set = 0, binding = 0) uniform sampler2DArray source_color;
#else
layout(set = 0, binding = 0) uniform sampler2D source_color;
#endif
-#endif
+
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
layout(set = 2, binding = 0) uniform sampler2D source_glow;
+
#ifdef USE_1D_LUT
layout(set = 3, binding = 0) uniform sampler2D source_color_correction;
#else
@@ -349,7 +349,7 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
}
#endif // !SUBPASS
-// From http://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
+// From https://alex.vlachos.com/graphics/Alex_Vlachos_Advanced_VR_Rendering_GDC2015.pdf
// and https://www.shadertoy.com/view/MslGR8 (5th one starting from the bottom)
// NOTE: `frag_coord` is in pixels (i.e. not normalized UV).
vec3 screen_space_dither(vec2 frag_coord) {
@@ -365,7 +365,7 @@ void main() {
#ifdef SUBPASS
// SUBPASS and MULTIVIEW can be combined but in that case we're already reading from the correct layer
vec3 color = subpassLoad(input_color).rgb;
-#elif MULTIVIEW
+#elif defined(MULTIVIEW)
vec3 color = textureLod(source_color, vec3(uv_interp, ViewIndex), 0.0f).rgb;
#else
vec3 color = textureLod(source_color, uv_interp, 0.0f).rgb;
diff --git a/servers/text_server.cpp b/servers/text_server.cpp
index 6bace8cf9e..e51e229418 100644
--- a/servers/text_server.cpp
+++ b/servers/text_server.cpp
@@ -665,9 +665,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
continue;
}
if (l_gl[i].count > 0) {
- //Ignore trailing spaces.
- bool is_space = (l_gl[i].flags & GRAPHEME_IS_SPACE) == GRAPHEME_IS_SPACE;
- if ((p_width > 0) && (width + (is_space ? 0 : l_gl[i].advance) > p_width) && (last_safe_break >= 0)) {
+ if ((p_width > 0) && (width + l_gl[i].advance * l_gl[i].repeat > p_width) && (last_safe_break >= 0)) {
lines.push_back(Vector2i(line_start, l_gl[last_safe_break].end));
line_start = l_gl[last_safe_break].end;
i = last_safe_break;
@@ -698,7 +696,7 @@ Vector<Vector2i> TextServer::shaped_text_get_line_breaks(RID p_shaped, float p_w
last_safe_break = i;
}
}
- width += l_gl[i].advance;
+ width += l_gl[i].advance * l_gl[i].repeat;
}
if (l_size > 0) {
diff --git a/tests/test_curve.h b/tests/test_curve.h
index 7eeee86f32..e079905e35 100644
--- a/tests/test_curve.h
+++ b/tests/test_curve.h
@@ -216,6 +216,41 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
Math::is_equal_approx(curve->interpolate_baked(0.7), (real_t)0.8),
"Custom free curve should return the expected baked value at offset 0.7 after removing point at invalid index 10.");
}
+
+TEST_CASE("[Curve2D] Linear sampling should return exact value") {
+ Ref<Curve2D> curve = memnew(Curve2D);
+ int len = 2048;
+
+ curve->add_point(Vector2(0, 0));
+ curve->add_point(Vector2((float)len, 0));
+
+ float baked_length = curve->get_baked_length();
+ CHECK((float)len == baked_length);
+
+ for (int i = 0; i < len; i++) {
+ float expected = (float)i;
+ Vector2 pos = curve->interpolate_baked(expected);
+ CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ }
+}
+
+TEST_CASE("[Curve3D] Linear sampling should return exact value") {
+ Ref<Curve3D> curve = memnew(Curve3D);
+ int len = 2048;
+
+ curve->add_point(Vector3(0, 0, 0));
+ curve->add_point(Vector3((float)len, 0, 0));
+
+ float baked_length = curve->get_baked_length();
+ CHECK((float)len == baked_length);
+
+ for (int i = 0; i < len; i++) {
+ float expected = (float)i;
+ Vector3 pos = curve->interpolate_baked(expected);
+ CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ }
+}
+
} // namespace TestCurve
#endif // TEST_CURVE_H