summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--SConstruct4
-rw-r--r--core/bind/core_bind.cpp1
-rw-r--r--core/bind/core_bind.h3
-rw-r--r--core/engine.cpp2
-rw-r--r--core/engine.h4
-rw-r--r--core/global_config.cpp80
-rw-r--r--core/global_config.h5
-rw-r--r--core/io/compression.cpp34
-rw-r--r--core/io/compression.h8
-rw-r--r--core/io/packet_peer.cpp2
-rw-r--r--core/io/resource_format_binary.cpp73
-rw-r--r--core/math/audio_frame.h10
-rw-r--r--core/math/vector3.h6
-rw-r--r--core/message_queue.cpp2
-rw-r--r--core/object.cpp26
-rw-r--r--core/object.h9
-rw-r--r--core/os/os.cpp2
-rw-r--r--core/register_core_types.cpp2
-rw-r--r--core/safe_refcount.cpp189
-rw-r--r--core/safe_refcount.h8
-rw-r--r--core/script_debugger_remote.cpp4
-rw-r--r--core/script_language.cpp5
-rw-r--r--core/script_language.h5
-rw-r--r--core/self_list.h19
-rw-r--r--core/variant_call.cpp2
-rw-r--r--doc/base/classes.xml3622
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp51
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h33
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp25
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h4
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl61
-rw-r--r--drivers/unix/os_unix.cpp6
-rw-r--r--editor/SCsub2
-rw-r--r--editor/animation_editor.cpp1
-rw-r--r--editor/asset_library_editor_plugin.cpp17
-rw-r--r--editor/editor_node.cpp195
-rw-r--r--editor/editor_node.h8
-rw-r--r--editor/editor_run.cpp8
-rw-r--r--editor/editor_settings.cpp9
-rw-r--r--editor/editor_themes.cpp248
-rw-r--r--editor/icons/2x/icon_GUI_checked.pngbin0 -> 516 bytes
-rw-r--r--editor/icons/2x/icon_GUI_dropdown.pngbin0 -> 183 bytes
-rw-r--r--editor/icons/2x/icon_GUI_hslider_bg.pngbin0 -> 124 bytes
-rw-r--r--editor/icons/2x/icon_GUI_hsplitter.pngbin0 -> 190 bytes
-rw-r--r--editor/icons/2x/icon_GUI_option_arrow.pngbin0 -> 304 bytes
-rw-r--r--editor/icons/2x/icon_GUI_play_button_group.pngbin0 -> 886 bytes
-rw-r--r--editor/icons/2x/icon_GUI_progress_bar.pngbin0 -> 289 bytes
-rw-r--r--editor/icons/2x/icon_GUI_progress_fill.pngbin0 -> 196 bytes
-rw-r--r--editor/icons/2x/icon_GUI_scroll_bg.pngbin0 -> 99 bytes
-rw-r--r--editor/icons/2x/icon_GUI_scroll_grabber.pngbin0 -> 193 bytes
-rw-r--r--editor/icons/2x/icon_GUI_scroll_grabber_hl.pngbin0 -> 297 bytes
-rw-r--r--editor/icons/2x/icon_GUI_slider_grabber.pngbin0 -> 260 bytes
-rw-r--r--editor/icons/2x/icon_GUI_slider_grabber_hl.pngbin0 -> 1040 bytes
-rw-r--r--editor/icons/2x/icon_GUI_spinbox_updown.pngbin0 -> 516 bytes
-rw-r--r--editor/icons/2x/icon_GUI_tab_menu.pngbin0 -> 221 bytes
-rw-r--r--editor/icons/2x/icon_GUI_toggle_off.pngbin0 -> 2606 bytes
-rw-r--r--editor/icons/2x/icon_GUI_toggle_on.pngbin0 -> 2178 bytes
-rw-r--r--editor/icons/2x/icon_GUI_tree_arrow_down.pngbin0 -> 256 bytes
-rw-r--r--editor/icons/2x/icon_GUI_tree_arrow_right.pngbin0 -> 263 bytes
-rw-r--r--editor/icons/2x/icon_GUI_unchecked.pngbin0 -> 369 bytes
-rw-r--r--editor/icons/2x/icon_GUI_vslider_bg.pngbin0 -> 131 bytes
-rw-r--r--editor/icons/2x/icon_GUI_vsplit_bg.pngbin0 -> 104 bytes
-rw-r--r--editor/icons/2x/icon_GUI_vsplitter.pngbin0 -> 168 bytes
-rw-r--r--editor/icons/2x/icon_gui_close_dark.pngbin0 -> 371 bytes
-rw-r--r--editor/icons/2x/icon_gui_close_light.pngbin0 -> 366 bytes
-rw-r--r--editor/icons/2x/icon_help.pngbin1126 -> 654 bytes
-rw-r--r--editor/icons/2x/icon_help_search.pngbin0 -> 881 bytes
-rw-r--r--editor/icons/2x/icon_variant.pngbin0 -> 398 bytes
-rw-r--r--editor/icons/icon_GUI_checked.pngbin0 -> 341 bytes
-rw-r--r--editor/icons/icon_GUI_dropdown.pngbin0 -> 130 bytes
-rw-r--r--editor/icons/icon_GUI_hslider_bg.pngbin0 -> 105 bytes
-rw-r--r--editor/icons/icon_GUI_hsplitter.pngbin0 -> 132 bytes
-rw-r--r--editor/icons/icon_GUI_option_arrow.pngbin0 -> 205 bytes
-rw-r--r--editor/icons/icon_GUI_play_button_group.pngbin0 -> 427 bytes
-rw-r--r--editor/icons/icon_GUI_progress_bar.pngbin0 -> 183 bytes
-rw-r--r--editor/icons/icon_GUI_progress_fill.pngbin0 -> 139 bytes
-rw-r--r--editor/icons/icon_GUI_scroll_bg.pngbin0 -> 90 bytes
-rw-r--r--editor/icons/icon_GUI_scroll_grabber.pngbin0 -> 147 bytes
-rw-r--r--editor/icons/icon_GUI_scroll_grabber_hl.pngbin0 -> 176 bytes
-rw-r--r--editor/icons/icon_GUI_slider_grabber.pngbin0 -> 168 bytes
-rw-r--r--editor/icons/icon_GUI_slider_grabber_hl.pngbin0 -> 477 bytes
-rw-r--r--editor/icons/icon_GUI_spinbox_updown.pngbin0 -> 345 bytes
-rw-r--r--editor/icons/icon_GUI_tab_menu.pngbin0 -> 146 bytes
-rw-r--r--editor/icons/icon_GUI_toggle_off.pngbin0 -> 1143 bytes
-rw-r--r--editor/icons/icon_GUI_toggle_on.pngbin0 -> 1030 bytes
-rw-r--r--editor/icons/icon_GUI_tree_arrow_down.pngbin0 -> 170 bytes
-rw-r--r--editor/icons/icon_GUI_tree_arrow_right.pngbin0 -> 189 bytes
-rw-r--r--editor/icons/icon_GUI_unchecked.pngbin0 -> 231 bytes
-rw-r--r--editor/icons/icon_GUI_vslider_bg.pngbin0 -> 108 bytes
-rw-r--r--editor/icons/icon_GUI_vsplit_bg.pngbin0 -> 96 bytes
-rw-r--r--editor/icons/icon_GUI_vsplitter.pngbin0 -> 122 bytes
-rw-r--r--editor/icons/icon_gui_close_dark.pngbin0 -> 171 bytes
-rw-r--r--editor/icons/icon_gui_close_light.pngbin0 -> 216 bytes
-rw-r--r--editor/icons/icon_help.pngbin578 -> 353 bytes
-rw-r--r--editor/icons/icon_help_search.pngbin0 -> 431 bytes
-rw-r--r--editor/icons/icon_variant.pngbin240 -> 237 bytes
-rw-r--r--editor/icons/source/icon_GUI_checked.svg79
-rw-r--r--editor/icons/source/icon_GUI_dropdown.svg93
-rw-r--r--editor/icons/source/icon_GUI_hslider_bg.svg83
-rw-r--r--editor/icons/source/icon_GUI_hsplitter.svg79
-rw-r--r--editor/icons/source/icon_GUI_option_arrow.svg80
-rw-r--r--editor/icons/source/icon_GUI_play_button_group.svg78
-rw-r--r--editor/icons/source/icon_GUI_progress_bar.svg81
-rw-r--r--editor/icons/source/icon_GUI_progress_fill.svg83
-rw-r--r--editor/icons/source/icon_GUI_scroll_bg.svg71
-rw-r--r--editor/icons/source/icon_GUI_scroll_grabber.svg78
-rw-r--r--editor/icons/source/icon_GUI_scroll_grabber_hl.svg82
-rw-r--r--editor/icons/source/icon_GUI_slider_grabber.svg81
-rw-r--r--editor/icons/source/icon_GUI_slider_grabber_hl.svg86
-rw-r--r--editor/icons/source/icon_GUI_spinbox_updown.svg83
-rw-r--r--editor/icons/source/icon_GUI_tab_menu.svg92
-rw-r--r--editor/icons/source/icon_GUI_toggle_off.svg80
-rw-r--r--editor/icons/source/icon_GUI_toggle_on.svg80
-rw-r--r--editor/icons/source/icon_GUI_tree_arrow_down.svg80
-rw-r--r--editor/icons/source/icon_GUI_tree_arrow_right.svg80
-rw-r--r--editor/icons/source/icon_GUI_unchecked.svg77
-rw-r--r--editor/icons/source/icon_GUI_vslider_bg.svg83
-rw-r--r--editor/icons/source/icon_GUI_vsplit_bg.svg79
-rw-r--r--editor/icons/source/icon_GUI_vsplitter.svg79
-rw-r--r--editor/icons/source/icon_gui_close_dark.svg79
-rw-r--r--editor/icons/source/icon_gui_close_light.svg79
-rw-r--r--editor/icons/source/icon_help.svg50
-rw-r--r--editor/icons/source/icon_help_search.svg91
-rw-r--r--editor/icons/source/icon_variant.svg146
-rw-r--r--editor/import/resource_importer_obj.cpp335
-rw-r--r--editor/import/resource_importer_obj.h25
-rw-r--r--editor/import/resource_importer_scene.cpp9
-rw-r--r--editor/import/resource_importer_texture.cpp8
-rw-r--r--editor/import_dock.cpp1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp71
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h3
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp2
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp638
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.h18
-rw-r--r--editor/plugins/mesh_instance_editor_plugin.cpp2
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp8
-rw-r--r--editor/plugins/script_editor_plugin.cpp12
-rw-r--r--editor/plugins/script_editor_plugin.h4
-rw-r--r--editor/plugins/script_text_editor.cpp3
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp33
-rw-r--r--editor/plugins/spatial_editor_plugin.h1
-rw-r--r--editor/project_export.cpp2
-rw-r--r--editor/project_settings.cpp2
-rw-r--r--editor/property_editor.cpp35
-rw-r--r--editor/property_editor.h6
-rw-r--r--editor/scene_tree_dock.cpp17
-rw-r--r--editor/scene_tree_editor.cpp6
-rw-r--r--editor/script_editor_debugger.cpp29
-rw-r--r--editor/settings_config_dialog.cpp2
-rw-r--r--editor/spatial_editor_gizmos.cpp127
-rw-r--r--editor/spatial_editor_gizmos.h19
-rw-r--r--main/main.cpp160
-rw-r--r--modules/gdnative/godot/godot_dictionary.cpp8
-rw-r--r--modules/gdnative/godot/godot_dictionary.h2
-rw-r--r--modules/gdscript/gd_script.cpp2
-rw-r--r--modules/gridmap/grid_map.cpp1
-rw-r--r--modules/visual_script/visual_script.cpp2
-rw-r--r--modules/visual_script/visual_script_editor.cpp7
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp8
-rw-r--r--platform/android/export/export.cpp16
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/iphone/app_delegate.mm7
-rw-r--r--platform/javascript/SCsub39
-rw-r--r--platform/osx/audio_driver_osx.cpp114
-rw-r--r--platform/osx/audio_driver_osx.h7
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/osx/export/export.cpp8
-rw-r--r--platform/uwp/os_uwp.cpp2
-rw-r--r--platform/windows/os_windows.cpp2
-rw-r--r--platform/x11/os_x11.cpp27
-rw-r--r--scene/3d/area.cpp117
-rw-r--r--scene/3d/area.h28
-rw-r--r--scene/3d/audio_stream_player_3d.cpp930
-rw-r--r--scene/3d/audio_stream_player_3d.h175
-rw-r--r--scene/3d/body_shape.cpp920
-rw-r--r--scene/3d/camera.cpp40
-rw-r--r--scene/3d/camera.h16
-rw-r--r--scene/3d/collision_object.cpp287
-rw-r--r--scene/3d/collision_object.h57
-rw-r--r--scene/3d/collision_polygon.cpp237
-rw-r--r--scene/3d/collision_polygon.h29
-rw-r--r--scene/3d/collision_shape.cpp214
-rw-r--r--scene/3d/collision_shape.h (renamed from scene/3d/body_shape.h)38
-rw-r--r--scene/3d/gi_probe.cpp34
-rw-r--r--scene/3d/gi_probe.h7
-rw-r--r--scene/3d/mesh_instance.cpp26
-rw-r--r--scene/3d/physics_body.cpp569
-rw-r--r--scene/3d/physics_body.h107
-rw-r--r--scene/3d/reflection_probe.cpp2
-rw-r--r--scene/3d/spatial_velocity_tracker.cpp104
-rw-r--r--scene/3d/spatial_velocity_tracker.h31
-rw-r--r--scene/gui/button.cpp9
-rw-r--r--scene/gui/color_picker.cpp44
-rw-r--r--scene/gui/color_picker.h2
-rw-r--r--scene/gui/dialogs.cpp1
-rw-r--r--scene/gui/gradient_edit.cpp4
-rw-r--r--scene/gui/label.cpp1
-rw-r--r--scene/gui/line_edit.cpp11
-rw-r--r--scene/gui/option_button.cpp17
-rw-r--r--scene/gui/popup_menu.cpp11
-rw-r--r--scene/gui/popup_menu.h1
-rw-r--r--scene/gui/slider.cpp7
-rw-r--r--scene/gui/tabs.cpp18
-rw-r--r--scene/gui/tabs.h2
-rw-r--r--scene/gui/tree.cpp8
-rw-r--r--scene/main/scene_tree.cpp28
-rw-r--r--scene/main/viewport.cpp12
-rw-r--r--scene/register_scene_types.cpp15
-rw-r--r--scene/resources/audio_stream_sample.cpp2
-rw-r--r--scene/resources/default_theme/default_theme.cpp10
-rw-r--r--scene/resources/environment.cpp2
-rw-r--r--scene/resources/mesh.cpp19
-rw-r--r--scene/resources/mesh.h2
-rw-r--r--scene/resources/sky_box.cpp9
-rw-r--r--scene/resources/style_box.cpp78
-rw-r--r--scene/resources/style_box.h34
-rw-r--r--scene/resources/surface_tool.cpp1
-rw-r--r--scene/resources/world.cpp7
-rw-r--r--scene/resources/world.h2
-rw-r--r--servers/audio/audio_filter_sw.cpp37
-rw-r--r--servers/audio/audio_filter_sw.h25
-rw-r--r--servers/audio/audio_stream.cpp131
-rw-r--r--servers/audio/audio_stream.h55
-rw-r--r--servers/physics/area_pair_sw.cpp22
-rw-r--r--servers/physics/body_pair_sw.cpp11
-rw-r--r--servers/physics/broad_phase_basic.cpp20
-rw-r--r--servers/physics/broad_phase_basic.h1
-rw-r--r--servers/physics/broad_phase_octree.cpp5
-rw-r--r--servers/physics/broad_phase_octree.h1
-rw-r--r--servers/physics/broad_phase_sw.h1
-rw-r--r--servers/physics/collision_object_sw.h8
-rw-r--r--servers/physics/physics_server_sw.cpp34
-rw-r--r--servers/physics/physics_server_sw.h9
-rw-r--r--servers/physics/shape_sw.cpp229
-rw-r--r--servers/physics/shape_sw.h24
-rw-r--r--servers/physics/space_sw.cpp417
-rw-r--r--servers/physics/space_sw.h6
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.cpp12
-rw-r--r--servers/physics_2d/space_2d_sw.cpp158
-rw-r--r--servers/physics_server.h38
-rw-r--r--servers/register_server_types.cpp3
-rw-r--r--servers/visual/rasterizer.h12
-rw-r--r--servers/visual/visual_server_raster.h3
-rw-r--r--servers/visual/visual_server_scene.cpp25
-rw-r--r--servers/visual/visual_server_viewport.cpp2
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp2
-rw-r--r--servers/visual/visual_server_wrap_mt.h3
-rw-r--r--servers/visual_server.cpp20
-rw-r--r--servers/visual_server.h3
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/libpng/png.c55
-rw-r--r--thirdparty/libpng/png.h26
-rw-r--r--thirdparty/libpng/pngconf.h2
-rw-r--r--thirdparty/libpng/pnglibconf.h6
-rw-r--r--thirdparty/libpng/pngpriv.h13
-rw-r--r--thirdparty/libpng/pngrtran.c8
-rw-r--r--thirdparty/libpng/pngrutil.c19
-rw-r--r--thirdparty/libpng/pngset.c15
-rw-r--r--thirdparty/libpng/pngtrans.c38
-rw-r--r--thirdparty/libpng/pngwutil.c6
265 files changed, 10085 insertions, 4706 deletions
diff --git a/README.md b/README.md
index 0c4ab6498a..dc0dad6b90 100644
--- a/README.md
+++ b/README.md
@@ -63,4 +63,4 @@ such as text and video tutorials, demos, etc. Consult the [community channels](h
for more info.
[![Build Status](https://travis-ci.org/godotengine/godot.svg?branch=master)](https://travis-ci.org/godotengine/godot)
-[![Code Triagers Badge](http://www.codetriage.com/godotengine/godot/badges/users.svg)](http://www.codetriage.com/godotengine/godot)
+[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
diff --git a/SConstruct b/SConstruct
index e2cfd3ec35..f8b2d82b66 100644
--- a/SConstruct
+++ b/SConstruct
@@ -210,8 +210,8 @@ if (env_base['target'] == 'debug'):
env_base.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC'])
env_base.Append(CPPFLAGS=['-DSCI_NAMESPACE'])
-if (env_base['deprecated'] != 'no'):
- env_base.Append(CPPFLAGS=['-DENABLE_DEPRECATED'])
+if (env_base['deprecated'] == 'no'):
+ env_base.Append(CPPFLAGS=['-DDISABLE_DEPRECATED'])
env_base.platforms = {}
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index e863078a48..a5ec9c1afc 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -1780,6 +1780,7 @@ void _File::_bind_methods() {
BIND_CONSTANT(COMPRESSION_FASTLZ);
BIND_CONSTANT(COMPRESSION_DEFLATE);
BIND_CONSTANT(COMPRESSION_ZSTD);
+ BIND_CONSTANT(COMPRESSION_GZIP);
}
_File::_File() {
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index f72f665d9e..ec4fd3f476 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -372,7 +372,8 @@ public:
enum CompressionMode {
COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
- COMPRESSION_ZSTD = Compression::MODE_ZSTD
+ COMPRESSION_ZSTD = Compression::MODE_ZSTD,
+ COMPRESSION_GZIP = Compression::MODE_GZIP
};
Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key);
diff --git a/core/engine.cpp b/core/engine.cpp
index 42850325b4..c16a2903d3 100644
--- a/core/engine.cpp
+++ b/core/engine.cpp
@@ -119,4 +119,6 @@ Engine::Engine() {
_fixed_frames = 0;
_idle_frames = 0;
_in_fixed = false;
+ _frame_ticks = 0;
+ _frame_step = 0;
}
diff --git a/core/engine.h b/core/engine.h
index 80b11c095d..16dfb77593 100644
--- a/core/engine.h
+++ b/core/engine.h
@@ -42,6 +42,8 @@ class Engine {
String _custom_level;
uint64_t frames_drawn;
uint32_t _frame_delay;
+ uint64_t _frame_ticks;
+ float _frame_step;
int ips;
float _fps;
@@ -72,6 +74,8 @@ public:
uint64_t get_fixed_frames() const { return _fixed_frames; }
uint64_t get_idle_frames() const { return _idle_frames; }
bool is_in_fixed_frame() const { return _in_fixed; }
+ uint64_t get_idle_frame_ticks() const { return _frame_ticks; }
+ float get_idle_frame_step() const { return _frame_step; }
void set_time_scale(float p_scale);
float get_time_scale() const;
diff --git a/core/global_config.cpp b/core/global_config.cpp
index caae73ee2e..95f4ec5e22 100644
--- a/core/global_config.cpp
+++ b/core/global_config.cpp
@@ -130,33 +130,8 @@ bool GlobalConfig::_set(const StringName &p_name, const Variant &p_value) {
if (!props[p_name].overrided)
props[p_name].variant = p_value;
- if (props[p_name].order >= NO_ORDER_BASE && registering_order) {
- props[p_name].order = last_order++;
- }
} else {
- props[p_name] = VariantContainer(p_value, last_order++ + (registering_order ? 0 : NO_ORDER_BASE));
- }
- }
-
- if (!disable_platform_override) {
-
- String s = String(p_name);
- int sl = s.find("/");
- int p = s.find(".");
- if (p != -1 && sl != -1 && p < sl) {
-
- Vector<String> ps = s.substr(0, sl).split(".");
- String prop = s.substr(sl, s.length() - sl);
- for (int i = 1; i < ps.size(); i++) {
-
- if (ps[i] == OS::get_singleton()->get_name()) {
-
- String fullprop = ps[0] + prop;
-
- set(fullprop, p_value);
- props[fullprop].overrided = true;
- }
- }
+ props[p_name] = VariantContainer(p_value, last_order++);
}
}
@@ -372,8 +347,6 @@ Error GlobalConfig::_load_settings_binary(const String p_path) {
ERR_FAIL_V(ERR_FILE_CORRUPT;)
}
- set_registering_order(false);
-
uint32_t count = f->get_32();
for (uint32_t i = 0; i < count; i++) {
@@ -397,8 +370,6 @@ Error GlobalConfig::_load_settings_binary(const String p_path) {
set(key, value);
}
- set_registering_order(true);
-
return OK;
}
Error GlobalConfig::_load_settings(const String p_path) {
@@ -468,6 +439,14 @@ void GlobalConfig::set_order(const String &p_name, int p_order) {
props[p_name].order = p_order;
}
+void GlobalConfig::set_builtin_order(const String &p_name) {
+
+ ERR_FAIL_COND(!props.has(p_name));
+ if (props[p_name].order >= NO_BUILTIN_ORDER_BASE) {
+ props[p_name].order = last_builtin_order++;
+ }
+}
+
void GlobalConfig::clear(const String &p_name) {
ERR_FAIL_COND(!props.has(p_name));
@@ -715,13 +694,16 @@ Error GlobalConfig::save_custom(const String &p_path, const CustomMap &p_custom,
Variant _GLOBAL_DEF(const String &p_var, const Variant &p_default) {
+ Variant ret;
if (GlobalConfig::get_singleton()->has(p_var)) {
- GlobalConfig::get_singleton()->set_initial_value(p_var, p_default);
- return GlobalConfig::get_singleton()->get(p_var);
+ ret = GlobalConfig::get_singleton()->get(p_var);
+ } else {
+ GlobalConfig::get_singleton()->set(p_var, p_default);
+ ret = p_default;
}
- GlobalConfig::get_singleton()->set(p_var, p_default);
GlobalConfig::get_singleton()->set_initial_value(p_var, p_default);
- return p_default;
+ GlobalConfig::get_singleton()->set_builtin_order(p_var);
+ return ret;
}
void GlobalConfig::add_singleton(const Singleton &p_singleton) {
@@ -843,7 +825,8 @@ void GlobalConfig::_bind_methods() {
GlobalConfig::GlobalConfig() {
singleton = this;
- last_order = 0;
+ last_order = NO_BUILTIN_ORDER_BASE;
+ last_builtin_order = 0;
disable_platform_override = false;
registering_order = true;
@@ -851,12 +834,12 @@ GlobalConfig::GlobalConfig() {
Ref<InputEventKey> key;
Ref<InputEventJoypadButton> joyb;
- GLOBAL_DEF("application/name", "");
- GLOBAL_DEF("application/main_scene", "");
- custom_prop_info["application/main_scene"] = PropertyInfo(Variant::STRING, "application/main_scene", PROPERTY_HINT_FILE, "tscn,scn,xscn,xml,res");
- GLOBAL_DEF("application/disable_stdout", false);
- GLOBAL_DEF("application/disable_stderr", false);
- GLOBAL_DEF("application/use_shared_user_dir", true);
+ GLOBAL_DEF("application/config/name", "");
+ GLOBAL_DEF("application/run/main_scene", "");
+ custom_prop_info["application/run/main_scene"] = PropertyInfo(Variant::STRING, "application/run/main_scene", PROPERTY_HINT_FILE, "tscn,scn,res");
+ GLOBAL_DEF("application/run/disable_stdout", false);
+ GLOBAL_DEF("application/run/disable_stderr", false);
+ GLOBAL_DEF("application/config/use_shared_user_dir", true);
key.instance();
key->set_scancode(KEY_RETURN);
@@ -964,16 +947,19 @@ GlobalConfig::GlobalConfig() {
//GLOBAL_DEF("display/handheld/orientation", "landscape");
- custom_prop_info["display/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
+ custom_prop_info["display/window/handheld/orientation"] = PropertyInfo(Variant::STRING, "display/window/handheld/orientation", PROPERTY_HINT_ENUM, "landscape,portrait,reverse_landscape,reverse_portrait,sensor_landscape,sensor_portrait,sensor");
custom_prop_info["rendering/threads/thread_model"] = PropertyInfo(Variant::INT, "rendering/threads/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
- GLOBAL_DEF("debug/profiler/max_functions", 16384);
+ GLOBAL_DEF("debug/settings/profiler/max_functions", 16384);
- GLOBAL_DEF("compression/zstd/compression_level", 3);
- custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1");
- GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION);
- custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
+ //assigning here, because using GLOBAL_GET on every block for compressing can be slow
+ Compression::zstd_level = GLOBAL_DEF("compression/formats/zstd/compression_level", 3);
+ custom_prop_info["compression/formats/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1");
+ Compression::zlib_level = GLOBAL_DEF("compression/formats/zlib/compression_level", Z_DEFAULT_COMPRESSION);
+ custom_prop_info["compression/formats/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
+ Compression::gzip_level = GLOBAL_DEF("compression/formats/gzip/compression_level", Z_DEFAULT_COMPRESSION);
+ custom_prop_info["compression/formats/gzip/compression_level"] = PropertyInfo(Variant::INT, "compression/formats/gzip/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
using_datapack = false;
}
diff --git a/core/global_config.h b/core/global_config.h
index d0f64dc23c..30c77bbc27 100644
--- a/core/global_config.h
+++ b/core/global_config.h
@@ -56,7 +56,8 @@ public:
protected:
enum {
- NO_ORDER_BASE = 1 << 18
+ //properties that are not for built in values begin from this value, so builtin ones are displayed first
+ NO_BUILTIN_ORDER_BASE = 1 << 16
};
struct VariantContainer {
@@ -83,6 +84,7 @@ protected:
bool registering_order;
int last_order;
+ int last_builtin_order;
Map<StringName, VariantContainer> props;
String resource_path;
Map<StringName, PropertyInfo> custom_prop_info;
@@ -130,6 +132,7 @@ public:
void clear(const String &p_name);
int get_order(const String &p_name) const;
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);
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index f806c4da6d..b0f5448b6c 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -52,23 +52,22 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
}
} break;
- case MODE_DEFLATE: {
+ case MODE_DEFLATE:
+ case MODE_GZIP: {
+
+ int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
- int level = GLOBAL_GET("compression/zlib/compression_level");
- int err = deflateInit(&strm, level);
+ int level = p_mode == MODE_DEFLATE ? zlib_level : gzip_level;
+ int err = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK)
return -1;
strm.avail_in = p_src_size;
int aout = deflateBound(&strm, p_src_size);
- /*if (aout>p_src_size) {
- deflateEnd(&strm);
- return -1;
- }*/
strm.avail_out = aout;
strm.next_in = (Bytef *)p_src;
strm.next_out = p_dst;
@@ -81,8 +80,7 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
case MODE_ZSTD: {
int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD);
- int level = GLOBAL_GET("compression/zstd/compression_level");
- return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, level);
+ return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, zstd_level);
} break;
}
@@ -100,13 +98,16 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
return ss;
} break;
- case MODE_DEFLATE: {
+ case MODE_DEFLATE:
+ case MODE_GZIP: {
+
+ int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
- int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
+ int err = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY);
if (err != Z_OK)
return -1;
int aout = deflateBound(&strm, p_src_size);
@@ -138,7 +139,10 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
}
return ret_size;
} break;
- case MODE_DEFLATE: {
+ case MODE_DEFLATE:
+ case MODE_GZIP: {
+
+ int window_bits = p_mode == MODE_DEFLATE ? 15 : 15 + 16;
z_stream strm;
strm.zalloc = zipio_alloc;
@@ -146,7 +150,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
- int err = inflateInit(&strm);
+ int err = inflateInit2(&strm, window_bits);
ERR_FAIL_COND_V(err != Z_OK, -1);
strm.avail_in = p_src_size;
@@ -168,3 +172,7 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
ERR_FAIL_V(-1);
}
+
+int Compression::zlib_level = Z_DEFAULT_COMPRESSION;
+int Compression::gzip_level = Z_DEFAULT_COMPRESSION;
+int Compression::zstd_level = 3;
diff --git a/core/io/compression.h b/core/io/compression.h
index 742f0f4d68..5eb7806d7b 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -33,11 +33,17 @@
#include "typedefs.h"
class Compression {
+
public:
+ static int zlib_level;
+ static int gzip_level;
+ static int zstd_level;
+
enum Mode {
MODE_FASTLZ,
MODE_DEFLATE,
- MODE_ZSTD
+ MODE_ZSTD,
+ MODE_GZIP
};
static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
diff --git a/core/io/packet_peer.cpp b/core/io/packet_peer.cpp
index ac68d5240c..93682e6b8a 100644
--- a/core/io/packet_peer.cpp
+++ b/core/io/packet_peer.cpp
@@ -254,7 +254,7 @@ void PacketPeerStream::set_input_buffer_max_size(int p_max_size) {
PacketPeerStream::PacketPeerStream() {
- int rbsize = GLOBAL_GET("network/packets/packet_stream_peer_max_buffer_po2");
+ int rbsize = GLOBAL_GET("network/limits/packet_peer_stream/max_buffer_po2");
ring_buffer.resize(rbsize);
temp_buffer.resize(1 << rbsize);
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index b474c2e078..728cd5d4ff 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -29,6 +29,7 @@
/*************************************************************************/
#include "resource_format_binary.h"
#include "global_config.h"
+#include "image.h"
#include "io/file_access_compressed.h"
#include "io/marshalls.h"
#include "os/dir_access.h"
@@ -54,7 +55,6 @@ enum {
VARIANT_TRANSFORM = 17,
VARIANT_MATRIX32 = 18,
VARIANT_COLOR = 20,
- //VARIANT_IMAGE = 21, - no longer variant type
VARIANT_NODE_PATH = 22,
VARIANT_RID = 23,
VARIANT_OBJECT = 24,
@@ -70,7 +70,13 @@ enum {
VARIANT_VECTOR2_ARRAY = 37,
VARIANT_INT64 = 40,
VARIANT_DOUBLE = 41,
-
+#ifndef DISABLE_DEPRECATED
+ VARIANT_IMAGE = 21, // - no longer variant type
+ IMAGE_ENCODING_EMPTY = 0,
+ IMAGE_ENCODING_RAW = 1,
+ IMAGE_ENCODING_LOSSLESS = 2,
+ IMAGE_ENCODING_LOSSY = 3,
+#endif
OBJECT_EMPTY = 0,
OBJECT_EXTERNAL_RESOURCE = 1,
OBJECT_INTERNAL_RESOURCE = 2,
@@ -541,7 +547,69 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
w = PoolVector<Color>::Write();
r_v = array;
} break;
+#ifndef DISABLE_DEPRECATED
+ case VARIANT_IMAGE: {
+ uint32_t encoding = f->get_32();
+ if (encoding == IMAGE_ENCODING_EMPTY) {
+ r_v = Ref<Image>();
+ break;
+ } else if (encoding == IMAGE_ENCODING_RAW) {
+ uint32_t width = f->get_32();
+ uint32_t height = f->get_32();
+ uint32_t mipmaps = f->get_32();
+ uint32_t format = f->get_32();
+ const uint32_t format_version_shift = 24;
+ const uint32_t format_version_mask = format_version_shift - 1;
+
+ uint32_t format_version = format >> format_version_shift;
+
+ const uint32_t current_version = 0;
+ if (format_version > current_version) {
+
+ ERR_PRINT("Format version for encoded binary image is too new");
+ return ERR_PARSE_ERROR;
+ }
+
+ Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top
+
+ uint32_t datalen = f->get_32();
+
+ PoolVector<uint8_t> imgdata;
+ imgdata.resize(datalen);
+ PoolVector<uint8_t>::Write w = imgdata.write();
+ f->get_buffer(w.ptr(), datalen);
+ _advance_padding(datalen);
+ w = PoolVector<uint8_t>::Write();
+
+ Ref<Image> image;
+ image.instance();
+ image->create(width, height, mipmaps, fmt, imgdata);
+ r_v = image;
+
+ } else {
+ //compressed
+ PoolVector<uint8_t> data;
+ data.resize(f->get_32());
+ PoolVector<uint8_t>::Write w = data.write();
+ f->get_buffer(w.ptr(), data.size());
+ w = PoolVector<uint8_t>::Write();
+
+ Ref<Image> image;
+ if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {
+
+ image = Image::lossy_unpacker(data);
+ } else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {
+
+ image = Image::lossless_unpacker(data);
+ }
+ _advance_padding(data.size());
+
+ r_v = image;
+ }
+
+ } break;
+#endif
default: {
ERR_FAIL_V(ERR_FILE_CORRUPT);
} break;
@@ -1644,7 +1712,6 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant
get_string_index(np.get_property());
} break;
-
default: {}
}
}
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index 5ccc9d9e5e..d54f622197 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -102,6 +102,16 @@ struct AudioFrame {
r = ::undenormalise(r);
}
+ _FORCE_INLINE_ AudioFrame linear_interpolate(const AudioFrame &p_b, float p_t) const {
+
+ AudioFrame res = *this;
+
+ res.l += (p_t * (p_b.l - l));
+ res.r += (p_t * (p_b.r - r));
+
+ return res;
+ }
+
_ALWAYS_INLINE_ AudioFrame(float p_l, float p_r) {
l = p_l;
r = p_r;
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 7dfcedd0da..6a7974681e 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -100,6 +100,7 @@ struct Vector3 {
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
+ _FORCE_INLINE_ Vector3 sign() const;
_FORCE_INLINE_ Vector3 ceil() const;
_FORCE_INLINE_ real_t distance_to(const Vector3 &p_b) const;
@@ -187,6 +188,11 @@ Vector3 Vector3::abs() const {
return Vector3(Math::abs(x), Math::abs(y), Math::abs(z));
}
+Vector3 Vector3::sign() const {
+
+ return Vector3(SGN(x), SGN(y), SGN(z));
+}
+
Vector3 Vector3::floor() const {
return Vector3(Math::floor(x), Math::floor(y), Math::floor(z));
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index d7d31b6c1e..1c980a56e3 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -382,7 +382,7 @@ MessageQueue::MessageQueue() {
buffer_end = 0;
buffer_max_used = 0;
- buffer_size = GLOBAL_DEF("memory/buffers/message_queue_max_size_kb", DEFAULT_QUEUE_SIZE_KB);
+ buffer_size = GLOBAL_DEF("memory/limits/message_queue/max_size_kb", DEFAULT_QUEUE_SIZE_KB);
buffer_size *= 1024;
buffer = memnew_arr(uint8_t, buffer_size);
}
diff --git a/core/object.cpp b/core/object.cpp
index 3416cd8c5a..9184fb9cd0 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1655,7 +1655,7 @@ void Object::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_script:Script"), &Object::get_script);
ClassDB::bind_method(D_METHOD("set_meta", "name", "value"), &Object::set_meta);
- ClassDB::bind_method(D_METHOD("get_meta", "name", "value"), &Object::get_meta);
+ ClassDB::bind_method(D_METHOD("get_meta:Variant", "name", "value"), &Object::get_meta);
ClassDB::bind_method(D_METHOD("has_meta", "name"), &Object::has_meta);
ClassDB::bind_method(D_METHOD("get_meta_list"), &Object::_get_meta_list_bind);
@@ -1817,6 +1817,23 @@ uint32_t Object::get_edited_version() const {
}
#endif
+void *Object::get_script_instance_binding(int p_script_language_index) {
+#ifdef DEBUG_ENABLED
+ ERR_FAIL_INDEX_V(p_script_language_index, MAX_SCRIPT_INSTANCE_BINDINGS, NULL);
+#endif
+
+ //it's up to the script language to make this thread safe, if the function is called twice due to threads being out of syncro
+ //just return the same pointer.
+ //if you want to put a big lock in the entire function and keep allocated pointers in a map or something, feel free to do it
+ //as it should not really affect performance much (won't be called too often), as in far most caes the condition below will be false afterwards
+
+ if (!_script_instance_bindings[p_script_language_index]) {
+ _script_instance_bindings[p_script_language_index] = ScriptServer::get_language(p_script_language_index)->alloc_instance_binding_data(this);
+ }
+
+ return _script_instance_bindings[p_script_language_index];
+}
+
Object::Object() {
_class_ptr = NULL;
@@ -1826,6 +1843,7 @@ Object::Object() {
_instance_ID = ObjectDB::add_instance(this);
_can_translate = true;
_is_queued_for_deletion = false;
+ memset(_script_instance_bindings, 0, sizeof(void *) * MAX_SCRIPT_INSTANCE_BINDINGS);
script_instance = NULL;
#ifdef TOOLS_ENABLED
@@ -1877,6 +1895,12 @@ Object::~Object() {
ObjectDB::remove_instance(this);
_instance_ID = 0;
_predelete_ok = 2;
+
+ for (int i = 0; i < MAX_SCRIPT_INSTANCE_BINDINGS; i++) {
+ if (_script_instance_bindings[i]) {
+ ScriptServer::get_language(i)->free_instance_binding_data(_script_instance_bindings[i]);
+ }
+ }
}
bool predelete_handler(Object *p_object) {
diff --git a/core/object.h b/core/object.h
index f87705c48b..556f3f1586 100644
--- a/core/object.h
+++ b/core/object.h
@@ -381,6 +381,10 @@ public:
};
private:
+ enum {
+ MAX_SCRIPT_INSTANCE_BINDINGS = 8
+ };
+
#ifdef DEBUG_ENABLED
friend class _ObjectDebugLock;
#endif
@@ -447,6 +451,8 @@ private:
void _set_bind(const String &p_set, const Variant &p_value);
Variant _get_bind(const String &p_name) const;
+ void *_script_instance_bindings[MAX_SCRIPT_INSTANCE_BINDINGS];
+
void property_list_changed_notify();
protected:
@@ -683,6 +689,9 @@ public:
bool editor_is_section_unfolded(const String &p_section);
#endif
+ //used by script languages to store binding data
+ void *get_script_instance_binding(int p_script_language_index);
+
void clear_internal_resource_paths();
Object();
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 8bee725813..48463722cf 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -269,7 +269,7 @@ String OS::get_system_dir(SystemDir p_dir) const {
}
String OS::get_safe_application_name() const {
- String an = GlobalConfig::get_singleton()->get("application/name");
+ String an = GlobalConfig::get_singleton()->get("application/config/name");
Vector<String> invalid_char = String("\\ / : * ? \" < > |").split(" ");
for (int i = 0; i < invalid_char.size(); i++) {
an = an.replace(invalid_char[i], "-");
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index b089ba9129..d6a521a86f 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -172,7 +172,7 @@ void register_core_types() {
void register_core_settings() {
//since in register core types, globals may not e present
- GLOBAL_DEF("network/packets/packet_stream_peer_max_buffer_po2", (16));
+ GLOBAL_DEF("network/limits/packet_peer_stream/max_buffer_po2", (16));
}
void register_core_singletons() {
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp
index e4a5a994e6..1bd16f9e4f 100644
--- a/core/safe_refcount.cpp
+++ b/core/safe_refcount.cpp
@@ -33,7 +33,10 @@
#ifdef NO_THREADS
-uint32_t atomic_conditional_increment(register uint32_t *pw) {
+/* Bogus implementation unaware of multiprocessing */
+
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) {
if (*pw == 0)
return 0;
@@ -43,74 +46,202 @@ uint32_t atomic_conditional_increment(register uint32_t *pw) {
return *pw;
}
-uint32_t atomic_increment(register uint32_t *pw) {
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) {
+
+ (*pw)--;
+
+ return *pw;
+}
+
+template <class T>
+static _ALWAYS_INLINE_T _atomic_increment_impl(register T *pw) {
(*pw)++;
return *pw;
}
-uint32_t atomic_decrement(register uint32_t *pw) {
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) {
- (*pw)--;
+ (*pw) -= val;
return *pw;
}
-#else
+template <class T>
+static _ALWAYS_INLINE_T _atomic_add_impl(register T *pw, register T val) {
-#ifdef _MSC_VER
+ (*pw) += val;
-// don't pollute my namespace!
-#include <windows.h>
-uint32_t atomic_conditional_increment(register uint32_t *pw) {
+ return *pw;
+}
+
+#elif defined(__GNUC__)
+
+/* Implementation for GCC & Clang */
+
+// GCC guarantees atomic intrinsics for sizes of 1, 2, 4 and 8 bytes.
+// Clang states it supports GCC atomic builtins.
- /* try to increment until it actually works */
- // taken from boost
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_conditional_increment_impl(register T *pw) {
while (true) {
- uint32_t tmp = static_cast<uint32_t const volatile &>(*pw);
+ T tmp = static_cast<T const volatile &>(*pw);
if (tmp == 0)
return 0; // if zero, can't add to it anymore
- if (InterlockedCompareExchange((LONG volatile *)pw, tmp + 1, tmp) == tmp)
+ if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp)
return tmp + 1;
}
}
-uint32_t atomic_decrement(register uint32_t *pw) {
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_decrement_impl(register T *pw) {
+
+ return __sync_sub_and_fetch(pw, 1);
+}
+
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_increment_impl(register T *pw) {
+
+ return __sync_add_and_fetch(pw, 1);
+}
+
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_sub_impl(register T *pw, register T val) {
+
+ return __sync_sub_and_fetch(pw, val);
+}
+
+template <class T>
+static _ALWAYS_INLINE_ T _atomic_add_impl(register T *pw, register T val) {
+
+ return __sync_add_and_fetch(pw, val);
+}
+
+#elif defined(_MSC_VER)
+
+/* Implementation for MSVC-Windows */
+
+// don't pollute my namespace!
+#include <windows.h>
+
+#define ATOMIC_CONDITIONAL_INCREMENT_BODY(m_pw, m_win_type, m_win_cmpxchg, m_cpp_type) \
+ /* try to increment until it actually works */ \
+ /* taken from boost */ \
+ while (true) { \
+ m_cpp_type tmp = static_cast<m_cpp_type const volatile &>(*(m_pw)); \
+ if (tmp == 0) \
+ return 0; /* if zero, can't add to it anymore */ \
+ if (m_win_cmpxchg((m_win_type volatile *)(m_pw), tmp + 1, tmp) == tmp) \
+ return tmp + 1; \
+ }
+
+static _ALWAYS_INLINE_ uint32_t _atomic_conditional_increment_impl(register uint32_t *pw) {
+
+ ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONG, InterlockedCompareExchange, uint32_t)
+}
+
+static _ALWAYS_INLINE_ uint32_t _atomic_decrement_impl(register uint32_t *pw) {
+
return InterlockedDecrement((LONG volatile *)pw);
}
-uint32_t atomic_increment(register uint32_t *pw) {
+static _ALWAYS_INLINE_ uint32_t _atomic_increment_impl(register uint32_t *pw) {
+
return InterlockedIncrement((LONG volatile *)pw);
}
-#elif defined(__GNUC__)
-uint32_t atomic_conditional_increment(register uint32_t *pw) {
+static _ALWAYS_INLINE_ uint32_t _atomic_sub_impl(register uint32_t *pw, register uint32_t val) {
- while (true) {
- uint32_t tmp = static_cast<uint32_t const volatile &>(*pw);
- if (tmp == 0)
- return 0; // if zero, can't add to it anymore
- if (__sync_val_compare_and_swap(pw, tmp, tmp + 1) == tmp)
- return tmp + 1;
- }
+#if _WIN32_WINNT >= 0x0601 // Windows 7+
+ return InterlockedExchangeSubtract(pw, val) - val;
+#else
+ return InterlockedExchangeAdd((LONG volatile *)pw, -(int32_t)val) - val;
+#endif
}
-uint32_t atomic_decrement(register uint32_t *pw) {
+static _ALWAYS_INLINE_ uint32_t _atomic_add_impl(register uint32_t *pw, register uint32_t val) {
- return __sync_sub_and_fetch(pw, 1);
+ return InterlockedAdd((LONG volatile *)pw, val);
}
-uint32_t atomic_increment(register uint32_t *pw) {
+static _ALWAYS_INLINE_ uint64_t _atomic_conditional_increment_impl(register uint64_t *pw) {
- return __sync_add_and_fetch(pw, 1);
+ ATOMIC_CONDITIONAL_INCREMENT_BODY(pw, LONGLONG, InterlockedCompareExchange64, uint64_t)
+}
+
+static _ALWAYS_INLINE_ uint64_t _atomic_decrement_impl(register uint64_t *pw) {
+
+ return InterlockedDecrement64((LONGLONG volatile *)pw);
+}
+
+static _ALWAYS_INLINE_ uint64_t _atomic_increment_impl(register uint64_t *pw) {
+
+ return InterlockedIncrement64((LONGLONG volatile *)pw);
+}
+
+static _ALWAYS_INLINE_ uint64_t _atomic_sub_impl(register uint64_t *pw, register uint64_t val) {
+
+#if _WIN32_WINNT >= 0x0601 // Windows 7+
+ return InterlockedExchangeSubtract64(pw, val) - val;
+#else
+ return InterlockedExchangeAdd64((LONGLONG volatile *)pw, -(int64_t)val) - val;
+#endif
+}
+
+static _ALWAYS_INLINE_ uint64_t _atomic_add_impl(register uint64_t *pw, register uint64_t val) {
+
+ return InterlockedAdd64((LONGLONG volatile *)pw, val);
}
#else
+
//no threads supported?
#error Must provide atomic functions for this platform or compiler!
#endif
-#endif
+// The actual advertised functions; they'll call the right implementation
+
+uint32_t atomic_conditional_increment(register uint32_t *counter) {
+ return _atomic_conditional_increment_impl(counter);
+}
+
+uint32_t atomic_decrement(register uint32_t *pw) {
+ return _atomic_decrement_impl(pw);
+}
+
+uint32_t atomic_increment(register uint32_t *pw) {
+ return _atomic_increment_impl(pw);
+}
+
+uint32_t atomic_sub(register uint32_t *pw, register uint32_t val) {
+ return _atomic_sub_impl(pw, val);
+}
+
+uint32_t atomic_add(register uint32_t *pw, register uint32_t val) {
+ return _atomic_add_impl(pw, val);
+}
+
+uint64_t atomic_conditional_increment(register uint64_t *counter) {
+ return _atomic_conditional_increment_impl(counter);
+}
+
+uint64_t atomic_decrement(register uint64_t *pw) {
+ return _atomic_decrement_impl(pw);
+}
+
+uint64_t atomic_increment(register uint64_t *pw) {
+ return _atomic_increment_impl(pw);
+}
+
+uint64_t atomic_sub(register uint64_t *pw, register uint64_t val) {
+ return _atomic_sub_impl(pw, val);
+}
+
+uint64_t atomic_add(register uint64_t *pw, register uint64_t val) {
+ return _atomic_add_impl(pw, val);
+}
diff --git a/core/safe_refcount.h b/core/safe_refcount.h
index d30f563b56..a2d2b5e127 100644
--- a/core/safe_refcount.h
+++ b/core/safe_refcount.h
@@ -39,6 +39,14 @@
uint32_t atomic_conditional_increment(register uint32_t *counter);
uint32_t atomic_decrement(register uint32_t *pw);
uint32_t atomic_increment(register uint32_t *pw);
+uint32_t atomic_sub(register uint32_t *pw, register uint32_t val);
+uint32_t atomic_add(register uint32_t *pw, register uint32_t val);
+
+uint64_t atomic_conditional_increment(register uint64_t *counter);
+uint64_t atomic_decrement(register uint64_t *pw);
+uint64_t atomic_increment(register uint64_t *pw);
+uint64_t atomic_sub(register uint64_t *pw, register uint64_t val);
+uint64_t atomic_add(register uint64_t *pw, register uint64_t val);
struct SafeRefCount {
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index f230a4bc95..7fc151d83f 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -957,7 +957,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
poll_every = 0;
request_scene_tree = NULL;
live_edit_funcs = NULL;
- max_cps = GLOBAL_DEF("network/debug/max_remote_stdout_chars_per_second", 2048);
+ max_cps = GLOBAL_GET("network/limits/debugger_stdout/max_chars_per_second");
char_count = 0;
msec_count = 0;
last_msec = 0;
@@ -967,7 +967,7 @@ ScriptDebuggerRemote::ScriptDebuggerRemote() {
eh.userdata = this;
add_error_handler(&eh);
- profile_info.resize(CLAMP(int(GlobalConfig::get_singleton()->get("debug/profiler/max_functions")), 128, 65535));
+ profile_info.resize(CLAMP(int(GlobalConfig::get_singleton()->get("debug/settings/profiler/max_functions")), 128, 65535));
profile_info_ptrs.resize(profile_info.size());
profiling = false;
max_frame_functions = 16;
diff --git a/core/script_language.cpp b/core/script_language.cpp
index 72f0acec3b..4a7fdc9d64 100644
--- a/core/script_language.cpp
+++ b/core/script_language.cpp
@@ -66,11 +66,6 @@ bool ScriptServer::is_scripting_enabled() {
return scripting_enabled;
}
-int ScriptServer::get_language_count() {
-
- return _language_count;
-}
-
ScriptLanguage *ScriptServer::get_language(int p_idx) {
ERR_FAIL_INDEX_V(p_idx, _language_count, NULL);
diff --git a/core/script_language.h b/core/script_language.h
index 6e39593a89..a81300233f 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -57,7 +57,7 @@ public:
static void set_scripting_enabled(bool p_enabled);
static bool is_scripting_enabled();
- static int get_language_count();
+ _FORCE_INLINE_ static int get_language_count() { return _language_count; }
static ScriptLanguage *get_language(int p_idx);
static void register_language(ScriptLanguage *p_language);
static void unregister_language(ScriptLanguage *p_language);
@@ -274,6 +274,9 @@ public:
virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) = 0;
+ virtual void *alloc_instance_binding_data(Object *p_object) { return NULL; } //optional, not used by all languages
+ virtual void free_instance_binding_data(void *p_data) {} //optional, not used by all languages
+
virtual void frame();
virtual ~ScriptLanguage(){};
diff --git a/core/self_list.h b/core/self_list.h
index 9edf735f7b..e229d5bf8e 100644
--- a/core/self_list.h
+++ b/core/self_list.h
@@ -51,6 +51,25 @@ public:
_first->_prev = p_elem;
_first = p_elem;
}
+ void add_last(SelfList<T> *p_elem) {
+
+ ERR_FAIL_COND(p_elem->_root);
+
+ if (!_first) {
+ add(p_elem);
+ return;
+ }
+
+ SelfList<T> *e = _first;
+
+ while (e->next()) {
+ e = e->next();
+ }
+
+ e->_next = p_elem;
+ p_elem->_prev = e->_next;
+ p_elem->_root = this;
+ }
void remove(SelfList<T> *p_elem) {
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 6936a362e1..4a806aec6c 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -516,7 +516,7 @@ struct _VariantCall {
PoolByteArray compressed;
Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]);
- compressed.resize(Compression::get_max_compressed_buffer_size(ba->size()));
+ compressed.resize(Compression::get_max_compressed_buffer_size(ba->size(), mode));
int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode);
result = result >= 0 ? result : 0;
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 7a81eddd92..a137f9be7d 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -2081,6 +2081,14 @@
<description>
</description>
</method>
+ <method name="has_point" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="remove_point">
<argument index="0" name="id" type="int">
</argument>
@@ -3754,6 +3762,12 @@
Return the angular damp rate.
</description>
</method>
+ <method name="get_audio_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_collision_layer" qualifiers="const">
<return type="int">
</return>
@@ -3835,6 +3849,24 @@
Return the processing order of this area.
</description>
</method>
+ <method name="get_reverb_amount" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_reverb_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_reverb_uniformity" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_space_override_mode" qualifiers="const">
<return type="int">
</return>
@@ -3863,6 +3895,18 @@
Return whether this area detects bodies/areas entering/exiting it.
</description>
</method>
+ <method name="is_overriding_audio_bus" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_using_reverb_bus" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="overlaps_area" qualifiers="const">
<return type="bool">
</return>
@@ -3889,6 +3933,18 @@
In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second.
</description>
</method>
+ <method name="set_audio_bus">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_audio_bus_override">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_collision_layer">
<argument index="0" name="collision_layer" type="int">
</argument>
@@ -3983,6 +4039,24 @@
Areas with the same priority value get evaluated in an unpredictable order, and should be differentiated if evaluation order is to be important.
</description>
</method>
+ <method name="set_reverb_amount">
+ <argument index="0" name="amount" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_reverb_bus">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_reverb_uniformity">
+ <argument index="0" name="amount" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_space_override_mode">
<argument index="0" name="enable" type="int">
</argument>
@@ -3995,10 +4069,20 @@
AREA_SPACE_OVERRIDE_REPLACE_COMBINE: This area replaces any gravity/damp calculated so far, but keeps calculating the rest of the areas, down to the default one.
</description>
</method>
+ <method name="set_use_reverb_bus">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief="">
</member>
+ <member name="audio_bus_name" type="String" setter="set_audio_bus" getter="get_audio_bus" brief="">
+ </member>
+ <member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus" brief="">
+ </member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="">
@@ -4019,6 +4103,14 @@
</member>
<member name="priority" type="int" setter="set_priority" getter="get_priority" brief="">
</member>
+ <member name="reverb_bus_amount" type="float" setter="set_reverb_amount" getter="get_reverb_amount" brief="">
+ </member>
+ <member name="reverb_bus_enable" type="bool" setter="set_use_reverb_bus" getter="is_using_reverb_bus" brief="">
+ </member>
+ <member name="reverb_bus_name" type="String" setter="set_reverb_bus" getter="get_reverb_bus" brief="">
+ </member>
+ <member name="reverb_bus_uniformity" type="float" setter="set_reverb_uniformity" getter="get_reverb_uniformity" brief="">
+ </member>
<member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" brief="">
</member>
</members>
@@ -4122,6 +4214,12 @@
Return the angular damp rate.
</description>
</method>
+ <method name="get_audio_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_collision_layer" qualifiers="const">
<return type="int">
</return>
@@ -4231,6 +4329,12 @@
Return whether this area detects bodies/areas entering/exiting it.
</description>
</method>
+ <method name="is_overriding_audio_bus" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="overlaps_area" qualifiers="const">
<return type="bool">
</return>
@@ -4257,6 +4361,18 @@
In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second.
</description>
</method>
+ <method name="set_audio_bus">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_audio_bus_override">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_collision_layer">
<argument index="0" name="collision_layer" type="int">
</argument>
@@ -4367,6 +4483,10 @@
<members>
<member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief="">
</member>
+ <member name="audio_bus_name" type="String" setter="set_audio_bus" getter="get_audio_bus" brief="">
+ </member>
+ <member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus" brief="">
+ </member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="">
@@ -4937,27 +5057,6 @@
<constant name="ARRAY_FORMAT_INDEX" value="256">
Index array will be used.
</constant>
- <constant name="PRIMITIVE_POINTS" value="0">
- Render array as points (one vertex equals one point).
- </constant>
- <constant name="PRIMITIVE_LINES" value="1">
- Render array as lines (every two vertices a line is created).
- </constant>
- <constant name="PRIMITIVE_LINE_STRIP" value="2">
- Render array as line strip.
- </constant>
- <constant name="PRIMITIVE_LINE_LOOP" value="3">
- Render array as line loop (like line strip, but closed).
- </constant>
- <constant name="PRIMITIVE_TRIANGLES" value="4">
- Render array as triangles (every three vertices a triangle is created).
- </constant>
- <constant name="PRIMITIVE_TRIANGLE_STRIP" value="5">
- Render array as triangle strips.
- </constant>
- <constant name="PRIMITIVE_TRIANGLE_FAN" value="6">
- Render array as triangle fans.
- </constant>
</constants>
</class>
<class name="AtlasTexture" inherits="Texture" category="Core">
@@ -5326,7 +5425,7 @@
<description>
</description>
</method>
- <method name="get_treshold" qualifiers="const">
+ <method name="get_threshold" qualifiers="const">
<return type="float">
</return>
<description>
@@ -5368,8 +5467,8 @@
<description>
</description>
</method>
- <method name="set_treshold">
- <argument index="0" name="treshold" type="float">
+ <method name="set_threshold">
+ <argument index="0" name="threshold" type="float">
</argument>
<description>
</description>
@@ -5388,7 +5487,7 @@
</member>
<member name="sidechain" type="float" setter="set_sidechain" getter="get_sidechain" brief="">
</member>
- <member name="treshold" type="float" setter="set_treshold" getter="get_treshold" brief="">
+ <member name="threshold" type="float" setter="set_threshold" getter="get_threshold" brief="">
</member>
</members>
<constants>
@@ -5844,7 +5943,7 @@
<description>
</description>
</method>
- <method name="get_treshold_db" qualifiers="const">
+ <method name="get_threshold_db" qualifiers="const">
<return type="float">
</return>
<description>
@@ -5868,8 +5967,8 @@
<description>
</description>
</method>
- <method name="set_treshold_db">
- <argument index="0" name="treshold" type="float">
+ <method name="set_threshold_db">
+ <argument index="0" name="threshold" type="float">
</argument>
<description>
</description>
@@ -5882,7 +5981,7 @@
</member>
<member name="soft_clip_ratio" type="float" setter="set_soft_clip_ratio" getter="get_soft_clip_ratio" brief="">
</member>
- <member name="treshold_db" type="float" setter="set_treshold_db" getter="get_treshold_db" brief="">
+ <member name="threshold_db" type="float" setter="set_threshold_db" getter="get_threshold_db" brief="">
</member>
</members>
<constants>
@@ -6230,118 +6329,6 @@
<constants>
</constants>
</class>
-<class name="AudioPlayer" inherits="Node" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_bus" qualifiers="const">
- <return type="String">
- </return>
- <description>
- </description>
- </method>
- <method name="get_mix_target" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_pos">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_stream" qualifiers="const">
- <return type="Object">
- </return>
- <description>
- </description>
- </method>
- <method name="get_volume_db" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="is_autoplay_enabled">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="is_playing" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="play">
- <argument index="0" name="from_pos" type="float" default="0">
- </argument>
- <description>
- </description>
- </method>
- <method name="seek">
- <argument index="0" name="to_pos" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_autoplay">
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_bus">
- <argument index="0" name="bus" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_mix_target">
- <argument index="0" name="mix_target" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_stream">
- <argument index="0" name="stream" type="AudioStream">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_volume_db">
- <argument index="0" name="volume_db" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="stop">
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled" brief="">
- </member>
- <member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
- </member>
- <member name="mix_target" type="int" setter="set_mix_target" getter="get_mix_target" brief="">
- </member>
- <member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
- </member>
- <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" brief="">
- </member>
- <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief="">
- </member>
- </members>
- <constants>
- </constants>
-</class>
<class name="AudioServer" inherits="Object" category="Core">
<brief_description>
Server interface for low level audio access.
@@ -6398,6 +6385,14 @@
<description>
</description>
</method>
+ <method name="get_bus_index" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="bus_name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_bus_name" qualifiers="const">
<return type="String">
</return>
@@ -6672,6 +6667,580 @@
<constants>
</constants>
</class>
+<class name="AudioStreamPlayer" inherits="Node" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_mix_target" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_pos">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_stream" qualifiers="const">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_volume_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_autoplay_enabled">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_playing" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="play">
+ <argument index="0" name="from_pos" type="float" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="seek">
+ <argument index="0" name="to_pos" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_autoplay">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_bus">
+ <argument index="0" name="bus" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_mix_target">
+ <argument index="0" name="mix_target" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stream">
+ <argument index="0" name="stream" type="AudioStream">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_volume_db">
+ <argument index="0" name="volume_db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="stop">
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled" brief="">
+ </member>
+ <member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
+ </member>
+ <member name="mix_target" type="int" setter="set_mix_target" getter="get_mix_target" brief="">
+ </member>
+ <member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
+ </member>
+ <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" brief="">
+ </member>
+ <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="AudioStreamPlayer2D" inherits="Node2D" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_area_mask" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_attenuation" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_max_distance" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_pos">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_stream" qualifiers="const">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_volume_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_autoplay_enabled">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_playing" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="play">
+ <argument index="0" name="from_pos" type="float" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="seek">
+ <argument index="0" name="to_pos" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_area_mask">
+ <argument index="0" name="mask" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_attenuation">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_autoplay">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_bus">
+ <argument index="0" name="bus" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_max_distance">
+ <argument index="0" name="pixels" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stream">
+ <argument index="0" name="stream" type="AudioStream">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_volume_db">
+ <argument index="0" name="volume_db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="stop">
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask" brief="">
+ </member>
+ <member name="attenuation" type="float" setter="set_attenuation" getter="get_attenuation" brief="">
+ </member>
+ <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled" brief="">
+ </member>
+ <member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
+ </member>
+ <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" brief="">
+ </member>
+ <member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
+ </member>
+ <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" brief="">
+ </member>
+ <member name="volume_db" type="float" setter="set_volume_db" getter="get_volume_db" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="AudioStreamPlayer3D" inherits="Spatial" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_area_mask" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_attenuation_filter_cutoff_hz" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_attenuation_filter_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_attenuation_model" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_bus" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_doppler_tracking" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_emission_angle" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_emission_angle_filter_attenuation_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_max_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_max_distance" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_out_of_range_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_pos">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_stream" qualifiers="const">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_unit_db" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_unit_size" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_autoplay_enabled">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_emission_angle_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_playing" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="play">
+ <argument index="0" name="from_pos" type="float" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="seek">
+ <argument index="0" name="to_pos" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_area_mask">
+ <argument index="0" name="mask" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_attenuation_filter_cutoff_hz">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_attenuation_filter_db">
+ <argument index="0" name="db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_attenuation_model">
+ <argument index="0" name="model" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_autoplay">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_bus">
+ <argument index="0" name="bus" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_doppler_tracking">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_emission_angle">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_emission_angle_enabled">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_emission_angle_filter_attenuation_db">
+ <argument index="0" name="db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_max_db">
+ <argument index="0" name="max_db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_max_distance">
+ <argument index="0" name="metres" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_out_of_range_mode">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_stream">
+ <argument index="0" name="stream" type="AudioStream">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_unit_db">
+ <argument index="0" name="unit_db" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_unit_size">
+ <argument index="0" name="unit_size" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="stop">
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="area_mask" type="int" setter="set_area_mask" getter="get_area_mask" brief="">
+ </member>
+ <member name="attenuation_filter_cutoff_hz" type="float" setter="set_attenuation_filter_cutoff_hz" getter="get_attenuation_filter_cutoff_hz" brief="">
+ </member>
+ <member name="attenuation_filter_db" type="float" setter="set_attenuation_filter_db" getter="get_attenuation_filter_db" brief="">
+ </member>
+ <member name="attenuation_model" type="int" setter="set_attenuation_model" getter="get_attenuation_model" brief="">
+ </member>
+ <member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled" brief="">
+ </member>
+ <member name="bus" type="String" setter="set_bus" getter="get_bus" brief="">
+ </member>
+ <member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" brief="">
+ </member>
+ <member name="emission_angle_degrees" type="float" setter="set_emission_angle" getter="get_emission_angle" brief="">
+ </member>
+ <member name="emission_angle_enabled" type="bool" setter="set_emission_angle_enabled" getter="is_emission_angle_enabled" brief="">
+ </member>
+ <member name="emission_angle_filter_attenuation_db" type="float" setter="set_emission_angle_filter_attenuation_db" getter="get_emission_angle_filter_attenuation_db" brief="">
+ </member>
+ <member name="max_db" type="float" setter="set_max_db" getter="get_max_db" brief="">
+ </member>
+ <member name="max_distance" type="float" setter="set_max_distance" getter="get_max_distance" brief="">
+ </member>
+ <member name="out_of_range_mode" type="int" setter="set_out_of_range_mode" getter="get_out_of_range_mode" brief="">
+ </member>
+ <member name="playing" type="bool" setter="_set_playing" getter="_is_active" brief="">
+ </member>
+ <member name="stream" type="AudioStream" setter="set_stream" getter="get_stream" brief="">
+ </member>
+ <member name="unit_db" type="float" setter="set_unit_db" getter="get_unit_db" brief="">
+ </member>
+ <member name="unit_size" type="float" setter="set_unit_size" getter="get_unit_size" brief="">
+ </member>
+ </members>
+ <constants>
+ <constant name="ATTENUATION_INVERSE_DISTANCE" value="0">
+ </constant>
+ <constant name="ATTENUATION_INVERSE_SQUARE_DISTANCE" value="1">
+ </constant>
+ <constant name="ATTENUATION_LOGARITHMIC" value="2">
+ </constant>
+ <constant name="OUT_OF_RANGE_MIX" value="0">
+ </constant>
+ <constant name="OUT_OF_RANGE_PAUSE" value="1">
+ </constant>
+ <constant name="DOPPLER_TRACKING_DISABLED" value="0">
+ </constant>
+ <constant name="DOPPLER_TRACKING_IDLE_STEP" value="1">
+ </constant>
+ <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2">
+ </constant>
+ </constants>
+</class>
+<class name="AudioStreamRandomPitch" inherits="AudioStream" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_audio_stream" qualifiers="const">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_random_pitch" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_audio_stream">
+ <argument index="0" name="stream" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_random_pitch">
+ <argument index="0" name="scale" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="audio_stream" type="AudioStream" setter="set_audio_stream" getter="get_audio_stream" brief="">
+ </member>
+ <member name="random_pitch" type="float" setter="set_random_pitch" getter="get_random_pitch" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="AudioStreamSample" inherits="AudioStream" category="Core">
<brief_description>
</brief_description>
@@ -7705,6 +8274,12 @@
<description>
</description>
</method>
+ <method name="get_doppler_tracking" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_environment" qualifiers="const">
<return type="Environment">
</return>
@@ -7819,6 +8394,12 @@
<description>
</description>
</method>
+ <method name="set_doppler_tracking">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_environment">
<argument index="0" name="env" type="Environment">
</argument>
@@ -7886,6 +8467,12 @@
</constant>
<constant name="KEEP_HEIGHT" value="1">
</constant>
+ <constant name="DOPPLER_TRACKING_DISABLED" value="0">
+ </constant>
+ <constant name="DOPPLER_TRACKING_IDLE_STEP" value="1">
+ </constant>
+ <constant name="DOPPLER_TRACKING_FIXED_STEP" value="2">
+ </constant>
</constants>
</class>
<class name="Camera2D" inherits="Node2D" category="Core">
@@ -8004,18 +8591,36 @@
<description>
</description>
</method>
+ <method name="is_limit_drawing_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_limit_smoothing_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
+ <method name="is_margin_drawing_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_rotating" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
+ <method name="is_screen_drawing_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_v_drag_enabled" qualifiers="const">
<return type="bool">
</return>
@@ -8087,6 +8692,12 @@
Set the scrolling limit in pixels.
</description>
</method>
+ <method name="set_limit_drawing_enabled">
+ <argument index="0" name="limit_drawing_enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_limit_smoothing_enabled">
<argument index="0" name="limit_smoothing_enabled" type="bool">
</argument>
@@ -8095,6 +8706,12 @@
This requires camera smoothing being enabled to have a noticeable effect.
</description>
</method>
+ <method name="set_margin_drawing_enabled">
+ <argument index="0" name="margin_drawing_enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_offset">
<argument index="0" name="offset" type="Vector2">
</argument>
@@ -8108,6 +8725,12 @@
<description>
</description>
</method>
+ <method name="set_screen_drawing_enabled">
+ <argument index="0" name="screen_drawing_enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_v_drag_enabled">
<argument index="0" name="enabled" type="bool">
</argument>
@@ -8144,6 +8767,12 @@
</member>
<member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled" brief="">
</member>
+ <member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled" brief="">
+ </member>
+ <member name="editor_draw_limits" type="bool" setter="set_limit_drawing_enabled" getter="is_limit_drawing_enabled" brief="">
+ </member>
+ <member name="editor_draw_screen" type="bool" setter="set_screen_drawing_enabled" getter="is_screen_drawing_enabled" brief="">
+ </member>
<member name="limit_bottom" type="int" setter="set_limit" getter="get_limit" brief="">
</member>
<member name="limit_left" type="int" setter="set_limit" getter="get_limit" brief="">
@@ -8226,6 +8855,8 @@
</argument>
<argument index="3" name="texture" type="Texture" default="NULL">
</argument>
+ <argument index="4" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
Draw a colored polygon of any amount of points, convex or concave.
</description>
@@ -8254,10 +8885,36 @@
</argument>
<argument index="3" name="texture" type="Texture" default="NULL">
</argument>
+ <argument index="4" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
Draw a polygon of any amount of points, convex or concave.
</description>
</method>
+ <method name="draw_polyline">
+ <argument index="0" name="points" type="PoolVector2Array">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <argument index="2" name="width" type="float" default="1">
+ </argument>
+ <argument index="3" name="antialiased" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="draw_polyline_colors">
+ <argument index="0" name="points" type="PoolVector2Array">
+ </argument>
+ <argument index="1" name="colors" type="PoolColorArray">
+ </argument>
+ <argument index="2" name="width" type="float" default="1">
+ </argument>
+ <argument index="3" name="antialiased" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="draw_primitive">
<argument index="0" name="points" type="PoolVector2Array">
</argument>
@@ -8269,6 +8926,8 @@
</argument>
<argument index="4" name="width" type="float" default="1">
</argument>
+ <argument index="5" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
Draw a custom primitive, 1 point for a point, 2 points for a line, 3 points for a triangle and 4 points for a quad.
</description>
@@ -8278,6 +8937,8 @@
</argument>
<argument index="1" name="color" type="Color">
</argument>
+ <argument index="2" name="filled" type="bool" default="true">
+ </argument>
<description>
Draw a colored rectangle.
</description>
@@ -8330,6 +8991,8 @@
</argument>
<argument index="2" name="modulate" type="Color" default="Color(1,1,1,1)">
</argument>
+ <argument index="3" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
Draw a texture at a given position.
</description>
@@ -8345,6 +9008,8 @@
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
+ <argument index="5" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
Draw a textured rectangle at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture.
</description>
@@ -8360,6 +9025,10 @@
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
+ <argument index="5" name="normal_map" type="Texture" default="NULL">
+ </argument>
+ <argument index="6" name="clip_uv" type="bool" default="true">
+ </argument>
<description>
Draw a textured rectangle region at a given position, optionally modulated by a color. Transpose swaps the x and y coordinates when reading the texture.
</description>
@@ -8462,7 +9131,7 @@
</description>
</method>
<method name="get_material" qualifiers="const">
- <return type="ShaderMaterial">
+ <return type="Material">
</return>
<description>
Get the material of this item.
@@ -8599,7 +9268,7 @@
</description>
</method>
<method name="set_material">
- <argument index="0" name="material" type="ShaderMaterial">
+ <argument index="0" name="material" type="Material">
</argument>
<description>
Set the material of this item.
@@ -8660,7 +9329,7 @@
<members>
<member name="light_mask" type="int" setter="set_light_mask" getter="get_light_mask" brief="">
</member>
- <member name="material" type="ShaderMaterial" setter="set_material" getter="get_material" brief="">
+ <member name="material" type="ShaderMaterial,CanvasItemMaterial" setter="set_material" getter="get_material" brief="">
</member>
<member name="modulate" type="Color" setter="set_modulate" getter="get_modulate" brief="">
</member>
@@ -8730,6 +9399,62 @@
</constant>
</constants>
</class>
+<class name="CanvasItemMaterial" inherits="Material" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_blend_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_light_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_blend_mode">
+ <argument index="0" name="blend_mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_light_mode">
+ <argument index="0" name="light_mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="blend_mode" type="int" setter="set_blend_mode" getter="get_blend_mode" brief="">
+ </member>
+ <member name="light_mode" type="int" setter="set_light_mode" getter="get_light_mode" brief="">
+ </member>
+ </members>
+ <constants>
+ <constant name="BLEND_MODE_MIX" value="0">
+ </constant>
+ <constant name="BLEND_MODE_ADD" value="1">
+ </constant>
+ <constant name="BLEND_MODE_SUB" value="2">
+ </constant>
+ <constant name="BLEND_MODE_MUL" value="3">
+ </constant>
+ <constant name="BLEND_MODE_PREMULT_ALPHA" value="4">
+ </constant>
+ <constant name="LIGHT_MODE_NORMAL" value="0">
+ </constant>
+ <constant name="LIGHT_MODE_UNSHADED" value="1">
+ </constant>
+ <constant name="LIGHT_MODE_LIGHT_ONLY" value="2">
+ </constant>
+ </constants>
+</class>
<class name="CanvasLayer" inherits="Node" category="Core">
<brief_description>
Canvas Item layer.
@@ -9409,18 +10134,6 @@
<description>
</description>
</method>
- <method name="add_shape">
- <argument index="0" name="shape" type="Shape">
- </argument>
- <argument index="1" name="transform" type="Transform" default="Transform()">
- </argument>
- <description>
- </description>
- </method>
- <method name="clear_shapes">
- <description>
- </description>
- </method>
<method name="get_capture_input_on_drag" qualifiers="const">
<return type="bool">
</return>
@@ -9433,48 +10146,12 @@
<description>
</description>
</method>
- <method name="get_shape" qualifiers="const">
- <return type="Shape">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="get_shape_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_shape_transform" qualifiers="const">
- <return type="Transform">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="is_ray_pickable" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="is_shape_set_as_trigger" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="remove_shape">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="set_capture_input_on_drag">
<argument index="0" name="enable" type="bool">
</argument>
@@ -9487,30 +10164,6 @@
<description>
</description>
</method>
- <method name="set_shape">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="shape" type="Shape">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_shape_as_trigger">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="enable" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_shape_transform">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="transform" type="Transform">
- </argument>
- <description>
- </description>
- </method>
</methods>
<members>
<member name="input_capture_on_drag" type="bool" setter="set_capture_input_on_drag" getter="get_capture_input_on_drag" brief="">
@@ -9563,20 +10216,6 @@
<description>
</description>
</method>
- <method name="add_shape">
- <argument index="0" name="shape" type="Shape2D">
- </argument>
- <argument index="1" name="transform" type="Transform2D" default="((1, 0), (0, 1), (0, 0))">
- </argument>
- <description>
- Add a [Shape2D] to the collision body, with a given custom transform.
- </description>
- </method>
- <method name="clear_shapes">
- <description>
- Remove all shapes.
- </description>
- </method>
<method name="get_rid" qualifiers="const">
<return type="RID">
</return>
@@ -9584,31 +10223,6 @@
Return the RID of this object.
</description>
</method>
- <method name="get_shape" qualifiers="const">
- <return type="Shape2D">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- Return the shape in the given index.
- </description>
- </method>
- <method name="get_shape_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the amount of shapes in the collision body. Because a [CollisionPolygon2D] can generate more than one [Shape2D], the amount returned does not have to match the sum of [CollisionShape2D] and [CollisionPolygon2D].
- </description>
- </method>
- <method name="get_shape_transform" qualifiers="const">
- <return type="Transform2D">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- Return the shape transform in the given index.
- </description>
- </method>
<method name="is_pickable" qualifiers="const">
<return type="bool">
</return>
@@ -9616,22 +10230,6 @@
Return whether this object is pickable.
</description>
</method>
- <method name="is_shape_set_as_trigger" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- Return whether a shape is a trigger. A trigger shape detects collisions, but is otherwise unaffected by physics (i.e. colliding objects will not get blocked).
- </description>
- </method>
- <method name="remove_shape">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <description>
- Remove the shape in the given index.
- </description>
- </method>
<method name="set_pickable">
<argument index="0" name="enabled" type="bool">
</argument>
@@ -9639,33 +10237,6 @@
Set whether this object is pickable. A pickable object can detect the mouse pointer enter/leave it and, if the mouse is inside it, report input events.
</description>
</method>
- <method name="set_shape">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="shape" type="Shape">
- </argument>
- <description>
- Change a shape in the collision body.
- </description>
- </method>
- <method name="set_shape_as_trigger">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="enable" type="bool">
- </argument>
- <description>
- Set whether a shape is a trigger. A trigger shape detects collisions, but is otherwise unaffected by physics (i.e. colliding objects will not get blocked).
- </description>
- </method>
- <method name="set_shape_transform">
- <argument index="0" name="shape_idx" type="int">
- </argument>
- <argument index="1" name="transform" type="Transform2D">
- </argument>
- <description>
- Change the shape transform in the collision body.
- </description>
- </method>
</methods>
<members>
<member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable" brief="">
@@ -9702,24 +10273,6 @@
<description>
</description>
<methods>
- <method name="get_build_mode" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_collision_object_first_shape" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_collision_object_last_shape" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="get_depth" qualifiers="const">
<return type="float">
</return>
@@ -9732,9 +10285,9 @@
<description>
</description>
</method>
- <method name="set_build_mode">
- <argument index="0" name="build_mode" type="int">
- </argument>
+ <method name="is_disabled" qualifiers="const">
+ <return type="bool">
+ </return>
<description>
</description>
</method>
@@ -9744,6 +10297,12 @@
<description>
</description>
</method>
+ <method name="set_disabled">
+ <argument index="0" name="disabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_polygon">
<argument index="0" name="polygon" type="PoolVector2Array">
</argument>
@@ -9752,13 +10311,11 @@
</method>
</methods>
<members>
- <member name="build_mode" type="int" setter="set_build_mode" getter="get_build_mode" brief="">
- </member>
<member name="depth" type="float" setter="set_depth" getter="get_depth" brief="">
</member>
- <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" brief="">
+ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
- <member name="shape_range" type="Vector2" setter="_set_shape_range" getter="_get_shape_range" brief="">
+ <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" brief="">
</member>
</members>
<constants>
@@ -9779,34 +10336,23 @@
Return whether the polygon is a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
- <method name="get_collision_object_first_shape" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the index of the first shape generated by the editor.
- When [code]build_mode[/code] is set to generate convex polygons, the shape shown in the editor may be decomposed into many convex polygons. In that case, a range of indexes is needed to directly access the [Shape2D].
- When [code]build_mode[/code] is set to generate concave polygons, there is only one [Shape2D] generated, so the start index and the end index are the same.
- </description>
- </method>
- <method name="get_collision_object_last_shape" qualifiers="const">
- <return type="int">
+ <method name="get_polygon" qualifiers="const">
+ <return type="PoolVector2Array">
</return>
<description>
- Return the index of the last shape generated by the editor.
+ Return the list of points that define the polygon.
</description>
</method>
- <method name="get_polygon" qualifiers="const">
- <return type="PoolVector2Array">
+ <method name="is_disabled" qualifiers="const">
+ <return type="bool">
</return>
<description>
- Return the list of points that define the polygon.
</description>
</method>
- <method name="is_trigger" qualifiers="const">
+ <method name="is_one_way_collision_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether this polygon is a trigger.
</description>
</method>
<method name="set_build_mode">
@@ -9816,30 +10362,35 @@
Set whether the polygon is to be a [ConvexPolygonShape2D] ([code]build_mode==0[/code]), or a [ConcavePolygonShape2D] ([code]build_mode==1[/code]).
</description>
</method>
- <method name="set_polygon">
- <argument index="0" name="polygon" type="PoolVector2Array">
+ <method name="set_disabled">
+ <argument index="0" name="disabled" type="bool">
</argument>
<description>
- Set the array of points forming the polygon.
- When editing the point list via the editor, depending on [method get_build_mode], it has to be a list of points (for [code]build_mode==0[/code]), or a list of lines (for [code]build_mode==1[/code]). In the second case, the even elements of the array define the start point of the line, and the odd elements the end point.
</description>
</method>
- <method name="set_trigger">
- <argument index="0" name="trigger" type="bool">
+ <method name="set_one_way_collision">
+ <argument index="0" name="enabled" type="bool">
</argument>
<description>
- Set whether this polygon is a trigger. A trigger polygon detects collisions, but is otherwise unaffected by physics (i.e. colliding objects will not get blocked).
+ </description>
+ </method>
+ <method name="set_polygon">
+ <argument index="0" name="polygon" type="PoolVector2Array">
+ </argument>
+ <description>
+ Set the array of points forming the polygon.
+ When editing the point list via the editor, depending on [method get_build_mode], it has to be a list of points (for [code]build_mode==0[/code]), or a list of lines (for [code]build_mode==1[/code]). In the second case, the even elements of the array define the start point of the line, and the odd elements the end point.
</description>
</method>
</methods>
<members>
<member name="build_mode" type="int" setter="set_build_mode" getter="get_build_mode" brief="">
</member>
- <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" brief="">
+ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
- <member name="shape_range" type="Vector2" setter="_set_shape_range" getter="_get_shape_range" brief="">
+ <member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled" brief="">
</member>
- <member name="trigger" type="bool" setter="set_trigger" getter="is_trigger" brief="">
+ <member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon" brief="">
</member>
</members>
<constants>
@@ -9851,19 +10402,13 @@
<description>
</description>
<methods>
- <method name="get_collision_object_shape_index" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="get_shape" qualifiers="const">
<return type="Object">
</return>
<description>
</description>
</method>
- <method name="is_trigger" qualifiers="const">
+ <method name="is_disabled" qualifiers="const">
<return type="bool">
</return>
<description>
@@ -9879,26 +10424,24 @@
<description>
</description>
</method>
- <method name="set_shape">
- <argument index="0" name="shape" type="Object">
+ <method name="set_disabled">
+ <argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
- <method name="set_trigger">
- <argument index="0" name="enable" type="bool">
+ <method name="set_shape">
+ <argument index="0" name="shape" type="Object">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="_update_shape_index" type="int" setter="_set_update_shape_index" getter="_get_update_shape_index" brief="">
+ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
<member name="shape" type="Shape" setter="set_shape" getter="get_shape" brief="">
</member>
- <member name="trigger" type="bool" setter="set_trigger" getter="is_trigger" brief="">
- </member>
</members>
<constants>
</constants>
@@ -9911,48 +10454,51 @@
Editor-only class. This is not present when running the game. It's used in the editor to properly edit and position collision shapes in [CollisionObject2D]. This is not accessible from regular code.
</description>
<methods>
- <method name="get_collision_object_shape_index" qualifiers="const">
- <return type="int">
+ <method name="get_shape" qualifiers="const">
+ <return type="Object">
</return>
<description>
- Return the index of this shape inside its container [CollisionObject2D]. This can be used to directly access the underlying [Shape2D].
+ Return this shape's [Shape2D].
</description>
</method>
- <method name="get_shape" qualifiers="const">
- <return type="Object">
+ <method name="is_disabled" qualifiers="const">
+ <return type="bool">
</return>
<description>
- Return this shape's [Shape2D].
</description>
</method>
- <method name="is_trigger" qualifiers="const">
+ <method name="is_one_way_collision_enabled" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether this shape is a trigger.
</description>
</method>
- <method name="set_shape">
- <argument index="0" name="shape" type="Object">
+ <method name="set_disabled">
+ <argument index="0" name="disabled" type="bool">
</argument>
<description>
- Set this shape's [Shape2D]. This will not appear as a node, but can be directly edited as a property.
</description>
</method>
- <method name="set_trigger">
- <argument index="0" name="enable" type="bool">
+ <method name="set_one_way_collision">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_shape">
+ <argument index="0" name="shape" type="Object">
</argument>
<description>
- Set whether this shape is a trigger. A trigger shape detects collisions, but is otherwise unaffected by physics (i.e. will not block movement of colliding objects).
+ Set this shape's [Shape2D]. This will not appear as a node, but can be directly edited as a property.
</description>
</method>
</methods>
<members>
- <member name="_update_shape_index" type="int" setter="_set_update_shape_index" getter="_get_update_shape_index" brief="">
+ <member name="disabled" type="bool" setter="set_disabled" getter="is_disabled" brief="">
</member>
- <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape" brief="">
+ <member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled" brief="">
</member>
- <member name="trigger" type="bool" setter="set_trigger" getter="is_trigger" brief="">
+ <member name="shape" type="Shape2D" setter="set_shape" getter="get_shape" brief="">
</member>
</members>
<constants>
@@ -10822,6 +11368,12 @@
Return position and size of the Control, relative to the top-left corner of the [i]window[/i] Control. This is a helper (see [method get_global_pos], [method get_size]).
</description>
</method>
+ <method name="get_h_grow_direction" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_h_size_flags" qualifiers="const">
<return type="int">
</return>
@@ -10874,6 +11426,12 @@
<description>
</description>
</method>
+ <method name="get_pivot_offset" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_position" qualifiers="const">
<return type="Vector2">
</return>
@@ -10948,6 +11506,12 @@
Return the tooltip, which will appear when the cursor is resting over this control.
</description>
</method>
+ <method name="get_v_grow_direction" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_v_size_flags" qualifiers="const">
<return type="int">
</return>
@@ -11180,6 +11744,12 @@
Move the Control to a new position, relative to the top-left corner of the [i]window[/i] Control, and without changing current anchor mode. (see [method set_margin]).
</description>
</method>
+ <method name="set_h_grow_direction">
+ <argument index="0" name="direction" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_h_size_flags">
<argument index="0" name="flags" type="int">
</argument>
@@ -11203,6 +11773,12 @@
Set when the control is ignoring mouse events (even touchpad events send mouse events). (see the MOUSE_FILTER_* constants)
</description>
</method>
+ <method name="set_pivot_offset">
+ <argument index="0" name="pivot_offset" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_position">
<argument index="0" name="pos" type="Vector2">
</argument>
@@ -11258,6 +11834,12 @@
Set a tooltip, which will appear when the cursor is resting over this control.
</description>
</method>
+ <method name="set_v_grow_direction">
+ <argument index="0" name="direction" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_v_size_flags">
<argument index="0" name="flags" type="int">
</argument>
@@ -11296,6 +11878,10 @@
</member>
<member name="focus_neighbour_top" type="NodePath" setter="set_focus_neighbour" getter="get_focus_neighbour" brief="">
</member>
+ <member name="grow_horizontal" type="int" setter="set_h_grow_direction" getter="get_h_grow_direction" brief="">
+ </member>
+ <member name="grow_vertical" type="int" setter="set_v_grow_direction" getter="get_v_grow_direction" brief="">
+ </member>
<member name="hint_tooltip" type="String" setter="set_tooltip" getter="_get_tooltip" brief="">
</member>
<member name="margin_bottom" type="int" setter="set_margin" getter="get_margin" brief="">
@@ -11312,6 +11898,8 @@
</member>
<member name="rect_min_size" type="Vector2" setter="set_custom_minimum_size" getter="get_custom_minimum_size" brief="">
</member>
+ <member name="rect_pivot_offset" type="Vector2" setter="set_pivot_offset" getter="get_pivot_offset" brief="">
+ </member>
<member name="rect_position" type="Vector2" setter="set_position" getter="get_position" brief="">
</member>
<member name="rect_rotation" type="float" setter="set_rotation_deg" getter="get_rotation_deg" brief="">
@@ -11455,12 +12043,20 @@
</constant>
<constant name="SIZE_EXPAND_FILL" value="3">
</constant>
+ <constant name="SIZE_SHRINK_CENTER" value="4">
+ </constant>
+ <constant name="SIZE_SHRINK_END" value="8">
+ </constant>
<constant name="MOUSE_FILTER_STOP" value="0">
</constant>
<constant name="MOUSE_FILTER_PASS" value="1">
</constant>
<constant name="MOUSE_FILTER_IGNORE" value="2">
</constant>
+ <constant name="GROW_DIRECTION_BEGIN" value="0">
+ </constant>
+ <constant name="GROW_DIRECTION_END" value="1">
+ </constant>
</constants>
</class>
<class name="ConvexPolygonShape" inherits="Shape" category="Core">
@@ -11697,6 +12293,206 @@
<constants>
</constants>
</class>
+<class name="Curve" inherits="Resource" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="add_point">
+ <return type="int">
+ </return>
+ <argument index="0" name="pos" type="Vector2">
+ </argument>
+ <argument index="1" name="left_tangent" type="float" default="0">
+ </argument>
+ <argument index="2" name="right_tangent" type="float" default="0">
+ </argument>
+ <argument index="3" name="left_mode" type="int" default="0">
+ </argument>
+ <argument index="4" name="right_mode" type="int" default="0">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="bake">
+ <description>
+ </description>
+ </method>
+ <method name="clean_dupes">
+ <description>
+ </description>
+ </method>
+ <method name="clear_points">
+ <description>
+ </description>
+ </method>
+ <method name="get_bake_resolution" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_max_value" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_min_value" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_point_left_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_point_left_tangent" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_point_pos" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_point_right_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_point_right_tangent" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="interpolate" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="offset" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="interpolate_baked">
+ <return type="float">
+ </return>
+ <argument index="0" name="offset" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="remove_point">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_bake_resolution">
+ <argument index="0" name="resolution" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_max_value">
+ <argument index="0" name="max" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_min_value">
+ <argument index="0" name="min" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_left_mode">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_left_tangent">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="tangent" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_offset">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="offset" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_right_mode">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_right_tangent">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="tangent" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_point_value">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <argument index="1" name="y" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="_data" type="int" setter="_set_data" getter="_get_data" brief="">
+ </member>
+ <member name="bake_resolution" type="int" setter="set_bake_resolution" getter="get_bake_resolution" brief="">
+ </member>
+ <member name="max_value" type="float" setter="set_max_value" getter="get_max_value" brief="">
+ </member>
+ <member name="min_value" type="float" setter="set_min_value" getter="get_min_value" brief="">
+ </member>
+ </members>
+ <signals>
+ <signal name="range_changed">
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
<class name="Curve2D" inherits="Resource" category="Core">
<brief_description>
Describes a Bezier curve in 2D space.
@@ -12091,38 +12887,14 @@
<description>
</description>
<methods>
- <method name="get_max" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_min" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_points" qualifiers="const">
- <return type="PoolVector2Array">
+ <method name="get_curve" qualifiers="const">
+ <return type="Curve">
</return>
<description>
</description>
</method>
- <method name="set_max">
- <argument index="0" name="max" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_min">
- <argument index="0" name="min" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_points">
- <argument index="0" name="points" type="PoolVector2Array">
+ <method name="set_curve">
+ <argument index="0" name="curve" type="Curve">
</argument>
<description>
</description>
@@ -12135,11 +12907,7 @@
</method>
</methods>
<members>
- <member name="max" type="float" setter="set_max" getter="get_max" brief="">
- </member>
- <member name="min" type="float" setter="set_min" getter="get_min" brief="">
- </member>
- <member name="points" type="PoolVector2Array" setter="set_points" getter="get_points" brief="">
+ <member name="curve" type="Curve" setter="set_curve" getter="get_curve" brief="">
</member>
<member name="width" type="int" setter="set_width" getter="get_width" brief="">
</member>
@@ -13313,22 +14081,6 @@
<description>
</description>
</method>
- <method name="open_scene_from_path">
- <argument index="0" name="scene_filepath" type="String">
- </argument>
- </return>
- <description>
- Opens scene in editor. Do not use during plugin initialization. If you need, then use it together with [method Object.call_deferred].
- </description>
- </method>
- <method name="reload_scene_from_path">
- <argument index="0" name="scene_filepath" type="String">
- </argument>
- </return>
- <description>
- Reloads already loaded editor scene.
- </description>
- </method>
<method name="forward_canvas_gui_input" qualifiers="virtual">
<return type="bool">
</return>
@@ -13478,11 +14230,25 @@
Remember that you have to manage the visibility of all your editor controls manually.
</description>
</method>
+ <method name="open_scene_from_path">
+ <argument index="0" name="scene_filepath" type="String">
+ </argument>
+ <description>
+ Opens scene in editor. Do not use during plugin initialization. If you need, then use it together with [method Object.call_deferred].
+ </description>
+ </method>
<method name="queue_save_layout" qualifiers="const">
<description>
Queue save the project's editor layout.
</description>
</method>
+ <method name="reload_scene_from_path">
+ <argument index="0" name="scene_filepath" type="String">
+ </argument>
+ <description>
+ Reloads already loaded editor scene.
+ </description>
+ </method>
<method name="remove_control_from_bottom_panel">
<argument index="0" name="control" type="Control">
</argument>
@@ -13515,6 +14281,10 @@
This method is called after the editor saves the project or when it's closed. It asks the plugin to save edited external scenes/resources.
</description>
</method>
+ <method name="set_input_event_forwarding_always_enabled">
+ <description>
+ </description>
+ </method>
<method name="set_state" qualifiers="virtual">
<argument index="0" name="state" type="Dictionary">
</argument>
@@ -14271,7 +15041,7 @@
<description>
</description>
</method>
- <method name="get_glow_hdr_bleed_treshold" qualifiers="const">
+ <method name="get_glow_hdr_bleed_threshold" qualifiers="const">
<return type="float">
</return>
<description>
@@ -14741,8 +15511,8 @@
<description>
</description>
</method>
- <method name="set_glow_hdr_bleed_treshold">
- <argument index="0" name="treshold" type="float">
+ <method name="set_glow_hdr_bleed_threshold">
+ <argument index="0" name="threshold" type="float">
</argument>
<description>
</description>
@@ -14768,7 +15538,7 @@
</description>
</method>
<method name="set_sky">
- <argument index="0" name="sky" type="CubeMap">
+ <argument index="0" name="sky" type="Sky">
</argument>
<description>
</description>
@@ -15013,7 +15783,7 @@
</member>
<member name="glow_hdr_scale" type="float" setter="set_glow_hdr_bleed_scale" getter="get_glow_hdr_bleed_scale" brief="">
</member>
- <member name="glow_hdr_treshold" type="float" setter="set_glow_hdr_bleed_treshold" getter="get_glow_hdr_bleed_treshold" brief="">
+ <member name="glow_hdr_threshold" type="float" setter="set_glow_hdr_bleed_threshold" getter="get_glow_hdr_bleed_threshold" brief="">
</member>
<member name="glow_intensity" type="float" setter="set_glow_intensity" getter="get_glow_intensity" brief="">
</member>
@@ -15831,6 +16601,14 @@
</description>
</method>
</methods>
+ <signals>
+ <signal name="completed">
+ <argument index="0" name="result" type="Nil">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ </signals>
<constants>
</constants>
</class>
@@ -16880,7 +17658,7 @@
</member>
<member name="lod_min_hysteresis" type="int" setter="set_lod_min_hysteresis" getter="get_lod_min_hysteresis" brief="">
</member>
- <member name="material_override" type="Material" setter="set_material_override" getter="get_material_override" brief="">
+ <member name="material_override" type="ShaderMaterial,SpatialMaterial" setter="set_material_override" getter="get_material_override" brief="">
</member>
<member name="use_in_baked_light" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
@@ -17008,6 +17786,8 @@
</description>
</method>
<method name="property_get_revert">
+ <return type="Variant">
+ </return>
<argument index="0" name="name" type="String">
</argument>
<description>
@@ -17168,86 +17948,14 @@
<description>
</description>
<methods>
- <method name="add_point">
- <argument index="0" name="offset" type="float">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- </description>
- </method>
- <method name="get_color" qualifiers="const">
- <return type="Color">
- </return>
- <argument index="0" name="point" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="get_colors" qualifiers="const">
- <return type="PoolColorArray">
- </return>
- <description>
- </description>
- </method>
- <method name="get_offset" qualifiers="const">
- <return type="float">
- </return>
- <argument index="0" name="point" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="get_offsets" qualifiers="const">
- <return type="PoolRealArray">
- </return>
- <description>
- </description>
- </method>
- <method name="get_point_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="interpolate">
- <return type="Color">
+ <method name="get_gradient" qualifiers="const">
+ <return type="Gradient">
</return>
- <argument index="0" name="offset" type="float">
- </argument>
<description>
</description>
</method>
- <method name="remove_point">
- <argument index="0" name="offset" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_color">
- <argument index="0" name="point" type="int">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_colors">
- <argument index="0" name="colors" type="PoolColorArray">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_offset">
- <argument index="0" name="point" type="int">
- </argument>
- <argument index="1" name="offset" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_offsets">
- <argument index="0" name="offsets" type="PoolRealArray">
+ <method name="set_gradient">
+ <argument index="0" name="gradient" type="Gradient">
</argument>
<description>
</description>
@@ -17260,9 +17968,7 @@
</method>
</methods>
<members>
- <member name="colors" type="float" setter="set_colors" getter="get_colors" brief="">
- </member>
- <member name="offsets" type="float" setter="set_offsets" getter="get_offsets" brief="">
+ <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" brief="">
</member>
<member name="width" type="int" setter="set_width" getter="get_width" brief="">
</member>
@@ -18247,6 +18953,10 @@
</theme_item>
<theme_item name="grabber" type="Texture">
</theme_item>
+ <theme_item name="grabber_disabled" type="Texture">
+ </theme_item>
+ <theme_item name="grabber_disabled" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_highlight" type="Texture">
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
@@ -19023,6 +19733,19 @@
Copy a "src_rect" [Rect2] from "src" [Image] to this [Image] on coordinates "dest".
</description>
</method>
+ <method name="blit_rect_mask">
+ <argument index="0" name="src" type="Image">
+ </argument>
+ <argument index="1" name="mask" type="Image">
+ </argument>
+ <argument index="2" name="src_rect" type="Rect2">
+ </argument>
+ <argument index="3" name="dst" type="Vector2">
+ </argument>
+ <description>
+ Blits a "src_rect" [Rect2] from "src" [Image] to this [Image] using a "mask" [Image] on coordinates "dest". Alpha channel is required for "mask", will copy src pixel onto dest if the corresponding mask pixel's alpha value is not 0. "src" [Image] and "mask" [Image] *must* have the same size (width and height) but they can have different formats
+ </description>
+ </method>
<method name="clear_mipmaps">
<description>
</description>
@@ -19234,16 +19957,6 @@
<description>
</description>
</method>
- <method name="set_pixel">
- <argument index="0" name="x" type="int">
- </argument>
- <argument index="1" name="y" type="int">
- </argument>
- <argument index="2" name="color" type="Color">
- </argument>
- <description>
- </description>
- </method>
<method name="resize">
<argument index="0" name="width" type="int">
</argument>
@@ -19255,7 +19968,7 @@
</description>
</method>
<method name="resize_to_po2">
- <argument index="0" name="square" type="bool" default="&quot;false&quot;">
+ <argument index="0" name="square" type="bool" default="false">
</argument>
<description>
</description>
@@ -19269,6 +19982,16 @@
Save this [Image] as a png.
</description>
</method>
+ <method name="set_pixel">
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <argument index="2" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="shrink_x2">
<description>
</description>
@@ -20000,6 +20723,14 @@
<description>
</description>
</method>
+ <method name="shortcut_match" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="event" type="InputEvent">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="xformed_by" qualifiers="const">
<return type="InputEvent">
</return>
@@ -20011,6 +20742,10 @@
</description>
</method>
</methods>
+ <members>
+ <member name="device" type="int" setter="set_device" getter="get_device" brief="">
+ </member>
+ </members>
<constants>
</constants>
</class>
@@ -20898,6 +21633,8 @@
</description>
</method>
<method name="get_item_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -21167,6 +21904,26 @@
</description>
</method>
</methods>
+ <members>
+ <member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select" brief="">
+ </member>
+ <member name="fixed_column_width" type="int" setter="set_fixed_column_width" getter="get_fixed_column_width" brief="">
+ </member>
+ <member name="icon_mode" type="int" setter="set_icon_mode" getter="get_icon_mode" brief="">
+ </member>
+ <member name="icon_scale" type="float" setter="set_icon_scale" getter="get_icon_scale" brief="">
+ </member>
+ <member name="items" type="Array" setter="_set_items" getter="_get_items" brief="">
+ </member>
+ <member name="max_columns" type="int" setter="set_max_columns" getter="get_max_columns" brief="">
+ </member>
+ <member name="max_text_lines" type="int" setter="set_max_text_lines" getter="get_max_text_lines" brief="">
+ </member>
+ <member name="same_column_width" type="bool" setter="set_same_column_width" getter="is_same_column_width" brief="">
+ </member>
+ <member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" brief="">
+ </member>
+ </members>
<signals>
<signal name="item_activated">
<argument index="0" name="index" type="int">
@@ -21396,124 +22153,130 @@
Kinematic Characters: KinematicBody also has an api for moving objects (the [method move] method) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<methods>
- <method name="can_collide_with_character_bodies" qualifiers="const">
- <return type="bool">
+ <method name="get_collision_collider" qualifiers="const">
+ <return type="Object">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return if this body can collide with character bodies.
</description>
</method>
- <method name="can_collide_with_kinematic_bodies" qualifiers="const">
- <return type="bool">
+ <method name="get_collision_collider_id" qualifiers="const">
+ <return type="int">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return if this body can collide with kinematic bodies.
</description>
</method>
- <method name="can_collide_with_rigid_bodies" qualifiers="const">
- <return type="bool">
- </return>
+ <method name="get_collision_collider_metadata" qualifiers="const">
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return if this body can collide with rigid bodies.
</description>
</method>
- <method name="can_collide_with_static_bodies" qualifiers="const">
- <return type="bool">
+ <method name="get_collision_collider_shape" qualifiers="const">
+ <return type="Object">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return if this body can collide with static bodies.
</description>
</method>
- <method name="can_teleport_to">
- <return type="bool">
+ <method name="get_collision_collider_shape_index" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="position" type="Vector3">
+ <argument index="0" name="collision" type="int">
</argument>
<description>
- Returns whether the KinematicBody can be teleported to the destination given as an argument, checking all collision shapes of the body against potential colliders at the destination.
</description>
</method>
- <method name="get_collider" qualifiers="const">
- <return type="Variant">
+ <method name="get_collision_collider_velocity" qualifiers="const">
+ <return type="Vector3">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the body that collided with this one.
</description>
</method>
- <method name="get_collider_shape" qualifiers="const">
+ <method name="get_collision_count" qualifiers="const">
<return type="int">
</return>
<description>
- Return the shape index from the body that collided with this one. If there is no collision, this method will return 0, so collisions must be checked first with [method is_colliding].
</description>
</method>
- <method name="get_collider_velocity" qualifiers="const">
- <return type="Vector3">
+ <method name="get_collision_local_shape" qualifiers="const">
+ <return type="Object">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the velocity of the body that collided with this one.
</description>
</method>
- <method name="get_collision_margin" qualifiers="const">
- <return type="float">
+ <method name="get_collision_normal" qualifiers="const">
+ <return type="Vector3">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the collision margin for this object.
</description>
</method>
- <method name="get_collision_normal" qualifiers="const">
+ <method name="get_collision_position" qualifiers="const">
<return type="Vector3">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the normal of the surface the body collided with. This is useful to implement sliding along a surface.
</description>
</method>
- <method name="get_collision_pos" qualifiers="const">
+ <method name="get_collision_remainder" qualifiers="const">
<return type="Vector3">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the point in space where the body is touching another. If there is no collision, this method will return (0,0,0), so collisions must be checked first with [method is_colliding].
</description>
</method>
- <method name="get_move_and_slide_colliders" qualifiers="const">
- <return type="Array">
+ <method name="get_collision_travel" qualifiers="const">
+ <return type="Vector3">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
</description>
</method>
- <method name="get_travel" qualifiers="const">
+ <method name="get_floor_velocity" qualifiers="const">
<return type="Vector3">
</return>
<description>
</description>
</method>
- <method name="is_colliding" qualifiers="const">
- <return type="bool">
+ <method name="get_safe_margin" qualifiers="const">
+ <return type="float">
</return>
<description>
- Return whether the body is colliding with another.
</description>
</method>
- <method name="is_move_and_slide_on_ceiling" qualifiers="const">
+ <method name="is_on_ceiling" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="is_move_and_slide_on_floor" qualifiers="const">
+ <method name="is_on_floor" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="is_move_and_slide_on_wall" qualifiers="const">
+ <method name="is_on_wall" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
<method name="move">
- <return type="Vector3">
+ <return type="Dictionary">
</return>
<argument index="0" name="rel_vec" type="Vector3">
</argument>
@@ -21528,78 +22291,34 @@
</argument>
<argument index="1" name="floor_normal" type="Vector3" default="Vector3(0, 0, 0)">
</argument>
- <argument index="2" name="ceil_normal" type="Vector3" default="Vector3(0, 0, 0)">
- </argument>
- <argument index="3" name="slope_stop_min_velocity" type="float" default="5">
- </argument>
- <argument index="4" name="max_bounces" type="int" default="4">
- </argument>
- <argument index="5" name="floor_max_angle" type="float" default="0.785398">
+ <argument index="2" name="slope_stop_min_velocity" type="float" default="0.05">
</argument>
- <argument index="6" name="ceil_max_angle" type="float" default="0.785398">
- </argument>
- <description>
- </description>
- </method>
- <method name="move_to">
- <return type="Vector3">
- </return>
- <argument index="0" name="position" type="Vector3">
- </argument>
- <description>
- Move the body to the given position. This is not a teleport, and the body will stop if there is an obstacle. The returned vector is how much movement was remaining before being stopped.
- </description>
- </method>
- <method name="revert_motion">
- <description>
- </description>
- </method>
- <method name="set_collide_with_character_bodies">
- <argument index="0" name="enable" type="bool">
+ <argument index="3" name="max_bounces" type="int" default="4">
</argument>
- <description>
- Set if this body should collide with character bodies.
- </description>
- </method>
- <method name="set_collide_with_kinematic_bodies">
- <argument index="0" name="enable" type="bool">
+ <argument index="4" name="floor_max_angle" type="float" default="0.785398">
</argument>
<description>
- Set if this body should collide with kinematic bodies.
</description>
</method>
- <method name="set_collide_with_rigid_bodies">
- <argument index="0" name="enable" type="bool">
+ <method name="set_safe_margin">
+ <argument index="0" name="pixels" type="float">
</argument>
<description>
- Set if this body should collide with rigid bodies.
</description>
</method>
- <method name="set_collide_with_static_bodies">
- <argument index="0" name="enable" type="bool">
+ <method name="test_move">
+ <return type="bool">
+ </return>
+ <argument index="0" name="from" type="Transform">
</argument>
- <description>
- Set if this body should collide with static bodies.
- </description>
- </method>
- <method name="set_collision_margin">
- <argument index="0" name="pixels" type="float">
+ <argument index="1" name="rel_vec" type="Vector3">
</argument>
<description>
- Set the collision margin for this object. A collision margin is an amount that all shapes will grow when computing collisions, to account for numerical imprecision.
</description>
</method>
</methods>
<members>
- <member name="collide_with/character" type="bool" setter="set_collide_with_character_bodies" getter="can_collide_with_character_bodies" brief="">
- </member>
- <member name="collide_with/kinematic" type="bool" setter="set_collide_with_kinematic_bodies" getter="can_collide_with_kinematic_bodies" brief="">
- </member>
- <member name="collide_with/rigid" type="bool" setter="set_collide_with_rigid_bodies" getter="can_collide_with_rigid_bodies" brief="">
- </member>
- <member name="collide_with/static" type="bool" setter="set_collide_with_static_bodies" getter="can_collide_with_static_bodies" brief="">
- </member>
- <member name="collision/margin" type="float" setter="set_collision_margin" getter="get_collision_margin" brief="">
+ <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" brief="">
</member>
</members>
<constants>
@@ -21615,95 +22334,131 @@
Kinematic Characters: KinematicBody2D also has an api for moving objects (the [method move] method) while performing collision tests. This makes them really useful to implement characters that collide against a world, but that don't require advanced physics.
</description>
<methods>
- <method name="get_collider" qualifiers="const">
- <return type="Variant">
+ <method name="get_collision_collider" qualifiers="const">
+ <return type="Object">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the body that collided with this one.
</description>
</method>
- <method name="get_collider_metadata" qualifiers="const">
- <return type="Variant">
+ <method name="get_collision_collider_id" qualifiers="const">
+ <return type="int">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the metadata of the shape that collided with this body. If there is no collision, it will return 0, so collisions must be checked first with [method is_colliding]. Additionally, this metadata can not be set with [method Object.set_meta], it must be set with [method Physics2DServer.body_set_shape_metadata].
</description>
</method>
- <method name="get_collider_shape" qualifiers="const">
+ <method name="get_collision_collider_metadata" qualifiers="const">
+ <argument index="0" name="collision" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_collision_collider_shape" qualifiers="const">
+ <return type="Object">
+ </return>
+ <argument index="0" name="collision" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_collision_collider_shape_index" qualifiers="const">
<return type="int">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the shape index from the body that collided with this one. If there is no collision, this method will return 0, so collisions must be checked first with [method is_colliding].
</description>
</method>
- <method name="get_collider_velocity" qualifiers="const">
+ <method name="get_collision_collider_velocity" qualifiers="const">
<return type="Vector2">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
Return the velocity of the body that collided with this one.
</description>
</method>
- <method name="get_collision_margin" qualifiers="const">
- <return type="float">
+ <method name="get_collision_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_collision_local_shape" qualifiers="const">
+ <return type="Object">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the collision margin for this object.
</description>
</method>
<method name="get_collision_normal" qualifiers="const">
<return type="Vector2">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the normal of the surface the body collided with. This is useful to implement sliding along a surface.
</description>
</method>
- <method name="get_collision_pos" qualifiers="const">
+ <method name="get_collision_position" qualifiers="const">
<return type="Vector2">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the point in space where the body is touching another. If there is no collision, this method will return (0,0), so collisions must be checked first with [method is_colliding].
</description>
</method>
- <method name="get_move_and_slide_colliders" qualifiers="const">
- <return type="Array">
+ <method name="get_collision_remainder" qualifiers="const">
+ <return type="Vector2">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
</description>
</method>
- <method name="get_travel" qualifiers="const">
+ <method name="get_collision_travel" qualifiers="const">
<return type="Vector2">
</return>
+ <argument index="0" name="collision" type="int">
+ </argument>
<description>
- Return the last movement done by the body.
</description>
</method>
- <method name="is_colliding" qualifiers="const">
- <return type="bool">
+ <method name="get_floor_velocity" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_safe_margin" qualifiers="const">
+ <return type="float">
</return>
<description>
- Return whether the body is colliding with another.
</description>
</method>
- <method name="is_move_and_slide_on_ceiling" qualifiers="const">
+ <method name="is_on_ceiling" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="is_move_and_slide_on_floor" qualifiers="const">
+ <method name="is_on_floor" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
- <method name="is_move_and_slide_on_wall" qualifiers="const">
+ <method name="is_on_wall" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
<method name="move">
- <return type="Vector2">
+ <return type="Dictionary">
</return>
<argument index="0" name="rel_vec" type="Vector2">
</argument>
@@ -21727,26 +22482,10 @@
<description>
</description>
</method>
- <method name="move_to">
- <return type="Vector2">
- </return>
- <argument index="0" name="position" type="Vector2">
- </argument>
- <description>
- Move the body to the given position. This is not a teleport, and the body will stop if there is an obstacle. The returned vector is how much movement was remaining before being stopped.
- [code]floor_max_angle[/code] is in radians (default is pi/4), and filters which obstacles should be considered as floors/cellings instead of walls.
- </description>
- </method>
- <method name="revert_motion">
- <description>
- Undo the last movement done by the body.
- </description>
- </method>
- <method name="set_collision_margin">
+ <method name="set_safe_margin">
<argument index="0" name="pixels" type="float">
</argument>
<description>
- Set the collision margin for this object. A collision margin is an amount (in pixels) that all shapes will grow when computing collisions, to account for numerical imprecision.
</description>
</method>
<method name="test_move">
@@ -21762,7 +22501,7 @@
</method>
</methods>
<members>
- <member name="collision/margin" type="float" setter="set_collision_margin" getter="get_collision_margin" brief="">
+ <member name="collision/safe_margin" type="float" setter="set_safe_margin" getter="get_safe_margin" brief="">
</member>
</members>
<constants>
@@ -23466,7 +24205,23 @@
Material is a base [Resource] used for coloring and shading geometry. All materials inherit from it and almost all [VisualInstance] derived nodes carry a Material. A few flags and parameters are shared between all material types and are configured here.
</description>
<methods>
+ <method name="get_next_pass" qualifiers="const">
+ <return type="Material">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_next_pass">
+ <argument index="0" name="next_pass" type="Material">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
+ <members>
+ <member name="next_pass" type="Material" setter="set_next_pass" getter="get_next_pass" brief="">
+ </member>
+ </members>
<constants>
</constants>
</class>
@@ -23565,6 +24320,27 @@
</method>
</methods>
<constants>
+ <constant name="PRIMITIVE_POINTS" value="0">
+ Render array as points (one vertex equals one point).
+ </constant>
+ <constant name="PRIMITIVE_LINES" value="1">
+ Render array as lines (every two vertices a line is created).
+ </constant>
+ <constant name="PRIMITIVE_LINE_STRIP" value="2">
+ Render array as line strip.
+ </constant>
+ <constant name="PRIMITIVE_LINE_LOOP" value="3">
+ Render array as line loop (like line strip, but closed).
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLES" value="4">
+ Render array as triangles (every three vertices a triangle is created).
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLE_STRIP" value="5">
+ Render array as triangle strips.
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLE_FAN" value="6">
+ Render array as triangle fans.
+ </constant>
</constants>
</class>
<class name="MeshDataTool" inherits="Reference" category="Core">
@@ -23610,6 +24386,8 @@
</description>
</method>
<method name="get_edge_meta" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -23642,6 +24420,8 @@
</description>
</method>
<method name="get_face_meta" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -23724,6 +24504,8 @@
</description>
</method>
<method name="get_vertex_meta" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -23879,6 +24661,10 @@
<description>
</description>
</method>
+ <method name="create_debug_tagents">
+ <description>
+ </description>
+ </method>
<method name="create_trimesh_collision">
<description>
This helper creates a [StaticBody] child [Node] using the mesh geometry as collision. It's mainly used for testing.
@@ -23897,6 +24683,14 @@
<description>
</description>
</method>
+ <method name="get_surface_material" qualifiers="const">
+ <return type="Material">
+ </return>
+ <argument index="0" name="surface" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_mesh">
<argument index="0" name="mesh" type="Mesh">
</argument>
@@ -23910,6 +24704,14 @@
<description>
</description>
</method>
+ <method name="set_surface_material">
+ <argument index="0" name="surface" type="int">
+ </argument>
+ <argument index="1" name="material" type="Material">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="mesh" type="Mesh" setter="set_mesh" getter="get_mesh" brief="">
@@ -24974,6 +25776,12 @@
<description>
</description>
</method>
+ <method name="get_h_axis_stretch_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_patch_margin" qualifiers="const">
<return type="int">
</return>
@@ -24994,12 +25802,24 @@
<description>
</description>
</method>
+ <method name="get_v_axis_stretch_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_draw_center">
<argument index="0" name="draw_center" type="bool">
</argument>
<description>
</description>
</method>
+ <method name="set_h_axis_stretch_mode">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_patch_margin">
<argument index="0" name="margin" type="int">
</argument>
@@ -25020,8 +25840,18 @@
<description>
</description>
</method>
+ <method name="set_v_axis_stretch_mode">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
+ <member name="axis_stretch_horizontal" type="int" setter="set_h_axis_stretch_mode" getter="get_h_axis_stretch_mode" brief="">
+ </member>
+ <member name="axis_stretch_vertical" type="int" setter="set_v_axis_stretch_mode" getter="get_v_axis_stretch_mode" brief="">
+ </member>
<member name="draw_center" type="bool" setter="set_draw_center" getter="get_draw_center" brief="">
</member>
<member name="patch_margin_bottom" type="int" setter="set_patch_margin" getter="get_patch_margin" brief="">
@@ -25044,6 +25874,12 @@
</signal>
</signals>
<constants>
+ <constant name="AXIS_STRETCH_MODE_STRETCH" value="0">
+ </constant>
+ <constant name="AXIS_STRETCH_MODE_TILE" value="1">
+ </constant>
+ <constant name="AXIS_STRETCH_MODE_TILE_FIT" value="2">
+ </constant>
</constants>
</class>
<class name="Node" inherits="Object" category="Core">
@@ -25224,7 +26060,7 @@
Return the name of the node. This name is unique among the siblings (other child nodes from the same parent).
</description>
</method>
- <method name="get_network_mode" qualifiers="const">
+ <method name="get_network_master" qualifiers="const">
<return type="int">
</return>
<description>
@@ -25628,11 +26464,12 @@
Set the name of the [Node]. Name must be unique within parent, and setting an already existing name will cause for the node to be automatically renamed.
</description>
</method>
- <method name="set_network_mode">
- <argument index="0" name="mode" type="int">
+ <method name="set_network_master">
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="recursive" type="bool" default="true">
</argument>
<description>
- Change the networking mode of the [Node], where [i]mode[/i] is one of the constants NETWORK_MODE_*. Master nodes will only call gdscript methods defined as [i]master func[/i] if a RPC call is received (slave nodes will only call [i]slave func[/i]; both will call [i]remote func[/i] if the call is not local, and [i]sync func[/i] in any case). Inherit mode looks at the parent node to determine the value (root node depends on the [SceneTree] having a networking peer set with [method SceneTree.set_network_peer])
</description>
</method>
<method name="set_owner">
@@ -25749,12 +26586,6 @@
</constant>
<constant name="NOTIFICATION_INTERNAL_FIXED_PROCESS" value="26">
</constant>
- <constant name="NETWORK_MODE_INHERIT" value="0">
- </constant>
- <constant name="NETWORK_MODE_MASTER" value="1">
- </constant>
- <constant name="NETWORK_MODE_SLAVE" value="2">
- </constant>
<constant name="RPC_MODE_DISABLED" value="0">
</constant>
<constant name="RPC_MODE_REMOTE" value="1">
@@ -26717,6 +27548,12 @@
<description>
</description>
</method>
+ <method name="set_ime_position">
+ <argument index="0" name="arg0" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_keep_screen_on">
<argument index="0" name="enabled" type="bool">
</argument>
@@ -27053,6 +27890,17 @@
Return the class of the object as a string.
</description>
</method>
+ <method name="get_incoming_connections" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ Returns an [Array] of dictionaries with informations 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.
+ - "method_name" is a name of method to which signal is connected.
+ </description>
+ </method>
<method name="get_instance_ID" qualifiers="const">
<return type="int">
</return>
@@ -27425,6 +28273,8 @@
</description>
</method>
<method name="get_item_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -27453,6 +28303,8 @@
</description>
</method>
<method name="get_selected_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<description>
</description>
</method>
@@ -28096,102 +28948,6 @@
<constants>
</constants>
</class>
-<class name="ParticleAttractor2D" inherits="Node2D" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_absorption" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_disable_radius" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_gravity" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="get_particles_path" qualifiers="const">
- <return type="NodePath">
- </return>
- <description>
- </description>
- </method>
- <method name="get_radius" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
- <method name="is_enabled" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="set_absorption">
- <argument index="0" name="absorption" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_disable_radius">
- <argument index="0" name="radius" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_enabled">
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_gravity">
- <argument index="0" name="gravity" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_particles_path">
- <argument index="0" name="path" type="NodePath">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_radius">
- <argument index="0" name="radius" type="float">
- </argument>
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="absorption" type="float" setter="set_absorption" getter="get_absorption" brief="">
- </member>
- <member name="disable_radius" type="float" setter="set_disable_radius" getter="get_disable_radius" brief="">
- </member>
- <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief="">
- </member>
- <member name="gravity" type="float" setter="set_gravity" getter="get_gravity" brief="">
- </member>
- <member name="particles_path" type="NodePath" setter="set_particles_path" getter="get_particles_path" brief="">
- </member>
- <member name="radius" type="float" setter="set_radius" getter="get_radius" brief="">
- </member>
- </members>
- <constants>
- </constants>
-</class>
<class name="Particles" inherits="GeometryInstance" category="Core">
<brief_description>
</brief_description>
@@ -28254,6 +29010,12 @@
<description>
</description>
</method>
+ <method name="get_one_shot" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_pre_process_time" qualifiers="const">
<return type="float">
</return>
@@ -28296,6 +29058,10 @@
<description>
</description>
</method>
+ <method name="restart">
+ <description>
+ </description>
+ </method>
<method name="set_amount">
<argument index="0" name="amount" type="int">
</argument>
@@ -28352,6 +29118,12 @@
<description>
</description>
</method>
+ <method name="set_one_shot">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_pre_process_time">
<argument index="0" name="secs" type="float">
</argument>
@@ -28416,9 +29188,11 @@
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" brief="">
</member>
+ <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" brief="">
+ </member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" brief="">
</member>
- <member name="process_material" type="ParticlesMaterial,ShaderMaterial" setter="set_process_material" getter="get_process_material" brief="">
+ <member name="process_material" type="ShaderMaterial,ParticlesMaterial" setter="set_process_material" getter="get_process_material" brief="">
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" brief="">
</member>
@@ -28446,129 +29220,90 @@
Particles2D is a particle system 2D [Node] that is used to simulate several types of particle effects, such as explosions, rain, snow, fireflies, or other magical-like shinny sparkles. Particles are drawn using impostors, and given their dynamic behavior, the user must provide a visibility bounding box (although helpers to create one automatically exist).
</description>
<methods>
- <method name="get_amount" qualifiers="const">
- <return type="int">
+ <method name="capture_rect" qualifiers="const">
+ <return type="Rect2">
</return>
<description>
- Returns the amount of particles spawned at each emission
</description>
</method>
- <method name="get_color" qualifiers="const">
- <return type="Color">
+ <method name="get_amount" qualifiers="const">
+ <return type="int">
</return>
<description>
- Returns the tint color for each particle.
+ Returns the amount of particles spawned at each emission
</description>
</method>
- <method name="get_color_phase_color" qualifiers="const">
- <return type="Color">
+ <method name="get_draw_order" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="phase" type="int">
- </argument>
<description>
</description>
</method>
- <method name="get_color_phase_pos" qualifiers="const">
+ <method name="get_explosiveness_ratio" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="phase" type="int">
- </argument>
<description>
</description>
</method>
- <method name="get_color_phases" qualifiers="const">
+ <method name="get_fixed_fps" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
- <method name="get_emission_half_extents" qualifiers="const">
- <return type="Vector2">
- </return>
- <description>
- Returns the half extents of the emission box.
- </description>
- </method>
- <method name="get_emission_points" qualifiers="const">
- <return type="PoolVector2Array">
- </return>
- <description>
- </description>
- </method>
- <method name="get_emissor_offset" qualifiers="const">
- <return type="Vector2">
+ <method name="get_fractional_delta" qualifiers="const">
+ <return type="bool">
</return>
<description>
- Returns the particle spawn origin position relative to the emitter.
</description>
</method>
- <method name="get_emit_timeout" qualifiers="const">
- <return type="float">
+ <method name="get_h_frames" qualifiers="const">
+ <return type="int">
</return>
<description>
- Returns the amount of seconds during which the emitter will spawn particles
</description>
</method>
- <method name="get_explosiveness" qualifiers="const">
+ <method name="get_lifetime" qualifiers="const">
<return type="float">
</return>
<description>
+ Gets the amount of seconds that each particle will be visible.
</description>
</method>
- <method name="get_gradient" qualifiers="const">
- <return type="Gradient">
- </return>
- <description>
- Returns the [Gradient] used to tint each particle.
- </description>
- </method>
- <method name="get_h_frames" qualifiers="const">
- <return type="int">
+ <method name="get_normal_map" qualifiers="const">
+ <return type="Texture">
</return>
<description>
</description>
</method>
- <method name="get_initial_velocity" qualifiers="const">
- <return type="Vector2">
+ <method name="get_one_shot" qualifiers="const">
+ <return type="bool">
</return>
<description>
</description>
</method>
- <method name="get_lifetime" qualifiers="const">
+ <method name="get_pre_process_time" qualifiers="const">
<return type="float">
</return>
<description>
- Gets the amount of seconds that each particle will be visible.
</description>
</method>
- <method name="get_param" qualifiers="const">
- <return type="float">
+ <method name="get_process_material" qualifiers="const">
+ <return type="Material">
</return>
- <argument index="0" name="param" type="int">
- </argument>
<description>
- Returns the value of the specified emitter parameter
</description>
</method>
- <method name="get_pre_process_time" qualifiers="const">
+ <method name="get_randomness_ratio" qualifiers="const">
<return type="float">
</return>
<description>
</description>
</method>
- <method name="get_process_mode" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_randomness" qualifiers="const">
+ <method name="get_speed_scale" qualifiers="const">
<return type="float">
</return>
- <argument index="0" name="param" type="int">
- </argument>
<description>
- Returns the randomness value of the specified emitter parameter
</description>
</method>
<method name="get_texture" qualifiers="const">
@@ -28578,11 +29313,10 @@
Returns the texture for emitted particles
</description>
</method>
- <method name="get_time_scale" qualifiers="const">
- <return type="float">
+ <method name="get_use_local_coordinates" qualifiers="const">
+ <return type="bool">
</return>
<description>
- Returns the emitter time scale
</description>
</method>
<method name="get_v_frames" qualifiers="const">
@@ -28591,38 +29325,20 @@
<description>
</description>
</method>
- <method name="is_emitting" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- Returns whether this emitter is currently emitting or not
- </description>
- </method>
- <method name="is_flipped_h" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="is_flipped_v" qualifiers="const">
- <return type="bool">
+ <method name="get_visibility_rect" qualifiers="const">
+ <return type="Rect2">
</return>
<description>
</description>
</method>
- <method name="is_using_local_space" qualifiers="const">
+ <method name="is_emitting" qualifiers="const">
<return type="bool">
</return>
<description>
+ Returns whether this emitter is currently emitting or not
</description>
</method>
- <method name="pre_process">
- <argument index="0" name="time" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="reset">
+ <method name="restart">
<description>
</description>
</method>
@@ -28633,348 +29349,153 @@
Sets the amount of particles spawned at each emission
</description>
</method>
- <method name="set_color">
- <argument index="0" name="color" type="Color">
- </argument>
- <description>
- Set the tint color for each particle.
- </description>
- </method>
- <method name="set_color_phase_color">
- <argument index="0" name="phase" type="int">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_color_phase_pos">
- <argument index="0" name="phase" type="int">
- </argument>
- <argument index="1" name="pos" type="float">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_color_phases">
- <argument index="0" name="phases" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_emission_half_extents">
- <argument index="0" name="extents" type="Vector2">
- </argument>
- <description>
- Sets the half extents of the emission box, particles will be spawned at random inside this box.
- </description>
- </method>
- <method name="set_emission_points">
- <argument index="0" name="points" type="PoolVector2Array">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_emissor_offset">
- <argument index="0" name="offset" type="Vector2">
- </argument>
- <description>
- Sets the particle spawn origin position relative to the emitter center. for example if this value is set to (50, 50), the particle will spawn 50 units to the right and 50 units to the bottom of the emitter center.
- </description>
- </method>
- <method name="set_emit_timeout">
- <argument index="0" name="value" type="float">
+ <method name="set_draw_order">
+ <argument index="0" name="order" type="int">
</argument>
<description>
- Sets the amount of seconds during which the emitter will spawn particles, after the specified seconds the emitter state will be set to non emitting, so calling [method is_emitting] will return false. If the timeout is 0 the emitter will spawn forever.
</description>
</method>
<method name="set_emitting">
- <argument index="0" name="active" type="bool">
+ <argument index="0" name="emitting" type="bool">
</argument>
<description>
If this is set to true then the particle emitter will emit particles, if its false it will not.
</description>
</method>
- <method name="set_explosiveness">
- <argument index="0" name="amount" type="float">
+ <method name="set_explosiveness_ratio">
+ <argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_flip_h">
- <argument index="0" name="enable" type="bool">
+ <method name="set_fixed_fps">
+ <argument index="0" name="fps" type="int">
</argument>
<description>
</description>
</method>
- <method name="set_flip_v">
+ <method name="set_fractional_delta">
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
- <method name="set_gradient">
- <return type="Gradient">
- </return>
- <argument index="0" name="gradient" type="Object">
+ <method name="set_h_frames">
+ <argument index="0" name="frames" type="int">
</argument>
<description>
- Sets the [Gradient] used to tint each particle. Particle will be tinted according to their lifetimes.
</description>
</method>
- <method name="set_h_frames">
- <argument index="0" name="enable" type="int">
+ <method name="set_lifetime">
+ <argument index="0" name="secs" type="float">
</argument>
<description>
+ Sets the amount of seconds that each particle will be visible.
</description>
</method>
- <method name="set_initial_velocity">
- <argument index="0" name="velocity" type="Vector2">
+ <method name="set_normal_map">
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
</description>
</method>
- <method name="set_lifetime">
- <argument index="0" name="lifetime" type="float">
+ <method name="set_one_shot">
+ <argument index="0" name="secs" type="bool">
</argument>
<description>
- Sets the amount of seconds that each particle will be visible.
</description>
</method>
- <method name="set_param">
- <argument index="0" name="param" type="int">
- </argument>
- <argument index="1" name="value" type="float">
+ <method name="set_pre_process_time">
+ <argument index="0" name="secs" type="float">
</argument>
<description>
- Sets the value of the specified emitter parameter (see the constants secction for the list of parameters)
</description>
</method>
- <method name="set_pre_process_time">
- <argument index="0" name="time" type="float">
+ <method name="set_process_material">
+ <argument index="0" name="material" type="Material">
</argument>
<description>
</description>
</method>
- <method name="set_process_mode">
- <argument index="0" name="mode" type="int">
+ <method name="set_randomness_ratio">
+ <argument index="0" name="ratio" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_randomness">
- <argument index="0" name="param" type="int">
- </argument>
- <argument index="1" name="value" type="float">
+ <method name="set_speed_scale">
+ <argument index="0" name="scale" type="float">
</argument>
<description>
- Sets the randomness value of the specified emitter parameter (see the constants secction for the list of parameters), 0 means no randomness, so every particle will have the parameters specified, 1 means that the parameter will be chosen at random, the closer the randomness value gets to 0 the more conservative the variation of the parameter will be.
</description>
</method>
<method name="set_texture">
- <return type="Texture">
- </return>
- <argument index="0" name="texture" type="Object">
+ <argument index="0" name="texture" type="Texture">
</argument>
<description>
- Sets the texture for each particle
</description>
</method>
- <method name="set_time_scale">
- <argument index="0" name="time_scale" type="float">
+ <method name="set_use_local_coordinates">
+ <argument index="0" name="enable" type="bool">
</argument>
<description>
- Sets the increment or decrement for the particle lifetime. for example: if the time scale is set to 2, the particles will die and move twice as fast.
</description>
</method>
- <method name="set_use_local_space">
- <argument index="0" name="enable" type="bool">
+ <method name="set_v_frames">
+ <argument index="0" name="frames" type="int">
</argument>
<description>
</description>
</method>
- <method name="set_v_frames">
- <argument index="0" name="enable" type="int">
+ <method name="set_visibility_rect">
+ <argument index="0" name="aabb" type="Rect2">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="color/color" type="Color" setter="set_color" getter="get_color" brief="">
- </member>
- <member name="color/color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp" brief="">
- </member>
- <member name="color_phases/count" type="int" setter="set_color_phases" getter="get_color_phases" brief="">
- </member>
- <member name="config/amount" type="int" setter="set_amount" getter="get_amount" brief="">
- </member>
- <member name="config/emit_timeout" type="float" setter="set_emit_timeout" getter="get_emit_timeout" brief="">
- </member>
- <member name="config/emitting" type="bool" setter="set_emitting" getter="is_emitting" brief="">
- </member>
- <member name="config/explosiveness" type="float" setter="set_explosiveness" getter="get_explosiveness" brief="">
- </member>
- <member name="config/flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" brief="">
- </member>
- <member name="config/flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v" brief="">
- </member>
- <member name="config/h_frames" type="int" setter="set_h_frames" getter="get_h_frames" brief="">
- </member>
- <member name="config/half_extents" type="Vector2" setter="set_emission_half_extents" getter="get_emission_half_extents" brief="">
- </member>
- <member name="config/lifetime" type="float" setter="set_lifetime" getter="get_lifetime" brief="">
- </member>
- <member name="config/local_space" type="bool" setter="set_use_local_space" getter="is_using_local_space" brief="">
- </member>
- <member name="config/offset" type="Vector2" setter="set_emissor_offset" getter="get_emissor_offset" brief="">
- </member>
- <member name="config/preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" brief="">
- </member>
- <member name="config/process_mode" type="int" setter="set_process_mode" getter="get_process_mode" brief="">
- </member>
- <member name="config/texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
- </member>
- <member name="config/time_scale" type="float" setter="set_time_scale" getter="get_time_scale" brief="">
- </member>
- <member name="config/v_frames" type="int" setter="set_v_frames" getter="get_v_frames" brief="">
- </member>
- <member name="emission_points" type="PoolVector2Array" setter="set_emission_points" getter="get_emission_points" brief="">
- </member>
- <member name="params/anim_initial_pos" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/anim_speed_scale" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/damping" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/direction" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/final_size" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/gravity_direction" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/gravity_strength" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/hue_variation" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/initial_angle" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/initial_size" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/linear_velocity" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/orbit_velocity" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/radial_accel" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/spin_velocity" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/spread" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="params/tangential_accel" type="float" setter="set_param" getter="get_param" brief="">
- </member>
- <member name="phase_0/color" type="Color" setter="set_color_phase_color" getter="get_color_phase_color" brief="">
- </member>
- <member name="phase_0/pos" type="float" setter="set_color_phase_pos" getter="get_color_phase_pos" brief="">
- </member>
- <member name="phase_1/color" type="Color" setter="set_color_phase_color" getter="get_color_phase_color" brief="">
- </member>
- <member name="phase_1/pos" type="float" setter="set_color_phase_pos" getter="get_color_phase_pos" brief="">
- </member>
- <member name="phase_2/color" type="Color" setter="set_color_phase_color" getter="get_color_phase_color" brief="">
- </member>
- <member name="phase_2/pos" type="float" setter="set_color_phase_pos" getter="get_color_phase_pos" brief="">
- </member>
- <member name="phase_3/color" type="Color" setter="set_color_phase_color" getter="get_color_phase_color" brief="">
+ <member name="amount" type="int" setter="set_amount" getter="get_amount" brief="">
</member>
- <member name="phase_3/pos" type="float" setter="set_color_phase_pos" getter="get_color_phase_pos" brief="">
+ <member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="">
</member>
- <member name="randomness/anim_initial_pos" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="emitting" type="bool" setter="set_emitting" getter="is_emitting" brief="">
</member>
- <member name="randomness/anim_speed_scale" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio" brief="">
</member>
- <member name="randomness/damping" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="fixed_fps" type="int" setter="set_fixed_fps" getter="get_fixed_fps" brief="">
</member>
- <member name="randomness/direction" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" brief="">
</member>
- <member name="randomness/final_size" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="h_frames" type="int" setter="set_h_frames" getter="get_h_frames" brief="">
</member>
- <member name="randomness/gravity_direction" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" brief="">
</member>
- <member name="randomness/gravity_strength" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" brief="">
</member>
- <member name="randomness/hue_variation" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" brief="">
</member>
- <member name="randomness/initial_angle" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot" brief="">
</member>
- <member name="randomness/initial_size" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time" brief="">
</member>
- <member name="randomness/linear_velocity" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="process_material" type="ShaderMaterial,ParticlesMaterial" setter="set_process_material" getter="get_process_material" brief="">
</member>
- <member name="randomness/orbit_velocity" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" brief="">
</member>
- <member name="randomness/radial_accel" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" brief="">
</member>
- <member name="randomness/spin_velocity" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="randomness/spread" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="v_frames" type="int" setter="set_v_frames" getter="get_v_frames" brief="">
</member>
- <member name="randomness/tangential_accel" type="float" setter="set_randomness" getter="get_randomness" brief="">
+ <member name="visibility_rect" type="Rect3" setter="set_visibility_rect" getter="get_visibility_rect" brief="">
</member>
</members>
- <signals>
- <signal name="emission_finished">
- <description>
- </description>
- </signal>
- </signals>
<constants>
- <constant name="PARAM_DIRECTION" value="0">
- Direction in degrees at which the particles will be launched, Notice that when the direction is set to 0 the particles will be launched to the negative
- </constant>
- <constant name="PARAM_SPREAD" value="1">
- </constant>
- <constant name="PARAM_LINEAR_VELOCITY" value="2">
- Velocity at which the particles will be launched.
- </constant>
- <constant name="PARAM_SPIN_VELOCITY" value="3">
- The speed at which particles will spin around its own center.
- </constant>
- <constant name="PARAM_ORBIT_VELOCITY" value="4">
- Velocity at which the particles will orbit around the emitter center
- </constant>
- <constant name="PARAM_GRAVITY_DIRECTION" value="5">
- Direction in degrees at which the particles will be attracted
- </constant>
- <constant name="PARAM_GRAVITY_STRENGTH" value="6">
- Strength of the gravitation attraction for each particle
- </constant>
- <constant name="PARAM_RADIAL_ACCEL" value="7">
- </constant>
- <constant name="PARAM_TANGENTIAL_ACCEL" value="8">
- </constant>
- <constant name="PARAM_DAMPING" value="9">
- Amount of damping for each particle
- </constant>
- <constant name="PARAM_INITIAL_ANGLE" value="10">
- Initial angle in radians at which each particle will be spawned
- </constant>
- <constant name="PARAM_INITIAL_SIZE" value="11">
- Initial size of each particle
- </constant>
- <constant name="PARAM_FINAL_SIZE" value="12">
- Final size of each particle, the particle size will interpolate to this value during its lifetime.
- </constant>
- <constant name="PARAM_HUE_VARIATION" value="13">
- </constant>
- <constant name="PARAM_ANIM_SPEED_SCALE" value="14">
- </constant>
- <constant name="PARAM_ANIM_INITIAL_POS" value="15">
- </constant>
- <constant name="PARAM_MAX" value="16">
+ <constant name="DRAW_ORDER_INDEX" value="0">
</constant>
- <constant name="MAX_COLOR_PHASES" value="4">
+ <constant name="DRAW_ORDER_LIFETIME" value="1">
</constant>
</constants>
</class>
@@ -29002,6 +29523,12 @@
<description>
</description>
</method>
+ <method name="get_emission_color_texture" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_emission_normal_texture" qualifiers="const">
<return type="Texture">
</return>
@@ -29118,6 +29645,12 @@
<description>
</description>
</method>
+ <method name="set_emission_color_texture">
+ <argument index="0" name="texture" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_emission_normal_texture">
<argument index="0" name="texture" type="Texture">
</argument>
@@ -29230,6 +29763,8 @@
</member>
<member name="angular_velocity_random" type="float" setter="set_param_randomness" getter="get_param_randomness" brief="">
</member>
+ <member name="anim_loop" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
<member name="anim_offset" type="float" setter="set_param" getter="get_param" brief="">
</member>
<member name="anim_offset_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
@@ -29254,6 +29789,8 @@
</member>
<member name="emission_box_extents" type="Vector3" setter="set_emission_box_extents" getter="get_emission_box_extents" brief="">
</member>
+ <member name="emission_color_texture" type="Texture" setter="set_emission_color_texture" getter="get_emission_color_texture" brief="">
+ </member>
<member name="emission_normal_texture" type="Texture" setter="set_emission_normal_texture" getter="get_emission_normal_texture" brief="">
</member>
<member name="emission_point_count" type="int" setter="set_emission_point_count" getter="get_emission_point_count" brief="">
@@ -29266,6 +29803,8 @@
</member>
<member name="flag_align_y" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
+ <member name="flag_disable_z" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
<member name="flag_rotate_y" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
<member name="flatness" type="float" setter="set_flatness" getter="get_flatness" brief="">
@@ -29352,7 +29891,7 @@
</constant>
<constant name="FLAG_ROTATE_Y" value="1">
</constant>
- <constant name="FLAG_MAX" value="2">
+ <constant name="FLAG_MAX" value="4">
</constant>
<constant name="EMISSION_SHAPE_POINT" value="0">
</constant>
@@ -30289,6 +30828,16 @@
Substitute 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">
+ <argument index="0" name="area" type="RID">
+ </argument>
+ <argument index="1" name="shape_idx" type="int">
+ </argument>
+ <argument index="2" name="disable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="area_set_shape_transform">
<argument index="0" name="area" type="RID">
</argument>
@@ -30450,24 +30999,6 @@
Get the instance ID of the object the area is assigned to.
</description>
</method>
- <method name="body_get_one_way_collision_direction" qualifiers="const">
- <return type="Vector2">
- </return>
- <argument index="0" name="body" type="RID">
- </argument>
- <description>
- Return the direction used for one-way collision detection.
- </description>
- </method>
- <method name="body_get_one_way_collision_max_depth" qualifiers="const">
- <return type="float">
- </return>
- <argument index="0" name="body" type="RID">
- </argument>
- <description>
- Return how far a body can go through the given one, when it allows one-way collisions.
- </description>
- </method>
<method name="body_get_param" qualifiers="const">
<return type="float">
</return>
@@ -30546,17 +31077,6 @@
Return 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_shape_set_as_trigger" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="body" type="RID">
- </argument>
- <argument index="1" name="shape_idx" type="int">
- </argument>
- <description>
- Return whether a body's shape is marked as a trigger.
- </description>
- </method>
<method name="body_remove_collision_exception">
<argument index="0" name="body" type="RID">
</argument>
@@ -30652,24 +31172,6 @@
Set 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_one_way_collision_direction">
- <argument index="0" name="body" type="RID">
- </argument>
- <argument index="1" name="normal" type="Vector2">
- </argument>
- <description>
- Set a direction in which bodies can go through the given one. If this value is different from (0,0), any movement within 90 degrees of this vector is considered a valid movement. Set this direction to (0,0) to disable one-way collisions.
- </description>
- </method>
- <method name="body_set_one_way_collision_max_depth">
- <argument index="0" name="body" type="RID">
- </argument>
- <argument index="1" name="depth" type="float">
- </argument>
- <description>
- Set how far a body can go through the given one, if it allows one-way collisions (see [method body_set_one_way_collision_direction]).
- </description>
- </method>
<method name="body_set_param">
<argument index="0" name="body" type="RID">
</argument>
@@ -30692,7 +31194,7 @@
Substitute 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_trigger">
+ <method name="body_set_shape_as_one_way_collision">
<argument index="0" name="body" type="RID">
</argument>
<argument index="1" name="shape_idx" type="int">
@@ -30700,7 +31202,16 @@
<argument index="2" name="enable" type="bool">
</argument>
<description>
- Mark a body's shape as a trigger. A trigger shape cannot affect other bodies, but detects other shapes entering and exiting it.
+ </description>
+ </method>
+ <method name="body_set_shape_disabled">
+ <argument index="0" name="body" type="RID">
+ </argument>
+ <argument index="1" name="shape_idx" type="int">
+ </argument>
+ <argument index="2" name="disable" type="bool">
+ </argument>
+ <description>
</description>
</method>
<method name="body_set_shape_metadata">
@@ -30984,11 +31495,9 @@
<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_TRESHOLD" value="3">
- Constant to set/get the linear velocity threshold. Bodies slower than this will be marked as potentially inactive.
+ <constant name="SPACE_PARAM_BODY_LINEAR_VELOCITY_SLEEP_THRESHOLD" value="3">
</constant>
- <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_TRESHOLD" value="4">
- Constant to set/get the angular velocity threshold. Bodies slower than this will be marked as potentially inactive.
+ <constant name="SPACE_PARAM_BODY_ANGULAR_VELOCITY_SLEEP_THRESHOLD" value="4">
</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.
@@ -31528,20 +32037,6 @@
Return an individual bit on the collision mask.
</description>
</method>
- <method name="get_one_way_collision_direction" qualifiers="const">
- <return type="Vector2">
- </return>
- <description>
- Return the direction used for one-way collision detection.
- </description>
- </method>
- <method name="get_one_way_collision_max_depth" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Return how far a body can go through this one, when it allows one-way collisions.
- </description>
- </method>
<method name="remove_collision_exception_with">
<argument index="0" name="body" type="PhysicsBody2D">
</argument>
@@ -31583,20 +32078,6 @@
Set/clear individual bits on the collision mask. This makes selecting the areas scanned easier.
</description>
</method>
- <method name="set_one_way_collision_direction">
- <argument index="0" name="dir" type="Vector2">
- </argument>
- <description>
- Set a direction in which bodies can go through this one. If this value is different from (0,0), any movement within 90 degrees of this vector is considered a valid movement. Set this direction to (0,0) to disable one-way collisions.
- </description>
- </method>
- <method name="set_one_way_collision_max_depth">
- <argument index="0" name="depth" type="float">
- </argument>
- <description>
- Set how far a body can go through this one, when it allows one-way collisions (see [method set_one_way_collision_direction]).
- </description>
- </method>
</methods>
<members>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
@@ -31605,10 +32086,6 @@
</member>
<member name="layers" type="int" setter="_set_layers" getter="_get_layers" brief="">
</member>
- <member name="one_way_collision/direction" type="Vector2" setter="set_one_way_collision_direction" getter="get_one_way_collision_direction" brief="">
- </member>
- <member name="one_way_collision/max_depth" type="float" setter="set_one_way_collision_max_depth" getter="get_one_way_collision_max_depth" brief="">
- </member>
</members>
<constants>
</constants>
@@ -33809,7 +34286,7 @@
<argument index="0" name="compression_mode" type="int" default="0">
</argument>
<description>
- Returns a new [PoolByteArray] with the data compressed. The compression mode can be set using one of the COMPRESS_* constants of [File].
+ Returns a new [PoolByteArray] with the data compressed. The compression mode can be set using one of the COMPRESS_* constants of [File].
</description>
</method>
<method name="decompress">
@@ -33820,7 +34297,7 @@
<argument index="1" name="compression_mode" type="int" default="0">
</argument>
<description>
- Returns a new [PoolByteArray] with the data decompressed. The buffer_size should be set as the size of the uncompressed data. The compression mode can be set using one of the COMPRESS_* constants of [File].
+ Returns a new [PoolByteArray] with the data decompressed. The buffer_size should be set as the size of the uncompressed data. The compression mode can be set using one of the COMPRESS_* constants of [File].
</description>
</method>
<method name="get_string_from_ascii">
@@ -34694,6 +35171,8 @@
</description>
</method>
<method name="get_item_metadata" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<description>
@@ -34734,6 +35213,13 @@
<description>
</description>
</method>
+ <method name="is_hide_on_checkable_item_selection">
+ <return type="bool">
+ </return>
+ <description>
+ Returns a boolean that indicates whether or not the PopupMenu will hide on checkable item selection.
+ </description>
+ </method>
<method name="is_hide_on_item_selection">
<return type="bool">
</return>
@@ -34741,13 +35227,6 @@
Returns a boolean that indicates whether or not the PopupMenu will hide on item selection.
</description>
</method>
- <method name="is_hide_on_checkable_item_selection">
- <return type="bool">
- </return>
- <description>
- Returns a boolean that indicates whether or not the PopupMenu will hide on checkable item selection.
- </description>
- </method>
<method name="is_item_checkable" qualifiers="const">
<return type="bool">
</return>
@@ -34791,6 +35270,13 @@
Removes the item at index "idx" from the menu. Note that the indexes of items after the removed item are going to be shifted by one.
</description>
</method>
+ <method name="set_hide_on_checkable_item_selection">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ Sets whether or not the PopupMenu will hide on checkable item selection.
+ </description>
+ </method>
<method name="set_hide_on_item_selection">
<argument index="0" name="enable" type="bool">
</argument>
@@ -34798,13 +35284,6 @@
Sets whether or not the PopupMenu will hide on item selection.
</description>
</method>
- <method name="set_hide_on_checkable_item_selection">
- <argument index="0" name="enable" type="bool">
- </argument>
- <description>
- Sets whether or not the PopupMenu will hide on checkable item selection.
- </description>
- </method>
<method name="set_item_ID">
<argument index="0" name="idx" type="int">
</argument>
@@ -34921,6 +35400,8 @@
</method>
</methods>
<members>
+ <member name="hide_on_checkable_item_selection" type="bool" setter="set_hide_on_checkable_item_selection" getter="is_hide_on_checkable_item_selection" brief="">
+ </member>
<member name="hide_on_item_selection" type="bool" setter="set_hide_on_item_selection" getter="is_hide_on_item_selection" brief="">
</member>
<member name="items" type="Array" setter="_set_items" getter="_get_items" brief="">
@@ -36400,6 +36881,7 @@
Ending corner.
</member>
<member name="position" type="Vector2" setter="" getter="" brief="">
+ Position (starting corner).
</member>
<member name="size" type="Vector2" setter="" getter="" brief="">
Size from position to end.
@@ -36596,8 +37078,7 @@
<member name="end" type="Vector3" setter="" getter="" brief="">
Ending corner.
</member>
- <member name="pos" type="Vector3" setter="" getter="" brief="">
- Position (starting corner).
+ <member name="position" type="Vector3" setter="" getter="" brief="">
</member>
<member name="size" type="Vector3" setter="" getter="" brief="">
Size from position to end.
@@ -36940,7 +37421,7 @@
</description>
</method>
<method name="search" qualifiers="const">
- <return type="Object">
+ <return type="RegExMatch">
</return>
<argument index="0" name="text" type="String">
</argument>
@@ -37063,16 +37544,72 @@
<description>
</description>
</method>
+ <method name="get_update_position" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_update_rotation" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_update_scale" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_use_global_coordinates" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_remote_node">
<argument index="0" name="path" type="NodePath">
</argument>
<description>
</description>
</method>
+ <method name="set_update_position">
+ <argument index="0" name="update_remote_position" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_update_rotation">
+ <argument index="0" name="update_remote_rotation" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_update_scale">
+ <argument index="0" name="update_remote_scale" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_use_global_coordinates">
+ <argument index="0" name="use_global_coordinates" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="remote_path" type="NodePath" setter="set_remote_node" getter="get_remote_node" brief="">
</member>
+ <member name="update_position" type="bool" setter="set_update_position" getter="get_update_position" brief="">
+ </member>
+ <member name="update_rotation" type="bool" setter="set_update_rotation" getter="get_update_rotation" brief="">
+ </member>
+ <member name="update_scale" type="bool" setter="set_update_scale" getter="get_update_scale" brief="">
+ </member>
+ <member name="use_global_coordinates" type="bool" setter="set_use_global_coordinates" getter="get_use_global_coordinates" brief="">
+ </member>
</members>
<constants>
</constants>
@@ -37089,16 +37626,72 @@
<description>
</description>
</method>
+ <method name="get_update_position" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_update_rotation" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_update_scale" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_use_global_coordinates" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_remote_node">
<argument index="0" name="path" type="NodePath">
</argument>
<description>
</description>
</method>
+ <method name="set_update_position">
+ <argument index="0" name="update_remote_position" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_update_rotation">
+ <argument index="0" name="update_remote_rotation" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_update_scale">
+ <argument index="0" name="update_remote_scale" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_use_global_coordinates">
+ <argument index="0" name="use_global_coordinates" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="remote_path" type="NodePath" setter="set_remote_node" getter="get_remote_node" brief="">
</member>
+ <member name="update_position" type="bool" setter="set_update_position" getter="get_update_position" brief="">
+ </member>
+ <member name="update_rotation" type="bool" setter="set_update_rotation" getter="get_update_rotation" brief="">
+ </member>
+ <member name="update_scale" type="bool" setter="set_update_scale" getter="get_update_scale" brief="">
+ </member>
+ <member name="use_global_coordinates" type="bool" setter="set_use_global_coordinates" getter="get_use_global_coordinates" brief="">
+ </member>
</members>
<constants>
</constants>
@@ -37488,6 +38081,12 @@
<description>
</description>
</method>
+ <method name="get_percent_visible" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_tab_size" qualifiers="const">
<return type="int">
</return>
@@ -37508,7 +38107,7 @@
</description>
</method>
<method name="get_v_scroll">
- <return type="Object">
+ <return type="VScrollBar">
</return>
<description>
</description>
@@ -37583,7 +38182,7 @@
</description>
</method>
<method name="push_font">
- <argument index="0" name="font" type="Object">
+ <argument index="0" name="font" type="Font">
</argument>
<description>
</description>
@@ -37642,6 +38241,12 @@
<description>
</description>
</method>
+ <method name="set_percent_visible">
+ <argument index="0" name="percent_visible" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_scroll_active">
<argument index="0" name="active" type="bool">
</argument>
@@ -37677,6 +38282,12 @@
<description>
</description>
</method>
+ <method name="set_text">
+ <argument index="0" name="text" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_use_bbcode">
<argument index="0" name="enable" type="bool">
</argument>
@@ -37695,6 +38306,8 @@
</member>
<member name="bbcode_text" type="String" setter="set_bbcode" getter="get_bbcode" brief="">
</member>
+ <member name="percent_visible" type="float" setter="set_percent_visible" getter="get_percent_visible" brief="">
+ </member>
<member name="visible_characters" type="int" setter="set_visible_characters" getter="get_visible_characters" brief="">
</member>
</members>
@@ -38777,6 +39390,8 @@
</description>
</method>
<method name="get_node_property_value" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="idx" type="int">
</argument>
<argument index="1" name="prop_idx" type="int">
@@ -38878,6 +39493,12 @@
<description>
</description>
</method>
+ <method name="get_network_connected_peers" qualifiers="const">
+ <return type="PoolIntArray">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_network_unique_id" qualifiers="const">
<return type="int">
</return>
@@ -39523,6 +40144,8 @@
</description>
</method>
<method name="get_shader_param" qualifiers="const">
+ <return type="Variant">
+ </return>
<argument index="0" name="param" type="String">
</argument>
<description>
@@ -39949,6 +40572,18 @@
Return true if ticks are visible on borders.
</description>
</method>
+ <method name="is_editable" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_editable">
+ <argument index="0" name="editable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_ticks">
<argument index="0" name="count" type="int">
</argument>
@@ -39965,6 +40600,8 @@
</method>
</methods>
<members>
+ <member name="editable" type="bool" setter="set_editable" getter="is_editable" brief="">
+ </member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" brief="">
</member>
<member name="tick_count" type="int" setter="set_ticks" getter="get_ticks" brief="">
@@ -40513,6 +41150,12 @@
<description>
</description>
</method>
+ <method name="get_grow" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_line_width" qualifiers="const">
<return type="float">
</return>
@@ -40585,6 +41228,12 @@
<description>
</description>
</method>
+ <method name="get_specular_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_subsurface_scattering_strength" qualifiers="const">
<return type="float">
</return>
@@ -40600,25 +41249,37 @@
</description>
</method>
<method name="get_uv1_offset" qualifiers="const">
- <return type="Vector2">
+ <return type="Vector3">
</return>
<description>
</description>
</method>
<method name="get_uv1_scale" qualifiers="const">
- <return type="Vector2">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_uv1_triplanar_blend_sharpness" qualifiers="const">
+ <return type="float">
</return>
<description>
</description>
</method>
<method name="get_uv2_offset" qualifiers="const">
- <return type="Vector2">
+ <return type="Vector3">
</return>
<description>
</description>
</method>
<method name="get_uv2_scale" qualifiers="const">
- <return type="Vector2">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_uv2_triplanar_blend_sharpness" qualifiers="const">
+ <return type="float">
</return>
<description>
</description>
@@ -40629,6 +41290,12 @@
<description>
</description>
</method>
+ <method name="is_grow_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_albedo">
<argument index="0" name="albedo" type="Color">
</argument>
@@ -40747,6 +41414,18 @@
<description>
</description>
</method>
+ <method name="set_grow">
+ <argument index="0" name="amount" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_grow_enabled">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_line_width">
<argument index="0" name="line_width" type="float">
</argument>
@@ -40819,6 +41498,12 @@
<description>
</description>
</method>
+ <method name="set_specular_mode">
+ <argument index="0" name="specular_mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_subsurface_scattering_strength">
<argument index="0" name="strength" type="float">
</argument>
@@ -40834,25 +41519,37 @@
</description>
</method>
<method name="set_uv1_offset">
- <argument index="0" name="offset" type="Vector2">
+ <argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv1_scale">
- <argument index="0" name="scale" type="Vector2">
+ <argument index="0" name="scale" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_uv1_triplanar_blend_sharpness">
+ <argument index="0" name="sharpness" type="float">
</argument>
<description>
</description>
</method>
<method name="set_uv2_offset">
- <argument index="0" name="offset" type="Vector2">
+ <argument index="0" name="offset" type="Vector3">
</argument>
<description>
</description>
</method>
<method name="set_uv2_scale">
- <argument index="0" name="scale" type="Vector2">
+ <argument index="0" name="scale" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_uv2_triplanar_blend_sharpness">
+ <argument index="0" name="sharpness" type="float">
</argument>
<description>
</description>
@@ -40863,7 +41560,7 @@
</member>
<member name="albedo_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="anisotropy_anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy" brief="">
+ <member name="anisotropy" type="float" setter="set_anisotropy" getter="get_anisotropy" brief="">
</member>
<member name="anisotropy_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40871,9 +41568,11 @@
</member>
<member name="ao_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
+ <member name="ao_on_uv2" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
<member name="ao_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="clearcoat_amount" type="float" setter="set_clearcoat" getter="get_clearcoat" brief="">
+ <member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat" brief="">
</member>
<member name="clearcoat_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40905,7 +41604,7 @@
</member>
<member name="detail_uv_layer" type="int" setter="set_detail_uv" getter="get_detail_uv" brief="">
</member>
- <member name="emission_color" type="Color" setter="set_emission" getter="get_emission" brief="">
+ <member name="emission" type="Color" setter="set_emission" getter="get_emission" brief="">
</member>
<member name="emission_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40923,7 +41622,7 @@
</member>
<member name="flags_use_point_size" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
- <member name="metallic_amount" type="float" setter="set_metallic" getter="get_metallic" brief="">
+ <member name="metallic" type="float" setter="set_metallic" getter="get_metallic" brief="">
</member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" brief="">
</member>
@@ -40945,10 +41644,16 @@
</member>
<member name="params_diffuse_mode" type="int" setter="set_diffuse_mode" getter="get_diffuse_mode" brief="">
</member>
+ <member name="params_grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled" brief="">
+ </member>
+ <member name="params_grow_amount" type="float" setter="set_grow" getter="get_grow" brief="">
+ </member>
<member name="params_line_width" type="float" setter="set_line_width" getter="get_line_width" brief="">
</member>
<member name="params_point_size" type="float" setter="set_point_size" getter="get_point_size" brief="">
</member>
+ <member name="params_specular_mode" type="int" setter="set_specular_mode" getter="get_specular_mode" brief="">
+ </member>
<member name="particles_anim_h_frames" type="int" setter="set_particles_anim_h_frames" getter="get_particles_anim_h_frames" brief="">
</member>
<member name="particles_anim_loop" type="bool" setter="set_particles_anim_loop" getter="get_particles_anim_loop" brief="">
@@ -40961,7 +41666,7 @@
</member>
<member name="refraction_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="rim_amount" type="float" setter="set_rim" getter="get_rim" brief="">
+ <member name="rim" type="float" setter="set_rim" getter="get_rim" brief="">
</member>
<member name="rim_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40969,7 +41674,7 @@
</member>
<member name="rim_tint" type="float" setter="set_rim_tint" getter="get_rim_tint" brief="">
</member>
- <member name="roughness_amount" type="float" setter="set_roughness" getter="get_roughness" brief="">
+ <member name="roughness" type="float" setter="set_roughness" getter="get_roughness" brief="">
</member>
<member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
@@ -40979,13 +41684,21 @@
</member>
<member name="subsurf_scatter_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
- <member name="uv1_offset" type="Vector2" setter="set_uv1_offset" getter="get_uv1_offset" brief="">
+ <member name="uv1_offset" type="Vector3" setter="set_uv1_offset" getter="get_uv1_offset" brief="">
</member>
- <member name="uv1_scale" type="Vector2" setter="set_uv1_scale" getter="get_uv1_scale" brief="">
+ <member name="uv1_scale" type="Vector3" setter="set_uv1_scale" getter="get_uv1_scale" brief="">
</member>
- <member name="uv2_offset" type="Vector2" setter="set_uv2_offset" getter="get_uv2_offset" brief="">
+ <member name="uv1_triplanar" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
- <member name="uv2_scale" type="Vector2" setter="set_uv2_scale" getter="get_uv2_scale" brief="">
+ <member name="uv1_triplanar_sharpness" type="float" setter="set_uv1_triplanar_blend_sharpness" getter="get_uv1_triplanar_blend_sharpness" brief="">
+ </member>
+ <member name="uv2_offset" type="Vector3" setter="set_uv2_offset" getter="get_uv2_offset" brief="">
+ </member>
+ <member name="uv2_scale" type="Vector3" setter="set_uv2_scale" getter="get_uv2_scale" brief="">
+ </member>
+ <member name="uv2_triplanar" type="bool" setter="set_flag" getter="get_flag" brief="">
+ </member>
+ <member name="uv2_triplanar_sharpness" type="float" setter="set_uv2_triplanar_blend_sharpness" getter="get_uv2_triplanar_blend_sharpness" brief="">
</member>
<member name="vertex_color_is_srgb" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
@@ -41087,7 +41800,7 @@
</constant>
<constant name="FLAG_FIXED_SIZE" value="5">
</constant>
- <constant name="FLAG_MAX" value="6">
+ <constant name="FLAG_MAX" value="9">
</constant>
<constant name="DIFFUSE_LAMBERT" value="0">
</constant>
@@ -41097,6 +41810,18 @@
</constant>
<constant name="DIFFUSE_BURLEY" value="3">
</constant>
+ <constant name="DIFFUSE_TOON" value="4">
+ </constant>
+ <constant name="SPECULAR_SCHLICK_GGX" value="0">
+ </constant>
+ <constant name="SPECULAR_BLINN" value="1">
+ </constant>
+ <constant name="SPECULAR_PHONG" value="2">
+ </constant>
+ <constant name="SPECULAR_TOON" value="3">
+ </constant>
+ <constant name="SPECULAR_DISABLED" value="4">
+ </constant>
<constant name="BILLBOARD_DISABLED" value="0">
</constant>
<constant name="BILLBOARD_ENABLED" value="1">
@@ -41107,6 +41832,46 @@
</constant>
</constants>
</class>
+<class name="SpatialVelocityTracker" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_tracked_linear_velocity" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_tracking_fixed_step" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="reset">
+ <argument index="0" name="position" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_track_fixed_step">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="update_position">
+ <argument index="0" name="position" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="SphereMesh" inherits="PrimitiveMesh" category="Core">
<brief_description>
</brief_description>
@@ -41410,6 +42175,12 @@
Return the amount of horizontal frames. See [method set_hframes].
</description>
</method>
+ <method name="get_normal_map" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_offset" qualifiers="const">
<return type="Vector2">
</return>
@@ -41466,6 +42237,12 @@
Return if the sprite reads from a region.
</description>
</method>
+ <method name="is_region_filter_clip_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_centered">
<argument index="0" name="centered" type="bool">
</argument>
@@ -41501,6 +42278,12 @@
Set the amount of horizontal frames and converts the sprite into a sprite-sheet. This is useful for animation.
</description>
</method>
+ <method name="set_normal_map">
+ <argument index="0" name="normal_map" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_offset">
<argument index="0" name="offset" type="Vector2">
</argument>
@@ -41515,6 +42298,12 @@
Set the sprite as a sub-region of a bigger texture. Useful for texture-atlases.
</description>
</method>
+ <method name="set_region_filter_clip">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_region_rect">
<argument index="0" name="rect" type="Rect2">
</argument>
@@ -41548,9 +42337,13 @@
</member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" brief="">
</member>
+ <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" brief="">
+ </member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset" brief="">
</member>
- <member name="region" type="bool" setter="set_region" getter="is_region" brief="">
+ <member name="region_enabled" type="bool" setter="set_region" getter="is_region" brief="">
+ </member>
+ <member name="region_filter_clip" type="bool" setter="set_region_filter_clip" getter="is_region_filter_clip_enabled" brief="">
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" brief="">
</member>
@@ -41656,7 +42449,7 @@
</member>
<member name="hframes" type="int" setter="set_hframes" getter="get_hframes" brief="">
</member>
- <member name="region" type="bool" setter="set_region" getter="is_region" brief="">
+ <member name="region_enabled" type="bool" setter="set_region" getter="is_region" brief="">
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" brief="">
</member>
@@ -41818,6 +42611,8 @@
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered" brief="">
</member>
+ <member name="double_sided" type="bool" setter="set_draw_flag" getter="get_draw_flag" brief="">
+ </member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h" brief="">
</member>
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v" brief="">
@@ -41840,7 +42635,9 @@
</constant>
<constant name="FLAG_SHADED" value="1">
</constant>
- <constant name="FLAG_MAX" value="2">
+ <constant name="FLAG_DOUBLE_SIDED" value="2">
+ </constant>
+ <constant name="FLAG_MAX" value="3">
</constant>
<constant name="ALPHA_CUT_DISABLED" value="0">
</constant>
@@ -43559,6 +44356,12 @@
<description>
</description>
</method>
+ <method name="get_normal_map" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_region_rect" qualifiers="const">
<return type="Rect2">
</return>
@@ -43599,6 +44402,12 @@
<description>
</description>
</method>
+ <method name="set_normal_map">
+ <argument index="0" name="normal_map" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_region_rect">
<argument index="0" name="region" type="Rect2">
</argument>
@@ -43633,6 +44442,8 @@
</member>
<member name="modulate_color" type="Color" setter="set_modulate" getter="get_modulate" brief="">
</member>
+ <member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map" brief="">
+ </member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect" brief="">
</member>
<member name="texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
@@ -44112,6 +44923,15 @@
<description>
</description>
</method>
+ <method name="get_tab_rect">
+ <return type="Rect2">
+ </return>
+ <argument index="0" name="tab_idx" type="int">
+ </argument>
+ <description>
+ Returns tab [Rect2] with local position and size.
+ </description>
+ </method>
<method name="get_tab_title" qualifiers="const">
<return type="String">
</return>
@@ -44120,6 +44940,15 @@
<description>
</description>
</method>
+ <method name="move_tab">
+ <argument index="0" name="from" type="int">
+ </argument>
+ <argument index="1" name="to" type="int">
+ </argument>
+ <description>
+ Rearrange tab.
+ </description>
+ </method>
<method name="remove_tab">
<argument index="0" name="tab_idx" type="int">
</argument>
@@ -44168,6 +44997,12 @@
</member>
</members>
<signals>
+ <signal name="reposition_active_tab_request">
+ <argument index="0" name="idx_to" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="right_button_pressed">
<argument index="0" name="tab" type="int">
</argument>
@@ -44729,6 +45564,8 @@
</argument>
<argument index="3" name="transpose" type="bool" default="false">
</argument>
+ <argument index="4" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
</description>
</method>
@@ -44743,6 +45580,8 @@
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
+ <argument index="5" name="normal_map" type="Texture" default="NULL">
+ </argument>
<description>
</description>
</method>
@@ -44757,6 +45596,10 @@
</argument>
<argument index="4" name="transpose" type="bool" default="false">
</argument>
+ <argument index="5" name="normal_map" type="Texture" default="NULL">
+ </argument>
+ <argument index="6" name="clip_uv" type="bool" default="true">
+ </argument>
<description>
</description>
</method>
@@ -46014,6 +46857,18 @@
Remove the tile referenced by the given ID.
</description>
</method>
+ <method name="tile_add_shape">
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="shape" type="Shape2D">
+ </argument>
+ <argument index="2" name="shape_transform" type="Transform2D">
+ </argument>
+ <argument index="3" name="one_way" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="tile_get_light_occluder" qualifiers="const">
<return type="OccluderPolygon2D">
</return>
@@ -46059,6 +46914,14 @@
Return the offset of the tile's navigation polygon.
</description>
</method>
+ <method name="tile_get_normal_map" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="tile_get_occluder_offset" qualifiers="const">
<return type="Vector2">
</return>
@@ -46082,17 +46945,37 @@
</return>
<argument index="0" name="id" type="int">
</argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
<description>
- Return the shape of the tile.
</description>
</method>
- <method name="tile_get_shape_offset" qualifiers="const">
- <return type="Vector2">
+ <method name="tile_get_shape_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="tile_get_shape_one_way" qualifiers="const">
+ <return type="bool">
</return>
<argument index="0" name="id" type="int">
</argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="tile_get_shape_transform" qualifiers="const">
+ <return type="Transform2D">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
<description>
- Return the shape offset of the tile.
</description>
</method>
<method name="tile_get_shapes" qualifiers="const">
@@ -46167,6 +47050,14 @@
Set an offset for the tile's navigation polygon.
</description>
</method>
+ <method name="tile_set_normal_map">
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="normal_map" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="tile_set_occluder_offset">
<argument index="0" name="id" type="int">
</argument>
@@ -46188,19 +47079,31 @@
<method name="tile_set_shape">
<argument index="0" name="id" type="int">
</argument>
- <argument index="1" name="shape" type="Shape2D">
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <argument index="2" name="shape" type="Shape2D">
</argument>
<description>
- Set a shape for the tile, enabling physics to collide with it.
</description>
</method>
- <method name="tile_set_shape_offset">
+ <method name="tile_set_shape_one_way">
<argument index="0" name="id" type="int">
</argument>
- <argument index="1" name="shape_offset" type="Vector2">
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <argument index="2" name="one_way" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="tile_set_shape_transform">
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="shape_id" type="int">
+ </argument>
+ <argument index="2" name="shape_transform" type="Transform2D">
</argument>
<description>
- Set the shape offset of the tile.
</description>
</method>
<method name="tile_set_shapes">
@@ -46846,7 +47749,7 @@
</method>
</methods>
<members>
- <member name="o" type="Vector2" setter="" getter="" brief="">
+ <member name="origin" type="Vector2" setter="" getter="" brief="">
</member>
<member name="x" type="Vector2" setter="" getter="" brief="">
</member>
@@ -47513,6 +48416,14 @@
<description>
</description>
</method>
+ <method name="get_expand_right" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_icon" qualifiers="const">
<return type="Texture">
</return>
@@ -47597,6 +48508,14 @@
<description>
</description>
</method>
+ <method name="get_text_align" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_tooltip" qualifiers="const">
<return type="String">
</return>
@@ -47645,6 +48564,12 @@
<description>
</description>
</method>
+ <method name="is_folding_disabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_selectable" qualifiers="const">
<return type="bool">
</return>
@@ -47751,6 +48676,12 @@
<description>
</description>
</method>
+ <method name="set_disable_folding">
+ <argument index="0" name="disable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_editable">
<argument index="0" name="column" type="int">
</argument>
@@ -47759,6 +48690,14 @@
<description>
</description>
</method>
+ <method name="set_expand_right">
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_icon">
<argument index="0" name="column" type="int">
</argument>
@@ -47829,6 +48768,14 @@
<description>
</description>
</method>
+ <method name="set_text_align">
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="text_align" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_tooltip">
<argument index="0" name="column" type="int">
</argument>
@@ -48511,6 +49458,10 @@ do_property].
<theme_items>
<theme_item name="grabber" type="Texture">
</theme_item>
+ <theme_item name="grabber_disabled" type="Texture">
+ </theme_item>
+ <theme_item name="grabber_disabled" type="StyleBox">
+ </theme_item>
<theme_item name="grabber_highlight" type="Texture">
</theme_item>
<theme_item name="grabber_highlight" type="StyleBox">
@@ -48761,12 +49712,6 @@ do_property].
</method>
</methods>
<members>
- <member name="height" type="float" setter="" getter="" brief="">
- Height of the vector (Same as Y).
- </member>
- <member name="width" type="float" setter="" getter="" brief="">
- Width of the vector (Same as X).
- </member>
<member name="x" type="float" setter="" getter="" brief="">
X component of the vector.
</member>
@@ -50960,6 +51905,8 @@ do_property].
</description>
</method>
<method name="get_constant_value" qualifiers="const">
+ <return type="Variant">
+ </return>
<description>
</description>
</method>
@@ -50977,9 +51924,9 @@ do_property].
</method>
</methods>
<members>
- <member name="constant/type" type="int" setter="set_constant_type" getter="get_constant_type" brief="">
+ <member name="type" type="int" setter="set_constant_type" getter="get_constant_type" brief="">
</member>
- <member name="constant/value" type="Nil" setter="set_constant_value" getter="get_constant_value" brief="">
+ <member name="value" type="Nil" setter="set_constant_value" getter="get_constant_value" brief="">
</member>
</members>
<constants>
@@ -51201,7 +52148,7 @@ do_property].
</method>
</methods>
<members>
- <member name="signal/signal" type="String" setter="set_signal" getter="get_signal" brief="">
+ <member name="signal" type="String" setter="set_signal" getter="get_signal" brief="">
</member>
</members>
<constants>
@@ -51381,27 +52328,27 @@ do_property].
</method>
</methods>
<members>
- <member name="function/argument_cache" type="Dictionary" setter="_set_argument_cache" getter="_get_argument_cache" brief="">
+ <member name="argument_cache" type="Dictionary" setter="_set_argument_cache" getter="_get_argument_cache" brief="">
</member>
- <member name="function/base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
+ <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
</member>
- <member name="function/base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="function/basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
</member>
- <member name="function/call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
</member>
- <member name="function/function" type="String" setter="set_function" getter="get_function" brief="">
+ <member name="function" type="String" setter="set_function" getter="get_function" brief="">
</member>
- <member name="function/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
+ <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
- <member name="function/singleton" type="String" setter="set_singleton" getter="get_singleton" brief="">
+ <member name="rpc_call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" brief="">
</member>
- <member name="function/use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args" brief="">
+ <member name="singleton" type="String" setter="set_singleton" getter="get_singleton" brief="">
</member>
- <member name="function/validate" type="bool" setter="set_validate" getter="get_validate" brief="">
+ <member name="use_default_args" type="int" setter="set_use_default_args" getter="get_use_default_args" brief="">
</member>
- <member name="rpc/call_mode" type="int" setter="set_rpc_call_mode" getter="get_rpc_call_mode" brief="">
+ <member name="validate" type="bool" setter="set_validate" getter="get_validate" brief="">
</member>
</members>
<constants>
@@ -51577,9 +52524,9 @@ do_property].
</method>
</methods>
<members>
- <member name="variable/name" type="String" setter="set_var_name" getter="get_var_name" brief="">
+ <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="">
</member>
- <member name="variable/type" type="int" setter="set_var_type" getter="get_var_type" brief="">
+ <member name="var_name" type="String" setter="set_var_name" getter="get_var_name" brief="">
</member>
</members>
<constants>
@@ -51617,9 +52564,9 @@ do_property].
</method>
</methods>
<members>
- <member name="variable/name" type="String" setter="set_var_name" getter="get_var_name" brief="">
+ <member name="type" type="int" setter="set_var_type" getter="get_var_type" brief="">
</member>
- <member name="variable/type" type="int" setter="set_var_type" getter="get_var_type" brief="">
+ <member name="var_name" type="String" setter="set_var_name" getter="get_var_name" brief="">
</member>
</members>
<constants>
@@ -51725,9 +52672,9 @@ do_property].
</method>
</methods>
<members>
- <member name="operator_value/type" type="int" setter="set_operator" getter="get_operator" brief="">
+ <member name="operator" type="int" setter="set_operator" getter="get_operator" brief="">
</member>
- <member name="typed_value/typed" type="int" setter="set_typed" getter="get_typed" brief="">
+ <member name="type" type="int" setter="set_typed" getter="get_typed" brief="">
</member>
</members>
<constants>
@@ -51795,6 +52742,12 @@ do_property].
<description>
</description>
</method>
+ <method name="get_index" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_property" qualifiers="const">
<return type="String">
</return>
@@ -51831,6 +52784,12 @@ do_property].
<description>
</description>
</method>
+ <method name="set_index">
+ <argument index="0" name="index" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_property">
<argument index="0" name="property" type="String">
</argument>
@@ -51839,19 +52798,21 @@ do_property].
</method>
</methods>
<members>
- <member name="property/base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
+ <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
</member>
- <member name="property/base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="property/basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
</member>
- <member name="property/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
+ <member name="index" type="String" setter="set_index" getter="get_index" brief="">
</member>
- <member name="property/property" type="String" setter="set_property" getter="get_property" brief="">
+ <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
- <member name="property/set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="property" type="String" setter="set_property" getter="get_property" brief="">
</member>
- <member name="property/type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
+ <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ </member>
+ <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
</member>
</members>
<constants>
@@ -51869,6 +52830,12 @@ do_property].
<description>
</description>
<methods>
+ <method name="get_assign_op" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_base_path" qualifiers="const">
<return type="NodePath">
</return>
@@ -51899,12 +52866,24 @@ do_property].
<description>
</description>
</method>
+ <method name="get_index" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_property" qualifiers="const">
<return type="String">
</return>
<description>
</description>
</method>
+ <method name="set_assign_op">
+ <argument index="0" name="assign_op" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_base_path">
<argument index="0" name="base_path" type="NodePath">
</argument>
@@ -51935,6 +52914,12 @@ do_property].
<description>
</description>
</method>
+ <method name="set_index">
+ <argument index="0" name="index" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_property">
<argument index="0" name="property" type="String">
</argument>
@@ -51943,19 +52928,23 @@ do_property].
</method>
</methods>
<members>
- <member name="property/base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
+ <member name="assign_op" type="int" setter="set_assign_op" getter="get_assign_op" brief="">
</member>
- <member name="property/base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
</member>
- <member name="property/basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
+ <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ </member>
+ <member name="basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
</member>
- <member name="property/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
+ <member name="index" type="String" setter="set_index" getter="get_index" brief="">
</member>
- <member name="property/property" type="String" setter="set_property" getter="get_property" brief="">
+ <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
- <member name="property/set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="property" type="String" setter="set_property" getter="get_property" brief="">
</member>
- <member name="property/type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
+ <member name="set_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ </member>
+ <member name="type_cache" type="int" setter="_set_type_cache" getter="_get_type_cache" brief="">
</member>
</members>
<constants>
@@ -52025,9 +53014,9 @@ do_property].
</method>
</methods>
<members>
- <member name="return_value/enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled" brief="">
+ <member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled" brief="">
</member>
- <member name="return_value/type" type="int" setter="set_return_type" getter="get_return_type" brief="">
+ <member name="return_type" type="int" setter="set_return_type" getter="get_return_type" brief="">
</member>
</members>
<constants>
@@ -52069,6 +53058,32 @@ do_property].
<constants>
</constants>
</class>
+<class name="VisualScriptSelect" inherits="VisualScriptNode" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_typed" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_typed">
+ <argument index="0" name="type" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="type" type="int" setter="set_typed" getter="get_typed" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="VisualScriptSelf" inherits="VisualScriptNode" category="Core">
<brief_description>
</brief_description>
@@ -52163,9 +53178,9 @@ do_property].
</method>
</methods>
<members>
- <member name="function/base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ <member name="base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
</member>
- <member name="property/base_script" type="String" setter="set_base_script" getter="get_base_script" brief="">
+ <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
</members>
<constants>
@@ -52191,7 +53206,7 @@ do_property].
</method>
</methods>
<members>
- <member name="variable/name" type="String" setter="set_variable" getter="get_variable" brief="">
+ <member name="var_name" type="String" setter="set_variable" getter="get_variable" brief="">
</member>
</members>
<constants>
@@ -52217,7 +53232,7 @@ do_property].
</method>
</methods>
<members>
- <member name="variable/name" type="String" setter="set_variable" getter="get_variable" brief="">
+ <member name="var_name" type="String" setter="set_variable" getter="get_variable" brief="">
</member>
</members>
<constants>
@@ -52335,13 +53350,13 @@ do_property].
</method>
</methods>
<members>
- <member name="signal/base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
+ <member name="base_type" type="String" setter="set_base_type" getter="get_base_type" brief="">
</member>
- <member name="signal/call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
+ <member name="call_mode" type="int" setter="set_call_mode" getter="get_call_mode" brief="">
</member>
- <member name="signal/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
+ <member name="node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
- <member name="signal/signal" type="String" setter="set_signal" getter="get_signal" brief="">
+ <member name="signal" type="String" setter="set_signal" getter="get_signal" brief="">
</member>
</members>
<constants>
@@ -52592,13 +53607,6 @@ do_property].
Retrieve the state of this world's physics space. This allows arbitrary querying for collision.
</description>
</method>
- <method name="get_sound_space">
- <return type="RID">
- </return>
- <description>
- Retrieve the [RID] of this world's sound space resource. Used by the [SpatialSound2DServer] for 2D spatial audio.
- </description>
- </method>
<method name="get_space">
<return type="RID">
</return>
@@ -52610,7 +53618,7 @@ do_property].
<constants>
</constants>
</class>
-<class name="WorldEnvironment" inherits="Spatial" category="Core">
+<class name="WorldEnvironment" inherits="Node" category="Core">
<brief_description>
Sets environment properties for the entire scene
</brief_description>
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 25c0f8925d..e854abb6a1 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -3941,7 +3941,7 @@ void RasterizerGLES2::begin_frame() {
//fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
#ifdef TOOLS_ENABLED
- canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false));
+ canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/use_2d_pixel_snap", false));
shadow_filter = ShadowFilterTechnique(int(GlobalConfig::get_singleton()->get("rasterizer/shadow_filter")));
#endif
@@ -10386,7 +10386,7 @@ void RasterizerGLES2::init() {
copy_shader.set_conditional(CopyShaderGLES2::USE_8BIT_HDR, !use_fp16_fb);
canvas_shader.set_conditional(CanvasShaderGLES2::USE_DEPTH_SHADOWS, read_depth_supported);
- canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("display/use_2d_pixel_snap", false));
+ canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP, GLOBAL_DEF("rendering/use_2d_pixel_snap", false));
npo2_textures_available = true;
//fragment_lighting=false;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 268d6b44c6..98e55c5a53 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -1658,7 +1658,7 @@ void RasterizerCanvasGLES3::initialize() {
}
{
- uint32_t poly_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_buffer_size_kb", 128);
+ uint32_t poly_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_buffer_size_kb", 128);
poly_size *= 1024; //kb
poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
glGenBuffers(1, &data.polygon_buffer);
@@ -1704,7 +1704,7 @@ void RasterizerCanvasGLES3::initialize() {
glGenVertexArrays(1, &data.polygon_buffer_pointer_array);
- uint32_t index_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_index_buffer_size_kb", 128);
+ uint32_t index_size = GLOBAL_DEF("rendering/limits/buffers/canvas_polygon_index_buffer_size_kb", 128);
index_size *= 1024; //kb
glGenBuffers(1, &data.polygon_index_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index 0cfa8a7d6e..233095dec2 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -400,10 +400,8 @@ void RasterizerGLES3::make_current() {
void RasterizerGLES3::register_config() {
- GLOBAL_DEF("rendering/gles3/render_architecture", 0);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/gles3/render_architecture", PropertyInfo(Variant::INT, "", PROPERTY_HINT_ENUM, "Desktop,Mobile"));
- GLOBAL_DEF("rendering/quality/use_nearest_mipmap_filter", false);
- GLOBAL_DEF("rendering/quality/anisotropic_filter_level", 4.0);
+ GLOBAL_DEF("rendering/quality/filters/use_nearest_mipmap_filter", false);
+ GLOBAL_DEF("rendering/quality/filters/anisotropic_filter_level", 4.0);
}
RasterizerGLES3::RasterizerGLES3() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index e8c6502bf4..b7547f53a8 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -761,7 +761,7 @@ bool RasterizerSceneGLES3::reflection_probe_instance_postprocess_step(RID p_inst
storage->shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::LOW_QUALITY, rpi->probe_ptr->update_mode == VS::REFLECTION_PROBE_UPDATE_ALWAYS);
for (int i = 0; i < 2; i++) {
- storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i > 0);
+ storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::Z_FLIP, i == 0);
storage->shaders.cubemap_filter.set_uniform(CubemapFilterShaderGLES3::ROUGHNESS, rpi->render_step / 5.0);
uint32_t local_width = width, local_height = height;
@@ -1834,12 +1834,14 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
+ float bias_scale = e->instance->baked_light ? 1 : 0;
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER1, gipi->probe ? gipi->probe->dynamic_range * gipi->probe->energy : 0.0);
- state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS1, gipi->probe ? gipi->probe->bias : 0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS1, gipi->probe ? gipi->probe->bias * bias_scale : 0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_NORMAL_BIAS1, gipi->probe ? gipi->probe->normal_bias * bias_scale : 0.0);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT1, gipi->probe ? !gipi->probe->interior : false);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE1, gipi->cell_size_cache);
if (gi_probe_count > 1) {
@@ -1852,7 +1854,8 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_CELL_SIZE2, gipi2->cell_size_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_MULTIPLIER2, gipi2->probe ? gipi2->probe->dynamic_range * gipi2->probe->energy : 0.0);
- state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS2, gipi2->probe ? gipi2->probe->bias : 0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BIAS2, gipi2->probe ? gipi2->probe->bias * bias_scale : 0.0);
+ state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_NORMAL_BIAS2, gipi2->probe ? gipi2->probe->normal_bias * bias_scale : 0.0);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BLEND_AMBIENT2, gipi2->probe ? !gipi2->probe->interior : false);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE2_ENABLED, true);
} else {
@@ -2889,7 +2892,7 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul
reflection_ubo.atlas_clamp[0] = float(x) / reflection_atlas->size;
reflection_ubo.atlas_clamp[1] = float(y) / reflection_atlas->size;
reflection_ubo.atlas_clamp[2] = float(width) / reflection_atlas->size;
- reflection_ubo.atlas_clamp[3] = float(height / 2) / reflection_atlas->size;
+ reflection_ubo.atlas_clamp[3] = float(height) / reflection_atlas->size;
Transform proj = (p_camera_inverse_transform * rpi->transform).inverse();
store_transform(proj, reflection_ubo.local_matrix);
@@ -4156,7 +4159,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glDrawBuffers(1, &gldb);
}
- if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+ if (env && env->bg_mode == VS::ENV_BG_SKY && (!storage->frame.current_rt || (!storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW))) {
/*
if (use_mrt) {
@@ -4175,7 +4178,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_render_mrts(env, p_cam_projection);
} else {
//FIXME: check that this is possible to use
- if (state.used_screen_texture) {
+ if (storage->frame.current_rt && state.used_screen_texture) {
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
@@ -4189,7 +4192,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
}
}
- if (state.used_screen_texture) {
+ if (storage->frame.current_rt && state.used_screen_texture) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
}
@@ -4199,7 +4202,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glEnable(GL_DEPTH_TEST);
glDisable(GL_SCISSOR_TEST);
- render_list.sort_by_depth(true);
+ render_list.sort_by_reverse_depth(true);
if (state.directional_light_count == 0) {
directional_light = NULL;
@@ -4635,7 +4638,7 @@ void RasterizerSceneGLES3::initialize() {
glBufferData(GL_UNIFORM_BUFFER, sizeof(State::EnvironmentRadianceUBO), &state.env_radiance_ubo, GL_DYNAMIC_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
- render_list.max_elements = GLOBAL_DEF("rendering/gles3/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS);
+ render_list.max_elements = GLOBAL_DEF("rendering/limits/rendering/max_renderable_elements", (int)RenderList::DEFAULT_MAX_ELEMENTS);
if (render_list.max_elements > 1000000)
render_list.max_elements = 1000000;
if (render_list.max_elements < 1024)
@@ -4709,7 +4712,7 @@ void RasterizerSceneGLES3::initialize() {
{
//directional light shadow
directional_shadow.light_count = 0;
- directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 4096));
+ directional_shadow.size = nearest_power_of_2(GLOBAL_GET("rendering/quality/directional_shadow/size"));
glGenFramebuffers(1, &directional_shadow.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
glGenTextures(1, &directional_shadow.depth);
@@ -4776,8 +4779,8 @@ void RasterizerSceneGLES3::initialize() {
state.scene_shader.add_custom_define("#define MAX_SKELETON_BONES " + itos(state.max_skeleton_bones) + "\n");
}
- GLOBAL_DEF("rendering/gles3/shadow_filter_mode", 1);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/gles3/shadow_filter_mode", PropertyInfo(Variant::INT, "rendering/gles3/shadow_filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
+ GLOBAL_DEF("rendering/quality/shadows/filter_mode", 1);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadows/filter_mode", PropertyInfo(Variant::INT, "rendering/quality/shadows/filter_mode", PROPERTY_HINT_ENUM, "Disabled,PCF5,PCF13"));
shadow_filter_mode = SHADOW_FILTER_NEAREST;
{ //reflection cubemaps
@@ -4841,7 +4844,7 @@ void RasterizerSceneGLES3::initialize() {
{
- uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/buffers/immediate_buffer_size_kb", 2048);
+ uint32_t immediate_buffer_size = GLOBAL_DEF("rendering/limits/buffers/immediate_buffer_size_kb", 2048);
glGenBuffers(1, &state.immediate_buffer);
glBindBuffer(GL_ARRAY_BUFFER, state.immediate_buffer);
@@ -4868,13 +4871,13 @@ void RasterizerSceneGLES3::initialize() {
state.tonemap_shader.init();
{
- GLOBAL_DEF("rendering/ssurf_scattering/quality", 1);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/ssurf_scattering/quality", PropertyInfo(Variant::INT, "rendering/ssurf_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High"));
- GLOBAL_DEF("rendering/ssurf_scattering/max_size", 1.0);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/ssurf_scattering/max_size", PropertyInfo(Variant::INT, "rendering/ssurf_scattering/max_size", PROPERTY_HINT_RANGE, "0.01,8,0.01"));
- GLOBAL_DEF("rendering/ssurf_scattering/follow_surface", false);
+ GLOBAL_DEF("rendering/quality/subsurface_scattering/quality", 1);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/quality", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/quality", PROPERTY_HINT_ENUM, "Low,Medium,High"));
+ GLOBAL_DEF("rendering/quality/subsurface_scattering/scale", 1.0);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/subsurface_scattering/scale", PropertyInfo(Variant::INT, "rendering/quality/subsurface_scattering/scale", PROPERTY_HINT_RANGE, "0.01,8,0.01"));
+ GLOBAL_DEF("rendering/quality/subsurface_scattering/follow_surface", false);
- GLOBAL_DEF("rendering/reflections/high_quality_vct_gi", true);
+ GLOBAL_DEF("rendering/quality/voxel_cone_tracing/high_quality", true);
}
exposure_shrink_size = 243;
@@ -4913,12 +4916,12 @@ void RasterizerSceneGLES3::initialize() {
void RasterizerSceneGLES3::iteration() {
- shadow_filter_mode = ShadowFilterMode(int(GlobalConfig::get_singleton()->get("rendering/gles3/shadow_filter_mode")));
- subsurface_scatter_follow_surface = GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/follow_surface");
- subsurface_scatter_quality = SubSurfaceScatterQuality(int(GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/quality")));
- subsurface_scatter_size = GlobalConfig::get_singleton()->get("rendering/ssurf_scattering/max_size");
+ shadow_filter_mode = ShadowFilterMode(int(GlobalConfig::get_singleton()->get("rendering/quality/shadows/filter_mode")));
+ subsurface_scatter_follow_surface = GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/follow_surface");
+ subsurface_scatter_quality = SubSurfaceScatterQuality(int(GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/quality")));
+ subsurface_scatter_size = GlobalConfig::get_singleton()->get("rendering/quality/subsurface_scattering/scale");
- state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GlobalConfig::get_singleton()->get("rendering/reflections/high_quality_vct_gi"));
+ state.scene_shader.set_conditional(SceneShaderGLES3::VCT_QUALITY_HIGH, GlobalConfig::get_singleton()->get("rendering/quality/voxel_cone_tracing/high_quality"));
}
void RasterizerSceneGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 37bbd60797..a03e3dbe3d 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -666,7 +666,7 @@ public:
uint64_t sort_key;
};
- Element *_elements;
+ Element *base_elements;
Element **elements;
int element_count;
@@ -700,11 +700,11 @@ public:
struct SortByDepth {
_FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
- return A->instance->depth > B->instance->depth;
+ return A->instance->depth < B->instance->depth;
}
};
- void sort_by_depth(bool p_alpha) {
+ void sort_by_depth(bool p_alpha) { //used for shadows
SortArray<Element *, SortByDepth> sorter;
if (p_alpha) {
@@ -714,11 +714,28 @@ public:
}
}
+ struct SortByReverseDepth {
+
+ _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
+ return A->instance->depth > B->instance->depth;
+ }
+ };
+
+ void sort_by_reverse_depth(bool p_alpha) { //used for alpha
+
+ SortArray<Element *, SortByReverseDepth> sorter;
+ if (p_alpha) {
+ sorter.sort(&elements[max_elements - alpha_element_count], alpha_element_count);
+ } else {
+ sorter.sort(elements, element_count);
+ }
+ }
+
_FORCE_INLINE_ Element *add_element() {
if (element_count + alpha_element_count >= max_elements)
return NULL;
- elements[element_count] = &_elements[element_count];
+ elements[element_count] = &base_elements[element_count];
return elements[element_count++];
}
@@ -727,7 +744,7 @@ public:
if (element_count + alpha_element_count >= max_elements)
return NULL;
int idx = max_elements - alpha_element_count - 1;
- elements[idx] = &_elements[idx];
+ elements[idx] = &base_elements[idx];
alpha_element_count++;
return elements[idx];
}
@@ -737,9 +754,9 @@ public:
element_count = 0;
alpha_element_count = 0;
elements = memnew_arr(Element *, max_elements);
- _elements = memnew_arr(Element, max_elements);
+ base_elements = memnew_arr(Element, max_elements);
for (int i = 0; i < max_elements; i++)
- elements[i] = &_elements[i]; // assign elements
+ elements[i] = &base_elements[i]; // assign elements
}
RenderList() {
@@ -749,7 +766,7 @@ public:
~RenderList() {
memdelete_arr(elements);
- memdelete_arr(_elements);
+ memdelete_arr(base_elements);
}
};
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 14fb36f3b0..981426f4dc 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -4866,6 +4866,7 @@ RID RasterizerStorageGLES3::gi_probe_create() {
gip->energy = 1.0;
gip->propagation = 1.0;
gip->bias = 0.4;
+ gip->normal_bias = 0.4;
gip->interior = false;
gip->compress = false;
gip->version = 1;
@@ -4972,6 +4973,14 @@ void RasterizerStorageGLES3::gi_probe_set_bias(RID p_probe, float p_range) {
gip->bias = p_range;
}
+void RasterizerStorageGLES3::gi_probe_set_normal_bias(RID p_probe, float p_range) {
+
+ GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND(!gip);
+
+ gip->normal_bias = p_range;
+}
+
void RasterizerStorageGLES3::gi_probe_set_propagation(RID p_probe, float p_range) {
GIProbe *gip = gi_probe_owner.getornull(p_probe);
@@ -5027,6 +5036,14 @@ float RasterizerStorageGLES3::gi_probe_get_bias(RID p_probe) const {
return gip->bias;
}
+float RasterizerStorageGLES3::gi_probe_get_normal_bias(RID p_probe) const {
+
+ const GIProbe *gip = gi_probe_owner.getornull(p_probe);
+ ERR_FAIL_COND_V(!gip, 0);
+
+ return gip->normal_bias;
+}
+
float RasterizerStorageGLES3::gi_probe_get_propagation(RID p_probe) const {
const GIProbe *gip = gi_probe_owner.getornull(p_probe);
@@ -6831,8 +6848,8 @@ void RasterizerStorageGLES3::initialize() {
}
config.shrink_textures_x2 = false;
- config.use_fast_texture_filter = int(GlobalConfig::get_singleton()->get("rendering/quality/use_nearest_mipmap_filter"));
- config.use_anisotropic_filter = config.extensions.has("GL_EXT_texture_filter_anisotropic");
+ config.use_fast_texture_filter = int(GlobalConfig::get_singleton()->get("rendering/quality/filters/use_nearest_mipmap_filter"));
+ config.use_anisotropic_filter = config.extensions.has("rendering/quality/filters/anisotropic_filter_level");
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
config.etc_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture");
@@ -6966,7 +6983,7 @@ void RasterizerStorageGLES3::initialize() {
{
//transform feedback buffers
- uint32_t xf_feedback_size = GLOBAL_DEF("rendering/buffers/blend_shape_max_buffer_size_kb", 4096);
+ uint32_t xf_feedback_size = GLOBAL_DEF("rendering/limits/buffers/blend_shape_max_buffer_size_kb", 4096);
for (int i = 0; i < 2; i++) {
glGenBuffers(1, &resources.transform_feedback_buffers[i]);
@@ -6992,7 +7009,7 @@ void RasterizerStorageGLES3::initialize() {
frame.current_rt = NULL;
config.keep_original_textures = false;
config.generate_wireframes = false;
- config.use_texture_array_environment = GLOBAL_DEF("rendering/quality/texture_array_environments", true);
+ config.use_texture_array_environment = GLOBAL_DEF("rendering/quality/reflections/texture_array_reflections", true);
}
void RasterizerStorageGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 183db534ac..b24da44afd 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -972,6 +972,7 @@ public:
int dynamic_range;
float energy;
float bias;
+ float normal_bias;
float propagation;
bool interior;
bool compress;
@@ -1006,6 +1007,9 @@ public:
virtual void gi_probe_set_bias(RID p_probe, float p_range);
virtual float gi_probe_get_bias(RID p_probe) const;
+ virtual void gi_probe_set_normal_bias(RID p_probe, float p_range);
+ virtual float gi_probe_get_normal_bias(RID p_probe) const;
+
virtual void gi_probe_set_propagation(RID p_probe, float p_range);
virtual float gi_probe_get_propagation(RID p_probe) const;
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 393ef2892a..ac4e47a440 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -247,6 +247,7 @@ void main() {
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+ N.y=-N.y;
frag_color=vec4(texture(N,source_cube).rgb,1.0);
#endif
@@ -277,6 +278,7 @@ void main() {
#endif
#if !defined(USE_SOURCE_DUAL_PARABOLOID_ARRAY) && !defined(USE_SOURCE_PANORAMA)
+ H.y=-H.y;
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
#endif
sum.a += ndotl;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 6fbfeeff6c..9d474d3902 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -1093,27 +1093,19 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
}
-
- vec3 splane=normalize(local_ref_vec);
vec4 clamp_rect=reflections[idx].atlas_clamp;
-
- splane.z*=-1.0;
- if (splane.z>=0.0) {
- splane.z+=1.0;
- clamp_rect.y+=clamp_rect.w;
- } else {
- splane.z=1.0 - splane.z;
- splane.y=-splane.y;
+ vec3 norm = normalize(local_ref_vec);
+ norm.xy/=1.0+abs(norm.z);
+ norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25);
+ if (norm.z>0) {
+ norm.y=0.5-norm.y+0.5;
}
- splane.xy/=splane.z;
- splane.xy=splane.xy * 0.5 + 0.5;
-
- splane.xy = splane.xy * clamp_rect.zw + clamp_rect.xy;
- splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
+ vec2 atlas_uv = norm.xy * clamp_rect.zw + clamp_rect.xy;
+ atlas_uv = clamp(atlas_uv,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
highp vec4 reflection;
- reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb;
+ reflection.rgb = textureLod(reflection_atlas,atlas_uv,roughness*5.0).rgb;
if (reflections[idx].params.z < 0.5) {
reflection.rgb = mix(skybox,reflection.rgb,blend);
@@ -1180,6 +1172,7 @@ uniform highp vec3 gi_probe_bounds1;
uniform highp vec3 gi_probe_cell_size1;
uniform highp float gi_probe_multiplier1;
uniform highp float gi_probe_bias1;
+uniform highp float gi_probe_normal_bias1;
uniform bool gi_probe_blend_ambient1;
uniform mediump sampler3D gi_probe2; //texunit:-10
@@ -1188,12 +1181,12 @@ uniform highp vec3 gi_probe_bounds2;
uniform highp vec3 gi_probe_cell_size2;
uniform highp float gi_probe_multiplier2;
uniform highp float gi_probe_bias2;
+uniform highp float gi_probe_normal_bias2;
uniform bool gi_probe2_enabled;
uniform bool gi_probe_blend_ambient2;
vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, bool blend_ambient, vec3 direction, float tan_half_angle, float max_distance, float p_bias) {
-
float dist = p_bias;//1.0; //dot(direction,mix(vec3(-1.0),vec3(1.0),greaterThan(direction,vec3(0.0))))*2.0;
float alpha=0.0;
vec3 color = vec3(0.0);
@@ -1214,27 +1207,30 @@ vec3 voxel_cone_trace(sampler3D probe, vec3 cell_size, vec3 pos, vec3 ambient, b
return color;
}
-void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias, out vec4 out_spec, out vec4 out_diff) {
+void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_size,vec3 pos, vec3 ambient, vec3 environment, bool blend_ambient,float multiplier, mat3 normal_mtx,vec3 ref_vec, float roughness,float p_bias,float p_normal_bias, inout vec4 out_spec, inout vec4 out_diff) {
vec3 probe_pos = (probe_xform * vec4(pos,1.0)).xyz;
vec3 ref_pos = (probe_xform * vec4(pos+ref_vec,1.0)).xyz;
-
ref_vec = normalize(ref_pos - probe_pos);
+ probe_pos+=(probe_xform * vec4(normal_mtx[2],0.0)).xyz*p_normal_bias;
+
/* out_diff.rgb = voxel_cone_trace(probe,cell_size,probe_pos,normalize((probe_xform * vec4(ref_vec,0.0)).xyz),0.0 ,100.0);
out_diff.a = 1.0;
return;*/
//out_diff = vec4(textureLod(probe,probe_pos*cell_size,3.0).rgb,1.0);
//return;
- if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds)))))
+ //this causes corrupted pixels, i have no idea why..
+ if (any(bvec2(any(lessThan(probe_pos,vec3(0.0))),any(greaterThan(probe_pos,bounds))))) {
return;
+ }
- vec3 blendv = probe_pos/bounds * 2.0 - 1.0;
- float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z));
- blend=1.0;
+ //vec3 blendv = probe_pos/bounds * 2.0 - 1.0;
+ //float blend = 1.001-max(blendv.x,max(blendv.y,blendv.z));
+ float blend=1.0;
float max_distance = length(bounds);
@@ -1281,7 +1277,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
light*=multiplier;
- out_diff = vec4(light*blend,blend);
+ out_diff += vec4(light*blend,blend);
//irradiance
@@ -1290,7 +1286,8 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
irr_light *= multiplier;
//irr_light=vec3(0.0);
- out_spec = vec4(irr_light*blend,blend);
+ out_spec += vec4(irr_light*blend,blend);
+
}
@@ -1316,11 +1313,11 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_sp
out_specular = vec3(0.0);
- gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,spec_accum,diff_accum);
+ gi_probe_compute(gi_probe1,gi_probe_xform1,gi_probe_bounds1,gi_probe_cell_size1,pos,ambient,environment,gi_probe_blend_ambient1,gi_probe_multiplier1,normal_mat,ref_vec,roughness,gi_probe_bias1,gi_probe_normal_bias1,spec_accum,diff_accum);
if (gi_probe2_enabled) {
- gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,spec_accum,diff_accum);
+ gi_probe_compute(gi_probe2,gi_probe_xform2,gi_probe_bounds2,gi_probe_cell_size2,pos,ambient,environment,gi_probe_blend_ambient2,gi_probe_multiplier2,normal_mat,ref_vec,roughness,gi_probe_bias2,gi_probe_normal_bias2,spec_accum,diff_accum);
}
if (diff_accum.a>0.0) {
@@ -1466,6 +1463,7 @@ FRAGMENT_SHADER_CODE
vec3 specular_light = vec3(0.0,0.0,0.0);
vec3 ambient_light;
vec3 diffuse_light = vec3(0.0,0.0,0.0);
+ vec3 env_reflection_light = vec3(0.0,0.0,0.0);
vec3 eye_vec = -normalize( vertex_interp );
@@ -1483,7 +1481,7 @@ FRAGMENT_SHADER_CODE
vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
vec3 radiance = textureDualParaboloid(radiance_map,ref_vec,roughness) * bg_energy;
- specular_light = radiance;
+ env_reflection_light = radiance;
}
//no longer a cubemap
@@ -1662,7 +1660,7 @@ FRAGMENT_SHADER_CODE
#endif //#USE_LIGHT_DIRECTIONAL
#ifdef USE_GI_PROBES
- gi_probes_compute(vertex,normal,roughness,specular_light,ambient_light);
+ gi_probes_compute(vertex,normal,roughness,env_reflection_light,ambient_light);
#endif
@@ -1673,12 +1671,15 @@ FRAGMENT_SHADER_CODE
highp vec4 ambient_accum = vec4(0.0,0.0,0.0,0.0);
for(int i=0;i<reflection_count;i++) {
- reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum);
+ reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,env_reflection_light,reflection_accum,ambient_accum);
}
if (reflection_accum.a>0.0) {
specular_light+=reflection_accum.rgb/reflection_accum.a;
+ } else {
+ specular_light+=env_reflection_light;
}
+
if (ambient_accum.a>0.0) {
ambient_light+=ambient_accum.rgb/ambient_accum.a;
}
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 75f40cacca..2f88296ea4 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -50,7 +50,7 @@
#include <mach-o/dyld.h>
#endif
-#ifdef __FreeBSD__
+#if defined(__FreeBSD__) || defined(__OpenBSD__)
#include <sys/param.h>
#endif
#include "global_config.h"
@@ -494,7 +494,7 @@ String OS_Unix::get_data_dir() const {
if (has_environment("HOME")) {
- bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir");
+ bool use_godot = GlobalConfig::get_singleton()->get("application/config/use_shared_user_dir");
if (use_godot)
return get_environment("HOME") + "/.godot/app_userdata/" + an;
else
@@ -532,7 +532,7 @@ String OS_Unix::get_executable_path() const {
return OS::get_executable_path();
}
return b;
-#elif defined(__FreeBSD__)
+#elif defined(__FreeBSD__) || defined(__OpenBSD__)
char resolved_path[MAXPATHLEN];
realpath(OS::get_executable_path().utf8().get_data(), resolved_path);
diff --git a/editor/SCsub b/editor/SCsub
index f0d378c097..fd56c9d772 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -268,6 +268,8 @@ def make_license_header(target, source, env):
tp_license = ""
tp_current = 0
+ tp_licensetext.append([tp_licensename, tp_licensebody])
+
about_thirdparty = ""
about_tp_copyright_count = ""
about_tp_license = ""
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp
index 1798e66e8a..45da365695 100644
--- a/editor/animation_editor.cpp
+++ b/editor/animation_editor.cpp
@@ -3774,6 +3774,7 @@ AnimationKeyEditor::AnimationKeyEditor() {
zoom->set_max(2.0);
zoom->set_value(1.0);
zoom->set_h_size_flags(SIZE_EXPAND_FILL);
+ zoom->set_v_size_flags(SIZE_EXPAND_FILL);
zoom->set_stretch_ratio(2);
hb->add_child(zoom);
zoom->connect("value_changed", this, "_scroll_changed");
diff --git a/editor/asset_library_editor_plugin.cpp b/editor/asset_library_editor_plugin.cpp
index fcb92e13b4..27d468bc25 100644
--- a/editor/asset_library_editor_plugin.cpp
+++ b/editor/asset_library_editor_plugin.cpp
@@ -98,10 +98,10 @@ EditorAssetLibraryItem::EditorAssetLibraryItem() {
Ref<StyleBoxEmpty> border;
border.instance();
- /*border->set_default_margin(MARGIN_LEFT,5);
- border->set_default_margin(MARGIN_RIGHT,5);
- border->set_default_margin(MARGIN_BOTTOM,5);
- border->set_default_margin(MARGIN_TOP,5);*/
+ border->set_default_margin(MARGIN_LEFT, 5);
+ border->set_default_margin(MARGIN_RIGHT, 5);
+ border->set_default_margin(MARGIN_BOTTOM, 5);
+ border->set_default_margin(MARGIN_TOP, 5);
add_style_override("panel", border);
HBoxContainer *hb = memnew(HBoxContainer);
@@ -1261,15 +1261,6 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
templates_only = p_templates_only;
- Ref<StyleBoxEmpty> border;
- border.instance();
- border->set_default_margin(MARGIN_LEFT, 15);
- border->set_default_margin(MARGIN_RIGHT, 15);
- border->set_default_margin(MARGIN_BOTTOM, 5);
- border->set_default_margin(MARGIN_TOP, 5);
-
- add_style_override("panel", border);
-
VBoxContainer *library_main = memnew(VBoxContainer);
add_child(library_main);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 450bc5b626..79c7aa044c 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -163,7 +163,7 @@ void EditorNode::_update_scene_tabs() {
void EditorNode::_update_title() {
- String appname = GlobalConfig::get_singleton()->get("application/name");
+ String appname = GlobalConfig::get_singleton()->get("application/config/name");
String title = appname.empty() ? String(VERSION_FULL_NAME) : String(_MKSTR(VERSION_NAME) + String(" - ") + appname);
String edited = editor_data.get_edited_scene_root() ? editor_data.get_edited_scene_root()->get_filename() : String();
if (!edited.empty())
@@ -272,7 +272,7 @@ void EditorNode::_notification(int p_what) {
}
editor_selection->update();
- scene_root->set_size_override(true, Size2(GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height")));
+ scene_root->set_size_override(true, Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height")));
ResourceImporterTexture::get_singleton()->update_imports();
}
@@ -341,7 +341,7 @@ void EditorNode::_notification(int p_what) {
gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
- bottom_panel->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) {
@@ -1132,7 +1132,7 @@ void EditorNode::_dialog_action(String p_file) {
} break;
case SETTINGS_PICK_MAIN_SCENE: {
- GlobalConfig::get_singleton()->set("application/main_scene", p_file);
+ GlobalConfig::get_singleton()->set("application/run/main_scene", p_file);
GlobalConfig::get_singleton()->save();
//would be nice to show the project manager opened with the highlighted field..
_run(false, ""); // automatically run the project
@@ -1633,7 +1633,7 @@ void EditorNode::_edit_current() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("property_editor/make_subresources_unique", TTR("Make Sub-Resources Unique")), OBJECT_UNIQUE_RESOURCES);
p->add_separator();
- p->add_icon_shortcut(gui_base->get_icon("Help", "EditorIcons"), ED_SHORTCUT("property_editor/open_help", TTR("Open in Help")), OBJECT_REQUEST_HELP);
+ p->add_icon_shortcut(gui_base->get_icon("HelpSearch", "EditorIcons"), ED_SHORTCUT("property_editor/open_help", TTR("Open in Help")), OBJECT_REQUEST_HELP);
}
List<MethodInfo> methods;
@@ -1736,7 +1736,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
if (run_filename == "") {
//evidently, run the scene
- main_scene = GLOBAL_DEF("application/main_scene", "");
+ main_scene = GLOBAL_DEF("application/run/main_scene", "");
if (main_scene == "") {
current_option = -1;
@@ -2923,7 +2923,6 @@ void EditorNode::remove_editor_plugin(EditorPlugin *p_editor) {
}
}
- //singleton->main_editor_tabs->add_tab(p_editor->get_name());
singleton->editor_table.erase(p_editor);
}
p_editor->make_visible(false);
@@ -3599,15 +3598,6 @@ void EditorNode::_open_recent_scene(int p_idx) {
ERR_FAIL_INDEX(p_idx, rc.size());
String path = "res://" + rc[p_idx];
-
- /*if (unsaved_cache) {
- _recent_scene=rc[p_idx];
- open_recent_confirmation->set_text("Discard current scene and open:\n'"+rc[p_idx]+"'");
- open_recent_confirmation->get_label()->set_align(Label::ALIGN_CENTER);
- open_recent_confirmation->popup_centered(Size2(400,100));
- return;
- }*/
-
load_scene(path);
}
@@ -5162,10 +5152,6 @@ EditorNode::EditorNode() {
import_wav.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_wav);
- Ref<ResourceImporterOBJ> import_obj;
- import_obj.instance();
- ResourceFormatImporter::get_singleton()->add_importer(import_obj);
-
Ref<ResourceImporterScene> import_scene;
import_scene.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_scene);
@@ -5174,6 +5160,10 @@ EditorNode::EditorNode() {
Ref<EditorSceneImporterCollada> import_collada;
import_collada.instance();
import_scene->add_importer(import_collada);
+
+ Ref<EditorOBJImporter> import_obj;
+ import_obj.instance();
+ import_scene->add_importer(import_obj);
}
}
@@ -5233,28 +5223,9 @@ EditorNode::EditorNode() {
main_vbox->set_area_as_parent_rect(8);
main_vbox->set_margin(MARGIN_TOP, 5);
-#if 0
- PanelContainer *top_dark_panel = memnew( PanelContainer );
- Ref<StyleBoxTexture> top_dark_sb;
- top_dark_sb.instance();
- top_dark_sb->set_texture(theme->get_icon("PanelTop","EditorIcons"));
- for(int i=0;i<4;i++) {
- top_dark_sb->set_margin_size(Margin(i),3);
- top_dark_sb->set_default_margin(Margin(i),0);
- }
- top_dark_sb->set_expand_margin_size(MARGIN_LEFT,20);
- top_dark_sb->set_expand_margin_size(MARGIN_RIGHT,20);
-
- top_dark_panel->add_style_override("panel",top_dark_sb);
- VBoxContainer *top_dark_vb = memnew( VBoxContainer );
- main_vbox->add_child(top_dark_panel);
- top_dark_panel->add_child(top_dark_vb);
-#endif
-
menu_hb = memnew(HBoxContainer);
main_vbox->add_child(menu_hb);
- //top_dark_vb->add_child(scene_tabs);
//left
left_l_hsplit = memnew(HSplitContainer);
main_vbox->add_child(left_l_hsplit);
@@ -5329,10 +5300,10 @@ EditorNode::EditorNode() {
main_hsplit->connect("dragged", this, "_dock_split_dragged");
right_hsplit->connect("dragged", this, "_dock_split_dragged");
- dock_select_popoup = memnew(PopupPanel);
- gui_base->add_child(dock_select_popoup);
+ dock_select_popup = memnew(PopupPanel);
+ gui_base->add_child(dock_select_popup);
VBoxContainer *dock_vb = memnew(VBoxContainer);
- dock_select_popoup->add_child(dock_vb);
+ dock_select_popup->add_child(dock_vb);
HBoxContainer *dock_hb = memnew(HBoxContainer);
dock_tab_move_left = memnew(ToolButton);
@@ -5359,14 +5330,13 @@ EditorNode::EditorNode() {
dock_select->set_v_size_flags(Control::SIZE_EXPAND_FILL);
dock_vb->add_child(dock_select);
- dock_select_popoup->set_as_minsize();
+ dock_select_popup->set_as_minsize();
dock_select_rect_over = -1;
dock_popup_selected = -1;
- //dock_select_popoup->set_(Size2(20,20));
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
dock_slot[i]->set_custom_minimum_size(Size2(230, 220) * EDSCALE);
dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- dock_slot[i]->set_popup(dock_select_popoup);
+ dock_slot[i]->set_popup(dock_select_popup);
dock_slot[i]->connect("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
}
@@ -5387,10 +5357,6 @@ EditorNode::EditorNode() {
top_split->add_child(srt);
srt->add_constant_override("separation", 0);
- /* main_editor_tabs = memnew( Tabs );
- main_editor_tabs->connect("tab_changed",this,"_editor_select");
- main_editor_tabs->set_tab_close_display_policy(Tabs::SHOW_NEVER);
-*/
tab_preview_panel = memnew(Panel);
tab_preview_panel->set_size(Size2(100, 100) * EDSCALE);
tab_preview_panel->hide();
@@ -5433,6 +5399,7 @@ EditorNode::EditorNode() {
scene_root_parent = memnew(PanelContainer);
scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
+ // sc->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
//Ref<StyleBox> sp = scene_root_parent->get_stylebox("panel","TabContainer");
//scene_root_parent->add_style_override("panel",sp);
@@ -5503,7 +5470,6 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/close_scene", TTR("Close Scene"), KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_W), FILE_CLOSE);
p->add_separator();
- //p->add_shortcut(ED_SHORTCUT("editor/save_scene",TTR("Close Goto Prev. Scene")),FILE_OPEN_PREV,KEY_MASK_SHIFT+KEY_MASK_CMD+KEY_P);
p->add_submenu_item(TTR("Open Recent"), "RecentScenes", FILE_OPEN_RECENT);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("editor/quick_open_scene", TTR("Quick Open Scene.."), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_O), FILE_QUICK_OPEN_SCENE);
@@ -5571,35 +5537,6 @@ EditorNode::EditorNode() {
menu_hb->add_spacer();
menu_hb->add_child(editor_region);
-//menu_hb->add_spacer();
-#if 0
- node_menu = memnew( MenuButton );
- node_menu->set_text("Node");
- node_menu->set_position( Point2( 50,0) );
- menu_panel->add_child( node_menu );
-
- p=node_menu->get_popup();
- p->add_item("Create",NODE_CREATE);
- p->add_item("Instance",NODE_INSTANCE);
- p->add_separator();
- p->add_item("Reparent",NODE_REPARENT);
- p->add_item("Move Up",NODE_MOVE_UP);
- p->add_item("Move Down",NODE_MOVE_DOWN);
- p->add_separator();
- p->add_item("Duplicate",NODE_DUPLICATE);
- p->add_separator();
- p->add_item("Remove (Branch)",NODE_REMOVE_BRANCH);
- p->add_item("Remove (Element)",NODE_REMOVE_ELEMENT);
- p->add_separator();
- p->add_item("Edit Subscriptions..",NODE_CONNECTIONS);
- p->add_item("Edit Groups..",NODE_GROUPS);
-
- resource_menu = memnew( MenuButton );
- resource_menu->set_text("Resource");
- resource_menu->set_position( Point2( 90,0) );
- menu_panel->add_child( resource_menu );
-#endif
-
debug_menu = memnew(MenuButton);
debug_menu->set_text(TTR("Debug"));
debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
@@ -5652,7 +5589,7 @@ EditorNode::EditorNode() {
p = help_menu->get_popup();
p->connect("id_pressed", this, "_menu_option");
p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
- p->add_icon_item(gui_base->get_icon("Help", "EditorIcons"), TTR("Search"), HELP_SEARCH);
+ p->add_icon_item(gui_base->get_icon("HelpSearch", "EditorIcons"), TTR("Search"), HELP_SEARCH);
p->add_separator();
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Q&A"), HELP_QA);
@@ -5661,11 +5598,6 @@ EditorNode::EditorNode() {
p->add_separator();
p->add_icon_item(gui_base->get_icon("GodotDocs", "EditorIcons"), TTR("About"), HELP_ABOUT);
- //Separator *s1 = memnew( VSeparator );
- //menu_panel->add_child(s1);
- //s1->set_position(Point2(210,4));
- //s1->set_size(Point2(10,15));
-
play_cc = memnew(CenterContainer);
play_cc->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
menu_hb->add_child(play_cc);
@@ -5690,7 +5622,6 @@ EditorNode::EditorNode() {
play_button->set_shortcut(ED_SHORTCUT("editor/play", TTR("Play"), KEY_F5));
pause_button = memnew(ToolButton);
- //menu_panel->add_child(pause_button); - not needed for now?
pause_button->set_toggle_mode(true);
pause_button->set_icon(gui_base->get_icon("Pause", "EditorIcons"));
pause_button->set_focus_mode(Control::FOCUS_NONE);
@@ -5718,9 +5649,6 @@ EditorNode::EditorNode() {
native_play_button->get_popup()->connect("id_pressed", this, "_run_in_device");
run_native->connect("native_run", this, "_menu_option", varray(RUN_PLAY_NATIVE));
- //VSeparator *s1 = memnew( VSeparator );
- //play_hb->add_child(s1);
-
play_scene_button = memnew(ToolButton);
play_hb->add_child(play_scene_button);
play_scene_button->set_toggle_mode(true);
@@ -5739,24 +5667,6 @@ EditorNode::EditorNode() {
play_custom_scene_button->set_tooltip(TTR("Play custom scene"));
play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5));
- /*
- run_settings_button = memnew( ToolButton );
- //menu_hb->add_child(run_settings_button);
- //run_settings_button->set_toggle_mode(true);
- run_settings_button->set_focus_mode(Control::FOCUS_NONE);
- run_settings_button->set_icon(gui_base->get_icon("Run","EditorIcons"));
- run_settings_button->connect("pressed", this,"_menu_option",make_binds(RUN_SCENE_SETTINGS));
-*/
-
- /*
- run_settings_button = memnew( ToolButton );
- menu_panel->add_child(run_settings_button);
- run_settings_button->set_position(Point2(305,0));
- run_settings_button->set_focus_mode(Control::FOCUS_NONE);
- run_settings_button->set_icon(gui_base->get_icon("Run","EditorIcons"));
- run_settings_button->connect("pressed", this,"_menu_option",make_binds(RUN_SETTINGS));
-*/
-
progress_hb = memnew(BackgroundProgress);
//menu_hb->add_child(progress_hb);
@@ -5795,52 +5705,15 @@ EditorNode::EditorNode() {
p->add_check_item(TTR("Disable Update Spinner"), SETTINGS_UPDATE_SPINNER_HIDE);
p->set_item_checked(1, true);
- //sources_button->connect();
-
- /*
- Separator *s2 = memnew( VSeparator );
- menu_panel->add_child(s2);
- s2->set_position(Point2(338,4));
- s2->set_size(Point2(10,15));
-*/
-
- //editor_hsplit = memnew( HSplitContainer );
- //main_split->add_child(editor_hsplit);
- //editor_hsplit->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- //editor_vsplit = memnew( VSplitContainer );
- //editor_hsplit->add_child(editor_vsplit);
-
- //top_pallete = memnew( TabContainer );
scene_tree_dock = memnew(SceneTreeDock(this, scene_root, editor_selection, editor_data));
scene_tree_dock->set_name(TTR("Scene"));
- //top_pallete->add_child(scene_tree_dock);
dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(scene_tree_dock);
#if 0
resources_dock = memnew( ResourcesDock(this) );
resources_dock->set_name("Resources");
- //top_pallete->add_child(resources_dock);
dock_slot[DOCK_SLOT_RIGHT_BL]->add_child(resources_dock);
- //top_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
#endif
dock_slot[DOCK_SLOT_LEFT_BR]->hide();
- /*Control *editor_spacer = memnew( Control );
- editor_spacer->set_custom_minimum_size(Size2(260,200));
- editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor_vsplit->add_child( editor_spacer );
- editor_spacer->add_child( top_pallete );
- top_pallete->set_area_as_parent_rect();*/
-
- //prop_pallete = memnew( TabContainer );
-
- //prop_pallete->set_v_size_flags(Control::SIZE_EXPAND_FILL);
-
- /*editor_spacer = memnew( Control );
- editor_spacer->set_custom_minimum_size(Size2(260,200));
- editor_spacer->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- editor_vsplit->add_child( editor_spacer );
- editor_spacer->add_child( prop_pallete );
- prop_pallete->set_area_as_parent_rect();*/
VBoxContainer *prop_editor_base = memnew(VBoxContainer);
prop_editor_base->set_name(TTR("Inspector")); // Properties?
@@ -5947,6 +5820,7 @@ EditorNode::EditorNode() {
property_editor->set_use_folding(true);
property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
property_editor->set_use_doc_hints(true);
+ property_editor->set_hide_script(false);
property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true)));
property_editor->hide_top_label();
@@ -5981,7 +5855,6 @@ EditorNode::EditorNode() {
} else {
dock_slot[DOCK_SLOT_LEFT_UR]->add_child(filesystem_dock);
}
- //prop_pallete->add_child(filesystem_dock);
filesystem_dock->connect("open", this, "open_request");
filesystem_dock->connect("instance", this, "_instance_request");
@@ -6001,7 +5874,7 @@ EditorNode::EditorNode() {
_update_layouts_menu();
bottom_panel = memnew(PanelContainer);
- bottom_panel->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("panel", "TabContainer"));
center_split->add_child(bottom_panel);
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
@@ -6032,17 +5905,6 @@ EditorNode::EditorNode() {
//progress_hb->set_h_size_flags(Control::SIZE_EXPAND_FILL);
- /*
- animation_menu = memnew( ToolButton );
- animation_menu->set_position(Point2(500,0));
- animation_menu->set_size(Size2(20,20));
- animation_menu->set_toggle_mode(true);
- animation_menu->set_focus_mode(Control::FOCUS_NONE);
- menu_panel->add_child(animation_menu);
- animation_menu->set_icon(gui_base->get_icon("Animation","EditorIcons"));
- animation_menu->connect("pressed",this,"_animation_visibility_toggle");
-*/
-
orphan_resources = memnew(OrphanResourcesDialog);
gui_base->add_child(orphan_resources);
@@ -6097,10 +5959,6 @@ EditorNode::EditorNode() {
import_confirmation->connect("custom_action", this, "_import_action");
gui_base->add_child(import_confirmation);
- open_recent_confirmation = memnew(ConfirmationDialog);
- add_child(open_recent_confirmation);
- open_recent_confirmation->connect("confirmed", this, "_open_recent_scene_confirm");
-
run_settings_dialog = memnew(RunSettingsDialog);
gui_base->add_child(run_settings_dialog);
@@ -6354,21 +6212,17 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( ShaderEditorPlugin(this,false) ) );*/
add_editor_plugin(memnew(CameraEditorPlugin(this)));
- // add_editor_plugin( memnew( SampleEditorPlugin(this) ) );
- // add_editor_plugin( memnew( SampleLibraryEditorPlugin(this) ) );
add_editor_plugin(memnew(ThemeEditorPlugin(this)));
add_editor_plugin(memnew(MultiMeshEditorPlugin(this)));
add_editor_plugin(memnew(MeshInstanceEditorPlugin(this)));
add_editor_plugin(memnew(AnimationTreeEditorPlugin(this)));
- //add_editor_plugin( memnew( SamplePlayerEditorPlugin(this) ) ); - this is kind of useless at this point
//add_editor_plugin( memnew( MeshLibraryEditorPlugin(this) ) );
- //add_editor_plugin( memnew( StreamEditorPlugin(this) ) );
add_editor_plugin(memnew(StyleBoxEditorPlugin(this)));
add_editor_plugin(memnew(ParticlesEditorPlugin(this)));
add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this)));
add_editor_plugin(memnew(ItemListEditorPlugin(this)));
//add_editor_plugin( memnew( RichTextEditorPlugin(this) ) );
- //add_editor_plugin( memnew( CollisionPolygonEditorPlugin(this) ) );
+ add_editor_plugin(memnew(CollisionPolygonEditorPlugin(this)));
add_editor_plugin(memnew(CollisionPolygon2DEditorPlugin(this)));
add_editor_plugin(memnew(TileSetEditorPlugin(this)));
add_editor_plugin(memnew(TileMapEditorPlugin(this)));
@@ -6378,7 +6232,6 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(GIProbeEditorPlugin(this)));
add_editor_plugin(memnew(Path2DEditorPlugin(this)));
add_editor_plugin(memnew(PathEditorPlugin(this)));
- //add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) );
add_editor_plugin(memnew(Line2DEditorPlugin(this)));
add_editor_plugin(memnew(Polygon2DEditorPlugin(this)));
add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
@@ -6547,10 +6400,10 @@ EditorNode::EditorNode() {
_dim_timer->connect("timeout", this, "_dim_timeout");
add_child(_dim_timer);
- ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F2);
- ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F3);
- ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F4);
- ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1);
+ ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F1);
+ ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F2);
+ ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F3); //hack neded for script editor F3 search to work :) Assign like this or don't use F3
+ ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F4);
ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"));
ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor"));
ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor"));
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 991cf1df71..228fbe7196 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -247,10 +247,7 @@ private:
Control *vp_base;
PaneDrag *pd;
//PaneDrag *pd_anim;
- Panel *menu_panel;
- //HSplitContainer *editor_hsplit;
- //VSplitContainer *editor_vsplit;
CenterContainer *play_cc;
HBoxContainer *menu_hb;
Control *viewport;
@@ -300,7 +297,6 @@ private:
ConfirmationDialog *confirmation;
ConfirmationDialog *save_confirmation;
ConfirmationDialog *import_confirmation;
- ConfirmationDialog *open_recent_confirmation;
ConfirmationDialog *pick_main_scene;
AcceptDialog *accept;
AcceptDialog *about;
@@ -326,8 +322,6 @@ private:
String current_path;
MenuButton *update_menu;
- //TabContainer *prop_pallete;
- //TabContainer *top_pallete;
String defer_load_scene;
String defer_export;
String defer_export_platform;
@@ -363,7 +357,7 @@ private:
TabContainer *dock_slot[DOCK_SLOT_MAX];
Rect2 dock_select_rect[DOCK_SLOT_MAX];
int dock_select_rect_over;
- PopupPanel *dock_select_popoup;
+ PopupPanel *dock_select_popup;
Control *dock_select;
ToolButton *dock_tab_move_left;
ToolButton *dock_tab_move_right;
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index a8106b4eec..8d01484b34 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -79,12 +79,12 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
Size2 desired_size;
- desired_size.x = GlobalConfig::get_singleton()->get("display/window/width");
- desired_size.y = GlobalConfig::get_singleton()->get("display/window/height");
+ desired_size.x = GlobalConfig::get_singleton()->get("display/window/size/width");
+ desired_size.y = GlobalConfig::get_singleton()->get("display/window/size/height");
Size2 test_size;
- test_size.x = GlobalConfig::get_singleton()->get("display/window/test_width");
- test_size.y = GlobalConfig::get_singleton()->get("display/window/test_height");
+ test_size.x = GlobalConfig::get_singleton()->get("display/window/size/test_width");
+ test_size.y = GlobalConfig::get_singleton()->get("display/window/size/test_height");
if (test_size.x > 0 && test_size.y > 0) {
desired_size = test_size;
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 7a7b2b7d1e..4ab1a435f8 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -537,12 +537,15 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/theme/preset", 0);
hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("interface/theme/base_color", Color::html("#273241"));
+ set("interface/theme/base_color", Color::html("#323b4f"));
hints["interface/theme/highlight_color"] = PropertyInfo(Variant::COLOR, "interface/theme/highlight_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("interface/theme/highlight_color", Color::html("#b79047"));
+ set("interface/theme/highlight_color", Color::html("#699ce8"));
hints["interface/theme/base_color"] = PropertyInfo(Variant::COLOR, "interface/theme/base_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/contrast", 0.2);
hints["interface/theme/contrast"] = PropertyInfo(Variant::REAL, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01");
+ set("interface/theme/highlight_tabs", false);
+ set("interface/theme/border_size", 1);
+ hints["interface/theme/border_size"] = PropertyInfo(Variant::INT, "interface/theme/border_size", PROPERTY_HINT_RANGE, "0,2,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/theme/custom_theme", "");
hints["interface/theme/custom_theme"] = PropertyInfo(Variant::STRING, "interface/theme/custom_theme", PROPERTY_HINT_GLOBAL_FILE, "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
@@ -613,7 +616,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/grid_map/pick_distance", 5000.0);
- set("editors/3d/grid_color", Color(0, 1, 0, 0.2));
+ set("editors/3d/grid_color", Color(1, 1, 1, 0.2));
hints["editors/3d/grid_color"] = PropertyInfo(Variant::COLOR, "editors/3d/grid_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("editors/3d/default_fov", 55.0);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 5b8f41e75f..4e8f7029ff 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -69,6 +69,15 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color color, float p_margin_left = -
return style;
}
+static Ref<StyleBoxLine> make_line_stylebox(Color color, int thickness = 1, float grow = 1, bool vertical = false) {
+ Ref<StyleBoxLine> style(memnew(StyleBoxLine));
+ style->set_color(color);
+ style->set_grow(grow);
+ style->set_thickness(thickness);
+ style->set_vertical(vertical);
+ return style;
+}
+
static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_color) {
Ref<StyleBoxFlat> style = p_style->duplicate();
style->set_light_color(p_color);
@@ -94,17 +103,21 @@ Ref<Theme> create_editor_theme() {
editor_register_fonts(theme);
editor_register_icons(theme);
+ const float default_contrast = 0.25;
+
// Define colors
- Color highlight_color = EDITOR_DEF("interface/theme/highlight_color", Color::html("#b79047"));
- Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#273241"));
- float contrast = EDITOR_DEF("interface/theme/contrast", 0.25);
+ Color highlight_color = EDITOR_DEF("interface/theme/highlight_color", Color::html("#000000"));
+ Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#000000"));
+ float contrast = EDITOR_DEF("interface/theme/contrast", default_contrast);
int preset = EDITOR_DEF("interface/theme/preset", 0);
+ bool highlight_tabs = EDITOR_DEF("interface/theme/highlight_tabs", false);
+ int border_size = EDITOR_DEF("interface/theme/border_size", 1);
switch (preset) {
case 0: { // Default
- highlight_color = Color::html("#b79047");
- base_color = Color::html("#273241");
- contrast = 0.25;
+ highlight_color = Color::html("#699ce8");
+ base_color = Color::html("#323b4f");
+ contrast = default_contrast;
} break;
case 1: { // Grey
highlight_color = Color::html("#3e3e3e");
@@ -130,6 +143,18 @@ Ref<Theme> create_editor_theme() {
Color light_color_1 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast);
Color light_color_2 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast * 1.5);
+ const int border_width = (border_size % 3) * EDSCALE;
+
+ Color title_color_hl = base_color;
+ if (highlight_tabs)
+ title_color_hl = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast / default_contrast / 10);
+ bool dark_bg = ((title_color_hl.r + title_color_hl.g + title_color_hl.b) / 3.0) < 0.5;
+ Color title_color_hl_text_color = dark_bg ? Color(1, 1, 1, 0.9) : Color(0, 0, 0, 0.9);
+ Ref<Texture> title_hl_close_icon = theme->get_icon((dark_bg ? "GuiCloseLight" : "GuiCloseDark"), "EditorIcons");
+
+ bool dark_base = ((base_color.r + base_color.g + base_color.b) / 3.0) < 0.5;
+ Color separator_color = dark_base ? Color(1, 1, 1, 0.1) : Color(0, 0, 0, 0.1);
+
theme->set_color("highlight_color", "Editor", highlight_color);
theme->set_color("base_color", "Editor", base_color);
theme->set_color("dark_color_1", "Editor", dark_color_1);
@@ -139,10 +164,10 @@ Ref<Theme> create_editor_theme() {
theme->set_color("light_color_2", "Editor", light_color_2);
// Checkbox icon
- theme->set_icon("checked", "CheckBox", theme->get_icon("Checked", "EditorIcons"));
- theme->set_icon("unchecked", "CheckBox", theme->get_icon("Unchecked", "EditorIcons"));
- theme->set_icon("checked", "PopupMenu", theme->get_icon("Checked", "EditorIcons"));
- theme->set_icon("unchecked", "PopupMenu", theme->get_icon("Unchecked", "EditorIcons"));
+ theme->set_icon("checked", "CheckBox", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("unchecked", "CheckBox", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_icon("checked", "PopupMenu", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("unchecked", "PopupMenu", theme->get_icon("GuiUnchecked", "EditorIcons"));
// Editor background
Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
@@ -151,7 +176,7 @@ Ref<Theme> create_editor_theme() {
// Focus
Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(light_color_1, 4, 4, 4, 4);
focus_sbt->set_draw_center(false);
- focus_sbt->set_border_size(1 * EDSCALE);
+ focus_sbt->set_border_size(border_width);
focus_sbt = change_border_color(focus_sbt, light_color_2);
theme->set_stylebox("Focus", "EditorStyles", focus_sbt);
@@ -161,13 +186,13 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("MenuPanel", "EditorStyles", style_menu);
// Play button group
- theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_stylebox(theme->get_icon("PlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
+ theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_stylebox(theme->get_icon("GuiPlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
Ref<StyleBoxFlat> style_menu_hover_border = make_flat_stylebox(highlight_color, 4, 4, 4, 4);
Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
style_menu_hover_border->set_draw_center(false);
- style_menu_hover_border->_set_additional_border_size(MARGIN_BOTTOM, 1 * EDSCALE);
+ style_menu_hover_border->_set_additional_border_size(MARGIN_BOTTOM, border_width);
theme->set_stylebox("normal", "MenuButton", style_menu);
theme->set_stylebox("hover", "MenuButton", style_menu);
theme->set_stylebox("pressed", "MenuButton", style_menu);
@@ -193,22 +218,37 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
// Content of each tab
- Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 1, 4, 1, 1);
+ Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 4, 5, 4, 4);
+ style_content_panel->set_dark_color(title_color_hl);
+ style_content_panel->set_light_color(title_color_hl);
+ style_content_panel->set_border_size(border_width);
+ style_content_panel->set_border_blend(false);
+ Ref<StyleBoxFlat> style_content_panel_vp = make_flat_stylebox(base_color, border_width, 5, border_width, border_width);
+ style_content_panel_vp->set_dark_color(title_color_hl);
+ style_content_panel_vp->set_light_color(title_color_hl);
+ style_content_panel_vp->set_border_size(border_width);
+ style_content_panel_vp->set_border_blend(false);
theme->set_stylebox("panel", "TabContainer", style_content_panel);
- theme->set_stylebox("Content", "EditorStyles", style_content_panel);
+ theme->set_stylebox("Content", "EditorStyles", style_content_panel_vp);
+
+ Ref<StyleBoxFlat> style_button_type = make_flat_stylebox(dark_color_1, 4, 4, 6, 4);
+ style_button_type->set_draw_center(true);
+ style_button_type->set_border_size(border_width);
+ style_button_type->set_light_color(light_color_1);
+ style_button_type->set_dark_color(light_color_1);
+ style_button_type->set_border_blend(false);
+
+ Ref<StyleBoxFlat> style_button_type_disabled = change_border_color(style_button_type, dark_color_2);
+
+ Color button_font_color = light_color_1.linear_interpolate(Color(1, 1, 1, 1), .6);
// Button
- Ref<StyleBoxFlat> style_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
- style_button->set_draw_center(true);
- style_button->set_border_size(2 * EDSCALE);
- style_button->set_light_color(light_color_1);
- style_button->set_dark_color(light_color_1);
- style_button->set_border_blend(false);
- theme->set_stylebox("normal", "Button", style_button);
- theme->set_stylebox("hover", "Button", style_button);
- theme->set_stylebox("pressed", "Button", style_button);
- theme->set_stylebox("focus", "Button", style_button);
- theme->set_stylebox("disabled", "Button", style_button);
+ theme->set_stylebox("normal", "Button", style_button_type);
+ theme->set_stylebox("hover", "Button", change_border_color(style_button_type, HIGHLIGHT_COLOR_LIGHT));
+ theme->set_stylebox("pressed", "Button", change_border_color(style_button_type, highlight_color));
+ theme->set_stylebox("focus", "Button", change_border_color(style_button_type, highlight_color));
+ theme->set_stylebox("disabled", "Button", style_button_type_disabled);
+ theme->set_color("font_color", "Button", button_font_color);
theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
theme->set_color("font_color_pressed", "Button", highlight_color);
theme->set_color("icon_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
@@ -216,42 +256,60 @@ Ref<Theme> create_editor_theme() {
theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a));
// OptionButton
- Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
- style_option_button->set_border_size(1 * EDSCALE);
+ Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 8, 4);
+ style_option_button->set_border_size(border_width);
style_option_button->set_light_color(light_color_1);
style_option_button->set_dark_color(light_color_1);
- style_option_button->_set_additional_border_size(MARGIN_RIGHT, -16 * EDSCALE);
- theme->set_stylebox("hover", "OptionButton", change_border_color(style_option_button, HIGHLIGHT_COLOR_LIGHT));
- theme->set_stylebox("pressed", "OptionButton", change_border_color(style_option_button, highlight_color));
- theme->set_stylebox("focus", "OptionButton", change_border_color(style_option_button, highlight_color));
- theme->set_stylebox("disabled", "OptionButton", style_option_button);
- theme->set_stylebox("normal", "OptionButton", style_option_button);
- theme->set_icon("arrow", "OptionButton", theme->get_icon("OptionArrow", "EditorIcons"));
+ style_option_button->set_border_blend(false);
+ theme->set_stylebox("hover", "OptionButton", change_border_color(style_button_type, HIGHLIGHT_COLOR_LIGHT));
+ theme->set_stylebox("pressed", "OptionButton", change_border_color(style_button_type, highlight_color));
+ theme->set_stylebox("focus", "OptionButton", change_border_color(style_button_type, highlight_color));
+ theme->set_stylebox("disabled", "OptionButton", style_button_type_disabled);
+ theme->set_stylebox("normal", "OptionButton", style_button_type);
+ theme->set_color("font_color", "OptionButton", button_font_color);
+ theme->set_color("font_color_hover", "OptionButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_pressed", "OptionButton", highlight_color);
+ theme->set_color("icon_color_hover", "OptionButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_icon("arrow", "OptionButton", theme->get_icon("GuiOptionArrow", "EditorIcons"));
+ theme->set_constant("arrow_margin", "OptionButton", 4);
+ theme->set_constant("modulate_arrow", "OptionButton", true);
+
+ // CheckButton
+ theme->set_icon("on", "CheckButton", theme->get_icon("GuiToggleOn", "EditorIcons"));
+ theme->set_icon("off", "CheckButton", theme->get_icon("GuiToggleOff", "EditorIcons"));
// PopupMenu
Ref<StyleBoxFlat> style_popup_menu = make_flat_stylebox(dark_color_1, 8, 8, 8, 8);
- style_popup_menu->set_border_size(2 * EDSCALE);
+ style_popup_menu->set_border_size(border_width);
style_popup_menu->set_light_color(light_color_1);
style_popup_menu->set_dark_color(light_color_1);
+ style_popup_menu->set_border_blend(false);
theme->set_stylebox("panel", "PopupMenu", style_popup_menu);
+ theme->set_stylebox("separator", "PopupMenu", make_line_stylebox(separator_color, border_width, 8 - border_width));
// Tree & ItemList background
Ref<StyleBoxFlat> style_tree_bg = make_flat_stylebox(dark_color_1, 2, 4, 2, 4);
+ style_tree_bg->set_border_size(border_width);
+ style_tree_bg->set_light_color(dark_color_3);
+ style_tree_bg->set_dark_color(dark_color_3);
theme->set_stylebox("bg", "Tree", style_tree_bg);
// Script background
Ref<StyleBoxFlat> style_script_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
+ style_script_bg->set_border_size(border_width);
+ style_script_bg->set_light_color(dark_color_3);
+ style_script_bg->set_dark_color(dark_color_3);
theme->set_stylebox("ScriptPanel", "EditorStyles", style_script_bg);
// Tree
- theme->set_icon("checked", "Tree", theme->get_icon("Checked", "EditorIcons"));
- theme->set_icon("unchecked", "Tree", theme->get_icon("Unchecked", "EditorIcons"));
- theme->set_icon("arrow", "Tree", theme->get_icon("TreeArrowDown", "EditorIcons"));
- theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("TreeArrowRight", "EditorIcons"));
- theme->set_icon("select_arrow", "Tree", theme->get_icon("Dropdown", "EditorIcons"));
+ theme->set_icon("checked", "Tree", theme->get_icon("GuiChecked", "EditorIcons"));
+ theme->set_icon("unchecked", "Tree", theme->get_icon("GuiUnchecked", "EditorIcons"));
+ theme->set_icon("arrow", "Tree", theme->get_icon("GuiTreeArrowDown", "EditorIcons"));
+ theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("GuiTreeArrowRight", "EditorIcons"));
+ theme->set_icon("select_arrow", "Tree", theme->get_icon("GuiDropdown", "EditorIcons"));
theme->set_stylebox("bg_focus", "Tree", focus_sbt);
- theme->set_stylebox("custom_button", "Tree", style_button);
- theme->set_stylebox("custom_button_pressed", "Tree", style_button);
- theme->set_stylebox("custom_button_hover", "Tree", style_button);
+ theme->set_stylebox("custom_button", "Tree", style_button_type);
+ theme->set_stylebox("custom_button_pressed", "Tree", style_button_type);
+ theme->set_stylebox("custom_button_hover", "Tree", style_button_type);
theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT);
Ref<StyleBox> style_tree_btn = make_flat_stylebox(light_color_1, 2, 4, 2, 4);
@@ -265,7 +323,7 @@ Ref<Theme> create_editor_theme() {
Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 4, 4, 4, 4);
style_tree_cursor->set_draw_center(false);
- style_tree_cursor->set_border_size(1 * EDSCALE);
+ style_tree_cursor->set_border_size(border_width);
style_tree_cursor->set_light_color(light_color_1);
style_tree_cursor->set_dark_color(light_color_1);
Ref<StyleBoxFlat> style_tree_title = make_flat_stylebox(dark_color_3, 4, 4, 4, 4);
@@ -284,9 +342,12 @@ Ref<Theme> create_editor_theme() {
// ItemList
Ref<StyleBoxFlat> style_itemlist_bg = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
+ style_itemlist_bg->set_border_size(border_width);
+ style_itemlist_bg->set_light_color(dark_color_3);
+ style_itemlist_bg->set_dark_color(dark_color_3);
Ref<StyleBoxFlat> style_itemlist_cursor = make_flat_stylebox(highlight_color, 0, 0, 0, 0);
style_itemlist_cursor->set_draw_center(false);
- style_itemlist_cursor->set_border_size(1 * EDSCALE);
+ style_itemlist_cursor->set_border_size(border_width);
style_itemlist_cursor->set_light_color(HIGHLIGHT_COLOR_DARK);
style_itemlist_cursor->set_dark_color(HIGHLIGHT_COLOR_DARK);
theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor);
@@ -297,7 +358,7 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("bg", "ItemList", style_itemlist_bg);
theme->set_constant("vseparation", "ItemList", 5 * EDSCALE);
- Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(base_color, 15, 5, 15, 5);
+ Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(title_color_hl, 15, 5, 15, 5);
Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(base_color, 15, 5, 15, 5);
style_tab_bg->set_draw_center(false);
@@ -306,12 +367,17 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("tab_bg", "TabContainer", style_tab_bg);
theme->set_stylebox("tab_fg", "Tabs", style_tab_fg);
theme->set_stylebox("tab_bg", "Tabs", style_tab_bg);
- theme->set_color("font_color_fg", "TabContainer", Color(1, 1, 1, 1));
+ theme->set_color("font_color_fg", "TabContainer", title_color_hl_text_color);
theme->set_color("font_color_bg", "TabContainer", light_color_2);
- theme->set_icon("menu", "TabContainer", theme->get_icon("TabMenu", "EditorIcons"));
- theme->set_icon("menu_hl", "TabContainer", theme->get_icon("TabMenu", "EditorIcons"));
- theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(base_color, 10, 5, 10, 5));
+ theme->set_icon("menu", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
+ theme->set_icon("menu_hl", "TabContainer", theme->get_icon("GuiTabMenu", "EditorIcons"));
+ theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(title_color_hl, 10, 5, 10, 5));
theme->set_stylebox("SceneTabBG", "EditorStyles", make_empty_stylebox(6, 5, 6, 5));
+ theme->set_icon("close", "Tabs", title_hl_close_icon);
+
+ // Separatos (no separatos)
+ theme->set_stylebox("separator", "HSeparator", make_line_stylebox(separator_color, border_width));
+ theme->set_stylebox("separator", "VSeparator", make_line_stylebox(separator_color, border_width, 0, true));
// Debugger
Ref<StyleBoxFlat> style_panel_debugger = make_flat_stylebox(dark_color_2, 0, 4, 0, 0);
@@ -325,16 +391,15 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("DebuggerTabBG", "EditorStyles", style_tab_bg_debugger);
// LineEdit
- Ref<StyleBoxFlat> style_lineedit = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
- style_lineedit->set_border_size(1 * EDSCALE);
+ Ref<StyleBoxFlat> style_lineedit = style_button_type;
style_lineedit = change_border_color(style_lineedit, light_color_1);
- Ref<StyleBoxFlat> style_lineedit_disabled = style_lineedit->duplicate();
- style_lineedit_disabled->set_bg_color(light_color_1);
+ Ref<StyleBoxFlat> style_lineedit_disabled = change_border_color(style_lineedit, dark_color_1);
+ style_lineedit_disabled->set_bg_color(Color(0, 0, 0, .1));
Ref<StyleBoxFlat> style_lineedit_focus = change_border_color(style_lineedit, highlight_color);
- style_lineedit_focus->set_draw_center(false);
theme->set_stylebox("normal", "LineEdit", style_lineedit);
theme->set_stylebox("focus", "LineEdit", style_lineedit_focus);
theme->set_stylebox("read_only", "LineEdit", style_lineedit_disabled);
+ theme->set_color("read_only", "LineEdit", dark_color_1);
// TextEdit
Ref<StyleBoxFlat> style_textedit_normal(memnew(StyleBoxFlat));
@@ -348,31 +413,36 @@ Ref<Theme> create_editor_theme() {
theme->set_constant("side_margin", "TabContainer", 0);
// H/VSplitContainer
- theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("VsplitBg", "EditorIcons"), 1, 1, 1, 1));
- theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon("HsplitBg", "EditorIcons"), 1, 1, 1, 1));
+ theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("GuiVsplitBg", "EditorIcons"), 1, 1, 1, 1));
+ theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon("GuiHsplitBg", "EditorIcons"), 1, 1, 1, 1));
- theme->set_icon("grabber", "VSplitContainer", theme->get_icon("Vsplitter", "EditorIcons"));
- theme->set_icon("grabber", "HSplitContainer", theme->get_icon("Hsplitter", "EditorIcons"));
+ theme->set_icon("grabber", "VSplitContainer", theme->get_icon("GuiVsplitter", "EditorIcons"));
+ theme->set_icon("grabber", "HSplitContainer", theme->get_icon("GuiHsplitter", "EditorIcons"));
theme->set_constant("separation", "HSplitContainer", 8 * EDSCALE);
theme->set_constant("separation", "VSplitContainer", 8 * EDSCALE);
// WindowDialog
Ref<StyleBoxFlat> style_window = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
- style_window->set_border_size(2 * EDSCALE);
+ style_window->set_border_size(border_width);
style_window->set_border_blend(false);
- style_window->set_light_color(light_color_2);
- style_window->set_dark_color(light_color_2);
+ style_window->set_light_color(title_color_hl);
+ style_window->set_dark_color(title_color_hl);
style_window->_set_additional_border_size(MARGIN_TOP, 24 * EDSCALE);
theme->set_stylebox("panel", "WindowDialog", style_window);
+ theme->set_color("title_color", "WindowDialog", title_color_hl_text_color);
+ theme->set_icon("close", "WindowDialog", title_hl_close_icon);
+ theme->set_icon("close_highlight", "WindowDialog", title_hl_close_icon);
+ theme->set_constant("close_h_ofs", "WindowDialog", 22 * EDSCALE);
+ theme->set_constant("close_v_ofs", "WindowDialog", 18 * EDSCALE);
// HScrollBar
Ref<Texture> empty_icon = memnew(ImageTexture);
- theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
- theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
- theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon("ScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
- theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon("ScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
+ theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon("GuiScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon("GuiScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon("GuiScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
+ theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon("GuiScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
theme->set_icon("increment", "HScrollBar", empty_icon);
theme->set_icon("increment_highlight", "HScrollBar", empty_icon);
@@ -380,10 +450,10 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("decrement_highlight", "HScrollBar", empty_icon);
// VScrollBar
- theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
- theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
- theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon("ScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
- theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon("ScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
+ theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon("GuiScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon("GuiScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon("GuiScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
+ theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon("GuiScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
theme->set_icon("increment", "VScrollBar", empty_icon);
theme->set_icon("increment_highlight", "VScrollBar", empty_icon);
@@ -391,21 +461,21 @@ Ref<Theme> create_editor_theme() {
theme->set_icon("decrement_highlight", "VScrollBar", empty_icon);
// HSlider
- theme->set_stylebox("slider", "HSlider", make_stylebox(theme->get_icon("HsliderBg", "EditorIcons"), 4, 4, 4, 4));
- theme->set_icon("grabber", "HSlider", theme->get_icon("SliderGrabber", "EditorIcons"));
- theme->set_icon("grabber_highlight", "HSlider", theme->get_icon("SliderGrabberHl", "EditorIcons"));
+ theme->set_stylebox("slider", "HSlider", make_stylebox(theme->get_icon("GuiHsliderBg", "EditorIcons"), 4, 4, 4, 4));
+ theme->set_icon("grabber", "HSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
+ theme->set_icon("grabber_highlight", "HSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
// VSlider
- theme->set_stylebox("slider", "VSlider", make_stylebox(theme->get_icon("VsliderBg", "EditorIcons"), 4, 4, 4, 4));
- theme->set_icon("grabber", "VSlider", theme->get_icon("SliderGrabber", "EditorIcons"));
- theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("SliderGrabberHl", "EditorIcons"));
+ theme->set_stylebox("slider", "VSlider", make_stylebox(theme->get_icon("GuiVsliderBg", "EditorIcons"), 4, 4, 4, 4));
+ theme->set_icon("grabber", "VSlider", theme->get_icon("GuiSliderGrabber", "EditorIcons"));
+ theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("GuiSliderGrabberHl", "EditorIcons"));
// Panel
theme->set_stylebox("panel", "Panel", style_panel);
// TooltipPanel
Ref<StyleBoxFlat> style_tooltip = make_flat_stylebox(Color(1, 1, 1, 0.8), 8, 8, 8, 8);
- style_tooltip->set_border_size(2 * EDSCALE);
+ style_tooltip->set_border_size(border_width);
style_tooltip->set_border_blend(false);
style_tooltip->set_light_color(Color(1, 1, 1, 0.9));
style_tooltip->set_dark_color(Color(1, 1, 1, 0.9));
@@ -419,30 +489,42 @@ Ref<Theme> create_editor_theme() {
theme->set_stylebox("panel", "PopupPanel", style_dock_select);
// SpinBox
- theme->set_icon("updown", "SpinBox", theme->get_icon("SpinboxUpdown", "EditorIcons"));
+ theme->set_icon("updown", "SpinBox", theme->get_icon("GuiSpinboxUpdown", "EditorIcons"));
+
+ // ProgressBar
+ theme->set_stylebox("bg", "ProgressBar", make_stylebox(theme->get_icon("GuiProgressBar", "EditorIcons"), 4, 4, 4, 4, 0, 0, 0, 0));
+ theme->set_stylebox("fg", "ProgressBar", make_stylebox(theme->get_icon("GuiProgressFill", "EditorIcons"), 6, 6, 6, 6, 2, 1, 2, 1));
+
+ // theme->set_font("font", "ProgressBar", default_font);
+
+ // theme->set_color("font_color", "ProgressBar", control_font_color_hover);
+ theme->set_color("font_color_shadow", "ProgressBar", Color(0, 0, 0));
+
+ // GraphEdit
+ theme->set_stylebox("bg", "GraphEdit", make_flat_stylebox(dark_color_2, 4, 4, 4, 4));
// GraphNode
Ref<StyleBoxFlat> graphsb = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
graphsb->set_border_blend(false);
- graphsb->set_border_size(2);
+ graphsb->set_border_size(border_width);
graphsb->set_light_color(Color(1, 1, 1, 0.6));
graphsb->set_dark_color(Color(1, 1, 1, 0.6));
graphsb = add_additional_border(graphsb, 0, -22, 0, 0);
Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
graphsbselected->set_border_blend(false);
- graphsbselected->set_border_size(2);
+ graphsbselected->set_border_size(border_width);
graphsbselected->set_light_color(Color(1, 1, 1, 0.9));
graphsbselected->set_dark_color(Color(1, 1, 1, 0.9));
graphsbselected = add_additional_border(graphsbselected, 0, -22, 0, 0);
Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
graphsbcomment->set_border_blend(false);
- graphsbcomment->set_border_size(1);
+ graphsbcomment->set_border_size(border_width);
graphsbcomment->set_light_color(Color(1, 1, 1, 0.6));
graphsbcomment->set_dark_color(Color(1, 1, 1, 0.6));
graphsbcomment = add_additional_border(graphsbcomment, 0, -22, 0, 0);
Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
graphsbcommentselected->set_border_blend(false);
- graphsbcommentselected->set_border_size(1);
+ graphsbcommentselected->set_border_size(border_width);
graphsbcommentselected->set_light_color(Color(1, 1, 1, 0.9));
graphsbcommentselected->set_dark_color(Color(1, 1, 1, 0.9));
graphsbcommentselected = add_additional_border(graphsbcommentselected, 0, -22, 0, 0);
diff --git a/editor/icons/2x/icon_GUI_checked.png b/editor/icons/2x/icon_GUI_checked.png
new file mode 100644
index 0000000000..d51f20b867
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_checked.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_dropdown.png b/editor/icons/2x/icon_GUI_dropdown.png
new file mode 100644
index 0000000000..c959378430
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_dropdown.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_hslider_bg.png b/editor/icons/2x/icon_GUI_hslider_bg.png
new file mode 100644
index 0000000000..38af962095
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_hslider_bg.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_hsplitter.png b/editor/icons/2x/icon_GUI_hsplitter.png
new file mode 100644
index 0000000000..063f0c90fc
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_hsplitter.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_option_arrow.png b/editor/icons/2x/icon_GUI_option_arrow.png
new file mode 100644
index 0000000000..87fdc8aa51
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_option_arrow.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_play_button_group.png b/editor/icons/2x/icon_GUI_play_button_group.png
new file mode 100644
index 0000000000..6a569d5e80
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_play_button_group.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_progress_bar.png b/editor/icons/2x/icon_GUI_progress_bar.png
new file mode 100644
index 0000000000..ca53eba8d0
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_progress_bar.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_progress_fill.png b/editor/icons/2x/icon_GUI_progress_fill.png
new file mode 100644
index 0000000000..ac6c562650
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_progress_fill.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_scroll_bg.png b/editor/icons/2x/icon_GUI_scroll_bg.png
new file mode 100644
index 0000000000..58369d6f96
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_scroll_bg.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_scroll_grabber.png b/editor/icons/2x/icon_GUI_scroll_grabber.png
new file mode 100644
index 0000000000..6f74a9365f
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_scroll_grabber.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_scroll_grabber_hl.png b/editor/icons/2x/icon_GUI_scroll_grabber_hl.png
new file mode 100644
index 0000000000..c03ca1adf9
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_scroll_grabber_hl.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_slider_grabber.png b/editor/icons/2x/icon_GUI_slider_grabber.png
new file mode 100644
index 0000000000..97e97cb536
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_slider_grabber.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_slider_grabber_hl.png b/editor/icons/2x/icon_GUI_slider_grabber_hl.png
new file mode 100644
index 0000000000..2229e25a60
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_slider_grabber_hl.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_spinbox_updown.png b/editor/icons/2x/icon_GUI_spinbox_updown.png
new file mode 100644
index 0000000000..a20b43f9c3
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_spinbox_updown.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_tab_menu.png b/editor/icons/2x/icon_GUI_tab_menu.png
new file mode 100644
index 0000000000..3887615fee
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_tab_menu.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_toggle_off.png b/editor/icons/2x/icon_GUI_toggle_off.png
new file mode 100644
index 0000000000..9da02707d1
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_toggle_off.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_toggle_on.png b/editor/icons/2x/icon_GUI_toggle_on.png
new file mode 100644
index 0000000000..41a25e9345
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_toggle_on.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_tree_arrow_down.png b/editor/icons/2x/icon_GUI_tree_arrow_down.png
new file mode 100644
index 0000000000..c71c6f4159
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_tree_arrow_down.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_tree_arrow_right.png b/editor/icons/2x/icon_GUI_tree_arrow_right.png
new file mode 100644
index 0000000000..66331c730a
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_tree_arrow_right.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_unchecked.png b/editor/icons/2x/icon_GUI_unchecked.png
new file mode 100644
index 0000000000..f76b6351d8
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_unchecked.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_vslider_bg.png b/editor/icons/2x/icon_GUI_vslider_bg.png
new file mode 100644
index 0000000000..eeb68e2d7a
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_vslider_bg.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_vsplit_bg.png b/editor/icons/2x/icon_GUI_vsplit_bg.png
new file mode 100644
index 0000000000..09524bd25a
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_vsplit_bg.png
Binary files differ
diff --git a/editor/icons/2x/icon_GUI_vsplitter.png b/editor/icons/2x/icon_GUI_vsplitter.png
new file mode 100644
index 0000000000..84920525b7
--- /dev/null
+++ b/editor/icons/2x/icon_GUI_vsplitter.png
Binary files differ
diff --git a/editor/icons/2x/icon_gui_close_dark.png b/editor/icons/2x/icon_gui_close_dark.png
new file mode 100644
index 0000000000..fe47e003f9
--- /dev/null
+++ b/editor/icons/2x/icon_gui_close_dark.png
Binary files differ
diff --git a/editor/icons/2x/icon_gui_close_light.png b/editor/icons/2x/icon_gui_close_light.png
new file mode 100644
index 0000000000..2d93123f20
--- /dev/null
+++ b/editor/icons/2x/icon_gui_close_light.png
Binary files differ
diff --git a/editor/icons/2x/icon_help.png b/editor/icons/2x/icon_help.png
index f16a34c918..771b815020 100644
--- a/editor/icons/2x/icon_help.png
+++ b/editor/icons/2x/icon_help.png
Binary files differ
diff --git a/editor/icons/2x/icon_help_search.png b/editor/icons/2x/icon_help_search.png
new file mode 100644
index 0000000000..a35c4b6070
--- /dev/null
+++ b/editor/icons/2x/icon_help_search.png
Binary files differ
diff --git a/editor/icons/2x/icon_variant.png b/editor/icons/2x/icon_variant.png
new file mode 100644
index 0000000000..bb8075a069
--- /dev/null
+++ b/editor/icons/2x/icon_variant.png
Binary files differ
diff --git a/editor/icons/icon_GUI_checked.png b/editor/icons/icon_GUI_checked.png
new file mode 100644
index 0000000000..aa5e7f6bdb
--- /dev/null
+++ b/editor/icons/icon_GUI_checked.png
Binary files differ
diff --git a/editor/icons/icon_GUI_dropdown.png b/editor/icons/icon_GUI_dropdown.png
new file mode 100644
index 0000000000..4bd6544830
--- /dev/null
+++ b/editor/icons/icon_GUI_dropdown.png
Binary files differ
diff --git a/editor/icons/icon_GUI_hslider_bg.png b/editor/icons/icon_GUI_hslider_bg.png
new file mode 100644
index 0000000000..1286b887f6
--- /dev/null
+++ b/editor/icons/icon_GUI_hslider_bg.png
Binary files differ
diff --git a/editor/icons/icon_GUI_hsplitter.png b/editor/icons/icon_GUI_hsplitter.png
new file mode 100644
index 0000000000..3ac1dddf90
--- /dev/null
+++ b/editor/icons/icon_GUI_hsplitter.png
Binary files differ
diff --git a/editor/icons/icon_GUI_option_arrow.png b/editor/icons/icon_GUI_option_arrow.png
new file mode 100644
index 0000000000..b7bc38e03f
--- /dev/null
+++ b/editor/icons/icon_GUI_option_arrow.png
Binary files differ
diff --git a/editor/icons/icon_GUI_play_button_group.png b/editor/icons/icon_GUI_play_button_group.png
new file mode 100644
index 0000000000..83820c8e0c
--- /dev/null
+++ b/editor/icons/icon_GUI_play_button_group.png
Binary files differ
diff --git a/editor/icons/icon_GUI_progress_bar.png b/editor/icons/icon_GUI_progress_bar.png
new file mode 100644
index 0000000000..7d70e6beb5
--- /dev/null
+++ b/editor/icons/icon_GUI_progress_bar.png
Binary files differ
diff --git a/editor/icons/icon_GUI_progress_fill.png b/editor/icons/icon_GUI_progress_fill.png
new file mode 100644
index 0000000000..4b7b4c554c
--- /dev/null
+++ b/editor/icons/icon_GUI_progress_fill.png
Binary files differ
diff --git a/editor/icons/icon_GUI_scroll_bg.png b/editor/icons/icon_GUI_scroll_bg.png
new file mode 100644
index 0000000000..1908fd8aee
--- /dev/null
+++ b/editor/icons/icon_GUI_scroll_bg.png
Binary files differ
diff --git a/editor/icons/icon_GUI_scroll_grabber.png b/editor/icons/icon_GUI_scroll_grabber.png
new file mode 100644
index 0000000000..4be7f4e6cc
--- /dev/null
+++ b/editor/icons/icon_GUI_scroll_grabber.png
Binary files differ
diff --git a/editor/icons/icon_GUI_scroll_grabber_hl.png b/editor/icons/icon_GUI_scroll_grabber_hl.png
new file mode 100644
index 0000000000..98e357f82a
--- /dev/null
+++ b/editor/icons/icon_GUI_scroll_grabber_hl.png
Binary files differ
diff --git a/editor/icons/icon_GUI_slider_grabber.png b/editor/icons/icon_GUI_slider_grabber.png
new file mode 100644
index 0000000000..76edc3b81f
--- /dev/null
+++ b/editor/icons/icon_GUI_slider_grabber.png
Binary files differ
diff --git a/editor/icons/icon_GUI_slider_grabber_hl.png b/editor/icons/icon_GUI_slider_grabber_hl.png
new file mode 100644
index 0000000000..97a2f4b67a
--- /dev/null
+++ b/editor/icons/icon_GUI_slider_grabber_hl.png
Binary files differ
diff --git a/editor/icons/icon_GUI_spinbox_updown.png b/editor/icons/icon_GUI_spinbox_updown.png
new file mode 100644
index 0000000000..ff65df801b
--- /dev/null
+++ b/editor/icons/icon_GUI_spinbox_updown.png
Binary files differ
diff --git a/editor/icons/icon_GUI_tab_menu.png b/editor/icons/icon_GUI_tab_menu.png
new file mode 100644
index 0000000000..ffc63f2d41
--- /dev/null
+++ b/editor/icons/icon_GUI_tab_menu.png
Binary files differ
diff --git a/editor/icons/icon_GUI_toggle_off.png b/editor/icons/icon_GUI_toggle_off.png
new file mode 100644
index 0000000000..c4c599172d
--- /dev/null
+++ b/editor/icons/icon_GUI_toggle_off.png
Binary files differ
diff --git a/editor/icons/icon_GUI_toggle_on.png b/editor/icons/icon_GUI_toggle_on.png
new file mode 100644
index 0000000000..9dd6ce7bee
--- /dev/null
+++ b/editor/icons/icon_GUI_toggle_on.png
Binary files differ
diff --git a/editor/icons/icon_GUI_tree_arrow_down.png b/editor/icons/icon_GUI_tree_arrow_down.png
new file mode 100644
index 0000000000..4ef7b41de6
--- /dev/null
+++ b/editor/icons/icon_GUI_tree_arrow_down.png
Binary files differ
diff --git a/editor/icons/icon_GUI_tree_arrow_right.png b/editor/icons/icon_GUI_tree_arrow_right.png
new file mode 100644
index 0000000000..13a42f730d
--- /dev/null
+++ b/editor/icons/icon_GUI_tree_arrow_right.png
Binary files differ
diff --git a/editor/icons/icon_GUI_unchecked.png b/editor/icons/icon_GUI_unchecked.png
new file mode 100644
index 0000000000..8341cdc643
--- /dev/null
+++ b/editor/icons/icon_GUI_unchecked.png
Binary files differ
diff --git a/editor/icons/icon_GUI_vslider_bg.png b/editor/icons/icon_GUI_vslider_bg.png
new file mode 100644
index 0000000000..fa8c6cac1f
--- /dev/null
+++ b/editor/icons/icon_GUI_vslider_bg.png
Binary files differ
diff --git a/editor/icons/icon_GUI_vsplit_bg.png b/editor/icons/icon_GUI_vsplit_bg.png
new file mode 100644
index 0000000000..0c29b1e35c
--- /dev/null
+++ b/editor/icons/icon_GUI_vsplit_bg.png
Binary files differ
diff --git a/editor/icons/icon_GUI_vsplitter.png b/editor/icons/icon_GUI_vsplitter.png
new file mode 100644
index 0000000000..56fb20bc3f
--- /dev/null
+++ b/editor/icons/icon_GUI_vsplitter.png
Binary files differ
diff --git a/editor/icons/icon_gui_close_dark.png b/editor/icons/icon_gui_close_dark.png
new file mode 100644
index 0000000000..8f1d7d8b2c
--- /dev/null
+++ b/editor/icons/icon_gui_close_dark.png
Binary files differ
diff --git a/editor/icons/icon_gui_close_light.png b/editor/icons/icon_gui_close_light.png
new file mode 100644
index 0000000000..b8e3a80e3b
--- /dev/null
+++ b/editor/icons/icon_gui_close_light.png
Binary files differ
diff --git a/editor/icons/icon_help.png b/editor/icons/icon_help.png
index f05b512f4c..d70807000e 100644
--- a/editor/icons/icon_help.png
+++ b/editor/icons/icon_help.png
Binary files differ
diff --git a/editor/icons/icon_help_search.png b/editor/icons/icon_help_search.png
new file mode 100644
index 0000000000..7a1506853e
--- /dev/null
+++ b/editor/icons/icon_help_search.png
Binary files differ
diff --git a/editor/icons/icon_variant.png b/editor/icons/icon_variant.png
index 1ae2812ff7..af7590345e 100644
--- a/editor/icons/icon_variant.png
+++ b/editor/icons/icon_variant.png
Binary files differ
diff --git a/editor/icons/source/icon_GUI_checked.svg b/editor/icons/source/icon_GUI_checked.svg
new file mode 100644
index 0000000000..6d2c03f4c5
--- /dev/null
+++ b/editor/icons/source/icon_GUI_checked.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ sodipodi:docname="checked.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="8.555527"
+ inkscape:cy="7.1886752"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <path
+ style="opacity:1;fill:#e0e0e0;fill-opacity:0.78431374;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4 2 C 2.8954305 2 2 2.8954305 2 4 L 2 12 C 2 13.104569 2.8954305 14 4 14 L 12 14 C 13.104569 14 14 13.104569 14 12 L 14 4 C 14 2.8954305 13.104569 2 12 2 L 4 2 z M 11.292969 4.2929688 L 12.707031 5.7070312 L 6 12.414062 L 3.2929688 9.7070312 L 4.7070312 8.2929688 L 6 9.5859375 L 11.292969 4.2929688 z "
+ transform="translate(0,1036.3623)"
+ id="circle4178" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_dropdown.svg b/editor/icons/source/icon_GUI_dropdown.svg
new file mode 100644
index 0000000000..f313b09983
--- /dev/null
+++ b/editor/icons/source/icon_GUI_dropdown.svg
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="8"
+ height="14"
+ viewBox="0 0 8 14"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="icon_GUI_dropdown.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254834"
+ inkscape:cx="1.2944669"
+ inkscape:cy="5.9830116"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1038.3622)">
+ <circle
+ style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
+ id="path4268"
+ cx="4.5"
+ cy="1040.8622"
+ r="1.5" />
+ <circle
+ r="1.5"
+ cy="1045.8622"
+ cx="4.5"
+ id="circle4271"
+ style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686" />
+ <circle
+ style="fill:#ffffff;fill-opacity:0.58823532;stroke-width:2;stroke-linejoin:round;stroke-opacity:0.39215686"
+ id="circle4273"
+ cx="4.5"
+ cy="1050.8622"
+ r="1.5" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_hslider_bg.svg b/editor/icons/source/icon_GUI_hslider_bg.svg
new file mode 100644
index 0000000000..a920bf34ab
--- /dev/null
+++ b/editor/icons/source/icon_GUI_hslider_bg.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_hslider_bg.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/2x/icon_hslider_bg.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="5.4823689"
+ inkscape:cy="7.6591052"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <rect
+ style="fill:#000000;fill-opacity:0.39215687;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902"
+ id="rect4266"
+ width="14"
+ height="6"
+ x="1"
+ y="1041.3623"
+ ry="0" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_hsplitter.svg b/editor/icons/source/icon_GUI_hsplitter.svg
new file mode 100644
index 0000000000..01c893fc56
--- /dev/null
+++ b/editor/icons/source/icon_GUI_hsplitter.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="8"
+ height="64"
+ viewBox="0 0 8 64"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="hsplitter.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="11.313709"
+ inkscape:cx="-2.0338296"
+ inkscape:cy="39.22669"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-988.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 4,990.3622 v 60"
+ id="path814"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_option_arrow.svg b/editor/icons/source/icon_GUI_option_arrow.svg
new file mode 100644
index 0000000000..5cd943e9e3
--- /dev/null
+++ b/editor/icons/source/icon_GUI_option_arrow.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="option_arrow.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254834"
+ inkscape:cx="3.1667338"
+ inkscape:cy="5.9875884"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3622)">
+ <path
+ inkscape:connector-curvature="0"
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 9.9999996,1043.3583 c -0.2637796,0.01 -0.5144012,0.1165 -0.697265,0.3067 l -3.292969,3.2929 -3.2929688,-3.2929 C 2.5285367,1043.4714 2.2700113,1043.3622 2,1043.3622 c -0.8974208,2e-4 -1.34038281,1.0909 -0.6972656,1.7168 l 4,4 c 0.3905299,0.3904 1.0235325,0.3904 1.4140624,0 l 4.0000002,-4 c 0.657344,-0.6321 0.194906,-1.7422 -0.7167974,-1.7207 z"
+ id="path4484"
+ sodipodi:nodetypes="cccccccccc" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_play_button_group.svg b/editor/icons/source/icon_GUI_play_button_group.svg
new file mode 100644
index 0000000000..84bdb00505
--- /dev/null
+++ b/editor/icons/source/icon_GUI_play_button_group.svg
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="32"
+ height="32"
+ viewBox="0 0 32 31.999998"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ sodipodi:docname="button_group.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_disabled.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="16"
+ inkscape:cx="15.144473"
+ inkscape:cy="14.499068"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1020.3623)">
+ <circle
+ style="fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:2.54545379;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path4503"
+ cx="16"
+ cy="1036.3623"
+ r="13.999995" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_progress_bar.svg b/editor/icons/source/icon_GUI_progress_bar.svg
new file mode 100644
index 0000000000..1edd33dd85
--- /dev/null
+++ b/editor/icons/source/icon_GUI_progress_bar.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_progress_bar.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="11.875071"
+ inkscape:cy="9.2973804"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.39215687;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 2,1036.3623 c -1.09070018,-2e-4 -2,0.9073 -2,1.998 v 12.002 c 0,1.0907 0.9092998,2 2,2 h 12 c 1.0907,0 2,-0.9093 2,-2 v -12 c 0,-1.0907 -0.9093,-1.9978 -2,-1.998 z m 0,2 12,0 v 11.998 H 2 Z"
+ id="path4310"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="sssssssssccccc" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_progress_fill.svg b/editor/icons/source/icon_GUI_progress_fill.svg
new file mode 100644
index 0000000000..cf55c55ab1
--- /dev/null
+++ b/editor/icons/source/icon_GUI_progress_fill.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_progress_fill.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254834"
+ inkscape:cx="10.136535"
+ inkscape:cy="8.7983986"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <rect
+ style="fill:#e0e0e0;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
+ id="rect4338"
+ width="8"
+ height="7.9999952"
+ x="4"
+ y="1040.3623"
+ ry="0.99999499" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_scroll_bg.svg b/editor/icons/source/icon_GUI_scroll_bg.svg
new file mode 100644
index 0000000000..29604b9e14
--- /dev/null
+++ b/editor/icons/source/icon_GUI_scroll_bg.svg
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 11.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ sodipodi:docname="scroll_bg.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254836"
+ inkscape:cx="4.4464273"
+ inkscape:cy="6.9717582"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3623)" />
+</svg>
diff --git a/editor/icons/source/icon_GUI_scroll_grabber.svg b/editor/icons/source/icon_GUI_scroll_grabber.svg
new file mode 100644
index 0000000000..b9d2bbbec0
--- /dev/null
+++ b/editor/icons/source/icon_GUI_scroll_grabber.svg
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 11.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ sodipodi:docname="scroll_grabber.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254836"
+ inkscape:cx="1.3086411"
+ inkscape:cy="6.9275641"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3623)">
+ <circle
+ style="opacity:1;fill:#ffffff;fill-opacity:0.27450982;stroke:none;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path4239"
+ cx="6"
+ cy="1046.3623"
+ r="2" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_scroll_grabber_hl.svg b/editor/icons/source/icon_GUI_scroll_grabber_hl.svg
new file mode 100644
index 0000000000..ce9a66c5bc
--- /dev/null
+++ b/editor/icons/source/icon_GUI_scroll_grabber_hl.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 11.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 unknown"
+ sodipodi:docname="icon_scroll_grabber_hl.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/icon_scroll_grabber_hl.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254836"
+ inkscape:cx="3.0874565"
+ inkscape:cy="5.7564185"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1097"
+ inkscape:window-height="1076"
+ inkscape:window-x="161"
+ inkscape:window-y="200"
+ inkscape:window-maximized="0"
+ inkscape:snap-nodes="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3623)">
+ <circle
+ style="opacity:1;fill:#f9f9f9;fill-opacity:0.73000002;stroke:none;stroke-width:2.24999642;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="path4239"
+ cx="6"
+ cy="1046.3623"
+ r="2.9999952"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/icon_scroll_grabber_hl.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_slider_grabber.svg b/editor/icons/source/icon_GUI_slider_grabber.svg
new file mode 100644
index 0000000000..fb6c9d1c5c
--- /dev/null
+++ b/editor/icons/source/icon_GUI_slider_grabber.svg
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_slider_grabber.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="4.462853"
+ inkscape:cy="8.2694974"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <circle
+ style="fill:#ffffff;fill-opacity:0.78431374;stroke-width:2.99999523;stroke-linejoin:round;stroke-opacity:0.39215686"
+ id="path4266"
+ cx="8"
+ cy="1044.3623"
+ r="2.9999952" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_slider_grabber_hl.svg b/editor/icons/source/icon_GUI_slider_grabber_hl.svg
new file mode 100644
index 0000000000..c7e9018ac3
--- /dev/null
+++ b/editor/icons/source/icon_GUI_slider_grabber_hl.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_slider_grabber_hl.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="9.784247"
+ inkscape:cy="7.9005685"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <path
+ style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 8 1 A 6.9999943 6.9999943 0 0 0 1 8 A 6.9999943 6.9999943 0 0 0 8 15 A 6.9999943 6.9999943 0 0 0 15 8 A 6.9999943 6.9999943 0 0 0 8 1 z M 8 3 A 4.9999943 4.9999943 0 0 1 8.5 3.0253906 A 4.9999943 4.9999943 0 0 1 8.9941406 3.0996094 A 4.9999943 4.9999943 0 0 1 9.4785156 3.2226562 A 4.9999943 4.9999943 0 0 1 9.9472656 3.3945312 A 4.9999943 4.9999943 0 0 1 10.396484 3.6113281 A 4.9999943 4.9999943 0 0 1 10.822266 3.8730469 A 4.9999943 4.9999943 0 0 1 11.220703 4.1757812 A 4.9999943 4.9999943 0 0 1 11.585938 4.515625 A 4.9999943 4.9999943 0 0 1 11.916016 4.8925781 A 4.9999943 4.9999943 0 0 1 12.207031 5.2988281 A 4.9999943 4.9999943 0 0 1 12.455078 5.7324219 A 4.9999943 4.9999943 0 0 1 12.660156 6.1875 A 4.9999943 4.9999943 0 0 1 12.818359 6.6621094 A 4.9999943 4.9999943 0 0 1 12.927734 7.1503906 A 4.9999943 4.9999943 0 0 1 12.988281 7.6464844 A 4.9999943 4.9999943 0 0 1 13 8 A 4.9999943 4.9999943 0 0 1 12.974609 8.5 A 4.9999943 4.9999943 0 0 1 12.900391 8.9941406 A 4.9999943 4.9999943 0 0 1 12.777344 9.4785156 A 4.9999943 4.9999943 0 0 1 12.605469 9.9472656 A 4.9999943 4.9999943 0 0 1 12.388672 10.396484 A 4.9999943 4.9999943 0 0 1 12.126953 10.822266 A 4.9999943 4.9999943 0 0 1 11.824219 11.220703 A 4.9999943 4.9999943 0 0 1 11.484375 11.585938 A 4.9999943 4.9999943 0 0 1 11.107422 11.916016 A 4.9999943 4.9999943 0 0 1 10.701172 12.207031 A 4.9999943 4.9999943 0 0 1 10.267578 12.455078 A 4.9999943 4.9999943 0 0 1 9.8125 12.660156 A 4.9999943 4.9999943 0 0 1 9.3378906 12.818359 A 4.9999943 4.9999943 0 0 1 8.8496094 12.927734 A 4.9999943 4.9999943 0 0 1 8.3535156 12.988281 A 4.9999943 4.9999943 0 0 1 8 13 A 4.9999943 4.9999943 0 0 1 7.5 12.974609 A 4.9999943 4.9999943 0 0 1 7.0058594 12.900391 A 4.9999943 4.9999943 0 0 1 6.5214844 12.777344 A 4.9999943 4.9999943 0 0 1 6.0527344 12.605469 A 4.9999943 4.9999943 0 0 1 5.6035156 12.388672 A 4.9999943 4.9999943 0 0 1 5.1777344 12.126953 A 4.9999943 4.9999943 0 0 1 4.7792969 11.824219 A 4.9999943 4.9999943 0 0 1 4.4140625 11.484375 A 4.9999943 4.9999943 0 0 1 4.0839844 11.107422 A 4.9999943 4.9999943 0 0 1 3.7929688 10.701172 A 4.9999943 4.9999943 0 0 1 3.5449219 10.267578 A 4.9999943 4.9999943 0 0 1 3.3398438 9.8125 A 4.9999943 4.9999943 0 0 1 3.1816406 9.3378906 A 4.9999943 4.9999943 0 0 1 3.0722656 8.8496094 A 4.9999943 4.9999943 0 0 1 3.0117188 8.3535156 A 4.9999943 4.9999943 0 0 1 3 8 A 4.9999943 4.9999943 0 0 1 3.0253906 7.5 A 4.9999943 4.9999943 0 0 1 3.0996094 7.0058594 A 4.9999943 4.9999943 0 0 1 3.2226562 6.5214844 A 4.9999943 4.9999943 0 0 1 3.3945312 6.0527344 A 4.9999943 4.9999943 0 0 1 3.6113281 5.6035156 A 4.9999943 4.9999943 0 0 1 3.8730469 5.1777344 A 4.9999943 4.9999943 0 0 1 4.1757812 4.7792969 A 4.9999943 4.9999943 0 0 1 4.515625 4.4140625 A 4.9999943 4.9999943 0 0 1 4.8925781 4.0839844 A 4.9999943 4.9999943 0 0 1 5.2988281 3.7929688 A 4.9999943 4.9999943 0 0 1 5.7324219 3.5449219 A 4.9999943 4.9999943 0 0 1 6.1875 3.3398438 A 4.9999943 4.9999943 0 0 1 6.6621094 3.1816406 A 4.9999943 4.9999943 0 0 1 7.1503906 3.0722656 A 4.9999943 4.9999943 0 0 1 7.6464844 3.0117188 A 4.9999943 4.9999943 0 0 1 8 3 z "
+ id="circle4262"
+ transform="translate(0,1036.3623)" />
+ <circle
+ style="fill:#ffffff;fill-opacity:0.58823529;stroke-width:2.99999523;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902"
+ id="path4271"
+ cx="8"
+ cy="1044.3623"
+ r="2.9999952" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_spinbox_updown.svg b/editor/icons/source/icon_GUI_spinbox_updown.svg
new file mode 100644
index 0000000000..e29d7fe0d2
--- /dev/null
+++ b/editor/icons/source/icon_GUI_spinbox_updown.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="spinbox_updown.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="16"
+ inkscape:cx="-1.901723"
+ inkscape:cy="9.1326297"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1-5"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 7.984375 1.0019531 A 1.0001 1.0001 0 0 0 7.2929688 1.2929688 L 3.2929688 5.2929688 A 1.0001 1.0001 0 1 0 4.7070312 6.7070312 L 8 3.4140625 L 11.292969 6.7070312 A 1.0001 1.0001 0 1 0 12.707031 5.2929688 L 8.7070312 1.2929688 A 1.0001 1.0001 0 0 0 7.984375 1.0019531 z M 11.990234 8.9863281 A 1.0001 1.0001 0 0 0 11.292969 9.2929688 L 8 12.585938 L 4.7070312 9.2929688 A 1.0001 1.0001 0 0 0 3.9902344 8.9902344 A 1.0001 1.0001 0 0 0 3.2929688 10.707031 L 7.2929688 14.707031 A 1.0001 1.0001 0 0 0 8.7070312 14.707031 L 12.707031 10.707031 A 1.0001 1.0001 0 0 0 11.990234 8.9863281 z "
+ transform="translate(0,1036.3622)"
+ id="path4484" />
+ <g
+ id="layer1-5"
+ inkscape:label="Layer 1"
+ transform="translate(14.210182,-5.3664)" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_tab_menu.svg b/editor/icons/source/icon_GUI_tab_menu.svg
new file mode 100644
index 0000000000..39e0d1f261
--- /dev/null
+++ b/editor/icons/source/icon_GUI_tab_menu.svg
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="tab_menu.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32.000001"
+ inkscape:cx="4.0814179"
+ inkscape:cy="8.4695645"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <circle
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
+ id="path819"
+ cx="8"
+ cy="1038.3622"
+ r="2" />
+ <circle
+ r="2"
+ cy="1044.3622"
+ cx="8"
+ id="circle821"
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118" />
+ <circle
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
+ id="circle823"
+ cx="8"
+ cy="1050.3622"
+ r="2" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_toggle_off.svg b/editor/icons/source/icon_GUI_toggle_off.svg
new file mode 100644
index 0000000000..f0cf10a653
--- /dev/null
+++ b/editor/icons/source/icon_GUI_toggle_off.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="64"
+ height="32"
+ viewBox="0 0 64 31.999998"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_toggle_off.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/2x/icon_hslider_bg.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="16"
+ inkscape:cx="35.349571"
+ inkscape:cy="18.723365"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1020.3623)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter-blend-mode:normal;filter-gaussianBlur-deviation:0;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;opacity:1"
+ d="M 24 4.0019531 C 17.3693 4.0019531 12 9.3673469 12 15.998047 L 12 16.001953 C 12 22.632653 17.3693 28.001953 24 28.001953 L 40 28.001953 C 46.6307 28.001953 52 22.632653 52 16.001953 L 52 15.998047 C 52 9.3673469 46.6307 4.0019531 40 4.0019531 L 24 4.0019531 z M 24 6.0019531 L 40 6.0019531 C 45.557295 6.0019531 50 10.440747 50 15.998047 L 50 16.001953 C 50 21.559253 45.557295 26.001953 40 26.001953 L 24 26.001953 C 18.442705 26.001953 14 21.559253 14 16.001953 L 14 15.998047 C 14 10.440747 18.442705 6.0019531 24 6.0019531 z M 31 10.998047 A 1.0001 1.0001 0 0 0 30 11.998047 L 30 19.998047 A 1 1 0 0 0 31 20.998047 A 1 1 0 0 0 32 19.998047 L 32 16.998047 L 34 16.998047 A 1 1 0 0 0 35 15.998047 A 1 1 0 0 0 34 14.998047 L 32 14.998047 L 32 12.998047 L 36 12.998047 A 1 1 0 0 0 37 11.998047 A 1 1 0 0 0 36 10.998047 L 31 10.998047 z M 40 10.998047 A 1.0001 1.0001 0 0 0 39 11.998047 L 39 15.998047 L 39 19.998047 A 1 1 0 0 0 40 20.998047 A 1 1 0 0 0 41 19.998047 L 41 16.998047 L 43 16.998047 A 1 1 0 0 0 44 15.998047 A 1 1 0 0 0 43 14.998047 L 41 14.998047 L 41 12.998047 L 45 12.998047 A 1 1 0 0 0 46 11.998047 A 1 1 0 0 0 45 10.998047 L 40 10.998047 z M 23 11.001953 C 20.250421 11.001953 18 13.252353 18 16.001953 C 18 18.751553 20.250421 21.001953 23 21.001953 C 25.749579 21.001953 28 18.751553 28 16.001953 C 28 13.252353 25.749579 11.001953 23 11.001953 z M 23 13.001953 C 24.668699 13.001953 26 14.333253 26 16.001953 C 26 17.670653 24.668699 19.001953 23 19.001953 C 21.331301 19.001953 20 17.670653 20 16.001953 C 20 14.333253 21.331301 13.001953 23 13.001953 z "
+ transform="translate(0,1020.3623)"
+ id="path4442" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_toggle_on.svg b/editor/icons/source/icon_GUI_toggle_on.svg
new file mode 100644
index 0000000000..79715dd767
--- /dev/null
+++ b/editor/icons/source/icon_GUI_toggle_on.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="64"
+ height="32"
+ viewBox="0 0 64 31.999998"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_toggle_on.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/2x/icon_hslider_bg.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="8"
+ inkscape:cx="32.275235"
+ inkscape:cy="18.558884"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1020.3623)">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 24 4.0019531 C 17.3693 4.0019531 12 9.3673469 12 15.998047 C 12 22.628747 17.3693 27.998047 24 27.998047 L 40 27.998047 C 46.6307 27.998047 52 22.628747 52 15.998047 C 52 9.3673469 46.6307 4.0019531 40 4.0019531 L 24 4.0019531 z M 41 10.998047 A 1 1 0 0 1 42 11.998047 L 42 19.998047 A 1.0001 1.0001 0 0 1 40.248047 20.660156 L 35 14.660156 L 35 19.998047 A 1 1 0 0 1 34 20.998047 A 1 1 0 0 1 33 19.998047 L 33 11.998047 A 1.0001 1.0001 0 0 1 34.751953 11.339844 L 40 17.339844 L 40 11.998047 A 1 1 0 0 1 41 10.998047 z M 26 11.001953 C 28.749579 11.001953 31 13.252353 31 16.001953 C 31 18.751553 28.749579 21.001953 26 21.001953 C 23.250421 21.001953 21 18.751553 21 16.001953 C 21 13.252353 23.250421 11.001953 26 11.001953 z M 26 13.001953 C 24.331301 13.001953 23 14.333253 23 16.001953 C 23 17.670653 24.331301 19.001953 26 19.001953 C 27.668699 19.001953 29 17.670653 29 16.001953 C 29 14.333253 27.668699 13.001953 26 13.001953 z "
+ transform="translate(0,1020.3623)"
+ id="path4272" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_tree_arrow_down.svg b/editor/icons/source/icon_GUI_tree_arrow_down.svg
new file mode 100644
index 0000000000..1dd209720f
--- /dev/null
+++ b/editor/icons/source/icon_GUI_tree_arrow_down.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="arrow_down.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627417"
+ inkscape:cx="1.7981958"
+ inkscape:cy="7.5815407"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
+ d="m 3,1045.3622 3,3 3,-3"
+ id="path814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_tree_arrow_right.svg b/editor/icons/source/icon_GUI_tree_arrow_right.svg
new file mode 100644
index 0000000000..43134ba1b1
--- /dev/null
+++ b/editor/icons/source/icon_GUI_tree_arrow_right.svg
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="arrow_right.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254836"
+ inkscape:cx="4.0845752"
+ inkscape:cy="5.8802612"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
+ d="m 4,1049.3622 3.0000202,-3 -3.0000202,-3"
+ id="path814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_unchecked.svg b/editor/icons/source/icon_GUI_unchecked.svg
new file mode 100644
index 0000000000..053cbe6de5
--- /dev/null
+++ b/editor/icons/source/icon_GUI_unchecked.svg
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ sodipodi:docname="unchecked.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/unchecked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="4.8224661"
+ inkscape:cy="8.2065809"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <path
+ style="opacity:1;fill:#e0e0e0;fill-opacity:0.78431374;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="M 4 2 A 2 2 0 0 0 2 4 L 2 12 A 2 2 0 0 0 4 14 L 12 14 A 2 2 0 0 0 14 12 L 14 4 A 2 2 0 0 0 12 2 L 4 2 z M 4.8007812 4 L 11.199219 4 A 0.8000012 0.8000012 0 0 1 12 4.8007812 L 12 11.199219 A 0.8000012 0.8000012 0 0 1 11.199219 12 L 4.8007812 12 A 0.8000012 0.8000012 0 0 1 4 11.199219 L 4 4.8007812 A 0.8000012 0.8000012 0 0 1 4.8007812 4 z "
+ transform="translate(0,1036.3623)"
+ id="circle4178" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_vslider_bg.svg b/editor/icons/source/icon_GUI_vslider_bg.svg
new file mode 100644
index 0000000000..cfa4feeca6
--- /dev/null
+++ b/editor/icons/source/icon_GUI_vslider_bg.svg
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 15.999999"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ sodipodi:docname="icon_GUI_vslider_bg.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="8.3954629"
+ inkscape:cy="7.6047847"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3623)">
+ <rect
+ style="fill:#000000;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902;fill-opacity:0.39215687"
+ id="rect4267"
+ width="4"
+ height="14"
+ x="6"
+ y="1037.3623"
+ ry="0" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_vsplit_bg.svg b/editor/icons/source/icon_GUI_vsplit_bg.svg
new file mode 100644
index 0000000000..e11940cf53
--- /dev/null
+++ b/editor/icons/source/icon_GUI_vsplit_bg.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="8"
+ height="8"
+ viewBox="0 0 8 7.9999995"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="vsplit_bg.svg"
+ inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="64.000003"
+ inkscape:cx="-1.1524794"
+ inkscape:cy="3.8847002"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4136"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1044.3623)">
+ <rect
+ style="opacity:1;fill:#000000;fill-opacity:0.09803922;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect4213"
+ width="8"
+ height="7.999999"
+ x="0"
+ y="1044.3623" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_GUI_vsplitter.svg b/editor/icons/source/icon_GUI_vsplitter.svg
new file mode 100644
index 0000000000..80f7c2ce12
--- /dev/null
+++ b/editor/icons/source/icon_GUI_vsplitter.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="64"
+ height="8"
+ viewBox="0 0 64 8"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="vsplitter.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32.000001"
+ inkscape:cx="59.744611"
+ inkscape:cy="0.46378871"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1600"
+ inkscape:window-height="836"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1044.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 2,1048.3622 H 62"
+ id="path814"
+ inkscape:connector-curvature="0" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_gui_close_dark.svg b/editor/icons/source/icon_gui_close_dark.svg
new file mode 100644
index 0000000000..ccb4239784
--- /dev/null
+++ b/editor/icons/source/icon_gui_close_dark.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="icon_gui_close_dark.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32.000001"
+ inkscape:cx="5.2641929"
+ inkscape:cy="7.5472551"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="fill:#000000;fill-opacity:0.89803922;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 3.7578125 2.34375 L 2.34375 3.7578125 L 6.5859375 8 L 2.34375 12.242188 L 3.7578125 13.65625 L 8 9.4140625 L 12.242188 13.65625 L 13.65625 12.242188 L 9.4140625 8 L 13.65625 3.7578125 L 12.242188 2.34375 L 8 6.5859375 L 3.7578125 2.34375 z "
+ transform="translate(0,1036.3622)"
+ id="rect4137" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_gui_close_light.svg b/editor/icons/source/icon_gui_close_light.svg
new file mode 100644
index 0000000000..90d811965b
--- /dev/null
+++ b/editor/icons/source/icon_gui_close_light.svg
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="icon_gui_close_light.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32.000001"
+ inkscape:cx="5.2641929"
+ inkscape:cy="7.5472551"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="fill:#ffffff;fill-opacity:0.89803922;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 3.7578125 2.34375 L 2.34375 3.7578125 L 6.5859375 8 L 2.34375 12.242188 L 3.7578125 13.65625 L 8 9.4140625 L 12.242188 13.65625 L 13.65625 12.242188 L 9.4140625 8 L 13.65625 3.7578125 L 12.242188 2.34375 L 8 6.5859375 L 3.7578125 2.34375 z "
+ transform="translate(0,1036.3622)"
+ id="rect4137" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_help.svg b/editor/icons/source/icon_help.svg
index 01e85e0f55..cc8517d2d1 100644
--- a/editor/icons/source/icon_help.svg
+++ b/editor/icons/source/icon_help.svg
@@ -14,7 +14,7 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92+devel unknown"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_help.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="31.999999"
- inkscape:cx="5.4018713"
- inkscape:cy="8.2308388"
+ inkscape:cx="9.7940153"
+ inkscape:cy="7.5068869"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -46,7 +46,8 @@
inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
- inkscape:window-maximized="1">
+ inkscape:window-maximized="1"
+ inkscape:document-rotation="0">
<inkscape:grid
type="xygrid"
id="grid3336" />
@@ -59,7 +60,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
+ <dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
@@ -69,42 +70,9 @@
id="layer1"
transform="translate(0,-1036.3622)">
<path
- style="opacity:1;fill:#f1f1f1;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="M 8 1 A 7 7 0 0 0 1 8 A 7 7 0 0 0 8 15 A 7 7 0 0 0 15 8 A 7 7 0 0 0 8 1 z M 8 4 A 4.0000172 4.0000172 0 0 1 12 8 A 4.0000172 4.0000172 0 0 1 8 12 A 4.0000172 4.0000172 0 0 1 4 8 A 4.0000172 4.0000172 0 0 1 8 4 z "
+ style="fill:#e0e0e0;fill-opacity:0.58823532;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902"
+ d="M 5.0292969 1 C 4.0296094 0.989075 3.0196929 1.31165 2 2 L 2 9 C 4.0172141 7.6471 6.0167145 7.6864 8 9 C 9.9832855 7.6864 11.982786 7.6471 14 9 L 14 2 C 12.980307 1.31165 11.970391 0.989075 10.970703 1 C 10.309402 1.007227 9.6532285 1.1734956 9 1.4628906 L 9 6 L 8 6 L 8 2 C 7.0184429 1.35535 6.0289844 1.010925 5.0292969 1 z M 0 10 L 0 16 L 2 16 A 3 3 0 0 0 5 13 A 3 3 0 0 0 2 10 L 0 10 z M 5 13 A 3 3 0 0 0 8 16 A 3 3 0 0 0 11 13 A 3 3 0 0 0 8 10 A 3 3 0 0 0 5 13 z M 11 13 A 3 3 0 0 0 14 16 L 15 16 L 15 14 L 14 14 A 1.0000174 1.0000174 0 0 1 13 13 A 1.0000174 1.0000174 0 0 1 14 12 L 15 12 L 15 10 L 14 10 A 3 3 0 0 0 11 13 z M 2 12 A 1 1 0 0 1 3 13 A 1 1 0 0 1 2 14 L 2 12 z M 8 12 A 1.0000174 1.0000174 0 0 1 9 13 A 1.0000174 1.0000174 0 0 1 8 14 A 1.0000174 1.0000174 0 0 1 7 13 A 1.0000174 1.0000174 0 0 1 8 12 z "
transform="translate(0,1036.3622)"
- id="circle4160" />
- <path
- style="opacity:1;fill:#ff8484;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="m 8,1 0,3 c 1.1045715,-4.8e-6 2.104267,0.4480167 2.828125,1.171875 L 12.949219,3.0507812 C 11.68247,1.7840321 9.9329986,1.0000047 8,1 Z"
- transform="translate(0,1036.3622)"
- id="circle4154"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- inkscape:transform-center-x="-2.4746095"
- inkscape:transform-center-y="-4.9140625" />
- <path
- inkscape:transform-center-y="2.4746"
- inkscape:transform-center-x="-4.9140625"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path4163"
- d="m 15,1044.3622 -3,0 c 5e-6,1.1046 -0.448017,2.1043 -1.171875,2.8281 l 2.121094,2.1211 c 1.266749,-1.2667 2.050776,-3.0162 2.050781,-4.9492 z"
- style="opacity:1;fill:#ff8484;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
- <path
- style="opacity:1;fill:#ff8484;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="m 8,1051.3622 0,-3 c -1.1046,0 -2.1043,-0.448 -2.8281,-1.1719 l -2.1211,2.1211 c 1.2667,1.2668 3.0162,2.0508 4.9492,2.0508 z"
- id="path4165"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccc"
- inkscape:transform-center-x="2.4746"
- inkscape:transform-center-y="4.91405" />
- <path
- inkscape:transform-center-y="-2.4746"
- inkscape:transform-center-x="4.91405"
- sodipodi:nodetypes="ccccc"
- inkscape:connector-curvature="0"
- id="path4167"
- d="m 1,1044.3622 3,0 c 0,-1.1046 0.448,-2.1043 1.1719,-2.8281 L 3.0508,1039.413 C 1.784,1040.6797 1,1042.4292 1,1044.3622 Z"
- style="opacity:1;fill:#ff8484;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ id="path4270" />
</g>
</svg>
diff --git a/editor/icons/source/icon_help_search.svg b/editor/icons/source/icon_help_search.svg
new file mode 100644
index 0000000000..ab914c0c64
--- /dev/null
+++ b/editor/icons/source/icon_help_search.svg
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_help.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:docname="icon_help_search.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627417"
+ inkscape:cx="10.167683"
+ inkscape:cy="7.1383117"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="fill:#e0e0e0;fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902"
+ d="m 0,10 v 6 H 2 C 3.6568542,16 5,14.656854 5,13 5,11.343146 3.6568542,10 2,10 Z m 5,3 c 0,1.656854 1.3431458,3 3,3 1.6568542,0 3,-1.343146 3,-3 0,-1.656854 -1.3431458,-3 -3,-3 -1.6568542,0 -3,1.343146 -3,3 z m 6,0 c 0,1.656854 1.343146,3 3,3 h 1 v -2 h -1 c -0.552281,-10e-6 -0.99999,-0.447719 -1,-1 10e-6,-0.552281 0.447719,-0.99999 1,-1 h 1 v -2 h -1 c -1.656854,0 -3,1.343146 -3,3 z M 2,12 c 0.5522847,0 1,0.447715 1,1 0,0.552285 -0.4477153,1 -1,1 z m 6,0 c 0.5522808,10e-6 0.9999904,0.447719 1,1 -9.6e-6,0.552281 -0.4477192,0.99999 -1,1 -0.5522808,-10e-6 -0.9999904,-0.447719 -1,-1 9.6e-6,-0.552281 0.4477192,-0.99999 1,-1 z"
+ transform="translate(0,1036.3622)"
+ id="path4270"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccssscssssssscccccccsscsccccccc" />
+ <path
+ style="fill:#e0e0e0;fill-opacity:1;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.3254902"
+ d="m 9,1036.3622 a 4,4 0 0 0 -4,4 4,4 0 0 0 4,4 4,4 0 0 0 4,-4 4,4 0 0 0 -4,-4 z m 0,2 a 2.0000174,2.0000174 0 0 1 2,2 2.0000174,2.0000174 0 0 1 -2,2 2.0000174,2.0000174 0 0 1 -2,-2 2.0000174,2.0000174 0 0 1 2,-2 z"
+ id="path4285"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 7,1042.3622 -3,3"
+ id="path4290"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cc" />
+ </g>
+</svg>
diff --git a/editor/icons/source/icon_variant.svg b/editor/icons/source/icon_variant.svg
new file mode 100644
index 0000000000..d966190ab0
--- /dev/null
+++ b/editor/icons/source/icon_variant.svg
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92+devel unknown"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="icon_variant.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627418"
+ inkscape:cx="12.635414"
+ inkscape:cy="11.860443"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:snap-midpoints="true"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true"
+ inkscape:document-rotation="0">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <g
+ transform="translate(0,-3)"
+ id="layer1-5"
+ inkscape:label="Layer 1"
+ style="fill:#e0e0e0;fill-opacity:1">
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4320"
+ width="2"
+ height="5.9999666"
+ x="3"
+ y="1044.3622" />
+ <rect
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4324"
+ width="2"
+ height="5.9999843"
+ x="6"
+ y="1044.3622" />
+ <rect
+ y="1044.3622"
+ x="3"
+ height="2.0000174"
+ width="1"
+ id="rect4326"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3,1044.3622 a 3,3 0 0 0 -3,3 h 2 a 1.0000174,1.0000174 0 0 1 1,-1 z"
+ id="path4328"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path4330"
+ d="m 14,1050.3622 a 3,3 0 0 1 -3,-3 h 2 a 1.0000174,1.0000174 0 0 0 1,1 z"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ inkscape:connector-curvature="0" />
+ <rect
+ transform="scale(1,-1)"
+ y="-1052.3622"
+ x="14"
+ height="7.9999843"
+ width="2"
+ id="rect4334"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="scale(1,-1)"
+ y="-1047.3622"
+ x="11"
+ height="2.9999826"
+ width="2"
+ id="rect4338"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4340"
+ d="m 3,1050.3622 a 3,3 0 0 1 -3,-3 h 2 a 1.0000174,1.0000174 0 0 0 1,1 z"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4342"
+ d="m 8,1044.3622 a 3,3 0 0 1 3,3 H 9 a 1.0000174,1.0000174 0 0 0 -1,-1 z"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="1047.3622"
+ x="9"
+ height="3.0000174"
+ width="2"
+ id="rect4344"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </g>
+ </g>
+</svg>
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 4a2f37e319..9bb598ec92 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -31,82 +31,206 @@
#include "io/resource_saver.h"
#include "os/file_access.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/spatial.h"
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
-String ResourceImporterOBJ::get_importer_name() const {
+uint32_t EditorOBJImporter::get_import_flags() const {
- return "obj_mesh";
+ return IMPORT_SCENE;
}
+void EditorOBJImporter::get_extensions(List<String> *r_extensions) const {
-String ResourceImporterOBJ::get_visible_name() const {
-
- return "OBJ As Mesh";
+ r_extensions->push_back("obj");
}
-void ResourceImporterOBJ::get_recognized_extensions(List<String> *p_extensions) const {
- p_extensions->push_back("obj");
-}
-String ResourceImporterOBJ::get_save_extension() const {
- return "mesh";
-}
+Error EditorOBJImporter::_parse_material_library(const String &p_path, Map<String, Ref<SpatialMaterial> > &material_map, List<String> *r_missing_deps) {
-String ResourceImporterOBJ::get_resource_type() const {
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
- return "ArrayMesh";
-}
+ Ref<SpatialMaterial> current;
+ String current_name;
+ String base_path = p_path.get_base_dir();
+ while (true) {
-bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+ String l = f->get_line().strip_edges();
- return true;
-}
+ if (l.begins_with("newmtl ")) {
+ //vertex
-int ResourceImporterOBJ::get_preset_count() const {
- return 0;
-}
-String ResourceImporterOBJ::get_preset_name(int p_idx) const {
+ current_name = l.replace("newmtl", "").strip_edges();
+ current.instance();
+ material_map[current_name] = current;
+ } else if (l.begins_with("Ka ")) {
+ //uv
+ print_line("Warning: Ambient light for material '" + current_name + "' is ignored in PBR");
- return String();
-}
+ } else if (l.begins_with("Kd ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+ Vector<String> v = l.split(" ", false);
+ ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
+ Color c = current->get_albedo();
+ c.r = v[1].to_float();
+ c.g = v[2].to_float();
+ c.b = v[3].to_float();
+ current->set_albedo(c);
+ } else if (l.begins_with("Ks ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+ Vector<String> v = l.split(" ", false);
+ ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
+ float r = v[1].to_float();
+ float g = v[2].to_float();
+ float b = v[3].to_float();
+ float metalness = MAX(r, MAX(g, b));
+ current->set_metallic(metalness);
+ } else if (l.begins_with("Ns ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+ Vector<String> v = l.split(" ", false);
+ ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
+ float s = v[1].to_float();
+ current->set_metallic((1000.0 - s) / 1000.0);
+ } else if (l.begins_with("d ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+ Vector<String> v = l.split(" ", false);
+ ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
+ float d = v[1].to_float();
+ Color c = current->get_albedo();
+ c.a = d;
+ current->set_albedo(c);
+ if (c.a < 0.99) {
+ current->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ }
+ } else if (l.begins_with("Tr ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+ Vector<String> v = l.split(" ", false);
+ ERR_FAIL_COND_V(v.size() != 2, ERR_INVALID_DATA);
+ float d = v[1].to_float();
+ Color c = current->get_albedo();
+ c.a = 1.0 - d;
+ current->set_albedo(c);
+ if (c.a < 0.99) {
+ current->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ }
+
+ } else if (l.begins_with("map_Ka ")) {
+ //uv
+ print_line("Warning: Ambient light texture for material '" + current_name + "' is ignored in PBR");
+
+ } else if (l.begins_with("map_Kd ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+
+ String p = l.replace("map_Kd", "").replace("\\", "/").strip_edges();
+ String path = base_path.plus_file(p);
+
+ Ref<Texture> texture = ResourceLoader::load(path);
+
+ if (texture.is_valid()) {
+ current->set_texture(SpatialMaterial::TEXTURE_ALBEDO, texture);
+ } else {
+ r_missing_deps->push_back(path);
+ }
+
+ } else if (l.begins_with("map_Ks ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+
+ String p = l.replace("map_Ks", "").replace("\\", "/").strip_edges();
+ String path = base_path.plus_file(p);
+
+ Ref<Texture> texture = ResourceLoader::load(path);
+
+ if (texture.is_valid()) {
+ current->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
+ } else {
+ r_missing_deps->push_back(path);
+ }
+
+ } else if (l.begins_with("map_Ns ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+
+ String p = l.replace("map_Ns", "").replace("\\", "/").strip_edges();
+ String path = base_path.plus_file(p);
+
+ Ref<Texture> texture = ResourceLoader::load(path);
+
+ if (texture.is_valid()) {
+ current->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, texture);
+ } else {
+ r_missing_deps->push_back(path);
+ }
+ } else if (l.begins_with("map_bump ")) {
+ //normal
+ ERR_FAIL_COND_V(current.is_null(), ERR_FILE_CORRUPT);
+
+ String p = l.replace("map_bump", "").replace("\\", "/").strip_edges();
+ String path = base_path.plus_file(p);
-void ResourceImporterOBJ::get_import_options(List<ImportOption> *r_options, int p_preset) const {
-
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate/tangents"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "generate/normals"), true));
- //not for nowp
- //r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"import/materials")));
- //r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"import/textures")));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/flip_faces"), false));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/smooth_shading"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "force/weld_vertices"), true));
- r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "force/weld_tolerance", PROPERTY_HINT_RANGE, "0.00001,16,0.00001"), 0.0001));
- //r_options->push_back(PropertyInfo(Variant::INT,"compress/bitrate",PROPERTY_HINT_ENUM,"64,96,128,192"));
+ Ref<Texture> texture = ResourceLoader::load(path);
+
+ if (texture.is_valid()) {
+ current->set_feature(SpatialMaterial::FEATURE_NORMAL_MAPPING, true);
+ current->set_texture(SpatialMaterial::TEXTURE_NORMAL, texture);
+ } else {
+ r_missing_deps->push_back(path);
+ }
+ } else if (f->eof_reached()) {
+ break;
+ }
+ }
+
+ return OK;
}
-Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files) {
+Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err) {
- FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
- ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
+ FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+
+ if (r_err) {
+ *r_err = ERR_CANT_OPEN;
+ }
+
+ ERR_FAIL_COND_V(!f, NULL);
+
+ if (r_err) {
+ *r_err = OK;
+ }
+
+ Spatial *scene = memnew(Spatial);
+
+ Ref<ArrayMesh> mesh;
+ mesh.instance();
- Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Map<String, Ref<Material> > name_map;
- bool generate_normals = p_options["generate/normals"];
- bool generate_tangents = p_options["generate/tangents"];
- bool flip_faces = p_options["force/flip_faces"];
- bool force_smooth = p_options["force/smooth_shading"];
- bool weld_vertices = p_options["force/weld_vertices"];
- float weld_tolerance = p_options["force/weld_tolerance"];
+ bool generate_tangents = p_flags & IMPORT_GENERATE_TANGENT_ARRAYS;
+ bool flip_faces = false;
+ //bool flip_faces = p_options["force/flip_faces"];
+ //bool force_smooth = p_options["force/smooth_shading"];
+ //bool weld_vertices = p_options["force/weld_vertices"];
+ //float weld_tolerance = p_options["force/weld_tolerance"];
+
Vector<Vector3> vertices;
Vector<Vector3> normals;
Vector<Vector2> uvs;
String name;
+ Map<String, Map<String, Ref<SpatialMaterial> > > material_map;
+
Ref<SurfaceTool> surf_tool = memnew(SurfaceTool);
surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
- if (force_smooth)
- surf_tool->add_smooth_group(true);
- int has_index_data = false;
+
+ String current_material_library;
+ String current_material;
+ String current_group;
while (true) {
@@ -115,7 +239,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
if (l.begins_with("v ")) {
//vertex
Vector<String> v = l.split(" ", false);
- ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(v.size() < 4, NULL);
Vector3 vtx;
vtx.x = v[1].to_float();
vtx.y = v[2].to_float();
@@ -124,7 +248,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
} else if (l.begins_with("vt ")) {
//uv
Vector<String> v = l.split(" ", false);
- ERR_FAIL_COND_V(v.size() < 3, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(v.size() < 3, NULL);
Vector2 uv;
uv.x = v[1].to_float();
uv.y = 1.0 - v[2].to_float();
@@ -133,7 +257,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
} else if (l.begins_with("vn ")) {
//normal
Vector<String> v = l.split(" ", false);
- ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(v.size() < 4, NULL);
Vector3 nrm;
nrm.x = v[1].to_float();
nrm.y = v[2].to_float();
@@ -142,21 +266,20 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
} else if (l.begins_with("f ")) {
//vertex
- has_index_data = true;
Vector<String> v = l.split(" ", false);
- ERR_FAIL_COND_V(v.size() < 4, ERR_INVALID_DATA);
+ ERR_FAIL_COND_V(v.size() < 4, NULL);
//not very fast, could be sped up
Vector<String> face[3];
face[0] = v[1].split("/");
face[1] = v[2].split("/");
- ERR_FAIL_COND_V(face[0].size() == 0, ERR_PARSE_ERROR);
- ERR_FAIL_COND_V(face[0].size() != face[1].size(), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(face[0].size() == 0, NULL);
+ ERR_FAIL_COND_V(face[0].size() != face[1].size(), NULL);
for (int i = 2; i < v.size() - 1; i++) {
face[2] = v[i + 1].split("/");
- ERR_FAIL_COND_V(face[0].size() != face[2].size(), ERR_PARSE_ERROR);
+ ERR_FAIL_COND_V(face[0].size() != face[2].size(), NULL);
for (int j = 0; j < 3; j++) {
int idx = j;
@@ -169,7 +292,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
int norm = face[idx][2].to_int() - 1;
if (norm < 0)
norm += normals.size() + 1;
- ERR_FAIL_INDEX_V(norm, normals.size(), ERR_PARSE_ERROR);
+ ERR_FAIL_INDEX_V(norm, normals.size(), NULL);
surf_tool->add_normal(normals[norm]);
}
@@ -177,58 +300,105 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
int uv = face[idx][1].to_int() - 1;
if (uv < 0)
uv += uvs.size() + 1;
- ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_PARSE_ERROR);
+ ERR_FAIL_INDEX_V(uv, uvs.size(), NULL);
surf_tool->add_uv(uvs[uv]);
}
int vtx = face[idx][0].to_int() - 1;
if (vtx < 0)
vtx += vertices.size() + 1;
- ERR_FAIL_INDEX_V(vtx, vertices.size(), ERR_PARSE_ERROR);
+ ERR_FAIL_INDEX_V(vtx, vertices.size(), NULL);
Vector3 vertex = vertices[vtx];
- if (weld_vertices)
- vertex.snap(Vector3(weld_tolerance, weld_tolerance, weld_tolerance));
+ //if (weld_vertices)
+ // vertex.snap(Vector3(weld_tolerance, weld_tolerance, weld_tolerance));
surf_tool->add_vertex(vertex);
}
face[1] = face[2];
}
- } else if (l.begins_with("s ") && !force_smooth) { //smoothing
+ } else if (l.begins_with("s ")) { //smoothing
String what = l.substr(2, l.length()).strip_edges();
if (what == "off")
surf_tool->add_smooth_group(false);
else
surf_tool->add_smooth_group(true);
+ } else if (l.begins_with("g ") || l.begins_with("usemtl ") || (l.begins_with("o ") || f->eof_reached())) { //commit group to mesh
- } else if (l.begins_with("o ") || f->eof_reached()) { //new surface or done
-
- if (has_index_data) {
- //new object/surface
- if (generate_normals || force_smooth)
+ if (surf_tool->get_vertex_array().size()) {
+ //another group going on, commit it
+ if (normals.size() == 0) {
surf_tool->generate_normals();
- if (uvs.size() && (normals.size() || generate_normals) && generate_tangents)
+ }
+
+ if (generate_tangents && uvs.size()) {
surf_tool->generate_tangents();
+ }
surf_tool->index();
+
+ print_line("current material library " + current_material_library + " has " + itos(material_map.has(current_material_library)));
+ print_line("current material " + current_material + " has " + itos(material_map.has(current_material_library) && material_map[current_material_library].has(current_material)));
+
+ if (material_map.has(current_material_library) && material_map[current_material_library].has(current_material)) {
+ surf_tool->set_material(material_map[current_material_library][current_material]);
+ }
+
mesh = surf_tool->commit(mesh);
- if (name == "")
- name = vformat(TTR("Surface %d"), mesh->get_surface_count() - 1);
- mesh->surface_set_name(mesh->get_surface_count() - 1, name);
- name = "";
+
+ if (current_material != String()) {
+ mesh->surface_set_name(mesh->get_surface_count() - 1, current_material.get_basename());
+ } else if (current_group != String()) {
+ mesh->surface_set_name(mesh->get_surface_count() - 1, current_group);
+ }
+
+ print_line("Added surface :" + mesh->surface_get_name(mesh->get_surface_count() - 1));
surf_tool->clear();
surf_tool->begin(Mesh::PRIMITIVE_TRIANGLES);
- if (force_smooth)
- surf_tool->add_smooth_group(true);
+ }
+
+ if (l.begins_with("o ") || f->eof_reached()) {
+
+ MeshInstance *mi = memnew(MeshInstance);
+ mi->set_name(name);
+ mi->set_mesh(mesh);
- has_index_data = false;
+ scene->add_child(mi);
+ mi->set_owner(scene);
- if (f->eof_reached())
- break;
+ mesh.instance();
+ current_group = "";
+ current_material = "";
}
- if (l.begins_with("o ")) //name
+ if (f->eof_reached()) {
+ break;
+ }
+
+ if (l.begins_with("o ")) {
name = l.substr(2, l.length()).strip_edges();
+ }
+
+ if (l.begins_with("usemtl ")) {
+
+ current_material = l.replace("usemtl", "").strip_edges();
+ }
+
+ if (l.begins_with("g ")) {
+
+ current_group = l.substr(2, l.length()).strip_edges();
+ }
+
+ } else if (l.begins_with("mtllib ")) { //parse material
+
+ current_material_library = l.replace("mtllib", "").strip_edges();
+ if (!material_map.has(current_material_library)) {
+ Map<String, Ref<SpatialMaterial> > lib;
+ Error err = _parse_material_library(current_material_library, lib, r_missing_deps);
+ if (err == OK) {
+ material_map[current_material_library] = lib;
+ }
+ }
}
}
@@ -243,10 +413,11 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
}
*/
- Error err = ResourceSaver::save(p_save_path + ".mesh", mesh);
-
- return err;
+ return scene;
}
+Ref<Animation> EditorOBJImporter::import_animation(const String &p_path, uint32_t p_flags) {
-ResourceImporterOBJ::ResourceImporterOBJ() {
+ return Ref<Animation>();
+}
+EditorOBJImporter::EditorOBJImporter() {
}
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index b7443c71a6..c8285ce6c9 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -30,26 +30,21 @@
#ifndef RESOURCEIMPORTEROBJ_H
#define RESOURCEIMPORTEROBJ_H
-#include "io/resource_import.h"
+#include "import/resource_importer_scene.h"
-class ResourceImporterOBJ : public ResourceImporter {
- GDCLASS(ResourceImporterOBJ, ResourceImporter)
-public:
- virtual String get_importer_name() const;
- virtual String get_visible_name() const;
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual String get_save_extension() const;
- virtual String get_resource_type() const;
+class EditorOBJImporter : public EditorSceneImporter {
- virtual int get_preset_count() const;
- virtual String get_preset_name(int p_idx) const;
+ GDCLASS(EditorOBJImporter, EditorSceneImporter);
- virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
- virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
+ Error _parse_material_library(const String &p_path, Map<String, Ref<SpatialMaterial> > &material_map, List<String> *r_missing_deps);
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL);
+public:
+ virtual uint32_t get_import_flags() const;
+ virtual void get_extensions(List<String> *r_extensions) const;
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
+ virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags);
- ResourceImporterOBJ();
+ EditorOBJImporter();
};
#endif // RESOURCEIMPORTEROBJ_H
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 2ccbd36e18..dbf7a1bea5 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -33,7 +33,7 @@
#include "io/resource_saver.h"
#include "scene/resources/packed_scene.h"
-#include "scene/3d/body_shape.h"
+#include "scene/3d/collision_shape.h"
#include "scene/3d/mesh_instance.h"
#include "scene/3d/navigation.h"
#include "scene/3d/physics_body.h"
@@ -369,10 +369,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Array
p_node = col;
StaticBody *sb = col->cast_to<StaticBody>();
- CollisionShape *colshape = memnew(CollisionShape);
- colshape->set_shape(sb->get_shape(0));
+ CollisionShape *colshape = sb->get_child(0)->cast_to<CollisionShape>();
colshape->set_name("shape");
- sb->add_child(colshape);
colshape->set_owner(p_node->get_owner());
} else if (p_node->has_meta("empty_draw_type")) {
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
@@ -463,8 +461,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Array
p_node->add_child(col);
StaticBody *sb = col->cast_to<StaticBody>();
- CollisionShape *colshape = memnew(CollisionShape);
- colshape->set_shape(sb->get_shape(0));
+ CollisionShape *colshape = sb->get_child(0)->cast_to<CollisionShape>();
colshape->set_name("shape");
col->add_child(colshape);
colshape->set_owner(p_node->get_owner());
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 3834e52fab..7e23a422f7 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -418,24 +418,24 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
if (compress_mode == COMPRESS_VIDEO_RAM) {
//must import in all formats
//Android, GLES 2.x
- if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_s3tc")) {
+ if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_s3tc")) {
_save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("s3tc");
}
- if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_etc")) {
+ if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_etc")) {
_save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("etc");
}
- if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_etc2")) {
+ if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_etc2")) {
_save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("etc2");
}
- if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_pvrtc")) {
+ if (GlobalConfig::get_singleton()->get("rendering/vram_compression/import_pvrtc")) {
_save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
r_platform_variants->push_back("pvrtc");
diff --git a/editor/import_dock.cpp b/editor/import_dock.cpp
index 6c7a633477..24647734ce 100644
--- a/editor/import_dock.cpp
+++ b/editor/import_dock.cpp
@@ -328,7 +328,6 @@ ImportDock::ImportDock() {
add_child(import_opts);
import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
import_opts->hide_top_label();
- import_opts->set_hide_script(true);
hb = memnew(HBoxContainer);
add_child(hb);
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 7ce884a455..c8936c8c35 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -1897,11 +1897,6 @@ void CanvasItemEditor::_viewport_draw() {
if (viewport->has_focus()) {
Size2 size = viewport->get_size();
- if (v_scroll->is_visible_in_tree())
- size.width -= v_scroll->get_size().width;
- if (h_scroll->is_visible_in_tree())
- size.height -= h_scroll->get_size().height;
-
get_stylebox("Focus", "EditorStyles")->draw(ci, Rect2(Point2(), size));
}
@@ -2012,7 +2007,7 @@ void CanvasItemEditor::_viewport_draw() {
VisualServer::get_singleton()->canvas_item_add_line(ci, transform.xform(display_rotate_from), transform.xform(display_rotate_to), rotate_color);
}
- Size2 screen_size = Size2(GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height"));
+ Size2 screen_size = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
Vector2 screen_endpoints[4] = {
transform.xform(Vector2(0, 0)),
@@ -2239,6 +2234,7 @@ void CanvasItemEditor::_notification(int p_what) {
p->add_icon_item(get_icon("ControlHcenterWide", "EditorIcons"), "HCenter Wide ", ANCHOR_ALIGN_HCENTER_WIDE);
p->add_separator();
p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect", ANCHOR_ALIGN_WIDE);
+ p->add_icon_item(get_icon("ControlAlignWide", "EditorIcons"), "Full Rect and Fit Parent", ANCHOR_ALIGN_WIDE_FIT);
AnimationPlayerEditor::singleton->get_key_editor()->connect("visibility_changed", this, "_keying_changed");
_keying_changed();
@@ -2327,7 +2323,7 @@ void CanvasItemEditor::_update_scrollbars() {
h_scroll->set_begin(Point2(0, size.height - hmin.height));
h_scroll->set_end(Point2(size.width - vmin.width, size.height));
- Size2 screen_rect = Size2(GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height"));
+ Size2 screen_rect = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
Rect2 local_rect = Rect2(Point2(), viewport->get_size() - Size2(vmin.width, hmin.height));
@@ -2444,6 +2440,35 @@ void CanvasItemEditor::_set_anchor(Control::AnchorType p_left, Control::AnchorTy
undo_redo->commit_action();
}
+void CanvasItemEditor::_set_full_rect() {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ undo_redo->create_action(TTR("Change Anchors"));
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Control *c = E->get()->cast_to<Control>();
+
+ undo_redo->add_do_method(c, "set_anchor", MARGIN_LEFT, ANCHOR_BEGIN);
+ undo_redo->add_do_method(c, "set_anchor", MARGIN_TOP, ANCHOR_BEGIN);
+ undo_redo->add_do_method(c, "set_anchor", MARGIN_RIGHT, ANCHOR_END);
+ undo_redo->add_do_method(c, "set_anchor", MARGIN_BOTTOM, ANCHOR_END);
+ undo_redo->add_do_method(c, "set_margin", MARGIN_LEFT, 0);
+ undo_redo->add_do_method(c, "set_margin", MARGIN_TOP, 0);
+ undo_redo->add_do_method(c, "set_margin", MARGIN_RIGHT, 0);
+ undo_redo->add_do_method(c, "set_margin", MARGIN_BOTTOM, 0);
+ undo_redo->add_undo_method(c, "set_anchor", MARGIN_LEFT, c->get_anchor(MARGIN_LEFT));
+ undo_redo->add_undo_method(c, "set_anchor", MARGIN_TOP, c->get_anchor(MARGIN_TOP));
+ undo_redo->add_undo_method(c, "set_anchor", MARGIN_RIGHT, c->get_anchor(MARGIN_RIGHT));
+ undo_redo->add_undo_method(c, "set_anchor", MARGIN_BOTTOM, c->get_anchor(MARGIN_BOTTOM));
+ undo_redo->add_undo_method(c, "set_margin", MARGIN_LEFT, c->get_margin(MARGIN_LEFT));
+ undo_redo->add_undo_method(c, "set_margin", MARGIN_TOP, c->get_margin(MARGIN_TOP));
+ undo_redo->add_undo_method(c, "set_margin", MARGIN_RIGHT, c->get_margin(MARGIN_RIGHT));
+ undo_redo->add_undo_method(c, "set_margin", MARGIN_BOTTOM, c->get_margin(MARGIN_BOTTOM));
+ }
+
+ undo_redo->commit_action();
+}
+
void CanvasItemEditor::_popup_callback(int p_op) {
last_option = MenuOption(p_op);
@@ -2601,29 +2626,6 @@ void CanvasItemEditor::_popup_callback(int p_op) {
} break;
- case EXPAND_TO_PARENT: {
-
- List<Node *> &selection = editor_selection->get_selected_node_list();
-
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
-
- CanvasItem *canvas_item = E->get()->cast_to<CanvasItem>();
- if (!canvas_item || !canvas_item->is_visible_in_tree())
- continue;
-
- if (canvas_item->get_viewport() != EditorNode::get_singleton()->get_scene_root())
- continue;
-
- Control *c = canvas_item->cast_to<Control>();
- if (!c)
- continue;
- c->set_area_as_parent_rect();
- }
-
- viewport->update();
-
- } break;
-
case ALIGN_VERTICAL: {
#if 0
if ( ref_item && canvas_items.size() > 1 ) {
@@ -2716,6 +2718,9 @@ void CanvasItemEditor::_popup_callback(int p_op) {
case ANCHOR_ALIGN_WIDE: {
_set_anchor(ANCHOR_BEGIN, ANCHOR_BEGIN, ANCHOR_END, ANCHOR_END);
} break;
+ case ANCHOR_ALIGN_WIDE_FIT: {
+ _set_full_rect();
+ } break;
case ANIM_INSERT_KEY:
case ANIM_INSERT_KEY_EXISTING: {
@@ -3331,8 +3336,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("canvas_item_editor/use_pixel_snap", TTR("Use Pixel Snap")), SNAP_USE_PIXEL);
p->add_separator();
- p->add_shortcut(ED_SHORTCUT("canvas_item_editor/expand_to_parent", TTR("Expand to Parent"), KEY_MASK_CMD | KEY_P), EXPAND_TO_PARENT);
- p->add_separator();
p->add_submenu_item(TTR("Skeleton.."), "skeleton");
skeleton_menu = memnew(PopupMenu);
p->add_child(skeleton_menu);
@@ -3383,6 +3386,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
key_loc_button = memnew(Button("loc"));
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));
@@ -3391,6 +3395,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->add_child(key_loc_button);
key_rot_button = memnew(Button("rot"));
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));
@@ -3399,12 +3404,14 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->add_child(key_rot_button);
key_scale_button = memnew(Button("scl"));
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);
+ key_insert_button->set_flat(true);
key_insert_button->set_focus_mode(FOCUS_NONE);
key_insert_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_KEY));
key_insert_button->set_tooltip(TTR("Insert Keys"));
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 702deb51f9..f40a7cbc4a 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -111,10 +111,10 @@ class CanvasItemEditor : public VBoxContainer {
ANCHOR_ALIGN_VCENTER_WIDE,
ANCHOR_ALIGN_HCENTER_WIDE,
ANCHOR_ALIGN_WIDE,
+ ANCHOR_ALIGN_WIDE_FIT,
SPACE_HORIZONTAL,
SPACE_VERTICAL,
- EXPAND_TO_PARENT,
ANIM_INSERT_KEY,
ANIM_INSERT_KEY_EXISTING,
ANIM_INSERT_POS,
@@ -361,6 +361,7 @@ class CanvasItemEditor : public VBoxContainer {
void _focus_selection(int p_op);
void _set_anchor(Control::AnchorType p_left, Control::AnchorType p_top, Control::AnchorType p_right, Control::AnchorType p_bottom);
+ void _set_full_rect();
HSplitContainer *palette_split;
VSplitContainer *bottom_split;
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index abee3ead71..346c00df64 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -99,7 +99,7 @@ bool CollisionPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event)
if (!node)
return false;
- Ref<InputEventMouseButton> mb;
+ Ref<InputEventMouseButton> mb = p_event;
if (mb.is_valid()) {
Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index c89e6f59a4..5b364ed2c1 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -35,339 +35,304 @@
#include "scene/3d/camera.h"
#include "spatial_editor_plugin.h"
-#if 0
-
void CollisionPolygonEditor::_notification(int p_what) {
- switch(p_what) {
+ switch (p_what) {
case NOTIFICATION_READY: {
- button_create->set_icon( get_icon("Edit","EditorIcons"));
- button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
+ button_create->set_icon(get_icon("Edit", "EditorIcons"));
+ button_edit->set_icon(get_icon("MovePoint", "EditorIcons"));
button_edit->set_pressed(true);
- get_tree()->connect("node_removed",this,"_node_removed");
-
+ get_tree()->connect("node_removed", this, "_node_removed");
} break;
case NOTIFICATION_PROCESS: {
if (node->get_depth() != prev_depth) {
_polygon_draw();
- prev_depth=node->get_depth();
+ prev_depth = node->get_depth();
}
} break;
}
-
}
void CollisionPolygonEditor::_node_removed(Node *p_node) {
- if(p_node==node) {
- node=NULL;
- if (imgeom->get_parent()==p_node)
+ if (p_node == node) {
+ node = NULL;
+ if (imgeom->get_parent() == p_node)
p_node->remove_child(imgeom);
hide();
set_process(false);
}
-
}
-
void CollisionPolygonEditor::_menu_option(int p_option) {
- switch(p_option) {
+ switch (p_option) {
case MODE_CREATE: {
- mode=MODE_CREATE;
+ mode = MODE_CREATE;
button_create->set_pressed(true);
button_edit->set_pressed(false);
} break;
case MODE_EDIT: {
- mode=MODE_EDIT;
+ mode = MODE_EDIT;
button_create->set_pressed(false);
button_edit->set_pressed(true);
} break;
-
}
}
void CollisionPolygonEditor::_wip_close() {
undo_redo->create_action(TTR("Create Poly3D"));
- undo_redo->add_undo_method(node,"set_polygon",node->get_polygon());
- undo_redo->add_do_method(node,"set_polygon",wip);
- undo_redo->add_do_method(this,"_polygon_draw");
- undo_redo->add_undo_method(this,"_polygon_draw");
+ undo_redo->add_undo_method(node, "set_polygon", node->get_polygon());
+ undo_redo->add_do_method(node, "set_polygon", wip);
+ undo_redo->add_do_method(this, "_polygon_draw");
+ undo_redo->add_undo_method(this, "_polygon_draw");
wip.clear();
- wip_active=false;
- mode=MODE_EDIT;
+ wip_active = false;
+ mode = MODE_EDIT;
button_edit->set_pressed(true);
button_create->set_pressed(false);
- edited_point=-1;
+ edited_point = -1;
undo_redo->commit_action();
-
}
-bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) {
+bool CollisionPolygonEditor::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
if (!node)
return false;
Transform gt = node->get_global_transform();
Transform gi = gt.affine_inverse();
- float depth = node->get_depth()*0.5;
+ float depth = node->get_depth() * 0.5;
Vector3 n = gt.basis.get_axis(2).normalized();
- Plane p(gt.origin+n*depth,n);
-
-
- switch(p_event.type) {
+ Plane p(gt.origin + n * depth, n);
- case InputEvent::MOUSE_BUTTON: {
+ Ref<InputEventMouseButton> mb = p_event;
- const InputEventMouseButton &mb=p_event.mouse_button;
+ if (mb.is_valid()) {
+ Vector2 gpoint = mb->get_position();
+ Vector3 ray_from = p_camera->project_ray_origin(gpoint);
+ Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
+ Vector3 spoint;
- Vector2 gpoint=Point2(mb->get_pos().x,mb->get_pos().y);
- Vector3 ray_from = p_camera->project_ray_origin(gpoint);
- Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
-
- Vector3 spoint;
-
- if (!p.intersects_ray(ray_from,ray_dir,&spoint))
- break;
+ if (!p.intersects_ray(ray_from, ray_dir, &spoint))
+ return false;
- spoint = gi.xform(spoint);
+ spoint = gi.xform(spoint);
- Vector2 cpoint(spoint.x,spoint.y);
+ Vector2 cpoint(spoint.x, spoint.y);
- cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint);
+ cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint);
- Vector<Vector2> poly = node->get_polygon();
+ Vector<Vector2> poly = node->get_polygon();
- //first check if a point is to be added (segment split)
- real_t grab_treshold=EDITOR_DEF("editors/poly_editor/point_grab_radius",8);
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- switch(mode) {
+ switch (mode) {
+ case MODE_CREATE: {
- case MODE_CREATE: {
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- if (mb->get_button_index()==BUTTON_LEFT && mb->is_pressed()) {
+ if (!wip_active) {
+ wip.clear();
+ wip.push_back(cpoint);
+ wip_active = true;
+ edited_point_pos = cpoint;
+ _polygon_draw();
+ edited_point = 1;
+ return true;
+ } else {
- if (!wip_active) {
+ if (wip.size() > 1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x, wip[0].y, depth))).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close();
- wip.clear();
- wip.push_back( cpoint );
- wip_active=true;
- edited_point_pos=cpoint;
- _polygon_draw();
- edited_point=1;
return true;
} else {
-
- if (wip.size()>1 && p_camera->unproject_position(gt.xform(Vector3(wip[0].x,wip[0].y,depth))).distance_to(gpoint)<grab_treshold) {
- //wip closed
- _wip_close();
-
- return true;
- } else {
-
- wip.push_back( cpoint );
- edited_point=wip.size();
- _polygon_draw();
- return true;
-
- //add wip point
- }
+ wip.push_back(cpoint);
+ edited_point = wip.size();
+ _polygon_draw();
+ return true;
}
- } else if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && wip_active) {
- _wip_close();
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close();
+ }
+ } break;
+ case MODE_EDIT: {
- } break;
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- case MODE_EDIT: {
+ if (mb->get_control()) {
- if (mb->get_button_index()==BUTTON_LEFT) {
- if (mb->is_pressed()) {
+ if (poly.size() < 3) {
- if (mb->get_control()) {
-
-
- if (poly.size() < 3) {
-
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node,"set_polygon",poly);
- poly.push_back(cpoint);
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(this,"_polygon_draw");
- undo_redo->add_undo_method(this,"_polygon_draw");
- undo_redo->commit_action();
- return true;
- }
-
- //search edges
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
-
- Vector2 points[2] ={
- p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth))),
- p_camera->unproject_position(gt.xform(Vector3(poly[(i+1)%poly.size()].x,poly[(i+1)%poly.size()].y,depth)))
- };
-
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
- if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
- continue; //not valid to reuse point
-
- real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
- closest_dist=d;
- closest_pos=cp;
- closest_idx=i;
- }
-
-
- }
-
- if (closest_idx>=0) {
-
- pre_move_edit=poly;
- poly.insert(closest_idx+1,cpoint);
- edited_point=closest_idx+1;
- edited_point_pos=cpoint;
- node->set_polygon(poly);
- _polygon_draw();
- return true;
- }
- } else {
-
- //look for points to move
-
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
-
- Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth)));
-
- real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
- closest_dist=d;
- closest_pos=cp;
- closest_idx=i;
- }
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(this, "_polygon_draw");
+ undo_redo->add_undo_method(this, "_polygon_draw");
+ undo_redo->commit_action();
+ return true;
+ }
+ //search edges
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
+
+ Vector2 points[2] = {
+ p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth))),
+ p_camera->unproject_position(gt.xform(Vector3(poly[(i + 1) % poly.size()].x, poly[(i + 1) % poly.size()].y, depth)))
+ };
+
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ continue; //not valid to reuse point
+
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
}
+ }
- if (closest_idx>=0) {
+ if (closest_idx >= 0) {
- pre_move_edit=poly;
- edited_point=closest_idx;
- edited_point_pos=poly[closest_idx];
- _polygon_draw();
- return true;
- }
+ pre_move_edit = poly;
+ poly.insert(closest_idx + 1, cpoint);
+ edited_point = closest_idx + 1;
+ edited_point_pos = cpoint;
+ node->set_polygon(poly);
+ _polygon_draw();
+ return true;
}
} else {
- if (edited_point!=-1) {
+ //look for points to move
- //apply
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- ERR_FAIL_INDEX_V(edited_point,poly.size(),false);
- poly[edited_point]=edited_point_pos;
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_undo_method(node,"set_polygon",pre_move_edit);
- undo_redo->add_do_method(this,"_polygon_draw");
- undo_redo->add_undo_method(this,"_polygon_draw");
- undo_redo->commit_action();
+ Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));
- edited_point=-1;
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
}
- }
- } if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && edited_point==-1) {
-
+ if (closest_idx >= 0) {
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
-
- Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x,poly[i].y,depth)));
-
- real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
- closest_dist=d;
- closest_pos=cp;
- closest_idx=i;
+ pre_move_edit = poly;
+ edited_point = closest_idx;
+ edited_point_pos = poly[closest_idx];
+ _polygon_draw();
+ return true;
}
-
}
+ } else {
- if (closest_idx>=0) {
+ if (edited_point != -1) {
+ //apply
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node,"set_polygon",poly);
- poly.remove(closest_idx);
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(this,"_polygon_draw");
- undo_redo->add_undo_method(this,"_polygon_draw");
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly[edited_point] = edited_point_pos;
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
+ undo_redo->add_do_method(this, "_polygon_draw");
+ undo_redo->add_undo_method(this, "_polygon_draw");
undo_redo->commit_action();
+
+ edited_point = -1;
return true;
}
-
}
+ }
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
+ Vector2 cp = p_camera->unproject_position(gt.xform(Vector3(poly[i].x, poly[i].y, depth)));
- } break;
- }
-
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
+ }
+ if (closest_idx >= 0) {
- } break;
- case InputEvent::MOUSE_MOTION: {
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(this, "_polygon_draw");
+ undo_redo->add_undo_method(this, "_polygon_draw");
+ undo_redo->commit_action();
+ return true;
+ }
+ }
- const InputEventMouseMotion &mm=p_event.mouse_motion;
+ } break;
+ }
+ }
- if (edited_point!=-1 && (wip_active || mm->get_button_mask()&BUTTON_MASK_LEFT)) {
+ Ref<InputEventMouseMotion> mm = p_event;
- Vector2 gpoint = Point2(mm.x,mm.y);
+ if (mm.is_valid()) {
- Vector3 ray_from = p_camera->project_ray_origin(gpoint);
- Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
+ if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
- Vector3 spoint;
+ Vector2 gpoint = mm->get_position();
- if (!p.intersects_ray(ray_from,ray_dir,&spoint))
- break;
+ Vector3 ray_from = p_camera->project_ray_origin(gpoint);
+ Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
- spoint = gi.xform(spoint);
+ Vector3 spoint;
- Vector2 cpoint(spoint.x,spoint.y);
+ if (!p.intersects_ray(ray_from, ray_dir, &spoint))
+ return false;
- cpoint=CanvasItemEditor::get_singleton()->snap_point(cpoint);
- edited_point_pos = cpoint;
+ spoint = gi.xform(spoint);
- _polygon_draw();
+ Vector2 cpoint(spoint.x, spoint.y);
- }
+ cpoint = CanvasItemEditor::get_singleton()->snap_point(cpoint);
+ edited_point_pos = cpoint;
- } break;
+ _polygon_draw();
+ }
}
return false;
@@ -380,41 +345,38 @@ void CollisionPolygonEditor::_polygon_draw() {
Vector<Vector2> poly;
if (wip_active)
- poly=wip;
+ poly = wip;
else
- poly=node->get_polygon();
-
+ poly = node->get_polygon();
- float depth = node->get_depth()*0.5;
+ float depth = node->get_depth() * 0.5;
imgeom->clear();
imgeom->set_material_override(line_material);
- imgeom->begin(Mesh::PRIMITIVE_LINES,Ref<Texture>());
-
+ imgeom->begin(Mesh::PRIMITIVE_LINES, Ref<Texture>());
Rect2 rect;
- for(int i=0;i<poly.size();i++) {
-
+ for (int i = 0; i < poly.size(); i++) {
- Vector2 p,p2;
- p = i==edited_point ? edited_point_pos : poly[i];
- if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point))
- p2=edited_point_pos;
+ Vector2 p, p2;
+ p = i == edited_point ? edited_point_pos : poly[i];
+ if ((wip_active && i == poly.size() - 1) || (((i + 1) % poly.size()) == edited_point))
+ p2 = edited_point_pos;
else
- p2 = poly[(i+1)%poly.size()];
+ p2 = poly[(i + 1) % poly.size()];
- if (i==0)
- rect.pos=p;
+ if (i == 0)
+ rect.position = p;
else
rect.expand_to(p);
- Vector3 point = Vector3(p.x,p.y,depth);
- Vector3 next_point = Vector3(p2.x,p2.y,depth);
+ Vector3 point = Vector3(p.x, p.y, depth);
+ Vector3 next_point = Vector3(p2.x, p2.y, depth);
- imgeom->set_color(Color(1,0.3,0.1,0.8));
+ imgeom->set_color(Color(1, 0.3, 0.1, 0.8));
imgeom->add_vertex(point);
- imgeom->set_color(Color(1,0.3,0.1,0.8));
+ imgeom->set_color(Color(1, 0.3, 0.1, 0.8));
imgeom->add_vertex(next_point);
//Color col=Color(1,0.3,0.1,0.8);
@@ -422,60 +384,59 @@ void CollisionPolygonEditor::_polygon_draw() {
//vpc->draw_texture(handle,point-handle->get_size()*0.5);
}
- rect=rect.grow(1);
-
- AABB r;
- r.pos.x=rect.pos.x;
- r.pos.y=rect.pos.y;
- r.pos.z=depth;
- r.size.x=rect.size.x;
- r.size.y=rect.size.y;
- r.size.z=0;
-
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos);
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0.3,0,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos);
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0.0,0.3,0));
-
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)-Vector3(0.3,0,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(r.size.x,0,0)+Vector3(0,0.3,0));
-
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)-Vector3(0,0.3,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+Vector3(0,r.size.y,0)+Vector3(0.3,0,0));
-
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+r.size);
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+r.size-Vector3(0.3,0,0));
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+r.size);
- imgeom->set_color(Color(0.8,0.8,0.8,0.2));
- imgeom->add_vertex(r.pos+r.size-Vector3(0.0,0.3,0));
+ rect = rect.grow(1);
+
+ Rect3 r;
+ r.position.x = rect.position.x;
+ r.position.y = rect.position.y;
+ r.position.z = depth;
+ r.size.x = rect.size.x;
+ r.size.y = rect.size.y;
+ r.size.z = 0;
+
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position);
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0.3, 0, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position);
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0.0, 0.3, 0));
+
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) - Vector3(0.3, 0, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(r.size.x, 0, 0) + Vector3(0, 0.3, 0));
+
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) - Vector3(0, 0.3, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + Vector3(0, r.size.y, 0) + Vector3(0.3, 0, 0));
+
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + r.size);
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + r.size - Vector3(0.3, 0, 0));
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + r.size);
+ imgeom->set_color(Color(0.8, 0.8, 0.8, 0.2));
+ imgeom->add_vertex(r.position + r.size - Vector3(0.0, 0.3, 0));
imgeom->end();
-
- while(m->get_surface_count()) {
+ while (m->get_surface_count()) {
m->surface_remove(0);
}
- if (poly.size()==0)
+ if (poly.size() == 0)
return;
Array a;
@@ -484,78 +445,69 @@ void CollisionPolygonEditor::_polygon_draw() {
{
va.resize(poly.size());
- PoolVector<Vector3>::Write w=va.write();
- for(int i=0;i<poly.size();i++) {
-
+ PoolVector<Vector3>::Write w = va.write();
+ for (int i = 0; i < poly.size(); i++) {
- Vector2 p,p2;
- p = i==edited_point ? edited_point_pos : poly[i];
+ Vector2 p, p2;
+ p = i == edited_point ? edited_point_pos : poly[i];
- Vector3 point = Vector3(p.x,p.y,depth);
- w[i]=point;
+ Vector3 point = Vector3(p.x, p.y, depth);
+ w[i] = point;
}
}
- a[Mesh::ARRAY_VERTEX]=va;
- m->add_surface(Mesh::PRIMITIVE_POINTS,a);
- m->surface_set_material(0,handle_material);
-
+ a[Mesh::ARRAY_VERTEX] = va;
+ m->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, a);
+ m->surface_set_material(0, handle_material);
}
-
-
void CollisionPolygonEditor::edit(Node *p_collision_polygon) {
-
-
if (p_collision_polygon) {
- node=p_collision_polygon->cast_to<CollisionPolygon>();
+ node = p_collision_polygon->cast_to<CollisionPolygon>();
wip.clear();
- wip_active=false;
- edited_point=-1;
+ wip_active = false;
+ edited_point = -1;
p_collision_polygon->add_child(imgeom);
_polygon_draw();
set_process(true);
- prev_depth=-1;
+ prev_depth = -1;
} else {
- node=NULL;
+ node = NULL;
if (imgeom->get_parent())
imgeom->get_parent()->remove_child(imgeom);
set_process(false);
}
-
}
void CollisionPolygonEditor::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_menu_option"),&CollisionPolygonEditor::_menu_option);
- ClassDB::bind_method(D_METHOD("_polygon_draw"),&CollisionPolygonEditor::_polygon_draw);
- ClassDB::bind_method(D_METHOD("_node_removed"),&CollisionPolygonEditor::_node_removed);
-
+ ClassDB::bind_method(D_METHOD("_menu_option"), &CollisionPolygonEditor::_menu_option);
+ ClassDB::bind_method(D_METHOD("_polygon_draw"), &CollisionPolygonEditor::_polygon_draw);
+ ClassDB::bind_method(D_METHOD("_node_removed"), &CollisionPolygonEditor::_node_removed);
}
CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
-
- node=NULL;
- editor=p_editor;
+ node = NULL;
+ editor = p_editor;
undo_redo = editor->get_undo_redo();
- add_child( memnew( VSeparator ));
- button_create = memnew( ToolButton );
+ add_child(memnew(VSeparator));
+ button_create = memnew(ToolButton);
add_child(button_create);
- button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE));
+ button_create->connect("pressed", this, "_menu_option", varray(MODE_CREATE));
button_create->set_toggle_mode(true);
- button_edit = memnew( ToolButton );
+ button_edit = memnew(ToolButton);
add_child(button_edit);
- button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT));
+ button_edit->connect("pressed", this, "_menu_option", varray(MODE_EDIT));
button_edit->set_toggle_mode(true);
- //add_constant_override("separation",0);
+//add_constant_override("separation",0);
#if 0
options = memnew( MenuButton );
@@ -567,46 +519,40 @@ CollisionPolygonEditor::CollisionPolygonEditor(EditorNode *p_editor) {
#endif
mode = MODE_EDIT;
- wip_active=false;
- imgeom = memnew( ImmediateGeometry );
- imgeom->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
-
+ wip_active = false;
+ imgeom = memnew(ImmediateGeometry);
+ imgeom->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001)));
- line_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
- line_material->set_flag(Material::FLAG_UNSHADED, true);
+ line_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
line_material->set_line_width(3.0);
- line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
- line_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, true);
- line_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
-
-
-
-
- handle_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
- handle_material->set_flag(Material::FLAG_UNSHADED, true);
- handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
- handle_material->set_parameter(SpatialMaterial::PARAM_DIFFUSE,Color(1,1,1));
- handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
- handle_material->set_fixed_flag(SpatialMaterial::FLAG_USE_COLOR_ARRAY, false);
- Ref<Texture> handle=editor->get_gui_base()->get_icon("Editor3DHandle","EditorIcons");
+ line_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ line_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ line_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ line_material->set_albedo(Color(1, 1, 1));
+
+ handle_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ handle_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_USE_POINT_SIZE, true);
+ handle_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+ handle_material->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
+ Ref<Texture> handle = editor->get_gui_base()->get_icon("Editor3DHandle", "EditorIcons");
handle_material->set_point_size(handle->get_width());
- handle_material->set_texture(SpatialMaterial::PARAM_DIFFUSE,handle);
+ handle_material->set_texture(SpatialMaterial::TEXTURE_ALBEDO, handle);
- pointsm = memnew( MeshInstance );
+ pointsm = memnew(MeshInstance);
imgeom->add_child(pointsm);
- m = Ref<Mesh>( memnew( Mesh ) );
+ m.instance();
pointsm->set_mesh(m);
- pointsm->set_transform(Transform(Matrix3(),Vector3(0,0,0.00001)));
-
-
+ pointsm->set_transform(Transform(Basis(), Vector3(0, 0, 0.00001)));
}
CollisionPolygonEditor::~CollisionPolygonEditor() {
- memdelete( imgeom );
+ memdelete(imgeom);
}
-
void CollisionPolygonEditorPlugin::edit(Object *p_object) {
collision_polygon_editor->edit(p_object->cast_to<Node>());
@@ -614,7 +560,7 @@ void CollisionPolygonEditorPlugin::edit(Object *p_object) {
bool CollisionPolygonEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("CollisionPolygon");
+ return p_object->is_class("CollisionPolygon");
}
void CollisionPolygonEditorPlugin::make_visible(bool p_visible) {
@@ -626,24 +572,16 @@ void CollisionPolygonEditorPlugin::make_visible(bool p_visible) {
collision_polygon_editor->hide();
collision_polygon_editor->edit(NULL);
}
-
}
CollisionPolygonEditorPlugin::CollisionPolygonEditorPlugin(EditorNode *p_node) {
- editor=p_node;
- collision_polygon_editor = memnew( CollisionPolygonEditor(p_node) );
+ editor = p_node;
+ collision_polygon_editor = memnew(CollisionPolygonEditor(p_node));
SpatialEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
collision_polygon_editor->hide();
-
-
-
}
-
-CollisionPolygonEditorPlugin::~CollisionPolygonEditorPlugin()
-{
+CollisionPolygonEditorPlugin::~CollisionPolygonEditorPlugin() {
}
-
-#endif
diff --git a/editor/plugins/collision_polygon_editor_plugin.h b/editor/plugins/collision_polygon_editor_plugin.h
index 995f2224bf..3a8428fc62 100644
--- a/editor/plugins/collision_polygon_editor_plugin.h
+++ b/editor/plugins/collision_polygon_editor_plugin.h
@@ -42,12 +42,11 @@
@author Juan Linietsky <reduzio@gmail.com>
*/
-#if 0
class CanvasItemEditor;
class CollisionPolygonEditor : public HBoxContainer {
- GDCLASS(CollisionPolygonEditor, HBoxContainer );
+ GDCLASS(CollisionPolygonEditor, HBoxContainer);
UndoRedo *undo_redo;
enum Mode {
@@ -62,7 +61,6 @@ class CollisionPolygonEditor : public HBoxContainer {
ToolButton *button_create;
ToolButton *button_edit;
-
Ref<SpatialMaterial> line_material;
Ref<SpatialMaterial> handle_material;
@@ -71,7 +69,7 @@ class CollisionPolygonEditor : public HBoxContainer {
CollisionPolygon *node;
ImmediateGeometry *imgeom;
MeshInstance *pointsm;
- Ref<Mesh> m;
+ Ref<ArrayMesh> m;
MenuButton *options;
@@ -91,9 +89,9 @@ protected:
void _notification(int p_what);
void _node_removed(Node *p_node);
static void _bind_methods();
-public:
- virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event);
+public:
+ virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
CollisionPolygonEditor(EditorNode *p_editor);
~CollisionPolygonEditor();
@@ -101,14 +99,13 @@ public:
class CollisionPolygonEditorPlugin : public EditorPlugin {
- GDCLASS( CollisionPolygonEditorPlugin, EditorPlugin );
+ GDCLASS(CollisionPolygonEditorPlugin, EditorPlugin);
CollisionPolygonEditor *collision_polygon_editor;
EditorNode *editor;
public:
-
- virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) { return collision_polygon_editor->forward_spatial_gui_input(p_camera,p_event); }
+ virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_spatial_gui_input(p_camera, p_event); }
virtual String get_name() const { return "CollisionPolygon"; }
bool has_main_screen() const { return false; }
@@ -118,7 +115,6 @@ public:
CollisionPolygonEditorPlugin(EditorNode *p_node);
~CollisionPolygonEditorPlugin();
-
};
-#endif
+
#endif // COLLISION_POLYGON_EDITOR_PLUGIN_H
diff --git a/editor/plugins/mesh_instance_editor_plugin.cpp b/editor/plugins/mesh_instance_editor_plugin.cpp
index ab09d0dd96..49498d0fa0 100644
--- a/editor/plugins/mesh_instance_editor_plugin.cpp
+++ b/editor/plugins/mesh_instance_editor_plugin.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "mesh_instance_editor_plugin.h"
-#include "scene/3d/body_shape.h"
+#include "scene/3d/collision_shape.h"
#include "scene/3d/navigation_mesh.h"
#include "scene/3d/physics_body.h"
#include "scene/gui/box_container.h"
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index f9f16fea16..3a210f3fe0 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -248,7 +248,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
edited_point=1;
return true;
} else {
- if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
+ if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_threshold) {
//wip closed
_wip_close();
@@ -307,7 +307,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
continue; //not valid to reuse point
real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
@@ -343,7 +343,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector2 cp =xform.xform(poly[i]);
real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
@@ -396,7 +396,7 @@ bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Vector2 cp =xform.xform(poly[i]);
real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index b28b559b71..f7952e77f2 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -1083,7 +1083,7 @@ void ScriptEditor::_notification(int p_what) {
}
EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed");
- help_search->set_icon(get_icon("Help", "EditorIcons"));
+ help_search->set_icon(get_icon("HelpSearch", "EditorIcons"));
site_search->set_icon(get_icon("Instance", "EditorIcons"));
class_search->set_icon(get_icon("ClassList", "EditorIcons"));
@@ -2231,11 +2231,17 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
members_overview_enabled = true;
editor = p_editor;
+ Ref<StyleBox> sb = p_editor->get_gui_base()->get_stylebox("panel", "TabContainer")->duplicate();
+ sb->set_default_margin(MARGIN_TOP, 0);
+ add_style_override("panel", sb);
+ VBoxContainer *main_container = memnew(VBoxContainer);
+ add_child(main_container);
+
menu_hb = memnew(HBoxContainer);
- add_child(menu_hb);
+ main_container->add_child(menu_hb);
script_split = memnew(HSplitContainer);
- add_child(script_split);
+ main_container->add_child(script_split);
script_split->set_v_size_flags(SIZE_EXPAND_FILL);
list_split = memnew(VSplitContainer);
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 225e9fc099..3d03eb0f49 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -115,9 +115,9 @@ typedef ScriptEditorBase *(*CreateScriptEditorFunc)(const Ref<Script> &p_script)
class EditorScriptCodeCompletionCache;
-class ScriptEditor : public VBoxContainer {
+class ScriptEditor : public PanelContainer {
- GDCLASS(ScriptEditor, VBoxContainer);
+ GDCLASS(ScriptEditor, PanelContainer);
EditorNode *editor;
enum {
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 83741c7fb8..e260b1ea22 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1276,8 +1276,6 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
color_picker->set_pick_color(Color(color[0], color[1], color[2], alpha));
}
color_panel->set_position(get_global_transform().xform(get_local_mouse_pos()));
- Size2 ms = Size2(300, color_picker->get_combined_minimum_size().height + 10);
- color_panel->set_size(ms);
} else {
have_color = false;
}
@@ -1360,7 +1358,6 @@ ScriptTextEditor::ScriptTextEditor() {
add_child(color_panel);
color_picker = memnew(ColorPicker);
color_panel->add_child(color_picker);
- color_panel->set_child_rect(color_picker); //NOT
color_picker->connect("color_changed", this, "_color_changed");
edit_hb = memnew(HBoxContainer);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 995d13f6a8..58fc32309f 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -1717,11 +1717,11 @@ void SpatialEditorViewport::_notification(int p_what) {
//update shadow atlas if changed
- int shadowmap_size = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/size");
- int atlas_q0 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_0_subdiv");
- int atlas_q1 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_1_subdiv");
- int atlas_q2 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_2_subdiv");
- int atlas_q3 = GlobalConfig::get_singleton()->get("rendering/shadow_atlas/quadrant_3_subdiv");
+ int shadowmap_size = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/size");
+ int atlas_q0 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_0_subdiv");
+ int atlas_q1 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_1_subdiv");
+ int atlas_q2 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_2_subdiv");
+ int atlas_q3 = GlobalConfig::get_singleton()->get("rendering/quality/shadow_atlas/quadrant_3_subdiv");
viewport->set_shadow_atlas_size(shadowmap_size);
viewport->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(atlas_q0));
@@ -1731,10 +1731,10 @@ void SpatialEditorViewport::_notification(int p_what) {
//update msaa if changed
- int msaa_mode = GlobalConfig::get_singleton()->get("rendering/quality/msaa");
+ int msaa_mode = GlobalConfig::get_singleton()->get("rendering/quality/filters/msaa");
viewport->set_msaa(Viewport::MSAA(msaa_mode));
- bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/hdr");
+ bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/depth/hdr");
viewport->set_hdr(hdr);
bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
@@ -1834,7 +1834,7 @@ void SpatialEditorViewport::_draw() {
if (previewing) {
- Size2 ss = Size2(GlobalConfig::get_singleton()->get("display/width"), GlobalConfig::get_singleton()->get("display/height"));
+ Size2 ss = Size2(GlobalConfig::get_singleton()->get("display/window/size/width"), GlobalConfig::get_singleton()->get("display/window/size/height"));
float aspect = ss.aspect();
Size2 s = get_size();
@@ -2025,6 +2025,15 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, current);
} break;
+ case VIEW_AUDIO_DOPPLER: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ current = !current;
+ camera->set_doppler_tracking(current ? Camera::DOPPLER_TRACKING_IDLE_STEP : Camera::DOPPLER_TRACKING_DISABLED);
+ view_menu->get_popup()->set_item_checked(idx, current);
+
+ } break;
case VIEW_GIZMOS: {
int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
@@ -2237,6 +2246,13 @@ void SpatialEditorViewport::set_state(const Dictionary &p_state) {
viewport->set_as_audio_listener(listener);
view_menu->get_popup()->set_item_checked(idx, listener);
}
+ if (p_state.has("doppler")) {
+ bool doppler = p_state["doppler"];
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_DOPPLER);
+ camera->set_doppler_tracking(doppler ? Camera::DOPPLER_TRACKING_IDLE_STEP : Camera::DOPPLER_TRACKING_DISABLED);
+ view_menu->get_popup()->set_item_checked(idx, doppler);
+ }
if (p_state.has("previewing")) {
Node *pv = EditorNode::get_singleton()->get_edited_scene()->get_node(p_state["previewing"]);
@@ -2395,6 +2411,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_doppler", TTR("Doppler Enable")), VIEW_AUDIO_DOPPLER);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 6b05a8b370..9b626054c0 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -83,6 +83,7 @@ class SpatialEditorViewport : public Control {
VIEW_ENVIRONMENT,
VIEW_ORTHOGONAL,
VIEW_AUDIO_LISTENER,
+ VIEW_AUDIO_DOPPLER,
VIEW_GIZMOS,
VIEW_INFORMATION,
VIEW_DISPLAY_NORMAL,
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 355f8ba22e..ce22ed4731 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -763,7 +763,7 @@ ProjectExportDialog::ProjectExportDialog() {
parameters->set_name(TTR("Options"));
parameters->hide_top_label();
parameters->set_v_size_flags(SIZE_EXPAND_FILL);
- parameters->set_hide_script(true);
+
parameters->connect("property_edited", this, "_update_parameters");
VBoxContainer *resources_vb = memnew(VBoxContainer);
diff --git a/editor/project_settings.cpp b/editor/project_settings.cpp
index 17a35282de..f72c655561 100644
--- a/editor/project_settings.cpp
+++ b/editor/project_settings.cpp
@@ -1411,7 +1411,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
globals_editor->get_property_editor()->set_undo_redo(EditorNode::get_singleton()->get_undo_redo());
//globals_editor->hide_top_label();
globals_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- globals_editor->get_property_editor()->register_text_enter(search_box);
+ globals_editor->register_search_box(search_box);
globals_editor->get_property_editor()->get_scene_tree()->connect("cell_selected", this, "_item_selected");
globals_editor->get_property_editor()->connect("property_toggled", this, "_item_checked", varray(), CONNECT_DEFERRED);
globals_editor->get_property_editor()->connect("property_edited", this, "_settings_prop_edited");
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 8a9fd2cde5..31be4e1818 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -815,16 +815,12 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
color_picker = memnew(ColorPicker);
add_child(color_picker);
color_picker->hide();
- color_picker->set_area_as_parent_rect();
- for (int i = 0; i < 4; i++)
- color_picker->set_margin((Margin)i, 5);
color_picker->connect("color_changed", this, "_color_changed");
}
color_picker->show();
color_picker->set_edit_alpha(hint != PROPERTY_HINT_COLOR_NO_ALPHA);
color_picker->set_pick_color(v);
- set_size(Size2(307 * EDSCALE, 460 * EDSCALE));
color_picker->set_focus_on_line_edit();
/*
int ofs=80;
@@ -4331,7 +4327,7 @@ PropertyEditor::PropertyEditor() {
_prop_edited = "property_edited";
- hide_script = false;
+ hide_script = true;
use_folding = false;
undo_redo = NULL;
@@ -4512,6 +4508,7 @@ public:
void SectionedPropertyEditor::_bind_methods() {
ClassDB::bind_method("_section_selected", &SectionedPropertyEditor::_section_selected);
+ ClassDB::bind_method("_search_changed", &SectionedPropertyEditor::_search_changed);
ClassDB::bind_method("update_category_list", &SectionedPropertyEditor::update_category_list);
}
@@ -4609,6 +4606,10 @@ void SectionedPropertyEditor::update_category_list() {
if (pi.name.find(":") != -1 || pi.name == "script" || pi.name == "resource_name" || pi.name == "resource_path")
continue;
+
+ if (search_box && search_box->get_text() != String() && pi.name.findn(search_box->get_text()) == -1)
+ continue;
+
int sp = pi.name.find("/");
if (sp == -1)
pi.name = "Global/" + pi.name;
@@ -4616,7 +4617,9 @@ void SectionedPropertyEditor::update_category_list() {
Vector<String> sectionarr = pi.name.split("/");
String metasection;
- for (int i = 0; i < MIN(2, sectionarr.size() - 1); i++) {
+ int sc = MIN(2, sectionarr.size() - 1);
+
+ for (int i = 0; i < sc; i++) {
TreeItem *parent = section_map[metasection];
@@ -4631,6 +4634,12 @@ void SectionedPropertyEditor::update_category_list() {
section_map[metasection] = ms;
ms->set_text(0, sectionarr[i].capitalize());
ms->set_metadata(0, metasection);
+ ms->set_selectable(0, false);
+ }
+
+ if (i == sc - 1) {
+ //if it has children, make selectable
+ section_map[metasection]->set_selectable(0, true);
}
}
}
@@ -4640,6 +4649,18 @@ void SectionedPropertyEditor::update_category_list() {
}
}
+void SectionedPropertyEditor::register_search_box(LineEdit *p_box) {
+
+ search_box = p_box;
+ editor->register_text_enter(p_box);
+ search_box->connect("text_changed", this, "_search_changed");
+}
+
+void SectionedPropertyEditor::_search_changed(const String &p_what) {
+
+ update_category_list();
+}
+
PropertyEditor *SectionedPropertyEditor::get_property_editor() {
return editor;
@@ -4649,6 +4670,8 @@ SectionedPropertyEditor::SectionedPropertyEditor() {
obj = -1;
+ search_box = NULL;
+
VBoxContainer *left_vb = memnew(VBoxContainer);
left_vb->set_custom_minimum_size(Size2(160, 0) * EDSCALE);
add_child(left_vb);
diff --git a/editor/property_editor.h b/editor/property_editor.h
index 47bd807c3f..1ae44e473b 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -1,4 +1,4 @@
-/*************************************************************************/
+/*************************************************************************/
/* property_editor.h */
/*************************************************************************/
/* This file is part of: */
@@ -307,11 +307,15 @@ class SectionedPropertyEditor : public HBoxContainer {
Map<String, TreeItem *> section_map;
PropertyEditor *editor;
+ LineEdit *search_box;
static void _bind_methods();
void _section_selected();
+ void _search_changed(const String &p_what);
+
public:
+ void register_search_box(LineEdit *p_box);
PropertyEditor *get_property_editor();
void edit(Object *p_object);
String get_full_item_path(const String &p_item);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 886474200e..cdae9baaf2 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -663,13 +663,16 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (List<Node *>::Element *e = selection.front()) {
if (Node *node = e->get()) {
bool editable = EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(node);
+ int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children"));
+ int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder"));
editable = !editable;
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, editable);
- menu->set_item_checked(18, editable);
+
+ menu->set_item_checked(editable_item_idx, editable);
if (editable) {
node->set_scene_instance_load_placeholder(false);
- menu->set_item_checked(19, false);
+ menu->set_item_checked(placeholder_item_idx, false);
}
scene_tree->update_tree();
}
@@ -681,12 +684,14 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (Node *node = e->get()) {
bool placeholder = node->get_scene_instance_load_placeholder();
placeholder = !placeholder;
+ int editable_item_idx = menu->get_item_idx_from_text(TTR("Editable Children"));
+ int placeholder_item_idx = menu->get_item_idx_from_text(TTR("Load As Placeholder"));
if (placeholder)
EditorNode::get_singleton()->get_edited_scene()->set_editable_instance(node, false);
node->set_scene_instance_load_placeholder(placeholder);
- menu->set_item_checked(18, false);
- menu->set_item_checked(19, placeholder);
+ menu->set_item_checked(editable_item_idx, false);
+ menu->set_item_checked(placeholder_item_idx, placeholder);
scene_tree->update_tree();
}
}
@@ -1892,8 +1897,8 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->add_check_item(TTR("Load As Placeholder"), TOOL_SCENE_USE_PLACEHOLDER);
menu->add_item(TTR("Discard Instancing"), TOOL_SCENE_CLEAR_INSTANCING);
menu->add_icon_item(get_icon("Load", "EditorIcons"), TTR("Open in Editor"), TOOL_SCENE_OPEN);
- menu->set_item_checked(18, editable);
- menu->set_item_checked(19, placeholder);
+ menu->set_item_checked(menu->get_item_idx_from_text(TTR("Editable Children")), editable);
+ menu->set_item_checked(menu->get_item_idx_from_text(TTR("Load As Placeholder")), placeholder);
}
}
}
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index d12d8b5528..f35e098065 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -161,7 +161,7 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
item->set_selectable(0, true);
if (can_rename) {
-#ifdef ENABLE_DEPRECATED
+#ifndef DISABLE_DEPRECATED
if (p_node->has_meta("_editor_collapsed")) {
//remove previous way of storing folding, which did not get along with scene inheritance and instancing
if ((bool)p_node->get_meta("_editor_collapsed"))
@@ -224,11 +224,11 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (p_node == get_scene_node() && p_node->get_scene_inherited_state().is_valid()) {
- item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Subscene options"));
+ item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
item->set_tooltip(0, TTR("Inherits:") + " " + p_node->get_scene_inherited_state()->get_path() + "\n" + TTR("Type:") + " " + p_node->get_class());
} else if (p_node != get_scene_node() && p_node->get_filename() != "" && can_open_instance) {
- item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Subscene options"));
+ item->add_button(0, get_icon("InstanceOptions", "EditorIcons"), BUTTON_SUBSCENE, false, TTR("Open in Editor"));
item->set_tooltip(0, TTR("Instance:") + " " + p_node->get_filename() + "\n" + TTR("Type:") + " " + p_node->get_class());
} else {
item->set_tooltip(0, String(p_node->get_name()) + "\n" + TTR("Type:") + " " + p_node->get_class());
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 9dce48937c..c2e54ebd69 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -1625,24 +1625,24 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
hbc->add_child(memnew(VSeparator));
- step = memnew(Button);
+ step = memnew(ToolButton);
hbc->add_child(step);
step->set_tooltip(TTR("Step Into"));
step->connect("pressed", this, "debug_step");
- next = memnew(Button);
+ next = memnew(ToolButton);
hbc->add_child(next);
next->set_tooltip(TTR("Step Over"));
next->connect("pressed", this, "debug_next");
hbc->add_child(memnew(VSeparator));
- dobreak = memnew(Button);
+ dobreak = memnew(ToolButton);
hbc->add_child(dobreak);
dobreak->set_tooltip(TTR("Break"));
dobreak->connect("pressed", this, "debug_break");
- docontinue = memnew(Button);
+ docontinue = memnew(ToolButton);
hbc->add_child(docontinue);
docontinue->set_tooltip(TTR("Continue"));
docontinue->connect("pressed", this, "debug_continue");
@@ -1816,7 +1816,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_total->set_editable(false);
vmem_total->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
vmem_hb->add_child(vmem_total);
- vmem_refresh = memnew(Button);
+ vmem_refresh = memnew(ToolButton);
vmem_hb->add_child(vmem_refresh);
vmem_vb->add_child(vmem_hb);
vmem_refresh->connect("pressed", this, "_video_mem_request");
@@ -1849,30 +1849,31 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
}
{ // misc
- VBoxContainer *info_left = memnew(VBoxContainer);
- info_left->set_h_size_flags(SIZE_EXPAND_FILL);
+ GridContainer *info_left = memnew(GridContainer);
+ info_left->set_columns(2);
info_left->set_name(TTR("Misc"));
tabs->add_child(info_left);
clicked_ctrl = memnew(LineEdit);
- info_left->add_margin_child(TTR("Clicked Control:"), clicked_ctrl);
+ clicked_ctrl->set_h_size_flags(SIZE_EXPAND_FILL);
+ info_left->add_child(memnew(Label(TTR("Clicked Control:"))));
+ info_left->add_child(clicked_ctrl);
clicked_ctrl_type = memnew(LineEdit);
- info_left->add_margin_child(TTR("Clicked Control Type:"), clicked_ctrl_type);
+ info_left->add_child(memnew(Label(TTR("Clicked Control Type:"))));
+ info_left->add_child(clicked_ctrl_type);
live_edit_root = memnew(LineEdit);
+ live_edit_root->set_h_size_flags(SIZE_EXPAND_FILL);
{
HBoxContainer *lehb = memnew(HBoxContainer);
Label *l = memnew(Label(TTR("Live Edit Root:")));
- lehb->add_child(l);
- l->set_h_size_flags(SIZE_EXPAND_FILL);
+ info_left->add_child(l);
+ lehb->add_child(live_edit_root);
le_set = memnew(Button(TTR("Set From Tree")));
lehb->add_child(le_set);
le_clear = memnew(Button(TTR("Clear")));
lehb->add_child(le_clear);
info_left->add_child(lehb);
- MarginContainer *mc = memnew(MarginContainer);
- mc->add_child(live_edit_root);
- info_left->add_child(mc);
le_set->set_disabled(true);
le_clear->set_disabled(true);
}
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 6f613981b8..6c64f3af42 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -332,7 +332,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
property_editor = memnew(SectionedPropertyEditor);
//property_editor->hide_top_label();
property_editor->get_property_editor()->set_use_filter(true);
- property_editor->get_property_editor()->register_text_enter(search_box);
+ property_editor->register_search_box(search_box);
property_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
vbc->add_child(property_editor);
property_editor->get_property_editor()->connect("property_edited", this, "_settings_property_edited");
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 62fa93ac23..faf9dee5d0 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -867,6 +867,127 @@ LightSpatialGizmo::LightSpatialGizmo(Light *p_light) {
//////
+//// player gizmo
+
+String AudioStreamPlayer3DSpatialGizmo::get_handle_name(int p_idx) const {
+
+ return "Emission Radius";
+}
+
+Variant AudioStreamPlayer3DSpatialGizmo::get_handle_value(int p_idx) const {
+
+ return player->get_emission_angle();
+}
+
+void AudioStreamPlayer3DSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
+
+ Transform gt = player->get_global_transform();
+ gt.orthonormalize();
+ Transform gi = gt.affine_inverse();
+
+ Vector3 ray_from = p_camera->project_ray_origin(p_point);
+ Vector3 ray_dir = p_camera->project_ray_normal(p_point);
+ Vector3 ray_to = ray_from + ray_dir * 4096;
+
+ ray_from = gi.xform(ray_from);
+ ray_to = gi.xform(ray_to);
+
+ float closest_dist = 1e20;
+ float closest_angle = 1e20;
+
+ for (int i = 0; i < 180; i++) {
+
+ float a = i * Math_PI / 180.0;
+ float an = (i + 1) * Math_PI / 180.0;
+
+ Vector3 from(Math::sin(a), 0, -Math::cos(a));
+ Vector3 to(Math::sin(an), 0, -Math::cos(an));
+
+ Vector3 r1, r2;
+ Geometry::get_closest_points_between_segments(from, to, ray_from, ray_to, r1, r2);
+ float d = r1.distance_to(r2);
+ if (d < closest_dist) {
+ closest_dist = d;
+ closest_angle = i;
+ }
+ }
+
+ if (closest_angle < 91) {
+ player->set_emission_angle(closest_angle);
+ }
+}
+
+void AudioStreamPlayer3DSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
+
+ if (p_cancel) {
+
+ player->set_emission_angle(p_restore);
+
+ } else {
+
+ UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
+ ur->create_action(TTR("Change AudioStreamPlayer3D Emission Angle"));
+ ur->add_do_method(player, "set_emission_angle", player->get_emission_angle());
+ ur->add_undo_method(player, "set_emission_angle", p_restore);
+ ur->commit_action();
+ }
+}
+
+void AudioStreamPlayer3DSpatialGizmo::redraw() {
+
+ clear();
+
+ if (player->is_emission_angle_enabled()) {
+ float pc = player->get_emission_angle();
+
+ Vector<Vector3> points;
+ points.resize(208);
+
+ float ofs = -Math::cos(Math::deg2rad(pc));
+ float radius = Math::sin(Math::deg2rad(pc));
+
+ for (int i = 0; i < 100; i++) {
+
+ float a = i * 2.0 * Math_PI / 100.0;
+ float an = (i + 1) * 2.0 * Math_PI / 100.0;
+
+ Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
+ Vector3 to(Math::sin(an) * radius, Math::cos(an) * radius, ofs);
+
+ points[i * 2 + 0] = from;
+ points[i * 2 + 1] = to;
+ }
+
+ for (int i = 0; i < 4; i++) {
+
+ float a = i * 2.0 * Math_PI / 4.0;
+
+ Vector3 from(Math::sin(a) * radius, Math::cos(a) * radius, ofs);
+
+ points[200 + i * 2 + 0] = from;
+ points[200 + i * 2 + 1] = Vector3();
+ }
+
+ add_lines(points, SpatialEditorGizmos::singleton->car_wheel_material);
+ add_collision_segments(points);
+
+ Vector<Vector3> handles;
+ float ha = Math::deg2rad(player->get_emission_angle());
+ handles.push_back(Vector3(Math::sin(ha), 0, -Math::cos(ha)));
+ add_handles(handles);
+ }
+
+ add_unscaled_billboard(SpatialEditorGizmos::singleton->sample_player_icon, 0.05);
+}
+
+AudioStreamPlayer3DSpatialGizmo::AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player) {
+
+ player = p_player;
+ set_spatial_node(p_player);
+}
+
+//////
+
String CameraSpatialGizmo::get_handle_name(int p_idx) const {
if (camera->get_projection() == Camera::PROJECTION_PERSPECTIVE) {
@@ -3101,6 +3222,12 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
return misg;
}
+ if (p_spatial->cast_to<AudioStreamPlayer3D>()) {
+
+ Ref<AudioStreamPlayer3DSpatialGizmo> misg = memnew(AudioStreamPlayer3DSpatialGizmo(p_spatial->cast_to<AudioStreamPlayer3D>()));
+ return misg;
+ }
+
return Ref<SpatialEditorGizmo>();
}
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index a8ace87530..469a2d594a 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -31,9 +31,10 @@
#define SPATIAL_EDITOR_GIZMOS_H
#include "editor/plugins/spatial_editor_plugin.h"
-#include "scene/3d/body_shape.h"
+#include "scene/3d/audio_stream_player_3d.h"
#include "scene/3d/camera.h"
#include "scene/3d/collision_polygon.h"
+#include "scene/3d/collision_shape.h"
#include "scene/3d/gi_probe.h"
#include "scene/3d/light.h"
#include "scene/3d/listener.h"
@@ -137,6 +138,22 @@ public:
LightSpatialGizmo(Light *p_light = NULL);
};
+class AudioStreamPlayer3DSpatialGizmo : public EditorSpatialGizmo {
+
+ GDCLASS(AudioStreamPlayer3DSpatialGizmo, EditorSpatialGizmo);
+
+ AudioStreamPlayer3D *player;
+
+public:
+ virtual String get_handle_name(int p_idx) const;
+ virtual Variant get_handle_value(int p_idx) const;
+ virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
+ virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
+
+ void redraw();
+ AudioStreamPlayer3DSpatialGizmo(AudioStreamPlayer3D *p_player = NULL);
+};
+
class CameraSpatialGizmo : public EditorSpatialGizmo {
GDCLASS(CameraSpatialGizmo, EditorSpatialGizmo);
diff --git a/main/main.cpp b/main/main.cpp
index 218321ef25..ece54e7427 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -578,9 +578,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
I = N;
}
- GLOBAL_DEF("memory/multithread/thread_rid_pool_prealloc", 60);
-
- GLOBAL_DEF("network/debug/max_remote_stdout_chars_per_second", 2048);
+ GLOBAL_DEF("memory/limits/multithreaded_server/rid_pool_prealloc", 60);
+ GLOBAL_DEF("network/limits/debugger_stdout/max_chars_per_second", 2048);
if (debug_mode == "remote") {
@@ -666,10 +665,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
use_custom_res = false;
}
- if (bool(GlobalConfig::get_singleton()->get("application/disable_stdout"))) {
+ if (bool(GlobalConfig::get_singleton()->get("application/run/disable_stdout"))) {
quiet_stdout = true;
}
- if (bool(GlobalConfig::get_singleton()->get("application/disable_stderr"))) {
+ if (bool(GlobalConfig::get_singleton()->get("application/run/disable_stderr"))) {
_print_error_enabled = false;
};
@@ -680,7 +679,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#ifdef TOOLS_ENABLED
- if (main_args.size() == 0 && (!GlobalConfig::get_singleton()->has("application/main_loop_type")) && (!GlobalConfig::get_singleton()->has("application/main_scene") || String(GlobalConfig::get_singleton()->get("application/main_scene")) == ""))
+ if (main_args.size() == 0 && (!GlobalConfig::get_singleton()->has("application/run/main_loop_type")) && (!GlobalConfig::get_singleton()->has("application/main_scene") || String(GlobalConfig::get_singleton()->get("application/main_scene")) == ""))
use_custom_res = false; //project manager (run without arguments)
#endif
@@ -690,43 +689,43 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
else
input_map->load_from_globals(); //keys for game
- if (video_driver == "") // specified in project.godot
- video_driver = GLOBAL_DEF("display/driver/name", Variant((const char *)OS::get_singleton()->get_video_driver_name(0)));
+ //if (video_driver == "") // useless for now, so removing
+ // video_driver = GLOBAL_DEF("display/driver/name", Variant((const char *)OS::get_singleton()->get_video_driver_name(0)));
- if (!force_res && use_custom_res && globals->has("display/window/width"))
- video_mode.width = globals->get("display/window/width");
- if (!force_res && use_custom_res && globals->has("display/window/height"))
- video_mode.height = globals->get("display/window/height");
- if (!editor && ((globals->has("display/window/allow_hidpi") && !globals->get("display/window/allow_hidpi")) || force_lowdpi)) {
+ if (!force_res && use_custom_res && globals->has("display/window/size/width"))
+ video_mode.width = globals->get("display/window/size/width");
+ if (!force_res && use_custom_res && globals->has("display/window/size/height"))
+ video_mode.height = globals->get("display/window/size/height");
+ if (!editor && ((globals->has("display/window/dpi/allow_hidpi") && !globals->get("display/window/dpi/allow_hidpi")) || force_lowdpi)) {
OS::get_singleton()->_allow_hidpi = false;
}
- if (use_custom_res && globals->has("display/window/fullscreen"))
- video_mode.fullscreen = globals->get("display/window/fullscreen");
- if (use_custom_res && globals->has("display/window/resizable"))
- video_mode.resizable = globals->get("display/window/resizable");
- if (use_custom_res && globals->has("display/window/borderless"))
- video_mode.borderless_window = globals->get("display/window/borderless");
-
- if (!force_res && use_custom_res && globals->has("display/window/test_width") && globals->has("display/window/test_height")) {
- int tw = globals->get("display/window/test_width");
- int th = globals->get("display/window/test_height");
+ if (use_custom_res && globals->has("display/window/size/fullscreen"))
+ video_mode.fullscreen = globals->get("display/window/size/fullscreen");
+ if (use_custom_res && globals->has("display/window/size/resizable"))
+ video_mode.resizable = globals->get("display/window/size/resizable");
+ if (use_custom_res && globals->has("display/window/size/borderless"))
+ video_mode.borderless_window = globals->get("display/window/size/borderless");
+
+ if (!force_res && use_custom_res && globals->has("display/window/size/test_width") && globals->has("display/window/size/test_height")) {
+ int tw = globals->get("display/window/size/test_width");
+ int th = globals->get("display/window/size/test_height");
if (tw > 0 && th > 0) {
video_mode.width = tw;
video_mode.height = th;
}
}
- GLOBAL_DEF("display/window/width", video_mode.width);
- GLOBAL_DEF("display/window/height", video_mode.height);
- GLOBAL_DEF("display/window/allow_hidpi", false);
- GLOBAL_DEF("display/window/fullscreen", video_mode.fullscreen);
- GLOBAL_DEF("display/window/resizable", video_mode.resizable);
- GLOBAL_DEF("display/window/borderless", video_mode.borderless_window);
- use_vsync = GLOBAL_DEF("display/window/use_vsync", use_vsync);
- GLOBAL_DEF("display/window/test_width", 0);
- GLOBAL_DEF("display/window/test_height", 0);
- Engine::get_singleton()->_pixel_snap = GLOBAL_DEF("rendering/2d/use_pixel_snap", false);
- OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/energy_saving/keep_screen_on", true);
+ GLOBAL_DEF("display/window/size/width", video_mode.width);
+ GLOBAL_DEF("display/window/size/height", video_mode.height);
+ GLOBAL_DEF("display/window/dpi/allow_hidpi", false);
+ GLOBAL_DEF("display/window/size/fullscreen", video_mode.fullscreen);
+ GLOBAL_DEF("display/window/size/resizable", video_mode.resizable);
+ GLOBAL_DEF("display/window/size/borderless", video_mode.borderless_window);
+ use_vsync = GLOBAL_DEF("display/window/vsync/use_vsync", use_vsync);
+ GLOBAL_DEF("display/window/size/test_width", 0);
+ GLOBAL_DEF("display/window/size/test_height", 0);
+ Engine::get_singleton()->_pixel_snap = GLOBAL_DEF("rendering/quality/2d/use_pixel_snap", false);
+ OS::get_singleton()->_keep_screen_on = GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true);
if (rtm == -1) {
rtm = GLOBAL_DEF("rendering/threads/thread_model", OS::RENDER_THREAD_SAFE);
if (rtm >= 1) //hack for now
@@ -757,7 +756,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
if (video_driver_idx < 0) {
- OS::get_singleton()->alert("Invalid Video Driver: " + video_driver);
+ //OS::get_singleton()->alert("Invalid Video Driver: " + video_driver);
video_driver_idx = 0;
//goto error;
}
@@ -779,7 +778,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
{
- String orientation = GLOBAL_DEF("display/handheld/orientation", "landscape");
+ String orientation = GLOBAL_DEF("display/window/handheld/orientation", "landscape");
if (orientation == "portrait")
OS::get_singleton()->set_screen_orientation(OS::SCREEN_PORTRAIT);
@@ -798,15 +797,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
}
Engine::get_singleton()->set_iterations_per_second(GLOBAL_DEF("physics/common/fixed_fps", 60));
- Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/fps/force_fps", 0));
+ Engine::get_singleton()->set_target_fps(GLOBAL_DEF("debug/settings/fps/force_fps", 0));
- GLOBAL_DEF("debug/stdout/print_fps", OS::get_singleton()->is_stdout_verbose());
+ GLOBAL_DEF("debug/settings/stdout/print_fps", OS::get_singleton()->is_stdout_verbose());
if (!OS::get_singleton()->_verbose_stdout) //overrided
- OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/stdout/verbose_stdout", false);
+ OS::get_singleton()->_verbose_stdout = GLOBAL_DEF("debug/settings/stdout/verbose_stdout", false);
if (frame_delay == 0) {
- frame_delay = GLOBAL_DEF("application/frame_delay_msec", 0);
+ frame_delay = GLOBAL_DEF("application/run/frame_delay_msec", 0);
}
Engine::get_singleton()->set_frame_delay(frame_delay);
@@ -908,13 +907,13 @@ Error Main::setup2() {
MAIN_PRINT("Main: Load Remaps");
- Color clear = GLOBAL_DEF("rendering/viewport/default_clear_color", Color(0.3, 0.3, 0.3));
+ Color clear = GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3));
VisualServer::get_singleton()->set_default_clear_color(clear);
if (show_logo) { //boot logo!
- String boot_logo_path = GLOBAL_DEF("application/boot_splash", String());
- bool boot_logo_scale = GLOBAL_DEF("application/boot_splash_fullsize", true);
- GlobalConfig::get_singleton()->set_custom_property_info("application/boot_splash", PropertyInfo(Variant::STRING, "application/boot_splash", PROPERTY_HINT_FILE, "*.png"));
+ String boot_logo_path = GLOBAL_DEF("application/boot_splash/image", String());
+ bool boot_logo_scale = GLOBAL_DEF("application/boot_splash/fullsize", true);
+ GlobalConfig::get_singleton()->set_custom_property_info("application/boot_splash/image", PropertyInfo(Variant::STRING, "application/boot_splash/image", PROPERTY_HINT_FILE, "*.png"));
Ref<Image> boot_logo;
@@ -930,7 +929,7 @@ Error Main::setup2() {
if (boot_logo.is_valid()) {
OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec();
- Color boot_bg = GLOBAL_DEF("application/boot_bg_color", clear);
+ Color boot_bg = GLOBAL_DEF("application/boot_splash/bg_color", clear);
VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale);
#ifndef TOOLS_ENABLED
//no tools, so free the boot logo (no longer needed)
@@ -955,13 +954,13 @@ Error Main::setup2() {
}
MAIN_PRINT("Main: DCC");
- VisualServer::get_singleton()->set_default_clear_color(GLOBAL_DEF("rendering/viewport/default_clear_color", Color(0.3, 0.3, 0.3)));
+ VisualServer::get_singleton()->set_default_clear_color(GLOBAL_DEF("rendering/environment/default_clear_color", Color(0.3, 0.3, 0.3)));
MAIN_PRINT("Main: END");
- GLOBAL_DEF("application/icon", String());
- GlobalConfig::get_singleton()->set_custom_property_info("application/icon", PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
+ GLOBAL_DEF("application/config/icon", String());
+ GlobalConfig::get_singleton()->set_custom_property_info("application/config/icon", PropertyInfo(Variant::STRING, "application/config/icon", PROPERTY_HINT_FILE, "*.png,*.webp"));
- if (bool(GLOBAL_DEF("display/handheld/emulate_touchscreen", false))) {
+ if (bool(GLOBAL_DEF("display/window/handheld/emulate_touchscreen", false))) {
if (!OS::get_singleton()->has_touchscreen_ui_hint() && Input::get_singleton() && !editor) {
//only if no touchscreen ui hint, set emulation
InputDefault *id = Input::get_singleton()->cast_to<InputDefault>();
@@ -1145,8 +1144,8 @@ bool Main::start() {
}
}
- if (script == "" && game_path == "" && String(GLOBAL_DEF("application/main_scene", "")) != "") {
- game_path = GLOBAL_DEF("application/main_scene", "");
+ if (script == "" && game_path == "" && String(GLOBAL_DEF("application/run/main_scene", "")) != "") {
+ game_path = GLOBAL_DEF("application/run/main_scene", "");
}
MainLoop *main_loop = NULL;
@@ -1189,7 +1188,7 @@ bool Main::start() {
}
} else {
- main_loop_type = GLOBAL_DEF("application/main_loop_type", "");
+ main_loop_type = GLOBAL_DEF("application/run/main_loop_type", "");
}
if (!main_loop && main_loop_type == "")
@@ -1249,12 +1248,15 @@ bool Main::start() {
}
#endif
+ {
+ }
+
if (!editor) {
//standard helpers that can be changed from main config
- String stretch_mode = GLOBAL_DEF("display/stretch/mode", "disabled");
- String stretch_aspect = GLOBAL_DEF("display/stretch/aspect", "ignore");
- Size2i stretch_size = Size2(GLOBAL_DEF("display/window/width", 0), GLOBAL_DEF("display/window/height", 0));
+ 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));
SceneTree::StretchMode sml_sm = SceneTree::STRETCH_MODE_DISABLED;
if (stretch_mode == "2d")
@@ -1272,17 +1274,17 @@ bool Main::start() {
sml->set_screen_stretch(sml_sm, sml_aspect, stretch_size);
- sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit", true));
- sml->set_quit_on_go_back(GLOBAL_DEF("application/quit_on_go_back", true));
- String appname = GlobalConfig::get_singleton()->get("application/name");
+ sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
+ sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
+ String appname = GlobalConfig::get_singleton()->get("application/config/name");
appname = TranslationServer::get_singleton()->translate(appname);
OS::get_singleton()->set_window_title(appname);
- int shadow_atlas_size = GLOBAL_DEF("rendering/shadow_atlas/size", 2048);
- int shadow_atlas_q0_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_0_subdiv", 2);
- int shadow_atlas_q1_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_1_subdiv", 2);
- int shadow_atlas_q2_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_2_subdiv", 3);
- int shadow_atlas_q3_subdiv = GLOBAL_DEF("rendering/shadow_atlas/quadrant_3_subdiv", 4);
+ int shadow_atlas_size = GLOBAL_GET("rendering/quality/shadow_atlas/size");
+ int shadow_atlas_q0_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_0_subdiv");
+ int shadow_atlas_q1_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_1_subdiv");
+ int shadow_atlas_q2_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_2_subdiv");
+ int shadow_atlas_q3_subdiv = GLOBAL_GET("rendering/quality/shadow_atlas/quadrant_3_subdiv");
sml->get_root()->set_shadow_atlas_size(shadow_atlas_size);
sml->get_root()->set_shadow_atlas_quadrant_subdiv(0, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q0_subdiv));
@@ -1291,24 +1293,12 @@ bool Main::start() {
sml->get_root()->set_shadow_atlas_quadrant_subdiv(3, Viewport::ShadowAtlasQuadrantSubdiv(shadow_atlas_q3_subdiv));
} else {
- GLOBAL_DEF("display/stretch/mode", "disabled");
- GlobalConfig::get_singleton()->set_custom_property_info("display/stretch/mode", PropertyInfo(Variant::STRING, "display/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
- GLOBAL_DEF("display/stretch/aspect", "ignore");
- GlobalConfig::get_singleton()->set_custom_property_info("display/stretch/aspect", PropertyInfo(Variant::STRING, "display/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height"));
- sml->set_auto_accept_quit(GLOBAL_DEF("application/auto_accept_quit", true));
- sml->set_quit_on_go_back(GLOBAL_DEF("application/quit_on_go_back", true));
-
- GLOBAL_DEF("rendering/shadow_atlas/size", 2048);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
-
- GLOBAL_DEF("rendering/shadow_atlas/quadrant_0_subdiv", 2);
- GLOBAL_DEF("rendering/shadow_atlas/quadrant_1_subdiv", 2);
- GLOBAL_DEF("rendering/shadow_atlas/quadrant_2_subdiv", 3);
- GLOBAL_DEF("rendering/shadow_atlas/quadrant_3_subdiv", 4);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ GLOBAL_DEF("display/window/stretch/mode", "disabled");
+ GlobalConfig::get_singleton()->set_custom_property_info("display/window/stretch/mode", PropertyInfo(Variant::STRING, "display/window/stretch/mode", PROPERTY_HINT_ENUM, "disabled,2d,viewport"));
+ GLOBAL_DEF("display/window/stretch/aspect", "ignore");
+ GlobalConfig::get_singleton()->set_custom_property_info("display/window/stretch/aspect", PropertyInfo(Variant::STRING, "display/window/stretch/aspect", PROPERTY_HINT_ENUM, "ignore,keep,keep_width,keep_height"));
+ sml->set_auto_accept_quit(GLOBAL_DEF("application/config/auto_accept_quit", true));
+ sml->set_quit_on_go_back(GLOBAL_DEF("application/config/quit_on_go_back", true));
}
String local_game_path;
@@ -1463,7 +1453,7 @@ bool Main::start() {
//sml->get_root()->add_child(scene);
sml->add_current_scene(scene);
- String iconpath = GLOBAL_DEF("application/icon", "Variant()");
+ String iconpath = GLOBAL_DEF("application/config/icon", "Variant()");
if (iconpath != "") {
Ref<Image> icon;
if (icon->load(iconpath) == OK)
@@ -1525,11 +1515,15 @@ static uint64_t idle_process_max = 0;
bool Main::iteration() {
uint64_t ticks = OS::get_singleton()->get_ticks_usec();
+ Engine::get_singleton()->_frame_ticks = ticks;
+
uint64_t ticks_elapsed = ticks - last_ticks;
double step = (double)ticks_elapsed / 1000000.0;
float frame_slice = 1.0 / Engine::get_singleton()->get_iterations_per_second();
+ Engine::get_singleton()->_frame_step = step;
+
/*
if (time_accum+step < frame_slice)
return false;
@@ -1637,7 +1631,7 @@ bool Main::iteration() {
if (frame > 1000000) {
- if (GLOBAL_DEF("debug/stdout/print_fps", OS::get_singleton()->is_stdout_verbose())) {
+ if (GLOBAL_DEF("debug/settings/stdout/print_fps", OS::get_singleton()->is_stdout_verbose())) {
print_line("FPS: " + itos(frames));
};
diff --git a/modules/gdnative/godot/godot_dictionary.cpp b/modules/gdnative/godot/godot_dictionary.cpp
index 12c40f0564..a14a86248b 100644
--- a/modules/gdnative/godot/godot_dictionary.cpp
+++ b/modules/gdnative/godot/godot_dictionary.cpp
@@ -124,11 +124,17 @@ void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p
}
godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key) {
- Array *self = (Array *)p_self;
+ Dictionary *self = (Dictionary *)p_self;
const Variant *key = (const Variant *)p_key;
return (godot_variant *)&self->operator[](*key);
}
+godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key) {
+ Dictionary *self = (Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ return (godot_variant *)self->next(key);
+}
+
godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b) {
const Dictionary *self = (const Dictionary *)p_self;
const Dictionary *b = (const Dictionary *)p_b;
diff --git a/modules/gdnative/godot/godot_dictionary.h b/modules/gdnative/godot/godot_dictionary.h
index 0325670b15..4ded0d38da 100644
--- a/modules/gdnative/godot/godot_dictionary.h
+++ b/modules/gdnative/godot/godot_dictionary.h
@@ -74,6 +74,8 @@ void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p
godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key);
+godot_variant GDAPI *godot_dictionary_next(const godot_dictionary *p_self, const godot_variant *p_key);
+
godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b);
godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self);
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 1dcc442234..0afb6ac179 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -1885,7 +1885,7 @@ GDScriptLanguage::GDScriptLanguage() {
script_frame_time = 0;
_debug_call_stack_pos = 0;
- int dmcs = GLOBAL_DEF("debug/script/max_call_stack", 1024);
+ int dmcs = GLOBAL_DEF("debug/settings/gdscript/max_call_stack", 1024);
if (ScriptDebugger::get_singleton()) {
//debugging enabled!
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index 9d3da8227c..8c2c2ea345 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -380,6 +380,7 @@ void GridMap::set_cell_item(int p_x, int p_y, int p_z, int p_item, int p_rot) {
ii.multimesh->set_mesh(ii.mesh);
ii.multimesh_instance = VS::get_singleton()->instance_create();
VS::get_singleton()->instance_set_base(ii.multimesh_instance, ii.multimesh->get_rid());
+ VS::get_singleton()->instance_geometry_set_flag(ii.multimesh_instance, VS::INSTANCE_FLAG_USE_BAKED_LIGHT, true);
g.items[p_item] = ii;
}
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index a922fdf354..84b4b0cab1 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -2658,7 +2658,7 @@ VisualScriptLanguage::VisualScriptLanguage() {
_debug_parse_err_node = -1;
_debug_parse_err_file = "";
_debug_call_stack_pos = 0;
- int dmcs = GLOBAL_DEF("debug/script/max_call_stack", 1024);
+ int dmcs = GLOBAL_DEF("debug/settings/visual_script/max_call_stack", 1024);
if (ScriptDebugger::get_singleton()) {
//debugging enabled!
_debug_max_call_stack = dmcs;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index a6b53b67fa..08757f4c61 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -492,7 +492,8 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
if (EditorSettings::get_singleton()->has("editors/visual_script/color_" + node->get_category())) {
- gnode->set_modulate(EditorSettings::get_singleton()->get("editors/visual_script/color_" + node->get_category()));
+ Color c = EditorSettings::get_singleton()->get("editors/visual_script/color_" + node->get_category());
+ gnode->set_self_modulate(c);
}
gnode->set_meta("__vnode", node);
@@ -2745,7 +2746,7 @@ void VisualScriptEditor::_node_filter_changed(const String &p_text) {
void VisualScriptEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
- node_filter_icon->set_texture(Control::get_icon("Zoom", "EditorIcons"));
+ node_filter_icon->set_texture(Control::get_icon("Search", "EditorIcons"));
variable_editor->connect("changed", this, "_update_members");
signal_editor->connect("changed", this, "_update_members");
}
@@ -3375,7 +3376,7 @@ static void register_editor_callback() {
EditorSettings::get_singleton()->set("editors/visual_script/color_functions", Color(1, 0.9, 0.9));
EditorSettings::get_singleton()->set("editors/visual_script/color_data", Color(0.9, 1.0, 0.9));
EditorSettings::get_singleton()->set("editors/visual_script/color_operators", Color(0.9, 0.9, 1.0));
- EditorSettings::get_singleton()->set("editors/visual_script/color_flow_control", Color(1.0, 1.0, 0.8));
+ EditorSettings::get_singleton()->set("editors/visual_script/color_flow_control", Color(1.0, 1.0, 1.0));
EditorSettings::get_singleton()->set("editors/visual_script/color_custom", Color(0.8, 1.0, 1.0));
EditorSettings::get_singleton()->set("editors/visual_script/color_constants", Color(1.0, 0.8, 1.0));
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 28622bed47..b53a21c53b 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -944,7 +944,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
filters[idx] = Ref<InputEvent>();
filters[idx].type = Ref<InputEvent>::Type(int(p_value));
if (filters[idx].type == Ref<InputEvent>::JOYPAD_MOTION) {
- filters[idx].joy_motion.axis_value = 0.5; //for treshold
+ filters[idx].joy_motion.axis_value = 0.5; //for threshold
} else if (filters[idx].type == Ref<InputEvent>::KEY) {
filters[idx]->is_pressed() = true; //put these as true to make it more user friendly
} else if (filters[idx].type == Ref<InputEvent>::MOUSE_BUTTON) {
@@ -1071,7 +1071,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
filters[idx].joy_motion.axis = int(p_value) << 1 | filters[idx].joy_motion.axis;
} else if (what == "mode") {
filters[idx].joy_motion.axis |= int(p_value);
- } else if (what == "treshold") {
+ } else if (what == "threshold") {
filters[idx].joy_motion.axis_value = p_value;
} else {
return false;
@@ -1281,7 +1281,7 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
r_ret = filters[idx].joy_motion.axis >> 1;
} else if (what == "mode") {
r_ret = filters[idx].joy_motion.axis & 1;
- } else if (what == "treshold") {
+ } else if (what == "threshold") {
r_ret = filters[idx].joy_motion.axis_value;
} else {
return false;
@@ -1434,7 +1434,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::INT, base + "axis_index"));
p_list->push_back(PropertyInfo(Variant::INT, base + "mode", PROPERTY_HINT_ENUM, "Min,Max"));
- p_list->push_back(PropertyInfo(Variant::REAL, base + "treshold", PROPERTY_HINT_RANGE, "0,1,0.01"));
+ p_list->push_back(PropertyInfo(Variant::REAL, base + "threshold", PROPERTY_HINT_RANGE, "0,1,0.01"));
} break;
case Ref<InputEvent>::JOYPAD_BUTTON: {
p_list->push_back(PropertyInfo(Variant::INT, base + "button_index"));
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index a72e8aa90e..95f48521f8 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -554,7 +554,7 @@ void EditorExportPlatformAndroid::_fix_resources(Vector<uint8_t>& p_manifest) {
} else {
String lang = str.substr(str.find_last("-")+1,str.length()).replace("-","_");
- String prop = "application/name_"+lang;
+ String prop = "application/config/name_"+lang;
if (GlobalConfig::get_singleton()->has(prop)) {
str = GlobalConfig::get_singleton()->get(prop);
} else {
@@ -628,7 +628,7 @@ String EditorExportPlatformAndroid::get_project_name() const {
if (this->name!="") {
aname=this->name;
} else {
- aname = GlobalConfig::get_singleton()->get("application/name");
+ aname = GlobalConfig::get_singleton()->get("application/config/name");
}
@@ -1144,7 +1144,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (!found) {
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
+ String appicon = GlobalConfig::get_singleton()->get("application/config/icon");
if (appicon!="" && appicon.ends_with(".png")) {
FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
if (f) {
@@ -1763,7 +1763,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
String EditorExportPlatformAndroid::get_package_name() {
String pname = package;
- String basename = GlobalConfig::get_singleton()->get("application/name");
+ String basename = GlobalConfig::get_singleton()->get("application/config/name");
basename=basename.to_lower();
String name;
@@ -2208,7 +2208,7 @@ class EditorExportAndroid : public EditorExportPlatform {
if (p_name != "") {
aname = p_name;
} else {
- aname = GlobalConfig::get_singleton()->get("application/name");
+ aname = GlobalConfig::get_singleton()->get("application/config/name");
}
if (aname == "") {
@@ -2221,7 +2221,7 @@ class EditorExportAndroid : public EditorExportPlatform {
String get_package_name(const String &p_package) {
String pname = p_package;
- String basename = GlobalConfig::get_singleton()->get("application/name");
+ String basename = GlobalConfig::get_singleton()->get("application/config/name");
basename = basename.to_lower();
String name;
@@ -2750,7 +2750,7 @@ class EditorExportAndroid : public EditorExportPlatform {
} else {
String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_");
- String prop = "application/name_" + lang;
+ String prop = "application/config/name_" + lang;
if (GlobalConfig::get_singleton()->has(prop)) {
str = GlobalConfig::get_singleton()->get(prop);
} else {
@@ -3219,7 +3219,7 @@ public:
if (!found) {
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
+ String appicon = GlobalConfig::get_singleton()->get("application/config/icon");
if (appicon != "" && appicon.ends_with(".png")) {
FileAccess *f = FileAccess::open(appicon, FileAccess::READ);
if (f) {
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 88928089b6..d620b2b9c4 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -273,7 +273,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this);
layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
- setKeepScreenOn(GodotLib.getGlobal("display/keep_screen_on").equals("True"));
+ setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True"));
edittext.setView(mView);
io.setEdit(edittext);
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index 1f81f0f86e..b6cd43b3a2 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -29,11 +29,11 @@
/*************************************************************************/
#import "app_delegate.h"
+#include "audio_driver_iphone.h"
#include "core/global_config.h"
#import "gl_view.h"
#include "main/main.h"
#include "os_iphone.h"
-#include "audio_driver_iphone.h"
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
#include "modules/FacebookScorer_ios/FacebookScorer.h"
@@ -615,7 +615,7 @@ static int frame_count = 0;
view_controller.view = glView;
window.rootViewController = view_controller;
- _set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on", true)) ? YES : NO);
+ _set_keep_screen_on(bool(GLOBAL_DEF("display/window/keep_screen_on", true)) ? YES : NO);
glView.useCADisplayLink =
bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
@@ -673,7 +673,6 @@ static int frame_count = 0;
isAdvertisingTrackingEnabled]];
#endif
-
};
- (void)applicationWillTerminate:(UIApplication *)application {
@@ -737,7 +736,7 @@ static int frame_count = 0;
};
// Fixed audio can not resume if it is interrupted cause by an incoming phone call
- if(AudioDriverIphone::get_singleton() != NULL)
+ if (AudioDriverIphone::get_singleton() != NULL)
AudioDriverIphone::get_singleton()->start();
}
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 02ff2090f9..ca9fcb54e4 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -22,26 +22,31 @@ for x in javascript_files:
env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync']\""])
env.Append(LINKFLAGS=["--shell-file", '"platform/javascript/godot_shell.html"'])
-html_file = env.Program('#bin/godot', javascript_objects, PROGSUFFIX=env["PROGSUFFIX"] + ".html")[0]
+# output file name without file extension
+basename = "godot" + env["PROGSUFFIX"]
+target_dir = env.Dir("#bin")
+js_file = target_dir.File(basename + ".js")
+implicit_targets = [js_file]
+
+zip_dir = target_dir.Dir('.javascript_zip')
+zip_files = env.InstallAs([zip_dir.File("godot.js"), zip_dir.File("godotfs.js")], [js_file, "#misc/dist/html_fs/godotfs.js"])
+
+if env['wasm'] == 'yes':
+ wasm_file = target_dir.File(basename+'.wasm')
+ implicit_targets.append(wasm_file)
+ zip_files.append(InstallAs(zip_dir.File('godot.wasm'), wasm_file))
+else:
+ asmjs_files = [target_dir.File(basename+'.asm.js'), target_dir.File(basename+'.html.mem')]
+ zip_files.append(InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
+ implicit_targets.extend(asmjs_files)
+
+# HTML file must be the first target in the list
+html_file = env.Program(["#bin/godot"] + implicit_targets, javascript_objects, PROGSUFFIX=env["PROGSUFFIX"]+".html")[0]
Depends(html_file, "godot_shell.html")
-basename = "godot" + env["PROGSUFFIX"] # output file name without file extension
# Emscripten hardcodes file names, so replace common base name with
# placeholder while leaving extension; also change `.html.mem` to just `.mem`
fixup_html = env.Substfile(html_file, SUBST_DICT=[(basename, '$$GODOT_BASE'), ('.html.mem', '.mem')], SUBSTFILESUFFIX='.fixup.html')
-zip_dir = env.Dir('#bin/.javascript_zip')
-zip_files = []
-js_file = env.SideEffect(html_file.File(basename+'.js'), html_file)
-zip_files.append(env.InstallAs(
- [zip_dir.File('godot.html'), zip_dir.File('godot.js'), zip_dir.File('godotfs.js')],
- [fixup_html, js_file, '#misc/dist/html_fs/godotfs.js']))
-
-if env['wasm'] == 'yes':
- wasm_file = env.SideEffect(html_file.File(basename+'.wasm'), html_file)
- zip_files.append(env.InstallAs(zip_dir.File('godot.wasm'), wasm_file))
-else:
- asmjs_files = env.SideEffect([html_file.File(basename+'.asm.js'), html_file.File(basename+'.html.mem')], html_file)
- zip_files.append(env.InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
-
-Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir)
+zip_files.append(InstallAs(zip_dir.File('godot.html'), fixup_html))
+Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET")
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
index 7469d52976..a4233b5264 100644
--- a/platform/osx/audio_driver_osx.cpp
+++ b/platform/osx/audio_driver_osx.cpp
@@ -31,11 +31,15 @@
#include "audio_driver_osx.h"
-Error AudioDriverOSX::init() {
+static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
+ AudioDriverOSX *driver = (AudioDriverOSX *)inClientData;
- active = false;
- channels = 2;
+ driver->reopen();
+
+ return noErr;
+}
+Error AudioDriverOSX::initDevice() {
AudioStreamBasicDescription strdesc;
strdesc.mFormatID = kAudioFormatLinearPCM;
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
@@ -43,12 +47,10 @@ Error AudioDriverOSX::init() {
strdesc.mSampleRate = 44100;
strdesc.mFramesPerPacket = 1;
strdesc.mBitsPerChannel = 16;
- strdesc.mBytesPerFrame =
- strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
- strdesc.mBytesPerPacket =
- strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
+ strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
+ strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
- OSStatus result = noErr;
+ OSStatus result;
AURenderCallbackStruct callback;
AudioComponentDescription desc;
AudioComponent comp = NULL;
@@ -66,32 +68,90 @@ Error AudioDriverOSX::init() {
ERR_FAIL_COND_V(result != noErr, FAILED);
ERR_FAIL_COND_V(comp == NULL, FAILED);
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_StreamFormat,
- scope, bus, &strdesc, sizeof(strdesc));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, scope, bus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
zeromem(&callback, sizeof(AURenderCallbackStruct));
callback.inputProc = &AudioDriverOSX::output_callback;
callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_SetRenderCallback,
- scope, bus, &callback, sizeof(callback));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, scope, bus, &callback, sizeof(callback));
ERR_FAIL_COND_V(result != noErr, FAILED);
result = AudioUnitInitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
- result = AudioOutputUnitStart(audio_unit);
+ return OK;
+}
+
+Error AudioDriverOSX::finishDevice() {
+ OSStatus result;
+
+ if (active) {
+ result = AudioOutputUnitStop(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ active = false;
+ }
+
+ result = AudioUnitUninitialize(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ return OK;
+}
+
+Error AudioDriverOSX::init() {
+ OSStatus result;
+
+ active = false;
+ channels = 2;
+
+ outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+ outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal;
+ outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
const int samples = 1024;
samples_in = memnew_arr(int32_t, samples); // whatever
buffer_frames = samples / channels;
- return OK;
+ return initDevice();
};
+Error AudioDriverOSX::reopen() {
+ Error err;
+ bool restart = false;
+
+ lock();
+
+ if (active) {
+ restart = true;
+ }
+
+ err = finishDevice();
+ if (err != OK) {
+ ERR_PRINT("finishDevice failed");
+ unlock();
+ return err;
+ }
+
+ err = initDevice();
+ if (err != OK) {
+ ERR_PRINT("initDevice failed");
+ unlock();
+ return err;
+ }
+
+ if (restart) {
+ start();
+ }
+
+ unlock();
+
+ return OK;
+}
+
OSStatus AudioDriverOSX::output_callback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
@@ -149,7 +209,14 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
};
void AudioDriverOSX::start() {
- active = true;
+ if (!active) {
+ OSStatus result = AudioOutputUnitStart(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioOutputUnitStart failed");
+ } else {
+ active = true;
+ }
+ }
};
int AudioDriverOSX::get_mix_rate() const {
@@ -161,18 +228,23 @@ AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const {
};
void AudioDriverOSX::lock() {
- if (active && mutex)
+ if (mutex)
mutex->lock();
};
void AudioDriverOSX::unlock() {
- if (active && mutex)
+ if (mutex)
mutex->unlock();
};
void AudioDriverOSX::finish() {
+ OSStatus result;
+
+ finishDevice();
- if (active)
- AudioOutputUnitStop(audio_unit);
+ result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
+ if (result != noErr) {
+ ERR_PRINT("AudioObjectRemovePropertyListener failed");
+ }
memdelete_arr(samples_in);
};
diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h
index 9b48dab405..d6d00b7970 100644
--- a/platform/osx/audio_driver_osx.h
+++ b/platform/osx/audio_driver_osx.h
@@ -35,10 +35,12 @@
#include "servers/audio_server.h"
#include <AudioUnit/AudioUnit.h>
+#include <CoreAudio/AudioHardware.h>
class AudioDriverOSX : public AudioDriver {
AudioComponentInstance audio_unit;
+ AudioObjectPropertyAddress outputDeviceAddress;
bool active;
Mutex *mutex;
@@ -52,6 +54,9 @@ class AudioDriverOSX : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
+ Error initDevice();
+ Error finishDevice();
+
public:
const char *get_name() const {
return "AudioUnit";
@@ -65,6 +70,8 @@ public:
virtual void unlock();
virtual void finish();
+ Error reopen();
+
AudioDriverOSX();
~AudioDriverOSX();
};
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index dfefbbc1ba..d9891dda61 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -90,7 +90,7 @@ def configure(env):
env.Append(CPPPATH=['#platform/osx'])
env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS'])
- env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
+ env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
env.Append(LIBS=['pthread'])
env.Append(CPPFLAGS=['-mmacosx-version-min=10.9'])
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index c81fb00b36..ca5535f771 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -345,7 +345,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (p_preset->get("application/icon") != "")
iconpath = p_preset->get("application/icon");
else
- iconpath = GlobalConfig::get_singleton()->get("application/icon");
+ iconpath = GlobalConfig::get_singleton()->get("application/config/icon");
print_line("icon? " + iconpath);
if (iconpath != "") {
Ref<Image> icon;
@@ -484,8 +484,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
String pkg_name;
if (p_preset->get("application/name") != "")
pkg_name = p_preset->get("application/name"); // app_name
- else if (String(GlobalConfig::get_singleton()->get("application/name")) != "")
- pkg_name = String(GlobalConfig::get_singleton()->get("application/name"));
+ else if (String(GlobalConfig::get_singleton()->get("application/config/name")) != "")
+ pkg_name = String(GlobalConfig::get_singleton()->get("application/config/name"));
else
pkg_name = "Unnamed";
@@ -539,7 +539,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
if (p_preset->get("application/icon") != "")
iconpath = p_preset->get("application/icon");
else
- iconpath = GlobalConfig::get_singleton()->get("application/icon");
+ iconpath = GlobalConfig::get_singleton()->get("application/config/icon");
print_line("icon? " + iconpath);
if (iconpath != "") {
Ref<Image> icon;
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 28aaf9161b..b9ef778e01 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -310,7 +310,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
if (is_keep_screen_on())
display_request->RequestActive();
- set_keep_screen_on(GLOBAL_DEF("display/keep_screen_on", true));
+ set_keep_screen_on(GLOBAL_DEF("display/window/keep_screen_on", true));
}
void OSUWP::set_clipboard(const String &p_text) {
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 2daf580c0d..36d6cd8565 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2229,7 +2229,7 @@ String OS_Windows::get_data_dir() const {
if (has_environment("APPDATA")) {
- bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir");
+ bool use_godot = GlobalConfig::get_singleton()->get("application/config/use_shared_user_dir");
if (!use_godot)
return (OS::get_singleton()->get_environment("APPDATA") + "/" + an).replace("\\", "/");
else
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 4aca1468b1..04f41b2e89 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -686,6 +686,16 @@ void OS_X11::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) con
}
void OS_X11::set_wm_fullscreen(bool p_enabled) {
+ if (p_enabled && !is_window_resizable()) {
+ // Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
+ XSizeHints *xsh;
+
+ xsh = XAllocSizeHints();
+ xsh->flags = 0L;
+ XSetWMNormalHints(x11_display, x11_window, xsh);
+ XFree(xsh);
+ }
+
// Using EWMH -- Extened Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
@@ -701,6 +711,23 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XFlush(x11_display);
+
+ if (!p_enabled && !is_window_resizable()) {
+ // Reset the non-resizable flags if we un-set these before.
+ Size2 size = get_window_size();
+ XSizeHints *xsh;
+
+ xsh = XAllocSizeHints();
+ xsh->flags = PMinSize | PMaxSize;
+ xsh->min_width = size.x;
+ xsh->max_width = size.x;
+ xsh->min_height = size.y;
+ xsh->max_height = size.y;
+
+ XSetWMNormalHints(x11_display, x11_window, xsh);
+ XFree(xsh);
+ }
}
int OS_X11::get_screen_count() const {
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index c62a866d8d..59227070b3 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "area.h"
#include "scene/scene_string_names.h"
+#include "servers/audio_server.h"
#include "servers/physics_server.h"
+
void Area::set_space_override_mode(SpaceOverride p_mode) {
space_override = p_mode;
@@ -538,6 +540,87 @@ bool Area::get_collision_layer_bit(int p_bit) const {
return get_collision_layer() & (1 << p_bit);
}
+void Area::set_audio_bus_override(bool p_override) {
+
+ audio_bus_override = p_override;
+}
+
+bool Area::is_overriding_audio_bus() const {
+
+ return audio_bus_override;
+}
+
+void Area::set_audio_bus(const StringName &p_audio_bus) {
+
+ audio_bus = p_audio_bus;
+}
+StringName Area::get_audio_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
+ return audio_bus;
+ }
+ }
+ return "Master";
+}
+
+void Area::set_use_reverb_bus(bool p_enable) {
+
+ use_reverb_bus = p_enable;
+}
+bool Area::is_using_reverb_bus() const {
+
+ return use_reverb_bus;
+}
+
+void Area::set_reverb_bus(const StringName &p_audio_bus) {
+
+ reverb_bus = p_audio_bus;
+}
+StringName Area::get_reverb_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == reverb_bus) {
+ return reverb_bus;
+ }
+ }
+ return "Master";
+}
+
+void Area::set_reverb_amount(float p_amount) {
+
+ reverb_amount = p_amount;
+}
+float Area::get_reverb_amount() const {
+
+ return reverb_amount;
+}
+
+void Area::set_reverb_uniformity(float p_uniformity) {
+
+ reverb_uniformity = p_uniformity;
+}
+float Area::get_reverb_uniformity() const {
+
+ return reverb_uniformity;
+}
+
+void Area::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "audio_bus_name" || property.name == "reverb_bus_name") {
+
+ String options;
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (i > 0)
+ options += ",";
+ String name = AudioServer::get_singleton()->get_bus_name(i);
+ options += name;
+ }
+
+ property.hint_string = options;
+ }
+}
+
void Area::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_enter_tree", "id"), &Area::_body_enter_tree);
@@ -597,6 +680,24 @@ void Area::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_inout"), &Area::_body_inout);
ClassDB::bind_method(D_METHOD("_area_inout"), &Area::_area_inout);
+ ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area::set_audio_bus_override);
+ ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area::is_overriding_audio_bus);
+
+ ClassDB::bind_method(D_METHOD("set_audio_bus", "name"), &Area::set_audio_bus);
+ ClassDB::bind_method(D_METHOD("get_audio_bus"), &Area::get_audio_bus);
+
+ ClassDB::bind_method(D_METHOD("set_use_reverb_bus", "enable"), &Area::set_use_reverb_bus);
+ ClassDB::bind_method(D_METHOD("is_using_reverb_bus"), &Area::is_using_reverb_bus);
+
+ ClassDB::bind_method(D_METHOD("set_reverb_bus", "name"), &Area::set_reverb_bus);
+ ClassDB::bind_method(D_METHOD("get_reverb_bus"), &Area::get_reverb_bus);
+
+ ClassDB::bind_method(D_METHOD("set_reverb_amount", "amount"), &Area::set_reverb_amount);
+ ClassDB::bind_method(D_METHOD("get_reverb_amount"), &Area::get_reverb_amount);
+
+ ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area::set_reverb_uniformity);
+ ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area::get_reverb_uniformity);
+
ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::INT, "body_id"), PropertyInfo(Variant::OBJECT, "body"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "area_shape")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body")));
@@ -620,6 +721,14 @@ void Area::_bind_methods() {
ADD_GROUP("Collision", "collision_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
+ ADD_GROUP("Audio Bus", "audio_bus_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus");
+ ADD_GROUP("Reverb Bus", "reverb_bus_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "reverb_bus_enable"), "set_use_reverb_bus", "is_using_reverb_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "reverb_bus_name", PROPERTY_HINT_ENUM, ""), "set_reverb_bus", "get_reverb_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "reverb_bus_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_amount", "get_reverb_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "reverb_bus_uniformity", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_reverb_uniformity", "get_reverb_uniformity");
}
Area::Area()
@@ -640,6 +749,14 @@ Area::Area()
set_ray_pickable(false);
set_monitoring(true);
set_monitorable(true);
+
+ audio_bus_override = false;
+ audio_bus = "Master";
+
+ use_reverb_bus = false;
+ reverb_bus = "Master";
+ reverb_amount = 0.0;
+ reverb_uniformity = 0.0;
}
Area::~Area() {
diff --git a/scene/3d/area.h b/scene/3d/area.h
index 279a52ee69..5df308fc47 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -126,6 +126,16 @@ private:
Map<ObjectID, AreaState> area_map;
void _clear_monitoring();
+ bool audio_bus_override;
+ StringName audio_bus;
+
+ bool use_reverb_bus;
+ StringName reverb_bus;
+ float reverb_amount;
+ float reverb_uniformity;
+
+ void _validate_property(PropertyInfo &property) const;
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -179,6 +189,24 @@ public:
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
+ void set_audio_bus_override(bool p_override);
+ bool is_overriding_audio_bus() const;
+
+ void set_audio_bus(const StringName &p_audio_bus);
+ StringName get_audio_bus() const;
+
+ void set_use_reverb_bus(bool p_enable);
+ bool is_using_reverb_bus() const;
+
+ void set_reverb_bus(const StringName &p_audio_bus);
+ StringName get_reverb_bus() const;
+
+ void set_reverb_amount(float p_amount);
+ float get_reverb_amount() const;
+
+ void set_reverb_uniformity(float p_uniformity);
+ float get_reverb_uniformity() const;
+
Area();
~Area();
};
diff --git a/scene/3d/audio_stream_player_3d.cpp b/scene/3d/audio_stream_player_3d.cpp
new file mode 100644
index 0000000000..87ea018425
--- /dev/null
+++ b/scene/3d/audio_stream_player_3d.cpp
@@ -0,0 +1,930 @@
+#include "audio_stream_player_3d.h"
+#include "engine.h"
+#include "scene/3d/area.h"
+#include "scene/3d/camera.h"
+#include "scene/main/viewport.h"
+void AudioStreamPlayer3D::_mix_audio() {
+
+ if (!stream_playback.is_valid()) {
+ return;
+ }
+
+ if (!active) {
+ return;
+ }
+
+ bool started = false;
+ if (setseek >= 0.0) {
+ stream_playback->start(setseek);
+ setseek = -1.0; //reset seek
+ started = true;
+ }
+
+ //get data
+ AudioFrame *buffer = mix_buffer.ptr();
+ int buffer_size = mix_buffer.size();
+
+ //mix
+ if (output_count > 0 || out_of_range_mode == OUT_OF_RANGE_MIX) {
+
+ float pitch_scale = 0.0;
+ if (output_count) {
+ //used for doppler, not realistic but good enough
+ for (int i = 0; i < output_count; i++) {
+ pitch_scale += outputs[i].pitch_scale;
+ }
+ pitch_scale /= float(output_count);
+ } else {
+ pitch_scale = 1.0;
+ }
+
+ stream_playback->mix(buffer, pitch_scale, buffer_size);
+ }
+
+ //write all outputs
+ for (int i = 0; i < output_count; i++) {
+
+ Output current = outputs[i];
+
+ //see if current output exists, to keep volume ramp
+ bool found = false;
+ for (int j = i; j < prev_output_count; j++) {
+ if (prev_outputs[j].viewport == current.viewport) {
+ if (j != i) {
+ SWAP(prev_outputs[j], prev_outputs[i]);
+ }
+ found = true;
+ break;
+ }
+ }
+
+ bool interpolate_filter = !started;
+ ;
+ if (!found) {
+ //create new if was not used before
+ if (prev_output_count < MAX_OUTPUTS) {
+ prev_outputs[prev_output_count] = prev_outputs[i]; //may be owned by another viewport
+ prev_output_count++;
+ }
+ prev_outputs[i] = current;
+ interpolate_filter = false;
+ }
+
+ //mix!
+
+ int buffers = 0;
+ int first = 0;
+
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+
+ case AudioServer::SPEAKER_MODE_STEREO: {
+ buffers = 1;
+ first = 0;
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_51: {
+ buffers = 2;
+ first = 1;
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_71: {
+
+ buffers = 3;
+ first = 1;
+
+ } break;
+ }
+
+ for (int k = 0; k < buffers; k++) {
+ AudioFrame vol_inc = (current.vol[k] - prev_outputs[i].vol[k]) / float(buffer_size);
+ AudioFrame vol = current.vol[k];
+
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, first + k);
+
+ current.filter.set_mode(AudioFilterSW::HIGHSHELF);
+ current.filter.set_sampling_rate(AudioServer::get_singleton()->get_mix_rate());
+ current.filter.set_cutoff(attenuation_filter_cutoff_hz);
+ current.filter.set_resonance(1);
+ current.filter.set_stages(1);
+ current.filter.set_gain(current.filter_gain);
+
+ if (interpolate_filter) {
+
+ current.filter_process[k * 2 + 0] = prev_outputs[i].filter_process[k * 2 + 0];
+ current.filter_process[k * 2 + 1] = prev_outputs[i].filter_process[k * 2 + 1];
+
+ current.filter_process[k * 2 + 0].set_filter(&current.filter, false);
+ current.filter_process[k * 2 + 1].set_filter(&current.filter, false);
+
+ current.filter_process[k * 2 + 0].update_coeffs(buffer_size);
+ current.filter_process[k * 2 + 1].update_coeffs(buffer_size);
+ for (int j = 0; j < buffer_size; j++) {
+
+ AudioFrame f = buffer[j] * vol;
+ current.filter_process[k * 2 + 0].process_one_interp(f.l);
+ current.filter_process[k * 2 + 1].process_one_interp(f.r);
+
+ target[j] += f;
+ vol += vol_inc;
+ }
+ } else {
+ current.filter_process[k * 2 + 0].set_filter(&current.filter);
+ current.filter_process[k * 2 + 1].set_filter(&current.filter);
+
+ current.filter_process[k * 2 + 0].update_coeffs();
+ current.filter_process[k * 2 + 1].update_coeffs();
+ for (int j = 0; j < buffer_size; j++) {
+
+ AudioFrame f = buffer[j] * vol;
+ current.filter_process[k * 2 + 0].process_one(f.l);
+ current.filter_process[k * 2 + 1].process_one(f.r);
+
+ target[j] += f;
+ vol += vol_inc;
+ }
+ }
+
+ if (current.reverb_bus_index >= 0) {
+
+ AudioFrame *rtarget = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.reverb_bus_index, first + k);
+
+ if (current.reverb_bus_index == prev_outputs[i].reverb_bus_index) {
+ AudioFrame rvol_inc = (current.reverb_vol[k] - prev_outputs[i].reverb_vol[k]) / float(buffer_size);
+ AudioFrame rvol = prev_outputs[i].reverb_vol[k];
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ rtarget[j] += buffer[j] * rvol;
+ rvol += rvol_inc;
+ }
+ } else {
+
+ AudioFrame rvol = current.reverb_vol[k];
+ for (int j = 0; j < buffer_size; j++) {
+
+ rtarget[j] += buffer[j] * rvol;
+ }
+ }
+ }
+ }
+
+ prev_outputs[i] = current;
+ }
+
+ prev_output_count = output_count;
+
+ //stream is no longer active, disable this.
+ if (!stream_playback->is_playing()) {
+ active = false;
+ }
+
+ output_ready = false;
+}
+
+float AudioStreamPlayer3D::_get_attenuation_db(float p_distance) const {
+
+ float att;
+ switch (attenuation_model) {
+ case ATTENUATION_INVERSE_DISTANCE: {
+ att = Math::linear2db(1.0 / ((p_distance / unit_size) + 000001));
+ } break;
+ case ATTENUATION_INVERSE_SQUARE_DISTANCE: {
+ float d = (p_distance / unit_size);
+ d *= d;
+ att = Math::linear2db(1.0 / (d + 0.00001));
+ } break;
+ case ATTENUATION_LOGARITHMIC: {
+ att = -20 * Math::log(p_distance / unit_size + 000001);
+ } break;
+ }
+
+ att += unit_db;
+ if (att > max_db) {
+ att = max_db;
+ }
+
+ return att;
+}
+
+void _update_sound() {
+}
+
+void AudioStreamPlayer3D::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+
+ velocity_tracker->reset(get_global_transform().origin);
+ AudioServer::get_singleton()->add_callback(_mix_audios, this);
+ if (autoplay && !get_tree()->is_editor_hint()) {
+ play();
+ }
+ }
+
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+
+ AudioServer::get_singleton()->remove_callback(_mix_audios, this);
+ }
+ if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
+
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+ velocity_tracker->update_position(get_global_transform().origin);
+ }
+ }
+
+ if (p_what == NOTIFICATION_INTERNAL_FIXED_PROCESS) {
+
+ //update anything related to position first, if possible of course
+
+ if (!output_ready) {
+
+ Vector3 linear_velocity;
+
+ //compute linear velocity for doppler
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+ linear_velocity = velocity_tracker->get_tracked_linear_velocity();
+ }
+
+ Ref<World> world = get_world();
+ ERR_FAIL_COND(world.is_null());
+
+ int new_output_count = 0;
+
+ Vector3 global_pos = get_global_transform().origin;
+
+ int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
+
+ //check if any area is diverting sound into a bus
+
+ PhysicsDirectSpaceState *space_state = PhysicsServer::get_singleton()->space_get_direct_state(world->get_space());
+
+ PhysicsDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS];
+
+ int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, PhysicsDirectSpaceState::TYPE_MASK_AREA);
+ Area *area = NULL;
+
+ for (int i = 0; i < areas; i++) {
+ if (!sr[i].collider)
+ continue;
+
+ Area *tarea = sr[i].collider->cast_to<Area>();
+ if (!tarea)
+ continue;
+
+ if (!tarea->is_overriding_audio_bus() && !tarea->is_using_reverb_bus())
+ continue;
+
+ area = tarea;
+ break;
+ }
+
+ List<Camera *> cameras;
+ world->get_camera_list(&cameras);
+
+ for (List<Camera *>::Element *E = cameras.front(); E; E = E->next()) {
+
+ Camera *camera = E->get();
+ Viewport *vp = camera->get_viewport();
+ if (!vp->is_audio_listener())
+ continue;
+
+ Vector3 local_pos = camera->get_global_transform().orthonormalized().affine_inverse().xform(global_pos);
+
+ float dist = local_pos.length();
+
+ Vector3 area_sound_pos;
+ Vector3 cam_area_pos;
+
+ if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
+ area_sound_pos = space_state->get_closest_point_to_object_volume(area->get_rid(), camera->get_global_transform().origin);
+ cam_area_pos = camera->get_global_transform().affine_inverse().xform(area_sound_pos);
+ }
+
+ if (max_distance > 0) {
+
+ float total_max = max_distance;
+
+ if (area && area->is_using_reverb_bus() && area->get_reverb_uniformity() > 0) {
+ total_max = MAX(total_max, cam_area_pos.length());
+ }
+ if (total_max > max_distance) {
+ continue; //cant hear this sound in this camera
+ }
+ }
+
+ float multiplier = Math::db2linear(_get_attenuation_db(dist));
+ if (max_distance > 0) {
+ multiplier *= MAX(0, 1.0 - (dist / max_distance));
+ }
+
+ Output output;
+ output.bus_index = bus_index;
+ output.reverb_bus_index = -1; //no reverb by default
+ output.viewport = vp;
+
+ float db_att = (1.0 - MIN(1.0, multiplier)) * attenuation_filter_db;
+
+ if (emission_angle_enabled) {
+ Vector3 camtopos = global_pos - camera->get_global_transform().origin;
+ float c = camtopos.normalized().dot(get_global_transform().basis.get_axis(2).normalized()); //it's z negative
+ float angle = Math::rad2deg(Math::acos(c));
+ if (angle > emission_angle)
+ db_att -= -emission_angle_filter_attenuation_db;
+ }
+
+ output.filter_gain = Math::db2linear(db_att);
+
+ Vector3 flat_pos = local_pos;
+ flat_pos.y = 0;
+ flat_pos.normalize();
+
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+
+ case AudioServer::SPEAKER_MODE_STEREO: {
+
+ float c = flat_pos.x * 0.5 + 0.5;
+ output.vol[0].l = 1.0 - c;
+ output.vol[0].r = c;
+
+ output.vol[0] *= multiplier;
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_51: {
+
+ float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+
+ output.vol[0].l = xl;
+ output.vol[1].r = 1.0 - xl;
+ output.vol[0].r = xr;
+ output.vol[1].l = 1.0 - xr;
+
+ output.vol[0] *= multiplier;
+ output.vol[1] *= multiplier;
+ } break;
+ case AudioServer::SPEAKER_SURROUND_71: {
+
+ float xl = Vector3(-1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(flat_pos) * 0.5 + 0.5;
+
+ output.vol[0].l = xl;
+ output.vol[1].r = 1.0 - xl;
+ output.vol[0].r = xr;
+ output.vol[1].l = 1.0 - xr;
+
+ float c = flat_pos.x * 0.5 + 0.5;
+ output.vol[2].l = 1.0 - c;
+ output.vol[2].r = c;
+
+ output.vol[0] *= multiplier;
+ output.vol[1] *= multiplier;
+ output.vol[2] *= multiplier;
+
+ } break;
+ }
+
+ bool filled_reverb = false;
+ int vol_index_max = AudioServer::get_singleton()->get_speaker_mode() + 1;
+
+ if (area) {
+
+ if (area->is_overriding_audio_bus()) {
+ //override audio bus
+ StringName bus_name = area->get_audio_bus();
+ output.bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
+ }
+
+ if (area->is_using_reverb_bus()) {
+
+ filled_reverb = true;
+ StringName bus_name = area->get_reverb_bus();
+ output.reverb_bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
+
+ float uniformity = area->get_reverb_uniformity();
+ float area_send = area->get_reverb_amount();
+
+ if (uniformity > 0.0) {
+
+ float distance = cam_area_pos.length();
+ float attenuation = Math::db2linear(_get_attenuation_db(distance));
+
+ //float dist_att_db = -20 * Math::log(dist + 0.00001); //logarithmic attenuation, like in real life
+
+ float center_val[3] = { 0.5, 0.25, 0.16666 };
+ AudioFrame center_frame(center_val[vol_index_max - 1], center_val[vol_index_max - 1]);
+
+ if (attenuation < 1.0) {
+ //pan the uniform sound
+ Vector3 rev_pos = cam_area_pos;
+ rev_pos.y = 0;
+ rev_pos.normalize();
+
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+
+ case AudioServer::SPEAKER_MODE_STEREO: {
+
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[0].l = 1.0 - c;
+ output.reverb_vol[0].r = c;
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_51: {
+
+ float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+
+ output.reverb_vol[0].l = xl;
+ output.reverb_vol[1].r = 1.0 - xl;
+ output.reverb_vol[0].r = xr;
+ output.reverb_vol[1].l = 1.0 - xr;
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_71: {
+
+ float xl = Vector3(-1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+ float xr = Vector3(1, 0, -1).normalized().dot(rev_pos) * 0.5 + 0.5;
+
+ output.reverb_vol[0].l = xl;
+ output.reverb_vol[1].r = 1.0 - xl;
+ output.reverb_vol[0].r = xr;
+ output.reverb_vol[1].l = 1.0 - xr;
+
+ float c = rev_pos.x * 0.5 + 0.5;
+ output.reverb_vol[2].l = 1.0 - c;
+ output.reverb_vol[2].r = c;
+
+ } break;
+ }
+
+ for (int i = 0; i < vol_index_max; i++) {
+
+ output.reverb_vol[i] = output.reverb_vol[i].linear_interpolate(center_frame, attenuation);
+ }
+ } else {
+ for (int i = 0; i < vol_index_max; i++) {
+
+ output.reverb_vol[i] = center_frame;
+ }
+ }
+
+ for (int i = 0; i < vol_index_max; i++) {
+
+ output.reverb_vol[i] = output.vol[i].linear_interpolate(output.reverb_vol[i] * attenuation, uniformity);
+ output.reverb_vol[i] *= area_send;
+ }
+
+ } else {
+
+ for (int i = 0; i < vol_index_max; i++) {
+
+ output.reverb_vol[i] = output.vol[i] * area_send;
+ }
+ }
+ }
+ }
+
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+
+ Vector3 camera_velocity = camera->get_doppler_tracked_velocity();
+
+ Vector3 local_velocity = camera->get_global_transform().orthonormalized().basis.xform_inv(linear_velocity - camera_velocity);
+
+ if (local_velocity == Vector3()) {
+ output.pitch_scale = 1.0;
+ } else {
+ float approaching = local_pos.normalized().dot(local_velocity.normalized());
+ float velocity = local_velocity.length();
+ float speed_of_sound = 343.0;
+
+ output.pitch_scale = speed_of_sound / (speed_of_sound + velocity * approaching);
+ output.pitch_scale = CLAMP(output.pitch_scale, (1 / 8.0), 8.0); //avoid crazy stuff
+ }
+
+ } else {
+ output.pitch_scale = 1.0;
+ }
+
+ if (!filled_reverb) {
+
+ for (int i = 0; i < vol_index_max; i++) {
+
+ output.reverb_vol[i] = AudioFrame(0, 0);
+ }
+ }
+
+ outputs[new_output_count] = output;
+ new_output_count++;
+ if (new_output_count == MAX_OUTPUTS)
+ break;
+ }
+
+ output_count = new_output_count;
+ output_ready = true;
+ }
+
+ //start playing if requested
+ if (setplay >= 0.0) {
+ setseek = setplay;
+ active = true;
+ setplay = -1;
+ _change_notify("playing"); //update property in editor
+ }
+
+ //stop playing if no longer active
+ if (!active) {
+ set_fixed_process_internal(false);
+ _change_notify("playing"); //update property in editor
+ }
+ }
+}
+
+void AudioStreamPlayer3D::set_stream(Ref<AudioStream> p_stream) {
+
+ ERR_FAIL_COND(!p_stream.is_valid());
+ AudioServer::get_singleton()->lock();
+
+ mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
+
+ if (stream_playback.is_valid()) {
+ stream_playback.unref();
+ stream.unref();
+ active = false;
+ setseek = -1;
+ }
+
+ stream = p_stream;
+ stream_playback = p_stream->instance_playback();
+
+ if (stream_playback.is_null()) {
+ stream.unref();
+ ERR_FAIL_COND(stream_playback.is_null());
+ }
+
+ AudioServer::get_singleton()->unlock();
+}
+
+Ref<AudioStream> AudioStreamPlayer3D::get_stream() const {
+
+ return stream;
+}
+
+void AudioStreamPlayer3D::set_unit_db(float p_volume) {
+
+ unit_db = p_volume;
+}
+float AudioStreamPlayer3D::get_unit_db() const {
+
+ return unit_db;
+}
+
+void AudioStreamPlayer3D::set_unit_size(float p_volume) {
+
+ unit_size = p_volume;
+}
+float AudioStreamPlayer3D::get_unit_size() const {
+
+ return unit_size;
+}
+
+void AudioStreamPlayer3D::set_max_db(float p_boost) {
+
+ max_db = p_boost;
+}
+float AudioStreamPlayer3D::get_max_db() const {
+
+ return max_db;
+}
+
+void AudioStreamPlayer3D::play(float p_from_pos) {
+
+ if (stream_playback.is_valid()) {
+ setplay = p_from_pos;
+ output_ready = false;
+ set_fixed_process_internal(true);
+ }
+}
+
+void AudioStreamPlayer3D::seek(float p_seconds) {
+
+ if (stream_playback.is_valid()) {
+ setseek = p_seconds;
+ }
+}
+
+void AudioStreamPlayer3D::stop() {
+
+ if (stream_playback.is_valid()) {
+ active = false;
+ set_fixed_process_internal(false);
+ setplay = -1;
+ }
+}
+
+bool AudioStreamPlayer3D::is_playing() const {
+
+ if (stream_playback.is_valid()) {
+ return active; // && stream_playback->is_playing();
+ }
+
+ return false;
+}
+
+float AudioStreamPlayer3D::get_pos() {
+
+ if (stream_playback.is_valid()) {
+ return stream_playback->get_pos();
+ }
+
+ return 0;
+}
+
+void AudioStreamPlayer3D::set_bus(const StringName &p_bus) {
+
+ //if audio is active, must lock this
+ AudioServer::get_singleton()->lock();
+ bus = p_bus;
+ AudioServer::get_singleton()->unlock();
+}
+StringName AudioStreamPlayer3D::get_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
+ return bus;
+ }
+ }
+ return "Master";
+}
+
+void AudioStreamPlayer3D::set_autoplay(bool p_enable) {
+
+ autoplay = p_enable;
+}
+bool AudioStreamPlayer3D::is_autoplay_enabled() {
+
+ return autoplay;
+}
+
+void AudioStreamPlayer3D::_set_playing(bool p_enable) {
+
+ if (p_enable)
+ play();
+ else
+ stop();
+}
+bool AudioStreamPlayer3D::_is_active() const {
+
+ return active;
+}
+
+void AudioStreamPlayer3D::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "bus") {
+
+ String options;
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (i > 0)
+ options += ",";
+ String name = AudioServer::get_singleton()->get_bus_name(i);
+ options += name;
+ }
+
+ property.hint_string = options;
+ }
+}
+
+void AudioStreamPlayer3D::_bus_layout_changed() {
+
+ _change_notify();
+}
+
+void AudioStreamPlayer3D::set_max_distance(float p_metres) {
+
+ ERR_FAIL_COND(p_metres < 0.0);
+ max_distance = p_metres;
+}
+
+float AudioStreamPlayer3D::get_max_distance() const {
+
+ return max_distance;
+}
+
+void AudioStreamPlayer3D::set_area_mask(uint32_t p_mask) {
+
+ area_mask = p_mask;
+}
+
+uint32_t AudioStreamPlayer3D::get_area_mask() const {
+
+ return area_mask;
+}
+
+void AudioStreamPlayer3D::set_emission_angle_enabled(bool p_enable) {
+ emission_angle_enabled = p_enable;
+ update_gizmo();
+}
+
+bool AudioStreamPlayer3D::is_emission_angle_enabled() const {
+ return emission_angle_enabled;
+}
+
+void AudioStreamPlayer3D::set_emission_angle(float p_angle) {
+ ERR_FAIL_COND(p_angle < 0 || p_angle > 90);
+ emission_angle = p_angle;
+ update_gizmo();
+}
+
+float AudioStreamPlayer3D::get_emission_angle() const {
+ return emission_angle;
+}
+
+void AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db) {
+
+ emission_angle_filter_attenuation_db = p_angle_attenuation_db;
+}
+
+float AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db() const {
+
+ return emission_angle_filter_attenuation_db;
+}
+
+void AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz(float p_hz) {
+
+ attenuation_filter_cutoff_hz = p_hz;
+}
+float AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz() const {
+
+ return attenuation_filter_cutoff_hz;
+}
+
+void AudioStreamPlayer3D::set_attenuation_filter_db(float p_db) {
+
+ attenuation_filter_db = p_db;
+}
+float AudioStreamPlayer3D::get_attenuation_filter_db() const {
+
+ return attenuation_filter_db;
+}
+
+void AudioStreamPlayer3D::set_attenuation_model(AttenuationModel p_model) {
+ ERR_FAIL_INDEX(p_model, 3);
+ attenuation_model = p_model;
+}
+
+AudioStreamPlayer3D::AttenuationModel AudioStreamPlayer3D::get_attenuation_model() const {
+ return attenuation_model;
+}
+
+void AudioStreamPlayer3D::set_out_of_range_mode(OutOfRangeMode p_mode) {
+
+ ERR_FAIL_INDEX(p_mode, 2);
+ out_of_range_mode = p_mode;
+}
+
+AudioStreamPlayer3D::OutOfRangeMode AudioStreamPlayer3D::get_out_of_range_mode() const {
+
+ return out_of_range_mode;
+}
+
+void AudioStreamPlayer3D::set_doppler_tracking(DopplerTracking p_tracking) {
+
+ if (doppler_tracking == p_tracking)
+ return;
+
+ doppler_tracking = p_tracking;
+
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+ set_notify_transform(true);
+ velocity_tracker->set_track_fixed_step(doppler_tracking == DOPPLER_TRACKING_FIXED_STEP);
+ velocity_tracker->reset(get_global_transform().origin);
+ } else {
+ set_notify_transform(false);
+ }
+}
+
+AudioStreamPlayer3D::DopplerTracking AudioStreamPlayer3D::get_doppler_tracking() const {
+
+ return doppler_tracking;
+}
+
+void AudioStreamPlayer3D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioStreamPlayer3D::set_stream);
+ ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer3D::get_stream);
+
+ ClassDB::bind_method(D_METHOD("set_unit_db", "unit_db"), &AudioStreamPlayer3D::set_unit_db);
+ ClassDB::bind_method(D_METHOD("get_unit_db"), &AudioStreamPlayer3D::get_unit_db);
+
+ ClassDB::bind_method(D_METHOD("set_unit_size", "unit_size"), &AudioStreamPlayer3D::set_unit_size);
+ ClassDB::bind_method(D_METHOD("get_unit_size"), &AudioStreamPlayer3D::get_unit_size);
+
+ ClassDB::bind_method(D_METHOD("set_max_db", "max_db"), &AudioStreamPlayer3D::set_max_db);
+ ClassDB::bind_method(D_METHOD("get_max_db"), &AudioStreamPlayer3D::get_max_db);
+
+ ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioStreamPlayer3D::play, DEFVAL(0.0));
+ ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioStreamPlayer3D::seek);
+ ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer3D::stop);
+
+ ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer3D::is_playing);
+ ClassDB::bind_method(D_METHOD("get_pos"), &AudioStreamPlayer3D::get_pos);
+
+ ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer3D::set_bus);
+ ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer3D::get_bus);
+
+ ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer3D::set_autoplay);
+ ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer3D::is_autoplay_enabled);
+
+ ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer3D::_set_playing);
+ ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer3D::_is_active);
+
+ ClassDB::bind_method(D_METHOD("set_max_distance", "metres"), &AudioStreamPlayer3D::set_max_distance);
+ ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer3D::get_max_distance);
+
+ ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer3D::set_area_mask);
+ ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer3D::get_area_mask);
+
+ ClassDB::bind_method(D_METHOD("set_emission_angle", "degrees"), &AudioStreamPlayer3D::set_emission_angle);
+ ClassDB::bind_method(D_METHOD("get_emission_angle"), &AudioStreamPlayer3D::get_emission_angle);
+
+ ClassDB::bind_method(D_METHOD("set_emission_angle_enabled", "enabled"), &AudioStreamPlayer3D::set_emission_angle_enabled);
+ ClassDB::bind_method(D_METHOD("is_emission_angle_enabled"), &AudioStreamPlayer3D::is_emission_angle_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_emission_angle_filter_attenuation_db", "db"), &AudioStreamPlayer3D::set_emission_angle_filter_attenuation_db);
+ ClassDB::bind_method(D_METHOD("get_emission_angle_filter_attenuation_db"), &AudioStreamPlayer3D::get_emission_angle_filter_attenuation_db);
+
+ ClassDB::bind_method(D_METHOD("set_attenuation_filter_cutoff_hz", "degrees"), &AudioStreamPlayer3D::set_attenuation_filter_cutoff_hz);
+ ClassDB::bind_method(D_METHOD("get_attenuation_filter_cutoff_hz"), &AudioStreamPlayer3D::get_attenuation_filter_cutoff_hz);
+
+ ClassDB::bind_method(D_METHOD("set_attenuation_filter_db", "db"), &AudioStreamPlayer3D::set_attenuation_filter_db);
+ ClassDB::bind_method(D_METHOD("get_attenuation_filter_db"), &AudioStreamPlayer3D::get_attenuation_filter_db);
+
+ ClassDB::bind_method(D_METHOD("set_attenuation_model", "model"), &AudioStreamPlayer3D::set_attenuation_model);
+ ClassDB::bind_method(D_METHOD("get_attenuation_model"), &AudioStreamPlayer3D::get_attenuation_model);
+
+ ClassDB::bind_method(D_METHOD("set_out_of_range_mode", "mode"), &AudioStreamPlayer3D::set_out_of_range_mode);
+ ClassDB::bind_method(D_METHOD("get_out_of_range_mode"), &AudioStreamPlayer3D::get_out_of_range_mode);
+
+ ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &AudioStreamPlayer3D::set_doppler_tracking);
+ ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &AudioStreamPlayer3D::get_doppler_tracking);
+
+ ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer3D::_bus_layout_changed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "attenuation_model", PROPERTY_HINT_ENUM, "Inverse,InverseSquare,Log"), "set_attenuation_model", "get_attenuation_model");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_db", PROPERTY_HINT_RANGE, "-80,80"), "set_unit_db", "get_unit_db");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "unit_size", PROPERTY_HINT_RANGE, "0.1,100,0.1"), "set_unit_size", "get_unit_size");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_db", PROPERTY_HINT_RANGE, "-24,6"), "set_max_db", "get_max_db");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "0,65536,1"), "set_max_distance", "get_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "out_of_range_mode", PROPERTY_HINT_ENUM, "Mix,Pause"), "set_out_of_range_mode", "get_out_of_range_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");
+ ADD_GROUP("Emission Angle", "emission_angle");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "emission_angle_enabled"), "set_emission_angle_enabled", "is_emission_angle_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_degrees", PROPERTY_HINT_RANGE, "0.1,90,0.1"), "set_emission_angle", "get_emission_angle");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_angle_filter_attenuation_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_emission_angle_filter_attenuation_db", "get_emission_angle_filter_attenuation_db");
+ ADD_GROUP("Attenuation Filter", "attenuation_filter_");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_cutoff_hz", PROPERTY_HINT_RANGE, "50,50000,1"), "set_attenuation_filter_cutoff_hz", "get_attenuation_filter_cutoff_hz");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation_filter_db", PROPERTY_HINT_RANGE, "-80,0,0.1"), "set_attenuation_filter_db", "get_attenuation_filter_db");
+ ADD_GROUP("Doppler", "doppler_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "doppler_tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Fixed"), "set_doppler_tracking", "get_doppler_tracking");
+
+ BIND_CONSTANT(ATTENUATION_INVERSE_DISTANCE);
+ BIND_CONSTANT(ATTENUATION_INVERSE_SQUARE_DISTANCE);
+ BIND_CONSTANT(ATTENUATION_LOGARITHMIC);
+
+ BIND_CONSTANT(OUT_OF_RANGE_MIX);
+ BIND_CONSTANT(OUT_OF_RANGE_PAUSE);
+
+ BIND_CONSTANT(DOPPLER_TRACKING_DISABLED);
+ BIND_CONSTANT(DOPPLER_TRACKING_IDLE_STEP);
+ BIND_CONSTANT(DOPPLER_TRACKING_FIXED_STEP);
+}
+
+AudioStreamPlayer3D::AudioStreamPlayer3D() {
+
+ unit_db = 0;
+ unit_size = 1;
+ attenuation_model = ATTENUATION_INVERSE_DISTANCE;
+ max_db = 3;
+ autoplay = false;
+ setseek = -1;
+ active = false;
+ output_count = 0;
+ prev_output_count = 0;
+ max_distance = 0;
+ setplay = -1;
+ output_ready = false;
+ area_mask = 1;
+ emission_angle = 45;
+ emission_angle_enabled = false;
+ emission_angle_filter_attenuation_db = -12;
+ attenuation_filter_cutoff_hz = 5000;
+ attenuation_filter_db = -24;
+ out_of_range_mode = OUT_OF_RANGE_MIX;
+ doppler_tracking = DOPPLER_TRACKING_DISABLED;
+
+ velocity_tracker.instance();
+ AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
+}
+AudioStreamPlayer3D::~AudioStreamPlayer3D() {
+}
diff --git a/scene/3d/audio_stream_player_3d.h b/scene/3d/audio_stream_player_3d.h
new file mode 100644
index 0000000000..8603cab5a4
--- /dev/null
+++ b/scene/3d/audio_stream_player_3d.h
@@ -0,0 +1,175 @@
+#ifndef AUDIO_STREAM_PLAYER_3D_H
+#define AUDIO_STREAM_PLAYER_3D_H
+
+#include "scene/3d/spatial.h"
+#include "scene/3d/spatial_velocity_tracker.h"
+#include "servers/audio/audio_filter_sw.h"
+#include "servers/audio/audio_stream.h"
+#include "servers/audio_server.h"
+
+class Camera;
+class AudioStreamPlayer3D : public Spatial {
+
+ GDCLASS(AudioStreamPlayer3D, Spatial)
+public:
+ enum AttenuationModel {
+ ATTENUATION_INVERSE_DISTANCE,
+ ATTENUATION_INVERSE_SQUARE_DISTANCE,
+ ATTENUATION_LOGARITHMIC,
+ };
+
+ enum OutOfRangeMode {
+ OUT_OF_RANGE_MIX,
+ OUT_OF_RANGE_PAUSE,
+ };
+
+ enum DopplerTracking {
+ DOPPLER_TRACKING_DISABLED,
+ DOPPLER_TRACKING_IDLE_STEP,
+ DOPPLER_TRACKING_FIXED_STEP
+ };
+
+private:
+ enum {
+ MAX_OUTPUTS = 8,
+ MAX_INTERSECT_AREAS = 32
+
+ };
+
+ struct Output {
+
+ AudioFilterSW filter;
+ AudioFilterSW::Processor filter_process[6];
+ AudioFrame vol[3];
+ float filter_gain;
+ float pitch_scale;
+ int bus_index;
+ int reverb_bus_index;
+ AudioFrame reverb_vol[3];
+ Viewport *viewport; //pointer only used for reference to previous mix
+
+ Output() {
+ filter_gain = 0;
+ viewport = NULL;
+ reverb_bus_index = -1;
+ bus_index = -1;
+ }
+ };
+
+ Output outputs[MAX_OUTPUTS];
+ volatile int output_count;
+ volatile bool output_ready;
+
+ //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
+ Output prev_outputs[MAX_OUTPUTS];
+ int prev_output_count;
+
+ Ref<AudioStreamPlayback> stream_playback;
+ Ref<AudioStream> stream;
+ Vector<AudioFrame> mix_buffer;
+
+ volatile float setseek;
+ volatile bool active;
+ volatile float setplay;
+
+ AttenuationModel attenuation_model;
+ float unit_db;
+ float unit_size;
+ float max_db;
+ bool autoplay;
+ StringName bus;
+
+ void _mix_audio();
+ static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer3D *>(self)->_mix_audio(); }
+
+ void _set_playing(bool p_enable);
+ bool _is_active() const;
+
+ void _bus_layout_changed();
+
+ uint32_t area_mask;
+
+ bool emission_angle_enabled;
+ float emission_angle;
+ float emission_angle_filter_attenuation_db;
+ float attenuation_filter_cutoff_hz;
+ float attenuation_filter_db;
+
+ float max_distance;
+
+ Ref<SpatialVelocityTracker> velocity_tracker;
+
+ DopplerTracking doppler_tracking;
+
+ OutOfRangeMode out_of_range_mode;
+
+ float _get_attenuation_db(float p_distance) const;
+
+protected:
+ void _validate_property(PropertyInfo &property) const;
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_stream(Ref<AudioStream> p_stream);
+ Ref<AudioStream> get_stream() const;
+
+ void set_unit_db(float p_volume);
+ float get_unit_db() const;
+
+ void set_unit_size(float p_volume);
+ float get_unit_size() const;
+
+ void set_max_db(float p_boost);
+ float get_max_db() const;
+
+ void play(float p_from_pos = 0.0);
+ void seek(float p_seconds);
+ void stop();
+ bool is_playing() const;
+ float get_pos();
+
+ void set_bus(const StringName &p_bus);
+ StringName get_bus() const;
+
+ void set_autoplay(bool p_enable);
+ bool is_autoplay_enabled();
+
+ void set_max_distance(float p_metres);
+ float get_max_distance() const;
+
+ void set_area_mask(uint32_t p_mask);
+ uint32_t get_area_mask() const;
+
+ void set_emission_angle_enabled(bool p_enable);
+ bool is_emission_angle_enabled() const;
+
+ void set_emission_angle(float p_angle);
+ float get_emission_angle() const;
+
+ void set_emission_angle_filter_attenuation_db(float p_angle_attenuation_db);
+ float get_emission_angle_filter_attenuation_db() const;
+
+ void set_attenuation_filter_cutoff_hz(float p_hz);
+ float get_attenuation_filter_cutoff_hz() const;
+
+ void set_attenuation_filter_db(float p_db);
+ float get_attenuation_filter_db() const;
+
+ void set_attenuation_model(AttenuationModel p_model);
+ AttenuationModel get_attenuation_model() const;
+
+ void set_out_of_range_mode(OutOfRangeMode p_mode);
+ OutOfRangeMode get_out_of_range_mode() const;
+
+ void set_doppler_tracking(DopplerTracking p_tracking);
+ DopplerTracking get_doppler_tracking() const;
+
+ AudioStreamPlayer3D();
+ ~AudioStreamPlayer3D();
+};
+
+VARIANT_ENUM_CAST(AudioStreamPlayer3D::AttenuationModel)
+VARIANT_ENUM_CAST(AudioStreamPlayer3D::OutOfRangeMode)
+VARIANT_ENUM_CAST(AudioStreamPlayer3D::DopplerTracking)
+#endif // AUDIO_STREAM_PLAYER_3D_H
diff --git a/scene/3d/body_shape.cpp b/scene/3d/body_shape.cpp
deleted file mode 100644
index 68f166c5b9..0000000000
--- a/scene/3d/body_shape.cpp
+++ /dev/null
@@ -1,920 +0,0 @@
-/*************************************************************************/
-/* body_shape.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 "body_shape.h"
-#include "scene/resources/box_shape.h"
-#include "scene/resources/capsule_shape.h"
-#include "scene/resources/concave_polygon_shape.h"
-#include "scene/resources/convex_polygon_shape.h"
-#include "scene/resources/plane_shape.h"
-#include "scene/resources/ray_shape.h"
-#include "scene/resources/sphere_shape.h"
-#include "servers/visual_server.h"
-//TODO: Implement CylinderShape and HeightMapShape?
-#include "mesh_instance.h"
-#include "physics_body.h"
-#include "quick_hull.h"
-
-void CollisionShape::_update_body() {
-
- if (!is_inside_tree() || !can_update_body)
- return;
- if (!get_tree()->is_editor_hint())
- return;
- if (get_parent() && get_parent()->cast_to<CollisionObject>())
- get_parent()->cast_to<CollisionObject>()->_update_shapes_from_children();
-}
-
-void CollisionShape::make_convex_from_brothers() {
-
- Node *p = get_parent();
- if (!p)
- return;
-
- for (int i = 0; i < p->get_child_count(); i++) {
-
- Node *n = p->get_child(i);
- if (n->cast_to<MeshInstance>()) {
-
- MeshInstance *mi = n->cast_to<MeshInstance>();
- Ref<Mesh> m = mi->get_mesh();
- if (m.is_valid()) {
-
- Ref<Shape> s = m->create_convex_shape();
- set_shape(s);
- }
- }
- }
-}
-/*
-
-void CollisionShape::_update_indicator() {
-
- while (VisualServer::get_singleton()->mesh_get_surface_count(indicator))
- VisualServer::get_singleton()->mesh_remove_surface(indicator,0);
-
- if (shape.is_null())
- return;
-
- PoolVector<Vector3> points;
- PoolVector<Vector3> normals;
-
- VS::PrimitiveType pt = VS::PRIMITIVE_TRIANGLES;
-
- if (shape->cast_to<RayShape>()) {
-
- RayShape *rs = shape->cast_to<RayShape>();
- points.push_back(Vector3());
- points.push_back(Vector3(0,0,rs->get_length()));
- pt = VS::PRIMITIVE_LINES;
- } else if (shape->cast_to<SphereShape>()) {
-
- //VisualServer *vs=VisualServer::get_singleton();
- SphereShape *shapeptr=shape->cast_to<SphereShape>();
-
-
- Color col(0.4,1.0,1.0,0.5);
-
- int lats=6;
- int lons=12;
- float size=shapeptr->get_radius();
-
-
- for(int i = 1; i <= lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
-
- double lat1 = Math_PI * (-0.5 + (double) i / lats);
- double z1 = Math::sin(lat1);
- double zr1 = Math::cos(lat1);
-
- for(int j = lons; j >= 1; j--) {
-
- double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
- double x0 = Math::cos(lng0);
- double y0 = Math::sin(lng0);
-
- double lng1 = 2 * Math_PI * (double) (j) / lons;
- double x1 = Math::cos(lng1);
- double y1 = Math::sin(lng1);
-
- Vector3 v4=Vector3(x0 * zr0, z0, y0 *zr0)*size;
- Vector3 v3=Vector3(x0 * zr1, z1, y0 *zr1)*size;
- Vector3 v2=Vector3(x1 * zr1, z1, y1 *zr1)*size;
- Vector3 v1=Vector3(x1 * zr0, z0, y1 *zr0)*size;
-
- Vector<Vector3> line;
- line.push_back(v1);
- line.push_back(v2);
- line.push_back(v3);
- line.push_back(v4);
-
-
- points.push_back(v1);
- points.push_back(v2);
- points.push_back(v3);
-
- points.push_back(v1);
- points.push_back(v3);
- points.push_back(v4);
-
- normals.push_back(v1.normalized());
- normals.push_back(v2.normalized());
- normals.push_back(v3.normalized());
-
- normals.push_back(v1.normalized());
- normals.push_back(v3.normalized());
- normals.push_back(v4.normalized());
-
- }
- }
- } else if (shape->cast_to<BoxShape>()) {
-
- BoxShape *shapeptr=shape->cast_to<BoxShape>();
-
- for (int i=0;i<6;i++) {
-
-
- Vector3 face_points[4];
-
-
- for (int j=0;j<4;j++) {
-
- float v[3];
- v[0]=1.0;
- v[1]=1-2*((j>>1)&1);
- v[2]=v[1]*(1-2*(j&1));
-
- for (int k=0;k<3;k++) {
-
- if (i<3)
- face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
- else
- face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
- }
- }
- Vector3 normal;
- normal[i%3]=(i>=3?-1:1);
-
- for(int j=0;j<4;j++)
- face_points[j]*=shapeptr->get_extents();
-
- points.push_back(face_points[0]);
- points.push_back(face_points[1]);
- points.push_back(face_points[2]);
-
- points.push_back(face_points[0]);
- points.push_back(face_points[2]);
- points.push_back(face_points[3]);
-
- for(int n=0;n<6;n++)
- normals.push_back(normal);
-
- }
-
- } else if (shape->cast_to<ConvexPolygonShape>()) {
-
- ConvexPolygonShape *shapeptr=shape->cast_to<ConvexPolygonShape>();
-
- Geometry::MeshData md;
- QuickHull::build(Variant(shapeptr->get_points()),md);
-
- for(int i=0;i<md.faces.size();i++) {
-
- for(int j=2;j<md.faces[i].indices.size();j++) {
- points.push_back(md.vertices[md.faces[i].indices[0]]);
- points.push_back(md.vertices[md.faces[i].indices[j-1]]);
- points.push_back(md.vertices[md.faces[i].indices[j]]);
- normals.push_back(md.faces[i].plane.normal);
- normals.push_back(md.faces[i].plane.normal);
- normals.push_back(md.faces[i].plane.normal);
- }
- }
- } else if (shape->cast_to<ConcavePolygonShape>()) {
-
- ConcavePolygonShape *shapeptr=shape->cast_to<ConcavePolygonShape>();
-
- points = shapeptr->get_faces();
- for(int i=0;i<points.size()/3;i++) {
-
- Vector3 n = Plane( points[i*3+0],points[i*3+1],points[i*3+2] ).normal;
- normals.push_back(n);
- normals.push_back(n);
- normals.push_back(n);
- }
-
- } else if (shape->cast_to<CapsuleShape>()) {
-
- CapsuleShape *shapeptr=shape->cast_to<CapsuleShape>();
-
- PoolVector<Plane> planes = Geometry::build_capsule_planes(shapeptr->get_radius(), shapeptr->get_height()/2.0, 12, Vector3::AXIS_Z);
- Geometry::MeshData md = Geometry::build_convex_mesh(planes);
-
- for(int i=0;i<md.faces.size();i++) {
-
- for(int j=2;j<md.faces[i].indices.size();j++) {
- points.push_back(md.vertices[md.faces[i].indices[0]]);
- points.push_back(md.vertices[md.faces[i].indices[j-1]]);
- points.push_back(md.vertices[md.faces[i].indices[j]]);
- normals.push_back(md.faces[i].plane.normal);
- normals.push_back(md.faces[i].plane.normal);
- normals.push_back(md.faces[i].plane.normal);
-
- }
- }
-
- } else if (shape->cast_to<PlaneShape>()) {
-
- PlaneShape *shapeptr=shape->cast_to<PlaneShape>();
-
- Plane p = shapeptr->get_plane();
- Vector3 n1 = p.get_any_perpendicular_normal();
- Vector3 n2 = p.normal.cross(n1).normalized();
-
- Vector3 pface[4]={
- p.normal*p.d+n1*100.0+n2*100.0,
- p.normal*p.d+n1*100.0+n2*-100.0,
- p.normal*p.d+n1*-100.0+n2*-100.0,
- p.normal*p.d+n1*-100.0+n2*100.0,
- };
-
- points.push_back(pface[0]);
- points.push_back(pface[1]);
- points.push_back(pface[2]);
-
- points.push_back(pface[0]);
- points.push_back(pface[2]);
- points.push_back(pface[3]);
-
- normals.push_back(p.normal);
- normals.push_back(p.normal);
- normals.push_back(p.normal);
- normals.push_back(p.normal);
- normals.push_back(p.normal);
- normals.push_back(p.normal);
-
- }
-
- if (!points.size())
- return;
- RID material = VisualServer::get_singleton()->fixed_material_create();
- VisualServer::get_singleton()->fixed_material_set_param(material,VS::FIXED_MATERIAL_PARAM_DIFFUSE,Color(0,0.6,0.7,0.3));
- VisualServer::get_singleton()->fixed_material_set_param(material,VS::FIXED_MATERIAL_PARAM_EMISSION,0.7);
- if (normals.size()==0)
- VisualServer::get_singleton()->material_set_flag(material,VS::MATERIAL_FLAG_UNSHADED,true);
- VisualServer::get_singleton()->material_set_flag(material,VS::MATERIAL_FLAG_DOUBLE_SIDED,true);
- Array d;
- d.resize(VS::ARRAY_MAX);
- d[VS::ARRAY_VERTEX]=points;
- if (normals.size())
- d[VS::ARRAY_NORMAL]=normals;
- VisualServer::get_singleton()->mesh_add_surface(indicator,pt,d);
- VisualServer::get_singleton()->mesh_surface_set_material(indicator,0,material,true);
-
-}
-
-*/
-void CollisionShape::_add_to_collision_object(Object *p_cshape) {
-
- if (unparenting)
- return;
-
- CollisionObject *co = p_cshape->cast_to<CollisionObject>();
- ERR_FAIL_COND(!co);
-
- if (shape.is_valid()) {
-
- update_shape_index = co->get_shape_count();
- co->add_shape(shape, get_transform());
- if (trigger)
- co->set_shape_as_trigger(co->get_shape_count() - 1, true);
- } else {
- update_shape_index = -1;
- }
-}
-
-void CollisionShape::_notification(int p_what) {
-
- switch (p_what) {
-
- case NOTIFICATION_ENTER_TREE: {
- unparenting = false;
- can_update_body = get_tree()->is_editor_hint();
- set_notify_local_transform(!can_update_body);
-
- if (get_tree()->is_debugging_collisions_hint()) {
- _create_debug_shape();
- }
-
- //indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
- //VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
- if (can_update_body && updating_body) {
- _update_body();
- }
- } break;
- case NOTIFICATION_EXIT_TREE: {
- /* if (indicator_instance.is_valid()) {
- VisualServer::get_singleton()->free(indicator_instance);
- indicator_instance=RID();
- }*/
- can_update_body = false;
- set_notify_local_transform(false);
- if (debug_shape) {
- debug_shape->queue_delete();
- debug_shape = NULL;
- }
- } break;
- case NOTIFICATION_UNPARENTED: {
- unparenting = true;
- if (can_update_body && updating_body)
- _update_body();
- } break;
- case NOTIFICATION_PARENTED: {
- if (can_update_body && updating_body)
- _update_body();
- } break;
- case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
-
- if (!can_update_body && update_shape_index >= 0) {
-
- CollisionObject *co = get_parent()->cast_to<CollisionObject>();
- if (co) {
- co->set_shape_transform(update_shape_index, get_transform());
- }
- }
-
- } break;
- }
-}
-
-void CollisionShape::resource_changed(RES res) {
-
- update_gizmo();
-}
-
-void CollisionShape::_set_update_shape_index(int p_index) {
-
- update_shape_index = p_index;
-}
-
-int CollisionShape::_get_update_shape_index() const {
-
- return update_shape_index;
-}
-
-String CollisionShape::get_configuration_warning() const {
-
- if (!get_parent()->cast_to<CollisionObject>()) {
- return TTR("CollisionShape only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape.");
- }
-
- if (!shape.is_valid()) {
- return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!");
- }
-
- return String();
-}
-
-void CollisionShape::_bind_methods() {
-
- //not sure if this should do anything
- ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &CollisionShape::resource_changed);
- ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape::set_shape);
- ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape::get_shape);
- ClassDB::bind_method(D_METHOD("_add_to_collision_object"), &CollisionShape::_add_to_collision_object);
- ClassDB::bind_method(D_METHOD("set_trigger", "enable"), &CollisionShape::set_trigger);
- ClassDB::bind_method(D_METHOD("is_trigger"), &CollisionShape::is_trigger);
- ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape::make_convex_from_brothers);
- ClassDB::set_method_flags("CollisionShape", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::bind_method(D_METHOD("_set_update_shape_index", "index"), &CollisionShape::_set_update_shape_index);
- ClassDB::bind_method(D_METHOD("_get_update_shape_index"), &CollisionShape::_get_update_shape_index);
-
- ClassDB::bind_method(D_METHOD("get_collision_object_shape_index"), &CollisionShape::get_collision_object_shape_index);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), "set_shape", "get_shape");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "trigger"), "set_trigger", "is_trigger");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "_update_shape_index", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_update_shape_index", "_get_update_shape_index");
-}
-
-void CollisionShape::set_shape(const Ref<Shape> &p_shape) {
-
- if (!shape.is_null())
- shape->unregister_owner(this);
- shape = p_shape;
- if (!shape.is_null())
- shape->register_owner(this);
- update_gizmo();
- if (updating_body) {
- _update_body();
- } else if (can_update_body && update_shape_index >= 0 && is_inside_tree()) {
- CollisionObject *co = get_parent()->cast_to<CollisionObject>();
- if (co) {
- co->set_shape(update_shape_index, p_shape);
- }
- }
-}
-
-Ref<Shape> CollisionShape::get_shape() const {
-
- return shape;
-}
-
-void CollisionShape::set_updating_body(bool p_update) {
- updating_body = p_update;
-}
-
-bool CollisionShape::is_updating_body() const {
-
- return updating_body;
-}
-
-void CollisionShape::set_trigger(bool p_trigger) {
-
- trigger = p_trigger;
- if (updating_body) {
- _update_body();
- } else if (can_update_body && update_shape_index >= 0 && is_inside_tree()) {
- CollisionObject *co = get_parent()->cast_to<CollisionObject>();
- if (co) {
- co->set_shape_as_trigger(update_shape_index, p_trigger);
- }
- }
-}
-
-bool CollisionShape::is_trigger() const {
-
- return trigger;
-}
-
-CollisionShape::CollisionShape() {
-
- //indicator = VisualServer::get_singleton()->mesh_create();
- updating_body = true;
- unparenting = false;
- update_shape_index = -1;
- trigger = false;
- can_update_body = false;
- debug_shape = NULL;
-}
-
-CollisionShape::~CollisionShape() {
- if (!shape.is_null())
- shape->unregister_owner(this);
- //VisualServer::get_singleton()->free(indicator);
-}
-
-void CollisionShape::_create_debug_shape() {
-
- if (debug_shape) {
- debug_shape->queue_delete();
- debug_shape = NULL;
- }
-
- Ref<Shape> s = get_shape();
-
- if (s.is_null())
- return;
-
- Ref<Mesh> mesh = s->get_debug_mesh();
-
- MeshInstance *mi = memnew(MeshInstance);
- mi->set_mesh(mesh);
-
- add_child(mi);
- debug_shape = mi;
-}
-
-#if 0
-#include "body_volume.h"
-
-#include "geometry.h"
-#include "scene/3d/physics_body.h"
-
-#define ADD_TRIANGLE(m_a, m_b, m_c, m_color) \
- { \
- Vector<Vector3> points; \
- points.resize(3); \
- points[0] = m_a; \
- points[1] = m_b; \
- points[2] = m_c; \
- Vector<Color> colors; \
- colors.resize(3); \
- colors[0] = m_color; \
- colors[1] = m_color; \
- colors[2] = m_color; \
- vs->poly_add_primitive(p_indicator, points, Vector<Vector3>(), colors, Vector<Vector3>()); \
- }
-
-
-void CollisionShape::_notification(int p_what) {
-
- switch (p_what) {
- case NOTIFICATION_ENTER_SCENE: {
-
-
- if (get_root_node()->get_editor() && !indicator.is_valid()) {
-
- indicator=VisualServer::get_singleton()->poly_create();
- RID mat=VisualServer::get_singleton()->fixed_material_create();
- VisualServer::get_singleton()->material_set_flag( mat, VisualServer::MATERIAL_FLAG_UNSHADED, true );
- VisualServer::get_singleton()->material_set_flag( mat, VisualServer::MATERIAL_FLAG_WIREFRAME, true );
- VisualServer::get_singleton()->material_set_flag( mat, VisualServer::MATERIAL_FLAG_DOUBLE_SIDED, true );
- VisualServer::get_singleton()->material_set_line_width( mat, 3 );
-
- VisualServer::get_singleton()->poly_set_material(indicator,mat,true);
-
- update_indicator(indicator);
- }
-
- if (indicator.is_valid()) {
-
- indicator_instance=VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
- VisualServer::get_singleton()->instance_attach_object_instance_ID(indicator_instance,get_instance_ID());
- }
- volume_changed();
- } break;
- case NOTIFICATION_EXIT_SCENE: {
-
- if (indicator_instance.is_valid()) {
-
- VisualServer::get_singleton()->free(indicator_instance);
- }
- volume_changed();
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (indicator_instance.is_valid()) {
-
- VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
- }
- volume_changed();
- } break;
- default: {}
- }
-}
-
-void CollisionShape::volume_changed() {
-
- if (indicator.is_valid())
- update_indicator(indicator);
-
- Object *parent=get_parent();
- if (!parent)
- return;
- PhysicsBody *physics_body=parent->cast_to<PhysicsBody>();
-
- ERR_EXPLAIN("CollisionShape parent is not of type PhysicsBody");
- ERR_FAIL_COND(!physics_body);
-
- physics_body->recompute_child_volumes();
-
-}
-
-RID CollisionShape::_get_visual_instance_rid() const {
-
- return indicator_instance;
-
-}
-
-void CollisionShape::_bind_methods() {
-
- ClassDB::bind_method("_get_visual_instance_rid",&CollisionShape::_get_visual_instance_rid);
-}
-
-CollisionShape::CollisionShape() {
-
-}
-
-CollisionShape::~CollisionShape() {
-
- if (indicator.is_valid()) {
-
- VisualServer::get_singleton()->free(indicator);
- }
-
-}
-
-void CollisionShapeSphere::_set(const String& p_name, const Variant& p_value) {
-
- if (p_name=="radius") {
- radius=p_value;
- volume_changed();
- }
-
-}
-
-Variant CollisionShapeSphere::_get(const String& p_name) const {
-
- if (p_name=="radius") {
- return radius;
- }
-
- return Variant();
-}
-
-void CollisionShapeSphere::_get_property_list( List<PropertyInfo> *p_list) const {
-
- p_list->push_back( PropertyInfo(Variant::REAL,"radius",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
-}
-
-void CollisionShapeSphere::update_indicator(RID p_indicator) {
-
- VisualServer *vs=VisualServer::get_singleton();
-
- vs->poly_clear(p_indicator);
- Color col(0.4,1.0,1.0,0.5);
-
- int lats=6;
- int lons=12;
- float size=radius;
-
- for(int i = 1; i <= lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
-
- double lat1 = Math_PI * (-0.5 + (double) i / lats);
- double z1 = Math::sin(lat1);
- double zr1 = Math::cos(lat1);
-
- for(int j = lons; j >= 1; j--) {
-
- double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
- double x0 = Math::cos(lng0);
- double y0 = Math::sin(lng0);
-
- double lng1 = 2 * Math_PI * (double) (j) / lons;
- double x1 = Math::cos(lng1);
- double y1 = Math::sin(lng1);
-
- Vector3 v4=Vector3(x0 * zr0, z0, y0 *zr0)*size;
- Vector3 v3=Vector3(x0 * zr1, z1, y0 *zr1)*size;
- Vector3 v2=Vector3(x1 * zr1, z1, y1 *zr1)*size;
- Vector3 v1=Vector3(x1 * zr0, z0, y1 *zr0)*size;
-
- Vector<Vector3> line;
- line.push_back(v1);
- line.push_back(v2);
- line.push_back(v3);
- line.push_back(v4);
-
- Vector<Color> cols;
- cols.push_back(col);
- cols.push_back(col);
- cols.push_back(col);
- cols.push_back(col);
-
-
- VisualServer::get_singleton()->poly_add_primitive(p_indicator,line,Vector<Vector3>(),cols,Vector<Vector3>());
- }
- }
-}
-
-void CollisionShapeSphere::append_to_volume(Ref<Shape> p_volume) {
-
- p_volume->add_sphere_shape(radius,get_transform());
-}
-
-
-CollisionShapeSphere::CollisionShapeSphere() {
-
- radius=1.0;
-}
-
-/* BOX */
-
-
-void CollisionShapeBox::_set(const String& p_name, const Variant& p_value) {
-
- if (p_name=="half_extents") {
- half_extents=p_value;
- volume_changed();
- }
-
-}
-
-Variant CollisionShapeBox::_get(const String& p_name) const {
-
- if (p_name=="half_extents") {
- return half_extents;
- }
-
- return Variant();
-}
-
-void CollisionShapeBox::_get_property_list( List<PropertyInfo> *p_list) const {
-
- p_list->push_back( PropertyInfo(Variant::VECTOR3,"half_extents" ) );
-}
-
-
-void CollisionShapeBox::update_indicator(RID p_indicator) {
-
- VisualServer *vs=VisualServer::get_singleton();
-
- vs->poly_clear(p_indicator);
- Color col(0.4,1.0,1.0,0.5);
-
-
- for (int i=0;i<6;i++) {
-
-
- Vector3 face_points[4];
-
- for (int j=0;j<4;j++) {
-
- float v[3];
- v[0]=1.0;
- v[1]=1-2*((j>>1)&1);
- v[2]=v[1]*(1-2*(j&1));
-
- for (int k=0;k<3;k++) {
-
- if (i<3)
- face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
- else
- face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
- }
- }
-
- for(int j=0;j<4;j++)
- face_points[i]*=half_extents;
-
- ADD_TRIANGLE(face_points[0],face_points[1],face_points[2],col);
- ADD_TRIANGLE(face_points[2],face_points[3],face_points[0],col);
-
- }
-}
-
-void CollisionShapeBox::append_to_volume(Ref<Shape> p_volume) {
-
- p_volume->add_box_shape(half_extents,get_transform());
-}
-
-
-CollisionShapeBox::CollisionShapeBox() {
-
- half_extents=Vector3(1,1,1);
-}
-
-/* CYLINDER */
-
-
-void CollisionShapeCylinder::_set(const String& p_name, const Variant& p_value) {
-
- if (p_name=="radius") {
- radius=p_value;
- volume_changed();
- }
- if (p_name=="height") {
- height=p_value;
- volume_changed();
- }
-
-}
-
-Variant CollisionShapeCylinder::_get(const String& p_name) const {
-
- if (p_name=="radius") {
- return radius;
- }
- if (p_name=="height") {
- return height;
- }
- return Variant();
-}
-
-void CollisionShapeCylinder::_get_property_list( List<PropertyInfo> *p_list) const {
-
- p_list->push_back( PropertyInfo(Variant::REAL,"radius",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
- p_list->push_back( PropertyInfo(Variant::REAL,"height",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
-}
-
-
-void CollisionShapeCylinder::update_indicator(RID p_indicator) {
-
- VisualServer *vs=VisualServer::get_singleton();
-
- vs->poly_clear(p_indicator);
- Color col(0.4,1.0,1.0,0.5);
-
- PoolVector<Plane> planes = Geometry::build_cylinder_planes(radius, height, 12, Vector3::AXIS_Z);
- Geometry::MeshData md = Geometry::build_convex_mesh(planes);
-
- for(int i=0;i<md.faces.size();i++) {
-
- for(int j=2;j<md.faces[i].indices.size();j++) {
- ADD_TRIANGLE(md.vertices[md.faces[i].indices[0]],md.vertices[md.faces[i].indices[j-1]],md.vertices[md.faces[i].indices[j]],col);
- }
- }
-
-}
-
-void CollisionShapeCylinder::append_to_volume(Ref<Shape> p_volume) {
-
- p_volume->add_cylinder_shape(radius,height*2.0,get_transform());
-}
-
-
-CollisionShapeCylinder::CollisionShapeCylinder() {
-
- height=1;
- radius=1;
-}
-
-/* CAPSULE */
-
-
-void CollisionShapeCapsule::_set(const String& p_name, const Variant& p_value) {
-
- if (p_name=="radius") {
- radius=p_value;
- volume_changed();
- }
-
- if (p_name=="height") {
- height=p_value;
- volume_changed();
- }
-
-}
-
-Variant CollisionShapeCapsule::_get(const String& p_name) const {
-
- if (p_name=="radius") {
- return radius;
- }
- if (p_name=="height") {
- return height;
- }
- return Variant();
-}
-
-void CollisionShapeCapsule::_get_property_list( List<PropertyInfo> *p_list) const {
-
- p_list->push_back( PropertyInfo(Variant::REAL,"radius",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
- p_list->push_back( PropertyInfo(Variant::REAL,"height",PROPERTY_HINT_RANGE,"0.01,16384,0.01") );
-}
-
-
-void CollisionShapeCapsule::update_indicator(RID p_indicator) {
-
- VisualServer *vs=VisualServer::get_singleton();
-
- vs->poly_clear(p_indicator);
- Color col(0.4,1.0,1.0,0.5);
-
- PoolVector<Plane> planes = Geometry::build_capsule_planes(radius, height, 12, 3, Vector3::AXIS_Z);
- Geometry::MeshData md = Geometry::build_convex_mesh(planes);
-
- for(int i=0;i<md.faces.size();i++) {
-
- for(int j=2;j<md.faces[i].indices.size();j++) {
- ADD_TRIANGLE(md.vertices[md.faces[i].indices[0]],md.vertices[md.faces[i].indices[j-1]],md.vertices[md.faces[i].indices[j]],col);
- }
- }
-
-}
-
-void CollisionShapeCapsule::append_to_volume(Ref<Shape> p_volume) {
-
-
- p_volume->add_capsule_shape(radius,height,get_transform());
-}
-
-
-CollisionShapeCapsule::CollisionShapeCapsule() {
-
- height=1;
- radius=1;
-}
-#endif
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index 0f4378acdd..697d91c863 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -94,6 +94,8 @@ bool Camera::_set(const StringName &p_name, const Variant &p_value) {
set_cull_mask(p_value);
} else if (p_name == "environment") {
set_environment(p_value);
+ } else if (p_name == "doppler/tracking") {
+ set_doppler_tracking(DopplerTracking(int(p_value)));
} else
return false;
@@ -131,6 +133,8 @@ bool Camera::_get(const StringName &p_name, Variant &r_ret) const {
r_ret = get_v_offset();
} else if (p_name == "environment") {
r_ret = get_environment();
+ } else if (p_name == "doppler/tracking") {
+ r_ret = get_doppler_tracking();
} else
return false;
@@ -171,6 +175,7 @@ void Camera::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"));
p_list->push_back(PropertyInfo(Variant::REAL, "h_offset"));
p_list->push_back(PropertyInfo(Variant::REAL, "v_offset"));
+ p_list->push_back(PropertyInfo(Variant::INT, "doppler/tracking", PROPERTY_HINT_ENUM, "Disabled,Idle,Fixed"));
}
void Camera::_update_camera() {
@@ -209,6 +214,9 @@ void Camera::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: {
_request_camera_update();
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+ velocity_tracker->update_position(get_global_transform().origin);
+ }
} break;
case NOTIFICATION_EXIT_WORLD: {
@@ -507,6 +515,22 @@ Camera::KeepAspect Camera::get_keep_aspect_mode() const {
return keep_aspect;
}
+void Camera::set_doppler_tracking(DopplerTracking p_tracking) {
+
+ if (doppler_tracking == p_tracking)
+ return;
+
+ doppler_tracking = p_tracking;
+ if (p_tracking != DOPPLER_TRACKING_DISABLED) {
+ velocity_tracker->set_track_fixed_step(doppler_tracking == DOPPLER_TRACKING_FIXED_STEP);
+ velocity_tracker->reset(get_global_transform().origin);
+ }
+}
+
+Camera::DopplerTracking Camera::get_doppler_tracking() const {
+ return doppler_tracking;
+}
+
void Camera::_bind_methods() {
ClassDB::bind_method(D_METHOD("project_ray_normal", "screen_point"), &Camera::project_ray_normal);
@@ -536,6 +560,8 @@ void Camera::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_environment:Environment"), &Camera::get_environment);
ClassDB::bind_method(D_METHOD("set_keep_aspect_mode", "mode"), &Camera::set_keep_aspect_mode);
ClassDB::bind_method(D_METHOD("get_keep_aspect_mode"), &Camera::get_keep_aspect_mode);
+ ClassDB::bind_method(D_METHOD("set_doppler_tracking", "mode"), &Camera::set_doppler_tracking);
+ ClassDB::bind_method(D_METHOD("get_doppler_tracking"), &Camera::get_doppler_tracking);
//ClassDB::bind_method(D_METHOD("_camera_make_current"),&Camera::_camera_make_current );
BIND_CONSTANT(PROJECTION_PERSPECTIVE);
@@ -543,6 +569,10 @@ void Camera::_bind_methods() {
BIND_CONSTANT(KEEP_WIDTH);
BIND_CONSTANT(KEEP_HEIGHT);
+
+ BIND_CONSTANT(DOPPLER_TRACKING_DISABLED)
+ BIND_CONSTANT(DOPPLER_TRACKING_IDLE_STEP)
+ BIND_CONSTANT(DOPPLER_TRACKING_FIXED_STEP)
}
float Camera::get_fov() const {
@@ -616,6 +646,14 @@ float Camera::get_h_offset() const {
return h_offset;
}
+Vector3 Camera::get_doppler_tracked_velocity() const {
+
+ if (doppler_tracking != DOPPLER_TRACKING_DISABLED) {
+ return velocity_tracker->get_tracked_linear_velocity();
+ } else {
+ return Vector3();
+ }
+}
Camera::Camera() {
camera = VisualServer::get_singleton()->camera_create();
@@ -633,6 +671,8 @@ Camera::Camera() {
h_offset = 0;
VisualServer::get_singleton()->camera_set_cull_mask(camera, layers);
//active=false;
+ velocity_tracker.instance();
+ doppler_tracking = DOPPLER_TRACKING_DISABLED;
set_notify_transform(true);
}
diff --git a/scene/3d/camera.h b/scene/3d/camera.h
index 472cfaa008..43975892b4 100644
--- a/scene/3d/camera.h
+++ b/scene/3d/camera.h
@@ -31,6 +31,7 @@
#define CAMERA_H
#include "scene/3d/spatial.h"
+#include "scene/3d/spatial_velocity_tracker.h"
#include "scene/main/viewport.h"
#include "scene/resources/environment.h"
/**
@@ -52,6 +53,12 @@ public:
KEEP_HEIGHT
};
+ enum DopplerTracking {
+ DOPPLER_TRACKING_DISABLED,
+ DOPPLER_TRACKING_IDLE_STEP,
+ DOPPLER_TRACKING_FIXED_STEP
+ };
+
private:
bool force_change;
bool current;
@@ -80,6 +87,9 @@ private:
friend class Viewport;
void _update_audio_listener_state();
+ DopplerTracking doppler_tracking;
+ Ref<SpatialVelocityTracker> velocity_tracker;
+
protected:
void _update_camera();
virtual void _request_camera_update();
@@ -140,11 +150,17 @@ public:
void set_h_offset(float p_offset);
float get_h_offset() const;
+ void set_doppler_tracking(DopplerTracking p_tracking);
+ DopplerTracking get_doppler_tracking() const;
+
+ Vector3 get_doppler_tracked_velocity() const;
+
Camera();
~Camera();
};
VARIANT_ENUM_CAST(Camera::Projection);
VARIANT_ENUM_CAST(Camera::KeepAspect);
+VARIANT_ENUM_CAST(Camera::DopplerTracking);
#endif
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 1b27313d3b..874e5f01ea 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -30,17 +30,6 @@
#include "collision_object.h"
#include "scene/scene_string_names.h"
#include "servers/physics_server.h"
-void CollisionObject::_update_shapes_from_children() {
-
- shapes.clear();
- for (int i = 0; i < get_child_count(); i++) {
-
- Node *n = get_child(i);
- n->call("_add_to_collision_object", this);
- }
-
- _update_shapes();
-}
void CollisionObject::_notification(int p_what) {
@@ -87,91 +76,6 @@ void CollisionObject::_notification(int p_what) {
}
}
-void CollisionObject::_update_shapes() {
-
- if (!rid.is_valid())
- return;
-
- if (area)
- PhysicsServer::get_singleton()->area_clear_shapes(rid);
- else
- PhysicsServer::get_singleton()->body_clear_shapes(rid);
-
- for (int i = 0; i < shapes.size(); i++) {
-
- if (shapes[i].shape.is_null())
- continue;
- if (area)
- PhysicsServer::get_singleton()->area_add_shape(rid, shapes[i].shape->get_rid(), shapes[i].xform);
- else {
- PhysicsServer::get_singleton()->body_add_shape(rid, shapes[i].shape->get_rid(), shapes[i].xform);
- if (shapes[i].trigger)
- PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid, i, shapes[i].trigger);
- }
- }
-}
-
-bool CollisionObject::_set(const StringName &p_name, const Variant &p_value) {
- String name = p_name;
-
- if (name == "shape_count") {
-
- shapes.resize(p_value);
- _update_shapes();
- _change_notify();
-
- } else if (name.begins_with("shapes/")) {
-
- int idx = name.get_slicec('/', 1).to_int();
- String what = name.get_slicec('/', 2);
- if (what == "shape")
- set_shape(idx, RefPtr(p_value));
- else if (what == "transform")
- set_shape_transform(idx, p_value);
- else if (what == "trigger")
- set_shape_as_trigger(idx, p_value);
-
- } else
- return false;
-
- return true;
-}
-
-bool CollisionObject::_get(const StringName &p_name, Variant &r_ret) const {
-
- String name = p_name;
-
- if (name == "shape_count") {
- r_ret = shapes.size();
- } else if (name.begins_with("shapes/")) {
-
- int idx = name.get_slicec('/', 1).to_int();
- String what = name.get_slicec('/', 2);
- if (what == "shape")
- r_ret = get_shape(idx);
- else if (what == "transform")
- r_ret = get_shape_transform(idx);
- else if (what == "trigger")
- r_ret = is_shape_set_as_trigger(idx);
-
- } else
- return false;
-
- return true;
-}
-
-void CollisionObject::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::INT, "shape_count", PROPERTY_HINT_RANGE, "0,256,1", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
-
- for (int i = 0; i < shapes.size(); i++) {
- String path = "shapes/" + itos(i) + "/";
- p_list->push_back(PropertyInfo(Variant::OBJECT, path + "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
- p_list->push_back(PropertyInfo(Variant::TRANSFORM, path + "transform", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
- p_list->push_back(PropertyInfo(Variant::BOOL, path + "trigger", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_NO_INSTANCE_STATE));
- }
-}
-
void CollisionObject::_input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
if (get_script_instance()) {
@@ -219,17 +123,6 @@ bool CollisionObject::is_ray_pickable() const {
void CollisionObject::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_shape", "shape:Shape", "transform"), &CollisionObject::add_shape, DEFVAL(Transform()));
- ClassDB::bind_method(D_METHOD("get_shape_count"), &CollisionObject::get_shape_count);
- ClassDB::bind_method(D_METHOD("set_shape", "shape_idx", "shape:Shape"), &CollisionObject::set_shape);
- ClassDB::bind_method(D_METHOD("set_shape_transform", "shape_idx", "transform"), &CollisionObject::set_shape_transform);
- // ClassDB::bind_method(D_METHOD("set_shape_transform","shape_idx","transform"),&CollisionObject::set_shape_transform);
- ClassDB::bind_method(D_METHOD("set_shape_as_trigger", "shape_idx", "enable"), &CollisionObject::set_shape_as_trigger);
- ClassDB::bind_method(D_METHOD("is_shape_set_as_trigger", "shape_idx"), &CollisionObject::is_shape_set_as_trigger);
- ClassDB::bind_method(D_METHOD("get_shape:Shape", "shape_idx"), &CollisionObject::get_shape);
- ClassDB::bind_method(D_METHOD("get_shape_transform", "shape_idx"), &CollisionObject::get_shape_transform);
- ClassDB::bind_method(D_METHOD("remove_shape", "shape_idx"), &CollisionObject::remove_shape);
- ClassDB::bind_method(D_METHOD("clear_shapes"), &CollisionObject::clear_shapes);
ClassDB::bind_method(D_METHOD("set_ray_pickable", "ray_pickable"), &CollisionObject::set_ray_pickable);
ClassDB::bind_method(D_METHOD("is_ray_pickable"), &CollisionObject::is_ray_pickable);
ClassDB::bind_method(D_METHOD("set_capture_input_on_drag", "enable"), &CollisionObject::set_capture_input_on_drag);
@@ -245,72 +138,176 @@ void CollisionObject::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "input_capture_on_drag"), "set_capture_input_on_drag", "get_capture_input_on_drag");
}
-void CollisionObject::add_shape(const Ref<Shape> &p_shape, const Transform &p_transform) {
+uint32_t CollisionObject::create_shape_owner(Object *p_owner) {
+
+ ShapeData sd;
+ uint32_t id;
+
+ if (shapes.size() == 0) {
+ id = 1;
+ } else {
+ id = shapes.back()->key() + 1;
+ }
+
+ sd.owner = p_owner;
+
+ shapes[id] = sd;
- ShapeData sdata;
- sdata.shape = p_shape;
- sdata.xform = p_transform;
- shapes.push_back(sdata);
- _update_shapes();
+ return id;
}
-int CollisionObject::get_shape_count() const {
- return shapes.size();
+void CollisionObject::remove_shape_owner(uint32_t owner) {
+
+ ERR_FAIL_COND(!shapes.has(owner));
+
+ shape_owner_clear_shapes(owner);
+
+ shapes.erase(owner);
}
-void CollisionObject::set_shape(int p_shape_idx, const Ref<Shape> &p_shape) {
- ERR_FAIL_INDEX(p_shape_idx, shapes.size());
- shapes[p_shape_idx].shape = p_shape;
- _update_shapes();
+void CollisionObject::shape_owner_set_disabled(uint32_t p_owner, bool p_disabled) {
+ ERR_FAIL_COND(!shapes.has(p_owner));
+
+ ShapeData &sd = shapes[p_owner];
+ sd.disabled = p_disabled;
+ for (int i = 0; i < sd.shapes.size(); i++) {
+ if (area) {
+ PhysicsServer::get_singleton()->area_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
+ } else {
+ PhysicsServer::get_singleton()->body_set_shape_disabled(rid, sd.shapes[i].index, p_disabled);
+ }
+ }
}
-void CollisionObject::set_shape_transform(int p_shape_idx, const Transform &p_transform) {
+bool CollisionObject::is_shape_owner_disabled(uint32_t p_owner) const {
- ERR_FAIL_INDEX(p_shape_idx, shapes.size());
- shapes[p_shape_idx].xform = p_transform;
+ ERR_FAIL_COND_V(!shapes.has(p_owner), false);
- _update_shapes();
+ return shapes[p_owner].disabled;
}
-Ref<Shape> CollisionObject::get_shape(int p_shape_idx) const {
+void CollisionObject::get_shape_owners(List<uint32_t> *r_owners) {
- ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), Ref<Shape>());
- return shapes[p_shape_idx].shape;
+ for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
+ r_owners->push_back(E->key());
+ }
}
-Transform CollisionObject::get_shape_transform(int p_shape_idx) const {
- ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), Transform());
- return shapes[p_shape_idx].xform;
+void CollisionObject::shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform) {
+
+ ERR_FAIL_COND(!shapes.has(p_owner));
+
+ ShapeData &sd = shapes[p_owner];
+ sd.xform = p_transform;
+ for (int i = 0; i < sd.shapes.size(); i++) {
+ if (area) {
+ PhysicsServer::get_singleton()->area_set_shape_transform(rid, sd.shapes[i].index, p_transform);
+ } else {
+ PhysicsServer::get_singleton()->body_set_shape_transform(rid, sd.shapes[i].index, p_transform);
+ }
+ }
}
-void CollisionObject::remove_shape(int p_shape_idx) {
+Transform CollisionObject::shape_owner_get_transform(uint32_t p_owner) const {
- ERR_FAIL_INDEX(p_shape_idx, shapes.size());
- shapes.remove(p_shape_idx);
+ ERR_FAIL_COND_V(!shapes.has(p_owner), Transform());
- _update_shapes();
+ return shapes[p_owner].xform;
}
-void CollisionObject::clear_shapes() {
+Object *CollisionObject::shape_owner_get_owner(uint32_t p_owner) const {
- shapes.clear();
+ ERR_FAIL_COND_V(!shapes.has(p_owner), NULL);
- _update_shapes();
+ return shapes[p_owner].owner;
}
-void CollisionObject::set_shape_as_trigger(int p_shape_idx, bool p_trigger) {
+void CollisionObject::shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> &p_shape) {
- ERR_FAIL_INDEX(p_shape_idx, shapes.size());
- shapes[p_shape_idx].trigger = p_trigger;
- if (!area && rid.is_valid()) {
+ ERR_FAIL_COND(!shapes.has(p_owner));
+ ERR_FAIL_COND(p_shape.is_null());
- PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid, p_shape_idx, p_trigger);
+ ShapeData &sd = shapes[p_owner];
+ ShapeData::ShapeBase s;
+ s.index = total_subshapes;
+ s.shape = p_shape;
+ if (area) {
+ PhysicsServer::get_singleton()->area_add_shape(rid, p_shape->get_rid(), sd.xform);
+ } else {
+ PhysicsServer::get_singleton()->body_add_shape(rid, p_shape->get_rid(), sd.xform);
}
+ sd.shapes.push_back(s);
+
+ total_subshapes++;
}
+int CollisionObject::shape_owner_get_shape_count(uint32_t p_owner) const {
-bool CollisionObject::is_shape_set_as_trigger(int p_shape_idx) const {
+ ERR_FAIL_COND_V(!shapes.has(p_owner), 0);
- ERR_FAIL_INDEX_V(p_shape_idx, shapes.size(), false);
- return shapes[p_shape_idx].trigger;
+ return shapes[p_owner].shapes.size();
+}
+Ref<Shape> CollisionObject::shape_owner_get_shape(uint32_t p_owner, int p_shape) const {
+
+ ERR_FAIL_COND_V(!shapes.has(p_owner), Ref<Shape>());
+ ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), Ref<Shape>());
+
+ return shapes[p_owner].shapes[p_shape].shape;
+}
+int CollisionObject::shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const {
+
+ ERR_FAIL_COND_V(!shapes.has(p_owner), -1);
+ ERR_FAIL_INDEX_V(p_shape, shapes[p_owner].shapes.size(), -1);
+
+ return shapes[p_owner].shapes[p_shape].index;
+}
+
+void CollisionObject::shape_owner_remove_shape(uint32_t p_owner, int p_shape) {
+
+ ERR_FAIL_COND(!shapes.has(p_owner));
+ ERR_FAIL_INDEX(p_shape, shapes[p_owner].shapes.size());
+
+ int index_to_remove = shapes[p_owner].shapes[p_shape].index;
+ if (area) {
+ PhysicsServer::get_singleton()->area_remove_shape(rid, index_to_remove);
+ } else {
+ PhysicsServer::get_singleton()->body_remove_shape(rid, index_to_remove);
+ }
+
+ shapes[p_owner].shapes.remove(p_shape);
+
+ for (Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().shapes.size(); i++) {
+ if (E->get().shapes[i].index > index_to_remove) {
+ E->get().shapes[i].index -= 1;
+ }
+ }
+ }
+
+ total_subshapes--;
+}
+
+void CollisionObject::shape_owner_clear_shapes(uint32_t p_owner) {
+
+ ERR_FAIL_COND(!shapes.has(p_owner));
+
+ while (shape_owner_get_shape_count(p_owner) > 0) {
+ shape_owner_remove_shape(p_owner, 0);
+ }
+}
+
+uint32_t CollisionObject::shape_find_owner(int p_shape_index) const {
+
+ ERR_FAIL_INDEX_V(p_shape_index, total_subshapes, 0);
+
+ for (const Map<uint32_t, ShapeData>::Element *E = shapes.front(); E; E = E->next()) {
+ for (int i = 0; i < E->get().shapes.size(); i++) {
+ if (E->get().shapes[i].index == p_shape_index) {
+ return E->key();
+ }
+ }
+ }
+
+ //in theory it should be unreachable
+ return 0;
}
CollisionObject::CollisionObject(RID p_rid, bool p_area) {
@@ -320,6 +317,8 @@ CollisionObject::CollisionObject(RID p_rid, bool p_area) {
capture_input_on_drag = false;
ray_pickable = true;
set_notify_transform(true);
+ total_subshapes = 0;
+
if (p_area) {
PhysicsServer::get_singleton()->area_attach_object_instance_ID(rid, get_instance_ID());
} else {
diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h
index 3822fb0d5a..fac05b6e8c 100644
--- a/scene/3d/collision_object.h
+++ b/scene/3d/collision_object.h
@@ -41,33 +41,36 @@ class CollisionObject : public Spatial {
RID rid;
struct ShapeData {
+
+ Object *owner;
Transform xform;
- Ref<Shape> shape;
- bool trigger;
+ struct ShapeBase {
+ Ref<Shape> shape;
+ int index;
+ };
+
+ Vector<ShapeBase> shapes;
+ bool disabled;
ShapeData() {
- trigger = false;
+ disabled = false;
+ owner = NULL;
}
};
+ int total_subshapes;
+
+ Map<uint32_t, ShapeData> shapes;
+
bool capture_input_on_drag;
bool ray_pickable;
- Vector<ShapeData> shapes;
void _update_pickable();
- void _update_shapes();
-
- friend class CollisionShape;
- friend class CollisionPolygon;
- void _update_shapes_from_children();
protected:
CollisionObject(RID p_rid, bool p_area);
void _notification(int p_what);
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
friend class Viewport;
virtual void _input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
@@ -75,16 +78,26 @@ protected:
virtual void _mouse_exit();
public:
- void add_shape(const Ref<Shape> &p_shape, const Transform &p_transform = Transform());
- int get_shape_count() const;
- void set_shape(int p_shape_idx, const Ref<Shape> &p_shape);
- void set_shape_transform(int p_shape_idx, const Transform &p_transform);
- Ref<Shape> get_shape(int p_shape_idx) const;
- Transform get_shape_transform(int p_shape_idx) const;
- void remove_shape(int p_shape_idx);
- void clear_shapes();
- void set_shape_as_trigger(int p_shape_idx, bool p_trigger);
- bool is_shape_set_as_trigger(int p_shape_idx) const;
+ uint32_t create_shape_owner(Object *p_owner);
+ void remove_shape_owner(uint32_t owner);
+ void get_shape_owners(List<uint32_t> *r_owners);
+
+ void shape_owner_set_transform(uint32_t p_owner, const Transform &p_transform);
+ Transform shape_owner_get_transform(uint32_t p_owner) const;
+ Object *shape_owner_get_owner(uint32_t p_owner) const;
+
+ void shape_owner_set_disabled(uint32_t p_owner, bool p_disabled);
+ bool is_shape_owner_disabled(uint32_t p_owner) const;
+
+ void shape_owner_add_shape(uint32_t p_owner, const Ref<Shape> &p_shape);
+ int shape_owner_get_shape_count(uint32_t p_owner) const;
+ Ref<Shape> shape_owner_get_shape(uint32_t p_owner, int p_shape) const;
+ int shape_owner_get_shape_index(uint32_t p_owner, int p_shape) const;
+
+ void shape_owner_remove_shape(uint32_t p_owner, int p_shape);
+ void shape_owner_clear_shapes(uint32_t p_owner);
+
+ uint32_t shape_find_owner(int p_shape_index) const;
void set_ray_pickable(bool p_ray_pickable);
bool is_ray_pickable() const;
diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp
index d9321f7134..0c61c96d07 100644
--- a/scene/3d/collision_polygon.cpp
+++ b/scene/3d/collision_polygon.cpp
@@ -33,186 +33,82 @@
#include "scene/resources/concave_polygon_shape.h"
#include "scene/resources/convex_polygon_shape.h"
-void CollisionPolygon::_add_to_collision_object(Object *p_obj) {
+void CollisionPolygon::_build_polygon() {
- if (!can_update_body)
+ if (!parent)
return;
- CollisionObject *co = p_obj->cast_to<CollisionObject>();
- ERR_FAIL_COND(!co);
+ parent->shape_owner_clear_shapes(owner_id);
if (polygon.size() == 0)
return;
- bool solids = build_mode == BUILD_SOLIDS;
-
Vector<Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
if (decomp.size() == 0)
return;
- if (true || solids) {
-
- //here comes the sun, lalalala
- //decompose concave into multiple convex polygons and add them
- shape_from = co->get_shape_count();
- for (int i = 0; i < decomp.size(); i++) {
- Ref<ConvexPolygonShape> convex = memnew(ConvexPolygonShape);
- PoolVector<Vector3> cp;
- int cs = decomp[i].size();
- cp.resize(cs * 2);
- {
- PoolVector<Vector3>::Write w = cp.write();
- int idx = 0;
- for (int j = 0; j < cs; j++) {
-
- Vector2 d = decomp[i][j];
- w[idx++] = Vector3(d.x, d.y, depth * 0.5);
- w[idx++] = Vector3(d.x, d.y, -depth * 0.5);
- }
+ //here comes the sun, lalalala
+ //decompose concave into multiple convex polygons and add them
+
+ for (int i = 0; i < decomp.size(); i++) {
+ Ref<ConvexPolygonShape> convex = memnew(ConvexPolygonShape);
+ PoolVector<Vector3> cp;
+ int cs = decomp[i].size();
+ cp.resize(cs * 2);
+ {
+ PoolVector<Vector3>::Write w = cp.write();
+ int idx = 0;
+ for (int j = 0; j < cs; j++) {
+
+ Vector2 d = decomp[i][j];
+ w[idx++] = Vector3(d.x, d.y, depth * 0.5);
+ w[idx++] = Vector3(d.x, d.y, -depth * 0.5);
}
-
- convex->set_points(cp);
- co->add_shape(convex, get_transform());
- }
- shape_to = co->get_shape_count() - 1;
- if (shape_to < shape_from) {
- shape_from = -1;
- shape_to = -1;
- }
-
- } else {
-#if 0
- Ref<ConcavePolygonShape> concave = memnew( ConcavePolygonShape );
-
- PoolVector<Vector2> segments;
- segments.resize(polygon.size()*2);
- PoolVector<Vector2>::Write w=segments.write();
-
- for(int i=0;i<polygon.size();i++) {
- w[(i<<1)+0]=polygon[i];
- w[(i<<1)+1]=polygon[(i+1)%polygon.size()];
}
- w=PoolVector<Vector2>::Write();
- concave->set_segments(segments);
-
- co->add_shape(concave,get_transform());
-#endif
+ convex->set_points(cp);
+ parent->shape_owner_add_shape(owner_id, convex);
+ parent->shape_owner_set_disabled(owner_id, disabled);
}
-
- //co->add_shape(shape,get_transform());
-}
-
-void CollisionPolygon::_update_parent() {
-
- if (!can_update_body)
- return;
-
- Node *parent = get_parent();
- if (!parent)
- return;
- CollisionObject *co = parent->cast_to<CollisionObject>();
- if (!co)
- return;
- co->_update_shapes_from_children();
-}
-
-void CollisionPolygon::_set_shape_range(const Vector2 &p_range) {
-
- shape_from = p_range.x;
- shape_to = p_range.y;
-}
-
-Vector2 CollisionPolygon::_get_shape_range() const {
-
- return Vector2(shape_from, shape_to);
}
void CollisionPolygon::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_ENTER_TREE: {
- can_update_body = get_tree()->is_editor_hint();
- set_notify_local_transform(!can_update_body);
- //indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
- } break;
- case NOTIFICATION_EXIT_TREE: {
- can_update_body = false;
- set_notify_local_transform(false);
- } break;
- case NOTIFICATION_TRANSFORM_CHANGED: {
-
- if (!is_inside_tree())
- break;
- if (can_update_body) {
- _update_parent();
+ case NOTIFICATION_PARENTED: {
+ parent = get_parent()->cast_to<CollisionObject>();
+ if (parent) {
+ owner_id = parent->create_shape_owner(this);
+ _build_polygon();
+ parent->shape_owner_set_transform(owner_id, get_transform());
+ parent->shape_owner_set_disabled(owner_id, disabled);
}
-
} break;
case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
- if (!can_update_body && shape_from >= 0 && shape_to >= 0) {
-
- CollisionObject *co = get_parent()->cast_to<CollisionObject>();
- if (co) {
- for (int i = shape_from; i <= shape_to; i++) {
- co->set_shape_transform(i, get_transform());
- }
- }
- }
- } break;
-#if 0
- case NOTIFICATION_DRAW: {
- for(int i=0;i<polygon.size();i++) {
-
- Vector2 p = polygon[i];
- Vector2 n = polygon[(i+1)%polygon.size()];
- draw_line(p,n,Color(0,0.6,0.7,0.5),3);
+ if (parent) {
+ parent->shape_owner_set_transform(owner_id, get_transform());
}
- Vector< Vector<Vector2> > decomp = Geometry::decompose_polygon(polygon);
-#define DEBUG_DECOMPOSE
-#ifdef DEBUG_DECOMPOSE
- Color c(0.4,0.9,0.1);
- for(int i=0;i<decomp.size();i++) {
-
- c.set_hsv( Math::fmod(c.get_h() + 0.738,1),c.get_s(),c.get_v(),0.5);
- draw_colored_polygon(decomp[i],c);
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ if (parent) {
+ parent->remove_shape_owner(owner_id);
}
-#endif
-
+ owner_id = 0;
+ parent = NULL;
} break;
-#endif
}
}
void CollisionPolygon::set_polygon(const Vector<Point2> &p_polygon) {
polygon = p_polygon;
- if (can_update_body) {
-
- for (int i = 0; i < polygon.size(); i++) {
-
- Vector3 p1(polygon[i].x, polygon[i].y, depth * 0.5);
-
- if (i == 0)
- aabb = Rect3(p1, Vector3());
- else
- aabb.expand_to(p1);
-
- Vector3 p2(polygon[i].x, polygon[i].y, -depth * 0.5);
- aabb.expand_to(p2);
- }
- if (aabb == Rect3()) {
-
- aabb = Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- } else {
- aabb.position -= aabb.size * 0.3;
- aabb.size += aabb.size * 0.6;
- }
- _update_parent();
+ if (parent) {
+ _build_polygon();
}
+ update_configuration_warning();
update_gizmo();
}
@@ -221,20 +117,6 @@ Vector<Point2> CollisionPolygon::get_polygon() const {
return polygon;
}
-void CollisionPolygon::set_build_mode(BuildMode p_mode) {
-
- ERR_FAIL_INDEX(p_mode, 2);
- build_mode = p_mode;
- if (!can_update_body)
- return;
- _update_parent();
-}
-
-CollisionPolygon::BuildMode CollisionPolygon::get_build_mode() const {
-
- return build_mode;
-}
-
Rect3 CollisionPolygon::get_item_rect() const {
return aabb;
@@ -243,9 +125,7 @@ Rect3 CollisionPolygon::get_item_rect() const {
void CollisionPolygon::set_depth(float p_depth) {
depth = p_depth;
- if (!can_update_body)
- return;
- _update_parent();
+ _build_polygon();
update_gizmo();
}
@@ -254,6 +134,17 @@ float CollisionPolygon::get_depth() const {
return depth;
}
+void CollisionPolygon::set_disabled(bool p_disabled) {
+ disabled = p_disabled;
+ if (parent) {
+ parent->shape_owner_set_disabled(owner_id, p_disabled);
+ }
+}
+
+bool CollisionPolygon::is_disabled() const {
+ return disabled;
+}
+
String CollisionPolygon::get_configuration_warning() const {
if (!get_parent()->cast_to<CollisionObject>()) {
@@ -269,36 +160,26 @@ String CollisionPolygon::get_configuration_warning() const {
void CollisionPolygon::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_add_to_collision_object"), &CollisionPolygon::_add_to_collision_object);
-
- ClassDB::bind_method(D_METHOD("set_build_mode", "build_mode"), &CollisionPolygon::set_build_mode);
- ClassDB::bind_method(D_METHOD("get_build_mode"), &CollisionPolygon::get_build_mode);
-
ClassDB::bind_method(D_METHOD("set_depth", "depth"), &CollisionPolygon::set_depth);
ClassDB::bind_method(D_METHOD("get_depth"), &CollisionPolygon::get_depth);
ClassDB::bind_method(D_METHOD("set_polygon", "polygon"), &CollisionPolygon::set_polygon);
ClassDB::bind_method(D_METHOD("get_polygon"), &CollisionPolygon::get_polygon);
- ClassDB::bind_method(D_METHOD("_set_shape_range", "shape_range"), &CollisionPolygon::_set_shape_range);
- ClassDB::bind_method(D_METHOD("_get_shape_range"), &CollisionPolygon::_get_shape_range);
-
- ClassDB::bind_method(D_METHOD("get_collision_object_first_shape"), &CollisionPolygon::get_collision_object_first_shape);
- ClassDB::bind_method(D_METHOD("get_collision_object_last_shape"), &CollisionPolygon::get_collision_object_last_shape);
+ ClassDB::bind_method(D_METHOD("set_disabled", "disabled"), &CollisionPolygon::set_disabled);
+ ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionPolygon::is_disabled);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "build_mode", PROPERTY_HINT_ENUM, "Solids,Triangles"), "set_build_mode", "get_build_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth"), "set_depth", "get_depth");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "polygon"), "set_polygon", "get_polygon");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shape_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_shape_range", "_get_shape_range");
}
CollisionPolygon::CollisionPolygon() {
- shape_from = -1;
- shape_to = -1;
- can_update_body = false;
-
aabb = Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
- build_mode = BUILD_SOLIDS;
depth = 1.0;
+ set_notify_local_transform(true);
+ parent = NULL;
+ owner_id = 0;
+ disabled = false;
}
diff --git a/scene/3d/collision_polygon.h b/scene/3d/collision_polygon.h
index d45b4738ae..beefae182c 100644
--- a/scene/3d/collision_polygon.h
+++ b/scene/3d/collision_polygon.h
@@ -33,55 +33,42 @@
#include "scene/3d/spatial.h"
#include "scene/resources/shape.h"
+class CollisionObject;
class CollisionPolygon : public Spatial {
GDCLASS(CollisionPolygon, Spatial);
-public:
- enum BuildMode {
- BUILD_SOLIDS,
- BUILD_TRIANGLES,
- };
-
protected:
float depth;
Rect3 aabb;
- BuildMode build_mode;
Vector<Point2> polygon;
- void _add_to_collision_object(Object *p_obj);
- void _update_parent();
+ uint32_t owner_id;
+ CollisionObject *parent;
- bool can_update_body;
- int shape_from;
- int shape_to;
+ bool disabled;
- void _set_shape_range(const Vector2 &p_range);
- Vector2 _get_shape_range() const;
+ void _build_polygon();
protected:
void _notification(int p_what);
static void _bind_methods();
public:
- void set_build_mode(BuildMode p_mode);
- BuildMode get_build_mode() const;
-
void set_depth(float p_depth);
float get_depth() const;
void set_polygon(const Vector<Point2> &p_polygon);
Vector<Point2> get_polygon() const;
- virtual Rect3 get_item_rect() const;
+ void set_disabled(bool p_disabled);
+ bool is_disabled() const;
- int get_collision_object_first_shape() const { return shape_from; }
- int get_collision_object_last_shape() const { return shape_to; }
+ virtual Rect3 get_item_rect() const;
String get_configuration_warning() const;
CollisionPolygon();
};
-VARIANT_ENUM_CAST(CollisionPolygon::BuildMode);
#endif // COLLISION_POLYGON_H
diff --git a/scene/3d/collision_shape.cpp b/scene/3d/collision_shape.cpp
new file mode 100644
index 0000000000..4fd215bd1a
--- /dev/null
+++ b/scene/3d/collision_shape.cpp
@@ -0,0 +1,214 @@
+/*************************************************************************/
+/* body_shape.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 "collision_shape.h"
+#include "scene/resources/box_shape.h"
+#include "scene/resources/capsule_shape.h"
+#include "scene/resources/concave_polygon_shape.h"
+#include "scene/resources/convex_polygon_shape.h"
+#include "scene/resources/plane_shape.h"
+#include "scene/resources/ray_shape.h"
+#include "scene/resources/sphere_shape.h"
+#include "servers/visual_server.h"
+//TODO: Implement CylinderShape and HeightMapShape?
+#include "mesh_instance.h"
+#include "physics_body.h"
+#include "quick_hull.h"
+
+void CollisionShape::make_convex_from_brothers() {
+
+ Node *p = get_parent();
+ if (!p)
+ return;
+
+ for (int i = 0; i < p->get_child_count(); i++) {
+
+ Node *n = p->get_child(i);
+ if (n->cast_to<MeshInstance>()) {
+
+ MeshInstance *mi = n->cast_to<MeshInstance>();
+ Ref<Mesh> m = mi->get_mesh();
+ if (m.is_valid()) {
+
+ Ref<Shape> s = m->create_convex_shape();
+ set_shape(s);
+ }
+ }
+ }
+}
+
+void CollisionShape::_notification(int p_what) {
+
+ switch (p_what) {
+
+ case NOTIFICATION_PARENTED: {
+ parent = get_parent()->cast_to<CollisionObject>();
+ if (parent) {
+ owner_id = parent->create_shape_owner(this);
+ if (shape.is_valid()) {
+ parent->shape_owner_add_shape(owner_id, shape);
+ }
+ parent->shape_owner_set_transform(owner_id, get_transform());
+ parent->shape_owner_set_disabled(owner_id, disabled);
+ }
+ } break;
+ case NOTIFICATION_ENTER_TREE: {
+ if (get_tree()->is_debugging_collisions_hint()) {
+ _create_debug_shape();
+ }
+
+ } break;
+ case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: {
+ if (parent) {
+ parent->shape_owner_set_transform(owner_id, get_transform());
+ }
+ } break;
+ case NOTIFICATION_EXIT_TREE: {
+ if (parent) {
+ parent->remove_shape_owner(owner_id);
+ }
+ owner_id = 0;
+ parent = NULL;
+ } break;
+ case NOTIFICATION_UNPARENTED: {
+ if (parent) {
+ parent->remove_shape_owner(owner_id);
+ }
+ owner_id = 0;
+ parent = NULL;
+ } break;
+ }
+}
+
+void CollisionShape::resource_changed(RES res) {
+
+ update_gizmo();
+}
+
+String CollisionShape::get_configuration_warning() const {
+
+ if (!get_parent()->cast_to<CollisionObject>()) {
+ return TTR("CollisionShape only serves to provide a collision shape to a CollisionObject derived node. Please only use it as a child of Area, StaticBody, RigidBody, KinematicBody, etc. to give them a shape.");
+ }
+
+ if (!shape.is_valid()) {
+ return TTR("A shape must be provided for CollisionShape to function. Please create a shape resource for it!");
+ }
+
+ return String();
+}
+
+void CollisionShape::_bind_methods() {
+
+ //not sure if this should do anything
+ ClassDB::bind_method(D_METHOD("resource_changed", "resource"), &CollisionShape::resource_changed);
+ ClassDB::bind_method(D_METHOD("set_shape", "shape"), &CollisionShape::set_shape);
+ ClassDB::bind_method(D_METHOD("get_shape"), &CollisionShape::get_shape);
+ ClassDB::bind_method(D_METHOD("set_disabled", "enable"), &CollisionShape::set_disabled);
+ ClassDB::bind_method(D_METHOD("is_disabled"), &CollisionShape::is_disabled);
+ ClassDB::bind_method(D_METHOD("make_convex_from_brothers"), &CollisionShape::make_convex_from_brothers);
+ ClassDB::set_method_flags("CollisionShape", "make_convex_from_brothers", METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shape", PROPERTY_HINT_RESOURCE_TYPE, "Shape"), "set_shape", "get_shape");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disabled"), "set_disabled", "is_disabled");
+}
+
+void CollisionShape::set_shape(const Ref<Shape> &p_shape) {
+
+ if (!shape.is_null())
+ shape->unregister_owner(this);
+ shape = p_shape;
+ if (!shape.is_null())
+ shape->register_owner(this);
+ update_gizmo();
+ if (parent) {
+ parent->shape_owner_clear_shapes(owner_id);
+ if (shape.is_valid()) {
+ parent->shape_owner_add_shape(owner_id, shape);
+ }
+ }
+
+ update_configuration_warning();
+}
+
+Ref<Shape> CollisionShape::get_shape() const {
+
+ return shape;
+}
+
+void CollisionShape::set_disabled(bool p_disabled) {
+
+ disabled = p_disabled;
+ update_gizmo();
+ if (parent) {
+ parent->shape_owner_set_disabled(owner_id, p_disabled);
+ }
+}
+
+bool CollisionShape::is_disabled() const {
+
+ return disabled;
+}
+
+CollisionShape::CollisionShape() {
+
+ //indicator = VisualServer::get_singleton()->mesh_create();
+ disabled = false;
+ debug_shape = NULL;
+ parent = NULL;
+ owner_id = 0;
+ set_notify_local_transform(true);
+}
+
+CollisionShape::~CollisionShape() {
+ if (!shape.is_null())
+ shape->unregister_owner(this);
+ //VisualServer::get_singleton()->free(indicator);
+}
+
+void CollisionShape::_create_debug_shape() {
+
+ if (debug_shape) {
+ debug_shape->queue_delete();
+ debug_shape = NULL;
+ }
+
+ Ref<Shape> s = get_shape();
+
+ if (s.is_null())
+ return;
+
+ Ref<Mesh> mesh = s->get_debug_mesh();
+
+ MeshInstance *mi = memnew(MeshInstance);
+ mi->set_mesh(mesh);
+
+ add_child(mi);
+ debug_shape = mi;
+}
diff --git a/scene/3d/body_shape.h b/scene/3d/collision_shape.h
index f4392dda62..277e0dfa77 100644
--- a/scene/3d/body_shape.h
+++ b/scene/3d/collision_shape.h
@@ -32,7 +32,7 @@
#include "scene/3d/spatial.h"
#include "scene/resources/shape.h"
-
+class CollisionObject;
class CollisionShape : public Spatial {
GDCLASS(CollisionShape, Spatial);
@@ -40,34 +40,13 @@ class CollisionShape : public Spatial {
Ref<Shape> shape;
- /*
- RID _get_visual_instance_rid() const;
-
-
- void _update_indicator();
-
- RID material;
- RID indicator;
- RID indicator_instance;
- */
+ uint32_t owner_id;
+ CollisionObject *parent;
Node *debug_shape;
void resource_changed(RES res);
-
- bool updating_body;
- bool unparenting;
- bool trigger;
-
- bool can_update_body;
-
- int update_shape_index;
-
- void _update_body();
- void _add_to_collision_object(Object *p_cshape);
-
- void _set_update_shape_index(int p_index);
- int _get_update_shape_index() const;
+ bool disabled;
void _create_debug_shape();
@@ -81,13 +60,8 @@ public:
void set_shape(const Ref<Shape> &p_shape);
Ref<Shape> get_shape() const;
- void set_updating_body(bool p_update);
- bool is_updating_body() const;
-
- void set_trigger(bool p_trigger);
- bool is_trigger() const;
-
- int get_collision_object_shape_index() const { return _get_update_shape_index(); }
+ void set_disabled(bool p_disabled);
+ bool is_disabled() const;
String get_configuration_warning() const;
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index adca1492c3..581dfb32c8 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -95,6 +95,16 @@ float GIProbeData::get_bias() const {
return VS::get_singleton()->gi_probe_get_bias(probe);
}
+void GIProbeData::set_normal_bias(float p_range) {
+
+ VS::get_singleton()->gi_probe_set_normal_bias(probe, p_range);
+}
+
+float GIProbeData::get_normal_bias() const {
+
+ return VS::get_singleton()->gi_probe_get_normal_bias(probe);
+}
+
void GIProbeData::set_propagation(float p_range) {
VS::get_singleton()->gi_probe_set_propagation(probe, p_range);
@@ -158,6 +168,9 @@ void GIProbeData::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bias", "bias"), &GIProbeData::set_bias);
ClassDB::bind_method(D_METHOD("get_bias"), &GIProbeData::get_bias);
+ ClassDB::bind_method(D_METHOD("set_normal_bias", "bias"), &GIProbeData::set_normal_bias);
+ ClassDB::bind_method(D_METHOD("get_normal_bias"), &GIProbeData::get_normal_bias);
+
ClassDB::bind_method(D_METHOD("set_propagation", "propagation"), &GIProbeData::set_propagation);
ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbeData::get_propagation);
@@ -175,6 +188,7 @@ void GIProbeData::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "dynamic_range", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_dynamic_range", "get_dynamic_range");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_energy", "get_energy");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_bias", "get_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_normal_bias", "get_normal_bias");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_propagation", "get_propagation");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_interior", "is_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_compress", "is_compressed");
@@ -265,6 +279,18 @@ float GIProbe::get_bias() const {
return bias;
}
+void GIProbe::set_normal_bias(float p_normal_bias) {
+
+ normal_bias = p_normal_bias;
+ if (probe_data.is_valid()) {
+ probe_data->set_normal_bias(normal_bias);
+ }
+}
+float GIProbe::get_normal_bias() const {
+
+ return normal_bias;
+}
+
void GIProbe::set_propagation(float p_propagation) {
propagation = p_propagation;
@@ -1261,6 +1287,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
probe_data->set_dynamic_range(dynamic_range);
probe_data->set_energy(energy);
probe_data->set_bias(bias);
+ probe_data->set_normal_bias(normal_bias);
probe_data->set_propagation(propagation);
probe_data->set_interior(interior);
probe_data->set_compress(compress);
@@ -1434,6 +1461,9 @@ void GIProbe::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bias", "max"), &GIProbe::set_bias);
ClassDB::bind_method(D_METHOD("get_bias"), &GIProbe::get_bias);
+ ClassDB::bind_method(D_METHOD("set_normal_bias", "max"), &GIProbe::set_normal_bias);
+ ClassDB::bind_method(D_METHOD("get_normal_bias"), &GIProbe::get_normal_bias);
+
ClassDB::bind_method(D_METHOD("set_propagation", "max"), &GIProbe::set_propagation);
ClassDB::bind_method(D_METHOD("get_propagation"), &GIProbe::get_propagation);
@@ -1453,6 +1483,7 @@ void GIProbe::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_energy", "get_energy");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "propagation", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_propagation", "get_propagation");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_bias", "get_bias");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "normal_bias", PROPERTY_HINT_RANGE, "0,4,0.001"), "set_normal_bias", "get_normal_bias");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "interior"), "set_interior", "is_interior");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "compress"), "set_compress", "is_compressed");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "data", PROPERTY_HINT_RESOURCE_TYPE, "GIProbeData"), "set_probe_data", "get_probe_data");
@@ -1468,7 +1499,8 @@ GIProbe::GIProbe() {
subdiv = SUBDIV_128;
dynamic_range = 4;
energy = 1.0;
- bias = 1.8;
+ bias = 0.0;
+ normal_bias = 0.8;
propagation = 1.0;
extents = Vector3(10, 10, 10);
color_scan_cell_width = 4;
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index b5ee86455e..3f5a50a560 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -67,6 +67,9 @@ public:
void set_bias(float p_range);
float get_bias() const;
+ void set_normal_bias(float p_range);
+ float get_normal_bias() const;
+
void set_interior(bool p_enable);
bool is_interior() const;
@@ -163,6 +166,7 @@ private:
int dynamic_range;
float energy;
float bias;
+ float normal_bias;
float propagation;
bool interior;
bool compress;
@@ -204,6 +208,9 @@ public:
void set_bias(float p_bias);
float get_bias() const;
+ void set_normal_bias(float p_normal_bias);
+ float get_normal_bias() const;
+
void set_propagation(float p_propagation);
float get_propagation() const;
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index 62e1a95209..558932ceb9 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "mesh_instance.h"
-#include "body_shape.h"
+#include "collision_shape.h"
#include "core_string_names.h"
#include "physics_body.h"
#include "scene/resources/material.h"
@@ -194,7 +194,9 @@ Node *MeshInstance::create_trimesh_collision_node() {
return NULL;
StaticBody *static_body = memnew(StaticBody);
- static_body->add_shape(shape);
+ CollisionShape *cshape = memnew(CollisionShape);
+ cshape->set_shape(shape);
+ static_body->add_child(cshape);
return static_body;
}
@@ -205,13 +207,11 @@ void MeshInstance::create_trimesh_collision() {
static_body->set_name(String(get_name()) + "_col");
add_child(static_body);
- if (get_owner())
+ if (get_owner()) {
+ CollisionShape *cshape = static_body->get_child(0)->cast_to<CollisionShape>();
static_body->set_owner(get_owner());
- CollisionShape *cshape = memnew(CollisionShape);
- cshape->set_shape(static_body->get_shape(0));
- static_body->add_child(cshape);
- if (get_owner())
cshape->set_owner(get_owner());
+ }
}
Node *MeshInstance::create_convex_collision_node() {
@@ -224,7 +224,9 @@ Node *MeshInstance::create_convex_collision_node() {
return NULL;
StaticBody *static_body = memnew(StaticBody);
- static_body->add_shape(shape);
+ CollisionShape *cshape = memnew(CollisionShape);
+ cshape->set_shape(shape);
+ static_body->add_child(cshape);
return static_body;
}
@@ -235,13 +237,11 @@ void MeshInstance::create_convex_collision() {
static_body->set_name(String(get_name()) + "_col");
add_child(static_body);
- if (get_owner())
+ if (get_owner()) {
+ CollisionShape *cshape = static_body->get_child(0)->cast_to<CollisionShape>();
static_body->set_owner(get_owner());
- CollisionShape *cshape = memnew(CollisionShape);
- cshape->set_shape(static_body->get_shape(0));
- static_body->add_child(cshape);
- if (get_owner())
cshape->set_owner(get_owner());
+ }
}
void MeshInstance::_notification(int p_what) {
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 718daab75a..7e599ce2f5 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -879,313 +879,105 @@ RigidBody::~RigidBody() {
//////////////////////////////////////////////////////
//////////////////////////
-Variant KinematicBody::_get_collider() const {
-
- ObjectID oid = get_collider();
- if (oid == 0)
- return Variant();
- Object *obj = ObjectDB::get_instance(oid);
- if (!obj)
- return Variant();
-
- Reference *ref = obj->cast_to<Reference>();
- if (ref) {
- return Ref<Reference>(ref);
- }
+Dictionary KinematicBody::_move(const Vector3 &p_motion) {
+
+ Collision col;
+ if (move(p_motion, col)) {
+ Dictionary d;
+ d["position"] = col.collision;
+ d["normal"] = col.collision;
+ d["local_shape"] = col.local_shape;
+ d["travel"] = col.travel;
+ d["remainder"] = col.remainder;
+ d["collider_id"] = col.collider;
+ if (col.collider) {
+ d["collider"] = ObjectDB::get_instance(col.collider);
+ } else {
+ d["collider"] = Variant();
+ }
- return obj;
-}
+ d["collider_shape_index"] = col.collider_shape;
+ d["collider_metadata"] = col.collider_metadata;
-bool KinematicBody::_ignores_mode(PhysicsServer::BodyMode p_mode) const {
+ return d;
- switch (p_mode) {
- case PhysicsServer::BODY_MODE_STATIC: return !collide_static;
- case PhysicsServer::BODY_MODE_KINEMATIC: return !collide_kinematic;
- case PhysicsServer::BODY_MODE_RIGID: return !collide_rigid;
- case PhysicsServer::BODY_MODE_CHARACTER: return !collide_character;
+ } else {
+ return Dictionary();
}
-
- return true;
}
-void KinematicBody::revert_motion() {
+bool KinematicBody::move(const Vector3 &p_motion, Collision &r_collision) {
Transform gt = get_global_transform();
- gt.origin -= travel; //I do hope this is correct.
- travel = Vector3();
- set_global_transform(gt);
-}
-
-Vector3 KinematicBody::get_travel() const {
-
- return travel;
-}
-
-Vector3 KinematicBody::move(const Vector3 &p_motion) {
-
- //give me back regular physics engine logic
- //this is madness
- //and most people using this function will think
- //what it does is simpler than using physics
- //this took about a week to get right..
- //but is it right? who knows at this point..
-
- colliding = false;
- ERR_FAIL_COND_V(!is_inside_tree(), Vector3());
- PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
- ERR_FAIL_COND_V(!dss, Vector3());
- const int max_shapes = 32;
- Vector3 sr[max_shapes * 2];
- int res_shapes;
-
- Set<RID> exclude;
- exclude.insert(get_rid());
-
- //recover first
- int recover_attempts = 4;
-
- bool collided = false;
- uint32_t mask = 0;
- if (collide_static)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (collide_kinematic)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (collide_rigid)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (collide_character)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-
- //print_line("motion: "+p_motion+" margin: "+rtos(margin));
-
- //print_line("margin: "+rtos(margin));
-
- float m = margin;
- //m=0.001;
-
- do {
-
- //motion recover
- for (int i = 0; i < get_shape_count(); i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), m, sr, max_shapes, res_shapes, exclude, get_collision_layer(), mask)) {
- collided = true;
- }
- }
-
- if (!collided)
- break;
-
- //print_line("have to recover");
- Vector3 recover_motion;
- bool all_outside = true;
- for (int j = 0; j < 8; j++) {
- for (int i = 0; i < res_shapes; i++) {
-
- Vector3 a = sr[i * 2 + 0];
- Vector3 b = sr[i * 2 + 1];
-//print_line(String()+a+" -> "+b);
-#if 0
- float d = a.distance_to(b);
-
- /*
- if (d<margin)
- continue;
- */
- recover_motion+=(b-a)*0.2;
-#else
- float dist = a.distance_to(b);
- if (dist > CMP_EPSILON) {
- Vector3 norm = (b - a).normalized();
- if (dist > margin * 0.5)
- all_outside = false;
- float adv = norm.dot(recover_motion);
- //print_line(itos(i)+" dist: "+rtos(dist)+" adv: "+rtos(adv));
- recover_motion += norm * MAX(dist - adv, 0) * 0.4;
- }
-#endif
- }
- }
-
- if (recover_motion == Vector3()) {
- collided = false;
- break;
- }
-
- //print_line("**** RECOVER: "+recover_motion);
-
- Transform gt = get_global_transform();
- gt.origin += recover_motion;
- set_global_transform(gt);
-
- recover_attempts--;
-
- if (all_outside)
- break;
-
- } while (recover_attempts);
-
- //move second
- float safe = 1.0;
- float unsafe = 1.0;
- int best_shape = -1;
-
- PhysicsDirectSpaceState::ShapeRestInfo rest;
-
- //print_line("pos: "+get_global_transform().origin);
- //print_line("motion: "+p_motion);
-
- for (int i = 0; i < get_shape_count(); i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- float lsafe, lunsafe;
- PhysicsDirectSpaceState::ShapeRestInfo lrest;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0, lsafe, lunsafe, exclude, get_collision_layer(), mask, &lrest);
- //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
- if (!valid) {
- safe = 0;
- unsafe = 0;
- best_shape = i; //sadly it's the best
- //print_line("initial stuck");
-
- break;
- }
- if (lsafe == 1.0) {
- //print_line("initial free");
- continue;
- }
- if (lsafe < safe) {
-
- //print_line("initial at "+rtos(lsafe));
- safe = lsafe;
- safe = MAX(0, lsafe - 0.01);
- unsafe = lunsafe;
- best_shape = i;
- rest = lrest;
- }
- }
-
- //print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
-
- if (safe >= 1) {
- //not collided
- colliding = false;
- } else {
-
- colliding = true;
-
- if (true || (safe == 0 && unsafe == 0)) { //use it always because it's more precise than GJK
- //no advance, use rest info from collision
- Transform ugt = get_global_transform();
- ugt.origin += p_motion * unsafe;
-
- PhysicsDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt * get_shape_transform(best_shape), m, &rest, exclude, get_collision_layer(), mask);
- if (!c2) {
- //should not happen, but floating point precision is so weird..
- colliding = false;
- }
-
- //print_line("Rest Travel: "+rest.normal);
- }
-
- if (colliding) {
-
- collision = rest.point;
- normal = rest.normal;
- collider = rest.collider_id;
- collider_vel = rest.linear_velocity;
- collider_shape = rest.shape;
- }
+ PhysicsServer::MotionResult result;
+ bool colliding = PhysicsServer::get_singleton()->body_test_motion(get_rid(), gt, p_motion, margin, &result);
+
+ if (colliding) {
+ r_collision.collider_metadata = result.collider_metadata;
+ r_collision.collider_shape = result.collider_shape;
+ r_collision.collider_vel = result.collider_velocity;
+ r_collision.collision = result.collision_point;
+ r_collision.normal = result.collision_normal;
+ r_collision.collider = result.collider_id;
+ r_collision.travel = result.motion;
+ r_collision.remainder = result.remainder;
+ r_collision.local_shape = result.collision_local_shape;
}
- Vector3 motion = p_motion * safe;
- /*
- if (colliding)
- motion+=normal*0.001;
- */
- Transform gt = get_global_transform();
- gt.origin += motion;
+ gt.origin += result.motion;
set_global_transform(gt);
- travel = motion;
- return p_motion - motion;
+ return colliding;
}
-Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, const Vector3 &p_ceil_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle, float p_ceil_max_angle) {
-
- /*
- Things to note:
- 1. This function is basically the KinematicBody2D function ported over.
- 2. The 'travel' variable and stuff relating to it exists more or less for this function's sake.
- 3. Someone is going to have to document this, so here's an example for them:
- vel = move_and_slide(vel, Vector3(0, 1, 0), Vector3(0, -1, 0), 0.1);
- Very useful for FPS controllers so long as you control horizontal motion properly - even for Quake-style AABB colliders.
- The slope stop system is... rather weird, and it's correct operation depends on what scale your game is built on,
- but as far as I can tell in theory it's suppposed to be a way of turning impassable slopes into invisible walls.
- It can also be a pain, since there's a better-known way of defining such things: "let gravity do the work".
- If you don't like it, set it to positive infinity.
- 4. Might be a bug somewhere else in physics: When there are two CollisionShape nodes with a shared Shape, only one is considered, I think.
- Test this further.
- */
+Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction, float p_slope_stop_min_velocity, int p_max_bounces, float p_floor_max_angle) {
- Vector3 motion = (move_and_slide_floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
+ Vector3 motion = (floor_velocity + p_linear_velocity) * get_fixed_process_delta_time();
Vector3 lv = p_linear_velocity;
- move_and_slide_on_floor = false;
- move_and_slide_on_ceiling = false;
- move_and_slide_on_wall = false;
- move_and_slide_colliders.clear();
- move_and_slide_floor_velocity = Vector3();
+ on_floor = false;
+ on_ceiling = false;
+ on_wall = false;
+ colliders.clear();
+ floor_velocity = Vector3();
while (p_max_bounces) {
- motion = move(motion);
+ Collision collision;
- if (is_colliding()) {
+ bool collided = move(motion, collision);
- bool hit_horizontal = false; //hit floor or ceiling
+ if (collided) {
- if (p_floor_direction != Vector3()) {
- if (get_collision_normal().dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
+ motion = collision.remainder;
- hit_horizontal = true;
- move_and_slide_on_floor = true;
- move_and_slide_floor_velocity = get_collider_velocity();
+ if (p_floor_direction == Vector3()) {
+ //all is a wall
+ on_wall = true;
+ } else {
+ if (collision.normal.dot(p_floor_direction) >= Math::cos(p_floor_max_angle)) { //floor
- //Note: These two lines are the only lines that really changed between 3D/2D, see if it can't be reused somehow???
- Vector2 hz_velocity = Vector2(lv.x - move_and_slide_floor_velocity.x, lv.z - move_and_slide_floor_velocity.z);
- if (get_travel().length() < 1 && hz_velocity.length() < p_slope_stop_min_velocity) {
- revert_motion();
- return Vector3();
- }
- }
- }
+ on_floor = true;
+ floor_velocity = collision.collider_vel;
- if (p_ceil_direction != Vector3()) {
- if (get_collision_normal().dot(p_ceil_direction) >= Math::cos(p_ceil_max_angle)) { //ceiling
- hit_horizontal = true;
- move_and_slide_on_ceiling = true;
+ /*if (collision.travel.length() < 0.01 && ABS((lv.x - floor_velocity.x)) < p_slope_stop_min_velocity) {
+ Transform gt = get_global_transform();
+ gt.elements[2] -= collision.travel;
+ set_global_transform(gt);
+ return Vector3();
+ }*/
+ } else if (collision.normal.dot(-p_floor_direction) >= Math::cos(p_floor_max_angle)) { //ceiling
+ on_ceiling = true;
+ } else {
+ on_wall = true;
}
}
- //if it hit something but didn't hit a floor or ceiling, it is by default a wall
- //(this imitates the pre-specifiable-ceiling logic more or less, except ceiling is optional)
- if (!hit_horizontal) {
- move_and_slide_on_wall = true;
- }
-
- Vector3 n = get_collision_normal();
+ Vector3 n = collision.normal;
motion = motion.slide(n);
lv = lv.slide(n);
- Variant collider = _get_collider();
- if (collider.get_type() != Variant::NIL) {
- move_and_slide_colliders.push_back(collider);
- }
+
+ colliders.push_back(collision);
} else {
break;
@@ -1199,199 +991,148 @@ Vector3 KinematicBody::move_and_slide(const Vector3 &p_linear_velocity, const Ve
return lv;
}
-bool KinematicBody::is_move_and_slide_on_floor() const {
-
- return move_and_slide_on_floor;
-}
-bool KinematicBody::is_move_and_slide_on_wall() const {
+bool KinematicBody::is_on_floor() const {
- return move_and_slide_on_wall;
+ return on_floor;
}
-bool KinematicBody::is_move_and_slide_on_ceiling() const {
+bool KinematicBody::is_on_wall() const {
- return move_and_slide_on_ceiling;
+ return on_wall;
}
-Array KinematicBody::get_move_and_slide_colliders() const {
+bool KinematicBody::is_on_ceiling() const {
- return move_and_slide_colliders;
+ return on_ceiling;
}
-Vector3 KinematicBody::move_to(const Vector3 &p_position) {
+Vector3 KinematicBody::get_floor_velocity() const {
- return move(p_position - get_global_transform().origin);
+ return floor_velocity;
}
-bool KinematicBody::can_teleport_to(const Vector3 &p_position) {
+bool KinematicBody::test_move(const Transform &p_from, const Vector3 &p_motion) {
ERR_FAIL_COND_V(!is_inside_tree(), false);
- PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(get_world()->get_space());
- ERR_FAIL_COND_V(!dss, false);
-
- uint32_t mask = 0;
- if (collide_static)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (collide_kinematic)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (collide_rigid)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (collide_character)
- mask |= PhysicsDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-
- Transform xform = get_global_transform();
- xform.origin = p_position;
-
- Set<RID> exclude;
- exclude.insert(get_rid());
-
- for (int i = 0; i < get_shape_count(); i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i), 0, NULL, 1, exclude, get_collision_layer(), mask);
- if (col)
- return false;
- }
- return true;
+ return PhysicsServer::get_singleton()->body_test_motion(get_rid(), p_from, p_motion, margin);
}
-bool KinematicBody::is_colliding() const {
+void KinematicBody::set_safe_margin(float p_margin) {
- ERR_FAIL_COND_V(!is_inside_tree(), false);
-
- return colliding;
+ margin = p_margin;
}
-Vector3 KinematicBody::get_collision_pos() const {
- ERR_FAIL_COND_V(!colliding, Vector3());
- return collision;
-}
-Vector3 KinematicBody::get_collision_normal() const {
+float KinematicBody::get_safe_margin() const {
- ERR_FAIL_COND_V(!colliding, Vector3());
- return normal;
+ return margin;
}
-Vector3 KinematicBody::get_collider_velocity() const {
+int KinematicBody::get_collision_count() const {
- return collider_vel;
+ return colliders.size();
}
+Vector3 KinematicBody::get_collision_position(int p_collision) const {
-ObjectID KinematicBody::get_collider() const {
-
- ERR_FAIL_COND_V(!colliding, 0);
- return collider;
-}
-int KinematicBody::get_collider_shape() const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
- ERR_FAIL_COND_V(!colliding, -1);
- return collider_shape;
+ return colliders[p_collision].collision;
}
-void KinematicBody::set_collide_with_static_bodies(bool p_enable) {
-
- collide_static = p_enable;
+Vector3 KinematicBody::get_collision_normal(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
+ return colliders[p_collision].normal;
}
-bool KinematicBody::can_collide_with_static_bodies() const {
- return collide_static;
+Vector3 KinematicBody::get_collision_travel(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
+ return colliders[p_collision].travel;
}
-
-void KinematicBody::set_collide_with_rigid_bodies(bool p_enable) {
-
- collide_rigid = p_enable;
+Vector3 KinematicBody::get_collision_remainder(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
+ return colliders[p_collision].remainder;
}
-bool KinematicBody::can_collide_with_rigid_bodies() const {
-
- return collide_rigid;
+Object *KinematicBody::get_collision_local_shape(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+ uint32_t owner = shape_find_owner(colliders[p_collision].local_shape);
+ return shape_owner_get_owner(owner);
}
+Object *KinematicBody::get_collision_collider(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
-void KinematicBody::set_collide_with_kinematic_bodies(bool p_enable) {
+ if (colliders[p_collision].collider) {
+ return ObjectDB::get_instance(colliders[p_collision].collider);
+ }
- collide_kinematic = p_enable;
+ return NULL;
}
-bool KinematicBody::can_collide_with_kinematic_bodies() const {
+ObjectID KinematicBody::get_collision_collider_id(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), 0);
- return collide_kinematic;
+ return colliders[p_collision].collider;
}
+Object *KinematicBody::get_collision_collider_shape(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), NULL);
+ Object *collider = get_collision_collider(p_collision);
+ if (collider) {
+ CollisionObject *obj2d = collider->cast_to<CollisionObject>();
+ if (obj2d) {
+ uint32_t owner = shape_find_owner(colliders[p_collision].collider_shape);
+ return obj2d->shape_owner_get_owner(owner);
+ }
+ }
-void KinematicBody::set_collide_with_character_bodies(bool p_enable) {
-
- collide_character = p_enable;
+ return NULL;
}
-bool KinematicBody::can_collide_with_character_bodies() const {
-
- return collide_character;
+int KinematicBody::get_collision_collider_shape_index(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), -1);
+ return colliders[p_collision].collider_shape;
}
-
-void KinematicBody::set_collision_margin(float p_margin) {
-
- margin = p_margin;
+Vector3 KinematicBody::get_collision_collider_velocity(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Vector3());
+ return colliders[p_collision].collider_vel;
}
-
-float KinematicBody::get_collision_margin() const {
-
- return margin;
+Variant KinematicBody::get_collision_collider_metadata(int p_collision) const {
+ ERR_FAIL_INDEX_V(p_collision, colliders.size(), Variant());
+ return colliders[p_collision].collider_metadata;
}
void KinematicBody::_bind_methods() {
- ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::move);
- ClassDB::bind_method(D_METHOD("move_to", "position"), &KinematicBody::move_to);
- ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "ceil_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle", "ceil_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(Vector3(0, 0, 0)), DEFVAL(5), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)), DEFVAL(Math::deg2rad((float)45)));
-
- ClassDB::bind_method(D_METHOD("can_teleport_to", "position"), &KinematicBody::can_teleport_to);
+ ClassDB::bind_method(D_METHOD("move", "rel_vec"), &KinematicBody::_move);
+ ClassDB::bind_method(D_METHOD("move_and_slide", "linear_velocity", "floor_normal", "slope_stop_min_velocity", "max_bounces", "floor_max_angle"), &KinematicBody::move_and_slide, DEFVAL(Vector3(0, 0, 0)), DEFVAL(0.05), DEFVAL(4), DEFVAL(Math::deg2rad((float)45)));
- ClassDB::bind_method(D_METHOD("is_colliding"), &KinematicBody::is_colliding);
+ ClassDB::bind_method(D_METHOD("test_move", "from", "rel_vec"), &KinematicBody::test_move);
- ClassDB::bind_method(D_METHOD("get_collision_pos"), &KinematicBody::get_collision_pos);
- ClassDB::bind_method(D_METHOD("get_collision_normal"), &KinematicBody::get_collision_normal);
- ClassDB::bind_method(D_METHOD("get_collider_velocity"), &KinematicBody::get_collider_velocity);
- ClassDB::bind_method(D_METHOD("get_collider:Variant"), &KinematicBody::_get_collider);
- ClassDB::bind_method(D_METHOD("get_collider_shape"), &KinematicBody::get_collider_shape);
+ ClassDB::bind_method(D_METHOD("is_on_floor"), &KinematicBody::is_on_floor);
+ ClassDB::bind_method(D_METHOD("is_on_ceiling"), &KinematicBody::is_on_ceiling);
+ ClassDB::bind_method(D_METHOD("is_on_wall"), &KinematicBody::is_on_wall);
+ ClassDB::bind_method(D_METHOD("get_floor_velocity"), &KinematicBody::get_floor_velocity);
- ClassDB::bind_method(D_METHOD("set_collide_with_static_bodies", "enable"), &KinematicBody::set_collide_with_static_bodies);
- ClassDB::bind_method(D_METHOD("can_collide_with_static_bodies"), &KinematicBody::can_collide_with_static_bodies);
+ ClassDB::bind_method(D_METHOD("set_safe_margin", "pixels"), &KinematicBody::set_safe_margin);
+ ClassDB::bind_method(D_METHOD("get_safe_margin", "pixels"), &KinematicBody::get_safe_margin);
- ClassDB::bind_method(D_METHOD("set_collide_with_kinematic_bodies", "enable"), &KinematicBody::set_collide_with_kinematic_bodies);
- ClassDB::bind_method(D_METHOD("can_collide_with_kinematic_bodies"), &KinematicBody::can_collide_with_kinematic_bodies);
+ ClassDB::bind_method(D_METHOD("get_collision_count"), &KinematicBody::get_collision_count);
+ ClassDB::bind_method(D_METHOD("get_collision_position", "collision"), &KinematicBody::get_collision_position);
+ ClassDB::bind_method(D_METHOD("get_collision_normal", "collision"), &KinematicBody::get_collision_normal);
+ ClassDB::bind_method(D_METHOD("get_collision_travel", "collision"), &KinematicBody::get_collision_travel);
+ ClassDB::bind_method(D_METHOD("get_collision_remainder", "collision"), &KinematicBody::get_collision_remainder);
+ ClassDB::bind_method(D_METHOD("get_collision_local_shape", "collision"), &KinematicBody::get_collision_local_shape);
+ ClassDB::bind_method(D_METHOD("get_collision_collider", "collision"), &KinematicBody::get_collision_collider);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_id", "collision"), &KinematicBody::get_collision_collider_id);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_shape", "collision"), &KinematicBody::get_collision_collider_shape);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_shape_index", "collision"), &KinematicBody::get_collision_collider_shape_index);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_velocity", "collision"), &KinematicBody::get_collision_collider_velocity);
+ ClassDB::bind_method(D_METHOD("get_collision_collider_metadata", "collision"), &KinematicBody::get_collision_collider_metadata);
- ClassDB::bind_method(D_METHOD("set_collide_with_rigid_bodies", "enable"), &KinematicBody::set_collide_with_rigid_bodies);
- ClassDB::bind_method(D_METHOD("can_collide_with_rigid_bodies"), &KinematicBody::can_collide_with_rigid_bodies);
-
- ClassDB::bind_method(D_METHOD("set_collide_with_character_bodies", "enable"), &KinematicBody::set_collide_with_character_bodies);
- ClassDB::bind_method(D_METHOD("can_collide_with_character_bodies"), &KinematicBody::can_collide_with_character_bodies);
-
- ClassDB::bind_method(D_METHOD("set_collision_margin", "pixels"), &KinematicBody::set_collision_margin);
- ClassDB::bind_method(D_METHOD("get_collision_margin", "pixels"), &KinematicBody::get_collision_margin);
-
- ClassDB::bind_method(D_METHOD("get_travel"), &KinematicBody::get_travel);
- ClassDB::bind_method(D_METHOD("revert_motion"), &KinematicBody::revert_motion);
-
- ClassDB::bind_method(D_METHOD("get_move_and_slide_colliders"), &KinematicBody::get_move_and_slide_colliders);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_floor"), &KinematicBody::is_move_and_slide_on_floor);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_ceiling"), &KinematicBody::is_move_and_slide_on_ceiling);
- ClassDB::bind_method(D_METHOD("is_move_and_slide_on_wall"), &KinematicBody::is_move_and_slide_on_wall);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with/static"), "set_collide_with_static_bodies", "can_collide_with_static_bodies");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with/kinematic"), "set_collide_with_kinematic_bodies", "can_collide_with_kinematic_bodies");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with/rigid"), "set_collide_with_rigid_bodies", "can_collide_with_rigid_bodies");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collide_with/character"), "set_collide_with_character_bodies", "can_collide_with_character_bodies");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_collision_margin", "get_collision_margin");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision/safe_margin", PROPERTY_HINT_RANGE, "0.001,256,0.001"), "set_safe_margin", "get_safe_margin");
}
KinematicBody::KinematicBody()
: PhysicsBody(PhysicsServer::BODY_MODE_KINEMATIC) {
- collide_static = true;
- collide_rigid = true;
- collide_kinematic = true;
- collide_character = true;
-
- colliding = false;
- collider = 0;
margin = 0.001;
- collider_shape = 0;
+
+ on_floor = false;
+ on_ceiling = false;
+ on_wall = false;
}
KinematicBody::~KinematicBody() {
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index db4147f8f6..f86d7d957f 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -263,75 +263,60 @@ class KinematicBody : public PhysicsBody {
GDCLASS(KinematicBody, PhysicsBody);
- float margin;
- bool collide_static;
- bool collide_rigid;
- bool collide_kinematic;
- bool collide_character;
-
- bool colliding;
- Vector3 collision;
- Vector3 normal;
- Vector3 collider_vel;
- ObjectID collider;
- int collider_shape;
- Vector3 travel;
-
- Vector3 move_and_slide_floor_velocity;
- bool move_and_slide_on_floor;
- bool move_and_slide_on_ceiling;
- bool move_and_slide_on_wall;
- Array move_and_slide_colliders;
-
- Variant _get_collider() const;
-
- _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
-
-protected:
- static void _bind_methods();
-
public:
- enum {
- SLIDE_FLAG_FLOOR,
- SLIDE_FLAG_WALL,
- SLIDE_FLAG_ROOF
+ struct Collision {
+ Vector3 collision;
+ Vector3 normal;
+ Vector3 collider_vel;
+ ObjectID collider;
+ int collider_shape;
+ Variant collider_metadata;
+ Vector3 remainder;
+ Vector3 travel;
+ int local_shape;
};
- Vector3 move(const Vector3 &p_motion);
- Vector3 move_to(const Vector3 &p_position);
-
- bool can_teleport_to(const Vector3 &p_position);
- bool is_colliding() const;
-
- Vector3 get_travel() const; // Set by move and others. Consider unreliable except immediately after a move call.
- void revert_motion();
-
- Vector3 get_collision_pos() const;
- Vector3 get_collision_normal() const;
- Vector3 get_collider_velocity() const;
- ObjectID get_collider() const;
- int get_collider_shape() const;
-
- void set_collide_with_static_bodies(bool p_enable);
- bool can_collide_with_static_bodies() const;
+private:
+ float margin;
- void set_collide_with_rigid_bodies(bool p_enable);
- bool can_collide_with_rigid_bodies() const;
+ Vector3 floor_velocity;
+ bool on_floor;
+ bool on_ceiling;
+ bool on_wall;
+ Vector<Collision> colliders;
- void set_collide_with_kinematic_bodies(bool p_enable);
- bool can_collide_with_kinematic_bodies() const;
+ _FORCE_INLINE_ bool _ignores_mode(PhysicsServer::BodyMode) const;
- void set_collide_with_character_bodies(bool p_enable);
- bool can_collide_with_character_bodies() const;
+ Dictionary _move(const Vector3 &p_motion);
- void set_collision_margin(float p_margin);
- float get_collision_margin() const;
+protected:
+ static void _bind_methods();
- Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), const Vector3 &p_ceil_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 5, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45), float p_ceil_max_angle = Math::deg2rad((float)45));
- bool is_move_and_slide_on_floor() const;
- bool is_move_and_slide_on_wall() const;
- bool is_move_and_slide_on_ceiling() const;
- Array get_move_and_slide_colliders() const;
+public:
+ bool move(const Vector3 &p_motion, Collision &r_collision);
+ bool test_move(const Transform &p_from, const Vector3 &p_motion);
+
+ void set_safe_margin(float p_margin);
+ float get_safe_margin() const;
+
+ Vector3 move_and_slide(const Vector3 &p_linear_velocity, const Vector3 &p_floor_direction = Vector3(0, 0, 0), float p_slope_stop_min_velocity = 0.05, int p_max_bounces = 4, float p_floor_max_angle = Math::deg2rad((float)45));
+ bool is_on_floor() const;
+ bool is_on_wall() const;
+ bool is_on_ceiling() const;
+ Vector3 get_floor_velocity() const;
+
+ int get_collision_count() const;
+ Vector3 get_collision_position(int p_collision) const;
+ Vector3 get_collision_normal(int p_collision) const;
+ Vector3 get_collision_travel(int p_collision) const;
+ Vector3 get_collision_remainder(int p_collision) const;
+ Object *get_collision_local_shape(int p_collision) const;
+ Object *get_collision_collider(int p_collision) const;
+ ObjectID get_collision_collider_id(int p_collision) const;
+ Object *get_collision_collider_shape(int p_collision) const;
+ int get_collision_collider_shape_index(int p_collision) const;
+ Vector3 get_collision_collider_velocity(int p_collision) const;
+ Variant get_collision_collider_metadata(int p_collision) const;
KinematicBody();
~KinematicBody();
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 86a62bec97..0dc5b58e45 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -162,7 +162,7 @@ bool ReflectionProbe::are_shadows_enabled() const {
void ReflectionProbe::set_cull_mask(uint32_t p_layers) {
cull_mask = p_layers;
- VS::get_singleton()->reflection_probe_set_enable_shadows(probe, p_layers);
+ VS::get_singleton()->reflection_probe_set_cull_mask(probe, p_layers);
}
uint32_t ReflectionProbe::get_cull_mask() const {
diff --git a/scene/3d/spatial_velocity_tracker.cpp b/scene/3d/spatial_velocity_tracker.cpp
new file mode 100644
index 0000000000..dc822d0446
--- /dev/null
+++ b/scene/3d/spatial_velocity_tracker.cpp
@@ -0,0 +1,104 @@
+#include "spatial_velocity_tracker.h"
+#include "engine.h"
+
+void SpatialVelocityTracker::set_track_fixed_step(bool p_track_fixed_step) {
+
+ fixed_step = p_track_fixed_step;
+}
+
+bool SpatialVelocityTracker::is_tracking_fixed_step() const {
+
+ return fixed_step;
+}
+void SpatialVelocityTracker::update_position(const Vector3 &p_position) {
+
+ PositionHistory ph;
+ ph.position = p_position;
+ if (fixed_step) {
+ ph.frame = Engine::get_singleton()->get_fixed_frames();
+ } else {
+ ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ }
+
+ if (position_history_len == 0 || position_history[0].frame != ph.frame) { //in same frame, use latest
+ position_history_len = MIN(position_history.size(), position_history_len + 1);
+ for (int i = position_history_len - 1; i > 0; i--) {
+ position_history[i] = position_history[i - 1];
+ }
+ }
+
+ position_history[0] = ph;
+}
+Vector3 SpatialVelocityTracker::get_tracked_linear_velocity() const {
+
+ Vector3 linear_velocity;
+
+ float max_time = 1 / 5.0; //maximum time to interpolate a velocity
+
+ Vector3 distance_accum;
+ float time_accum = 0.0;
+ float base_time = 0.0;
+
+ if (position_history_len) {
+ if (fixed_step) {
+ uint64_t base = Engine::get_singleton()->get_fixed_frames();
+ base_time = float(base - position_history[0].frame) / Engine::get_singleton()->get_iterations_per_second();
+ } else {
+ uint64_t base = Engine::get_singleton()->get_idle_frame_ticks();
+ base_time = double(base - position_history[0].frame) / 1000000.0;
+ }
+ }
+
+ for (int i = 0; i < position_history_len - 1; i++) {
+ float delta = 0.0;
+ uint64_t diff = position_history[i].frame - position_history[i + 1].frame;
+ Vector3 distance = position_history[i].position - position_history[i + 1].position;
+
+ if (fixed_step) {
+ delta = float(diff) / Engine::get_singleton()->get_iterations_per_second();
+ } else {
+ delta = double(diff) / 1000000.0;
+ }
+
+ if (base_time + time_accum + delta > max_time)
+ break;
+
+ distance_accum += distance;
+ time_accum += delta;
+ }
+
+ if (time_accum) {
+ linear_velocity = distance_accum / time_accum;
+ }
+
+ return linear_velocity;
+}
+
+void SpatialVelocityTracker::reset(const Vector3 &p_new_pos) {
+
+ PositionHistory ph;
+ ph.position = p_new_pos;
+ if (fixed_step) {
+ ph.frame = Engine::get_singleton()->get_fixed_frames();
+ } else {
+ ph.frame = Engine::get_singleton()->get_idle_frame_ticks();
+ }
+
+ position_history[0] = ph;
+ position_history_len = 1;
+}
+
+void SpatialVelocityTracker::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_track_fixed_step", "enable"), &SpatialVelocityTracker::set_track_fixed_step);
+ ClassDB::bind_method(D_METHOD("is_tracking_fixed_step"), &SpatialVelocityTracker::is_tracking_fixed_step);
+ ClassDB::bind_method(D_METHOD("update_position", "position"), &SpatialVelocityTracker::update_position);
+ ClassDB::bind_method(D_METHOD("get_tracked_linear_velocity"), &SpatialVelocityTracker::get_tracked_linear_velocity);
+ ClassDB::bind_method(D_METHOD("reset", "position"), &SpatialVelocityTracker::reset);
+}
+
+SpatialVelocityTracker::SpatialVelocityTracker() {
+ position_history.resize(4); // should be configurable
+ position_history_len = 0;
+ fixed_step = false;
+}
diff --git a/scene/3d/spatial_velocity_tracker.h b/scene/3d/spatial_velocity_tracker.h
new file mode 100644
index 0000000000..65f3eaca93
--- /dev/null
+++ b/scene/3d/spatial_velocity_tracker.h
@@ -0,0 +1,31 @@
+#ifndef SPATIAL_VELOCITY_TRACKER_H
+#define SPATIAL_VELOCITY_TRACKER_H
+
+#include "scene/3d/spatial.h"
+
+class SpatialVelocityTracker : public Reference {
+ GDCLASS(SpatialVelocityTracker, Reference)
+
+ struct PositionHistory {
+ uint64_t frame;
+ Vector3 position;
+ };
+
+ bool fixed_step;
+ Vector<PositionHistory> position_history;
+ int position_history_len;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void reset(const Vector3 &p_new_pos);
+ void set_track_fixed_step(bool p_use_fixed_step);
+ bool is_tracking_fixed_step() const;
+ void update_position(const Vector3 &p_position);
+ Vector3 get_tracked_linear_velocity() const;
+
+ SpatialVelocityTracker();
+};
+
+#endif // SPATIAL_VELOCITY_TRACKER_H
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index a456759281..03798c01a2 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -89,7 +89,8 @@ void Button::_notification(int p_what) {
case DRAW_PRESSED: {
style = get_stylebox("pressed");
- style->draw(ci, Rect2(Point2(0, 0), size));
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
if (has_color("font_color_pressed"))
color = get_color("font_color_pressed");
else
@@ -101,7 +102,8 @@ void Button::_notification(int p_what) {
case DRAW_HOVER: {
style = get_stylebox("hover");
- style->draw(ci, Rect2(Point2(0, 0), size));
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
color = get_color("font_color_hover");
if (has_color("icon_color_hover"))
color_icon = get_color("icon_color_hover");
@@ -110,7 +112,8 @@ void Button::_notification(int p_what) {
case DRAW_DISABLED: {
style = get_stylebox("disabled");
- style->draw(ci, Rect2(Point2(0, 0), size));
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
color = get_color("font_color_disabled");
if (has_color("icon_color_disabled"))
color_icon = get_color("icon_color_disabled");
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 9ef340edbc..faaf761598 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -50,6 +50,19 @@ void ColorPicker::_notification(int p_what) {
_update_color();
} break;
+ case NOTIFICATION_PARENTED: {
+ for (int i = 0; i < 4; i++)
+ set_margin((Margin)i, get_constant("margin"));
+ } break;
+
+ case NOTIFICATION_VISIBILITY_CHANGED: {
+ if (get_parent()) {
+ Popup *p = get_parent()->cast_to<Popup>();
+ if (p)
+ p->set_size(Size2(get_combined_minimum_size().width + get_constant("margin") * 2, get_combined_minimum_size().height + get_constant("margin") * 2));
+ }
+ } break;
+
case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
if (screen != NULL) {
if (screen->is_visible()) {
@@ -254,13 +267,13 @@ void ColorPicker::_update_text_value() {
}
void ColorPicker::_sample_draw() {
- sample->draw_rect(Rect2(Point2(), Size2(uv_edit->get_size().width, 20)), color);
+ sample->draw_rect(Rect2(Point2(), Size2(uv_edit->get_size().width, sample->get_size().height * 0.95)), color);
}
-void ColorPicker::_hsv_draw(int p_wich, Control *c) {
+void ColorPicker::_hsv_draw(int p_which, Control *c) {
if (!c)
return;
- if (p_wich == 0) {
+ if (p_which == 0) {
Vector<Point2> points;
points.push_back(Vector2());
points.push_back(Vector2(c->get_size().x, 0));
@@ -291,7 +304,7 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) {
c->draw_line(Point2(x, 0), Point2(x, c->get_size().y), col.inverted());
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
c->draw_line(Point2(x, y), Point2(x, y), Color(1, 1, 1), 2);
- } else if (p_wich == 1) {
+ } else if (p_which == 1) {
Ref<Texture> hue = get_icon("color_hue", "ColorPicker");
c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
int y = c->get_size().y - c->get_size().y * (1.0 - h);
@@ -512,23 +525,18 @@ ColorPicker::ColorPicker()
uv_edit->set_mouse_filter(MOUSE_FILTER_PASS);
uv_edit->set_h_size_flags(SIZE_EXPAND_FILL);
uv_edit->set_v_size_flags(SIZE_EXPAND_FILL);
- Vector<Variant> args = Vector<Variant>();
- args.push_back(0);
- args.push_back(uv_edit);
- uv_edit->connect("draw", this, "_hsv_draw", args);
+ uv_edit->set_custom_minimum_size(Size2(get_constant("sv_width"), get_constant("sv_height")));
+ uv_edit->connect("draw", this, "_hsv_draw", make_binds(0, uv_edit));
add_child(hb_edit);
w_edit = memnew(Control);
//w_edit->set_ignore_mouse(false);
- w_edit->set_custom_minimum_size(Size2(30, 0));
+ w_edit->set_custom_minimum_size(Size2(get_constant("h_width"), 0));
w_edit->set_h_size_flags(SIZE_FILL);
w_edit->set_v_size_flags(SIZE_EXPAND_FILL);
w_edit->connect("gui_input", this, "_w_input");
- args.clear();
- args.push_back(1);
- args.push_back(w_edit);
- w_edit->connect("draw", this, "_hsv_draw", args);
+ w_edit->connect("draw", this, "_hsv_draw", make_binds(1, w_edit));
hb_edit->add_child(uv_edit);
hb_edit->add_child(memnew(VSeparator));
@@ -549,10 +557,12 @@ ColorPicker::ColorPicker()
HBoxContainer *hbc = memnew(HBoxContainer);
labels[i] = memnew(Label(lt[i]));
- labels[i]->set_custom_minimum_size(Size2(10, 0));
+ labels[i]->set_custom_minimum_size(Size2(get_constant("label_width"), 0));
+ labels[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
hbc->add_child(labels[i]);
scroll[i] = memnew(HSlider);
+ scroll[i]->set_v_size_flags(SIZE_SHRINK_CENTER);
hbc->add_child(scroll[i]);
values[i] = memnew(SpinBox);
@@ -571,7 +581,7 @@ ColorPicker::ColorPicker()
HBoxContainer *hhb = memnew(HBoxContainer);
btn_mode = memnew(CheckButton);
- btn_mode->set_text(TTR("RAW Mode"));
+ btn_mode->set_text(TTR("Raw Mode"));
btn_mode->connect("toggled", this, "set_raw_mode");
hhb->add_child(btn_mode);
vbr->add_child(hhb);
@@ -617,9 +627,7 @@ void ColorPickerButton::_color_changed(const Color &p_color) {
void ColorPickerButton::pressed() {
- Size2 ms = Size2(300, picker->get_combined_minimum_size().height + 10);
- popup->set_position(get_global_position() - Size2(0, ms.height));
- popup->set_size(ms);
+ popup->set_position(get_global_position() - picker->get_combined_minimum_size());
popup->popup();
picker->set_focus_on_line_edit();
}
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index de624fd029..1a79266409 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -79,7 +79,7 @@ private:
void _update_text_value();
void _text_type_toggled();
void _sample_draw();
- void _hsv_draw(int p_wich, Control *c);
+ void _hsv_draw(int p_which, Control *c);
void _uv_input(const Ref<InputEvent> &p_input);
void _w_input(const Ref<InputEvent> &p_input);
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index d5e852f840..8885bec03c 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -584,5 +584,6 @@ Button *ConfirmationDialog::get_cancel() {
ConfirmationDialog::ConfirmationDialog() {
set_title(RTR("Please Confirm..."));
+ set_custom_minimum_size(Size2(200, 70));
cancel = add_cancel();
}
diff --git a/scene/gui/gradient_edit.cpp b/scene/gui/gradient_edit.cpp
index 58bce57580..22de28ea7f 100644
--- a/scene/gui/gradient_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -61,10 +61,8 @@ int GradientEdit::_get_point_from_pos(int x) {
void GradientEdit::_show_color_picker() {
if (grabbed == -1)
return;
- Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10);
picker->set_pick_color(points[grabbed].color);
- popup->set_position(get_global_position() - Vector2(ms.width - get_size().width, ms.height));
- popup->set_size(ms);
+ popup->set_position(get_global_position() - popup->get_combined_minimum_size());
popup->popup();
}
diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp
index fb85930ceb..f02e01d85a 100644
--- a/scene/gui/label.cpp
+++ b/scene/gui/label.cpp
@@ -686,6 +686,7 @@ Label::Label(const String &p_text) {
max_lines_visible = -1;
set_text(p_text);
uppercase = false;
+ set_v_size_flags(SIZE_SHRINK_CENTER);
}
Label::~Label() {
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 8d3271ca8c..adcf86357d 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -574,8 +574,12 @@ void LineEdit::_notification(int p_what) {
RID ci = get_canvas_item();
Ref<StyleBox> style = get_stylebox("normal");
- if (!is_editable())
+ float disabled_alpha = 1.0; // used to set the disabled input text color
+ if (!is_editable()) {
style = get_stylebox("read_only");
+ disabled_alpha = .5;
+ draw_caret = false;
+ }
Ref<Font> font = get_font("font");
@@ -622,6 +626,7 @@ void LineEdit::_notification(int p_what) {
// draw placeholder color
if (text.empty())
font_color.a *= placeholder_alpha;
+ font_color.a *= disabled_alpha;
int caret_height = font->get_height() > y_area ? y_area : font->get_height();
while (true) {
@@ -1191,7 +1196,9 @@ void LineEdit::menu_option(int p_option) {
select_all();
} break;
case MENU_UNDO: {
- undo();
+ if (editable) {
+ undo();
+ }
} break;
}
}
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index f75e0986c1..b842419eab 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -52,11 +52,26 @@ void OptionButton::_notification(int p_what) {
RID ci = get_canvas_item();
Ref<Texture> arrow = Control::get_icon("arrow");
Ref<StyleBox> normal = get_stylebox("normal");
+ Color clr = Color(1, 1, 1);
+ if (get_constant("modulate_arrow"))
+ switch (get_draw_mode()) {
+ case DRAW_PRESSED:
+ clr = get_color("font_color_pressed");
+ break;
+ case DRAW_HOVER:
+ clr = get_color("font_color_hover");
+ break;
+ case DRAW_DISABLED:
+ clr = get_color("font_color_disabled");
+ break;
+ default:
+ clr = get_color("font_color");
+ }
Size2 size = get_size();
Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2)));
- arrow->draw(ci, ofs);
+ arrow->draw(ci, ofs, clr);
} break;
}
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 072e90df3a..864fb3d3d5 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -696,6 +696,17 @@ String PopupMenu::get_item_text(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, items.size(), "");
return items[p_idx].text;
}
+
+int PopupMenu::get_item_idx_from_text(const String &text) const {
+
+ for (int idx = 0; idx < items.size(); idx++) {
+ if (items[idx].text == text)
+ return idx;
+ }
+
+ return -1;
+}
+
Ref<Texture> PopupMenu::get_item_icon(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, items.size(), Ref<Texture>());
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index a9bd8f7e50..6f1a2db363 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -132,6 +132,7 @@ public:
void toggle_item_checked(int p_idx);
String get_item_text(int p_idx) const;
+ int get_item_idx_from_text(const String &text) const;
Ref<Texture> get_item_icon(int p_idx) const;
bool is_item_checked(int p_idx) const;
int get_item_ID(int p_idx) const;
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index c84608ef2e..9ba17ce34f 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -167,7 +167,8 @@ void Slider::_notification(int p_what) {
if (orientation == VERTICAL) {
- style->draw(ci, Rect2i(Point2i(), Size2i(style->get_minimum_size().width + style->get_center_size().width, size.height)));
+ int widget_width = style->get_minimum_size().width + style->get_center_size().width;
+ style->draw(ci, Rect2i(Point2i(size.width / 2 - widget_width / 2, 0), Size2i(widget_width, size.height)));
/*
if (mouse_inside||has_focus())
focus->draw(ci,Rect2i(Point2i(),Size2i(style->get_minimum_size().width+style->get_center_size().width,size.height)));
@@ -183,7 +184,9 @@ void Slider::_notification(int p_what) {
}
grabber->draw(ci, Point2i(size.width / 2 - grabber->get_size().width / 2, size.height - get_as_ratio() * areasize - grabber->get_size().height));
} else {
- style->draw(ci, Rect2i(Point2i(), Size2i(size.width, style->get_minimum_size().height + style->get_center_size().height)));
+
+ int widget_height = style->get_minimum_size().height + style->get_center_size().height;
+ style->draw(ci, Rect2i(Point2i(0, size.height / 2 - widget_height / 2), Size2i(size.width, widget_height)));
/*
if (mouse_inside||has_focus())
focus->draw(ci,Rect2i(Point2i(),Size2i(size.width,style->get_minimum_size().height+style->get_center_size().height)));
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index 4316f06a53..ee0ae1fb41 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -639,6 +639,22 @@ Tabs::TabAlign Tabs::get_tab_align() const {
return tab_align;
}
+void Tabs::move_tab(int from, int to) {
+
+ if (from == to)
+ return;
+
+ ERR_FAIL_INDEX(from, tabs.size());
+ ERR_FAIL_INDEX(to, tabs.size());
+
+ Tab tab_from = tabs[from];
+ tabs.remove(from);
+ tabs.insert(to, tab_from);
+
+ _update_cache();
+ update();
+}
+
int Tabs::get_tab_width(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, tabs.size(), 0);
@@ -773,6 +789,8 @@ void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_tab_align", "align"), &Tabs::set_tab_align);
ClassDB::bind_method(D_METHOD("get_tab_align"), &Tabs::get_tab_align);
ClassDB::bind_method(D_METHOD("ensure_tab_visible", "idx"), &Tabs::ensure_tab_visible);
+ ClassDB::bind_method(D_METHOD("get_tab_rect", "tab_idx"), &Tabs::get_tab_rect);
+ ClassDB::bind_method(D_METHOD("move_tab", "from", "to"), &Tabs::move_tab);
ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab")));
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 613c604b12..a9dd6bddd7 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -119,6 +119,8 @@ public:
void set_tab_align(TabAlign p_align);
TabAlign get_tab_align() const;
+ void move_tab(int from, int to);
+
void set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy);
int get_tab_count() const;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index d8788b4eca..44f71a2c4e 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1953,6 +1953,14 @@ void Tree::text_editor_enter(String p_text) {
c.val = evaluator->eval(p_text);
else
c.val = p_text.to_double();
+
+ if (c.step > 0)
+ c.val = Math::stepify(c.val, c.step);
+ if (c.val < c.min)
+ c.val = c.min;
+ else if (c.val > c.max)
+ c.val = c.max;
+
} break;
default: { ERR_FAIL(); }
}
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index 1e5735de97..65c7c1a36f 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -614,7 +614,7 @@ bool SceneTree::idle(float p_time) {
if (is_editor_hint()) {
//simple hack to reload fallback environment if it changed from editor
- String env_path = GlobalConfig::get_singleton()->get("rendering/viewport/default_environment");
+ String env_path = GlobalConfig::get_singleton()->get("rendering/environment/default_environment");
env_path = env_path.strip_edges(); //user may have added a space or two
String cpath;
Ref<Environment> fallback = get_root()->get_world()->get_fallback_environment();
@@ -2317,11 +2317,11 @@ SceneTree::SceneTree() {
debug_collisions_hint = false;
debug_navigation_hint = false;
#endif
- debug_collisions_color = GLOBAL_DEF("debug/collision/shape_color", Color(0.0, 0.6, 0.7, 0.5));
- debug_collision_contact_color = GLOBAL_DEF("debug/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8));
- debug_navigation_color = GLOBAL_DEF("debug/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4));
- debug_navigation_disabled_color = GLOBAL_DEF("debug/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4));
- collision_debug_contacts = GLOBAL_DEF("debug/collision/max_contacts_displayed", 10000);
+ debug_collisions_color = GLOBAL_DEF("debug/shapes/collision/shape_color", Color(0.0, 0.6, 0.7, 0.5));
+ debug_collision_contact_color = GLOBAL_DEF("debug/shapes/collision/contact_color", Color(1.0, 0.2, 0.1, 0.8));
+ debug_navigation_color = GLOBAL_DEF("debug/shapes/navigation/geometry_color", Color(0.1, 1.0, 0.7, 0.4));
+ debug_navigation_disabled_color = GLOBAL_DEF("debug/shapes/navigation/disabled_geometry_color", Color(1.0, 0.7, 0.1, 0.4));
+ collision_debug_contacts = GLOBAL_DEF("debug/shapes/collision/max_contacts_displayed", 10000);
tree_version = 1;
fixed_process_time = 1;
@@ -2348,12 +2348,12 @@ SceneTree::SceneTree() {
root->set_as_audio_listener_2d(true);
current_scene = NULL;
- int ref_atlas_size = GLOBAL_DEF("rendering/reflections/atlas_size", 2048);
- int ref_atlas_subdiv = GLOBAL_DEF("rendering/reflections/atlas_subdiv", 8);
- int msaa_mode = GLOBAL_DEF("rendering/quality/msaa", 0);
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/msaa", PropertyInfo(Variant::INT, "rendering/quality/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"));
+ int ref_atlas_size = GLOBAL_DEF("rendering/quality/reflections/atlas_size", 2048);
+ int ref_atlas_subdiv = GLOBAL_DEF("rendering/quality/reflections/atlas_subdiv", 8);
+ int msaa_mode = GLOBAL_DEF("rendering/quality/filters/msaa", 0);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/filters/msaa", PropertyInfo(Variant::INT, "rendering/quality/filters/msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"));
root->set_msaa(Viewport::MSAA(msaa_mode));
- bool hdr = GLOBAL_DEF("rendering/quality/hdr", true);
+ bool hdr = GLOBAL_DEF("rendering/quality/depth/hdr", true);
root->set_hdr(hdr);
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
@@ -2369,9 +2369,9 @@ SceneTree::SceneTree() {
ext_hint += "*." + E->get();
}
//get path
- String env_path = GLOBAL_DEF("rendering/viewport/default_environment", "");
+ String env_path = GLOBAL_DEF("rendering/environment/default_environment", "");
//setup property
- GlobalConfig::get_singleton()->set_custom_property_info("rendering/viewport/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/environment/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
env_path = env_path.strip_edges();
if (env_path != String()) {
Ref<Environment> env = ResourceLoader::load(env_path);
@@ -2380,7 +2380,7 @@ SceneTree::SceneTree() {
} else {
if (is_editor_hint()) {
//file was erased, clear the field.
- GlobalConfig::get_singleton()->set("rendering/viewport/default_environment", "");
+ GlobalConfig::get_singleton()->set("rendering/environment/default_environment", "");
} else {
//file was erased, notify user.
ERR_PRINTS(RTR("Default Environment as specified in Project Setings (Rendering -> Viewport -> Default Environment) could not be loaded."));
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 4fb4e02148..824f968c49 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -2057,6 +2057,10 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
//keyboard focus
//if (from && p_event->is_pressed() && !p_event->get_alt() && !p_event->get_metakey() && !p_event->key->get_command()) {
+ Ref<InputEventKey> k = p_event;
+ //need to check for mods, otherwise any combination of alt/ctrl/shift+<up/down/left/righ/etc> is handled here when it shouldn't be.
+ bool mods = k.is_valid() && (k->get_control() || k->get_alt() || k->get_shift() || k->get_metakey());
+
if (from && p_event->is_pressed()) {
Control *next = NULL;
@@ -2070,22 +2074,22 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
next = from->find_prev_valid_focus();
}
- if (p_event->is_action("ui_up")) {
+ if (!mods && p_event->is_action("ui_up")) {
next = from->_get_focus_neighbour(MARGIN_TOP);
}
- if (p_event->is_action("ui_left")) {
+ if (!mods && p_event->is_action("ui_left")) {
next = from->_get_focus_neighbour(MARGIN_LEFT);
}
- if (p_event->is_action("ui_right")) {
+ if (!mods && p_event->is_action("ui_right")) {
next = from->_get_focus_neighbour(MARGIN_RIGHT);
}
- if (p_event->is_action("ui_down")) {
+ if (!mods && p_event->is_action("ui_down")) {
next = from->_get_focus_neighbour(MARGIN_BOTTOM);
}
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 76e07db93d..c6d26f4d4c 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -164,7 +164,7 @@
#include "scene/resources/polygon_path_finder.h"
//#include "scene/resources/sample.h"
-//#include "scene/audio/sample_player.h"
+#include "scene/3d/audio_stream_player_3d.h"
#include "scene/resources/material.h"
#include "scene/resources/mesh.h"
#include "scene/resources/room.h"
@@ -212,7 +212,7 @@
#include "scene/3d/area.h"
-#include "scene/3d/body_shape.h"
+#include "scene/3d/collision_shape.h"
#include "scene/3d/immediate_geometry.h"
#include "scene/3d/multimesh_instance.h"
#include "scene/3d/physics_joint.h"
@@ -532,8 +532,6 @@ void register_scene_types() {
ClassDB::register_class<SphereMesh>();
ClassDB::register_virtual_class<Material>();
ClassDB::register_class<SpatialMaterial>();
- ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial");
- ClassDB::add_compatibility_class("Mesh", "ArrayMesh");
SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
SpatialMaterial::init_shaders();
@@ -562,6 +560,7 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
+ ClassDB::register_class<SpatialVelocityTracker>();
#endif
ClassDB::register_class<World>();
ClassDB::register_class<Environment>();
@@ -598,6 +597,7 @@ void register_scene_types() {
ClassDB::register_class<AudioStreamPlayer>();
ClassDB::register_class<AudioStreamPlayer2D>();
+ ClassDB::register_class<AudioStreamPlayer3D>();
ClassDB::register_virtual_class<VideoStream>();
ClassDB::register_class<AudioStreamSample>();
@@ -628,6 +628,13 @@ void register_scene_types() {
ClassDB::register_class<SceneTree>();
ClassDB::register_virtual_class<SceneTreeTimer>(); //sorry, you can't create it
+#ifndef DISABLE_DEPRECATED
+ ClassDB::add_compatibility_class("ImageSkyBox", "PanoramaSky");
+ ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial");
+ ClassDB::add_compatibility_class("Mesh", "ArrayMesh");
+
+#endif
+
OS::get_singleton()->yield(); //may take time to init
resource_saver_text = memnew(ResourceFormatSaverText);
diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp
index f12e231074..c8f6007e60 100644
--- a/scene/resources/audio_stream_sample.cpp
+++ b/scene/resources/audio_stream_sample.cpp
@@ -231,7 +231,7 @@ void AudioStreamPlaybackSample::mix(AudioFrame *p_buffer, float p_rate_scale, in
/* some 64-bit fixed point precaches */
- int64_t loop_begin_fp = ((int64_t)len << MIX_FRAC_BITS);
+ int64_t loop_begin_fp = ((int64_t)base->loop_begin << MIX_FRAC_BITS);
int64_t loop_end_fp = ((int64_t)base->loop_end << MIX_FRAC_BITS);
int64_t length_fp = ((int64_t)len << MIX_FRAC_BITS);
int64_t begin_limit = (base->loop_mode != AudioStreamSample::LOOP_DISABLED) ? loop_begin_fp : 0;
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index d70d91a17e..3e612c745f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -761,11 +761,11 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// colorPicker
- t->set_constant("value_height", "ColorPicker", 23 * scale);
- t->set_constant("value_width", "ColorPicker", 50 * scale);
- t->set_constant("color_width", "ColorPicker", 100 * scale);
- t->set_constant("label_width", "ColorPicker", 20 * scale);
- t->set_constant("hseparator", "ColorPicker", 4 * scale);
+ t->set_constant("margin", "ColorPicker", 4 * scale);
+ t->set_constant("sv_width", "ColorPicker", 256 * scale);
+ t->set_constant("sv_height", "ColorPicker", 256 * scale);
+ t->set_constant("h_width", "ColorPicker", 30 * scale);
+ t->set_constant("label_width", "ColorPicker", 10 * scale);
t->set_icon("screen_picker", "ColorPicker", make_icon(icon_color_pick_png));
t->set_icon("add_preset", "ColorPicker", make_icon(icon_add_png));
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 33e62e3a00..125bbd2d64 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1113,8 +1113,6 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_adjustment_color_correction", "get_adjustment_color_correction");
- GLOBAL_DEF("rendering/sky/irradiance_cube_resolution", 256);
-
BIND_CONSTANT(BG_KEEP);
BIND_CONSTANT(BG_CLEAR_COLOR);
BIND_CONSTANT(BG_COLOR);
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index ef7011b2af..414d0a6240 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -413,6 +413,17 @@ Ref<Mesh> Mesh::create_outline(float p_margin) const {
return newmesh;
}
+void Mesh::_bind_methods() {
+
+ BIND_CONSTANT(PRIMITIVE_POINTS);
+ BIND_CONSTANT(PRIMITIVE_LINES);
+ BIND_CONSTANT(PRIMITIVE_LINE_STRIP);
+ BIND_CONSTANT(PRIMITIVE_LINE_LOOP);
+ BIND_CONSTANT(PRIMITIVE_TRIANGLES);
+ BIND_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
+ BIND_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
+}
+
Mesh::Mesh() {
}
@@ -1034,14 +1045,6 @@ void ArrayMesh::_bind_methods() {
BIND_CONSTANT(ARRAY_FORMAT_BONES);
BIND_CONSTANT(ARRAY_FORMAT_WEIGHTS);
BIND_CONSTANT(ARRAY_FORMAT_INDEX);
-
- BIND_CONSTANT(PRIMITIVE_POINTS);
- BIND_CONSTANT(PRIMITIVE_LINES);
- BIND_CONSTANT(PRIMITIVE_LINE_STRIP);
- BIND_CONSTANT(PRIMITIVE_LINE_LOOP);
- BIND_CONSTANT(PRIMITIVE_TRIANGLES);
- BIND_CONSTANT(PRIMITIVE_TRIANGLE_STRIP);
- BIND_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
}
ArrayMesh::ArrayMesh() {
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index f716b59fe9..4adb871e09 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -46,6 +46,8 @@ class Mesh : public Resource {
protected:
void _clear_triangle_mesh();
+ static void _bind_methods();
+
public:
enum {
diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp
index 61aaaf8fb4..c373ad67ee 100644
--- a/scene/resources/sky_box.cpp
+++ b/scene/resources/sky_box.cpp
@@ -474,15 +474,14 @@ ProceduralSky::ProceduralSky() {
texture = VS::get_singleton()->texture_create();
update_queued = false;
-
- sky_top_color = Color::hex(0x4d67e8ff);
+ sky_top_color = Color::hex(0x0c74f9ff);
sky_horizon_color = Color::hex(0x8ed2e8ff);
sky_curve = 0.25;
sky_energy = 1;
- ground_bottom_color = Color::hex(0x322719ff);
- ground_horizon_color = Color::hex(0x543610ff);
- ground_curve = 0.25;
+ ground_bottom_color = Color::hex(0x1a2530ff);
+ ground_horizon_color = Color::hex(0x7bc9f3ff);
+ ground_curve = 0.01;
ground_energy = 1;
sun_color = Color(1, 1, 1);
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 2714ffec10..f108809c83 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -437,3 +437,81 @@ StyleBoxFlat::StyleBoxFlat() {
}
StyleBoxFlat::~StyleBoxFlat() {
}
+
+void StyleBoxLine::set_color(const Color &p_color) {
+ color = p_color;
+ emit_changed();
+}
+Color StyleBoxLine::get_color() const {
+ return color;
+}
+
+void StyleBoxLine::set_thickness(int p_thickness) {
+ thickness = p_thickness;
+ emit_changed();
+}
+int StyleBoxLine::get_thickness() const {
+ return thickness;
+}
+
+void StyleBoxLine::set_vertical(bool p_vertical) {
+ vertical = p_vertical;
+}
+bool StyleBoxLine::is_vertical() const {
+ return vertical;
+}
+
+void StyleBoxLine::set_grow(float p_grow) {
+ grow = p_grow;
+ emit_changed();
+}
+float StyleBoxLine::get_grow() const {
+ return grow;
+}
+
+void StyleBoxLine::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_color", "color"), &StyleBoxLine::set_color);
+ ClassDB::bind_method(D_METHOD("get_color"), &StyleBoxLine::get_color);
+ ClassDB::bind_method(D_METHOD("set_thickness", "thickness"), &StyleBoxLine::set_thickness);
+ ClassDB::bind_method(D_METHOD("get_thickness"), &StyleBoxLine::get_thickness);
+ ClassDB::bind_method(D_METHOD("set_grow", "grow"), &StyleBoxLine::set_grow);
+ ClassDB::bind_method(D_METHOD("get_grow"), &StyleBoxLine::get_grow);
+ ClassDB::bind_method(D_METHOD("set_vertical", "vertical"), &StyleBoxLine::set_vertical);
+ ClassDB::bind_method(D_METHOD("is_vertical"), &StyleBoxLine::is_vertical);
+
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "thickness", PROPERTY_HINT_RANGE, "0,10"), "set_thickness", "get_thickness");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "get_vertical");
+}
+float StyleBoxLine::get_style_margin(Margin p_margin) const {
+ return thickness;
+}
+Size2 StyleBoxLine::get_center_size() const {
+ return Size2();
+}
+
+void StyleBoxLine::draw(RID p_canvas_item, const Rect2 &p_rect) const {
+ VisualServer *vs = VisualServer::get_singleton();
+ Rect2i r = p_rect;
+
+ if (vertical) {
+ r.position.y -= grow;
+ r.size.y += grow * 2;
+ r.size.x = thickness;
+ } else {
+ r.position.x -= grow;
+ r.size.x += grow * 2;
+ r.size.y = thickness;
+ }
+
+ vs->canvas_item_add_rect(p_canvas_item, r, color);
+}
+
+StyleBoxLine::StyleBoxLine() {
+ grow = 1.0;
+ thickness = 1;
+ color = Color(0.0, 0.0, 0.0);
+ vertical = false;
+}
+StyleBoxLine::~StyleBoxLine() {}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index 7547c2ea81..64ce3528aa 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -164,4 +164,38 @@ public:
~StyleBoxFlat();
};
+// just used to draw lines.
+class StyleBoxLine : public StyleBox {
+
+ GDCLASS(StyleBoxLine, StyleBox);
+ Color color;
+ int thickness;
+ bool vertical;
+ float grow;
+
+protected:
+ virtual float get_style_margin(Margin p_margin) const;
+ static void _bind_methods();
+
+public:
+ void set_color(const Color &p_color);
+ Color get_color() const;
+
+ void set_thickness(int p_thickness);
+ int get_thickness() const;
+
+ void set_vertical(bool p_vertical);
+ bool is_vertical() const;
+
+ void set_grow(float p_grow);
+ float get_grow() const;
+
+ virtual Size2 get_center_size() const;
+
+ virtual void draw(RID p_canvas_item, const Rect2 &p_rect) const;
+
+ StyleBoxLine();
+ ~StyleBoxLine();
+};
+
#endif
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index b2822ca0c4..8b747e1b43 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -812,6 +812,7 @@ void SurfaceTool::clear() {
index_array.clear();
vertex_array.clear();
smooth_groups.clear();
+ material.unref();
}
void SurfaceTool::_bind_methods() {
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index 24551e9135..b84cc9563e 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -299,6 +299,13 @@ PhysicsDirectSpaceState *World::get_direct_space_state() {
return PhysicsServer::get_singleton()->space_get_direct_state(space);
}
+void World::get_camera_list(List<Camera *> *r_cameras) {
+
+ for (Map<Camera *, SpatialIndexer::CameraData>::Element *E = indexer->cameras.front(); E; E = E->next()) {
+ r_cameras->push_back(E->key());
+ }
+}
+
void World::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_space"), &World::get_space);
diff --git a/scene/resources/world.h b/scene/resources/world.h
index 5291b3974b..158086974c 100644
--- a/scene/resources/world.h
+++ b/scene/resources/world.h
@@ -76,6 +76,8 @@ public:
void set_fallback_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_fallback_environment() const;
+ void get_camera_list(List<Camera *> *r_cameras);
+
PhysicsDirectSpaceState *get_direct_space_state();
World();
diff --git a/servers/audio/audio_filter_sw.cpp b/servers/audio/audio_filter_sw.cpp
index 1210312ac5..4bf1cebf12 100644
--- a/servers/audio/audio_filter_sw.cpp
+++ b/servers/audio/audio_filter_sw.cpp
@@ -242,28 +242,49 @@ AudioFilterSW::Processor::Processor() {
set_filter(NULL);
}
-void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter) {
+void AudioFilterSW::Processor::set_filter(AudioFilterSW *p_filter, bool p_clear_history) {
- ha1 = ha2 = hb1 = hb2 = 0;
+ if (p_clear_history) {
+ ha1 = ha2 = hb1 = hb2 = 0;
+ }
filter = p_filter;
}
-void AudioFilterSW::Processor::update_coeffs() {
+void AudioFilterSW::Processor::update_coeffs(int p_interp_buffer_len) {
if (!filter)
return;
- filter->prepare_coefficients(&coeffs);
+ if (p_interp_buffer_len) { //interpolate
+ Coeffs old_coeffs = coeffs;
+ filter->prepare_coefficients(&coeffs);
+ incr_coeffs.a1 = (coeffs.a1 - old_coeffs.a1) / p_interp_buffer_len;
+ incr_coeffs.a2 = (coeffs.a2 - old_coeffs.a2) / p_interp_buffer_len;
+ incr_coeffs.b0 = (coeffs.b0 - old_coeffs.b0) / p_interp_buffer_len;
+ incr_coeffs.b1 = (coeffs.b1 - old_coeffs.b1) / p_interp_buffer_len;
+ incr_coeffs.b2 = (coeffs.b2 - old_coeffs.b2) / p_interp_buffer_len;
+ coeffs = old_coeffs;
+ } else {
+ filter->prepare_coefficients(&coeffs);
+ }
}
-void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride) {
+void AudioFilterSW::Processor::process(float *p_samples, int p_amount, int p_stride, bool p_interpolate) {
if (!filter)
return;
- for (int i = 0; i < p_amount; i++) {
+ if (p_interpolate) {
+ for (int i = 0; i < p_amount; i++) {
+
+ process_one_interp(*p_samples);
+ p_samples += p_stride;
+ }
+ } else {
+ for (int i = 0; i < p_amount; i++) {
- process_one(*p_samples);
- p_samples += p_stride;
+ process_one(*p_samples);
+ p_samples += p_stride;
+ }
}
}
diff --git a/servers/audio/audio_filter_sw.h b/servers/audio/audio_filter_sw.h
index e1dd5e5c0e..f5a07c4c8f 100644
--- a/servers/audio/audio_filter_sw.h
+++ b/servers/audio/audio_filter_sw.h
@@ -60,11 +60,14 @@ public:
AudioFilterSW *filter;
Coeffs coeffs;
float ha1, ha2, hb1, hb2; //history
+ Coeffs incr_coeffs;
+
public:
- void set_filter(AudioFilterSW *p_filter);
- void process(float *p_samples, int p_amount, int p_stride = 1);
- void update_coeffs();
+ void set_filter(AudioFilterSW *p_filter, bool p_clear_history = true);
+ void process(float *p_samples, int p_amount, int p_stride = 1, bool p_interpolate = false);
+ void update_coeffs(int p_interp_buffer_len = 0);
_ALWAYS_INLINE_ void process_one(float &p_sample);
+ _ALWAYS_INLINE_ void process_one_interp(float &p_sample);
Processor();
};
@@ -104,4 +107,20 @@ void AudioFilterSW::Processor::process_one(float &p_val) {
ha1 = p_val;
}
+void AudioFilterSW::Processor::process_one_interp(float &p_val) {
+
+ float pre = p_val;
+ p_val = (p_val * coeffs.b0 + hb1 * coeffs.b1 + hb2 * coeffs.b2 + ha1 * coeffs.a1 + ha2 * coeffs.a2);
+ ha2 = ha1;
+ hb2 = hb1;
+ hb1 = pre;
+ ha1 = p_val;
+
+ coeffs.b0 += incr_coeffs.b0;
+ coeffs.b1 += incr_coeffs.b1;
+ coeffs.b2 += incr_coeffs.b2;
+ coeffs.a1 += incr_coeffs.a1;
+ coeffs.a2 += incr_coeffs.a2;
+}
+
#endif // AUDIO_FILTER_SW_H
diff --git a/servers/audio/audio_stream.cpp b/servers/audio/audio_stream.cpp
index 14a091e27c..aa498cccad 100644
--- a/servers/audio/audio_stream.cpp
+++ b/servers/audio/audio_stream.cpp
@@ -81,3 +81,134 @@ void AudioStreamPlaybackResampled::mix(AudioFrame *p_buffer, float p_rate_scale,
}
}
}
+////////////////////////////////
+
+void AudioStreamRandomPitch::set_audio_stream(const Ref<AudioStream> &p_audio_stream) {
+
+ audio_stream = p_audio_stream;
+ if (audio_stream.is_valid()) {
+ for (Set<AudioStreamPlaybackRandomPitch *>::Element *E = playbacks.front(); E; E = E->next()) {
+ E->get()->playback = audio_stream->instance_playback();
+ }
+ }
+}
+
+Ref<AudioStream> AudioStreamRandomPitch::get_audio_stream() const {
+
+ return audio_stream;
+}
+
+void AudioStreamRandomPitch::set_random_pitch(float p_pitch) {
+
+ if (p_pitch < 1)
+ p_pitch = 1;
+ random_pitch = p_pitch;
+}
+
+float AudioStreamRandomPitch::get_random_pitch() const {
+ return random_pitch;
+}
+
+Ref<AudioStreamPlayback> AudioStreamRandomPitch::instance_playback() {
+ Ref<AudioStreamPlaybackRandomPitch> playback;
+ playback.instance();
+ if (audio_stream.is_valid())
+ playback->playback = audio_stream->instance_playback();
+
+ playbacks.insert(playback.ptr());
+ playback->random_pitch = Ref<AudioStreamRandomPitch>((AudioStreamRandomPitch *)this);
+ return playback;
+}
+
+String AudioStreamRandomPitch::get_stream_name() const {
+
+ if (audio_stream.is_valid()) {
+ return "Random: " + audio_stream->get_name();
+ }
+ return "RandomPitch";
+}
+
+void AudioStreamRandomPitch::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_audio_stream", "stream"), &AudioStreamRandomPitch::set_audio_stream);
+ ClassDB::bind_method(D_METHOD("get_audio_stream"), &AudioStreamRandomPitch::get_audio_stream);
+
+ ClassDB::bind_method(D_METHOD("set_random_pitch", "scale"), &AudioStreamRandomPitch::set_random_pitch);
+ ClassDB::bind_method(D_METHOD("get_random_pitch"), &AudioStreamRandomPitch::get_random_pitch);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "audio_stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_audio_stream", "get_audio_stream");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "random_pitch", PROPERTY_HINT_RANGE, "1,16,0.01"), "set_random_pitch", "get_random_pitch");
+}
+
+AudioStreamRandomPitch::AudioStreamRandomPitch() {
+ random_pitch = 1.1;
+}
+
+void AudioStreamPlaybackRandomPitch::start(float p_from_pos) {
+ playing = playback;
+ float range_from = 1.0 / random_pitch->random_pitch;
+ float range_to = random_pitch->random_pitch;
+
+ pitch_scale = range_from + Math::randf() * (range_to - range_from);
+
+ if (playing.is_valid()) {
+ playing->start(p_from_pos);
+ }
+}
+
+void AudioStreamPlaybackRandomPitch::stop() {
+ if (playing.is_valid()) {
+ playing->stop();
+ ;
+ }
+}
+bool AudioStreamPlaybackRandomPitch::is_playing() const {
+ if (playing.is_valid()) {
+ return playing->is_playing();
+ }
+
+ return false;
+}
+
+int AudioStreamPlaybackRandomPitch::get_loop_count() const {
+ if (playing.is_valid()) {
+ return playing->get_loop_count();
+ }
+
+ return 0;
+}
+
+float AudioStreamPlaybackRandomPitch::get_pos() const {
+ if (playing.is_valid()) {
+ return playing->get_pos();
+ }
+
+ return 0;
+}
+void AudioStreamPlaybackRandomPitch::seek_pos(float p_time) {
+ if (playing.is_valid()) {
+ playing->seek_pos(p_time);
+ }
+}
+
+void AudioStreamPlaybackRandomPitch::mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames) {
+ if (playing.is_valid()) {
+ playing->mix(p_bufer, p_rate_scale * pitch_scale, p_frames);
+ } else {
+ for (int i = 0; i < p_frames; i++) {
+ p_bufer[i] = AudioFrame(0, 0);
+ }
+ }
+}
+
+float AudioStreamPlaybackRandomPitch::get_length() const {
+ if (playing.is_valid()) {
+ return playing->get_length();
+ }
+
+ return 0;
+}
+
+AudioStreamPlaybackRandomPitch::~AudioStreamPlaybackRandomPitch() {
+ random_pitch->playbacks.erase(this);
+}
diff --git a/servers/audio/audio_stream.h b/servers/audio/audio_stream.h
index 1cf3cd294d..a35826be21 100644
--- a/servers/audio/audio_stream.h
+++ b/servers/audio/audio_stream.h
@@ -31,6 +31,7 @@
#define AUDIO_STREAM_H
#include "resource.h"
+#include "servers/audio/audio_filter_sw.h"
#include "servers/audio_server.h"
class AudioStreamPlayback : public Reference {
@@ -88,4 +89,58 @@ public:
virtual String get_stream_name() const = 0;
};
+class AudioStreamPlaybackRandomPitch;
+
+class AudioStreamRandomPitch : public AudioStream {
+
+ GDCLASS(AudioStreamRandomPitch, AudioStream)
+ friend class AudioStreamPlaybackRandomPitch;
+
+ Set<AudioStreamPlaybackRandomPitch *> playbacks;
+ Ref<AudioStream> audio_stream;
+ float random_pitch;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_audio_stream(const Ref<AudioStream> &audio_stream);
+ Ref<AudioStream> get_audio_stream() const;
+
+ void set_random_pitch(float p_pitch);
+ float get_random_pitch() const;
+
+ virtual Ref<AudioStreamPlayback> instance_playback();
+ virtual String get_stream_name() const;
+
+ AudioStreamRandomPitch();
+};
+
+class AudioStreamPlaybackRandomPitch : public AudioStreamPlayback {
+
+ GDCLASS(AudioStreamPlaybackRandomPitch, AudioStreamPlayback)
+ friend class AudioStreamRandomPitch;
+
+ Ref<AudioStreamRandomPitch> random_pitch;
+ Ref<AudioStreamPlayback> playback;
+ Ref<AudioStreamPlayback> playing;
+ float pitch_scale;
+
+public:
+ virtual void start(float p_from_pos = 0.0);
+ virtual void stop();
+ virtual bool is_playing() const;
+
+ virtual int get_loop_count() const; //times it looped
+
+ virtual float get_pos() const;
+ virtual void seek_pos(float p_time);
+
+ virtual void mix(AudioFrame *p_bufer, float p_rate_scale, int p_frames);
+
+ virtual float get_length() const; //if supported, otherwise return 0
+
+ ~AudioStreamPlaybackRandomPitch();
+};
+
#endif // AUDIO_STREAM_H
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp
index 8ec001709d..5c418c473f 100644
--- a/servers/physics/area_pair_sw.cpp
+++ b/servers/physics/area_pair_sw.cpp
@@ -32,12 +32,13 @@
bool AreaPairSW::setup(real_t p_step) {
- if (!area->test_collision_mask(body)) {
- colliding = false;
- return false;
- }
+ bool result = false;
- bool result = CollisionSolverSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), NULL, this);
+ if (area->is_shape_set_as_disabled(area_shape) || body->is_shape_set_as_disabled(body_shape)) {
+ result = false;
+ } else if (area->test_collision_mask(body) && CollisionSolverSW::solve_static(body->get_shape(body_shape), body->get_transform() * body->get_shape_transform(body_shape), area->get_shape(area_shape), area->get_transform() * area->get_shape_transform(area_shape), NULL, this)) {
+ result = true;
+ }
if (result != colliding) {
@@ -95,14 +96,13 @@ AreaPairSW::~AreaPairSW() {
bool Area2PairSW::setup(real_t p_step) {
- if (!area_a->test_collision_mask(area_b)) {
- colliding = false;
- return false;
+ bool result = false;
+ if (area_a->is_shape_set_as_disabled(shape_a) || area_b->is_shape_set_as_disabled(shape_b)) {
+ result = false;
+ } else if (area_a->test_collision_mask(area_b) && CollisionSolverSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), NULL, this)) {
+ result = true;
}
- //bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this);
- bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a), area_a->get_transform() * area_a->get_shape_transform(shape_a), area_b->get_shape(shape_b), area_b->get_transform() * area_b->get_shape_transform(shape_b), NULL, this);
-
if (result != colliding) {
if (result) {
diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp
index d740d3c384..9ada1fbc50 100644
--- a/servers/physics/body_pair_sw.cpp
+++ b/servers/physics/body_pair_sw.cpp
@@ -214,6 +214,11 @@ bool BodyPairSW::setup(real_t p_step) {
return false;
}
+ if (A->is_shape_set_as_disabled(shape_A) || B->is_shape_set_as_disabled(shape_B)) {
+ collided = false;
+ return false;
+ }
+
offset_B = B->get_transform().get_origin() - A->get_transform().get_origin();
validate_contacts();
@@ -313,12 +318,6 @@ bool BodyPairSW::setup(real_t p_step) {
B->add_contact(global_B, c.normal, depth, shape_B, global_A, shape_A, A->get_instance_id(), A->get_self(), crB);
}
- if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode() <= PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode() <= PhysicsServer::BODY_MODE_KINEMATIC)) {
- c.active = false;
- collided = false;
- continue;
- }
-
c.active = true;
// Precompute normal mass, tangent mass, and bias.
diff --git a/servers/physics/broad_phase_basic.cpp b/servers/physics/broad_phase_basic.cpp
index 77d8538574..679b9a31fc 100644
--- a/servers/physics/broad_phase_basic.cpp
+++ b/servers/physics/broad_phase_basic.cpp
@@ -105,6 +105,26 @@ int BroadPhaseBasic::get_subindex(ID p_id) const {
return E->get().subindex;
}
+int BroadPhaseBasic::cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
+
+ int rc = 0;
+
+ for (Map<ID, Element>::Element *E = element_map.front(); E; E = E->next()) {
+
+ const Rect3 aabb = E->get().aabb;
+ if (aabb.has_point(p_point)) {
+
+ p_results[rc] = E->get().owner;
+ p_result_indices[rc] = E->get().subindex;
+ rc++;
+ if (rc >= p_max_results)
+ break;
+ }
+ }
+
+ return rc;
+}
+
int BroadPhaseBasic::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
int rc = 0;
diff --git a/servers/physics/broad_phase_basic.h b/servers/physics/broad_phase_basic.h
index a285204a32..8dabf72f11 100644
--- a/servers/physics/broad_phase_basic.h
+++ b/servers/physics/broad_phase_basic.h
@@ -91,6 +91,7 @@ public:
virtual bool is_static(ID p_id) const;
virtual int get_subindex(ID p_id) const;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
diff --git a/servers/physics/broad_phase_octree.cpp b/servers/physics/broad_phase_octree.cpp
index d18da1b238..2439fbeae9 100644
--- a/servers/physics/broad_phase_octree.cpp
+++ b/servers/physics/broad_phase_octree.cpp
@@ -66,6 +66,11 @@ int BroadPhaseOctree::get_subindex(ID p_id) const {
return octree.get_subindex(p_id);
}
+int BroadPhaseOctree::cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
+
+ return octree.cull_point(p_point, p_results, p_max_results, p_result_indices);
+}
+
int BroadPhaseOctree::cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices) {
return octree.cull_segment(p_from, p_to, p_results, p_max_results, p_result_indices);
diff --git a/servers/physics/broad_phase_octree.h b/servers/physics/broad_phase_octree.h
index 086fb0a1a3..88d72a2bd8 100644
--- a/servers/physics/broad_phase_octree.h
+++ b/servers/physics/broad_phase_octree.h
@@ -56,6 +56,7 @@ public:
virtual bool is_static(ID p_id) const;
virtual int get_subindex(ID p_id) const;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL);
diff --git a/servers/physics/broad_phase_sw.h b/servers/physics/broad_phase_sw.h
index 8fe901c8ef..5564cf5077 100644
--- a/servers/physics/broad_phase_sw.h
+++ b/servers/physics/broad_phase_sw.h
@@ -57,6 +57,7 @@ public:
virtual bool is_static(ID p_id) const = 0;
virtual int get_subindex(ID p_id) const = 0;
+ virtual int cull_point(const Vector3 &p_point, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
virtual int cull_segment(const Vector3 &p_from, const Vector3 &p_to, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
virtual int cull_aabb(const Rect3 &p_aabb, CollisionObjectSW **p_results, int p_max_results, int *p_result_indices = NULL) = 0;
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 15082a0551..a56253e33d 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -64,9 +64,9 @@ private:
Rect3 aabb_cache; //for rayqueries
real_t area_cache;
ShapeSW *shape;
- bool trigger;
+ bool disabled;
- Shape() { trigger = false; }
+ Shape() { disabled = false; }
};
Vector<Shape> shapes;
@@ -131,8 +131,8 @@ public:
_FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable = p_enable; }
_FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; }
- _FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
- _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
+ _FORCE_INLINE_ void set_shape_as_disabled(int p_idx, bool p_enable) { shapes[p_idx].disabled = p_enable; }
+ _FORCE_INLINE_ bool is_shape_set_as_disabled(int p_idx) const { return shapes[p_idx].disabled; }
_FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
_FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 733bd5b63b..101bd4b185 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -330,6 +330,14 @@ void PhysicsServerSW::area_clear_shapes(RID p_area) {
area->remove_shape(0);
}
+void PhysicsServerSW::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+ ERR_FAIL_INDEX(p_shape_idx, area->get_shape_count());
+ area->set_shape_as_disabled(p_shape_idx, p_disabled);
+}
+
void PhysicsServerSW::area_attach_object_instance_ID(RID p_area, ObjectID p_ID) {
if (space_owner.owns(p_area)) {
@@ -551,21 +559,12 @@ RID PhysicsServerSW::body_get_shape(RID p_body, int p_shape_idx) const {
return shape->get_self();
}
-void PhysicsServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) {
+void PhysicsServerSW::body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
ERR_FAIL_INDEX(p_shape_idx, body->get_shape_count());
- body->set_shape_as_trigger(p_shape_idx, p_enable);
-}
-
-bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const {
-
- BodySW *body = body_owner.get(p_body);
- ERR_FAIL_COND_V(!body, false);
- ERR_FAIL_INDEX_V(p_shape_idx, body->get_shape_count(), false);
-
- return body->is_shape_set_as_trigger(p_shape_idx);
+ body->set_shape_as_disabled(p_shape_idx, p_disabled);
}
Transform PhysicsServerSW::body_get_shape_transform(RID p_body, int p_shape_idx) const {
@@ -875,6 +874,16 @@ bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const {
return body->is_ray_pickable();
}
+bool PhysicsServerSW::body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin, MotionResult *r_result) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND_V(!body, false);
+ ERR_FAIL_COND_V(!body->get_space(), false);
+ ERR_FAIL_COND_V(body->get_space()->is_locked(), false);
+
+ return body->get_space()->test_body_motion(body, p_from, p_motion, p_margin, r_result);
+}
+
/* JOINT API */
RID PhysicsServerSW::joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B) {
@@ -1530,8 +1539,9 @@ void PhysicsServerSW::_shape_col_cbk(const Vector3 &p_point_A, const Vector3 &p_
}
}
+PhysicsServerSW *PhysicsServerSW::singleton = NULL;
PhysicsServerSW::PhysicsServerSW() {
-
+ singleton = this;
BroadPhaseSW::create_func = BroadPhaseOctree::_create;
island_count = 0;
active_objects = 0;
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index a0a1bcf963..591fe4af46 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -63,6 +63,8 @@ class PhysicsServerSW : public PhysicsServer {
//void _clear_query(QuerySW *p_query);
public:
+ static PhysicsServerSW *singleton;
+
struct CollCbkData {
int max;
@@ -117,6 +119,8 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx);
virtual void area_clear_shapes(RID p_area);
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled);
+
virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID);
virtual ObjectID area_get_object_instance_ID(RID p_area) const;
@@ -156,8 +160,7 @@ public:
virtual RID body_get_shape(RID p_body, int p_shape_idx) const;
virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable);
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled);
virtual void body_remove_shape(RID p_body, int p_shape_idx);
virtual void body_clear_shapes(RID p_body);
@@ -214,6 +217,8 @@ public:
virtual void body_set_ray_pickable(RID p_body, bool p_enable);
virtual bool body_is_ray_pickable(RID p_body) const;
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL);
+
/* JOINT API */
virtual RID joint_create_pin(RID p_body_A, const Vector3 &p_local_A, RID p_body_B, const Vector3 &p_local_B);
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index a5cea8aff7..b4004c8c94 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -117,6 +117,20 @@ bool PlaneShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_en
return inters;
}
+bool PlaneShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return plane.distance_to(p_point) < 0;
+}
+
+Vector3 PlaneShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ if (plane.is_point_over(p_point)) {
+ return plane.project(p_point);
+ } else {
+ return p_point;
+ }
+}
+
Vector3 PlaneShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3(); //wtf
@@ -184,6 +198,21 @@ bool RayShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end,
return false; //simply not possible
}
+bool RayShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //simply not possible
+}
+
+Vector3 RayShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 s[2] = {
+ Vector3(0, 0, 0),
+ Vector3(0, 0, length)
+ };
+
+ return Geometry::get_closest_point_to_segment(p_point, s);
+}
+
Vector3 RayShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3();
@@ -245,6 +274,20 @@ bool SphereShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_e
return Geometry::segment_intersects_sphere(p_begin, p_end, Vector3(), radius, &r_result, &r_normal);
}
+bool SphereShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return p_point.length() < radius;
+}
+
+Vector3 SphereShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 p = p_point;
+ float l = p.length();
+ if (l < radius)
+ return p_point;
+ return (p / l) * radius;
+}
+
Vector3 SphereShapeSW::get_moment_of_inertia(real_t p_mass) const {
real_t s = 0.4 * p_mass * radius * radius;
@@ -390,6 +433,62 @@ bool BoxShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end,
return aabb.intersects_segment(p_begin, p_end, &r_result, &r_normal);
}
+bool BoxShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return (Math::abs(p_point.x) < half_extents.x && Math::abs(p_point.y) < half_extents.y && Math::abs(p_point.z) < half_extents.z);
+}
+
+Vector3 BoxShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ int outside = 0;
+ Vector3 min_point;
+
+ for (int i = 0; i < 3; i++) {
+
+ if (Math::abs(p_point[i]) > half_extents[i]) {
+ outside++;
+ if (outside == 1) {
+ //use plane if only one side matches
+ Vector3 n;
+ n[i] = SGN(p_point[i]);
+
+ Plane p(n, half_extents[i]);
+ min_point = p.project(p_point);
+ }
+ }
+ }
+
+ if (!outside)
+ return p_point; //it's inside, don't do anything else
+
+ if (outside == 1) //if only above one plane, this plane clearly wins
+ return min_point;
+
+ //check segments
+ float min_distance = 1e20;
+ Vector3 closest_vertex = half_extents * p_point.sign();
+ Vector3 s[2] = {
+ closest_vertex,
+ closest_vertex
+ };
+
+ for (int i = 0; i < 3; i++) {
+
+ s[1] = closest_vertex;
+ s[1][i] = -s[1][i]; //edge
+
+ Vector3 closest_edge = Geometry::get_closest_point_to_segment(p_point, s);
+
+ float d = p_point.distance_to(closest_edge);
+ if (d < min_distance) {
+ min_point = closest_edge;
+ min_distance = d;
+ }
+ }
+
+ return min_point;
+}
+
Vector3 BoxShapeSW::get_moment_of_inertia(real_t p_mass) const {
real_t lx = half_extents.x;
@@ -542,6 +641,32 @@ bool CapsuleShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_
return collision;
}
+bool CapsuleShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ if (Math::abs(p_point.z) < height * 0.5) {
+ return Vector3(p_point.x, p_point.y, 0).length() < radius;
+ } else {
+ Vector3 p = p_point;
+ p.z = Math::abs(p.z) - height * 0.5;
+ return p.length() < radius;
+ }
+}
+
+Vector3 CapsuleShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ Vector3 s[2] = {
+ Vector3(0, 0, -height * 0.5),
+ Vector3(0, 0, height * 0.5),
+ };
+
+ Vector3 p = Geometry::get_closest_point_to_segment(p_point, s);
+
+ if (p.distance_to(p_point) < radius)
+ return p_point;
+
+ return p + (p_point - p).normalized() * radius;
+}
+
Vector3 CapsuleShapeSW::get_moment_of_inertia(real_t p_mass) const {
// use crappy AABB approximation
@@ -738,6 +863,81 @@ bool ConvexPolygonShapeSW::intersect_segment(const Vector3 &p_begin, const Vecto
return col;
}
+bool ConvexPolygonShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ const Geometry::MeshData::Face *faces = mesh.faces.ptr();
+ int fc = mesh.faces.size();
+
+ for (int i = 0; i < fc; i++) {
+
+ if (faces[i].plane.distance_to(p_point) >= 0)
+ return false;
+ }
+
+ return true;
+}
+
+Vector3 ConvexPolygonShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ const Geometry::MeshData::Face *faces = mesh.faces.ptr();
+ int fc = mesh.faces.size();
+ const Vector3 *vertices = mesh.vertices.ptr();
+
+ bool all_inside = true;
+ for (int i = 0; i < fc; i++) {
+
+ if (!faces[i].plane.is_point_over(p_point))
+ continue;
+
+ all_inside = false;
+ bool is_inside = true;
+ int ic = faces[i].indices.size();
+ const int *indices = faces[i].indices.ptr();
+
+ for (int j = 0; j < ic; j++) {
+
+ Vector3 a = vertices[indices[j]];
+ Vector3 b = vertices[indices[(j + 1) % ic]];
+ Vector3 n = (a - b).cross(faces[i].plane.normal).normalized();
+ if (Plane(a, n).is_point_over(p_point)) {
+ is_inside = false;
+ break;
+ }
+ }
+
+ if (is_inside) {
+ return faces[i].plane.project(p_point);
+ }
+ }
+
+ if (all_inside) {
+ return p_point;
+ }
+
+ float min_distance = 1e20;
+ Vector3 min_point;
+
+ //check edges
+ const Geometry::MeshData::Edge *edges = mesh.edges.ptr();
+ int ec = mesh.edges.size();
+ for (int i = 0; i < ec; i++) {
+
+ Vector3 s[2] = {
+ vertices[edges[i].a],
+ vertices[edges[i].b]
+ };
+
+ Vector3 closest = Geometry::get_closest_point_to_segment(p_point, s);
+ float d = closest.distance_to(p_point);
+ if (d < min_distance) {
+ min_distance = d;
+ min_point = closest;
+ }
+ }
+
+ return min_point;
+}
+
Vector3 ConvexPolygonShapeSW::get_moment_of_inertia(real_t p_mass) const {
// use crappy AABB approximation
@@ -880,6 +1080,16 @@ bool FaceShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &p_end
return c;
}
+bool FaceShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //face is flat
+}
+
+Vector3 FaceShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Face3(vertex[0], vertex[1], vertex[2]).get_closest_point_to(p_point);
+}
+
Vector3 FaceShapeSW::get_moment_of_inertia(real_t p_mass) const {
return Vector3(); // Sorry, but i don't think anyone cares, FaceShape!
@@ -1046,6 +1256,16 @@ bool ConcavePolygonShapeSW::intersect_segment(const Vector3 &p_begin, const Vect
}
}
+bool ConcavePolygonShapeSW::intersect_point(const Vector3 &p_point) const {
+
+ return false; //face is flat
+}
+
+Vector3 ConcavePolygonShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Vector3();
+}
+
void ConcavePolygonShapeSW::_cull(int p_idx, _CullParams *p_params) const {
const BVH *bvh = &p_params->bvh[p_idx];
@@ -1471,6 +1691,15 @@ bool HeightMapShapeSW::intersect_segment(const Vector3 &p_begin, const Vector3 &
return false;
}
+bool HeightMapShapeSW::intersect_point(const Vector3 &p_point) const {
+ return false;
+}
+
+Vector3 HeightMapShapeSW::get_closest_point_to(const Vector3 &p_point) const {
+
+ return Vector3();
+}
+
void HeightMapShapeSW::cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const {
}
diff --git a/servers/physics/shape_sw.h b/servers/physics/shape_sw.h
index 808ff0a3a1..aa1975b655 100644
--- a/servers/physics/shape_sw.h
+++ b/servers/physics/shape_sw.h
@@ -87,8 +87,9 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const = 0;
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const = 0;
-
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const = 0;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_point, Vector3 &r_normal) const = 0;
+ virtual bool intersect_point(const Vector3 &p_point) const = 0;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const = 0;
virtual void set_data(const Variant &p_data) = 0;
@@ -134,7 +135,8 @@ public:
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
-
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
virtual void set_data(const Variant &p_data);
@@ -159,6 +161,8 @@ public:
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -185,6 +189,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -209,6 +215,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -237,6 +245,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -261,6 +271,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -338,6 +350,8 @@ public:
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const;
@@ -372,7 +386,9 @@ public:
virtual void project_range(const Vector3 &p_normal, const Transform &p_transform, real_t &r_min, real_t &r_max) const;
virtual Vector3 get_support(const Vector3 &p_normal) const;
virtual bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
virtual void cull(const Rect3 &p_local_aabb, Callback p_callback, void *p_userdata) const;
virtual Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -397,6 +413,8 @@ struct FaceShapeSW : public ShapeSW {
Vector3 get_support(const Vector3 &p_normal) const;
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const;
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const;
+ virtual bool intersect_point(const Vector3 &p_point) const;
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const;
Vector3 get_moment_of_inertia(real_t p_mass) const;
@@ -436,6 +454,8 @@ struct MotionShapeSW : public ShapeSW {
}
virtual void get_supports(const Vector3 &p_normal, int p_max, Vector3 *r_supports, int &r_amount) const { r_amount = 0; }
bool intersect_segment(const Vector3 &p_begin, const Vector3 &p_end, Vector3 &r_result, Vector3 &r_normal) const { return false; }
+ virtual bool intersect_point(const Vector3 &p_point) const { return false; }
+ virtual Vector3 get_closest_point_to(const Vector3 &p_point) const { return p_point; }
Vector3 get_moment_of_inertia(real_t p_mass) const { return Vector3(); }
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index 2bf98cecfa..2d71fd6061 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -45,6 +45,50 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object,
return (1 << body->get_mode()) & p_type_mask;
}
+int PhysicsDirectSpaceStateSW::intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
+
+ ERR_FAIL_COND_V(space->locked, false);
+ int amount = space->broadphase->cull_point(p_point, space->intersection_query_results, SpaceSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
+ int cc = 0;
+
+ //Transform ai = p_xform.affine_inverse();
+
+ for (int i = 0; i < amount; i++) {
+
+ if (cc >= p_result_max)
+ break;
+
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
+ continue;
+
+ //area can't be picked by ray (default)
+
+ if (p_exclude.has(space->intersection_query_results[i]->get_self()))
+ continue;
+
+ const CollisionObjectSW *col_obj = space->intersection_query_results[i];
+ int shape_idx = space->intersection_query_subindex_results[i];
+
+ Transform inv_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+ inv_xform.affine_invert();
+
+ if (!col_obj->get_shape(shape_idx)->intersect_point(inv_xform.xform(p_point)))
+ continue;
+
+ r_results[cc].collider_id = col_obj->get_instance_id();
+ if (r_results[cc].collider_id != 0)
+ r_results[cc].collider = ObjectDB::get_instance(r_results[cc].collider_id);
+ else
+ r_results[cc].collider = NULL;
+ r_results[cc].rid = col_obj->get_self();
+ r_results[cc].shape = shape_idx;
+
+ cc++;
+ }
+
+ return cc;
+}
+
bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, bool p_pick_ray) {
ERR_FAIL_COND_V(space->locked, false);
@@ -428,6 +472,48 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
return true;
}
+Vector3 PhysicsDirectSpaceStateSW::get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const {
+
+ CollisionObjectSW *obj = NULL;
+ obj = PhysicsServerSW::singleton->area_owner.getornull(p_object);
+ if (!obj) {
+ obj = PhysicsServerSW::singleton->body_owner.getornull(p_object);
+ }
+ ERR_FAIL_COND_V(!obj, Vector3());
+
+ ERR_FAIL_COND_V(obj->get_space() != space, Vector3());
+
+ float min_distance = 1e20;
+ Vector3 min_point;
+
+ bool shapes_found = false;
+
+ for (int i = 0; i < obj->get_shape_count(); i++) {
+
+ if (obj->is_shape_set_as_disabled(i))
+ continue;
+
+ Transform shape_xform = obj->get_transform() * obj->get_shape_transform(i);
+ ShapeSW *shape = obj->get_shape(i);
+
+ Vector3 point = shape->get_closest_point_to(shape_xform.affine_inverse().xform(p_point));
+ point = shape_xform.xform(point);
+
+ float dist = point.distance_to(p_point);
+ if (dist < min_distance) {
+ min_distance = dist;
+ min_point = point;
+ }
+ shapes_found = true;
+ }
+
+ if (!shapes_found) {
+ return obj->get_transform().origin; //no shapes found, use distance to origin.
+ } else {
+ return min_point;
+ }
+}
+
PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() {
space = NULL;
@@ -435,6 +521,337 @@ PhysicsDirectSpaceStateSW::PhysicsDirectSpaceStateSW() {
////////////////////////////////////////////////////////////////////////////////////////////////////////////
+int SpaceSW::_cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb) {
+
+ int amount = broadphase->cull_aabb(p_aabb, intersection_query_results, INTERSECTION_QUERY_MAX, intersection_query_subindex_results);
+
+ for (int i = 0; i < amount; i++) {
+
+ bool keep = true;
+
+ if (intersection_query_results[i] == p_body)
+ keep = false;
+ else if (intersection_query_results[i]->get_type() == CollisionObjectSW::TYPE_AREA)
+ keep = false;
+ else if ((static_cast<BodySW *>(intersection_query_results[i])->test_collision_mask(p_body)) == 0)
+ keep = false;
+ else if (static_cast<BodySW *>(intersection_query_results[i])->has_exception(p_body->get_self()) || p_body->has_exception(intersection_query_results[i]->get_self()))
+ keep = false;
+ else if (static_cast<BodySW *>(intersection_query_results[i])->is_shape_set_as_disabled(intersection_query_subindex_results[i]))
+ keep = false;
+
+ if (!keep) {
+
+ if (i < amount - 1) {
+ SWAP(intersection_query_results[i], intersection_query_results[amount - 1]);
+ SWAP(intersection_query_subindex_results[i], intersection_query_subindex_results[amount - 1]);
+ }
+
+ amount--;
+ i--;
+ }
+ }
+
+ return amount;
+}
+
+bool SpaceSW::test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result) {
+
+ //give me back regular physics engine logic
+ //this is madness
+ //and most people using this function will think
+ //what it does is simpler than using physics
+ //this took about a week to get right..
+ //but is it right? who knows at this point..
+
+ if (r_result) {
+ r_result->collider_id = 0;
+ r_result->collider_shape = 0;
+ }
+ Rect3 body_aabb;
+
+ for (int i = 0; i < p_body->get_shape_count(); i++) {
+
+ if (i == 0)
+ body_aabb = p_body->get_shape_aabb(i);
+ else
+ body_aabb = body_aabb.merge(p_body->get_shape_aabb(i));
+ }
+
+ // Undo the currently transform the physics server is aware of and apply the provided one
+ body_aabb = p_from.xform(p_body->get_inv_transform().xform(body_aabb));
+ body_aabb = body_aabb.grow(p_margin);
+
+ Transform body_transform = p_from;
+
+ {
+ //STEP 1, FREE BODY IF STUCK
+
+ const int max_results = 32;
+ int recover_attempts = 4;
+ Vector3 sr[max_results * 2];
+
+ do {
+
+ PhysicsServerSW::CollCbkData cbk;
+ cbk.max = max_results;
+ cbk.amount = 0;
+ cbk.ptr = sr;
+
+ CollisionSolverSW::CallbackResult cbkres = NULL;
+
+ PhysicsServerSW::CollCbkData *cbkptr = NULL;
+ cbkptr = &cbk;
+ cbkres = PhysicsServerSW::_shape_col_cbk;
+
+ bool collided = false;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
+ ShapeSW *body_shape = p_body->get_shape(j);
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ if (CollisionSolverSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), cbkres, cbkptr, NULL, p_margin)) {
+ collided = cbk.amount > 0;
+ }
+ }
+ }
+
+ if (!collided) {
+ break;
+ }
+
+ Vector3 recover_motion;
+
+ for (int i = 0; i < cbk.amount; i++) {
+
+ Vector3 a = sr[i * 2 + 0];
+ Vector3 b = sr[i * 2 + 1];
+
+#if 0
+ Vector3 rel = b-a;
+ real_t d = rel.length();
+ if (d==0)
+ continue;
+
+ Vector3 n = rel/d;
+ real_t traveled = n.dot(recover_motion);
+ a+=n*traveled;
+
+ real_t d = a.distance_to(b);
+ if (d<margin)
+ continue;
+#endif
+ recover_motion += (b - a) * 0.4;
+ }
+
+ if (recover_motion == Vector3()) {
+ collided = false;
+ break;
+ }
+
+ body_transform.origin += recover_motion;
+ body_aabb.position += recover_motion;
+
+ recover_attempts--;
+
+ } while (recover_attempts);
+ }
+
+ real_t safe = 1.0;
+ real_t unsafe = 1.0;
+ int best_shape = -1;
+
+ {
+ // STEP 2 ATTEMPT MOTION
+
+ Rect3 motion_aabb = body_aabb;
+ motion_aabb.position += p_motion;
+ motion_aabb = motion_aabb.merge(body_aabb);
+
+ int amount = _cull_aabb_for_body(p_body, motion_aabb);
+
+ for (int j = 0; j < p_body->get_shape_count(); j++) {
+
+ if (p_body->is_shape_set_as_disabled(j))
+ continue;
+
+ Transform body_shape_xform = body_transform * p_body->get_shape_transform(j);
+ ShapeSW *body_shape = p_body->get_shape(j);
+
+ Transform body_shape_xform_inv = body_shape_xform.affine_inverse();
+ MotionShapeSW mshape;
+ mshape.shape = body_shape;
+ mshape.motion = body_shape_xform_inv.basis.xform(p_motion);
+
+ bool stuck = false;
+
+ real_t best_safe = 1;
+ real_t best_unsafe = 1;
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ //test initial overlap, does it collide if going all the way?
+ Vector3 point_A, point_B;
+ Vector3 sep_axis = p_motion.normalized();
+
+ Transform col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
+ //test initial overlap, does it collide if going all the way?
+ if (CollisionSolverSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
+ //print_line("failed motion cast (no collision)");
+ continue;
+ }
+ sep_axis = p_motion.normalized();
+
+ if (!CollisionSolverSW::solve_distance(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, point_A, point_B, motion_aabb, &sep_axis)) {
+ //print_line("failed motion cast (no collision)");
+ stuck = true;
+ break;
+ }
+
+ //just do kinematic solving
+ real_t low = 0;
+ real_t hi = 1;
+ Vector3 mnormal = p_motion.normalized();
+
+ for (int i = 0; i < 8; i++) { //steps should be customizable..
+
+ real_t ofs = (low + hi) * 0.5;
+
+ Vector3 sep = mnormal; //important optimization for this to work fast enough
+
+ mshape.motion = body_shape_xform_inv.basis.xform(p_motion * ofs);
+
+ Vector3 lA, lB;
+
+ bool collided = !CollisionSolverSW::solve_distance(&mshape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj_xform, lA, lB, motion_aabb, &sep);
+
+ if (collided) {
+
+ //print_line(itos(i)+": "+rtos(ofs));
+ hi = ofs;
+ } else {
+
+ point_A = lA;
+ point_B = lB;
+ low = ofs;
+ }
+ }
+
+ if (low < best_safe) {
+ best_safe = low;
+ best_unsafe = hi;
+ }
+ }
+
+ if (stuck) {
+
+ safe = 0;
+ unsafe = 0;
+ best_shape = j; //sadly it's the best
+ break;
+ }
+ if (best_safe == 1.0) {
+ continue;
+ }
+ if (best_safe < safe) {
+
+ safe = best_safe;
+ unsafe = best_unsafe;
+ best_shape = j;
+ }
+ }
+ }
+
+ bool collided = false;
+ if (safe >= 1) {
+ //not collided
+ collided = false;
+ if (r_result) {
+
+ r_result->motion = p_motion;
+ r_result->remainder = Vector3();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ } else {
+
+ //it collided, let's get the rest info in unsafe advance
+ Transform ugt = body_transform;
+ ugt.origin += p_motion * unsafe;
+
+ _RestCallbackData rcd;
+ rcd.best_len = 0;
+ rcd.best_object = NULL;
+ rcd.best_shape = 0;
+
+ Transform body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
+ ShapeSW *body_shape = p_body->get_shape(best_shape);
+
+ body_aabb.position += p_motion * unsafe;
+
+ int amount = _cull_aabb_for_body(p_body, body_aabb);
+
+ for (int i = 0; i < amount; i++) {
+
+ const CollisionObjectSW *col_obj = intersection_query_results[i];
+ int shape_idx = intersection_query_subindex_results[i];
+
+ rcd.object = col_obj;
+ rcd.shape = shape_idx;
+ bool sc = CollisionSolverSW::solve_static(body_shape, body_shape_xform, col_obj->get_shape(shape_idx), col_obj->get_transform() * col_obj->get_shape_transform(shape_idx), _rest_cbk_result, &rcd, NULL, p_margin);
+ if (!sc)
+ continue;
+ }
+
+ if (rcd.best_len != 0) {
+
+ if (r_result) {
+ r_result->collider = rcd.best_object->get_self();
+ r_result->collider_id = rcd.best_object->get_instance_id();
+ r_result->collider_shape = rcd.best_shape;
+ r_result->collision_local_shape = best_shape;
+ r_result->collision_normal = rcd.best_normal;
+ r_result->collision_point = rcd.best_contact;
+ //r_result->collider_metadata = rcd.best_object->get_shape_metadata(rcd.best_shape);
+
+ const BodySW *body = static_cast<const BodySW *>(rcd.best_object);
+ //Vector3 rel_vec = r_result->collision_point - body->get_transform().get_origin();
+ // r_result->collider_velocity = Vector3(-body->get_angular_velocity() * rel_vec.y, body->get_angular_velocity() * rel_vec.x) + body->get_linear_velocity();
+ r_result->collider_velocity = body->get_linear_velocity() + (body->get_angular_velocity()).cross(body->get_transform().origin - rcd.best_contact); // * mPos);
+
+ r_result->motion = safe * p_motion;
+ r_result->remainder = p_motion - safe * p_motion;
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ collided = true;
+ } else {
+ if (r_result) {
+
+ r_result->motion = p_motion;
+ r_result->remainder = Vector3();
+ r_result->motion += (body_transform.get_origin() - p_from.get_origin());
+ }
+
+ collided = false;
+ }
+ }
+
+ return collided;
+}
+
void *SpaceSW::_broadphase_pair(CollisionObjectSW *A, int p_subindex_A, CollisionObjectSW *B, int p_subindex_B, void *p_self) {
CollisionObjectSW::Type type_A = A->get_type();
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index b0e54f647c..6ef12dbeae 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -47,11 +47,13 @@ class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
public:
SpaceSW *space;
+ virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const;
PhysicsDirectSpaceStateSW();
};
@@ -120,6 +122,8 @@ private:
friend class PhysicsDirectSpaceStateSW;
+ int _cull_aabb_for_body(BodySW *p_body, const Rect3 &p_aabb);
+
public:
_FORCE_INLINE_ void set_self(const RID &p_self) { self = p_self; }
_FORCE_INLINE_ RID get_self() const { return self; }
@@ -192,6 +196,8 @@ public:
void set_elapsed_time(ElapsedTime p_time, uint64_t p_msec) { elapsed_time[p_time] = p_msec; }
uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; }
+ bool test_body_motion(BodySW *p_body, const Transform &p_from, const Vector3 &p_motion, real_t p_margin, PhysicsServer::MotionResult *r_result);
+
SpaceSW();
~SpaceSW();
};
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.cpp b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
index d92c033e35..d39231b161 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.cpp
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.cpp
@@ -161,12 +161,12 @@ Physics2DServerWrapMT::Physics2DServerWrapMT(Physics2DServer *p_contained, bool
step_thread_up = false;
alloc_mutex = Mutex::create();
- shape_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- area_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- body_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- pin_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- groove_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
- damped_spring_joint_pool_max_size = GLOBAL_GET("memory/multithread/thread_rid_pool_prealloc");
+ shape_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ area_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ body_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ pin_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ groove_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
+ damped_spring_joint_pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
if (!p_create_thread) {
server_thread = Thread::get_caller_ID();
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index 7049a9cf34..c407a17bc6 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -809,162 +809,6 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
return collided;
-
-#if 0
- //give me back regular physics engine logic
- //this is madness
- //and most people using this function will think
- //what it does is simpler than using physics
- //this took about a week to get right..
- //but is it right? who knows at this point..
-
-
- colliding=false;
- ERR_FAIL_COND_V(!is_inside_tree(),Vector2());
- Physics2DDirectSpaceState *dss = Physics2DServer::get_singleton()->space_get_direct_state(get_world_2d()->get_space());
- ERR_FAIL_COND_V(!dss,Vector2());
- const int max_shapes=32;
- Vector2 sr[max_shapes*2];
- int res_shapes;
-
- Set<RID> exclude;
- exclude.insert(get_rid());
-
-
- //recover first
- int recover_attempts=4;
-
- bool collided=false;
- uint32_t mask=0;
- if (collide_static)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_STATIC_BODY;
- if (collide_kinematic)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_KINEMATIC_BODY;
- if (collide_rigid)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_RIGID_BODY;
- if (collide_character)
- mask|=Physics2DDirectSpaceState::TYPE_MASK_CHARACTER_BODY;
-
- //print_line("motion: "+p_motion+" margin: "+rtos(margin));
-
- //print_line("margin: "+rtos(margin));
- do {
-
- //motion recover
- for(int i=0;i<get_shape_count();i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
- if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask))
- collided=true;
-
- }
-
- if (!collided)
- break;
-
- Vector2 recover_motion;
-
- for(int i=0;i<res_shapes;i++) {
-
- Vector2 a = sr[i*2+0];
- Vector2 b = sr[i*2+1];
-
- real_t d = a.distance_to(b);
-
- /*
- if (d<margin)
- continue;
- */
- recover_motion+=(b-a)*0.4;
- }
-
- if (recover_motion==Vector2()) {
- collided=false;
- break;
- }
-
- Matrix32 gt = get_global_transform();
- gt.elements[2]+=recover_motion;
- set_global_transform(gt);
-
- recover_attempts--;
-
- } while (recover_attempts);
-
-
- //move second
- real_t safe = 1.0;
- real_t unsafe = 1.0;
- int best_shape=-1;
-
- for(int i=0;i<get_shape_count();i++) {
-
- if (is_shape_set_as_trigger(i))
- continue;
-
- real_t lsafe,lunsafe;
- bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask);
- //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
- if (!valid) {
-
- safe=0;
- unsafe=0;
- best_shape=i; //sadly it's the best
- break;
- }
- if (lsafe==1.0) {
- continue;
- }
- if (lsafe < safe) {
-
- safe=lsafe;
- unsafe=lunsafe;
- best_shape=i;
- }
- }
-
-
- //print_line("best shape: "+itos(best_shape)+" motion "+p_motion);
-
- if (safe>=1) {
- //not collided
- colliding=false;
- } else {
-
- //it collided, let's get the rest info in unsafe advance
- Matrix32 ugt = get_global_transform();
- ugt.elements[2]+=p_motion*unsafe;
- Physics2DDirectSpaceState::ShapeRestInfo rest_info;
- bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask);
- if (!c2) {
- //should not happen, but floating point precision is so weird..
-
- colliding=false;
- } else {
-
-
- //print_line("Travel: "+rtos(travel));
- colliding=true;
- collision=rest_info.point;
- normal=rest_info.normal;
- collider=rest_info.collider_id;
- collider_vel=rest_info.linear_velocity;
- collider_shape=rest_info.shape;
- collider_metadata=rest_info.metadata;
- }
-
- }
-
- Vector2 motion=p_motion*safe;
- Matrix32 gt = get_global_transform();
- gt.elements[2]+=motion;
- set_global_transform(gt);
-
- return p_motion-motion;
-
-#endif
- return false;
}
void *Space2DSW::_broadphase_pair(CollisionObject2DSW *A, int p_subindex_A, CollisionObject2DSW *B, int p_subindex_B, void *p_self) {
@@ -1186,7 +1030,7 @@ Space2DSW::Space2DSW() {
contact_max_allowed_penetration = 0.3;
constraint_bias = 0.2;
- body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threashold_linear", 2.0);
+ body_linear_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_linear", 2.0);
body_angular_velocity_sleep_threshold = GLOBAL_DEF("physics/2d/sleep_threshold_angular", (8.0 / 180.0 * Math_PI));
body_time_to_sleep = GLOBAL_DEF("physics/2d/time_before_sleep", 0.5);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 21c65a74d0..0f07fca637 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -156,26 +156,28 @@ protected:
static void _bind_methods();
public:
- struct RayResult {
+ struct ShapeResult {
- Vector3 position;
- Vector3 normal;
RID rid;
ObjectID collider_id;
Object *collider;
int shape;
};
- virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
+ virtual int intersect_point(const Vector3 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- struct ShapeResult {
+ struct RayResult {
+ Vector3 position;
+ Vector3 normal;
RID rid;
ObjectID collider_id;
Object *collider;
int shape;
};
+ virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
+
virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeRestInfo {
@@ -194,6 +196,8 @@ public:
virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual Vector3 get_closest_point_to_object_volume(RID p_object, const Vector3 p_point) const = 0;
+
PhysicsDirectSpaceState();
};
@@ -322,6 +326,8 @@ public:
virtual void area_remove_shape(RID p_area, int p_shape_idx) = 0;
virtual void area_clear_shapes(RID p_area) = 0;
+ virtual void area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) = 0;
+
virtual void area_attach_object_instance_ID(RID p_area, ObjectID p_ID) = 0;
virtual ObjectID area_get_object_instance_ID(RID p_area) const = 0;
@@ -370,12 +376,11 @@ public:
virtual RID body_get_shape(RID p_body, int p_shape_idx) const = 0;
virtual Transform body_get_shape_transform(RID p_body, int p_shape_idx) const = 0;
- virtual void body_set_shape_as_trigger(RID p_body, int p_shape_idx, bool p_enable) = 0;
- virtual bool body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) const = 0;
-
virtual void body_remove_shape(RID p_body, int p_shape_idx) = 0;
virtual void body_clear_shapes(RID p_body) = 0;
+ virtual void body_set_shape_disabled(RID p_body, int p_shape_idx, bool p_disabled) = 0;
+
virtual void body_attach_object_instance_ID(RID p_body, uint32_t p_ID) = 0;
virtual uint32_t body_get_object_instance_ID(RID p_body) const = 0;
@@ -458,6 +463,23 @@ public:
virtual void body_set_ray_pickable(RID p_body, bool p_enable) = 0;
virtual bool body_is_ray_pickable(RID p_body) const = 0;
+ struct MotionResult {
+
+ Vector3 motion;
+ Vector3 remainder;
+
+ Vector3 collision_point;
+ Vector3 collision_normal;
+ Vector3 collider_velocity;
+ int collision_local_shape;
+ ObjectID collider_id;
+ RID collider;
+ int collider_shape;
+ Variant collider_metadata;
+ };
+
+ virtual bool body_test_motion(RID p_body, const Transform &p_from, const Vector3 &p_motion, float p_margin = 0.001, MotionResult *r_result = NULL) = 0;
+
/* JOINT API */
enum JointType {
diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp
index 79b994dd27..8ee431cc68 100644
--- a/servers/register_server_types.cpp
+++ b/servers/register_server_types.cpp
@@ -73,8 +73,6 @@ ShaderTypes *shader_types = NULL;
void register_server_types() {
- GLOBAL_DEF("memory/multithread/thread_rid_pool_prealloc", 20);
-
GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("VisualServer", VisualServer::get_singleton()));
GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("AudioServer", AudioServer::get_singleton()));
GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("PhysicsServer", PhysicsServer::get_singleton()));
@@ -84,6 +82,7 @@ void register_server_types() {
ClassDB::register_virtual_class<AudioStream>();
ClassDB::register_virtual_class<AudioStreamPlayback>();
+ ClassDB::register_class<AudioStreamRandomPitch>();
ClassDB::register_virtual_class<AudioEffect>();
ClassDB::register_class<AudioBusLayout>();
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index ca80d5e457..9c264ead49 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -109,19 +109,20 @@ public:
bool mirror : 8;
bool receive_shadows : 8;
bool visible : 8;
+ bool baked_light : 8; //this flag is only to know if it actually did use baked light
float depth; //used for sorting
SelfList<InstanceBase> dependency_item;
- InstanceBase *baked_light; //baked light to use
- SelfList<InstanceBase> baked_light_item;
+ //InstanceBase *baked_light; //baked light to use
+ //SelfList<InstanceBase> baked_light_item;
virtual void base_removed() = 0;
virtual void base_changed() = 0;
virtual void base_material_changed() = 0;
InstanceBase()
- : dependency_item(this), baked_light_item(this) {
+ : dependency_item(this) {
base_type = VS::INSTANCE_NONE;
cast_shadows = VS::SHADOW_CASTING_SETTING_ON;
@@ -129,7 +130,7 @@ public:
visible = true;
depth_layer = 0;
layer_mask = 1;
- baked_light = NULL;
+ baked_light = false;
}
};
@@ -422,6 +423,9 @@ public:
virtual void gi_probe_set_bias(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_bias(RID p_probe) const = 0;
+ virtual void gi_probe_set_normal_bias(RID p_probe, float p_range) = 0;
+ virtual float gi_probe_get_normal_bias(RID p_probe) const = 0;
+
virtual void gi_probe_set_propagation(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_propagation(RID p_probe) const = 0;
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 1573116c50..58481fc3f6 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -844,6 +844,9 @@ public:
BIND2(gi_probe_set_bias, RID, float)
BIND1RC(float, gi_probe_get_bias, RID)
+ BIND2(gi_probe_set_normal_bias, RID, float)
+ BIND1RC(float, gi_probe_get_normal_bias, RID)
+
BIND2(gi_probe_set_propagation, RID, float)
BIND1RC(float, gi_probe_get_propagation, RID)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index fb1c66d0b9..97583dc849 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -993,6 +993,11 @@ void VisualServerScene::instance_geometry_set_flag(RID p_instance, VS::InstanceF
instance->visible_in_all_rooms = p_enabled;
} break;
+ case VS::INSTANCE_FLAG_USE_BAKED_LIGHT: {
+
+ instance->baked_light = p_enabled;
+
+ } break;
}
}
void VisualServerScene::instance_geometry_set_cast_shadows_setting(RID p_instance, VS::ShadowCastingSetting p_shadow_casting_setting) {
@@ -1482,6 +1487,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// a pre pass will need to be needed to determine the actual z-near to be used
+ Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
+
for (int j = 0; j < cull_count; j++) {
float min, max;
@@ -1494,6 +1501,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
}
instance->transformed_aabb.project_range_in_plane(Plane(z_vec, 0), min, max);
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
if (max > z_max)
z_max = max;
}
@@ -1539,6 +1548,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
planes[4] = p_instance->transform.xform(Plane(Vector3(0, -1, z).normalized(), radius));
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(p_instance->transform.origin, p_instance->transform.basis.get_axis(2) * z);
for (int j = 0; j < cull_count; j++) {
@@ -1547,6 +1557,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1587,6 +1600,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(xform.origin, -xform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1594,6 +1608,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1619,6 +1636,7 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
Vector<Plane> planes = cm.get_projection_planes(p_instance->transform);
int cull_count = p_scenario->octree.cull_convex(planes, instance_shadow_cull_result, MAX_INSTANCE_CULL, VS::INSTANCE_GEOMETRY_MASK);
+ Plane near_plane(p_instance->transform.origin, -p_instance->transform.basis.get_axis(2));
for (int j = 0; j < cull_count; j++) {
Instance *instance = instance_shadow_cull_result[j];
@@ -1626,6 +1644,9 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
cull_count--;
SWAP(instance_shadow_cull_result[j], instance_shadow_cull_result[cull_count]);
j--;
+ } else {
+ instance->depth = near_plane.distance_to(instance->transform.origin);
+ instance->depth_layer = 0;
}
}
@@ -1833,7 +1854,7 @@ void VisualServerScene::_render_scene(const Transform p_cam_transform, const Cam
if (reflection_probe->reflection_dirty || VSG::scene_render->reflection_probe_instance_needs_redraw(reflection_probe->instance)) {
if (!reflection_probe->update_list.in_list()) {
reflection_probe->render_step = 0;
- reflection_probe_render_list.add(&reflection_probe->update_list);
+ reflection_probe_render_list.add_last(&reflection_probe->update_list);
}
reflection_probe->reflection_dirty = false;
@@ -3344,6 +3365,8 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
for (int i = 0; i < dp; i++) {
RID mesh = VSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
+ if (!mesh.is_valid())
+ continue;
int sc = VSG::storage->mesh_get_surface_count(mesh);
for (int j = 0; j < sc; j++) {
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 433b6e945e..4d53181b43 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -265,7 +265,7 @@ void VisualServerViewport::draw_viewports() {
//draw viewports
- clear_color = GLOBAL_GET("rendering/viewport/default_clear_color");
+ clear_color = GLOBAL_GET("rendering/environment/default_clear_color");
active_viewports.sort_custom<ViewportSort>();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
index fd15633244..a358e99fb3 100644
--- a/servers/visual/visual_server_wrap_mt.cpp
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -176,7 +176,7 @@ VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_
draw_pending = 0;
draw_thread_up = false;
alloc_mutex = Mutex::create();
- pool_max_size = GLOBAL_DEF("memory/servers/thread_rid_prealloc_amount", 20);
+ pool_max_size = GLOBAL_GET("memory/limits/multithreaded_server/rid_pool_prealloc");
if (!p_create_thread) {
server_thread = Thread::get_caller_ID();
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index 6a1b0f7e46..4567d87706 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -288,6 +288,9 @@ public:
FUNC2(gi_probe_set_bias, RID, float)
FUNC1RC(float, gi_probe_get_bias, RID)
+ FUNC2(gi_probe_set_normal_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_normal_bias, RID)
+
FUNC2(gi_probe_set_propagation, RID, float)
FUNC1RC(float, gi_probe_get_propagation, RID)
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index c833f4eabd..1e217649ba 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1567,10 +1567,22 @@ VisualServer::VisualServer() {
//ERR_FAIL_COND(singleton);
singleton = this;
- GLOBAL_DEF("rendering/vram_formats/use_s3tc", true);
- GLOBAL_DEF("rendering/vram_formats/use_etc", false);
- GLOBAL_DEF("rendering/vram_formats/use_etc2", true);
- GLOBAL_DEF("rendering/vram_formats/use_pvrtc", false);
+ GLOBAL_DEF("rendering/vram_compression/import_s3tc", true);
+ GLOBAL_DEF("rendering/vram_compression/import_etc", false);
+ GLOBAL_DEF("rendering/vram_compression/import_etc2", true);
+ GLOBAL_DEF("rendering/vram_compression/import_pvrtc", false);
+
+ GLOBAL_DEF("rendering/quality/directional_shadow/size", 4096);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/size", 4096);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/shadow_atlas/size", PropertyInfo(Variant::INT, "rendering/shadow_atlas/size", PROPERTY_HINT_RANGE, "256,16384"));
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_0_subdiv", 1);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_1_subdiv", 2);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_2_subdiv", 3);
+ GLOBAL_DEF("rendering/quality/shadow_atlas/quadrant_3_subdiv", 4);
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_0_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_0_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_1_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_1_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_2_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_2_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/quality/shadow_atlas/quadrant_3_subdiv", PropertyInfo(Variant::INT, "rendering/quality/shadow_atlas/quadrant_3_subdiv", PROPERTY_HINT_ENUM, "Disabled,1 Shadow,4 Shadows,16 Shadows,64 Shadows,256 Shadows,1024 Shadows"));
}
VisualServer::~VisualServer() {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index fbd7fc16ac..f515a7b990 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -463,6 +463,9 @@ public:
virtual void gi_probe_set_bias(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_bias(RID p_probe) const = 0;
+ virtual void gi_probe_set_normal_bias(RID p_probe, float p_range) = 0;
+ virtual float gi_probe_get_normal_bias(RID p_probe) const = 0;
+
virtual void gi_probe_set_propagation(RID p_probe, float p_range) = 0;
virtual float gi_probe_get_propagation(RID p_probe) const = 0;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index ef4f83d4ad..0067f0ff26 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -107,7 +107,7 @@ Files extracted from upstream source:
## libpng
- Upstream: http://libpng.org/pub/png/libpng.html
-- Version: 1.6.28
+- Version: 1.6.30
- License: libpng/zlib
Files extracted from upstream source:
diff --git a/thirdparty/libpng/png.c b/thirdparty/libpng/png.c
index 2c9fea2123..40688be123 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.29 [March 16, 2017]
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
* 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_29 Your_png_h_is_not_version_1_6_29;
+typedef png_libpng_version_1_6_30 Your_png_h_is_not_version_1_6_30;
/* Tells libpng that we have already handled the first "num_bytes" bytes
* of the PNG file signature. If the PNG data is embedded into another
@@ -776,14 +776,14 @@ png_get_copyright(png_const_structrp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
- "libpng version 1.6.29 - March 16, 2017" PNG_STRING_NEWLINE \
+ "libpng version 1.6.30 - June 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.29 - March 16, 2017\
+ return "libpng version 1.6.30 - June 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.";
@@ -2832,7 +2832,7 @@ png_pow10(int power)
if (power < 0)
{
if (power < DBL_MIN_10_EXP) return 0;
- recip = 1, power = -power;
+ recip = 1; power = -power;
}
if (power > 0)
@@ -2910,7 +2910,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
double test = png_pow10(exp_b10+1);
if (test <= DBL_MAX)
- ++exp_b10, base = test;
+ {
+ ++exp_b10; base = test;
+ }
else
break;
@@ -2924,7 +2926,10 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
* test on DBL_MAX above.
*/
fp /= base;
- while (fp >= 1) fp /= 10, ++exp_b10;
+ while (fp >= 1)
+ {
+ fp /= 10; ++exp_b10;
+ }
/* Because of the code above fp may, at this point, be
* less than .1, this is ok because the code below can
@@ -2975,7 +2980,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
/* Rounding up to 10, handle that here. */
if (czero > 0)
{
- --czero, d = 1;
+ --czero; d = 1;
if (cdigits == 0) --clead;
}
else
@@ -2989,7 +2994,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
else if (ch == 46)
{
- ch = *--ascii, ++size;
+ ch = *--ascii; ++size;
/* Advance exp_b10 to '1', so that the
* decimal point happens after the
* previous digit.
@@ -3016,7 +3021,9 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
int ch = *--ascii;
if (ch == 46)
- ++size, exp_b10 = 1;
+ {
+ ++size; exp_b10 = 1;
+ }
/* Else lost a leading zero, so 'exp_b10' is
* still ok at (-1)
@@ -3052,21 +3059,26 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
*/
if (exp_b10 != (-1))
{
- if (exp_b10 == 0) *ascii++ = 46, --size;
+ if (exp_b10 == 0)
+ {
+ *ascii++ = 46; --size;
+ }
/* PLUS 1: TOTAL 4 */
--exp_b10;
}
- *ascii++ = 48, --czero;
+ *ascii++ = 48; --czero;
}
if (exp_b10 != (-1))
{
if (exp_b10 == 0)
- *ascii++ = 46, --size; /* counted above */
+ {
+ *ascii++ = 46; --size; /* counted above */
+ }
--exp_b10;
}
- *ascii++ = (char)(48 + (int)d), ++cdigits;
+ *ascii++ = (char)(48 + (int)d); ++cdigits;
}
}
while (cdigits+czero < precision+clead && fp > DBL_MIN);
@@ -3107,7 +3119,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
*/
size -= cdigits;
- *ascii++ = 69, --size; /* 'E': PLUS 1 TOTAL 2+precision */
+ *ascii++ = 69; --size; /* 'E': PLUS 1 TOTAL 2+precision */
/* The following use of an unsigned temporary avoids ambiguities in
* the signed arithmetic on exp_b10 and permits GCC at least to do
@@ -3118,7 +3130,7 @@ png_ascii_from_fp(png_const_structrp png_ptr, png_charp ascii, png_size_t size,
if (exp_b10 < 0)
{
- *ascii++ = 45, --size; /* '-': PLUS 1 TOTAL 3+precision */
+ *ascii++ = 45; --size; /* '-': PLUS 1 TOTAL 3+precision */
uexp_b10 = (unsigned int)(-exp_b10);
}
@@ -3185,7 +3197,9 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
/* Avoid overflow here on the minimum integer. */
if (fp < 0)
- *ascii++ = 45, num = (png_uint_32)(-fp);
+ {
+ *ascii++ = 45; num = (png_uint_32)(-fp);
+ }
else
num = (png_uint_32)fp;
@@ -3223,7 +3237,10 @@ png_ascii_from_fixed(png_const_structrp png_ptr, png_charp ascii,
* then ndigits digits to first:
*/
i = 5;
- while (ndigits < i) *ascii++ = 48, --i;
+ while (ndigits < i)
+ {
+ *ascii++ = 48; --i;
+ }
while (ndigits >= first) *ascii++ = digits[--ndigits];
/* Don't output the trailing zeros! */
}
@@ -4278,7 +4295,7 @@ png_set_option(png_structrp png_ptr, int option, int onoff)
defined(PNG_SIMPLIFIED_WRITE_SUPPORTED)
/* sRGB conversion tables; these are machine generated with the code in
* contrib/tools/makesRGB.c. The actual sRGB transfer curve defined in the
- * specification (see the article at http://en.wikipedia.org/wiki/SRGB)
+ * specification (see the article at https://en.wikipedia.org/wiki/SRGB)
* is used, not the gamma=1/2.2 approximation use elsewhere in libpng.
* The sRGB to linear table is exact (to the nearest 16-bit linear fraction).
* The inverse (linear to sRGB) table has accuracies as follows:
diff --git a/thirdparty/libpng/png.h b/thirdparty/libpng/png.h
index 2431e0dfc0..c2c4fdf251 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.29, March 16, 2017
+ * libpng version 1.6.30, June 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.29, March 16, 2017:
+ * libpng versions 0.97, January 1998, through 1.6.30, June 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.29, March 16, 2017 are
+ * libpng versions 1.0.7, July 1, 2000 through 1.6.30, June 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.29 16 10629 16.so.16.29[.0]
+ * 1.6.30 16 10630 16.so.16.30[.0]
*
* Henceforth the source version will match the shared-library major
* and minor numbers; the shared-library major version number will be
@@ -234,20 +234,20 @@
*
* See libpng.txt or libpng.3 for more information. The PNG specification
* is available as a W3C Recommendation and as an ISO Specification,
- * <http://www.w3.org/TR/2003/REC-PNG-20031110/
+ * <https://www.w3.org/TR/2003/REC-PNG-20031110/
*/
/*
* Y2K compliance in libpng:
* =========================
*
- * March 16, 2017
+ * June 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.29 are Y2K compliant. It is my belief that
+ * upward through 1.6.30 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.29"
-#define PNG_HEADER_VERSION_STRING " libpng version 1.6.29 - March 16, 2017\n"
+#define PNG_LIBPNG_VER_STRING "1.6.30"
+#define PNG_HEADER_VERSION_STRING " libpng version 1.6.30 - June 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 29
+#define PNG_LIBPNG_VER_RELEASE 30
/* 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 10629 /* 1.6.29 */
+#define PNG_LIBPNG_VER 10630 /* 1.6.30 */
/* 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_29;
+typedef char* png_libpng_version_1_6_30;
/* Basic control structions. Read libpng-manual.txt or libpng.3 for more info.
*
@@ -2753,7 +2753,7 @@ typedef struct
*
* When the simplified API needs to convert between sRGB and linear colorspaces,
* the actual sRGB transfer curve defined in the sRGB specification (see the
- * article at http://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
+ * article at https://en.wikipedia.org/wiki/SRGB) is used, not the gamma=1/2.2
* approximation used elsewhere in libpng.
*
* When an alpha channel is present it is expected to denote pixel coverage
diff --git a/thirdparty/libpng/pngconf.h b/thirdparty/libpng/pngconf.h
index 78d8b92b0e..f64592acd7 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.29, March 16, 2017
+ * libpng version 1.6.30, June 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 82f6ba4619..da3d8359f4 100644
--- a/thirdparty/libpng/pnglibconf.h
+++ b/thirdparty/libpng/pnglibconf.h
@@ -1,10 +1,10 @@
-/* libpng 1.6.29 STANDARD API DEFINITION */
+/* libpng 1.6.30 STANDARD API DEFINITION */
/* pnglibconf.h - library build configuration */
-/* Libpng version 1.6.29 - March 16, 2017 */
+/* Libpng version 1.6.30 - June 28, 2017 */
-/* Copyright (c) 1998-2015 Glenn Randers-Pehrson */
+/* Copyright (c) 1998-2017 Glenn Randers-Pehrson */
/* This code is released under the libpng license. */
/* For conditions of distribution and use, see the disclaimer */
diff --git a/thirdparty/libpng/pngpriv.h b/thirdparty/libpng/pngpriv.h
index 6d2e424d2e..a062a8da16 100644
--- a/thirdparty/libpng/pngpriv.h
+++ b/thirdparty/libpng/pngpriv.h
@@ -1,7 +1,7 @@
/* pngpriv.h - private declarations for use inside libpng
*
- * Last changed in libpng 1.6.29 [March 16, 2017]
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
* 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.)
@@ -466,7 +466,16 @@
static_cast<type>(static_cast<const void*>(value))
#else
# define png_voidcast(type, value) (value)
-# define png_constcast(type, value) ((type)(value))
+# ifdef _WIN64
+# ifdef __GNUC__
+ typedef unsigned long long png_ptruint;
+# else
+ typedef unsigned __int64 png_ptruint;
+# endif
+# else
+ typedef unsigned long png_ptruint;
+# endif
+# define png_constcast(type, value) ((type)(png_ptruint)(const void*)(value))
# define png_aligncast(type, value) ((void*)(value))
# define png_aligncastconst(type, value) ((const void*)(value))
#endif /* __cplusplus */
diff --git a/thirdparty/libpng/pngrtran.c b/thirdparty/libpng/pngrtran.c
index 16c1ed6086..3886833af0 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.29 [March 16, 2017]
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
* 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.)
@@ -2934,7 +2934,7 @@ png_do_gray_to_rgb(png_row_infop row_info, png_bytep row)
* using the equation given in Poynton's ColorFAQ of 1998-01-04 at
* <http://www.inforamp.net/~poynton/> (THIS LINK IS DEAD June 2008 but
* versions dated 1998 through November 2002 have been archived at
- * http://web.archive.org/web/20000816232553/http://www.inforamp.net/
+ * https://web.archive.org/web/20000816232553/www.inforamp.net/
* ~poynton/notes/colour_and_gamma/ColorFAQ.txt )
* Charles Poynton poynton at poynton.com
*
@@ -4601,7 +4601,9 @@ png_do_expand_16(png_row_infop row_info, png_bytep row)
png_byte *sp = row + row_info->rowbytes; /* source, last byte + 1 */
png_byte *dp = sp + row_info->rowbytes; /* destination, end + 1 */
while (dp > sp)
- dp[-2] = dp[-1] = *--sp, dp -= 2;
+ {
+ dp[-2] = dp[-1] = *--sp; dp -= 2;
+ }
row_info->rowbytes *= 2;
row_info->bit_depth = 16;
diff --git a/thirdparty/libpng/pngrutil.c b/thirdparty/libpng/pngrutil.c
index 76f079a69f..f60545bf90 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.29 [March 16, 2017]
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
* 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.)
@@ -2537,6 +2537,9 @@ png_handle_zTXt(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
if ((png_ptr->mode & PNG_HAVE_IDAT) != 0)
png_ptr->mode |= PNG_AFTER_IDAT;
+ /* Note, "length" is sufficient here; we won't be adding
+ * a null terminator later.
+ */
buffer = png_read_buffer(png_ptr, length, 2/*silent*/);
if (buffer == NULL)
@@ -3377,7 +3380,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
*/
do
{
- dp[0] = sp[0], dp[1] = sp[1];
+ dp[0] = sp[0]; dp[1] = sp[1];
if (row_width <= bytes_to_jump)
return;
@@ -3398,7 +3401,7 @@ png_combine_row(png_const_structrp png_ptr, png_bytep dp, int display)
*/
for (;;)
{
- dp[0] = sp[0], dp[1] = sp[1], dp[2] = sp[2];
+ dp[0] = sp[0]; dp[1] = sp[1]; dp[2] = sp[2];
if (row_width <= bytes_to_jump)
return;
@@ -3887,7 +3890,10 @@ png_read_filter_row_paeth_1byte_pixel(png_row_infop row_info, png_bytep row,
/* Find the best predictor, the least of pa, pb, pc favoring the earlier
* ones in the case of a tie.
*/
- if (pb < pa) pa = pb, a = b;
+ if (pb < pa)
+ {
+ pa = pb; a = b;
+ }
if (pc < pa) a = c;
/* Calculate the current pixel in a, and move the previous row pixel to c
@@ -3939,7 +3945,10 @@ png_read_filter_row_paeth_multibyte_pixel(png_row_infop row_info, png_bytep row,
pc = (p + pc) < 0 ? -(p + pc) : p + pc;
#endif
- if (pb < pa) pa = pb, a = b;
+ if (pb < pa)
+ {
+ pa = pb; a = b;
+ }
if (pc < pa) a = c;
a += *row;
diff --git a/thirdparty/libpng/pngset.c b/thirdparty/libpng/pngset.c
index 28ff3a064d..fb495ac3fb 100644
--- a/thirdparty/libpng/pngset.c
+++ b/thirdparty/libpng/pngset.c
@@ -1,8 +1,8 @@
/* pngset.c - storage of image information into info struct
*
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
+ * Copyright (c) 1998-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.)
*
@@ -1102,8 +1102,9 @@ png_set_sPLT(png_const_structrp png_ptr,
info_ptr->valid |= PNG_INFO_sPLT;
++(info_ptr->splt_palettes_num);
++np;
+ ++entries;
}
- while (++entries, --nentries);
+ while (--nentries);
if (nentries > 0)
png_chunk_report(png_ptr, "sPLT out of memory", PNG_CHUNK_WRITE_ERROR);
@@ -1696,14 +1697,16 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
png_byte ch = (png_byte)*key++;
if ((ch > 32 && ch <= 126) || (ch >= 161 /*&& ch <= 255*/))
- *new_key++ = ch, ++key_len, space = 0;
+ {
+ *new_key++ = ch; ++key_len; space = 0;
+ }
else if (space == 0)
{
/* A space or an invalid character when one wasn't seen immediately
* before; output just a space.
*/
- *new_key++ = 32, ++key_len, space = 1;
+ *new_key++ = 32; ++key_len; space = 1;
/* If the character was not a space then it is invalid. */
if (ch != 32)
@@ -1716,7 +1719,7 @@ png_check_keyword(png_structrp png_ptr, png_const_charp key, png_bytep new_key)
if (key_len > 0 && space != 0) /* trailing space */
{
- --key_len, --new_key;
+ --key_len; --new_key;
if (bad_character == 0)
bad_character = 32;
}
diff --git a/thirdparty/libpng/pngtrans.c b/thirdparty/libpng/pngtrans.c
index da7413fb80..6c8c646239 100644
--- a/thirdparty/libpng/pngtrans.c
+++ b/thirdparty/libpng/pngtrans.c
@@ -1,8 +1,8 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
*
- * Last changed in libpng 1.6.26 [October 20, 2016]
- * Copyright (c) 1998-2002,2004,2006-2016 Glenn Randers-Pehrson
+ * Last changed in libpng 1.6.30 [(PENDING RELEASE)]
+ * 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.)
*
@@ -514,11 +514,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
++sp;
else /* Skip initial channel and, for sp, the filler */
- sp += 2, ++dp;
+ {
+ sp += 2; ++dp;
+ }
/* For a 1 pixel wide image there is nothing to do */
while (sp < ep)
- *dp++ = *sp, sp += 2;
+ {
+ *dp++ = *sp; sp += 2;
+ }
row_info->pixel_depth = 8;
}
@@ -528,10 +532,14 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
sp += 2;
else /* Skip initial channel and, for sp, the filler */
- sp += 4, dp += 2;
+ {
+ sp += 4; dp += 2;
+ }
while (sp < ep)
- *dp++ = *sp++, *dp++ = *sp, sp += 3;
+ {
+ *dp++ = *sp++; *dp++ = *sp; sp += 3;
+ }
row_info->pixel_depth = 16;
}
@@ -554,11 +562,15 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
++sp;
else /* Skip initial channels and, for sp, the filler */
- sp += 4, dp += 3;
+ {
+ sp += 4; dp += 3;
+ }
/* Note that the loop adds 3 to dp and 4 to sp each time. */
while (sp < ep)
- *dp++ = *sp++, *dp++ = *sp++, *dp++ = *sp, sp += 2;
+ {
+ *dp++ = *sp++; *dp++ = *sp++; *dp++ = *sp; sp += 2;
+ }
row_info->pixel_depth = 24;
}
@@ -568,14 +580,16 @@ png_do_strip_channel(png_row_infop row_info, png_bytep row, int at_start)
if (at_start != 0) /* Skip initial filler */
sp += 2;
else /* Skip initial channels and, for sp, the filler */
- sp += 8, dp += 6;
+ {
+ sp += 8; dp += 6;
+ }
while (sp < ep)
{
/* Copy 6 bytes, skip 2 */
- *dp++ = *sp++, *dp++ = *sp++;
- *dp++ = *sp++, *dp++ = *sp++;
- *dp++ = *sp++, *dp++ = *sp, sp += 3;
+ *dp++ = *sp++; *dp++ = *sp++;
+ *dp++ = *sp++; *dp++ = *sp++;
+ *dp++ = *sp++; *dp++ = *sp; sp += 3;
}
row_info->pixel_depth = 48;
diff --git a/thirdparty/libpng/pngwutil.c b/thirdparty/libpng/pngwutil.c
index 0f98d582da..dd800586be 100644
--- a/thirdparty/libpng/pngwutil.c
+++ b/thirdparty/libpng/pngwutil.c
@@ -1003,7 +1003,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr));
#endif
- png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ if (size > 0)
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->mode |= PNG_HAVE_IDAT;
png_ptr->zstream.next_out = data;
@@ -1049,7 +1050,8 @@ png_compress_IDAT(png_structrp png_ptr, png_const_bytep input,
optimize_cmf(data, png_image_size(png_ptr));
#endif
- png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+ if (size > 0)
+ png_write_complete_chunk(png_ptr, png_IDAT, data, size);
png_ptr->zstream.avail_out = 0;
png_ptr->zstream.next_out = NULL;
png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;