summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes1
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--core/class_db.cpp19
-rw-r--r--core/class_db.h1
-rw-r--r--core/image.cpp1
-rw-r--r--core/io/file_access_encrypted.cpp4
-rw-r--r--core/io/logger.cpp6
-rw-r--r--core/make_binders.py2
-rw-r--r--core/os/input.cpp1
-rw-r--r--core/project_settings.cpp53
-rw-r--r--core/project_settings.h2
-rw-r--r--core/script_debugger_remote.cpp12
-rw-r--r--core/variant.h8
-rw-r--r--core/variant_op.cpp8
-rw-r--r--doc/Makefile2
-rw-r--r--doc/classes/ARVRInterface.xml2
-rw-r--r--doc/classes/ARVRScriptInterface.xml118
-rw-r--r--doc/classes/ARVRServer.xml8
-rw-r--r--doc/classes/AnimationPlayer.xml6
-rw-r--r--doc/classes/AnimationTreePlayer.xml2
-rw-r--r--doc/classes/Array.xml6
-rw-r--r--doc/classes/AudioEffectDistortion.xml2
-rw-r--r--doc/classes/AudioEffectReverb.xml2
-rw-r--r--doc/classes/AudioServer.xml2
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml8
-rw-r--r--doc/classes/BitmapFont.xml31
-rw-r--r--doc/classes/Camera.xml2
-rw-r--r--doc/classes/CheckBox.xml2
-rw-r--r--doc/classes/ColorPicker.xml2
-rw-r--r--doc/classes/ColorPickerButton.xml2
-rw-r--r--doc/classes/ConeTwistJoint.xml25
-rw-r--r--doc/classes/ConfigFile.xml31
-rw-r--r--doc/classes/Control.xml33
-rw-r--r--doc/classes/Curve.xml2
-rw-r--r--doc/classes/DynamicFont.xml28
-rw-r--r--doc/classes/DynamicFontData.xml5
-rw-r--r--doc/classes/EditorImportPlugin.xml2
-rw-r--r--doc/classes/EditorInterface.xml22
-rw-r--r--doc/classes/EditorResourcePreview.xml2
-rw-r--r--doc/classes/EditorScript.xml16
-rw-r--r--doc/classes/EditorSelection.xml2
-rw-r--r--doc/classes/EditorSettings.xml52
-rw-r--r--doc/classes/EditorSpatialGizmo.xml2
-rw-r--r--doc/classes/Environment.xml10
-rw-r--r--doc/classes/FileDialog.xml6
-rw-r--r--doc/classes/Generic6DOFJoint.xml73
-rw-r--r--doc/classes/HSlider.xml2
-rw-r--r--doc/classes/HTTPRequest.xml2
-rw-r--r--doc/classes/HingeJoint.xml22
-rw-r--r--doc/classes/Input.xml30
-rw-r--r--doc/classes/ItemList.xml4
-rw-r--r--doc/classes/JSONParseResult.xml2
-rw-r--r--doc/classes/Joint.xml6
-rw-r--r--doc/classes/KinematicBody2D.xml2
-rw-r--r--doc/classes/NinePatchRect.xml2
-rw-r--r--doc/classes/Node.xml97
-rw-r--r--doc/classes/OS.xml16
-rw-r--r--doc/classes/Object.xml4
-rw-r--r--doc/classes/Particles2D.xml12
-rw-r--r--doc/classes/Performance.xml4
-rw-r--r--doc/classes/Physics2DServer.xml178
-rw-r--r--doc/classes/Physics2DServerSW.xml2
-rw-r--r--doc/classes/Physics2DShapeQueryParameters.xml2
-rw-r--r--doc/classes/PhysicsServer.xml240
-rw-r--r--doc/classes/PhysicsServerSW.xml2
-rw-r--r--doc/classes/PinJoint.xml12
-rw-r--r--doc/classes/PinJoint2D.xml1
-rw-r--r--doc/classes/ProjectSettings.xml20
-rw-r--r--doc/classes/RayCast.xml9
-rw-r--r--doc/classes/RayCast2D.xml6
-rw-r--r--doc/classes/RigidBody2D.xml4
-rw-r--r--doc/classes/SceneTree.xml10
-rw-r--r--doc/classes/SliderJoint.xml50
-rw-r--r--doc/classes/Spatial.xml8
-rw-r--r--doc/classes/SpatialMaterial.xml24
-rw-r--r--doc/classes/SpatialVelocityTracker.xml4
-rw-r--r--doc/classes/SpriteBase3D.xml2
-rw-r--r--doc/classes/StyleBoxFlat.xml6
-rw-r--r--doc/classes/TabContainer.xml26
-rw-r--r--doc/classes/Timer.xml4
-rw-r--r--doc/classes/TouchScreenButton.xml31
-rw-r--r--doc/classes/Transform.xml4
-rw-r--r--doc/classes/Transform2D.xml2
-rw-r--r--doc/classes/TreeItem.xml2
-rw-r--r--doc/classes/Tween.xml14
-rw-r--r--doc/classes/VSlider.xml2
-rw-r--r--doc/classes/VehicleWheel.xml6
-rw-r--r--doc/classes/VideoPlayer.xml4
-rw-r--r--doc/classes/Viewport.xml4
-rw-r--r--doc/classes/VisibilityEnabler2D.xml8
-rw-r--r--doc/classes/VisualScript.xml2
-rw-r--r--doc/classes/VisualScriptClassConstant.xml12
-rw-r--r--doc/classes/VisualScriptConstant.xml8
-rw-r--r--doc/classes/VisualScriptEmitSignal.xml8
-rw-r--r--doc/classes/VisualScriptIterator.xml9
-rw-r--r--doc/classes/VisualScriptLocalVar.xml8
-rw-r--r--doc/classes/VisualScriptLocalVarSet.xml10
-rw-r--r--doc/classes/VisualScriptMathConstant.xml15
-rw-r--r--doc/classes/VisualScriptOperator.xml4
-rw-r--r--doc/classes/VisualScriptPreload.xml7
-rw-r--r--doc/classes/VisualScriptReturn.xml9
-rw-r--r--doc/classes/VisualScriptSelect.xml9
-rw-r--r--doc/classes/VisualScriptSelf.xml6
-rw-r--r--doc/classes/VisualScriptSequence.xml9
-rw-r--r--doc/classes/VisualScriptSwitch.xml11
-rw-r--r--doc/classes/VisualScriptVariableGet.xml7
-rw-r--r--doc/classes/VisualScriptVariableSet.xml8
-rw-r--r--doc/classes/VisualScriptWhile.xml8
-rw-r--r--doc/classes/VisualScriptYield.xml2
-rw-r--r--doc/classes/VisualServer.xml20
-rw-r--r--doc/classes/WeakRef.xml2
-rw-r--r--doc/tools/doc_status.py11
-rw-r--r--doc/tools/makerst.py20
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp71
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp3
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp1
-rw-r--r--drivers/gles3/shaders/copy.glsl24
-rw-r--r--drivers/gles3/shaders/scene.glsl79
-rw-r--r--drivers/gles3/shaders/tonemap.glsl7
-rw-r--r--drivers/unix/os_unix.cpp2
-rw-r--r--drivers/windows/dir_access_windows.cpp2
-rw-r--r--editor/animation_editor.cpp36
-rw-r--r--editor/dependency_editor.cpp154
-rw-r--r--editor/dependency_editor.h27
-rw-r--r--editor/editor_help.cpp11
-rw-r--r--editor/editor_node.cpp38
-rw-r--r--editor/editor_node.h4
-rw-r--r--editor/editor_plugin.cpp10
-rw-r--r--editor/editor_plugin.h4
-rw-r--r--editor/editor_settings.cpp3
-rw-r--r--editor/editor_themes.cpp9
-rw-r--r--editor/filesystem_dock.cpp607
-rw-r--r--editor/filesystem_dock.h41
-rw-r--r--editor/icons/icon_GUI_unchecked.svg4
-rw-r--r--editor/icons/icon_a_r_v_r_anchor.svg3
-rw-r--r--editor/icons/icon_a_r_v_r_camera.svg2
-rw-r--r--editor/icons/icon_a_r_v_r_controller.svg3
-rw-r--r--editor/icons/icon_a_r_v_r_origin.svg3
-rw-r--r--editor/icons/icon_animated_sprite.svg8
-rw-r--r--editor/icons/icon_animated_sprite_3d.svg8
-rw-r--r--editor/icons/icon_center_container.svg4
-rw-r--r--editor/icons/icon_color_pick.svg2
-rw-r--r--editor/icons/icon_color_picker.svg4
-rw-r--r--editor/icons/icon_color_picker_button.svg6
-rw-r--r--editor/icons/icon_connection_and_groups.svg5
-rw-r--r--editor/icons/icon_control_layout.svg3
-rw-r--r--editor/icons/icon_edit.svg2
-rw-r--r--editor/icons/icon_edit_key.svg5
-rw-r--r--editor/icons/icon_groups.svg4
-rw-r--r--editor/icons/icon_key_position.svg (renamed from editor/icons/icon_key_move_enabled.svg)0
-rw-r--r--editor/icons/icon_key_rotation.svg (renamed from editor/icons/icon_key_rotate_enabled.svg)0
-rw-r--r--editor/icons/icon_key_scale.svg (renamed from editor/icons/icon_key_scale_enabled.svg)0
-rw-r--r--editor/icons/icon_kinematic_body.svg2
-rw-r--r--editor/icons/icon_kinematic_body_2d.svg4
-rw-r--r--editor/icons/icon_multi_edit.svg2
-rw-r--r--editor/icons/icon_shader.svg12
-rw-r--r--editor/icons/icon_signals.svg (renamed from editor/icons/icon_connect.svg)0
-rw-r--r--editor/icons/icon_signals_and_groups.svg5
-rw-r--r--editor/icons/icon_sprite.svg4
-rw-r--r--editor/icons/icon_sprite_3d.svg4
-rw-r--r--editor/icons/icon_sprite_frames.svg4
-rw-r--r--editor/icons/icon_viewport_speed.svg4
-rw-r--r--editor/icons/icon_viewport_sprite.svg7
-rw-r--r--editor/icons/icon_viewport_zoom.svg6
-rw-r--r--editor/node_dock.cpp4
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.cpp21
-rw-r--r--editor/plugins/abstract_polygon_2d_editor.h6
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp63
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h5
-rw-r--r--[-rwxr-xr-x]editor/plugins/collision_polygon_2d_editor_plugin.cpp0
-rw-r--r--[-rwxr-xr-x]editor/plugins/collision_polygon_2d_editor_plugin.h0
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp44
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h7
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp27
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h7
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp24
-rw-r--r--editor/plugins/line_2d_editor_plugin.h37
-rw-r--r--editor/plugins/material_editor_plugin.cpp47
-rw-r--r--editor/plugins/material_editor_plugin.h8
-rw-r--r--[-rwxr-xr-x]editor/plugins/navigation_polygon_editor_plugin.cpp0
-rw-r--r--[-rwxr-xr-x]editor/plugins/navigation_polygon_editor_plugin.h0
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp19
-rw-r--r--editor/plugins/path_2d_editor_plugin.h5
-rw-r--r--[-rwxr-xr-x]editor/plugins/polygon_2d_editor_plugin.cpp0
-rw-r--r--[-rwxr-xr-x]editor/plugins/polygon_2d_editor_plugin.h0
-rw-r--r--editor/plugins/script_editor_plugin.cpp17
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp260
-rw-r--r--editor/plugins/spatial_editor_plugin.h12
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp21
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp9
-rw-r--r--editor/plugins/tile_map_editor_plugin.h4
-rw-r--r--editor/project_export.cpp12
-rw-r--r--editor/project_export.h1
-rw-r--r--editor/project_manager.cpp3
-rw-r--r--editor/project_settings_editor.cpp2
-rw-r--r--editor/property_editor.cpp4
-rw-r--r--editor/scene_tree_editor.cpp4
-rw-r--r--editor/script_editor_debugger.h6
-rw-r--r--editor/settings_config_dialog.cpp104
-rw-r--r--editor/settings_config_dialog.h5
-rw-r--r--editor/spatial_editor_gizmos.cpp4
-rw-r--r--main/SCsub2
-rw-r--r--main/main.cpp20
-rw-r--r--main/splash.pngbin29867 -> 21504 bytes
-rw-r--r--misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme10
-rw-r--r--modules/gdnative/SCsub6
-rw-r--r--modules/gdnative/config.py8
-rw-r--r--modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml26
-rw-r--r--modules/gdnative/doc_classes/GDNative.xml (renamed from doc/classes/GDNative.xml)0
-rw-r--r--modules/gdnative/doc_classes/GDNativeLibrary.xml (renamed from doc/classes/GDNativeLibrary.xml)6
-rw-r--r--modules/gdnative/doc_classes/NativeScript.xml (renamed from doc/classes/NativeScript.xml)0
-rw-r--r--modules/gdnative/gdnative.cpp65
-rw-r--r--modules/gdnative/gdnative.h12
-rw-r--r--modules/gdnative/gdnative/string.cpp4
-rw-r--r--modules/gdnative/gdnative_api.json79
-rw-r--r--modules/gdnative/include/gdnative/array.h9
-rw-r--r--modules/gdnative/include/gdnative/basis.h9
-rw-r--r--modules/gdnative/include/gdnative/color.h9
-rw-r--r--modules/gdnative/include/gdnative/dictionary.h9
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h4
-rw-r--r--modules/gdnative/include/gdnative/node_path.h9
-rw-r--r--modules/gdnative/include/gdnative/plane.h9
-rw-r--r--modules/gdnative/include/gdnative/pool_arrays.h9
-rw-r--r--modules/gdnative/include/gdnative/quat.h9
-rw-r--r--modules/gdnative/include/gdnative/rect2.h9
-rw-r--r--modules/gdnative/include/gdnative/rect3.h9
-rw-r--r--modules/gdnative/include/gdnative/rid.h9
-rw-r--r--modules/gdnative/include/gdnative/string.h9
-rw-r--r--modules/gdnative/include/gdnative/string_name.h9
-rw-r--r--modules/gdnative/include/gdnative/transform.h9
-rw-r--r--modules/gdnative/include/gdnative/transform2d.h9
-rw-r--r--modules/gdnative/include/gdnative/variant.h9
-rw-r--r--modules/gdnative/include/gdnative/vector2.h9
-rw-r--r--modules/gdnative/include/gdnative/vector3.h9
-rw-r--r--modules/gdnative/include/nativearvr/godot_nativearvr.h78
-rw-r--r--modules/gdnative/include/pluginscript/godot_pluginscript.h170
-rw-r--r--modules/gdnative/nativearvr/SCsub13
-rw-r--r--modules/gdnative/nativearvr/arvr_interface_gdnative.cpp386
-rw-r--r--modules/gdnative/nativearvr/arvr_interface_gdnative.h86
-rw-r--r--modules/gdnative/nativearvr/config.py5
-rw-r--r--modules/gdnative/nativearvr/register_types.cpp39
-rw-r--r--modules/gdnative/nativearvr/register_types.h32
-rw-r--r--modules/gdnative/nativescript/SCsub1
-rw-r--r--modules/gdnative/nativescript/api_generator.cpp2
-rw-r--r--modules/gdnative/nativescript/api_generator.h2
-rw-r--r--modules/gdnative/nativescript/nativescript.cpp51
-rw-r--r--modules/gdnative/nativescript/nativescript.h6
-rw-r--r--modules/gdnative/nativescript/register_types.cpp50
-rw-r--r--modules/gdnative/pluginscript/SCsub9
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.cpp181
-rw-r--r--modules/gdnative/pluginscript/pluginscript_instance.h90
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.cpp431
-rw-r--r--modules/gdnative/pluginscript/pluginscript_language.h131
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.cpp113
-rw-r--r--modules/gdnative/pluginscript/pluginscript_loader.h62
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.cpp454
-rw-r--r--modules/gdnative/pluginscript/pluginscript_script.h129
-rw-r--r--modules/gdnative/pluginscript/register_types.cpp118
-rw-r--r--modules/gdnative/pluginscript/register_types.h31
-rw-r--r--modules/gdnative/register_types.cpp74
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml32
-rw-r--r--modules/mobile_vr/mobile_interface.h2
-rw-r--r--modules/mono/config.py8
-rw-r--r--modules/mono/csharp_script.cpp187
-rw-r--r--modules/mono/csharp_script.h4
-rw-r--r--modules/mono/editor/bindings_generator.cpp34
-rw-r--r--modules/mono/glue/cs_files/ExportAttribute.cs4
-rw-r--r--modules/mono/godotsharp_dirs.cpp21
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp32
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h6
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp16
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp8
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h8
-rw-r--r--modules/mono/signal_awaiter_utils.cpp77
-rw-r--r--modules/mono/signal_awaiter_utils.h19
-rw-r--r--modules/mono/utils/string_utils.cpp29
-rw-r--r--modules/mono/utils/string_utils.h6
-rw-r--r--modules/openssl/stream_peer_openssl.cpp6
-rw-r--r--modules/openssl/stream_peer_openssl.h2
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.cpp3
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.cpp57
-rw-r--r--modules/visual_script/visual_script_builtin_funcs.h3
-rw-r--r--modules/visual_script/visual_script_editor.cpp2
-rw-r--r--modules/visual_script/visual_script_nodes.cpp1
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java10
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java8
-rw-r--r--platform/haiku/context_gl_haiku.cpp2
-rw-r--r--platform/haiku/context_gl_haiku.h2
-rw-r--r--platform/haiku/os_haiku.cpp4
-rw-r--r--platform/haiku/os_haiku.h2
-rw-r--r--platform/iphone/export/export.cpp24
-rw-r--r--platform/iphone/game_center.h9
-rw-r--r--platform/iphone/game_center.mm72
-rw-r--r--platform/javascript/javascript_eval.cpp82
-rw-r--r--platform/osx/export/export.cpp4
-rw-r--r--platform/server/detect.py3
-rw-r--r--platform/windows/context_gl_win.cpp2
-rw-r--r--platform/windows/context_gl_win.h2
-rw-r--r--platform/windows/key_mapping_win.cpp2
-rw-r--r--platform/x11/context_gl_x11.cpp2
-rw-r--r--platform/x11/context_gl_x11.h2
-rw-r--r--platform/x11/detect.py3
-rw-r--r--platform/x11/os_x11.cpp20
-rw-r--r--platform/x11/os_x11.h2
-rw-r--r--scene/2d/navigation_polygon.cpp2
-rw-r--r--scene/2d/parallax_background.cpp2
-rw-r--r--scene/3d/arvr_nodes.cpp3
-rw-r--r--scene/3d/particles.cpp340
-rw-r--r--scene/3d/particles.h2
-rw-r--r--scene/animation/animation_player.cpp8
-rw-r--r--scene/gui/color_picker.cpp4
-rw-r--r--scene/gui/graph_edit.cpp1
-rw-r--r--scene/gui/item_list.cpp6
-rw-r--r--scene/gui/rich_text_label.cpp17
-rw-r--r--scene/gui/rich_text_label.h4
-rw-r--r--scene/gui/separator.cpp6
-rw-r--r--scene/gui/slider.cpp6
-rw-r--r--scene/gui/tab_container.cpp9
-rw-r--r--scene/gui/text_edit.cpp41
-rw-r--r--scene/gui/text_edit.h3
-rwxr-xr-xscene/main/node.cpp2
-rw-r--r--scene/main/scene_tree.cpp9
-rw-r--r--scene/main/scene_tree.h6
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--scene/resources/animation.cpp17
-rw-r--r--scene/resources/audio_stream_sample.cpp3
-rw-r--r--scene/resources/default_theme/default_theme.cpp4
-rw-r--r--scene/resources/material.cpp9
-rw-r--r--scene/resources/material.h2
-rw-r--r--scene/resources/shader.cpp2
-rw-r--r--scene/resources/style_box.cpp2
-rw-r--r--servers/arvr/arvr_script_interface.cpp136
-rw-r--r--servers/arvr/arvr_script_interface.h52
-rw-r--r--servers/arvr_server.cpp6
-rw-r--r--servers/physics/joints/pin_joint_sw.h4
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h45
-rw-r--r--servers/register_server_types.cpp8
-rw-r--r--servers/visual/shader_language.cpp2
-rw-r--r--servers/visual_server.cpp408
-rw-r--r--servers/visual_server.h16
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/enet/enet/enet.h1
-rw-r--r--thirdparty/libpng/LICENSE9
-rw-r--r--thirdparty/libpng/png.c32
-rw-r--r--thirdparty/libpng/png.h24
-rw-r--r--thirdparty/libpng/pngconf.h2
-rw-r--r--thirdparty/libpng/pnglibconf.h4
-rw-r--r--thirdparty/libpng/pngread.c14
-rw-r--r--thirdparty/libpng/pngrtran.c22
-rw-r--r--thirdparty/libpng/pngrutil.c47
-rw-r--r--thirdparty/libpng/pngtrans.c6
-rw-r--r--thirdparty/libpng/pngwrite.c2
355 files changed, 6865 insertions, 2247 deletions
diff --git a/.gitattributes b/.gitattributes
index f8959dd2d1..03c6f96f80 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -8,3 +8,4 @@ drivers/* linguist-vendored
*.h eol=lf
*.py eol=lf
*.hpp eol=lf
+*.xml eol=lf
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a9ada58e64..6cb52cf5ff 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -87,7 +87,7 @@ rebase -i`` and relevant help about rebasing or ammending commits on the
Internet).
This git style guide has some good practices to have in mind:
-https://github.com/agis-/git-style-guide
+[Git Style Guide](https://github.com/agis-/git-style-guide)
#### Format your commit logs with readability in mind
diff --git a/core/class_db.cpp b/core/class_db.cpp
index 12310f6151..57e88044b5 100644
--- a/core/class_db.cpp
+++ b/core/class_db.cpp
@@ -187,6 +187,25 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
return md;
}
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11) {
+
+ MethodDefinition md;
+ md.name = StaticCString::create(p_name);
+ md.args.resize(11);
+ md.args[0] = StaticCString::create(p_arg1);
+ md.args[1] = StaticCString::create(p_arg2);
+ md.args[2] = StaticCString::create(p_arg3);
+ md.args[3] = StaticCString::create(p_arg4);
+ md.args[4] = StaticCString::create(p_arg5);
+ md.args[5] = StaticCString::create(p_arg6);
+ md.args[6] = StaticCString::create(p_arg7);
+ md.args[7] = StaticCString::create(p_arg8);
+ md.args[8] = StaticCString::create(p_arg9);
+ md.args[9] = StaticCString::create(p_arg10);
+ md.args[10] = StaticCString::create(p_arg11);
+ return md;
+}
+
#endif
ClassDB::APIType ClassDB::current_api = API_CORE;
diff --git a/core/class_db.h b/core/class_db.h
index 5910a2ce01..24db4c61bb 100644
--- a/core/class_db.h
+++ b/core/class_db.h
@@ -66,6 +66,7 @@ MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9);
MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10);
+MethodDefinition D_METHOD(const char *p_name, const char *p_arg1, const char *p_arg2, const char *p_arg3, const char *p_arg4, const char *p_arg5, const char *p_arg6, const char *p_arg7, const char *p_arg8, const char *p_arg9, const char *p_arg10, const char *p_arg11);
#else
diff --git a/core/image.cpp b/core/image.cpp
index c7f21d5599..943cbaf51d 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -2474,6 +2474,7 @@ void Image::fix_alpha_edges() {
if (rp[3] < alpha_threshold)
continue;
+ closest_dist = dist;
closest_color[0] = rp[0];
closest_color[1] = rp[1];
closest_color[2] = rp[2];
diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp
index c93e12f7da..e5da307153 100644
--- a/core/io/file_access_encrypted.cpp
+++ b/core/io/file_access_encrypted.cpp
@@ -62,12 +62,12 @@ Error FileAccessEncrypted::open_and_parse(FileAccess *p_base, const Vector<uint8
writing = false;
key = p_key;
uint32_t magic = p_base->get_32();
- print_line("MAGIC: " + itos(magic));
ERR_FAIL_COND_V(magic != COMP_MAGIC, ERR_FILE_UNRECOGNIZED);
+
mode = Mode(p_base->get_32());
ERR_FAIL_INDEX_V(mode, MODE_MAX, ERR_FILE_CORRUPT);
ERR_FAIL_COND_V(mode == 0, ERR_FILE_CORRUPT);
- print_line("MODE: " + itos(mode));
+
unsigned char md5d[16];
p_base->get_buffer(md5d, 16);
length = p_base->get_64();
diff --git a/core/io/logger.cpp b/core/io/logger.cpp
index ad6371f1e1..ce2ce44b1d 100644
--- a/core/io/logger.cpp
+++ b/core/io/logger.cpp
@@ -110,7 +110,7 @@ void RotatedFileLogger::close_file() {
void RotatedFileLogger::clear_old_backups() {
int max_backups = max_files - 1; // -1 for the current file
- String basename = base_path.get_basename();
+ String basename = base_path.get_file().get_basename();
String extension = "." + base_path.get_extension();
DirAccess *da = DirAccess::open(base_path.get_base_dir());
@@ -122,7 +122,7 @@ void RotatedFileLogger::clear_old_backups() {
String f = da->get_next();
Set<String> backups;
while (f != String()) {
- if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path) {
+ if (!da->current_is_dir() && f.begins_with(basename) && f.ends_with(extension) && f != base_path.get_file()) {
backups.insert(f);
}
f = da->get_next();
@@ -149,7 +149,7 @@ void RotatedFileLogger::rotate_file() {
char timestamp[21];
OS::Date date = OS::get_singleton()->get_date();
OS::Time time = OS::get_singleton()->get_time();
- sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day + 1, time.hour, time.min, time.sec);
+ sprintf(timestamp, "-%04d-%02d-%02d-%02d-%02d-%02d", date.year, date.month, date.day, time.hour, time.min, time.sec);
String backup_name = base_path.get_basename() + timestamp + "." + base_path.get_extension();
diff --git a/core/make_binders.py b/core/make_binders.py
index 6468c029f0..6f42c6e8eb 100644
--- a/core/make_binders.py
+++ b/core/make_binders.py
@@ -244,7 +244,7 @@ def make_version(template, nargs, argmax, const, ret):
def run(target, source, env):
- versions = 10
+ versions = 11
versions_ext = 6
text = ""
text_ext = ""
diff --git a/core/os/input.cpp b/core/os/input.cpp
index a4b82299a7..848b003d5e 100644
--- a/core/os/input.cpp
+++ b/core/os/input.cpp
@@ -58,6 +58,7 @@ void Input::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_action_just_released", "action"), &Input::is_action_just_released);
ClassDB::bind_method(D_METHOD("add_joy_mapping", "mapping", "update_existing"), &Input::add_joy_mapping, DEFVAL(false));
ClassDB::bind_method(D_METHOD("remove_joy_mapping", "guid"), &Input::remove_joy_mapping);
+ ClassDB::bind_method(D_METHOD("joy_connection_changed", "device", "connected", "name", "guid"), &Input::joy_connection_changed);
ClassDB::bind_method(D_METHOD("is_joy_known", "device"), &Input::is_joy_known);
ClassDB::bind_method(D_METHOD("get_joy_axis", "device", "axis"), &Input::get_joy_axis);
ClassDB::bind_method(D_METHOD("get_joy_name", "device"), &Input::get_joy_name);
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 3994011c06..c4d1b199a0 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -261,7 +261,7 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack) {
return true;
}
-Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
+Error ProjectSettings::setup(const String &p_path, const String &p_main_pack, bool p_upwards) {
//If looking for files in network, just use network!
@@ -270,11 +270,6 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
_load_settings("res://override.cfg");
-#ifdef DEBUG_ENABLED
- } else {
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Couldn't open project over network");
-#endif
}
return OK;
@@ -292,12 +287,6 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
//load override from location of the main pack
_load_settings(p_main_pack.get_base_dir().plus_file("override.cfg"));
-#ifdef DEBUG_ENABLED
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Successfully loaded " + p_main_pack + "/project.godot or project.binary");
- } else {
- print_line("Couldn't load/find " + p_main_pack + "/project.godot or project.binary");
-#endif
}
return OK;
@@ -315,18 +304,9 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
if (_load_resource_pack(datapack_name)) {
found = true;
} else {
-#ifdef DEBUG_ENABLED
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Couldn't open " + datapack_name);
-#endif
datapack_name = filebase_name + ".pck";
if (_load_resource_pack(datapack_name)) {
found = true;
-#ifdef DEBUG_ENABLED
- } else {
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Couldn't open " + datapack_name);
-#endif
}
}
@@ -335,13 +315,6 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
// load override from location of executable
_load_settings(exec_path.get_base_dir().plus_file("override.cfg"));
-
-#ifdef DEBUG_ENABLED
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Successfully loaded " + datapack_name + "/project.godot or project.binary");
- } else {
- print_line("Couldn't load/find " + datapack_name + "/project.godot or project.binary");
-#endif
}
return OK;
@@ -362,12 +335,6 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
if (_load_settings("res://project.godot") == OK || _load_settings_binary("res://project.binary") == OK) {
_load_settings("res://override.cfg");
-#ifdef DEBUG_ENABLED
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Successfully loaded " + resource_path + "/project.godot or project.binary");
- } else {
- print_line("Couldn't load/find " + resource_path + "/project.godot or project.binary");
-#endif
}
return OK;
@@ -393,18 +360,16 @@ Error ProjectSettings::setup(const String &p_path, const String &p_main_pack) {
candidate = current_dir;
found = true;
break;
-#ifdef DEBUG_ENABLED
- // when debug version of godot is used, provide some feedback to the developer
- print_line("Successfully loaded " + current_dir + "/project.godot or project.binary");
- } else {
- print_line("Couldn't load/find " + current_dir + "/project.godot or project.binary");
-#endif
}
- d->change_dir("..");
- if (d->get_current_dir() == current_dir)
- break; //not doing anything useful
- current_dir = d->get_current_dir();
+ if (p_upwards) {
+ d->change_dir("..");
+ if (d->get_current_dir() == current_dir)
+ break; //not doing anything useful
+ current_dir = d->get_current_dir();
+ } else {
+ break;
+ }
}
resource_path = candidate;
diff --git a/core/project_settings.h b/core/project_settings.h
index ea6034dc84..f75cad815f 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -139,7 +139,7 @@ public:
void set_order(const String &p_name, int p_order);
void set_builtin_order(const String &p_name);
- Error setup(const String &p_path, const String &p_main_pack);
+ Error setup(const String &p_path, const String &p_main_pack, bool p_upwards = false);
Error save_custom(const String &p_path = "", const CustomMap &p_custom = CustomMap(), const Vector<String> &p_custom_features = Vector<String>(), bool p_merge_with_current = true);
Error save();
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index 4653ade294..2feb068ecb 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -855,15 +855,19 @@ void ScriptDebuggerRemote::_print_handler(void *p_this, const String &p_string)
}
sdr->char_count += allowed_chars;
-
- if (sdr->char_count >= sdr->max_cps) {
- s += "\n[output overflow, print less text!]\n";
- }
+ bool overflowed = sdr->char_count >= sdr->max_cps;
sdr->mutex->lock();
if (!sdr->locking && sdr->tcp_client->is_connected_to_host()) {
+ if (overflowed)
+ s += "[...]";
+
sdr->output_strings.push_back(s);
+
+ if (overflowed) {
+ sdr->output_strings.push_back("[output overflow, print less text!]");
+ }
}
sdr->mutex->unlock();
}
diff --git a/core/variant.h b/core/variant.h
index e0d0bf05c8..45066af401 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -99,15 +99,15 @@ public:
_RID,
OBJECT,
DICTIONARY,
- ARRAY, // 20
+ ARRAY,
// arrays
- POOL_BYTE_ARRAY,
+ POOL_BYTE_ARRAY, // 20
POOL_INT_ARRAY,
POOL_REAL_ARRAY,
POOL_STRING_ARRAY,
- POOL_VECTOR2_ARRAY, // 25
- POOL_VECTOR3_ARRAY,
+ POOL_VECTOR2_ARRAY,
+ POOL_VECTOR3_ARRAY, // 25
POOL_COLOR_ARRAY,
VARIANT_MAX
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index 03ec336291..6362090902 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -1655,13 +1655,13 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
} else if (p_index == CoreStringNames::singleton->a) {
return v->a;
} else if (p_index == CoreStringNames::singleton->r8) {
- return v->r * 255.0;
+ return int(v->r * 255.0);
} else if (p_index == CoreStringNames::singleton->g8) {
- return v->g * 255.0;
+ return int(v->g * 255.0);
} else if (p_index == CoreStringNames::singleton->b8) {
- return v->b * 255.0;
+ return int(v->b * 255.0);
} else if (p_index == CoreStringNames::singleton->a8) {
- return v->a * 255.0;
+ return int(v->a * 255.0);
} else if (p_index == CoreStringNames::singleton->h) {
return v->get_h();
} else if (p_index == CoreStringNames::singleton->s) {
diff --git a/doc/Makefile b/doc/Makefile
index d68c66f8eb..2f9fefe794 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -24,5 +24,5 @@ rst:
rm -rf $(OUTPUTDIR)/rst
mkdir -p $(OUTPUTDIR)/rst
pushd $(OUTPUTDIR)/rst
- python2 $(TOOLSDIR)/makerst.py $(CLASSES)
+ python $(TOOLSDIR)/makerst.py $(CLASSES)
popd
diff --git a/doc/classes/ARVRInterface.xml b/doc/classes/ARVRInterface.xml
index 1c2e761b57..9aed6c96ef 100644
--- a/doc/classes/ARVRInterface.xml
+++ b/doc/classes/ARVRInterface.xml
@@ -94,7 +94,7 @@
<argument index="0" name="initialized" type="bool">
</argument>
<description>
- Initialise/uninitilise this interface (same effect as calling intialize/uninitialize).
+ Initialize/uninitialize this interface (same effect as calling initialize/uninitialize).
</description>
</method>
<method name="set_is_primary">
diff --git a/doc/classes/ARVRScriptInterface.xml b/doc/classes/ARVRScriptInterface.xml
deleted file mode 100644
index 182147a015..0000000000
--- a/doc/classes/ARVRScriptInterface.xml
+++ /dev/null
@@ -1,118 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" ?>
-<class name="ARVRScriptInterface" inherits="ARVRInterface" category="Core" version="3.0.alpha.custom_build">
- <brief_description>
- Base class for GDNative based ARVR interfaces.
- </brief_description>
- <description>
- This class is used as a base class/interface class for implementing GDNative based ARVR interfaces and as a result exposes more of the internals of the ARVR server.
- </description>
- <tutorials>
- </tutorials>
- <demos>
- </demos>
- <methods>
- <method name="_get_projection_for_eye" qualifiers="virtual">
- <return type="void">
- </return>
- <description>
- Should return the projection 4x4 matrix for the requested eye.
- </description>
- </method>
- <method name="commit_for_eye" qualifiers="virtual">
- <return type="void">
- </return>
- <argument index="0" name="eye" type="int">
- </argument>
- <argument index="1" name="render_target" type="RID">
- </argument>
- <description>
- Outputs a finished render buffer to the AR/VR device for the given eye.
- </description>
- </method>
- <method name="get_anchor_detection_is_enabled" qualifiers="virtual">
- <return type="bool">
- </return>
- <description>
- Returns true if achor detection is enabled (AR only).
- </description>
- </method>
- <method name="get_capabilities" qualifiers="virtual">
- <return type="int">
- </return>
- <description>
- Returns a combination of flags providing information about the capabilities of this interface.
- </description>
- </method>
- <method name="get_recommended_render_targetsize" qualifiers="virtual">
- <return type="Vector2">
- </return>
- <description>
- Returns the size at which we should render our scene to get optimal quality on the output device.
- </description>
- </method>
- <method name="get_tracking_status" qualifiers="virtual">
- <return type="int">
- </return>
- <description>
- If supported, returns the status of our tracking. This will allow you to provide feedback to the user whether there are issues with positional tracking.
- </description>
- </method>
- <method name="get_transform_for_eye" qualifiers="virtual">
- <return type="Transform">
- </return>
- <argument index="0" name="eye" type="int">
- </argument>
- <argument index="1" name="cam_transform" type="Transform">
- </argument>
- <description>
- Get the location and orientation transform used when rendering a specific eye.
- </description>
- </method>
- <method name="initialize" qualifiers="virtual">
- <return type="bool">
- </return>
- <description>
- Initialize this interface.
- </description>
- </method>
- <method name="is_initialized" qualifiers="virtual">
- <return type="bool">
- </return>
- <description>
- Returns true if this interface has been initialized and is active.
- </description>
- </method>
- <method name="is_stereo" qualifiers="virtual">
- <return type="bool">
- </return>
- <description>
- Returns true if we require stereoscopic rendering for this interface.
- </description>
- </method>
- <method name="process" qualifiers="virtual">
- <return type="void">
- </return>
- <description>
- Gets called before rendering each frame so tracking data gets updated in time.
- </description>
- </method>
- <method name="set_anchor_detection_is_enabled" qualifiers="virtual">
- <return type="void">
- </return>
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- Enables anchor detection, this is used on AR interfaces and enables the extra logic that will detect planes, features, objects, etc. and adds/modifies anchor points.
- </description>
- </method>
- <method name="uninitialize" qualifiers="virtual">
- <return type="void">
- </return>
- <description>
- Turn this interface off.
- </description>
- </method>
- </methods>
- <constants>
- </constants>
-</class>
diff --git a/doc/classes/ARVRServer.xml b/doc/classes/ARVRServer.xml
index 6a7262bd14..5e1055d568 100644
--- a/doc/classes/ARVRServer.xml
+++ b/doc/classes/ARVRServer.xml
@@ -14,7 +14,7 @@
<method name="add_interface">
<return type="void">
</return>
- <argument index="0" name="arg0" type="ARVRInterface">
+ <argument index="0" name="interface" type="ARVRInterface">
</argument>
<description>
Mostly exposed for GDNative based interfaces, this is called to register an available interface with the AR/VR server.
@@ -94,7 +94,7 @@
<method name="remove_interface">
<return type="void">
</return>
- <argument index="0" name="arg0" type="ARVRInterface">
+ <argument index="0" name="interface" type="ARVRInterface">
</argument>
<description>
Removes a registered interface, again exposed mostly for GDNative based interfaces.
@@ -103,7 +103,7 @@
<method name="set_primary_interface">
<return type="void">
</return>
- <argument index="0" name="arg0" type="ARVRInterface">
+ <argument index="0" name="interface" type="ARVRInterface">
</argument>
<description>
Changes the primary interface to the specified interface. Again mostly exposed for GDNative interfaces.
@@ -178,7 +178,7 @@
Used internally to filter trackers of any known type.
</constant>
<constant name="TRACKER_ANY" value="255">
- Used interally to select all trackers.
+ Used internally to select all trackers.
</constant>
</constants>
</class>
diff --git a/doc/classes/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index 74a7f6c8a4..70b880eb43 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -380,11 +380,11 @@
</signal>
</signals>
<constants>
- <constant name="ANIMATION_PROCESS_FIXED" value="0">
- Process animation on fixed process. This is specially useful when animating kinematic bodies.
+ <constant name="ANIMATION_PROCESS_PHYSICS" value="0">
+ Process animation during the physics process. This is specially useful when animating physics bodies.
</constant>
<constant name="ANIMATION_PROCESS_IDLE" value="1">
- Process animation on idle process.
+ Process animation during the idle process.
</constant>
</constants>
</class>
diff --git a/doc/classes/AnimationTreePlayer.xml b/doc/classes/AnimationTreePlayer.xml
index f088d21e41..b92e59b902 100644
--- a/doc/classes/AnimationTreePlayer.xml
+++ b/doc/classes/AnimationTreePlayer.xml
@@ -659,7 +659,7 @@
<constant name="NODE_TRANSITION" value="9">
Transition node.
</constant>
- <constant name="ANIMATION_PROCESS_FIXED" value="0">
+ <constant name="ANIMATION_PROCESS_PHYSICS" value="0">
</constant>
<constant name="ANIMATION_PROCESS_IDLE" value="1">
</constant>
diff --git a/doc/classes/Array.xml b/doc/classes/Array.xml
index 2cfbaffe04..7c1d72333b 100644
--- a/doc/classes/Array.xml
+++ b/doc/classes/Array.xml
@@ -178,8 +178,6 @@
</description>
</method>
<method name="invert">
- <return type="Array">
- </return>
<description>
Reverse the order of the elements in the array (so first element will now be the last) and return reference to the array.
</description>
@@ -241,15 +239,11 @@
</description>
</method>
<method name="sort">
- <return type="Array">
- </return>
<description>
Sort the array using natural order and return reference to the array.
</description>
</method>
<method name="sort_custom">
- <return type="Array">
- </return>
<argument index="0" name="obj" type="Object">
</argument>
<argument index="1" name="func" type="String">
diff --git a/doc/classes/AudioEffectDistortion.xml b/doc/classes/AudioEffectDistortion.xml
index 1a6aa1d2b6..8b970e675e 100644
--- a/doc/classes/AudioEffectDistortion.xml
+++ b/doc/classes/AudioEffectDistortion.xml
@@ -5,7 +5,7 @@
Modify the sound to make it dirty.
</brief_description>
<description>
- Modify the sound and make it dirty. Differents types available : clip, tan, lofi (bit crushing), overdrive, or waveshape.
+ Modify the sound and make it dirty. Different types are available : clip, tan, lofi (bit crushing), overdrive, or waveshape.
By distorting the waveform the frequency content change, which will often make the sound "crunchy" or "abrasive". For games, it can simulate sound coming from some saturated device or speaker very efficiently.
</description>
<tutorials>
diff --git a/doc/classes/AudioEffectReverb.xml b/doc/classes/AudioEffectReverb.xml
index 4cda24530b..f399f9f07a 100644
--- a/doc/classes/AudioEffectReverb.xml
+++ b/doc/classes/AudioEffectReverb.xml
@@ -136,7 +136,7 @@
High-pass filter passes signals with a frequency higher than a certain cutoff frequency and attenuates signals with frequencies lower than the cutoff frequency. Value can range from 0 to 1. Default value: [code]0[/code].
</member>
<member name="predelay_feedback" type="float" setter="set_predelay_msec" getter="get_predelay_msec">
- Output percent of predelay. Value can range from 0 to 1. Default value: [code]1[/code].
+ Output percent of predelay. Value can range from 0 to 1. Default value: [code]1[/code].
</member>
<member name="predelay_msec" type="float" setter="set_predelay_msec" getter="get_predelay_msec">
Time between the original signal and the early reflections of the reverb signal. Default value: [code]150ms[/code].
diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml
index 0a59da5355..f8320c23af 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -298,7 +298,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is in solo mode.
+ If [code]true[/code] the bus at index [code]bus_idx[/code] is in solo mode.
</description>
</method>
<method name="set_bus_volume_db">
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index 2085b35e2e..84f6792ef0 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -310,7 +310,7 @@
Sets the absolute maximum of the soundlevel, in dB.
</member>
<member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance">
- Sets the distance from wich the 'out_of_range_mode' takes effect. Has no effect if set to 0.
+ Sets the distance from which the 'out_of_range_mode' takes effect. Has no effect if set to 0.
</member>
<member name="out_of_range_mode" type="int" setter="set_out_of_range_mode" getter="get_out_of_range_mode" enum="AudioStreamPlayer3D.OutOfRangeMode">
Decides if audio should pause when source is outside of 'max_distance' range.
@@ -355,10 +355,10 @@
Disables doppler tracking.
</constant>
<constant name="DOPPLER_TRACKING_IDLE_STEP" value="1">
- Executes doppler trackin in idle step.
+ Executes doppler tracking in idle step.
</constant>
- <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2">
- Executes doppler tracking in fixed step.
+ <constant name="DOPPLER_TRACKING_PHYSICS_STEP" value="2">
+ Executes doppler tracking in physics step.
</constant>
</constants>
</class>
diff --git a/doc/classes/BitmapFont.xml b/doc/classes/BitmapFont.xml
index e983c59782..07027c4b42 100644
--- a/doc/classes/BitmapFont.xml
+++ b/doc/classes/BitmapFont.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="BitmapFont" inherits="Font" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Renders text using [code]*.fnt[/code] fonts.
</brief_description>
<description>
+ Renders text using [code]*.fnt[/code] fonts containing texture atlases. Supports distance fields. For using vector font files like TTF directly, see [DynamicFont].
</description>
<tutorials>
</tutorials>
@@ -23,7 +25,7 @@
<argument index="4" name="advance" type="float" default="-1">
</argument>
<description>
- Add a character to the font, where [i]character[/i] is the unicode value, [i]texture[/i] is the texture index, [i]rect[/i] is the region in the texture (in pixels!), [i]align[/i] is the (optional) alignment for the character and [i]advance[/i] is the (optional) advance.
+ Adds a character to the font, where [code]character[/code] is the unicode value, [code]texture[/code] is the texture index, [code]rect[/code] is the region in the texture (in pixels!), [code]align[/code] is the (optional) alignment for the character and [code]advance[/code] is the (optional) advance.
</description>
</method>
<method name="add_kerning_pair">
@@ -36,7 +38,7 @@
<argument index="2" name="kerning" type="int">
</argument>
<description>
- Add a kerning pair to the [BitmapFont] as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character.
+ Adds a kerning pair to the [BitmapFont] as a difference. Kerning pairs are special cases where a typeface advance is determined by the next character.
</description>
</method>
<method name="add_texture">
@@ -45,14 +47,14 @@
<argument index="0" name="texture" type="Texture">
</argument>
<description>
- Add a texture to the [BitmapFont].
+ Adds a texture to the [BitmapFont].
</description>
</method>
<method name="clear">
<return type="void">
</return>
<description>
- Clear all the font data.
+ Clears all the font data and settings.
</description>
</method>
<method name="create_from_fnt">
@@ -61,6 +63,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
+ Creates a BitmapFont from the [code]*.fnt[/code] file at [code]path[/code].
</description>
</method>
<method name="get_char_size" qualifiers="const">
@@ -71,13 +74,14 @@
<argument index="1" name="next" type="int" default="0">
</argument>
<description>
- Return the size of a character, optionally taking kerning into account if the next character is provided.
+ Returns the size of a character, optionally taking kerning into account if the next character is provided.
</description>
</method>
<method name="get_fallback" qualifiers="const">
<return type="BitmapFont">
</return>
<description>
+ Returns the fallback BitmapFont.
</description>
</method>
<method name="get_kerning_pair" qualifiers="const">
@@ -88,7 +92,7 @@
<argument index="1" name="char_b" type="int">
</argument>
<description>
- Return a kerning pair as a difference.
+ Returns a kerning pair as a difference.
</description>
</method>
<method name="get_texture" qualifiers="const">
@@ -97,12 +101,14 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the font atlas texture at index [code]idx[/code].
</description>
</method>
<method name="get_texture_count" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the number of textures in the BitmapFont atlas.
</description>
</method>
<method name="set_ascent">
@@ -111,7 +117,7 @@
<argument index="0" name="px" type="float">
</argument>
<description>
- Set the font ascent (number of pixels above the baseline).
+ Sets the font ascent (number of pixels above the baseline).
</description>
</method>
<method name="set_distance_field_hint">
@@ -120,6 +126,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ If [code]true[/code] distance field hint is enabled.
</description>
</method>
<method name="set_fallback">
@@ -128,6 +135,7 @@
<argument index="0" name="fallback" type="BitmapFont">
</argument>
<description>
+ Sets the fallback BitmapFont.
</description>
</method>
<method name="set_height">
@@ -136,24 +144,31 @@
<argument index="0" name="px" type="float">
</argument>
<description>
- Set the total font height (ascent plus descent) in pixels.
+ Sets the total font height (ascent plus descent) in pixels.
</description>
</method>
</methods>
<members>
<member name="ascent" type="float" setter="set_ascent" getter="get_ascent">
+ Ascent (number of pixels above the baseline).
</member>
<member name="chars" type="PoolIntArray" setter="_set_chars" getter="_get_chars">
+ The characters in the BitmapFont.
</member>
<member name="distance_field" type="bool" setter="set_distance_field_hint" getter="is_distance_field_hint">
+ If [code]true[/code] distance field hint is enabled.
</member>
<member name="fallback" type="BitmapFont" setter="set_fallback" getter="get_fallback">
+ The fallback font.
</member>
<member name="height" type="float" setter="set_height" getter="get_height">
+ Total font height (ascent plus descent) in pixels.
</member>
<member name="kernings" type="PoolIntArray" setter="_set_kernings" getter="_get_kernings">
+ The font's kernings as [PoolIntArray].
</member>
<member name="textures" type="Array" setter="_set_textures" getter="_get_textures">
+ The font's [Texture]\ s.
</member>
</members>
<constants>
diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml
index 068b91204c..aeebcf9c87 100644
--- a/doc/classes/Camera.xml
+++ b/doc/classes/Camera.xml
@@ -267,7 +267,7 @@
<constant name="DOPPLER_TRACKING_IDLE_STEP" value="1">
Simulate Doppler effect by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this Camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
</constant>
- <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2">
+ <constant name="DOPPLER_TRACKING_PHYSICS_STEP" value="2">
Simulate Doppler effect by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this Camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
</constant>
</constants>
diff --git a/doc/classes/CheckBox.xml b/doc/classes/CheckBox.xml
index 6258eb503f..50b431e00c 100644
--- a/doc/classes/CheckBox.xml
+++ b/doc/classes/CheckBox.xml
@@ -4,7 +4,7 @@
Binary choice user interface widget
</brief_description>
<description>
- A checkbox allows the user to make a binary choice (choosing only one of two posible options), for example Answer 'yes' or 'no'.
+ A checkbox allows the user to make a binary choice (choosing only one of two possible options), for example Answer 'yes' or 'no'.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index 87414eb03a..74c12cb9b2 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -93,6 +93,8 @@
</theme_item>
<theme_item name="margin" type="int">
</theme_item>
+ <theme_item name="preset_bg" type="Texture">
+ </theme_item>
<theme_item name="screen_picker" type="Texture">
</theme_item>
<theme_item name="sv_height" type="int">
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index 59b74edd77..7b54be36c9 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -72,6 +72,8 @@
<constants>
</constants>
<theme_items>
+ <theme_item name="bg" type="Texture">
+ </theme_item>
<theme_item name="disabled" type="StyleBox">
</theme_item>
<theme_item name="focus" type="StyleBox">
diff --git a/doc/classes/ConeTwistJoint.xml b/doc/classes/ConeTwistJoint.xml
index 67c7cc4cfe..78655c496d 100644
--- a/doc/classes/ConeTwistJoint.xml
+++ b/doc/classes/ConeTwistJoint.xml
@@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="ConeTwistJoint" inherits="Joint" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ A twist joint between two 3D bodies
</brief_description>
<description>
+ The joint can rotate the bodies across an axis defined by the local x-axes of the [Joint].
+ The twist axis is initiated as the x-axis of the [Joint].
+ Once the Bodies swing, the twist axis is calculated as the middle of the x-axes of the Joint in the local space of the two Bodies.
</description>
<tutorials>
</tutorials>
@@ -30,28 +34,49 @@
</methods>
<members>
<member name="bias" type="float" setter="set_param" getter="get_param">
+ The speed with which the swing or twist will take place.
+ The higher, the faster.
</member>
<member name="relaxation" type="float" setter="set_param" getter="get_param">
+ Defines, how fast the swing- and twist-speed-difference on both sides gets synced.
</member>
<member name="softness" type="float" setter="set_param" getter="get_param">
+ The ease with which the joint starts to twist. If it's too low, it takes more force to start twisting the joint.
</member>
<member name="swing_span" type="float" setter="_set_swing_span" getter="_get_swing_span">
+ Swing is rotation from side to side, around the axis perpendicular to the twist axis.
+ The swing span defines, how much rotation will not get corrected allong the swing axis.
+ Could be defined as looseness in the [ConeTwistJoint].
+ If below 0.05, this behaviour is locked. Default value: [code]PI/4[/code].
</member>
<member name="twist_span" type="float" setter="_set_twist_span" getter="_get_twist_span">
+ Twist is the rotation around the twist axis, this value defined how far the joint can twist.
+ Twist is locked if below 0.05.
</member>
</members>
<constants>
<constant name="PARAM_SWING_SPAN" value="0">
+ Swing is rotation from side to side, around the axis perpendicular to the twist axis.
+ The swing span defines, how much rotation will not get corrected allong the swing axis.
+ Could be defined as looseness in the [ConeTwistJoint].
+ If below 0.05, this behaviour is locked. Default value: [code]PI/4[/code].
</constant>
<constant name="PARAM_TWIST_SPAN" value="1">
+ Twist is the rotation around the twist axis, this value defined how far the joint can twist.
+ Twist is locked if below 0.05.
</constant>
<constant name="PARAM_BIAS" value="2">
+ The speed with which the swing or twist will take place.
+ The higher, the faster.
</constant>
<constant name="PARAM_SOFTNESS" value="3">
+ The ease with which the joint starts to twist. If it's too low, it takes more force to start twisting the joint.
</constant>
<constant name="PARAM_RELAXATION" value="4">
+ Defines, how fast the swing- and twist-speed-difference on both sides gets synced.
</constant>
<constant name="PARAM_MAX" value="5">
+ End flag of PARAM_* constants, used internally.
</constant>
</constants>
</class>
diff --git a/doc/classes/ConfigFile.xml b/doc/classes/ConfigFile.xml
index c2d1ec1355..846a100f3c 100644
--- a/doc/classes/ConfigFile.xml
+++ b/doc/classes/ConfigFile.xml
@@ -4,15 +4,22 @@
Helper class to handle INI-style files.
</brief_description>
<description>
- This helper class can be used to store [Variant] values on the filesystem using an INI-style formatting. The stored values as referenced by a section and a key. The stored data can be saved to or parsed from a file, though ConfigFile objects can also be used directly with accessing the filesystem.
- The following example shows how to parse a INI-style file from the system, read its contents and store new values in it:
+ This helper class can be used to store [Variant] values on the filesystem using INI-style formatting. The stored values are indentified by a section and a key:
+ [codeblock]
+ [section]
+ some_key=42
+ string_example="Hello World!"
+ a_vector=Vector3( 1, 0, 2 )
+ [/codeblock]
+ The stored data can be saved to or parsed from a file, though ConfigFile objects can also be used directly without accessing the filesystem.
+ The following example shows how to parse an INI-style file from the system, read its contents and store new values in it:
[codeblock]
var config = ConfigFile.new()
var err = config.load("user://settings.cfg")
if err == OK: # if not, something went wrong with the file loading
# Look for the display/width pair, and default to 1024 if missing
var screen_width = get_value("display", "width", 1024)
- # Store a variable if and only it hasn't been defined yet
+ # Store a variable if and only if it hasn't been defined yet
if not config.has_section_key("audio", "mute"):
config.set_value("audio", "mute", false)
# Save the changes by overwriting the previous file
@@ -30,6 +37,7 @@
<argument index="0" name="section" type="String">
</argument>
<description>
+ Deletes the specified section along with all the key-value pairs inside.
</description>
</method>
<method name="get_section_keys" qualifiers="const">
@@ -38,14 +46,14 @@
<argument index="0" name="section" type="String">
</argument>
<description>
- Return an array of all defined key identifiers in the specified section.
+ Returns an array of all defined key identifiers in the specified section.
</description>
</method>
<method name="get_sections" qualifiers="const">
<return type="PoolStringArray">
</return>
<description>
- Return an array of all defined section identifiers.
+ Returns an array of all defined section identifiers.
</description>
</method>
<method name="get_value" qualifiers="const">
@@ -58,7 +66,7 @@
<argument index="2" name="default" type="Variant" default="null">
</argument>
<description>
- Return the current value for the specified section and key. If the section and/or the key do not exist, the method returns the value of the optional [i]default[/i] argument (and thus [code]NULL[/code] if not specified).
+ Returns the current value for the specified section and key. If the section and/or the key do not exist, the method returns the value of the optional [code]default[/code] argument, or [code]null[/code] if it is omitted.
</description>
</method>
<method name="has_section" qualifiers="const">
@@ -67,7 +75,7 @@
<argument index="0" name="section" type="String">
</argument>
<description>
- Check if the specified section exists.
+ Returns [code]true[/code] if the specified section exists.
</description>
</method>
<method name="has_section_key" qualifiers="const">
@@ -78,7 +86,7 @@
<argument index="1" name="key" type="String">
</argument>
<description>
- Check if the specified section-key pair exists.
+ Returns [code]true[/code] if the specified section-key pair exists.
</description>
</method>
<method name="load">
@@ -87,7 +95,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Load the config file specified as a parameter. The file's contents are parsed and loaded in the ConfigFile object from which the method was called. The return value is one of the OK, FAILED or ERR_* constants listed in [@Global Scope] (if the load was successful, it returns OK).
+ Loads the config file specified as a parameter. The file's contents are parsed and loaded in the ConfigFile object which the method was called on. Returns one of the [code]OK[/code], [code]FAILED[/code] or [code]ERR_*[/code] constants listed in [@Global Scope]. If the load was successful, the return value is [code]OK[/code].
</description>
</method>
<method name="save">
@@ -96,8 +104,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Save the contents of the ConfigFile object to the file specified as a parameter. The output file uses an INI-style structure.
- The return value is one of the OK, FAILED or ERR_* constants listed in [@Global Scope] (if the save was successful, it returns OK).
+ Saves the contents of the ConfigFile object to the file specified as a parameter. The output file uses an INI-style structure. Returns one of the [code]OK[/code], [code]FAILED[/code] or [code]ERR_*[/code] constants listed in [@Global Scope]. If the load was successful, the return value is [code]OK[/code].
</description>
</method>
<method name="set_value">
@@ -110,7 +117,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
- Assign a value to the specified key of the the specified section. If the section and/or the key do not exist, they are created. Passing a [code]NULL[/code] value deletes the specified key if it exists (and deletes the section if it ends up empty once the key has been removed).
+ Assigns a value to the specified key of the the specified section. If the section and/or the key do not exist, they are created. Passing a [code]null[/code] value deletes the specified key if it exists, and deletes the section if it ends up empty once the key has been removed.
</description>
</method>
</methods>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index b3bdd1d6c2..77bbfa186b 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -578,23 +578,26 @@
<description>
</description>
</method>
- <method name="set_anchors_preset">
+ <method name="set_anchors_and_margins_preset">
<return type="void">
</return>
<argument index="0" name="preset" type="int" enum="Control.LayoutPreset">
</argument>
- <argument index="1" name="keep_margin" type="bool" default="false">
+ <argument index="1" name="resize_mode" type="int" enum="Control.LayoutPresetMode" default="0">
+ </argument>
+ <argument index="2" name="margin" type="int" default="0">
</argument>
<description>
</description>
</method>
- <method name="set_area_as_parent_rect">
+ <method name="set_anchors_preset">
<return type="void">
</return>
- <argument index="0" name="margin" type="int" default="0">
+ <argument index="0" name="preset" type="int" enum="Control.LayoutPreset">
+ </argument>
+ <argument index="1" name="keep_margin" type="bool" default="false">
</argument>
<description>
- Change all margins and anchors, so this Control always takes up the same area as the parent Control. This is a helper (see [method set_anchor], [method set_margin]).
</description>
</method>
<method name="set_begin">
@@ -713,6 +716,18 @@
Set a margin offset. Margin can be one of (MARGIN_LEFT, MARGIN_TOP, MARGIN_RIGHT, MARGIN_BOTTOM). Offset value being set depends on the anchor mode.
</description>
</method>
+ <method name="set_margins_preset">
+ <return type="void">
+ </return>
+ <argument index="0" name="preset" type="int" enum="Control.LayoutPreset">
+ </argument>
+ <argument index="1" name="resize_mode" type="int" enum="Control.LayoutPresetMode" default="0">
+ </argument>
+ <argument index="2" name="margin" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_mouse_filter">
<return type="void">
</return>
@@ -1096,6 +1111,14 @@
<constant name="PRESET_WIDE" value="15">
Snap all 4 anchors to the respective corners of the parent container. Set all 4 margins to 0 after you applied this preset and the [code]Control[/code] will fit its parent container. Use with [method set_anchors_preset].
</constant>
+ <constant name="PRESET_MODE_MINSIZE" value="0">
+ </constant>
+ <constant name="PRESET_MODE_KEEP_HEIGHT" value="2">
+ </constant>
+ <constant name="PRESET_MODE_KEEP_WIDTH" value="1">
+ </constant>
+ <constant name="PRESET_MODE_KEEP_SIZE" value="3">
+ </constant>
<constant name="SIZE_EXPAND" value="2">
Tells the parent [Container] to let this node take all the available space on the axis you flag. If multiple neighboring nodes are set to expand, they'll share the space based on their stretch ratio. See [member size_flags_stretch_ratio]. Use with [member size_flags_horizontal] and [member size_flags_vertical].
</constant>
diff --git a/doc/classes/Curve.xml b/doc/classes/Curve.xml
index ef43d9024c..c89ab6fb9b 100644
--- a/doc/classes/Curve.xml
+++ b/doc/classes/Curve.xml
@@ -170,7 +170,7 @@
</description>
</method>
<method name="set_point_offset">
- <return type="void">
+ <return type="int">
</return>
<argument index="0" name="index" type="int">
</argument>
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index e4ce2ff3f0..c130add523 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="DynamicFont" inherits="Font" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ DynamicFont renders vector font files at runtime.
</brief_description>
<description>
+ DynamicFont renders vector font files (such as TTF or OTF) dynamically at runtime instead of using a prerendered texture atlas like [BitmapFont]. This trades the faster loading time of [BitmapFont]\ s for the ability to change font parameters like size and spacing during runtime. [DynamicFontData] is used for referencing the font file paths.
</description>
<tutorials>
</tutorials>
@@ -15,6 +17,7 @@
<argument index="0" name="data" type="DynamicFontData">
</argument>
<description>
+ Adds a fallback font.
</description>
</method>
<method name="get_fallback" qualifiers="const">
@@ -23,12 +26,14 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the fallback font at index [code]idx[/code].
</description>
</method>
<method name="get_fallback_count" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the number of fallback fonts.
</description>
</method>
<method name="get_font_data" qualifiers="const">
@@ -41,6 +46,7 @@
<return type="int">
</return>
<description>
+ Returns the font size in pixels.
</description>
</method>
<method name="get_spacing" qualifiers="const">
@@ -49,18 +55,21 @@
<argument index="0" name="type" type="int">
</argument>
<description>
+ Returns the given type of spacing in pixels. See [code]SPACING_*[/code] constants.
</description>
</method>
<method name="get_use_filter" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if filtering is used.
</description>
</method>
<method name="get_use_mipmaps" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if mipmapping is used.
</description>
</method>
<method name="remove_fallback">
@@ -69,6 +78,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Removes the fallback font at index [code]idx[/code].
</description>
</method>
<method name="set_fallback">
@@ -79,6 +89,7 @@
<argument index="1" name="data" type="DynamicFontData">
</argument>
<description>
+ Sets the fallback font at index [code]idx[/code].
</description>
</method>
<method name="set_font_data">
@@ -87,6 +98,7 @@
<argument index="0" name="data" type="DynamicFontData">
</argument>
<description>
+ Sets the [DynamicFontData].
</description>
</method>
<method name="set_size">
@@ -95,6 +107,7 @@
<argument index="0" name="data" type="int">
</argument>
<description>
+ Sets the font size.
</description>
</method>
<method name="set_spacing">
@@ -105,6 +118,7 @@
<argument index="1" name="value" type="int">
</argument>
<description>
+ Sets the spacing of the given type. See [code]SPACING_*[/code] constants.
</description>
</method>
<method name="set_use_filter">
@@ -113,6 +127,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set to [code]true[/code] to use filtering.
</description>
</method>
<method name="set_use_mipmaps">
@@ -121,35 +136,48 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set to [code]true[/code] to use mipmapping.
</description>
</method>
</methods>
<members>
<member name="extra_spacing_bottom" type="int" setter="set_spacing" getter="get_spacing">
+ Extra spacing at the bottom in pixels.
</member>
<member name="extra_spacing_char" type="int" setter="set_spacing" getter="get_spacing">
+ Extra character spacing in pixels.
</member>
<member name="extra_spacing_space" type="int" setter="set_spacing" getter="get_spacing">
+ Extra space spacing in pixels.
</member>
<member name="extra_spacing_top" type="int" setter="set_spacing" getter="get_spacing">
+ Extra spacing at the top in pixels.
</member>
<member name="font_data" type="DynamicFontData" setter="set_font_data" getter="get_font_data">
+ The font data.
</member>
<member name="size" type="int" setter="set_size" getter="get_size">
+ The font size.
</member>
<member name="use_filter" type="bool" setter="set_use_filter" getter="get_use_filter">
+ If [code]true[/code] filtering is used.
</member>
<member name="use_mipmaps" type="bool" setter="set_use_mipmaps" getter="get_use_mipmaps">
+ If [code]true[/code] mipmapping is used.
</member>
</members>
<constants>
<constant name="SPACING_TOP" value="0">
+ Spacing at the top.
</constant>
<constant name="SPACING_BOTTOM" value="1">
+ Spacing at the bottom.
</constant>
<constant name="SPACING_CHAR" value="2">
+ Character spacing.
</constant>
<constant name="SPACING_SPACE" value="3">
+ Space spacing.
</constant>
</constants>
</class>
diff --git a/doc/classes/DynamicFontData.xml b/doc/classes/DynamicFontData.xml
index 51e4e0d231..9012b46e08 100644
--- a/doc/classes/DynamicFontData.xml
+++ b/doc/classes/DynamicFontData.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="DynamicFontData" inherits="Resource" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Used with [DynamicFont] to describe the location of a font file.
</brief_description>
<description>
+ Used with [DynamicFont] to describe the location of a vector font file for dynamic rendering at runtime.
</description>
<tutorials>
</tutorials>
@@ -13,6 +15,7 @@
<return type="String">
</return>
<description>
+ Returns the font path.
</description>
</method>
<method name="set_font_path">
@@ -21,11 +24,13 @@
<argument index="0" name="path" type="String">
</argument>
<description>
+ Sets the font path.
</description>
</method>
</methods>
<members>
<member name="font_path" type="String" setter="set_font_path" getter="get_font_path">
+ The path to the vector font file.
</member>
</members>
<constants>
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index 05319e926c..da8f0f235b 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -35,7 +35,7 @@
func get_preset_name(i):
return "Default"
- func get_import_optons(i):
+ func get_import_options(i):
return [{"name": "my_option", "default_value": false}]
func load(src, dst, opts, r_platform_variants, r_gen_files):
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index 0422e9a64e..23a937791c 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorInterface" inherits="Node" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Editor interface and main components.
</brief_description>
<description>
+ Editor interface. Allows saving and (re-)loading scenes, rendering mesh previews, inspecting and editing resources and objects and provides access to [EditorSettings], [EditorFileSystem], [EditorResourcePreview]\ er, [ScriptEditor], the editor viewport, as well as information about scenes. Also see [EditorPlugin] and [EditorScript].
</description>
<tutorials>
</tutorials>
@@ -15,60 +17,70 @@
<argument index="0" name="resource" type="Resource">
</argument>
<description>
+ Edits the given [Resource].
</description>
</method>
<method name="get_base_control">
<return type="Control">
</return>
<description>
+ Returns the base [Control].
</description>
</method>
<method name="get_edited_scene_root">
<return type="Node">
</return>
<description>
+ Returns the edited scene's root [Node].
</description>
</method>
<method name="get_editor_settings">
<return type="EditorSettings">
</return>
<description>
+ Returns the [EditorSettings].
</description>
</method>
<method name="get_editor_viewport">
<return type="Control">
</return>
<description>
+ Returns the editor [Viewport].
</description>
</method>
<method name="get_open_scenes" qualifiers="const">
<return type="Array">
</return>
<description>
+ Returns an [Array] of the currently opened scenes.
</description>
</method>
<method name="get_resource_filesystem">
<return type="EditorFileSystem">
</return>
<description>
+ Returns the [EditorFileSystem].
</description>
</method>
<method name="get_resource_previewer">
<return type="EditorResourcePreview">
</return>
<description>
+ Returns the [EditorResourcePreview]\ er.
</description>
</method>
<method name="get_script_editor">
<return type="ScriptEditor">
</return>
<description>
+ Returns the [ScriptEditor].
</description>
</method>
<method name="get_selection">
<return type="EditorSelection">
</return>
<description>
+ Returns the [EditorSelection].
</description>
</method>
<method name="inspect_object">
@@ -79,16 +91,18 @@
<argument index="1" name="for_property" type="String" default="&quot;&quot;">
</argument>
<description>
+ Shows the given property on the given [code]object[/code] in the Editor's Inspector dock.
</description>
</method>
<method name="make_mesh_previews">
<return type="Array">
</return>
- <argument index="0" name="arg0" type="Array">
+ <argument index="0" name="meshes" type="Array">
</argument>
- <argument index="1" name="arg1" type="int">
+ <argument index="1" name="preview_size" type="int">
</argument>
<description>
+ Returns mesh previews rendered at the given size as an [Array] of [Texture]\ s.
</description>
</method>
<method name="open_scene_from_path">
@@ -97,6 +111,7 @@
<argument index="0" name="scene_filepath" type="String">
</argument>
<description>
+ Opens the scene at the given path.
</description>
</method>
<method name="reload_scene_from_path">
@@ -105,12 +120,14 @@
<argument index="0" name="scene_filepath" type="String">
</argument>
<description>
+ Reloads the scene at the given path.
</description>
</method>
<method name="save_scene">
<return type="int" enum="Error">
</return>
<description>
+ Saves the scene. Returns either OK or ERR_CANT_CREATE. See [@Global Scope] constants.
</description>
</method>
<method name="save_scene_as">
@@ -121,6 +138,7 @@
<argument index="1" name="with_preview" type="bool" default="true">
</argument>
<description>
+ Saves the scene as a file at [code]path[/code].
</description>
</method>
</methods>
diff --git a/doc/classes/EditorResourcePreview.xml b/doc/classes/EditorResourcePreview.xml
index acf36b6a08..5174d9243b 100644
--- a/doc/classes/EditorResourcePreview.xml
+++ b/doc/classes/EditorResourcePreview.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorResourcePreview" inherits="Node" category="Core" version="3.0.alpha.custom_build">
<brief_description>
- Helper to generate previews of reources or files.
+ Helper to generate previews of resources or files.
</brief_description>
<description>
This object is used to generate previews for resources of files.
diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml
index 48cf3e9843..9e774345a2 100644
--- a/doc/classes/EditorScript.xml
+++ b/doc/classes/EditorScript.xml
@@ -1,10 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="EditorScript" inherits="Reference" category="Core" version="3.0.alpha.custom_build">
<brief_description>
- Simple script to perform changes in the currently edited scene.
+ Base script that can be used to add extension functions to the editor.
</brief_description>
<description>
- This script can be run from the Scene -&gt; Run Script menu option.
+ Scripts extending this class and implementing its [code]_run()[/code] method can be executed from the Script Editor's [code]File -> Run[/code] menu option (or by pressing [code]CTRL+Shift+X[/code]) while the editor is running. This is useful for adding custom in-editor functionality to Godot. For more complex additions, consider using [EditorPlugin]\ s instead. Note that extending scripts need to have [code]tool mode[/code] enabled.
+ Example script:
+ [codeblock]
+ tool
+ extends EditorScript
+
+ func _run():
+ print("Hello from the Godot Editor!")
+ [/codeblock]
+ Note that the script is run in the Editor context, which means the output is visible in the console window started with the Editor (STDOUT) instead of the usual Godot *Output* dock.
</description>
<tutorials>
</tutorials>
@@ -15,6 +24,7 @@
<return type="void">
</return>
<description>
+ This method is executed by the Editor when [code]File -> Run[/code] is used.
</description>
</method>
<method name="add_root_node">
@@ -29,12 +39,14 @@
<return type="EditorInterface">
</return>
<description>
+ Returns the [EditorInterface] singleton instance.
</description>
</method>
<method name="get_scene">
<return type="Node">
</return>
<description>
+ Returns the Editor's currently active scene.
</description>
</method>
</methods>
diff --git a/doc/classes/EditorSelection.xml b/doc/classes/EditorSelection.xml
index 8d9bdd2c05..a6dc60ee7b 100644
--- a/doc/classes/EditorSelection.xml
+++ b/doc/classes/EditorSelection.xml
@@ -31,7 +31,7 @@
<return type="Array">
</return>
<description>
- Get the list of selectes nodes.
+ Get the list of selected nodes.
</description>
</method>
<method name="get_transformable_selected_nodes">
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 37c7a47a51..17a4d2fe4b 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -69,6 +69,14 @@
Get the list of recently visited folders in the file dialog for this project.
</description>
</method>
+ <method name="get_setting" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_settings_path" qualifiers="const">
<return type="String">
</return>
@@ -78,6 +86,30 @@
settings/templates - where export templates are located
</description>
</method>
+ <method name="has_setting" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="property_can_revert">
+ <return type="bool">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="property_get_revert">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_favorite_dirs">
<return type="void">
</return>
@@ -87,6 +119,16 @@
Set the list of favorite directories for this project.
</description>
</method>
+ <method name="set_initial_value">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_recent_dirs">
<return type="void">
</return>
@@ -96,6 +138,16 @@
Set the list of recently visited folders in the file dialog for this project.
</description>
</method>
+ <method name="set_setting">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<signals>
<signal name="settings_changed">
diff --git a/doc/classes/EditorSpatialGizmo.xml b/doc/classes/EditorSpatialGizmo.xml
index baab995fab..545eadeed2 100644
--- a/doc/classes/EditorSpatialGizmo.xml
+++ b/doc/classes/EditorSpatialGizmo.xml
@@ -96,7 +96,7 @@
<argument index="2" name="cancel" type="bool" default="false">
</argument>
<description>
- Commit a handle being edited (handles must have been prevously added by [method add_handles]).
+ Commit a handle being edited (handles must have been previously added by [method add_handles]).
If the cancel parameter is true, an option to restore the edited value to the original is provided.
</description>
</method>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 3880c45a86..2918200633 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
-<class name="Environment" inherits="Resource" category="Core" version="3.0">
+<class name="Environment" inherits="Resource" category="Core" version="3.0.alpha.custom_build">
<brief_description>
Resource for environment nodes (like [WorldEnvironment]) that define multiple rendering options.
</brief_description>
@@ -226,7 +226,7 @@
<description>
</description>
</method>
- <method name="get_sky_scale" qualifiers="const">
+ <method name="get_sky_custom_fov" qualifiers="const">
<return type="float">
</return>
<description>
@@ -794,7 +794,7 @@
<description>
</description>
</method>
- <method name="set_sky_scale">
+ <method name="set_sky_custom_fov">
<return type="void">
</return>
<argument index="0" name="scale" type="float">
@@ -1042,8 +1042,8 @@
<member name="background_sky" type="Sky" setter="set_sky" getter="get_sky">
[Sky] resource defined as background.
</member>
- <member name="background_sky_scale" type="float" setter="set_sky_scale" getter="get_sky_scale">
- [Sky] resource's scale.
+ <member name="background_sky_custom_fov" type="float" setter="set_sky_custom_fov" getter="get_sky_custom_fov">
+ [Sky] resource's custom field of view.
</member>
<member name="dof_blur_far_amount" type="float" setter="set_dof_blur_far_amount" getter="get_dof_blur_far_amount">
Amount of far blur.
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index d7a08368a5..b3d131ca40 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -86,7 +86,7 @@
<return type="bool">
</return>
<description>
- Return true if the diaog allows show hidden files.
+ Return true if the dialog allows show hidden files.
</description>
</method>
<method name="set_access">
@@ -205,10 +205,10 @@
The dialog allows the selection of file and directory.
</constant>
<constant name="ACCESS_USERDATA" value="1">
- The dialog allows ascess files under [Resource] path(res://) .
+ The dialog allows access files under [Resource] path(res://) .
</constant>
<constant name="ACCESS_FILESYSTEM" value="2">
- The dialog allows ascess files in whole file system.
+ The dialog allows access files in whole file system.
</constant>
</constants>
<theme_items>
diff --git a/doc/classes/Generic6DOFJoint.xml b/doc/classes/Generic6DOFJoint.xml
index 4b782e994a..89ec1fd836 100644
--- a/doc/classes/Generic6DOFJoint.xml
+++ b/doc/classes/Generic6DOFJoint.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Generic6DOFJoint" inherits="Joint" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ The generic 6 degrees of freedom joint can implement a variety of joint-types by locking certain axes' rotation or translation.
</brief_description>
<description>
+ The first 3 dof axes are linear axes, which represent translation of Bodies, and the latter 3 dof axes represent the angular motion. Each axis can be either locked, or limited.
</description>
<tutorials>
</tutorials>
@@ -120,146 +122,217 @@
</methods>
<members>
<member name="angular_limit_x/damping" type="float" setter="set_param_x" getter="get_param_x">
+ The amount of rotational damping across the x-axis.
+ The lower, the longer an impulse from one side takes to travel to the other side.
</member>
<member name="angular_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
+ If [code]true[/code] rotation across the x-axis is enabled.
</member>
<member name="angular_limit_x/erp" type="float" setter="set_param_x" getter="get_param_x">
+ When rotating across x-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
</member>
<member name="angular_limit_x/force_limit" type="float" setter="set_param_x" getter="get_param_x">
+ The maximum amount of force that can occur, when rotating arround x-axis.
</member>
<member name="angular_limit_x/lower_angle" type="float" setter="_set_angular_lo_limit_x" getter="_get_angular_lo_limit_x">
+ The minimum rotation in negative direction to break loose and rotate arround the x-axis.
</member>
<member name="angular_limit_x/restitution" type="float" setter="set_param_x" getter="get_param_x">
+ The amount of rotational restitution across the x-axis. The lower, the more restitution occurs.
</member>
<member name="angular_limit_x/softness" type="float" setter="set_param_x" getter="get_param_x">
+ The speed of all rotations across the x-axis.
</member>
<member name="angular_limit_x/upper_angle" type="float" setter="_set_angular_hi_limit_x" getter="_get_angular_hi_limit_x">
+ The minimum rotation in positive direction to break loose and rotate arround the x-axis.
</member>
<member name="angular_limit_y/damping" type="float" setter="set_param_y" getter="get_param_y">
+ The amount of rotational damping across the y-axis. The lower, the more dampening occurs.
</member>
<member name="angular_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
+ If [code]true[/code] rotation across the y-axis is enabled.
</member>
<member name="angular_limit_y/erp" type="float" setter="set_param_y" getter="get_param_y">
+ When rotating across y-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
</member>
<member name="angular_limit_y/force_limit" type="float" setter="set_param_y" getter="get_param_y">
+ The maximum amount of force that can occur, when rotating arround y-axis.
</member>
<member name="angular_limit_y/lower_angle" type="float" setter="_set_angular_lo_limit_y" getter="_get_angular_lo_limit_y">
+ The minimum rotation in negative direction to break loose and rotate arround the y-axis.
</member>
<member name="angular_limit_y/restitution" type="float" setter="set_param_y" getter="get_param_y">
+ The amount of rotational restitution across the y-axis. The lower, the more restitution occurs.
</member>
<member name="angular_limit_y/softness" type="float" setter="set_param_y" getter="get_param_y">
+ The speed of all rotations across the y-axis.
</member>
<member name="angular_limit_y/upper_angle" type="float" setter="_set_angular_hi_limit_y" getter="_get_angular_hi_limit_y">
+ The minimum rotation in positive direction to break loose and rotate arround the y-axis.
</member>
<member name="angular_limit_z/damping" type="float" setter="set_param_z" getter="get_param_z">
+ The amount of rotational damping across the z-axis. The lower, the more dampening occurs.
</member>
<member name="angular_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
+ If [code]true[/code] rotation across the z-axis is enabled.
</member>
<member name="angular_limit_z/erp" type="float" setter="set_param_z" getter="get_param_z">
+ When rotating across z-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
</member>
<member name="angular_limit_z/force_limit" type="float" setter="set_param_z" getter="get_param_z">
+ The maximum amount of force that can occur, when rotating arround z-axis.
</member>
<member name="angular_limit_z/lower_angle" type="float" setter="_set_angular_lo_limit_z" getter="_get_angular_lo_limit_z">
+ The minimum rotation in negative direction to break loose and rotate arround the z-axis.
</member>
<member name="angular_limit_z/restitution" type="float" setter="set_param_z" getter="get_param_z">
+ The amount of rotational restitution across the z-axis. The lower, the more restitution occurs.
</member>
<member name="angular_limit_z/softness" type="float" setter="set_param_z" getter="get_param_z">
+ The speed of all rotations across the z-axis.
</member>
<member name="angular_limit_z/upper_angle" type="float" setter="_set_angular_hi_limit_z" getter="_get_angular_hi_limit_z">
+ The minimum rotation in positive direction to break loose and rotate arround the z-axis.
</member>
<member name="angular_motor_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
+ If [code]true[/code] a rotating motor at the x-axis is enabled.
</member>
<member name="angular_motor_x/force_limit" type="float" setter="set_param_x" getter="get_param_x">
+ Maximum acceleration for the motor at the x-axis.
</member>
<member name="angular_motor_x/target_velocity" type="float" setter="set_param_x" getter="get_param_x">
+ Target speed for the motor at the x-axis.
</member>
<member name="angular_motor_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
+ If [code]true[/code] a rotating motor at the y-axis is enabled.
</member>
<member name="angular_motor_y/force_limit" type="float" setter="set_param_y" getter="get_param_y">
+ Maximum acceleration for the motor at the y-axis.
</member>
<member name="angular_motor_y/target_velocity" type="float" setter="set_param_y" getter="get_param_y">
+ Target speed for the motor at the y-axis.
</member>
<member name="angular_motor_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
+ If [code]true[/code] a rotating motor at the z-axis is enabled.
</member>
<member name="angular_motor_z/force_limit" type="float" setter="set_param_z" getter="get_param_z">
+ Maximum acceleration for the motor at the z-axis.
</member>
<member name="angular_motor_z/target_velocity" type="float" setter="set_param_z" getter="get_param_z">
+ Target speed for the motor at the z-axis.
</member>
<member name="linear_limit_x/damping" type="float" setter="set_param_x" getter="get_param_x">
+ The amount of damping that happens at the x-motion.
</member>
<member name="linear_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
+ If [code]true[/code] the linear motion across the x-axis is enabled.
</member>
<member name="linear_limit_x/lower_distance" type="float" setter="set_param_x" getter="get_param_x">
+ The minimum difference between the pivot points' x-axis.
</member>
<member name="linear_limit_x/restitution" type="float" setter="set_param_x" getter="get_param_x">
+ The amount of restitution on the x-axis movement The lower, the more momentum gets lost.
</member>
<member name="linear_limit_x/softness" type="float" setter="set_param_x" getter="get_param_x">
+ A factor applied to the movement across the x-axis The lower, the slower the movement.
</member>
<member name="linear_limit_x/upper_distance" type="float" setter="set_param_x" getter="get_param_x">
+ The maximum difference between the pivot points' x-axis.
</member>
<member name="linear_limit_y/damping" type="float" setter="set_param_y" getter="get_param_y">
+ The amount of damping that happens at the y-motion.
</member>
<member name="linear_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
+ If [code]true[/code] the linear motion across the y-axis is enabled.
</member>
<member name="linear_limit_y/lower_distance" type="float" setter="set_param_y" getter="get_param_y">
+ The minimum difference between the pivot points' y-axis.
</member>
<member name="linear_limit_y/restitution" type="float" setter="set_param_y" getter="get_param_y">
+ The amount of restitution on the y-axis movement The lower, the more momentum gets lost.
</member>
<member name="linear_limit_y/softness" type="float" setter="set_param_y" getter="get_param_y">
+ A factor applied to the movement across the y-axis The lower, the slower the movement.
</member>
<member name="linear_limit_y/upper_distance" type="float" setter="set_param_y" getter="get_param_y">
+ The maximum difference between the pivot points' y-axis.
</member>
<member name="linear_limit_z/damping" type="float" setter="set_param_z" getter="get_param_z">
+ The amount of damping that happens at the z-motion.
</member>
<member name="linear_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
+ If [code]true[/code] the linear motion across the z-axis is enabled.
</member>
<member name="linear_limit_z/lower_distance" type="float" setter="set_param_z" getter="get_param_z">
+ The minimum difference between the pivot points' z-axis.
</member>
<member name="linear_limit_z/restitution" type="float" setter="set_param_z" getter="get_param_z">
+ The amount of restitution on the z-axis movement The lower, the more momentum gets lost.
</member>
<member name="linear_limit_z/softness" type="float" setter="set_param_z" getter="get_param_z">
+ A factor applied to the movement across the z-axis The lower, the slower the movement.
</member>
<member name="linear_limit_z/upper_distance" type="float" setter="set_param_z" getter="get_param_z">
+ The maximum difference between the pivot points' z-axis.
</member>
</members>
<constants>
<constant name="PARAM_LINEAR_LOWER_LIMIT" value="0">
+ The minimum difference between the pivot points' axes.
</constant>
<constant name="PARAM_LINEAR_UPPER_LIMIT" value="1">
+ The maximum difference between the pivot points' axes.
</constant>
<constant name="PARAM_LINEAR_LIMIT_SOFTNESS" value="2">
+ A factor applied to the movement across the axes The lower, the slower the movement.
</constant>
<constant name="PARAM_LINEAR_RESTITUTION" value="3">
+ The amount of restitution on the axes movement The lower, the more momentum gets lost.
</constant>
<constant name="PARAM_LINEAR_DAMPING" value="4">
+ The amount of damping that happens at the linear motion across the axes.
</constant>
<constant name="PARAM_ANGULAR_LOWER_LIMIT" value="5">
+ The minimum rotation in negative direction to break loose and rotate arround the axes.
</constant>
<constant name="PARAM_ANGULAR_UPPER_LIMIT" value="6">
+ The minimum rotation in positive direction to break loose and rotate arround the axes.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_SOFTNESS" value="7">
+ The speed of all rotations across the axes.
</constant>
<constant name="PARAM_ANGULAR_DAMPING" value="8">
+ The amount of rotational damping across the axes. The lower, the more dampening occurs.
</constant>
<constant name="PARAM_ANGULAR_RESTITUTION" value="9">
+ The amount of rotational restitution across the axes. The lower, the more restitution occurs.
</constant>
<constant name="PARAM_ANGULAR_FORCE_LIMIT" value="10">
+ The maximum amount of force that can occur, when rotating arround the axes.
</constant>
<constant name="PARAM_ANGULAR_ERP" value="11">
+ When rotating across the axes, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
</constant>
<constant name="PARAM_ANGULAR_MOTOR_TARGET_VELOCITY" value="12">
+ Target speed for the motor at the axes.
</constant>
<constant name="PARAM_ANGULAR_MOTOR_FORCE_LIMIT" value="13">
+ Maximum acceleration for the motor at the axes.
</constant>
<constant name="PARAM_MAX" value="14">
+ End flag of PARAM_* constants, used internally.
</constant>
<constant name="FLAG_ENABLE_LINEAR_LIMIT" value="0">
+ If [code]set[/code] there is linear motion possible within the given limits.
</constant>
<constant name="FLAG_ENABLE_ANGULAR_LIMIT" value="1">
+ If [code]set[/code] there is rotational motion possible.
</constant>
<constant name="FLAG_ENABLE_MOTOR" value="2">
+ If [code]set[/code] there is a rotational motor across these axes.
</constant>
<constant name="FLAG_MAX" value="3">
+ End flag of FLAG_* constants, used internally.
</constant>
</constants>
</class>
diff --git a/doc/classes/HSlider.xml b/doc/classes/HSlider.xml
index 91f95d1548..25e62b90e3 100644
--- a/doc/classes/HSlider.xml
+++ b/doc/classes/HSlider.xml
@@ -19,6 +19,8 @@
</theme_item>
<theme_item name="grabber" type="Texture">
</theme_item>
+ <theme_item name="grabber_area" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture">
</theme_item>
<theme_item name="grabber_disabled" type="StyleBox">
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index c2839890cf..b780d29d0e 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -166,7 +166,7 @@
Request does not have a response(yet).
</constant>
<constant name="RESULT_BODY_SIZE_LIMIT_EXCEEDED" value="7">
- Request exceded its maximum size limit, see [method set_body_size_limit].
+ Request exceeded its maximum size limit, see [method set_body_size_limit].
</constant>
<constant name="RESULT_REQUEST_FAILED" value="8">
Request failed. (unused)
diff --git a/doc/classes/HingeJoint.xml b/doc/classes/HingeJoint.xml
index ae3693c3a4..d18e63f8a3 100644
--- a/doc/classes/HingeJoint.xml
+++ b/doc/classes/HingeJoint.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="HingeJoint" inherits="Joint" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ A hinge between two 3D bodies.
</brief_description>
<description>
+ Normaly uses the z-axis of body A as the hinge axis, another axis can be specified when adding it manually though.
</description>
<tutorials>
</tutorials>
@@ -48,50 +50,70 @@
</methods>
<members>
<member name="angular_limit/bias" type="float" setter="set_param" getter="get_param">
+ The speed with which the rotation across the axis perpendicular to the hinge gets corrected.
</member>
<member name="angular_limit/enable" type="bool" setter="set_flag" getter="get_flag">
+ If [code]true[/code] the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
</member>
<member name="angular_limit/lower" type="float" setter="_set_lower_limit" getter="_get_lower_limit">
+ The minimum rotation. only active if [member angular_limit/enable] is [code]true[/code].
</member>
<member name="angular_limit/relaxation" type="float" setter="set_param" getter="get_param">
+ The lower this value, the more the rotation gets slowed down.
</member>
<member name="angular_limit/softness" type="float" setter="set_param" getter="get_param">
</member>
<member name="angular_limit/upper" type="float" setter="_set_upper_limit" getter="_get_upper_limit">
+ The maximum rotation. only active if [member angular_limit/enable] is [code]true[/code].
</member>
<member name="motor/enable" type="bool" setter="set_flag" getter="get_flag">
+ When activated, a motor turns the hinge.
</member>
<member name="motor/max_impulse" type="float" setter="set_param" getter="get_param">
+ Maximum acceleration for the motor.
</member>
<member name="motor/target_velocity" type="float" setter="set_param" getter="get_param">
+ Target speed for the motor.
</member>
<member name="params/bias" type="float" setter="set_param" getter="get_param">
+ The speed with wich the two bodies get pulled together when they move in different directions.
</member>
</members>
<constants>
<constant name="PARAM_BIAS" value="0">
+ The speed with wich the two bodies get pulled together when they move in different directions.
</constant>
<constant name="PARAM_LIMIT_UPPER" value="1">
+ The maximum rotation. only active if [member angular_limit/enable] is [code]true[/code].
</constant>
<constant name="PARAM_LIMIT_LOWER" value="2">
+ The minimum rotation. only active if [member angular_limit/enable] is [code]true[/code].
</constant>
<constant name="PARAM_LIMIT_BIAS" value="3">
+ The speed with which the rotation across the axis perpendicular to the hinge gets corrected.
</constant>
<constant name="PARAM_LIMIT_SOFTNESS" value="4">
</constant>
<constant name="PARAM_LIMIT_RELAXATION" value="5">
+ The lower this value, the more the rotation gets slowed down.
</constant>
<constant name="PARAM_MOTOR_TARGET_VELOCITY" value="6">
+ Target speed for the motor.
</constant>
<constant name="PARAM_MOTOR_MAX_IMPULSE" value="7">
+ Maximum acceleration for the motor.
</constant>
<constant name="PARAM_MAX" value="8">
+ End flag of PARAM_* constants, used internally.
</constant>
<constant name="FLAG_USE_LIMIT" value="0">
+ If [code]true[/code] the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
</constant>
<constant name="FLAG_ENABLE_MOTOR" value="1">
+ When activated, a motor turns the hinge.
</constant>
<constant name="FLAG_MAX" value="2">
+ End flag of FLAG_* constants, used internally.
</constant>
</constants>
</class>
diff --git a/doc/classes/Input.xml b/doc/classes/Input.xml
index 3d8b4154f8..d2d01dacb4 100644
--- a/doc/classes/Input.xml
+++ b/doc/classes/Input.xml
@@ -4,7 +4,7 @@
A Singleton that deals with inputs.
</brief_description>
<description>
- A Singleton that deals with inputs. This includes key presses, mouse buttons and movement, joypads, and input actions.
+ A Singleton that deals with inputs. This includes key presses, mouse buttons and movement, joypads, and input actions. Actions and their events can be set in the Project Settings / Input Map tab. Or be set with [InputMap].
</description>
<tutorials>
</tutorials>
@@ -75,7 +75,7 @@
<argument index="1" name="axis" type="int">
</argument>
<description>
- Returns the current value of the joypad axis at given index (see JOY_* constants in [@Global Scope])
+ Returns the current value of the joypad axis at given index (see [code]JOY_*[/code] constants in [@Global Scope])
</description>
</method>
<method name="get_joy_axis_index_from_string">
@@ -180,6 +180,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
+ Returns [code]true[/code] when you start pressing the action event.
</description>
</method>
<method name="is_action_just_released" qualifiers="const">
@@ -188,6 +189,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
+ Returns [code]true[/code] when you stop pressing the action event.
</description>
</method>
<method name="is_action_pressed" qualifiers="const">
@@ -196,7 +198,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
- Returns true or false depending on whether the action event is pressed. Actions and their events can be set in the Project Settings / Input Map tab. Or be set with [InputMap].
+ Returns [code]true[/code] if you are pressing the action event.
</description>
</method>
<method name="is_joy_button_pressed" qualifiers="const">
@@ -207,7 +209,7 @@
<argument index="1" name="button" type="int">
</argument>
<description>
- Returns if the joypad button at the given index is currently pressed. (see JOY_* constants in [@Global Scope])
+ Returns [code]true[/code] if you are pressing the joypad button. (see [code]JOY_*[/code] constants in [@Global Scope])
</description>
</method>
<method name="is_joy_known">
@@ -216,7 +218,7 @@
<argument index="0" name="device" type="int">
</argument>
<description>
- Returns if the specified device is known by the system. This means that it sets all button and axis indices exactly as defined in the JOY_* constants (see [@Global Scope]). Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
+ Returns [code]true[/code] if the system knows the specified device. This means that it sets all button and axis indices exactly as defined in the [code]JOY_*[/code] constants (see [@Global Scope]). Unknown joypads are not expected to match these constants, but you can still retrieve events from them.
</description>
</method>
<method name="is_key_pressed" qualifiers="const">
@@ -225,7 +227,7 @@
<argument index="0" name="scancode" type="int">
</argument>
<description>
- Returns true or false depending on whether the key is pressed or not. You can pass KEY_*, which are pre-defined constants listed in [@Global Scope].
+ Returns [code]true[/code] if you are pressing the key. You can pass [code]KEY_*[/code], which are pre-defined constants listed in [@Global Scope].
</description>
</method>
<method name="is_mouse_button_pressed" qualifiers="const">
@@ -234,7 +236,21 @@
<argument index="0" name="button" type="int">
</argument>
<description>
- Returns true or false depending on whether mouse button is pressed or not. You can pass BUTTON_*, which are pre-defined constants listed in [@Global Scope].
+ Returns [code]true[/code] if you are pressing the mouse button. You can pass [code]BUTTON_*[/code], which are pre-defined constants listed in [@Global Scope].
+ </description>
+ </method>
+ <method name="joy_connection_changed">
+ <return type="void">
+ </return>
+ <argument index="0" name="device" type="int">
+ </argument>
+ <argument index="1" name="connected" type="bool">
+ </argument>
+ <argument index="2" name="name" type="String">
+ </argument>
+ <argument index="3" name="guid" type="String">
+ </argument>
+ <description>
</description>
</method>
<method name="parse_input_event">
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index a8d879888f..37c1db51f5 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -217,7 +217,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns whether the tooptip is enabled for specified item index.
+ Returns whether the tooltip is enabled for specified item index.
</description>
</method>
<method name="is_same_column_width" qualifiers="const">
@@ -511,7 +511,7 @@
<argument index="1" name="selected" type="bool">
</argument>
<description>
- Fired when a multiple selection is altered on a list allowing mutliple selection.
+ Fired when a multiple selection is altered on a list allowing multiple selection.
</description>
</signal>
</signals>
diff --git a/doc/classes/JSONParseResult.xml b/doc/classes/JSONParseResult.xml
index 86edaaf1e6..db9a681896 100644
--- a/doc/classes/JSONParseResult.xml
+++ b/doc/classes/JSONParseResult.xml
@@ -79,7 +79,7 @@
The error message if JSON source was not successfully parsed. See [@Global Scope]ERR_* constants.
</member>
<member name="result" type="Variant" setter="set_result" getter="get_result">
- A [Variant] containing the parsed JSON. Use typeof() to check if it is what you expect. For exemple, if JSON source starts with braces [code]{}[/code] a [Dictionary] will be returned, if JSON source starts with array braces [code][][/code] an [Array] will be returned.
+ A [Variant] containing the parsed JSON. Use typeof() to check if it is what you expect. For example, if JSON source starts with braces [code]{}[/code] a [Dictionary] will be returned, if JSON source starts with array braces [code][][/code] an [Array] will be returned.
[i]Be aware that the JSON specification does not define integer or float types, but only a number type. Therefore, parsing a JSON text will convert all numerical values to float types.[/i]
[codeblock]
p = JSON.parse('["hello", "world", "!"]')
diff --git a/doc/classes/Joint.xml b/doc/classes/Joint.xml
index 2e7d24aac1..901f84fe5e 100644
--- a/doc/classes/Joint.xml
+++ b/doc/classes/Joint.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="Joint" inherits="Spatial" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Base class for all 3D joints
</brief_description>
<description>
+ All 3D joints link two nodes, has a priority, and can decide if the two bodies of the nodes should be able to collide with each other
</description>
<tutorials>
</tutorials>
@@ -68,12 +70,16 @@
</methods>
<members>
<member name="collision/exclude_nodes" type="bool" setter="set_exclude_nodes_from_collision" getter="get_exclude_nodes_from_collision">
+ If [code]true[/code] the two bodies of the nodes are not able to collide with each other.
</member>
<member name="nodes/node_a" type="NodePath" setter="set_node_a" getter="get_node_a">
+ The [Node], the first side of the Joint attaches to.
</member>
<member name="nodes/node_b" type="NodePath" setter="set_node_b" getter="get_node_b">
+ The [Node], the second side of the Joint attaches to.
</member>
<member name="solver/priority" type="int" setter="set_solver_priority" getter="get_solver_priority">
+ The order in wich the solver is executed compared to the other [Joints], the lower, the earlier.
</member>
</members>
<constants>
diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml
index e7c58fdb3a..badc098494 100644
--- a/doc/classes/KinematicBody2D.xml
+++ b/doc/classes/KinematicBody2D.xml
@@ -122,4 +122,4 @@
</members>
<constants>
</constants>
-</class> \ No newline at end of file
+</class>
diff --git a/doc/classes/NinePatchRect.xml b/doc/classes/NinePatchRect.xml
index 6829b36e14..c74f3c5a68 100644
--- a/doc/classes/NinePatchRect.xml
+++ b/doc/classes/NinePatchRect.xml
@@ -111,7 +111,7 @@
If [code]true[/code], draw the panel's center. Else, only draw the 9-slice's borders. Default value: [code]true[/code]
</member>
<member name="patch_margin_bottom" type="int" setter="set_patch_margin" getter="get_patch_margin">
- The height of the 9-slice's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values indivually to create panels with non-uniform borders.
+ The height of the 9-slice's bottom row. A margin of 16 means the 9-slice's bottom corners and side will have a height of 16 pixels. You can set all 4 margin values individually to create panels with non-uniform borders.
</member>
<member name="patch_margin_left" type="int" setter="set_patch_margin" getter="get_patch_margin">
The height of the 9-slice's left column.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index e35f64a9c0..a484556e69 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -9,7 +9,7 @@
[b]Scene tree:[/b] The [SceneTree] contains the active tree of nodes. When a node is added to the scene tree, it receives the NOTIFICATION_ENTER_TREE notification and its [method _enter_tree] callback is triggered. Children nodes are always added [i]after[/i] their parent node, i.e. the [method _enter_tree] callback of a parent node will be triggered before its child's.
Once all nodes have been added in the scene tree, they receive the NOTIFICATION_READY notification and their respective [method _ready] callbacks are triggered. For groups of nodes, the [method _ready] callback is called in reverse order, from the children up to the parent nodes.
It means that when adding a scene to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (and that recursively for the whole scene).
- [b]Processing:[/b] Nodes can be set to the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is variable. Fixed processing (callback [method _fixed_process], toggled with [method set_fixed_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics.
+ [b]Processing:[/b] Nodes can be set to the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is variable. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed amount of times per second (by default 60) and is useful to link itself to the physics.
Nodes can also process input events. When set, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it.
To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with [method set_owner]. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
Finally, when a node is freed with [method free] or [method queue_free], it will also free all its children.
@@ -36,24 +36,24 @@
Corresponds to the NOTIFICATION_EXIT_TREE notification in [method Object._notification].
</description>
</method>
- <method name="_fixed_process" qualifiers="virtual">
+ <method name="_input" qualifiers="virtual">
<return type="void">
</return>
- <argument index="0" name="delta" type="float">
+ <argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Called during the fixed processing step of the main loop. Fixed processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant.
- It is only called if fixed processing has been enabled with [method set_fixed_process].
- Corresponds to the NOTIFICATION_FIXED_PROCESS notification in [method Object._notification].
+ Called when there is a change to input devices. Propagated through the node tree until a Node consumes it.
</description>
</method>
- <method name="_input" qualifiers="virtual">
+ <method name="_physics_process" qualifiers="virtual">
<return type="void">
</return>
- <argument index="0" name="event" type="InputEvent">
+ <argument index="0" name="delta" type="float">
</argument>
<description>
- Called when there is a change to input devices. Propagated through the node tree until a Node consumes it.
+ Called during the physics processing step of the main loop. Physics processing means that the frame rate is synced to the physics, i.e. the [code]delta[/code] variable should be constant.
+ It is only called if physics processing has been enabled with [method set_physics_process].
+ Corresponds to the NOTIFICATION_PHYSICS_PROCESS notification in [method Object._notification].
</description>
</method>
<method name="_process" qualifiers="virtual">
@@ -187,13 +187,6 @@
Return a filename that may be contained by the node. When a scene is instanced from a file, it topmost node contains the filename from where it was loaded (see [method set_filename]).
</description>
</method>
- <method name="get_fixed_process_delta_time" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Return the time elapsed since the last fixed frame (see [method _fixed_process]). This is always the same in fixed processing unless the frames per second is changed in [OS].
- </description>
- </method>
<method name="get_groups" qualifiers="const">
<return type="Array">
</return>
@@ -294,6 +287,13 @@
Return the pause mode (PAUSE_MODE_*) of this Node.
</description>
</method>
+ <method name="get_physics_process_delta_time" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ Return the time elapsed since the last physics-bound frame (see [method _physics_process]). This is always a constant value in physics processing unless the frames per second is changed in [OS].
+ </description>
+ </method>
<method name="get_position_in_parent" qualifiers="const">
<return type="int">
</return>
@@ -359,19 +359,6 @@
<description>
</description>
</method>
- <method name="is_fixed_processing" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Return true if fixed processing is enabled (see [method set_fixed_process]).
- </description>
- </method>
- <method name="is_fixed_processing_internal" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="is_greater_than" qualifiers="const">
<return type="bool">
</return>
@@ -403,6 +390,19 @@
<description>
</description>
</method>
+ <method name="is_physics_processing" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ Return true if physics processing is enabled (see [method set_physics_process]).
+ </description>
+ </method>
+ <method name="is_physics_processing_internal" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_processing" qualifiers="const">
<return type="bool">
</return>
@@ -666,23 +666,6 @@
A node can contain a filename. This filename should not be changed by the user, unless writing editors and tools. When a scene is instanced from a file, it topmost node contains the filename from where it was loaded.
</description>
</method>
- <method name="set_fixed_process">
- <return type="void">
- </return>
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Enables or disables node fixed framerate processing. When a node is being processed, it will receive a NOTIFICATION_PROCESS at a fixed (usually 60 fps, check [OS] to change that) interval (and the [method _fixed_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_fixed_process_delta_time].
- </description>
- </method>
- <method name="set_fixed_process_internal">
- <return type="void">
- </return>
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- </description>
- </method>
<method name="set_name">
<return type="void">
</return>
@@ -720,6 +703,23 @@
Set pause mode (PAUSE_MODE_*) of this Node.
</description>
</method>
+ <method name="set_physics_process">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ Enables or disables the node's physics (alias fixed framerate) processing. When a node is being processed, it will receive a NOTIFICATION_PHYSICS_PROCESS at a fixed (usually 60 fps, check [OS] to change that) interval (and the [method _physics_process] callback will be called if exists). It is common to check how much time was elapsed since the previous frame by calling [method get_physics_process_delta_time].
+ </description>
+ </method>
+ <method name="set_physics_process_internal">
+ <return type="void">
+ </return>
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_process">
<return type="void">
</return>
@@ -806,7 +806,8 @@
</constant>
<constant name="NOTIFICATION_READY" value="13" enum="">
</constant>
- <constant name="NOTIFICATION_FIXED_PROCESS" value="16" enum="">
+ <constant name="NOTIFICATION_PHYSICS_PROCESS" value="16" enum="">
+ Notification received every frame when the physics process flag is set (see [method set_physics_process]).
</constant>
<constant name="NOTIFICATION_PROCESS" value="17" enum="">
Notification received every frame when the process flag is set (see [method set_process]).
@@ -833,7 +834,7 @@
</constant>
<constant name="NOTIFICATION_INTERNAL_PROCESS" value="25" enum="">
</constant>
- <constant name="NOTIFICATION_INTERNAL_FIXED_PROCESS" value="26" enum="">
+ <constant name="NOTIFICATION_INTERNAL_PHYSICS_PROCESS" value="26" enum="">
</constant>
<constant name="RPC_MODE_DISABLED" value="0">
</constant>
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index f78821e158..73b424eb12 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -397,6 +397,12 @@
You can pass the output from [method get_datetime_from_unix_time] directly into this function. Daylight savings time (dst), if present, is ignored.
</description>
</method>
+ <method name="get_virtual_keyboard_height">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_window_position" qualifiers="const">
<return type="Vector2">
</return>
@@ -420,6 +426,14 @@
Returns [code]true[/code] if an environment variable exists.
</description>
</method>
+ <method name="has_feature" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="tag_name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="has_touchscreen_ui_hint" qualifiers="const">
<return type="bool">
</return>
@@ -468,7 +482,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the "Okay" button should appear on the left and "Cancel" on the right.
+ Returns [code]true[/code] if the "Okay" button should appear on the left and "Cancel" on the right.
</description>
</method>
<method name="is_scancode_unicode" qualifiers="const">
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index 67421487f1..d30ebfaef8 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -6,7 +6,7 @@
<description>
Base class for all non built-in types. Everything not a built-in type starts the inheritance chain from this class.
Objects do not manage memory, if inheriting from one the object will most likely have to be deleted manually (call the [method free] function from the script or delete from C++).
- Some derivates add memory management, such as [Reference] (which keeps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
+ Some derivatives add memory management, such as [Reference] (which keeps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them.
Objects also receive notifications ([method _notification]). Notifications are a simple way to notify the object about simple events, so they can all be handled together.
</description>
@@ -165,7 +165,7 @@
<return type="Array">
</return>
<description>
- Returns an [Array] of dictionaries with informations about signals that are connected to this object.
+ Returns an [Array] of dictionaries with information about signals that are connected to this object.
Inside each [Dictionary] there are 3 fields:
- "source" is a reference to signal emitter.
- "signal_name" is name of connected signal.
diff --git a/doc/classes/Particles2D.xml b/doc/classes/Particles2D.xml
index b2c63ea0c3..cfc907b727 100644
--- a/doc/classes/Particles2D.xml
+++ b/doc/classes/Particles2D.xml
@@ -286,7 +286,7 @@
</methods>
<members>
<member name="amount" type="int" setter="set_amount" getter="get_amount">
- Number of particles to emit.
+ Number of particles emitted in one emission cycle.
</member>
<member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" enum="Particles2D.DrawOrder">
Particle draw order. Uses [code]DRAW_ORDER_*[/code] values. Default value: [code]DRAW_ORDER_INDEX[/code].
@@ -295,7 +295,7 @@
If [code]true[/code] particles are being emitted. Default value: [code]true[/code].
</member>
<member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio">
- Time ratio between each emission. If [code]0[/code] particles are emitted continuously. If [code]1[/code] all particles are emitted simultaneously. Default value: [code]0[/code].
+ How rapidly particles in an emission cycle are emitted. If greater than [code]0[/code], there will be a gap in emissions before the next cycle begins. Default value: [code]0[/code].
</member>
<member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps">
</member>
@@ -313,18 +313,19 @@
<member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map">
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot">
- If [code]true[/code] only [code]amount[/code] particles will be emitted. Default value: [code]false[/code].
+ 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. Default value: [code]false[/code].
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time">
+ Particle system starts as if it had already run for this many seconds.
</member>
<member name="process_material" type="Material" setter="set_process_material" getter="get_process_material">
[Material] for processing particles. Can be a [ParticlesMaterial] or a [ShaderMaterial].
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio">
- Emission randomness ratio. Default value: [code]0[/code].
+ Emission lifetime randomness ratio. Default value: [code]0[/code].
</member>
<member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale">
- Speed scaling ratio. Default value: [code]1[/code].
+ Particle system's running speed scaling ratio. Default value: [code]1[/code].
</member>
<member name="texture" type="Texture" setter="set_texture" getter="get_texture">
Particle texture. If [code]null[/code] particles will be squares.
@@ -333,6 +334,7 @@
Number of vertical frames in [code]texture[/code].
</member>
<member name="visibility_rect" type="Rect2" setter="set_visibility_rect" getter="get_visibility_rect">
+ Editor visibility helper.
</member>
</members>
<constants>
diff --git a/doc/classes/Performance.xml b/doc/classes/Performance.xml
index 82ee3531f1..2dc3aa239b 100644
--- a/doc/classes/Performance.xml
+++ b/doc/classes/Performance.xml
@@ -77,6 +77,8 @@
<constant name="RENDER_DRAW_CALLS_IN_FRAME" value="16">
Draw calls per frame. 3D only.
</constant>
+ <constant name="RENDER_USAGE_VIDEO_MEM_TOTAL" value="20">
+ </constant>
<constant name="RENDER_VIDEO_MEM_USED" value="17">
Video memory used. Includes both texture and vertex memory.
</constant>
@@ -86,8 +88,6 @@
<constant name="RENDER_VERTEX_MEM_USED" value="19">
Vertex memory used.
</constant>
- <constant name="RENDER_USAGE_VIDEO_MEM_TOTAL" value="20">
- </constant>
<constant name="PHYSICS_2D_ACTIVE_OBJECTS" value="21">
Number of active [RigidBody2D] nodes in the game.
</constant>
diff --git a/doc/classes/Physics2DServer.xml b/doc/classes/Physics2DServer.xml
index fd093edc84..edc46a53d0 100644
--- a/doc/classes/Physics2DServer.xml
+++ b/doc/classes/Physics2DServer.xml
@@ -21,7 +21,7 @@
<argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
</argument>
<description>
- Add a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
+ Adds a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="area_attach_object_instance_id">
@@ -32,7 +32,7 @@
<argument index="1" name="id" type="int">
</argument>
<description>
- Assign the area to a descendant of [Object], so it can exist in the node tree.
+ Assigns the area to a descendant of [Object], so it can exist in the node tree.
</description>
</method>
<method name="area_clear_shapes">
@@ -41,14 +41,14 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Remove all shapes from an area. It does not delete the shapes, so they can be reassigned later.
+ Removes all shapes from an area. It does not delete the shapes, so they can be reassigned later.
</description>
</method>
<method name="area_create">
<return type="RID">
</return>
<description>
- Create an [Area2D].
+ Creates an [Area2D].
</description>
</method>
<method name="area_get_object_instance_id" qualifiers="const">
@@ -57,7 +57,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Get the instance ID of the object the area is assigned to.
+ Gets the instance ID of the object the area is assigned to.
</description>
</method>
<method name="area_get_param" qualifiers="const">
@@ -68,7 +68,7 @@
<argument index="1" name="param" type="int" enum="Physics2DServer.AreaParameter">
</argument>
<description>
- Return an area parameter value.
+ Returns an area parameter value. A list of available parameters is on the AREA_PARAM_* constants.
</description>
</method>
<method name="area_get_shape" qualifiers="const">
@@ -79,7 +79,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Return the [RID] of the nth shape of an area.
+ Returns the [RID] of the nth shape of an area.
</description>
</method>
<method name="area_get_shape_count" qualifiers="const">
@@ -88,7 +88,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Return the number of shapes assigned to an area.
+ Returns the number of shapes assigned to an area.
</description>
</method>
<method name="area_get_shape_transform" qualifiers="const">
@@ -99,7 +99,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Return the transform matrix of a shape within an area.
+ Returns the transform matrix of a shape within an area.
</description>
</method>
<method name="area_get_space" qualifiers="const">
@@ -108,7 +108,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Return the space assigned to the area.
+ Returns the space assigned to the area.
</description>
</method>
<method name="area_get_space_override_mode" qualifiers="const">
@@ -117,7 +117,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Return the space override mode for the area.
+ Returns the space override mode for the area.
</description>
</method>
<method name="area_get_transform" qualifiers="const">
@@ -126,7 +126,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- Return the transform matrix for an area.
+ Returns the transform matrix for an area.
</description>
</method>
<method name="area_remove_shape">
@@ -137,7 +137,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Remove a shape from an area. It does not delete the shape, so it can be reassigned later.
+ Removes a shape from an area. It does not delete the shape, so it can be reassigned later.
</description>
</method>
<method name="area_set_collision_layer">
@@ -148,7 +148,7 @@
<argument index="1" name="layer" type="int">
</argument>
<description>
- Assign the area to one or many physics layers.
+ Assigns the area to one or many physics layers.
</description>
</method>
<method name="area_set_collision_mask">
@@ -159,7 +159,7 @@
<argument index="1" name="mask" type="int">
</argument>
<description>
- Set which physics layers the area will monitor.
+ Sets which physics layers the area will monitor.
</description>
</method>
<method name="area_set_monitor_callback">
@@ -172,7 +172,7 @@
<argument index="2" name="method" type="String">
</argument>
<description>
- Set the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters:
+ Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters:
1: AREA_BODY_ADDED or AREA_BODY_REMOVED, depending on whether the object entered or exited the area.
2: [RID] of the object that entered/exited the area.
3: Instance ID of the object that entered/exited the area.
@@ -190,7 +190,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
- Set the value for an area parameter. A list of available parameters is on the AREA_PARAM_* constants.
+ Sets the value for an area parameter. A list of available parameters is on the AREA_PARAM_* constants.
</description>
</method>
<method name="area_set_shape">
@@ -203,7 +203,7 @@
<argument index="2" name="shape" type="RID">
</argument>
<description>
- Substitute a given area shape by another. The old shape is selected by its index, the new one by its [RID].
+ Substitutes a given area shape by another. The old shape is selected by its index, the new one by its [RID].
</description>
</method>
<method name="area_set_shape_disabled">
@@ -216,6 +216,7 @@
<argument index="2" name="disable" type="bool">
</argument>
<description>
+ Disables a given shape in this area if [code]disable is true[/code]
</description>
</method>
<method name="area_set_shape_transform">
@@ -228,7 +229,7 @@
<argument index="2" name="transform" type="Transform2D">
</argument>
<description>
- Set the transform matrix for an area shape.
+ Sets the transform matrix for an area shape.
</description>
</method>
<method name="area_set_space">
@@ -239,7 +240,7 @@
<argument index="1" name="space" type="RID">
</argument>
<description>
- Assign a space to the area.
+ Assigns a space to the area.
</description>
</method>
<method name="area_set_space_override_mode">
@@ -250,7 +251,7 @@
<argument index="1" name="mode" type="int" enum="Physics2DServer.AreaSpaceOverrideMode">
</argument>
<description>
- Set the space override mode for the area. The modes are described in the constants AREA_SPACE_OVERRIDE_*.
+ Sets the space override mode for the area. The modes are described in the constants AREA_SPACE_OVERRIDE_*.
</description>
</method>
<method name="area_set_transform">
@@ -261,7 +262,7 @@
<argument index="1" name="transform" type="Transform2D">
</argument>
<description>
- Set the transform matrix for an area.
+ Sets the transform matrix for an area.
</description>
</method>
<method name="body_add_collision_exception">
@@ -272,7 +273,7 @@
<argument index="1" name="excepted_body" type="RID">
</argument>
<description>
- Add a body to the list of bodies exempt from collisions.
+ Adds a body to the list of bodies exempt from collisions.
</description>
</method>
<method name="body_add_force">
@@ -285,7 +286,7 @@
<argument index="2" name="force" type="Vector2">
</argument>
<description>
- Add a positioned force to the applied force and torque. As with [method body_apply_impulse], both the force and the offset from the body origin are in global coordinates. A force differs from an impulse in that, while the two are forces, the impulse clears itself after being applied.
+ Adds a positioned force to the applied force and torque. As with [method body_apply_impulse], both the force and the offset from the body origin are in global coordinates. A force differs from an impulse in that, while the two are forces, the impulse clears itself after being applied.
</description>
</method>
<method name="body_add_shape">
@@ -298,7 +299,7 @@
<argument index="2" name="transform" type="Transform2D" default="Transform2D( 1, 0, 0, 1, 0, 0 )">
</argument>
<description>
- Add a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
+ Adds a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="body_apply_impulse">
@@ -311,7 +312,7 @@
<argument index="2" name="impulse" type="Vector2">
</argument>
<description>
- Add a positioned impulse to the applied force and torque. Both the force and the offset from the body origin are in global coordinates.
+ Adds a positioned impulse to the applied force and torque. Both the force and the offset from the body origin are in global coordinates.
</description>
</method>
<method name="body_attach_object_instance_id">
@@ -322,7 +323,7 @@
<argument index="1" name="id" type="int">
</argument>
<description>
- Assign the area to a descendant of [Object], so it can exist in the node tree.
+ Assigns the area to a descendant of [Object], so it can exist in the node tree.
</description>
</method>
<method name="body_clear_shapes">
@@ -331,7 +332,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Remove all shapes from a body.
+ Removes all shapes from a body.
</description>
</method>
<method name="body_create">
@@ -342,7 +343,7 @@
<argument index="1" name="init_sleeping" type="bool" default="false">
</argument>
<description>
- Create a physics body. The first parameter can be any value from constants BODY_MODE*, for the type of body created. Additionally, the body can be created in sleeping state to save processing time.
+ Creates a physics body. The first parameter can be any value from constants BODY_MODE*, for the type of body created. Additionally, the body can be created in sleeping state to save processing time.
</description>
</method>
<method name="body_get_collision_layer" qualifiers="const">
@@ -351,7 +352,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the physics layer or layers a body belongs to.
+ Returns the physics layer or layers a body belongs to.
</description>
</method>
<method name="body_get_collision_mask" qualifiers="const">
@@ -360,7 +361,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the physics layer or layers a body can collide with.
+ Returns the physics layer or layers a body can collide with.
</description>
</method>
<method name="body_get_continuous_collision_detection_mode" qualifiers="const">
@@ -369,7 +370,16 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the continuous collision detection mode.
+ Returns the continuous collision detection mode.
+ </description>
+ </method>
+ <method name="body_get_direct_state">
+ <return type="Physics2DDirectBodyState">
+ </return>
+ <argument index="0" name="body" type="RID">
+ </argument>
+ <description>
+ Returns the [Physics2DDirectBodyState] of the body.
</description>
</method>
<method name="body_get_max_contacts_reported" qualifiers="const">
@@ -378,7 +388,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the maximum contacts that can be reported. See [method body_set_max_contacts_reported].
+ Returns the maximum contacts that can be reported. See [method body_set_max_contacts_reported].
</description>
</method>
<method name="body_get_mode" qualifiers="const">
@@ -387,7 +397,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the body mode.
+ Returns the body mode.
</description>
</method>
<method name="body_get_object_instance_id" qualifiers="const">
@@ -396,7 +406,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Get the instance ID of the object the area is assigned to.
+ Gets the instance ID of the object the area is assigned to.
</description>
</method>
<method name="body_get_param" qualifiers="const">
@@ -407,7 +417,7 @@
<argument index="1" name="param" type="int" enum="Physics2DServer.BodyParameter">
</argument>
<description>
- Return the value of a body parameter.
+ Returns the value of a body parameter. A list of available parameters is on the BODY_PARAM_* constants.
</description>
</method>
<method name="body_get_shape" qualifiers="const">
@@ -418,7 +428,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Return the [RID] of the nth shape of a body.
+ Returns the [RID] of the nth shape of a body.
</description>
</method>
<method name="body_get_shape_count" qualifiers="const">
@@ -427,7 +437,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the number of shapes assigned to a body.
+ Returns the number of shapes assigned to a body.
</description>
</method>
<method name="body_get_shape_metadata" qualifiers="const">
@@ -438,7 +448,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Return the metadata of a shape of a body.
+ Returns the metadata of a shape of a body.
</description>
</method>
<method name="body_get_shape_transform" qualifiers="const">
@@ -449,7 +459,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Return the transform matrix of a body shape.
+ Returns the transform matrix of a body shape.
</description>
</method>
<method name="body_get_space" qualifiers="const">
@@ -458,7 +468,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the [RID] of the space assigned to a body.
+ Returns the [RID] of the space assigned to a body.
</description>
</method>
<method name="body_get_state" qualifiers="const">
@@ -469,7 +479,7 @@
<argument index="1" name="state" type="int" enum="Physics2DServer.BodyState">
</argument>
<description>
- Return a body state.
+ Returns a body state.
</description>
</method>
<method name="body_is_omitting_force_integration" qualifiers="const">
@@ -478,7 +488,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
+ Returns whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
</description>
</method>
<method name="body_remove_collision_exception">
@@ -489,7 +499,7 @@
<argument index="1" name="excepted_body" type="RID">
</argument>
<description>
- Remove a body from the list of bodies exempt from collisions.
+ Removes a body from the list of bodies exempt from collisions.
</description>
</method>
<method name="body_remove_shape">
@@ -500,7 +510,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
- Remove a shape from a body. The shape is not deleted, so it can be reused afterwards.
+ Removes a shape from a body. The shape is not deleted, so it can be reused afterwards.
</description>
</method>
<method name="body_set_axis_velocity">
@@ -511,7 +521,7 @@
<argument index="1" name="axis_velocity" type="Vector2">
</argument>
<description>
- Set an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
+ Sets an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
</description>
</method>
<method name="body_set_collision_layer">
@@ -522,7 +532,7 @@
<argument index="1" name="layer" type="int">
</argument>
<description>
- Set the physics layer or layers a body belongs to.
+ Sets the physics layer or layers a body belongs to.
</description>
</method>
<method name="body_set_collision_mask">
@@ -533,7 +543,7 @@
<argument index="1" name="mask" type="int">
</argument>
<description>
- Set the physics layer or layers a body can collide with.
+ Sets the physics layer or layers a body can collide with.
</description>
</method>
<method name="body_set_continuous_collision_detection_mode">
@@ -544,7 +554,7 @@
<argument index="1" name="mode" type="int" enum="Physics2DServer.CCDMode">
</argument>
<description>
- Set the continuous collision detection mode from any of the CCD_MODE_* constants.
+ Sets the continuous collision detection mode from any of the CCD_MODE_* constants.
Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided.
</description>
</method>
@@ -560,7 +570,7 @@
<argument index="3" name="userdata" type="Variant" default="null">
</argument>
<description>
- Set the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force integration]).
+ Sets the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force integration]).
</description>
</method>
<method name="body_set_max_contacts_reported">
@@ -571,7 +581,7 @@
<argument index="1" name="amount" type="int">
</argument>
<description>
- Set the maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0.
+ Sets the maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0.
</description>
</method>
<method name="body_set_mode">
@@ -582,7 +592,7 @@
<argument index="1" name="mode" type="int" enum="Physics2DServer.BodyMode">
</argument>
<description>
- Set the body mode, from one of the constants BODY_MODE*.
+ Sets the body mode, from one of the constants BODY_MODE*.
</description>
</method>
<method name="body_set_omit_force_integration">
@@ -593,7 +603,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- Set whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
+ Sets whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
</description>
</method>
<method name="body_set_param">
@@ -606,7 +616,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
- Set a body parameter (see BODY_PARAM* constants).
+ Sets a body parameter. A list of available parameters is on the BODY_PARAM_* constants.
</description>
</method>
<method name="body_set_shape">
@@ -619,7 +629,7 @@
<argument index="2" name="shape" type="RID">
</argument>
<description>
- Substitute a given body shape by another. The old shape is selected by its index, the new one by its [RID].
+ Substitutes a given body shape by another. The old shape is selected by its index, the new one by its [RID].
</description>
</method>
<method name="body_set_shape_as_one_way_collision">
@@ -632,6 +642,7 @@
<argument index="2" name="enable" type="bool">
</argument>
<description>
+ Enables one way collision on body if [code]enable is true[/code].
</description>
</method>
<method name="body_set_shape_disabled">
@@ -644,6 +655,7 @@
<argument index="2" name="disable" type="bool">
</argument>
<description>
+ Disables shape in body if [code]disable is true[/code].
</description>
</method>
<method name="body_set_shape_metadata">
@@ -656,7 +668,7 @@
<argument index="2" name="metadata" type="Variant">
</argument>
<description>
- Set metadata of a shape within a body. This metadata is different from [method Object.set_meta], and can be retrieved on shape queries.
+ Sets metadata of a shape within a body. This metadata is different from [method Object.set_meta], and can be retrieved on shape queries.
</description>
</method>
<method name="body_set_shape_transform">
@@ -669,7 +681,7 @@
<argument index="2" name="transform" type="Transform2D">
</argument>
<description>
- Set the transform matrix for a body shape.
+ Sets the transform matrix for a body shape.
</description>
</method>
<method name="body_set_space">
@@ -680,7 +692,7 @@
<argument index="1" name="space" type="RID">
</argument>
<description>
- Assign a space to the body (see [method create_space]).
+ Assigns a space to the body (see [method create_space]).
</description>
</method>
<method name="body_set_state">
@@ -693,7 +705,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
- Set a body state (see BODY_STATE* constants).
+ Sets a body state (see BODY_STATE* constants).
</description>
</method>
<method name="body_test_motion">
@@ -710,7 +722,7 @@
<argument index="4" name="result" type="Physics2DTestMotionResult" default="null">
</argument>
<description>
- Return whether a body can move from a given point in a given direction. Apart from the boolean return value, a [Physics2DTestMotionResult] can be passed to return additional information in.
+ Returns whether a body can move from a given point in a given direction. Apart from the boolean return value, a [Physics2DTestMotionResult] can be passed to return additional information in.
</description>
</method>
<method name="damped_spring_joint_create">
@@ -725,7 +737,7 @@
<argument index="3" name="body_b" type="RID">
</argument>
<description>
- Create a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself.
+ Creates a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself.
</description>
</method>
<method name="damped_string_joint_get_param" qualifiers="const">
@@ -736,7 +748,7 @@
<argument index="1" name="param" type="int" enum="Physics2DServer.DampedStringParam">
</argument>
<description>
- Return the value of a damped spring joint parameter.
+ Returns the value of a damped spring joint parameter.
</description>
</method>
<method name="damped_string_joint_set_param">
@@ -749,7 +761,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
- Set a damped spring joint parameter. Parameters are explained in the DAMPED_STRING* constants.
+ Sets a damped spring joint parameter. Parameters are explained in the DAMPED_STRING* constants.
</description>
</method>
<method name="free_rid">
@@ -758,7 +770,7 @@
<argument index="0" name="rid" type="RID">
</argument>
<description>
- Destroy any of the objects created by Physics2DServer. If the [RID] passed is not one of the objects that can be created by Physics2DServer, an error will be sent to the console.
+ Destroys any of the objects created by Physics2DServer. If the [RID] passed is not one of the objects that can be created by Physics2DServer, an error will be sent to the console.
</description>
</method>
<method name="get_process_info">
@@ -767,7 +779,7 @@
<argument index="0" name="process_info" type="int" enum="Physics2DServer.ProcessInfo">
</argument>
<description>
- Return information about the current state of the 2D physics engine. The states are listed under the INFO_* constants.
+ Returns information about the current state of the 2D physics engine. The states are listed under the INFO_* constants.
</description>
</method>
<method name="groove_joint_create">
@@ -784,7 +796,7 @@
<argument index="4" name="body_b" type="RID">
</argument>
<description>
- Create a groove joint between two bodies. If not specified, the bodyies are assumed to be the joint itself.
+ Creates a groove joint between two bodies. If not specified, the bodyies are assumed to be the joint itself.
</description>
</method>
<method name="joint_get_param" qualifiers="const">
@@ -795,7 +807,7 @@
<argument index="1" name="param" type="int" enum="Physics2DServer.JointParam">
</argument>
<description>
- Return the value of a joint parameter.
+ Returns the value of a joint parameter.
</description>
</method>
<method name="joint_get_type" qualifiers="const">
@@ -804,7 +816,7 @@
<argument index="0" name="joint" type="RID">
</argument>
<description>
- Return the type of a joint (see JOINT_* constants).
+ Returns the type of a joint (see JOINT_* constants).
</description>
</method>
<method name="joint_set_param">
@@ -817,7 +829,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
- Set a joint parameter. Parameters are explained in the JOINT_PARAM* constants.
+ Sets a joint parameter. Parameters are explained in the JOINT_PARAM* constants.
</description>
</method>
<method name="pin_joint_create">
@@ -830,7 +842,7 @@
<argument index="2" name="body_b" type="RID">
</argument>
<description>
- Create a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself.
+ Creates a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself.
</description>
</method>
<method name="set_active">
@@ -839,7 +851,7 @@
<argument index="0" name="active" type="bool">
</argument>
<description>
- Activate or deactivate the 2D physics engine.
+ Activates or deactivates the 2D physics engine.
</description>
</method>
<method name="shape_create">
@@ -848,7 +860,7 @@
<argument index="0" name="type" type="int" enum="Physics2DServer.ShapeType">
</argument>
<description>
- Create a shape of type SHAPE_*. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape].
+ Creates a shape of type SHAPE_*. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape].
</description>
</method>
<method name="shape_get_data" qualifiers="const">
@@ -857,7 +869,7 @@
<argument index="0" name="shape" type="RID">
</argument>
<description>
- Return the shape data.
+ Returns the shape data.
</description>
</method>
<method name="shape_get_type" qualifiers="const">
@@ -866,7 +878,7 @@
<argument index="0" name="shape" type="RID">
</argument>
<description>
- Return the type of shape (see SHAPE_* constants).
+ Returns the type of shape (see SHAPE_* constants).
</description>
</method>
<method name="shape_set_data">
@@ -877,14 +889,14 @@
<argument index="1" name="data" type="Variant">
</argument>
<description>
- Set the shape data that defines its shape and size. The data to be passed depends on the kind of shape created [method shape_get_type].
+ Sets the shape data that defines its shape and size. The data to be passed depends on the kind of shape created [method shape_get_type].
</description>
</method>
<method name="space_create">
<return type="RID">
</return>
<description>
- Create a space. A space is a collection of parameters for the physics engine that can be assigned to an area or a body. It can be assigned to an area with [method area_set_space], or to a body with [method body_set_space].
+ Creates a space. A space is a collection of parameters for the physics engine that can be assigned to an area or a body. It can be assigned to an area with [method area_set_space], or to a body with [method body_set_space].
</description>
</method>
<method name="space_get_direct_state">
@@ -893,7 +905,7 @@
<argument index="0" name="space" type="RID">
</argument>
<description>
- Return the state of a space, a [Physics2DDirectSpaceState]. This object can be used to make collision/intersection queries.
+ Returns the state of a space, a [Physics2DDirectSpaceState]. This object can be used to make collision/intersection queries.
</description>
</method>
<method name="space_get_param" qualifiers="const">
@@ -904,7 +916,7 @@
<argument index="1" name="param" type="int" enum="Physics2DServer.SpaceParameter">
</argument>
<description>
- Return the value of a space parameter.
+ Returns the value of a space parameter.
</description>
</method>
<method name="space_is_active" qualifiers="const">
@@ -913,7 +925,7 @@
<argument index="0" name="space" type="RID">
</argument>
<description>
- Return whether the space is active.
+ Returns whether the space is active.
</description>
</method>
<method name="space_set_active">
@@ -924,7 +936,7 @@
<argument index="1" name="active" type="bool">
</argument>
<description>
- Mark a space as active. It will not have an effect, unless it is assigned to an area or body.
+ Marks a space as active. It will not have an effect, unless it is assigned to an area or body.
</description>
</method>
<method name="space_set_param">
@@ -937,7 +949,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
- Set the value for a space parameter. A list of available parameters is on the SPACE_PARAM_* constants.
+ Sets the value for a space parameter. A list of available parameters is on the SPACE_PARAM_* constants.
</description>
</method>
</methods>
@@ -952,8 +964,10 @@
Constant to set/get the maximum distance a shape can penetrate another shape before it is considered a collision.
</constant>
<constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="3">
+ Constant to set/get the threshold linear velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
<constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="4">
+ Constant to set/get the threshold angular velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
<constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="5">
Constant to set/get the maximum time of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after this time.
@@ -977,7 +991,7 @@
This is the constant for creating capsule shapes. A capsule shape is defined by a radius and a length. It can be used for intersections and inside/outside checks.
</constant>
<constant name="SHAPE_CONVEX_POLYGON" value="6">
- This is the constant for creating convex polygon shapes. A polygon is defined by a list of points. It can be used for intersections and inside/outside checks. Unlike the method [method CollisionPolygon2D.set_polygon], polygons modified with [method shape_set_data] do not verify that the points supplied form, in fact, a convex polygon.
+ This is the constant for creating convex polygon shapes. A polygon is defined by a list of points. It can be used for intersections and inside/outside checks. Unlike the method [method CollisionPolygon2D.set_polygon], polygons modified with [method shape_set_data] do not verify that the points supplied form is a convex polygon.
</constant>
<constant name="SHAPE_CONCAVE_POLYGON" value="7">
This is the constant for creating concave polygon shapes. A polygon is defined by a list of points. It can be used for intersections checks, but not for inside/outside checks.
diff --git a/doc/classes/Physics2DServerSW.xml b/doc/classes/Physics2DServerSW.xml
index a8645c0b96..67fd7a21d8 100644
--- a/doc/classes/Physics2DServerSW.xml
+++ b/doc/classes/Physics2DServerSW.xml
@@ -4,7 +4,7 @@
Software implementation of [Physics2DServer].
</brief_description>
<description>
- Software implementation of [Physics2DServer]. This class exposes no new methods or properties and should not be used, as [Physics2DServer] automatically selects the best implementation available.
+ This class exposes no new methods or properties and should not be used, as [Physics2DServer] automatically selects the best implementation available.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/Physics2DShapeQueryParameters.xml b/doc/classes/Physics2DShapeQueryParameters.xml
index 78d12e0b73..d838ff2317 100644
--- a/doc/classes/Physics2DShapeQueryParameters.xml
+++ b/doc/classes/Physics2DShapeQueryParameters.xml
@@ -129,7 +129,7 @@
<argument index="0" name="transform" type="Transform2D">
</argument>
<description>
- Set the transormation matrix of the shape. This is necessary to set its position/rotation/scale.
+ Set the transformation matrix of the shape. This is necessary to set its position/rotation/scale.
</description>
</method>
</methods>
diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml
index 145f5a0163..12c1abccc6 100644
--- a/doc/classes/PhysicsServer.xml
+++ b/doc/classes/PhysicsServer.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServer" inherits="Object" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Server interface for low level physics access.
</brief_description>
<description>
+ Everything related to physics in 3D.
</description>
<tutorials>
</tutorials>
@@ -19,6 +21,7 @@
<argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
</argument>
<description>
+ Adds a shape to the area, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="area_attach_object_instance_id">
@@ -29,6 +32,7 @@
<argument index="1" name="id" type="int">
</argument>
<description>
+ Assigns the area to a descendant of [Object], so it can exist in the node tree.
</description>
</method>
<method name="area_clear_shapes">
@@ -37,12 +41,14 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Removes all shapes from an area. It does not delete the shapes, so they can be reassigned later.
</description>
</method>
<method name="area_create">
<return type="RID">
</return>
<description>
+ Creates an [Area].
</description>
</method>
<method name="area_get_object_instance_id" qualifiers="const">
@@ -51,6 +57,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Gets the instance ID of the object the area is assigned to.
</description>
</method>
<method name="area_get_param" qualifiers="const">
@@ -61,6 +68,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.AreaParameter">
</argument>
<description>
+ Returns an area parameter value. A list of available parameters is on the AREA_PARAM_* constants.
</description>
</method>
<method name="area_get_shape" qualifiers="const">
@@ -71,6 +79,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Returns the [RID] of the nth shape of an area.
</description>
</method>
<method name="area_get_shape_count" qualifiers="const">
@@ -79,6 +88,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Returns the number of shapes assigned to an area.
</description>
</method>
<method name="area_get_shape_transform" qualifiers="const">
@@ -89,6 +99,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Returns the transform matrix of a shape within an area.
</description>
</method>
<method name="area_get_space" qualifiers="const">
@@ -97,6 +108,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Returns the space assigned to the area.
</description>
</method>
<method name="area_get_space_override_mode" qualifiers="const">
@@ -105,6 +117,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Returns the space override mode for the area.
</description>
</method>
<method name="area_get_transform" qualifiers="const">
@@ -113,6 +126,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ Returns the transform matrix for an area.
</description>
</method>
<method name="area_is_ray_pickable" qualifiers="const">
@@ -121,6 +135,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
+ If [code]true[/code] area collides with rays.
</description>
</method>
<method name="area_remove_shape">
@@ -131,6 +146,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Removes a shape from an area. It does not delete the shape, so it can be reassigned later.
</description>
</method>
<method name="area_set_collision_layer">
@@ -141,6 +157,7 @@
<argument index="1" name="layer" type="int">
</argument>
<description>
+ Assigns the area to one or many physics layers.
</description>
</method>
<method name="area_set_collision_mask">
@@ -151,6 +168,7 @@
<argument index="1" name="mask" type="int">
</argument>
<description>
+ Sets which physics layers the area will monitor.
</description>
</method>
<method name="area_set_monitor_callback">
@@ -163,6 +181,12 @@
<argument index="2" name="method" type="String">
</argument>
<description>
+ Sets the function to call when any body/area enters or exits the area. This callback will be called for any object interacting with the area, and takes five parameters:
+ 1: AREA_BODY_ADDED or AREA_BODY_REMOVED, depending on whether the object entered or exited the area.
+ 2: [RID] of the object that entered/exited the area.
+ 3: Instance ID of the object that entered/exited the area.
+ 4: The shape index of the object that entered/exited the area.
+ 5: The shape index of the area where the object entered/exited.
</description>
</method>
<method name="area_set_param">
@@ -175,6 +199,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Sets the value for an area parameter. A list of available parameters is on the AREA_PARAM_* constants.
</description>
</method>
<method name="area_set_ray_pickable">
@@ -185,6 +210,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
+ Sets object pickable with rays.
</description>
</method>
<method name="area_set_shape">
@@ -197,6 +223,7 @@
<argument index="2" name="shape" type="RID">
</argument>
<description>
+ Substitutes a given area shape by another. The old shape is selected by its index, the new one by its [RID].
</description>
</method>
<method name="area_set_shape_transform">
@@ -209,6 +236,7 @@
<argument index="2" name="transform" type="Transform">
</argument>
<description>
+ Sets the transform matrix for an area shape.
</description>
</method>
<method name="area_set_space">
@@ -219,6 +247,7 @@
<argument index="1" name="space" type="RID">
</argument>
<description>
+ Assigns a space to the area.
</description>
</method>
<method name="area_set_space_override_mode">
@@ -229,6 +258,7 @@
<argument index="1" name="mode" type="int" enum="PhysicsServer.AreaSpaceOverrideMode">
</argument>
<description>
+ Sets the space override mode for the area. The modes are described in the constants AREA_SPACE_OVERRIDE_*.
</description>
</method>
<method name="area_set_transform">
@@ -239,6 +269,7 @@
<argument index="1" name="transform" type="Transform">
</argument>
<description>
+ Sets the transform matrix for an area.
</description>
</method>
<method name="body_add_collision_exception">
@@ -249,6 +280,7 @@
<argument index="1" name="excepted_body" type="RID">
</argument>
<description>
+ Adds a body to the list of bodies exempt from collisions.
</description>
</method>
<method name="body_add_shape">
@@ -261,6 +293,7 @@
<argument index="2" name="transform" type="Transform" default="Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0 )">
</argument>
<description>
+ Adds a shape to the body, along with a transform matrix. Shapes are usually referenced by their index, so you should track which shape has a given index.
</description>
</method>
<method name="body_apply_impulse">
@@ -273,6 +306,7 @@
<argument index="2" name="impulse" type="Vector3">
</argument>
<description>
+ Gives the body a push at a [code]position[/code] in the direction of the [code]impulse[/code].
</description>
</method>
<method name="body_apply_torque_impulse">
@@ -283,6 +317,7 @@
<argument index="1" name="impulse" type="Vector3">
</argument>
<description>
+ Gives the body a push to rotate it.
</description>
</method>
<method name="body_attach_object_instance_id">
@@ -293,6 +328,7 @@
<argument index="1" name="id" type="int">
</argument>
<description>
+ Assigns the area to a descendant of [Object], so it can exist in the node tree.
</description>
</method>
<method name="body_clear_shapes">
@@ -301,6 +337,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Removes all shapes from a body.
</description>
</method>
<method name="body_create">
@@ -311,6 +348,7 @@
<argument index="1" name="init_sleeping" type="bool" default="false">
</argument>
<description>
+ Creates a physics body. The first parameter can be any value from constants BODY_MODE*, for the type of body created. Additionally, the body can be created in sleeping state to save processing time.
</description>
</method>
<method name="body_get_axis_lock" qualifiers="const">
@@ -319,6 +357,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Gets the information, which Axis is locked if any. The can be any calue from the constants BODY_AXIS_LOCK*
</description>
</method>
<method name="body_get_collision_layer" qualifiers="const">
@@ -327,6 +366,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the physics layer or layers a body belongs to.
</description>
</method>
<method name="body_get_collision_mask" qualifiers="const">
@@ -335,6 +375,16 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the physics layer or layers a body can collide with.
+- </description>
+- </method>
+- <method name="body_get_direct_state">
+- <return type="PhysicsDirectBodyState">
+- </return>
+- <argument index="0" name="body" type="RID">
+- </argument>
+- <description>
+ Returns the [PhysicsDirectBodyState] of the body.
</description>
</method>
<method name="body_get_max_contacts_reported" qualifiers="const">
@@ -343,6 +393,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the maximum contacts that can be reported. See [method body_set_max_contacts_reported].
</description>
</method>
<method name="body_get_mode" qualifiers="const">
@@ -351,6 +402,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the body mode.
</description>
</method>
<method name="body_get_object_instance_id" qualifiers="const">
@@ -359,6 +411,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Gets the instance ID of the object the area is assigned to.
</description>
</method>
<method name="body_get_param" qualifiers="const">
@@ -369,6 +422,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.BodyParameter">
</argument>
<description>
+ Returns the value of a body parameter. A list of available parameters is on the BODY_PARAM_* constants.
</description>
</method>
<method name="body_get_shape" qualifiers="const">
@@ -379,6 +433,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Returns the [RID] of the nth shape of a body.
</description>
</method>
<method name="body_get_shape_count" qualifiers="const">
@@ -387,6 +442,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the number of shapes assigned to a body.
</description>
</method>
<method name="body_get_shape_transform" qualifiers="const">
@@ -397,6 +453,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Returns the transform matrix of a body shape.
</description>
</method>
<method name="body_get_space" qualifiers="const">
@@ -405,6 +462,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns the [RID] of the space assigned to a body.
</description>
</method>
<method name="body_get_state" qualifiers="const">
@@ -415,6 +473,7 @@
<argument index="1" name="state" type="int" enum="PhysicsServer.BodyState">
</argument>
<description>
+ Returns a body state.
</description>
</method>
<method name="body_is_continuous_collision_detection_enabled" qualifiers="const">
@@ -423,6 +482,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ If [code]true[/code] the continuous collision detection mode is enabled.
</description>
</method>
<method name="body_is_omitting_force_integration" qualifiers="const">
@@ -431,6 +491,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ Returns whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
</description>
</method>
<method name="body_is_ray_pickable" qualifiers="const">
@@ -439,6 +500,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
+ If [code]true[/code] the body can be detected by rays
</description>
</method>
<method name="body_remove_collision_exception">
@@ -449,6 +511,8 @@
<argument index="1" name="excepted_body" type="RID">
</argument>
<description>
+ Removes a body from the list of bodies exempt from collisions.
+ Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided.
</description>
</method>
<method name="body_remove_shape">
@@ -459,6 +523,7 @@
<argument index="1" name="shape_idx" type="int">
</argument>
<description>
+ Removes a shape from a body. The shape is not deleted, so it can be reused afterwards.
</description>
</method>
<method name="body_set_axis_lock">
@@ -469,6 +534,7 @@
<argument index="1" name="axis" type="int" enum="PhysicsServer.BodyAxisLock">
</argument>
<description>
+ Locks velocity along one axis to 0 and only allows rotation along this axis, can also be set to disabled which disables this functionality.
</description>
</method>
<method name="body_set_axis_velocity">
@@ -479,6 +545,7 @@
<argument index="1" name="axis_velocity" type="Vector3">
</argument>
<description>
+ Sets an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
</description>
</method>
<method name="body_set_collision_layer">
@@ -489,6 +556,7 @@
<argument index="1" name="layer" type="int">
</argument>
<description>
+ Sets the physics layer or layers a body belongs to.
</description>
</method>
<method name="body_set_collision_mask">
@@ -499,6 +567,7 @@
<argument index="1" name="mask" type="int">
</argument>
<description>
+ Sets the physics layer or layers a body can collide with.
</description>
</method>
<method name="body_set_enable_continuous_collision_detection">
@@ -509,6 +578,8 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
+ If [code]true[/code] the continuous collision detection mode is enabled.
+ Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided.
</description>
</method>
<method name="body_set_force_integration_callback">
@@ -523,6 +594,7 @@
<argument index="3" name="userdata" type="Variant" default="null">
</argument>
<description>
+ Sets the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force integration]).
</description>
</method>
<method name="body_set_max_contacts_reported">
@@ -533,6 +605,7 @@
<argument index="1" name="amount" type="int">
</argument>
<description>
+ Sets the maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0.
</description>
</method>
<method name="body_set_mode">
@@ -543,6 +616,7 @@
<argument index="1" name="mode" type="int" enum="PhysicsServer.BodyMode">
</argument>
<description>
+ Sets the body mode, from one of the constants BODY_MODE*.
</description>
</method>
<method name="body_set_omit_force_integration">
@@ -553,6 +627,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
+ Sets whether a body uses a callback function to calculate its own physics (see [method body_set_force_integration_callback]).
</description>
</method>
<method name="body_set_param">
@@ -565,6 +640,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Sets a body parameter. A list of available parameters is on the BODY_PARAM_* constants.
</description>
</method>
<method name="body_set_ray_pickable">
@@ -575,6 +651,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
+ Sets the body pickable with rays if [code]enabled[/code] is set.
</description>
</method>
<method name="body_set_shape">
@@ -587,6 +664,7 @@
<argument index="2" name="shape" type="RID">
</argument>
<description>
+ Substitutes a given body shape by another. The old shape is selected by its index, the new one by its [RID].
</description>
</method>
<method name="body_set_shape_transform">
@@ -599,6 +677,7 @@
<argument index="2" name="transform" type="Transform">
</argument>
<description>
+ Sets the transform matrix for a body shape.
</description>
</method>
<method name="body_set_space">
@@ -609,6 +688,7 @@
<argument index="1" name="space" type="RID">
</argument>
<description>
+ Assigns a space to the body (see [method create_space]).
</description>
</method>
<method name="body_set_state">
@@ -621,6 +701,7 @@
<argument index="2" name="value" type="Variant">
</argument>
<description>
+ Sets a body state (see BODY_STATE* constants).
</description>
</method>
<method name="cone_twist_joint_get_param" qualifiers="const">
@@ -631,6 +712,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.ConeTwistJointParam">
</argument>
<description>
+ Gets a cone_twist_joint parameter (see CONE_TWIST_JOINT* constants).
</description>
</method>
<method name="cone_twist_joint_set_param">
@@ -643,6 +725,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Sets a cone_twist_joint parameter (see CONE_TWIST_JOINT* constants).
</description>
</method>
<method name="free_rid">
@@ -651,6 +734,7 @@
<argument index="0" name="rid" type="RID">
</argument>
<description>
+ Destroys any of the objects created by PhysicsServer. If the [RID] passed is not one of the objects that can be created by PhysicsServer, an error will be sent to the console.
</description>
</method>
<method name="generic_6dof_joint_get_flag">
@@ -662,7 +746,8 @@
</argument>
<argument index="2" name="flag" type="int" enum="PhysicsServer.G6DOFJointAxisFlag">
</argument>
- <description>
+ <description>
+ Gets a generic_6_DOF_joint flag (see G6DOF_JOINT_FLAG* constants).
</description>
</method>
<method name="generic_6dof_joint_get_param">
@@ -675,6 +760,7 @@
<argument index="2" name="param" type="int" enum="PhysicsServer.G6DOFJointAxisParam">
</argument>
<description>
+ Gets a generic_6_DOF_joint parameter (see G6DOF_JOINT* constants without the G6DOF_JOINT_FLAG*).
</description>
</method>
<method name="generic_6dof_joint_set_flag">
@@ -689,6 +775,7 @@
<argument index="3" name="enable" type="bool">
</argument>
<description>
+ Sets a generic_6_DOF_joint flag (see G6DOF_JOINT_FLAG* constants).
</description>
</method>
<method name="generic_6dof_joint_set_param">
@@ -703,6 +790,7 @@
<argument index="3" name="value" type="float">
</argument>
<description>
+ Sets a generic_6_DOF_joint parameter (see G6DOF_JOINT* constants without the G6DOF_JOINT_FLAG*).
</description>
</method>
<method name="get_process_info">
@@ -711,6 +799,7 @@
<argument index="0" name="process_info" type="int" enum="PhysicsServer.ProcessInfo">
</argument>
<description>
+ Returns an Info defined by the [ProcessInfo] input given.
</description>
</method>
<method name="hinge_joint_get_flag" qualifiers="const">
@@ -721,6 +810,7 @@
<argument index="1" name="flag" type="int" enum="PhysicsServer.HingeJointFlag">
</argument>
<description>
+ Gets a hinge_joint flag (see HINGE_JOINT_FLAG* constants).
</description>
</method>
<method name="hinge_joint_get_param" qualifiers="const">
@@ -731,6 +821,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.HingeJointParam">
</argument>
<description>
+ Gets a hinge_joint parameter (see HINGE_JOINT* constants without the HINGE_JOINT_FLAG*).
</description>
</method>
<method name="hinge_joint_set_flag">
@@ -743,6 +834,7 @@
<argument index="2" name="enabled" type="bool">
</argument>
<description>
+ Sets a hinge_joint flag (see HINGE_JOINT_FLAG* constants).
</description>
</method>
<method name="hinge_joint_set_param">
@@ -755,6 +847,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Sets a hinge_joint parameter (see HINGE_JOINT* constants without the HINGE_JOINT_FLAG*).
</description>
</method>
<method name="joint_create_cone_twist">
@@ -769,6 +862,7 @@
<argument index="3" name="local_ref_B" type="Transform">
</argument>
<description>
+ Creates a [ConeTwistJoint].
</description>
</method>
<method name="joint_create_generic_6dof">
@@ -783,6 +877,7 @@
<argument index="3" name="local_ref_B" type="Transform">
</argument>
<description>
+ Creates a [Generic6DOFJoint].
</description>
</method>
<method name="joint_create_hinge">
@@ -797,6 +892,7 @@
<argument index="3" name="hinge_B" type="Transform">
</argument>
<description>
+ Creates a [HingeJoint].
</description>
</method>
<method name="joint_create_pin">
@@ -811,6 +907,7 @@
<argument index="3" name="local_B" type="Vector3">
</argument>
<description>
+ Creates a [PinJoint].
</description>
</method>
<method name="joint_create_slider">
@@ -825,6 +922,7 @@
<argument index="3" name="local_ref_B" type="Transform">
</argument>
<description>
+ Creates a [SliderJoint].
</description>
</method>
<method name="joint_get_solver_priority" qualifiers="const">
@@ -833,6 +931,7 @@
<argument index="0" name="joint" type="RID">
</argument>
<description>
+ Gets the priority value of the Joint.
</description>
</method>
<method name="joint_get_type" qualifiers="const">
@@ -841,6 +940,7 @@
<argument index="0" name="joint" type="RID">
</argument>
<description>
+ Returns the type of the Joint.
</description>
</method>
<method name="joint_set_solver_priority">
@@ -851,6 +951,7 @@
<argument index="1" name="priority" type="int">
</argument>
<description>
+ Sets the priority value of the Joint.
</description>
</method>
<method name="pin_joint_get_local_a" qualifiers="const">
@@ -859,6 +960,7 @@
<argument index="0" name="joint" type="RID">
</argument>
<description>
+ Returns position of the joint in the local space of body a of the joint.
</description>
</method>
<method name="pin_joint_get_local_b" qualifiers="const">
@@ -867,6 +969,7 @@
<argument index="0" name="joint" type="RID">
</argument>
<description>
+ Returns position of the joint in the local space of body b of the joint.
</description>
</method>
<method name="pin_joint_get_param" qualifiers="const">
@@ -877,6 +980,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.PinJointParam">
</argument>
<description>
+ Gets a pin_joint parameter (see PIN_JOINT* constants).
</description>
</method>
<method name="pin_joint_set_local_a">
@@ -887,6 +991,7 @@
<argument index="1" name="local_A" type="Vector3">
</argument>
<description>
+ Sets position of the joint in the local space of body a of the joint.
</description>
</method>
<method name="pin_joint_set_local_b">
@@ -897,6 +1002,7 @@
<argument index="1" name="local_B" type="Vector3">
</argument>
<description>
+ Sets position of the joint in the local space of body b of the joint.
</description>
</method>
<method name="pin_joint_set_param">
@@ -909,6 +1015,7 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Sets a pin_joint parameter (see PIN_JOINT* constants).
</description>
</method>
<method name="set_active">
@@ -917,6 +1024,7 @@
<argument index="0" name="active" type="bool">
</argument>
<description>
+ Activates or deactivates the 3D physics engine.
</description>
</method>
<method name="shape_create">
@@ -925,6 +1033,7 @@
<argument index="0" name="type" type="int" enum="PhysicsServer.ShapeType">
</argument>
<description>
+ Creates a shape of type SHAPE_*. Does not assign it to a body or an area. To do so, you must use [method area_set_shape] or [method body_set_shape].
</description>
</method>
<method name="shape_get_data" qualifiers="const">
@@ -933,6 +1042,7 @@
<argument index="0" name="shape" type="RID">
</argument>
<description>
+ Returns the shape data.
</description>
</method>
<method name="shape_get_type" qualifiers="const">
@@ -941,6 +1051,7 @@
<argument index="0" name="shape" type="RID">
</argument>
<description>
+ Returns the type of shape (see SHAPE_* constants).
</description>
</method>
<method name="shape_set_data">
@@ -951,6 +1062,7 @@
<argument index="1" name="data" type="Variant">
</argument>
<description>
+ Sets the shape data that defines its shape and size. The data to be passed depends on the kind of shape created [method shape_get_type].
</description>
</method>
<method name="slider_joint_get_param" qualifiers="const">
@@ -961,6 +1073,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.SliderJointParam">
</argument>
<description>
+ Gets a slider_joint parameter (see SLIDER_JOINT* constants).
</description>
</method>
<method name="slider_joint_set_param">
@@ -973,12 +1086,14 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Gets a slider_joint parameter (see SLIDER_JOINT* constants).
</description>
</method>
<method name="space_create">
<return type="RID">
</return>
<description>
+ Creates a space. A space is a collection of parameters for the physics engine that can be assigned to an area or a body. It can be assigned to an area with [method area_set_space], or to a body with [method body_set_space].
</description>
</method>
<method name="space_get_direct_state">
@@ -987,6 +1102,7 @@
<argument index="0" name="space" type="RID">
</argument>
<description>
+ Returns the state of a space, a [PhysicsDirectSpaceState]. This object can be used to make collision/intersection queries.
</description>
</method>
<method name="space_get_param" qualifiers="const">
@@ -997,6 +1113,7 @@
<argument index="1" name="param" type="int" enum="PhysicsServer.SpaceParameter">
</argument>
<description>
+ Returns the value of a space parameter.
</description>
</method>
<method name="space_is_active" qualifiers="const">
@@ -1005,6 +1122,7 @@
<argument index="0" name="space" type="RID">
</argument>
<description>
+ Returns whether the space is active.
</description>
</method>
<method name="space_set_active">
@@ -1015,6 +1133,7 @@
<argument index="1" name="active" type="bool">
</argument>
<description>
+ Marks a space as active. It will not have an effect, unless it is assigned to an area or body.
</description>
</method>
<method name="space_set_param">
@@ -1027,169 +1146,256 @@
<argument index="2" name="value" type="float">
</argument>
<description>
+ Sets the value for a space parameter. A list of available parameters is on the SPACE_PARAM_* constants.
</description>
</method>
</methods>
<constants>
<constant name="JOINT_PIN" value="0">
+ The [Joint] is a [PinJoint].
</constant>
<constant name="JOINT_HINGE" value="1">
+ The [Joint] is a [HingeJoint].
</constant>
<constant name="JOINT_SLIDER" value="2">
+ The [Joint] is a [SliderJoint].
</constant>
<constant name="JOINT_CONE_TWIST" value="3">
+ The [Joint] is a [ConeTwistJoint].
</constant>
<constant name="JOINT_6DOF" value="4">
+ The [Joint] is a [Generic6DOFJoint].
</constant>
<constant name="PIN_JOINT_BIAS" value="0">
+ The strength with which the pinned objects try to stay in positional relation to each other.
+ The higher, the stronger.
</constant>
<constant name="PIN_JOINT_DAMPING" value="1">
+ The strength with which the pinned objects try to stay in velocity relation to each other.
+ The higher, the stronger.
</constant>
<constant name="PIN_JOINT_IMPULSE_CLAMP" value="2">
+ If above 0, this value is the maximum value for an impulse that this Joint puts on it's ends.
</constant>
<constant name="HINGE_JOINT_BIAS" value="0">
+ The speed with wich the two bodies get pulled together when they move in different directions.
</constant>
<constant name="HINGE_JOINT_LIMIT_UPPER" value="1">
+ The maximum rotation across the Hinge.
</constant>
<constant name="HINGE_JOINT_LIMIT_LOWER" value="2">
+ The minimum rotation across the Hinge.
</constant>
<constant name="HINGE_JOINT_LIMIT_BIAS" value="3">
+ The speed with which the rotation across the axis perpendicular to the hinge gets corrected.
</constant>
<constant name="HINGE_JOINT_LIMIT_SOFTNESS" value="4">
</constant>
<constant name="HINGE_JOINT_LIMIT_RELAXATION" value="5">
+ The lower this value, the more the rotation gets slowed down.
</constant>
<constant name="HINGE_JOINT_MOTOR_TARGET_VELOCITY" value="6">
+ Target speed for the motor.
</constant>
<constant name="HINGE_JOINT_MOTOR_MAX_IMPULSE" value="7">
+ Maximum acceleration for the motor.
</constant>
<constant name="HINGE_JOINT_FLAG_USE_LIMIT" value="0">
+ If [code]true[/code] the Hinge has a maximum and a minimum rotation.
</constant>
<constant name="HINGE_JOINT_FLAG_ENABLE_MOTOR" value="1">
+ If [code]true[/code] a motor turns the Hinge
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_UPPER" value="0">
+ The maximum difference between the pivot points on their x-axis before damping happens.
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_LOWER" value="1">
+ The minimum difference between the pivot points on their x-axis before damping happens.
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_SOFTNESS" value="2">
+ A factor applied to the movement accross the slider axis once the limits get surpassed. The lower, the slower the movement.
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_RESTITUTION" value="3">
+ The amount of restitution once the limits are surpassed. The lower, the more velocityenergy gets lost.
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_DAMPING" value="4">
+ The amount of damping once the slider limits are surpassed.
</constant>
<constant name="SLIDER_JOINT_LINEAR_MOTION_SOFTNESS" value="5">
+ A factor applied to the movement accross the slider axis as long as the slider is in the limits. The lower, the slower the movement.
</constant>
<constant name="SLIDER_JOINT_LINEAR_MOTION_RESTITUTION" value="6">
+ The amount of restitution inside the slider limits.
</constant>
<constant name="SLIDER_JOINT_LINEAR_MOTION_DAMPING" value="7">
+ The amount of damping inside the slider limits.
</constant>
<constant name="SLIDER_JOINT_LINEAR_ORTHOGONAL_SOFTNESS" value="8">
+ A factor applied to the movement accross axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_LINEAR_ORTHOGONAL_RESTITUTION" value="9">
+ The amount of restitution when movement is accross axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_LINEAR_ORTHOGONAL_DAMPING" value="10">
+ The amount of damping when movement is accross axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_LIMIT_UPPER" value="11">
+ The upper limit of rotation in the slider.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_LIMIT_LOWER" value="12">
+ The lower limit of rotation in the slider.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_LIMIT_SOFTNESS" value="13">
+ A factor applied to the all rotation once the limit is surpassed.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_LIMIT_RESTITUTION" value="14">
+ The amount of restitution of the rotation when the limit is surpassed.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_LIMIT_DAMPING" value="15">
+ The amount of damping of the rotation when the limit is surpassed.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_MOTION_SOFTNESS" value="16">
+ A factor that gets applied to the all rotation in the limits.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_MOTION_RESTITUTION" value="17">
+ The amount of restitution of the rotation in the limits.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_MOTION_DAMPING" value="18">
+ The amount of damping of the rotation in the limits.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_ORTHOGONAL_SOFTNESS" value="19">
+ A factor that gets applied to the all rotation across axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_ORTHOGONAL_RESTITUTION" value="20">
+ The amount of restitution of the rotation across axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_ANGULAR_ORTHOGONAL_DAMPING" value="21">
+ The amount of damping of the rotation across axes orthogonal to the slider.
</constant>
<constant name="SLIDER_JOINT_MAX" value="22">
+ End flag of SLIDER_JOINT_* constants, used internally.
</constant>
<constant name="CONE_TWIST_JOINT_SWING_SPAN" value="0">
+ Swing is rotation from side to side, around the axis perpendicular to the twist axis.
+ The swing span defines, how much rotation will not get corrected allong the swing axis.
+ Could be defined as looseness in the [ConeTwistJoint].
+ If below 0.05, this behaviour is locked. Default value: [code]PI/4[/code].
</constant>
<constant name="CONE_TWIST_JOINT_TWIST_SPAN" value="1">
+ Twist is the rotation around the twist axis, this value defined how far the joint can twist.
+ Twist is locked if below 0.05.
</constant>
<constant name="CONE_TWIST_JOINT_BIAS" value="2">
+ The speed with which the swing or twist will take place.
+ The higher, the faster.
</constant>
<constant name="CONE_TWIST_JOINT_SOFTNESS" value="3">
+ The ease with which the Joint twists, if it's too low, it takes more force to twist the joint.
</constant>
<constant name="CONE_TWIST_JOINT_RELAXATION" value="4">
+ Defines, how fast the swing- and twist-speed-difference on both sides gets synced.
</constant>
<constant name="G6DOF_JOINT_LINEAR_LOWER_LIMIT" value="0">
+ The minimum difference between the pivot points' axes.
</constant>
<constant name="G6DOF_JOINT_LINEAR_UPPER_LIMIT" value="1">
+ The maximum difference between the pivot points' axes.
</constant>
<constant name="G6DOF_JOINT_LINEAR_LIMIT_SOFTNESS" value="2">
+ A factor that gets applied to the movement accross the axes. The lower, the slower the movement.
</constant>
<constant name="G6DOF_JOINT_LINEAR_RESTITUTION" value="3">
+ The amount of restitution on the axes movement. The lower, the more velocity-energy gets lost.
</constant>
<constant name="G6DOF_JOINT_LINEAR_DAMPING" value="4">
+ The amount of damping that happens at the linear motion across the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_LOWER_LIMIT" value="5">
+ The minimum rotation in negative direction to break loose and rotate arround the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_UPPER_LIMIT" value="6">
+ The minimum rotation in positive direction to break loose and rotate arround the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_LIMIT_SOFTNESS" value="7">
+ A factor that gets multiplied onto all rotations accross the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_DAMPING" value="8">
+ The amount of rotational damping accross the axes. The lower, the more dampening occurs.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_RESTITUTION" value="9">
+ The amount of rotational restitution accross the axes. The lower, the more restitution occurs.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_FORCE_LIMIT" value="10">
+ The maximum amount of force that can occur, when rotating arround the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_ERP" value="11">
+ When correcting the crossing of limits in rotation accross the axes, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_MOTOR_TARGET_VELOCITY" value="12">
+ Target speed for the motor at the axes.
</constant>
<constant name="G6DOF_JOINT_ANGULAR_MOTOR_FORCE_LIMIT" value="13">
+ Maximum acceleration for the motor at the axes.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT" value="0">
+ If [code]set[/code] there is linear motion possible within the given limits.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT" value="1">
+ If [code]set[/code] there is rotational motion possible.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_MOTOR" value="2">
+ If [code]set[/code] there is a rotational motor across these axes.
</constant>
<constant name="SHAPE_PLANE" value="0">
+ The [Shape] is a [PlaneShape].
</constant>
<constant name="SHAPE_RAY" value="1">
+ The [Shape] is a [RayShape].
</constant>
<constant name="SHAPE_SPHERE" value="2">
+ The [Shape] is a [SphereShape].
</constant>
<constant name="SHAPE_BOX" value="3">
+ The [Shape] is a [BoxShape].
</constant>
<constant name="SHAPE_CAPSULE" value="4">
+ The [Shape] is a [CapsuleShape].
</constant>
<constant name="SHAPE_CONVEX_POLYGON" value="5">
+ The [Shape] is a [ConvexPolygonShape].
</constant>
<constant name="SHAPE_CONCAVE_POLYGON" value="6">
+ The [Shape] is a [ConcavePolygonShape].
</constant>
<constant name="SHAPE_HEIGHTMAP" value="7">
+ The [Shape] is a [HeightMapShape].
</constant>
<constant name="SHAPE_CUSTOM" value="8">
+ This constant is used internally by the engine. Any attempt to create this kind of shape results in an error.
</constant>
<constant name="AREA_PARAM_GRAVITY" value="0">
+ Constant to set/get gravity strength in an area.
</constant>
<constant name="AREA_PARAM_GRAVITY_VECTOR" value="1">
+ Constant to set/get gravity vector/center in an area.
</constant>
<constant name="AREA_PARAM_GRAVITY_IS_POINT" value="2">
+ Constant to set/get whether the gravity vector of an area is a direction, or a center point.
</constant>
<constant name="AREA_PARAM_GRAVITY_DISTANCE_SCALE" value="3">
+ Constant to set/get the falloff factor for point gravity of an area. The greater this value is, the faster the strength of gravity decreases with the square of distance.
</constant>
<constant name="AREA_PARAM_GRAVITY_POINT_ATTENUATION" value="4">
+ This constant was used to set/get the falloff factor for point gravity. It has been superseded by AREA_PARAM_GRAVITY_DISTANCE_SCALE.
</constant>
<constant name="AREA_PARAM_LINEAR_DAMP" value="5">
+ Constant to set/get the linear dampening factor of an area.
</constant>
<constant name="AREA_PARAM_ANGULAR_DAMP" value="6">
+ Constant to set/get the angular dampening factor of an area.
</constant>
<constant name="AREA_PARAM_PRIORITY" value="7">
+ Constant to set/get the priority (order of processing) of an area.
</constant>
<constant name="AREA_SPACE_OVERRIDE_DISABLED" value="0">
This area does not affect gravity/damp. These are generally areas that exist only to detect collisions, and objects entering or exiting them.
@@ -1207,70 +1413,102 @@
This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one.
</constant>
<constant name="BODY_MODE_STATIC" value="0">
+ Constant for static bodies.
</constant>
<constant name="BODY_MODE_KINEMATIC" value="1">
+ Constant for kinematic bodies.
</constant>
<constant name="BODY_MODE_RIGID" value="2">
+ Constant for rigid bodies.
</constant>
<constant name="BODY_MODE_CHARACTER" value="3">
+ Constant for rigid bodies in character mode. In this mode, a body can not rotate, and only its linear velocity is affected by physics.
</constant>
<constant name="BODY_PARAM_BOUNCE" value="0">
+ Constant to set/get a body's bounce factor.
</constant>
<constant name="BODY_PARAM_FRICTION" value="1">
+ Constant to set/get a body's friction.
</constant>
<constant name="BODY_PARAM_MASS" value="2">
+ Constant to set/get a body's mass.
</constant>
<constant name="BODY_PARAM_GRAVITY_SCALE" value="3">
+ Constant to set/get a body's gravity multiplier.
</constant>
<constant name="BODY_PARAM_ANGULAR_DAMP" value="5">
+ Constant to set/get a body's angular dampening factor.
</constant>
<constant name="BODY_PARAM_LINEAR_DAMP" value="4">
+ Constant to set/get a body's linear dampening factor.
</constant>
<constant name="BODY_PARAM_MAX" value="6">
+ This is the last ID for body parameters. Any attempt to set this property is ignored. Any attempt to get it returns 0.
</constant>
<constant name="BODY_STATE_TRANSFORM" value="0">
+ Constant to set/get the current transform matrix of the body.
</constant>
<constant name="BODY_STATE_LINEAR_VELOCITY" value="1">
+ Constant to set/get the current linear velocity of the body.
</constant>
<constant name="BODY_STATE_ANGULAR_VELOCITY" value="2">
+ Constant to set/get the current angular velocity of the body.
</constant>
<constant name="BODY_STATE_SLEEPING" value="3">
+ Constant to sleep/wake up a body, or to get whether it is sleeping.
</constant>
<constant name="BODY_STATE_CAN_SLEEP" value="4">
+ Constant to set/get whether the body can sleep.
</constant>
<constant name="AREA_BODY_ADDED" value="0">
+ The value of the first parameter and area callback function receives, when an object enters one of its shapes.
</constant>
<constant name="AREA_BODY_REMOVED" value="1">
+ The value of the first parameter and area callback function receives, when an object exits one of its shapes.
</constant>
<constant name="INFO_ACTIVE_OBJECTS" value="0">
+ Constant to get the number of objects that are not sleeping.
</constant>
<constant name="INFO_COLLISION_PAIRS" value="1">
+ Constant to get the number of possible collisions.
</constant>
<constant name="INFO_ISLAND_COUNT" value="2">
+ Constant to get the number of space regions where a collision could occur.
</constant>
<constant name="SPACE_PARAM_CONTACT_RECYCLE_RADIUS" value="0">
+ Constant to set/get the maximum distance a pair of bodies has to move before their collision status has to be recalculated.
</constant>
<constant name="SPACE_PARAM_CONTACT_MAX_SEPARATION" value="1">
+ Constant to set/get the maximum distance a shape can be from another before they are considered separated.
</constant>
<constant name="SPACE_PARAM_BODY_MAX_ALLOWED_PENETRATION" value="2">
+ Constant to set/get the maximum distance a shape can penetrate another shape before it is considered a collision.
</constant>
<constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="3">
+ Constant to set/get the threshold linear velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
<constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="4">
+ Constant to set/get the threshold angular velocity of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after the time given.
</constant>
<constant name="SPACE_PARAM_BODY_TIME_TO_SLEEP" value="5">
+ Constant to set/get the maximum time of activity. A body marked as potentially inactive for both linear and angular velocity will be put to sleep after this time.
</constant>
<constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO" value="6">
</constant>
<constant name="SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS" value="7">
+ Constant to set/get the default solver bias for all physics constraints. A solver bias is a factor controlling how much two objects "rebound", after violating a constraint, to avoid leaving them in that state because of numerical imprecision.
</constant>
<constant name="BODY_AXIS_LOCK_DISABLED" value="0">
+ The [Body] can rotate and move freely.
</constant>
<constant name="BODY_AXIS_LOCK_X" value="1">
+ The [Body] cannot move across x axis can only rotate across x axis.
</constant>
<constant name="BODY_AXIS_LOCK_Y" value="2">
+ The [Body] cannot move across y axis can only rotate across y axis.
</constant>
<constant name="BODY_AXIS_LOCK_Z" value="3">
+ The [Body] cannot move across z axis can only rotate across z axis.
</constant>
</constants>
</class>
diff --git a/doc/classes/PhysicsServerSW.xml b/doc/classes/PhysicsServerSW.xml
index 7bffc23258..53e1c0057e 100644
--- a/doc/classes/PhysicsServerSW.xml
+++ b/doc/classes/PhysicsServerSW.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PhysicsServerSW" inherits="PhysicsServer" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Software implementation of [PhysicsServer].
</brief_description>
<description>
+ This class exposes no new methods or properties and should not be used, as [PhysicsServer] automatically selects the best implementation available.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/PinJoint.xml b/doc/classes/PinJoint.xml
index 22aa35a0a4..1cc381b1b3 100644
--- a/doc/classes/PinJoint.xml
+++ b/doc/classes/PinJoint.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PinJoint" inherits="Joint" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Pin Joint for 3D Shapes.
</brief_description>
<description>
+ Pin Joint for 3D Rigid Bodies. It pins 2 bodies (rigid or static) together.
</description>
<tutorials>
</tutorials>
@@ -30,18 +32,28 @@
</methods>
<members>
<member name="params/bias" type="float" setter="set_param" getter="get_param">
+ The force with wich the pinned objects stay in positional relation to each other.
+ The higher, the stronger.
</member>
<member name="params/damping" type="float" setter="set_param" getter="get_param">
+ The force with wich the pinned objects stay in velocity relation to each other.
+ The higher, the stronger.
</member>
<member name="params/impulse_clamp" type="float" setter="set_param" getter="get_param">
+ If above 0, this value is the maximum value for an impulse that this Joint produces.
</member>
</members>
<constants>
<constant name="PARAM_BIAS" value="0">
+ The force with wich the pinned objects stay in positional relation to each other.
+ The higher, the stronger.
</constant>
<constant name="PARAM_DAMPING" value="1">
+ The force with wich the pinned objects stay in velocity relation to each other.
+ The higher, the stronger.
</constant>
<constant name="PARAM_IMPULSE_CLAMP" value="2">
+ If above 0, this value is the maximum value for an impulse that this Joint produces.
</constant>
</constants>
</class>
diff --git a/doc/classes/PinJoint2D.xml b/doc/classes/PinJoint2D.xml
index 826a1684a4..009b0ec2f2 100644
--- a/doc/classes/PinJoint2D.xml
+++ b/doc/classes/PinJoint2D.xml
@@ -28,6 +28,7 @@
</methods>
<members>
<member name="softness" type="float" setter="set_softness" getter="get_softness">
+ The higher this value, the more the bond to the pinned partner can flex.
</member>
</members>
<constants>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 1a3ea5c5c7..bdf2cc0062 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -51,6 +51,14 @@
Return the order of a configuration value (influences when saved to the config file).
</description>
</method>
+ <method name="get_setting" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_singleton" qualifiers="const">
<return type="Object">
</return>
@@ -68,7 +76,7 @@
Convert a localized path (res://) to a full native OS path.
</description>
</method>
- <method name="has" qualifiers="const">
+ <method name="has_setting" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="name" type="String">
@@ -153,6 +161,16 @@
Set the order of a configuration value (influences when saved to the config file).
</description>
</method>
+ <method name="set_setting">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<constants>
</constants>
diff --git a/doc/classes/RayCast.xml b/doc/classes/RayCast.xml
index 2e6efff769..3782a98e3e 100644
--- a/doc/classes/RayCast.xml
+++ b/doc/classes/RayCast.xml
@@ -5,12 +5,9 @@
</brief_description>
<description>
A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 3D space in order to find the closest object along the path of the ray.
-
RayCast can ignore some objects by adding them to the exception list via [code]add_exception[/code], by setting proper filtering with collision layers, or by filtering object types with type masks.
-
Only enabled raycasts will be able to query the space and report collisions.
-
- RayCast calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
+ RayCast calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
</tutorials>
@@ -47,7 +44,7 @@
</return>
<description>
Updates the collision information for the ray.
- Use this method to update the collision information immediately instead of waiting for the next [code]_fixed_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work.
+ Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work.
</description>
</method>
<method name="get_cast_to" qualifiers="const">
@@ -183,7 +180,7 @@
The ray's destination point, relative to the RayCast's [code]position[/code].
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
- The RayCast's collison layer(s). Only bodies in the same collision layer(s) will be detected.
+ The RayCast's collision layer(s). Only bodies in the same collision layer(s) will be detected.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled">
If [code]true[/code], collisions will be reported. Default value: [code]false[/code].
diff --git a/doc/classes/RayCast2D.xml b/doc/classes/RayCast2D.xml
index 5520abe050..74ee0a8911 100644
--- a/doc/classes/RayCast2D.xml
+++ b/doc/classes/RayCast2D.xml
@@ -7,7 +7,7 @@
A RayCast represents a line from its origin to its destination position, [code]cast_to[/code]. It is used to query the 2D space in order to find the closest object along the path of the ray.
RayCast2D can ignore some objects by adding them to the exception list via [code]add_exception[/code], by setting proper filtering with collision layers, or by filtering object types with type masks.
Only enabled raycasts will be able to query the space and report collisions.
- RayCast2D calculates intersection every fixed frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between fixed frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
+ RayCast2D calculates intersection every physics frame (see [Node]), and the result is cached so it can be used later until the next frame. If multiple queries are required between physics frames (or during the same frame) use [method force_raycast_update] after adjusting the raycast.
</description>
<tutorials>
</tutorials>
@@ -43,7 +43,7 @@
<return type="void">
</return>
<description>
- Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next [code]_fixed_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work.
+ Updates the collision information for the ray. Use this method to update the collision information immediately instead of waiting for the next [code]_physics_process[/code] call, for example if the ray or its parent has changed state. Note: [code]enabled == true[/code] is not required for this to work.
</description>
</method>
<method name="get_cast_to" qualifiers="const">
@@ -195,7 +195,7 @@
The ray's destination point, relative to the RayCast's [code]position[/code].
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
- The RayCast2D's collison layer(s). Only bodies in the same collision layer(s) will be detected.
+ The RayCast2D's collision layer(s). Only bodies in the same collision layer(s) will be detected.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled">
If [code]true[/code], collisions will be reported. Default value: [code]false[/code].
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index a4faa697de..f2584de5aa 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -113,7 +113,7 @@
<return type="float">
</return>
<description>
- Return the body's moment of inertia. This is usually automatically computed from the mass and the shapes. Note that this doesn't seem to work in a [code]_ready[/code] function: it apparently has not been auto-computed yet.
+ Returns the body's moment of inertia. Automatically computed from associated [class CollisionShape2D]s' mass during physic frames. Inertia is not computed the same frame in which the node was added in. Therefore inertia is not computed during the [code]_ready[/code] function.
</description>
</method>
<method name="get_linear_damp" qualifiers="const">
@@ -127,7 +127,7 @@
<return type="Vector2">
</return>
<description>
- Return the body linear velocity. This changes by physics granularity. See [method set_linear_velocity].
+ Returns the body's linear velocity. This changes when a physics frame has passed, not during a normal update. See [method set_linear_velocity].
</description>
</method>
<method name="get_mass" qualifiers="const">
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index c40d9339d1..fd32f35a06 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -336,10 +336,6 @@
<description>
</description>
</signal>
- <signal name="fixed_frame">
- <description>
- </description>
- </signal>
<signal name="idle_frame">
<description>
</description>
@@ -368,6 +364,10 @@
<description>
</description>
</signal>
+ <signal name="physics_frame">
+ <description>
+ </description>
+ </signal>
<signal name="screen_resized">
<description>
</description>
@@ -404,5 +404,7 @@
</constant>
<constant name="STRETCH_ASPECT_KEEP_HEIGHT" value="3">
</constant>
+ <constant name="STRETCH_ASPECT_EXPAND" value="4">
+ </constant>
</constants>
</class>
diff --git a/doc/classes/SliderJoint.xml b/doc/classes/SliderJoint.xml
index 617390b6a4..adea8658d1 100644
--- a/doc/classes/SliderJoint.xml
+++ b/doc/classes/SliderJoint.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SliderJoint" inherits="Joint" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Piston kind of slider between two bodies in 3D.
</brief_description>
<description>
+ Slides across the x-axis of the [Pivot] object.
</description>
<tutorials>
</tutorials>
@@ -30,96 +32,144 @@
</methods>
<members>
<member name="angular_limit/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping of the rotation when the limit is surpassed.
+ A lower damping value allows a rotation initiated by body A to travel to body B slower.
</member>
<member name="angular_limit/lower_angle" type="float" setter="_set_lower_limit_angular" getter="_get_lower_limit_angular">
+ The lower limit of rotation in the slider.
</member>
<member name="angular_limit/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution of the rotation when the limit is surpassed.
+ Does not affect damping.
</member>
<member name="angular_limit/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the all rotation once the limit is surpassed.
+ Makes all rotation slower when between 0 and 1.
</member>
<member name="angular_limit/upper_angle" type="float" setter="_set_upper_limit_angular" getter="_get_upper_limit_angular">
+ The upper limit of rotation in the slider.
</member>
<member name="angular_motion/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping of the rotation in the limits.
</member>
<member name="angular_motion/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution of the rotation in the limits.
</member>
<member name="angular_motion/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the all rotation in the limits.
</member>
<member name="angular_ortho/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping of the rotation across axes orthogonal to the slider.
</member>
<member name="angular_ortho/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution of the rotation across axes orthogonal to the slider.
</member>
<member name="angular_ortho/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the all rotation across axes orthogonal to the slider.
</member>
<member name="linear_limit/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping that happens once the limit defined by [member linear_limit/lower_distance] and [member linear_limit/upper_distance] is surpassed.
</member>
<member name="linear_limit/lower_distance" type="float" setter="set_param" getter="get_param">
+ The minimum difference between the pivot points on their x-axis before damping happens.
</member>
<member name="linear_limit/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution once the limits are surpassed. The lower, the more velocity-energy gets lost.
</member>
<member name="linear_limit/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the movement accross the slider axis once the limits get surpassed. The lower, the slower the movement.
</member>
<member name="linear_limit/upper_distance" type="float" setter="set_param" getter="get_param">
+ The maximum difference between the pivot points on their x-axis before damping happens.
</member>
<member name="linear_motion/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping inside the slider limits.
</member>
<member name="linear_motion/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution inside the slider limits.
</member>
<member name="linear_motion/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the movement accross the slider axis as long as the slider is in the limits. The lower, the slower the movement.
</member>
<member name="linear_ortho/damping" type="float" setter="set_param" getter="get_param">
+ The amount of damping when movement is accross axes orthogonal to the slider.
</member>
<member name="linear_ortho/restitution" type="float" setter="set_param" getter="get_param">
+ The amount of restitution when movement is accross axes orthogonal to the slider.
</member>
<member name="linear_ortho/softness" type="float" setter="set_param" getter="get_param">
+ A factor applied to the movement accross axes orthogonal to the slider.
</member>
</members>
<constants>
<constant name="PARAM_LINEAR_LIMIT_UPPER" value="0">
+ The maximum difference between the pivot points on their x-axis before damping happens.
</constant>
<constant name="PARAM_LINEAR_LIMIT_LOWER" value="1">
+ The minimum difference between the pivot points on their x-axis before damping happens.
</constant>
<constant name="PARAM_LINEAR_LIMIT_SOFTNESS" value="2">
+ A factor applied to the movement accross the slider axis once the limits get surpassed. The lower, the slower the movement.
</constant>
<constant name="PARAM_LINEAR_LIMIT_RESTITUTION" value="3">
+ The amount of restitution once the limits are surpassed. The lower, the more velocityenergy gets lost.
</constant>
<constant name="PARAM_LINEAR_LIMIT_DAMPING" value="4">
+ The amount of damping once the slider limits are surpassed.
</constant>
<constant name="PARAM_LINEAR_MOTION_SOFTNESS" value="5">
+ A factor applied to the movement accross the slider axis as long as the slider is in the limits. The lower, the slower the movement.
</constant>
<constant name="PARAM_LINEAR_MOTION_RESTITUTION" value="6">
+ The amount of restitution inside the slider limits.
</constant>
<constant name="PARAM_LINEAR_MOTION_DAMPING" value="7">
+ The amount of damping inside the slider limits.
</constant>
<constant name="PARAM_LINEAR_ORTHOGONAL_SOFTNESS" value="8">
+ A factor applied to the movement accross axes orthogonal to the slider.
</constant>
<constant name="PARAM_LINEAR_ORTHOGONAL_RESTITUTION" value="9">
+ The amount of restitution when movement is accross axes orthogonal to the slider.
</constant>
<constant name="PARAM_LINEAR_ORTHOGONAL_DAMPING" value="10">
+ The amount of damping when movement is accross axes orthogonal to the slider.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_UPPER" value="11">
+ The upper limit of rotation in the slider.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_LOWER" value="12">
+ The lower limit of rotation in the slider.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_SOFTNESS" value="13">
+ A factor applied to the all rotation once the limit is surpassed.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_RESTITUTION" value="14">
+ The amount of restitution of the rotation when the limit is surpassed.
</constant>
<constant name="PARAM_ANGULAR_LIMIT_DAMPING" value="15">
+ The amount of damping of the rotation when the limit is surpassed.
</constant>
<constant name="PARAM_ANGULAR_MOTION_SOFTNESS" value="16">
+ A factor applied to the all rotation in the limits.
</constant>
<constant name="PARAM_ANGULAR_MOTION_RESTITUTION" value="17">
+ The amount of restitution of the rotation in the limits.
</constant>
<constant name="PARAM_ANGULAR_MOTION_DAMPING" value="18">
+ The amount of damping of the rotation in the limits.
</constant>
<constant name="PARAM_ANGULAR_ORTHOGONAL_SOFTNESS" value="19">
+ A factor applied to the all rotation across axes orthogonal to the slider.
</constant>
<constant name="PARAM_ANGULAR_ORTHOGONAL_RESTITUTION" value="20">
+ The amount of restitution of the rotation across axes orthogonal to the slider.
</constant>
<constant name="PARAM_ANGULAR_ORTHOGONAL_DAMPING" value="21">
+ The amount of damping of the rotation across axes orthogonal to the slider.
</constant>
<constant name="PARAM_MAX" value="22">
+ End flag of PARAM_* constants, used internally.
</constant>
</constants>
</class>
diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml
index 54eb82fbff..abb0bfa246 100644
--- a/doc/classes/Spatial.xml
+++ b/doc/classes/Spatial.xml
@@ -209,7 +209,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- Makes the node ignore its parents tranformations. Node tranformations are only in global space.
+ Makes the node ignore its parents transformations. Node transformations are only in global space.
</description>
</method>
<method name="set_gizmo">
@@ -234,7 +234,7 @@
<return type="void">
</return>
<description>
- Reset all tranformations for this node. Set its [Transform3D] to identity matrix.
+ Reset all transformations for this node. Set its [Transform3D] to identity matrix.
</description>
</method>
<method name="set_ignore_transform_notification">
@@ -329,7 +329,7 @@
<argument index="0" name="local_point" type="Vector3">
</argument>
<description>
- Tranforms [Vector3] "local_point" from this node's local space to world space.
+ Transforms [Vector3] "local_point" from this node's local space to world space.
</description>
</method>
<method name="to_local" qualifiers="const">
@@ -338,7 +338,7 @@
<argument index="0" name="global_point" type="Vector3">
</argument>
<description>
- Tranforms [Vector3] "global_point" from world space to this node's local space.
+ Transforms [Vector3] "global_point" from world space to this node's local space.
</description>
</method>
<method name="translate">
diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml
index 344a42b7c0..db47875050 100644
--- a/doc/classes/SpatialMaterial.xml
+++ b/doc/classes/SpatialMaterial.xml
@@ -27,6 +27,12 @@
<description>
</description>
</method>
+ <method name="get_ao_light_affect" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_ao_texture_channel" qualifiers="const">
<return type="int" enum="SpatialMaterial.TextureChannel">
</return>
@@ -357,6 +363,14 @@
<description>
</description>
</method>
+ <method name="set_ao_light_affect">
+ <return type="void">
+ </return>
+ <argument index="0" name="amount" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_ao_texture_channel">
<return type="void">
</return>
@@ -777,6 +791,8 @@
</member>
<member name="ao_enabled" type="bool" setter="set_feature" getter="get_feature">
</member>
+ <member name="ao_light_affect" type="float" setter="set_ao_light_affect" getter="get_ao_light_affect">
+ </member>
<member name="ao_on_uv2" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="ao_texture" type="Texture" setter="set_texture" getter="get_texture">
@@ -1059,13 +1075,13 @@
</constant>
<constant name="FLAG_MAX" value="12">
</constant>
- <constant name="DIFFUSE_LAMBERT" value="0">
+ <constant name="DIFFUSE_BURLEY" value="0">
</constant>
- <constant name="DIFFUSE_LAMBERT_WRAP" value="1">
+ <constant name="DIFFUSE_LAMBERT" value="1">
</constant>
- <constant name="DIFFUSE_OREN_NAYAR" value="2">
+ <constant name="DIFFUSE_LAMBERT_WRAP" value="2">
</constant>
- <constant name="DIFFUSE_BURLEY" value="3">
+ <constant name="DIFFUSE_OREN_NAYAR" value="3">
</constant>
<constant name="DIFFUSE_TOON" value="4">
</constant>
diff --git a/doc/classes/SpatialVelocityTracker.xml b/doc/classes/SpatialVelocityTracker.xml
index 2cbc2b9739..95871c8cdc 100644
--- a/doc/classes/SpatialVelocityTracker.xml
+++ b/doc/classes/SpatialVelocityTracker.xml
@@ -15,7 +15,7 @@
<description>
</description>
</method>
- <method name="is_tracking_fixed_step" qualifiers="const">
+ <method name="is_tracking_physics_step" qualifiers="const">
<return type="bool">
</return>
<description>
@@ -29,7 +29,7 @@
<description>
</description>
</method>
- <method name="set_track_fixed_step">
+ <method name="set_track_physics_step">
<return type="void">
</return>
<argument index="0" name="enable" type="bool">
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index 7ed681ea12..f6c3367704 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -210,7 +210,7 @@
If set, texture can be seen from the back as well, if not, it is invisible when looking at it from behind.
</constant>
<constant name="FLAG_MAX" value="3">
- Used internally to mark the end of the Flags section.
+ Used internally to mark the end of the Flags section.
</constant>
<constant name="ALPHA_CUT_DISABLED" value="0">
</constant>
diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml
index b09b9f0679..756b7f9225 100644
--- a/doc/classes/StyleBoxFlat.xml
+++ b/doc/classes/StyleBoxFlat.xml
@@ -14,12 +14,12 @@
[codeblock]
height = 30
corner_radius_top_left = 50
- corner_raidus_bottom_left = 100
+ corner_radius_bottom_left = 100
[/codeblock]
The relative system now would take the 1:2 ratio of the two left corners to calculate the actual corner width. Both corners added will [b]never[/b] be more than the height. Result:
[codeblock]
corner_radius_top_left: 10
- corner_raidus_bottom_left: 20
+ corner_radius_bottom_left: 20
[/codeblock]
</description>
<tutorials>
@@ -268,7 +268,7 @@
</methods>
<members>
<member name="anti_aliasing" type="bool" setter="set_anti_aliased" getter="is_anti_aliased">
- Anti Aliasing draws a small ring around edges. This ring fades to transparent. As a result edges look much smoother. This is only noticable when using rounded corners.
+ Anti Aliasing draws a small ring around edges. This ring fades to transparent. As a result edges look much smoother. This is only noticeable when using rounded corners.
</member>
<member name="anti_aliasing_size" type="int" setter="set_aa_size" getter="get_aa_size">
This changes the size of the faded ring. Higher values can be used to achieve a "blurry" effect.
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index ffe99eb82b..ad02064862 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -16,14 +16,14 @@
<return type="bool">
</return>
<description>
- Return whether the tabs should be visible or hidden.
+ Returns [code]true[/code] if the tabs are visible.
</description>
</method>
<method name="get_current_tab" qualifiers="const">
<return type="int">
</return>
<description>
- Return the current tab index that is being shown.
+ Returns the current tab index that is being shown.
</description>
</method>
<method name="get_current_tab_control" qualifiers="const">
@@ -42,14 +42,14 @@
<return type="int">
</return>
<description>
- Return the previous tab index that was being shown.
+ Returns the previous tab index that was being shown.
</description>
</method>
<method name="get_tab_align" qualifiers="const">
<return type="int" enum="TabContainer.TabAlign">
</return>
<description>
- Return tab alignment, from the ALIGN_* enum.
+ Returns the tab alignment.See the ALIGN_* constants.
</description>
</method>
<method name="get_tab_control" qualifiers="const">
@@ -58,14 +58,14 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Return the current tab control that is being shown.
+ Returns the current tab control that is being shown.
</description>
</method>
<method name="get_tab_count" qualifiers="const">
<return type="int">
</return>
<description>
- Return the amount of tabs.
+ Returns the amount of tabs.
</description>
</method>
<method name="get_tab_disabled" qualifiers="const">
@@ -74,6 +74,7 @@
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
+ Returns [code]true[/code] if the tab at index [code]tab_idx[/code] is disabled.
</description>
</method>
<method name="get_tab_icon" qualifiers="const">
@@ -82,6 +83,7 @@
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
+ Returns the [Texture] for the tab at index [code]tab_idx[/code] or null if the tab has no [Texture].
</description>
</method>
<method name="get_tab_title" qualifiers="const">
@@ -90,7 +92,7 @@
<argument index="0" name="tab_idx" type="int">
</argument>
<description>
- Return the title for the tab. Tab titles are by default the children node name, but this can be overridden.
+ Returns the title for the tab at index [code]tab_idx[/code]. Tab titles are by default the children node name, but this can be overridden.
</description>
</method>
<method name="set_current_tab">
@@ -127,6 +129,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
+ Set tab at index [code]tab_idx[/code] disabled.
</description>
</method>
<method name="set_tab_icon">
@@ -137,7 +140,7 @@
<argument index="1" name="icon" type="Texture">
</argument>
<description>
- Set an icon for a tab.
+ Set an icon for a tab at index [code]tab_idx[/code].
</description>
</method>
<method name="set_tab_title">
@@ -148,7 +151,7 @@
<argument index="1" name="title" type="String">
</argument>
<description>
- Set a title for the tab. Tab titles are by default the children node name, but this can be overridden.
+ Set a title for the tab at index [code]tab_idx[/code]. Tab titles are by default the children node name, but this can be overridden.
</description>
</method>
<method name="set_tabs_visible">
@@ -157,16 +160,19 @@
<argument index="0" name="visible" type="bool">
</argument>
<description>
- Set whether the tabs should be visible or hidden.
+ If [code]true[/code] all the tabs will be visible.
</description>
</method>
</methods>
<members>
<member name="current_tab" type="int" setter="set_current_tab" getter="get_current_tab">
+ The current tab.
</member>
<member name="tab_align" type="int" setter="set_tab_align" getter="get_tab_align" enum="TabContainer.TabAlign">
+ The alignment of all the tabs of the tab container. See the [code]ALIGN_*[/code] constants.
</member>
<member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible">
+ If [code]true[/code] all tabs that are children of the TabContainer will be visible.
</member>
</members>
<signals>
diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml
index 35979bb1fc..035dec7980 100644
--- a/doc/classes/Timer.xml
+++ b/doc/classes/Timer.xml
@@ -141,8 +141,8 @@
</signal>
</signals>
<constants>
- <constant name="TIMER_PROCESS_FIXED" value="0">
- Update the Timer at fixed intervals (framerate processing).
+ <constant name="TIMER_PROCESS_PHYSICS" value="0">
+ Update the Timer during the physics step at each frame (fixed framerate processing).
</constant>
<constant name="TIMER_PROCESS_IDLE" value="1">
Update the Timer during the idle time at each frame.
diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml
index 8a96fa1454..51cb7f86f2 100644
--- a/doc/classes/TouchScreenButton.xml
+++ b/doc/classes/TouchScreenButton.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="TouchScreenButton" inherits="Node2D" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Button for touch screen devices.
</brief_description>
<description>
+ Button for touch screen devices. You can set it to be visible on all screens, or only on touch devices.
</description>
<tutorials>
</tutorials>
@@ -13,36 +15,42 @@
<return type="String">
</return>
<description>
+ Returns the button's action.
</description>
</method>
<method name="get_bitmask" qualifiers="const">
<return type="BitMap">
</return>
<description>
+ Returns the button's bitmask.
</description>
</method>
<method name="get_shape" qualifiers="const">
<return type="Shape2D">
</return>
<description>
+ Returns the button's shape.
</description>
</method>
<method name="get_texture" qualifiers="const">
<return type="Texture">
</return>
<description>
+ Returns the button's texture for the normal state.
</description>
</method>
<method name="get_texture_pressed" qualifiers="const">
<return type="Texture">
</return>
<description>
+ Returns the button's texture for the pressed state.
</description>
</method>
<method name="get_visibility_mode" qualifiers="const">
<return type="int" enum="TouchScreenButton.VisibilityMode">
</return>
<description>
+ Sets the button's visibility mode. See [code]VISIBILITY_*[/code] constants.
</description>
</method>
<method name="is_passby_press_enabled" qualifiers="const">
@@ -55,6 +63,7 @@
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if this button is currently pressed.
</description>
</method>
<method name="is_shape_centered" qualifiers="const">
@@ -75,6 +84,7 @@
<argument index="0" name="action" type="String">
</argument>
<description>
+ Sets the button's action.
</description>
</method>
<method name="set_bitmask">
@@ -83,6 +93,7 @@
<argument index="0" name="bitmask" type="BitMap">
</argument>
<description>
+ Sets the button's [BitMap] bitmask.
</description>
</method>
<method name="set_passby_press">
@@ -91,6 +102,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
+ If [code]true[/code] passby presses are enabled for this button.
</description>
</method>
<method name="set_shape">
@@ -99,6 +111,7 @@
<argument index="0" name="shape" type="Shape2D">
</argument>
<description>
+ Sets the button's shape.
</description>
</method>
<method name="set_shape_centered">
@@ -107,6 +120,7 @@
<argument index="0" name="bool" type="bool">
</argument>
<description>
+ If [code]true[/code] the button's shape is centered.
</description>
</method>
<method name="set_shape_visible">
@@ -115,6 +129,7 @@
<argument index="0" name="bool" type="bool">
</argument>
<description>
+ If [code]true[/code] the button's shape is visible.
</description>
</method>
<method name="set_texture">
@@ -123,6 +138,7 @@
<argument index="0" name="texture" type="Texture">
</argument>
<description>
+ Sets the button's [Texture] for the normal state.
</description>
</method>
<method name="set_texture_pressed">
@@ -131,6 +147,7 @@
<argument index="0" name="texture_pressed" type="Texture">
</argument>
<description>
+ Sets the button's [Texture] for the pressed state.
</description>
</method>
<method name="set_visibility_mode">
@@ -139,43 +156,57 @@
<argument index="0" name="mode" type="int" enum="TouchScreenButton.VisibilityMode">
</argument>
<description>
+ Sets the button's visibility mode. See the [code]VISIBILITY_*[/code] constants.
</description>
</method>
</methods>
<members>
<member name="action" type="String" setter="set_action" getter="get_action">
+ The button's action. Actions can be handled with [InputEventAction].
</member>
<member name="bitmask" type="BitMap" setter="set_bitmask" getter="get_bitmask">
+ The button's bitmask.
</member>
<member name="normal" type="Texture" setter="set_texture" getter="get_texture">
+ The button's texture for the normal state.
</member>
<member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled">
+ If [code]true[/code] passby presses are enabled.
</member>
<member name="pressed" type="Texture" setter="set_texture_pressed" getter="get_texture_pressed">
+ The button's texture for the pressed state.
</member>
<member name="shape" type="Shape2D" setter="set_shape" getter="get_shape">
+ The button's shape.
</member>
<member name="shape_centered" type="bool" setter="set_shape_centered" getter="is_shape_centered">
+ If [code]true[/code] the button's shape is centered.
</member>
<member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible">
+ If [code]true[/code] the button's shape is visible.
</member>
<member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="TouchScreenButton.VisibilityMode">
+ The button's visibility mode. See [code]VISIBILITY_*[/code] constants.
</member>
</members>
<signals>
<signal name="pressed">
<description>
+ Emitted when the button is pressed (down).
</description>
</signal>
<signal name="released">
<description>
+ Emitted when the button is released (up).
</description>
</signal>
</signals>
<constants>
<constant name="VISIBILITY_ALWAYS" value="0">
+ Always visible.
</constant>
<constant name="VISIBILITY_TOUCHSCREEN_ONLY" value="1">
+ Visible on touch screens only.
</constant>
</constants>
</class>
diff --git a/doc/classes/Transform.xml b/doc/classes/Transform.xml
index 6780de1943..cd80d568e7 100644
--- a/doc/classes/Transform.xml
+++ b/doc/classes/Transform.xml
@@ -68,7 +68,7 @@
<return type="Transform">
</return>
<description>
- Returns the inverse of the transfrom, under the assumption that the transformation is composed of rotation, scaling and translation.
+ Returns the inverse of the transform, under the assumption that the transformation is composed of rotation, scaling and translation.
</description>
</method>
<method name="interpolate_with">
@@ -104,7 +104,7 @@
<return type="Transform">
</return>
<description>
- Returns the transfrom with the basis orthogonal (90 degrees), and normalized axis vectors.
+ Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors.
</description>
</method>
<method name="rotated">
diff --git a/doc/classes/Transform2D.xml b/doc/classes/Transform2D.xml
index 0e39505ac3..76b9b0e845 100644
--- a/doc/classes/Transform2D.xml
+++ b/doc/classes/Transform2D.xml
@@ -112,7 +112,7 @@
<return type="Transform2D">
</return>
<description>
- Returns the transfrom with the basis orthogonal (90 degrees), and normalized axis vectors.
+ Returns the transform with the basis orthogonal (90 degrees), and normalized axis vectors.
</description>
</method>
<method name="rotated">
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index 10ebc72134..3cf56bbf11 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -25,7 +25,7 @@
<argument index="4" name="tooltip" type="String" default="&quot;&quot;">
</argument>
<description>
- Adds a button with [Texture] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [code]get_buton_count()[/code] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code].
+ Adds a button with [Texture] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [code]get_buton_count()[/code] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code].
</description>
</method>
<method name="clear_custom_bg_color">
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index d291f44de3..23229aec4a 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -12,7 +12,7 @@
tween.start()
[/codeblock]
Some of the methods of this class require a property name. You can get the property name by hovering over the property in the inspector of the editor.
- Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an TRANS_* constant, and refers to the way the timing of the animation is handled (you might want to see [code]http://easings.net/[/code] for some examples). The second accepts an EASE_* constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transision and easing to pick, you can try different TRANS_* constants with EASE_IN_OUT, and use the one that looks best.
+ Many of the methods accept [code]trans_type[/code] and [code]ease_type[/code]. The first accepts an TRANS_* constant, and refers to the way the timing of the animation is handled (you might want to see [code]http://easings.net/[/code] for some examples). The second accepts an EASE_* constant, and controls the where [code]trans_type[/code] is applied to the interpolation (in the beginning, the end, or both). If you don't know which transition and easing to pick, you can try different TRANS_* constants with EASE_IN_OUT, and use the one that looks best.
</description>
<tutorials>
</tutorials>
@@ -135,7 +135,7 @@
<argument index="7" name="arg5" type="Variant" default="null">
</argument>
<description>
- Call [code]callback[/code] of [code]object[/code] after [code]duration[/code] on the main thread (similar to [methog Object.call_deferred). [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
+ Call [code]callback[/code] of [code]object[/code] after [code]duration[/code] on the main thread (similar to [method Object.call_deferred]). [code]arg1[/code]-[code]arg5[/code] are arguments to be passed to the callback.
</description>
</method>
<method name="interpolate_method">
@@ -158,7 +158,7 @@
<argument index="7" name="delay" type="float" default="0">
</argument>
<description>
- Animate [code]method[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+ Animate [code]method[/code] of [code]object[/code] from [code]initial_val[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecutive values.
[code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the beginning, the end, or both). You can read more about them in the class description.
</description>
</method>
@@ -296,7 +296,7 @@
<argument index="0" name="mode" type="int" enum="Tween.TweenProcessMode">
</argument>
<description>
- Set whether the Tween uses [code]_process[/code] or [code]_fixed_process[/code] (accepts TWEEN_PROCESS_IDLE and TWEEN_PROCESS_FIXED constants, respectively).
+ Set whether the Tween uses [code]_process[/code] or [code]_physics_process[/code] (accepts TWEEN_PROCESS_IDLE and TWEEN_PROCESS_PHYSICS constants, respectively).
</description>
</method>
<method name="start">
@@ -346,7 +346,7 @@
<argument index="8" name="delay" type="float" default="0">
</argument>
<description>
- Animate [code]method[/code] of [code]object[/code] from the value returned by [code]initial.initial_method[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecuitive values.
+ Animate [code]method[/code] of [code]object[/code] from the value returned by [code]initial.initial_method[/code] to [code]final_val[/code] for [code]duration[/code] seconds, [code]delay[/code] seconds later. Methods are animated by calling them with consecutive values.
[code]trans_type[/code] accepts TRANS_* constants, and is the way the animation is interpolated, while [code]ease_type[/code] accepts EASE_* constants, and controls the place of the interpolation (the beginning, the end, or both). You can read more about them in the class description.
</description>
</method>
@@ -422,8 +422,8 @@
</signal>
</signals>
<constants>
- <constant name="TWEEN_PROCESS_FIXED" value="0">
- The [Tween] should use [code]_fixed_process[/code] for timekeeping when this is enabled.
+ <constant name="TWEEN_PROCESS_PHYSICS" value="0">
+ The [Tween] should use [code]_physics_process[/code] for timekeeping when this is enabled.
</constant>
<constant name="TWEEN_PROCESS_IDLE" value="1">
The [Tween] should use [code]_process[/code] for timekeeping when this is enabled (default).
diff --git a/doc/classes/VSlider.xml b/doc/classes/VSlider.xml
index e4ba4a19c5..fa4fa34d54 100644
--- a/doc/classes/VSlider.xml
+++ b/doc/classes/VSlider.xml
@@ -19,6 +19,8 @@
</theme_item>
<theme_item name="grabber" type="Texture">
</theme_item>
+ <theme_item name="grabber_area" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_disabled" type="Texture">
</theme_item>
<theme_item name="grabber_disabled" type="StyleBox">
diff --git a/doc/classes/VehicleWheel.xml b/doc/classes/VehicleWheel.xml
index 82e93e0f01..b2e54e25bc 100644
--- a/doc/classes/VehicleWheel.xml
+++ b/doc/classes/VehicleWheel.xml
@@ -39,6 +39,12 @@
<description>
</description>
</method>
+ <method name="get_skidinfo" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_suspension_max_force" qualifiers="const">
<return type="float">
</return>
diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml
index bac7d1e3b0..5387ec30b3 100644
--- a/doc/classes/VideoPlayer.xml
+++ b/doc/classes/VideoPlayer.xml
@@ -22,7 +22,7 @@
<return type="int">
</return>
<description>
- Get the amount of miliseconds to store in buffer while playing.
+ Get the amount of milliseconds to store in buffer while playing.
</description>
</method>
<method name="get_stream" qualifiers="const">
@@ -126,7 +126,7 @@
<argument index="0" name="msec" type="int">
</argument>
<description>
- Set the amount of miliseconds to buffer during playback.
+ Set the amount of milliseconds to buffer during playback.
</description>
</method>
<method name="set_expand">
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 2cf36ba69b..58626356bf 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -192,14 +192,14 @@
<return type="Variant">
</return>
<description>
- Returs the drag data from the GUI, that was previously returned by [method Control.get_drag_data].
+ Returns the drag data from the GUI, that was previously returned by [method Control.get_drag_data].
</description>
</method>
<method name="gui_has_modal_stack" qualifiers="const">
<return type="bool">
</return>
<description>
- Returs whether there are shown modals on-screen.
+ Returns whether there are shown modals on-screen.
</description>
</method>
<method name="has_transparent_background" qualifiers="const">
diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml
index b8ef1f8d22..0359f4694d 100644
--- a/doc/classes/VisibilityEnabler2D.xml
+++ b/doc/classes/VisibilityEnabler2D.xml
@@ -33,8 +33,6 @@
</method>
</methods>
<members>
- <member name="fixed_process_parent" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- </member>
<member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled">
</member>
<member name="pause_animated_sprites" type="bool" setter="set_enabler" getter="is_enabler_enabled">
@@ -43,6 +41,8 @@
</member>
<member name="pause_particles" type="bool" setter="set_enabler" getter="is_enabler_enabled">
</member>
+ <member name="physics_process_parent" type="bool" setter="set_enabler" getter="is_enabler_enabled">
+ </member>
<member name="process_parent" type="bool" setter="set_enabler" getter="is_enabler_enabled">
</member>
</members>
@@ -61,8 +61,8 @@
<constant name="ENABLER_PARENT_PROCESS" value="3">
This enabler will stop the parent's _process function.
</constant>
- <constant name="ENABLER_PARENT_FIXED_PROCESS" value="4">
- This enabler will stop the parent's _fixed_process function.
+ <constant name="ENABLER_PARENT_PHYSICS_PROCESS" value="4">
+ This enabler will stop the parent's _physics_process function.
</constant>
<constant name="ENABLER_MAX" value="6">
</constant>
diff --git a/doc/classes/VisualScript.xml b/doc/classes/VisualScript.xml
index e44547cd8f..8961ff1564 100644
--- a/doc/classes/VisualScript.xml
+++ b/doc/classes/VisualScript.xml
@@ -4,7 +4,7 @@
A script implemented in the Visual Script programming environment.
</brief_description>
<description>
- A script implemented in the Visual Script programming environment. The script exends the functionality of all objects that instance it.
+ A script implemented in the Visual Script programming environment. The script extends the functionality of all objects that instance it.
[method Object.set_script] extends an existing object, if that object's class matches one of the script's base classes.
You are most likely to use this class via the Visual Script editor or when writing plugins for it.
</description>
diff --git a/doc/classes/VisualScriptClassConstant.xml b/doc/classes/VisualScriptClassConstant.xml
index 70e7de5dd9..0377fa8f09 100644
--- a/doc/classes/VisualScriptClassConstant.xml
+++ b/doc/classes/VisualScriptClassConstant.xml
@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptClassConstant" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
- A Visual Script node representing a constant from a class.
+ Gets a constant from a given class.
</brief_description>
<description>
- A Visual Script node representing a constant from the classes, such as [@GlobalScope.TYPE_INT].
+ This node returns a constant from a given class, such as [@GlobalScope.TYPE_INT]. See the given class' documentation for available constants.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (variant): [code]value[/code]
</description>
<tutorials>
</tutorials>
@@ -42,10 +46,10 @@
</methods>
<members>
<member name="base_type" type="String" setter="set_base_type" getter="get_base_type">
- The type to get the constant from.
+ The constant's parent class.
</member>
<member name="constant" type="String" setter="set_class_constant" getter="get_class_constant">
- The name of the constant to return.
+ The constant to return. See the given class for its available constants.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptConstant.xml b/doc/classes/VisualScriptConstant.xml
index 508087a928..2a704adecf 100644
--- a/doc/classes/VisualScriptConstant.xml
+++ b/doc/classes/VisualScriptConstant.xml
@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptConstant" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
- A Visual Script node which returns a constant value.
+ Gets a contant's value.
</brief_description>
<description>
- A Visual Script node which returns the specified constant value.
+ This node returns a constant's value.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (variant): [code]get[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptEmitSignal.xml b/doc/classes/VisualScriptEmitSignal.xml
index 844b5a40ec..8d132ed321 100644
--- a/doc/classes/VisualScriptEmitSignal.xml
+++ b/doc/classes/VisualScriptEmitSignal.xml
@@ -1,10 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptEmitSignal" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
- A Visual Script node which emits a specified signal.
+ Emits a specified signal.
</brief_description>
<description>
- A Visual Script node which emits a specified signal when it is executed.
+ Emits a specified signal when it is executed.
+ [b]Input Ports:[/b]
+ - Sequence: [code]emit[/code]
+ [b]Output Ports:[/b]
+ - Sequence
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptIterator.xml b/doc/classes/VisualScriptIterator.xml
index 74309fcf00..1f9a4fddde 100644
--- a/doc/classes/VisualScriptIterator.xml
+++ b/doc/classes/VisualScriptIterator.xml
@@ -1,8 +1,17 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptIterator" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Steps through items in a given input.
</brief_description>
<description>
+ This node steps through each item in a given input. Input can be any sequence data type, such as an [Array] or [String]. When each item has been processed, execution passed out the [code]exit[/code] Sequence port.
+ [b]Input Ports:[/b]
+ - Sequence: [code]for (elem) in (input)[/code]
+ - Data (variant): [code]input[/code]
+ [b]Output Ports:[/b]
+ - Sequence: [code]each[/code]
+ - Sequence: [code]exit[/code]
+ - Data (variant): [code]elem[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptLocalVar.xml b/doc/classes/VisualScriptLocalVar.xml
index 7db550d5fe..3101b3e34b 100644
--- a/doc/classes/VisualScriptLocalVar.xml
+++ b/doc/classes/VisualScriptLocalVar.xml
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptLocalVar" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Gets a local variable's value.
</brief_description>
<description>
+ Returns a local variable's value. "Var Name" must be supplied, with an optional type.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (variant): [code]get[/code]
</description>
<tutorials>
</tutorials>
@@ -40,8 +46,10 @@
</methods>
<members>
<member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type">
+ The local variable's type.
</member>
<member name="var_name" type="String" setter="set_var_name" getter="get_var_name">
+ The local variable's name.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptLocalVarSet.xml b/doc/classes/VisualScriptLocalVarSet.xml
index 6e69f13383..e039a7204e 100644
--- a/doc/classes/VisualScriptLocalVarSet.xml
+++ b/doc/classes/VisualScriptLocalVarSet.xml
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptLocalVarSet" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Changes a local variable's value.
</brief_description>
<description>
+ Changes a local variable's value to the given input. The new value is also provided on an output Data port.
+ [b]Input Ports:[/b]
+ - Sequence
+ - Data (variant): [code]set[/code]
+ [b]Output Ports:[/b]
+ - Sequence
+ - Data (variant): [code]get[/code]
</description>
<tutorials>
</tutorials>
@@ -40,8 +48,10 @@
</methods>
<members>
<member name="type" type="int" setter="set_var_type" getter="get_var_type" enum="Variant.Type">
+ The local variable's type.
</member>
<member name="var_name" type="String" setter="set_var_name" getter="get_var_name">
+ The local variable's name.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptMathConstant.xml b/doc/classes/VisualScriptMathConstant.xml
index 1ef7d71e10..86744e5caf 100644
--- a/doc/classes/VisualScriptMathConstant.xml
+++ b/doc/classes/VisualScriptMathConstant.xml
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptMathConstant" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Commonly used mathematical constants.
</brief_description>
<description>
+ Provides common math constants, such as Pi or Euler's constant, on an output Data port.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (variant): [code]get[/code]
</description>
<tutorials>
</tutorials>
@@ -26,24 +32,33 @@
</methods>
<members>
<member name="constant" type="int" setter="set_math_constant" getter="get_math_constant" enum="VisualScriptMathConstant.MathConstant">
+ The math constant.
</member>
</members>
<constants>
<constant name="MATH_CONSTANT_ONE" value="0">
+ Unity: [code]1[/code]
</constant>
<constant name="MATH_CONSTANT_PI" value="1">
+ Pi: [code]3.141593[/code]
</constant>
<constant name="MATH_CONSTANT_2PI" value="2">
+ Pi times two: [code]6.283185[/code]
</constant>
<constant name="MATH_CONSTANT_HALF_PI" value="3">
+ Pi divided by two: [code]1.570796[/code]
</constant>
<constant name="MATH_CONSTANT_E" value="4">
+ Natural log: [code]2.718282[/code]
</constant>
<constant name="MATH_CONSTANT_SQRT2" value="5">
+ Square root of two: [code]1.414214[/code]
</constant>
<constant name="MATH_CONSTANT_INF" value="6">
+ Infinity: [code]inf[/code]
</constant>
<constant name="MATH_CONSTANT_NAN" value="7">
+ Not a number: [code]nan[/code]
</constant>
<constant name="MATH_CONSTANT_MAX" value="8">
</constant>
diff --git a/doc/classes/VisualScriptOperator.xml b/doc/classes/VisualScriptOperator.xml
index 7e85af8af2..de08075af2 100644
--- a/doc/classes/VisualScriptOperator.xml
+++ b/doc/classes/VisualScriptOperator.xml
@@ -7,9 +7,7 @@
- Data (variant): [code]A[/code]
- Data (variant): [code]B[/code]
[b]Output Ports:[/b]
- - Sequence: [code]true[/code]
- - Sequence: [code]false[/code]
- - Sequence: [code]done[/code]
+ - Data (variant): [code]result[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptPreload.xml b/doc/classes/VisualScriptPreload.xml
index b68bf5546b..b683439751 100644
--- a/doc/classes/VisualScriptPreload.xml
+++ b/doc/classes/VisualScriptPreload.xml
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptPreload" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Creates a new [Resource] or loads one from the filesystem.
</brief_description>
<description>
+ Creates a new [Resource] or loads one from the filesystem.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (object): [code]res[/code]
</description>
<tutorials>
</tutorials>
@@ -26,6 +32,7 @@
</methods>
<members>
<member name="resource" type="Resource" setter="set_preload" getter="get_preload">
+ The [Resource] to load.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptReturn.xml b/doc/classes/VisualScriptReturn.xml
index 55c53e17a0..ad18e96230 100644
--- a/doc/classes/VisualScriptReturn.xml
+++ b/doc/classes/VisualScriptReturn.xml
@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptReturn" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Exits a function and returns an optional value.
</brief_description>
<description>
+ Ends the execution of a function and returns control to the calling function. Optionally, it can return a [Variant] value.
+ [b]Input Ports:[/b]
+ - Sequence
+ - Data (variant): [code]result[/code] (optional)
+ [b]Output Ports:[/b]
+ none
</description>
<tutorials>
</tutorials>
@@ -40,8 +47,10 @@
</methods>
<members>
<member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled">
+ If [code]true[/code] the [code]return[/code] input port is available.
</member>
<member name="return_type" type="int" setter="set_return_type" getter="get_return_type" enum="Variant.Type">
+ The return value's data type.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptSelect.xml b/doc/classes/VisualScriptSelect.xml
index 855da76e6c..f265c57645 100644
--- a/doc/classes/VisualScriptSelect.xml
+++ b/doc/classes/VisualScriptSelect.xml
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptSelect" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Chooses between two input values.
</brief_description>
<description>
+ Chooses between two input values based on a Boolean condition.
+ [b]Input Ports:[/b]
+ - Data (boolean): [code]cond[/code]
+ - Data (variant): [code]a[/code]
+ - Data (variant): [code]b[/code]
+ [b]Output Ports:[/b]
+ - Data (variant): [code]out[/code]
</description>
<tutorials>
</tutorials>
@@ -26,6 +34,7 @@
</methods>
<members>
<member name="type" type="int" setter="set_typed" getter="get_typed" enum="Variant.Type">
+ The input variables' type.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptSelf.xml b/doc/classes/VisualScriptSelf.xml
index a60f7eee03..723b138722 100644
--- a/doc/classes/VisualScriptSelf.xml
+++ b/doc/classes/VisualScriptSelf.xml
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptSelf" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Outputs a reference to the current instance.
</brief_description>
<description>
+ Provides a reference to the node running the visual script.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (object): [code]instance[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptSequence.xml b/doc/classes/VisualScriptSequence.xml
index a60c9e782b..4ea4203407 100644
--- a/doc/classes/VisualScriptSequence.xml
+++ b/doc/classes/VisualScriptSequence.xml
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptSequence" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Executes a series of Sequence ports.
</brief_description>
<description>
+ Steps through a series of one or more output Sequence ports. The [code]current[/code] data port outputs the currently executing item.
+ [b]Input Ports:[/b]
+ - Sequence: [code]in order[/code]
+ [b]Output Ports:[/b]
+ - Sequence: [code]1[/code]
+ - Sequence: [code]2 - n[/code] (optional)
+ - Data (int): [code]current[/code]
</description>
<tutorials>
</tutorials>
@@ -26,6 +34,7 @@
</methods>
<members>
<member name="steps" type="int" setter="set_steps" getter="get_steps">
+ The number of steps in the sequence.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptSwitch.xml b/doc/classes/VisualScriptSwitch.xml
index 95ed737372..2540ae54cc 100644
--- a/doc/classes/VisualScriptSwitch.xml
+++ b/doc/classes/VisualScriptSwitch.xml
@@ -1,8 +1,19 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptSwitch" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Branches program flow based on a given input's value.
</brief_description>
<description>
+ Branches the flow based on an input's value. Use "Case Count" in the Inspector to set the number of branches and each comparison's optional type.
+ [b]Input Ports:[/b]
+ - Sequence: [code]'input' is[/code]
+ - Data (variant): [code]=[/code]
+ - Data (variant): [code]=[/code] (optional)
+ - Data (variant): [code]input[/code]
+ [b]Output Ports:[/b]
+ - Sequence
+ - Sequence (optional)
+ - Sequence: [code]done[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptVariableGet.xml b/doc/classes/VisualScriptVariableGet.xml
index 8411933756..5b45dd0cc4 100644
--- a/doc/classes/VisualScriptVariableGet.xml
+++ b/doc/classes/VisualScriptVariableGet.xml
@@ -1,8 +1,14 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptVariableGet" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Gets a variable's value.
</brief_description>
<description>
+ Returns a variable's value. "Var Name" must be supplied, with an optional type.
+ [b]Input Ports:[/b]
+ none
+ [b]Output Ports:[/b]
+ - Data (variant): [code]value[/code]
</description>
<tutorials>
</tutorials>
@@ -26,6 +32,7 @@
</methods>
<members>
<member name="var_name" type="String" setter="set_variable" getter="get_variable">
+ The variable's name.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptVariableSet.xml b/doc/classes/VisualScriptVariableSet.xml
index fbe0f8e275..51f85f6881 100644
--- a/doc/classes/VisualScriptVariableSet.xml
+++ b/doc/classes/VisualScriptVariableSet.xml
@@ -1,8 +1,15 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptVariableSet" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Changes a variable's value.
</brief_description>
<description>
+ Changes a variable's value to the given input.
+ [b]Input Ports:[/b]
+ - Sequence
+ - Data (variant): [code]set[/code]
+ [b]Output Ports:[/b]
+ - Sequence
</description>
<tutorials>
</tutorials>
@@ -26,6 +33,7 @@
</methods>
<members>
<member name="var_name" type="String" setter="set_variable" getter="get_variable">
+ The variable's name.
</member>
</members>
<constants>
diff --git a/doc/classes/VisualScriptWhile.xml b/doc/classes/VisualScriptWhile.xml
index b49678582e..60bf161339 100644
--- a/doc/classes/VisualScriptWhile.xml
+++ b/doc/classes/VisualScriptWhile.xml
@@ -1,8 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VisualScriptWhile" inherits="VisualScriptNode" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Conditional loop.
</brief_description>
<description>
+ Loops while a condition is [code]true[/code]. Execution continues out the [code]exit[/code] Sequence port when the loop terminates.
+ [b]Input Ports:[/b]
+ - Sequence: [code]while(cond)[/code]
+ - Data (bool): [code]cond[/code]
+ [b]Output Ports:[/b]
+ - Sequence: [code]repeat[/code]
+ - Sequence: [code]exit[/code]
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/VisualScriptYield.xml b/doc/classes/VisualScriptYield.xml
index b8938daa67..a0d95f151a 100644
--- a/doc/classes/VisualScriptYield.xml
+++ b/doc/classes/VisualScriptYield.xml
@@ -47,7 +47,7 @@
<constants>
<constant name="YIELD_FRAME" value="1">
</constant>
- <constant name="YIELD_FIXED_FRAME" value="2">
+ <constant name="YIELD_PHYSICS_FRAME" value="2">
</constant>
<constant name="YIELD_WAIT" value="3">
</constant>
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index 242fc18ab9..4bc6a49e91 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -18,6 +18,26 @@
<description>
</description>
</method>
+ <method name="force_sync">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="request_frame_drawn_callback">
+ <return type="void">
+ </return>
+ <argument index="0" name="where" type="Object">
+ </argument>
+ <argument index="1" name="method" type="String">
+ </argument>
+ <argument index="2" name="userdata" type="Variant">
+ </argument>
+ <description>
+ Schedules a callback to the corresponding named 'method' on 'where' after a frame has been drawn.
+ The callback method must use only 1 argument which will be called with 'userdata'.
+ </description>
+ </method>
<method name="texture_create">
<return type="RID">
</return>
diff --git a/doc/classes/WeakRef.xml b/doc/classes/WeakRef.xml
index 1071a40c3b..23629881d3 100644
--- a/doc/classes/WeakRef.xml
+++ b/doc/classes/WeakRef.xml
@@ -4,7 +4,7 @@
Holds an [Object], but does not contribute to the reference count if the object is a reference.
</brief_description>
<description>
- A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GDScript.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to eachother. Without weakrefs, using these classes could lead to memory leaks, since both references keep eachother from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
+ A weakref can hold a [Reference], without contributing to the reference counter. A weakref can be created from an [Object] using [method @GDScript.weakref]. If this object is not a reference, weakref still works, however, it does not have any effect on the object. Weakrefs are useful in cases where multiple classes have variables that refer to each other. Without weakrefs, using these classes could lead to memory leaks, since both references keep each other from being released. Making part of the variables a weakref can prevent this cyclic dependency, and allows the references to be released.
</description>
<tutorials>
</tutorials>
diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py
index e89b49eb4d..170ded9f50 100644
--- a/doc/tools/doc_status.py
+++ b/doc/tools/doc_status.py
@@ -250,15 +250,16 @@ class ClassStatus:
for tag in list(c):
if tag.tag in ['methods']:
for sub_tag in list(tag):
- methods.append(sub_tag.find('name'))
+ methods.append(sub_tag.attrib['name'])
if tag.tag in ['members']:
for sub_tag in list(tag):
try:
- methods.remove(sub_tag.find('setter'))
- methods.remove(sub_tag.find('getter'))
+ if(sub_tag.attrib['setter'].startswith('_') == False):
+ methods.remove(sub_tag.attrib['setter'])
+ if(sub_tag.attrib['getter'].startswith('_') == False):
+ methods.remove(sub_tag.attrib['getter'])
except:
pass
-
for tag in list(c):
if tag.tag == 'brief_description':
@@ -269,7 +270,7 @@ class ClassStatus:
elif tag.tag in ['methods', 'signals']:
for sub_tag in list(tag):
- if sub_tag.find('name') in methods or tag.tag == 'signals':
+ if sub_tag.attrib['name'] in methods or tag.tag == 'signals':
descr = sub_tag.find('description')
status.progresses[tag.tag].increment(len(descr.text.strip()) > 0)
elif tag.tag in ['constants', 'members']:
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index c4dff588b0..0c67e3be4c 100644
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -14,14 +14,14 @@ for arg in sys.argv[1:]:
input_list.append(arg)
if len(input_list) < 1:
- print 'usage: makerst.py <path to folders> and/or <path to .xml files> (order of arguments irrelevant)'
- print 'example: makerst.py "../../modules/" "../classes" path_to/some_class.xml'
+ print('usage: makerst.py <path to folders> and/or <path to .xml files> (order of arguments irrelevant)')
+ print('example: makerst.py "../../modules/" "../classes" path_to/some_class.xml')
sys.exit(0)
def validate_tag(elem, tag):
if elem.tag != tag:
- print "Tag mismatch, expected '" + tag + "', got " + elem.tag
+ print("Tag mismatch, expected '" + tag + "', got " + elem.tag)
sys.exit(255)
@@ -41,7 +41,7 @@ def make_class_list(class_list, columns):
f = codecs.open('class_list.rst', 'wb', 'utf-8')
prev = 0
col_max = len(class_list) / columns + 1
- print ('col max is ', col_max)
+ print(('col max is ', col_max))
col_count = 0
row_count = 0
last_initial = ''
@@ -300,11 +300,6 @@ def make_method(
if declare or pp == None:
- # span.attrib["class"]="funcdecl"
- # a=ET.SubElement(span,"a")
- # a.attrib["name"]=name+"_"+m.attrib["name"]
- # a.text=name+"::"+m.attrib["name"]
-
s = ' **' + m.attrib['name'] + '** '
else:
s = ':ref:`' + m.attrib['name'] + '<class_' + cname + "_" + m.attrib['name'] + '>` '
@@ -446,6 +441,7 @@ def make_rst_class(node):
f.write(make_heading('Signals', '-'))
for m in list(events):
make_method(f, node.attrib['name'], m, True, name, True)
+ f.write('\n')
d = m.find('description')
if d == None or d.text.strip() == '':
continue
@@ -507,8 +503,8 @@ for path in input_list:
for subdir, dirs, _ in os.walk(path):
if 'doc_classes' in dirs:
doc_dir = os.path.join(subdir, 'doc_classes')
- class_file_name = [f for f in os.listdir(doc_dir) if f.endswith('.xml')][0]
- file_list.append(os.path.join(doc_dir, class_file_name))
+ class_file_names = [f for f in os.listdir(doc_dir) if f.endswith('.xml')]
+ file_list += [os.path.join(doc_dir, f) for f in class_file_names]
elif not os.path.isfile(path):
file_list += [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml')]
elif os.path.isfile(path) and path.endswith('.xml'):
@@ -519,7 +515,7 @@ for file in file_list:
doc = tree.getroot()
if 'version' not in doc.attrib:
- print "Version missing from 'doc'"
+ print("Version missing from 'doc'")
sys.exit(255)
version = doc.attrib['version']
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index ba8d490762..39f027a5aa 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -2350,22 +2350,7 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
glDepthFunc(GL_LEQUAL);
glColorMask(1, 1, 1, 1);
- float flip_sign = p_vflip ? -1 : 1;
-
- Vector3 vertices[8] = {
- Vector3(-1, -1 * flip_sign, 1),
- Vector3(0, 1, 0),
- Vector3(1, -1 * flip_sign, 1),
- Vector3(1, 1, 0),
- Vector3(1, 1 * flip_sign, 1),
- Vector3(1, 0, 0),
- Vector3(-1, 1 * flip_sign, 1),
- Vector3(0, 0, 0)
-
- };
-
- //sky uv vectors
- float vw, vh, zn;
+ // Camera
CameraMatrix camera;
if (p_custom_fov) {
@@ -2380,17 +2365,39 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
camera = p_projection;
}
- camera.get_viewport_size(vw, vh);
- zn = p_projection.get_z_near();
+ float flip_sign = p_vflip ? -1 : 1;
- for (int i = 0; i < 4; i++) {
+ /*
+ If matrix[2][0] or matrix[2][1] we're dealing with an asymmetrical projection matrix. This is the case for stereoscopic rendering (i.e. VR).
+ To ensure the image rendered is perspective correct we need to move some logic into the shader. For this the USE_ASYM_PANO option is introduced.
+ It also means the uv coordinates are ignored in this mode and we don't need our loop.
+ */
+ bool asymmetrical = ((camera.matrix[2][0] != 0.0) || (camera.matrix[2][1] != 0.0));
- Vector3 uv = vertices[i * 2 + 1];
- uv.x = (uv.x * 2.0 - 1.0) * vw;
- uv.y = -(uv.y * 2.0 - 1.0) * vh;
- uv.z = -zn;
- vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
- vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
+ Vector3 vertices[8] = {
+ Vector3(-1, -1 * flip_sign, 1),
+ Vector3(0, 1, 0),
+ Vector3(1, -1 * flip_sign, 1),
+ Vector3(1, 1, 0),
+ Vector3(1, 1 * flip_sign, 1),
+ Vector3(1, 0, 0),
+ Vector3(-1, 1 * flip_sign, 1),
+ Vector3(0, 0, 0)
+ };
+
+ if (!asymmetrical) {
+ float vw, vh, zn;
+ camera.get_viewport_size(vw, vh);
+ zn = p_projection.get_z_near();
+
+ for (int i = 0; i < 4; i++) {
+ Vector3 uv = vertices[i * 2 + 1];
+ uv.x = (uv.x * 2.0 - 1.0) * vw;
+ uv.y = -(uv.y * 2.0 - 1.0) * vh;
+ uv.z = -zn;
+ vertices[i * 2 + 1] = p_transform.basis.xform(uv).normalized();
+ vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
+ }
}
glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
@@ -2399,16 +2406,24 @@ void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const C
glBindVertexArray(state.sky_array);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_ASYM_PANO, asymmetrical);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, !asymmetrical);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, true);
storage->shaders.copy.bind();
storage->shaders.copy.set_uniform(CopyShaderGLES3::MULTIPLIER, p_energy);
+ if (asymmetrical) {
+ // pack the bits we need from our projection matrix
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::ASYM_PROJ, camera.matrix[2][0], camera.matrix[0][0], camera.matrix[2][1], camera.matrix[1][1]);
+ ///@TODO I couldn't get mat3 + p_transform.basis to work, that would be better here.
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::PANO_TRANSFORM, p_transform);
+ }
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glColorMask(1, 1, 1, 1);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_ASYM_PANO, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, false);
}
@@ -2554,8 +2569,8 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
ubo_data.light_direction_attenuation[3] = 1.0;
ubo_data.light_params[0] = 0;
- ubo_data.light_params[1] = li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
- ubo_data.light_params[2] = 0;
+ ubo_data.light_params[1] = 0;
+ ubo_data.light_params[2] = li->light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
ubo_data.light_params[3] = 0;
Color shadow_color = li->light_ptr->shadow_color.to_linear();
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 44a9909bd7..296d945cda 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -2430,7 +2430,8 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (material->shader && material->shader->mode == VS::SHADER_SPATIAL) {
- if (!material->shader->spatial.uses_alpha && material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX) {
+ if (material->shader->spatial.blend_mode == Shader::Spatial::BLEND_MODE_MIX &&
+ (!material->shader->spatial.uses_alpha || (material->shader->spatial.uses_alpha && material->shader->spatial.depth_draw_mode == Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))) {
can_cast_shadow = true;
}
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 91159e3381..5fe7b53a7d 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -838,6 +838,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_lambert_wrap"] = "#define DIFFUSE_LAMBERT_WRAP\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["specular_schlick_ggx"] = "#define SPECULAR_SCHLICK_GGX\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n";
actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n";
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index d33193ee50..743fe122d1 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -27,6 +27,8 @@ void main() {
#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
+#elif defined(USE_ASYM_PANO)
+ uv_interp = vertex_attrib.xy;
#else
uv_interp = uv_in;
#ifdef V_FLIP
@@ -59,6 +61,11 @@ in vec3 cube_interp;
in vec2 uv_interp;
#endif
+#ifdef USE_ASYM_PANO
+uniform highp mat4 pano_transform;
+uniform highp vec4 asym_proj;
+#endif
+
#ifdef USE_CUBEMAP
uniform samplerCube source_cube; //texunit:0
#else
@@ -70,7 +77,7 @@ uniform sampler2D source; //texunit:0
uniform float multiplier;
#endif
-#ifdef USE_PANORAMA
+#if defined(USE_PANORAMA) || defined(USE_ASYM_PANO)
vec4 texturePanorama(vec3 normal,sampler2D pano ) {
@@ -122,6 +129,21 @@ void main() {
vec4 color = texturePanorama( normalize(cube_interp), source );
+#elif defined(USE_ASYM_PANO)
+
+ // When an assymetrical projection matrix is used (applicable for stereoscopic rendering i.e. VR) we need to do this calculation per fragment to get a perspective correct result.
+ // Note that we're ignoring the x-offset for IPD, with Z sufficiently in the distance it becomes neglectible, as a result we could probably just set cube_normal.z to -1.
+ // The Matrix[2][0] (= asym_proj.x) and Matrix[2][1] (= asym_proj.z) values are what provide the right shift in the image.
+
+ vec3 cube_normal;
+ cube_normal.z = -1000000.0;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - asym_proj.x)) / asym_proj.y;
+ cube_normal.y = (cube_normal.z * (-uv_interp.y - asym_proj.z)) / asym_proj.a;
+ cube_normal = mat3(pano_transform) * cube_normal;
+ cube_normal.z = -cube_normal.z;
+
+ vec4 color = texturePanorama( normalize(cube_normal.xyz), source );
+
#elif defined(USE_CUBEMAP)
vec4 color = texture( source_cube, normalize(cube_interp) );
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 341a5bf2c7..2c6dd5552e 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -865,11 +865,57 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
#endif
-// GGX Specular
-// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
-float G1V(float dotNV, float k)
-{
- return 1.0 / (dotNV * (1.0 - k) + k);
+
+// This returns the G_GGX function divided by 2 cos_theta_m, where in practice cos_theta_m is either N.L or N.V.
+// We're dividing this factor off because the overall term we'll end up looks like
+// (see, for example, the first unnumbered equation in B. Burley, "Physically Based Shading at Disney", SIGGRAPH 2012):
+//
+// F(L.V) D(N.H) G(N.L) G(N.V) / (4 N.L N.V)
+//
+// We're basically regouping this as
+//
+// F(L.V) D(N.H) [G(N.L)/(2 N.L)] [G(N.V) / (2 N.V)]
+//
+// and thus, this function implements the [G(N.m)/(2 N.m)] part with m = L or V.
+//
+// The contents of the D and G (G1) functions (GGX) are taken from
+// E. Heitz, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs", J. Comp. Graph. Tech. 3 (2) (2014).
+// Eqns 71-72 and 85-86 (see also Eqns 43 and 80).
+
+float G_GGX_2cos(float cos_theta_m, float alpha) {
+ // Schlick's approximation
+ // C. Schlick, "An Inexpensive BRDF Model for Physically-based Rendering", Computer Graphics Forum. 13 (3): 233 (1994)
+ // Eq. (19), although see Heitz (2014) the about the problems with his derivation.
+ // It nevertheless approximates GGX well with k = alpha/2.
+ float k = 0.5*alpha;
+ return 0.5 / (cos_theta_m * (1.0 - k) + k);
+
+ // float cos2 = cos_theta_m*cos_theta_m;
+ // float sin2 = (1.0-cos2);
+ // return 1.0 /( cos_theta_m + sqrt(cos2 + alpha*alpha*sin2) );
+}
+
+float D_GGX(float cos_theta_m, float alpha) {
+ float alpha2 = alpha*alpha;
+ float d = 1.0 + (alpha2-1.0)*cos_theta_m*cos_theta_m;
+ return alpha2/(M_PI * d * d);
+}
+
+float G_GGX_anisotropic_2cos(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
+ float cos2 = cos_theta_m * cos_theta_m;
+ float sin2 = (1.0-cos2);
+ float s_x = alpha_x * cos_phi;
+ float s_y = alpha_y * sin_phi;
+ return 1.0 / (cos_theta_m + sqrt(cos2 + (s_x*s_x + s_y*s_y)*sin2 ));
+}
+
+float D_GGX_anisotropic(float cos_theta_m, float alpha_x, float alpha_y, float cos_phi, float sin_phi) {
+ float cos2 = cos_theta_m * cos_theta_m;
+ float sin2 = (1.0-cos2);
+ float r_x = cos_phi/alpha_x;
+ float r_y = sin_phi/alpha_y;
+ float d = cos2 + sin2*(r_x * r_x + r_y * r_y);
+ return 1.0 / (M_PI * alpha_x * alpha_y * d * d );
}
@@ -1019,7 +1065,6 @@ LIGHT_SHADER_CODE
#elif defined(SPECULAR_SCHLICK_GGX)
// shlick+ggx as default
- float alpha = roughness * roughness;
vec3 H = normalize(V + L);
@@ -1035,26 +1080,22 @@ LIGHT_SHADER_CODE
float ay = ry*ry;
float XdotH = dot( T, H );
float YdotH = dot( B, H );
- float denom = XdotH*XdotH / (ax*ax) + YdotH*YdotH / (ay*ay) + cNdotH*cNdotH;
- float D = 1.0 / ( M_PI * ax*ay * denom*denom );
+ float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH);
+ float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
#else
- float alphaSqr = alpha * alpha;
- float denom = cNdotH * cNdotH * (alphaSqr - 1.0) + 1.0;
- float D = alphaSqr / (M_PI * denom * denom);
+ float alpha = roughness * roughness;
+ float D = D_GGX(cNdotH, alpha);
+ float G = G_GGX_2cos(cNdotL, alpha) * G_GGX_2cos(cNdotV, alpha);
#endif
// F
float F0 = 1.0; // FIXME
float cLdotH5 = SchlickFresnel(cLdotH);
float F = mix(cLdotH5, 1.0, F0);
- // V
- float k = alpha / 2.0f;
- float vis = G1V(cNdotL, k) * G1V(cNdotV, k);
+ float specular_brdf_NL = cNdotL * D * F * G;
- float speci = cNdotL * D * F * vis;
-
- specular_light += speci * light_color * specular_blob_intensity * attenuation;
+ specular_light += specular_brdf_NL * light_color * specular_blob_intensity * attenuation;
#endif
#if defined(LIGHT_USE_CLEARCOAT)
@@ -1069,7 +1110,7 @@ LIGHT_SHADER_CODE
#endif
float Dr = GTR1(cNdotH, mix(.1, .001, clearcoat_gloss));
float Fr = mix(.04, 1.0, cLdotH5);
- float Gr = G1V(cNdotL, .25) * G1V(cNdotV, .25);
+ float Gr = G_GGX_2cos(cNdotL, .25) * G_GGX_2cos(cNdotV, .25);
specular_light += .25*clearcoat*Gr*Fr*Dr;
@@ -2063,5 +2104,3 @@ FRAGMENT_SHADER_CODE
}
-
-
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 73dec4f90c..2f671158b2 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -175,12 +175,9 @@ vec3 tonemap_reindhart(vec3 color,float white) {
return ( color * ( 1.0 + ( color / ( white) ) ) ) / ( 1.0 + color );
}
-
void main() {
- ivec2 coord = ivec2(gl_FragCoord.xy);
- vec3 color = texelFetch(source,coord,0).rgb;
-
+ vec4 color = textureLod(source, uv_interp, 0.0);
#ifdef USE_AUTO_EXPOSURE
@@ -324,5 +321,3 @@ void main() {
frag_color=vec4(color.rgb,1.0);
}
-
-
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index e0a62b316d..2a3d48746f 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -343,7 +343,7 @@ Error OS_Unix::execute(const String &p_path, const List<String> &p_arguments, bo
execvp(getprogname(), &args[0]);
}
#else
- execv(p_path.utf8().get_data(), &args[0]);
+ execvp(p_path.utf8().get_data(), &args[0]);
#endif
// still alive? something failed..
fprintf(stderr, "**ERROR** OS_Unix::execute - Could not create child process while executing: %s\n", p_path.utf8().get_data());
diff --git a/drivers/windows/dir_access_windows.cpp b/drivers/windows/dir_access_windows.cpp
index 8d6e78dbee..0bc4201ba3 100644
--- a/drivers/windows/dir_access_windows.cpp
+++ b/drivers/windows/dir_access_windows.cpp
@@ -164,7 +164,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
p_dir = fix_path(p_dir);
if (p_dir.is_rel_path())
- p_dir = get_current_dir().plus_file(p_dir);
+ p_dir = current_dir.plus_file(p_dir);
p_dir = p_dir.replace("/", "\\");
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp
index b832b993bb..54eb695178 100644
--- a/editor/animation_editor.cpp
+++ b/editor/animation_editor.cpp
@@ -64,6 +64,8 @@ private:
float transition;
Mode mode;
+ LineEdit *value_edit;
+
void _notification(int p_what) {
if (p_what == NOTIFICATION_DRAW) {
@@ -144,14 +146,11 @@ private:
}
}
- String txt = String::num(exp, 2);
if (mode == MODE_DISABLED) {
- txt = TTR("Disabled");
+ f->draw(ci, Point2(5, 5 + f->get_ascent()), TTR("Disabled"), color);
} else if (mode == MODE_MULTIPLE) {
- txt += " - " + TTR("All Selection");
+ f->draw(ci, Point2(5, 5 + f->get_ascent() + value_edit->get_size().height), TTR("All Selection"), color);
}
-
- f->draw(ci, Point2(10, 10 + f->get_ascent()), txt, color);
}
}
@@ -163,6 +162,8 @@ private:
if (mode == MODE_DISABLED)
return;
+ value_edit->release_focus();
+
float rel = mm->get_relative().x;
if (rel == 0)
return;
@@ -187,24 +188,28 @@ private:
if (sg)
val = -val;
- transition = val;
- update();
- //emit_signal("variant_changed");
- emit_signal("transition_changed", transition);
+ force_transition(val);
}
}
+ void _edit_value_changed(const String &p_value_str) {
+
+ force_transition(p_value_str.to_float());
+ }
+
public:
static void _bind_methods() {
//ClassDB::bind_method("_update_obj",&AnimationKeyEdit::_update_obj);
ClassDB::bind_method("_gui_input", &AnimationCurveEdit::_gui_input);
+ ClassDB::bind_method("_edit_value_changed", &AnimationCurveEdit::_edit_value_changed);
ADD_SIGNAL(MethodInfo("transition_changed"));
}
void set_mode(Mode p_mode) {
mode = p_mode;
+ value_edit->set_visible(mode != MODE_DISABLED);
update();
}
@@ -218,7 +223,8 @@ public:
}
void set_transition(float p_transition) {
- transition = p_transition;
+ transition = Math::stepify(p_transition, 0.01);
+ value_edit->set_text(String::num(transition));
update();
}
@@ -229,9 +235,8 @@ public:
void force_transition(float p_value) {
if (mode == MODE_DISABLED)
return;
- transition = p_value;
+ set_transition(p_value);
emit_signal("transition_changed", p_value);
- update();
}
AnimationCurveEdit() {
@@ -239,6 +244,11 @@ public:
transition = 1.0;
set_default_cursor_shape(CURSOR_HSPLIT);
mode = MODE_DISABLED;
+
+ value_edit = memnew(LineEdit);
+ value_edit->hide();
+ value_edit->connect("text_entered", this, "_edit_value_changed");
+ add_child(value_edit);
}
};
@@ -1101,7 +1111,7 @@ void AnimationKeyEditor::_track_editor_draw() {
Color select_color = color;
select_color.a = 0.1;
Color invalid_path_color = get_color("error_color", "Editor");
- Color track_select_color = get_color("accent", "Editor");
+ Color track_select_color = get_color("highlighted_font_color", "Editor");
Ref<Texture> remove_icon = get_icon("Remove", "EditorIcons");
Ref<Texture> move_up_icon = get_icon("MoveUp", "EditorIcons");
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index 5305c4f256..64f1c4ccb2 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -337,92 +337,142 @@ DependencyEditorOwners::DependencyEditorOwners() {
///////////////////////
-void DependencyRemoveDialog::_fill_owners(EditorFileSystemDirectory *efsd) {
+void DependencyRemoveDialog::_find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder) {
+ if (!efsd)
+ return;
+
+ for (int i = 0; i < efsd->get_subdir_count(); ++i) {
+ _find_files_in_removed_folder(efsd->get_subdir(i), p_folder);
+ }
+ for (int i = 0; i < efsd->get_file_count(); i++) {
+ String file = efsd->get_file_path(i);
+ ERR_FAIL_COND(all_remove_files.has(file)); //We are deleting a directory which is contained in a directory we are deleting...
+ all_remove_files[file] = p_folder; //Point the file to the ancestor directory we are deleting so we know what to parent it under in the tree.
+ }
+}
+void DependencyRemoveDialog::_find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed) {
if (!efsd)
return;
for (int i = 0; i < efsd->get_subdir_count(); i++) {
- _fill_owners(efsd->get_subdir(i));
+ _find_all_removed_dependencies(efsd->get_subdir(i), p_removed);
}
for (int i = 0; i < efsd->get_file_count(); i++) {
+ const String path = efsd->get_file_path(i);
- Vector<String> deps = efsd->get_file_deps(i);
- //print_line(":::"+efsd->get_file_path(i));
- Set<String> met;
- for (int j = 0; j < deps.size(); j++) {
- if (files.has(deps[j])) {
- met.insert(deps[j]);
- }
- }
- if (!met.size())
+ //It doesn't matter if a file we are about to delete will have some of its dependencies removed too
+ if (all_remove_files.has(path))
continue;
- exist = true;
-
- Ref<Texture> icon;
- String type = efsd->get_file_type(i);
- if (!has_icon(type, "EditorIcons")) {
- icon = get_icon("Object", "EditorIcons");
- } else {
- icon = get_icon(type, "EditorIcons");
+ Vector<String> all_deps = efsd->get_file_deps(i);
+ for (int j = 0; j < all_deps.size(); ++j) {
+ if (all_remove_files.has(all_deps[j])) {
+ RemovedDependency dep;
+ dep.file = path;
+ dep.file_type = efsd->get_file_type(i);
+ dep.dependency = all_deps[j];
+ dep.dependency_folder = all_remove_files[all_deps[j]];
+ p_removed.push_back(dep);
+ }
}
+ }
+}
- for (Set<String>::Element *E = met.front(); E; E = E->next()) {
+void DependencyRemoveDialog::_build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed) {
+ owners->clear();
+ owners->create_item(); // root
- String which = E->get();
- if (!files[which]) {
- TreeItem *ti = owners->create_item(owners->get_root());
- ti->set_text(0, which.get_file());
- files[which] = ti;
+ Map<String, TreeItem *> tree_items;
+ for (int i = 0; i < p_removed.size(); i++) {
+ RemovedDependency rd = p_removed[i];
+
+ //Ensure that the dependency is already in the tree
+ if (!tree_items.has(rd.dependency)) {
+ if (rd.dependency_folder.length() > 0) {
+ //Ensure the ancestor folder is already in the tree
+ if (!tree_items.has(rd.dependency_folder)) {
+ TreeItem *folder_item = owners->create_item(owners->get_root());
+ folder_item->set_text(0, rd.dependency_folder);
+ folder_item->set_icon(0, get_icon("Folder", "EditorIcons"));
+ tree_items[rd.dependency_folder] = folder_item;
+ }
+ TreeItem *dependency_item = owners->create_item(tree_items[rd.dependency_folder]);
+ dependency_item->set_text(0, rd.dependency);
+ dependency_item->set_icon(0, get_icon("Warning", "EditorIcons"));
+ tree_items[rd.dependency] = dependency_item;
+ } else {
+ TreeItem *dependency_item = owners->create_item(owners->get_root());
+ dependency_item->set_text(0, rd.dependency);
+ dependency_item->set_icon(0, get_icon("Warning", "EditorIcons"));
+ tree_items[rd.dependency] = dependency_item;
}
- TreeItem *ti = owners->create_item(files[which]);
- ti->set_text(0, efsd->get_file_path(i));
- ti->set_icon(0, icon);
}
+
+ //List this file under this dependency
+ Ref<Texture> icon = has_icon(rd.file_type, "EditorIcons") ? get_icon(rd.file_type, "EditorIcons") : get_icon("Object", "EditorIcons");
+ TreeItem *file_item = owners->create_item(tree_items[rd.dependency]);
+ file_item->set_text(0, rd.file);
+ file_item->set_icon(0, icon);
}
}
-void DependencyRemoveDialog::show(const Vector<String> &to_erase) {
-
- exist = false;
+void DependencyRemoveDialog::show(const Vector<String> &p_folders, const Vector<String> &p_files) {
+ all_remove_files.clear();
+ to_delete.clear();
owners->clear();
- files.clear();
- owners->create_item(); // root
- for (int i = 0; i < to_erase.size(); i++) {
- files[to_erase[i]] = NULL;
+
+ for (int i = 0; i < p_folders.size(); ++i) {
+ String folder = p_folders[i].ends_with("/") ? p_folders[i] : (p_folders[i] + "/");
+ _find_files_in_removed_folder(EditorFileSystem::get_singleton()->get_filesystem_path(folder), folder);
+ to_delete.push_back(folder);
+ }
+ for (int i = 0; i < p_files.size(); ++i) {
+ all_remove_files[p_files[i]] = String();
+ to_delete.push_back(p_files[i]);
}
- _fill_owners(EditorFileSystem::get_singleton()->get_filesystem());
+ Vector<RemovedDependency> removed_deps;
+ _find_all_removed_dependencies(EditorFileSystem::get_singleton()->get_filesystem(), removed_deps);
+ removed_deps.sort();
- if (exist) {
- owners->show();
- text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)"));
- popup_centered_minsize(Size2(500, 220));
- } else {
+ if (removed_deps.empty()) {
owners->hide();
text->set_text(TTR("Remove selected files from the project? (no undo)"));
popup_centered_minsize(Size2(400, 100));
+ } else {
+ _build_removed_dependency_tree(removed_deps);
+ owners->show();
+ text->set_text(TTR("The files being removed are required by other resources in order for them to work.\nRemove them anyway? (no undo)"));
+ popup_centered_minsize(Size2(500, 350));
}
}
void DependencyRemoveDialog::ok_pressed() {
-
- bool changed = false;
-
- for (Map<String, TreeItem *>::Element *E = files.front(); E; E = E->next()) {
-
- if (ResourceCache::has(E->key())) {
- Resource *res = ResourceCache::get(E->key());
+ bool files_only = true;
+ for (int i = 0; i < to_delete.size(); ++i) {
+ if (to_delete[i].ends_with("/")) {
+ files_only = false;
+ } else if (ResourceCache::has(to_delete[i])) {
+ Resource *res = ResourceCache::get(to_delete[i]);
res->set_path(""); //clear reference to path
}
- String fpath = OS::get_singleton()->get_resource_dir() + E->key().replace_first("res://", "/");
- OS::get_singleton()->move_to_trash(fpath);
- changed = true;
+
+ String path = OS::get_singleton()->get_resource_dir() + to_delete[i].replace_first("res://", "/");
+ print_line("Moving to trash: " + path);
+ Error err = OS::get_singleton()->move_to_trash(path);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot remove:\n") + to_delete[i] + "\n");
+ }
}
- if (changed) {
+ if (files_only) {
+ //If we only deleted files we should only need to tell the file system about the files we touched.
+ for (int i = 0; i < to_delete.size(); ++i) {
+ EditorFileSystem::get_singleton()->update_file(to_delete[i]);
+ }
+ } else {
EditorFileSystem::get_singleton()->scan_changes();
}
}
diff --git a/editor/dependency_editor.h b/editor/dependency_editor.h
index 4dfb9de268..c7e9baa5c2 100644
--- a/editor/dependency_editor.h
+++ b/editor/dependency_editor.h
@@ -84,14 +84,33 @@ class DependencyRemoveDialog : public ConfirmationDialog {
Label *text;
Tree *owners;
- bool exist;
- Map<String, TreeItem *> files;
- void _fill_owners(EditorFileSystemDirectory *efsd);
+
+ Map<String, String> all_remove_files;
+ Vector<String> to_delete;
+
+ struct RemovedDependency {
+ String file;
+ String file_type;
+ String dependency;
+ String dependency_folder;
+
+ bool operator<(const RemovedDependency &p_other) const {
+ if (dependency_folder.empty() != p_other.dependency_folder.empty()) {
+ return p_other.dependency_folder.empty();
+ } else {
+ return dependency < p_other.dependency;
+ }
+ }
+ };
+
+ void _find_files_in_removed_folder(EditorFileSystemDirectory *efsd, const String &p_folder);
+ void _find_all_removed_dependencies(EditorFileSystemDirectory *efsd, Vector<RemovedDependency> &p_removed);
+ void _build_removed_dependency_tree(const Vector<RemovedDependency> &p_removed);
void ok_pressed();
public:
- void show(const Vector<String> &to_erase);
+ void show(const Vector<String> &p_folders, const Vector<String> &p_files);
DependencyRemoveDialog();
};
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index cb94ea72d1..2c4d3035a4 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -694,7 +694,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
inherits = doc->class_list[inherits].inherits;
if (inherits != "") {
- class_desc->add_text(" , ");
+ class_desc->add_text(" < ");
}
}
@@ -1699,7 +1699,7 @@ void EditorHelp::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
+ class_desc->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor"));
} break;
@@ -1788,7 +1788,7 @@ EditorHelp::EditorHelp() {
class_desc = memnew(RichTextLabel);
vbc->add_child(class_desc);
class_desc->set_v_size_flags(SIZE_EXPAND_FILL);
- class_desc->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
+ class_desc->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor"));
class_desc->connect("meta_clicked", this, "_class_desc_select");
class_desc->connect("gui_input", this, "_class_desc_input");
}
@@ -1879,7 +1879,7 @@ void EditorHelpBit::_notification(int p_what) {
switch (p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
+ rich_text->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor"));
} break;
default: break;
@@ -1898,6 +1898,7 @@ EditorHelpBit::EditorHelpBit() {
add_child(rich_text);
rich_text->set_anchors_and_margins_preset(Control::PRESET_WIDE);
rich_text->connect("meta_clicked", this, "_meta_clicked");
- rich_text->add_color_override("selection_color", EDITOR_DEF("text_editor/highlighting/selection_color", Color(0.2, 0.2, 1)));
+ rich_text->add_color_override("selection_color", get_color("text_editor/theme/selection_color", "Editor"));
+ rich_text->set_override_selected_font_color(false);
set_custom_minimum_size(Size2(0, 70 * EDSCALE));
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index ff415c83f1..f109cdddc3 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -373,6 +373,9 @@ void EditorNode::_fs_changed() {
String err = "Preset \"" + export_defer.preset + "\" doesn't have a platform.";
ERR_PRINT(err.utf8().get_data());
} else {
+ // ensures export_project does not loop infinitely, because notifications may
+ // come during the export
+ export_defer.preset = "";
platform->export_project(preset, export_defer.debug, export_defer.path, /*p_flags*/ 0);
}
}
@@ -1451,7 +1454,7 @@ void EditorNode::_edit_current() {
}
} else if (current_res->get_path().is_resource_file()) {
if (FileAccess::exists(current_res->get_path() + ".import")) {
- editable_warning = TTR("This resource was imported, so it's not editable. Change it's settings in the import panel and re-import.");
+ editable_warning = TTR("This resource was imported, so it's not editable. Change its settings in the import panel and then re-import.");
}
}
} else if (is_node) {
@@ -3153,12 +3156,19 @@ void EditorNode::_add_to_recent_scenes(const String &p_scene) {
void EditorNode::_open_recent_scene(int p_idx) {
String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
- Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
- ERR_FAIL_INDEX(p_idx, rc.size());
+ if (p_idx == recent_scenes->get_item_count() - 1) {
+
+ EditorSettings::get_singleton()->erase(base + "/_recent_scenes");
+ call_deferred("_update_recent_scenes");
+ } else {
+
+ Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
+ ERR_FAIL_INDEX(p_idx, rc.size());
- String path = "res://" + rc[p_idx];
- load_scene(path);
+ String path = "res://" + rc[p_idx];
+ load_scene(path);
+ }
}
void EditorNode::_update_recent_scenes() {
@@ -3166,10 +3176,15 @@ void EditorNode::_update_recent_scenes() {
String base = "_" + ProjectSettings::get_singleton()->get_resource_path().replace("\\", "::").replace("/", "::");
Vector<String> rc = EDITOR_DEF(base + "/_recent_scenes", Array());
recent_scenes->clear();
+
for (int i = 0; i < rc.size(); i++) {
recent_scenes->add_item(rc[i], i);
}
+
+ recent_scenes->add_separator();
+ recent_scenes->add_shortcut(ED_SHORTCUT("editor/clear_recent", TTR("Clear Recent Scenes")));
+ recent_scenes->set_as_minsize();
}
void EditorNode::_quick_opened() {
@@ -4510,6 +4525,7 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state);
ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs);
ClassDB::bind_method("_discard_changes", &EditorNode::_discard_changes);
+ ClassDB::bind_method("_update_recent_scenes", &EditorNode::_update_recent_scenes);
ClassDB::bind_method("_prepare_history", &EditorNode::_prepare_history);
ClassDB::bind_method("_select_history", &EditorNode::_select_history);
@@ -5525,6 +5541,10 @@ EditorNode::EditorNode() {
Ref<SpatialMaterialConversionPlugin> spatial_mat_convert;
spatial_mat_convert.instance();
resource_conversion_plugins.push_back(spatial_mat_convert);
+
+ Ref<ParticlesMaterialConversionPlugin> particles_mat_convert;
+ particles_mat_convert.instance();
+ resource_conversion_plugins.push_back(particles_mat_convert);
}
circle_step_msec = OS::get_singleton()->get_ticks_msec();
circle_step_frame = Engine::get_singleton()->get_frames_drawn();
@@ -5675,12 +5695,12 @@ void EditorPluginList::edit(Object *p_object) {
}
}
-bool EditorPluginList::forward_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) {
+bool EditorPluginList::forward_gui_input(const Ref<InputEvent> &p_event) {
bool discard = false;
for (int i = 0; i < plugins_list.size(); i++) {
- if (plugins_list[i]->forward_canvas_gui_input(p_canvas_xform, p_event)) {
+ if (plugins_list[i]->forward_canvas_gui_input(p_event)) {
discard = true;
}
}
@@ -5704,10 +5724,10 @@ bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const Ref<Inp
return discard;
}
-void EditorPluginList::forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas) {
+void EditorPluginList::forward_draw_over_canvas(Control *p_canvas) {
for (int i = 0; i < plugins_list.size(); i++) {
- plugins_list[i]->forward_draw_over_canvas(p_canvas_xform, p_canvas);
+ plugins_list[i]->forward_draw_over_canvas(p_canvas);
}
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 0d1c6787cd..32d46e686b 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -812,9 +812,9 @@ public:
void make_visible(bool p_visible);
void edit(Object *p_object);
- bool forward_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
- void forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas);
+ void forward_draw_over_canvas(Control *p_canvas);
void add_plugin(EditorPlugin *p_plugin);
void clear();
bool empty();
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index b4460c5619..229d6adfef 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -258,7 +258,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_resource_previewer"), &EditorInterface::get_resource_previewer);
ClassDB::bind_method(D_METHOD("get_resource_filesystem"), &EditorInterface::get_resource_file_system);
ClassDB::bind_method(D_METHOD("get_editor_viewport"), &EditorInterface::get_editor_viewport);
- ClassDB::bind_method(D_METHOD("make_mesh_previews"), &EditorInterface::_make_mesh_previews);
+ ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
@@ -402,18 +402,18 @@ Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
return Ref<SpatialEditorGizmo>();
}
-bool EditorPlugin::forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) {
+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_canvas_xform, p_event);
+ return get_script_instance()->call("forward_canvas_gui_input", p_event);
}
return false;
}
-void EditorPlugin::forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas) {
+void EditorPlugin::forward_draw_over_canvas(Control *p_canvas) {
if (get_script_instance() && get_script_instance()->has_method("forward_draw_over_canvas")) {
- get_script_instance()->call("forward_draw_over_canvas", p_canvas_xform, p_canvas);
+ get_script_instance()->call("forward_draw_over_canvas", p_canvas);
}
}
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 18530e9ce4..1d68eee117 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -156,8 +156,8 @@ public:
void notify_scene_closed(const String &scene_filepath);
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event);
- virtual void forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas);
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
+ virtual void forward_draw_over_canvas(Control *p_canvas);
virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
virtual String get_name() const;
virtual bool has_main_screen() const;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index b532bb793a..7c45e19f5f 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -719,12 +719,13 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// freelook
_initial_set("editors/3d/freelook/freelook_inertia", 0.1);
hints["editors/3d/freelook/freelook_inertia"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_inertia", PROPERTY_HINT_RANGE, "0.0, 1, 0.01");
- _initial_set("editors/3d/freelook/freelook_base_speed", 0.1);
+ _initial_set("editors/3d/freelook/freelook_base_speed", 5.0);
hints["editors/3d/freelook/freelook_base_speed"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_base_speed", PROPERTY_HINT_RANGE, "0.0, 10, 0.01");
_initial_set("editors/3d/freelook/freelook_activation_modifier", 0);
hints["editors/3d/freelook/freelook_activation_modifier"] = PropertyInfo(Variant::INT, "editors/3d/freelook/freelook_activation_modifier", PROPERTY_HINT_ENUM, "None,Shift,Alt,Meta,Ctrl");
_initial_set("editors/3d/freelook/freelook_modifier_speed_factor", 3.0);
hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1");
+ _initial_set("editors/3d/freelook/freelook_speed_zoom_link", false);
_initial_set("editors/2d/bone_width", 5);
_initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9));
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 0436ac78df..992322978e 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -350,6 +350,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_color("contrast_color_2", "Editor", contrast_color_2);
theme->set_color("font_color", "Editor", font_color);
+ theme->set_color("highlighted_font_color", "Editor", font_color_hl);
theme->set_color("disabled_font_color", "Editor", font_color_disabled);
theme->set_color("mono_color", "Editor", mono_color);
@@ -391,7 +392,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
editor_register_and_generate_icons(theme, dark_theme, thumb_size);
}
// thumbnail size has changed, so we regenerate the medium sizes
- if (p_theme != NULL && fabs(p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) {
+ if (p_theme != NULL && fabs((double)p_theme->get_constant("thumb_size", "Editor") - thumb_size) > 0.00001) {
editor_register_and_generate_icons(p_theme, dark_theme, thumb_size, true);
}
@@ -971,8 +972,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color dim_color = Color(font_color.r, font_color.g, font_color.b, 0.5);
const float mono_value = mono_color.r;
- const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.1);
- const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.3);
+ const Color alpha1 = Color(mono_value, mono_value, mono_value, 0.07);
+ const Color alpha2 = Color(mono_value, mono_value, mono_value, 0.14);
const Color alpha3 = Color(mono_value, mono_value, mono_value, 0.5);
const Color alpha4 = Color(mono_value, mono_value, mono_value, 0.7);
@@ -997,7 +998,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
const Color caret_color = mono_color;
const Color caret_background_color = mono_color.inverted();
const Color text_selected_color = dark_color_3;
- const Color selection_color = alpha3;
+ const Color selection_color = alpha2;
const Color brace_mismatch_color = error_color;
const Color current_line_color = alpha1;
const Color line_length_guideline_color = warning_color;
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index a9d72607b4..dfd35fdd96 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -458,9 +458,9 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
if (path != "res://") {
if (use_thumbnails) {
- files->add_item("..", folder_thumbnail, true);
+ files->add_item("..", folder_thumbnail, false);
} else {
- files->add_item("..", get_icon("folder", "FileDialog"), true);
+ files->add_item("..", get_icon("folder", "FileDialog"), false);
}
String bd = path.get_base_dir();
@@ -567,9 +567,22 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
}
void FileSystemDock::_select_file(int p_idx) {
-
- files->select(p_idx, true);
- _file_option(FILE_OPEN);
+ String path = files->get_item_metadata(p_idx);
+ if (path.ends_with("/")) {
+ if (path != "res://") {
+ path = path.substr(0, path.length() - 1);
+ }
+ this->path = path;
+ _update_files(false);
+ current_path->set_text(path);
+ _push_to_history();
+ } else {
+ if (ResourceLoader::get_resource_type(path) == "PackedScene") {
+ editor->open_request(path);
+ } else {
+ editor->load_resource(path);
+ }
+ }
}
void FileSystemDock::_go_to_tree() {
@@ -704,18 +717,19 @@ void FileSystemDock::_push_to_history() {
button_hist_next->set_disabled(history_pos + 1 == history.size());
}
-void FileSystemDock::_find_inside_move_files(EditorFileSystemDirectory *efsd, Vector<String> &files) {
+void FileSystemDock::_get_all_files_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files) const {
+ if (efsd == NULL)
+ return;
for (int i = 0; i < efsd->get_subdir_count(); i++) {
- _find_inside_move_files(efsd->get_subdir(i), files);
+ _get_all_files_in_dir(efsd->get_subdir(i), files);
}
for (int i = 0; i < efsd->get_file_count(); i++) {
files.push_back(efsd->get_file_path(i));
}
}
-void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, Map<String, String> &renames, List<String> &to_remaps) {
-
+void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const {
for (int i = 0; i < efsd->get_subdir_count(); i++) {
_find_remaps(efsd->get_subdir(i), renames, to_remaps);
}
@@ -730,199 +744,157 @@ void FileSystemDock::_find_remaps(EditorFileSystemDirectory *efsd, Map<String, S
}
}
-void FileSystemDock::_rename_operation(const String &p_to_path) {
+void FileSystemDock::_try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const {
+ //Ensure folder paths end with "/"
+ String old_path = (p_item.is_file || p_item.path.ends_with("/")) ? p_item.path : (p_item.path + "/");
+ String new_path = (p_item.is_file || p_new_path.ends_with("/")) ? p_new_path : (p_new_path + "/");
- if (move_files[0] == p_to_path) {
- EditorNode::get_singleton()->show_warning(TTR("Same source and destination files, doing nothing."));
+ if (new_path == old_path) {
return;
- }
- if (FileAccess::exists(p_to_path)) {
- EditorNode::get_singleton()->show_warning(TTR("Target file exists, can't overwrite. Delete first."));
+ } else if (old_path == "res://") {
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot move/rename resources root."));
+ return;
+ } else if (!p_item.is_file && new_path.begins_with(old_path)) {
+ //This check doesn't erroneously catch renaming to a longer name as folder paths always end with "/"
+ EditorNode::get_singleton()->add_io_error(TTR("Cannot move a folder into itself.\n") + old_path + "\n");
return;
}
- Map<String, String> renames;
- renames[move_files[0]] = p_to_path;
-
- List<String> remap;
-
- _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), renames, remap);
- print_line("found files to remap: " + itos(remap.size()));
-
- //perform remaps
- for (List<String>::Element *E = remap.front(); E; E = E->next()) {
-
- Error err = ResourceLoader::rename_dependencies(E->get(), renames);
- print_line("remapping: " + E->get());
-
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error("Can't rename deps for:\n" + E->get() + "\n");
- }
+ //Build a list of files which will have new paths as a result of this operation
+ Vector<String> changed_paths;
+ if (p_item.is_file) {
+ changed_paths.push_back(old_path);
+ } else {
+ _get_all_files_in_dir(EditorFileSystem::get_singleton()->get_filesystem_path(old_path), changed_paths);
}
- //finally, perform moves
-
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ print_line("Moving " + old_path + " -> " + new_path);
+ Error err = da->rename(old_path, new_path);
+ if (err == OK) {
+ //Move/Rename any corresponding import settings too
+ if (p_item.is_file && FileAccess::exists(old_path + ".import")) {
+ err = da->rename(old_path + ".import", new_path + ".import");
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + ".import\n");
+ }
+ }
- Error err = da->rename(move_files[0], p_to_path);
- print_line("moving file " + move_files[0] + " to " + p_to_path);
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error("Error moving file:\n" + move_files[0] + "\n");
+ //Only treat as a changed dependency if it was successfully moved
+ for (int i = 0; i < changed_paths.size(); ++i) {
+ p_renames[changed_paths[i]] = changed_paths[i].replace_first(old_path, new_path);
+ print_line(" Remap: " + changed_paths[i] + " -> " + p_renames[changed_paths[i]]);
+ }
+ } else {
+ EditorNode::get_singleton()->add_io_error(TTR("Error moving:\n") + old_path + "\n");
}
-
- //rescan everything
memdelete(da);
- print_line("call rescan!");
- _rescan();
}
-void FileSystemDock::_move_operation(const String &p_to_path) {
-
- if (p_to_path == path) {
- EditorNode::get_singleton()->show_warning(TTR("Same source and destination paths, doing nothing."));
- return;
+void FileSystemDock::_update_dependencies_after_move(const Map<String, String> &p_renames) const {
+ //The following code assumes that the following holds:
+ // 1) EditorFileSystem contains the old paths/folder structure from before the rename/move.
+ // 2) ResourceLoader can use the new paths without needing to call rescan.
+ Vector<String> remaps;
+ _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps);
+ for (int i = 0; i < remaps.size(); ++i) {
+ //Because we haven't called a rescan yet the found remap might still be an old path itself.
+ String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i];
+ print_line("Remapping dependencies for: " + file);
+ Error err = ResourceLoader::rename_dependencies(file, p_renames);
+ if (err != OK) {
+ EditorNode::get_singleton()->add_io_error(TTR("Unable to update dependencies:\n") + remaps[i] + "\n");
+ }
}
+}
- //find files inside dirs to be moved
-
- Vector<String> inside_files;
-
- for (int i = 0; i < move_dirs.size(); i++) {
- if (p_to_path.begins_with(move_dirs[i])) {
- EditorNode::get_singleton()->show_warning(TTR("Can't move directories to within themselves."));
- return;
- }
+void FileSystemDock::_make_dir_confirm() {
+ String dir_name = make_dir_dialog_text->get_text().strip_edges();
- EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->get_filesystem_path(move_dirs[i]);
- if (!efsd)
- continue;
- _find_inside_move_files(efsd, inside_files);
+ if (dir_name.length() == 0) {
+ EditorNode::get_singleton()->show_warning(TTR("No name provided"));
+ return;
+ } else if (dir_name.find("/") != -1 || dir_name.find("\\") != -1 || dir_name.find(":") != -1) {
+ EditorNode::get_singleton()->show_warning(TTR("Provided name contains invalid characters"));
+ return;
}
- //make list of remaps
- Map<String, String> renames;
- String repfrom = path == "res://" ? path : String(path + "/");
- String repto = p_to_path;
- if (!repto.ends_with("/")) {
- repto += "/";
+ print_line("Making folder " + dir_name + " in " + path);
+ DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ Error err = da->change_dir(path);
+ if (err == OK) {
+ err = da->make_dir(dir_name);
}
+ memdelete(da);
- print_line("reprfrom: " + repfrom + " repto " + repto);
-
- for (int i = 0; i < move_files.size(); i++) {
- renames[move_files[i]] = move_files[i].replace_first(repfrom, repto);
- print_line("move file " + move_files[i] + " -> " + renames[move_files[i]]);
- }
- for (int i = 0; i < inside_files.size(); i++) {
- renames[inside_files[i]] = inside_files[i].replace_first(repfrom, repto);
- print_line("inside file " + inside_files[i] + " -> " + renames[inside_files[i]]);
+ if (err == OK) {
+ print_line("call rescan!");
+ _rescan();
+ } else {
+ EditorNode::get_singleton()->show_warning(TTR("Could not create folder."));
}
+}
- //make list of files that will be run the remapping
- List<String> remap;
-
- _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), renames, remap);
- print_line("found files to remap: " + itos(remap.size()));
-
- //perform remaps
- for (List<String>::Element *E = remap.front(); E; E = E->next()) {
-
- Error err = ResourceLoader::rename_dependencies(E->get(), renames);
- print_line("remapping: " + E->get());
+void FileSystemDock::_rename_operation_confirm() {
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Can't rename deps for:\n") + E->get() + "\n");
- }
+ String new_name = rename_dialog_text->get_text().strip_edges();
+ if (new_name.length() == 0) {
+ EditorNode::get_singleton()->show_warning(TTR("No name provided."));
+ return;
+ } else if (new_name.find("/") != -1 || new_name.find("\\") != -1 || new_name.find(":") != -1) {
+ EditorNode::get_singleton()->show_warning(TTR("Name contains invalid characters."));
+ return;
}
- //finally, perform moves
+ String old_path = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1) : to_rename.path;
+ String new_path = old_path.get_base_dir().plus_file(new_name);
+ if (old_path == new_path) {
+ return;
+ }
+ //Present a more user friendly warning for name conflict
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-
- for (int i = 0; i < move_files.size(); i++) {
-
- String to = move_files[i].replace_first(repfrom, repto);
- Error err = da->rename(move_files[i], to);
- print_line("moving file " + move_files[i] + " to " + to);
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + "\n");
- }
- if (FileAccess::exists(move_files[i] + ".import")) { //move imported files too
- //@todo should remove the files in .import folder
- err = da->rename(move_files[i] + ".import", to + ".import");
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error moving file:\n") + move_files[i] + ".import\n");
- }
- }
+ if (da->file_exists(new_path) || da->dir_exists(new_path)) {
+ EditorNode::get_singleton()->show_warning(TTR("A file or folder with this name already exists."));
+ memdelete(da);
+ return;
}
+ memdelete(da);
- for (int i = 0; i < move_dirs.size(); i++) {
+ Map<String, String> renames;
+ _try_move_item(to_rename, new_path, renames);
+ _update_dependencies_after_move(renames);
- String mdir = move_dirs[i];
- if (mdir == "res://")
- continue;
+ //Rescan everything
+ print_line("call rescan!");
+ _rescan();
+}
- if (mdir.ends_with("/")) {
- mdir = mdir.substr(0, mdir.length() - 1);
- }
+void FileSystemDock::_move_operation_confirm(const String &p_to_path) {
- String to = p_to_path.plus_file(mdir.get_file());
- Error err = da->rename(mdir, to);
- print_line("moving dir " + mdir + " to " + to);
- if (err != OK) {
- EditorNode::get_singleton()->add_io_error(TTR("Error moving dir:\n") + move_dirs[i] + "\n");
- }
+ Map<String, String> renames;
+ for (int i = 0; i < to_move.size(); i++) {
+ String old_path = to_move[i].path.ends_with("/") ? to_move[i].path.substr(0, to_move[i].path.length() - 1) : to_move[i].path;
+ String new_path = p_to_path.plus_file(old_path.get_file());
+ _try_move_item(to_move[i], new_path, renames);
}
- memdelete(da);
- //rescan everything
+ _update_dependencies_after_move(renames);
print_line("call rescan!");
_rescan();
}
void FileSystemDock::_file_option(int p_option) {
-
switch (p_option) {
-
- case FILE_SHOW_IN_EXPLORER:
+ case FILE_SHOW_IN_EXPLORER: {
+ String dir = ProjectSettings::get_singleton()->globalize_path(this->path);
+ OS::get_singleton()->shell_open(String("file://") + dir);
+ } break;
case FILE_OPEN: {
- int idx = -1;
- for (int i = 0; i < files->get_item_count(); i++) {
- if (files->is_selected(i)) {
- idx = i;
- break;
- }
- }
-
- if (idx < 0)
- return;
-
- String path = files->get_item_metadata(idx);
- if (p_option == FILE_SHOW_IN_EXPLORER) {
- String dir = ProjectSettings::get_singleton()->globalize_path(path);
- dir = dir.substr(0, dir.find_last("/"));
- OS::get_singleton()->shell_open(String("file://") + dir);
- return;
- }
-
- if (path.ends_with("/")) {
- if (path != "res://") {
- path = path.substr(0, path.length() - 1);
- }
- this->path = path;
- _update_files(false);
- current_path->set_text(path);
- _push_to_history();
- } else {
-
- if (ResourceLoader::get_resource_type(path) == "PackedScene") {
-
- editor->open_request(path);
- } else {
-
- editor->load_resource(path);
- }
- }
+ int idx = files->get_current();
+ if (idx < 0 || idx >= files->get_item_count())
+ break;
+ _select_file(idx);
} break;
case FILE_INSTANCE: {
@@ -958,64 +930,59 @@ void FileSystemDock::_file_option(int p_option) {
owners_editor->show(path);
} break;
case FILE_MOVE: {
-
- move_dirs.clear();
- move_files.clear();
-
+ to_move.clear();
for (int i = 0; i < files->get_item_count(); i++) {
-
- String path = files->get_item_metadata(i);
if (!files->is_selected(i))
continue;
- if (files->get_item_text(i) == "..") {
- EditorNode::get_singleton()->show_warning(TTR("Can't operate on '..'"));
- return;
- }
-
- if (path.ends_with("/")) {
- move_dirs.push_back(path.substr(0, path.length() - 1));
- } else {
- move_files.push_back(path);
- }
+ String path = files->get_item_metadata(i);
+ to_move.push_back(FileOrFolder(path, !path.ends_with("/")));
}
-
- if (move_dirs.empty() && move_files.size() == 1) {
-
- rename_dialog->clear_filters();
- rename_dialog->add_filter("*." + move_files[0].get_extension());
- rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
- rename_dialog->set_current_path(move_files[0]);
- rename_dialog->popup_centered_ratio();
- rename_dialog->set_title(TTR("Pick New Name and Location For:") + " " + move_files[0].get_file());
-
- } else {
- //just move
+ if (to_move.size() > 0) {
move_dialog->popup_centered_ratio();
}
+ } break;
+ case FILE_RENAME: {
+ int idx = files->get_current();
+ if (idx < 0 || idx >= files->get_item_count())
+ break;
+ to_rename.path = files->get_item_metadata(idx);
+ to_rename.is_file = !to_rename.path.ends_with("/");
+ if (to_rename.is_file) {
+ String name = to_rename.path.get_file();
+ rename_dialog->set_title(TTR("Renaming file:") + " " + name);
+ rename_dialog_text->set_text(name);
+ rename_dialog_text->select(0, name.find_last("."));
+ } else {
+ String name = to_rename.path.substr(0, to_rename.path.length() - 1).get_file();
+ rename_dialog->set_title(TTR("Renaming folder:") + " " + name);
+ rename_dialog_text->set_text(name);
+ rename_dialog_text->select(0, name.length());
+ }
+ rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
+ rename_dialog_text->grab_focus();
} break;
case FILE_REMOVE: {
-
- Vector<String> torem;
+ Vector<String> remove_files;
+ Vector<String> remove_folders;
for (int i = 0; i < files->get_item_count(); i++) {
-
String path = files->get_item_metadata(i);
- if (!files->is_selected(i))
- continue;
- torem.push_back(path);
+ if (files->is_selected(i) && path != "res://") {
+ if (path.ends_with("/")) {
+ remove_folders.push_back(path);
+ } else {
+ remove_files.push_back(path);
+ }
+ }
}
- if (torem.empty()) {
- EditorNode::get_singleton()->show_warning(TTR("No files selected!"));
- break;
+ if (remove_files.size() + remove_folders.size() > 0) {
+ remove_dialog->show(remove_folders, remove_files);
+ //1) find if used
+ //2) warn
}
-
- remove_dialog->show(torem);
- //1) find if used
- //2) warn
-
} break;
case FILE_INFO: {
@@ -1052,15 +1019,20 @@ void FileSystemDock::_file_option(int p_option) {
}
*/
-
} break;
- case FILE_COPY_PATH:
-
+ case FILE_NEW_FOLDER: {
+ make_dir_dialog_text->set_text("new folder");
+ make_dir_dialog_text->select_all();
+ make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
+ make_dir_dialog_text->grab_focus();
+ } break;
+ case FILE_COPY_PATH: {
int idx = files->get_current();
if (idx < 0 || idx >= files->get_item_count())
break;
String path = files->get_item_metadata(idx);
OS::get_singleton()->set_clipboard(path);
+ } break;
}
}
@@ -1070,26 +1042,64 @@ void FileSystemDock::_folder_option(int p_option) {
TreeItem *child = item->get_children();
switch (p_option) {
-
- case FOLDER_EXPAND_ALL:
+ case FOLDER_EXPAND_ALL: {
item->set_collapsed(false);
while (child) {
child->set_collapsed(false);
child = child->get_next();
}
- break;
-
- case FOLDER_COLLAPSE_ALL:
+ } break;
+ case FOLDER_COLLAPSE_ALL: {
while (child) {
child->set_collapsed(true);
child = child->get_next();
}
- break;
- case FOLDER_SHOW_IN_EXPLORER:
+ } break;
+ case FOLDER_MOVE: {
+ to_move.clear();
+ String fpath = item->get_metadata(tree->get_selected_column());
+ if (fpath != "res://") {
+ fpath = fpath.ends_with("/") ? fpath.substr(0, fpath.length() - 1) : fpath;
+ to_move.push_back(FileOrFolder(fpath, false));
+ move_dialog->popup_centered_ratio();
+ }
+ } break;
+ case FOLDER_RENAME: {
+ to_rename.path = item->get_metadata(tree->get_selected_column());
+ to_rename.is_file = false;
+ if (to_rename.path != "res://") {
+ String name = to_rename.path.ends_with("/") ? to_rename.path.substr(0, to_rename.path.length() - 1).get_file() : to_rename.path.get_file();
+ rename_dialog->set_title(TTR("Renaming folder:") + " " + name);
+ rename_dialog_text->set_text(name);
+ rename_dialog_text->select(0, name.length());
+ rename_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
+ rename_dialog_text->grab_focus();
+ }
+ } break;
+ case FOLDER_REMOVE: {
+ Vector<String> remove_folders;
+ Vector<String> remove_files;
+ String path = item->get_metadata(tree->get_selected_column());
+ if (path != "res://") {
+ remove_folders.push_back(path);
+ remove_dialog->show(remove_folders, remove_files);
+ }
+ } break;
+ case FOLDER_NEW_FOLDER: {
+ make_dir_dialog_text->set_text("new folder");
+ make_dir_dialog_text->select_all();
+ make_dir_dialog->popup_centered_minsize(Size2(250, 80) * EDSCALE);
+ make_dir_dialog_text->grab_focus();
+ } break;
+ case FOLDER_COPY_PATH: {
+ String path = item->get_metadata(tree->get_selected_column());
+ OS::get_singleton()->set_clipboard(path);
+ } break;
+ case FOLDER_SHOW_IN_EXPLORER: {
String path = item->get_metadata(tree->get_selected_column());
String dir = ProjectSettings::get_singleton()->globalize_path(path);
OS::get_singleton()->shell_open(String("file://") + dir);
- return;
+ } break;
}
}
@@ -1128,9 +1138,20 @@ void FileSystemDock::_dir_rmb_pressed(const Vector2 &p_pos) {
folder_options->add_item(TTR("Expand all"), FOLDER_EXPAND_ALL);
folder_options->add_item(TTR("Collapse all"), FOLDER_COLLAPSE_ALL);
- folder_options->add_separator();
- folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER);
-
+ TreeItem *item = tree->get_selected();
+ if (item) {
+ String fpath = item->get_metadata(tree->get_selected_column());
+ folder_options->add_separator();
+ folder_options->add_item(TTR("Copy Path"), FOLDER_COPY_PATH);
+ if (fpath != "res://") {
+ folder_options->add_item(TTR("Rename.."), FOLDER_RENAME);
+ folder_options->add_item(TTR("Move To.."), FOLDER_MOVE);
+ folder_options->add_item(TTR("Delete"), FOLDER_REMOVE);
+ }
+ folder_options->add_separator();
+ folder_options->add_item(TTR("New Folder.."), FOLDER_NEW_FOLDER);
+ folder_options->add_item(TTR("Show In File Manager"), FOLDER_SHOW_IN_EXPLORER);
+ }
folder_options->set_position(tree->get_global_position() + p_pos);
folder_options->popup();
}
@@ -1445,117 +1466,79 @@ void FileSystemDock::drop_data_fw(const Point2 &p_point, const Variant &p_data,
}
Vector<String> fnames = drag_data["files"];
- move_files.clear();
- move_dirs.clear();
-
+ to_move.clear();
for (int i = 0; i < fnames.size(); i++) {
- if (fnames[i].ends_with("/"))
- move_dirs.push_back(fnames[i]);
- else
- move_files.push_back(fnames[i]);
+ to_move.push_back(FileOrFolder(fnames[i], !fnames[i].ends_with("/")));
}
-
- _move_operation(to_dir);
+ _move_operation_confirm(to_dir);
}
}
}
void FileSystemDock::_files_list_rmb_select(int p_item, const Vector2 &p_pos) {
- Vector<String> filenames;
+ //Right clicking ".." should clear current selection
+ if (files->get_item_text(p_item) == "..") {
+ for (int i = 0; i < files->get_item_count(); i++) {
+ files->unselect(i);
+ }
+ }
- bool all_scenes = true;
- bool all_can_reimport = true;
- bool is_dir = false;
- Set<String> types;
+ Vector<String> filenames;
+ Vector<String> foldernames;
+ bool all_files = true;
+ bool all_files_scenes = true;
+ bool all_folders = true;
for (int i = 0; i < files->get_item_count(); i++) {
-
- if (!files->is_selected(i))
+ if (!files->is_selected(i)) {
continue;
-
- String path = files->get_item_metadata(i);
-
- if (files->get_item_text(i) == "..") {
- // no operate on ..
- return;
}
+ String path = files->get_item_metadata(i);
if (path.ends_with("/")) {
- is_dir = true;
- }
-
- int pos;
-
- EditorFileSystemDirectory *efsd = EditorFileSystem::get_singleton()->find_file(path, &pos);
-
- if (efsd) {
-
+ foldernames.push_back(path);
+ all_files = false;
} else {
- all_can_reimport = false;
+ filenames.push_back(path);
+ all_folders = false;
+ all_files_scenes &= (EditorFileSystem::get_singleton()->get_file_type(path) == "PackedScene");
}
-
- filenames.push_back(path);
- if (EditorFileSystem::get_singleton()->get_file_type(path) != "PackedScene")
- all_scenes = false;
}
- if (filenames.size() == 0)
- return;
-
file_options->clear();
file_options->set_size(Size2(1, 1));
+ if (all_files && filenames.size() > 0) {
+ file_options->add_item(TTR("Open"), FILE_OPEN);
+ if (all_files_scenes) {
+ file_options->add_item(TTR("Instance"), FILE_INSTANCE);
+ }
+ file_options->add_separator();
- file_options->add_item(TTR("Open"), FILE_OPEN);
- if (all_scenes) {
- file_options->add_item(TTR("Instance"), FILE_INSTANCE);
- }
-
- file_options->add_separator();
-
- if (filenames.size() == 1 && !is_dir) {
- file_options->add_item(TTR("Edit Dependencies.."), FILE_DEPENDENCIES);
- file_options->add_item(TTR("View Owners.."), FILE_OWNERS);
+ if (filenames.size() == 1) {
+ file_options->add_item(TTR("Edit Dependencies.."), FILE_DEPENDENCIES);
+ file_options->add_item(TTR("View Owners.."), FILE_OWNERS);
+ file_options->add_separator();
+ }
+ } else if (all_folders && foldernames.size() > 0) {
+ file_options->add_item(TTR("Open"), FILE_OPEN);
file_options->add_separator();
}
- if (!is_dir) {
- if (filenames.size() == 1) {
+ int num_items = filenames.size() + foldernames.size();
+ if (num_items >= 1) {
+ if (num_items == 1) {
file_options->add_item(TTR("Copy Path"), FILE_COPY_PATH);
- file_options->add_item(TTR("Rename or Move.."), FILE_MOVE);
- } else {
- file_options->add_item(TTR("Move To.."), FILE_MOVE);
+ file_options->add_item(TTR("Rename.."), FILE_RENAME);
}
+ file_options->add_item(TTR("Move To.."), FILE_MOVE);
+ file_options->add_item(TTR("Delete"), FILE_REMOVE);
+ file_options->add_separator();
}
- file_options->add_item(TTR("Delete"), FILE_REMOVE);
-
- //file_options->add_item(TTR("Info"),FILE_INFO);
-
- file_options->add_separator();
+ file_options->add_item(TTR("New Folder.."), FILE_NEW_FOLDER);
file_options->add_item(TTR("Show In File Manager"), FILE_SHOW_IN_EXPLORER);
- if (all_can_reimport && types.size() == 1) { //all can reimport and are of the same type
-
- /*
- bool valid=true;
- Ref<EditorImportPlugin> rimp = EditorImportExport::get_singleton()->get_import_plugin_by_name(types.front()->get());
- if (rimp.is_valid()) {
-
- if (filenames.size()>1 && !rimp->can_reimport_multiple_files()) {
- valid=false;
- }
- } else {
- valid=false;
- }
-
- if (valid) {
- file_options->add_separator();
- file_options->add_item(TTR("Re-Import.."),FILE_REIMPORT);
- }
- */
- }
-
file_options->set_position(files->get_global_position() + p_pos);
file_options->popup();
}
@@ -1640,8 +1623,9 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_dir_selected"), &FileSystemDock::_dir_selected);
ClassDB::bind_method(D_METHOD("_file_option"), &FileSystemDock::_file_option);
ClassDB::bind_method(D_METHOD("_folder_option"), &FileSystemDock::_folder_option);
- ClassDB::bind_method(D_METHOD("_move_operation"), &FileSystemDock::_move_operation);
- ClassDB::bind_method(D_METHOD("_rename_operation"), &FileSystemDock::_rename_operation);
+ ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileSystemDock::_make_dir_confirm);
+ ClassDB::bind_method(D_METHOD("_move_operation_confirm"), &FileSystemDock::_move_operation_confirm);
+ ClassDB::bind_method(D_METHOD("_rename_operation_confirm"), &FileSystemDock::_rename_operation_confirm);
ClassDB::bind_method(D_METHOD("_search_changed"), &FileSystemDock::_search_changed);
@@ -1796,13 +1780,30 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
move_dialog = memnew(EditorDirDialog);
add_child(move_dialog);
- move_dialog->connect("dir_selected", this, "_move_operation");
+ move_dialog->connect("dir_selected", this, "_move_operation_confirm");
move_dialog->get_ok()->set_text(TTR("Move"));
- rename_dialog = memnew(EditorFileDialog);
- rename_dialog->set_mode(EditorFileDialog::MODE_SAVE_FILE);
- rename_dialog->connect("file_selected", this, "_rename_operation");
+ rename_dialog = memnew(ConfirmationDialog);
+ VBoxContainer *rename_dialog_vb = memnew(VBoxContainer);
+ rename_dialog->add_child(rename_dialog_vb);
+
+ rename_dialog_text = memnew(LineEdit);
+ rename_dialog_vb->add_margin_child(TTR("Name:"), rename_dialog_text);
+ rename_dialog->get_ok()->set_text(TTR("Rename"));
add_child(rename_dialog);
+ rename_dialog->register_text_enter(rename_dialog_text);
+ rename_dialog->connect("confirmed", this, "_rename_operation_confirm");
+
+ make_dir_dialog = memnew(ConfirmationDialog);
+ make_dir_dialog->set_title(TTR("Create Folder"));
+ VBoxContainer *make_folder_dialog_vb = memnew(VBoxContainer);
+ make_dir_dialog->add_child(make_folder_dialog_vb);
+
+ make_dir_dialog_text = memnew(LineEdit);
+ make_folder_dialog_vb->add_margin_child(TTR("Name:"), make_dir_dialog_text);
+ add_child(make_dir_dialog);
+ make_dir_dialog->register_text_enter(make_dir_dialog_text);
+ make_dir_dialog->connect("confirmed", this, "_make_dir_confirm");
updating_tree = false;
initialized = false;
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index aec049ba43..89b250e295 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -32,6 +32,7 @@
#include "scene/gui/box_container.h"
#include "scene/gui/control.h"
+#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
#include "scene/gui/label.h"
#include "scene/gui/menu_button.h"
@@ -67,9 +68,11 @@ private:
FILE_DEPENDENCIES,
FILE_OWNERS,
FILE_MOVE,
+ FILE_RENAME,
FILE_REMOVE,
FILE_REIMPORT,
FILE_INFO,
+ FILE_NEW_FOLDER,
FILE_SHOW_IN_EXPLORER,
FILE_COPY_PATH
};
@@ -77,7 +80,12 @@ private:
enum FolderMenu {
FOLDER_EXPAND_ALL,
FOLDER_COLLAPSE_ALL,
- FOLDER_SHOW_IN_EXPLORER
+ FOLDER_MOVE,
+ FOLDER_RENAME,
+ FOLDER_REMOVE,
+ FOLDER_NEW_FOLDER,
+ FOLDER_SHOW_IN_EXPLORER,
+ FOLDER_COPY_PATH
};
VBoxContainer *scanning_vb;
@@ -110,10 +118,23 @@ private:
DependencyRemoveDialog *remove_dialog;
EditorDirDialog *move_dialog;
- EditorFileDialog *rename_dialog;
+ ConfirmationDialog *rename_dialog;
+ LineEdit *rename_dialog_text;
+ ConfirmationDialog *make_dir_dialog;
+ LineEdit *make_dir_dialog_text;
- Vector<String> move_dirs;
- Vector<String> move_files;
+ class FileOrFolder {
+ public:
+ String path;
+ bool is_file;
+
+ FileOrFolder()
+ : path(""), is_file(false) {}
+ FileOrFolder(const String &p_path, bool p_is_file)
+ : path(p_path), is_file(p_is_file) {}
+ };
+ FileOrFolder to_rename;
+ Vector<FileOrFolder> to_move;
Vector<String> history;
int history_pos;
@@ -135,11 +156,15 @@ private:
bool _create_tree(TreeItem *p_parent, EditorFileSystemDirectory *p_dir);
void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
- void _find_inside_move_files(EditorFileSystemDirectory *efsd, Vector<String> &files);
- void _find_remaps(EditorFileSystemDirectory *efsd, Map<String, String> &renames, List<String> &to_remaps);
- void _rename_operation(const String &p_to_path);
- void _move_operation(const String &p_to_path);
+ void _get_all_files_in_dir(EditorFileSystemDirectory *efsd, Vector<String> &files) const;
+ void _find_remaps(EditorFileSystemDirectory *efsd, const Map<String, String> &renames, Vector<String> &to_remaps) const;
+ void _try_move_item(const FileOrFolder &p_item, const String &p_new_path, Map<String, String> &p_renames) const;
+ void _update_dependencies_after_move(const Map<String, String> &p_renames) const;
+
+ void _make_dir_confirm();
+ void _rename_operation_confirm();
+ void _move_operation_confirm(const String &p_to_path);
void _file_option(int p_option);
void _folder_option(int p_option);
diff --git a/editor/icons/icon_GUI_unchecked.svg b/editor/icons/icon_GUI_unchecked.svg
index 4adf3dd61e..59df40954f 100644
--- a/editor/icons/icon_GUI_unchecked.svg
+++ b/editor/icons/icon_GUI_unchecked.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 15.999999" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#e0e0e0" fill-opacity=".78431"/>
-</g>
+<path d="m4 2a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h8a2 2 0 0 0 2 -2v-8a2 2 0 0 0 -2 -2h-8zm0.80078 2h6.3984a0.8 0.8 0 0 1 0.80078 0.80078v6.3984a0.8 0.8 0 0 1 -0.80078 0.80078h-6.3984a0.8 0.8 0 0 1 -0.80078 -0.80078v-6.3984a0.8 0.8 0 0 1 0.80078 -0.80078z" fill="#e0e0e0" fill-opacity=".78431"/>
</svg>
diff --git a/editor/icons/icon_a_r_v_r_anchor.svg b/editor/icons/icon_a_r_v_r_anchor.svg
new file mode 100644
index 0000000000..1a8398a1be
--- /dev/null
+++ b/editor/icons/icon_a_r_v_r_anchor.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7 1v2h-2v2h2v3.2656l-2.5527-1.2773c-0.15005-0.075253-0.31662-0.11152-0.48438-0.10547-0.36536 0.013648-0.69415 0.2256-0.85742 0.55273-0.24709 0.49403-0.046823 1.0948 0.44727 1.3418l4.4473 2.2227 4.4473-2.2227c0.49409-0.24697 0.69435-0.84777 0.44726-1.3418-0.24697-0.49409-0.84777-0.69435-1.3418-0.44727l-2.5527 1.2773v-3.2656h2v-2h-2v-2zm-3 11v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1zm5 0v4h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1zm1 1h1v1h-1z" fill="#fc9c9c"/>
+</svg>
diff --git a/editor/icons/icon_a_r_v_r_camera.svg b/editor/icons/icon_a_r_v_r_camera.svg
index a02b4d983c..5bf815bcef 100644
--- a/editor/icons/icon_a_r_v_r_camera.svg
+++ b/editor/icons/icon_a_r_v_r_camera.svg
@@ -1,3 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<path d="m2 1c-0.55401 0-1 0.446-1 1v7c0 0.554 0.44599 1 1 1h4l1-2c0.24699-0.494 0.44772-1 1-1s0.75301 0.506 1 1l1 2h4c0.55401 0 1-0.446 1-1v-7c0-0.554-0.44599-1-1-1h-12zm2 3a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm8 0a2 2 0 0 1 2 2 2 2 0 0 1 -2 2 2 2 0 0 1 -2 -2 2 2 0 0 1 2 -2zm-8 7v4h2c0.502 4e-4 0.9265-0.37144 0.99219-0.86914 0.0059-0.047 0.0085325-0.094025 0.0078125-0.14062v-2.9902h-1v3h-1v-3h-1zm5 0v4h1v-1h1v1h1v-1c-7.73e-4 -0.1811-0.05073-0.35867-0.14453-0.51367 0.08369-0.1462 0.14453-0.30573 0.14453-0.48633v-1c0-0.5523-0.4485-1.0293-1-1h-2zm1 1h1v1h-1v-1z" fill="#fc9c9c"/>
+<path d="m9.5 0a3 3 0 0 0 -2.9883 2.7773 3 3 0 0 0 -2.0117 -0.77734 3 3 0 0 0 -3 3 3 3 0 0 0 2 2.8242v2.1758c0 0.554 0.44599 1 1 1h6c0.55401 0 1-0.446 1-1v-1l3 2v-6l-3 2v-1.7695a3 3 0 0 0 1 -2.2305 3 3 0 0 0 -3 -3zm-5.5 12v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/>
</svg>
diff --git a/editor/icons/icon_a_r_v_r_controller.svg b/editor/icons/icon_a_r_v_r_controller.svg
new file mode 100644
index 0000000000..a61f99ffdf
--- /dev/null
+++ b/editor/icons/icon_a_r_v_r_controller.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m2 1c-0.554 0-1 0.446-1 1v6c0 0.554 0.446 1 1 1h12c0.554 0 1-0.446 1-1v-6c0-0.554-0.446-1-1-1h-12zm2 1h2v2h2v2h-2v2h-2v-2h-2v-2h2v-2zm9 1c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-2 2c0.55228 0 1 0.44772 1 1s-0.44772 1-1 1-1-0.44772-1-1 0.44772-1 1-1zm-7 7v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/>
+</svg>
diff --git a/editor/icons/icon_a_r_v_r_origin.svg b/editor/icons/icon_a_r_v_r_origin.svg
new file mode 100644
index 0000000000..53a149cec6
--- /dev/null
+++ b/editor/icons/icon_a_r_v_r_origin.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m7 1v3h2v-3h-2zm-4 4v2h3v-2h-3zm5 0c-0.55228 0-1 0.44772-1 1s0.44772 1 1 1 1-0.44772 1-1-0.44772-1-1-1zm2 0v2h3v-2h-3zm-3 3v3h2v-3h-2zm-3 4v1c0 0.55228 0.44772 1 1 1-0.55228 0-1 0.44772-1 1v1h1v-1h1v1h1v-1c0-0.55228-0.44772-1-1-1 0.55228 0 1-0.44772 1-1v-1h-1v1h-1v-1h-1zm5 0v1 3h1v-1h1v1h1v-1c-8.34e-4 -0.17579-0.047991-0.34825-0.13672-0.5 0.088728-0.15175 0.13588-0.32421 0.13672-0.5v-1c0-0.55228-0.44772-1-1-1h-1-1zm1 1h1v1h-1v-1z" fill="#fc9c9c"/>
+</svg>
diff --git a/editor/icons/icon_animated_sprite.svg b/editor/icons/icon_animated_sprite.svg
index fe7fde5a39..6fdf8a7a40 100644
--- a/editor/icons/icon_animated_sprite.svg
+++ b/editor/icons/icon_animated_sprite.svg
@@ -1,7 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#a5b7f3">
-<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/>
-<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
+<g fill="#a5b7f3">
+<path d="m7 0c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2z" fill-opacity=".39216"/>
+<path d="m5 2c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7z" fill-opacity=".58824"/>
+<path d="m3 4c-1.108 0-2 0.89199-2 2v7c0 1.108 0.89199 2 2 2h7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7zm0 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm7 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
</g>
</svg>
diff --git a/editor/icons/icon_animated_sprite_3d.svg b/editor/icons/icon_animated_sprite_3d.svg
index 658ba3e5c2..ccc836832c 100644
--- a/editor/icons/icon_animated_sprite_3d.svg
+++ b/editor/icons/icon_animated_sprite_3d.svg
@@ -1,7 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#fc9c9c">
-<path transform="translate(0 1036.4)" d="m10.5 0a5.5 5.5 0 0 0 -5.3301 4.1699 5.5 5.5 0 0 1 1.3301 -0.16992 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.16992 1.3301 5.5 5.5 0 0 0 4.1699 -5.3301 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".39216"/>
-<path transform="translate(0 1036.4)" d="m8.5 2a5.5 5.5 0 0 0 -4.7559 2.748 5.5 5.5 0 0 1 2.7559 -0.74805 5.5 5.5 0 0 1 5.5 5.5 5.5 5.5 0 0 1 -0.74414 2.752 5.5 5.5 0 0 0 2.7441 -4.752 5.5 5.5 0 0 0 -5.5 -5.5z" fill-opacity=".58824"/>
-<path transform="translate(0 1036.4)" d="m6.5 4a5.5 5.5 0 0 0 -5.5 5.5 5.5 5.5 0 0 0 5.5 5.5 5.5 5.5 0 0 0 5.5 -5.5 5.5 5.5 0 0 0 -5.5 -5.5zm-2.5 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm5 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-5 3h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
+<g fill="#fc9c9c">
+<path d="m7 0c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2z" fill-opacity=".39216"/>
+<path d="m5 2c-1.108 0-2 0.89199-2 2h7c1.108 0 2 0.89199 2 2v7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7z" fill-opacity=".58824"/>
+<path d="m3 4c-1.108 0-2 0.89199-2 2v7c0 1.108 0.89199 2 2 2h7c1.108 0 2-0.89199 2-2v-7c0-1.108-0.89199-2-2-2h-7zm0 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm7 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm-6 4h5a2.5 2 0 0 1 -1.25 1.7324 2.5 2 0 0 1 -2.5 0 2.5 2 0 0 1 -1.25 -1.7324z"/>
</g>
</svg>
diff --git a/editor/icons/icon_center_container.svg b/editor/icons/icon_center_container.svg
index 446e9e0f9c..fc0abc5c28 100644
--- a/editor/icons/icon_center_container.svg
+++ b/editor/icons/icon_center_container.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm3 1l2 2 2-2h-4zm-2 2v4l2-2-2-2zm8 0l-2 2 2 2v-4zm-4 4l-2 2h4l-2-2z" fill="#a5efac"/>
-</g>
+<path d="m3 1c-1.1046 0-2 0.89543-2 2v10c0 1.1046 0.89543 2 2 2h10c1.1046 0 2-0.89543 2-2v-10c0-1.1046-0.89543-2-2-2h-10zm0 2h10v10h-10v-10zm3 1l2 2 2-2h-4zm-2 2v4l2-2-2-2zm8 0l-2 2 2 2v-4zm-4 4l-2 2h4l-2-2z" fill="#a5efac"/>
</svg>
diff --git a/editor/icons/icon_color_pick.svg b/editor/icons/icon_color_pick.svg
index 893afb4eb4..5c21eeba8b 100644
--- a/editor/icons/icon_color_pick.svg
+++ b/editor/icons/icon_color_pick.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#e0e0e0" fill-opacity=".99608"/>
+<path transform="translate(0 1036.4)" d="m8 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_color_picker.svg b/editor/icons/icon_color_picker.svg
index 272dfeca48..55c55fe205 100644
--- a/editor/icons/icon_color_picker.svg
+++ b/editor/icons/icon_color_picker.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211l1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#a5efac"/>
-</g>
+<path d="m8 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-1 6h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5z" fill="#a5efac"/>
</svg>
diff --git a/editor/icons/icon_color_picker_button.svg b/editor/icons/icon_color_picker_button.svg
index 5d734a5b20..d8de02b298 100644
--- a/editor/icons/icon_color_picker_button.svg
+++ b/editor/icons/icon_color_picker_button.svg
@@ -1,7 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m13.051 0.97852a2 2 0 0 0 -1.4434 0.58594l-1.4141 1.4141-1.416-1.4141-1.4141 1.4141 1.4141 1.4141-7.0703 7.0723-0.35352 1.7676-0.35352 1.7676 1.7676-0.35352 1.7676-0.35352 7.0723-7.0703 1.4141 1.4141 1.4141-1.4141-1.4141-1.416 1.4141-1.4141a2 2 0 0 0 0 -2.8281 2 2 0 0 0 -1.3848 -0.58594zm-3.5664 4.1211 1.416 1.416-7.0723 7.0703-0.70703-0.70703-0.70703-0.70703 7.0703-7.0723z" fill="#a5efac"/>
-<path transform="translate(0 1036.4)" d="m1 3v6.3438l4.9492-4.9512-1.3926-1.3926h-3.5566zm14 6.4863l-1.5137 1.5137h-0.92969l-0.94922-0.94922-2.9492 2.9492h6.3418v-3.5137z" fill="#a5efac"/>
-<path transform="translate(0 1036.4)" d="m10.658 11l-2 2h6.3418v-2h-1.5137-0.92969-1.8984z" fill-opacity=".078431"/>
-</g>
+<path d="m13 1c-1.108 0-2 0.892-2 2v2h-1v2h1v5a2 2 0 0 0 1 1.7285v1.2715h2v-1.2695a2 2 0 0 0 1 -1.7305v-5h1v-2h-1v-2c0-1.108-0.892-2-2-2zm-9 1v3.1328l-1.4453-0.96484-1.1094 1.6641 3 2c0.3359 0.2239 0.77347 0.2239 1.1094 0l3-2-1.1094-1.6641-1.4453 0.96484v-3.1328h-2zm8 5h2v5a1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1v-5zm-8.5 3c-0.831 0-1.5 0.669-1.5 1.5v0.5 1h-1v2h8v-2h-1v-1-0.5c0-0.831-0.669-1.5-1.5-1.5h-3z" fill="#a5efac"/>
</svg>
diff --git a/editor/icons/icon_connection_and_groups.svg b/editor/icons/icon_connection_and_groups.svg
deleted file mode 100644
index 67a73f02b3..0000000000
--- a/editor/icons/icon_connection_and_groups.svg
+++ /dev/null
@@ -1,5 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m2 0v1 5 1h12v-1-6h-11-1zm1 1h10v5h-10v-5zm2.5 1a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm5 0a1.5 1.5 0 0 0 -1.5 1.5 1.5 1.5 0 0 0 1.5 1.5 1.5 1.5 0 0 0 1.5 -1.5 1.5 1.5 0 0 0 -1.5 -1.5zm-0.5 7a2 2 0 0 0 -2 2v1h-6v1h6v1a2 2 0 0 0 2 2h2v-1h2v-1h-2v-3h2v-1h-2v-1h-2z" fill="#e0e0e0"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_control_layout.svg b/editor/icons/icon_control_layout.svg
new file mode 100644
index 0000000000..4bf60cf751
--- /dev/null
+++ b/editor/icons/icon_control_layout.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<path d="m1 1v14h14v-14zm2 2h3v3h-3zm5 0h5v3h-5zm-5 5h3v5h-3zm5 0h5v5h-5z" fill="#a5efac"/>
+</svg>
diff --git a/editor/icons/icon_edit.svg b/editor/icons/icon_edit.svg
index b1bce158c4..1805aab54f 100644
--- a/editor/icons/icon_edit.svg
+++ b/editor/icons/icon_edit.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z" fill="#e0e0e0"/>
+<path transform="translate(0 1036.4)" d="m7 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-1 4v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_edit_key.svg b/editor/icons/icon_edit_key.svg
index 2959900d04..443a9a0455 100644
--- a/editor/icons/icon_edit_key.svg
+++ b/editor/icons/icon_edit_key.svg
@@ -1,6 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)" fill="#e0e0e0">
-<path d="m1.7071 1047.8-0.70711 3.5356l3.5355-0.7071 7.7782-7.7782-2.8284-2.8284zm9.1924-9.1924 2.8284 2.8285 1.4142-1.4142-2.8284-2.8285z"/>
-<ellipse cx="3.5" cy="1039.9" rx="2.5" ry="2.5"/>
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m12 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-7 3c-0.195 0-0.38964 0.07519-0.53906 0.22461l-3.2363 3.2363c-0.29884 0.29884-0.29884 0.77929 0 1.0781l3.2363 3.2363c0.29884 0.29884 0.77929 0.29884 1.0781 0l3.2363-3.2363c0.29884-0.29884 0.29884-0.77929 0-1.0781l-3.2363-3.2363c-0.14942-0.14942-0.34406-0.22461-0.53906-0.22461zm6 1v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_groups.svg b/editor/icons/icon_groups.svg
index 37e40749b8..55cf3c48eb 100644
--- a/editor/icons/icon_groups.svg
+++ b/editor/icons/icon_groups.svg
@@ -1,7 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<rect x="1" y="1040.4" width="14" height="8" fill="none" stroke="#e0e0e0" stroke-linejoin="round" stroke-width="2"/>
-<ellipse cx="5" cy="1044.4" rx="2" ry="2" fill="#e0e0e0"/>
-<ellipse cx="11" cy="1044.4" rx="2" ry="2" fill="#e0e0e0"/>
+<path transform="translate(0 1036.4)" d="m2 1a1.0001 1.0001 0 0 0 -1 1v12a1.0001 1.0001 0 0 0 1 1h12a1.0001 1.0001 0 0 0 1 -1v-12a1.0001 1.0001 0 0 0 -1 -1h-12zm1 2h10v10h-10v-10zm5 2a3 3 0 0 0 -3 3 3 3 0 0 0 3 3 3 3 0 0 0 3 -3 3 3 0 0 0 -3 -3z" color="#000000" color-rendering="auto" dominant-baseline="auto" fill="#e0e0e0" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
</g>
</svg>
diff --git a/editor/icons/icon_key_move_enabled.svg b/editor/icons/icon_key_position.svg
index 203b697ad2..203b697ad2 100644
--- a/editor/icons/icon_key_move_enabled.svg
+++ b/editor/icons/icon_key_position.svg
diff --git a/editor/icons/icon_key_rotate_enabled.svg b/editor/icons/icon_key_rotation.svg
index 0f975631b2..0f975631b2 100644
--- a/editor/icons/icon_key_rotate_enabled.svg
+++ b/editor/icons/icon_key_rotation.svg
diff --git a/editor/icons/icon_key_scale_enabled.svg b/editor/icons/icon_key_scale.svg
index eaa12fdf0e..eaa12fdf0e 100644
--- a/editor/icons/icon_key_scale_enabled.svg
+++ b/editor/icons/icon_key_scale.svg
diff --git a/editor/icons/icon_kinematic_body.svg b/editor/icons/icon_kinematic_body.svg
index 393e21a529..6f8d69fa53 100644
--- a/editor/icons/icon_kinematic_body.svg
+++ b/editor/icons/icon_kinematic_body.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#fc9c9c" fill-opacity=".99608"/>
+<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.040884 0.018715 0.075662 0.023438 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1h-4zm0 2h1v2h-1v-2z" fill="#fc9c9c" fill-opacity=".99608"/>
</g>
</svg>
diff --git a/editor/icons/icon_kinematic_body_2d.svg b/editor/icons/icon_kinematic_body_2d.svg
index e269efd12a..51026e5f28 100644
--- a/editor/icons/icon_kinematic_body_2d.svg
+++ b/editor/icons/icon_kinematic_body_2d.svg
@@ -1,5 +1,7 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m4 4v1h1v-1h-1zm1 1v1h-1v1h-1v1h-1v1 2h1v-2h1v1 1h1v-1h5v1h1v-2h1v2h1v-2-1h-1v-1h-1v-1h-1v-1h-1v1h-3v-1h-1zm5 0h1v-1h-1v1zm0 6h-2v1h2v-1zm-5 0v1h2v-1h-2zm0-4h1v1h-1v-1zm4 0h1v1h-1v-1z" fill="#a5b7f3" fill-opacity=".98824"/>
+<g transform="translate(.49212 -.0044019)" fill="#a5b7f5" fill-opacity=".98824">
+<path transform="translate(0 1036.4)" d="m6 1c-0.55401 0-1 0.44599-1 1v3c0 0.55401 0.44599 1 1 1h1v0.99023a1.0001 1.0001 0 0 0 -0.31641 0.0625l-2.0508 0.68359-0.68359-2.0508a1.0001 1.0001 0 0 0 -0.99023 -0.69727 1.0001 1.0001 0 0 0 -0.9082 1.3281l1 3a1.0001 1.0001 0 0 0 1.2656 0.63281l1.6836-0.56055v0.61133c0 0.04088 0.018715 0.07566 0.023437 0.11523l-4.5781 3.0527a1.0001 1.0001 0 1 0 1.1094 1.6641l5.0566-3.3711 1.4941 2.9863a1.0001 1.0001 0 0 0 1.2109 0.50195l3-1a1.0001 1.0001 0 1 0 -0.63281 -1.8965l-2.1777 0.72461-0.97461-1.9512c0.2759-0.17764 0.46875-0.47227 0.46875-0.82617v-1h1.3828l0.72266 1.4473a1.0001 1.0001 0 1 0 1.7891 -0.89453l-1-2a1.0001 1.0001 0 0 0 -0.89453 -0.55273h-3v-1h1c0.55401 0 1-0.44599 1-1v-3c0-0.55401-0.44599-1-1-1zm0 2h1v2h-1z" fill="#a5b7f5" fill-opacity=".98824"/>
+</g>
</g>
</svg>
diff --git a/editor/icons/icon_multi_edit.svg b/editor/icons/icon_multi_edit.svg
index 36f62006e0..9a1cfe8e16 100644
--- a/editor/icons/icon_multi_edit.svg
+++ b/editor/icons/icon_multi_edit.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m12.314 0.85742l-1.4141 1.4141 2.8281 2.8281 1.4141-1.4141-2.8281-2.8281zm-11.314 0.14258v2h2v-2h-2zm4 0v2h2v-2h-2zm4.4844 2.6855l-7.7773 7.7793-0.70703 3.5352 3.5352-0.70703 7.7793-7.7773-2.8301-2.8301zm-8.4844 1.3145v2h2v-2h-2z" fill="#e0e0e0"/>
+<path transform="translate(0 1036.4)" d="m2 1c-0.554 0-1 0.446-1 1v2h4v-2c0-0.554-0.446-1-1-1h-2zm-1 4v7l2 3 2-3v-7h-4zm1 1h1v5h-1v-5zm8 1v3h-3v2h3v3h2v-3h3v-2h-3v-3h-2z" fill="#e0e0e0"/>
</g>
</svg>
diff --git a/editor/icons/icon_shader.svg b/editor/icons/icon_shader.svg
new file mode 100644
index 0000000000..659d81519a
--- /dev/null
+++ b/editor/icons/icon_shader.svg
@@ -0,0 +1,12 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m2 1c-0.55226 1e-4 -0.99994 0.4477-1 1v12c5.52e-5 0.5523 0.44774 0.9999 1 1h12c0.55226-1e-4 0.99994-0.4477 1-1v-8l-5-5zm1 2h6v3c0 0.554 0.44599 1 1 1h3v6h-10z" fill="#e0e0e0"/>
+<path d="m10 11h2v1h-2z" fill="#9f70ff"/>
+<path d="m4 6h2v1h-2z" fill="#ffeb70"/>
+<path d="m8 8h4v1h-4z" fill="#9dff70"/>
+<path d="m7 6h1v1h-1z" fill="#70deff"/>
+<path d="m4 11h5v1h-5z" fill="#ff70ac"/>
+<path d="m4 4h3v1h-3z" fill="#ff7070"/>
+<path d="m4 8h3v1h-3z" fill="#70ffb9"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_connect.svg b/editor/icons/icon_signals.svg
index 97859370b7..97859370b7 100644
--- a/editor/icons/icon_connect.svg
+++ b/editor/icons/icon_signals.svg
diff --git a/editor/icons/icon_signals_and_groups.svg b/editor/icons/icon_signals_and_groups.svg
new file mode 100644
index 0000000000..5dedbaa433
--- /dev/null
+++ b/editor/icons/icon_signals_and_groups.svg
@@ -0,0 +1,5 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g transform="translate(0 -1036.4)">
+<path transform="translate(0 1036.4)" d="m6 0c-0.55228 0-1 0.4477-1 1s0.44772 1 1 1c4.4301 0 8 3.5699 8 8 0 0.5523 0.44772 1 1 1s1-0.4477 1-1c0-5.511-4.489-10-10-10zm0 4c-0.55228 0-1 0.4477-1 1s0.44772 1 1 1c2.221 0 4 1.779 4 4 0 0.5523 0.44772 1 1 1s1-0.4477 1-1c0-3.3018-2.6981-6-6-6zm-5 4a1.0001 1.0001 0 0 0 -1 1v6a1.0001 1.0001 0 0 0 1 1h6a1.0001 1.0001 0 0 0 1 -1v-6a1.0001 1.0001 0 0 0 -1 -1h-6zm1 2h4v4h-4v-4z" fill="#e0e0e0"/>
+</g>
+</svg>
diff --git a/editor/icons/icon_sprite.svg b/editor/icons/icon_sprite.svg
index 4feea4d265..09fc2f0979 100644
--- a/editor/icons/icon_sprite.svg
+++ b/editor/icons/icon_sprite.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#a5b7f3"/>
-</g>
+<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4h-6zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#a5b7f6" fill-opacity=".98824"/>
</svg>
diff --git a/editor/icons/icon_sprite_3d.svg b/editor/icons/icon_sprite_3d.svg
index 0d5caae501..eb163e3f43 100644
--- a/editor/icons/icon_sprite_3d.svg
+++ b/editor/icons/icon_sprite_3d.svg
@@ -1,5 +1,5 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m8 1a7 7 0 0 0 -7 7 7 7 0 0 0 7 7 7 7 0 0 0 7 -7 7 7 0 0 0 -7 -7zm-4 5a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm8 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm-7 3h6a3 3 0 0 1 -1.5 2.5977 3 3 0 0 1 -3 0 3 3 0 0 1 -1.5 -2.5977z" fill="#fc9c9c" fill-opacity=".99608"/>
+<g fill="#fc9c9c">
+<path d="m5 1c-2.216 0-4 1.784-4 4v6c0 2.216 1.784 4 4 4h6c2.216 0 4-1.784 4-4v-6c0-2.216-1.784-4-4-4zm-1 5c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm8 0c0.554 0 1 0.446 1 1v2c0 0.554-0.446 1-1 1s-1-0.446-1-1v-2c0-0.554 0.446-1 1-1zm-1.8887 5.1074a1.0001 1.0001 0 0 1 0.7168 1.7207c-0.74987 0.74987-1.7676 1.1719-2.8281 1.1719s-2.0783-0.422-2.8281-1.1719a1.0001 1.0001 0 0 1 0.69727 -1.7168 1.0001 1.0001 0 0 1 0.7168 0.30273c0.37534 0.37535 0.88325 0.58594 1.4141 0.58594s1.0387-0.21059 1.4141-0.58594a1.0001 1.0001 0 0 1 0.69727 -0.30664z" fill="#fc9c9c"/>
</g>
</svg>
diff --git a/editor/icons/icon_sprite_frames.svg b/editor/icons/icon_sprite_frames.svg
index e797819892..8123cbd6b4 100644
--- a/editor/icons/icon_sprite_frames.svg
+++ b/editor/icons/icon_sprite_frames.svg
@@ -1,5 +1,3 @@
<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<path transform="translate(0 1036.4)" d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 5 -5 5 5 0 0 0 -5 -5zm-3 4a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm6 0a1 1 0 0 1 1 1 1 1 0 0 1 -1 1 1 1 0 0 1 -1 -1 1 1 0 0 1 1 -1zm4 2v2h2v-2h-2zm-5.0039 0.49219a0.50005 0.50005 0 0 1 0.35742 0.86133c-0.61785 0.6179-1.4924 0.89648-2.3535 0.89648s-1.7357-0.27858-2.3535-0.89648a0.50005 0.50005 0 0 1 0.34766 -0.85742 0.50005 0.50005 0 0 1 0.35938 0.15039c0.38215 0.3822 1.0076 0.60352 1.6465 0.60352s1.2643-0.22132 1.6465-0.60352a0.50005 0.50005 0 0 1 0.34961 -0.1543zm2.0039 2.5078v2h2v-2h-2zm3 0v2h2v-2h-2zm-6 3v2h2v-2h-2zm3 0v2h2v-2h-2zm3 0v2h2v-2h-2z" fill="#e0e0e0"/>
-</g>
+<path d="m3 1c-1.108 0-2 0.89199-2 2v6c0 1.108 0.89199 2 2 2h6c1.108 0 2-0.89199 2-2v-6c0-1.108-0.89199-2-2-2h-6zm10 0v2h2v-2h-2zm-10 4c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm6 0c0.554 0 1 0.446 1 1v1c0 0.554-0.446 1-1 1s-1-0.446-1-1v-1c0-0.554 0.446-1 1-1zm4 0v2h2v-2h-2zm-9 4h2 2a2 1 0 0 1 -1 0.86523 2 1 0 0 1 -2 0 2 1 0 0 1 -1 -0.86523zm9 0v2h2v-2h-2zm-12 4v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-2h-2zm4 0v2h2v-2h-2z" fill="#e0e0e0"/>
</svg>
diff --git a/editor/icons/icon_viewport_speed.svg b/editor/icons/icon_viewport_speed.svg
new file mode 100644
index 0000000000..e64b5a8059
--- /dev/null
+++ b/editor/icons/icon_viewport_speed.svg
@@ -0,0 +1,4 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 4.2333333 4.2333333" xmlns="http://www.w3.org/2000/svg">
+<path d="m1.5875 0c-0.28858 0-0.52917 0.24059-0.52917 0.52917v0.61132c-0.085589-0.051-0.18113-0.0891-0.28525-0.0853-0.34849 0.0127-0.5952 0.37346-0.48059 0.70278l0.26355 0.79066c0.048664 0.14623 0.15979 0.24805 0.29249 0.30644l-0.60927 0.40669c-0.13121 0.0845-0.22102 0.22389-0.24133 0.3633-0.020312 0.13941 0.017471 0.26985 0.087333 0.37465s0.17614 0.19045 0.31264 0.22532c0.13634 0.0348 0.29946 6e-3 0.42788-0.0827h5.159e-4l1.0852-0.72348 0.26097 0.52192c0.11682 0.23391 0.39274 0.34829 0.64079 0.26561l0.79375-0.26458-0.00775 3e-3c0.15105-0.0454 0.27732-0.15615 0.33486-0.2863 0.057538-0.13015 0.055144-0.26773 0.014986-0.38809-0.03156-0.0946-0.10972-0.1687-0.19275-0.23617 0.069099-0.0546 0.1445-0.10364 0.18035-0.19325 0.051761-0.12941 0.045257-0.29292-0.02377-0.43098l-0.26459-0.52946c-0.089407-0.17933-0.27348-0.29308-0.47335-0.29305h-0.1111c0.052029-0.0817 0.1111-0.16214 0.1111-0.26458v-0.79375c0-0.28858-0.24059-0.52917-0.52917-0.52917z" color="#000000" color-rendering="auto" dominant-baseline="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path d="m1.5875 0.26458c-0.14658 0-0.26458 0.118-0.26458 0.26459v0.79375c0 0.14658 0.118 0.26458 0.26458 0.26458h0.26458v0.262a0.26461 0.26461 0 0 0 -0.083716 0.0165l-0.5426 0.18086-0.18087-0.5426a0.26461 0.26461 0 0 0 -0.262 -0.18448 0.26461 0.26461 0 0 0 -0.2403 0.3514l0.26458 0.79375a0.26461 0.26461 0 0 0 0.33486 0.16743l0.44545-0.14831v0.16174c0 0.0108 0.00495 0.02 0.0062 0.0305l-1.2113 0.80771a0.26461 0.26461 0 1 0 0.29352 0.44028l1.3379-0.89194 0.39532 0.79014a0.26461 0.26461 0 0 0 0.32039 0.1328l0.79375-0.26458a0.26461 0.26461 0 1 0 -0.16743 -0.50175l-0.57619 0.19172-0.25787-0.51625c0.072998-0.047 0.12402-0.12495 0.12402-0.21859v-0.26458h0.36587l0.1912 0.38292a0.26461 0.26461 0 1 0 0.47336 -0.23668l-0.26458-0.52916a0.26461 0.26461 0 0 0 -0.23668 -0.14625h-0.79375v-0.26458h0.26458c0.14658 0 0.26458-0.118 0.26458-0.26458v-0.79375c0-0.14659-0.118-0.26459-0.26458-0.26459zm0 0.52917h0.26458v0.52917h-0.26458z" fill="#fff" fill-opacity=".99608"/>
+</svg>
diff --git a/editor/icons/icon_viewport_sprite.svg b/editor/icons/icon_viewport_sprite.svg
deleted file mode 100644
index 4b8bbeaeba..0000000000
--- a/editor/icons/icon_viewport_sprite.svg
+++ /dev/null
@@ -1,7 +0,0 @@
-<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
-<g transform="translate(0 -1036.4)">
-<rect x="20" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<rect x="29" y="1042.4" width="1" height="1" fill="#fefeff"/>
-<path transform="translate(0 1036.4)" d="m3 2c-0.5304 8.01e-5 -1.0391 0.21085-1.4141 0.58594-0.37509 0.37501-0.58586 0.88366-0.58594 1.4141v8c8.03e-5 0.5304 0.21085 1.0391 0.58594 1.4141 0.37501 0.37509 0.88366 0.58586 1.4141 0.58594h10c1.1046 0 2-0.89543 2-2v-8c0-1.1046-0.89543-2-2-2h-10zm0 1h10c0.55228 9.6e-6 0.99999 0.44772 1 1v8c-1e-5 0.55228-0.44772 0.99999-1 1h-10c-0.55228-1e-5 -0.99999-0.44772-1-1v-8c9.6e-6 -0.55228 0.44772-0.99999 1-1zm1 3v2h2v-2h-2zm6 0v2h2v-2h-2zm-6 3v1h8v-1h-8z" fill="#a5b7f3" fill-opacity=".98824"/>
-</g>
-</svg>
diff --git a/editor/icons/icon_viewport_zoom.svg b/editor/icons/icon_viewport_zoom.svg
new file mode 100644
index 0000000000..18d4ec32ce
--- /dev/null
+++ b/editor/icons/icon_viewport_zoom.svg
@@ -0,0 +1,6 @@
+<svg width="16" height="16" version="1.1" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+<g>
+<path d="m6 0c-3.3019 0-6 2.6981-6 6s2.6981 6 6 6h0.00195c0.88828 0 1.737-0.2588 2.5332-0.6367l3.8281 3.8281c0.39053 0.3904 1.0235 0.3904 1.4141 0l1.4141-1.4141c0.39033-0.3905 0.39033-1.0235 0-1.414l-3.791-3.791c0.02779-0.058 0.06588-0.1109 0.0918-0.17 0.05554-0.1268 0.08414-0.2638 0.08398-0.4023h1.4238c0.55226-1e-4 0.99994-0.4477 1-1v-1h1c0.55226-1e-4 0.99994-0.4477 1-1v-2c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-1v-1c-5.5e-5 -0.5523-0.44774-0.9999-1-1h-2c-0.55226 1e-4 -0.99994 0.4477-1 1v1h-0.00977c1.44e-4 -0.3151-0.14822-0.6118-0.40039-0.8008-1.0353-0.7764-2.2938-1.1967-3.5879-1.1992h-0.00195z" color="#000000" color-rendering="auto" dominant-baseline="auto" image-rendering="auto" shape-rendering="auto" solid-color="#000000" style="font-feature-settings:normal;font-variant-alternates:normal;font-variant-caps:normal;font-variant-ligatures:normal;font-variant-numeric:normal;font-variant-position:normal;isolation:auto;mix-blend-mode:normal;shape-padding:0;text-decoration-color:#000000;text-decoration-line:none;text-decoration-style:solid;text-indent:0;text-orientation:mixed;text-transform:none;white-space:normal"/>
+<path d="m6 1a5 5 0 0 0 -5 5 5 5 0 0 0 5 5 5 5 0 0 0 2.752 -0.83398l4.3184 4.3184 1.4141-1.4141-4.3184-4.3184a5 5 0 0 0 0.41016 -0.75195h-0.57617v-2h-1a3 3 0 0 1 -3 3 3 3 0 0 1 -3 -3 3 3 0 0 1 3 -3 3 3 0 0 1 2 0.76758v-1.7676h0.99023a5 5 0 0 0 -2.9902 -1zm5 0v2h-2v2h2v2h2v-2h2v-2h-2v-2z" fill="#fff"/>
+</g>
+</svg>
diff --git a/editor/node_dock.cpp b/editor/node_dock.cpp
index 7edaf0e5af..20392a67a7 100644
--- a/editor/node_dock.cpp
+++ b/editor/node_dock.cpp
@@ -56,10 +56,10 @@ void NodeDock::_bind_methods() {
void NodeDock::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- connections_button->set_icon(get_icon("Connect", "EditorIcons"));
+ connections_button->set_icon(get_icon("Signals", "EditorIcons"));
groups_button->set_icon(get_icon("Groups", "EditorIcons"));
} else if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
- connections_button->set_icon(get_icon("Connect", "EditorIcons"));
+ connections_button->set_icon(get_icon("Signals", "EditorIcons"));
groups_button->set_icon(get_icon("Groups", "EditorIcons"));
}
}
diff --git a/editor/plugins/abstract_polygon_2d_editor.cpp b/editor/plugins/abstract_polygon_2d_editor.cpp
index 2fd74d529e..ffa4e36b5a 100644
--- a/editor/plugins/abstract_polygon_2d_editor.cpp
+++ b/editor/plugins/abstract_polygon_2d_editor.cpp
@@ -195,9 +195,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
Transform2D xform = canvas_item_editor->get_canvas_transform() * _get_node()->get_global_transform();
Vector2 gpoint = mb->get_position();
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = _get_node()->get_global_transform().affine_inverse().xform(cpoint);
+ Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
//first check if a point is to be added (segment split)
real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
@@ -425,15 +423,14 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
if (edited_point != -1 && (wip_active || (mm->get_button_mask() & BUTTON_MASK_LEFT))) {
Vector2 gpoint = mm->get_position();
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- edited_point_pos = _get_node()->get_global_transform().affine_inverse().xform(cpoint);
+ Vector2 cpoint = _get_node()->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())));
+ edited_point_pos = cpoint;
if (!wip_active) {
Vector<Vector2> vertices = _get_polygon(edited_polygon);
ERR_FAIL_INDEX_V(edited_point, vertices.size(), false);
- vertices[edited_point] = edited_point_pos - _get_offset(edited_polygon);
+ vertices[edited_point] = cpoint - _get_offset(edited_polygon);
_set_polygon(edited_polygon, vertices);
}
@@ -444,8 +441,7 @@ bool AbstractPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
return false;
}
-void AbstractPolygon2DEditor::_canvas_draw() {
-
+void AbstractPolygon2DEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!_get_node())
return;
@@ -527,9 +523,6 @@ void AbstractPolygon2DEditor::edit(Node *p_polygon) {
if (_is_empty())
_menu_option(MODE_CREATE);
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
-
wip.clear();
wip_active = false;
edited_point = -1;
@@ -539,15 +532,11 @@ void AbstractPolygon2DEditor::edit(Node *p_polygon) {
} else {
_set_node(NULL);
-
- if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw");
}
}
void AbstractPolygon2DEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_canvas_draw"), &AbstractPolygon2DEditor::_canvas_draw);
ClassDB::bind_method(D_METHOD("_node_removed"), &AbstractPolygon2DEditor::_node_removed);
ClassDB::bind_method(D_METHOD("_menu_option"), &AbstractPolygon2DEditor::_menu_option);
ClassDB::bind_method(D_METHOD("_create_resource"), &AbstractPolygon2DEditor::_create_resource);
diff --git a/editor/plugins/abstract_polygon_2d_editor.h b/editor/plugins/abstract_polygon_2d_editor.h
index 86e14694da..3e3bff6d0d 100644
--- a/editor/plugins/abstract_polygon_2d_editor.h
+++ b/editor/plugins/abstract_polygon_2d_editor.h
@@ -75,7 +75,6 @@ protected:
virtual void _menu_option(int p_option);
void _wip_close();
- void _canvas_draw();
void _notification(int p_what);
void _node_removed(Node *p_node);
@@ -103,6 +102,8 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
+ void forward_draw_over_canvas(Control *p_canvas);
+
void edit(Node *p_polygon);
AbstractPolygon2DEditor(EditorNode *p_editor, bool p_wip_destructive = true);
};
@@ -116,7 +117,8 @@ class AbstractPolygon2DEditorPlugin : public EditorPlugin {
String klass;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return polygon_editor->forward_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { polygon_editor->forward_draw_over_canvas(p_canvas); }
bool has_main_screen() const { return false; }
virtual String get_name() const { return klass; }
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index bdfe380211..2b9c625aa4 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -557,7 +557,7 @@ void AnimationPlayerEditor::_animation_blend() {
String current = animation->get_item_text(animation->get_selected());
- blend_editor.dialog->popup_centered(Size2(400, 400));
+ blend_editor.dialog->popup_centered(Size2(400, 400) * EDSCALE);
blend_editor.tree->set_hide_root(true);
blend_editor.tree->set_column_min_width(0, 10);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 4b216d63f5..2270421eca 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1198,14 +1198,23 @@ void CanvasItemEditor::_update_cursor() {
viewport->set_default_cursor_shape(c);
}
-void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event) {
+void CanvasItemEditor::_gui_input_viewport_base(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventMouseMotion> m = p_event;
+ if (m.is_valid()) {
+ if (!viewport_base->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
+ viewport_base->call_deferred("grab_focus");
+ }
+}
+
+void CanvasItemEditor::_gui_input_viewport(const Ref<InputEvent> &p_event) {
{
EditorNode *en = editor;
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
- bool discard = over_plugin_list->forward_gui_input(transform, p_event);
+ bool discard = over_plugin_list->forward_gui_input(p_event);
if (discard) {
accept_event();
return;
@@ -1224,7 +1233,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
_update_scroll(0);
viewport->update();
} else {
- _zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()));
+ _zoom_on_position(zoom * (1 - (0.05 * b->get_factor())), b->get_position());
}
return;
@@ -1237,7 +1246,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
_update_scroll(0);
viewport->update();
} else {
- _zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()));
+ _zoom_on_position(zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95), b->get_position());
}
return;
@@ -1320,7 +1329,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) {
if (b->is_pressed()) {
// Set the pivot point
- Point2 mouse_pos = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
+ Point2 mouse_pos = b->get_position();
mouse_pos = transform.affine_inverse().xform(mouse_pos);
mouse_pos = snap_point(mouse_pos, SNAP_DEFAULT, _get_single_item());
_edit_set_pivot(mouse_pos);
@@ -1443,8 +1452,8 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
E->get().to
};
- Vector2 p = Geometry::get_closest_point_to_segment_2d(viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()), s);
- float d = p.distance_to(viewport_scrollable->get_transform().affine_inverse().xform(b->get_position()));
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(b->get_position(), s);
+ float d = p.distance_to(b->get_position());
if (d < bone_width && d < closest_dist) {
Cbone = E;
closest_dist = d;
@@ -1506,7 +1515,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
ERR_FAIL_COND(!se);
- Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
+ Point2 click = b->get_position();
// Rotation
if ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
@@ -1561,7 +1570,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
}
// Multiple selected items
- Point2 click = viewport_scrollable->get_transform().affine_inverse().xform(b->get_position());
+ Point2 click = b->get_position();
if ((b->get_alt() || tool == TOOL_MOVE) && get_item_count()) {
// Drag the nodes
@@ -1621,12 +1630,9 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
// Mouse motion event
_update_cursor();
- if (!viewport_base->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
- viewport_base->call_deferred("grab_focus");
-
if (box_selecting) {
// Update box selection
- box_selecting_to = transform.affine_inverse().xform(viewport_scrollable->get_transform().affine_inverse().xform(m->get_position()));
+ box_selecting_to = transform.affine_inverse().xform(m->get_position());
viewport->update();
return;
}
@@ -1672,7 +1678,7 @@ void CanvasItemEditor::_viewport_base_gui_input(const Ref<InputEvent> &p_event)
}
Vector2 dfrom = drag_from;
- Vector2 dto = transform.affine_inverse().xform(viewport_scrollable->get_transform().affine_inverse().xform(m->get_position()));
+ Vector2 dto = transform.affine_inverse().xform(m->get_position());
if (canvas_item->has_meta("_edit_lock_"))
continue;
@@ -2159,8 +2165,8 @@ void CanvasItemEditor::_draw_grid() {
Vector2 real_grid_offset;
if (snap_relative && get_item_count() > 0) {
Vector2 topleft = _find_topleftmost_point();
- real_grid_offset.x = fmod(topleft.x, grid_step.x * Math::pow(2.0, grid_step_multiplier));
- real_grid_offset.y = fmod(topleft.y, grid_step.y * Math::pow(2.0, grid_step_multiplier));
+ real_grid_offset.x = fmod(topleft.x, grid_step.x * (real_t)Math::pow(2.0, grid_step_multiplier));
+ real_grid_offset.y = fmod(topleft.y, grid_step.y * (real_t)Math::pow(2.0, grid_step_multiplier));
} else {
real_grid_offset = grid_offset;
}
@@ -2681,9 +2687,8 @@ void CanvasItemEditor::_draw_viewport() {
EditorPluginList *over_plugin_list = editor->get_editor_plugins_over();
if (!over_plugin_list->empty()) {
- over_plugin_list->forward_draw_over_canvas(transform, viewport);
+ over_plugin_list->forward_draw_over_canvas(viewport);
}
- _draw_focus();
_draw_bones();
}
@@ -2806,12 +2811,16 @@ void CanvasItemEditor::_notification(int p_what) {
unlock_button->set_icon(get_icon("Unlock", "EditorIcons"));
group_button->set_icon(get_icon("Group", "EditorIcons"));
ungroup_button->set_icon(get_icon("Ungroup", "EditorIcons"));
+ key_loc_button->set_icon(get_icon("KeyPosition", "EditorIcons"));
+ key_rot_button->set_icon(get_icon("KeyRotation", "EditorIcons"));
+ key_scale_button->set_icon(get_icon("KeyScale", "EditorIcons"));
key_insert_button->set_icon(get_icon("Key", "EditorIcons"));
zoom_minus->set_icon(get_icon("ZoomLess", "EditorIcons"));
zoom_reset->set_icon(get_icon("ZoomReset", "EditorIcons"));
zoom_plus->set_icon(get_icon("ZoomMore", "EditorIcons"));
+ presets_menu->set_icon(get_icon("ControlLayout", "EditorIcons"));
PopupMenu *p = presets_menu->get_popup();
p->clear();
@@ -3690,7 +3699,8 @@ void CanvasItemEditor::_bind_methods() {
ClassDB::bind_method("_unhandled_key_input", &CanvasItemEditor::_unhandled_key_input);
ClassDB::bind_method("_draw_viewport", &CanvasItemEditor::_draw_viewport);
ClassDB::bind_method("_draw_viewport_base", &CanvasItemEditor::_draw_viewport_base);
- ClassDB::bind_method("_viewport_base_gui_input", &CanvasItemEditor::_viewport_base_gui_input);
+ ClassDB::bind_method("_gui_input_viewport", &CanvasItemEditor::_gui_input_viewport);
+ ClassDB::bind_method("_gui_input_viewport_base", &CanvasItemEditor::_gui_input_viewport_base);
ClassDB::bind_method("_snap_changed", &CanvasItemEditor::_snap_changed);
ClassDB::bind_method(D_METHOD("_selection_result_pressed"), &CanvasItemEditor::_selection_result_pressed);
ClassDB::bind_method(D_METHOD("_selection_menu_hide"), &CanvasItemEditor::_selection_menu_hide);
@@ -3743,7 +3753,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
palette_split->add_child(viewport_base);
viewport_base->set_clip_contents(true);
viewport_base->connect("draw", this, "_draw_viewport_base");
- viewport_base->connect("gui_input", this, "_viewport_base_gui_input");
+ viewport_base->connect("gui_input", this, "_gui_input_viewport_base");
viewport_base->set_focus_mode(FOCUS_ALL);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
viewport_base->set_h_size_flags(SIZE_EXPAND_FILL);
@@ -3767,6 +3777,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
viewport->set_anchors_and_margins_preset(Control::PRESET_WIDE);
viewport->set_clip_contents(true);
viewport->connect("draw", this, "_draw_viewport");
+ viewport->connect("gui_input", this, "_gui_input_viewport");
h_scroll = memnew(HScrollBar);
viewport->add_child(h_scroll);
@@ -3949,30 +3960,24 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->add_child(memnew(VSeparator));
animation_hb->hide();
- key_loc_button = memnew(Button("loc"));
+ key_loc_button = memnew(Button);
key_loc_button->set_toggle_mode(true);
key_loc_button->set_flat(true);
key_loc_button->set_pressed(true);
key_loc_button->set_focus_mode(FOCUS_NONE);
- key_loc_button->add_color_override("font_color", Color(1, 0.6, 0.6));
- key_loc_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6));
key_loc_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS));
animation_hb->add_child(key_loc_button);
- key_rot_button = memnew(Button("rot"));
+ key_rot_button = memnew(Button);
key_rot_button->set_toggle_mode(true);
key_rot_button->set_flat(true);
key_rot_button->set_pressed(true);
key_rot_button->set_focus_mode(FOCUS_NONE);
- key_rot_button->add_color_override("font_color", Color(1, 0.6, 0.6));
- key_rot_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6));
key_rot_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT));
animation_hb->add_child(key_rot_button);
- key_scale_button = memnew(Button("scl"));
+ key_scale_button = memnew(Button);
key_scale_button->set_toggle_mode(true);
key_scale_button->set_flat(true);
key_scale_button->set_focus_mode(FOCUS_NONE);
- key_scale_button->add_color_override("font_color", Color(1, 0.6, 0.6));
- key_scale_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6));
key_scale_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE));
animation_hb->add_child(key_scale_button);
key_insert_button = memnew(Button);
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 69dc25d180..a8183ba286 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -410,10 +410,11 @@ class CanvasItemEditor : public VBoxContainer {
void _draw_locks_and_groups(Node *p_node, const Transform2D &p_xform);
void _draw_viewport();
-
- void _viewport_base_gui_input(const Ref<InputEvent> &p_event);
void _draw_viewport_base();
+ void _gui_input_viewport(const Ref<InputEvent> &p_event);
+ void _gui_input_viewport_base(const Ref<InputEvent> &p_event);
+
void _focus_selection(int p_op);
void _snap_if_closer(Point2 p_value, Point2 p_target_snap, Point2 &r_current_snap, bool (&r_snapped)[2], real_t rotation = 0.0, float p_radius = 10.0);
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index 00e6d617a1..00e6d617a1 100755..100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index edf3bbcc08..edf3bbcc08 100755..100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 3e6165e552..005de096cd 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -302,7 +302,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
undo_redo->commit_action();
}
-bool CollisionShape2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
+bool CollisionShape2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
if (!node) {
return false;
@@ -317,17 +317,17 @@ bool CollisionShape2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
}
Ref<InputEventMouseButton> mb = p_event;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
if (mb.is_valid()) {
- Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
-
- Point2 gpoint(mb->get_position().x, mb->get_position().y);
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
if (mb->get_button_index() == BUTTON_LEFT) {
if (mb->is_pressed()) {
for (int i = 0; i < handles.size(); i++) {
- if (gt.xform(handles[i]).distance_to(gpoint) < 8) {
+ if (xform.xform(handles[i]).distance_to(gpoint) < 8) {
edit_handle = i;
break;
@@ -368,9 +368,7 @@ bool CollisionShape2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
- Point2 gpoint = mm->get_position();
- Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
+ Vector2 cpoint = canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position()));
cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
set_handle(edit_handle, cpoint);
@@ -416,7 +414,7 @@ void CollisionShape2DEditor::_get_current_shape_type() {
canvas_item_editor->get_viewport_control()->update();
}
-void CollisionShape2DEditor::_canvas_draw() {
+void CollisionShape2DEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!node) {
return;
@@ -432,7 +430,6 @@ void CollisionShape2DEditor::_canvas_draw() {
return;
}
- Control *c = canvas_item_editor->get_viewport_control();
Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Ref<Texture> h = get_icon("EditorHandle", "EditorIcons");
@@ -451,8 +448,8 @@ void CollisionShape2DEditor::_canvas_draw() {
handles[0] = Point2(radius, -height);
handles[1] = Point2(0, -(height + radius));
- c->draw_texture(h, gt.xform(handles[0]) - size);
- c->draw_texture(h, gt.xform(handles[1]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@@ -462,7 +459,7 @@ void CollisionShape2DEditor::_canvas_draw() {
handles.resize(1);
handles[0] = Point2(shape->get_radius(), 0);
- c->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
} break;
@@ -481,8 +478,8 @@ void CollisionShape2DEditor::_canvas_draw() {
handles[0] = shape->get_normal() * shape->get_d();
handles[1] = shape->get_normal() * (shape->get_d() + 30.0);
- c->draw_texture(h, gt.xform(handles[0]) - size);
- c->draw_texture(h, gt.xform(handles[1]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@@ -492,7 +489,7 @@ void CollisionShape2DEditor::_canvas_draw() {
handles.resize(1);
handles[0] = Point2(0, shape->get_length());
- c->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
} break;
@@ -504,8 +501,8 @@ void CollisionShape2DEditor::_canvas_draw() {
handles[0] = Point2(ext.x, 0);
handles[1] = Point2(0, -ext.y);
- c->draw_texture(h, gt.xform(handles[0]) - size);
- c->draw_texture(h, gt.xform(handles[1]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
} break;
@@ -516,8 +513,8 @@ void CollisionShape2DEditor::_canvas_draw() {
handles[0] = shape->get_a();
handles[1] = shape->get_b();
- c->draw_texture(h, gt.xform(handles[0]) - size);
- c->draw_texture(h, gt.xform(handles[1]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[0]) - size);
+ p_canvas->draw_texture(h, gt.xform(handles[1]) - size);
} break;
}
@@ -532,18 +529,12 @@ void CollisionShape2DEditor::edit(Node *p_node) {
if (p_node) {
node = Object::cast_to<CollisionShape2D>(p_node);
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
-
_get_current_shape_type();
} else {
edit_handle = -1;
shape_type = -1;
- if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw");
-
node = NULL;
}
@@ -552,7 +543,6 @@ void CollisionShape2DEditor::edit(Node *p_node) {
void CollisionShape2DEditor::_bind_methods() {
- ClassDB::bind_method("_canvas_draw", &CollisionShape2DEditor::_canvas_draw);
ClassDB::bind_method("_get_current_shape_type", &CollisionShape2DEditor::_get_current_shape_type);
}
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index ffa91952e0..d4fbe87fb3 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -68,13 +68,13 @@ class CollisionShape2DEditor : public Control {
void commit_handle(int idx, Variant &p_org);
void _get_current_shape_type();
- void _canvas_draw();
protected:
static void _bind_methods();
public:
- bool forward_gui_input(const Ref<InputEvent> &p_event);
+ bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
+ void forward_draw_over_canvas(Control *p_canvas);
void edit(Node *p_node);
CollisionShape2DEditor(EditorNode *p_editor);
@@ -87,7 +87,8 @@ class CollisionShape2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_canvas_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { return collision_shape_2d_editor->forward_draw_over_canvas(p_canvas); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index ed0bc60d2f..485657d2c9 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -119,9 +119,7 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Vector2 gpoint = mb->get_position();
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon());
@@ -319,7 +317,8 @@ bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void LightOccluder2DEditor::_canvas_draw() {
+
+void LightOccluder2DEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!node || !node->get_occluder_polygon().is_valid())
return;
@@ -368,17 +367,12 @@ void LightOccluder2DEditor::edit(Node *p_collision_polygon) {
if (p_collision_polygon) {
node = Object::cast_to<LightOccluder2D>(p_collision_polygon);
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
wip.clear();
wip_active = false;
edited_point = -1;
canvas_item_editor->get_viewport_control()->update();
} else {
node = NULL;
-
- if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw");
}
}
@@ -395,7 +389,6 @@ void LightOccluder2DEditor::_create_poly() {
void LightOccluder2DEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_menu_option"), &LightOccluder2DEditor::_menu_option);
- ClassDB::bind_method(D_METHOD("_canvas_draw"), &LightOccluder2DEditor::_canvas_draw);
ClassDB::bind_method(D_METHOD("_node_removed"), &LightOccluder2DEditor::_node_removed);
ClassDB::bind_method(D_METHOD("_create_poly"), &LightOccluder2DEditor::_create_poly);
}
@@ -430,7 +423,7 @@ LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) {
void LightOccluder2DEditorPlugin::edit(Object *p_object) {
- collision_polygon_editor->edit(Object::cast_to<Node>(p_object));
+ light_occluder_editor->edit(Object::cast_to<Node>(p_object));
}
bool LightOccluder2DEditorPlugin::handles(Object *p_object) const {
@@ -441,21 +434,21 @@ bool LightOccluder2DEditorPlugin::handles(Object *p_object) const {
void LightOccluder2DEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
- collision_polygon_editor->show();
+ light_occluder_editor->show();
} else {
- collision_polygon_editor->hide();
- collision_polygon_editor->edit(NULL);
+ light_occluder_editor->hide();
+ light_occluder_editor->edit(NULL);
}
}
LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) {
editor = p_node;
- collision_polygon_editor = memnew(LightOccluder2DEditor(p_node));
- CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
+ light_occluder_editor = memnew(LightOccluder2DEditor(p_node));
+ CanvasItemEditor::get_singleton()->add_control_to_menu_panel(light_occluder_editor);
- collision_polygon_editor->hide();
+ light_occluder_editor->hide();
}
LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin() {
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index b270dcb6e5..068832d8ed 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -72,7 +72,6 @@ class LightOccluder2DEditor : public HBoxContainer {
ConfirmationDialog *create_poly;
void _wip_close(bool p_closed);
- void _canvas_draw();
void _menu_option(int p_option);
void _create_poly();
@@ -83,6 +82,7 @@ protected:
public:
Vector2 snap_point(const Vector2 &p_point) const;
+ void forward_draw_over_canvas(Control *p_canvas);
bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
LightOccluder2DEditor(EditorNode *p_editor);
@@ -92,11 +92,12 @@ class LightOccluder2DEditorPlugin : public EditorPlugin {
GDCLASS(LightOccluder2DEditorPlugin, EditorPlugin);
- LightOccluder2DEditor *collision_polygon_editor;
+ LightOccluder2DEditor *light_occluder_editor;
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return light_occluder_editor->forward_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { return light_occluder_editor->forward_draw_over_canvas(p_canvas); }
virtual String get_name() const { return "LightOccluder2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index ef3ee6a78f..0533aaa9c0 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -54,16 +54,10 @@ void Line2DEditor::_notification(int p_what) {
}
}
-Vector2 Line2DEditor::mouse_to_local_pos(Vector2 gpos, bool alt) {
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- return !alt ? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpos)) : node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpos)));
-}
-
-int Line2DEditor::get_point_index_at(Vector2 gpos) {
+int Line2DEditor::get_point_index_at(const Transform2D &xform, Vector2 gpos) {
ERR_FAIL_COND_V(node == 0, -1);
real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
for (int i = 0; i < node->get_point_count(); ++i) {
Point2 p = xform.xform(node->get_point_position(i));
@@ -75,7 +69,7 @@ int Line2DEditor::get_point_index_at(Vector2 gpos) {
return -1;
}
-bool Line2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
+bool Line2DEditor::forward_canvas_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
@@ -88,10 +82,10 @@ bool Line2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mb.is_valid()) {
Vector2 gpoint = mb->get_position();
- Vector2 cpoint = mouse_to_local_pos(gpoint, mb->get_alt());
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
if (mb->is_pressed() && _dragging == false) {
- int i = get_point_index_at(gpoint);
+ int i = get_point_index_at(canvas_item_editor->get_canvas_transform() * node->get_global_transform(), gpoint);
if (i != -1) {
if (mb->get_button_index() == BUTTON_LEFT && !mb->get_shift() && mode == MODE_EDIT) {
_dragging = true;
@@ -146,7 +140,8 @@ bool Line2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (mm.is_valid()) {
if (_dragging) {
- Vector2 cpoint = mouse_to_local_pos(mm->get_position(), mm->get_alt());
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())));
node->set_point_position(action_point, cpoint);
canvas_item_editor->get_viewport_control()->update();
return true;
@@ -156,7 +151,7 @@ bool Line2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void Line2DEditor::_canvas_draw() {
+void Line2DEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!node)
return;
@@ -190,13 +185,9 @@ void Line2DEditor::edit(Node *p_line2d) {
if (p_line2d) {
node = Object::cast_to<Line2D>(p_line2d);
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
if (!node->is_connected("visibility_changed", this, "_node_visibility_changed"))
node->connect("visibility_changed", this, "_node_visibility_changed");
} else {
- if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw");
// node may have been deleted at this point
if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed"))
node->disconnect("visibility_changed", this, "_node_visibility_changed");
@@ -205,7 +196,6 @@ void Line2DEditor::edit(Node *p_line2d) {
}
void Line2DEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_canvas_draw"), &Line2DEditor::_canvas_draw);
ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Line2DEditor::_node_visibility_changed);
ClassDB::bind_method(D_METHOD("_mode_selected"), &Line2DEditor::_mode_selected);
}
diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h
index dea0433084..6858680aed 100644
--- a/editor/plugins/line_2d_editor_plugin.h
+++ b/editor/plugins/line_2d_editor_plugin.h
@@ -40,27 +40,11 @@ class CanvasItemEditor;
class Line2DEditor : public HBoxContainer {
GDCLASS(Line2DEditor, HBoxContainer)
-
-public:
- bool forward_gui_input(const Ref<InputEvent> &p_event);
- void edit(Node *p_line2d);
- Line2DEditor(EditorNode *p_editor);
-
-protected:
- void _node_removed(Node *p_node);
- void _notification(int p_what);
-
- Vector2 mouse_to_local_pos(Vector2 mpos);
-
- static void _bind_methods();
-
private:
void _mode_selected(int p_mode);
- void _canvas_draw();
void _node_visibility_changed();
- int get_point_index_at(Vector2 gpos);
- Vector2 mouse_to_local_pos(Vector2 gpos, bool alt);
+ int get_point_index_at(const Transform2D &xform, Vector2 gpos);
UndoRedo *undo_redo;
@@ -86,17 +70,26 @@ private:
int action_point;
Point2 moving_from;
Point2 moving_screen_from;
+
+protected:
+ void _node_removed(Node *p_node);
+ void _notification(int p_what);
+
+ static void _bind_methods();
+
+public:
+ bool forward_canvas_gui_input(const Ref<InputEvent> &p_event);
+ void forward_draw_over_canvas(Control *p_canvas);
+ void edit(Node *p_line2d);
+ Line2DEditor(EditorNode *p_editor);
};
class Line2DEditorPlugin : public EditorPlugin {
GDCLASS(Line2DEditorPlugin, EditorPlugin)
public:
- virtual bool forward_canvas_gui_input(
- const Transform2D &p_canvas_xform,
- const Ref<InputEvent> &p_event) {
- return line2d_editor->forward_gui_input(p_event);
- }
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return line2d_editor->forward_canvas_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { return line2d_editor->forward_draw_over_canvas(p_canvas); }
virtual String get_name() const { return "Line2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/material_editor_plugin.cpp b/editor/plugins/material_editor_plugin.cpp
index 6b613c1bcc..bd4891ccb7 100644
--- a/editor/plugins/material_editor_plugin.cpp
+++ b/editor/plugins/material_editor_plugin.cpp
@@ -32,6 +32,7 @@
// Waiting for PropertyEditor rewrite (planned for 3.1) to be refactored.
#include "material_editor_plugin.h"
+#include "scene/3d/particles.h"
#if 0
@@ -449,6 +450,52 @@ Ref<Resource> SpatialMaterialConversionPlugin::convert(const Ref<Resource> &p_re
VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), &params);
for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
+
+ // Texture parameter has to be treated specially since SpatialMaterial saved it
+ // as RID but ShaderMaterial needs Texture itself
+ Ref<Texture> texture = mat->get_texture_by_name(E->get().name);
+ if (texture.is_valid()) {
+ smat->set_shader_param(E->get().name, texture);
+ } else {
+ Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
+ smat->set_shader_param(E->get().name, value);
+ }
+ }
+
+ smat->set_render_priority(mat->get_render_priority());
+ return smat;
+}
+
+String ParticlesMaterialConversionPlugin::converts_to() const {
+
+ return "ShaderMaterial";
+}
+bool ParticlesMaterialConversionPlugin::handles(const Ref<Resource> &p_resource) const {
+
+ Ref<ParticlesMaterial> mat = p_resource;
+ return mat.is_valid();
+}
+Ref<Resource> ParticlesMaterialConversionPlugin::convert(const Ref<Resource> &p_resource) {
+
+ Ref<ParticlesMaterial> mat = p_resource;
+ ERR_FAIL_COND_V(!mat.is_valid(), Ref<Resource>());
+
+ Ref<ShaderMaterial> smat;
+ smat.instance();
+
+ Ref<Shader> shader;
+ shader.instance();
+
+ String code = VS::get_singleton()->shader_get_code(mat->get_shader_rid());
+
+ shader->set_code(code);
+
+ smat->set_shader(shader);
+
+ List<PropertyInfo> params;
+ VS::get_singleton()->shader_get_param_list(mat->get_shader_rid(), &params);
+
+ for (List<PropertyInfo>::Element *E = params.front(); E; E = E->next()) {
Variant value = VS::get_singleton()->material_get_param(mat->get_rid(), E->get().name);
smat->set_shader_param(E->get().name, value);
}
diff --git a/editor/plugins/material_editor_plugin.h b/editor/plugins/material_editor_plugin.h
index af9602f944..52c73cb7d8 100644
--- a/editor/plugins/material_editor_plugin.h
+++ b/editor/plugins/material_editor_plugin.h
@@ -111,4 +111,12 @@ public:
virtual Ref<Resource> convert(const Ref<Resource> &p_resource);
};
+class ParticlesMaterialConversionPlugin : public EditorResourceConversionPlugin {
+ GDCLASS(ParticlesMaterialConversionPlugin, EditorResourceConversionPlugin)
+public:
+ virtual String converts_to() const;
+ virtual bool handles(const Ref<Resource> &p_resource) const;
+ virtual Ref<Resource> convert(const Ref<Resource> &p_resource);
+};
+
#endif // MATERIAL_EDITOR_PLUGIN_H
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index 6560a8dac7..6560a8dac7 100755..100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 54cc347a8c..54cc347a8c 100755..100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index df10ac8929..2174f08e23 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -76,10 +76,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Vector2 gpoint = mb->get_position();
- Vector2 cpoint =
- !mb->get_alt() ?
- canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) :
- node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mb->get_position())));
real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
@@ -239,10 +236,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
// Handle point/control movement.
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
Vector2 gpoint = mm->get_position();
- Vector2 cpoint =
- !mm->get_alt() ?
- canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) :
- node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
+ Vector2 cpoint = node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(mm->get_position())));
Ref<Curve2D> curve = node->get_curve();
@@ -274,7 +268,8 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void Path2DEditor::_canvas_draw() {
+
+void Path2DEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!node)
return;
@@ -329,16 +324,11 @@ void Path2DEditor::edit(Node *p_path2d) {
if (p_path2d) {
node = Object::cast_to<Path2D>(p_path2d);
- if (!canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->connect("draw", this, "_canvas_draw");
if (!node->is_connected("visibility_changed", this, "_node_visibility_changed"))
node->connect("visibility_changed", this, "_node_visibility_changed");
} else {
- if (canvas_item_editor->get_viewport_control()->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->get_viewport_control()->disconnect("draw", this, "_canvas_draw");
-
// node may have been deleted at this point
if (node && node->is_connected("visibility_changed", this, "_node_visibility_changed"))
node->disconnect("visibility_changed", this, "_node_visibility_changed");
@@ -349,7 +339,6 @@ void Path2DEditor::edit(Node *p_path2d) {
void Path2DEditor::_bind_methods() {
//ClassDB::bind_method(D_METHOD("_menu_option"),&Path2DEditor::_menu_option);
- ClassDB::bind_method(D_METHOD("_canvas_draw"), &Path2DEditor::_canvas_draw);
ClassDB::bind_method(D_METHOD("_node_visibility_changed"), &Path2DEditor::_node_visibility_changed);
ClassDB::bind_method(D_METHOD("_mode_selected"), &Path2DEditor::_mode_selected);
}
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index f0f5d4d637..516e48c471 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -84,7 +84,6 @@ class Path2DEditor : public HBoxContainer {
void _mode_selected(int p_mode);
- void _canvas_draw();
void _node_visibility_changed();
friend class Path2DEditorPlugin;
@@ -95,6 +94,7 @@ protected:
public:
bool forward_gui_input(const Ref<InputEvent> &p_event);
+ void forward_draw_over_canvas(Control *p_canvas);
void edit(Node *p_path2d);
Path2DEditor(EditorNode *p_editor);
};
@@ -107,7 +107,8 @@ class Path2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { return path2d_editor->forward_draw_over_canvas(p_canvas); }
virtual String get_name() const { return "Path2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index 0e8c13b067..0e8c13b067 100755..100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 90da3e61c1..90da3e61c1 100755..100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 477d440f28..84808cb876 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -467,6 +467,8 @@ void ScriptEditor::_update_recent_scripts() {
recent_scripts->add_separator();
recent_scripts->add_shortcut(ED_SHORTCUT("script_editor/clear_recent", TTR("Clear Recent Files")));
+
+ recent_scripts->set_as_minsize();
}
void ScriptEditor::_open_recent_script(int p_idx) {
@@ -474,7 +476,7 @@ void ScriptEditor::_open_recent_script(int p_idx) {
// clear button
if (p_idx == recent_scripts->get_item_count() - 1) {
previous_scripts.clear();
- _update_recent_scripts();
+ call_deferred("_update_recent_scripts");
return;
}
@@ -1407,8 +1409,10 @@ void ScriptEditor::_update_members_overview() {
void ScriptEditor::_update_help_overview_visibility() {
int selected = tab_container->get_current_tab();
- if (selected < 0 || selected >= tab_container->get_child_count())
+ if (selected < 0 || selected >= tab_container->get_child_count()) {
+ help_overview->set_visible(false);
return;
+ }
Node *current = tab_container->get_child(tab_container->get_current_tab());
EditorHelp *se = Object::cast_to<EditorHelp>(current);
@@ -1425,6 +1429,7 @@ void ScriptEditor::_update_help_overview_visibility() {
}
void ScriptEditor::_update_help_overview() {
+ help_overview->clear();
int selected = tab_container->get_current_tab();
if (selected < 0 || selected >= tab_container->get_child_count())
@@ -1436,8 +1441,6 @@ void ScriptEditor::_update_help_overview() {
return;
}
- help_overview->clear();
-
Vector<Pair<String, int> > sections = se->get_sections();
for (int i = 0; i < sections.size(); i++) {
help_overview->add_item(sections[i].first);
@@ -1445,9 +1448,6 @@ void ScriptEditor::_update_help_overview() {
}
}
-void _help_overview_selected(int p_idx) {
-}
-
void ScriptEditor::_update_script_colors() {
bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled");
@@ -1593,6 +1593,8 @@ void ScriptEditor::_update_script_names() {
_update_members_overview();
_update_help_overview();
+ _update_members_overview_visibility();
+ _update_help_overview_visibility();
_update_script_colors();
}
@@ -2240,6 +2242,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_live_auto_reload_running_scripts", &ScriptEditor::_live_auto_reload_running_scripts);
ClassDB::bind_method("_unhandled_input", &ScriptEditor::_unhandled_input);
ClassDB::bind_method("_script_changed", &ScriptEditor::_script_changed);
+ ClassDB::bind_method("_update_recent_scripts", &ScriptEditor::_update_recent_scripts);
ClassDB::bind_method(D_METHOD("get_current_script"), &ScriptEditor::_get_current_script);
ClassDB::bind_method(D_METHOD("get_open_scripts"), &ScriptEditor::_get_open_scripts);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 32973db6ec..547679b056 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -63,7 +63,8 @@
#define ZOOM_MULTIPLIER 1.08
#define ZOOM_INDICATOR_DELAY_S 1.5
-#define FREELOOK_MIN_SPEED 0.1
+#define FREELOOK_MIN_SPEED 0.01
+#define FREELOOK_SPEED_MULTIPLIER 1.08
#define MIN_Z 0.01
#define MAX_Z 10000
@@ -75,34 +76,66 @@ void SpatialEditorViewport::_update_camera(float p_interp_delta) {
bool is_orthogonal = camera->get_projection() == Camera::PROJECTION_ORTHOGONAL;
- //when not being manipulated, move softly
- float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
- float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
- //when being manipulated, move more quickly
- float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
- float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
+ Cursor old_camera_cursor = camera_cursor;
+ camera_cursor = cursor;
- float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
+ if (p_interp_delta > 0) {
- //determine if being manipulated
- bool manipulated = (Input::get_singleton()->get_mouse_button_mask() & (2 | 4)) || Input::get_singleton()->is_key_pressed(KEY_SHIFT) || Input::get_singleton()->is_key_pressed(KEY_ALT) || Input::get_singleton()->is_key_pressed(KEY_CONTROL);
+ //-------
+ // Perform smoothing
- float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
- float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
+ if (is_freelook_active()) {
- Cursor old_camera_cursor = camera_cursor;
- camera_cursor = cursor;
+ // Higher inertia should increase "lag" (lerp with factor between 0 and 1)
+ // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
+ real_t inertia = EDITOR_GET("editors/3d/freelook/freelook_inertia");
+ inertia = MAX(0.001, inertia);
+ real_t factor = (1.0 / inertia) * p_interp_delta;
+
+ // We interpolate a different point here, because in freelook mode the focus point (cursor.pos) orbits around eye_pos
+ camera_cursor.eye_pos = old_camera_cursor.eye_pos.linear_interpolate(cursor.eye_pos, CLAMP(factor, 0, 1));
+ //camera_cursor.pos = camera_cursor.eye_pos + (cursor.pos - cursor.eye_pos);
+
+ float orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ orbit_inertia = MAX(0.0001, orbit_inertia);
+ camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+
+ Vector3 forward = to_camera_transform(camera_cursor).basis.xform(Vector3(0, 0, -1));
+ camera_cursor.pos = camera_cursor.eye_pos + forward * camera_cursor.distance;
- camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
- camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ } else {
+
+ //when not being manipulated, move softly
+ float free_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/orbit_inertia");
+ float free_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/translation_inertia");
+ //when being manipulated, move more quickly
+ float manip_orbit_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_orbit_inertia");
+ float manip_translation_inertia = EDITOR_GET("editors/3d/navigation_feel/manipulation_translation_inertia");
+
+ float zoom_inertia = EDITOR_GET("editors/3d/navigation_feel/zoom_inertia");
+
+ //determine if being manipulated
+ bool manipulated = Input::get_singleton()->get_mouse_button_mask() & (2 | 4);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_SHIFT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_ALT);
+ manipulated |= Input::get_singleton()->is_key_pressed(KEY_CONTROL);
- camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
- camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia)));
+ float orbit_inertia = MAX(0.00001, manipulated ? manip_orbit_inertia : free_orbit_inertia);
+ float translation_inertia = MAX(0.0001, manipulated ? manip_translation_inertia : free_translation_inertia);
+ zoom_inertia = MAX(0.0001, zoom_inertia);
- if (p_interp_delta == 0 || is_freelook_active()) {
- camera_cursor = cursor;
+ camera_cursor.x_rot = Math::lerp(old_camera_cursor.x_rot, cursor.x_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+ camera_cursor.y_rot = Math::lerp(old_camera_cursor.y_rot, cursor.y_rot, MIN(1.f, p_interp_delta * (1 / orbit_inertia)));
+
+ camera_cursor.pos = old_camera_cursor.pos.linear_interpolate(cursor.pos, MIN(1.f, p_interp_delta * (1 / translation_inertia)));
+ camera_cursor.distance = Math::lerp(old_camera_cursor.distance, cursor.distance, MIN(1.f, p_interp_delta * (1 / zoom_inertia)));
+ }
}
+ //-------
+ // Apply camera transform
+
float tolerance = 0.001;
bool equal = true;
if (Math::abs(old_camera_cursor.x_rot - camera_cursor.x_rot) > tolerance || Math::abs(old_camera_cursor.y_rot - camera_cursor.y_rot) > tolerance) {
@@ -845,11 +878,17 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
switch (b->get_button_index()) {
case BUTTON_WHEEL_UP: {
- scale_cursor_distance(is_freelook_active() ? zoom_factor : 1.0 / zoom_factor);
+ if (is_freelook_active())
+ scale_freelook_speed(zoom_factor);
+ else
+ scale_cursor_distance(1.0 / zoom_factor);
} break;
case BUTTON_WHEEL_DOWN: {
- scale_cursor_distance(is_freelook_active() ? 1.0 / zoom_factor : zoom_factor);
+ if (is_freelook_active())
+ scale_freelook_speed(1.0 / zoom_factor);
+ else
+ scale_cursor_distance(zoom_factor);
} break;
case BUTTON_RIGHT: {
@@ -901,10 +940,10 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (b->is_pressed()) {
int mod = _get_key_modifier(b);
if (mod == _get_key_modifier_setting("editors/3d/freelook/freelook_activation_modifier")) {
- freelook_active = true;
+ set_freelook_active(true);
}
} else {
- freelook_active = false;
+ set_freelook_active(false);
}
if (freelook_active && !surface->has_focus()) {
@@ -1645,6 +1684,9 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
real_t degrees_per_pixel = EditorSettings::get_singleton()->get("editors/3d/navigation_feel/orbit_sensitivity");
real_t radians_per_pixel = Math::deg2rad(degrees_per_pixel);
+ // Note: do NOT assume the camera has the "current" transform, because it is interpolated and may have "lag".
+ Transform prev_camera_transform = to_camera_transform(cursor);
+
cursor.x_rot += relative.y * radians_per_pixel;
cursor.y_rot += relative.x * radians_per_pixel;
if (cursor.x_rot > Math_PI / 2.0)
@@ -1652,12 +1694,12 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (cursor.x_rot < -Math_PI / 2.0)
cursor.x_rot = -Math_PI / 2.0;
- // Look is like Orbit, except the cursor translates, not the camera
+ // Look is like the opposite of Orbit: the focus point rotates around the camera
Transform camera_transform = to_camera_transform(cursor);
Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
- Vector3 diff = camera->get_translation() - pos;
+ Vector3 prev_pos = prev_camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = prev_pos - pos;
cursor.pos += diff;
- freelook_target_position += diff;
name = "";
_update_name();
@@ -1755,23 +1797,57 @@ void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
}
}
+void SpatialEditorViewport::set_freelook_active(bool active_now) {
+
+ if (!freelook_active && active_now) {
+ // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
+ cursor = camera_cursor;
+
+ // Make sure eye_pos is synced, because freelook referential is eye pos rather than orbit pos
+ Vector3 forward = to_camera_transform(cursor).basis.xform(Vector3(0, 0, -1));
+ cursor.eye_pos = cursor.pos - cursor.distance * forward;
+ // Also sync the camera cursor, otherwise switching to freelook will be trippy if inertia is active
+ camera_cursor.eye_pos = cursor.eye_pos;
+
+ if (EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_speed_zoom_link")) {
+ // Re-adjust freelook speed from the current zoom level
+ real_t base_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed");
+ freelook_speed = base_speed * cursor.distance;
+ }
+
+ } else if (freelook_active && !active_now) {
+ // Sync camera cursor to cursor to "cut" interpolation jumps due to changing referential
+ cursor = camera_cursor;
+ }
+
+ freelook_active = active_now;
+}
+
void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
// Prevents zero distance which would short-circuit any scaling
if (cursor.distance < ZOOM_MIN_DISTANCE)
cursor.distance = ZOOM_MIN_DISTANCE;
- real_t prev_distance = cursor.distance;
cursor.distance *= scale;
if (cursor.distance < ZOOM_MIN_DISTANCE)
cursor.distance = ZOOM_MIN_DISTANCE;
- if (is_freelook_active()) {
- // In freelook mode, cursor reference is reversed so it needs to be adjusted
- Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
- cursor.pos += (cursor.distance - prev_distance) * forward;
- }
+ zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
+ surface->update();
+}
+
+void SpatialEditorViewport::scale_freelook_speed(real_t scale) {
+
+ // Prevents zero distance which would short-circuit any scaling
+ if (freelook_speed < FREELOOK_MIN_SPEED)
+ freelook_speed = FREELOOK_MIN_SPEED;
+
+ freelook_speed *= scale;
+
+ if (freelook_speed < FREELOOK_MIN_SPEED)
+ freelook_speed = FREELOOK_MIN_SPEED;
zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
surface->update();
@@ -1790,7 +1866,6 @@ Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMous
void SpatialEditorViewport::_update_freelook(real_t delta) {
if (!is_freelook_active()) {
- freelook_target_position = cursor.pos;
return;
}
@@ -1833,21 +1908,15 @@ void SpatialEditorViewport::_update_freelook(real_t delta) {
speed_modifier = true;
}
- real_t inertia = EDITOR_DEF("editors/3d/freelook/freelook_inertia", 0.1);
- inertia = MAX(0, inertia);
- const real_t base_speed = EDITOR_DEF("editors/3d/freelook/freelook_base_speed", 0.5);
- const real_t modifier_speed_factor = EDITOR_DEF("editors/3d/freelook/freelook_modifier_speed_factor", 3);
-
- real_t speed = base_speed * cursor.distance;
- if (speed_modifier)
+ real_t speed = freelook_speed;
+ if (speed_modifier) {
+ real_t modifier_speed_factor = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_modifier_speed_factor");
speed *= modifier_speed_factor;
+ }
- // Higher inertia should increase "lag" (lerp with factor between 0 and 1)
- // Inertia of zero should produce instant movement (lerp with factor of 1) in this case it returns a really high value and gets clamped to 1.
-
- freelook_target_position += direction * speed;
- real_t factor = (1.0 / (inertia + 0.001)) * delta;
- cursor.pos = cursor.pos.linear_interpolate(freelook_target_position, CLAMP(factor, 0, 1));
+ Vector3 motion = direction * speed * delta;
+ cursor.pos += motion;
+ cursor.eye_pos += motion;
}
void SpatialEditorViewport::set_message(String p_message, float p_time) {
@@ -1886,7 +1955,7 @@ void SpatialEditorViewport::_notification(int p_what) {
}
*/
- real_t delta = get_tree()->get_idle_process_time();
+ real_t delta = get_process_delta_time();
if (zoom_indicator_delay > 0) {
zoom_indicator_delay -= delta;
@@ -1897,7 +1966,7 @@ void SpatialEditorViewport::_notification(int p_what) {
_update_freelook(delta);
- _update_camera(get_process_delta_time());
+ _update_camera(delta);
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -2026,7 +2095,7 @@ void SpatialEditorViewport::_notification(int p_what) {
}
// TODO That should be part of the drawing API...
-static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = 1.0) {
+static void stroke_rect(CanvasItem &ci, Rect2 rect, Color color, real_t width = 1.0) {
// a---b
// | |
@@ -2036,10 +2105,31 @@ static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width =
Vector2 c(rect.position.x, rect.position.y + rect.size.y);
Vector2 d(rect.position + rect.size);
- ci->draw_line(a, b, color, width);
- ci->draw_line(b, d, color, width);
- ci->draw_line(d, c, color, width);
- ci->draw_line(c, a, color, width);
+ ci.draw_line(a, b, color, width);
+ ci.draw_line(b, d, color, width);
+ ci.draw_line(d, c, color, width);
+ ci.draw_line(c, a, color, width);
+}
+
+static void draw_indicator_bar(Control &surface, real_t fill, Ref<Texture> icon) {
+
+ // Adjust bar size from control height
+ Vector2 surface_size = surface.get_size();
+ real_t h = surface_size.y / 2.0;
+ real_t y = (surface_size.y - h) / 2.0;
+
+ Rect2 r(10, y, 6, h);
+ real_t sy = r.size.y * fill;
+
+ // Note: because this bar appears over the viewport, it has to stay readable for any background color
+ // Draw both neutral dark and bright colors to account this
+ surface.draw_rect(r, Color(1, 1, 1, 0.2));
+ surface.draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
+ stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+
+ Vector2 icon_size = icon->get_size();
+ Vector2 icon_pos = Vector2(r.position.x - (icon_size.x - r.size.x) / 2, r.position.y + r.size.y + 2);
+ surface.draw_texture(icon, icon_pos);
}
void SpatialEditorViewport::_draw() {
@@ -2098,35 +2188,47 @@ void SpatialEditorViewport::_draw() {
draw_rect = Rect2(Vector2(), s).clip(draw_rect);
- stroke_rect(surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
+ stroke_rect(*surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
} else {
if (zoom_indicator_delay > 0.0) {
- // Show indicative zoom factor
- real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
- real_t max_distance = camera->get_zfar();
- real_t scale_length = (max_distance - min_distance);
+ if (is_freelook_active()) {
+ // Show speed
- if (Math::abs(scale_length) > CMP_EPSILON) {
- real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
+ real_t min_speed = FREELOOK_MIN_SPEED;
+ real_t max_speed = camera->get_zfar();
+ real_t scale_length = (max_speed - min_speed);
- // There is no real maximum distance so that factor can become negative,
- // Let's make it look asymptotic instead (will decrease slower and slower).
- if (logscale_t < 0.25)
- logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + freelook_speed - min_speed) / Math::log(1 + scale_length);
- Vector2 surface_size = surface->get_size();
- real_t h = surface_size.y / 2.0;
- real_t y = (surface_size.y - h) / 2.0;
+ // There is no real maximum speed so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
- Rect2 r(10, y, 6, h);
- real_t sy = r.size.y * logscale_t;
+ draw_indicator_bar(*surface, 1.0 - logscale_t, get_icon("ViewportSpeed", "EditorIcons"));
+ }
+
+ } else {
+ // Show zoom
- surface->draw_rect(r, Color(1, 1, 1, 0.2));
- surface->draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
- stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+ real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
+ real_t max_distance = camera->get_zfar();
+ real_t scale_length = (max_distance - min_distance);
+
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
+
+ // There is no real maximum distance so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+
+ draw_indicator_bar(*surface, logscale_t, get_icon("ViewportZoom", "EditorIcons"));
+ }
}
}
}
@@ -2576,6 +2678,7 @@ void SpatialEditorViewport::reset() {
cursor.y_rot = 0.5;
cursor.distance = 4;
cursor.region_select = false;
+ cursor.pos = Vector3();
_update_name();
}
@@ -2662,8 +2765,14 @@ Vector3 SpatialEditorViewport::_get_instance_position(const Point2 &p_pos) const
normal = hit_normal;
}
}
- Vector3 center = preview_bounds->get_size() * 0.5;
- return point + (center * normal);
+ Vector3 offset = Vector3();
+ for (int i = 0; i < 3; i++) {
+ if (normal[i] > 0.0)
+ offset[i] = (preview_bounds->get_size()[i] - (preview_bounds->get_size()[i] + preview_bounds->get_position()[i]));
+ else if (normal[i] < 0.0)
+ offset[i] = -(preview_bounds->get_size()[i] + preview_bounds->get_position()[i]);
+ }
+ return point + offset;
}
Rect3 SpatialEditorViewport::_calculate_spatial_bounds(const Spatial *p_parent, const Rect3 p_bounds) {
@@ -3036,6 +3145,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
accept = NULL;
freelook_active = false;
+ freelook_speed = EditorSettings::get_singleton()->get("editors/3d/freelook/freelook_base_speed");
selection_menu = memnew(PopupMenu);
add_child(selection_menu);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 4f4c540048..a9dd1f1327 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -131,7 +131,7 @@ private:
float gizmo_scale;
bool freelook_active;
- Vector3 freelook_target_position;
+ real_t freelook_speed;
PanelContainer *info;
Label *info_label;
@@ -231,6 +231,7 @@ private:
Vector3 pos;
float x_rot, y_rot, distance;
+ Vector3 eye_pos; // Used in freelook mode
bool region_select;
Point2 region_begin, region_end;
@@ -239,10 +240,17 @@ private:
distance = 4;
region_select = false;
}
- } cursor, camera_cursor;
+ };
+ // Viewport camera supports movement smoothing,
+ // so one cursor is the real cursor, while the other can be an interpolated version.
+ Cursor cursor; // Immediate cursor
+ Cursor camera_cursor; // That one may be interpolated (don't modify this one except for smoothing purposes)
void scale_cursor_distance(real_t scale);
+ void set_freelook_active(bool active_now);
+ void scale_freelook_speed(real_t scale);
+
real_t zoom_indicator_delay;
RID move_gizmo_instance[3], move_plane_gizmo_instance[3], rotate_gizmo_instance[3], scale_gizmo_instance[3];
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 3b6eeb61d6..dc7acd9fdc 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -43,10 +43,10 @@ void SpriteFramesEditor::_notification(int p_what) {
}
if (p_what == NOTIFICATION_ENTER_TREE) {
- load->set_icon(get_icon("Folder", "EditorIcons"));
- _delete->set_icon(get_icon("Del", "EditorIcons"));
+ load->set_icon(get_icon("Load", "EditorIcons"));
+ _delete->set_icon(get_icon("Remove", "EditorIcons"));
new_anim->set_icon(get_icon("New", "EditorIcons"));
- remove_anim->set_icon(get_icon("Del", "EditorIcons"));
+ remove_anim->set_icon(get_icon("Remove", "EditorIcons"));
}
if (p_what == NOTIFICATION_READY) {
@@ -667,7 +667,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
VBoxContainer *vbc_animlist = memnew(VBoxContainer);
split->add_child(vbc_animlist);
- vbc_animlist->set_custom_minimum_size(Size2(150, 0));
+ vbc_animlist->set_custom_minimum_size(Size2(150, 0) * EDSCALE);
//vbc_animlist->set_v_size_flags(SIZE_EXPAND_FILL);
VBoxContainer *sub_vb = memnew(VBoxContainer);
@@ -678,12 +678,13 @@ SpriteFramesEditor::SpriteFramesEditor() {
sub_vb->add_child(hbc_animlist);
new_anim = memnew(Button);
+ new_anim->set_flat(true);
hbc_animlist->add_child(new_anim);
+ new_anim->set_h_size_flags(SIZE_EXPAND_FILL);
new_anim->connect("pressed", this, "_animation_add");
- hbc_animlist->add_spacer();
-
remove_anim = memnew(Button);
+ remove_anim->set_flat(true);
hbc_animlist->add_child(remove_anim);
remove_anim->connect("pressed", this, "_animation_remove");
@@ -720,6 +721,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
//animations = memnew( ItemList );
load = memnew(Button);
+ load->set_flat(true);
load->set_tooltip(TTR("Load Resource"));
hbc->add_child(load);
@@ -736,14 +738,15 @@ SpriteFramesEditor::SpriteFramesEditor() {
hbc->add_child(empty2);
move_up = memnew(Button);
- move_up->set_text(TTR("Up"));
+ move_up->set_text(TTR("Move (Before)"));
hbc->add_child(move_up);
move_down = memnew(Button);
- move_down->set_text(TTR("Down"));
+ move_down->set_text(TTR("Move (After)"));
hbc->add_child(move_down);
_delete = memnew(Button);
+ _delete->set_flat(true);
hbc->add_child(_delete);
file = memnew(EditorFileDialog);
@@ -818,7 +821,7 @@ SpriteFramesEditorPlugin::SpriteFramesEditorPlugin(EditorNode *p_node) {
editor = p_node;
frames_editor = memnew(SpriteFramesEditor);
- frames_editor->set_custom_minimum_size(Size2(0, 300));
+ frames_editor->set_custom_minimum_size(Size2(0, 300) * EDSCALE);
button = editor->add_bottom_panel_item("SpriteFrames", frames_editor);
button->hide();
}
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 2f2ed7bdf0..d12b3f1e0e 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -229,7 +229,7 @@ struct _PaletteEntry {
return name < p_rhs.name;
}
};
-}
+} // namespace
void TileMapEditor::_update_palette() {
@@ -1152,7 +1152,7 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
return false;
}
-void TileMapEditor::_canvas_draw() {
+void TileMapEditor::forward_draw_over_canvas(Control *p_canvas) {
if (!node)
return;
@@ -1379,8 +1379,6 @@ void TileMapEditor::edit(Node *p_tile_map) {
if (p_tile_map) {
node = Object::cast_to<TileMap>(p_tile_map);
- if (!canvas_item_editor->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->connect("draw", this, "_canvas_draw");
if (!canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
canvas_item_editor->connect("mouse_entered", this, "_canvas_mouse_enter");
if (!canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
@@ -1391,8 +1389,6 @@ void TileMapEditor::edit(Node *p_tile_map) {
} else {
node = NULL;
- if (canvas_item_editor->is_connected("draw", this, "_canvas_draw"))
- canvas_item_editor->disconnect("draw", this, "_canvas_draw");
if (canvas_item_editor->is_connected("mouse_entered", this, "_canvas_mouse_enter"))
canvas_item_editor->disconnect("mouse_entered", this, "_canvas_mouse_enter");
if (canvas_item_editor->is_connected("mouse_exited", this, "_canvas_mouse_exit"))
@@ -1428,7 +1424,6 @@ void TileMapEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_text_changed"), &TileMapEditor::_text_changed);
ClassDB::bind_method(D_METHOD("_sbox_input"), &TileMapEditor::_sbox_input);
ClassDB::bind_method(D_METHOD("_menu_option"), &TileMapEditor::_menu_option);
- ClassDB::bind_method(D_METHOD("_canvas_draw"), &TileMapEditor::_canvas_draw);
ClassDB::bind_method(D_METHOD("_canvas_mouse_enter"), &TileMapEditor::_canvas_mouse_enter);
ClassDB::bind_method(D_METHOD("_canvas_mouse_exit"), &TileMapEditor::_canvas_mouse_exit);
ClassDB::bind_method(D_METHOD("_tileset_settings_changed"), &TileMapEditor::_tileset_settings_changed);
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index c8f29dfb7b..5b042e4780 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -163,7 +163,6 @@ class TileMapEditor : public VBoxContainer {
void _text_changed(const String &p_text);
void _sbox_input(const Ref<InputEvent> &p_ie);
void _update_palette();
- void _canvas_draw();
void _menu_option(int p_option);
void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, bool p_with_undo = false);
@@ -183,6 +182,8 @@ public:
HBoxContainer *get_toolbar() const { return toolbar; }
bool forward_gui_input(const Ref<InputEvent> &p_event);
+ void forward_draw_over_canvas(Control *p_canvas);
+
void edit(Node *p_tile_map);
TileMapEditor(EditorNode *p_editor);
@@ -197,6 +198,7 @@ class TileMapEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); }
+ virtual void forward_draw_over_canvas(Control *p_canvas) { tile_map_editor->forward_draw_over_canvas(p_canvas); }
virtual String get_name() const { return "TileMap"; }
bool has_main_screen() const { return false; }
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index e5b6f8e406..d8a87e738f 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -733,8 +733,12 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
ERR_FAIL_COND(platform.is_null());
Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0);
- if (err != OK)
+ if (err != OK) {
+ error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted: ") + platform->get_name());
+ error_dialog->show();
+ error_dialog->popup_centered_minsize(Size2(300, 80));
ERR_PRINT("Failed to export project");
+ }
}
void ProjectExportDialog::_bind_methods() {
@@ -940,6 +944,12 @@ ProjectExportDialog::ProjectExportDialog() {
export_error2->add_color_override("font_color", get_color("error_color", "Editor"));
export_error2->set_text(" - " + TTR("Export templates for this platform are missing:") + " ");
+ error_dialog = memnew(AcceptDialog);
+ error_dialog->set_title("Error");
+ error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted:") + " ");
+ main_vb->add_child(error_dialog);
+ error_dialog->hide();
+
LinkButton *download_templates = memnew(LinkButton);
download_templates->set_text(TTR("Manage Export Templates"));
export_templates_error->add_child(download_templates);
diff --git a/editor/project_export.h b/editor/project_export.h
index 61de0f739a..288b0c290f 100644
--- a/editor/project_export.h
+++ b/editor/project_export.h
@@ -72,6 +72,7 @@ private:
Button *button_export;
bool updating;
+ AcceptDialog *error_dialog;
ConfirmationDialog *delete_confirm;
OptionButton *export_filter;
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 9f23df5c03..d1210ee26a 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -750,6 +750,9 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
if (!k->is_pressed())
return;
+ if (tabs->get_current_tab() != 0)
+ return;
+
bool scancode_handled = true;
switch (k->get_scancode()) {
diff --git a/editor/project_settings_editor.cpp b/editor/project_settings_editor.cpp
index 91ef9e36f3..723d7b14ff 100644
--- a/editor/project_settings_editor.cpp
+++ b/editor/project_settings_editor.cpp
@@ -1189,7 +1189,7 @@ void ProjectSettingsEditor::_translation_res_option_delete(Object *p_item, int p
ERR_FAIL_COND(!remaps.has(key));
PoolStringArray r = remaps[key];
- ERR_FAIL_INDEX(idx, remaps.size());
+ ERR_FAIL_INDEX(idx, r.size());
r.remove(idx);
remaps[key] = r;
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 658f67d6a4..b7cc9347f2 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -376,7 +376,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
if (hint == PROPERTY_HINT_RANGE) {
int c = hint_text.get_slice_count(",");
- float min = 0, max = 100, step = 1;
+ float min = 0, max = 100, step = type == Variant::REAL ? .01 : 1;
if (c >= 1) {
if (!hint_text.get_slice(",", 0).empty())
@@ -3032,7 +3032,7 @@ void PropertyEditor::update_tree() {
if (p.hint == PROPERTY_HINT_SPRITE_FRAME || p.hint == PROPERTY_HINT_RANGE || p.hint == PROPERTY_HINT_EXP_RANGE) {
int c = p.hint_string.get_slice_count(",");
- float min = 0, max = 100, step = 1;
+ float min = 0, max = 100, step = p.type == Variant::REAL ? .01 : 1;
if (c >= 1) {
min = p.hint_string.get_slice(",", 0).to_double();
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 6dcd5e54ec..a6e0af05b2 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -215,9 +215,9 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
bool has_groups = p_node->has_persistent_groups();
if (has_connections && has_groups) {
- item->add_button(0, get_icon("ConnectionAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s)\nClick to show signals dock."));
+ item->add_button(0, get_icon("SignalsAndGroups", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connection(s) and group(s)\nClick to show signals dock."));
} else if (has_connections) {
- item->add_button(0, get_icon("Connect", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock."));
+ item->add_button(0, get_icon("Signals", "EditorIcons"), BUTTON_SIGNALS, false, TTR("Node has connections.\nClick to show signals dock."));
} else if (has_groups) {
item->add_button(0, get_icon("Groups", "EditorIcons"), BUTTON_GROUPS, false, TTR("Node is in group(s).\nClick to show groups dock."));
}
diff --git a/editor/script_editor_debugger.h b/editor/script_editor_debugger.h
index 64ac2535a9..d0faab5892 100644
--- a/editor/script_editor_debugger.h
+++ b/editor/script_editor_debugger.h
@@ -166,9 +166,6 @@ class ScriptEditorDebugger : public Control {
void _method_changed(Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
void _property_changed(Object *p_base, const StringName &p_property, const Variant &p_value);
- static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
- static void _property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);
-
void _error_selected(int p_idx);
void _error_stack_selected(int p_idx);
@@ -196,6 +193,9 @@ public:
void set_live_debugging(bool p_enable);
+ static void _method_changeds(void *p_ud, Object *p_base, const StringName &p_name, VARIANT_ARG_DECLARE);
+ static void _property_changeds(void *p_ud, Object *p_base, const StringName &p_property, const Variant &p_value);
+
void live_debug_create_node(const NodePath &p_parent, const String &p_type, const String &p_name);
void live_debug_instance_node(const NodePath &p_parent, const String &p_path, const String &p_name);
void live_debug_remove_node(const NodePath &p_at);
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 86979a1174..c052845be9 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -35,6 +35,7 @@
#include "os/keyboard.h"
#include "project_settings.h"
#include "scene/gui/margin_container.h"
+#include "script_editor_debugger.h"
void EditorSettingsDialog::ok_pressed() {
@@ -91,6 +92,7 @@ void EditorSettingsDialog::popup_edit_settings() {
search_box->grab_focus();
_update_shortcuts();
+ set_process_unhandled_input(true);
// Restore valid window bounds or pop up at default size.
if (EditorSettings::get_singleton()->has_setting("interface/dialogs/editor_settings_bounds")) {
@@ -121,19 +123,62 @@ void EditorSettingsDialog::_filter_shortcuts(const String &p_filter) {
_update_shortcuts();
}
+void EditorSettingsDialog::_undo_redo_callback(void *p_self, const String &p_name) {
+ EditorNode::get_log()->add_message(p_name);
+}
+
void EditorSettingsDialog::_notification(int p_what) {
switch (p_what) {
+ case NOTIFICATION_READY: {
+ ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
+ undo_redo->set_method_notify_callback(sed->_method_changeds, sed);
+ undo_redo->set_property_notify_callback(sed->_property_changeds, sed);
+ undo_redo->set_commit_notify_callback(_undo_redo_callback, this);
+ } break;
case NOTIFICATION_ENTER_TREE: {
clear_button->set_icon(get_icon("Close", "EditorIcons"));
shortcut_clear_button->set_icon(get_icon("Close", "EditorIcons"));
} break;
case NOTIFICATION_POPUP_HIDE: {
EditorSettings::get_singleton()->set("interface/dialogs/editor_settings_bounds", get_rect());
+ set_process_unhandled_input(false);
} break;
}
}
+void EditorSettingsDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid() && is_window_modal_on_top()) {
+
+ if (k->is_pressed()) {
+
+ bool handled = false;
+
+ if (ED_IS_SHORTCUT("editor/undo", p_event)) {
+ String action = undo_redo->get_current_action_name();
+ if (action != "")
+ EditorNode::get_log()->add_message("UNDO: " + action);
+ undo_redo->undo();
+ handled = true;
+ }
+ if (ED_IS_SHORTCUT("editor/redo", p_event)) {
+ undo_redo->redo();
+ String action = undo_redo->get_current_action_name();
+ if (action != "")
+ EditorNode::get_log()->add_message("REDO: " + action);
+ handled = true;
+ }
+
+ if (handled) {
+ accept_event();
+ }
+ }
+ }
+}
+
void EditorSettingsDialog::_update_shortcuts() {
shortcuts->clear();
@@ -212,30 +257,28 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
if (!sc.is_valid())
return; //pointless, there is nothing
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action("Erase Shortcut");
- ur->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
- ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- ur->add_do_method(this, "_update_shortcuts");
- ur->add_undo_method(this, "_update_shortcuts");
- ur->add_do_method(this, "_settings_changed");
- ur->add_undo_method(this, "_settings_changed");
- ur->commit_action();
+ undo_redo->create_action("Erase Shortcut");
+ undo_redo->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
+ undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
} else if (p_idx == 2) { //revert to original
if (!sc.is_valid())
return; //pointless, there is nothing
Ref<InputEvent> original = sc->get_meta("original");
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action("Restore Shortcut");
- ur->add_do_method(sc.ptr(), "set_shortcut", original);
- ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- ur->add_do_method(this, "_update_shortcuts");
- ur->add_undo_method(this, "_update_shortcuts");
- ur->add_do_method(this, "_settings_changed");
- ur->add_undo_method(this, "_settings_changed");
- ur->commit_action();
+ undo_redo->create_action("Restore Shortcut");
+ undo_redo->add_do_method(sc.ptr(), "set_shortcut", original);
+ undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
}
}
@@ -276,19 +319,19 @@ void EditorSettingsDialog::_press_a_key_confirm() {
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
- UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action("Change Shortcut '" + shortcut_configured + "'");
- ur->add_do_method(sc.ptr(), "set_shortcut", ie);
- ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
- ur->add_do_method(this, "_update_shortcuts");
- ur->add_undo_method(this, "_update_shortcuts");
- ur->add_do_method(this, "_settings_changed");
- ur->add_undo_method(this, "_settings_changed");
- ur->commit_action();
+ undo_redo->create_action("Change Shortcut '" + shortcut_configured + "'");
+ undo_redo->add_do_method(sc.ptr(), "set_shortcut", ie);
+ undo_redo->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
+ undo_redo->add_do_method(this, "_update_shortcuts");
+ undo_redo->add_undo_method(this, "_update_shortcuts");
+ undo_redo->add_do_method(this, "_settings_changed");
+ undo_redo->add_undo_method(this, "_settings_changed");
+ undo_redo->commit_action();
}
void EditorSettingsDialog::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_unhandled_input"), &EditorSettingsDialog::_unhandled_input);
ClassDB::bind_method(D_METHOD("_settings_save"), &EditorSettingsDialog::_settings_save);
ClassDB::bind_method(D_METHOD("_settings_changed"), &EditorSettingsDialog::_settings_changed);
ClassDB::bind_method(D_METHOD("_settings_property_edited"), &EditorSettingsDialog::_settings_property_edited);
@@ -305,6 +348,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
set_title(TTR("Editor Settings"));
set_resizable(true);
+ undo_redo = memnew(UndoRedo);
tabs = memnew(TabContainer);
tabs->set_tab_align(TabContainer::ALIGN_LEFT);
@@ -336,7 +380,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
property_editor->get_property_editor()->set_use_filter(true);
property_editor->register_search_box(search_box);
property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- property_editor->get_property_editor()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
+ property_editor->get_property_editor()->set_undo_redo(undo_redo);
vbc->add_child(property_editor);
property_editor->get_property_editor()->connect("property_edited", this, "_settings_property_edited");
@@ -400,3 +444,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
updating = false;
}
+
+EditorSettingsDialog::~EditorSettingsDialog() {
+ memdelete(undo_redo);
+}
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index 8a66d5098c..a03b15c06d 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -50,6 +50,7 @@ class EditorSettingsDialog : public AcceptDialog {
Timer *timer;
+ UndoRedo *undo_redo;
Tree *shortcuts;
ConfirmationDialog *press_a_key;
@@ -65,6 +66,7 @@ class EditorSettingsDialog : public AcceptDialog {
void _settings_property_edited(const String &p_name);
void _settings_save();
+ void _unhandled_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
void _press_a_key_confirm();
@@ -78,6 +80,8 @@ class EditorSettingsDialog : public AcceptDialog {
void _update_shortcuts();
void _shortcut_button_pressed(Object *p_item, int p_column, int p_idx);
+ static void _undo_redo_callback(void *p_self, const String &p_name);
+
protected:
static void _bind_methods();
@@ -85,6 +89,7 @@ public:
void popup_edit_settings();
EditorSettingsDialog();
+ ~EditorSettingsDialog();
};
#endif // SETTINGS_CONFIG_DIALOG_H
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 3c1889e829..3f8d93d976 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -298,11 +298,11 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
}
}
-void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 size) {
+void EditorSpatialGizmo::add_solid_box(Ref<Material> &p_material, Vector3 p_size) {
ERR_FAIL_COND(!spatial_node);
CubeMesh cubem;
- cubem.set_size(size);
+ cubem.set_size(p_size);
Ref<ArrayMesh> m = memnew(ArrayMesh);
m->add_surface_from_arrays(cubem.surface_get_primitive_type(0), cubem.surface_get_arrays(0));
m->surface_set_material(0, p_material);
diff --git a/main/SCsub b/main/SCsub
index 1f97cd1be0..ae63b94864 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -16,7 +16,7 @@ def make_splash(target, source, env):
g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
g.write("#ifndef BOOT_SPLASH_H\n")
g.write("#define BOOT_SPLASH_H\n")
- g.write("static const Color boot_splash_bg_color = Color(1,1,1,1);\n")
+ g.write('static const Color boot_splash_bg_color = Color::html("#232323");\n')
g.write("static const unsigned char boot_splash_png[] = {\n")
for i in range(len(buf)):
g.write(byte_to_str(buf[i]) + ",\n")
diff --git a/main/main.cpp b/main/main.cpp
index c6d3c3f15c..04ed902c28 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -45,6 +45,7 @@
#include "input_map.h"
#include "io/resource_loader.h"
#include "scene/main/scene_tree.h"
+#include "servers/arvr_server.h"
#include "servers/audio_server.h"
#include "io/resource_loader.h"
@@ -82,6 +83,7 @@ static InputMap *input_map = NULL;
static bool _start_success = false;
static ScriptDebugger *script_debugger = NULL;
AudioServer *audio_server = NULL;
+ARVRServer *arvr_server = NULL;
static MessageQueue *message_queue = NULL;
static Performance *performance = NULL;
@@ -162,6 +164,7 @@ void Main::print_help(const char *p_binary) {
#endif
OS::get_singleton()->print(" -l, --language <locale> Use a specific locale (<locale> being a two-letter code).\n");
OS::get_singleton()->print(" --path <directory> Path to a project (<directory> must contain a 'project.godot' file).\n");
+ OS::get_singleton()->print(" -u, --upwards Scan folders upwards for project.godot file.\n");
OS::get_singleton()->print(" --main-pack <file> Path to a pack (.pck) file to load.\n");
OS::get_singleton()->print(" --render-thread <mode> Render thread mode ('unsafe', 'safe', 'separate').\n");
OS::get_singleton()->print(" --remote-fs <address> Remote filesystem (<host/IP>[:<port>] address).\n");
@@ -290,6 +293,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
String video_driver = "";
String audio_driver = "";
String game_path = ".";
+ bool upwards = false;
String debug_mode;
String debug_host;
String main_pack;
@@ -498,6 +502,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
OS::get_singleton()->print("Missing relative or absolute path, aborting.\n");
goto error;
}
+ } else if (I->get() == "-u" || I->get() == "--upwards") { // scan folders upwards
+ upwards = true;
} else if (I->get().ends_with("project.godot")) {
String path;
String file = I->get();
@@ -695,7 +701,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#endif
- if (globals->setup(game_path, main_pack) != OK) {
+ if (globals->setup(game_path, main_pack, upwards) != OK) {
#ifdef TOOLS_ENABLED
editor = false;
@@ -935,11 +941,14 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
OS::get_singleton()->set_window_position(init_custom_pos);
}
- //right moment to create and initialize the audio server
+ // right moment to create and initialize the audio server
audio_server = memnew(AudioServer);
audio_server->init();
+ // also init our arvr_server from here
+ arvr_server = memnew(ARVRServer);
+
OS::get_singleton()->set_use_vsync(use_vsync);
register_core_singletons();
@@ -1341,7 +1350,7 @@ bool Main::start() {
String stretch_mode = GLOBAL_DEF("display/window/stretch/mode", "disabled");
String stretch_aspect = GLOBAL_DEF("display/window/stretch/aspect", "ignore");
Size2i stretch_size = Size2(GLOBAL_DEF("display/window/size/width", 0), GLOBAL_DEF("display/window/size/height", 0));
- int stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1);
+ real_t stretch_shrink = GLOBAL_DEF("display/window/stretch/shrink", 1.0f);
SceneTree::StretchMode sml_sm = SceneTree::STRETCH_MODE_DISABLED;
if (stretch_mode == "2d")
@@ -1771,6 +1780,11 @@ void Main::cleanup() {
memdelete(audio_server);
}
+ if (arvr_server) {
+ // cleanup now before we pull the rug from underneath...
+ memdelete(arvr_server);
+ }
+
unregister_driver_types();
unregister_module_types();
unregister_scene_types();
diff --git a/main/splash.png b/main/splash.png
index 894a7d7aba..34be46557f 100644
--- a/main/splash.png
+++ b/main/splash.png
Binary files differ
diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme
index 3f0df5c437..b6beeb012f 100644
--- a/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme
+++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme
@@ -23,7 +23,7 @@
</BuildActionEntries>
</BuildAction>
<TestAction
- buildConfiguration = "Development"
+ buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
@@ -42,7 +42,7 @@
</AdditionalOptions>
</TestAction>
<LaunchAction
- buildConfiguration = "Development"
+ buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@@ -67,7 +67,7 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
- buildConfiguration = "Development"
+ buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
@@ -84,10 +84,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
- buildConfiguration = "Development">
+ buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
- buildConfiguration = "Development"
+ buildConfiguration = "Debug"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
diff --git a/modules/gdnative/SCsub b/modules/gdnative/SCsub
index 6592d0ae1d..a6ae143947 100644
--- a/modules/gdnative/SCsub
+++ b/modules/gdnative/SCsub
@@ -12,6 +12,9 @@ gdn_env.add_source_files(env.modules_sources, "nativescript/*.cpp")
gdn_env.Append(CPPPATH=['#modules/gdnative/include/'])
+SConscript("nativearvr/SCsub")
+SConscript("pluginscript/SCsub")
+
def _spaced(e):
return e if e[-1] == '*' else e + ' '
@@ -22,7 +25,9 @@ def _build_gdnative_api_struct_header(api):
'#define GODOT_GDNATIVE_API_STRUCT_H',
'',
'#include <gdnative/gdnative.h>',
+ '#include <nativearvr/godot_nativearvr.h>',
'#include <nativescript/godot_nativescript.h>',
+ '#include <pluginscript/godot_pluginscript.h>',
'',
'#define GDNATIVE_API_INIT(options) do { extern const godot_gdnative_api_struct *_gdnative_wrapper_api_struct; _gdnative_wrapper_api_struct = options->api_struct; } while (0)',
'',
@@ -95,6 +100,7 @@ def _build_gdnative_wrapper_code(api):
'',
'#include <gdnative/gdnative.h>',
'#include <nativescript/godot_nativescript.h>',
+ '#include <pluginscript/godot_pluginscript.h>',
'',
'#include <gdnative_api_struct.gen.h>',
'',
diff --git a/modules/gdnative/config.py b/modules/gdnative/config.py
index 9f57b9bb74..df3556249d 100644
--- a/modules/gdnative/config.py
+++ b/modules/gdnative/config.py
@@ -1,8 +1,12 @@
-
def can_build(platform):
return True
-
def configure(env):
env.use_ptrcall = True
+
+def get_doc_classes():
+ return ["GDNative", "GDNativeLibrary", "NativeScript", "ARVRInterfaceGDNative"]
+
+def get_doc_path():
+ return "doc_classes"
diff --git a/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
new file mode 100644
index 0000000000..74f71ff603
--- /dev/null
+++ b/modules/gdnative/doc_classes/ARVRInterfaceGDNative.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="ARVRInterfaceGDNative" inherits="ARVRInterface" category="Core" version="3.0.alpha.custom_build">
+ <brief_description>
+ GDNative wrapper for an ARVR interface
+ </brief_description>
+ <description>
+ This is a wrapper class for GDNative implementations of the ARVR interface. To use a GDNative ARVR interface simply instantiate this object and set your GDNative library containing the ARVR interface implementation.
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ <method name="set_gdnative_library">
+ <return type="void">
+ </return>
+ <argument index="0" name="library" type="GDNativeLibrary">
+ </argument>
+ <description>
+ Bind this GDNative library to our interface. The library must be a GDNative ARVR Interface for this to work.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GDNative.xml b/modules/gdnative/doc_classes/GDNative.xml
index ba813c4564..ba813c4564 100644
--- a/doc/classes/GDNative.xml
+++ b/modules/gdnative/doc_classes/GDNative.xml
diff --git a/doc/classes/GDNativeLibrary.xml b/modules/gdnative/doc_classes/GDNativeLibrary.xml
index c3561856cc..361c89e6b3 100644
--- a/doc/classes/GDNativeLibrary.xml
+++ b/modules/gdnative/doc_classes/GDNativeLibrary.xml
@@ -9,6 +9,12 @@
<demos>
</demos>
<methods>
+ <method name="get_active_library_path" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_library_path" qualifiers="const">
<return type="String">
</return>
diff --git a/doc/classes/NativeScript.xml b/modules/gdnative/doc_classes/NativeScript.xml
index b040cfd966..b040cfd966 100644
--- a/doc/classes/NativeScript.xml
+++ b/modules/gdnative/doc_classes/NativeScript.xml
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 373b98dc8b..3fc04a5498 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -199,10 +199,7 @@ void GDNative::_bind_methods() {
ClassDB::bind_method(D_METHOD("initialize"), &GDNative::initialize);
ClassDB::bind_method(D_METHOD("terminate"), &GDNative::terminate);
- // TODO(karroffel): get_native_(raw_)call_types binding?
-
- // TODO(karroffel): make this a varargs function?
- ClassDB::bind_method(D_METHOD("call_native", "procedure_name", "arguments"), &GDNative::call_native);
+ ClassDB::bind_method(D_METHOD("call_native", "calling_type", "procedure_name", "arguments"), &GDNative::call_native);
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "GDNativeLibrary"), "set_library", "get_library");
}
@@ -239,10 +236,7 @@ bool GDNative::initialize() {
}
void *library_init;
- err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- native_handle,
- init_symbol,
- library_init);
+ err = get_symbol(init_symbol, library_init);
if (err || !library_init) {
OS::get_singleton()->close_dynamic_library(native_handle);
@@ -277,11 +271,8 @@ bool GDNative::terminate() {
}
void *library_terminate;
- Error error = OS::get_singleton()->get_dynamic_library_symbol_handle(
- native_handle,
- terminate_symbol,
- library_terminate);
- if (error) {
+ Error error = get_symbol(terminate_symbol, library_terminate);
+ if (error || !library_terminate) {
OS::get_singleton()->close_dynamic_library(native_handle);
native_handle = NULL;
return true;
@@ -313,10 +304,6 @@ void GDNativeCallRegistry::register_native_call_type(StringName p_call_type, nat
native_calls.insert(p_call_type, p_callback);
}
-void GDNativeCallRegistry::register_native_raw_call_type(StringName p_raw_call_type, native_raw_call_cb p_callback) {
- native_raw_calls.insert(p_raw_call_type, p_callback);
-}
-
Vector<StringName> GDNativeCallRegistry::get_native_call_types() {
Vector<StringName> call_types;
call_types.resize(native_calls.size());
@@ -329,18 +316,6 @@ Vector<StringName> GDNativeCallRegistry::get_native_call_types() {
return call_types;
}
-Vector<StringName> GDNativeCallRegistry::get_native_raw_call_types() {
- Vector<StringName> call_types;
- call_types.resize(native_raw_calls.size());
-
- size_t idx = 0;
- for (Map<StringName, native_raw_call_cb>::Element *E = native_raw_calls.front(); E; E = E->next(), idx++) {
- call_types[idx] = E->key();
- }
-
- return call_types;
-}
-
Variant GDNative::call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments) {
Map<StringName, native_call_cb>::Element *E = GDNativeCallRegistry::singleton->native_calls.find(p_native_call_type);
@@ -349,20 +324,34 @@ Variant GDNative::call_native(StringName p_native_call_type, StringName p_proced
return Variant();
}
- String procedure_name = p_procedure_name;
- godot_variant result = E->get()(native_handle, (godot_string *)&procedure_name, (godot_array *)&p_arguments);
+ void *procedure_handle;
+
+ Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
+ native_handle,
+ p_procedure_name,
+ procedure_handle);
+
+ if (err != OK || procedure_handle == NULL) {
+ return Variant();
+ }
+
+ godot_variant result = E->get()(procedure_handle, (godot_array *)&p_arguments);
return *(Variant *)&result;
}
-void GDNative::call_native_raw(StringName p_raw_call_type, StringName p_procedure_name, void *data, int num_args, void **args, void *r_return) {
+Error GDNative::get_symbol(StringName p_procedure_name, void *&r_handle) {
- Map<StringName, native_raw_call_cb>::Element *E = GDNativeCallRegistry::singleton->native_raw_calls.find(p_raw_call_type);
- if (!E) {
- ERR_PRINT((String("No handler for native raw call type \"" + p_raw_call_type) + "\" found").utf8().get_data());
- return;
+ if (native_handle == NULL) {
+ ERR_PRINT("No valid library handle, can't get symbol from GDNative object");
+ return ERR_CANT_OPEN;
}
- String procedure_name = p_procedure_name;
- E->get()(native_handle, (godot_string *)&procedure_name, data, num_args, args, r_return);
+ Error result = OS::get_singleton()->get_dynamic_library_symbol_handle(
+ native_handle,
+ p_procedure_name,
+ r_handle,
+ true);
+
+ return result;
}
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 7bbad842eb..e44cc55a79 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -100,8 +100,7 @@ public:
_FORCE_INLINE_ void set_singleton_gdnative(bool p_singleton) { singleton_gdnative = p_singleton; }
};
-typedef godot_variant (*native_call_cb)(void *, godot_string *, godot_array *);
-typedef void (*native_raw_call_cb)(void *, godot_string *, void *, int, void **, void *);
+typedef godot_variant (*native_call_cb)(void *, godot_array *);
struct GDNativeCallRegistry {
static GDNativeCallRegistry *singleton;
@@ -111,17 +110,13 @@ struct GDNativeCallRegistry {
}
inline GDNativeCallRegistry()
- : native_calls(),
- native_raw_calls() {}
+ : native_calls() {}
Map<StringName, native_call_cb> native_calls;
- Map<StringName, native_raw_call_cb> native_raw_calls;
void register_native_call_type(StringName p_call_type, native_call_cb p_callback);
- void register_native_raw_call_type(StringName p_raw_call_type, native_raw_call_cb p_callback);
Vector<StringName> get_native_call_types();
- Vector<StringName> get_native_raw_call_types();
};
class GDNative : public Reference {
@@ -149,7 +144,8 @@ public:
bool terminate();
Variant call_native(StringName p_native_call_type, StringName p_procedure_name, Array p_arguments = Array());
- void call_native_raw(StringName p_raw_call_type, StringName p_procedure_name, void *data, int num_args, void **args, void *r_return);
+
+ Error get_symbol(StringName p_procedure_name, void *&r_handle);
};
#endif // GDNATIVE_H
diff --git a/modules/gdnative/gdnative/string.cpp b/modules/gdnative/gdnative/string.cpp
index 9b715ce36a..905c513d9d 100644
--- a/modules/gdnative/gdnative/string.cpp
+++ b/modules/gdnative/gdnative/string.cpp
@@ -29,9 +29,9 @@
/*************************************************************************/
#include "gdnative/string.h"
+#include "core/string_db.h"
+#include "core/ustring.h"
#include "core/variant.h"
-#include "string_db.h"
-#include "ustring.h"
#include <string.h>
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 4d3c024a8f..31b021b751 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -5229,6 +5229,85 @@
"arguments": [
["godot_object *", "p_instance"]
]
+ },
+ {
+ "name": "godot_arvr_register_interface",
+ "return_type": "void",
+ "arguments": [
+ ["const godot_arvr_interface_gdnative *", "p_interface"]
+ ]
+ },
+ {
+ "name": "godot_arvr_get_worldscale",
+ "return_type": "godot_real",
+ "arguments": []
+ },
+ {
+ "name": "godot_arvr_get_reference_frame",
+ "return_type": "godot_transform",
+ "arguments": []
+ },
+ {
+ "name": "godot_arvr_blit",
+ "return_type": "void",
+ "arguments": [
+ ["int", "p_eye"],
+ ["godot_rid *", "p_render_target"],
+ ["godot_rect2 *", "p_screen_rect"]
+ ]
+ },
+ {
+ "name": "godot_arvr_get_texid",
+ "return_type": "godot_int",
+ "arguments": [
+ ["godot_rid *", "p_render_target"]
+ ]
+ },
+ {
+ "name": "godot_arvr_add_controller",
+ "return_type": "godot_int",
+ "arguments": [
+ ["char *", "p_device_name"],
+ ["godot_int", "p_hand"],
+ ["godot_bool", "p_tracks_orientation"],
+ ["godot_bool", "p_tracks_position"]
+ ]
+ },
+ {
+ "name": "godot_arvr_remove_controller",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_transform",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_transform *", "p_transform"],
+ ["godot_bool", "p_tracks_orientation"],
+ ["godot_bool", "p_tracks_position"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_button",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_int", "p_button"],
+ ["godot_bool", "p_is_pressed"]
+ ]
+ },
+ {
+ "name": "godot_arvr_set_controller_axis",
+ "return_type": "void",
+ "arguments": [
+ ["godot_int", "p_controller_id"],
+ ["godot_int", "p_exis"],
+ ["godot_real", "p_value"],
+ ["godot_bool", "p_can_be_negative"]
+ ]
}
]
}
diff --git a/modules/gdnative/include/gdnative/array.h b/modules/gdnative/include/gdnative/array.h
index edab028cba..d0639589b7 100644
--- a/modules/gdnative/include/gdnative/array.h
+++ b/modules/gdnative/include/gdnative/array.h
@@ -46,11 +46,20 @@ typedef struct {
} godot_array;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/pool_arrays.h>
#include <gdnative/variant.h>
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_array_new(godot_array *r_dest);
void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca);
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index 8ff6a6f541..b86b1c17d8 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_basis;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/quat.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_basis_new_with_rows(godot_basis *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis);
void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler);
diff --git a/modules/gdnative/include/gdnative/color.h b/modules/gdnative/include/gdnative/color.h
index 14265466b9..857e86a738 100644
--- a/modules/gdnative/include/gdnative/color.h
+++ b/modules/gdnative/include/gdnative/color.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_color;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_color_new_rgba(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b, const godot_real p_a);
void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
diff --git a/modules/gdnative/include/gdnative/dictionary.h b/modules/gdnative/include/gdnative/dictionary.h
index c85c3f3830..e68d0fdc29 100644
--- a/modules/gdnative/include/gdnative/dictionary.h
+++ b/modules/gdnative/include/gdnative/dictionary.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_dictionary;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
void GDAPI godot_dictionary_destroy(godot_dictionary *p_self);
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 2d8726e5db..25d45db306 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -47,7 +47,7 @@ extern "C" {
#define GDAPI GDCALLINGCONV
#endif
#else
-#define GDCALLINGCONV __attribute__((sysv_abi, visibility("default")))
+#define GDCALLINGCONV __attribute__((sysv_abi))
#define GDAPI GDCALLINGCONV
#endif
@@ -255,7 +255,7 @@ godot_dictionary GDAPI godot_get_global_constants();
////// GDNative procedure types
typedef void (*godot_gdnative_init_fn)(godot_gdnative_init_options *);
typedef void (*godot_gdnative_terminate_fn)(godot_gdnative_terminate_options *);
-typedef godot_variant (*godot_gdnative_procedure_fn)(void *, godot_array *);
+typedef godot_variant (*godot_gdnative_procedure_fn)(godot_array *);
////// System Functions
diff --git a/modules/gdnative/include/gdnative/node_path.h b/modules/gdnative/include/gdnative/node_path.h
index 0cfdbc1127..42446175d8 100644
--- a/modules/gdnative/include/gdnative/node_path.h
+++ b/modules/gdnative/include/gdnative/node_path.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_node_path;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/string.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from);
void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src);
void GDAPI godot_node_path_destroy(godot_node_path *p_self);
diff --git a/modules/gdnative/include/gdnative/plane.h b/modules/gdnative/include/gdnative/plane.h
index 6a8915e08b..dddd172122 100644
--- a/modules/gdnative/include/gdnative/plane.h
+++ b/modules/gdnative/include/gdnative/plane.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_plane;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_plane_new_with_reals(godot_plane *r_dest, const godot_real p_a, const godot_real p_b, const godot_real p_c, const godot_real p_d);
void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3);
void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d);
diff --git a/modules/gdnative/include/gdnative/pool_arrays.h b/modules/gdnative/include/gdnative/pool_arrays.h
index cb1095ee8c..93181f2a6b 100644
--- a/modules/gdnative/include/gdnative/pool_arrays.h
+++ b/modules/gdnative/include/gdnative/pool_arrays.h
@@ -113,6 +113,11 @@ typedef struct {
} godot_pool_color_array;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/color.h>
#include <gdnative/vector2.h>
@@ -120,6 +125,10 @@ typedef struct {
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
// byte
void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest);
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index 4ffb96eb26..acae6e3e90 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_quat;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_quat_new(godot_quat *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z, const godot_real p_w);
void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
diff --git a/modules/gdnative/include/gdnative/rect2.h b/modules/gdnative/include/gdnative/rect2.h
index 9e6cf60342..1c66443d4f 100644
--- a/modules/gdnative/include/gdnative/rect2.h
+++ b/modules/gdnative/include/gdnative/rect2.h
@@ -43,9 +43,18 @@ typedef struct godot_rect2 {
} godot_rect2;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/vector2.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
diff --git a/modules/gdnative/include/gdnative/rect3.h b/modules/gdnative/include/gdnative/rect3.h
index f94b6fea25..f603a9268a 100644
--- a/modules/gdnative/include/gdnative/rect3.h
+++ b/modules/gdnative/include/gdnative/rect3.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_rect3;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/plane.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size);
godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self);
diff --git a/modules/gdnative/include/gdnative/rid.h b/modules/gdnative/include/gdnative/rid.h
index d9b5336fc9..caa1bb967e 100644
--- a/modules/gdnative/include/gdnative/rid.h
+++ b/modules/gdnative/include/gdnative/rid.h
@@ -45,8 +45,17 @@ typedef struct {
} godot_rid;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_rid_new(godot_rid *r_dest);
godot_int GDAPI godot_rid_get_id(const godot_rid *p_self);
diff --git a/modules/gdnative/include/gdnative/string.h b/modules/gdnative/include/gdnative/string.h
index aca23a81d8..f30fdb8dc7 100644
--- a/modules/gdnative/include/gdnative/string.h
+++ b/modules/gdnative/include/gdnative/string.h
@@ -46,9 +46,18 @@ typedef struct {
} godot_string;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_string_new(godot_string *r_dest);
void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size);
diff --git a/modules/gdnative/include/gdnative/string_name.h b/modules/gdnative/include/gdnative/string_name.h
index e217487250..ee9f603d20 100644
--- a/modules/gdnative/include/gdnative/string_name.h
+++ b/modules/gdnative/include/gdnative/string_name.h
@@ -46,8 +46,17 @@ typedef struct {
} godot_string_name;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_string_name_new(godot_string_name *r_dest, const godot_string *p_name);
void GDAPI godot_string_name_new_data(godot_string_name *r_dest, const char *p_name);
diff --git a/modules/gdnative/include/gdnative/transform.h b/modules/gdnative/include/gdnative/transform.h
index 656afae129..8f50b01fb5 100644
--- a/modules/gdnative/include/gdnative/transform.h
+++ b/modules/gdnative/include/gdnative/transform.h
@@ -45,11 +45,20 @@ typedef struct {
} godot_transform;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
#include <gdnative/vector3.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_transform_new_with_axis_origin(godot_transform *r_dest, const godot_vector3 *p_x_axis, const godot_vector3 *p_y_axis, const godot_vector3 *p_z_axis, const godot_vector3 *p_origin);
void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
diff --git a/modules/gdnative/include/gdnative/transform2d.h b/modules/gdnative/include/gdnative/transform2d.h
index a945868b17..c68bd2963f 100644
--- a/modules/gdnative/include/gdnative/transform2d.h
+++ b/modules/gdnative/include/gdnative/transform2d.h
@@ -45,10 +45,19 @@ typedef struct {
} godot_transform2d;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
#include <gdnative/variant.h>
#include <gdnative/vector2.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos);
void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin);
diff --git a/modules/gdnative/include/gdnative/variant.h b/modules/gdnative/include/gdnative/variant.h
index 7b804c1eaf..3d744ef1f2 100644
--- a/modules/gdnative/include/gdnative/variant.h
+++ b/modules/gdnative/include/gdnative/variant.h
@@ -99,6 +99,11 @@ typedef struct godot_variant_call_error {
godot_variant_type expected;
} godot_variant_call_error;
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/array.h>
#include <gdnative/basis.h>
#include <gdnative/color.h>
@@ -119,6 +124,10 @@ typedef struct godot_variant_call_error {
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
void GDAPI godot_variant_new_copy(godot_variant *r_dest, const godot_variant *p_src);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 0af4abae27..07105abaf2 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -45,8 +45,17 @@ typedef struct {
} godot_vector2;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index a27d516ec5..3ed23778ec 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -45,9 +45,18 @@ typedef struct {
} godot_vector3;
#endif
+// reduce extern "C" nesting for VS2013
+#ifdef __cplusplus
+}
+#endif
+
#include <gdnative/basis.h>
#include <gdnative/gdnative.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef enum {
GODOT_VECTOR3_AXIS_X,
GODOT_VECTOR3_AXIS_Y,
diff --git a/modules/gdnative/include/nativearvr/godot_nativearvr.h b/modules/gdnative/include/nativearvr/godot_nativearvr.h
new file mode 100644
index 0000000000..1a8970d396
--- /dev/null
+++ b/modules/gdnative/include/nativearvr/godot_nativearvr.h
@@ -0,0 +1,78 @@
+/*************************************************************************/
+/* godot_nativearvr.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 GODOT_NATIVEARVR_H
+#define GODOT_NATIVEARVR_H
+
+#include <gdnative/gdnative.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ void *(*constructor)(godot_object *);
+ void (*destructor)(void *);
+ godot_string (*get_name)(const void *);
+ godot_int (*get_capabilities)(const void *);
+ godot_bool (*get_anchor_detection_is_enabled)(const void *);
+ void (*set_anchor_detection_is_enabled)(void *, godot_bool);
+ godot_bool (*is_stereo)(const void *);
+ godot_bool (*is_initialized)(const void *);
+ godot_bool (*initialize)(void *);
+ void (*uninitialize)(void *);
+ godot_vector2 (*get_recommended_render_targetsize)(const void *);
+ godot_transform (*get_transform_for_eye)(void *, godot_int, godot_transform *);
+ void (*fill_projection_for_eye)(void *, godot_real *, godot_int, godot_real, godot_real, godot_real);
+ void (*commit_for_eye)(void *, godot_int, godot_rid *, godot_rect2 *);
+ void (*process)(void *);
+} godot_arvr_interface_gdnative;
+
+void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface);
+
+// helper functions to access ARVRServer data
+godot_real GDAPI godot_arvr_get_worldscale();
+godot_transform GDAPI godot_arvr_get_reference_frame();
+
+// helper functions for rendering
+void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect);
+godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target);
+
+// helper functions for updating ARVR controllers
+godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_arvr_remove_controller(godot_int p_controller_id);
+void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position);
+void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed);
+void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !GODOT_NATIVEARVR_H */
diff --git a/modules/gdnative/include/pluginscript/godot_pluginscript.h b/modules/gdnative/include/pluginscript/godot_pluginscript.h
new file mode 100644
index 0000000000..ec109bac83
--- /dev/null
+++ b/modules/gdnative/include/pluginscript/godot_pluginscript.h
@@ -0,0 +1,170 @@
+/*************************************************************************/
+/* godot_nativescript.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 GODOT_PLUGINSCRIPT_H
+#define GODOT_PLUGINSCRIPT_H
+
+#include <gdnative/gdnative.h>
+#include <nativescript/godot_nativescript.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void godot_pluginscript_instance_data;
+typedef void godot_pluginscript_script_data;
+typedef void godot_pluginscript_language_data;
+
+// --- Instance ---
+
+// TODO: use godot_string_name for faster lookup ?
+typedef struct {
+ godot_pluginscript_instance_data *(*init)(godot_pluginscript_script_data *p_data, godot_object *p_owner);
+ void (*finish)(godot_pluginscript_instance_data *p_data);
+
+ godot_bool (*set_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, const godot_variant *p_value);
+ godot_bool (*get_prop)(godot_pluginscript_instance_data *p_data, const godot_string *p_name, godot_variant *r_ret);
+
+ godot_variant (*call_method)(godot_pluginscript_instance_data *p_data,
+ const godot_string_name *p_method, const godot_variant **p_args,
+ int p_argcount, godot_variant_call_error *r_error);
+
+ void (*notification)(godot_pluginscript_instance_data *p_data, int p_notification);
+ // TODO: could this rpc mode stuff be moved to the godot_pluginscript_script_manifest ?
+ godot_method_rpc_mode (*get_rpc_mode)(godot_pluginscript_instance_data *p_data, const godot_string *p_method);
+ godot_method_rpc_mode (*get_rset_mode)(godot_pluginscript_instance_data *p_data, const godot_string *p_variable);
+
+ //this is used by script languages that keep a reference counter of their own
+ //you can make make Ref<> not die when it reaches zero, so deleting the reference
+ //depends entirely from the script.
+ // Note: You can set thoses function pointer to NULL if not needed.
+ void (*refcount_incremented)(godot_pluginscript_instance_data *p_data);
+ bool (*refcount_decremented)(godot_pluginscript_instance_data *p_data); // return true if it can die
+} godot_pluginscript_instance_desc;
+
+// --- Script ---
+
+typedef struct {
+ godot_pluginscript_script_data *data;
+ godot_string_name name;
+ godot_bool is_tool;
+ godot_string_name base;
+
+ // Member lines format: {<string>: <int>}
+ godot_dictionary member_lines;
+ // Method info dictionary format
+ // {
+ // name: <string>
+ // args: [<dict:property>]
+ // default_args: [<variant>]
+ // return: <dict:property>
+ // flags: <int>
+ // rpc_mode: <int:godot_method_rpc_mode>
+ // }
+ godot_array methods;
+ // Same format than for methods
+ godot_array signals;
+ // Property info dictionary format
+ // {
+ // name: <string>
+ // type: <int:godot_variant_type>
+ // hint: <int:godot_property_hint>
+ // hint_string: <string>
+ // usage: <int:godot_property_usage_flags>
+ // default_value: <variant>
+ // rset_mode: <int:godot_method_rpc_mode>
+ // }
+ godot_array properties;
+} godot_pluginscript_script_manifest;
+
+typedef struct {
+ godot_pluginscript_script_manifest (*init)(godot_pluginscript_language_data *p_data, const godot_string *p_path, const godot_string *p_source, godot_error *r_error);
+ void (*finish)(godot_pluginscript_script_data *p_data);
+ godot_pluginscript_instance_desc instance_desc;
+} godot_pluginscript_script_desc;
+
+// --- Language ---
+
+typedef struct {
+ godot_string_name signature;
+ godot_int call_count;
+ godot_int total_time; // In microseconds
+ godot_int self_time; // In microseconds
+} godot_pluginscript_profiling_data;
+
+typedef struct {
+ const char *name;
+ const char *type;
+ const char *extension;
+ const char **recognized_extensions; // NULL terminated array
+ godot_pluginscript_language_data *(*init)();
+ void (*finish)(godot_pluginscript_language_data *p_data);
+ const char **reserved_words; // NULL terminated array
+ const char **comment_delimiters; // NULL terminated array
+ const char **string_delimiters; // NULL terminated array
+ godot_bool has_named_classes;
+
+ godot_string (*get_template_source_code)(godot_pluginscript_language_data *p_data, const godot_string *p_class_name, const godot_string *p_base_class_name);
+ godot_bool (*validate)(godot_pluginscript_language_data *p_data, const godot_string *p_script, int *r_line_error, int *r_col_error, godot_string *r_test_error, const godot_string *p_path, godot_pool_string_array *r_functions);
+ int (*find_function)(godot_pluginscript_language_data *p_data, const godot_string *p_function, const godot_string *p_code); // Can be NULL
+ godot_string (*make_function)(godot_pluginscript_language_data *p_data, const godot_string *p_class, const godot_string *p_name, const godot_pool_string_array *p_args);
+ godot_error (*complete_code)(godot_pluginscript_language_data *p_data, const godot_string *p_code, const godot_string *p_base_path, godot_object *p_owner, godot_array *r_options, godot_bool *r_force, godot_string *r_call_hint);
+ void (*auto_indent_code)(godot_pluginscript_language_data *p_data, godot_string *p_code, int p_from_line, int p_to_line);
+
+ void (*add_global_constant)(godot_pluginscript_language_data *p_data, const godot_string *p_variable, const godot_variant *p_value);
+ godot_string (*debug_get_error)(godot_pluginscript_language_data *p_data);
+ int (*debug_get_stack_level_count)(godot_pluginscript_language_data *p_data);
+ int (*debug_get_stack_level_line)(godot_pluginscript_language_data *p_data, int p_level);
+ godot_string (*debug_get_stack_level_function)(godot_pluginscript_language_data *p_data, int p_level);
+ godot_string (*debug_get_stack_level_source)(godot_pluginscript_language_data *p_data, int p_level);
+ void (*debug_get_stack_level_locals)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_stack_level_members)(godot_pluginscript_language_data *p_data, int p_level, godot_pool_string_array *p_members, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ void (*debug_get_globals)(godot_pluginscript_language_data *p_data, godot_pool_string_array *p_locals, godot_array *p_values, int p_max_subitems, int p_max_depth);
+ godot_string (*debug_parse_stack_level_expression)(godot_pluginscript_language_data *p_data, int p_level, const godot_string *p_expression, int p_max_subitems, int p_max_depth);
+
+ // TODO: could this stuff be moved to the godot_pluginscript_language_desc ?
+ void (*get_public_functions)(godot_pluginscript_language_data *p_data, godot_array *r_functions);
+ void (*get_public_constants)(godot_pluginscript_language_data *p_data, godot_dictionary *r_constants);
+
+ void (*profiling_start)(godot_pluginscript_language_data *p_data);
+ void (*profiling_stop)(godot_pluginscript_language_data *p_data);
+ int (*profiling_get_accumulated_data)(godot_pluginscript_language_data *p_data, godot_pluginscript_profiling_data *r_info, int p_info_max);
+ int (*profiling_get_frame_data)(godot_pluginscript_language_data *p_data, godot_pluginscript_profiling_data *r_info, int p_info_max);
+ void (*profiling_frame)(godot_pluginscript_language_data *p_data);
+
+ godot_pluginscript_script_desc script_desc;
+} godot_pluginscript_language_desc;
+
+void GDAPI godot_pluginscript_register_language(const godot_pluginscript_language_desc *language_desc);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // GODOT_PLUGINSCRIPT_H
diff --git a/modules/gdnative/nativearvr/SCsub b/modules/gdnative/nativearvr/SCsub
new file mode 100644
index 0000000000..ecc5996108
--- /dev/null
+++ b/modules/gdnative/nativearvr/SCsub
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import os
+import methods
+
+Import('env')
+Import('env_modules')
+
+env_arvr_gdnative = env_modules.Clone()
+
+env_arvr_gdnative.Append(CPPPATH=['#modules/gdnative/include/'])
+env_arvr_gdnative.add_source_files(env.modules_sources, '*.cpp')
+
diff --git a/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp b/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp
new file mode 100644
index 0000000000..ff8bda162f
--- /dev/null
+++ b/modules/gdnative/nativearvr/arvr_interface_gdnative.cpp
@@ -0,0 +1,386 @@
+/*************************************************************************/
+/* arvr_interface_gdnative.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "arvr_interface_gdnative.h"
+#include "main/input_default.h"
+#include "servers/arvr/arvr_positional_tracker.h"
+#include "servers/visual/visual_server_global.h"
+
+ARVRInterfaceGDNative::ARVRInterfaceGDNative() {
+ // testing
+ printf("Construct gdnative interface\n");
+
+ // we won't have our data pointer until our library gets set
+ data = NULL;
+
+ interface = NULL;
+}
+
+ARVRInterfaceGDNative::~ARVRInterfaceGDNative() {
+ printf("Destruct gdnative interface\n");
+
+ if (is_initialized()) {
+ uninitialize();
+ };
+
+ // cleanup after ourselves
+ cleanup();
+}
+
+void ARVRInterfaceGDNative::cleanup() {
+ if (interface != NULL) {
+ interface->destructor(data);
+ data = NULL;
+ interface = NULL;
+ }
+}
+
+void ARVRInterfaceGDNative::set_interface(const godot_arvr_interface_gdnative *p_interface) {
+ // this should only be called once, just being paranoid..
+ if (interface) {
+ cleanup();
+ }
+
+ // bind to our interface
+ interface = p_interface;
+
+ // Now we do our constructing...
+ data = interface->constructor((godot_object *)this);
+}
+
+StringName ARVRInterfaceGDNative::get_name() const {
+
+ ERR_FAIL_COND_V(interface == NULL, StringName());
+
+ godot_string result = interface->get_name(data);
+
+ StringName name = *(String *)&result;
+
+ godot_string_destroy(&result);
+
+ return name;
+}
+
+int ARVRInterfaceGDNative::get_capabilities() const {
+ int capabilities;
+
+ ERR_FAIL_COND_V(interface == NULL, 0); // 0 = None
+
+ capabilities = interface->get_capabilities(data);
+
+ return capabilities;
+}
+
+bool ARVRInterfaceGDNative::get_anchor_detection_is_enabled() const {
+ bool enabled;
+
+ ERR_FAIL_COND_V(interface == NULL, false);
+
+ enabled = interface->get_anchor_detection_is_enabled(data);
+
+ return enabled;
+}
+
+void ARVRInterfaceGDNative::set_anchor_detection_is_enabled(bool p_enable) {
+
+ ERR_FAIL_COND(interface == NULL);
+
+ interface->set_anchor_detection_is_enabled(data, p_enable);
+}
+
+bool ARVRInterfaceGDNative::is_stereo() {
+ bool stereo;
+
+ ERR_FAIL_COND_V(interface == NULL, false);
+
+ stereo = interface->is_stereo(data);
+
+ return stereo;
+}
+
+bool ARVRInterfaceGDNative::is_initialized() {
+ bool initialized;
+
+ ERR_FAIL_COND_V(interface == NULL, false);
+
+ initialized = interface->is_initialized(data);
+
+ return initialized;
+}
+
+bool ARVRInterfaceGDNative::initialize() {
+ bool initialized;
+
+ ERR_FAIL_COND_V(interface == NULL, false);
+
+ initialized = interface->initialize(data);
+
+ if (initialized) {
+ // if we successfully initialize our interface and we don't have a primary interface yet, this becomes our primary interface
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ if ((arvr_server != NULL) && (arvr_server->get_primary_interface() == NULL)) {
+ arvr_server->set_primary_interface(this);
+ };
+ };
+
+ return initialized;
+}
+
+void ARVRInterfaceGDNative::uninitialize() {
+ ERR_FAIL_COND(interface == NULL);
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ if (arvr_server != NULL) {
+ // Whatever happens, make sure this is no longer our primary interface
+ arvr_server->clear_primary_interface_if(this);
+ }
+
+ interface->uninitialize(data);
+}
+
+Size2 ARVRInterfaceGDNative::get_recommended_render_targetsize() {
+
+ ERR_FAIL_COND_V(interface == NULL, Size2());
+
+ godot_vector2 result = interface->get_recommended_render_targetsize(data);
+ Vector2 *vec = (Vector2 *)&result;
+
+ return *vec;
+}
+
+Transform ARVRInterfaceGDNative::get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform) {
+ Transform *ret;
+
+ ERR_FAIL_COND_V(interface == NULL, Transform());
+
+ godot_transform t = interface->get_transform_for_eye(data, (int)p_eye, (godot_transform *)&p_cam_transform);
+
+ ret = (Transform *)&t;
+
+ return *ret;
+}
+
+CameraMatrix ARVRInterfaceGDNative::get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
+ CameraMatrix cm;
+
+ ERR_FAIL_COND_V(interface == NULL, CameraMatrix());
+
+ interface->fill_projection_for_eye(data, (godot_real *)cm.matrix, (godot_int)p_eye, p_aspect, p_z_near, p_z_far);
+
+ return cm;
+}
+
+void ARVRInterfaceGDNative::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
+
+ ERR_FAIL_COND(interface == NULL);
+
+ interface->commit_for_eye(data, (godot_int)p_eye, (godot_rid *)&p_render_target, (godot_rect2 *)&p_screen_rect);
+}
+
+void ARVRInterfaceGDNative::process() {
+ ERR_FAIL_COND(interface == NULL);
+
+ interface->process(data);
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+// some helper callbacks
+
+extern "C" {
+
+void GDAPI godot_arvr_register_interface(const godot_arvr_interface_gdnative *p_interface) {
+ Ref<ARVRInterfaceGDNative> new_interface;
+ new_interface.instance();
+ new_interface->set_interface((godot_arvr_interface_gdnative * const)p_interface);
+ ARVRServer::get_singleton()->add_interface(new_interface);
+}
+
+godot_real GDAPI godot_arvr_get_worldscale() {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, 1.0);
+
+ return arvr_server->get_world_scale();
+}
+
+godot_transform GDAPI godot_arvr_get_reference_frame() {
+ godot_transform reference_frame;
+ Transform *reference_frame_ptr = (Transform *)&reference_frame;
+
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ if (arvr_server != NULL) {
+ *reference_frame_ptr = arvr_server->get_reference_frame();
+ } else {
+ godot_transform_new_identity(&reference_frame);
+ }
+
+ return reference_frame;
+}
+
+void GDAPI godot_arvr_blit(godot_int p_eye, godot_rid *p_render_target, godot_rect2 *p_rect) {
+ // blits out our texture as is, handy for preview display of one of the eyes that is already rendered with lens distortion on an external HMD
+ ARVRInterface::Eyes eye = (ARVRInterface::Eyes)p_eye;
+ RID *render_target = (RID *)p_render_target;
+ Rect2 screen_rect = *(Rect2 *)p_rect;
+
+ if (eye == ARVRInterface::EYE_LEFT) {
+ screen_rect.size.x /= 2.0;
+ } else if (p_eye == ARVRInterface::EYE_RIGHT) {
+ screen_rect.size.x /= 2.0;
+ screen_rect.position.x += screen_rect.size.x;
+ }
+
+ VSG::rasterizer->set_current_render_target(RID());
+ VSG::rasterizer->blit_render_target_to_screen(*render_target, screen_rect, 0);
+}
+
+godot_int GDAPI godot_arvr_get_texid(godot_rid *p_render_target) {
+ // In order to send off our textures to display on our hardware we need the opengl texture ID instead of the render target RID
+ // This is a handy function to expose that.
+ RID *render_target = (RID *)p_render_target;
+
+ RID eye_texture = VSG::storage->render_target_get_texture(*render_target);
+ uint32_t texid = VS::get_singleton()->texture_get_texid(eye_texture);
+
+ return texid;
+}
+
+godot_int GDAPI godot_arvr_add_controller(char *p_device_name, godot_int p_hand, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL_V(arvr_server, 0);
+
+ InputDefault *input = (InputDefault *)Input::get_singleton();
+ ERR_FAIL_NULL_V(input, 0);
+
+ ARVRPositionalTracker *new_tracker = memnew(ARVRPositionalTracker);
+ new_tracker->set_name(p_device_name);
+ new_tracker->set_type(ARVRServer::TRACKER_CONTROLLER);
+ if (p_hand == 1) {
+ new_tracker->set_hand(ARVRPositionalTracker::TRACKER_LEFT_HAND);
+ } else if (p_hand == 2) {
+ new_tracker->set_hand(ARVRPositionalTracker::TRACKER_RIGHT_HAND);
+ }
+
+ // also register as joystick...
+ int joyid = input->get_unused_joy_id();
+ if (joyid != -1) {
+ new_tracker->set_joy_id(joyid);
+ input->joy_connection_changed(joyid, true, p_device_name, "");
+ }
+
+ if (p_tracks_orientation) {
+ Basis orientation;
+ new_tracker->set_orientation(orientation);
+ }
+ if (p_tracks_position) {
+ Vector3 position;
+ new_tracker->set_position(position);
+ }
+
+ // add our tracker to our server and remember its pointer
+ arvr_server->add_tracker(new_tracker);
+
+ // note, this ID is only unique within controllers!
+ return new_tracker->get_tracker_id();
+}
+
+void GDAPI godot_arvr_remove_controller(godot_int p_controller_id) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ InputDefault *input = (InputDefault *)Input::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ ARVRPositionalTracker *remove_tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (remove_tracker != NULL) {
+ // unset our joystick if applicable
+ int joyid = remove_tracker->get_joy_id();
+ if (joyid != -1) {
+ input->joy_connection_changed(joyid, false, "", "");
+ remove_tracker->set_joy_id(-1);
+ }
+
+ // remove our tracker from our server
+ arvr_server->remove_tracker(remove_tracker);
+ memdelete(remove_tracker);
+ }
+}
+
+void GDAPI godot_arvr_set_controller_transform(godot_int p_controller_id, godot_transform *p_transform, godot_bool p_tracks_orientation, godot_bool p_tracks_position) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != NULL) {
+ Transform *transform = (Transform *)p_transform;
+ if (p_tracks_orientation) {
+ tracker->set_orientation(transform->basis);
+ }
+ if (p_tracks_position) {
+ tracker->set_position(transform->origin);
+ }
+ }
+}
+
+void GDAPI godot_arvr_set_controller_button(godot_int p_controller_id, godot_int p_button, godot_bool p_is_pressed) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ InputDefault *input = (InputDefault *)Input::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != NULL) {
+ int joyid = tracker->get_joy_id();
+ if (joyid != -1) {
+ input->joy_button(joyid, p_button, p_is_pressed);
+ }
+ }
+}
+
+void GDAPI godot_arvr_set_controller_axis(godot_int p_controller_id, godot_int p_axis, godot_real p_value, godot_bool p_can_be_negative) {
+ ARVRServer *arvr_server = ARVRServer::get_singleton();
+ ERR_FAIL_NULL(arvr_server);
+
+ InputDefault *input = (InputDefault *)Input::get_singleton();
+ ERR_FAIL_NULL(input);
+
+ ARVRPositionalTracker *tracker = arvr_server->find_by_type_and_id(ARVRServer::TRACKER_CONTROLLER, p_controller_id);
+ if (tracker != NULL) {
+ int joyid = tracker->get_joy_id();
+ if (joyid != -1) {
+ InputDefault::JoyAxis jx;
+ jx.min = p_can_be_negative ? -1 : 0;
+ jx.value = p_value;
+ input->joy_axis(joyid, p_axis, jx);
+ }
+ }
+}
+}
diff --git a/modules/gdnative/nativearvr/arvr_interface_gdnative.h b/modules/gdnative/nativearvr/arvr_interface_gdnative.h
new file mode 100644
index 0000000000..e45b51e070
--- /dev/null
+++ b/modules/gdnative/nativearvr/arvr_interface_gdnative.h
@@ -0,0 +1,86 @@
+/*************************************************************************/
+/* arvr_interface_gdnative.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 ARVR_INTERFACE_GDNATIVE_H
+#define ARVR_INTERFACE_GDNATIVE_H
+
+#include "modules/gdnative/gdnative.h"
+#include "servers/arvr/arvr_interface.h"
+
+/**
+ @authors Hinsbart & Karroffel & Mux213
+
+ This subclass of our AR/VR interface forms a bridge to GDNative.
+*/
+
+class ARVRInterfaceGDNative : public ARVRInterface {
+ GDCLASS(ARVRInterfaceGDNative, ARVRInterface)
+
+ void cleanup();
+
+protected:
+ const godot_arvr_interface_gdnative *interface;
+ void *data;
+
+public:
+ /** general interface information **/
+ ARVRInterfaceGDNative();
+ ~ARVRInterfaceGDNative();
+
+ void set_interface(const godot_arvr_interface_gdnative *p_interface);
+
+ virtual StringName get_name() const;
+ virtual int get_capabilities() const;
+
+ virtual bool is_initialized();
+ virtual bool initialize();
+ virtual void uninitialize();
+
+ /** specific to AR **/
+ virtual bool get_anchor_detection_is_enabled() const;
+ virtual void set_anchor_detection_is_enabled(bool p_enable);
+
+ /** rendering and internal **/
+ virtual Size2 get_recommended_render_targetsize();
+ virtual bool is_stereo();
+ virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
+
+ // we expose a PoolVector<float> version of this function to GDNative
+ PoolVector<float> _get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+
+ // and a CameraMatrix version to ARVRServer
+ virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
+
+ virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
+
+ virtual void process();
+};
+
+#endif // ARVR_INTERFACE_GDNATIVE_H
diff --git a/modules/gdnative/nativearvr/config.py b/modules/gdnative/nativearvr/config.py
new file mode 100644
index 0000000000..4d1bdfe4d1
--- /dev/null
+++ b/modules/gdnative/nativearvr/config.py
@@ -0,0 +1,5 @@
+def can_build(platform):
+ return True
+
+def configure(env):
+ pass
diff --git a/modules/gdnative/nativearvr/register_types.cpp b/modules/gdnative/nativearvr/register_types.cpp
new file mode 100644
index 0000000000..c7d7847a21
--- /dev/null
+++ b/modules/gdnative/nativearvr/register_types.cpp
@@ -0,0 +1,39 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "register_types.h"
+#include "arvr_interface_gdnative.h"
+
+void register_nativearvr_types() {
+ ClassDB::register_class<ARVRInterfaceGDNative>();
+}
+
+void unregister_nativearvr_types() {
+}
diff --git a/modules/gdnative/nativearvr/register_types.h b/modules/gdnative/nativearvr/register_types.h
new file mode 100644
index 0000000000..5e7557c7e9
--- /dev/null
+++ b/modules/gdnative/nativearvr/register_types.h
@@ -0,0 +1,32 @@
+/*************************************************************************/
+/* register_types.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+void register_nativearvr_types();
+void unregister_nativearvr_types();
diff --git a/modules/gdnative/nativescript/SCsub b/modules/gdnative/nativescript/SCsub
index 178afec64a..ee3b9c351d 100644
--- a/modules/gdnative/nativescript/SCsub
+++ b/modules/gdnative/nativescript/SCsub
@@ -4,7 +4,6 @@ Import('env')
mod_env = env.Clone()
mod_env.add_source_files(env.modules_sources, "*.cpp")
-mod_env.Append(CPPPATH='#modules/gdnative')
mod_env.Append(CPPFLAGS=['-DGDAPI_BUILT_IN'])
if "platform" in env and env["platform"] in ["x11", "iphone"]:
diff --git a/modules/gdnative/nativescript/api_generator.cpp b/modules/gdnative/nativescript/api_generator.cpp
index 9a956ff594..63fb71feb6 100644
--- a/modules/gdnative/nativescript/api_generator.cpp
+++ b/modules/gdnative/nativescript/api_generator.cpp
@@ -31,7 +31,7 @@
#ifdef TOOLS_ENABLED
-#include "class_db.h"
+#include "core/class_db.h"
#include "core/global_constants.h"
#include "core/pair.h"
#include "core/project_settings.h"
diff --git a/modules/gdnative/nativescript/api_generator.h b/modules/gdnative/nativescript/api_generator.h
index 56c2d786e6..a8e2eaf0bf 100644
--- a/modules/gdnative/nativescript/api_generator.h
+++ b/modules/gdnative/nativescript/api_generator.h
@@ -30,8 +30,8 @@
#ifndef API_GENERATOR_H
#define API_GENERATOR_H
+#include "core/typedefs.h"
#include "core/ustring.h"
-#include "typedefs.h"
Error generate_c_api(const String &p_path);
diff --git a/modules/gdnative/nativescript/nativescript.cpp b/modules/gdnative/nativescript/nativescript.cpp
index b9bd65af53..aa1fdc32da 100644
--- a/modules/gdnative/nativescript/nativescript.cpp
+++ b/modules/gdnative/nativescript/nativescript.cpp
@@ -31,11 +31,11 @@
#include "gdnative/gdnative.h"
-#include "global_constants.h"
+#include "core/global_constants.h"
+#include "core/project_settings.h"
#include "io/file_access_encrypted.h"
#include "os/file_access.h"
#include "os/os.h"
-#include "project_settings.h"
#include "scene/main/scene_tree.h"
#include "scene/resources/scene_format_text.h"
@@ -137,7 +137,6 @@ bool NativeScript::can_instance() const {
#endif
}
-// TODO(karroffel): implement this
Ref<Script> NativeScript::get_base_script() const {
NativeScriptDesc *script_data = get_script_desc();
@@ -1010,17 +1009,15 @@ void NativeScriptLanguage::init_library(const Ref<GDNativeLibrary> &lib) {
if (!library_script_users.has(lib_path))
library_script_users.insert(lib_path, Set<NativeScript *>());
- void *args[1] = {
- (void *)&lib_path
- };
+ void *proc_ptr;
+
+ Error err = gdn->get_symbol(_init_call_name, proc_ptr);
- // here the library registers all the classes and stuff.
- gdn->call_native_raw(_init_call_type,
- _init_call_name,
- NULL,
- 1,
- args,
- NULL);
+ if (err != OK) {
+ ERR_PRINT(String("No " + _init_call_name + " in \"" + lib_path + "\" found").utf8().get_data());
+ } else {
+ ((void (*)(godot_string *))proc_ptr)((godot_string *)&lib_path);
+ }
} else {
// already initialized. Nice.
}
@@ -1053,13 +1050,13 @@ void NativeScriptLanguage::call_libraries_cb(const StringName &name) {
// library_gdnatives is modified only from the main thread, so it's safe not to use mutex here
for (Map<String, Ref<GDNative> >::Element *L = library_gdnatives.front(); L; L = L->next()) {
if (L->get()->is_initialized()) {
- L->get()->call_native_raw(
- _noarg_call_type,
- name,
- NULL,
- 0,
- NULL,
- NULL);
+
+ void *proc_ptr;
+ Error err = L->get()->get_symbol(name, proc_ptr);
+
+ if (!err) {
+ ((void (*)())proc_ptr)();
+ }
}
}
}
@@ -1142,12 +1139,14 @@ void NativeReloadNode::_notification(int p_what) {
};
// here the library registers all the classes and stuff.
- L->get()->call_native_raw(NSL->_init_call_type,
- NSL->_init_call_name,
- NULL,
- 1,
- args,
- NULL);
+
+ void *proc_ptr;
+ Error err = L->get()->get_symbol("godot_nativescript_init", proc_ptr);
+ if (err != OK) {
+ ERR_PRINT(String("No godot_nativescript_init in \"" + L->key() + "\" found").utf8().get_data());
+ } else {
+ ((void (*)(void *))proc_ptr)((void *)&L->key());
+ }
for (Map<String, Set<NativeScript *> >::Element *U = NSL->library_script_users.front(); U; U = U->next()) {
for (Set<NativeScript *>::Element *S = U->get().front(); S; S = S->next()) {
diff --git a/modules/gdnative/nativescript/nativescript.h b/modules/gdnative/nativescript/nativescript.h
index bc7e850d3e..b5db641179 100644
--- a/modules/gdnative/nativescript/nativescript.h
+++ b/modules/gdnative/nativescript/nativescript.h
@@ -30,14 +30,14 @@
#ifndef NATIVE_SCRIPT_H
#define NATIVE_SCRIPT_H
+#include "core/resource.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "ordered_hash_map.h"
#include "os/thread_safe.h"
-#include "resource.h"
#include "scene/main/node.h"
-#include "script_language.h"
-#include "self_list.h"
#include "modules/gdnative/gdnative.h"
#include <nativescript/godot_nativescript.h>
diff --git a/modules/gdnative/nativescript/register_types.cpp b/modules/gdnative/nativescript/register_types.cpp
index b846710ab8..d734bba810 100644
--- a/modules/gdnative/nativescript/register_types.cpp
+++ b/modules/gdnative/nativescript/register_types.cpp
@@ -38,53 +38,6 @@
NativeScriptLanguage *native_script_language;
-typedef void (*native_script_init_fn)(void *);
-
-void init_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call nativescript init procedure");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true); // we print our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_proc_name) + "\" does not exists and can't be called").utf8().get_data());
- return;
- }
-
- native_script_init_fn fn = (native_script_init_fn)library_proc;
-
- fn(args[0]);
-}
-
-typedef void (*native_script_empty_callback)();
-
-void noarg_call_cb(void *p_handle, godot_string *p_proc_name, void *p_data, int p_num_args, void **args, void *r_ret) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call nativescript callback");
- return;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- library_proc,
- true);
- if (err != OK) {
- // it's fine if thread callbacks are not present in the library.
- return;
- }
-
- native_script_empty_callback fn = (native_script_empty_callback)library_proc;
- fn();
-}
-
ResourceFormatLoaderNativeScript *resource_loader_gdns = NULL;
ResourceFormatSaverNativeScript *resource_saver_gdns = NULL;
@@ -95,9 +48,6 @@ void register_nativescript_types() {
ScriptServer::register_language(native_script_language);
- GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_init_call_type, init_call_cb);
- GDNativeCallRegistry::singleton->register_native_raw_call_type(native_script_language->_noarg_call_type, noarg_call_cb);
-
resource_saver_gdns = memnew(ResourceFormatSaverNativeScript);
ResourceSaver::add_resource_format_saver(resource_saver_gdns);
diff --git a/modules/gdnative/pluginscript/SCsub b/modules/gdnative/pluginscript/SCsub
new file mode 100644
index 0000000000..2031a4236b
--- /dev/null
+++ b/modules/gdnative/pluginscript/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_pluginscript = env_modules.Clone()
+
+env_pluginscript.Append(CPPPATH=['#modules/gdnative/include/'])
+env_pluginscript.add_source_files(env.modules_sources, '*.cpp')
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.cpp b/modules/gdnative/pluginscript/pluginscript_instance.cpp
new file mode 100644
index 0000000000..8f01350826
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_instance.cpp
@@ -0,0 +1,181 @@
+/*************************************************************************/
+/* pluginscript_instance.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/os.h"
+#include "core/variant.h"
+// PluginScript imports
+#include "pluginscript_instance.h"
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+
+bool PluginScriptInstance::set(const StringName &p_name, const Variant &p_value) {
+ String name = String(p_name);
+ return _desc->set_prop(_data, (const godot_string *)&name, (const godot_variant *)&p_value);
+}
+
+bool PluginScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
+ String name = String(p_name);
+ return _desc->get_prop(_data, (const godot_string *)&name, (godot_variant *)&r_ret);
+}
+
+Ref<Script> PluginScriptInstance::get_script() const {
+ return _script;
+}
+
+ScriptLanguage *PluginScriptInstance::get_language() {
+ return _script->get_language();
+}
+
+Variant::Type PluginScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
+ if (!_script->has_property(p_name)) {
+ if (r_is_valid) {
+ *r_is_valid = false;
+ }
+ return Variant::NIL;
+ }
+ if (r_is_valid) {
+ *r_is_valid = true;
+ }
+ return _script->get_property_info(p_name).type;
+}
+
+void PluginScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
+ _script->get_script_property_list(p_properties);
+}
+
+void PluginScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
+ _script->get_script_method_list(p_list);
+}
+
+bool PluginScriptInstance::has_method(const StringName &p_method) const {
+ return _script->has_method(p_method);
+}
+
+Variant PluginScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+ // TODO: optimize when calling a Godot method from Godot to avoid param conversion ?
+ godot_variant ret = _desc->call_method(
+ _data, (godot_string_name *)&p_method, (const godot_variant **)p_args,
+ p_argcount, (godot_variant_call_error *)&r_error);
+ Variant *var_ret = (Variant *)&ret;
+ return *var_ret;
+}
+
+#if 0 // TODO: Don't rely on default implementations provided by ScriptInstance ?
+void PluginScriptInstance::call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+#if 0
+ PluginScript *sptr=script.ptr();
+ Variant::CallError ce;
+
+ while(sptr) {
+ Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method);
+ if (E) {
+ E->get()->call(this,p_args,p_argcount,ce);
+ }
+ sptr = sptr->_base;
+ }
+#endif
+
+}
+
+#if 0
+void PluginScriptInstance::_ml_call_reversed(PluginScript *sptr,const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+ if (sptr->_base)
+ _ml_call_reversed(sptr->_base,p_method,p_args,p_argcount);
+
+ Variant::CallError ce;
+
+ Map<StringName,GDFunction*>::Element *E = sptr->member_functions.find(p_method);
+ if (E) {
+ E->get()->call(this,p_args,p_argcount,ce);
+ }
+
+}
+#endif
+
+
+void PluginScriptInstance::call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount) {
+
+#if 0
+ if (script.ptr()) {
+ _ml_call_reversed(script.ptr(),p_method,p_args,p_argcount);
+ }
+#endif
+}
+#endif // Multilevel stuff
+
+void PluginScriptInstance::notification(int p_notification) {
+ _desc->notification(_data, p_notification);
+}
+
+ScriptInstance::RPCMode PluginScriptInstance::get_rpc_mode(const StringName &p_method) const {
+ return _script->get_rpc_mode(p_method);
+}
+
+ScriptInstance::RPCMode PluginScriptInstance::get_rset_mode(const StringName &p_variable) const {
+ return _script->get_rset_mode(p_variable);
+}
+
+void PluginScriptInstance::refcount_incremented() {
+ if (_desc->refcount_decremented) {
+ _desc->refcount_incremented(_data);
+ }
+}
+
+bool PluginScriptInstance::refcount_decremented() {
+ // Return true if it can die
+ if (_desc->refcount_decremented) {
+ return _desc->refcount_decremented(_data);
+ }
+ return true;
+}
+
+PluginScriptInstance::PluginScriptInstance() {
+}
+
+bool PluginScriptInstance::init(PluginScript *p_script, Object *p_owner) {
+ _owner = p_owner;
+ _owner_variant = Variant(p_owner);
+ _script = Ref<PluginScript>(p_script);
+ _desc = &p_script->_desc->instance_desc;
+ _data = _desc->init(p_script->_data, (godot_object *)p_owner);
+ ERR_FAIL_COND_V(_data == NULL, false);
+ p_owner->set_script_instance(this);
+ return true;
+}
+
+PluginScriptInstance::~PluginScriptInstance() {
+ _desc->finish(_data);
+ _script->_language->lock();
+ _script->_instances.erase(_owner);
+ _script->_language->unlock();
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_instance.h b/modules/gdnative/pluginscript/pluginscript_instance.h
new file mode 100644
index 0000000000..68696b4417
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_instance.h
@@ -0,0 +1,90 @@
+/*************************************************************************/
+/* pluginscript_instance.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_INSTANCE_H
+#define PLUGINSCRIPT_INSTANCE_H
+
+// Godot imports
+#include "core/script_language.h"
+// PluginScript imports
+#include <pluginscript/godot_pluginscript.h>
+
+class PluginScript;
+
+class PluginScriptInstance : public ScriptInstance {
+ friend class PluginScript;
+
+private:
+ Ref<PluginScript> _script;
+ Object *_owner;
+ Variant _owner_variant;
+ godot_pluginscript_instance_data *_data;
+ const godot_pluginscript_instance_desc *_desc;
+
+public:
+ _FORCE_INLINE_ Object *get_owner() { return _owner; }
+
+ virtual bool set(const StringName &p_name, const Variant &p_value);
+ virtual bool get(const StringName &p_name, Variant &r_ret) const;
+ virtual void get_property_list(List<PropertyInfo> *p_properties) const;
+ virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = NULL) const;
+
+ virtual void get_method_list(List<MethodInfo> *p_list) const;
+ virtual bool has_method(const StringName &p_method) const;
+
+ virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+#if 0
+ // Rely on default implementations provided by ScriptInstance for the moment.
+ // Note that multilevel call could be removed in 3.0 release, so stay tunned
+ // (see https://godotengine.org/qa/9244/can-override-the-_ready-and-_process-functions-child-classes)
+ virtual void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount);
+ virtual void call_multilevel_reversed(const StringName& p_method,const Variant** p_args,int p_argcount);
+#endif
+
+ virtual void notification(int p_notification);
+
+ virtual Ref<Script> get_script() const;
+
+ virtual ScriptLanguage *get_language();
+
+ void set_path(const String &p_path);
+
+ virtual RPCMode get_rpc_mode(const StringName &p_method) const;
+ virtual RPCMode get_rset_mode(const StringName &p_variable) const;
+
+ virtual void refcount_incremented();
+ virtual bool refcount_decremented();
+
+ PluginScriptInstance();
+ bool init(PluginScript *p_script, Object *p_owner);
+ virtual ~PluginScriptInstance();
+};
+
+#endif // PLUGINSCRIPT_INSTANCE_H
diff --git a/modules/gdnative/pluginscript/pluginscript_language.cpp b/modules/gdnative/pluginscript/pluginscript_language.cpp
new file mode 100644
index 0000000000..d4b86ae5b4
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_language.cpp
@@ -0,0 +1,431 @@
+/*************************************************************************/
+/* pluginscript_language.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/file_access.h"
+#include "core/os/os.h"
+#include "core/project_settings.h"
+// PluginScript imports
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+
+String PluginScriptLanguage::get_name() const {
+ return String(_desc.name);
+}
+
+void PluginScriptLanguage::init() {
+ _data = _desc.init();
+}
+
+String PluginScriptLanguage::get_type() const {
+ return String(_desc.type);
+}
+
+String PluginScriptLanguage::get_extension() const {
+ return String(_desc.extension);
+}
+
+Error PluginScriptLanguage::execute_file(const String &p_path) {
+ // TODO: pretty sure this method is totally deprecated and should be removed...
+ return OK;
+}
+
+void PluginScriptLanguage::finish() {
+ _desc.finish(_data);
+}
+
+/* EDITOR FUNCTIONS */
+
+void PluginScriptLanguage::get_reserved_words(List<String> *p_words) const {
+ if (_desc.reserved_words) {
+ const char **w = _desc.reserved_words;
+ while (*w) {
+ p_words->push_back(*w);
+ w++;
+ }
+ }
+}
+
+void PluginScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
+ if (_desc.comment_delimiters) {
+ const char **w = _desc.comment_delimiters;
+ while (*w) {
+ p_delimiters->push_back(*w);
+ w++;
+ }
+ }
+}
+
+void PluginScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {
+ if (_desc.string_delimiters) {
+ const char **w = _desc.string_delimiters;
+ while (*w) {
+ p_delimiters->push_back(*w);
+ w++;
+ }
+ }
+}
+
+Ref<Script> PluginScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
+ Script *ns = create_script();
+ Ref<Script> script = Ref<Script>(ns);
+ if (_desc.get_template_source_code) {
+ godot_string src = _desc.get_template_source_code(_data, (godot_string *)&p_class_name, (godot_string *)&p_base_class_name);
+ script->set_source_code(*(String *)&src);
+ }
+ return script;
+}
+
+bool PluginScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
+ PoolStringArray functions;
+ if (_desc.validate) {
+ bool ret = _desc.validate(
+ _data,
+ (godot_string *)&p_script,
+ &r_line_error,
+ &r_col_error,
+ (godot_string *)&r_test_error,
+ (godot_string *)&p_path,
+ (godot_pool_string_array *)&functions);
+ for (int i = 0; i < functions.size(); i++) {
+ r_functions->push_back(functions[i]);
+ }
+ return ret;
+ }
+ return true;
+}
+
+Script *PluginScriptLanguage::create_script() const {
+ PluginScript *script = memnew(PluginScript());
+ // I'm hurting kittens doing this I guess...
+ script->init(const_cast<PluginScriptLanguage *>(this));
+ return script;
+}
+
+bool PluginScriptLanguage::has_named_classes() const {
+ return _desc.has_named_classes;
+}
+
+int PluginScriptLanguage::find_function(const String &p_function, const String &p_code) const {
+ if (_desc.find_function) {
+ return _desc.find_function(_data, (godot_string *)&p_function, (godot_string *)&p_code);
+ }
+ return -1;
+}
+
+String PluginScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+ if (_desc.make_function) {
+ godot_string tmp = _desc.make_function(_data, (godot_string *)&p_class, (godot_string *)&p_name, (godot_pool_string_array *)&p_args);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String();
+}
+
+Error PluginScriptLanguage::complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint) {
+ if (_desc.complete_code) {
+ Array options;
+ godot_error tmp = _desc.complete_code(
+ _data,
+ (godot_string *)&p_code,
+ (godot_string *)&p_base_path,
+ (godot_object *)p_owner,
+ (godot_array *)&options,
+ &r_force,
+ (godot_string *)&r_call_hint);
+ for (int i = 0; i < options.size(); i++) {
+ r_options->push_back(String(options[i]));
+ }
+ Error err = *(Error *)tmp;
+ return err;
+ }
+ return ERR_UNAVAILABLE;
+}
+
+void PluginScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
+ if (_desc.auto_indent_code) {
+ _desc.auto_indent_code(_data, (godot_string *)&p_code, p_from_line, p_to_line);
+ }
+ return;
+}
+
+void PluginScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
+ const String variable = String(p_variable);
+ _desc.add_global_constant(_data, (godot_string *)&variable, (godot_variant *)&p_value);
+}
+
+/* LOADER FUNCTIONS */
+
+void PluginScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {
+ for (int i = 0; _desc.recognized_extensions[i]; ++i) {
+ p_extensions->push_back(String(_desc.recognized_extensions[i]));
+ }
+}
+
+void PluginScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {
+ // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ if (_desc.get_public_functions) {
+ Array functions;
+ _desc.get_public_functions(_data, (godot_array *)&functions);
+ for (int i = 0; i < functions.size(); i++) {
+ MethodInfo mi = MethodInfo::from_dict(functions[i]);
+ p_functions->push_back(mi);
+ }
+ }
+}
+
+void PluginScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
+ // TODO: provid this statically in `godot_pluginscript_language_desc` ?
+ if (_desc.get_public_constants) {
+ Dictionary constants;
+ _desc.get_public_constants(_data, (godot_dictionary *)&constants);
+ for (const Variant *key = constants.next(); key; key = constants.next(key)) {
+ Variant value = constants[key];
+ p_constants->push_back(Pair<String, Variant>(*key, value));
+ }
+ }
+}
+
+void PluginScriptLanguage::profiling_start() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_start) {
+ lock();
+ _desc.profiling_start(_data);
+ unlock();
+ }
+#endif
+}
+
+void PluginScriptLanguage::profiling_stop() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_stop) {
+ lock();
+ _desc.profiling_stop(_data);
+ unlock();
+ }
+#endif
+}
+
+int PluginScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ int info_count = 0;
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_get_accumulated_data) {
+ godot_pluginscript_profiling_data *info = (godot_pluginscript_profiling_data *)memalloc(
+ sizeof(godot_pluginscript_profiling_data) * p_info_max);
+ info_count = _desc.profiling_get_accumulated_data(_data, info, p_info_max);
+ for (int i = 0; i < info_count; ++i) {
+ p_info_arr[i].signature = *(StringName *)&info[i].signature;
+ p_info_arr[i].call_count = info[i].call_count;
+ p_info_arr[i].total_time = info[i].total_time;
+ p_info_arr[i].self_time = info[i].self_time;
+ godot_string_name_destroy(&info[i].signature);
+ }
+ }
+#endif
+ return info_count;
+}
+
+int PluginScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) {
+ int info_count = 0;
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_get_frame_data) {
+ godot_pluginscript_profiling_data *info = (godot_pluginscript_profiling_data *)memalloc(
+ sizeof(godot_pluginscript_profiling_data) * p_info_max);
+ info_count = _desc.profiling_get_frame_data(_data, info, p_info_max);
+ for (int i = 0; i < info_count; ++i) {
+ p_info_arr[i].signature = *(StringName *)&info[i].signature;
+ p_info_arr[i].call_count = info[i].call_count;
+ p_info_arr[i].total_time = info[i].total_time;
+ p_info_arr[i].self_time = info[i].self_time;
+ godot_string_name_destroy(&info[i].signature);
+ }
+ }
+#endif
+ return info_count;
+}
+
+void PluginScriptLanguage::frame() {
+#ifdef DEBUG_ENABLED
+ if (_desc.profiling_frame) {
+ _desc.profiling_frame(_data);
+ }
+#endif
+}
+
+/* DEBUGGER FUNCTIONS */
+
+String PluginScriptLanguage::debug_get_error() const {
+ if (_desc.debug_get_error) {
+ godot_string tmp = _desc.debug_get_error(_data);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+int PluginScriptLanguage::debug_get_stack_level_count() const {
+ if (_desc.debug_get_stack_level_count) {
+ return _desc.debug_get_stack_level_count(_data);
+ }
+ return 1;
+}
+
+int PluginScriptLanguage::debug_get_stack_level_line(int p_level) const {
+ if (_desc.debug_get_stack_level_line) {
+ return _desc.debug_get_stack_level_line(_data, p_level);
+ }
+ return 1;
+}
+
+String PluginScriptLanguage::debug_get_stack_level_function(int p_level) const {
+ if (_desc.debug_get_stack_level_function) {
+ godot_string tmp = _desc.debug_get_stack_level_function(_data, p_level);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+String PluginScriptLanguage::debug_get_stack_level_source(int p_level) const {
+ if (_desc.debug_get_stack_level_source) {
+ godot_string tmp = _desc.debug_get_stack_level_source(_data, p_level);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+void PluginScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_stack_level_locals) {
+ PoolStringArray locals;
+ Array values;
+ _desc.debug_get_stack_level_locals(_data, p_level, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < locals.size(); i++) {
+ p_locals->push_back(locals[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+void PluginScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_stack_level_members) {
+ PoolStringArray members;
+ Array values;
+ _desc.debug_get_stack_level_members(_data, p_level, (godot_pool_string_array *)&members, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < members.size(); i++) {
+ p_members->push_back(members[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+void PluginScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_get_globals) {
+ PoolStringArray locals;
+ Array values;
+ _desc.debug_get_globals(_data, (godot_pool_string_array *)&locals, (godot_array *)&values, p_max_subitems, p_max_depth);
+ for (int i = 0; i < locals.size(); i++) {
+ p_locals->push_back(locals[i]);
+ }
+ for (int i = 0; i < values.size(); i++) {
+ p_values->push_back(values[i]);
+ }
+ }
+}
+
+String PluginScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
+ if (_desc.debug_parse_stack_level_expression) {
+ godot_string tmp = _desc.debug_parse_stack_level_expression(_data, p_level, (godot_string *)&p_expression, p_max_subitems, p_max_depth);
+ String ret = *(String *)&tmp;
+ godot_string_destroy(&tmp);
+ return ret;
+ }
+ return String("Nothing");
+}
+
+void PluginScriptLanguage::reload_all_scripts() {
+ // TODO
+}
+
+void PluginScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
+#ifdef DEBUG_ENABLED
+ lock();
+ // TODO
+ unlock();
+#endif
+}
+
+void PluginScriptLanguage::lock() {
+#ifndef NO_THREADS
+ if (_lock) {
+ _lock->lock();
+ }
+#endif
+}
+
+void PluginScriptLanguage::unlock() {
+#ifndef NO_THREADS
+ if (_lock) {
+ _lock->unlock();
+ }
+#endif
+}
+
+PluginScriptLanguage::PluginScriptLanguage(const godot_pluginscript_language_desc *desc)
+ : _desc(*desc) {
+ _resource_loader = memnew(ResourceFormatLoaderPluginScript(this));
+ _resource_saver = memnew(ResourceFormatSaverPluginScript(this));
+
+// TODO: totally remove _lock attribute if NO_THREADS is set
+#ifdef NO_THREADS
+ _lock = NULL;
+#else
+ _lock = Mutex::create();
+#endif
+}
+
+PluginScriptLanguage::~PluginScriptLanguage() {
+ memdelete(_resource_loader);
+ memdelete(_resource_saver);
+#ifndef NO_THREADS
+ if (_lock) {
+ memdelete(_lock);
+ _lock = NULL;
+ }
+#endif
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_language.h b/modules/gdnative/pluginscript/pluginscript_language.h
new file mode 100644
index 0000000000..a48dde97ce
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_language.h
@@ -0,0 +1,131 @@
+/*************************************************************************/
+/* pluginscript_language.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_LANGUAGE_H
+#define PLUGINSCRIPT_LANGUAGE_H
+
+// Godot imports
+#include "core/io/resource_loader.h"
+#include "core/io/resource_saver.h"
+#include "core/map.h"
+#include "core/script_language.h"
+#include "core/self_list.h"
+// PluginScript imports
+#include "pluginscript_loader.h"
+#include <pluginscript/godot_pluginscript.h>
+
+class PluginScript;
+class PluginScriptInstance;
+
+class PluginScriptLanguage : public ScriptLanguage {
+ friend class PluginScript;
+ friend class PluginScriptInstance;
+
+ ResourceFormatLoaderPluginScript *_resource_loader;
+ ResourceFormatSaverPluginScript *_resource_saver;
+ const godot_pluginscript_language_desc _desc;
+ godot_pluginscript_language_data *_data;
+
+ Mutex *_lock;
+ SelfList<PluginScript>::List _script_list;
+
+public:
+ virtual String get_name() const;
+
+ _FORCE_INLINE_ ResourceFormatLoaderPluginScript *get_resource_loader() { return _resource_loader; };
+ _FORCE_INLINE_ ResourceFormatSaverPluginScript *get_resource_saver() { return _resource_saver; };
+
+ /* LANGUAGE FUNCTIONS */
+ virtual void init();
+ virtual String get_type() const;
+ virtual String get_extension() const;
+ virtual Error execute_file(const String &p_path);
+ virtual void finish();
+
+ /* EDITOR FUNCTIONS */
+ virtual void get_reserved_words(List<String> *p_words) const;
+ virtual void get_comment_delimiters(List<String> *p_delimiters) const;
+ virtual void get_string_delimiters(List<String> *p_delimiters) const;
+ virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
+ virtual Script *create_script() const;
+ virtual bool has_named_classes() const;
+ virtual bool can_inherit_from_file() { return true; }
+ virtual int find_function(const String &p_function, const String &p_code) const;
+ virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
+ virtual Error complete_code(const String &p_code, const String &p_base_path, Object *p_owner, List<String> *r_options, bool &r_force, String &r_call_hint);
+ virtual void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
+ virtual void add_global_constant(const StringName &p_variable, const Variant &p_value);
+
+ /* MULTITHREAD FUNCTIONS */
+
+ //some VMs need to be notified of thread creation/exiting to allocate a stack
+ // void thread_enter() {}
+ // void thread_exit() {}
+
+ /* DEBUGGER FUNCTIONS */
+
+ virtual String debug_get_error() const;
+ virtual int debug_get_stack_level_count() const;
+ virtual int debug_get_stack_level_line(int p_level) const;
+ virtual String debug_get_stack_level_function(int p_level) const;
+ virtual String debug_get_stack_level_source(int p_level) const;
+ virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
+ virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1);
+
+ // virtual Vector<StackInfo> debug_get_current_stack_info() { return Vector<StackInfo>(); }
+
+ virtual void reload_all_scripts();
+ virtual void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
+
+ /* LOADER FUNCTIONS */
+
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual void get_public_functions(List<MethodInfo> *p_functions) const;
+ virtual void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
+
+ virtual void profiling_start();
+ virtual void profiling_stop();
+
+ virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max);
+ virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max);
+
+ virtual void frame();
+
+ void lock();
+ void unlock();
+
+ PluginScriptLanguage(const godot_pluginscript_language_desc *desc);
+ virtual ~PluginScriptLanguage();
+};
+
+#endif // PLUGINSCRIPT_LANGUAGE_H
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.cpp b/modules/gdnative/pluginscript/pluginscript_loader.cpp
new file mode 100644
index 0000000000..3648e1a5b4
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_loader.cpp
@@ -0,0 +1,113 @@
+/*************************************************************************/
+/* pluginscript_loader.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "os/file_access.h"
+// Pythonscript imports
+#include "pluginscript_language.h"
+#include "pluginscript_loader.h"
+#include "pluginscript_script.h"
+
+ResourceFormatLoaderPluginScript::ResourceFormatLoaderPluginScript(PluginScriptLanguage *language) {
+ _language = language;
+}
+
+RES ResourceFormatLoaderPluginScript::load(const String &p_path, const String &p_original_path, Error *r_error) {
+ if (r_error)
+ *r_error = ERR_FILE_CANT_OPEN;
+
+ PluginScript *script = memnew(PluginScript);
+ script->init(_language);
+
+ Ref<PluginScript> scriptres(script);
+
+ Error err = script->load_source_code(p_path);
+ ERR_FAIL_COND_V(err != OK, RES());
+
+ script->set_path(p_original_path);
+
+ script->reload();
+
+ if (r_error)
+ *r_error = OK;
+
+ return scriptres;
+}
+
+void ResourceFormatLoaderPluginScript::get_recognized_extensions(List<String> *p_extensions) const {
+ p_extensions->push_back(_language->get_extension());
+}
+
+bool ResourceFormatLoaderPluginScript::handles_type(const String &p_type) const {
+ return p_type == "Script" || p_type == _language->get_type();
+}
+
+String ResourceFormatLoaderPluginScript::get_resource_type(const String &p_path) const {
+ String el = p_path.get_extension().to_lower();
+ if (el == _language->get_extension())
+ return _language->get_type();
+ return "";
+}
+
+ResourceFormatSaverPluginScript::ResourceFormatSaverPluginScript(PluginScriptLanguage *language) {
+ _language = language;
+}
+
+Error ResourceFormatSaverPluginScript::save(const String &p_path, const RES &p_resource, uint32_t p_flags) {
+ Ref<PluginScript> sqscr = p_resource;
+ ERR_FAIL_COND_V(sqscr.is_null(), ERR_INVALID_PARAMETER);
+
+ String source = sqscr->get_source_code();
+
+ Error err;
+ FileAccess *file = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ ERR_FAIL_COND_V(err, err);
+
+ file->store_string(source);
+ if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) {
+ memdelete(file);
+ return ERR_CANT_CREATE;
+ }
+ file->close();
+ memdelete(file);
+ return OK;
+}
+
+void ResourceFormatSaverPluginScript::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const {
+
+ if (Object::cast_to<PluginScript>(*p_resource)) {
+ p_extensions->push_back(_language->get_extension());
+ }
+}
+
+bool ResourceFormatSaverPluginScript::recognize(const RES &p_resource) const {
+
+ return Object::cast_to<PluginScript>(*p_resource) != NULL;
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_loader.h b/modules/gdnative/pluginscript/pluginscript_loader.h
new file mode 100644
index 0000000000..b85e7725a1
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_loader.h
@@ -0,0 +1,62 @@
+/*************************************************************************/
+/* pluginscript_loader.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PYTHONSCRIPT_PY_LOADER_H
+#define PYTHONSCRIPT_PY_LOADER_H
+
+// Godot imports
+#include "core/script_language.h"
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+
+class PluginScriptLanguage;
+
+class ResourceFormatLoaderPluginScript : public ResourceFormatLoader {
+ PluginScriptLanguage *_language;
+
+public:
+ ResourceFormatLoaderPluginScript(PluginScriptLanguage *language);
+ virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ virtual bool handles_type(const String &p_type) const;
+ virtual String get_resource_type(const String &p_path) const;
+};
+
+class ResourceFormatSaverPluginScript : public ResourceFormatSaver {
+ PluginScriptLanguage *_language;
+
+public:
+ ResourceFormatSaverPluginScript(PluginScriptLanguage *language);
+ virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
+ virtual void get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const;
+ virtual bool recognize(const RES &p_resource) const;
+};
+
+#endif // PYTHONSCRIPT_PY_LOADER_H
diff --git a/modules/gdnative/pluginscript/pluginscript_script.cpp b/modules/gdnative/pluginscript/pluginscript_script.cpp
new file mode 100644
index 0000000000..7dd10a8bdf
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_script.cpp
@@ -0,0 +1,454 @@
+/*************************************************************************/
+/* pluginscript_script.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+
+// Godot imports
+#include "core/os/file_access.h"
+// PluginScript imports
+#include "pluginscript_instance.h"
+#include "pluginscript_script.h"
+
+#if DEBUG_ENABLED
+#define __ASSERT_SCRIPT_REASON "Cannot retrieve pluginscript class for this script, is you code correct ?"
+#define ASSERT_SCRIPT_VALID() \
+ { \
+ ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
+ ERR_FAIL_COND(!can_instance()) \
+ }
+#define ASSERT_SCRIPT_VALID_V(ret) \
+ { \
+ ERR_EXPLAIN(__ASSERT_SCRIPT_REASON); \
+ ERR_FAIL_COND_V(!can_instance(), ret) \
+ }
+#else
+#define ASSERT_SCRIPT_VALID()
+#define ASSERT_SCRIPT_VALID_V(ret)
+#endif
+
+void PluginScript::_bind_methods() {
+}
+
+#ifdef TOOLS_ENABLED
+
+void PluginScript::_placeholder_erased(PlaceHolderScriptInstance *p_placeholder) {
+ placeholders.erase(p_placeholder);
+}
+
+#endif
+
+bool PluginScript::can_instance() const {
+ bool can = _valid || (!_tool && !ScriptServer::is_scripting_enabled());
+ return can;
+}
+
+Ref<Script> PluginScript::get_base_script() const {
+ if (_ref_base_parent.is_valid()) {
+ return Ref<PluginScript>(_ref_base_parent);
+ } else {
+ return Ref<Script>();
+ }
+}
+
+StringName PluginScript::get_instance_base_type() const {
+ if (_native_parent)
+ return _native_parent;
+ if (_ref_base_parent.is_valid())
+ return _ref_base_parent->get_instance_base_type();
+ return StringName();
+}
+
+void PluginScript::update_exports() {
+// TODO
+#ifdef TOOLS_ENABLED
+#if 0
+ ASSERT_SCRIPT_VALID();
+ if (/*changed &&*/ placeholders.size()) { //hm :(
+
+ //update placeholders if any
+ Map<StringName, Variant> propdefvalues;
+ List<PropertyInfo> propinfos;
+ const String *props = (const String *)pybind_get_prop_list(_py_exposed_class);
+ for (int i = 0; props[i] != ""; ++i) {
+ const String propname = props[i];
+ pybind_get_prop_default_value(_py_exposed_class, propname.c_str(), (godot_variant *)&propdefvalues[propname]);
+ pybind_prop_info raw_info;
+ pybind_get_prop_info(_py_exposed_class, propname.c_str(), &raw_info);
+ PropertyInfo info;
+ info.type = (Variant::Type)raw_info.type;
+ info.name = propname;
+ info.hint = (PropertyHint)raw_info.hint;
+ info.hint_string = *(String *)&raw_info.hint_string;
+ info.usage = raw_info.usage;
+ propinfos.push_back(info);
+ }
+ for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+ E->get()->update(propinfos, propdefvalues);
+ }
+ }
+#endif
+#endif
+}
+
+// TODO: rename p_this "p_owner" ?
+ScriptInstance *PluginScript::instance_create(Object *p_this) {
+ ASSERT_SCRIPT_VALID_V(NULL);
+ // TODO check script validity ?
+ if (!_tool && !ScriptServer::is_scripting_enabled()) {
+#ifdef TOOLS_ENABLED
+ // Instance a fake script for editing the values
+ PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(get_language(), Ref<Script>(this), p_this));
+ placeholders.insert(si);
+ update_exports();
+ return si;
+#else
+ return NULL;
+#endif
+ }
+
+ PluginScript *top = this;
+ // TODO: can be optimized by storing a PluginScript::_base_parent direct pointer
+ while (top->_ref_base_parent.is_valid())
+ top = top->_ref_base_parent.ptr();
+ if (top->_native_parent) {
+ if (!ClassDB::is_parent_class(p_this->get_class_name(), top->_native_parent)) {
+ String msg = "Script inherits from native type '" + String(top->_native_parent) + "', so it can't be instanced in object of type: '" + p_this->get_class() + "'";
+ // TODO: implement PluginscriptLanguage::debug_break_parse
+ // if (ScriptDebugger::get_singleton()) {
+ // _language->debug_break_parse(get_path(), 0, msg);
+ // }
+ ERR_EXPLAIN(msg);
+ ERR_FAIL_V(NULL);
+ }
+ }
+
+ PluginScriptInstance *instance = memnew(PluginScriptInstance());
+ const bool success = instance->init(this, p_this);
+ if (success) {
+ _language->lock();
+ _instances.insert(instance->get_owner());
+ _language->unlock();
+ return instance;
+ } else {
+ memdelete(instance);
+ ERR_FAIL_V(NULL);
+ }
+}
+
+bool PluginScript::instance_has(const Object *p_this) const {
+ _language->lock();
+ bool hasit = _instances.has((Object *)p_this);
+ _language->unlock();
+ return hasit;
+}
+
+bool PluginScript::has_source_code() const {
+ bool has = _source != "";
+ return has;
+}
+
+String PluginScript::get_source_code() const {
+ return _source;
+}
+
+void PluginScript::set_source_code(const String &p_code) {
+ if (_source == p_code)
+ return;
+ _source = p_code;
+}
+
+Error PluginScript::reload(bool p_keep_state) {
+ _language->lock();
+ ERR_FAIL_COND_V(!p_keep_state && _instances.size(), ERR_ALREADY_IN_USE);
+ _language->unlock();
+
+ _valid = false;
+ String basedir = _path;
+
+ if (basedir == "")
+ basedir = get_path();
+
+ if (basedir != "")
+ basedir = basedir.get_base_dir();
+
+ if (_data) {
+ _desc->finish(_data);
+ }
+
+ Error err;
+ godot_pluginscript_script_manifest manifest = _desc->init(
+ _language->_data,
+ (godot_string *)&_path,
+ (godot_string *)&_source,
+ (godot_error *)&err);
+ if (err) {
+ // TODO: GDscript uses `ScriptDebugger` here to jump into the parsing error
+ return err;
+ }
+ _valid = true;
+ // Use the manifest to configure this script object
+ _data = manifest.data;
+ _name = *(StringName *)&manifest.name;
+ _tool = manifest.is_tool;
+ // Base name is either another PluginScript or a regular class accessible
+ // through ClassDB
+ StringName *base_name = (StringName *)&manifest.base;
+ for (SelfList<PluginScript> *e = _language->_script_list.first(); e != NULL; e = e->next()) {
+ if (e->self()->_name == *base_name) {
+ // Found you, base is a PluginScript !
+ _ref_base_parent = Ref<PluginScript>(e->self());
+ break;
+ }
+ }
+ if (!_ref_base_parent.is_valid()) {
+ // Base is a native ClassDB
+ if (!ClassDB::class_exists(*base_name)) {
+ ERR_EXPLAIN("Unknown script '" + String(_name) + "' parent '" + String(*base_name) + "'.");
+ ERR_FAIL_V(ERR_PARSE_ERROR);
+ }
+ _native_parent = *base_name;
+ }
+
+ Dictionary *members = (Dictionary *)&manifest.member_lines;
+ for (const Variant *key = members->next(); key != NULL; key = members->next(key)) {
+ _member_lines[*key] = (*members)[key];
+ }
+ Array *methods = (Array *)&manifest.methods;
+ for (int i = 0; i < methods->size(); ++i) {
+ Dictionary v = (*methods)[i];
+ MethodInfo mi = MethodInfo::from_dict(v);
+ _methods_info[mi.name] = mi;
+ // rpc_mode is passed as an optional field and is not part of MethodInfo
+ Variant var = v["rpc_mode"];
+ if (var == Variant()) {
+ _methods_rpc_mode[mi.name] = ScriptInstance::RPC_MODE_DISABLED;
+ } else {
+ _methods_rpc_mode[mi.name] = ScriptInstance::RPCMode(int(var));
+ }
+ }
+ Array *signals = (Array *)&manifest.signals;
+ for (int i = 0; i < signals->size(); ++i) {
+ Variant v = (*signals)[i];
+ MethodInfo mi = MethodInfo::from_dict(v);
+ _signals_info[mi.name] = mi;
+ }
+ Array *properties = (Array *)&manifest.properties;
+ for (int i = 0; i < properties->size(); ++i) {
+ Dictionary v = (*properties)[i];
+ PropertyInfo pi = PropertyInfo::from_dict(v);
+ _properties_info[pi.name] = pi;
+ _properties_default_values[pi.name] = v["default_value"];
+ // rset_mode is passed as an optional field and is not part of PropertyInfo
+ Variant var = v["rset_mode"];
+ if (var == Variant()) {
+ _methods_rpc_mode[pi.name] = ScriptInstance::RPC_MODE_DISABLED;
+ } else {
+ _methods_rpc_mode[pi.name] = ScriptInstance::RPCMode(int(var));
+ }
+ }
+ // Manifest's attributes must be explicitly freed
+ godot_string_name_destroy(&manifest.name);
+ godot_string_name_destroy(&manifest.base);
+ godot_dictionary_destroy(&manifest.member_lines);
+ godot_array_destroy(&manifest.methods);
+ godot_array_destroy(&manifest.signals);
+ godot_array_destroy(&manifest.properties);
+
+#ifdef TOOLS_ENABLED
+/*for (Set<PlaceHolderScriptInstance*>::Element *E=placeholders.front();E;E=E->next()) {
+
+ _update_placeholder(E->get());
+ }*/
+#endif
+ return OK;
+}
+
+void PluginScript::get_script_method_list(List<MethodInfo> *r_methods) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, MethodInfo>::Element *e = _methods_info.front(); e != NULL; e = e->next()) {
+ r_methods->push_back(e->get());
+ }
+}
+
+void PluginScript::get_script_property_list(List<PropertyInfo> *r_properties) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, PropertyInfo>::Element *e = _properties_info.front(); e != NULL; e = e->next()) {
+ r_properties->push_back(e->get());
+ }
+}
+
+bool PluginScript::has_method(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _methods_info.has(p_method);
+}
+
+MethodInfo PluginScript::get_method_info(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(MethodInfo());
+ const Map<StringName, MethodInfo>::Element *e = _methods_info.find(p_method);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return MethodInfo();
+ }
+}
+
+bool PluginScript::has_property(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _properties_info.has(p_method);
+}
+
+PropertyInfo PluginScript::get_property_info(const StringName &p_property) const {
+ ASSERT_SCRIPT_VALID_V(PropertyInfo());
+ const Map<StringName, PropertyInfo>::Element *e = _properties_info.find(p_property);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return PropertyInfo();
+ }
+}
+
+bool PluginScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
+ ASSERT_SCRIPT_VALID_V(false);
+#ifdef TOOLS_ENABLED
+ const Map<StringName, Variant>::Element *e = _properties_default_values.find(p_property);
+ if (e != NULL) {
+ r_value = e->get();
+ return true;
+ } else {
+ return false;
+ }
+#endif
+ return false;
+}
+
+String PluginScript::get_node_type() const {
+ // Even GDscript doesn't know what to put here !
+ return ""; // ?
+}
+
+ScriptLanguage *PluginScript::get_language() const {
+ return _language;
+}
+
+Error PluginScript::load_source_code(const String &p_path) {
+
+ PoolVector<uint8_t> sourcef;
+ Error err;
+ FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err);
+ if (err) {
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ int len = f->get_len();
+ sourcef.resize(len + 1);
+ PoolVector<uint8_t>::Write w = sourcef.write();
+ int r = f->get_buffer(w.ptr(), len);
+ f->close();
+ memdelete(f);
+ ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN);
+ w[len] = 0;
+
+ String s;
+ if (s.parse_utf8((const char *)w.ptr())) {
+ ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode.");
+ ERR_FAIL_V(ERR_INVALID_DATA);
+ }
+
+ _source = s;
+#ifdef TOOLS_ENABLED
+// source_changed_cache=true;
+#endif
+ _path = p_path;
+ return OK;
+}
+
+bool PluginScript::has_script_signal(const StringName &p_signal) const {
+ ASSERT_SCRIPT_VALID_V(false);
+ return _signals_info.has(p_signal);
+}
+
+void PluginScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
+ ASSERT_SCRIPT_VALID();
+ for (Map<StringName, MethodInfo>::Element *e = _signals_info.front(); e != NULL; e = e->next()) {
+ r_signals->push_back(e->get());
+ }
+}
+
+int PluginScript::get_member_line(const StringName &p_member) const {
+#ifdef TOOLS_ENABLED
+ if (_member_lines.has(p_member))
+ return _member_lines[p_member];
+ else
+#endif
+ return -1;
+}
+
+ScriptInstance::RPCMode PluginScript::get_rpc_mode(const StringName &p_method) const {
+ ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
+ const Map<StringName, ScriptInstance::RPCMode>::Element *e = _methods_rpc_mode.find(p_method);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return ScriptInstance::RPC_MODE_DISABLED;
+ }
+}
+
+ScriptInstance::RPCMode PluginScript::get_rset_mode(const StringName &p_variable) const {
+ ASSERT_SCRIPT_VALID_V(ScriptInstance::RPC_MODE_DISABLED);
+ const Map<StringName, ScriptInstance::RPCMode>::Element *e = _variables_rset_mode.find(p_variable);
+ if (e != NULL) {
+ return e->get();
+ } else {
+ return ScriptInstance::RPC_MODE_DISABLED;
+ }
+}
+
+PluginScript::PluginScript()
+ : _data(NULL), _tool(false), _valid(false), _script_list(this) {
+}
+
+void PluginScript::init(PluginScriptLanguage *language) {
+ _desc = &language->_desc.script_desc;
+ _language = language;
+
+#ifdef DEBUG_ENABLED
+ _language->lock();
+ _language->_script_list.add(&_script_list);
+ _language->unlock();
+#endif
+}
+
+PluginScript::~PluginScript() {
+ _desc->finish(_data);
+
+#ifdef DEBUG_ENABLED
+ _language->lock();
+ _language->_script_list.remove(&_script_list);
+ _language->unlock();
+#endif
+}
diff --git a/modules/gdnative/pluginscript/pluginscript_script.h b/modules/gdnative/pluginscript/pluginscript_script.h
new file mode 100644
index 0000000000..e6b8643cd9
--- /dev/null
+++ b/modules/gdnative/pluginscript/pluginscript_script.h
@@ -0,0 +1,129 @@
+/*************************************************************************/
+/* pluginscript_script.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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 PLUGINSCRIPT_SCRIPT_H
+#define PLUGINSCRIPT_SCRIPT_H
+
+// Godot imports
+#include "core/script_language.h"
+// PluginScript imports
+#include "pluginscript_language.h"
+#include <pluginscript/godot_pluginscript.h>
+
+class PyInstance;
+
+class PluginScript : public Script {
+
+ GDCLASS(PluginScript, Script);
+
+ friend class PluginScriptInstance;
+ friend class PluginScriptLanguage;
+
+private:
+ godot_pluginscript_script_data *_data;
+ const godot_pluginscript_script_desc *_desc;
+ PluginScriptLanguage *_language;
+ bool _tool;
+ bool _valid;
+
+ Ref<PluginScript> _ref_base_parent;
+ StringName _native_parent;
+ SelfList<PluginScript> _script_list;
+
+ Map<StringName, int> _member_lines;
+ Map<StringName, Variant> _properties_default_values;
+ Map<StringName, PropertyInfo> _properties_info;
+ Map<StringName, MethodInfo> _signals_info;
+ Map<StringName, MethodInfo> _methods_info;
+ Map<StringName, ScriptInstance::RPCMode> _variables_rset_mode;
+ Map<StringName, ScriptInstance::RPCMode> _methods_rpc_mode;
+
+ Set<Object *> _instances;
+ //exported members
+ String _source;
+ String _path;
+ StringName _name;
+
+protected:
+ static void _bind_methods();
+
+#ifdef TOOLS_ENABLED
+ Set<PlaceHolderScriptInstance *> placeholders;
+ //void _update_placeholder(PlaceHolderScriptInstance *p_placeholder);
+ virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder);
+#endif
+public:
+ virtual bool can_instance() const;
+
+ virtual Ref<Script> get_base_script() const; //for script inheritance
+
+ virtual StringName get_instance_base_type() const; // this may not work in all scripts, will return empty if so
+ virtual ScriptInstance *instance_create(Object *p_this);
+ virtual bool instance_has(const Object *p_this) const;
+
+ virtual bool has_source_code() const;
+ virtual String get_source_code() const;
+ virtual void set_source_code(const String &p_code);
+ virtual Error reload(bool p_keep_state = false);
+ // TODO: load_source_code only allow utf-8 file, should handle bytecode as well ?
+ virtual Error load_source_code(const String &p_path);
+
+ virtual bool has_method(const StringName &p_method) const;
+ virtual MethodInfo get_method_info(const StringName &p_method) const;
+
+ bool has_property(const StringName &p_method) const;
+ PropertyInfo get_property_info(const StringName &p_property) const;
+
+ bool is_tool() const { return _tool; }
+
+ virtual String get_node_type() const;
+
+ virtual ScriptLanguage *get_language() const;
+
+ virtual bool has_script_signal(const StringName &p_signal) const;
+ virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
+
+ virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const;
+
+ virtual void update_exports();
+ virtual void get_script_method_list(List<MethodInfo> *r_methods) const;
+ virtual void get_script_property_list(List<PropertyInfo> *r_propertieslist) const;
+
+ virtual int get_member_line(const StringName &p_member) const;
+
+ ScriptInstance::RPCMode get_rpc_mode(const StringName &p_method) const;
+ ScriptInstance::RPCMode get_rset_mode(const StringName &p_variable) const;
+
+ PluginScript();
+ void init(PluginScriptLanguage *language);
+ virtual ~PluginScript();
+};
+
+#endif // PLUGINSCRIPT_SCRIPT_H
diff --git a/modules/gdnative/pluginscript/register_types.cpp b/modules/gdnative/pluginscript/register_types.cpp
new file mode 100644
index 0000000000..5829d08dff
--- /dev/null
+++ b/modules/gdnative/pluginscript/register_types.cpp
@@ -0,0 +1,118 @@
+/*************************************************************************/
+/* register_types.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "register_types.h"
+
+#include "core/project_settings.h"
+#include "io/resource_loader.h"
+#include "io/resource_saver.h"
+#include "os/dir_access.h"
+#include "os/os.h"
+#include "scene/main/scene_tree.h"
+
+#include "pluginscript_language.h"
+#include "pluginscript_script.h"
+#include <pluginscript/godot_pluginscript.h>
+
+static List<PluginScriptLanguage *> pluginscript_languages;
+
+static Error _check_language_desc(const godot_pluginscript_language_desc *desc) {
+ ERR_FAIL_COND_V(!desc->name || desc->name == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->type || desc->type == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->extension || desc->extension == String(), ERR_BUG);
+ ERR_FAIL_COND_V(!desc->recognized_extensions || !desc->recognized_extensions[0], ERR_BUG);
+ ERR_FAIL_COND_V(!desc->init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->finish, ERR_BUG);
+
+ // desc->reserved_words is not mandatory
+ // desc->comment_delimiters is not mandatory
+ // desc->string_delimiters is not mandatory
+
+ // desc->get_template_source_code is not mandatory
+ // desc->validate is not mandatory
+
+ // desc->get_template_source_code is not mandatory
+ // desc->validate is not mandatory
+ // desc->find_function is not mandatory
+ // desc->make_function is not mandatory
+ // desc->complete_code is not mandatory
+ // desc->auto_indent_code is not mandatory
+ // desc->add_global_constant is not mandatory
+ // desc->debug_get_error is not mandatory
+ // desc->debug_get_stack_level_count is not mandatory
+ // desc->debug_get_stack_level_line is not mandatory
+ // desc->debug_get_stack_level_function is not mandatory
+ // desc->debug_get_stack_level_source is not mandatory
+ // desc->debug_get_stack_level_locals is not mandatory
+ // desc->debug_get_stack_level_members is not mandatory
+ // desc->debug_get_globals is not mandatory
+ // desc->debug_parse_stack_level_expression is not mandatory
+ // desc->profiling_start is not mandatory
+ // desc->profiling_stop is not mandatory
+ // desc->profiling_get_accumulated_data is not mandatory
+ // desc->profiling_get_frame_data is not mandatory
+ // desc->frame is not mandatory
+
+ ERR_FAIL_COND_V(!desc->script_desc.init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.finish, ERR_BUG);
+
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.init, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.finish, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.set_prop, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.get_prop, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.call_method, ERR_BUG);
+ ERR_FAIL_COND_V(!desc->script_desc.instance_desc.notification, ERR_BUG);
+ // desc->script_desc.instance_desc.refcount_incremented is not mandatory
+ // desc->script_desc.instance_desc.refcount_decremented is not mandatory
+ return OK;
+}
+
+void GDAPI godot_pluginscript_register_language(const godot_pluginscript_language_desc *language_desc) {
+ Error ret = _check_language_desc(language_desc);
+ if (ret) {
+ ERR_FAIL();
+ }
+ PluginScriptLanguage *language = memnew(PluginScriptLanguage(language_desc));
+ ScriptServer::register_language(language);
+ ResourceLoader::add_resource_format_loader(language->get_resource_loader());
+ ResourceSaver::add_resource_format_saver(language->get_resource_saver());
+ pluginscript_languages.push_back(language);
+}
+
+void register_pluginscript_types() {
+ ClassDB::register_class<PluginScript>();
+}
+
+void unregister_pluginscript_types() {
+ for (List<PluginScriptLanguage *>::Element *e = pluginscript_languages.front(); e; e = e->next()) {
+ PluginScriptLanguage *language = e->get();
+ ScriptServer::unregister_language(language);
+ memdelete(language);
+ }
+}
diff --git a/modules/gdnative/pluginscript/register_types.h b/modules/gdnative/pluginscript/register_types.h
new file mode 100644
index 0000000000..70bbb16c62
--- /dev/null
+++ b/modules/gdnative/pluginscript/register_types.h
@@ -0,0 +1,31 @@
+/*************************************************************************/
+/* register_types.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 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. */
+/*************************************************************************/
+void register_pluginscript_types();
+void unregister_pluginscript_types();
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 059cd197d1..d2a3e29849 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -35,7 +35,9 @@
#include "io/resource_loader.h"
#include "io/resource_saver.h"
+#include "nativearvr/register_types.h"
#include "nativescript/register_types.h"
+#include "pluginscript/register_types.h"
#include "core/engine.h"
#include "core/os/os.h"
@@ -127,57 +129,12 @@ static void editor_init_callback() {
#endif
-godot_variant cb_standard_varcall(void *handle, godot_string *p_procedure, godot_array *p_args) {
- if (handle == NULL) {
- ERR_PRINT("No valid library handle, can't call standard varcall procedure");
- godot_variant ret;
- godot_variant_new_nil(&ret);
- return ret;
- }
-
- void *library_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- handle,
- *(String *)p_procedure,
- library_proc,
- true); // we roll our own message
- if (err != OK) {
- ERR_PRINT((String("GDNative procedure \"" + *(String *)p_procedure) + "\" does not exists and can't be called").utf8().get_data());
- godot_variant ret;
- godot_variant_new_nil(&ret);
- return ret;
- }
+godot_variant cb_standard_varcall(void *p_procedure_handle, godot_array *p_args) {
godot_gdnative_procedure_fn proc;
- proc = (godot_gdnative_procedure_fn)library_proc;
+ proc = (godot_gdnative_procedure_fn)p_procedure_handle;
- return proc(NULL, p_args);
-}
-
-void cb_singleton_call(
- void *p_handle,
- godot_string *p_proc_name,
- void *p_data,
- int p_num_args,
- void **p_args,
- void *r_return) {
- if (p_handle == NULL) {
- ERR_PRINT("No valid library handle, can't call singleton procedure");
- return;
- }
-
- void *singleton_proc;
- Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(
- p_handle,
- *(String *)p_proc_name,
- singleton_proc);
-
- if (err != OK) {
- return;
- }
-
- void (*singleton_procedure_ptr)() = (void (*)())singleton_proc;
- singleton_procedure_ptr();
+ return proc(p_args);
}
GDNativeCallRegistry *GDNativeCallRegistry::singleton;
@@ -200,9 +157,9 @@ void register_gdnative_types() {
GDNativeCallRegistry::singleton->register_native_call_type("standard_varcall", cb_standard_varcall);
- GDNativeCallRegistry::singleton->register_native_raw_call_type("gdnative_singleton_call", cb_singleton_call);
-
+ register_nativearvr_types();
register_nativescript_types();
+ register_pluginscript_types();
// run singletons
@@ -223,13 +180,16 @@ void register_gdnative_types() {
continue;
}
- singleton_gdnatives[i]->call_native_raw(
- "gdnative_singleton_call",
+ void *proc_ptr;
+ Error err = singleton_gdnatives[i]->get_symbol(
"godot_gdnative_singleton",
- NULL,
- 0,
- NULL,
- NULL);
+ proc_ptr);
+
+ if (err != OK) {
+ ERR_PRINT((String("No godot_gdnative_singleton in \"" + singleton_gdnatives[i]->get_library()->get_active_library_path()) + "\" found").utf8().get_data());
+ } else {
+ ((void (*)())proc_ptr)();
+ }
}
}
@@ -249,7 +209,9 @@ void unregister_gdnative_types() {
}
singleton_gdnatives.clear();
+ unregister_pluginscript_types();
unregister_nativescript_types();
+ unregister_nativearvr_types();
memdelete(GDNativeCallRegistry::singleton);
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 3676570ec1..ed8c27e5d0 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="GridMap" inherits="Spatial" category="Core" version="3.0.alpha.custom_build">
<brief_description>
+ Node for 3D tile-based maps.
</brief_description>
<description>
+ GridMap lets you place meshes on a grid interactively. It works both from the editor and can help you create in-game level editors.
+ GridMaps use a [MeshLibrary] which contain a list of tiles: meshes with materials plus optional collisions and extra elements.
+ A GridMap contains a collection of cells. Each grid cell refers to a [MeshLibrary] item. All cells in the map have the same dimensions.
+ A GridMap is split into a sparse collection of octants for efficient rendering and physics processing. Every octant has the same dimensions and can contain several cells.
</description>
<tutorials>
</tutorials>
@@ -13,6 +18,7 @@
<return type="void">
</return>
<description>
+ Clear all cells.
</description>
</method>
<method name="get_cell_item" qualifiers="const">
@@ -25,6 +31,7 @@
<argument index="2" name="z" type="int">
</argument>
<description>
+ The [MeshLibrary] item index located at the grid-based X, Y and Z coordinates. If the cell is empty, [INVALID_CELL_ITEM] will be returned.
</description>
</method>
<method name="get_cell_item_orientation" qualifiers="const">
@@ -37,48 +44,63 @@
<argument index="2" name="z" type="int">
</argument>
<description>
+ The orientation of the cell at the grid-based X, Y and Z coordinates. -1 is retuned if the cell is empty.
</description>
</method>
<method name="get_cell_size" qualifiers="const">
<return type="Vector3">
</return>
<description>
+ The dimensions of the grid's cells.
</description>
</method>
<method name="get_center_x" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the X axis.
</description>
</method>
<method name="get_center_y" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the Y axis.
</description>
</method>
<method name="get_center_z" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether or not grid items are centered on the Z axis.
</description>
</method>
<method name="get_meshes">
<return type="Array">
</return>
<description>
+ Array of [Transform] and [Mesh] references corresponding to the non empty cells in the grid. The transforms are specified in world space.
</description>
</method>
<method name="get_octant_size" qualifiers="const">
<return type="int">
</return>
<description>
+ The size of each octant measured in number of cells. This applies to all three axis.
</description>
</method>
<method name="get_theme" qualifiers="const">
<return type="MeshLibrary">
</return>
<description>
+ The assigned [MeshLibrary].
+ </description>
+ </method>
+ <method name="get_used_cells" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ Array of [Vector3] with the non empty cell coordinates in the grid map.
</description>
</method>
<method name="resource_changed">
@@ -103,6 +125,9 @@
<argument index="4" name="orientation" type="int" default="0">
</argument>
<description>
+ Set the mesh index for the cell referenced by its grid-based X, Y and Z coordinates.
+ A negative item index will clear the cell.
+ Optionally, the item's orientation can be passed.
</description>
</method>
<method name="set_cell_size">
@@ -111,6 +136,7 @@
<argument index="0" name="size" type="Vector3">
</argument>
<description>
+ Sets the height, width and depth of the grid's cells.
</description>
</method>
<method name="set_center_x">
@@ -119,6 +145,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the X axis. By default it is enabled.
</description>
</method>
<method name="set_center_y">
@@ -127,6 +154,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the Y axis. By default it is enabled.
</description>
</method>
<method name="set_center_z">
@@ -135,6 +163,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
+ Set grid items to be centered on the Z axis. By default it is enabled.
</description>
</method>
<method name="set_clip">
@@ -157,6 +186,7 @@
<argument index="0" name="size" type="int">
</argument>
<description>
+ Sets the size for each octant measured in number of cells. This applies to all three axis.
</description>
</method>
<method name="set_theme">
@@ -165,11 +195,13 @@
<argument index="0" name="theme" type="MeshLibrary">
</argument>
<description>
+ Sets the collection of meshes for the map.
</description>
</method>
</methods>
<constants>
<constant name="INVALID_CELL_ITEM" value="-1" enum="">
+ Invalid cell item that can be used in [method set_cell_item] to clear cells (or represent an empty cell in [method get_cell_item]).
</constant>
</constants>
</class>
diff --git a/modules/mobile_vr/mobile_interface.h b/modules/mobile_vr/mobile_interface.h
index 6a5e01c163..747377ae46 100644
--- a/modules/mobile_vr/mobile_interface.h
+++ b/modules/mobile_vr/mobile_interface.h
@@ -90,7 +90,7 @@ private:
///@TODO a few support functions for trackers, most are math related and should likely be moved elsewhere
float floor_decimals(float p_value, float p_decimals) {
- float power_of_10 = pow(10.0, p_decimals);
+ float power_of_10 = pow(10.0f, p_decimals);
return floor(p_value * power_of_10) / power_of_10;
};
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 9de199bb5a..0833d30ce1 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -125,12 +125,16 @@ def configure(env):
else:
env.Append(LIBS=[mono_lib])
- env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+ if sys.platform == "darwin":
+ env.Append(LIBS=['iconv', 'pthread'])
+ elif sys.platform == "linux" or sys.platform == "linux2":
+ env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
+
else:
if mono_static:
raise RuntimeError('mono-static: Not supported with pkg-config. Specify a mono prefix manually')
- env.ParseConfig('pkg-config mono-2 --cflags --libs')
+ env.ParseConfig('pkg-config monosgen-2 --cflags --libs')
env.Append(LINKFLAGS='-rdynamic')
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index b475782729..ba8c7df9cc 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -41,6 +41,7 @@
#include "editor/csharp_project.h"
#include "editor/editor_node.h"
#include "editor/godotsharp_editor.h"
+#include "utils/string_utils.h"
#endif
#include "godotsharp_dirs.h"
@@ -48,8 +49,9 @@
#include "mono_gd/gd_mono_marshal.h"
#include "signal_awaiter_utils.h"
-#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->string_names.m_var)
+#define CACHED_STRING_NAME(m_var) (CSharpLanguage::get_singleton()->get_string_names().m_var)
+#ifdef TOOLS_ENABLED
static bool _create_project_solution_if_needed() {
String sln_path = GodotSharpDirs::get_project_sln_path();
@@ -64,6 +66,7 @@ static bool _create_project_solution_if_needed() {
return true;
}
+#endif
CSharpLanguage *CSharpLanguage::singleton = NULL;
@@ -295,20 +298,88 @@ bool CSharpLanguage::has_named_classes() const {
return true;
}
-String CSharpLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+static String variant_type_to_managed_name(const String &p_var_type_name) {
+
+ if (p_var_type_name.empty())
+ return "object";
+
+ if (!ClassDB::class_exists(p_var_type_name)) {
+ Variant::Type var_types[] = {
+ Variant::BOOL,
+ Variant::INT,
+ Variant::REAL,
+ Variant::STRING,
+ Variant::VECTOR2,
+ Variant::RECT2,
+ Variant::VECTOR3,
+ Variant::TRANSFORM2D,
+ Variant::PLANE,
+ Variant::QUAT,
+ Variant::RECT3,
+ Variant::BASIS,
+ Variant::TRANSFORM,
+ Variant::COLOR,
+ Variant::NODE_PATH,
+ Variant::_RID
+ };
+
+ for (int i = 0; i < sizeof(var_types) / sizeof(Variant::Type); i++) {
+ if (p_var_type_name == Variant::get_type_name(var_types[i]))
+ return p_var_type_name;
+ }
+
+ if (p_var_type_name == "String")
+ return "string"; // I prefer this one >:[
+
+ // TODO these will be rewritten later into custom containers
+
+ if (p_var_type_name == "Array")
+ return "object[]";
+
+ if (p_var_type_name == "Dictionary")
+ return "Dictionary<object, object>";
+ if (p_var_type_name == "PoolByteArray")
+ return "byte[]";
+ if (p_var_type_name == "PoolIntArray")
+ return "int[]";
+ if (p_var_type_name == "PoolRealArray")
+ return "float[]";
+ if (p_var_type_name == "PoolStringArray")
+ return "string[]";
+ if (p_var_type_name == "PoolVector2Array")
+ return "Vector2[]";
+ if (p_var_type_name == "PoolVector3Array")
+ return "Vector3[]";
+ if (p_var_type_name == "PoolColorArray")
+ return "Color[]";
+
+ return "object";
+ }
+
+ return p_var_type_name;
+}
+
+String CSharpLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
+#ifdef TOOLS_ENABLED
// FIXME
- // Due to Godot's API limitation this just appends the function to the end of the file
- // Another limitation is that the parameter types are not specified, so we must use System.Object
+ // - Due to Godot's API limitation this just appends the function to the end of the file
+ // - Use fully qualified name if there is ambiguity
String s = "private void " + p_name + "(";
for (int i = 0; i < p_args.size(); i++) {
+ const String &arg = p_args[i];
+
if (i > 0)
s += ", ";
- s += "object " + p_args[i];
+
+ s += variant_type_to_managed_name(arg.get_slice(":", 1)) + " " + escape_csharp_keyword(arg.get_slice(":", 0));
}
s += ")\n{\n // Replace with function body\n}\n";
return s;
+#else
+ return String();
+#endif
}
void CSharpLanguage::frame() {
@@ -903,46 +974,6 @@ Variant CSharpInstance::call(const StringName &p_method, const Variant **p_args,
} else {
return Variant();
}
- } else if (p_method == CACHED_STRING_NAME(_awaited_signal_callback)) {
- // shitty hack..
- // TODO move to its own function, thx
-
- if (p_argcount < 1) {
- r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- r_error.argument = 1;
- return Variant();
- }
-
- Ref<SignalAwaiterHandle> awaiter = *p_args[p_argcount - 1];
-
- if (awaiter.is_null()) {
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
- r_error.argument = p_argcount - 1;
- r_error.expected = Variant::OBJECT;
- return Variant();
- }
-
- awaiter->set_completed(true);
-
- int extra_argc = p_argcount - 1;
- MonoArray *extra_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), extra_argc);
-
- for (int i = 0; i < extra_argc; i++) {
- MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
- mono_array_set(extra_args, MonoObject *, i, boxed);
- }
-
- GDMonoUtils::GodotObject__AwaitedSignalCallback thunk = CACHED_METHOD_THUNK(GodotObject, _AwaitedSignalCallback);
-
- MonoObject *ex = NULL;
- thunk(mono_object, &extra_args, awaiter->get_target(), &ex);
-
- if (ex) {
- mono_print_unhandled_exception(ex);
- ERR_FAIL_V(Variant());
- }
-
- return Variant();
}
top = top->get_parent_class();
@@ -1239,8 +1270,11 @@ bool CSharpScript::_update_exports() {
for (int i = 0; i < fields.size(); i++) {
GDMonoField *field = fields[i];
- if (field->is_static() || field->get_visibility() != GDMono::PUBLIC)
+ if (field->is_static()) {
+ if (field->has_attribute(CACHED_CLASS(ExportAttribute)))
+ ERR_PRINTS("Cannot export field because it is static: " + top->get_full_name() + "." + field->get_name());
continue;
+ }
String name = field->get_name();
StringName cname = name;
@@ -1248,17 +1282,39 @@ bool CSharpScript::_update_exports() {
if (member_info.has(cname))
continue;
- Variant::Type type = GDMonoMarshal::managed_to_variant_type(field->get_type());
+ ManagedType field_type = field->get_type();
+ Variant::Type type = GDMonoMarshal::managed_to_variant_type(field_type);
if (field->has_attribute(CACHED_CLASS(ExportAttribute))) {
+ // Field has Export attribute
MonoObject *attr = field->get_attribute(CACHED_CLASS(ExportAttribute));
- // Field has Export attribute
- int hint = CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr);
- String hint_string = CACHED_FIELD(ExportAttribute, hint_string)->get_string_value(attr);
- int usage = CACHED_FIELD(ExportAttribute, usage)->get_int_value(attr);
+ PropertyHint hint;
+ String hint_string;
+
+ if (type == Variant::NIL) {
+ ERR_PRINTS("Unknown type of exported field: " + top->get_full_name() + "." + field->get_name());
+ continue;
+ } else if (type == Variant::INT && field_type.type_encoding == MONO_TYPE_VALUETYPE && mono_class_is_enum(field_type.type_class->get_raw())) {
+ type = Variant::INT;
+ hint = PROPERTY_HINT_ENUM;
+
+ Vector<MonoClassField *> fields = field_type.type_class->get_enum_fields();
+
+ for (int i = 0; i < fields.size(); i++) {
+ if (i > 0)
+ hint_string += ",";
+ hint_string += mono_field_get_name(fields[i]);
+ }
+ } else if (type == Variant::OBJECT && CACHED_CLASS(GodotReference)->is_assignable_from(field_type.type_class)) {
+ hint = PROPERTY_HINT_RESOURCE_TYPE;
+ hint_string = NATIVE_GDMONOCLASS_NAME(field_type.type_class);
+ } else {
+ hint = PropertyHint(CACHED_FIELD(ExportAttribute, hint)->get_int_value(attr));
+ hint_string = CACHED_FIELD(ExportAttribute, hint_string)->get_string_value(attr);
+ }
- PropertyInfo prop_info = PropertyInfo(type, name, PropertyHint(hint), hint_string, PropertyUsageFlags(usage));
+ PropertyInfo prop_info = PropertyInfo(type, name, hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
member_info[cname] = prop_info;
exported_members_cache.push_back(prop_info);
@@ -1392,12 +1448,15 @@ bool CSharpScript::can_instance() const {
#ifdef TOOLS_ENABLED
if (Engine::get_singleton()->is_editor_hint()) {
- if (_create_project_solution_if_needed()) {
- CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
- "Compile",
- ProjectSettings::get_singleton()->globalize_path(get_path()));
- } else {
- ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created.");
+
+ if (get_path().find("::") == -1) { // Ignore if built-in script. Can happen if the file is deleted...
+ if (_create_project_solution_if_needed()) {
+ CSharpProject::add_item(GodotSharpDirs::get_project_csproj_path(),
+ "Compile",
+ ProjectSettings::get_singleton()->globalize_path(get_path()));
+ } else {
+ ERR_PRINTS("Cannot add " + get_path() + " to the C# project because it could not be created.");
+ }
}
}
#endif
@@ -1679,16 +1738,6 @@ void CSharpScript::update_exports() {
#ifdef TOOLS_ENABLED
_update_exports();
-
- if (placeholders.size()) {
- Map<StringName, Variant> values;
- List<PropertyInfo> propnames;
- _update_exports_values(values, propnames);
-
- for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
- E->get()->update(propnames, values);
- }
- }
#endif
}
@@ -1915,7 +1964,7 @@ bool ResourceFormatSaverCSharpScript::recognize(const RES &p_resource) const {
CSharpLanguage::StringNameCache::StringNameCache() {
- _awaited_signal_callback = StaticCString::create("_AwaitedSignalCallback");
+ _signal_callback = StaticCString::create("_signal_callback");
_set = StaticCString::create("_set");
_get = StaticCString::create("_get");
_notification = StaticCString::create("_notification");
diff --git a/modules/mono/csharp_script.h b/modules/mono/csharp_script.h
index 3fcc3bdf04..6b8475fb61 100644
--- a/modules/mono/csharp_script.h
+++ b/modules/mono/csharp_script.h
@@ -225,7 +225,7 @@ class CSharpLanguage : public ScriptLanguage {
struct StringNameCache {
- StringName _awaited_signal_callback;
+ StringName _signal_callback;
StringName _set;
StringName _get;
StringName _notification;
@@ -242,6 +242,8 @@ public:
_FORCE_INLINE_ int get_language_index() { return lang_idx; }
void set_language_index(int p_idx);
+ _FORCE_INLINE_ const StringNameCache &get_string_names() { return string_names; }
+
_FORCE_INLINE_ static CSharpLanguage *get_singleton() { return singleton; }
bool debug_break(const String &p_error, bool p_allow_continue = true);
diff --git a/modules/mono/editor/bindings_generator.cpp b/modules/mono/editor/bindings_generator.cpp
index 704910c5b9..95e75f9103 100644
--- a/modules/mono/editor/bindings_generator.cpp
+++ b/modules/mono/editor/bindings_generator.cpp
@@ -108,36 +108,6 @@ const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN = "\t%0 %1_in
bool BindingsGenerator::verbose_output = false;
-static bool is_csharp_keyword(const String &p_name) {
-
- // Reserved keywords
-
- return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" ||
- p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" ||
- p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" ||
- p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" ||
- p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" ||
- p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" ||
- p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" ||
- p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" ||
- p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" ||
- p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" ||
- p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" ||
- p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" ||
- p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" ||
- p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" ||
- p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" ||
- p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" ||
- p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" ||
- p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" ||
- p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while";
-}
-
-inline static String escape_csharp_keyword(const String &p_name) {
-
- return is_csharp_keyword(p_name) ? "@" + p_name : p_name;
-}
-
static String snake_to_pascal_case(const String &p_identifier) {
String ret;
@@ -904,10 +874,6 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
return ERR_BUG;
}
- cs_file.push_back(MEMBER_BEGIN "private void _AwaitedSignalCallback(");
- cs_file.push_back(array_itype->get().cs_type);
- cs_file.push_back(" args, SignalAwaiter awaiter)\n" OPEN_BLOCK_L2 "awaiter.SignalCallback(args);\n" CLOSE_BLOCK_L2);
-
Map<String, TypeInterface>::Element *object_itype = obj_types.find("Object");
if (!object_itype) {
diff --git a/modules/mono/glue/cs_files/ExportAttribute.cs b/modules/mono/glue/cs_files/ExportAttribute.cs
index af3f603d6d..a4e7d447dd 100644
--- a/modules/mono/glue/cs_files/ExportAttribute.cs
+++ b/modules/mono/glue/cs_files/ExportAttribute.cs
@@ -7,13 +7,11 @@ namespace Godot
{
private int hint;
private string hint_string;
- private int usage;
- public ExportAttribute(int hint = GD.PROPERTY_HINT_NONE, string hint_string = "", int usage = GD.PROPERTY_USAGE_DEFAULT)
+ public ExportAttribute(int hint = GD.PROPERTY_HINT_NONE, string hint_string = "")
{
this.hint = hint;
this.hint_string = hint_string;
- this.usage = usage;
}
}
}
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 0a2010e99d..6bcf0e2355 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -33,6 +33,7 @@
#ifdef TOOLS_ENABLED
#include "editor/editor_settings.h"
+#include "os/dir_access.h"
#include "project_settings.h"
#include "version.h"
#endif
@@ -60,12 +61,20 @@ String _get_mono_user_dir() {
} else {
String settings_path;
- if (OS::get_singleton()->has_environment("APPDATA")) {
- String app_data = OS::get_singleton()->get_environment("APPDATA").replace("\\", "/");
- settings_path = app_data.plus_file(String(_MKSTR(VERSION_SHORT_NAME)).capitalize());
- } else if (OS::get_singleton()->has_environment("HOME")) {
- String home = OS::get_singleton()->get_environment("HOME");
- settings_path = home.plus_file("." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower());
+ String exe_dir = OS::get_singleton()->get_executable_path().get_base_dir();
+ DirAccessRef d = DirAccess::create_for_path(exe_dir);
+
+ if (d->file_exists("._sc_") || d->file_exists("_sc_")) {
+ // contain yourself
+ settings_path = exe_dir.plus_file("editor_data");
+ } else {
+ if (OS::get_singleton()->has_environment("APPDATA")) {
+ String app_data = OS::get_singleton()->get_environment("APPDATA").replace("\\", "/");
+ settings_path = app_data.plus_file(String(_MKSTR(VERSION_SHORT_NAME)).capitalize());
+ } else if (OS::get_singleton()->has_environment("HOME")) {
+ String home = OS::get_singleton()->get_environment("HOME");
+ settings_path = home.plus_file("." + String(_MKSTR(VERSION_SHORT_NAME)).to_lower());
+ }
}
return settings_path.plus_file("mono");
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index 0134ace5d7..77ba0ee90e 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -43,6 +43,14 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const {
return mono_class_is_assignable_from(mono_class, p_from->mono_class);
}
+String GDMonoClass::get_full_name() const {
+
+ String res = namespace_name;
+ if (res.length())
+ res += ".";
+ return res + class_name;
+}
+
GDMonoClass *GDMonoClass::get_parent_class() {
if (assembly) {
@@ -56,6 +64,30 @@ GDMonoClass *GDMonoClass::get_parent_class() {
return NULL;
}
+#ifdef TOOLS_ENABLED
+Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
+
+ bool class_is_enum = mono_class_is_enum(mono_class);
+ ERR_FAIL_COND_V(!class_is_enum, Vector<MonoClassField *>());
+
+ Vector<MonoClassField *> enum_fields;
+
+ void *iter = NULL;
+ MonoClassField *raw_field = NULL;
+ while ((raw_field = mono_class_get_fields(get_raw(), &iter)) != NULL) {
+ uint32_t field_flags = mono_field_get_flags(raw_field);
+
+ // Enums have an instance field named value__ which holds the value of the enum.
+ // Enum constants are static, so we will use this to ignore the value__ field.
+ if (field_flags & MONO_FIELD_ATTR_PUBLIC && field_flags & MONO_FIELD_ATTR_STATIC) {
+ enum_fields.push_back(raw_field);
+ }
+ }
+
+ return enum_fields;
+}
+#endif
+
bool GDMonoClass::has_method(const StringName &p_name) {
return get_method(p_name) != NULL;
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index 1e72553879..ef1ca425a7 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -98,8 +98,14 @@ public:
_FORCE_INLINE_ MonoClass *get_raw() const { return mono_class; }
_FORCE_INLINE_ const GDMonoAssembly *get_assembly() const { return assembly; }
+ String get_full_name() const;
+
GDMonoClass *get_parent_class();
+#ifdef TOOLS_ENABLED
+ Vector<MonoClassField *> get_enum_fields();
+#endif
+
bool has_method(const StringName &p_name);
bool has_attribute(GDMonoClass *p_attr_class);
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index c2d8eeaa32..81315ee87a 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -51,6 +51,7 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
{ \
m_type val = p_value.operator m_type(); \
mono_field_set_value(p_object, mono_field, &val); \
+ break; \
}
#define SET_FROM_ARRAY_AND_BREAK(m_type) \
@@ -137,6 +138,9 @@ void GDMonoField::set_value(MonoObject *p_object, const Variant &p_value) {
if (tclass == CACHED_CLASS(Plane))
SET_FROM_STRUCT_AND_BREAK(Plane);
+ if (mono_class_is_enum(tclass->get_raw()))
+ SET_FROM_PRIMITIVE(signed int);
+
ERR_EXPLAIN(String() + "Attempted to set the value of a field of unmarshallable type: " + tclass->get_name());
ERR_FAIL();
} break;
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 9a6c8f0cd6..77a1ef3cb0 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -112,6 +112,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
if (tclass == CACHED_CLASS(Plane))
return Variant::PLANE;
+
+ if (mono_class_is_enum(tclass->get_raw()))
+ return Variant::INT;
} break;
case MONO_TYPE_ARRAY:
@@ -165,9 +168,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type) {
return Variant::DICTIONARY;
}
} break;
+
+ default: {
+ } break;
}
- // No error, the caller will decide what to do in this case
+ // Unknown
return Variant::NIL;
}
@@ -299,6 +305,11 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty
if (tclass == CACHED_CLASS(Plane))
RETURN_BOXED_STRUCT(Plane, p_var);
+
+ if (mono_class_is_enum(tclass->get_raw())) {
+ int val = p_var->operator signed int();
+ return BOX_ENUM(tclass->get_raw(), val);
+ }
} break;
case MONO_TYPE_ARRAY:
@@ -515,6 +526,9 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
if (tclass == CACHED_CLASS(Plane))
RETURN_UNBOXED_STRUCT(Plane, p_obj);
+
+ if (mono_class_is_enum(tclass->get_raw()))
+ return unbox<int32_t>(p_obj);
} break;
case MONO_TYPE_ARRAY:
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 38dd22357d..9f403b787f 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -53,6 +53,7 @@ T unbox(MonoObject *p_obj) {
#define BOX_UINT8(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), &x)
#define BOX_BOOLEAN(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(bool), &x)
#define BOX_PTR(x) mono_value_box(mono_domain_get(), CACHED_CLASS_RAW(IntPtr), x)
+#define BOX_ENUM(m_enum_class, x) mono_value_box(mono_domain_get(), m_enum_class, &x)
Variant::Type managed_to_variant_type(const ManagedType &p_type);
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 5deca8e64d..53e45002c4 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -86,6 +86,7 @@ void MonoCache::clear_members() {
class_NodePath = NULL;
class_RID = NULL;
class_GodotObject = NULL;
+ class_GodotReference = NULL;
class_Node = NULL;
class_Control = NULL;
class_Spatial = NULL;
@@ -95,7 +96,6 @@ void MonoCache::clear_members() {
class_ExportAttribute = NULL;
field_ExportAttribute_hint = NULL;
field_ExportAttribute_hint_string = NULL;
- field_ExportAttribute_usage = NULL;
class_ToolAttribute = NULL;
class_RemoteAttribute = NULL;
class_SyncAttribute = NULL;
@@ -111,7 +111,7 @@ void MonoCache::clear_members() {
methodthunk_MarshalUtils_DictionaryToArrays = NULL;
methodthunk_MarshalUtils_ArraysToDictionary = NULL;
- methodthunk_GodotObject__AwaitedSignalCallback = NULL;
+ methodthunk_SignalAwaiter_SignalCallback = NULL;
methodthunk_SignalAwaiter_FailureCallback = NULL;
methodthunk_GodotTaskScheduler_Activate = NULL;
@@ -153,6 +153,7 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath));
CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(NodePath));
CACHE_CLASS_AND_CHECK(GodotObject, GODOT_API_CLASS(Object));
+ CACHE_CLASS_AND_CHECK(GodotReference, GODOT_API_CLASS(Reference));
CACHE_CLASS_AND_CHECK(Node, GODOT_API_CLASS(Node));
CACHE_CLASS_AND_CHECK(Control, GODOT_API_CLASS(Control));
CACHE_CLASS_AND_CHECK(Spatial, GODOT_API_CLASS(Spatial));
@@ -163,7 +164,6 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(ExportAttribute, GODOT_API_CLASS(ExportAttribute));
CACHE_FIELD_AND_CHECK(ExportAttribute, hint, CACHED_CLASS(ExportAttribute)->get_field("hint"));
CACHE_FIELD_AND_CHECK(ExportAttribute, hint_string, CACHED_CLASS(ExportAttribute)->get_field("hint_string"));
- CACHE_FIELD_AND_CHECK(ExportAttribute, usage, CACHED_CLASS(ExportAttribute)->get_field("usage"));
CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute));
CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute));
CACHE_CLASS_AND_CHECK(SyncAttribute, GODOT_API_CLASS(SyncAttribute));
@@ -178,7 +178,7 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryToArrays, (MarshalUtils_DictToArrays)CACHED_CLASS(MarshalUtils)->get_method("DictionaryToArrays", 3)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArraysToDictionary, (MarshalUtils_ArraysToDict)CACHED_CLASS(MarshalUtils)->get_method("ArraysToDictionary", 2)->get_thunk());
- CACHE_METHOD_THUNK_AND_CHECK(GodotObject, _AwaitedSignalCallback, (GodotObject__AwaitedSignalCallback)CACHED_CLASS(GodotObject)->get_method("_AwaitedSignalCallback", 2)->get_thunk());
+ CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, SignalCallback, (SignalAwaiter_SignalCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("SignalCallback", 1)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)->get_thunk());
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index f97f048aa9..e3af57e78a 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -42,7 +42,7 @@ namespace GDMonoUtils {
typedef MonoObject *(*MarshalUtils_DictToArrays)(MonoObject *, MonoArray **, MonoArray **, MonoObject **);
typedef MonoObject *(*MarshalUtils_ArraysToDict)(MonoArray *, MonoArray *, MonoObject **);
-typedef MonoObject *(*GodotObject__AwaitedSignalCallback)(MonoObject *, MonoArray **, MonoObject *, MonoObject **);
+typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray **, MonoObject **);
typedef MonoObject *(*SignalAwaiter_FailureCallback)(MonoObject *, MonoObject **);
typedef MonoObject *(*GodotTaskScheduler_Activate)(MonoObject *, MonoObject **);
@@ -88,6 +88,7 @@ struct MonoCache {
GDMonoClass *class_NodePath;
GDMonoClass *class_RID;
GDMonoClass *class_GodotObject;
+ GDMonoClass *class_GodotReference;
GDMonoClass *class_Node;
GDMonoClass *class_Control;
GDMonoClass *class_Spatial;
@@ -97,7 +98,6 @@ struct MonoCache {
GDMonoClass *class_ExportAttribute;
GDMonoField *field_ExportAttribute_hint;
GDMonoField *field_ExportAttribute_hint_string;
- GDMonoField *field_ExportAttribute_usage;
GDMonoClass *class_ToolAttribute;
GDMonoClass *class_RemoteAttribute;
GDMonoClass *class_SyncAttribute;
@@ -113,7 +113,7 @@ struct MonoCache {
MarshalUtils_DictToArrays methodthunk_MarshalUtils_DictionaryToArrays;
MarshalUtils_ArraysToDict methodthunk_MarshalUtils_ArraysToDictionary;
- GodotObject__AwaitedSignalCallback methodthunk_GodotObject__AwaitedSignalCallback;
+ SignalAwaiter_SignalCallback methodthunk_SignalAwaiter_SignalCallback;
SignalAwaiter_FailureCallback methodthunk_SignalAwaiter_FailureCallback;
GodotTaskScheduler_Activate methodthunk_GodotTaskScheduler_Activate;
@@ -164,7 +164,7 @@ String get_exception_name_and_message(MonoObject *p_ex);
} // GDMonoUtils
-#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field("nativeName")->get_value(NULL)))
+#define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoMarshal::mono_string_to_godot((MonoString *)m_class->get_field(BINDINGS_NATIVE_NAME_FIELD)->get_value(NULL)))
#define CACHED_CLASS(m_class) (GDMonoUtils::mono_cache.class_##m_class)
#define CACHED_CLASS_RAW(m_class) (GDMonoUtils::mono_cache.class_##m_class->get_raw())
diff --git a/modules/mono/signal_awaiter_utils.cpp b/modules/mono/signal_awaiter_utils.cpp
index 012dd119b1..7e99df29a1 100644
--- a/modules/mono/signal_awaiter_utils.cpp
+++ b/modules/mono/signal_awaiter_utils.cpp
@@ -29,6 +29,9 @@
/*************************************************************************/
#include "signal_awaiter_utils.h"
+#include "csharp_script.h"
+#include "mono_gd/gd_mono_class.h"
+#include "mono_gd/gd_mono_marshal.h"
#include "mono_gd/gd_mono_utils.h"
namespace SignalAwaiterUtils {
@@ -40,13 +43,20 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
uint32_t awaiter_handle = MonoGCHandle::make_strong_handle(p_awaiter);
Ref<SignalAwaiterHandle> sa_con = memnew(SignalAwaiterHandle(awaiter_handle));
+#ifdef DEBUG_ENABLED
+ sa_con->set_connection_target(p_target);
+#endif
+
Vector<Variant> binds;
binds.push_back(sa_con);
- Error err = p_source->connect(p_signal, p_target, "_AwaitedSignalCallback", binds, Object::CONNECT_ONESHOT);
+
+ Error err = p_source->connect(p_signal, sa_con.ptr(),
+ CSharpLanguage::get_singleton()->get_string_names()._signal_callback,
+ binds, Object::CONNECT_ONESHOT);
if (err != OK) {
- // set it as completed to prevent it from calling the failure callback when deleted
- // the awaiter will be aware of the failure by checking the returned error
+ // Set it as completed to prevent it from calling the failure callback when released.
+ // The awaiter will be aware of the failure by checking the returned error.
sa_con->set_completed(true);
}
@@ -54,11 +64,68 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
}
}
-SignalAwaiterHandle::SignalAwaiterHandle(uint32_t p_handle)
- : MonoGCHandle(p_handle) {
+Variant SignalAwaiterHandle::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
+
+#ifdef DEBUG_ENABLED
+ if (conn_target_id && !ObjectDB::get_instance(conn_target_id)) {
+ ERR_EXPLAIN("Resumed after await, but class instance is gone");
+ ERR_FAIL_V(Variant());
+ }
+#endif
+
+ if (p_argcount < 1) {
+ r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
+ r_error.argument = 1;
+ return Variant();
+ }
+
+ Ref<SignalAwaiterHandle> self = *p_args[p_argcount - 1];
+
+ if (self.is_null()) {
+ r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT;
+ r_error.argument = p_argcount - 1;
+ r_error.expected = Variant::OBJECT;
+ return Variant();
+ }
+
+ set_completed(true);
+
+ int signal_argc = p_argcount - 1;
+ MonoArray *signal_args = mono_array_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(MonoObject), signal_argc);
+
+ for (int i = 0; i < signal_argc; i++) {
+ MonoObject *boxed = GDMonoMarshal::variant_to_mono_object(*p_args[i]);
+ mono_array_set(signal_args, MonoObject *, i, boxed);
+ }
+
+ GDMonoUtils::SignalAwaiter_SignalCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, SignalCallback);
+
+ MonoObject *ex = NULL;
+ thunk(get_target(), &signal_args, &ex);
+
+ if (ex) {
+ mono_print_unhandled_exception(ex);
+ ERR_FAIL_V(Variant());
+ }
+
+ return Variant();
+}
+
+void SignalAwaiterHandle::_bind_methods() {
+
+ ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &SignalAwaiterHandle::_signal_callback, MethodInfo("_signal_callback"));
+}
+
+SignalAwaiterHandle::SignalAwaiterHandle(uint32_t p_managed_handle)
+ : MonoGCHandle(p_managed_handle) {
+
+#ifdef DEBUG_ENABLED
+ conn_target_id = 0;
+#endif
}
SignalAwaiterHandle::~SignalAwaiterHandle() {
+
if (!completed) {
GDMonoUtils::SignalAwaiter_FailureCallback thunk = CACHED_METHOD_THUNK(SignalAwaiter, FailureCallback);
diff --git a/modules/mono/signal_awaiter_utils.h b/modules/mono/signal_awaiter_utils.h
index 422ed4754f..0d615b5826 100644
--- a/modules/mono/signal_awaiter_utils.h
+++ b/modules/mono/signal_awaiter_utils.h
@@ -40,13 +40,30 @@ Error connect_signal_awaiter(Object *p_source, const String &p_signal, Object *p
class SignalAwaiterHandle : public MonoGCHandle {
+ GDCLASS(SignalAwaiterHandle, MonoGCHandle)
+
bool completed;
+#ifdef DEBUG_ENABLED
+ ObjectID conn_target_id;
+#endif
+
+ Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
+
+protected:
+ static void _bind_methods();
+
public:
_FORCE_INLINE_ bool is_completed() { return completed; }
_FORCE_INLINE_ void set_completed(bool p_completed) { completed = p_completed; }
- SignalAwaiterHandle(uint32_t p_handle);
+#ifdef DEBUG_ENABLED
+ _FORCE_INLINE_ void set_connection_target(Object *p_target) {
+ conn_target_id = p_target->get_instance_id();
+ }
+#endif
+
+ SignalAwaiterHandle(uint32_t p_managed_handle);
~SignalAwaiterHandle();
};
diff --git a/modules/mono/utils/string_utils.cpp b/modules/mono/utils/string_utils.cpp
index de1a60dbd1..f26663ea11 100644
--- a/modules/mono/utils/string_utils.cpp
+++ b/modules/mono/utils/string_utils.cpp
@@ -126,3 +126,32 @@ String sformat(const String &p_text, const Variant &p1, const Variant &p2, const
return new_string;
}
+
+bool is_csharp_keyword(const String &p_name) {
+
+ // Reserved keywords
+
+ return p_name == "abstract" || p_name == "as" || p_name == "base" || p_name == "bool" ||
+ p_name == "break" || p_name == "byte" || p_name == "case" || p_name == "catch" ||
+ p_name == "char" || p_name == "checked" || p_name == "class" || p_name == "const" ||
+ p_name == "continue" || p_name == "decimal" || p_name == "default" || p_name == "delegate" ||
+ p_name == "do" || p_name == "double" || p_name == "else" || p_name == "enum" ||
+ p_name == "event" || p_name == "explicit" || p_name == "extern" || p_name == "false" ||
+ p_name == "finally" || p_name == "fixed" || p_name == "float" || p_name == "for" ||
+ p_name == "forech" || p_name == "goto" || p_name == "if" || p_name == "implicit" ||
+ p_name == "in" || p_name == "int" || p_name == "interface" || p_name == "internal" ||
+ p_name == "is" || p_name == "lock" || p_name == "long" || p_name == "namespace" ||
+ p_name == "new" || p_name == "null" || p_name == "object" || p_name == "operator" ||
+ p_name == "out" || p_name == "override" || p_name == "params" || p_name == "private" ||
+ p_name == "protected" || p_name == "public" || p_name == "readonly" || p_name == "ref" ||
+ p_name == "return" || p_name == "sbyte" || p_name == "sealed" || p_name == "short" ||
+ p_name == "sizeof" || p_name == "stackalloc" || p_name == "static" || p_name == "string" ||
+ p_name == "struct" || p_name == "switch" || p_name == "this" || p_name == "throw" ||
+ p_name == "true" || p_name == "try" || p_name == "typeof" || p_name == "uint" || p_name == "ulong" ||
+ p_name == "unchecked" || p_name == "unsafe" || p_name == "ushort" || p_name == "using" ||
+ p_name == "virtual" || p_name == "volatile" || p_name == "void" || p_name == "while";
+}
+
+String escape_csharp_keyword(const String &p_name) {
+ return is_csharp_keyword(p_name) ? "@" + p_name : p_name;
+}
diff --git a/modules/mono/utils/string_utils.h b/modules/mono/utils/string_utils.h
index 2f2c3c2d89..a0d66ebdc3 100644
--- a/modules/mono/utils/string_utils.h
+++ b/modules/mono/utils/string_utils.h
@@ -35,4 +35,10 @@
String sformat(const String &p_text, const Variant &p1 = Variant(), const Variant &p2 = Variant(), const Variant &p3 = Variant(), const Variant &p4 = Variant(), const Variant &p5 = Variant());
+#ifdef TOOLS_ENABLED
+bool is_csharp_keyword(const String &p_name);
+
+String escape_csharp_keyword(const String &p_name);
+#endif
+
#endif // STRING_FORMAT_H
diff --git a/modules/openssl/stream_peer_openssl.cpp b/modules/openssl/stream_peer_openssl.cpp
index c19bdc4214..6d1d5485f3 100644
--- a/modules/openssl/stream_peer_openssl.cpp
+++ b/modules/openssl/stream_peer_openssl.cpp
@@ -30,7 +30,7 @@
#include "stream_peer_openssl.h"
// Compatibility with OpenSSL 1.1.0.
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
#define BIO_set_num(b, n)
#else
#define BIO_set_num(b, n) ((b)->num = (n))
@@ -269,7 +269,7 @@ int StreamPeerOpenSSL::_bio_puts(BIO *b, const char *str) {
return _bio_write(b, str, strlen(str));
}
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
BIO_METHOD *StreamPeerOpenSSL::_bio_method = NULL;
BIO_METHOD *StreamPeerOpenSSL::_get_bio_method() {
@@ -568,7 +568,7 @@ void StreamPeerOpenSSL::initialize_ssl() {
load_certs_func = _load_certs;
_create = _create_func;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
CRYPTO_malloc_init(); // Initialize malloc, free, etc for OpenSSL's use
#endif
SSL_library_init(); // Initialize OpenSSL's SSL libraries
diff --git a/modules/openssl/stream_peer_openssl.h b/modules/openssl/stream_peer_openssl.h
index 535114058d..ad09564447 100644
--- a/modules/openssl/stream_peer_openssl.h
+++ b/modules/openssl/stream_peer_openssl.h
@@ -53,7 +53,7 @@ private:
static int _bio_gets(BIO *b, char *buf, int len);
static int _bio_puts(BIO *b, const char *str);
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
static BIO_METHOD *_bio_method;
#else
static BIO_METHOD _bio_method;
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
index 27ea310780..5c252bda86 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.cpp
@@ -129,7 +129,6 @@ AudioStreamPlaybackOGGVorbis::~AudioStreamPlaybackOGGVorbis() {
Ref<AudioStreamPlayback> AudioStreamOGGVorbis::instance_playback() {
Ref<AudioStreamPlaybackOGGVorbis> ovs;
- printf("instance at %p, data %p\n", this, data);
ERR_FAIL_COND_V(data == NULL, ovs);
@@ -208,8 +207,6 @@ void AudioStreamOGGVorbis::set_data(const PoolVector<uint8_t> &p_data) {
break;
}
}
-
- printf("create at %p, data %p\n", this, data);
}
PoolVector<uint8_t> AudioStreamOGGVorbis::get_data() const {
diff --git a/modules/visual_script/visual_script_builtin_funcs.cpp b/modules/visual_script/visual_script_builtin_funcs.cpp
index 972be5f5a4..4b294325dc 100644
--- a/modules/visual_script/visual_script_builtin_funcs.cpp
+++ b/modules/visual_script/visual_script_builtin_funcs.cpp
@@ -65,6 +65,8 @@ const char *VisualScriptBuiltinFunc::func_name[VisualScriptBuiltinFunc::FUNC_MAX
"decimals",
"stepify",
"lerp",
+ "inverse_lerp",
+ "range_lerp",
"dectime",
"randomize",
"randi",
@@ -194,9 +196,12 @@ int VisualScriptBuiltinFunc::get_func_argument_count(BuiltinFunc p_func) {
case COLORN:
return 2;
case MATH_LERP:
+ case MATH_INVERSE_LERP:
case MATH_DECTIME:
case LOGIC_CLAMP:
return 3;
+ case MATH_RANGE_LERP:
+ return 5;
case FUNC_MAX: {
}
}
@@ -297,7 +302,26 @@ PropertyInfo VisualScriptBuiltinFunc::get_input_value_port_info(int p_idx) const
return PropertyInfo(Variant::REAL, "to");
else
return PropertyInfo(Variant::REAL, "weight");
-
+ } break;
+ case MATH_INVERSE_LERP: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "from");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "to");
+ else
+ return PropertyInfo(Variant::REAL, "value");
+ } break;
+ case MATH_RANGE_LERP: {
+ if (p_idx == 0)
+ return PropertyInfo(Variant::REAL, "value");
+ else if (p_idx == 1)
+ return PropertyInfo(Variant::REAL, "istart");
+ else if (p_idx == 2)
+ return PropertyInfo(Variant::REAL, "istop");
+ else if (p_idx == 3)
+ return PropertyInfo(Variant::REAL, "ostart");
+ else
+ return PropertyInfo(Variant::REAL, "ostop");
} break;
case MATH_DECTIME: {
if (p_idx == 0)
@@ -495,6 +519,8 @@ PropertyInfo VisualScriptBuiltinFunc::get_output_value_port_info(int p_idx) cons
} break;
case MATH_STEPIFY:
case MATH_LERP:
+ case MATH_INVERSE_LERP:
+ case MATH_RANGE_LERP:
case MATH_DECTIME: {
t = Variant::REAL;
@@ -795,6 +821,22 @@ void VisualScriptBuiltinFunc::exec_func(BuiltinFunc p_func, const Variant **p_in
VALIDATE_ARG_NUM(2);
*r_return = Math::lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
} break;
+ case VisualScriptBuiltinFunc::MATH_INVERSE_LERP: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ *r_return = Math::inverse_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2]);
+ } break;
+ case VisualScriptBuiltinFunc::MATH_RANGE_LERP: {
+
+ VALIDATE_ARG_NUM(0);
+ VALIDATE_ARG_NUM(1);
+ VALIDATE_ARG_NUM(2);
+ VALIDATE_ARG_NUM(3);
+ VALIDATE_ARG_NUM(4);
+ *r_return = Math::range_lerp((double)*p_inputs[0], (double)*p_inputs[1], (double)*p_inputs[2], (double)*p_inputs[3], (double)*p_inputs[4]);
+ } break;
case VisualScriptBuiltinFunc::MATH_DECTIME: {
VALIDATE_ARG_NUM(0);
@@ -1203,6 +1245,8 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(MATH_DECIMALS);
BIND_ENUM_CONSTANT(MATH_STEPIFY);
BIND_ENUM_CONSTANT(MATH_LERP);
+ BIND_ENUM_CONSTANT(MATH_INVERSE_LERP);
+ BIND_ENUM_CONSTANT(MATH_RANGE_LERP);
BIND_ENUM_CONSTANT(MATH_DECTIME);
BIND_ENUM_CONSTANT(MATH_RANDOMIZE);
BIND_ENUM_CONSTANT(MATH_RAND);
@@ -1236,6 +1280,11 @@ void VisualScriptBuiltinFunc::_bind_methods() {
BIND_ENUM_CONSTANT(FUNC_MAX);
}
+VisualScriptBuiltinFunc::VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func) {
+
+ this->func = func;
+}
+
VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() {
func = MATH_SIN;
@@ -1244,9 +1293,7 @@ VisualScriptBuiltinFunc::VisualScriptBuiltinFunc() {
template <VisualScriptBuiltinFunc::BuiltinFunc func>
static Ref<VisualScriptNode> create_builtin_func_node(const String &p_name) {
- Ref<VisualScriptBuiltinFunc> node;
- node.instance();
- node->set_func(func);
+ Ref<VisualScriptBuiltinFunc> node = memnew(VisualScriptBuiltinFunc(func));
return node;
}
@@ -1282,6 +1329,8 @@ void register_visual_script_builtin_func_node() {
VisualScriptLanguage::singleton->add_register_func("functions/built_in/decimals", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECIMALS>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/stepify", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_STEPIFY>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_LERP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/inverse_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_INVERSE_LERP>);
+ VisualScriptLanguage::singleton->add_register_func("functions/built_in/range_lerp", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANGE_LERP>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/dectime", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_DECTIME>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/randomize", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RANDOMIZE>);
VisualScriptLanguage::singleton->add_register_func("functions/built_in/rand", create_builtin_func_node<VisualScriptBuiltinFunc::MATH_RAND>);
diff --git a/modules/visual_script/visual_script_builtin_funcs.h b/modules/visual_script/visual_script_builtin_funcs.h
index 97ab307039..5758d23e8f 100644
--- a/modules/visual_script/visual_script_builtin_funcs.h
+++ b/modules/visual_script/visual_script_builtin_funcs.h
@@ -64,6 +64,8 @@ public:
MATH_DECIMALS,
MATH_STEPIFY,
MATH_LERP,
+ MATH_INVERSE_LERP,
+ MATH_RANGE_LERP,
MATH_DECTIME,
MATH_RANDOMIZE,
MATH_RAND,
@@ -130,6 +132,7 @@ public:
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);
+ VisualScriptBuiltinFunc(VisualScriptBuiltinFunc::BuiltinFunc func);
VisualScriptBuiltinFunc();
};
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index 47ef0182dc..03015df844 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -809,7 +809,7 @@ void VisualScriptEditor::_update_members() {
ti->set_text(0, E->get());
Variant var = script->get_variable_default_value(E->get());
- ti->set_suffix(0, "=" + String(var));
+ ti->set_suffix(0, "= " + String(var));
ti->set_icon(0, type_icons[script->get_variable_info(E->get()).type]);
ti->set_selectable(0, true);
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 5a34fc3cd9..d3cd839cf3 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -532,6 +532,7 @@ String VisualScriptOperator::get_text() const {
L"A or B", //OP_OR,
L"A xor B", //OP_XOR,
L"not A", //OP_NOT,
+ L"A in B", //OP_IN,
};
return op_names[op];
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 053dfa631a..59fefc498f 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -191,6 +191,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
protected void onMainPause() {}
protected void onMainResume() {}
protected void onMainDestroy() {}
+ protected boolean onMainBackPressed() { return false; }
protected void onGLDrawFrame(GL10 gl) {}
protected void onGLSurfaceChanged(GL10 gl, int width, int height) {} // singletons will always miss first onGLSurfaceChanged call
@@ -767,9 +768,16 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
*/
@Override public void onBackPressed() {
+ boolean shouldQuit = true;
+
+ for(int i=0;i<singleton_count;i++) {
+ if (singletons[i].onMainBackPressed()) {
+ shouldQuit = false;
+ }
+ }
System.out.printf("** BACK REQUEST!\n");
- if (mView != null) {
+ if (shouldQuit && mView != null) {
mView.queueEvent(new Runnable() {
@Override
public void run() {
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index 3c2ad7cc59..b807b952d4 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -285,13 +285,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener {
@Override public boolean onKeyDown(final int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
- queueEvent(new Runnable() {
- @Override
- public void run() {
- GodotLib.back();
- }
- });
-
+ activity.onBackPressed();
// press 'back' button should not terminate program
//normal handle 'back' event in game logic
return true;
diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp
index 2b943df5ba..80d0bd78d5 100644
--- a/platform/haiku/context_gl_haiku.cpp
+++ b/platform/haiku/context_gl_haiku.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "context_gl_haiku.h"
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
ContextGL_Haiku::ContextGL_Haiku(HaikuDirectWindow *p_window) {
window = p_window;
diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h
index 40daf43ab9..a9a13a2b7f 100644
--- a/platform/haiku/context_gl_haiku.h
+++ b/platform/haiku/context_gl_haiku.h
@@ -30,7 +30,7 @@
#ifndef CONTEXT_GL_HAIKU_H
#define CONTEXT_GL_HAIKU_H
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
#include "drivers/gl_context/context_gl.h"
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 9f2f88bb4e..1d52752f21 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -105,7 +105,7 @@ void OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_
window->SetFlags(flags);
}
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
context_gl = memnew(ContextGL_Haiku(window));
context_gl->initialize();
context_gl->make_current();
@@ -161,7 +161,7 @@ void OS_Haiku::finalize() {
memdelete(input);
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
memdelete(context_gl);
#endif
}
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index d2fafb9129..d929f7e43b 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -60,7 +60,7 @@ private:
AudioDriverMediaKit driver_media_kit;
#endif
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
ContextGL_Haiku *context_gl;
#endif
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index c91781ce1d..0507ef19d6 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -397,7 +397,7 @@ Error EditorExportPlatformIOS::_codesign(String p_file, void *p_userdata) {
codesign_args.push_back("-s");
codesign_args.push_back(data->preset->get(data->debug ? "application/code_sign_identity_debug" : "application/code_sign_identity_release"));
codesign_args.push_back(p_file);
- return OS::get_singleton()->execute("/usr/bin/codesign", codesign_args, true);
+ return OS::get_singleton()->execute("codesign", codesign_args, true);
}
return OK;
}
@@ -592,7 +592,15 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
return err;
#ifdef OSX_ENABLED
- ep.step("Making .xcarchive", 2);
+ ep.step("Code-signing dylibs", 2);
+ DirAccess *dylibs_dir = DirAccess::open(dest_dir + "dylibs");
+ ERR_FAIL_COND_V(!dylibs_dir, ERR_CANT_OPEN);
+ CodesignData codesign_data(p_preset, p_debug);
+ err = _walk_dir_recursive(dylibs_dir, _codesign, &codesign_data);
+ memdelete(dylibs_dir);
+ ERR_FAIL_COND_V(err, err);
+
+ ep.step("Making .xcarchive", 3);
String archive_path = p_path.get_basename() + ".xcarchive";
List<String> archive_args;
archive_args.push_back("-project");
@@ -608,15 +616,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
archive_args.push_back("archive");
archive_args.push_back("-archivePath");
archive_args.push_back(archive_path);
- err = OS::get_singleton()->execute("/usr/bin/xcodebuild", archive_args, true);
- ERR_FAIL_COND_V(err, err);
-
- ep.step("Code-signing dylibs", 3);
- DirAccess *dylibs_dir = DirAccess::open(archive_path + "/Products/Applications/" + binary_name + ".app/dylibs");
- ERR_FAIL_COND_V(!dylibs_dir, ERR_CANT_OPEN);
- CodesignData codesign_data(p_preset, p_debug);
- err = _walk_dir_recursive(dylibs_dir, _codesign, &codesign_data);
- memdelete(dylibs_dir);
+ err = OS::get_singleton()->execute("xcodebuild", archive_args, true);
ERR_FAIL_COND_V(err, err);
ep.step("Making .ipa", 4);
@@ -628,7 +628,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
export_args.push_back(dest_dir + "export_options.plist");
export_args.push_back("-exportPath");
export_args.push_back(dest_dir);
- err = OS::get_singleton()->execute("/usr/bin/xcodebuild", export_args, true);
+ err = OS::get_singleton()->execute("xcodebuild", export_args, true);
ERR_FAIL_COND_V(err, err);
#else
print_line(".ipa can only be built on macOS. Leaving XCode project without building the package.");
diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h
index c0a7830fe9..21f40fa362 100644
--- a/platform/iphone/game_center.h
+++ b/platform/iphone/game_center.h
@@ -43,11 +43,13 @@ class GameCenter : public Object {
List<Variant> pending_events;
- bool connected;
+ bool authenticated;
+
+ void return_connect_error(const char *p_error_description);
public:
- Error connect();
- bool is_connected();
+ void connect();
+ bool is_authenticated();
Error post_score(Variant p_score);
Error award_achievement(Variant p_params);
@@ -55,6 +57,7 @@ public:
void request_achievements();
void request_achievement_descriptions();
Error show_game_center(Variant p_params);
+ Error request_identity_verification_signature();
void game_center_closed();
diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm
index 3955b9f0aa..531b80eee3 100644
--- a/platform/iphone/game_center.mm
+++ b/platform/iphone/game_center.mm
@@ -49,8 +49,7 @@ extern "C" {
GameCenter *GameCenter::instance = NULL;
void GameCenter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("connect"), &GameCenter::connect);
- ClassDB::bind_method(D_METHOD("is_connected"), &GameCenter::is_connected);
+ ClassDB::bind_method(D_METHOD("is_authenticated"), &GameCenter::is_authenticated);
ClassDB::bind_method(D_METHOD("post_score"), &GameCenter::post_score);
ClassDB::bind_method(D_METHOD("award_achievement"), &GameCenter::award_achievement);
@@ -58,24 +57,41 @@ void GameCenter::_bind_methods() {
ClassDB::bind_method(D_METHOD("request_achievements"), &GameCenter::request_achievements);
ClassDB::bind_method(D_METHOD("request_achievement_descriptions"), &GameCenter::request_achievement_descriptions);
ClassDB::bind_method(D_METHOD("show_game_center"), &GameCenter::show_game_center);
+ ClassDB::bind_method(D_METHOD("request_identity_verification_signature"), &GameCenter::request_identity_verification_signature);
ClassDB::bind_method(D_METHOD("get_pending_event_count"), &GameCenter::get_pending_event_count);
ClassDB::bind_method(D_METHOD("pop_pending_event"), &GameCenter::pop_pending_event);
};
-Error GameCenter::connect() {
+void GameCenter::return_connect_error(const char *p_error_description) {
+ authenticated = false;
+ Dictionary ret;
+ ret["type"] = "authentication";
+ ret["result"] = "error";
+ ret["error_code"] = 0;
+ ret["error_description"] = p_error_description;
+ pending_events.push_back(ret);
+}
+
+void GameCenter::connect() {
//if this class isn't available, game center isn't implemented
if ((NSClassFromString(@"GKLocalPlayer")) == nil) {
- GameCenter::get_singleton()->connected = false;
- return ERR_UNAVAILABLE;
+ return_connect_error("GameCenter not available");
+ return;
}
GKLocalPlayer *player = [GKLocalPlayer localPlayer];
- ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE);
+ if (![player respondsToSelector:@selector(authenticateHandler)]) {
+ return_connect_error("GameCenter doesn't respond to 'authenticateHandler'");
+ return;
+ }
ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
- ERR_FAIL_COND_V(!root_controller, FAILED);
+ if (!root_controller) {
+ return_connect_error("Window doesn't have root ViewController");
+ return;
+ }
// This handler is called several times. First when the view needs to be shown, then again
// after the view is cancelled or the user logs in. Or if the user's already logged in, it's
@@ -90,23 +106,21 @@ Error GameCenter::connect() {
if (player.isAuthenticated) {
ret["result"] = "ok";
ret["player_id"] = [player.playerID UTF8String];
- GameCenter::get_singleton()->connected = true;
+ GameCenter::get_singleton()->authenticated = true;
} else {
ret["result"] = "error";
ret["error_code"] = error.code;
ret["error_description"] = [error.localizedDescription UTF8String];
- GameCenter::get_singleton()->connected = false;
+ GameCenter::get_singleton()->authenticated = false;
};
pending_events.push_back(ret);
};
});
-
- return OK;
};
-bool GameCenter::is_connected() {
- return connected;
+bool GameCenter::is_authenticated() {
+ return authenticated;
};
Error GameCenter::post_score(Variant p_score) {
@@ -117,7 +131,7 @@ Error GameCenter::post_score(Variant p_score) {
String category = params["category"];
NSString *cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease];
- GKScore *reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease];
+ GKScore *reporter = [[[GKScore alloc] initWithLeaderboardIdentifier:cat_str] autorelease];
reporter.value = score;
ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE);
@@ -326,6 +340,34 @@ Error GameCenter::show_game_center(Variant p_params) {
return OK;
};
+Error GameCenter::request_identity_verification_signature() {
+
+ ERR_FAIL_COND_V(!is_authenticated(), ERR_UNAUTHORIZED);
+
+ GKLocalPlayer *player = [GKLocalPlayer localPlayer];
+ [player generateIdentityVerificationSignatureWithCompletionHandler:^(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) {
+
+ Dictionary ret;
+ ret["type"] = "identity_verification_signature";
+ if (error == nil) {
+ ret["result"] = "ok";
+ ret["public_key_url"] = [publicKeyUrl.absoluteString UTF8String];
+ ret["signature"] = [[signature base64EncodedStringWithOptions:0] UTF8String];
+ ret["salt"] = [[salt base64EncodedStringWithOptions:0] UTF8String];
+ ret["timestamp"] = timestamp;
+ ret["player_id"] = [player.playerID UTF8String];
+ } else {
+ ret["result"] = "error";
+ ret["error_code"] = error.code;
+ ret["error_description"] = [error.localizedDescription UTF8String];
+ };
+
+ pending_events.push_back(ret);
+ }];
+
+ return OK;
+};
+
void GameCenter::game_center_closed() {
Dictionary ret;
@@ -354,7 +396,7 @@ GameCenter *GameCenter::get_singleton() {
GameCenter::GameCenter() {
ERR_FAIL_COND(instance != NULL);
instance = this;
- connected = false;
+ authenticated = false;
};
GameCenter::~GameCenter(){};
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index 74f8d80a76..1d737879f6 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -39,24 +39,41 @@ JavaScript *JavaScript::get_singleton() {
return singleton;
}
+extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_poolbytearray_and_open_write(PoolByteArray *p_arr, PoolByteArray::Write *r_write, int p_len) {
+
+ p_arr->resize(p_len);
+ *r_write = p_arr->write();
+ return r_write->ptr();
+}
+
Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
union {
- int i;
+ bool b;
double d;
char *s;
} js_data[4];
+
+ PoolByteArray arr;
+ PoolByteArray::Write arr_write;
+
/* clang-format off */
Variant::Type return_type = static_cast<Variant::Type>(EM_ASM_INT({
+ const CODE = $0;
+ const USE_GLOBAL_EXEC_CONTEXT = $1;
+ const PTR = $2;
+ const ELEM_LEN = $3;
+ const BYTEARRAY_PTR = $4;
+ const BYTEARRAY_WRITE_PTR = $5;
var eval_ret;
try {
- if ($3) { // p_use_global_exec_context
+ if (USE_GLOBAL_EXEC_CONTEXT) {
// indirect eval call grants global execution context
var global_eval = eval;
- eval_ret = global_eval(UTF8ToString($2));
+ eval_ret = global_eval(UTF8ToString(CODE));
} else {
- eval_ret = eval(UTF8ToString($2));
+ eval_ret = eval(UTF8ToString(CODE));
}
} catch (e) {
Module.printErr(e);
@@ -66,16 +83,11 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
switch (typeof eval_ret) {
case 'boolean':
- // bitwise op yields 32-bit int
- setValue($0, eval_ret|0, 'i32');
+ setValue(PTR, eval_ret, 'i32');
return 1; // BOOL
case 'number':
- if ((eval_ret|0)===eval_ret) {
- setValue($0, eval_ret|0, 'i32');
- return 2; // INT
- }
- setValue($0, eval_ret, 'double');
+ setValue(PTR, eval_ret, 'double');
return 3; // REAL
case 'string':
@@ -85,7 +97,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
if (array_ptr===0) {
throw new Error('String allocation failed (probably out of memory)');
}
- setValue($0, array_ptr|0 , '*');
+ setValue(PTR, array_ptr , '*');
stringToUTF8(eval_ret, array_ptr, array_len);
return 4; // STRING
} catch (e) {
@@ -102,41 +114,50 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
break;
}
- else if (typeof eval_ret.x==='number' && typeof eval_ret.y==='number') {
- setValue($0, eval_ret.x, 'double');
- setValue($0+$1, eval_ret.y, 'double');
+ if (ArrayBuffer.isView(eval_ret) && !(eval_ret instanceof Uint8Array)) {
+ eval_ret = new Uint8Array(eval_ret.buffer);
+ }
+ else if (eval_ret instanceof ArrayBuffer) {
+ eval_ret = new Uint8Array(eval_ret);
+ }
+ if (eval_ret instanceof Uint8Array) {
+ var bytes_ptr = ccall('resize_poolbytearray_and_open_write', 'number', ['number', 'number' ,'number'], [BYTEARRAY_PTR, BYTEARRAY_WRITE_PTR, eval_ret.length]);
+ HEAPU8.set(eval_ret, bytes_ptr);
+ return 20; // POOL_BYTE_ARRAY
+ }
+
+ if (typeof eval_ret.x==='number' && typeof eval_ret.y==='number') {
+ setValue(PTR, eval_ret.x, 'double');
+ setValue(PTR + ELEM_LEN, eval_ret.y, 'double');
if (typeof eval_ret.z==='number') {
- setValue($0+$1*2, eval_ret.z, 'double');
+ setValue(PTR + ELEM_LEN*2, eval_ret.z, 'double');
return 7; // VECTOR3
}
else if (typeof eval_ret.width==='number' && typeof eval_ret.height==='number') {
- setValue($0+$1*2, eval_ret.width, 'double');
- setValue($0+$1*3, eval_ret.height, 'double');
+ setValue(PTR + ELEM_LEN*2, eval_ret.width, 'double');
+ setValue(PTR + ELEM_LEN*3, eval_ret.height, 'double');
return 6; // RECT2
}
return 5; // VECTOR2
}
- else if (typeof eval_ret.r==='number' && typeof eval_ret.g==='number' && typeof eval_ret.b==='number') {
- // assume 8-bit rgb components since we're on the web
- setValue($0, eval_ret.r, 'double');
- setValue($0+$1, eval_ret.g, 'double');
- setValue($0+$1*2, eval_ret.b, 'double');
- setValue($0+$1*3, typeof eval_ret.a==='number' ? eval_ret.a : 1, 'double');
+ if (typeof eval_ret.r === 'number' && typeof eval_ret.g === 'number' && typeof eval_ret.b === 'number') {
+ setValue(PTR, eval_ret.r, 'double');
+ setValue(PTR + ELEM_LEN, eval_ret.g, 'double');
+ setValue(PTR + ELEM_LEN*2, eval_ret.b, 'double');
+ setValue(PTR + ELEM_LEN*3, typeof eval_ret.a === 'number' ? eval_ret.a : 1, 'double');
return 14; // COLOR
}
break;
}
return 0; // NIL
- }, js_data, sizeof *js_data, p_code.utf8().get_data(), p_use_global_exec_context));
+ }, p_code.utf8().get_data(), p_use_global_exec_context, js_data, sizeof *js_data, &arr, &arr_write));
/* clang-format on */
switch (return_type) {
case Variant::BOOL:
- return !!js_data->i;
- case Variant::INT:
- return js_data->i;
+ return js_data->b;
case Variant::REAL:
return js_data->d;
case Variant::STRING: {
@@ -153,7 +174,10 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) {
case Variant::RECT2:
return Rect2(js_data[0].d, js_data[1].d, js_data[2].d, js_data[3].d);
case Variant::COLOR:
- return Color(js_data[0].d / 255., js_data[1].d / 255., js_data[2].d / 255., js_data[3].d);
+ return Color(js_data[0].d, js_data[1].d, js_data[2].d, js_data[3].d);
+ case Variant::POOL_BYTE_ARRAY:
+ arr_write = PoolByteArray::Write();
+ return arr;
}
return Variant();
}
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index 0ba0ddec7d..8a6f1dc04c 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -244,7 +244,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese
args.push_back(p_path);
String str;
- Error err = OS::get_singleton()->execute("/usr/bin/codesign", args, true, NULL, &str, NULL, true);
+ Error err = OS::get_singleton()->execute("codesign", args, true, NULL, &str, NULL, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("codesign: " + str);
@@ -271,7 +271,7 @@ Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const Strin
args.push_back(p_app_path_name);
String str;
- Error err = OS::get_singleton()->execute("/usr/bin/hdiutil", args, true, NULL, &str, NULL, true);
+ Error err = OS::get_singleton()->execute("hdiutil", args, true, NULL, &str, NULL, true);
ERR_FAIL_COND_V(err != OK, err);
print_line("hdiutil returned: " + str);
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 04b38f280d..ffec2af933 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -12,6 +12,9 @@ def get_name():
def can_build():
+ # Doesn't build against Godot 3.0 for now, disable to avoid confusing users
+ return False
+
if (os.name != "posix" or sys.platform == "darwin"):
return False
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
index 8640f27699..64b6d202a1 100644
--- a/platform/windows/context_gl_win.cpp
+++ b/platform/windows/context_gl_win.cpp
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED)
+#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
//
// C++ Implementation: context_gl_x11
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
index 912d4d0133..0059cbc311 100644
--- a/platform/windows/context_gl_win.h
+++ b/platform/windows/context_gl_win.h
@@ -27,7 +27,7 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) || defined(GLES2_ENABLED)
+#if defined(OPENGL_ENABLED) || defined(GLES2_ENABLED)
//
// C++ Interface: context_gl_x11
//
diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp
index 57f8e965de..76bb5d5723 100644
--- a/platform/windows/key_mapping_win.cpp
+++ b/platform/windows/key_mapping_win.cpp
@@ -50,7 +50,7 @@ static _WinTranslatePair _vk_to_keycode[] = {
{ KEY_CONTROL, VK_CONTROL }, //(0x11)
- { KEY_MENU, VK_MENU }, //(0x12)
+ { KEY_ALT, VK_MENU }, //(0x12)
{ KEY_PAUSE, VK_PAUSE }, //(0x13)
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 0cc9734119..4f9d4a84b9 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -30,7 +30,7 @@
#include "context_gl_x11.h"
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index ba01b51d59..c37bac5e9b 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -35,7 +35,7 @@
*/
#ifdef X11_ENABLED
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
#include "drivers/gl_context/context_gl.h"
#include "os/os.h"
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 1f7f67fe10..8c68c9ffd1 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -239,6 +239,9 @@ def configure(env):
if (platform.system() == "Linux"):
env.Append(LIBS=['dl'])
+ if (platform.system().find("BSD") >= 0):
+ env.Append(LIBS=['execinfo'])
+
## Cross-compilation
if (is64 and env["bits"] == "32"):
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 041666a594..48e2d8f81e 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -35,7 +35,11 @@
#include "servers/physics/physics_server_sw.h"
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
+
+#ifdef HAVE_MNTENT
#include <mntent.h>
+#endif
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -235,7 +239,7 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
// maybe contextgl wants to be in charge of creating the window
//print_line("def videomode "+itos(current_videomode.width)+","+itos(current_videomode.height));
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, true));
context_gl->initialize();
@@ -533,7 +537,7 @@ void OS_X11::finalize() {
XUnmapWindow(x11_display, x11_window);
XDestroyWindow(x11_display, x11_window);
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
memdelete(context_gl);
#endif
for (int i = 0; i < CURSOR_MAX; i++) {
@@ -1939,7 +1943,7 @@ Error OS_X11::shell_open(String p_uri) {
Error ok;
List<String> args;
args.push_back(p_uri);
- ok = execute("/usr/bin/xdg-open", args, false);
+ ok = execute("xdg-open", args, false);
if (ok == OK)
return OK;
ok = execute("gnome-open", args, false);
@@ -2003,7 +2007,7 @@ String OS_X11::get_system_dir(SystemDir p_dir) const {
String pipe;
List<String> arg;
arg.push_back(xdgparam);
- Error err = const_cast<OS_X11 *>(this)->execute("/usr/bin/xdg-user-dir", arg, true, NULL, &pipe);
+ Error err = const_cast<OS_X11 *>(this)->execute("xdg-user-dir", arg, true, NULL, &pipe);
if (err != OK)
return ".";
return pipe.strip_edges();
@@ -2053,7 +2057,7 @@ void OS_X11::alert(const String &p_alert, const String &p_title) {
args.push_back(p_title);
args.push_back(p_alert);
- execute("/usr/bin/xmessage", args, true);
+ execute("xmessage", args, true);
}
void OS_X11::set_icon(const Ref<Image> &p_icon) {
@@ -2182,6 +2186,7 @@ static String get_mountpoint(const String &p_path) {
return "";
}
+#ifdef HAVE_MNTENT
dev_t dev = s.st_dev;
FILE *fd = setmntent("/proc/mounts", "r");
if (!fd) {
@@ -2199,6 +2204,7 @@ static String get_mountpoint(const String &p_path) {
}
endmntent(fd);
+#endif
return "";
}
@@ -2236,12 +2242,12 @@ Error OS_X11::move_to_trash(const String &p_path) {
List<String> args;
args.push_back("-p");
args.push_back(trashcan);
- Error err = execute("/bin/mkdir", args, true);
+ Error err = execute("mkdir", args, true);
if (err == OK) {
List<String> args2;
args2.push_back(p_path);
args2.push_back(trashcan);
- err = execute("/bin/mv", args2, true);
+ err = execute("mv", args2, true);
}
return err;
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 0d5c272ed4..36355f11bc 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -94,7 +94,7 @@ class OS_X11 : public OS_Unix {
int xdnd_version;
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+#if defined(OPENGL_ENABLED)
ContextGL_X11 *context_gl;
#endif
//Rasterizer *rasterizer;
diff --git a/scene/2d/navigation_polygon.cpp b/scene/2d/navigation_polygon.cpp
index 352ec3b300..35f94bff59 100644
--- a/scene/2d/navigation_polygon.cpp
+++ b/scene/2d/navigation_polygon.cpp
@@ -329,7 +329,7 @@ void NavigationPolygonInstance::_notification(int p_what) {
break;
}
- c = Object::cast_to<Node2D>(get_parent());
+ c = Object::cast_to<Node2D>(c->get_parent());
}
} break;
diff --git a/scene/2d/parallax_background.cpp b/scene/2d/parallax_background.cpp
index 0ddcb7b51b..a13ce6278e 100644
--- a/scene/2d/parallax_background.cpp
+++ b/scene/2d/parallax_background.cpp
@@ -49,8 +49,8 @@ void ParallaxBackground::_notification(int p_what) {
void ParallaxBackground::_camera_moved(const Transform2D &p_transform) {
- set_scroll_offset(p_transform.get_origin());
set_scroll_scale(p_transform.get_scale().dot(Vector2(0.5, 0.5)));
+ set_scroll_offset(p_transform.get_origin() / p_transform.get_scale());
}
void ParallaxBackground::set_scroll_scale(float p_scale) {
diff --git a/scene/3d/arvr_nodes.cpp b/scene/3d/arvr_nodes.cpp
index c6b6c02129..064a249190 100644
--- a/scene/3d/arvr_nodes.cpp
+++ b/scene/3d/arvr_nodes.cpp
@@ -204,7 +204,7 @@ void ARVRController::_notification(int p_what) {
int mask = 1;
// check button states
for (int i = 0; i < 16; i++) {
- bool was_pressed = (button_states && mask) == mask;
+ bool was_pressed = (button_states & mask) == mask;
bool is_pressed = Input::get_singleton()->is_joy_button_pressed(joy_id, i);
if (!was_pressed && is_pressed) {
@@ -336,6 +336,7 @@ String ARVRController::get_configuration_warning() const {
ARVRController::ARVRController() {
controller_id = 0;
is_active = true;
+ button_states = 0;
};
ARVRController::~ARVRController(){
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index 80c706898d..4e19214c59 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -462,8 +462,6 @@ void ParticlesMaterial::finish_shaders() {
void ParticlesMaterial::_update_shader() {
- print_line("updating shader");
-
dirty_materials.remove(&element);
MaterialKey mk = _compute_key();
@@ -587,298 +585,294 @@ void ParticlesMaterial::_update_shader() {
//need a random function
code += "\n\n";
code += "float rand_from_seed(inout uint seed) {\n";
- code += " int k;\n";
- code += " int s = int(seed);\n";
- code += " if (s == 0)\n";
+ code += " int k;\n";
+ code += " int s = int(seed);\n";
+ code += " if (s == 0)\n";
code += " s = 305420679;\n";
- code += " k = s / 127773;\n";
- code += " s = 16807 * (s - k * 127773) - 2836 * k;\n";
- code += " if (s < 0)\n";
- code += " s += 2147483647;\n";
- code += " seed = uint(s);\n";
- code += " return float(seed % uint(65536))/65535.0;\n";
+ code += " k = s / 127773;\n";
+ code += " s = 16807 * (s - k * 127773) - 2836 * k;\n";
+ code += " if (s < 0)\n";
+ code += " s += 2147483647;\n";
+ code += " seed = uint(s);\n";
+ code += " return float(seed % uint(65536))/65535.0;\n";
code += "}\n";
+ code += "\n";
+
//improve seed quality
code += "uint hash(uint x) {\n";
- code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
- code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
- code += " x = (x >> uint(16)) ^ x;\n";
- code += " return x;\n";
+ code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
+ code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n";
+ code += " x = (x >> uint(16)) ^ x;\n";
+ code += " return x;\n";
code += "}\n";
- code += "void vertex() {\n\n";
code += "\n";
- code += " uint base_number=NUMBER/uint(trail_divisor);\n";
- code += " uint alt_seed=hash(base_number+uint(1)+RANDOM_SEED);\n";
- code += " float angle_rand=rand_from_seed(alt_seed);\n";
- code += " float scale_rand=rand_from_seed(alt_seed);\n";
- code += " float hue_rot_rand=rand_from_seed(alt_seed);\n";
- code += " float anim_offset_rand=rand_from_seed(alt_seed);\n";
- code += "\n";
- code += "\n";
- code += "\n";
+ code += "void vertex() {\n";
+ code += " uint base_number = NUMBER/uint(trail_divisor);\n";
+ code += " uint alt_seed = hash(base_number+uint(1)+RANDOM_SEED);\n";
+ code += " float angle_rand = rand_from_seed(alt_seed);\n";
+ code += " float scale_rand = rand_from_seed(alt_seed);\n";
+ code += " float hue_rot_rand = rand_from_seed(alt_seed);\n";
+ code += " float anim_offset_rand = rand_from_seed(alt_seed);\n";
code += "\n";
+
if (emission_shape >= EMISSION_SHAPE_POINTS) {
- code += " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n";
- code += " ivec2 emission_tex_size = textureSize( emission_texture_points, 0 );\n";
- code += " ivec2 emission_tex_ofs = ivec2( point % emission_tex_size.x, point / emission_tex_size.x );\n";
+ code += " int point = min(emission_texture_point_count-1,int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n";
+ code += " ivec2 emission_tex_size = textureSize( emission_texture_points, 0 );\n";
+ code += " ivec2 emission_tex_ofs = ivec2( point % emission_tex_size.x, point / emission_tex_size.x );\n";
}
- code += " if (RESTART) {\n";
+ code += " if (RESTART) {\n";
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";
+ 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 = 0.0;\n";
if (tex_parameters[PARAM_ANGLE].is_valid())
- code += " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r;\n";
+ code += " float tex_angle = textureLod(angle_texture,vec2(0.0,0.0),0.0).r;\n";
else
- code += " float tex_angle = 0.0;\n";
+ code += " float tex_angle = 0.0;\n";
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";
+ 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 = 0.0;\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " float angle1 = (rand_from_seed(alt_seed)*2.0-1.0)*spread/180.0*3.1416;\n";
- code += " vec3 rot=vec3( cos(angle1), sin(angle1),0.0 );\n";
- code += " VELOCITY=(rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n";
+ code += " float angle1 = (rand_from_seed(alt_seed)*2.0-1.0)*spread/180.0*3.1416;\n";
+ code += " vec3 rot = vec3( cos(angle1), sin(angle1),0.0 );\n";
+ code += " VELOCITY = (rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n";
} else {
//initiate velocity spread in 3D
- code += " float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n";
- code += " float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n";
- code += " vec3 rot_xz=vec3( sin(angle1), 0.0, cos(angle1) );\n";
- code += " vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n";
- code += " VELOCITY=(rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n";
+ code += " float angle1 = rand_from_seed(alt_seed)*spread*3.1416;\n";
+ code += " float angle2 = rand_from_seed(alt_seed)*20.0*3.1416; // make it more random like\n";
+ code += " vec3 rot_xz = vec3( sin(angle1), 0.0, cos(angle1) );\n";
+ code += " vec3 rot = vec3( cos(angle2)*rot_xz.x,sin(angle2)*rot_xz.x, rot_xz.z);\n";
+ code += " VELOCITY = (rot*initial_linear_velocity+rot*initial_linear_velocity_random*rand_from_seed(alt_seed));\n";
}
- code += " float base_angle=(initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
- code += " CUSTOM.x=base_angle*3.1416/180.0;\n"; //angle
- code += " CUSTOM.y=0.0;\n"; //phase
- code += " CUSTOM.z=(anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1)
+ code += " float base_angle = (initial_angle+tex_angle)*mix(1.0,angle_rand,initial_angle_random);\n";
+ code += " CUSTOM.x = base_angle*3.1416/180.0;\n"; //angle
+ code += " CUSTOM.y = 0.0;\n"; //phase
+ code += " CUSTOM.z = (anim_offset+tex_anim_offset)*mix(1.0,anim_offset_rand,anim_offset_random);\n"; //animation offset (0-1)
switch (emission_shape) {
case EMISSION_SHAPE_POINT: {
//do none
} break;
case EMISSION_SHAPE_SPHERE: {
- code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius;\n";
+ code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0 ))*emission_sphere_radius;\n";
} break;
case EMISSION_SHAPE_BOX: {
- code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents;\n";
+ code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0-1.0, rand_from_seed(alt_seed) * 2.0-1.0)*emission_box_extents;\n";
} break;
case EMISSION_SHAPE_POINTS:
case EMISSION_SHAPE_DIRECTED_POINTS: {
- code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs,0).xyz;\n";
+ code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs,0).xyz;\n";
if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) {
if (flags[FLAG_DISABLE_Z]) {
- code += " mat2 rotm;";
- code += " rotm[0]=texelFetch(emission_texture_normal, emission_tex_ofs,0).xy;\n";
- code += " rotm[1]=rotm[0].yx * vec2(1.0,-1.0);\n";
- code += " VELOCITY.xy = rotm * VELOCITY.xy;\n";
+ code += " mat2 rotm;";
+ code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs,0).xy;\n";
+ code += " rotm[1] = rotm[0].yx * vec2(1.0,-1.0);\n";
+ code += " VELOCITY.xy = rotm * VELOCITY.xy;\n";
} else {
- code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs,0).xyz;\n";
- code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n";
- code += " vec3 tangent = normalize(cross(v0, normal));\n";
- code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
- code += " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY;\n";
+ code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs,0).xyz;\n";
+ code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n";
+ code += " vec3 tangent = normalize(cross(v0, normal));\n";
+ code += " vec3 bitangent = normalize(cross(tangent, normal));\n";
+ code += " VELOCITY = mat3(tangent,bitangent,normal) * VELOCITY;\n";
}
}
} break;
}
- code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz;\n";
- code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
+ code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY,0.0)).xyz;\n";
+ code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " VELOCITY.z=0.0;\n";
- code += " TRANSFORM[3].z=0.0;\n";
+ code += " VELOCITY.z = 0.0;\n";
+ code += " TRANSFORM[3].z = 0.0;\n";
}
- code += " } else {\n";
+ code += " } else {\n";
- code += " CUSTOM.y+=DELTA/LIFETIME;\n";
+ code += " CUSTOM.y += DELTA/LIFETIME;\n";
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid())
- code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_linear_velocity = textureLod(linear_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_linear_velocity = 0.0;\n";
+ code += " float tex_linear_velocity = 0.0;\n";
if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid())
- code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_orbit_velocity = 0.0;\n";
+ code += " float tex_orbit_velocity = 0.0;\n";
if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid())
- code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_angular_velocity = textureLod(angular_velocity_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_angular_velocity = 0.0;\n";
+ code += " float tex_angular_velocity = 0.0;\n";
if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid())
- code += " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_linear_accel = textureLod(linear_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_linear_accel = 0.0;\n";
+ code += " float tex_linear_accel = 0.0;\n";
if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid())
- code += " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_radial_accel = textureLod(radial_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_radial_accel = 0.0;\n";
+ code += " float tex_radial_accel = 0.0;\n";
if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid())
- code += " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_tangent_accel = textureLod(tangent_accel_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_tangent_accel = 0.0;\n";
+ code += " float tex_tangent_accel = 0.0;\n";
if (tex_parameters[PARAM_DAMPING].is_valid())
- code += " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_damping = textureLod(damping_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_damping = 0.0;\n";
+ code += " float tex_damping = 0.0;\n";
if (tex_parameters[PARAM_ANGLE].is_valid())
- code += " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_angle = textureLod(angle_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_angle = 0.0;\n";
+ code += " float tex_angle = 0.0;\n";
if (tex_parameters[PARAM_ANIM_SPEED].is_valid())
- code += " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_anim_speed = textureLod(anim_speed_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_anim_speed = 0.0;\n";
+ code += " float tex_anim_speed = 0.0;\n";
if (tex_parameters[PARAM_ANIM_OFFSET].is_valid())
- code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_anim_offset = textureLod(anim_offset_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_anim_offset = 0.0;\n";
+ code += " float tex_anim_offset = 0.0;\n";
- code += " vec3 force = gravity; \n";
- code += " vec3 pos = TRANSFORM[3].xyz; \n";
+ code += " vec3 force = gravity; \n";
+ code += " vec3 pos = TRANSFORM[3].xyz; \n";
if (flags[FLAG_DISABLE_Z]) {
- code += " pos.z=0.0; \n";
+ 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 += " //apply radial acceleration\n";
- code += " vec3 org = vec3(0.0);\n";
- code += " // if (!p_system->local_coordinates)\n";
- code += " //org=p_transform.origin;\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 += " //apply tangential acceleration;\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 += " //apply radial acceleration\n";
+ code += " vec3 org = vec3(0.0);\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 += " //apply tangential acceleration;\n";
if (flags[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),radial_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+tex_tangent_accel)*mix(1.0,rand_from_seed(alt_seed),radial_accel_random)) : 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),radial_accel_random)) : vec3(0.0);\n";
+ 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),radial_accel_random)) : vec3(0.0);\n";
}
- code += " //apply attractor forces\n";
- code += " VELOCITY+=force * DELTA;\n";
+ code += " //apply attractor forces\n";
+ code += " VELOCITY += force * DELTA;\n";
if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
- code += " VELOCITY=normalize(VELOCITY)*tex_linear_velocity;\n";
+ code += " VELOCITY = normalize(VELOCITY)*tex_linear_velocity;\n";
}
- code += " if (damping+tex_damping>0.0) {\n";
- code += " \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 += " v -= damp * DELTA;\n";
- code += " if (v<0.0) {\n";
- code += " VELOCITY=vec3(0.0);\n";
- code += " } else {\n";
- 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 += " CUSTOM.x=base_angle*3.1416/180.0;\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 += " if (damping + tex_damping > 0.0) {\n";
+ code += " \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 += " v -= damp * DELTA;\n";
+ code += " if (v < 0.0) {\n";
+ code += " VELOCITY = vec3(0.0);\n";
+ code += " } else {\n";
+ 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 += " CUSTOM.x = base_angle*3.1416/180.0;\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
if (flags[FLAG_ANIM_LOOP]) {
- code += " CUSTOM.z=mod(CUSTOM.z,1.0);\n"; //loop
+ code += " CUSTOM.z = mod(CUSTOM.z,1.0);\n"; //loop
} else {
- code += " CUSTOM.z=clamp(CUSTOM.z,0.0,1.0);\n"; //0 to 1 only
+ code += " CUSTOM.z = clamp(CUSTOM.z,0.0,1.0);\n"; //0 to 1 only
}
- code += " }\n";
+ code += " }\n";
//apply color
//apply hue rotation
if (tex_parameters[PARAM_SCALE].is_valid())
- code += " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_scale = textureLod(scale_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_scale = 1.0;\n";
+ code += " float tex_scale = 1.0;\n";
if (tex_parameters[PARAM_HUE_VARIATION].is_valid())
- code += " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
+ code += " float tex_hue_variation = textureLod(hue_variation_texture,vec2(CUSTOM.y,0.0),0.0).r;\n";
else
- code += " float tex_hue_variation = 0.0;\n";
-
- code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\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";
- code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
- code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
- code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n";
- code += " \n";
- code += " mat4( vec4(0.701, -0.587, -0.114, 0.0),\n";
- code += " vec4(-0.299, 0.413, -0.114, 0.0),\n";
- code += " vec4(-0.300, -0.588, 0.886, 0.0),\n";
- code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n";
- code += "\n";
- code += " mat4( vec4(0.168, 0.330, -0.497, 0.0),\n";
- code += " vec4(-0.328, 0.035, 0.292, 0.0),\n";
- code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
- code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
+ code += " float tex_hue_variation = 0.0;\n";
+
+ code += " float hue_rot_angle = (hue_variation+tex_hue_variation)*3.1416*2.0*mix(1.0,hue_rot_rand*2.0-1.0,hue_variation_random);\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";
+ code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
+ code += " vec4(0.299, 0.587, 0.114, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n";
+ code += " mat4( vec4(0.701, -0.587, -0.114, 0.0),\n";
+ code += " vec4(-0.299, 0.413, -0.114, 0.0),\n";
+ code += " vec4(-0.300, -0.588, 0.886, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n";
+ code += " mat4( vec4(0.168, 0.330, -0.497, 0.0),\n";
+ code += " vec4(-0.328, 0.035, 0.292, 0.0),\n";
+ code += " vec4(1.250, -1.050, -0.203, 0.0),\n";
+ code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n";
if (color_ramp.is_valid()) {
- code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n";
+ code += " COLOR = textureLod(color_ramp,vec2(CUSTOM.y,0.0),0.0) * hue_rot_mat;\n";
} else {
- code += " COLOR = color_value * hue_rot_mat;\n";
+ code += " COLOR = color_value * hue_rot_mat;\n";
}
if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) {
- code += " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0);\n";
+ code += " COLOR*= texelFetch(emission_texture_color,emission_tex_ofs,0);\n";
}
if (trail_color_modifier.is_valid()) {
- code += "if (trail_divisor>1) { COLOR*=textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); }\n";
+ code += " if (trail_divisor > 1) { COLOR *= textureLod(trail_color_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0); }\n";
}
code += "\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " TRANSFORM[0]=vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n";
- code += " TRANSFORM[1]=vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n";
- code += " TRANSFORM[2]=vec4(0.0,0.0,1.0,0.0);\n";
+ code += " TRANSFORM[0] = vec4(cos(CUSTOM.x),-sin(CUSTOM.x),0.0,0.0);\n";
+ code += " TRANSFORM[1] = vec4(sin(CUSTOM.x),cos(CUSTOM.x),0.0,0.0);\n";
+ code += " TRANSFORM[2] = vec4(0.0,0.0,1.0,0.0);\n";
} else {
//orient particle Y towards velocity
if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) {
- code += " if (length(VELOCITY)>0.0) {TRANSFORM[1].xyz=normalize(VELOCITY);} else {TRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);}\n";
- code += " if (TRANSFORM[1].xyz==normalize(TRANSFORM[0].xyz)) {\n";
- code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
- code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
- code += " } else {\n";
- code += "\tTRANSFORM[2].xyz=normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
- code += "\tTRANSFORM[0].xyz=normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
- code += " }\n";
+ code += " if (length(VELOCITY) > 0.0) { TRANSFORM[1].xyz = normalize(VELOCITY); } else { TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz); }\n";
+ code += " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) {\n";
+ code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
+ code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
+ code += " } else {\n";
+ code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz),normalize(TRANSFORM[1].xyz)));\n";
+ code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz),normalize(TRANSFORM[2].xyz)));\n";
+ code += " }\n";
} else {
- code += "\tTRANSFORM[0].xyz=normalize(TRANSFORM[0].xyz);\n";
- code += "\tTRANSFORM[1].xyz=normalize(TRANSFORM[1].xyz);\n";
- code += "\tTRANSFORM[2].xyz=normalize(TRANSFORM[2].xyz);\n";
+ code += " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);\n";
+ code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n";
+ code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n";
}
//turn particle by rotation in Y
if (flags[FLAG_ROTATE_Y]) {
- code += "\tTRANSFORM = 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 = 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";
}
}
//scale by scale
- code += " float base_scale=mix(scale*tex_scale,1.0,scale_random*scale_rand);\n";
+ code += " float base_scale = mix(scale*tex_scale,1.0,scale_random*scale_rand);\n";
if (trail_size_modifier.is_valid()) {
- code += "if (trail_divisor>1) { base_scale*=textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \n";
+ code += " if (trail_divisor > 1) { base_scale *= textureLod(trail_size_modifier,vec2(float(int(NUMBER)%trail_divisor)/float(trail_divisor-1),0.0),0.0).r; } \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;\n";
+ code += " TRANSFORM[1].xyz *= base_scale;\n";
+ code += " TRANSFORM[2].xyz *= base_scale;\n";
if (flags[FLAG_DISABLE_Z]) {
- code += " VELOCITY.z=0.0;\n";
- code += " TRANSFORM[3].z=0.0;\n";
+ code += " VELOCITY.z = 0.0;\n";
+ code += " TRANSFORM[3].z = 0.0;\n";
}
code += "}\n";
code += "\n";
@@ -913,9 +907,7 @@ void ParticlesMaterial::_queue_shader_change() {
if (material_mutex)
material_mutex->lock();
- print_line("queuing change");
if (!element.in_list()) {
- print_line("not in list, adding");
dirty_materials.add(&element);
}
@@ -1329,6 +1321,12 @@ Vector3 ParticlesMaterial::get_gravity() const {
return gravity;
}
+RID ParticlesMaterial::get_shader_rid() const {
+
+ ERR_FAIL_COND_V(!shader_map.has(current_key), RID());
+ return shader_map[current_key].shader;
+}
+
void ParticlesMaterial::_validate_property(PropertyInfo &property) const {
if (property.name == "color" && color_ramp.is_valid()) {
diff --git a/scene/3d/particles.h b/scene/3d/particles.h
index 2c109d6ec8..e3109f470f 100644
--- a/scene/3d/particles.h
+++ b/scene/3d/particles.h
@@ -388,6 +388,8 @@ public:
static void finish_shaders();
static void flush_changes();
+ RID get_shader_rid() const;
+
ParticlesMaterial();
~ParticlesMaterial();
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 05963acf56..2ecb184733 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -405,6 +405,10 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, float
if (a->value_track_get_update_mode(i) == Animation::UPDATE_CONTINUOUS || (p_delta == 0 && a->value_track_get_update_mode(i) == Animation::UPDATE_DISCRETE)) { //delta == 0 means seek
Variant value = a->value_track_interpolate(i, p_time);
+
+ if (value == Variant())
+ continue;
+
//thanks to trigger mode, this should be solved now..
/*
if (p_delta==0 && value.get_type()==Variant::STRING)
@@ -529,12 +533,12 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, float p_delta, f
if (&cd == &playback.current) {
- if (!backwards && cd.pos < len && next_pos == len /*&& playback.blend.empty()*/) {
+ if (!backwards && cd.pos <= len && next_pos == len /*&& playback.blend.empty()*/) {
//playback finished
end_notify = true;
}
- if (backwards && cd.pos > 0 && next_pos == 0 /*&& playback.blend.empty()*/) {
+ if (backwards && cd.pos >= 0 && next_pos == 0 /*&& playback.blend.empty()*/) {
//playback finished
end_notify = true;
}
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index e58cbe373b..dbd7c1bbc0 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -40,12 +40,15 @@ void ColorPicker::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
//sample->set_texture(get_icon("color_sample"));
+ btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
+ bt_add_preset->set_icon(get_icon("add_preset"));
_update_controls();
} break;
case NOTIFICATION_ENTER_TREE: {
btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
+ bt_add_preset->set_icon(get_icon("add_preset"));
_update_color();
} break;
@@ -601,7 +604,6 @@ ColorPicker::ColorPicker()
preset->connect("draw", this, "_update_presets");
bt_add_preset = memnew(Button);
- bt_add_preset->set_icon(get_icon("add_preset"));
bt_add_preset->set_tooltip(TTR("Add current color as a preset"));
bt_add_preset->connect("pressed", this, "_add_preset_pressed");
bbc->add_child(bt_add_preset);
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 0d3cccc2b5..946a8c47a3 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -284,7 +284,6 @@ void GraphEdit::_notification(int p_what) {
zoom_reset->set_icon(get_icon("reset"));
zoom_plus->set_icon(get_icon("more"));
snap_button->set_icon(get_icon("snap"));
- //zoom_icon->set_texture( get_icon("Zoom", "EditorIcons"));
}
if (p_what == NOTIFICATION_DRAW) {
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index a034c7224f..623a110263 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -489,7 +489,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
if (mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, pos);
+ emit_signal("item_rmb_selected", i, get_local_mouse_position());
}
} else {
@@ -500,7 +500,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
if (items[i].selected && mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, pos);
+ emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else {
bool selected = !items[i].selected;
@@ -515,7 +515,7 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
if (mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, pos);
+ emit_signal("item_rmb_selected", i, get_local_mouse_position());
} else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) {
emit_signal("item_activated", i);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index c2ce2a633e..07b49538d9 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -354,7 +354,7 @@ int RichTextLabel::_process_line(ItemFrame *p_frame, const Vector2 &p_ofs, int &
cw = font->get_char_size(c[i], c[i + 1]).x;
draw_rect(Rect2(p_ofs.x + pofs, p_ofs.y + y, cw, lh), selection_bg);
if (visible)
- font->draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - (fh - ascent)), c[i], c[i + 1], selection_fg);
+ font->draw_char(ci, p_ofs + Point2(align_ofs + pofs, y + lh - (fh - ascent)), c[i], c[i + 1], override_selected_font_color ? selection_fg : color);
} else {
if (visible)
@@ -1376,6 +1376,16 @@ bool RichTextLabel::is_meta_underlined() const {
return underline_meta;
}
+void RichTextLabel::set_override_selected_font_color(bool p_override_selected_font_color) {
+
+ override_selected_font_color = p_override_selected_font_color;
+}
+
+bool RichTextLabel::is_overriding_selected_font_color() const {
+
+ return override_selected_font_color;
+}
+
void RichTextLabel::set_offset(int p_pixel) {
vscroll->set_value(p_pixel);
@@ -1906,6 +1916,9 @@ void RichTextLabel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_meta_underline", "enable"), &RichTextLabel::set_meta_underline);
ClassDB::bind_method(D_METHOD("is_meta_underlined"), &RichTextLabel::is_meta_underlined);
+ ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &RichTextLabel::set_override_selected_font_color);
+ ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &RichTextLabel::is_overriding_selected_font_color);
+
ClassDB::bind_method(D_METHOD("set_scroll_active", "active"), &RichTextLabel::set_scroll_active);
ClassDB::bind_method(D_METHOD("is_scroll_active"), &RichTextLabel::is_scroll_active);
@@ -1948,6 +1961,7 @@ void RichTextLabel::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "visible_characters", PROPERTY_HINT_RANGE, "-1,128000,1"), "set_visible_characters", "get_visible_characters");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "percent_visible", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_percent_visible", "get_percent_visible");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_SIGNAL(MethodInfo("meta_clicked", PropertyInfo(Variant::NIL, "meta", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NIL_IS_VARIANT)));
@@ -2003,6 +2017,7 @@ RichTextLabel::RichTextLabel() {
tab_size = 4;
default_align = ALIGN_LEFT;
underline_meta = true;
+ override_selected_font_color = false;
scroll_visible = false;
scroll_follow = false;
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 24c1e5eb59..f9e37b1094 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -221,6 +221,7 @@ private:
int tab_size;
bool underline_meta;
+ bool override_selected_font_color;
Align default_align;
@@ -313,6 +314,9 @@ public:
void set_meta_underline(bool p_underline);
bool is_meta_underlined() const;
+ void set_override_selected_font_color(bool p_override_selected_font_color);
+ bool is_overriding_selected_font_color() const;
+
void set_scroll_active(bool p_active);
bool is_scroll_active() const;
diff --git a/scene/gui/separator.cpp b/scene/gui/separator.cpp
index 3db234f7cc..55d837458a 100644
--- a/scene/gui/separator.cpp
+++ b/scene/gui/separator.cpp
@@ -32,7 +32,11 @@
Size2 Separator::get_minimum_size() const {
Size2 ms(3, 3);
- ms[orientation] = get_constant("separation");
+ if (orientation == VERTICAL) {
+ ms.x = get_constant("separation");
+ } else { // HORIZONTAL
+ ms.y = get_constant("separation");
+ }
return ms;
}
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index 116e0ac354..e88742a3e3 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -157,6 +157,12 @@ void Slider::_notification(int p_what) {
mouse_inside = false;
update();
} break;
+ case NOTIFICATION_VISIBILITY_CHANGED: // fallthrough
+ case NOTIFICATION_EXIT_TREE: {
+
+ mouse_inside = false;
+ grab.active = false;
+ } break;
case NOTIFICATION_DRAW: {
RID ci = get_canvas_item();
Size2i size = get_size();
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 6e50614e8f..cfe924ecd4 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -94,15 +94,20 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
// Handle navigation buttons.
if (buttons_visible_cache) {
+ int popup_ofs = 0;
+ if (popup) {
+ popup_ofs = menu->get_width();
+ }
+
Ref<Texture> increment = get_icon("increment");
Ref<Texture> decrement = get_icon("decrement");
- if (pos.x > size.width - increment->get_width()) {
+ if (pos.x > size.width - increment->get_width() - popup_ofs) {
if (last_tab_cache < tabs.size() - 1) {
first_tab_cache += 1;
update();
}
return;
- } else if (pos.x > size.width - increment->get_width() - decrement->get_width()) {
+ } else if (pos.x > size.width - increment->get_width() - decrement->get_width() - popup_ofs) {
if (first_tab_cache > 0) {
first_tab_cache -= 1;
update();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 33c29547be..de69406b37 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -732,10 +732,6 @@ void TextEdit::_notification(int p_what) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg, ofs_y, xmargin_end - xmargin_beg, get_row_height()), cache.mark_color);
}
- if (line == cursor.line) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_end, get_row_height()), cache.current_line_color);
- }
-
if (text.is_breakpoint(line) && !draw_breakpoint_gutter) {
#ifdef TOOLS_ENABLED
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(xmargin_beg, ofs_y + get_row_height() - EDSCALE, xmargin_end - xmargin_beg, EDSCALE), cache.breakpoint_color);
@@ -764,6 +760,7 @@ void TextEdit::_notification(int p_what) {
cache.font->draw(ci, Point2(cache.style_normal->get_margin(MARGIN_LEFT) + cache.breakpoint_gutter_width, ofs_y + cache.font->get_ascent()), fc, cache.line_number_color);
}
+ //loop through charcters in one line
for (int j = 0; j < str.length(); j++) {
//look for keyword
@@ -952,10 +949,22 @@ void TextEdit::_notification(int p_what) {
}
}
+ //current line highlighting
bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || j >= selection.from_column) && (line < selection.to_line || j < selection.to_column));
+ if (line == cursor.line) {
+ if (j == 0)
+ //first char
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, (char_ofs + char_margin), get_row_height()), cache.current_line_color);
+ else if (j == str.length() - 1)
+ //last char
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(char_ofs + char_margin + char_w, ofs_y, xmargin_end - (char_ofs + char_margin + char_w), get_row_height()), cache.current_line_color);
+
+ if (!in_selection)
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin, ofs_y), Size2i(char_w, get_row_height())), cache.current_line_color);
+ }
+
if (in_selection) {
- //inside selection!
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2i(char_ofs + char_margin, ofs_y), Size2i(char_w, get_row_height())), cache.selection_color);
}
@@ -998,7 +1007,7 @@ void TextEdit::_notification(int p_what) {
if (brace_open_mismatch)
color = cache.brace_mismatch_color;
- cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), '_', str[j + 1], in_selection ? cache.font_selected_color : color);
+ cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color);
}
if (
@@ -1007,7 +1016,7 @@ void TextEdit::_notification(int p_what) {
if (brace_close_mismatch)
color = cache.brace_mismatch_color;
- cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), '_', str[j + 1], in_selection ? cache.font_selected_color : color);
+ cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), '_', str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color);
}
}
@@ -1066,15 +1075,15 @@ void TextEdit::_notification(int p_what) {
}
if (str[j] >= 32) {
- int w = cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), str[j], str[j + 1], in_selection ? cache.font_selected_color : color);
+ int w = cache.font->draw_char(ci, Point2i(char_ofs + char_margin, ofs_y + ascent), str[j], str[j + 1], in_selection && override_selected_font_color ? cache.font_selected_color : color);
if (underlined) {
- draw_rect(Rect2(char_ofs + char_margin, ofs_y + ascent + 2, w, 1), in_selection ? cache.font_selected_color : color);
+ draw_rect(Rect2(char_ofs + char_margin, ofs_y + ascent + 2, w, 1), in_selection && override_selected_font_color ? cache.font_selected_color : color);
}
}
else if (draw_tabs && str[j] == '\t') {
int yofs = (get_row_height() - cache.tab_icon->get_height()) / 2;
- cache.tab_icon->draw(ci, Point2(char_ofs + char_margin, ofs_y + yofs), in_selection ? cache.font_selected_color : color);
+ cache.tab_icon->draw(ci, Point2(char_ofs + char_margin, ofs_y + yofs), in_selection && override_selected_font_color ? cache.font_selected_color : color);
}
char_ofs += char_w;
@@ -4256,6 +4265,13 @@ bool TextEdit::is_drawing_tabs() const {
return draw_tabs;
}
+void TextEdit::set_override_selected_font_color(bool p_override_selected_font_color) {
+ override_selected_font_color = p_override_selected_font_color;
+}
+bool TextEdit::is_overriding_selected_font_color() const {
+ return override_selected_font_color;
+}
+
void TextEdit::set_insert_mode(bool p_enabled) {
insert_mode = p_enabled;
update();
@@ -4821,6 +4837,9 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_highlight_all_occurrences", "enable"), &TextEdit::set_highlight_all_occurrences);
ClassDB::bind_method(D_METHOD("is_highlight_all_occurrences_enabled"), &TextEdit::is_highlight_all_occurrences_enabled);
+ ClassDB::bind_method(D_METHOD("set_override_selected_font_color", "override"), &TextEdit::set_override_selected_font_color);
+ ClassDB::bind_method(D_METHOD("is_overriding_selected_font_color"), &TextEdit::is_overriding_selected_font_color);
+
ClassDB::bind_method(D_METHOD("set_syntax_coloring", "enable"), &TextEdit::set_syntax_coloring);
ClassDB::bind_method(D_METHOD("is_syntax_coloring_enabled"), &TextEdit::is_syntax_coloring_enabled);
@@ -4838,6 +4857,7 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "override_selected_font_color"), "set_override_selected_font_color", "is_overriding_selected_font_color");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "smooth_scrolling"), "set_smooth_scroll_enable", "is_smooth_scroll_enabled");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "v_scroll_speed"), "set_v_scroll_speed", "get_v_scroll_speed");
@@ -4868,6 +4888,7 @@ TextEdit::TextEdit() {
readonly = false;
setting_row = false;
draw_tabs = false;
+ override_selected_font_color = false;
draw_caret = true;
max_chars = 0;
clear();
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 7e61c4e8b1..03f412729d 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -238,6 +238,7 @@ class TextEdit : public Control {
bool setting_row;
bool wrap;
bool draw_tabs;
+ bool override_selected_font_color;
bool cursor_changed_dirty;
bool text_changed_dirty;
bool undo_enabled;
@@ -482,6 +483,8 @@ public:
void set_indent_size(const int p_size);
void set_draw_tabs(bool p_draw);
bool is_drawing_tabs() const;
+ void set_override_selected_font_color(bool p_override_selected_font_color);
+ bool is_overriding_selected_font_color() const;
void set_insert_mode(bool p_enabled);
bool is_insert_mode() const;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index c2a31b4a8b..cee25b53a1 100755
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -212,6 +212,8 @@ void Node::_propagate_enter_tree() {
emit_signal(SceneStringNames::get_singleton()->tree_entered);
+ data.tree->node_added(this);
+
data.blocked++;
//block while adding children
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 7a28e2a6f8..d4be683a2b 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -85,6 +85,11 @@ void SceneTree::tree_changed() {
emit_signal(tree_changed_name);
}
+void SceneTree::node_added(Node *p_node) {
+
+ emit_signal(node_added_name, p_node);
+}
+
void SceneTree::node_removed(Node *p_node) {
if (current_scene == p_node) {
@@ -1172,7 +1177,7 @@ void SceneTree::_update_root_rect() {
}
}
-void SceneTree::set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, int p_shrink) {
+void SceneTree::set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink) {
stretch_mode = p_mode;
stretch_aspect = p_aspect;
@@ -2189,6 +2194,7 @@ void SceneTree::_bind_methods() {
ClassDB::bind_method(D_METHOD("_server_disconnected"), &SceneTree::_server_disconnected);
ADD_SIGNAL(MethodInfo("tree_changed"));
+ ADD_SIGNAL(MethodInfo("node_added", PropertyInfo(Variant::OBJECT, "node")));
ADD_SIGNAL(MethodInfo("node_removed", PropertyInfo(Variant::OBJECT, "node")));
ADD_SIGNAL(MethodInfo("screen_resized"));
ADD_SIGNAL(MethodInfo("node_configuration_warning_changed", PropertyInfo(Variant::OBJECT, "node")));
@@ -2260,6 +2266,7 @@ SceneTree::SceneTree() {
root = NULL;
current_frame = 0;
tree_changed_name = "tree_changed";
+ node_added_name = "node_added";
node_removed_name = "node_removed";
ugc_locked = false;
call_lock = 0;
diff --git a/scene/main/scene_tree.h b/scene/main/scene_tree.h
index f3e689adab..bc3efdc42f 100644
--- a/scene/main/scene_tree.h
+++ b/scene/main/scene_tree.h
@@ -124,6 +124,7 @@ private:
bool input_handled;
Size2 last_screen_size;
StringName tree_changed_name;
+ StringName node_added_name;
StringName node_removed_name;
int64_t current_frame;
@@ -147,7 +148,7 @@ private:
StretchMode stretch_mode;
StretchAspect stretch_aspect;
Size2i stretch_min;
- int stretch_shrink;
+ real_t stretch_shrink;
void _update_root_rect();
@@ -233,6 +234,7 @@ private:
void _rpc(Node *p_from, int p_to, bool p_unreliable, bool p_set, const StringName &p_name, const Variant **p_arg, int p_argcount);
void tree_changed();
+ void node_added(Node *p_node);
void node_removed(Node *p_node);
Group *add_to_group(const StringName &p_group, Node *p_node);
@@ -415,7 +417,7 @@ public:
void get_nodes_in_group(const StringName &p_group, List<Node *> *p_list);
bool has_group(const StringName &p_identifier) const;
- void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, int p_shrink = 1);
+ void set_screen_stretch(StretchMode p_mode, StretchAspect p_aspect, const Size2 p_minsize, real_t p_shrink = 1);
//void change_scene(const String& p_path);
//Node *get_loaded_scene();
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 37a393b55b..0a02f471c1 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2371,8 +2371,13 @@ void Viewport::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(!is_inside_tree());
- get_tree()->_call_input_pause(input_group, "_input", p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
- _gui_input_event(p_event);
+ if (!get_tree()->is_input_handled()) {
+ get_tree()->_call_input_pause(input_group, "_input", p_event); //not a bug, must happen before GUI, order is _input -> gui input -> _unhandled input
+ }
+
+ if (!get_tree()->is_input_handled()) {
+ _gui_input_event(p_event);
+ }
//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
}
@@ -2711,7 +2716,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,NextFrame"), "set_clear_mode", "get_clear_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_clear_mode", PROPERTY_HINT_ENUM, "Always,Never,Next Frame"), "set_clear_mode", "get_clear_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "render_target_update_mode", PROPERTY_HINT_ENUM, "Disabled,Once,When Visible,Always"), "set_update_mode", "get_update_mode");
ADD_GROUP("Audio Listener", "audio_listener_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_listener_enable_2d"), "set_as_audio_listener_2d", "is_audio_listener_2d");
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 8dcc8d4e14..21e4a85cd1 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -1171,9 +1171,7 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol
ERR_FAIL_COND_V(idx == -2, T());
- if (p_ok)
- *p_ok = true;
-
+ bool result = true;
int next = 0;
float c = 0;
// prepare for all cases of interpolation
@@ -1243,10 +1241,19 @@ T Animation::_interpolate(const Vector<TKey<T> > &p_keys, float p_time, Interpol
} else if (idx < 0) {
- idx = next = 0;
+ // only allow extending first key to anim start if looping
+ if (loop)
+ idx = next = 0;
+ else
+ result = false;
}
}
+ if (p_ok)
+ *p_ok = result;
+ if (!result)
+ return T();
+
float tr = p_keys[idx].transition;
if (tr == 0 || idx == next) {
@@ -1298,7 +1305,7 @@ Error Animation::transform_track_interpolate(int p_track, float p_time, Vector3
TransformKey tk = _interpolate(tt->transforms, p_time, tt->interpolation, tt->loop_wrap, &ok);
- if (!ok) // ??
+ if (!ok)
return ERR_UNAVAILABLE;
if (r_loc)
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index 1fd84a860e..fdc3b79db6 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -486,7 +486,8 @@ PoolVector<uint8_t> AudioStreamSample::get_data() const {
{
PoolVector<uint8_t>::Write w = pv.write();
- copymem(w.ptr(), data, data_bytes);
+ uint8_t *dataptr = (uint8_t *)data;
+ copymem(w.ptr(), dataptr + DATA_PAD, data_bytes);
}
}
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 923639bc79..ce439fece6 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -512,6 +512,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// HSlider
theme->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_highlight", "HSlider", make_stylebox(hslider_grabber_hl_png, 6, 6, 6, 6));
theme->set_stylebox("grabber_disabled", "HSlider", make_stylebox(hslider_grabber_disabled_png, 6, 6, 6, 6));
theme->set_stylebox("focus", "HSlider", focus);
@@ -524,6 +525,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// VSlider
theme->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
+ theme->set_stylebox("grabber_area", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
theme->set_stylebox("grabber_highlight", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6));
theme->set_stylebox("grabber_disabled", "VSlider", make_stylebox(vslider_grabber_disabled_png, 6, 6, 6, 6));
theme->set_stylebox("focus", "VSlider", focus);
@@ -882,7 +884,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
theme->set_icon("minus", "GraphEdit", make_icon(icon_zoom_less_png));
theme->set_icon("reset", "GraphEdit", make_icon(icon_zoom_reset_png));
theme->set_icon("more", "GraphEdit", make_icon(icon_zoom_more_png));
- theme->set_icon("SnapGrid", "GraphEdit", make_icon(icon_snap_grid_png));
+ theme->set_icon("snap", "GraphEdit", make_icon(icon_snap_grid_png));
theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5));
theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05));
theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2));
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 2936df7a51..898a594498 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1242,6 +1242,15 @@ Ref<Texture> SpatialMaterial::get_texture(TextureParam p_param) const {
return textures[p_param];
}
+Ref<Texture> SpatialMaterial::get_texture_by_name(StringName p_name) const {
+ for (int i = 0; i < (int)SpatialMaterial::TEXTURE_MAX; i++) {
+ TextureParam param = TextureParam(i);
+ if (p_name == shader_names->texture_names[param])
+ return textures[param];
+ }
+ return Ref<Texture>();
+}
+
void SpatialMaterial::_validate_feature(const String &text, Feature feature, PropertyInfo &property) const {
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
property.usage = 0;
diff --git a/scene/resources/material.h b/scene/resources/material.h
index c0e007ac5f..2425f1a174 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -510,6 +510,8 @@ public:
void set_texture(TextureParam p_param, const Ref<Texture> &p_texture);
Ref<Texture> get_texture(TextureParam p_param) const;
+ // Used only for shader material conversion
+ Ref<Texture> get_texture_by_name(StringName p_name) const;
void set_feature(Feature p_feature, bool p_enabled);
bool get_feature(Feature p_feature) const;
diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp
index ec41630258..66df7dfda8 100644
--- a/scene/resources/shader.cpp
+++ b/scene/resources/shader.cpp
@@ -43,8 +43,6 @@ void Shader::set_code(const String &p_code) {
String type = ShaderLanguage::get_shader_type(p_code);
- print_line("mode: " + type);
-
if (type == "canvas_item") {
mode = MODE_CANVAS_ITEM;
} else if (type == "particles") {
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index b8a0a7864e..f4a9abc1ea 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -765,7 +765,7 @@ void StyleBoxFlat::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_border_blend", "blend"), &StyleBoxFlat::set_border_blend);
ClassDB::bind_method(D_METHOD("get_border_blend"), &StyleBoxFlat::get_border_blend);
- ClassDB::bind_method(D_METHOD("set_corner_radius_individual", "radius_top_left", "radius_top_right", "radius_botton_right", "radius_bottom_left"), &StyleBoxFlat::set_corner_radius_individual);
+ ClassDB::bind_method(D_METHOD("set_corner_radius_individual", "radius_top_left", "radius_top_right", "radius_bottom_right", "radius_bottom_left"), &StyleBoxFlat::set_corner_radius_individual);
ClassDB::bind_method(D_METHOD("set_corner_radius_all", "radius"), &StyleBoxFlat::set_corner_radius_all);
ClassDB::bind_method(D_METHOD("set_corner_radius", "corner", "radius"), &StyleBoxFlat::set_corner_radius);
diff --git a/servers/arvr/arvr_script_interface.cpp b/servers/arvr/arvr_script_interface.cpp
deleted file mode 100644
index 2755605a14..0000000000
--- a/servers/arvr/arvr_script_interface.cpp
+++ /dev/null
@@ -1,136 +0,0 @@
-#include "arvr_script_interface.h"
-
-ARVRScriptInterface::ARVRScriptInterface() {
- // testing
- printf("Construct script interface");
-}
-
-ARVRScriptInterface::~ARVRScriptInterface() {
- if (is_initialized()) {
- uninitialize();
- };
-
- // testing
- printf("Destruct script interface");
-}
-
-StringName ARVRScriptInterface::get_name() const {
- if (get_script_instance() && get_script_instance()->has_method("get_name")) {
- return get_script_instance()->call("get_name");
- } else {
- // just return something for now
- return "ARVR Script interface";
- }
-}
-
-int ARVRScriptInterface::get_capabilities() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_capabilities")), ARVRInterface::ARVR_NONE);
- return get_script_instance()->call("get_capabilities");
-};
-
-ARVRInterface::Tracking_status ARVRScriptInterface::get_tracking_status() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_tracking_status")), ARVRInterface::ARVR_NOT_TRACKING);
- int status = get_script_instance()->call("get_tracking_status");
- return (ARVRInterface::Tracking_status)status;
-}
-
-bool ARVRScriptInterface::get_anchor_detection_is_enabled() const {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_anchor_detection_is_enabled")), false);
- return get_script_instance()->call("get_anchor_detection_is_enabled");
-};
-
-void ARVRScriptInterface::set_anchor_detection_is_enabled(bool p_enable) {
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("set_anchor_detection_is_enabled")));
- get_script_instance()->call("set_anchor_detection_is_enabled");
-};
-
-bool ARVRScriptInterface::is_stereo() {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("is_stereo")), false);
- return get_script_instance()->call("is_stereo");
-}
-
-bool ARVRScriptInterface::is_initialized() {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("is_initialized")), false);
- return get_script_instance()->call("is_initialized");
-}
-
-bool ARVRScriptInterface::initialize() {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("initialize")), false);
- return get_script_instance()->call("initialize");
-}
-
-void ARVRScriptInterface::uninitialize() {
- ARVRServer *arvr_server = ARVRServer::get_singleton();
- if (arvr_server != NULL) {
- // Whatever happens, make sure this is no longer our primary interface
- arvr_server->clear_primary_interface_if(this);
- }
-
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("uninitialize")));
- get_script_instance()->call("uninitialize");
-}
-
-Size2 ARVRScriptInterface::get_recommended_render_targetsize() {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_recommended_render_targetsize")), Size2());
- return get_script_instance()->call("get_recommended_render_targetsize");
-}
-
-Transform ARVRScriptInterface::get_transform_for_eye(Eyes p_eye, const Transform &p_cam_transform) {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_transform_for_eye")), Transform());
- return get_script_instance()->call("get_transform_for_eye", p_eye, p_cam_transform);
-}
-
-// Suggestion from Reduz, as we can't return a CameraMatrix, return a PoolVector with our 16 floats
-PoolVector<float> ARVRScriptInterface::_get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
- ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("_get_projection_for_eye")), PoolVector<float>());
- return get_script_instance()->call("_get_projection_for_eye", p_eye, p_aspect, p_z_near, p_z_far);
-}
-
-CameraMatrix ARVRScriptInterface::get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far) {
- CameraMatrix cm;
- int i = 0;
- int j = 0;
-
- PoolVector<float> cm_as_floats = _get_projection_for_eye(p_eye, p_aspect, p_z_near, p_z_far);
-
- for (int k = 0; k < cm_as_floats.size() && i < 4; k++) {
- cm.matrix[i][j] = cm_as_floats[k];
- j++;
- if (j == 4) {
- j = 0;
- i++;
- };
- };
-
- return cm;
-}
-
-void ARVRScriptInterface::commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect) {
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("commit_for_eye")));
- get_script_instance()->call("commit_for_eye");
-}
-
-void ARVRScriptInterface::process() {
- ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("process")));
- get_script_instance()->call("process");
-}
-
-void ARVRScriptInterface::_bind_methods() {
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "get_capabilities"));
-
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "is_initialized"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "initialize"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("uninitialize"));
-
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "get_tracking_status"));
-
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "get_anchor_detection_is_enabled"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("set_anchor_detection_is_enabled", PropertyInfo(Variant::BOOL, "enabled")));
-
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "is_stereo"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::VECTOR2, "get_recommended_render_targetsize"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::TRANSFORM, "get_transform_for_eye", PropertyInfo(Variant::INT, "eye"), PropertyInfo(Variant::TRANSFORM, "cam_transform")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("_get_projection_for_eye"));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("commit_for_eye", PropertyInfo(Variant::INT, "eye"), PropertyInfo(Variant::_RID, "render_target")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo("process"));
-}
diff --git a/servers/arvr/arvr_script_interface.h b/servers/arvr/arvr_script_interface.h
deleted file mode 100644
index b1393b4fdb..0000000000
--- a/servers/arvr/arvr_script_interface.h
+++ /dev/null
@@ -1,52 +0,0 @@
-#ifndef SCRIPT_INTERFACE_H
-#define SCRIPT_INTERFACE_H
-
-#include "arvr_interface.h"
-
-/**
- @authors Hinsbart & Karroffel
-
- This subclass of our AR/VR interface forms a bridge to GDNative.
-*/
-
-class ARVRScriptInterface : public ARVRInterface {
- GDCLASS(ARVRScriptInterface, ARVRInterface);
-
-protected:
- static void _bind_methods();
-
-public:
- /** general interface information **/
- ARVRScriptInterface();
- ~ARVRScriptInterface();
-
- virtual StringName get_name() const;
- virtual int get_capabilities() const;
-
- virtual bool is_initialized();
- virtual bool initialize();
- virtual void uninitialize();
-
- ARVRInterface::Tracking_status get_tracking_status() const; /* get the status of our current tracking */
-
- /** specific to AR **/
- virtual bool get_anchor_detection_is_enabled() const;
- virtual void set_anchor_detection_is_enabled(bool p_enable);
-
- /** rendering and internal **/
- virtual Size2 get_recommended_render_targetsize();
- virtual bool is_stereo();
- virtual Transform get_transform_for_eye(ARVRInterface::Eyes p_eye, const Transform &p_cam_transform);
-
- // we expose a PoolVector<float> version of this function to GDNative
- PoolVector<float> _get_projection_for_eye(Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
-
- // and a CameraMatrix version to ARVRServer
- virtual CameraMatrix get_projection_for_eye(ARVRInterface::Eyes p_eye, real_t p_aspect, real_t p_z_near, real_t p_z_far);
-
- virtual void commit_for_eye(ARVRInterface::Eyes p_eye, RID p_render_target, const Rect2 &p_screen_rect);
-
- virtual void process();
-};
-
-#endif // SCRIPT_INTERFACE_H
diff --git a/servers/arvr_server.cpp b/servers/arvr_server.cpp
index aa879f8aed..4dfc40e9e4 100644
--- a/servers/arvr_server.cpp
+++ b/servers/arvr_server.cpp
@@ -53,10 +53,10 @@ void ARVRServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_tracker_count"), &ARVRServer::get_tracker_count);
ClassDB::bind_method(D_METHOD("get_tracker", "idx"), &ARVRServer::get_tracker);
- ClassDB::bind_method(D_METHOD("set_primary_interface"), &ARVRServer::set_primary_interface);
+ ClassDB::bind_method(D_METHOD("set_primary_interface", "interface"), &ARVRServer::set_primary_interface);
- ClassDB::bind_method(D_METHOD("add_interface"), &ARVRServer::add_interface);
- ClassDB::bind_method(D_METHOD("remove_interface"), &ARVRServer::remove_interface);
+ ClassDB::bind_method(D_METHOD("add_interface", "interface"), &ARVRServer::add_interface);
+ ClassDB::bind_method(D_METHOD("remove_interface", "interface"), &ARVRServer::remove_interface);
BIND_ENUM_CONSTANT(TRACKER_CONTROLLER);
BIND_ENUM_CONSTANT(TRACKER_BASESTATION);
diff --git a/servers/physics/joints/pin_joint_sw.h b/servers/physics/joints/pin_joint_sw.h
index ee9272ce06..f6c11c49b0 100644
--- a/servers/physics/joints/pin_joint_sw.h
+++ b/servers/physics/joints/pin_joint_sw.h
@@ -86,8 +86,8 @@ public:
void set_pos_a(const Vector3 &p_pos) { m_pivotInA = p_pos; }
void set_pos_b(const Vector3 &p_pos) { m_pivotInB = p_pos; }
- Vector3 get_position_a() { return m_pivotInB; }
- Vector3 get_position_b() { return m_pivotInA; }
+ Vector3 get_position_a() { return m_pivotInA; }
+ Vector3 get_position_b() { return m_pivotInB; }
PinJointSW(BodySW *p_body_a, const Vector3 &p_pos_a, BodySW *p_body_b, const Vector3 &p_pos_b);
~PinJointSW();
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index db1270633f..627ba8ea15 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -110,21 +110,48 @@ public:
void set_shape_metadata(int p_index, const Variant &p_metadata);
_FORCE_INLINE_ int get_shape_count() const { return shapes.size(); }
- _FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const { return shapes[p_index].shape; }
- _FORCE_INLINE_ const Transform2D &get_shape_transform(int p_index) const { return shapes[p_index].xform; }
- _FORCE_INLINE_ const Transform2D &get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; }
- _FORCE_INLINE_ const Rect2 &get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; }
- _FORCE_INLINE_ const Variant &get_shape_metadata(int p_index) const { return shapes[p_index].metadata; }
+ _FORCE_INLINE_ Shape2DSW *get_shape(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, shapes.size(), NULL);
+ return shapes[p_index].shape;
+ }
+ _FORCE_INLINE_ const Transform2D &get_shape_transform(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, shapes.size(), Transform2D());
+ return shapes[p_index].xform;
+ }
+ _FORCE_INLINE_ const Transform2D &get_shape_inv_transform(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, shapes.size(), Transform2D());
+ return shapes[p_index].xform_inv;
+ }
+ _FORCE_INLINE_ const Rect2 &get_shape_aabb(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, shapes.size(), Rect2());
+ return shapes[p_index].aabb_cache;
+ }
+ _FORCE_INLINE_ const Variant &get_shape_metadata(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, shapes.size(), Variant());
+ return shapes[p_index].metadata;
+ }
_FORCE_INLINE_ Transform2D get_transform() const { return transform; }
_FORCE_INLINE_ Transform2D get_inv_transform() const { return inv_transform; }
_FORCE_INLINE_ Space2DSW *get_space() const { return space; }
- _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) { shapes[p_idx].disabled = p_disabled; }
- _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_disabled) {
+ ERR_FAIL_INDEX(p_idx, shapes.size());
+ shapes[p_idx].disabled = p_disabled;
+ }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
+ return shapes[p_idx].disabled;
+ }
- _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) { shapes[p_idx].one_way_collision = p_one_way_collision; }
- _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const { return shapes[p_idx].one_way_collision; }
+ _FORCE_INLINE_ void set_shape_as_one_way_collision(int p_idx, bool p_one_way_collision) {
+ ERR_FAIL_INDEX(p_idx, shapes.size());
+ shapes[p_idx].one_way_collision = p_one_way_collision;
+ }
+ _FORCE_INLINE_ bool is_shape_set_as_one_way_collision(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, shapes.size(), false);
+ return shapes[p_idx].one_way_collision;
+ }
void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 1aee2144aa..7a9328e30f 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -32,7 +32,6 @@
#include "arvr/arvr_interface.h"
#include "arvr/arvr_positional_tracker.h"
-#include "arvr/arvr_script_interface.h"
#include "arvr_server.h"
#include "audio/audio_effect.h"
#include "audio/audio_stream.h"
@@ -74,10 +73,8 @@ static void _debugger_get_resource_usage(List<ScriptDebuggerRemote::ResourceUsag
}
ShaderTypes *shader_types = NULL;
-ARVRServer *arvr_server = NULL;
void register_server_types() {
- arvr_server = memnew(ARVRServer);
ClassDB::register_virtual_class<VisualServer>();
ClassDB::register_class<AudioServer>();
@@ -95,7 +92,6 @@ void register_server_types() {
ClassDB::register_virtual_class<ARVRInterface>();
ClassDB::register_class<ARVRPositionalTracker>();
- ClassDB::register_class<ARVRScriptInterface>();
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
@@ -152,9 +148,5 @@ void register_server_types() {
void unregister_server_types() {
- //@TODO move this into iPhone/Android implementation? just have this here for testing...
- // mobile_interface = NULL;
-
memdelete(shader_types);
- memdelete(arvr_server);
}
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index b2a11deea1..8fee6050a0 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2586,6 +2586,8 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} else if (tk.type == TK_BRACKET_OPEN) {
Node *index = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!index)
+ return NULL;
if (index->get_datatype() != TYPE_INT && index->get_datatype() != TYPE_UINT) {
_set_error("Only integer datatypes are allowed for indexing");
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 47a5f4c7f3..64bc978037 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -62,6 +62,31 @@ RID VisualServer::texture_create_from_image(const Ref<Image> &p_image, uint32_t
return texture;
}
+Array VisualServer::_texture_debug_usage_bind() {
+
+ List<TextureInfo> list;
+ texture_debug_usage(&list);
+ Array arr;
+ for (const List<TextureInfo>::Element *E = list.front(); E; E = E->next()) {
+
+ Dictionary dict;
+ dict["texture"] = E->get().texture;
+ dict["size"] = E->get().size;
+ dict["format"] = E->get().format;
+ dict["bytes"] = E->get().bytes;
+ dict["path"] = E->get().path;
+ arr.push_back(dict);
+ }
+ return arr;
+}
+
+Array VisualServer::_shader_get_param_list_bind(RID p_shader) const {
+
+ List<PropertyInfo> l;
+ shader_get_param_list(p_shader, &l);
+ return convert_property_list(&l);
+}
+
RID VisualServer::get_test_texture() {
if (test_texture.is_valid()) {
@@ -1443,20 +1468,395 @@ Array VisualServer::mesh_surface_get_blend_shape_arrays(RID p_mesh, int p_surfac
}
}
+Array VisualServer::_mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const {
+
+ Vector<Rect3> vec = VS::get_singleton()->mesh_surface_get_skeleton_aabb(p_mesh, p_surface);
+ Array arr;
+ for (int i = 0; i < vec.size(); i++) {
+ arr[i] = vec[i];
+ }
+ return arr;
+}
+
void VisualServer::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("force_sync"), &VisualServer::sync);
ClassDB::bind_method(D_METHOD("force_draw"), &VisualServer::draw);
+
ClassDB::bind_method(D_METHOD("texture_create"), &VisualServer::texture_create);
ClassDB::bind_method(D_METHOD("texture_create_from_image", "image", "flags"), &VisualServer::texture_create_from_image, DEFVAL(TEXTURE_FLAGS_DEFAULT));
- //ClassDB::bind_method(D_METHOD("texture_allocate"),&VisualServer::texture_allocate,DEFVAL( TEXTURE_FLAGS_DEFAULT ) );
- //ClassDB::bind_method(D_METHOD("texture_set_data"),&VisualServer::texture_blit_rect,DEFVAL( CUBEMAP_LEFT ) );
- //ClassDB::bind_method(D_METHOD("texture_get_rect"),&VisualServer::texture_get_rect );
+ ClassDB::bind_method(D_METHOD("texture_allocate", "texture", "width", "height", "format", "flags"), &VisualServer::texture_allocate, DEFVAL(TEXTURE_FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("texture_set_data", "texture", "image", "cube_side"), &VisualServer::texture_set_data, DEFVAL(CUBEMAP_LEFT));
+ ClassDB::bind_method(D_METHOD("texture_get_data", "texture", "cube_side"), &VisualServer::texture_get_data, DEFVAL(CUBEMAP_LEFT));
ClassDB::bind_method(D_METHOD("texture_set_flags", "texture", "flags"), &VisualServer::texture_set_flags);
ClassDB::bind_method(D_METHOD("texture_get_flags", "texture"), &VisualServer::texture_get_flags);
+ ClassDB::bind_method(D_METHOD("texture_get_format", "texture"), &VisualServer::texture_get_format);
+ ClassDB::bind_method(D_METHOD("texture_get_texid", "texture"), &VisualServer::texture_get_texid);
ClassDB::bind_method(D_METHOD("texture_get_width", "texture"), &VisualServer::texture_get_width);
ClassDB::bind_method(D_METHOD("texture_get_height", "texture"), &VisualServer::texture_get_height);
-
+ ClassDB::bind_method(D_METHOD("texture_set_size_override", "texture", "width", "height"), &VisualServer::texture_set_size_override);
+ ClassDB::bind_method(D_METHOD("texture_set_path", "texture", "path"), &VisualServer::texture_set_path);
+ ClassDB::bind_method(D_METHOD("texture_get_path", "texture"), &VisualServer::texture_get_path);
ClassDB::bind_method(D_METHOD("texture_set_shrink_all_x2_on_set_data", "shrink"), &VisualServer::texture_set_shrink_all_x2_on_set_data);
+
+ ClassDB::bind_method(D_METHOD("texture_debug_usage"), &VisualServer::_texture_debug_usage_bind);
+ ClassDB::bind_method(D_METHOD("textures_keep_original", "enable"), &VisualServer::textures_keep_original);
+
+ ClassDB::bind_method(D_METHOD("sky_create"), &VisualServer::sky_create);
+ ClassDB::bind_method(D_METHOD("sky_set_texture", "sky", "cube_map", "radiance_size"), &VisualServer::sky_set_texture);
+
+ ClassDB::bind_method(D_METHOD("shader_create"), &VisualServer::shader_create);
+ ClassDB::bind_method(D_METHOD("shader_set_code", "shader", "code"), &VisualServer::shader_set_code);
+ ClassDB::bind_method(D_METHOD("shader_get_code", "shader"), &VisualServer::shader_get_code);
+ ClassDB::bind_method(D_METHOD("shader_get_param_list", "shader"), &VisualServer::_shader_get_param_list_bind);
+ ClassDB::bind_method(D_METHOD("shader_set_default_texture_param", "shader", "name", "texture"), &VisualServer::shader_set_default_texture_param);
+ ClassDB::bind_method(D_METHOD("shader_get_default_texture_param", "shader", "name"), &VisualServer::shader_get_default_texture_param);
+
+ ClassDB::bind_method(D_METHOD("material_create"), &VisualServer::material_create);
+ ClassDB::bind_method(D_METHOD("material_set_shader", "shader_material", "shader"), &VisualServer::material_set_shader);
+ ClassDB::bind_method(D_METHOD("material_get_shader", "shader_material"), &VisualServer::material_get_shader);
+ ClassDB::bind_method(D_METHOD("material_set_param", "material", "parameter", "value"), &VisualServer::material_set_param);
+ ClassDB::bind_method(D_METHOD("material_get_param", "material", "parameter"), &VisualServer::material_get_param);
+ ClassDB::bind_method(D_METHOD("material_set_render_priority", "material", "priority"), &VisualServer::material_set_render_priority);
+ ClassDB::bind_method(D_METHOD("material_set_line_width", "material", "width"), &VisualServer::material_set_line_width);
+ ClassDB::bind_method(D_METHOD("material_set_next_pass", "material", "next_material"), &VisualServer::material_set_next_pass);
+
+ ClassDB::bind_method(D_METHOD("mesh_create"), &VisualServer::mesh_create);
+ ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primtive", "arrays", "blend_shapes", "compress_format"), &VisualServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_count", "mesh", "amount"), &VisualServer::mesh_set_blend_shape_count);
+ ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &VisualServer::mesh_get_blend_shape_count);
+ ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_mode", "mesh", "mode"), &VisualServer::mesh_set_blend_shape_mode);
+ ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_mode", "mesh"), &VisualServer::mesh_get_blend_shape_mode);
+ ClassDB::bind_method(D_METHOD("mesh_surface_set_material", "mesh", "surface", "material"), &VisualServer::mesh_surface_set_material);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_material", "mesh", "surface"), &VisualServer::mesh_surface_get_material);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_array_len", "mesh", "surface"), &VisualServer::mesh_surface_get_array_len);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_array_index_len", "mesh", "surface"), &VisualServer::mesh_surface_get_array_index_len);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_array", "mesh", "surface"), &VisualServer::mesh_surface_get_array);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_index_array", "mesh", "surface"), &VisualServer::mesh_surface_get_index_array);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_arrays", "mesh", "surface"), &VisualServer::mesh_surface_get_arrays);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_blend_shape_arrays", "mesh", "surface"), &VisualServer::mesh_surface_get_blend_shape_arrays);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_format", "mesh", "surface"), &VisualServer::mesh_surface_get_format);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_primitive_type", "mesh", "surface"), &VisualServer::mesh_surface_get_primitive_type);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_aabb", "mesh", "surface"), &VisualServer::mesh_surface_get_aabb);
+ ClassDB::bind_method(D_METHOD("mesh_surface_get_skeleton_aabb", "mesh", "surface"), &VisualServer::_mesh_surface_get_skeleton_aabb_bind);
+ ClassDB::bind_method(D_METHOD("mesh_remove_surface", "mesh", "index"), &VisualServer::mesh_remove_surface);
+ ClassDB::bind_method(D_METHOD("mesh_get_surface_count", "mesh"), &VisualServer::mesh_get_surface_count);
+ ClassDB::bind_method(D_METHOD("mesh_set_custom_aabb", "mesh", "aabb"), &VisualServer::mesh_set_custom_aabb);
+ ClassDB::bind_method(D_METHOD("mesh_get_custom_aabb", "mesh"), &VisualServer::mesh_get_custom_aabb);
+ ClassDB::bind_method(D_METHOD("mesh_clear", "mesh"), &VisualServer::mesh_clear);
+
+ // TODO: multimesh_*, immediate_*, skeleton_*, light_*, reflection_probe_*, gi_probe_*, particles_*, camera_*
+
+ ClassDB::bind_method(D_METHOD("viewport_create"), &VisualServer::viewport_create);
+ ClassDB::bind_method(D_METHOD("viewport_set_use_arvr", "viewport", "use_arvr"), &VisualServer::viewport_set_use_arvr);
+ ClassDB::bind_method(D_METHOD("viewport_set_size", "viewport", "width", "height"), &VisualServer::viewport_set_size);
+ ClassDB::bind_method(D_METHOD("viewport_set_active", "viewport", "active"), &VisualServer::viewport_set_active);
+ ClassDB::bind_method(D_METHOD("viewport_set_parent_viewport", "viewport", "parent_viewport"), &VisualServer::viewport_set_parent_viewport);
+ ClassDB::bind_method(D_METHOD("viewport_attach_to_screen", "viewport", "rect", "screen"), &VisualServer::viewport_attach_to_screen, DEFVAL(Rect2()), DEFVAL(0));
+ ClassDB::bind_method(D_METHOD("viewport_detach", "viewport"), &VisualServer::viewport_detach);
+ ClassDB::bind_method(D_METHOD("viewport_set_update_mode", "viewport", "update_mode"), &VisualServer::viewport_set_update_mode);
+ ClassDB::bind_method(D_METHOD("viewport_set_vflip", "viewport", "enabled"), &VisualServer::viewport_set_vflip);
+ ClassDB::bind_method(D_METHOD("viewport_set_clear_mode", "viewport", "clear_mode"), &VisualServer::viewport_set_clear_mode);
+ ClassDB::bind_method(D_METHOD("viewport_get_texture", "viewport"), &VisualServer::viewport_get_texture);
+ ClassDB::bind_method(D_METHOD("viewport_set_hide_scenario", "viewport", "hidden"), &VisualServer::viewport_set_hide_scenario);
+ ClassDB::bind_method(D_METHOD("viewport_set_hide_canvas", "viewport", "hidden"), &VisualServer::viewport_set_hide_canvas);
+ ClassDB::bind_method(D_METHOD("viewport_set_disable_environment", "viewport", "disabled"), &VisualServer::viewport_set_disable_environment);
+ ClassDB::bind_method(D_METHOD("viewport_set_disable_3d", "viewport", "disabled"), &VisualServer::viewport_set_disable_3d);
+ ClassDB::bind_method(D_METHOD("viewport_attach_camera", "viewport", "camera"), &VisualServer::viewport_attach_camera);
+ ClassDB::bind_method(D_METHOD("viewport_set_scenario", "viewport", "scenario"), &VisualServer::viewport_set_scenario);
+ ClassDB::bind_method(D_METHOD("viewport_attach_canvas", "viewport", "canvas"), &VisualServer::viewport_attach_canvas);
+ ClassDB::bind_method(D_METHOD("viewport_remove_canvas", "viewport", "canvas"), &VisualServer::viewport_remove_canvas);
+ ClassDB::bind_method(D_METHOD("viewport_set_canvas_transform", "viewport", "canvas", "offset"), &VisualServer::viewport_set_canvas_transform);
+ ClassDB::bind_method(D_METHOD("viewport_set_transparent_background", "viewport", "enabled"), &VisualServer::viewport_set_transparent_background);
+ ClassDB::bind_method(D_METHOD("viewport_set_global_canvas_transform", "viewport", "transform"), &VisualServer::viewport_set_global_canvas_transform);
+ ClassDB::bind_method(D_METHOD("viewport_set_canvas_layer", "viewport", "canvas", "layer"), &VisualServer::viewport_set_canvas_layer);
+ ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_size", "viewport", "size"), &VisualServer::viewport_set_shadow_atlas_size);
+ ClassDB::bind_method(D_METHOD("viewport_set_shadow_atlas_quadrant_subdivision", "viewport", "quadrant", "subdivision"), &VisualServer::viewport_set_shadow_atlas_quadrant_subdivision);
+ ClassDB::bind_method(D_METHOD("viewport_set_msaa", "viewport", "msaa"), &VisualServer::viewport_set_msaa);
+ ClassDB::bind_method(D_METHOD("viewport_set_hdr", "viewport", "enabled"), &VisualServer::viewport_set_hdr);
+ ClassDB::bind_method(D_METHOD("viewport_set_usage", "viewport", "usage"), &VisualServer::viewport_set_usage);
+ ClassDB::bind_method(D_METHOD("viewport_get_render_info", "viewport", "info"), &VisualServer::viewport_get_render_info);
+ ClassDB::bind_method(D_METHOD("viewport_set_debug_draw", "viewport", "draw"), &VisualServer::viewport_set_debug_draw);
+
+ // TODO: environment_*, scenario_*, instance_*
+
+ ClassDB::bind_method(D_METHOD("canvas_create"), &VisualServer::canvas_create);
+ ClassDB::bind_method(D_METHOD("canvas_set_item_mirroring", "canvas", "item", "mirroring"), &VisualServer::canvas_set_item_mirroring);
+ ClassDB::bind_method(D_METHOD("canvas_set_modulate", "canvas", "color"), &VisualServer::canvas_set_modulate);
+
+ ClassDB::bind_method(D_METHOD("canvas_item_create"), &VisualServer::canvas_item_create);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_parent", "item", "parent"), &VisualServer::canvas_item_set_parent);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_visible", "item", "visible"), &VisualServer::canvas_item_set_visible);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_light_mask", "item", "mask"), &VisualServer::canvas_item_set_light_mask);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_transform", "item", "transform"), &VisualServer::canvas_item_set_transform);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_clip", "item", "clip"), &VisualServer::canvas_item_set_clip);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_distance_field_mode", "item", "enabled"), &VisualServer::canvas_item_set_distance_field_mode);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_custom_rect", "item", "use_custom_rect", "rect"), &VisualServer::canvas_item_set_custom_rect, DEFVAL(Rect2()));
+ ClassDB::bind_method(D_METHOD("canvas_item_set_modulate", "item", "color"), &VisualServer::canvas_item_set_modulate);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_self_modulate", "item", "color"), &VisualServer::canvas_item_set_self_modulate);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_draw_behind_parent", "item", "enabled"), &VisualServer::canvas_item_set_draw_behind_parent);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width", "antialiased"), &VisualServer::canvas_item_add_line, DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &VisualServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_rect", "item", "rect", "color"), &VisualServer::canvas_item_add_rect);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_circle", "item", "pos", "radius", "color"), &VisualServer::canvas_item_add_circle);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect", "item", "rect", "texture", "tile", "modulate", "transpose", "normal_map"), &VisualServer::canvas_item_add_texture_rect, DEFVAL(false), DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_texture_rect_region", "item", "rect", "texture", "src_rect", "modulate", "transpose", "normal_map", "clip_uv"), &VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(RID()), DEFVAL(true));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_nine_patch", "item", "rect", "source", "texture", "topleft", "bottomright", "x_axis_mode", "y_axis_mode", "draw_center", "modulate", "normal_map"), &VisualServer::canvas_item_add_nine_patch, DEFVAL(NINE_PATCH_STRETCH), DEFVAL(NINE_PATCH_STRETCH), DEFVAL(true), DEFVAL(Color(1, 1, 1)), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_primitive", "item", "points", "colors", "uvs", "texture", "width", "normal_map"), &VisualServer::canvas_item_add_primitive, DEFVAL(1.0), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_polygon", "item", "points", "colors", "uvs", "texture", "normal_map", "antialiased"), &VisualServer::canvas_item_add_polygon, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(RID()), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_triangle_array", "item", "indices", "points", "colors", "uvs", "texture", "count", "normal_map"), &VisualServer::canvas_item_add_triangle_array, DEFVAL(Vector<Point2>()), DEFVAL(RID()), DEFVAL(-1), DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_mesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_mesh, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_multimesh", "item", "mesh", "skeleton"), &VisualServer::canvas_item_add_multimesh, DEFVAL(RID()));
+ ClassDB::bind_method(D_METHOD("canvas_item_add_particles", "item", "particles", "texture", "normal_map", "h_frames", "v_frames"), &VisualServer::canvas_item_add_particles);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_set_transform", "item", "transform"), &VisualServer::canvas_item_add_set_transform);
+ ClassDB::bind_method(D_METHOD("canvas_item_add_clip_ignore", "item", "ignore"), &VisualServer::canvas_item_add_clip_ignore);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_sort_children_by_y", "item", "enabled"), &VisualServer::canvas_item_set_sort_children_by_y);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_z", "item", "z"), &VisualServer::canvas_item_set_z);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_z_as_relative_to_parent", "item", "enabled"), &VisualServer::canvas_item_set_z_as_relative_to_parent);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_copy_to_backbuffer", "item", "enabled", "rect"), &VisualServer::canvas_item_set_copy_to_backbuffer);
+ ClassDB::bind_method(D_METHOD("canvas_item_clear", "item"), &VisualServer::canvas_item_clear);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_draw_index", "item", "index"), &VisualServer::canvas_item_set_draw_index);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_material", "item", "material"), &VisualServer::canvas_item_set_material);
+ ClassDB::bind_method(D_METHOD("canvas_item_set_use_parent_material", "item", "enabled"), &VisualServer::canvas_item_set_use_parent_material);
+ ClassDB::bind_method(D_METHOD("canvas_light_create"), &VisualServer::canvas_light_create);
+ ClassDB::bind_method(D_METHOD("canvas_light_attach_to_canvas", "light", "canvas"), &VisualServer::canvas_light_attach_to_canvas);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_enabled", "light", "enabled"), &VisualServer::canvas_light_set_enabled);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_scale", "light", "scale"), &VisualServer::canvas_light_set_scale);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_transform", "light", "transform"), &VisualServer::canvas_light_set_transform);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_texture", "light", "texture"), &VisualServer::canvas_light_set_texture);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_texture_offset", "light", "offset"), &VisualServer::canvas_light_set_texture_offset);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_color", "light", "color"), &VisualServer::canvas_light_set_color);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_height", "light", "height"), &VisualServer::canvas_light_set_height);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_energy", "light", "energy"), &VisualServer::canvas_light_set_energy);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_z_range", "light", "min_z", "max_z"), &VisualServer::canvas_light_set_z_range);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_layer_range", "light", "min_layer", "max_layer"), &VisualServer::canvas_light_set_layer_range);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_item_cull_mask", "light", "mask"), &VisualServer::canvas_light_set_item_cull_mask);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_item_shadow_cull_mask", "light", "mask"), &VisualServer::canvas_light_set_item_shadow_cull_mask);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_mode", "light", "mode"), &VisualServer::canvas_light_set_mode);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_enabled", "light", "enabled"), &VisualServer::canvas_light_set_shadow_enabled);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_buffer_size", "light", "size"), &VisualServer::canvas_light_set_shadow_buffer_size);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_gradient_length", "light", "length"), &VisualServer::canvas_light_set_shadow_gradient_length);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_filter", "light", "filter"), &VisualServer::canvas_light_set_shadow_filter);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_color", "light", "color"), &VisualServer::canvas_light_set_shadow_color);
+ ClassDB::bind_method(D_METHOD("canvas_light_set_shadow_smooth", "light", "smooth"), &VisualServer::canvas_light_set_shadow_smooth);
+
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_create"), &VisualServer::canvas_light_occluder_create);
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_attach_to_canvas", "occluder", "canvas"), &VisualServer::canvas_light_occluder_attach_to_canvas);
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_set_enabled", "occluder", "enabled"), &VisualServer::canvas_light_occluder_set_enabled);
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_set_polygon", "occluder", "polygon"), &VisualServer::canvas_light_occluder_set_polygon);
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_set_transform", "occluder", "transform"), &VisualServer::canvas_light_occluder_set_transform);
+ ClassDB::bind_method(D_METHOD("canvas_light_occluder_set_light_mask", "occluder", "mask"), &VisualServer::canvas_light_occluder_set_light_mask);
+
+ ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_create"), &VisualServer::canvas_occluder_polygon_create);
+ ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_shape", "occluder_polygon", "shape", "closed"), &VisualServer::canvas_occluder_polygon_set_shape);
+ ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_shape_as_lines", "occluder_polygon", "shape"), &VisualServer::canvas_occluder_polygon_set_shape_as_lines);
+ ClassDB::bind_method(D_METHOD("canvas_occluder_polygon_set_cull_mode", "occluder_polygon", "mode"), &VisualServer::canvas_occluder_polygon_set_cull_mode);
+
+ ClassDB::bind_method(D_METHOD("black_bars_set_margins", "left", "top", "right", "bottom"), &VisualServer::black_bars_set_margins);
+ ClassDB::bind_method(D_METHOD("black_bars_set_images", "left", "top", "right", "bottom"), &VisualServer::black_bars_set_images);
+
+ ClassDB::bind_method(D_METHOD("free", "rid"), &VisualServer::free);
+
+ ClassDB::bind_method(D_METHOD("request_frame_drawn_callback", "where", "method", "userdata"), &VisualServer::request_frame_drawn_callback);
+ ClassDB::bind_method(D_METHOD("draw"), &VisualServer::draw);
+ ClassDB::bind_method(D_METHOD("sync"), &VisualServer::sync);
+ ClassDB::bind_method(D_METHOD("has_changed"), &VisualServer::has_changed);
+ ClassDB::bind_method(D_METHOD("init"), &VisualServer::init);
+ ClassDB::bind_method(D_METHOD("finish"), &VisualServer::finish);
+ ClassDB::bind_method(D_METHOD("get_render_info", "info"), &VisualServer::get_render_info);
+
+ ClassDB::bind_method(D_METHOD("get_test_cube"), &VisualServer::get_test_cube);
+ ClassDB::bind_method(D_METHOD("get_test_texture"), &VisualServer::get_test_texture);
+ ClassDB::bind_method(D_METHOD("get_white_texture"), &VisualServer::get_white_texture);
+
+ ClassDB::bind_method(D_METHOD("make_sphere_mesh", "latitudes", "longitudes", "radius"), &VisualServer::make_sphere_mesh);
+
+ ClassDB::bind_method(D_METHOD("set_boot_image", "image", "color", "scale"), &VisualServer::set_boot_image);
+ ClassDB::bind_method(D_METHOD("set_default_clear_color", "color"), &VisualServer::set_default_clear_color);
+
+ ClassDB::bind_method(D_METHOD("has_feature", "feature"), &VisualServer::has_feature);
+ ClassDB::bind_method(D_METHOD("has_os_feature", "feature"), &VisualServer::has_os_feature);
+ ClassDB::bind_method(D_METHOD("set_debug_generate_wireframes", "generate"), &VisualServer::set_debug_generate_wireframes);
+
+ BIND_CONSTANT(NO_INDEX_ARRAY);
+ BIND_CONSTANT(ARRAY_WEIGHTS_SIZE);
+ BIND_CONSTANT(CANVAS_ITEM_Z_MIN);
+ BIND_CONSTANT(CANVAS_ITEM_Z_MAX);
+ BIND_CONSTANT(MAX_GLOW_LEVELS);
+ BIND_CONSTANT(MAX_CURSORS);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MIN);
+ BIND_CONSTANT(MATERIAL_RENDER_PRIORITY_MAX);
+
+ BIND_ENUM_CONSTANT(CUBEMAP_LEFT);
+ BIND_ENUM_CONSTANT(CUBEMAP_RIGHT);
+ BIND_ENUM_CONSTANT(CUBEMAP_BOTTOM);
+ BIND_ENUM_CONSTANT(CUBEMAP_TOP);
+ BIND_ENUM_CONSTANT(CUBEMAP_FRONT);
+ BIND_ENUM_CONSTANT(CUBEMAP_BACK);
+
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_MIPMAPS);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_REPEAT);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_FILTER);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_ANISOTROPIC_FILTER);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_CONVERT_TO_LINEAR);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_MIRRORED_REPEAT);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_CUBEMAP);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAG_USED_FOR_STREAMING);
+ BIND_ENUM_CONSTANT(TEXTURE_FLAGS_DEFAULT);
+
+ BIND_ENUM_CONSTANT(SHADER_SPATIAL);
+ BIND_ENUM_CONSTANT(SHADER_CANVAS_ITEM);
+ BIND_ENUM_CONSTANT(SHADER_PARTICLES);
+ BIND_ENUM_CONSTANT(SHADER_MAX);
+
+ BIND_ENUM_CONSTANT(ARRAY_VERTEX);
+ BIND_ENUM_CONSTANT(ARRAY_NORMAL);
+ BIND_ENUM_CONSTANT(ARRAY_TANGENT);
+ BIND_ENUM_CONSTANT(ARRAY_COLOR);
+ BIND_ENUM_CONSTANT(ARRAY_TEX_UV);
+ BIND_ENUM_CONSTANT(ARRAY_TEX_UV2);
+ BIND_ENUM_CONSTANT(ARRAY_BONES);
+ BIND_ENUM_CONSTANT(ARRAY_WEIGHTS);
+ BIND_ENUM_CONSTANT(ARRAY_INDEX);
+ BIND_ENUM_CONSTANT(ARRAY_MAX);
+
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS);
+ BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BASE);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_VERTEX);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_BONES);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_WEIGHTS);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX);
+ BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES);
+ BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_16_BIT_BONES);
+ BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT);
+
+ BIND_ENUM_CONSTANT(PRIMITIVE_POINTS);
+ BIND_ENUM_CONSTANT(PRIMITIVE_LINES);
+ BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP);
+ BIND_ENUM_CONSTANT(PRIMITIVE_LINE_LOOP);
+ BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES);
+ BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
+ BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
+ BIND_ENUM_CONSTANT(PRIMITIVE_MAX);
+
+ BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED);
+ BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE);
+
+ BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL);
+ BIND_ENUM_CONSTANT(LIGHT_OMNI);
+ BIND_ENUM_CONSTANT(LIGHT_SPOT);
+
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_ENERGY);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SPECULAR);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_RANGE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_ATTENUATION);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ANGLE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SPOT_ATTENUATION);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_CONTACT_SHADOW_SIZE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_MAX_DISTANCE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_NORMAL_BIAS);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE);
+ BIND_ENUM_CONSTANT(LIGHT_PARAM_MAX);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE);
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE);
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ALWAYS);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_CLEAR_ALWAYS);
+ BIND_ENUM_CONSTANT(VIEWPORT_CLEAR_NEVER);
+ BIND_ENUM_CONSTANT(VIEWPORT_CLEAR_ONLY_NEXT_FRAME);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_2X);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_4X);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_8X);
+ BIND_ENUM_CONSTANT(VIEWPORT_MSAA_16X);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D);
+ BIND_ENUM_CONSTANT(VIEWPORT_USAGE_2D_NO_SAMPLING);
+ BIND_ENUM_CONSTANT(VIEWPORT_USAGE_3D);
+ BIND_ENUM_CONSTANT(VIEWPORT_USAGE_3D_NO_EFFECTS);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME);
+ BIND_ENUM_CONSTANT(VIEWPORT_RENDER_INFO_MAX);
+
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_DISABLED);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_UNSHADED);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_OVERDRAW);
+ BIND_ENUM_CONSTANT(VIEWPORT_DEBUG_DRAW_WIREFRAME);
+
+ BIND_ENUM_CONSTANT(SCENARIO_DEBUG_DISABLED);
+ BIND_ENUM_CONSTANT(SCENARIO_DEBUG_WIREFRAME);
+ BIND_ENUM_CONSTANT(SCENARIO_DEBUG_OVERDRAW);
+ BIND_ENUM_CONSTANT(SCENARIO_DEBUG_SHADELESS);
+
+ BIND_ENUM_CONSTANT(INSTANCE_NONE);
+ BIND_ENUM_CONSTANT(INSTANCE_MESH);
+ BIND_ENUM_CONSTANT(INSTANCE_MULTIMESH);
+ BIND_ENUM_CONSTANT(INSTANCE_IMMEDIATE);
+ BIND_ENUM_CONSTANT(INSTANCE_PARTICLES);
+ BIND_ENUM_CONSTANT(INSTANCE_LIGHT);
+ BIND_ENUM_CONSTANT(INSTANCE_REFLECTION_PROBE);
+ BIND_ENUM_CONSTANT(INSTANCE_GI_PROBE);
+ BIND_ENUM_CONSTANT(INSTANCE_MAX);
+ BIND_ENUM_CONSTANT(INSTANCE_GEOMETRY_MASK);
+
+ BIND_ENUM_CONSTANT(NINE_PATCH_STRETCH);
+ BIND_ENUM_CONSTANT(NINE_PATCH_TILE);
+ BIND_ENUM_CONSTANT(NINE_PATCH_TILE_FIT);
+
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_ADD);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_SUB);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MIX);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_MODE_MASK);
+
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_NONE);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF3);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF5);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF7);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF9);
+ BIND_ENUM_CONSTANT(CANVAS_LIGHT_FILTER_PCF13);
+
+ BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_DISABLED);
+ BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE);
+ BIND_ENUM_CONSTANT(CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE);
+
+ BIND_ENUM_CONSTANT(INFO_OBJECTS_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_VERTICES_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_MATERIAL_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_SHADER_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_SURFACE_CHANGES_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_DRAW_CALLS_IN_FRAME);
+ BIND_ENUM_CONSTANT(INFO_USAGE_VIDEO_MEM_TOTAL);
+ BIND_ENUM_CONSTANT(INFO_VIDEO_MEM_USED);
+ BIND_ENUM_CONSTANT(INFO_TEXTURE_MEM_USED);
+ BIND_ENUM_CONSTANT(INFO_VERTEX_MEM_USED);
+
+ BIND_ENUM_CONSTANT(FEATURE_SHADERS);
+ BIND_ENUM_CONSTANT(FEATURE_MULTITHREADED);
}
void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector<float> &p_margins, const Color &p_modulate) {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 1cc097f50e..7b83bb929d 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -137,6 +137,7 @@ public:
};
virtual void texture_debug_usage(List<TextureInfo> *r_info) = 0;
+ Array _texture_debug_usage_bind();
virtual void textures_keep_original(bool p_enable) = 0;
@@ -160,6 +161,7 @@ public:
virtual void shader_set_code(RID p_shader, const String &p_code) = 0;
virtual String shader_get_code(RID p_shader) const = 0;
virtual void shader_get_param_list(RID p_shader, List<PropertyInfo> *p_param_list) const = 0;
+ Array _shader_get_param_list_bind(RID p_shader) const;
virtual void shader_set_default_texture_param(RID p_shader, const StringName &p_name, RID p_texture) = 0;
virtual RID shader_get_default_texture_param(RID p_shader, const StringName &p_name) const = 0;
@@ -275,6 +277,7 @@ public:
virtual Rect3 mesh_surface_get_aabb(RID p_mesh, int p_surface) const = 0;
virtual Vector<PoolVector<uint8_t> > mesh_surface_get_blend_shapes(RID p_mesh, int p_surface) const = 0;
virtual Vector<Rect3> mesh_surface_get_skeleton_aabb(RID p_mesh, int p_surface) const = 0;
+ Array _mesh_surface_get_skeleton_aabb_bind(RID p_mesh, int p_surface) const;
virtual void mesh_remove_surface(RID p_mesh, int p_index) = 0;
virtual int mesh_get_surface_count(RID p_mesh) const = 0;
@@ -941,18 +944,29 @@ public:
};
// make variant understand the enums
-
VARIANT_ENUM_CAST(VisualServer::CubeMapSide);
VARIANT_ENUM_CAST(VisualServer::TextureFlags);
VARIANT_ENUM_CAST(VisualServer::ShaderMode);
VARIANT_ENUM_CAST(VisualServer::ArrayType);
VARIANT_ENUM_CAST(VisualServer::ArrayFormat);
VARIANT_ENUM_CAST(VisualServer::PrimitiveType);
+VARIANT_ENUM_CAST(VisualServer::BlendShapeMode);
VARIANT_ENUM_CAST(VisualServer::LightType);
VARIANT_ENUM_CAST(VisualServer::LightParam);
+VARIANT_ENUM_CAST(VisualServer::ViewportUpdateMode);
+VARIANT_ENUM_CAST(VisualServer::ViewportClearMode);
+VARIANT_ENUM_CAST(VisualServer::ViewportMSAA);
+VARIANT_ENUM_CAST(VisualServer::ViewportUsage);
+VARIANT_ENUM_CAST(VisualServer::ViewportRenderInfo);
+VARIANT_ENUM_CAST(VisualServer::ViewportDebugDraw);
VARIANT_ENUM_CAST(VisualServer::ScenarioDebugMode);
VARIANT_ENUM_CAST(VisualServer::InstanceType);
+VARIANT_ENUM_CAST(VisualServer::NinePatchAxisMode);
+VARIANT_ENUM_CAST(VisualServer::CanvasLightMode);
+VARIANT_ENUM_CAST(VisualServer::CanvasLightShadowFilter);
+VARIANT_ENUM_CAST(VisualServer::CanvasOccluderPolygonCullMode);
VARIANT_ENUM_CAST(VisualServer::RenderInfo);
+VARIANT_ENUM_CAST(VisualServer::Features);
//typedef VisualServer VS; // makes it easier to use
#define VS VisualServer
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 6e1dcb8df4..335fcdd80b 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -121,7 +121,7 @@ Files extracted from upstream source:
## libpng
- Upstream: http://libpng.org/pub/png/libpng.html
-- Version: 1.6.32
+- Version: 1.6.33
- License: libpng/zlib
Files extracted from upstream source:
diff --git a/thirdparty/enet/enet/enet.h b/thirdparty/enet/enet/enet.h
index 8c9ad5463e..246cbb0a62 100644
--- a/thirdparty/enet/enet/enet.h
+++ b/thirdparty/enet/enet/enet.h
@@ -10,6 +10,7 @@ extern "C"
{
#endif
+#include <stdint.h>
#include <stdlib.h>
#include "enet/godot.h"
diff --git a/thirdparty/libpng/LICENSE b/thirdparty/libpng/LICENSE
index b7ad4b9eaf..57c366feea 100644
--- a/thirdparty/libpng/LICENSE
+++ b/thirdparty/libpng/LICENSE
@@ -10,8 +10,8 @@ this sentence.
This code is released under the libpng license.
-libpng versions 1.0.7, July 1, 2000 through 1.6.23, June 9, 2016 are
-Copyright (c) 2000-2002, 2004, 2006-2016 Glenn Randers-Pehrson, are
+libpng versions 1.0.7, July 1, 2000 through 1.6.33, September 28, 2017 are
+Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
derived from libpng-1.0.6, and are distributed according to the same
disclaimer and license as libpng-1.0.6 with the following individuals
added to the list of Contributing Authors:
@@ -22,6 +22,9 @@ added to the list of Contributing Authors:
Cosmin Truta
Gilles Vollant
James Yu
+ Mandar Sahastrabuddhe
+ Google Inc.
+ Vadim Barkov
and with the following additions to the disclaimer:
@@ -127,4 +130,4 @@ any encryption software. See the EAR, paragraphs 734.3(b)(3) and
Glenn Randers-Pehrson
glennrp at users.sourceforge.net
-June 9, 2016
+September 28, 2017
diff --git a/thirdparty/libpng/png.c b/thirdparty/libpng/png.c
index 2352df13cb..55134729c7 100644
--- a/thirdparty/libpng/png.c
+++ b/thirdparty/libpng/png.c
@@ -1,7 +1,7 @@
/* png.c - location for general purpose libpng functions
*
- * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -14,7 +14,7 @@
#include "pngpriv.h"
/* Generate a compiler error if there is an old png.h in the search path. */
-typedef png_libpng_version_1_6_32 Your_png_h_is_not_version_1_6_32;
+typedef png_libpng_version_1_6_33 Your_png_h_is_not_version_1_6_33;
#ifdef __GNUC__
/* The version tests may need to be added to, but the problem warning has
@@ -816,14 +816,14 @@ png_get_copyright(png_const_structrp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.32 - August 24, 2017" PNG_STRING_NEWLINE \
+ "libpng version 1.6.33 - September 28, 2017" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson" \
PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
- return "libpng version 1.6.32 - August 24, 2017\
+ return "libpng version 1.6.33 - September 28, 2017\
Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@@ -1913,12 +1913,12 @@ png_colorspace_set_sRGB(png_const_structrp png_ptr, png_colorspacerp colorspace,
*/
if (intent < 0 || intent >= PNG_sRGB_INTENT_LAST)
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
- (unsigned)intent, "invalid sRGB rendering intent");
+ (png_alloc_size_t)intent, "invalid sRGB rendering intent");
if ((colorspace->flags & PNG_COLORSPACE_HAVE_INTENT) != 0 &&
colorspace->rendering_intent != intent)
return png_icc_profile_error(png_ptr, colorspace, "sRGB",
- (unsigned)intent, "inconsistent rendering intents");
+ (png_alloc_size_t)intent, "inconsistent rendering intents");
if ((colorspace->flags & PNG_COLORSPACE_FROM_sRGB) != 0)
{
@@ -1979,7 +1979,6 @@ icc_check_length(png_const_structrp png_ptr, png_colorspacerp colorspace,
if (profile_length < 132)
return png_icc_profile_error(png_ptr, colorspace, name, profile_length,
"too short");
-
return 1;
}
@@ -2224,22 +2223,23 @@ png_icc_check_tag_table(png_const_structrp png_ptr, png_colorspacerp colorspace,
* being in range. All defined tag types have an 8 byte header - a 4 byte
* type signature then 0.
*/
+
+ /* This is a hard error; potentially it can cause read outside the
+ * profile.
+ */
+ if (tag_start > profile_length || tag_length > profile_length - tag_start)
+ return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
+ "ICC profile tag outside profile");
+
if ((tag_start & 3) != 0)
{
- /* CNHP730S.icc shipped with Microsoft Windows 64 violates this, it is
+ /* CNHP730S.icc shipped with Microsoft Windows 64 violates this; it is
* only a warning here because libpng does not care about the
* alignment.
*/
(void)png_icc_profile_error(png_ptr, NULL, name, tag_id,
"ICC profile tag start not a multiple of 4");
}
-
- /* This is a hard error; potentially it can cause read outside the
- * profile.
- */
- if (tag_start > profile_length || tag_length > profile_length - tag_start)
- return png_icc_profile_error(png_ptr, colorspace, name, tag_id,
- "ICC profile tag outside profile");
}
return 1; /* success, maybe with warnings */
@@ -3761,7 +3761,7 @@ png_log16bit(png_uint_32 x)
* of getting this accuracy in practice.
*
* To deal with this the following exp() function works out the exponent of the
- * frational part of the logarithm by using an accurate 32-bit value from the
+ * fractional part of the logarithm by using an accurate 32-bit value from the
* top four fractional bits then multiplying in the remaining bits.
*/
static const png_uint_32
diff --git a/thirdparty/libpng/png.h b/thirdparty/libpng/png.h
index 51ac8abe74..a5f142b89c 100644
--- a/thirdparty/libpng/png.h
+++ b/thirdparty/libpng/png.h
@@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
- * libpng version 1.6.32, August 24, 2017
+ * libpng version 1.6.33, September 28, 2017
*
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@@ -12,7 +12,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89, June 1996, through 0.96, May 1997: Andreas Dilger
- * libpng versions 0.97, January 1998, through 1.6.32, August 24, 2017:
+ * libpng versions 0.97, January 1998, through 1.6.33, September 28, 2017:
* Glenn Randers-Pehrson.
* See also "Contributing Authors", below.
*/
@@ -25,7 +25,7 @@
*
* This code is released under the libpng license.
*
- * libpng versions 1.0.7, July 1, 2000 through 1.6.32, August 24, 2017 are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.33, September 28, 2017 are
* Copyright (c) 2000-2002, 2004, 2006-2017 Glenn Randers-Pehrson, are
* derived from libpng-1.0.6, and are distributed according to the same
* disclaimer and license as libpng-1.0.6 with the following individuals
@@ -213,7 +213,7 @@
* ...
* 1.5.28 15 10527 15.so.15.28[.0]
* ...
- * 1.6.32 16 10632 16.so.16.32[.0]
+ * 1.6.33 16 10633 16.so.16.33[.0]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
@@ -241,13 +241,13 @@
* Y2K compliance in libpng:
* =========================
*
- * August 24, 2017
+ * September 28, 2017
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
*
* This is your unofficial assurance that libpng from version 0.71 and
- * upward through 1.6.32 are Y2K compliant. It is my belief that
+ * upward through 1.6.33 are Y2K compliant. It is my belief that
* earlier versions were also Y2K compliant.
*
* Libpng only has two year fields. One is a 2-byte unsigned integer
@@ -309,8 +309,8 @@
*/
/* Version information for png.h - this should match the version in png.c */
-#define PNG_LIBPNG_VER_STRING "1.6.32"
-#define PNG_HEADER_VERSION_STRING " libpng version 1.6.32 - August 24, 2017\n"
+#define PNG_LIBPNG_VER_STRING "1.6.33"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.33 - September 28, 2017\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@@ -318,7 +318,7 @@
/* These should match the first 3 components of PNG_LIBPNG_VER_STRING: */
#define PNG_LIBPNG_VER_MAJOR 1
#define PNG_LIBPNG_VER_MINOR 6
-#define PNG_LIBPNG_VER_RELEASE 32
+#define PNG_LIBPNG_VER_RELEASE 33
/* This should match the numeric part of the final component of
* PNG_LIBPNG_VER_STRING, omitting any leading zero:
@@ -349,7 +349,7 @@
* version 1.0.0 was mis-numbered 100 instead of 10000). From
* version 1.0.1 it's xxyyzz, where x=major, y=minor, z=release
*/
-#define PNG_LIBPNG_VER 10632 /* 1.6.32 */
+#define PNG_LIBPNG_VER 10633 /* 1.6.33 */
/* Library configuration: these options cannot be changed after
* the library has been built.
@@ -459,7 +459,7 @@ extern "C" {
/* This triggers a compiler error in png.c, if png.c and png.h
* do not agree upon the version number.
*/
-typedef char* png_libpng_version_1_6_32;
+typedef char* png_libpng_version_1_6_33;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@@ -2819,6 +2819,8 @@ typedef struct
# define PNG_FORMAT_FLAG_AFIRST 0x20U /* alpha channel comes first */
#endif
+#define PNG_FORMAT_FLAG_ASSOCIATED_ALPHA 0x40U /* alpha channel is associated */
+
/* Commonly used formats have predefined macros.
*
* First the single byte (sRGB) formats:
diff --git a/thirdparty/libpng/pngconf.h b/thirdparty/libpng/pngconf.h
index c0f15547be..e99e827dda 100644
--- a/thirdparty/libpng/pngconf.h
+++ b/thirdparty/libpng/pngconf.h
@@ -1,7 +1,7 @@
/* pngconf.h - machine configurable file for libpng
*
- * libpng version 1.6.32, August 24, 2017
+ * libpng version 1.6.33, September 28, 2017
*
* Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
diff --git a/thirdparty/libpng/pnglibconf.h b/thirdparty/libpng/pnglibconf.h
index 9e45f73129..cbf715dd93 100644
--- a/thirdparty/libpng/pnglibconf.h
+++ b/thirdparty/libpng/pnglibconf.h
@@ -1,8 +1,8 @@
-/* libpng 1.6.32 STANDARD API DEFINITION */
+/* libpng 1.6.33 STANDARD API DEFINITION */
/* pnglibconf.h - library build configuration */
-/* Libpng version 1.6.32 - August 24, 2017 */
+/* Libpng version 1.6.33 - September 28, 2017 */
/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */
diff --git a/thirdparty/libpng/pngread.c b/thirdparty/libpng/pngread.c
index e34ddd99a0..da32e9ad9c 100644
--- a/thirdparty/libpng/pngread.c
+++ b/thirdparty/libpng/pngread.c
@@ -1,7 +1,7 @@
/* pngread.c - read a PNG file
*
- * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -3759,7 +3759,13 @@ png_image_read_direct(png_voidp argument)
mode = PNG_ALPHA_PNG;
output_gamma = PNG_DEFAULT_sRGB;
}
-
+
+ if ((change & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0)
+ {
+ mode = PNG_ALPHA_OPTIMIZED;
+ change &= ~PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+ }
+
/* If 'do_local_background' is set check for the presence of gamma
* correction; this is part of the work-round for the libpng bug
* described above.
@@ -3985,6 +3991,10 @@ png_image_read_direct(png_voidp argument)
else if (do_local_compose != 0) /* internal error */
png_error(png_ptr, "png_image_read: alpha channel lost");
+ if ((format & PNG_FORMAT_FLAG_ASSOCIATED_ALPHA) != 0) {
+ info_format |= PNG_FORMAT_FLAG_ASSOCIATED_ALPHA;
+ }
+
if (info_ptr->bit_depth == 16)
info_format |= PNG_FORMAT_FLAG_LINEAR;
diff --git a/thirdparty/libpng/pngrtran.c b/thirdparty/libpng/pngrtran.c
index 9a30ddf22b..c189650313 100644
--- a/thirdparty/libpng/pngrtran.c
+++ b/thirdparty/libpng/pngrtran.c
@@ -1,7 +1,7 @@
/* pngrtran.c - transforms the data in a row for PNG readers
*
- * Last changed in libpng 1.6.31 [July 27, 2017]
+ * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -430,7 +430,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
int i;
png_ptr->quantize_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
for (i = 0; i < num_palette; i++)
png_ptr->quantize_index[i] = (png_byte)i;
}
@@ -447,7 +447,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize an array to sort colors */
png_ptr->quantize_sort = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)((png_uint_32)num_palette * (sizeof (png_byte))));
/* Initialize the quantize_sort array */
for (i = 0; i < num_palette; i++)
@@ -581,9 +581,11 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
/* Initialize palette index arrays */
png_ptr->index_to_palette = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)((png_uint_32)num_palette *
+ (sizeof (png_byte))));
png_ptr->palette_to_index = (png_bytep)png_malloc(png_ptr,
- (png_uint_32)((png_uint_32)num_palette * (sizeof (png_byte))));
+ (png_alloc_size_t)((png_uint_32)num_palette *
+ (sizeof (png_byte))));
/* Initialize the sort array */
for (i = 0; i < num_palette; i++)
@@ -592,7 +594,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_ptr->palette_to_index[i] = (png_byte)i;
}
- hash = (png_dsortpp)png_calloc(png_ptr, (png_uint_32)(769 *
+ hash = (png_dsortpp)png_calloc(png_ptr, (png_alloc_size_t)(769 *
(sizeof (png_dsortp))));
num_new_palette = num_palette;
@@ -623,7 +625,7 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
{
t = (png_dsortp)png_malloc_warn(png_ptr,
- (png_uint_32)(sizeof (png_dsort)));
+ (png_alloc_size_t)(sizeof (png_dsort)));
if (t == NULL)
break;
@@ -748,9 +750,9 @@ png_set_quantize(png_structrp png_ptr, png_colorp palette,
png_size_t num_entries = ((png_size_t)1 << total_bits);
png_ptr->palette_lookup = (png_bytep)png_calloc(png_ptr,
- (png_uint_32)(num_entries * (sizeof (png_byte))));
+ (png_alloc_size_t)(num_entries * (sizeof (png_byte))));
- distance = (png_bytep)png_malloc(png_ptr, (png_uint_32)(num_entries *
+ distance = (png_bytep)png_malloc(png_ptr, (png_alloc_size_t)(num_entries *
(sizeof (png_byte))));
memset(distance, 0xff, num_entries * (sizeof (png_byte)));
@@ -3322,7 +3324,7 @@ png_do_compose(png_row_infop row_info, png_bytep row, png_structrp png_ptr)
== png_ptr->trans_color.gray)
{
unsigned int tmp = *sp & (0x0f0f >> (4 - shift));
- tmp |=
+ tmp |=
(unsigned int)(png_ptr->background.gray << shift);
*sp = (png_byte)(tmp & 0xff);
}
diff --git a/thirdparty/libpng/pngrutil.c b/thirdparty/libpng/pngrutil.c
index a4fa71457b..8692933bd8 100644
--- a/thirdparty/libpng/pngrutil.c
+++ b/thirdparty/libpng/pngrutil.c
@@ -1,7 +1,7 @@
/* pngrutil.c - utilities to read a PNG file
*
- * Last changed in libpng 1.6.32 [August 24, 2017]
+ * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -314,6 +314,7 @@ png_read_buffer(png_structrp png_ptr, png_alloc_size_t new_size, int warn)
if (buffer != NULL)
{
+ memset(buffer, 0, new_size); /* just in case */
png_ptr->read_buffer = buffer;
png_ptr->read_buffer_size = new_size;
}
@@ -673,6 +674,8 @@ png_decompress_chunk(png_structrp png_ptr,
if (text != NULL)
{
+ memset(text, 0, buffer_size);
+
ret = png_inflate(png_ptr, png_ptr->chunk_name, 1/*finish*/,
png_ptr->read_buffer + prefix_size, &lzsize,
text + prefix_size, newlength);
@@ -736,9 +739,7 @@ png_decompress_chunk(png_structrp png_ptr,
{
/* inflateReset failed, store the error message */
png_zstream_error(png_ptr, ret);
-
- if (ret == Z_STREAM_END)
- ret = PNG_UNEXPECTED_ZLIB_RETURN;
+ ret = PNG_UNEXPECTED_ZLIB_RETURN;
}
}
@@ -1476,7 +1477,7 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
/* Now read the tag table; a variable size buffer is
* needed at this point, allocate one for the whole
* profile. The header check has already validated
- * that none of these stuff will overflow.
+ * that none of this stuff will overflow.
*/
const png_uint_32 tag_count = png_get_uint_32(
profile_header+128);
@@ -1583,19 +1584,11 @@ png_handle_iCCP(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
return;
}
}
-
- else if (size > 0)
- errmsg = "truncated";
-
-#ifndef __COVERITY__
- else
+ if (errmsg == NULL)
errmsg = png_ptr->zstream.msg;
-#endif
}
-
/* else png_icc_check_tag_table output an error */
}
-
else /* profile truncated */
errmsg = png_ptr->zstream.msg;
}
@@ -3144,28 +3137,28 @@ png_check_chunk_length(png_const_structrp png_ptr, const png_uint_32 length)
{
png_alloc_size_t limit = PNG_UINT_31_MAX;
- if (png_ptr->chunk_name != png_IDAT)
- {
# ifdef PNG_SET_USER_LIMITS_SUPPORTED
- if (png_ptr->user_chunk_malloc_max > 0 &&
- png_ptr->user_chunk_malloc_max < limit)
- limit = png_ptr->user_chunk_malloc_max;
+ if (png_ptr->user_chunk_malloc_max > 0 &&
+ png_ptr->user_chunk_malloc_max < limit)
+ limit = png_ptr->user_chunk_malloc_max;
# elif PNG_USER_CHUNK_MALLOC_MAX > 0
- if (PNG_USER_CHUNK_MALLOC_MAX < limit)
- limit = PNG_USER_CHUNK_MALLOC_MAX;
+ if (PNG_USER_CHUNK_MALLOC_MAX < limit)
+ limit = PNG_USER_CHUNK_MALLOC_MAX;
# endif
- }
- else
+ if (png_ptr->chunk_name == png_IDAT)
{
+ png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
size_t row_factor =
(png_ptr->width * png_ptr->channels * (png_ptr->bit_depth > 8? 2: 1)
+ 1 + (png_ptr->interlaced? 6: 0));
if (png_ptr->height > PNG_UINT_32_MAX/row_factor)
- limit=PNG_UINT_31_MAX;
+ idat_limit=PNG_UINT_31_MAX;
else
- limit = png_ptr->height * row_factor;
- limit += 6 + 5*(limit/32566+1); /* zlib+deflate overhead */
- limit=limit < PNG_UINT_31_MAX? limit : PNG_UINT_31_MAX;
+ idat_limit = png_ptr->height * row_factor;
+ row_factor = row_factor > 32566? 32566 : row_factor;
+ idat_limit += 6 + 5*(idat_limit/row_factor+1); /* zlib+deflate overhead */
+ idat_limit=idat_limit < PNG_UINT_31_MAX? idat_limit : PNG_UINT_31_MAX;
+ limit = limit < idat_limit? idat_limit : limit;
}
if (length > limit)
diff --git a/thirdparty/libpng/pngtrans.c b/thirdparty/libpng/pngtrans.c
index 326ac33f0e..6882f0fd7b 100644
--- a/thirdparty/libpng/pngtrans.c
+++ b/thirdparty/libpng/pngtrans.c
@@ -1,7 +1,7 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
- * Last changed in libpng 1.6.30 [June 28, 2017]
+ * Last changed in libpng 1.6.33 [September 28, 2017]
* Copyright (c) 1998-2002,2004,2006-2017 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@@ -609,7 +609,7 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
return; /* The filler channel has gone already */
/* Fix the rowbytes value. */
- row_info->rowbytes = (unsigned int)(dp-row);
+ row_info->rowbytes = (png_size_t)(dp-row);
}
#endif
@@ -708,7 +708,7 @@ png_do_check_palette_indexes(png_structrp png_ptr, png_row_infop row_info)
* forms produced on either GCC or MSVC.
*/
int padding = PNG_PADBITS(row_info->pixel_depth, row_info->width);
- png_bytep rp = png_ptr->row_buf + row_info->rowbytes;
+ png_bytep rp = png_ptr->row_buf + row_info->rowbytes - 1;
switch (row_info->bit_depth)
{
diff --git a/thirdparty/libpng/pngwrite.c b/thirdparty/libpng/pngwrite.c
index a7662acb71..a16d77ce00 100644
--- a/thirdparty/libpng/pngwrite.c
+++ b/thirdparty/libpng/pngwrite.c
@@ -1940,7 +1940,7 @@ png_image_write_main(png_voidp argument)
int colormap = (format & PNG_FORMAT_FLAG_COLORMAP);
int linear = !colormap && (format & PNG_FORMAT_FLAG_LINEAR); /* input */
int alpha = !colormap && (format & PNG_FORMAT_FLAG_ALPHA);
- int write_16bit = linear && !colormap && (display->convert_to_8bit == 0);
+ int write_16bit = linear && (display->convert_to_8bit == 0);
# ifdef PNG_BENIGN_ERRORS_SUPPORTED
/* Make sure we error out on any bad situation */