summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT.txt31
-rw-r--r--SConstruct6
-rw-r--r--core/SCsub16
-rw-r--r--core/bind/core_bind.cpp7
-rw-r--r--core/bind/core_bind.h1
-rw-r--r--core/os/os.cpp3
-rw-r--r--core/os/os.h1
-rw-r--r--core/project_settings.cpp26
-rw-r--r--core/project_settings.h6
-rw-r--r--core/variant_call.cpp2
-rw-r--r--doc/Makefile2
-rw-r--r--doc/classes/AcceptDialog.xml2
-rw-r--r--doc/classes/AnimatedSprite.xml8
-rw-r--r--doc/classes/AnimatedSprite3D.xml2
-rw-r--r--doc/classes/Animation.xml2
-rw-r--r--doc/classes/AnimationTreePlayer.xml2
-rw-r--r--doc/classes/Area.xml26
-rw-r--r--doc/classes/Area2D.xml24
-rw-r--r--doc/classes/AtlasTexture.xml2
-rw-r--r--doc/classes/AudioEffectDelay.xml2
-rw-r--r--doc/classes/AudioServer.xml16
-rw-r--r--doc/classes/AudioStreamPlayer.xml4
-rw-r--r--doc/classes/AudioStreamPlayer2D.xml4
-rw-r--r--doc/classes/AudioStreamPlayer3D.xml4
-rw-r--r--doc/classes/BakedLightmap.xml2
-rw-r--r--doc/classes/BaseButton.xml8
-rw-r--r--doc/classes/BitMap.xml2
-rw-r--r--doc/classes/BitmapFont.xml2
-rw-r--r--doc/classes/Camera.xml2
-rw-r--r--doc/classes/Camera2D.xml18
-rw-r--r--doc/classes/CanvasItem.xml8
-rw-r--r--doc/classes/CenterContainer.xml2
-rw-r--r--doc/classes/CollisionObject.xml8
-rw-r--r--doc/classes/CollisionObject2D.xml6
-rw-r--r--doc/classes/CollisionPolygon2D.xml4
-rw-r--r--doc/classes/ColorPicker.xml6
-rw-r--r--doc/classes/ColorPickerButton.xml2
-rw-r--r--doc/classes/Control.xml6
-rw-r--r--doc/classes/Curve2D.xml34
-rw-r--r--doc/classes/Curve3D.xml42
-rw-r--r--doc/classes/DirectionalLight.xml2
-rw-r--r--doc/classes/DynamicFont.xml4
-rw-r--r--doc/classes/EditorFileDialog.xml4
-rw-r--r--doc/classes/EditorImportPlugin.xml12
-rw-r--r--doc/classes/EditorInterface.xml2
-rw-r--r--doc/classes/EditorPlugin.xml28
-rw-r--r--doc/classes/EditorSpatialGizmoPlugin.xml175
-rw-r--r--doc/classes/File.xml2
-rw-r--r--doc/classes/FileDialog.xml2
-rw-r--r--doc/classes/GDNativeLibraryResourceLoader.xml15
-rw-r--r--doc/classes/GDNativeLibraryResourceSaver.xml15
-rw-r--r--doc/classes/Generic6DOFJoint.xml24
-rw-r--r--doc/classes/GeometryInstance.xml2
-rw-r--r--doc/classes/GradientTexture.xml2
-rw-r--r--doc/classes/GraphEdit.xml2
-rw-r--r--doc/classes/GridContainer.xml2
-rw-r--r--doc/classes/HTTPClient.xml4
-rw-r--r--doc/classes/HTTPRequest.xml10
-rw-r--r--doc/classes/HingeJoint.xml4
-rw-r--r--doc/classes/ImageTexture.xml13
-rw-r--r--doc/classes/InputEventAction.xml2
-rw-r--r--doc/classes/InputEventJoypadButton.xml2
-rw-r--r--doc/classes/InputEventKey.xml4
-rw-r--r--doc/classes/InputEventMouseButton.xml4
-rw-r--r--doc/classes/InputEventScreenTouch.xml2
-rw-r--r--doc/classes/InterpolatedCamera.xml2
-rw-r--r--doc/classes/ItemList.xml4
-rw-r--r--doc/classes/Joint.xml2
-rw-r--r--doc/classes/Joint2D.xml2
-rw-r--r--doc/classes/KinematicBody.xml5
-rw-r--r--doc/classes/KinematicBody2D.xml4
-rw-r--r--doc/classes/Light.xml6
-rw-r--r--doc/classes/Light2D.xml6
-rw-r--r--doc/classes/LineEdit.xml10
-rw-r--r--doc/classes/MultiplayerAPI.xml2
-rw-r--r--doc/classes/NetworkedMultiplayerPeer.xml2
-rw-r--r--doc/classes/Node.xml6
-rw-r--r--doc/classes/Node2D.xml2
-rw-r--r--doc/classes/OS.xml21
-rw-r--r--doc/classes/Object.xml2
-rw-r--r--doc/classes/OccluderPolygon2D.xml2
-rw-r--r--doc/classes/OrientedPathFollow.xml2
-rw-r--r--doc/classes/ParallaxBackground.xml2
-rw-r--r--doc/classes/Particles.xml6
-rw-r--r--doc/classes/Particles2D.xml6
-rw-r--r--doc/classes/ParticlesMaterial.xml2
-rw-r--r--doc/classes/PathFollow.xml2
-rw-r--r--doc/classes/PathFollow2D.xml2
-rw-r--r--doc/classes/PhysicsDirectBodyState.xml2
-rw-r--r--doc/classes/PhysicsServer.xml12
-rw-r--r--doc/classes/Polygon2D.xml4
-rw-r--r--doc/classes/Popup.xml2
-rw-r--r--doc/classes/ProgressBar.xml2
-rw-r--r--doc/classes/Range.xml8
-rw-r--r--doc/classes/RayCast.xml4
-rw-r--r--doc/classes/RayShape.xml2
-rw-r--r--doc/classes/RayShape2D.xml2
-rw-r--r--doc/classes/RemoteTransform.xml8
-rw-r--r--doc/classes/RemoteTransform2D.xml8
-rw-r--r--doc/classes/ResourceFormatLoader.xml16
-rw-r--r--doc/classes/ResourceFormatSaver.xml6
-rw-r--r--doc/classes/ResourceLoader.xml2
-rw-r--r--doc/classes/RichTextLabel.xml4
-rw-r--r--doc/classes/RigidBody.xml14
-rw-r--r--doc/classes/RigidBody2D.xml10
-rw-r--r--doc/classes/SceneTree.xml14
-rw-r--r--doc/classes/ShortCut.xml2
-rw-r--r--doc/classes/Spatial.xml2
-rw-r--r--doc/classes/SpatialMaterial.xml48
-rw-r--r--doc/classes/Sprite.xml10
-rw-r--r--doc/classes/Sprite3D.xml2
-rw-r--r--doc/classes/SpriteBase3D.xml12
-rw-r--r--doc/classes/SpriteFrames.xml6
-rw-r--r--doc/classes/String.xml9
-rw-r--r--doc/classes/StyleBoxFlat.xml6
-rw-r--r--doc/classes/TabContainer.xml2
-rw-r--r--doc/classes/Tabs.xml2
-rw-r--r--doc/classes/TextEdit.xml20
-rw-r--r--doc/classes/TextureButton.xml2
-rw-r--r--doc/classes/TextureProgress.xml2
-rw-r--r--doc/classes/TextureRect.xml2
-rw-r--r--doc/classes/TileMap.xml14
-rw-r--r--doc/classes/TileSet.xml183
-rw-r--r--doc/classes/Timer.xml10
-rw-r--r--doc/classes/TouchScreenButton.xml6
-rw-r--r--doc/classes/TranslationLoaderPO.xml15
-rw-r--r--doc/classes/Tree.xml12
-rw-r--r--doc/classes/TreeItem.xml12
-rw-r--r--doc/classes/Tween.xml2
-rw-r--r--doc/classes/VideoPlayer.xml6
-rw-r--r--doc/classes/Viewport.xml26
-rw-r--r--doc/classes/ViewportContainer.xml2
-rw-r--r--doc/classes/VisibilityEnabler.xml4
-rw-r--r--doc/classes/VisibilityEnabler2D.xml12
-rw-r--r--doc/classes/VisibilityNotifier.xml2
-rw-r--r--doc/classes/VisibilityNotifier2D.xml2
-rw-r--r--doc/classes/VisualServer.xml32
-rw-r--r--doc/classes/WindowDialog.xml2
-rw-r--r--doc/classes/YSort.xml2
-rwxr-xr-xdoc/tools/makerst.py340
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.cpp569
-rw-r--r--drivers/gles2/rasterizer_canvas_gles2.h17
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp201
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.h29
-rw-r--r--drivers/gles2/shaders/SCsub2
-rw-r--r--drivers/gles2/shaders/canvas.glsl381
-rw-r--r--drivers/gles2/shaders/canvas_shadow.glsl41
-rw-r--r--drivers/gles2/shaders/copy.glsl2
-rw-r--r--drivers/gles2/shaders/cube_to_dp.glsl2
-rw-r--r--drivers/gles2/shaders/cubemap_filter.glsl2
-rw-r--r--drivers/gles2/shaders/lens_distorted.glsl2
-rw-r--r--drivers/gles2/shaders/scene.glsl6
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp6
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp4
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h1
-rw-r--r--drivers/gles3/shaders/scene.glsl2
-rw-r--r--drivers/unix/ip_unix.cpp8
-rw-r--r--drivers/unix/os_unix.cpp6
-rw-r--r--drivers/unix/os_unix.h1
-rw-r--r--editor/code_editor.cpp35
-rw-r--r--editor/code_editor.h7
-rw-r--r--editor/editor_node.cpp1
-rw-r--r--editor/editor_plugin.cpp12
-rw-r--r--editor/editor_plugin.h4
-rw-r--r--editor/editor_themes.cpp10
-rw-r--r--editor/import/editor_import_plugin.cpp2
-rw-r--r--editor/import/resource_importer_obj.cpp8
-rw-r--r--editor/plugins/animation_blend_tree_editor_plugin.cpp1
-rw-r--r--editor/plugins/animation_state_machine_editor.cpp4
-rw-r--r--editor/plugins/path_editor_plugin.cpp2
-rw-r--r--editor/plugins/script_text_editor.cpp9
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp167
-rw-r--r--editor/plugins/spatial_editor_plugin.h22
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp6
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp686
-rw-r--r--editor/plugins/tile_set_editor_plugin.h11
-rw-r--r--editor/project_manager.cpp129
-rw-r--r--editor/project_manager.h24
-rw-r--r--main/main.cpp2
-rw-r--r--modules/bullet/godot_result_callbacks.cpp1
-rw-r--r--modules/bullet/shape_bullet.cpp2
-rw-r--r--modules/csg/csg_gizmos.cpp2
-rw-r--r--modules/gridmap/doc_classes/GridMap.xml6
-rw-r--r--modules/mono/config.py10
-rw-r--r--modules/mono/editor/godotsharp_editor.cpp8
-rw-r--r--modules/mono/glue/Managed/Files/Color.cs23
-rw-r--r--modules/mono/glue/Managed/Files/Colors.cs303
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp6
-rw-r--r--modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptCondition.xml2
-rw-r--r--modules/visual_script/doc_classes/VisualScriptReturn.xml2
-rw-r--r--modules/webm/libvpx/SCsub7
-rw-r--r--modules/websocket/doc_classes/WebSocketClient.xml2
-rw-r--r--modules/websocket/emws_client.cpp4
-rw-r--r--platform/android/SCsub11
-rw-r--r--platform/android/export/export.cpp26
-rw-r--r--platform/android/globals/global_defaults.cpp35
-rw-r--r--platform/android/globals/global_defaults.h31
-rw-r--r--platform/android/ifaddrs_android.cpp230
-rw-r--r--platform/iphone/SCsub2
-rw-r--r--platform/iphone/detect.py10
-rw-r--r--platform/iphone/globals/global_defaults.cpp35
-rw-r--r--platform/iphone/globals/global_defaults.h31
-rw-r--r--platform/osx/detect.py6
-rw-r--r--platform/windows/os_windows.cpp11
-rw-r--r--platform/windows/os_windows.h1
-rw-r--r--scene/2d/tile_map.cpp7
-rw-r--r--scene/3d/mesh_instance.cpp2
-rw-r--r--scene/3d/spatial.cpp3
-rw-r--r--scene/gui/graph_edit.cpp2
-rw-r--r--scene/gui/text_edit.cpp17
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/resources/bit_mask.cpp2
-rw-r--r--scene/resources/texture.cpp2
-rw-r--r--scene/resources/tile_set.cpp26
-rw-r--r--scene/resources/tile_set.h1
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp1
-rw-r--r--servers/visual/shader_language.cpp7
-rw-r--r--servers/visual_server.cpp2
-rw-r--r--thirdparty/README.md21
-rw-r--r--thirdparty/certs/ca-certificates.crt207
-rw-r--r--thirdparty/libvpx/third_party/android/cpu-features.c (renamed from platform/android/cpu-features.c)334
-rw-r--r--thirdparty/libvpx/third_party/android/cpu-features.h (renamed from platform/android/cpu-features.h)123
-rw-r--r--thirdparty/misc/ifaddrs-android.cc221
-rw-r--r--thirdparty/misc/ifaddrs-android.h (renamed from platform/android/ifaddrs_android.h)14
226 files changed, 4215 insertions, 1733 deletions
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
index 2a1fe20477..738fe3ff5a 100644
--- a/COPYRIGHT.txt
+++ b/COPYRIGHT.txt
@@ -55,31 +55,16 @@ Comment: Godot Engine logo
Copyright: 2017, Andrea Calabró
License: CC-BY-3.0
-Files: ./platform/android/android_native_app_glue.c
- ./platform/android/android_native_app_glue.h
- ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
+Files: ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml
- ./platform/android/java/src/com/android/vending/licensing/*
./platform/android/java/src/com/google/android/vending/expansion/downloader/*
+ ./platform/android/java/src/com/google/android/vending/licensing/*
./platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
./platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
- ./platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
Comment: The Android Open Source Project
Copyright: 2008-2013, The Android Open Source Project
License: Apache-2.0
-Files: ./platform/android/cpu-features.c
- ./platform/android/cpu-features.h
-Comment: The Android Open Source Project
-Copyright: 2010, The Android Open Source Project
-License: BSD-2-clause
-
-Files: ./platform/android/ifaddrs_android.cpp
- ./platform/android/ifaddrs_android.h
-Comment: The Android Open Source Project
-Copyright: 2012-2013, Google Inc.
-License: BSD-3-clause
-
Files: ./platform/android/java/src/com/android/vending/licensing/util/Base64.java
./platform/android/java/src/com/android/vending/licensing/util/Base64DecoderException.java
Comment: The Android Open Source Project
@@ -225,6 +210,12 @@ Comment: The WebM Project
Copyright: 2010, The WebM Project authors.
License: BSD-3-clause
+Files: ./thirdparty/libvpx/third_party/android/cpu-features.c
+ ./thirdparty/libvpx/third_party/android/cpu-features.h
+Comment: The Android Open Source Project
+Copyright: 2010, The Android Open Source Project
+License: BSD-2-clause
+
Files: ./thirdparty/libwebp/
Comment: WebP codec
Copyright: 2010, Google Inc.
@@ -295,6 +286,12 @@ Comment: hq2x implementation
Copyright: 2016, Bruno Ribeiro
License: Apache-2.0
+Files: ./thirdparty/misc/ifaddrs-android.cc
+ ./thirdparty/misc/ifaddrs-android.h
+Comment: libjingle
+Copyright: 2012-2013, Google Inc.
+License: BSD-3-clause
+
Files: ./thirdparty/misc/md5.cpp
./thirdparty/misc/md5.h
Comment: MD5 Message Digest Algorithm
diff --git a/SConstruct b/SConstruct
index 8b7b95a600..57fa305a15 100644
--- a/SConstruct
+++ b/SConstruct
@@ -21,7 +21,6 @@ active_platforms = []
active_platform_ids = []
platform_exporters = []
platform_apis = []
-global_defaults = []
for x in sorted(glob.glob("platform/*")):
if (not os.path.isdir(x) or not os.path.exists(x + "/detect.py")):
@@ -35,8 +34,6 @@ for x in sorted(glob.glob("platform/*")):
platform_exporters.append(x[9:])
if (os.path.exists(x + "/api/api.cpp")):
platform_apis.append(x[9:])
- if (os.path.exists(x + "/globals/global_defaults.cpp")):
- global_defaults.append(x[9:])
if (detect.is_active()):
active_platforms.append(detect.get_name())
active_platform_ids.append(x)
@@ -68,7 +65,6 @@ if 'TERM' in os.environ:
env_base['ENV']['TERM'] = os.environ['TERM']
env_base.AppendENVPath('PATH', os.getenv('PATH'))
env_base.AppendENVPath('PKG_CONFIG_PATH', os.getenv('PKG_CONFIG_PATH'))
-env_base.global_defaults = global_defaults
env_base.android_maven_repos = []
env_base.android_flat_dirs = []
env_base.android_dependencies = []
@@ -168,7 +164,7 @@ opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all
opts.Add(BoolVariable('vsproj', "Generate a Visual Studio solution", False))
opts.Add(EnumVariable('macports_clang', "Build using Clang from MacPorts", 'no', ('no', '5.0', 'devel')))
opts.Add(BoolVariable('disable_3d', "Disable 3D nodes for a smaller executable", False))
-opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced 3D GUI nodes and behaviors", False))
+opts.Add(BoolVariable('disable_advanced_gui', "Disable advanced GUI nodes and behaviors", False))
opts.Add(BoolVariable('no_editor_splash', "Don't use the custom splash screen for the editor", False))
opts.Add('system_certs_path', "Use this path as SSL certificates default for editor (for package maintainers)", '')
diff --git a/core/SCsub b/core/SCsub
index c6d0b7e5b1..fe379d6936 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -8,22 +8,6 @@ from platform_methods import run_in_subprocess
env.core_sources = []
-# Generate global defaults
-gd_call = ""
-gd_inc = ""
-
-for x in env.global_defaults:
- env.core_sources.append("#platform/" + x + "/globals/global_defaults.cpp")
- gd_inc += '#include "platform/' + x + '/globals/global_defaults.h"\n'
- gd_call += "\tregister_" + x + "_global_defaults();\n"
-
-gd_cpp = '#include "core/project_settings.h"\n'
-gd_cpp += gd_inc
-gd_cpp += "void ProjectSettings::register_global_defaults() {\n" + gd_call + "\n}\n"
-
-with open("global_defaults.gen.cpp", "w") as f:
- f.write(gd_cpp)
-
# Generate AES256 script encryption key
import os
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 8641af84d9..6ea70a2916 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -132,7 +132,7 @@ bool _ResourceLoader::exists(const String &p_path, const String &p_type_hint) {
void _ResourceLoader::_bind_methods() {
ClassDB::bind_method(D_METHOD("load_interactive", "path", "type_hint"), &_ResourceLoader::load_interactive, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "p_no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("load", "path", "type_hint", "no_cache"), &_ResourceLoader::load, DEFVAL(""), DEFVAL(false));
ClassDB::bind_method(D_METHOD("get_recognized_extensions_for_type", "type"), &_ResourceLoader::get_recognized_extensions_for_type);
ClassDB::bind_method(D_METHOD("set_abort_on_missing_resources", "abort"), &_ResourceLoader::set_abort_on_missing_resources);
ClassDB::bind_method(D_METHOD("get_dependencies", "path"), &_ResourceLoader::get_dependencies);
@@ -827,6 +827,10 @@ uint64_t _OS::get_system_time_secs() const {
return OS::get_singleton()->get_system_time_secs();
}
+uint64_t _OS::get_system_time_msecs() const {
+ return OS::get_singleton()->get_system_time_msecs();
+}
+
void _OS::delay_usec(uint32_t p_usec) const {
OS::get_singleton()->delay_usec(p_usec);
@@ -1182,6 +1186,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_datetime_from_unix_time", "unix_time_val"), &_OS::get_datetime_from_unix_time);
ClassDB::bind_method(D_METHOD("get_unix_time_from_datetime", "datetime"), &_OS::get_unix_time_from_datetime);
ClassDB::bind_method(D_METHOD("get_system_time_secs"), &_OS::get_system_time_secs);
+ ClassDB::bind_method(D_METHOD("get_system_time_msecs"), &_OS::get_system_time_msecs);
ClassDB::bind_method(D_METHOD("set_icon", "icon"), &_OS::set_icon);
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 4cdf09d522..39704286b6 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -281,6 +281,7 @@ public:
Dictionary get_time_zone_info() const;
uint64_t get_unix_time() const;
uint64_t get_system_time_secs() const;
+ uint64_t get_system_time_msecs() const;
int get_static_memory_usage() const;
int get_static_memory_peak_usage() const;
diff --git a/core/os/os.cpp b/core/os/os.cpp
index 7547b6a042..ea60a03373 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -61,6 +61,9 @@ uint64_t OS::get_unix_time() const {
uint64_t OS::get_system_time_secs() const {
return 0;
}
+uint64_t OS::get_system_time_msecs() const {
+ return 0;
+}
void OS::debug_break(){
// something
diff --git a/core/os/os.h b/core/os/os.h
index 05ec3ac424..046686ff51 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -328,6 +328,7 @@ public:
virtual TimeZoneInfo get_time_zone_info() const = 0;
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
+ virtual uint64_t get_system_time_msecs() const;
virtual void delay_usec(uint32_t p_usec) const = 0;
virtual uint64_t get_ticks_usec() const = 0;
diff --git a/core/project_settings.cpp b/core/project_settings.cpp
index 031ac06063..f3368a5595 100644
--- a/core/project_settings.cpp
+++ b/core/project_settings.cpp
@@ -43,8 +43,6 @@
#include <zlib.h>
-#define FORMAT_VERSION 4
-
ProjectSettings *ProjectSettings::singleton = NULL;
ProjectSettings *ProjectSettings::get_singleton() {
@@ -271,9 +269,9 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack) {
return true;
}
-void ProjectSettings::_convert_to_last_version() {
- if (!has_setting("config_version") || (int)get_setting("config_version") <= 3) {
+void ProjectSettings::_convert_to_last_version(int p_from_version) {
+ if (p_from_version <= 3) {
// Converts the actions from array to dictionary (array of events to dictionary with deadzone + events)
for (Map<StringName, ProjectSettings::VariantContainer>::Element *E = props.front(); E; E = E->next()) {
Variant value = E->get().variant;
@@ -396,7 +394,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
// Optional, we don't mind if it fails
_load_settings_text("res://override.cfg");
}
-
return err;
}
@@ -443,10 +440,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b
if (resource_path.length() && resource_path[resource_path.length() - 1] == '/')
resource_path = resource_path.substr(0, resource_path.length() - 1); // chop end
- // If we're loading a project.godot from source code, we can operate some
- // ProjectSettings conversions if need be.
- _convert_to_last_version();
-
return OK;
}
@@ -537,8 +530,8 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
int lines = 0;
String error_text;
-
String section;
+ int config_version = 0;
while (true) {
@@ -549,6 +542,9 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true);
if (err == ERR_FILE_EOF) {
memdelete(f);
+ // If we're loading a project.godot from source code, we can operate some
+ // ProjectSettings conversions if need be.
+ _convert_to_last_version(config_version);
return OK;
} else if (err != OK) {
ERR_PRINTS("Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted.");
@@ -558,13 +554,13 @@ Error ProjectSettings::_load_settings_text(const String p_path) {
if (assign != String()) {
if (section == String() && assign == "config_version") {
- int config_version = value;
- if (config_version > FORMAT_VERSION) {
+ config_version = value;
+ if (config_version > CONFIG_VERSION) {
memdelete(f);
- ERR_FAIL_COND_V(config_version > FORMAT_VERSION, ERR_FILE_CANT_OPEN);
+ ERR_EXPLAIN(vformat("Can't open project at '%s', its `config_version` (%d) is from a more recent and incompatible version of the engine. Expected config version: %d.", p_path, config_version, CONFIG_VERSION));
+ ERR_FAIL_COND_V(config_version > CONFIG_VERSION, ERR_FILE_CANT_OPEN);
}
} else {
- // config_version is checked and dropped
if (section == String()) {
set(assign, value);
} else {
@@ -740,7 +736,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const Map<Strin
file->store_line("; param=value ; assign values to parameters");
file->store_line("");
- file->store_string("config_version=" + itos(FORMAT_VERSION) + "\n");
+ file->store_string("config_version=" + itos(CONFIG_VERSION) + "\n");
if (p_custom_features != String())
file->store_string("custom_features=\"" + p_custom_features + "\"\n");
file->store_string("\n");
diff --git a/core/project_settings.h b/core/project_settings.h
index f150e4499b..2cb159e1c7 100644
--- a/core/project_settings.h
+++ b/core/project_settings.h
@@ -106,7 +106,7 @@ protected:
Error _save_custom_bnd(const String &p_file);
- void _convert_to_last_version();
+ void _convert_to_last_version(int p_from_version);
bool _load_resource_pack(const String &p_pack);
@@ -118,6 +118,8 @@ protected:
static void _bind_methods();
public:
+ static const int CONFIG_VERSION = 4;
+
void set_setting(const String &p_setting, const Variant &p_value);
Variant get_setting(const String &p_setting) const;
@@ -152,8 +154,6 @@ public:
void set_disable_feature_overrides(bool p_disable);
- void register_global_defaults();
-
bool is_using_datapack() const;
void set_registering_order(bool p_enable);
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 0c6e43fe36..aa180cd4ac 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -291,6 +291,7 @@ struct _VariantCall {
VCALL_LOCALMEM0R(String, is_valid_identifier);
VCALL_LOCALMEM0R(String, is_valid_integer);
VCALL_LOCALMEM0R(String, is_valid_float);
+ VCALL_LOCALMEM1R(String, is_valid_hex_number);
VCALL_LOCALMEM0R(String, is_valid_html_color);
VCALL_LOCALMEM0R(String, is_valid_ip_address);
VCALL_LOCALMEM0R(String, to_int);
@@ -1534,6 +1535,7 @@ void register_variant_methods() {
ADDFUNC0R(STRING, BOOL, String, is_valid_identifier, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_integer, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_float, varray());
+ ADDFUNC1R(STRING, BOOL, String, is_valid_hex_number, BOOL, "with_prefix", varray(false));
ADDFUNC0R(STRING, BOOL, String, is_valid_html_color, varray());
ADDFUNC0R(STRING, BOOL, String, is_valid_ip_address, varray());
ADDFUNC0R(STRING, INT, String, to_int, varray());
diff --git a/doc/Makefile b/doc/Makefile
index 2f9fefe794..7f3f7ea939 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -24,5 +24,5 @@ rst:
rm -rf $(OUTPUTDIR)/rst
mkdir -p $(OUTPUTDIR)/rst
pushd $(OUTPUTDIR)/rst
- python $(TOOLSDIR)/makerst.py $(CLASSES)
+ python3 $(TOOLSDIR)/makerst.py $(CLASSES)
popd
diff --git a/doc/classes/AcceptDialog.xml b/doc/classes/AcceptDialog.xml
index 7e871d68cb..fc27bdbb81 100644
--- a/doc/classes/AcceptDialog.xml
+++ b/doc/classes/AcceptDialog.xml
@@ -60,7 +60,7 @@
</methods>
<members>
<member name="dialog_hide_on_ok" type="bool" setter="set_hide_on_ok" getter="get_hide_on_ok">
- If [code]true[/code] the dialog is hidden when the OK button is pressed. You can set it to [code]false[/code] if you want to do e.g. input validation when receiving the [signal confirmed] signal, and handle hiding the dialog in your own logic. Default value: [code]true[/code].
+ If [code]true[/code], the dialog is hidden when the OK button is pressed. You can set it to [code]false[/code] if you want to do e.g. input validation when receiving the [signal confirmed] signal, and handle hiding the dialog in your own logic. Default value: [code]true[/code].
Note: Some nodes derived from this class can have a different default value, and potentially their own built-in logic overriding this setting. For example [FileDialog] defaults to [code]false[/code], and has its own input validation code that is called when you press OK, which eventually hides the dialog if the input is valid. As such this property can't be used in [FileDialog] to disable hiding the dialog when pressing OK.
</member>
<member name="dialog_text" type="String" setter="set_text" getter="get_text">
diff --git a/doc/classes/AnimatedSprite.xml b/doc/classes/AnimatedSprite.xml
index a41ed0e689..7f9167c49a 100644
--- a/doc/classes/AnimatedSprite.xml
+++ b/doc/classes/AnimatedSprite.xml
@@ -40,13 +40,13 @@
The current animation from the [code]frames[/code] resource. If this value changes, the [code]frame[/code] counter is reset.
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered">
- If [code]true[/code] texture will be centered. Default value: [code]true[/code].
+ If [code]true[/code], texture will be centered. Default value: [code]true[/code].
</member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h">
- If [code]true[/code] texture is flipped horizontally. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped horizontally. Default value: [code]false[/code].
</member>
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v">
- If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped vertically. Default value: [code]false[/code].
</member>
<member name="frame" type="int" setter="set_frame" getter="get_frame">
The displayed animation frame's index.
@@ -58,7 +58,7 @@
The texture's drawing offset.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="_is_playing">
- If [code]true[/code] the [member animation] is currently playing.
+ If [code]true[/code], the [member animation] is currently playing.
</member>
<member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale">
</member>
diff --git a/doc/classes/AnimatedSprite3D.xml b/doc/classes/AnimatedSprite3D.xml
index 733d565676..dcc44e2df4 100644
--- a/doc/classes/AnimatedSprite3D.xml
+++ b/doc/classes/AnimatedSprite3D.xml
@@ -46,7 +46,7 @@
The [SpriteFrames] resource containing the animation(s).
</member>
<member name="playing" type="bool" setter="_set_playing" getter="_is_playing">
- If [code]true[/code] the [member animation] is currently playing.
+ If [code]true[/code], the [member animation] is currently playing.
</member>
</members>
<signals>
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index 169fbcd5a8..a7cae709a4 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -513,7 +513,7 @@
<argument index="1" name="interpolation" type="bool">
</argument>
<description>
- If [code]true[/code] the track at [code]idx[/code] wraps the interpolation loop.
+ If [code]true[/code], the track at [code]idx[/code] wraps the interpolation loop.
</description>
</method>
<method name="track_set_interpolation_type">
diff --git a/doc/classes/AnimationTreePlayer.xml b/doc/classes/AnimationTreePlayer.xml
index a081c64f6d..b0b58fc7bd 100644
--- a/doc/classes/AnimationTreePlayer.xml
+++ b/doc/classes/AnimationTreePlayer.xml
@@ -607,7 +607,7 @@
</methods>
<members>
<member name="active" type="bool" setter="set_active" getter="is_active">
- If [code]true[/code] the [code]AnimationTreePlayer[/code] is able to play animations. Default value: [code]false[/code].
+ If [code]true[/code], the [code]AnimationTreePlayer[/code] is able to play animations. Default value: [code]false[/code].
</member>
<member name="base_path" type="NodePath" setter="set_base_path" getter="get_base_path">
The node from which to relatively access other nodes. Default value: [code]".."[/code].
diff --git a/doc/classes/Area.xml b/doc/classes/Area.xml
index 970d09a2ac..203af27f45 100644
--- a/doc/classes/Area.xml
+++ b/doc/classes/Area.xml
@@ -49,7 +49,7 @@
<argument index="0" name="area" type="Node">
</argument>
<description>
- If [code]true[/code] the given area overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
+ If [code]true[/code], the given area overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="overlaps_body" qualifiers="const">
@@ -58,7 +58,7 @@
<argument index="0" name="body" type="Node">
</argument>
<description>
- If [code]true[/code] the given body overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
+ If [code]true[/code], the given body overlaps the Area. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="set_collision_layer_bit">
@@ -92,10 +92,10 @@
The name of the area's audio bus.
</member>
<member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus">
- If [code]true[/code] the area's audio bus overrides the default audio bus. Default value: [code]false[/code].
+ If [code]true[/code], the area's audio bus overrides the default audio bus. Default value: [code]false[/code].
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
- The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [code]collision_mask[/code].
+ The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask].
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
The physics layers this area scans to determine collision detection.
@@ -107,19 +107,19 @@
The falloff factor for point gravity. The greater the value, the faster gravity decreases with distance.
</member>
<member name="gravity_point" type="bool" setter="set_gravity_is_point" getter="is_gravity_a_point">
- If [code]true[/code] gravity is calculated from a point (set via [code]gravity_vec[/code]). Also see [code]space_override[/code]. Default value: [code]false[/code].
+ If [code]true[/code], gravity is calculated from a point (set via [member gravity_vec]). Also see [member space_override]. Default value: [code]false[/code].
</member>
<member name="gravity_vec" type="Vector3" setter="set_gravity_vector" getter="get_gravity_vector">
- The area's gravity vector (not normalized). If gravity is a point (see [method is_gravity_a_point]), this will be the point of attraction.
+ The area's gravity vector (not normalized). If gravity is a point (see [member gravity_point]), this will be the point of attraction.
</member>
<member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp">
The rate at which objects stop moving in this area. Represents the linear velocity lost per second. Values range from [code]0[/code] (no damping) to [code]1[/code] (full damping).
</member>
<member name="monitorable" type="bool" setter="set_monitorable" getter="is_monitorable">
- If [code]true[/code] other monitoring areas can detect this area. Default value: [code]true[/code].
+ If [code]true[/code], other monitoring areas can detect this area. Default value: [code]true[/code].
</member>
<member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring">
- If [code]true[/code] the area detects bodies or areas entering and exiting it. Default value: [code]true[/code].
+ If [code]true[/code], the area detects bodies or areas entering and exiting it. Default value: [code]true[/code].
</member>
<member name="priority" type="float" setter="set_priority" getter="get_priority">
The area's priority. Higher priority areas are processed first. Default value: 0.
@@ -128,7 +128,7 @@
The degree to which this area applies reverb to its associated audio. Ranges from [code]0[/code] to [code]1[/code] with [code]0.1[/code] precision.
</member>
<member name="reverb_bus_enable" type="bool" setter="set_use_reverb_bus" getter="is_using_reverb_bus">
- If [code]true[/code] the area applies reverb to its associated audio.
+ If [code]true[/code], the area applies reverb to its associated audio.
</member>
<member name="reverb_bus_name" type="String" setter="set_reverb_bus" getter="get_reverb_bus">
The reverb bus name to use for this area's associated audio.
@@ -137,7 +137,7 @@
The degree to which this area's reverb is a uniform effect. Ranges from [code]0[/code] to [code]1[/code] with [code]0.1[/code] precision.
</member>
<member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" enum="Area.SpaceOverride">
- Override mode for gravity and damping calculations within this area. See the SPACE_OVERRIDE_* constants for values.
+ Override mode for gravity and damping calculations within this area. See [enum Area.SpaceOverride] for possible values.
</member>
</members>
<signals>
@@ -227,16 +227,16 @@
This area does not affect gravity/damping.
</constant>
<constant name="SPACE_OVERRIDE_COMBINE" value="1" enum="SpaceOverride">
- This area adds its gravity/damping values to whatever has been calculated so far (in [code]priority[/code] order).
+ This area adds its gravity/damping values to whatever has been calculated so far (in [member priority] order).
</constant>
<constant name="SPACE_OVERRIDE_COMBINE_REPLACE" value="2" enum="SpaceOverride">
- This area adds its gravity/damping values to whatever has been calculated so far (in [code]priority[/code] order), ignoring any lower priority areas.
+ This area adds its gravity/damping values to whatever has been calculated so far (in [member priority] order), ignoring any lower priority areas.
</constant>
<constant name="SPACE_OVERRIDE_REPLACE" value="3" enum="SpaceOverride">
This area replaces any gravity/damping, even the defaults, ignoring any lower priority areas.
</constant>
<constant name="SPACE_OVERRIDE_REPLACE_COMBINE" value="4" enum="SpaceOverride">
- This area replaces any gravity/damping calculated so far (in [code]priority[/code] order), but keeps calculating the rest of the areas.
+ This area replaces any gravity/damping calculated so far (in [member priority] order), but keeps calculating the rest of the areas.
</constant>
</constants>
</class>
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index b77a931201..11aef07c47 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -49,7 +49,7 @@
<argument index="0" name="area" type="Node">
</argument>
<description>
- If [code]true[/code] the given area overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
+ If [code]true[/code], the given area overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="overlaps_body" qualifiers="const">
@@ -58,7 +58,7 @@
<argument index="0" name="body" type="Node">
</argument>
<description>
- If [code]true[/code] the given body overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
+ If [code]true[/code], the given body overlaps the Area2D. Note that the result of this test is not immediate after moving objects. For performance, list of overlaps is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="set_collision_layer_bit">
@@ -92,10 +92,10 @@
The name of the area's audio bus.
</member>
<member name="audio_bus_override" type="bool" setter="set_audio_bus_override" getter="is_overriding_audio_bus">
- If [code]true[/code] the area's audio bus overrides the default audio bus. Default value: [code]false[/code].
+ If [code]true[/code], the area's audio bus overrides the default audio bus. Default value: [code]false[/code].
</member>
<member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer">
- The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [code]collision_mask[/code].
+ The area's physics layer(s). Collidable objects can exist in any of 32 different layers. A contact is detected if object A is in any of the layers that object B scans, or object B is in any layers that object A scans. See also [member collision_mask].
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask">
The physics layers this area scans to determine collision detection.
@@ -107,25 +107,25 @@
The falloff factor for point gravity. The greater the value, the faster gravity decreases with distance.
</member>
<member name="gravity_point" type="bool" setter="set_gravity_is_point" getter="is_gravity_a_point">
- If [code]true[/code] gravity is calculated from a point (set via [code]gravity_vec[/code]). Also see [code]space_override[/code]. Default value: [code]false[/code].
+ If [code]true[/code], gravity is calculated from a point (set via [member gravity_vec]). Also see [member space_override]. Default value: [code]false[/code].
</member>
<member name="gravity_vec" type="Vector2" setter="set_gravity_vector" getter="get_gravity_vector">
- The area's gravity vector (not normalized). If gravity is a point (see [method is_gravity_a_point]), this will be the point of attraction.
+ The area's gravity vector (not normalized). If gravity is a point (see [member gravity_point]), this will be the point of attraction.
</member>
<member name="linear_damp" type="float" setter="set_linear_damp" getter="get_linear_damp">
The rate at which objects stop moving in this area. Represents the linear velocity lost per second. Values range from [code]0[/code] (no damping) to [code]1[/code] (full damping).
</member>
<member name="monitorable" type="bool" setter="set_monitorable" getter="is_monitorable">
- If [code]true[/code] other monitoring areas can detect this area. Default value: [code]true[/code].
+ If [code]true[/code], other monitoring areas can detect this area. Default value: [code]true[/code].
</member>
<member name="monitoring" type="bool" setter="set_monitoring" getter="is_monitoring">
- If [code]true[/code] the area detects bodies or areas entering and exiting it. Default value: [code]true[/code].
+ If [code]true[/code], the area detects bodies or areas entering and exiting it. Default value: [code]true[/code].
</member>
<member name="priority" type="float" setter="set_priority" getter="get_priority">
The area's priority. Higher priority areas are processed first. Default value: 0.
</member>
<member name="space_override" type="int" setter="set_space_override_mode" getter="get_space_override_mode" enum="Area2D.SpaceOverride">
- Override mode for gravity and damping calculations within this area. See the SPACE_OVERRIDE_* constants for values.
+ Override mode for gravity and damping calculations within this area. See [Area2D.SpaceOverride] for possible values.
</member>
</members>
<signals>
@@ -215,16 +215,16 @@
This area does not affect gravity/damping.
</constant>
<constant name="SPACE_OVERRIDE_COMBINE" value="1" enum="SpaceOverride">
- This area adds its gravity/damping values to whatever has been calculated so far (in [code]priority[/code] order).
+ This area adds its gravity/damping values to whatever has been calculated so far (in [member priority] order).
</constant>
<constant name="SPACE_OVERRIDE_COMBINE_REPLACE" value="2" enum="SpaceOverride">
- This area adds its gravity/damping values to whatever has been calculated so far (in [code]priority[/code] order), ignoring any lower priority areas.
+ This area adds its gravity/damping values to whatever has been calculated so far (in [member priority] order), ignoring any lower priority areas.
</constant>
<constant name="SPACE_OVERRIDE_REPLACE" value="3" enum="SpaceOverride">
This area replaces any gravity/damping, even the defaults, ignoring any lower priority areas.
</constant>
<constant name="SPACE_OVERRIDE_REPLACE_COMBINE" value="4" enum="SpaceOverride">
- This area replaces any gravity/damping calculated so far (in [code]priority[/code] order), but keeps calculating the rest of the areas.
+ This area replaces any gravity/damping calculated so far (in [member priority] order), but keeps calculating the rest of the areas.
</constant>
</constants>
</class>
diff --git a/doc/classes/AtlasTexture.xml b/doc/classes/AtlasTexture.xml
index 409c40e809..3f5eb892af 100644
--- a/doc/classes/AtlasTexture.xml
+++ b/doc/classes/AtlasTexture.xml
@@ -18,7 +18,7 @@
The texture that contains the atlas. Can be any [Texture] subtype.
</member>
<member name="filter_clip" type="bool" setter="set_filter_clip" getter="has_filter_clip">
- If [code]true[/code] clips the area outside of the region to avoid bleeding of the surrounding texture pixels.
+ If [code]true[/code], clips the area outside of the region to avoid bleeding of the surrounding texture pixels.
</member>
<member name="margin" type="Rect2" setter="set_margin" getter="get_margin">
The margin around the region. The [Rect2]'s 'size' parameter ('w' and 'h' in the editor) resizes the texture so it fits within the margin.
diff --git a/doc/classes/AudioEffectDelay.xml b/doc/classes/AudioEffectDelay.xml
index 7c9d11111c..872b94a0cd 100644
--- a/doc/classes/AudioEffectDelay.xml
+++ b/doc/classes/AudioEffectDelay.xml
@@ -18,7 +18,7 @@
Output percent of original sound. At 0, only delayed sounds are output. Value can range from 0 to 1. Default value: [code]1[/code].
</member>
<member name="feedback/active" type="bool" setter="set_feedback_active" getter="is_feedback_active">
- If [code]true[/code] feedback is enabled. Default value: [code]false[/code].
+ If [code]true[/code], feedback is enabled. Default value: [code]false[/code].
</member>
<member name="feedback/delay_ms" type="float" setter="set_feedback_delay_ms" getter="get_feedback_delay_ms">
Feedback delay time in milliseconds. Default value: [code]340[/code].
diff --git a/doc/classes/AudioServer.xml b/doc/classes/AudioServer.xml
index e1939e679d..96f02137cf 100644
--- a/doc/classes/AudioServer.xml
+++ b/doc/classes/AudioServer.xml
@@ -187,7 +187,7 @@
<argument index="0" name="bus_idx" type="int">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is bypassing effects.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is bypassing effects.
</description>
</method>
<method name="is_bus_effect_enabled" qualifiers="const">
@@ -198,7 +198,7 @@
<argument index="1" name="effect_idx" type="int">
</argument>
<description>
- If [code]true[/code] the effect at index [code]effect_idx[/code] on the bus at index [code]bus_idx[/code] is enabled.
+ If [code]true[/code], the effect at index [code]effect_idx[/code] on the bus at index [code]bus_idx[/code] is enabled.
</description>
</method>
<method name="is_bus_mute" qualifiers="const">
@@ -207,7 +207,7 @@
<argument index="0" name="bus_idx" type="int">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is muted.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is muted.
</description>
</method>
<method name="is_bus_solo" qualifiers="const">
@@ -216,7 +216,7 @@
<argument index="0" name="bus_idx" type="int">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is in solo mode.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is in solo mode.
</description>
</method>
<method name="lock">
@@ -265,7 +265,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is bypassing effects.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is bypassing effects.
</description>
</method>
<method name="set_bus_count">
@@ -287,7 +287,7 @@
<argument index="2" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the effect at index [code]effect_idx[/code] on the bus at index [code]bus_idx[/code] is enabled.
+ If [code]true[/code], the effect at index [code]effect_idx[/code] on the bus at index [code]bus_idx[/code] is enabled.
</description>
</method>
<method name="set_bus_layout">
@@ -307,7 +307,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is muted.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is muted.
</description>
</method>
<method name="set_bus_name">
@@ -340,7 +340,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the bus at index [code]bus_idx[/code] is in solo mode.
+ If [code]true[/code], the bus at index [code]bus_idx[/code] is in solo mode.
</description>
</method>
<method name="set_bus_volume_db">
diff --git a/doc/classes/AudioStreamPlayer.xml b/doc/classes/AudioStreamPlayer.xml
index be4e4f137a..e04a808f34 100644
--- a/doc/classes/AudioStreamPlayer.xml
+++ b/doc/classes/AudioStreamPlayer.xml
@@ -48,7 +48,7 @@
</methods>
<members>
<member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled">
- If [code]true[/code] audio plays when added to scene tree. Default value: [code]false[/code].
+ If [code]true[/code], audio plays when added to scene tree. Default value: [code]false[/code].
</member>
<member name="bus" type="String" setter="set_bus" getter="get_bus">
Bus on which this audio is playing.
@@ -60,7 +60,7 @@
Changes the pitch and the tempo of the audio.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="is_playing">
- If [code]true[/code] audio is playing.
+ If [code]true[/code], audio is playing.
</member>
<member name="stream" type="AudioStream" setter="set_stream" getter="get_stream">
The [AudioStream] object to be played.
diff --git a/doc/classes/AudioStreamPlayer2D.xml b/doc/classes/AudioStreamPlayer2D.xml
index 3b81894c14..2051675488 100644
--- a/doc/classes/AudioStreamPlayer2D.xml
+++ b/doc/classes/AudioStreamPlayer2D.xml
@@ -54,7 +54,7 @@
Dampens audio over distance with this as an exponent.
</member>
<member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled">
- If [code]true[/code] audio plays when added to scene tree. Default value: [code]false[/code].
+ If [code]true[/code], audio plays when added to scene tree. Default value: [code]false[/code].
</member>
<member name="bus" type="String" setter="set_bus" getter="get_bus">
Bus on which this audio is playing.
@@ -66,7 +66,7 @@
Changes the pitch and the tempo of the audio.
</member>
<member name="playing" type="bool" setter="_set_playing" getter="is_playing">
- If [code]true[/code] audio is playing.
+ If [code]true[/code], audio is playing.
</member>
<member name="stream" type="AudioStream" setter="set_stream" getter="get_stream">
The [AudioStream] object to be played.
diff --git a/doc/classes/AudioStreamPlayer3D.xml b/doc/classes/AudioStreamPlayer3D.xml
index 5841f1f6dc..c7c9f4df9b 100644
--- a/doc/classes/AudioStreamPlayer3D.xml
+++ b/doc/classes/AudioStreamPlayer3D.xml
@@ -60,7 +60,7 @@
Decides if audio should get quieter with distance linearly, quadratically or logarithmically.
</member>
<member name="autoplay" type="bool" setter="set_autoplay" getter="is_autoplay_enabled">
- If [code]true[/code] audio plays when added to scene tree. Default value: [code]false[/code].
+ If [code]true[/code], audio plays when added to scene tree. Default value: [code]false[/code].
</member>
<member name="bus" type="String" setter="set_bus" getter="get_bus">
Bus on which this audio is playing.
@@ -72,7 +72,7 @@
The angle in which the audio reaches cameras undampened.
</member>
<member name="emission_angle_enabled" type="bool" setter="set_emission_angle_enabled" getter="is_emission_angle_enabled">
- If [code]true[/code] the audio should be dampened according to the direction of the sound.
+ If [code]true[/code], the audio should be dampened according to the direction of the sound.
</member>
<member name="emission_angle_filter_attenuation_db" type="float" setter="set_emission_angle_filter_attenuation_db" getter="get_emission_angle_filter_attenuation_db">
dampens audio if camera is outside of 'emission_angle_degrees' and 'emission_angle_enabled' is set by this factor, in dB.
diff --git a/doc/classes/BakedLightmap.xml b/doc/classes/BakedLightmap.xml
index 8e27dc8d5d..d376bf667f 100644
--- a/doc/classes/BakedLightmap.xml
+++ b/doc/classes/BakedLightmap.xml
@@ -39,7 +39,7 @@
Size of affected area.
</member>
<member name="bake_hdr" type="bool" setter="set_hdr" getter="is_hdr">
- If [code]true[/code] lightmap can capture light values greater than [code]1.0[/code]. Turning this off will result in a smaller lightmap. Default value:[code]false[/code].
+ If [code]true[/code], lightmap can capture light values greater than [code]1.0[/code]. Turning this off will result in a smaller lightmap. Default value:[code]false[/code].
</member>
<member name="bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="BakedLightmap.BakeMode">
Lightmapping mode. See [enum BakeMode].
diff --git a/doc/classes/BaseButton.xml b/doc/classes/BaseButton.xml
index 9c0459511c..8798ca5274 100644
--- a/doc/classes/BaseButton.xml
+++ b/doc/classes/BaseButton.xml
@@ -51,7 +51,7 @@
To allow both left-click and right-click, set this to 3, because it's BUTTON_MASK_LEFT | BUTTON_MASK_RIGHT.
</member>
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled">
- If [code]true[/code] the button is in disabled state and can't be clicked or toggled.
+ If [code]true[/code], the button is in disabled state and can't be clicked or toggled.
</member>
<member name="enabled_focus_mode" type="int" setter="set_enabled_focus_mode" getter="get_enabled_focus_mode" enum="Control.FocusMode">
Focus access mode to use when switching between enabled/disabled (see [method Control.set_focus_mode] and [member disabled]).
@@ -60,16 +60,16 @@
[ButtonGroup] associated to the button.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the button's state is pressed. Means the button is pressed down or toggled (if toggle_mode is active).
+ If [code]true[/code], the button's state is pressed. Means the button is pressed down or toggled (if toggle_mode is active).
</member>
<member name="shortcut" type="ShortCut" setter="set_shortcut" getter="get_shortcut">
[Shortcut] associated to the button.
</member>
<member name="shortcut_in_tooltip" type="bool" setter="set_shortcut_in_tooltip" getter="is_shortcut_in_tooltip_enabled">
- If [code]true[/code] the button will add information about its shortcut in the tooltip.
+ If [code]true[/code], the button will add information about its shortcut in the tooltip.
</member>
<member name="toggle_mode" type="bool" setter="set_toggle_mode" getter="is_toggle_mode">
- If [code]true[/code] the button is in toggle mode. Makes the button flip state between pressed and unpressed each time its area is clicked.
+ If [code]true[/code], the button is in toggle mode. Makes the button flip state between pressed and unpressed each time its area is clicked.
</member>
</members>
<signals>
diff --git a/doc/classes/BitMap.xml b/doc/classes/BitMap.xml
index 7fe6a2acef..4b7f8007ca 100644
--- a/doc/classes/BitMap.xml
+++ b/doc/classes/BitMap.xml
@@ -88,7 +88,7 @@
<method name="set_bit_rect">
<return type="void">
</return>
- <argument index="0" name="p_rect" type="Rect2">
+ <argument index="0" name="rect" type="Rect2">
</argument>
<argument index="1" name="bit" type="bool">
</argument>
diff --git a/doc/classes/BitmapFont.xml b/doc/classes/BitmapFont.xml
index c943caf636..8ed563be5b 100644
--- a/doc/classes/BitmapFont.xml
+++ b/doc/classes/BitmapFont.xml
@@ -110,7 +110,7 @@
Ascent (number of pixels above the baseline).
</member>
<member name="distance_field" type="bool" setter="set_distance_field_hint" getter="is_distance_field_hint">
- If [code]true[/code] distance field hint is enabled.
+ If [code]true[/code], distance field hint is enabled.
</member>
<member name="fallback" type="BitmapFont" setter="set_fallback" getter="get_fallback">
The fallback font.
diff --git a/doc/classes/Camera.xml b/doc/classes/Camera.xml
index c7eb365891..f4b1bc1519 100644
--- a/doc/classes/Camera.xml
+++ b/doc/classes/Camera.xml
@@ -138,7 +138,7 @@
The culling mask that describes which 3D render layers are rendered by this camera.
</member>
<member name="current" type="bool" setter="set_current" getter="is_current">
- If [code]true[/code] the ancestor [Viewport] is currently using this Camera. Default value: [code]false[/code].
+ If [code]true[/code], the ancestor [Viewport] is currently using this Camera. Default value: [code]false[/code].
</member>
<member name="doppler_tracking" type="int" setter="set_doppler_tracking" getter="get_doppler_tracking" enum="Camera.DopplerTracking">
If not [code]DOPPLER_TRACKING_DISABLED[/code] this Camera will simulate the Doppler effect for objects changed in particular [code]_process[/code] methods. Default value: [code]DOPPLER_TRACKING_DISABLED[/code].
diff --git a/doc/classes/Camera2D.xml b/doc/classes/Camera2D.xml
index 39cc1b84b3..4e9efaea2d 100644
--- a/doc/classes/Camera2D.xml
+++ b/doc/classes/Camera2D.xml
@@ -68,7 +68,7 @@
The Camera2D's anchor point. See [code]ANCHOR_MODE_*[/code] constants.
</member>
<member name="current" type="bool" setter="_set_current" getter="is_current">
- If [code]true[/code] the camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one.
+ If [code]true[/code], the camera is the active camera for the current scene. Only one camera can be current, so setting a different camera [code]current[/code] will disable this one.
</member>
<member name="custom_viewport" type="Node" setter="set_custom_viewport" getter="get_custom_viewport">
The custom [Viewport] node attached to the [code]Camera2D[/code]. If null or not a [Viewport], uses the default viewport instead.
@@ -77,7 +77,7 @@
Bottom margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
<member name="drag_margin_h_enabled" type="bool" setter="set_h_drag_enabled" getter="is_h_drag_enabled">
- If [code]true[/code] the camera only moves when reaching the horizontal drag margins. If [code]false[/code] the camera moves horizontally regardless of margins. Default value: [code]true[/code].
+ If [code]true[/code], the camera only moves when reaching the horizontal drag margins. If [code]false[/code], the camera moves horizontally regardless of margins. Default value: [code]true[/code].
</member>
<member name="drag_margin_left" type="float" setter="set_drag_margin" getter="get_drag_margin">
Left margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
@@ -89,16 +89,16 @@
Top margin needed to drag the camera. A value of [code]1[/code] makes the camera move only when reaching the edge of the screen.
</member>
<member name="drag_margin_v_enabled" type="bool" setter="set_v_drag_enabled" getter="is_v_drag_enabled">
- If [code]true[/code] the camera only moves when reaching the vertical drag margins. If [code]false[/code] the camera moves vertically regardless of margins. Default value: [code]true[/code].
+ If [code]true[/code], the camera only moves when reaching the vertical drag margins. If [code]false[/code], the camera moves vertically regardless of margins. Default value: [code]true[/code].
</member>
<member name="editor_draw_drag_margin" type="bool" setter="set_margin_drawing_enabled" getter="is_margin_drawing_enabled">
- If [code]true[/code] draws the camera's drag margin rectangle in the editor. Default value: [code]false[/code]
+ If [code]true[/code], draws the camera's drag margin rectangle in the editor. Default value: [code]false[/code]
</member>
<member name="editor_draw_limits" type="bool" setter="set_limit_drawing_enabled" getter="is_limit_drawing_enabled">
- If [code]true[/code] draws the camera's limits rectangle in the editor. Default value: [code]true[/code]
+ If [code]true[/code], draws the camera's limits rectangle in the editor. Default value: [code]true[/code]
</member>
<member name="editor_draw_screen" type="bool" setter="set_screen_drawing_enabled" getter="is_screen_drawing_enabled">
- If [code]true[/code] draws the camera's screen rectangle in the editor. Default value: [code]false[/code]
+ If [code]true[/code], draws the camera's screen rectangle in the editor. Default value: [code]false[/code]
</member>
<member name="limit_bottom" type="int" setter="set_limit" getter="get_limit">
Bottom scroll limit in pixels. The camera stops moving when reaching this value.
@@ -110,7 +110,7 @@
Right scroll limit in pixels. The camera stops moving when reaching this value.
</member>
<member name="limit_smoothed" type="bool" setter="set_limit_smoothing_enabled" getter="is_limit_smoothing_enabled">
- If [code]true[/code] the camera smoothly stops when reaches its limits. Default value: [code]false[/code]
+ If [code]true[/code], the camera smoothly stops when reaches its limits. Default value: [code]false[/code]
</member>
<member name="limit_top" type="int" setter="set_limit" getter="get_limit">
Top scroll limit in pixels. The camera stops moving when reaching this value.
@@ -125,10 +125,10 @@
The vertical offset of the camera, relative to the drag margins. Default value: [code]0[/code]
</member>
<member name="rotating" type="bool" setter="set_rotating" getter="is_rotating">
- If [code]true[/code] the camera rotates with the target. Default value: [code]false[/code]
+ If [code]true[/code], the camera rotates with the target. Default value: [code]false[/code]
</member>
<member name="smoothing_enabled" type="bool" setter="set_enable_follow_smoothing" getter="is_follow_smoothing_enabled">
- If [code]true[/code] the camera smoothly moves towards the target at [member smoothing_speed]. Default value: [code]false[/code]
+ If [code]true[/code], the camera smoothly moves towards the target at [member smoothing_speed]. Default value: [code]false[/code]
</member>
<member name="smoothing_speed" type="float" setter="set_follow_smoothing" getter="get_follow_smoothing">
Speed in pixels per second of the camera's smoothing effect when [member smoothing_enabled] is [code]true[/code]
diff --git a/doc/classes/CanvasItem.xml b/doc/classes/CanvasItem.xml
index 898fce78c4..0ec28f93a7 100644
--- a/doc/classes/CanvasItem.xml
+++ b/doc/classes/CanvasItem.xml
@@ -522,16 +522,16 @@
The color applied to textures on this [code]CanvasItem[/code]. This is not inherited by children [code]CanvasItem[/code]s. Default value: [code]Color(1, 1, 1, 1)[/code] (opaque "white")..
</member>
<member name="show_behind_parent" type="bool" setter="set_draw_behind_parent" getter="is_draw_behind_parent_enabled">
- If [code]true[/code] the object draws behind its parent. Default value: [code]false[/code].
+ If [code]true[/code], the object draws behind its parent. Default value: [code]false[/code].
</member>
<member name="show_on_top" type="bool" setter="_set_on_top" getter="_is_on_top">
- If [code]true[/code] the object draws on top of its parent. Default value: [code]true[/code].
+ If [code]true[/code], the object draws on top of its parent. Default value: [code]true[/code].
</member>
<member name="use_parent_material" type="bool" setter="set_use_parent_material" getter="get_use_parent_material">
- If [code]true[/code] the parent [code]CanvasItem[/code]'s [member material] property is used as this one's material. Default value: [code]false[/code].
+ If [code]true[/code], the parent [code]CanvasItem[/code]'s [member material] property is used as this one's material. Default value: [code]false[/code].
</member>
<member name="visible" type="bool" setter="set_visible" getter="is_visible">
- If [code]true[/code] this [code]CanvasItem[/code] is drawn. Default value: [code]true[/code]. For controls that inherit [Popup], the correct way to make them visible is to call one of the multiple popup*() functions instead.
+ If [code]true[/code], this [code]CanvasItem[/code] is drawn. Default value: [code]true[/code]. For controls that inherit [Popup], the correct way to make them visible is to call one of the multiple popup*() functions instead.
</member>
</members>
<signals>
diff --git a/doc/classes/CenterContainer.xml b/doc/classes/CenterContainer.xml
index 41c8cf7100..93c4208765 100644
--- a/doc/classes/CenterContainer.xml
+++ b/doc/classes/CenterContainer.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="use_top_left" type="bool" setter="set_use_top_left" getter="is_using_top_left">
- If [code]true[/code] centers children relative to the [code]CenterContainer[/code]'s top left corner. Default value: [code]false[/code].
+ If [code]true[/code], centers children relative to the [code]CenterContainer[/code]'s top left corner. Default value: [code]false[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/CollisionObject.xml b/doc/classes/CollisionObject.xml
index 5e4e740498..f702fbadbb 100644
--- a/doc/classes/CollisionObject.xml
+++ b/doc/classes/CollisionObject.xml
@@ -57,7 +57,7 @@
<argument index="0" name="owner_id" type="int">
</argument>
<description>
- If [code]true[/code] the shape owner and its shapes are disabled.
+ If [code]true[/code], the shape owner and its shapes are disabled.
</description>
</method>
<method name="remove_shape_owner">
@@ -166,7 +166,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- If [code]true[/code] disables the given shape owner.
+ If [code]true[/code], disables the given shape owner.
</description>
</method>
<method name="shape_owner_set_transform">
@@ -183,10 +183,10 @@
</methods>
<members>
<member name="input_capture_on_drag" type="bool" setter="set_capture_input_on_drag" getter="get_capture_input_on_drag">
- If [code]true[/code] the [code]CollisionObject[/code] will continue to receive input events as the mouse is dragged across its shapes. Default value: [code]false[/code].
+ If [code]true[/code], the [code]CollisionObject[/code] will continue to receive input events as the mouse is dragged across its shapes. Default value: [code]false[/code].
</member>
<member name="input_ray_pickable" type="bool" setter="set_ray_pickable" getter="is_ray_pickable">
- If [code]true[/code] the [CollisionObject]'s shapes will respond to [RayCast]s. Default value: [code]true[/code].
+ If [code]true[/code], the [CollisionObject]'s shapes will respond to [RayCast]s. Default value: [code]true[/code].
</member>
</members>
<signals>
diff --git a/doc/classes/CollisionObject2D.xml b/doc/classes/CollisionObject2D.xml
index b507204f0d..48a198b248 100644
--- a/doc/classes/CollisionObject2D.xml
+++ b/doc/classes/CollisionObject2D.xml
@@ -53,7 +53,7 @@
<argument index="0" name="owner_id" type="int">
</argument>
<description>
- If [code]true[/code] the shape owner and its shapes are disabled.
+ If [code]true[/code], the shape owner and its shapes are disabled.
</description>
</method>
<method name="is_shape_owner_one_way_collision_enabled" qualifiers="const">
@@ -171,7 +171,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- If [code]true[/code] disables the given shape owner.
+ If [code]true[/code], disables the given shape owner.
</description>
</method>
<method name="shape_owner_set_one_way_collision">
@@ -199,7 +199,7 @@
</methods>
<members>
<member name="input_pickable" type="bool" setter="set_pickable" getter="is_pickable">
- If [code]true[/code] this object is pickable. A pickable object can detect the mouse pointer entering/leaving, and if the mouse is inside it, report input events.
+ If [code]true[/code], this object is pickable. A pickable object can detect the mouse pointer entering/leaving, and if the mouse is inside it, report input events.
</member>
</members>
<signals>
diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml
index 5b940e7ff1..f63adbf71a 100644
--- a/doc/classes/CollisionPolygon2D.xml
+++ b/doc/classes/CollisionPolygon2D.xml
@@ -17,10 +17,10 @@
Collision build mode. Use one of the [code]BUILD_*[/code] constants. Default value: [code]BUILD_SOLIDS[/code].
</member>
<member name="disabled" type="bool" setter="set_disabled" getter="is_disabled">
- If [code]true[/code] no collisions will be detected.
+ If [code]true[/code], no collisions will be detected.
</member>
<member name="one_way_collision" type="bool" setter="set_one_way_collision" getter="is_one_way_collision_enabled">
- If [code]true[/code] only edges that face up, relative to CollisionPolygon2D's rotation, will collide with other objects.
+ If [code]true[/code], only edges that face up, relative to CollisionPolygon2D's rotation, will collide with other objects.
</member>
<member name="polygon" type="PoolVector2Array" setter="set_polygon" getter="get_polygon">
The polygon's list of vertices. The final point will be connected to the first.
diff --git a/doc/classes/ColorPicker.xml b/doc/classes/ColorPicker.xml
index b3a0164704..dfe0492d0b 100644
--- a/doc/classes/ColorPicker.xml
+++ b/doc/classes/ColorPicker.xml
@@ -42,13 +42,13 @@
The currently selected color.
</member>
<member name="deferred_mode" type="bool" setter="set_deferred_mode" getter="is_deferred_mode">
- If [code]true[/code] the color will apply only after the user releases the mouse button, otherwise it will apply immediately even in mouse motion event (which can cause performance issues).
+ If [code]true[/code], the color will apply only after the user releases the mouse button, otherwise it will apply immediately even in mouse motion event (which can cause performance issues).
</member>
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha">
- If [code]true[/code] shows an alpha channel slider (transparency).
+ If [code]true[/code], shows an alpha channel slider (transparency).
</member>
<member name="raw_mode" type="bool" setter="set_raw_mode" getter="is_raw_mode">
- If [code]true[/code] allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR).
+ If [code]true[/code], allows the color R, G, B component values to go beyond 1.0, which can be used for certain special operations that require it (like tinting without darkening or rendering sprites in HDR).
</member>
</members>
<signals>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index 8bc6d05bd4..e1a6290161 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -31,7 +31,7 @@
The currently selected color.
</member>
<member name="edit_alpha" type="bool" setter="set_edit_alpha" getter="is_editing_alpha">
- If [code]true[/code] the alpha channel in the displayed [ColorPicker] will be visible. Default value: [code]true[/code].
+ If [code]true[/code], the alpha channel in the displayed [ColorPicker] will be visible. Default value: [code]true[/code].
</member>
</members>
<signals>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 76a475e49d..00802e31d7 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -340,7 +340,7 @@
<return type="void">
</return>
<description>
- Steal the focus from another control and become the focused control (see [method set_focus_mode]).
+ Steal the focus from another control and become the focused control (see [member focus_mode]).
</description>
</method>
<method name="has_color" qualifiers="const">
@@ -786,7 +786,7 @@
Sent when the node loses focus.
</constant>
<constant name="NOTIFICATION_THEME_CHANGED" value="45">
- Sent when the node's [member theme] changes, right before Godot redraws the control. Happens when you call one of the [code]add_*_override[/code]
+ Sent when the node's [member theme] changes, right before Godot redraws the control. Happens when you call one of the [code]add_*_override[/code] methods.
</constant>
<constant name="NOTIFICATION_MODAL_CLOSE" value="46">
Sent when an open modal dialog closes. See [member show_modal].
@@ -796,7 +796,7 @@
<constant name="NOTIFICATION_SCROLL_END" value="48">
</constant>
<constant name="CURSOR_ARROW" value="0" enum="CursorShape">
- Show the system's arrow mouse cursor when the user hovers the node. Use with [method set_default_cursor_shape].
+ Show the system's arrow mouse cursor when the user hovers the node. Use with [member mouse_default_cursor_shape].
</constant>
<constant name="CURSOR_IBEAM" value="1" enum="CursorShape">
Show the system's I-beam mouse cursor when the user hovers the node. The I-beam pointer has a shape similar to "I". It tells the user they can highlight or insert text.
diff --git a/doc/classes/Curve2D.xml b/doc/classes/Curve2D.xml
index ab9b27542c..dd80ec8e8f 100644
--- a/doc/classes/Curve2D.xml
+++ b/doc/classes/Curve2D.xml
@@ -24,8 +24,8 @@
<argument index="3" name="at_position" type="int" default="-1">
</argument>
<description>
- Adds a point to a curve, at "position", with control points "in" and "out".
- If "at_position" is given, the point is inserted before the point number "at_position", moving that point (and every point after) after the inserted point. If "at_position" is not given, or is an illegal value (at_position &lt;0 or at_position &gt;= [method get_point_count]), the point will be appended at the end of the point list.
+ Adds a point to a curve, at [code]position[/code], with control points [code]in[/code] and [code]out[/code].
+ If [code]at_position[/code] is given, the point is inserted before the point number [code]at_position[/code], moving that point (and every point after) after the inserted point. If [code]at_position[/code] is not given, or is an illegal value ([code]at_position &lt;0[/code] or [code]at_position &gt;= [method get_point_count][/code]), the point will be appended at the end of the point list.
</description>
</method>
<method name="clear_points">
@@ -39,7 +39,7 @@
<return type="float">
</return>
<description>
- Returns the total length of the curve, based on the cached points. Given enough density (see [method set_bake_interval]), it should be approximate enough.
+ Returns the total length of the curve, based on the cached points. Given enough density (see [member bake_interval]), it should be approximate enough.
</description>
</method>
<method name="get_baked_points" qualifiers="const">
@@ -82,7 +82,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0).
+ Returns the position of the control point leading to the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0)[/code].
</description>
</method>
<method name="get_point_out" qualifiers="const">
@@ -91,7 +91,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0).
+ Returns the position of the control point leading out of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0)[/code].
</description>
</method>
<method name="get_point_position" qualifiers="const">
@@ -100,7 +100,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0).
+ Returns the position of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0)[/code].
</description>
</method>
<method name="interpolate" qualifiers="const">
@@ -111,8 +111,8 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the position between the vertex "idx" and the vertex "idx"+1, where "t" controls if the point is the first vertex (t = 0.0), the last vertex (t = 1.0), or in between. Values of "t" outside the range (0.0 &gt;= t &lt;=1) give strange, but predictable results.
- If "idx" is out of bounds it is truncated to the first or last vertex, and "t" is ignored. If the curve has no points, the function sends an error to the console, and returns (0, 0).
+ Returns the position between the vertex [code]idx[/code] and the vertex [code]idx + 1[/code], where [code]t[/code] controls if the point is the first vertex ([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in between. Values of [code]t[/code] outside the range ([code]0.0 &gt;= t &lt;=1[/code]) give strange, but predictable results.
+ If [code]idx[/code] is out of bounds it is truncated to the first or last vertex, and [code]t[/code] is ignored. If the curve has no points, the function sends an error to the console, and returns [code](0, 0)[/code].
</description>
</method>
<method name="interpolate_baked" qualifiers="const">
@@ -123,8 +123,8 @@
<argument index="1" name="cubic" type="bool" default="false">
</argument>
<description>
- Returns a point within the curve at position "offset", where "offset" is measured as a pixel distance along the curve.
- To do that, it finds the two cached points where the "offset" lies between, then interpolates the values. This interpolation is cubic if "cubic" is set to true, or linear if set to false.
+ Returns a point within the curve at position [code]offset[/code], where [code]offset[/code] is measured as a pixel distance along the curve.
+ To do that, it finds the two cached points where the [code]offset[/code] lies between, then interpolates the values. This interpolation is cubic if [code]cubic[/code] is set to true, or linear if set to false.
Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough).
</description>
</method>
@@ -134,7 +134,7 @@
<argument index="0" name="fofs" type="float">
</argument>
<description>
- Returns the position at the vertex "fofs". It calls [method interpolate] using the integer part of fofs as "idx", and its fractional part as "t".
+ Returns the position at the vertex [code]fofs[/code]. It calls [method interpolate] using the integer part of [code]fofs[/code] as [code]idx[/code], and its fractional part as [code]t[/code].
</description>
</method>
<method name="remove_point">
@@ -143,7 +143,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Deletes the point "idx" from the curve. Sends an error to the console if "idx" is out of bounds.
+ Deletes the point [code]idx[/code] from the curve. Sends an error to the console if [code]idx[/code] is out of bounds.
</description>
</method>
<method name="set_point_in">
@@ -154,7 +154,7 @@
<argument index="1" name="position" type="Vector2">
</argument>
<description>
- Sets the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position of the control point leading to the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="set_point_out">
@@ -165,7 +165,7 @@
<argument index="1" name="position" type="Vector2">
</argument>
<description>
- Sets the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position of the control point leading out of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="set_point_position">
@@ -176,7 +176,7 @@
<argument index="1" name="position" type="Vector2">
</argument>
<description>
- Sets the position for the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position for the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="tessellate" qualifiers="const">
@@ -189,8 +189,8 @@
<description>
Returns a list of points along the curve, with a curvature controlled point density. That is, the curvier parts will have more points than the straighter parts.
This approximation makes straight segments between each point, then subdivides those segments until the resulting shape is similar enough.
- "max_stages" controls how many subdivisions a curve segment may face before it is considered approximate enough. Each subdivision splits the segment in half, so the default 5 stages may mean up to 32 subdivisions per curve segment. Increase with care!
- "tolerance_degrees" controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided.
+ [code]max_stages[/code] controls how many subdivisions a curve segment may face before it is considered approximate enough. Each subdivision splits the segment in half, so the default 5 stages may mean up to 32 subdivisions per curve segment. Increase with care!
+ [code]tolerance_degrees[/code] controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided.
</description>
</method>
</methods>
diff --git a/doc/classes/Curve3D.xml b/doc/classes/Curve3D.xml
index c3ee309f0b..3aaf7b8afb 100644
--- a/doc/classes/Curve3D.xml
+++ b/doc/classes/Curve3D.xml
@@ -24,8 +24,8 @@
<argument index="3" name="at_position" type="int" default="-1">
</argument>
<description>
- Adds a point to a curve, at "position", with control points "in" and "out".
- If "at_position" is given, the point is inserted before the point number "at_position", moving that point (and every point after) after the inserted point. If "at_position" is not given, or is an illegal value (at_position &lt;0 or at_position &gt;= [method get_point_count]), the point will be appended at the end of the point list.
+ Adds a point to a curve, at [code]position[/code], with control points [code]in[/code] and [code]out[/code].
+ If [code]at_position[/code] is given, the point is inserted before the point number [code]at_position[/code], moving that point (and every point after) after the inserted point. If [code]at_position[/code] is not given, or is an illegal value ([code]at_position &lt;0[/code] or [code]at_position &gt;= [method get_point_count][/code]), the point will be appended at the end of the point list.
</description>
</method>
<method name="clear_points">
@@ -39,7 +39,7 @@
<return type="float">
</return>
<description>
- Returns the total length of the curve, based on the cached points. Given enough density (see [method set_bake_interval]), it should be approximate enough.
+ Returns the total length of the curve, based on the cached points. Given enough density (see [member bake_interval]), it should be approximate enough.
</description>
</method>
<method name="get_baked_points" qualifiers="const">
@@ -70,7 +70,7 @@
<argument index="0" name="to_point" type="Vector3">
</argument>
<description>
- Returns the closest offset to [code]to_point[/code]. This offset is meant to be used in one of the interpolate_baked* methods.
+ Returns the closest offset to [code]to_point[/code]. This offset is meant to be used in [method interpolate_baked] or [method interpolate_baked_up_vector].
[code]to_point[/code] must be in this curve's local space.
</description>
</method>
@@ -97,7 +97,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0, 0).
+ Returns the position of the control point leading to the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0, 0)[/code].
</description>
</method>
<method name="get_point_out" qualifiers="const">
@@ -106,7 +106,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0, 0).
+ Returns the position of the control point leading out of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0, 0)[/code].
</description>
</method>
<method name="get_point_position" qualifiers="const">
@@ -115,7 +115,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the position of the vertex "idx". If the index is out of bounds, the function sends an error to the console, and returns (0, 0, 0).
+ Returns the position of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code](0, 0, 0)[/code].
</description>
</method>
<method name="get_point_tilt" qualifiers="const">
@@ -124,7 +124,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Returns the tilt angle in radians for the point "idx". If the index is out of bounds, the function sends an error to the console, and returns 0.
+ Returns the tilt angle in radians for the point [code]idx[/code]. If the index is out of bounds, the function sends an error to the console, and returns [code]0[/code].
</description>
</method>
<method name="interpolate" qualifiers="const">
@@ -135,8 +135,8 @@
<argument index="1" name="t" type="float">
</argument>
<description>
- Returns the position between the vertex "idx" and the vertex "idx"+1, where "t" controls if the point is the first vertex (t = 0.0), the last vertex (t = 1.0), or in between. Values of "t" outside the range (0.0 &gt;= t &lt;=1) give strange, but predictable results.
- If "idx" is out of bounds it is truncated to the first or last vertex, and "t" is ignored. If the curve has no points, the function sends an error to the console, and returns (0, 0, 0).
+ Returns the position between the vertex [code]idx[/code] and the vertex [code]idx + 1[/code], where [code]t[/code] controls if the point is the first vertex ([code]t = 0.0[/code]), the last vertex ([code]t = 1.0[/code]), or in between. Values of [code]t[/code] outside the range ([code]0.0 &gt;= t &lt;=1[/code]) give strange, but predictable results.
+ If [code]idx[/code] is out of bounds it is truncated to the first or last vertex, and [code]t[/code] is ignored. If the curve has no points, the function sends an error to the console, and returns [code](0, 0, 0)[/code].
</description>
</method>
<method name="interpolate_baked" qualifiers="const">
@@ -147,8 +147,8 @@
<argument index="1" name="cubic" type="bool" default="false">
</argument>
<description>
- Returns a point within the curve at position "offset", where "offset" is measured as a distance in 3D units along the curve.
- To do that, it finds the two cached points where the "offset" lies between, then interpolates the values. This interpolation is cubic if "cubic" is set to true, or linear if set to false.
+ Returns a point within the curve at position [code]offset[/code], where [code]offset[/code] is measured as a pixel distance along the curve.
+ To do that, it finds the two cached points where the [code]offset[/code] lies between, then interpolates the values. This interpolation is cubic if [code]cubic[/code] is set to true, or linear if set to false.
Cubic interpolation tends to follow the curves better, but linear is faster (and often, precise enough).
</description>
</method>
@@ -162,7 +162,7 @@
<description>
Returns an up vector within the curve at position [code]offset[/code], where [code]offset[/code] is measured as a distance in 3D units along the curve.
To do that, it finds the two cached up vectors where the [code]offset[/code] lies between, then interpolates the values. If [code]apply_tilt[/code] is [code]true[/code], an interpolated tilt is applied to the interpolated up vector.
- If the curve has no up vectors, the function sends an error to the console, and returns (0, 1, 0).
+ If the curve has no up vectors, the function sends an error to the console, and returns [code](0, 1, 0)[/code].
</description>
</method>
<method name="interpolatef" qualifiers="const">
@@ -171,7 +171,7 @@
<argument index="0" name="fofs" type="float">
</argument>
<description>
- Returns the position at the vertex "fofs". It calls [method interpolate] using the integer part of fofs as "idx", and its fractional part as "t".
+ Returns the position at the vertex [code]fofs[/code]. It calls [method interpolate] using the integer part of [code]fofs[/code] as [code]idx[/code], and its fractional part as [code]t[/code].
</description>
</method>
<method name="remove_point">
@@ -180,7 +180,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
- Deletes the point "idx" from the curve. Sends an error to the console if "idx" is out of bounds.
+ Deletes the point [code]idx[/code] from the curve. Sends an error to the console if [code]idx[/code] is out of bounds.
</description>
</method>
<method name="set_point_in">
@@ -191,7 +191,7 @@
<argument index="1" name="position" type="Vector3">
</argument>
<description>
- Sets the position of the control point leading to the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position of the control point leading to the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="set_point_out">
@@ -202,7 +202,7 @@
<argument index="1" name="position" type="Vector3">
</argument>
<description>
- Sets the position of the control point leading out of the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position of the control point leading out of the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="set_point_position">
@@ -213,7 +213,7 @@
<argument index="1" name="position" type="Vector3">
</argument>
<description>
- Sets the position for the vertex "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the position for the vertex [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
</description>
</method>
<method name="set_point_tilt">
@@ -224,7 +224,7 @@
<argument index="1" name="tilt" type="float">
</argument>
<description>
- Sets the tilt angle in radians for the point "idx". If the index is out of bounds, the function sends an error to the console.
+ Sets the tilt angle in radians for the point [code]idx[/code]. If the index is out of bounds, the function sends an error to the console.
The tilt controls the rotation along the look-at axis an object traveling the path would have. In the case of a curve controlling a [PathFollow] or [OrientedPathFollow], this tilt is an offset over the natural tilt the [PathFollow] or [OrientedPathFollow] calculates.
</description>
</method>
@@ -238,8 +238,8 @@
<description>
Returns a list of points along the curve, with a curvature controlled point density. That is, the curvier parts will have more points than the straighter parts.
This approximation makes straight segments between each point, then subdivides those segments until the resulting shape is similar enough.
- "max_stages" controls how many subdivisions a curve segment may face before it is considered approximate enough. Each subdivision splits the segment in half, so the default 5 stages may mean up to 32 subdivisions per curve segment. Increase with care!
- "tolerance_degrees" controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided.
+ [code]max_stages[/code] controls how many subdivisions a curve segment may face before it is considered approximate enough. Each subdivision splits the segment in half, so the default 5 stages may mean up to 32 subdivisions per curve segment. Increase with care!
+ [code]tolerance_degrees[/code] controls how many degrees the midpoint of a segment may deviate from the real curve, before the segment has to be subdivided.
</description>
</method>
</methods>
diff --git a/doc/classes/DirectionalLight.xml b/doc/classes/DirectionalLight.xml
index 86c8f2f03a..63d686fe24 100644
--- a/doc/classes/DirectionalLight.xml
+++ b/doc/classes/DirectionalLight.xml
@@ -18,7 +18,7 @@
Amount of extra bias for shadow splits that are far away. If self shadowing occurs only on the splits far away, this value can fix them.
</member>
<member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled">
- If [code]true[/code] shadow detail is sacrificed in exchange for smoother transitions between splits. Default value:[code]false[/code].
+ If [code]true[/code], shadow detail is sacrificed in exchange for smoother transitions between splits. Default value:[code]false[/code].
</member>
<member name="directional_shadow_depth_range" type="int" setter="set_shadow_depth_range" getter="get_shadow_depth_range" enum="DirectionalLight.ShadowDepthRange">
Optimizes shadow rendering for detail versus movement. See [enum ShadowDepthRange].
diff --git a/doc/classes/DynamicFont.xml b/doc/classes/DynamicFont.xml
index 2e2904c16c..249d0955f2 100644
--- a/doc/classes/DynamicFont.xml
+++ b/doc/classes/DynamicFont.xml
@@ -81,10 +81,10 @@
The font size.
</member>
<member name="use_filter" type="bool" setter="set_use_filter" getter="get_use_filter">
- If [code]true[/code] filtering is used.
+ If [code]true[/code], filtering is used.
</member>
<member name="use_mipmaps" type="bool" setter="set_use_mipmaps" getter="get_use_mipmaps">
- If [code]true[/code] mipmapping is used.
+ If [code]true[/code], mipmapping is used.
</member>
</members>
<constants>
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
index fed9e264db..fc5a26fc33 100644
--- a/doc/classes/EditorFileDialog.xml
+++ b/doc/classes/EditorFileDialog.xml
@@ -55,7 +55,7 @@
The file system path in the address bar.
</member>
<member name="disable_overwrite_warning" type="bool" setter="set_disable_overwrite_warning" getter="is_overwrite_warning_disabled">
- If [code]true[/code] the [code]EditorFileDialog[/code] will not warn the user before overwriting files.
+ If [code]true[/code], the [code]EditorFileDialog[/code] will not warn the user before overwriting files.
</member>
<member name="display_mode" type="int" setter="set_display_mode" getter="get_display_mode" enum="EditorFileDialog.DisplayMode">
The view format in which the [code]EditorFileDialog[/code] displays resources to the user.
@@ -64,7 +64,7 @@
The purpose of the [code]EditorFileDialog[/code]. Changes allowed behaviors.
</member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files">
- If [code]true[/code] hidden files and directories will be visible in the [code]EditorFileDialog[/code].
+ If [code]true[/code], hidden files and directories will be visible in the [code]EditorFileDialog[/code].
</member>
</members>
<signals>
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index d1e90470e1..9005d4a765 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
EditorImportPlugins provide a way to extend the editor's resource import functionality. Use them to import resources from custom files or to provide alternatives to the editor's existing importers. Register your [EditorPlugin] with [method EditorPlugin.add_import_plugin].
- EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extension] and [method get_resource_type]). They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory.
+ EditorImportPlugins work by associating with specific file extensions and a resource type. See [method get_recognized_extensions] and [method get_resource_type]). They may optionally specify some import presets that affect the import process. EditorImportPlugins are responsible for creating the resources and saving them in the [code].import[/code] directory.
Below is an example EditorImportPlugin that imports a [Mesh] from a file with the extension ".special" or ".spec":
[codeblock]
tool
@@ -60,7 +60,7 @@
<argument index="0" name="preset" type="int">
</argument>
<description>
- Get the options and default values for the preset at this index. Returns an Array of Dictionaries with the following keys: "name", "default_value", "property_hint" (optional), "hint_string" (optional), "usage" (optional).
+ Get the options and default values for the preset at this index. Returns an Array of Dictionaries with the following keys: [code]name[/code], [code]default_value[/code], [code]property_hint[/code] (optional), [code]hint_string[/code] (optional), [code]usage[/code] (optional).
</description>
</method>
<method name="get_import_order" qualifiers="virtual">
@@ -114,14 +114,14 @@
<return type="Array">
</return>
<description>
- Get the list of file extensions to associate with this loader (case insensitive). e.g. ["obj"].
+ Get the list of file extensions to associate with this loader (case insensitive). e.g. [code]["obj"][/code].
</description>
</method>
<method name="get_resource_type" qualifiers="virtual">
<return type="String">
</return>
<description>
- Get the Godot resource type associated with this loader. e.g. "Mesh" or "Animation".
+ Get the Godot resource type associated with this loader. e.g. [code]"Mesh"[/code] or [code]"Animation"[/code].
</description>
</method>
<method name="get_save_extension" qualifiers="virtual">
@@ -147,9 +147,9 @@
</argument>
<argument index="2" name="options" type="Dictionary">
</argument>
- <argument index="3" name="r_platform_variants" type="Array">
+ <argument index="3" name="platform_variants" type="Array">
</argument>
- <argument index="4" name="r_gen_files" type="Array">
+ <argument index="4" name="gen_files" type="Array">
</argument>
<description>
</description>
diff --git a/doc/classes/EditorInterface.xml b/doc/classes/EditorInterface.xml
index f073c5e40b..c7b81d7c75 100644
--- a/doc/classes/EditorInterface.xml
+++ b/doc/classes/EditorInterface.xml
@@ -159,7 +159,7 @@
<method name="select_file">
<return type="void">
</return>
- <argument index="0" name="p_file" type="String">
+ <argument index="0" name="file" type="String">
</argument>
<description>
</description>
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index feaa24b0ab..f1c3481562 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -110,6 +110,14 @@
<description>
</description>
</method>
+ <method name="add_spatial_gizmo_plugin">
+ <return type="void">
+ </return>
+ <argument index="0" name="plugin" type="EditorSpatialGizmoPlugin">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="add_tool_menu_item">
<return type="void">
</return>
@@ -157,6 +165,12 @@
Clear all the state and reset the object being edited to zero. This ensures your plugin does not keep editing a currently existing node, or a node from the wrong scene.
</description>
</method>
+ <method name="disable_plugin" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="edit" qualifiers="virtual">
<return type="void">
</return>
@@ -166,6 +180,12 @@
This function is used for plugins that edit specific object types (nodes or resources). It requests the editor to edit the given object.
</description>
</method>
+ <method name="enable_plugin" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="forward_canvas_draw_over_viewport" qualifiers="virtual">
<return type="void">
</return>
@@ -394,6 +414,14 @@
<description>
</description>
</method>
+ <method name="remove_spatial_gizmo_plugin">
+ <return type="void">
+ </return>
+ <argument index="0" name="plugin" type="EditorSpatialGizmoPlugin">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="remove_tool_menu_item">
<return type="void">
</return>
diff --git a/doc/classes/EditorSpatialGizmoPlugin.xml b/doc/classes/EditorSpatialGizmoPlugin.xml
new file mode 100644
index 0000000000..521ec748b3
--- /dev/null
+++ b/doc/classes/EditorSpatialGizmoPlugin.xml
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="EditorSpatialGizmoPlugin" inherits="Resource" category="Core" version="3.1">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ <method name="add_material">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="material" type="SpatialMaterial">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="can_be_hidden" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="commit_handle" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <argument index="1" name="index" type="int">
+ </argument>
+ <argument index="2" name="restore" type="Variant">
+ </argument>
+ <argument index="3" name="cancel" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_gizmo" qualifiers="virtual">
+ <return type="EditorSpatialGizmo">
+ </return>
+ <argument index="0" name="spatial" type="Spatial">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_handle_material">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="billboard" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_icon_material">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="texture" type="Texture">
+ </argument>
+ <argument index="2" name="on_top" type="bool" default="false">
+ </argument>
+ <argument index="3" name="color" type="Color" default="Color( 1, 1, 1, 1 )">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create_material">
+ <return type="void">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <argument index="2" name="billboard" type="bool" default="false">
+ </argument>
+ <argument index="3" name="on_top" type="bool" default="false">
+ </argument>
+ <argument index="4" name="use_vertex_color" type="bool" default="false">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_handle_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <argument index="1" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_handle_value" qualifiers="virtual">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <argument index="1" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_material">
+ <return type="SpatialMaterial">
+ </return>
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="has_gizmo" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <argument index="0" name="spatial" type="Spatial">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_gizmo_handle_highlighted" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <argument index="1" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="is_selectable_when_hidden" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="redraw" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_handle" qualifiers="virtual">
+ <return type="void">
+ </return>
+ <argument index="0" name="gizmo" type="EditorSpatialGizmo">
+ </argument>
+ <argument index="1" name="index" type="int">
+ </argument>
+ <argument index="2" name="camera" type="Camera">
+ </argument>
+ <argument index="3" name="point" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index 058bb09090..1967349546 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -404,7 +404,7 @@
</methods>
<members>
<member name="endian_swap" type="bool" setter="set_endian_swap" getter="get_endian_swap">
- If [code]true[/code] the file's endianness is swapped. Use this if you're dealing with files written in big endian machines.
+ If [code]true[/code], the file's endianness is swapped. Use this if you're dealing with files written in big endian machines.
Note that this is about the file format, not CPU type. This is always reset to [code]false[/code] whenever you open the file.
</member>
</members>
diff --git a/doc/classes/FileDialog.xml b/doc/classes/FileDialog.xml
index 29aa26b67f..0af645975a 100644
--- a/doc/classes/FileDialog.xml
+++ b/doc/classes/FileDialog.xml
@@ -76,7 +76,7 @@
Set dialog to open or save mode, changes selection behavior. See enum [code]Mode[/code] constants.
</member>
<member name="mode_overrides_title" type="bool" setter="set_mode_overrides_title" getter="is_mode_overriding_title">
- If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e. g. setting mode to [code]MODE_OPEN_FILE[/code] will change the window title to "Open a File").
+ If [code]true[/code], changing the [code]Mode[/code] property will set the window title accordingly (e.g. setting mode to [code]MODE_OPEN_FILE[/code] will change the window title to "Open a File").
</member>
<member name="show_hidden_files" type="bool" setter="set_show_hidden_files" getter="is_showing_hidden_files">
If [code]true[/code], the dialog will show hidden files.
diff --git a/doc/classes/GDNativeLibraryResourceLoader.xml b/doc/classes/GDNativeLibraryResourceLoader.xml
new file mode 100644
index 0000000000..865381667d
--- /dev/null
+++ b/doc/classes/GDNativeLibraryResourceLoader.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GDNativeLibraryResourceLoader" inherits="ResourceFormatLoader" category="Core" version="3.1">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/GDNativeLibraryResourceSaver.xml b/doc/classes/GDNativeLibraryResourceSaver.xml
new file mode 100644
index 0000000000..39f423d762
--- /dev/null
+++ b/doc/classes/GDNativeLibraryResourceSaver.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="GDNativeLibraryResourceSaver" inherits="ResourceFormatSaver" category="Core" version="3.1">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/Generic6DOFJoint.xml b/doc/classes/Generic6DOFJoint.xml
index b6ac69e257..95f9a76662 100644
--- a/doc/classes/Generic6DOFJoint.xml
+++ b/doc/classes/Generic6DOFJoint.xml
@@ -18,7 +18,7 @@
The lower, the longer an impulse from one side takes to travel to the other side.
</member>
<member name="angular_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
- If [code]true[/code] rotation across the x-axis is limited.
+ If [code]true[/code], rotation across the x-axis is limited.
</member>
<member name="angular_limit_x/erp" type="float" setter="set_param_x" getter="get_param_x">
When rotating across x-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
@@ -42,7 +42,7 @@
The amount of rotational damping across the y-axis. The lower, the more dampening occurs.
</member>
<member name="angular_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
- If [code]true[/code] rotation across the y-axis is limited.
+ If [code]true[/code], rotation across the y-axis is limited.
</member>
<member name="angular_limit_y/erp" type="float" setter="set_param_y" getter="get_param_y">
When rotating across y-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
@@ -66,7 +66,7 @@
The amount of rotational damping across the z-axis. The lower, the more dampening occurs.
</member>
<member name="angular_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
- If [code]true[/code] rotation across the z-axis is limited.
+ If [code]true[/code], rotation across the z-axis is limited.
</member>
<member name="angular_limit_z/erp" type="float" setter="set_param_z" getter="get_param_z">
When rotating across z-axis, this error tolerance factor defines how much the correction gets slowed down. The lower, the slower.
@@ -87,7 +87,7 @@
The minimum rotation in positive direction to break loose and rotate around the z-axis.
</member>
<member name="angular_motor_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
- If [code]true[/code] a rotating motor at the x-axis is enabled.
+ If [code]true[/code], a rotating motor at the x-axis is enabled.
</member>
<member name="angular_motor_x/force_limit" type="float" setter="set_param_x" getter="get_param_x">
Maximum acceleration for the motor at the x-axis.
@@ -96,7 +96,7 @@
Target speed for the motor at the x-axis.
</member>
<member name="angular_motor_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
- If [code]true[/code] a rotating motor at the y-axis is enabled.
+ If [code]true[/code], a rotating motor at the y-axis is enabled.
</member>
<member name="angular_motor_y/force_limit" type="float" setter="set_param_y" getter="get_param_y">
Maximum acceleration for the motor at the y-axis.
@@ -105,7 +105,7 @@
Target speed for the motor at the y-axis.
</member>
<member name="angular_motor_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
- If [code]true[/code] a rotating motor at the z-axis is enabled.
+ If [code]true[/code], a rotating motor at the z-axis is enabled.
</member>
<member name="angular_motor_z/force_limit" type="float" setter="set_param_z" getter="get_param_z">
Maximum acceleration for the motor at the z-axis.
@@ -141,7 +141,7 @@
The amount of damping that happens at the x-motion.
</member>
<member name="linear_limit_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
- If [code]true[/code] the linear motion across the x-axis is limited.
+ If [code]true[/code], the linear motion across the x-axis is limited.
</member>
<member name="linear_limit_x/lower_distance" type="float" setter="set_param_x" getter="get_param_x">
The minimum difference between the pivot points' x-axis.
@@ -159,7 +159,7 @@
The amount of damping that happens at the y-motion.
</member>
<member name="linear_limit_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
- If [code]true[/code] the linear motion across the y-axis is limited.
+ If [code]true[/code], the linear motion across the y-axis is limited.
</member>
<member name="linear_limit_y/lower_distance" type="float" setter="set_param_y" getter="get_param_y">
The minimum difference between the pivot points' y-axis.
@@ -177,7 +177,7 @@
The amount of damping that happens at the z-motion.
</member>
<member name="linear_limit_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
- If [code]true[/code] the linear motion across the z-axis is limited.
+ If [code]true[/code], the linear motion across the z-axis is limited.
</member>
<member name="linear_limit_z/lower_distance" type="float" setter="set_param_z" getter="get_param_z">
The minimum difference between the pivot points' z-axis.
@@ -192,7 +192,7 @@
The maximum difference between the pivot points' z-axis.
</member>
<member name="linear_motor_x/enabled" type="bool" setter="set_flag_x" getter="get_flag_x">
- If [code]true[/code] then there is a linear motor on the x-axis. It will attempt to reach the target velocity while staying within the force limits.
+ If [code]true[/code], then there is a linear motor on the x-axis. It will attempt to reach the target velocity while staying within the force limits.
</member>
<member name="linear_motor_x/force_limit" type="float" setter="set_param_x" getter="get_param_x">
The maximum force the linear motor can apply on the x-axis while trying to reach the target velocity.
@@ -201,7 +201,7 @@
The speed that the linear motor will attempt to reach on the x-axis.
</member>
<member name="linear_motor_y/enabled" type="bool" setter="set_flag_y" getter="get_flag_y">
- If [code]true[/code] then there is a linear motor on the y-axis. It will attempt to reach the target velocity while staying within the force limits.
+ If [code]true[/code], then there is a linear motor on the y-axis. It will attempt to reach the target velocity while staying within the force limits.
</member>
<member name="linear_motor_y/force_limit" type="float" setter="set_param_y" getter="get_param_y">
The maximum force the linear motor can apply on the y-axis while trying to reach the target velocity.
@@ -210,7 +210,7 @@
The speed that the linear motor will attempt to reach on the y-axis.
</member>
<member name="linear_motor_z/enabled" type="bool" setter="set_flag_z" getter="get_flag_z">
- If [code]true[/code] then there is a linear motor on the z-axis. It will attempt to reach the target velocity while staying within the force limits.
+ If [code]true[/code], then there is a linear motor on the z-axis. It will attempt to reach the target velocity while staying within the force limits.
</member>
<member name="linear_motor_z/force_limit" type="float" setter="set_param_z" getter="get_param_z">
The maximum force the linear motor can apply on the z-axis while trying to reach the target velocity.
diff --git a/doc/classes/GeometryInstance.xml b/doc/classes/GeometryInstance.xml
index 8831805dde..d6267044f7 100644
--- a/doc/classes/GeometryInstance.xml
+++ b/doc/classes/GeometryInstance.xml
@@ -36,7 +36,7 @@
If there is a material in material_override, it will be used instead of any material set in any material slot of the mesh.
</member>
<member name="use_in_baked_light" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] this GeometryInstance will be used when baking lights using a [GIProbe] and/or any other form of baked lighting.
+ If [code]true[/code], this GeometryInstance will be used when baking lights using a [GIProbe] and/or any other form of baked lighting.
</member>
</members>
<constants>
diff --git a/doc/classes/GradientTexture.xml b/doc/classes/GradientTexture.xml
index 9d2465e23d..d064e15e17 100644
--- a/doc/classes/GradientTexture.xml
+++ b/doc/classes/GradientTexture.xml
@@ -4,7 +4,7 @@
Gradient filled texture.
</brief_description>
<description>
- Uses a [Gradient] to fill the texture data, the gradient will be filled from left to right using colors obtained from the gradient, this means that the texture does not necessarily represent an exact copy of the gradient, but instead an interpolation of samples obtained from the gradient at fixed steps (see [method set_width]).
+ Uses a [Gradient] to fill the texture data, the gradient will be filled from left to right using colors obtained from the gradient, this means that the texture does not necessarily represent an exact copy of the gradient, but instead an interpolation of samples obtained from the gradient at fixed steps (see [member width]).
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index 5ac3db1e8e..e778a6423a 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -254,7 +254,7 @@
</description>
</signal>
<signal name="popup_request">
- <argument index="0" name="p_position" type="Vector2">
+ <argument index="0" name="position" type="Vector2">
</argument>
<description>
Signal sent when a popup is requested. Happens on right-clicking in the GraphEdit. 'p_position' is the position of the mouse pointer when the signal is sent.
diff --git a/doc/classes/GridContainer.xml b/doc/classes/GridContainer.xml
index 346ab9d357..a304f34ed2 100644
--- a/doc/classes/GridContainer.xml
+++ b/doc/classes/GridContainer.xml
@@ -4,7 +4,7 @@
Grid container used to arrange elements in a grid like layout.
</brief_description>
<description>
- Grid container will arrange its children in a grid like structure, the grid columns are specified using the [method set_columns] method and the number of rows will be equal to the number of children in the container divided by the number of columns, for example: if the container has 5 children, and 2 columns, there will be 3 rows in the container. Notice that grid layout will preserve the columns and rows for every size of the container.
+ Grid container will arrange its children in a grid like structure, the grid columns are specified using the [member columns] property and the number of rows will be equal to the number of children in the container divided by the number of columns, for example: if the container has 5 children, and 2 columns, there will be 3 rows in the container. Notice that grid layout will preserve the columns and rows for every size of the container.
</description>
<tutorials>
</tutorials>
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index 3172a5d6c0..5436e2b1eb 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -82,14 +82,14 @@
<return type="bool">
</return>
<description>
- If [code]true[/code] this [code]HTTPClient[/code] has a response available.
+ If [code]true[/code], this [code]HTTPClient[/code] has a response available.
</description>
</method>
<method name="is_response_chunked" qualifiers="const">
<return type="bool">
</return>
<description>
- If [code]true[/code] this [code]HTTPClient[/code] has a response that is chunked.
+ If [code]true[/code], this [code]HTTPClient[/code] has a response that is chunked.
</description>
</method>
<method name="poll">
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index 3916eb2b5b..3271fef8e3 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -71,7 +71,7 @@
Maximum number of allowed redirects.
</member>
<member name="use_threads" type="bool" setter="set_use_threads" getter="is_using_threads">
- If [code]true[/code] multithreading is used to improve performance.
+ If [code]true[/code], multithreading is used to improve performance.
</member>
</members>
<signals>
@@ -102,16 +102,16 @@
Request failed while resolving.
</constant>
<constant name="RESULT_CONNECTION_ERROR" value="4" enum="Result">
- Request failed due to connection(read/write) error.
+ Request failed due to connection (read/write) error.
</constant>
<constant name="RESULT_SSL_HANDSHAKE_ERROR" value="5" enum="Result">
Request failed on SSL handshake.
</constant>
<constant name="RESULT_NO_RESPONSE" value="6" enum="Result">
- Request does not have a response(yet).
+ Request does not have a response (yet).
</constant>
<constant name="RESULT_BODY_SIZE_LIMIT_EXCEEDED" value="7" enum="Result">
- Request exceeded its maximum size limit, see [method set_body_size_limit].
+ Request exceeded its maximum size limit, see [member body_size_limit].
</constant>
<constant name="RESULT_REQUEST_FAILED" value="8" enum="Result">
Request failed. (Unused)
@@ -123,7 +123,7 @@
HTTPRequest couldn't write to the download file.
</constant>
<constant name="RESULT_REDIRECT_LIMIT_REACHED" value="11" enum="Result">
- Request reached its maximum redirect limit, see [method set_max_redirects].
+ Request reached its maximum redirect limit, see [member max_redirects].
</constant>
</constants>
</class>
diff --git a/doc/classes/HingeJoint.xml b/doc/classes/HingeJoint.xml
index 3c5719056b..41d3b2311d 100644
--- a/doc/classes/HingeJoint.xml
+++ b/doc/classes/HingeJoint.xml
@@ -17,7 +17,7 @@
The speed with which the rotation across the axis perpendicular to the hinge gets corrected.
</member>
<member name="angular_limit/enable" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
+ If [code]true[/code], the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
</member>
<member name="angular_limit/lower" type="float" setter="_set_lower_limit" getter="_get_lower_limit">
The minimum rotation. only active if [member angular_limit/enable] is [code]true[/code].
@@ -71,7 +71,7 @@
End flag of PARAM_* constants, used internally.
</constant>
<constant name="FLAG_USE_LIMIT" value="0" enum="Flag">
- If [code]true[/code] the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
+ If [code]true[/code], the hinges maximum and minimum rotation, defined by [member angular_limit/lower] and [member angular_limit/upper] has effects.
</constant>
<constant name="FLAG_ENABLE_MOTOR" value="1" enum="Flag">
When activated, a motor turns the hinge.
diff --git a/doc/classes/ImageTexture.xml b/doc/classes/ImageTexture.xml
index 5c57899468..579886c771 100644
--- a/doc/classes/ImageTexture.xml
+++ b/doc/classes/ImageTexture.xml
@@ -23,9 +23,8 @@
<argument index="3" name="flags" type="int" default="7">
</argument>
<description>
- Create a new [code]ImageTexture[/code] with "width" and "height".
- "format" one of [Image].FORMAT_*.
- "flags" one or more of [Texture].FLAG_*.
+ Create a new [code]ImageTexture[/code] with [code]width[/code] and [code]height[/code].
+ [code]format[/code] is a value from [enum Image.Format], [code]flags[/code] is any combination of [enum Texture.Flags].
</description>
</method>
<method name="create_from_image">
@@ -36,14 +35,14 @@
<argument index="1" name="flags" type="int" default="7">
</argument>
<description>
- Create a new [code]ImageTexture[/code] from an [Image] with "flags" from [Texture].FLAG_*. An sRGB to linear color space conversion can take place, according to [Image].FORMAT_*.
+ Create a new [code]ImageTexture[/code] from an [Image] with [code]flags[/code] from [enum Texture.Flags]. An sRGB to linear color space conversion can take place, according to [enum Image.Format].
</description>
</method>
<method name="get_format" qualifiers="const">
<return type="int" enum="Image.Format">
</return>
<description>
- Return the format of the [code]ImageTexture[/code], one of [Image].FORMAT_*.
+ Return the format of the [code]ImageTexture[/code], one of [enum Image.Format].
</description>
</method>
<method name="load">
@@ -76,7 +75,7 @@
</methods>
<members>
<member name="lossy_quality" type="float" setter="set_lossy_storage_quality" getter="get_lossy_storage_quality">
- The storage quality for [code]ImageTexture[/code].STORAGE_COMPRESS_LOSSY.
+ The storage quality for [code]STORAGE_COMPRESS_LOSSY[/code].
</member>
<member name="storage" type="int" setter="set_storage" getter="get_storage" enum="ImageTexture.Storage">
The storage type (raw, lossy, or compressed).
@@ -87,7 +86,7 @@
[Image] data is stored raw and unaltered.
</constant>
<constant name="STORAGE_COMPRESS_LOSSY" value="1" enum="Storage">
- [Image] data is compressed with a lossy algorithm. You can set the storage quality with [method set_lossy_storage_quality].
+ [Image] data is compressed with a lossy algorithm. You can set the storage quality with [member lossy_quality].
</constant>
<constant name="STORAGE_COMPRESS_LOSSLESS" value="2" enum="Storage">
[Image] data is compressed with a lossless algorithm.
diff --git a/doc/classes/InputEventAction.xml b/doc/classes/InputEventAction.xml
index 8a10dc6ab9..bd0d774180 100644
--- a/doc/classes/InputEventAction.xml
+++ b/doc/classes/InputEventAction.xml
@@ -18,7 +18,7 @@
The action's name. Actions are accessed via this [String].
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the action's state is pressed. If [code]false[/code] the action's state is released.
+ If [code]true[/code], the action's state is pressed. If [code]false[/code], the action's state is released.
</member>
</members>
<constants>
diff --git a/doc/classes/InputEventJoypadButton.xml b/doc/classes/InputEventJoypadButton.xml
index 18e33c2131..1875ea508a 100644
--- a/doc/classes/InputEventJoypadButton.xml
+++ b/doc/classes/InputEventJoypadButton.xml
@@ -18,7 +18,7 @@
Button identifier. One of the [code]JOY_BUTTON_*[/code] constants from [@GlobalScope].
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the button's state is pressed. If [code]false[/code] the button's state is released.
+ If [code]true[/code], the button's state is pressed. If [code]false[/code], the button's state is released.
</member>
<member name="pressure" type="float" setter="set_pressure" getter="get_pressure">
Represents the pressure the user puts on the button with his finger, if the controller supports it. Ranges from [code]0[/code] to [code]1[/code].
diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml
index 0118fda2df..4d8a2f6242 100644
--- a/doc/classes/InputEventKey.xml
+++ b/doc/classes/InputEventKey.xml
@@ -22,10 +22,10 @@
</methods>
<members>
<member name="echo" type="bool" setter="set_echo" getter="is_echo">
- If [code]true[/code] the key was already pressed before this event. It means the user is holding the key down.
+ If [code]true[/code], the key was already pressed before this event. It means the user is holding the key down.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the key's state is pressed. If [code]false[/code] the key's state is released.
+ If [code]true[/code], the key's state is pressed. If [code]false[/code], the key's state is released.
</member>
<member name="scancode" type="int" setter="set_scancode" getter="get_scancode">
Key scancode, one of the [code]KEY_*[/code] constants in [@GlobalScope].
diff --git a/doc/classes/InputEventMouseButton.xml b/doc/classes/InputEventMouseButton.xml
index 1342c7bf7e..8603a4f673 100644
--- a/doc/classes/InputEventMouseButton.xml
+++ b/doc/classes/InputEventMouseButton.xml
@@ -18,13 +18,13 @@
Mouse button identifier, one of the BUTTON_* or BUTTON_WHEEL_* constants in [@GlobalScope].
</member>
<member name="doubleclick" type="bool" setter="set_doubleclick" getter="is_doubleclick">
- If [code]true[/code] the mouse button's state is a double-click.
+ If [code]true[/code], the mouse button's state is a double-click.
</member>
<member name="factor" type="float" setter="set_factor" getter="get_factor">
Magnitude. Amount (or delta) of the event. Used for scroll events, indicates scroll amount (vertically or horizontally). Only supported on some platforms, sensitivity varies by platform. May be 0 if not supported.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the mouse button's state is pressed. If [code]false[/code] the mouse button's state is released.
+ If [code]true[/code], the mouse button's state is pressed. If [code]false[/code], the mouse button's state is released.
</member>
</members>
<constants>
diff --git a/doc/classes/InputEventScreenTouch.xml b/doc/classes/InputEventScreenTouch.xml
index 55f04cdd94..8b1b9cae9f 100644
--- a/doc/classes/InputEventScreenTouch.xml
+++ b/doc/classes/InputEventScreenTouch.xml
@@ -22,7 +22,7 @@
Touch position.
</member>
<member name="pressed" type="bool" setter="set_pressed" getter="is_pressed">
- If [code]true[/code] the touch's state is pressed. If [code]false[/code] the touch's state is released.
+ If [code]true[/code], the touch's state is pressed. If [code]false[/code], the touch's state is released.
</member>
</members>
<constants>
diff --git a/doc/classes/InterpolatedCamera.xml b/doc/classes/InterpolatedCamera.xml
index 1ac7b5107e..fdb4361091 100644
--- a/doc/classes/InterpolatedCamera.xml
+++ b/doc/classes/InterpolatedCamera.xml
@@ -24,7 +24,7 @@
</methods>
<members>
<member name="enabled" type="bool" setter="set_interpolation_enabled" getter="is_interpolation_enabled">
- If [code]true[/code] and a target is set, the camera will move automatically.
+ If [code]true[/code], and a target is set, the camera will move automatically.
</member>
<member name="speed" type="float" setter="set_speed" getter="get_speed">
How quickly the camera moves toward its target. Higher values will result in tighter camera motion.
diff --git a/doc/classes/ItemList.xml b/doc/classes/ItemList.xml
index 0b8ede92d5..4df8a14804 100644
--- a/doc/classes/ItemList.xml
+++ b/doc/classes/ItemList.xml
@@ -388,10 +388,10 @@
</methods>
<members>
<member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect">
- If [code]true[/code] the currently selected item may be selected again.
+ If [code]true[/code], the currently selected item may be selected again.
</member>
<member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select">
- If [code]true[/code] a right mouse button click can select items.
+ If [code]true[/code], a right mouse button click can select items.
</member>
<member name="auto_height" type="bool" setter="set_auto_height" getter="has_auto_height">
</member>
diff --git a/doc/classes/Joint.xml b/doc/classes/Joint.xml
index 8cafdbdbf3..6c93b1d1d2 100644
--- a/doc/classes/Joint.xml
+++ b/doc/classes/Joint.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="collision/exclude_nodes" type="bool" setter="set_exclude_nodes_from_collision" getter="get_exclude_nodes_from_collision">
- If [code]true[/code] the two bodies of the nodes are not able to collide with each other.
+ If [code]true[/code], the two bodies of the nodes are not able to collide with each other.
</member>
<member name="nodes/node_a" type="NodePath" setter="set_node_a" getter="get_node_a">
The [Node], the first side of the Joint attaches to.
diff --git a/doc/classes/Joint2D.xml b/doc/classes/Joint2D.xml
index 8247997927..641765e671 100644
--- a/doc/classes/Joint2D.xml
+++ b/doc/classes/Joint2D.xml
@@ -17,7 +17,7 @@
When [member node_a] and [member node_b] move in different directions the [code]bias[/code] controls how fast the joint pulls them back to their original position. The lower the [code]bias[/code] the more the two bodies can pull on the joint. Default value: [code]0[/code]
</member>
<member name="disable_collision" type="bool" setter="set_exclude_nodes_from_collision" getter="get_exclude_nodes_from_collision">
- If [code]true[/code] [member node_a] and [member node_b] can collide. Default value: [code]false[/code].
+ If [code]true[/code], [member node_a] and [member node_b] can collide. Default value: [code]false[/code].
</member>
<member name="node_a" type="NodePath" setter="set_node_a" getter="get_node_a">
The first body attached to the joint. Must derive from [PhysicsBody2D].
diff --git a/doc/classes/KinematicBody.xml b/doc/classes/KinematicBody.xml
index df8fb251ba..ad41f48ddd 100644
--- a/doc/classes/KinematicBody.xml
+++ b/doc/classes/KinematicBody.xml
@@ -89,7 +89,7 @@
</argument>
<description>
Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [code]KinematicBody[/code] or [RigidBody], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes.
- [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it with [code]delta[/code] — this is done by the method.
+ [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it by [code]delta[/code] — this is done by the method.
[code]floor_normal[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector3(0, 0, 0)[/code], everything is considered a wall. This is useful for topdown games.
[i]TODO: Update for new stop_on_slode argument.[/i] If the body is standing on a slope and the horizontal speed (relative to the floor's speed) goes below [code]slope_stop_min_velocity[/code], the body will stop completely. This prevents the body from sliding down slopes when you include gravity in [code]linear_velocity[/code]. When set to lower values, the body will not be able to stand still on steep slopes.
If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops.
@@ -138,10 +138,13 @@
If the body is at least this close to another body, this body will consider them to be colliding.
</member>
<member name="move_lock_x" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the x-axis.
</member>
<member name="move_lock_y" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the y-axis.
</member>
<member name="move_lock_z" type="bool" setter="set_axis_lock" getter="get_axis_lock">
+ Lock the body's movement in the z-axis.
</member>
</members>
<constants>
diff --git a/doc/classes/KinematicBody2D.xml b/doc/classes/KinematicBody2D.xml
index 8a644447ca..12d2bcec77 100644
--- a/doc/classes/KinematicBody2D.xml
+++ b/doc/classes/KinematicBody2D.xml
@@ -89,7 +89,7 @@
</argument>
<description>
Moves the body along a vector. If the body collides with another, it will slide along the other body rather than stop immediately. If the other body is a [code]KinematicBody2D[/code] or [RigidBody2D], it will also be affected by the motion of the other body. You can use this to make moving or rotating platforms, or to make nodes push other nodes.
- [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it with [code]delta[/code] — this is done by the method.
+ [code]linear_velocity[/code] is a value in pixels per second. Unlike in for example [method move_and_collide], you should [i]not[/i] multiply it by [code]delta[/code] — this is done by the method.
[code]floor_normal[/code] is the up direction, used to determine what is a wall and what is a floor or a ceiling. If set to the default value of [code]Vector2(0, 0)[/code], everything is considered a wall. This is useful for topdown games.
[i]TODO: Update for stop_on_slope argument.[/i] If the body is standing on a slope and the horizontal speed (relative to the floor's speed) goes below [code]slope_stop_min_velocity[/code], the body will stop completely. This prevents the body from sliding down slopes when you include gravity in [code]linear_velocity[/code]. When set to lower values, the body will not be able to stand still on steep slopes.
If the body collides, it will change direction a maximum of [code]max_slides[/code] times before it stops.
@@ -138,7 +138,7 @@
If the body is at least this close to another body, this body will consider them to be colliding.
</member>
<member name="motion/sync_to_physics" type="bool" setter="set_sync_to_physics" getter="is_sync_to_physics_enabled">
- If [code]true[/code] the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms.
+ If [code]true[/code], the body's movement will be synchronized to the physics frame. This is useful when animating movement via [AnimationPlayer], for example on moving platforms.
</member>
</members>
<constants>
diff --git a/doc/classes/Light.xml b/doc/classes/Light.xml
index cf873e5b28..a7b0d86a7a 100644
--- a/doc/classes/Light.xml
+++ b/doc/classes/Light.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only">
- If [code]true[/code] the light only appears in the editor and will not be visible at runtime. Default value:[code]false[/code].
+ If [code]true[/code], the light only appears in the editor and will not be visible at runtime. Default value:[code]false[/code].
</member>
<member name="light_bake_mode" type="int" setter="set_bake_mode" getter="get_bake_mode" enum="Light.BakeMode">
The light's bake mode. See [enum BakeMode].
@@ -33,7 +33,7 @@
Secondary multiplier used with indirect light (light bounces). This works in baked light or GIProbe.
</member>
<member name="light_negative" type="bool" setter="set_negative" getter="is_negative">
- If [code]true[/code] the light's effect is reversed, darkening areas and casting bright shadows. Default value: [code]false[/code].
+ If [code]true[/code], the light's effect is reversed, darkening areas and casting bright shadows. Default value: [code]false[/code].
</member>
<member name="light_specular" type="float" setter="set_param" getter="get_param">
The intensity of the specular blob in objects affected by the light. At [code]0[/code] the light becomes a pure diffuse light.
@@ -48,7 +48,7 @@
Attempts to reduce [member shadow_bias] gap.
</member>
<member name="shadow_enabled" type="bool" setter="set_shadow" getter="has_shadow">
- If [code]true[/code] the light will cast shadows. Default value: [code]false[/code].
+ If [code]true[/code], the light will cast shadows. Default value: [code]false[/code].
</member>
<member name="shadow_reverse_cull_face" type="bool" setter="set_shadow_reverse_cull_face" getter="get_shadow_reverse_cull_face">
</member>
diff --git a/doc/classes/Light2D.xml b/doc/classes/Light2D.xml
index f3903ffeae..476156846d 100644
--- a/doc/classes/Light2D.xml
+++ b/doc/classes/Light2D.xml
@@ -17,10 +17,10 @@
The Light2D's [Color].
</member>
<member name="editor_only" type="bool" setter="set_editor_only" getter="is_editor_only">
- If [code]true[/code] Light2D will only appear when editing the scene. Default value: [code]false[/code].
+ If [code]true[/code], Light2D will only appear when editing the scene. Default value: [code]false[/code].
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled">
- If [code]true[/code] Light2D will emit light. Default value: [code]true[/code].
+ If [code]true[/code], Light2D will emit light. Default value: [code]true[/code].
</member>
<member name="energy" type="float" setter="set_energy" getter="get_energy">
The Light2D's energy value. The larger the value, the stronger the light.
@@ -56,7 +56,7 @@
[Color] of shadows cast by the Light2D.
</member>
<member name="shadow_enabled" type="bool" setter="set_shadow_enabled" getter="is_shadow_enabled">
- If [code]true[/code] the Light2D will cast shadows. Default value: [code]false[/code].
+ If [code]true[/code], the Light2D will cast shadows. Default value: [code]false[/code].
</member>
<member name="shadow_filter" type="int" setter="set_shadow_filter" getter="get_shadow_filter" enum="Light2D.ShadowFilter">
Shadow filter type. Use SHADOW_FILTER_* constants to set [code]shadow_filter[/code]. Default value: [code]None[/code].
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml
index f842dd8311..930680c2ad 100644
--- a/doc/classes/LineEdit.xml
+++ b/doc/classes/LineEdit.xml
@@ -80,7 +80,7 @@
Text alignment as defined in the ALIGN_* enum.
</member>
<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled">
- If [code]true[/code] the caret (visual cursor) blinks.
+ If [code]true[/code], the caret (visual cursor) blinks.
</member>
<member name="caret_blink_speed" type="float" setter="cursor_set_blink_speed" getter="cursor_get_blink_speed">
Duration (in seconds) of a caret's blinking cycle.
@@ -89,16 +89,16 @@
The cursor's position inside the [code]LineEdit[/code]. When set, the text may scroll to accommodate it.
</member>
<member name="clear_button_enabled" type="bool" setter="set_clear_button_enabled" getter="is_clear_button_enabled">
- If [code]true[/code] the [code]LineEdit[/code] will show a clear button if [code]text[/code] is not empty.
+ If [code]true[/code], the [code]LineEdit[/code] will show a clear button if [code]text[/code] is not empty.
</member>
<member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled">
- If [code]true[/code] the context menu will appear when right clicked.
+ If [code]true[/code], the context menu will appear when right clicked.
</member>
<member name="editable" type="bool" setter="set_editable" getter="is_editable">
- If [code]false[/code] existing text cannot be modified and new text cannot be added.
+ If [code]false[/code], existing text cannot be modified and new text cannot be added.
</member>
<member name="expand_to_text_length" type="bool" setter="set_expand_to_text_length" getter="get_expand_to_text_length">
- If [code]true[/code] the [LineEdit] width will increase to stay longer than the [member text]. It will [b]not[/b] compress if the [member text] is shortened.
+ If [code]true[/code], the [LineEdit] width will increase to stay longer than the [member text]. It will [b]not[/b] compress if the [member text] is shortened.
</member>
<member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode">
Defines how the [LineEdit] can grab focus (Keyboard and mouse, only keyboard, or none). See [code]enum FocusMode[/code] in [Control] for details.
diff --git a/doc/classes/MultiplayerAPI.xml b/doc/classes/MultiplayerAPI.xml
index d8d7d9acfc..f3e26a3bcb 100644
--- a/doc/classes/MultiplayerAPI.xml
+++ b/doc/classes/MultiplayerAPI.xml
@@ -93,7 +93,7 @@
The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the MultiplayerAPI will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to MultiplayerAPI's signals.
</member>
<member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections">
- If [code]true[/code] the MultiplayerAPI's [member network_peer] refuses new incoming connections.
+ If [code]true[/code], the MultiplayerAPI's [member network_peer] refuses new incoming connections.
</member>
</members>
<signals>
diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml
index 990f928b25..42f08b36af 100644
--- a/doc/classes/NetworkedMultiplayerPeer.xml
+++ b/doc/classes/NetworkedMultiplayerPeer.xml
@@ -53,7 +53,7 @@
</methods>
<members>
<member name="refuse_new_connections" type="bool" setter="set_refuse_new_connections" getter="is_refusing_new_connections">
- If [code]true[/code] this [code]NetworkedMultiplayerPeer[/code] refuses new connections. Default value: [code]false[/code].
+ If [code]true[/code], this [code]NetworkedMultiplayerPeer[/code] refuses new connections. Default value: [code]false[/code].
</member>
<member name="transfer_mode" type="int" setter="set_transfer_mode" getter="get_transfer_mode" enum="NetworkedMultiplayerPeer.TransferMode">
The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode].
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index dcdb6d0500..02a8ee8e75 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -11,7 +11,7 @@
This means that when adding a node to the scene tree, the following order will be used for the callbacks: [method _enter_tree] of the parent, [method _enter_tree] of the children, [method _ready] of the children and finally [method _ready] of the parent (recursively for the entire scene tree).
[b]Processing:[/b] Nodes can override the "process" state, so that they receive a callback on each frame requesting them to process (do something). Normal processing (callback [method _process], toggled with [method set_process]) happens as fast as possible and is dependent on the frame rate, so the processing time [i]delta[/i] is passed as an argument. Physics processing (callback [method _physics_process], toggled with [method set_physics_process]) happens a fixed number of times per second (60 by default) and is useful for code related to the physics engine.
Nodes can also process input events. When present, the [method _input] function will be called for each input that the program receives. In many cases, this can be overkill (unless used for simple projects), and the [method _unhandled_input] function might be preferred; it is called when the input event was not handled by anyone else (typically, GUI [Control] nodes), ensuring that the node only receives the events that were meant for it.
- To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with [method set_owner]. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
+ To keep track of the scene hierarchy (especially when instancing scenes into other scenes), an "owner" can be set for the node with the [member owner] property. This keeps track of who instanced what. This is mostly useful when writing editors and tools, though.
Finally, when a node is freed with [method Object.free] or [method queue_free], it will also free all its children.
[b]Groups:[/b] Nodes can be added to as many groups as you want to be easy to manage, you could create groups like "enemies" or "collectables" for example, depending on your game. See [method add_to_group], [method is_in_group] and [method remove_from_group]. You can then retrieve all nodes in these groups, iterate them and even call methods on groups via the methods on [SceneTree].
[b]Networking with nodes:[/b] After connecting to a server (or making one, see [NetworkedMultiplayerENet]) it is possible to use the built-in RPC (remote procedure call) system to communicate over the network. By calling [method rpc] with a method name, it will be called locally and in all connected peers (peers = clients and the server that accepts connections). To identify which node receives the RPC call Godot will use its [NodePath] (make sure node names are the same on all peers). Also take a look at the high-level networking tutorial and corresponding demos.
@@ -152,7 +152,7 @@
<return type="bool">
</return>
<description>
- Returns [code]true[/code] if the node can process while the scene tree is paused (see [method set_pause_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree. FIXME: Why FAIL_COND?
+ Returns [code]true[/code] if the node can process while the scene tree is paused (see [member pause_mode]). Always returns [code]true[/code] if the scene tree is not paused, and [code]false[/code] if the node is not in the tree.
</description>
</method>
<method name="duplicate" qualifiers="const">
@@ -162,7 +162,7 @@
</argument>
<description>
Duplicates the node, returning a new node.
- You can fine-tune the behavior using the [code]flags[/code]. See DUPLICATE_* constants.
+ You can fine-tune the behavior using the [code]flags[/code] (see [enum Node.DuplicateFlags]).
</description>
</method>
<method name="find_node" qualifiers="const">
diff --git a/doc/classes/Node2D.xml b/doc/classes/Node2D.xml
index e955f6bb7d..80f9329402 100644
--- a/doc/classes/Node2D.xml
+++ b/doc/classes/Node2D.xml
@@ -148,7 +148,7 @@
Local [Transform2D].
</member>
<member name="z_as_relative" type="bool" setter="set_z_as_relative" getter="is_z_relative">
- If [code]true[/code] the node's Z-index is relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5.
+ If [code]true[/code], the node's Z-index is relative to its parent's Z-index. If this node's Z-index is 2 and its parent's effective Z-index is 3, then this node's effective Z-index will be 2 + 3 = 5.
</member>
<member name="z_index" type="int" setter="set_z_index" getter="get_z_index">
Z-index. Controls the order in which the nodes render. A node with a higher Z-index will display in front of others.
diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml
index ac865de3cd..62c5d9b694 100644
--- a/doc/classes/OS.xml
+++ b/doc/classes/OS.xml
@@ -374,6 +374,13 @@
Returns the actual path to commonly used folders across different platforms. Available locations are specified in [OS.SystemDir].
</description>
</method>
+ <method name="get_system_time_msecs" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the epoch time of the operating system in milliseconds.
+ </description>
+ </method>
<method name="get_system_time_secs" qualifiers="const">
<return type="int">
</return>
@@ -763,28 +770,28 @@
The exit code passed to the OS when the main loop exits.
</member>
<member name="keep_screen_on" type="bool" setter="set_keep_screen_on" getter="is_keep_screen_on">
- If [code]true[/code] the engine tries to keep the screen on while the game is running. Useful on mobile.
+ If [code]true[/code], the engine tries to keep the screen on while the game is running. Useful on mobile.
</member>
<member name="low_processor_usage_mode" type="bool" setter="set_low_processor_usage_mode" getter="is_in_low_processor_usage_mode">
- If [code]true[/code] the engine optimizes for low processor usage by only refreshing the screen if needed. Can improve battery consumption on mobile.
+ If [code]true[/code], the engine optimizes for low processor usage by only refreshing the screen if needed. Can improve battery consumption on mobile.
</member>
<member name="screen_orientation" type="int" setter="set_screen_orientation" getter="get_screen_orientation" enum="_OS.ScreenOrientation">
The current screen orientation.
</member>
<member name="vsync_enabled" type="bool" setter="set_use_vsync" getter="is_vsync_enabled">
- If [code]true[/code] vertical synchronization (Vsync) is enabled.
+ If [code]true[/code], vertical synchronization (Vsync) is enabled.
</member>
<member name="window_borderless" type="bool" setter="set_borderless_window" getter="get_borderless_window">
- If [code]true[/code] removes the window frame.
+ If [code]true[/code], removes the window frame.
</member>
<member name="window_fullscreen" type="bool" setter="set_window_fullscreen" getter="is_window_fullscreen">
- If [code]true[/code] the window is fullscreen.
+ If [code]true[/code], the window is fullscreen.
</member>
<member name="window_maximized" type="bool" setter="set_window_maximized" getter="is_window_maximized">
- If [code]true[/code] the window is maximized.
+ If [code]true[/code], the window is maximized.
</member>
<member name="window_minimized" type="bool" setter="set_window_minimized" getter="is_window_minimized">
- If [code]true[/code] the window is minimized.
+ If [code]true[/code], the window is minimized.
</member>
<member name="window_per_pixel_transparency_enabled" type="bool" setter="set_window_per_pixel_transparency_enabled" getter="get_window_per_pixel_transparency_enabled">
</member>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index e358ad90b5..76cbe5eebd 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -5,7 +5,7 @@
</brief_description>
<description>
Base class for all non built-in types. Everything which is not a built-in type starts the inheritance chain from this class.
- Objects can be constructed from scripting languages, using `Object.new()` in GDScript, `new Object` in C#, or the "Construct Object" node in VisualScript.
+ Objects can be constructed from scripting languages, using [code]Object.new()[/code] in GDScript, [code]new Object[/code] in C#, or the "Construct Object" node in VisualScript.
Objects do not manage memory, if inheriting from one the object will most likely have to be deleted manually (call the [method free] function from the script or delete from C++).
Some derivatives add memory management, such as [Reference] (which keeps a reference count and deletes itself automatically when no longer referenced) and [Node], which deletes the children tree when deleted.
Objects export properties, which are mainly useful for storage and editing, but not really so much in programming. Properties are exported in [method _get_property_list] and handled in [method _get] and [method _set]. However, scripting languages and C++ have simpler means to export them.
diff --git a/doc/classes/OccluderPolygon2D.xml b/doc/classes/OccluderPolygon2D.xml
index e8d6b54f27..58ad268f05 100644
--- a/doc/classes/OccluderPolygon2D.xml
+++ b/doc/classes/OccluderPolygon2D.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="closed" type="bool" setter="set_closed" getter="is_closed">
- If [code]true[/code] closes the polygon. A closed OccluderPolygon2D occludes the light coming from any direction. An opened OccluderPolygon2D occludes the light only at its outline's direction. Default value [code]true[/code].
+ If [code]true[/code], closes the polygon. A closed OccluderPolygon2D occludes the light coming from any direction. An opened OccluderPolygon2D occludes the light only at its outline's direction. Default value [code]true[/code].
</member>
<member name="cull_mode" type="int" setter="set_cull_mode" getter="get_cull_mode" enum="OccluderPolygon2D.CullMode">
Set the direction of the occlusion culling when not [code]CULL_DISABLED[/code]. Default value [code]DISABLED[/code].
diff --git a/doc/classes/OrientedPathFollow.xml b/doc/classes/OrientedPathFollow.xml
index bc6af4711b..665e3af6b2 100644
--- a/doc/classes/OrientedPathFollow.xml
+++ b/doc/classes/OrientedPathFollow.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="cubic_interp" type="bool" setter="set_cubic_interpolation" getter="get_cubic_interpolation">
- If [code]true[/code] the position between two cached points is interpolated cubically, and linearly otherwise.
+ If [code]true[/code], the position between two cached points is interpolated cubically, and linearly otherwise.
The points along the [Curve3D] of the [Path] are precomputed before use, for faster calculations. The point at the requested offset is then calculated interpolating between two adjacent cached points. This may present a problem if the curve makes sharp turns, as the cached points may not follow the curve closely enough.
There are two answers to this problem: Either increase the number of cached points and increase memory consumption, or make a cubic interpolation between two points at the cost of (slightly) slower calculations.
</member>
diff --git a/doc/classes/ParallaxBackground.xml b/doc/classes/ParallaxBackground.xml
index 2409b7a1c1..81795df87f 100644
--- a/doc/classes/ParallaxBackground.xml
+++ b/doc/classes/ParallaxBackground.xml
@@ -20,7 +20,7 @@
Base motion scale of all [ParallaxLayer] children.
</member>
<member name="scroll_ignore_camera_zoom" type="bool" setter="set_ignore_camera_zoom" getter="is_ignore_camera_zoom">
- If [code]true[/code] elements in [ParallaxLayer] child aren't affected by the zoom level of the camera.
+ If [code]true[/code], elements in [ParallaxLayer] child aren't affected by the zoom level of the camera.
</member>
<member name="scroll_limit_begin" type="Vector2" setter="set_limit_begin" getter="get_limit_begin">
Top left limits for scrolling to begin. If the camera is outside of this limit the background will stop scrolling. Must be lower than [member scroll_limit_end] to work.
diff --git a/doc/classes/Particles.xml b/doc/classes/Particles.xml
index 2e30750bf9..b6e31d3576 100644
--- a/doc/classes/Particles.xml
+++ b/doc/classes/Particles.xml
@@ -49,7 +49,7 @@
The number of draw passes when rendering particles.
</member>
<member name="emitting" type="bool" setter="set_emitting" getter="is_emitting">
- If [code]true[/code] particles are being emitted. Default value: [code]true[/code].
+ If [code]true[/code], particles are being emitted. Default value: [code]true[/code].
</member>
<member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio">
Time ratio between each emission. If [code]0[/code] particles are emitted continuously. If [code]1[/code] all particles are emitted simultaneously. Default value: [code]0[/code].
@@ -62,10 +62,10 @@
Amount of time each particle will exist. Default value: [code]1[/code].
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates">
- If [code]true[/code] particles use the parent node's coordinate space. If [code]false[/code] they use global coordinates. Default value: [code]true[/code].
+ If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. Default value: [code]true[/code].
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot">
- If [code]true[/code] only [code]amount[/code] particles will be emitted. Default value: [code]false[/code].
+ If [code]true[/code], only [code]amount[/code] particles will be emitted. Default value: [code]false[/code].
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time">
Amount of time to preprocess the particles before animation starts. Lets you start the animation some time after particles have started emitting.
diff --git a/doc/classes/Particles2D.xml b/doc/classes/Particles2D.xml
index 6416e409a3..a6d23ed0f2 100644
--- a/doc/classes/Particles2D.xml
+++ b/doc/classes/Particles2D.xml
@@ -33,7 +33,7 @@
Particle draw order. Uses [code]DRAW_ORDER_*[/code] values. Default value: [code]DRAW_ORDER_INDEX[/code].
</member>
<member name="emitting" type="bool" setter="set_emitting" getter="is_emitting">
- If [code]true[/code] particles are being emitted. Default value: [code]true[/code].
+ If [code]true[/code], particles are being emitted. Default value: [code]true[/code].
</member>
<member name="explosiveness" type="float" setter="set_explosiveness_ratio" getter="get_explosiveness_ratio">
How rapidly particles in an emission cycle are emitted. If greater than [code]0[/code], there will be a gap in emissions before the next cycle begins. Default value: [code]0[/code].
@@ -46,12 +46,12 @@
Amount of time each particle will exist. Default value: [code]1[/code].
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates">
- If [code]true[/code] particles use the parent node's coordinate space. If [code]false[/code] they use global coordinates. Default value: [code]true[/code].
+ If [code]true[/code], particles use the parent node's coordinate space. If [code]false[/code], they use global coordinates. Default value: [code]true[/code].
</member>
<member name="normal_map" type="Texture" setter="set_normal_map" getter="get_normal_map">
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="get_one_shot">
- If [code]true[/code] only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. Default value: [code]false[/code].
+ If [code]true[/code], only one emission cycle occurs. If set [code]true[/code] during a cycle, emission will stop at the cycle's end. Default value: [code]false[/code].
</member>
<member name="preprocess" type="float" setter="set_pre_process_time" getter="get_pre_process_time">
Particle system starts as if it had already run for this many seconds.
diff --git a/doc/classes/ParticlesMaterial.xml b/doc/classes/ParticlesMaterial.xml
index 2904d4c578..b34272d176 100644
--- a/doc/classes/ParticlesMaterial.xml
+++ b/doc/classes/ParticlesMaterial.xml
@@ -86,7 +86,7 @@
<member name="flag_align_y" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="flag_disable_z" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] particles will not move on the z axis. Default value: [code]true[/code] for [Particles2D], [code]false[/code] for [Particles].
+ If [code]true[/code], particles will not move on the z axis. Default value: [code]true[/code] for [Particles2D], [code]false[/code] for [Particles].
</member>
<member name="flag_rotate_y" type="bool" setter="set_flag" getter="get_flag">
</member>
diff --git a/doc/classes/PathFollow.xml b/doc/classes/PathFollow.xml
index 650fed7ec6..ed4a805a00 100644
--- a/doc/classes/PathFollow.xml
+++ b/doc/classes/PathFollow.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="cubic_interp" type="bool" setter="set_cubic_interpolation" getter="get_cubic_interpolation">
- If [code]true[/code] the position between two cached points is interpolated cubically, and linearly otherwise.
+ If [code]true[/code], the position between two cached points is interpolated cubically, and linearly otherwise.
The points along the [Curve3D] of the [Path] are precomputed before use, for faster calculations. The point at the requested offset is then calculated interpolating between two adjacent cached points. This may present a problem if the curve makes sharp turns, as the cached points may not follow the curve closely enough.
There are two answers to this problem: Either increase the number of cached points and increase memory consumption, or make a cubic interpolation between two points at the cost of (slightly) slower calculations.
</member>
diff --git a/doc/classes/PathFollow2D.xml b/doc/classes/PathFollow2D.xml
index 515c921d0d..a31652b7f9 100644
--- a/doc/classes/PathFollow2D.xml
+++ b/doc/classes/PathFollow2D.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="cubic_interp" type="bool" setter="set_cubic_interpolation" getter="get_cubic_interpolation">
- If [code]true[/code] the position between two cached points is interpolated cubically, and linearly otherwise.
+ If [code]true[/code], the position between two cached points is interpolated cubically, and linearly otherwise.
The points along the [Curve2D] of the [Path2D] are precomputed before use, for faster calculations. The point at the requested offset is then calculated interpolating between two adjacent cached points. This may present a problem if the curve makes sharp turns, as the cached points may not follow the curve closely enough.
There are two answers to this problem: Either increase the number of cached points and increase memory consumption, or make a cubic interpolation between two points at the cost of (slightly) slower calculations.
</member>
diff --git a/doc/classes/PhysicsDirectBodyState.xml b/doc/classes/PhysicsDirectBodyState.xml
index 2f3501ae5d..2b4125aef4 100644
--- a/doc/classes/PhysicsDirectBodyState.xml
+++ b/doc/classes/PhysicsDirectBodyState.xml
@@ -46,7 +46,7 @@
</argument>
<description>
Applies a single directional impulse without affecting rotation.
- This is equivalent to ``apply_impulse(Vector3(0,0,0), impulse)``.
+ This is equivalent to [code]apply_impulse(Vector3(0, 0, 0), impulse)[/code].
</description>
</method>
<method name="apply_impulse">
diff --git a/doc/classes/PhysicsServer.xml b/doc/classes/PhysicsServer.xml
index 7dfc8e66d4..40ee06fe6c 100644
--- a/doc/classes/PhysicsServer.xml
+++ b/doc/classes/PhysicsServer.xml
@@ -135,7 +135,7 @@
<argument index="0" name="area" type="RID">
</argument>
<description>
- If [code]true[/code] area collides with rays.
+ If [code]true[/code], area collides with rays.
</description>
</method>
<method name="area_remove_shape">
@@ -556,7 +556,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- If [code]true[/code] the continuous collision detection mode is enabled.
+ If [code]true[/code], the continuous collision detection mode is enabled.
</description>
</method>
<method name="body_is_omitting_force_integration" qualifiers="const">
@@ -574,7 +574,7 @@
<argument index="0" name="body" type="RID">
</argument>
<description>
- If [code]true[/code] the body can be detected by rays
+ If [code]true[/code], the body can be detected by rays
</description>
</method>
<method name="body_remove_collision_exception">
@@ -653,7 +653,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the continuous collision detection mode is enabled.
+ If [code]true[/code], the continuous collision detection mode is enabled.
Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided.
</description>
</method>
@@ -1286,10 +1286,10 @@
Maximum acceleration for the motor.
</constant>
<constant name="HINGE_JOINT_FLAG_USE_LIMIT" value="0" enum="HingeJointFlag">
- If [code]true[/code] the Hinge has a maximum and a minimum rotation.
+ If [code]true[/code], the Hinge has a maximum and a minimum rotation.
</constant>
<constant name="HINGE_JOINT_FLAG_ENABLE_MOTOR" value="1" enum="HingeJointFlag">
- If [code]true[/code] a motor turns the Hinge
+ If [code]true[/code], a motor turns the Hinge
</constant>
<constant name="SLIDER_JOINT_LINEAR_LIMIT_UPPER" value="0" enum="SliderJointParam">
The maximum difference between the pivot points on their x-axis before damping happens.
diff --git a/doc/classes/Polygon2D.xml b/doc/classes/Polygon2D.xml
index bf4519fd0a..c63d66ff5b 100644
--- a/doc/classes/Polygon2D.xml
+++ b/doc/classes/Polygon2D.xml
@@ -80,7 +80,7 @@
</methods>
<members>
<member name="antialiased" type="bool" setter="set_antialiased" getter="get_antialiased">
- If [code]true[/code] polygon edges will be anti-aliased. Default value: [code]false[/code].
+ If [code]true[/code], polygon edges will be anti-aliased. Default value: [code]false[/code].
</member>
<member name="bones" type="Array" setter="_set_bones" getter="_get_bones">
</member>
@@ -91,7 +91,7 @@
Added padding applied to the bounding box when using [code]invert[/code]. Setting this value too small may result in a "Bad Polygon" error. Default value: [code]100[/code].
</member>
<member name="invert_enable" type="bool" setter="set_invert" getter="get_invert">
- If [code]true[/code] polygon will be inverted, containing the area outside the defined points and extending to the [code]invert_border[/code]. Default value: [code]false[/code].
+ If [code]true[/code], polygon will be inverted, containing the area outside the defined points and extending to the [code]invert_border[/code]. Default value: [code]false[/code].
</member>
<member name="offset" type="Vector2" setter="set_offset" getter="get_offset">
The offset applied to each vertex.
diff --git a/doc/classes/Popup.xml b/doc/classes/Popup.xml
index 8eec105a80..be6e8b6ef1 100644
--- a/doc/classes/Popup.xml
+++ b/doc/classes/Popup.xml
@@ -50,7 +50,7 @@
</methods>
<members>
<member name="popup_exclusive" type="bool" setter="set_exclusive" getter="is_exclusive">
- If [code]true[/code] the popup will not be hidden when a click event occurs outside of it, or when it receives the [code]ui_cancel[/code] action event.
+ If [code]true[/code], the popup will not be hidden when a click event occurs outside of it, or when it receives the [code]ui_cancel[/code] action event.
</member>
</members>
<signals>
diff --git a/doc/classes/ProgressBar.xml b/doc/classes/ProgressBar.xml
index 0f03b7b80a..8d6e77751d 100644
--- a/doc/classes/ProgressBar.xml
+++ b/doc/classes/ProgressBar.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="percent_visible" type="bool" setter="set_percent_visible" getter="is_percent_visible">
- If [code]true[/code] the fill percentage is displayed on the bar. Default value: [code]true[/code].
+ If [code]true[/code], the fill percentage is displayed on the bar. Default value: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/Range.xml b/doc/classes/Range.xml
index 46a6132b94..0dc02a68da 100644
--- a/doc/classes/Range.xml
+++ b/doc/classes/Range.xml
@@ -30,13 +30,13 @@
</methods>
<members>
<member name="allow_greater" type="bool" setter="set_allow_greater" getter="is_greater_allowed">
- If [code]true[/code] [member value] may be greater than [member max_value]. Default value: [code]false[/code].
+ If [code]true[/code], [member value] may be greater than [member max_value]. Default value: [code]false[/code].
</member>
<member name="allow_lesser" type="bool" setter="set_allow_lesser" getter="is_lesser_allowed">
- If [code]true[/code] [member value] may be less than [member min_value]. Default value: [code]false[/code].
+ If [code]true[/code], [member value] may be less than [member min_value]. Default value: [code]false[/code].
</member>
<member name="exp_edit" type="bool" setter="set_exp_ratio" getter="is_ratio_exp">
- If [code]true[/code] and [code]min_value[/code] is greater than 0, [code]value[/code] will be represented exponentially rather than linearly.
+ If [code]true[/code], and [code]min_value[/code] is greater than 0, [code]value[/code] will be represented exponentially rather than linearly.
</member>
<member name="max_value" type="float" setter="set_max" getter="get_max">
Maximum value. Range is clamped if [code]value[/code] is greater than [code]max_value[/code]. Default value: [code]100[/code].
@@ -51,7 +51,7 @@
The value mapped between 0 and 1.
</member>
<member name="rounded" type="bool" setter="set_use_rounded_values" getter="is_using_rounded_values">
- If [code]true[/code] [code]value[/code] will always be rounded to the nearest integer. Default value: [code]false[/code].
+ If [code]true[/code], [code]value[/code] will always be rounded to the nearest integer. Default value: [code]false[/code].
</member>
<member name="step" type="float" setter="set_step" getter="get_step">
If greater than 0, [code]value[/code] will always be rounded to a multiple of [code]step[/code]. If [code]rounded[/code] is also [code]true[/code], [code]value[/code] will first be rounded to a multiple of [code]step[/code] then rounded to the nearest integer.
diff --git a/doc/classes/RayCast.xml b/doc/classes/RayCast.xml
index 84c83d1282..61f2737c01 100644
--- a/doc/classes/RayCast.xml
+++ b/doc/classes/RayCast.xml
@@ -136,10 +136,10 @@
The ray's collision mask. Only objects in at least one collision layer enabled in the mask will be detected.
</member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled">
- If [code]true[/code] collisions will be reported. Default value: [code]false[/code].
+ If [code]true[/code], collisions will be reported. Default value: [code]false[/code].
</member>
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body">
- If [code]true[/code] collisions will be ignored for this RayCast's immediate parent. Default value: [code]true[/code].
+ If [code]true[/code], collisions will be ignored for this RayCast's immediate parent. Default value: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/RayShape.xml b/doc/classes/RayShape.xml
index e03541011d..50d324f72c 100644
--- a/doc/classes/RayShape.xml
+++ b/doc/classes/RayShape.xml
@@ -17,7 +17,7 @@
The ray's length.
</member>
<member name="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope">
- If [code]true[/code] allow the shape to return the correct normal. Default value: [code]false[/code].
+ If [code]true[/code], allow the shape to return the correct normal. Default value: [code]false[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/RayShape2D.xml b/doc/classes/RayShape2D.xml
index 37cfe4f2d3..2fdc1930fb 100644
--- a/doc/classes/RayShape2D.xml
+++ b/doc/classes/RayShape2D.xml
@@ -17,7 +17,7 @@
The ray's length.
</member>
<member name="slips_on_slope" type="bool" setter="set_slips_on_slope" getter="get_slips_on_slope">
- If [code]true[/code] allow the shape to return the correct normal. Default value: [code]false[/code].
+ If [code]true[/code], allow the shape to return the correct normal. Default value: [code]false[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/RemoteTransform.xml b/doc/classes/RemoteTransform.xml
index 1a5d1eb907..3df94bdfca 100644
--- a/doc/classes/RemoteTransform.xml
+++ b/doc/classes/RemoteTransform.xml
@@ -18,16 +18,16 @@
The [NodePath] to the remote node, relative to the RemoteTransform's position in the scene.
</member>
<member name="update_position" type="bool" setter="set_update_position" getter="get_update_position">
- If [code]true[/code] the remote node's position is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's position is updated. Default value: [code]true[/code].
</member>
<member name="update_rotation" type="bool" setter="set_update_rotation" getter="get_update_rotation">
- If [code]true[/code] the remote node's rotation is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's rotation is updated. Default value: [code]true[/code].
</member>
<member name="update_scale" type="bool" setter="set_update_scale" getter="get_update_scale">
- If [code]true[/code] the remote node's scale is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's scale is updated. Default value: [code]true[/code].
</member>
<member name="use_global_coordinates" type="bool" setter="set_use_global_coordinates" getter="get_use_global_coordinates">
- If [code]true[/code] global coordinates are used. If [code]false[/code] local coordinates are used. Default value: [code]true[/code].
+ If [code]true[/code], global coordinates are used. If [code]false[/code], local coordinates are used. Default value: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/RemoteTransform2D.xml b/doc/classes/RemoteTransform2D.xml
index d83ec9f6b1..cf0e6c6199 100644
--- a/doc/classes/RemoteTransform2D.xml
+++ b/doc/classes/RemoteTransform2D.xml
@@ -18,16 +18,16 @@
The [NodePath] to the remote node, relative to the RemoteTransform2D's position in the scene.
</member>
<member name="update_position" type="bool" setter="set_update_position" getter="get_update_position">
- If [code]true[/code] the remote node's position is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's position is updated. Default value: [code]true[/code].
</member>
<member name="update_rotation" type="bool" setter="set_update_rotation" getter="get_update_rotation">
- If [code]true[/code] the remote node's rotation is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's rotation is updated. Default value: [code]true[/code].
</member>
<member name="update_scale" type="bool" setter="set_update_scale" getter="get_update_scale">
- If [code]true[/code] the remote node's scale is updated. Default value: [code]true[/code].
+ If [code]true[/code], the remote node's scale is updated. Default value: [code]true[/code].
</member>
<member name="use_global_coordinates" type="bool" setter="set_use_global_coordinates" getter="get_use_global_coordinates">
- If [code]true[/code] global coordinates are used. If [code]false[/code] local coordinates are used. Default value: [code]true[/code].
+ If [code]true[/code], global coordinates are used. If [code]false[/code], local coordinates are used. Default value: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/ResourceFormatLoader.xml b/doc/classes/ResourceFormatLoader.xml
index f03f0bbf54..97547a607a 100644
--- a/doc/classes/ResourceFormatLoader.xml
+++ b/doc/classes/ResourceFormatLoader.xml
@@ -4,9 +4,9 @@
Loads a specific resource type from a file.
</brief_description>
<description>
- Godot loads resources in the editor or in exported games using ResourceFormatLoaders. They get queried when you call `load`, or when a resource with internal dependencies is loaded. Each file type may load as a different resource type, so multiple ResourceFormatLoader are registered in the engine.
- Extending this class allows you to define your own. You should give it a global class name with `class_name` for it to be registered. You may as well implement a [ResourceFormatSaver].
- Note: you can also extend [EditorImportPlugin] if the resource type you need exists but Godot is unable to load its format. Choosing one way over another depends if the format is suitable or not for the final exported game. Example: it's better to import .PNG textures as .STEX first, so they can be loaded with better efficiency on the graphics card.
+ Godot loads resources in the editor or in exported games using ResourceFormatLoaders. They get queried when you call [code]load[/code], or when a resource with internal dependencies is loaded. Each file type may load as a different resource type, so multiple ResourceFormatLoader are registered in the engine.
+ Extending this class allows you to define your own. You should give it a global class name with [code]class_name[/code] for it to be registered. You may as well implement a [ResourceFormatSaver].
+ Note: You can also extend [EditorImportPlugin] if the resource type you need exists but Godot is unable to load its format. Choosing one way over another depends if the format is suitable or not for the final exported game. Example: it's better to import .PNG textures as .STEX first, so they can be loaded with better efficiency on the graphics card.
</description>
<tutorials>
</tutorials>
@@ -21,7 +21,7 @@
<argument index="1" name="add_types" type="String">
</argument>
<description>
- If implemented, gets the dependencies of a given resource. If add_types is true, paths should be appended "::TypeName", where `TypeName` is the class name of the dependency. Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just return "Resource" for them.
+ If implemented, gets the dependencies of a given resource. If [code]add_types[/code] is [code]true[/code], paths should be appended [code]::TypeName[/code], where [code]TypeName[/code] is the class name of the dependency. Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just return [code]Resource[/code] for them.
</description>
</method>
<method name="get_recognized_extensions" qualifiers="virtual">
@@ -37,7 +37,7 @@
<argument index="0" name="path" type="String">
</argument>
<description>
- Gets the class name of the resource associated with the given path. If the loader cannot handle it, it should return "". Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just return "Resource" for them.
+ Gets the class name of the resource associated with the given path. If the loader cannot handle it, it should return [code]""[/code]. Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just return [code]"Resource"[/code] for them.
</description>
</method>
<method name="handles_type" qualifiers="virtual">
@@ -46,7 +46,7 @@
<argument index="0" name="typename" type="String">
</argument>
<description>
- Tells which resource class this loader can load. Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just return "Resource" for them.
+ Tells which resource class this loader can load. Note that custom resource types defined by scripts aren't known by the [ClassDB], so you might just handle [code]"Resource"[/code] for them.
</description>
</method>
<method name="load" qualifiers="virtual">
@@ -57,7 +57,7 @@
<argument index="1" name="original_path" type="String">
</argument>
<description>
- Loads a resource when the engine finds this loader to be compatible. original_path: If the loaded resource is the result of an import, original_path will target the source file. Returns a resource object if succeeded, or an ERR_* constant listed in [@GlobalScope] if it failed.
+ Loads a resource when the engine finds this loader to be compatible. If the loaded resource is the result of an import, [code]original_path[/code] will target the source file. Returns a resource object if succeeded, or an [code]ERR_*[/code] constant listed in [@GlobalScope] if it failed.
</description>
</method>
<method name="rename_dependencies" qualifiers="virtual">
@@ -68,7 +68,7 @@
<argument index="1" name="renames" type="String">
</argument>
<description>
- If implemented, renames dependencies within the given resource and saves it. renames is a dictionary { String => String } mapping old dependency paths to new paths. Returns OK on success, or an ERR_* constant listed in [@GlobalScope] in case of failure.
+ If implemented, renames dependencies within the given resource and saves it. [code]renames[/code] is a dictionary [code]{ String =&gt; String }[/code] mapping old dependency paths to new paths. Returns [code]OK[/code] on success, or an [code]ERR_*[/code] constant listed in [@GlobalScope] in case of failure.
</description>
</method>
</methods>
diff --git a/doc/classes/ResourceFormatSaver.xml b/doc/classes/ResourceFormatSaver.xml
index d15d97fc84..d50027ef8e 100644
--- a/doc/classes/ResourceFormatSaver.xml
+++ b/doc/classes/ResourceFormatSaver.xml
@@ -4,8 +4,8 @@
Saves a specific resource type to a file.
</brief_description>
<description>
- The engine can save resources when you do it from the editor, or when you call `ResourceSaver.save(resource)`. This is accomplished with multiple `ResourceFormatSavers`, each handling its own format.
- By default, Godot saves resources as `.tres`, `.res` or another built-in format, but you can choose to create your own format by extending this class. You should give it a global class name with `class_name` for it to be registered. You may as well implement a [ResourceFormatLoader].
+ The engine can save resources when you do it from the editor, or when you call [method ResourceSaver.save]. This is accomplished with multiple [code]ResourceFormatSaver[/code]s, each handling its own format.
+ By default, Godot saves resources as [code].tres[/code], [code].res[/code] or another built-in format, but you can choose to create your own format by extending this class. You should give it a global class name with [code]class_name[/code] for it to be registered. You may as well implement a [ResourceFormatLoader].
</description>
<tutorials>
</tutorials>
@@ -40,7 +40,7 @@
<argument index="2" name="flags" type="int">
</argument>
<description>
- Saves the given resource object to a file. flags is a bitmask composed with FLAG_* constants defined in [ResourceSaver]. Returns OK on success, or an ERR_* constant listed in [@GlobalScope] if it failed.
+ Saves the given resource object to a file. [code]flags[/code] is a bitmask composed with [code]FLAG_*[/code] constants defined in [ResourceSaver]. Returns [code]OK[/code] on success, or an [code]ERR_*[/code] constant listed in [@GlobalScope] if it failed.
</description>
</method>
</methods>
diff --git a/doc/classes/ResourceLoader.xml b/doc/classes/ResourceLoader.xml
index ae900e34ef..926bd63de2 100644
--- a/doc/classes/ResourceLoader.xml
+++ b/doc/classes/ResourceLoader.xml
@@ -61,7 +61,7 @@
</argument>
<argument index="1" name="type_hint" type="String" default="&quot;&quot;">
</argument>
- <argument index="2" name="p_no_cache" type="bool" default="false">
+ <argument index="2" name="no_cache" type="bool" default="false">
</argument>
<description>
</description>
diff --git a/doc/classes/RichTextLabel.xml b/doc/classes/RichTextLabel.xml
index 145ce7537b..ae5e0496cb 100644
--- a/doc/classes/RichTextLabel.xml
+++ b/doc/classes/RichTextLabel.xml
@@ -225,7 +225,7 @@
</methods>
<members>
<member name="bbcode_enabled" type="bool" setter="set_use_bbcode" getter="is_using_bbcode">
- If [code]true[/code] the label uses BBCode formatting. Default value: [code]false[/code].
+ If [code]true[/code], the label uses BBCode formatting. Default value: [code]false[/code].
</member>
<member name="bbcode_text" type="String" setter="set_bbcode" getter="get_bbcode">
The label's text in BBCode format. Is not representative of manual modifications to the internal tag stack. Erases changes made by other methods when edited.
@@ -234,7 +234,7 @@
If [code]true[/code], the label underlines meta tags such as [url]{text}[/url]. Default value: [code]true[/code].
</member>
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color">
- If [code]true[/code] the label uses the custom font color. Default value: [code]false[/code].
+ If [code]true[/code], the label uses the custom font color. Default value: [code]false[/code].
</member>
<member name="percent_visible" type="float" setter="set_percent_visible" getter="get_percent_visible">
The text's visibility, as a [float] between 0.0 and 1.0.
diff --git a/doc/classes/RigidBody.xml b/doc/classes/RigidBody.xml
index 4ff332402b..3f28156915 100644
--- a/doc/classes/RigidBody.xml
+++ b/doc/classes/RigidBody.xml
@@ -21,7 +21,7 @@
<argument index="0" name="state" type="PhysicsDirectBodyState">
</argument>
<description>
- Called during physics processing, allowing you to read and safely modify the simulation state for the object. By default it works in addition to the usual physics behavior, but [method set_use_custom_integrator] allows you to disable the default behavior and do fully custom force integration for a body.
+ Called during physics processing, allowing you to read and safely modify the simulation state for the object. By default, it works in addition to the usual physics behavior, but the [member custom_integrator] property allows you to disable the default behavior and do fully custom force integration for a body.
</description>
</method>
<method name="add_central_force">
@@ -88,7 +88,7 @@
<return type="Array">
</return>
<description>
- Return a list of the bodies colliding with this one. By default, number of max contacts reported is at 0 , see [method set_max_contacts_reported] to increase it. Note that the result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead.
+ Return a list of the bodies colliding with this one. By default, number of max contacts reported is at 0, see the [member contacts_reported] property to increase it. Note that the result of this test is not immediate after moving objects. For performance, list of collisions is updated once per frame and before the physics step. Consider using signals instead.
</description>
</method>
<method name="set_axis_velocity">
@@ -130,20 +130,20 @@
RigidBody's bounciness.
</member>
<member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep">
- If [code]true[/code] the RigidBody will not calculate forces and will act as a static body while there is no movement. It will wake up when forces are applied through other collisions or when the [code]apply_impulse[/code] method is used.
+ If [code]true[/code], the RigidBody will not calculate forces and will act as a static body while there is no movement. It will wake up when forces are applied through other collisions or when the [code]apply_impulse[/code] method is used.
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled">
- If [code]true[/code] the RigidBody will emit signals when it collides with another RigidBody.
+ If [code]true[/code], the RigidBody will emit signals when it collides with another RigidBody.
</member>
<member name="contacts_reported" type="int" setter="set_max_contacts_reported" getter="get_max_contacts_reported">
The maximum contacts to report. Bodies can keep a log of the contacts with other bodies, this is enabled by setting the maximum amount of contacts reported to a number greater than 0.
</member>
<member name="continuous_cd" type="bool" setter="set_use_continuous_collision_detection" getter="is_using_continuous_collision_detection">
- If [code]true[/code] continuous collision detection is used.
+ If [code]true[/code], continuous collision detection is used.
Continuous collision detection tries to predict where a moving body will collide, instead of moving it and correcting its movement if it collided. Continuous collision detection is more precise, and misses less impacts by small, fast-moving objects. Not using continuous collision detection is faster to compute, but can miss small, fast-moving objects.
</member>
<member name="custom_integrator" type="bool" setter="set_use_custom_integrator" getter="is_using_custom_integrator">
- If [code]true[/code] internal force integration will be disabled (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined.
+ If [code]true[/code], internal force integration will be disabled (like gravity or air friction) for this body. Other than collision response, the body will only move as determined by the [method _integrate_forces] function, if defined.
</member>
<member name="friction" type="float" setter="set_friction" getter="get_friction">
The body's friction, from 0 (frictionless) to 1 (max friction).
@@ -166,7 +166,7 @@
<member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override">
</member>
<member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping">
- If [code]true[/code] the body is sleeping and will not calculate forces until woken up by a collision or the [code]apply_impulse[/code] method.
+ If [code]true[/code], the body is sleeping and will not calculate forces until woken up by a collision or the [code]apply_impulse[/code] method.
</member>
<member name="weight" type="float" setter="set_weight" getter="get_weight">
The body's weight based on its mass and the global 3D gravity. Global values are set in "Project &gt; Project Settings &gt; Physics &gt; 3d".
diff --git a/doc/classes/RigidBody2D.xml b/doc/classes/RigidBody2D.xml
index 079440ab8b..d4e0374bed 100644
--- a/doc/classes/RigidBody2D.xml
+++ b/doc/classes/RigidBody2D.xml
@@ -20,7 +20,7 @@
<argument index="0" name="state" type="Physics2DDirectBodyState">
</argument>
<description>
- Allows you to read and safely modify the simulation state for the object. Use this instead of [Node._physics_process] if you need to directly change the body's [code]position[/code] or other physics properties. By default it works in addition to the usual physics behavior, but [member custom_integrator] allows you to disable the default behavior and write custom force integration for a body.
+ Allows you to read and safely modify the simulation state for the object. Use this instead of [Node._physics_process] if you need to directly change the body's [code]position[/code] or other physics properties. By default, it works in addition to the usual physics behavior, but [member custom_integrator] allows you to disable the default behavior and write custom force integration for a body.
</description>
</method>
<method name="add_central_force">
@@ -130,10 +130,10 @@
The body's bounciness. Default value: [code]0[/code].
</member>
<member name="can_sleep" type="bool" setter="set_can_sleep" getter="is_able_to_sleep">
- If [code]true[/code] the body will not calculate forces and will act as a static body if there is no movement. The body will wake up when other forces are applied via collisions or by using [method apply_impulse] or [method add_force]. Default value: [code]true[/code].
+ If [code]true[/code], the body will not calculate forces and will act as a static body if there is no movement. The body will wake up when other forces are applied via collisions or by using [method apply_impulse] or [method add_force]. Default value: [code]true[/code].
</member>
<member name="contact_monitor" type="bool" setter="set_contact_monitor" getter="is_contact_monitor_enabled">
- If [code]true[/code] the body will emit signals when it collides with another RigidBody2D. See also [member contacts_reported]. Default value: [code]false[/code].
+ If [code]true[/code], the body will emit signals when it collides with another RigidBody2D. See also [member contacts_reported]. Default value: [code]false[/code].
</member>
<member name="contacts_reported" type="int" setter="set_max_contacts_reported" getter="get_max_contacts_reported">
The maximum number of contacts to report. Default value: [code]0[/code].
@@ -143,7 +143,7 @@
Continuous collision detection tries to predict where a moving body will collide instead of moving it and correcting its movement after collision. Continuous collision detection is slower, but more precise and misses fewer collisions with small, fast-moving objects. Raycasting and shapecasting methods are available. See [code]CCD_MODE_[/code] constants for details.
</member>
<member name="custom_integrator" type="bool" setter="set_use_custom_integrator" getter="is_using_custom_integrator">
- If [code]true[/code] internal force integration is disabled for this body. Aside from collision response, the body will only move as determined by the [method _integrate_forces] function.
+ If [code]true[/code], internal force integration is disabled for this body. Aside from collision response, the body will only move as determined by the [method _integrate_forces] function.
</member>
<member name="friction" type="float" setter="set_friction" getter="get_friction">
The body's friction. Values range from [code]0[/code] (frictionless) to [code]1[/code] (maximum friction). Default value: [code]1[/code].
@@ -169,7 +169,7 @@
<member name="physics_material_override" type="PhysicsMaterial" setter="set_physics_material_override" getter="get_physics_material_override">
</member>
<member name="sleeping" type="bool" setter="set_sleeping" getter="is_sleeping">
- If [code]true[/code] the body is sleeping and will not calculate forces until woken up by a collision or by using [method apply_impulse] or [method add_force].
+ If [code]true[/code], the body is sleeping and will not calculate forces until woken up by a collision or by using [method apply_impulse] or [method add_force].
</member>
<member name="weight" type="float" setter="set_weight" getter="get_weight">
The body's weight based on its mass and the "Default Gravity" value in "Project &gt; Project Settings &gt; Physics &gt; 2d".
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index dd94ee66d2..f39d221d89 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -192,7 +192,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the application automatically accepts quitting.
+ If [code]true[/code], the application automatically accepts quitting.
</description>
</method>
<method name="set_group">
@@ -236,7 +236,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the application quits automatically on going back (e.g. on Android).
+ If [code]true[/code], the application quits automatically on going back (e.g. on Android).
</description>
</method>
<method name="set_screen_stretch">
@@ -270,27 +270,27 @@
The default [MultiplayerAPI] instance for this SceneTree.
</member>
<member name="multiplayer_poll" type="bool" setter="set_multiplayer_poll_enabled" getter="is_multiplayer_poll_enabled">
- If [code]true[/code] (default) enable the automatic polling of the [MultiplayerAPI] for this SceneTree during [signal idle_frame].
+ If [code]true[/code], (default) enable the automatic polling of the [MultiplayerAPI] for this SceneTree during [signal idle_frame].
When [code]false[/code] you need to manually call [method MultiplayerAPI.poll] for processing network packets and delivering RPCs/RSETs. This allows to run RPCs/RSETs in a different loop (e.g. physics, thread, specific time step) and for manual [Mutex] protection when accessing the [MultiplayerAPI] from threads.
</member>
<member name="network_peer" type="NetworkedMultiplayerPeer" setter="set_network_peer" getter="get_network_peer">
- The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server()]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals.
+ The peer object to handle the RPC system (effectively enabling networking when set). Depending on the peer itself, the SceneTree will become a network server (check with [method is_network_server]) and will set root node's network mode to master (see NETWORK_MODE_* constants in [Node]), or it will become a regular peer with root node set to puppet. All child nodes are set to inherit the network mode by default. Handling of networking-related events (connection, disconnection, new clients) is done by connecting to SceneTree's signals.
</member>
<member name="paused" type="bool" setter="set_pause" getter="is_paused">
- If [code]true[/code] the SceneTree is paused.
+ If [code]true[/code], the SceneTree is paused.
Doing so will have the following behavior:
* 2D and 3D physics will be stopped.
* _process and _physics_process will not be called anymore in nodes.
* _input and _input_event will not be called anymore either.
</member>
<member name="refuse_new_network_connections" type="bool" setter="set_refuse_new_network_connections" getter="is_refusing_new_network_connections">
- If [code]true[/code] the SceneTree's [member network_peer] refuses new incoming connections.
+ If [code]true[/code], the SceneTree's [member network_peer] refuses new incoming connections.
</member>
<member name="root" type="Viewport" setter="" getter="get_root">
The SceneTree's [Viewport].
</member>
<member name="use_font_oversampling" type="bool" setter="set_use_font_oversampling" getter="is_using_font_oversampling">
- If [code]true[/code] font oversampling is used.
+ If [code]true[/code], font oversampling is used.
</member>
</members>
<signals>
diff --git a/doc/classes/ShortCut.xml b/doc/classes/ShortCut.xml
index 1b5fc035c2..b3bb364e54 100644
--- a/doc/classes/ShortCut.xml
+++ b/doc/classes/ShortCut.xml
@@ -32,7 +32,7 @@
<return type="bool">
</return>
<description>
- If [code]true[/code] this shortcut is valid.
+ If [code]true[/code], this shortcut is valid.
</description>
</method>
</methods>
diff --git a/doc/classes/Spatial.xml b/doc/classes/Spatial.xml
index 6f9d779737..e7dc0dcc3f 100644
--- a/doc/classes/Spatial.xml
+++ b/doc/classes/Spatial.xml
@@ -318,7 +318,7 @@
Local translation of this node.
</member>
<member name="visible" type="bool" setter="set_visible" getter="is_visible">
- If [code]true[/code] this node is drawn. Default value: [code]true[/code].
+ If [code]true[/code], this node is drawn. Default value: [code]true[/code].
</member>
</members>
<signals>
diff --git a/doc/classes/SpatialMaterial.xml b/doc/classes/SpatialMaterial.xml
index 3503505999..62a34821fe 100644
--- a/doc/classes/SpatialMaterial.xml
+++ b/doc/classes/SpatialMaterial.xml
@@ -23,12 +23,12 @@
The strength of the anisotropy effect.
</member>
<member name="anisotropy_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] anisotropy is enabled. Changes the shape of the specular blob and aligns it to tangent space. Default value: [code]false[/code].
+ If [code]true[/code], anisotropy is enabled. Changes the shape of the specular blob and aligns it to tangent space. Default value: [code]false[/code].
</member>
<member name="anisotropy_flowmap" type="Texture" setter="set_texture" getter="get_texture">
</member>
<member name="ao_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] ambient occlusion is enabled.
+ If [code]true[/code], ambient occlusion is enabled.
</member>
<member name="ao_light_affect" type="float" setter="set_ao_light_affect" getter="get_ao_light_affect">
</member>
@@ -41,7 +41,7 @@
<member name="clearcoat" type="float" setter="set_clearcoat" getter="get_clearcoat">
</member>
<member name="clearcoat_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] clearcoat rendering is enabled. Adds a secondary transparent pass to the material. Default value: [code]false[/code].
+ If [code]true[/code], clearcoat rendering is enabled. Adds a secondary transparent pass to the material. Default value: [code]false[/code].
</member>
<member name="clearcoat_gloss" type="float" setter="set_clearcoat_gloss" getter="get_clearcoat_gloss">
</member>
@@ -50,7 +50,7 @@
<member name="depth_deep_parallax" type="bool" setter="set_depth_deep_parallax" getter="is_depth_deep_parallax_enabled">
</member>
<member name="depth_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] Depth mapping is enabled. See also [member normal_enabled].
+ If [code]true[/code], Depth mapping is enabled. See also [member normal_enabled].
</member>
<member name="depth_flip_binormal" type="bool" setter="set_depth_deep_parallax_flip_binormal" getter="get_depth_deep_parallax_flip_binormal">
</member>
@@ -86,7 +86,7 @@
The emitted light's color. See [member emission_enabled].
</member>
<member name="emission_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] the body emits light.
+ If [code]true[/code], the body emits light.
</member>
<member name="emission_energy" type="float" setter="set_emission_energy" getter="get_emission_energy">
The emitted light's strength. See [member emission_enabled].
@@ -100,33 +100,33 @@
<member name="flags_albedo_tex_force_srgb" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="flags_disable_ambient_light" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the object receives no ambient light. Default value: [code]false[/code].
+ If [code]true[/code], the object receives no ambient light. Default value: [code]false[/code].
</member>
<member name="flags_do_not_receive_shadows" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the object receives no shadow that would otherwise be cast onto it. Default value: [code]false[/code].
+ If [code]true[/code], the object receives no shadow that would otherwise be cast onto it. Default value: [code]false[/code].
</member>
<member name="flags_ensure_correct_normals" type="bool" setter="set_flag" getter="get_flag">
</member>
<member name="flags_fixed_size" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the object is rendered at the same size regardless of distance. Default value: [code]false[/code].
+ If [code]true[/code], the object is rendered at the same size regardless of distance. Default value: [code]false[/code].
</member>
<member name="flags_no_depth_test" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] depth testing is disabled and the object will be drawn in render order.
+ If [code]true[/code], depth testing is disabled and the object will be drawn in render order.
</member>
<member name="flags_transparent" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] transparency is enabled on the body. Default value: [code]false[/code]. See also [member params_blend_mode].
+ If [code]true[/code], transparency is enabled on the body. Default value: [code]false[/code]. See also [member params_blend_mode].
</member>
<member name="flags_unshaded" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the object is unaffected by lighting. Default value: [code]false[/code].
+ If [code]true[/code], the object is unaffected by lighting. Default value: [code]false[/code].
</member>
<member name="flags_use_point_size" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] render point size can be changed. Note: this is only effective for objects whose geometry is point-based rather than triangle-based. See also [member params_point_size].
+ If [code]true[/code], render point size can be changed. Note: this is only effective for objects whose geometry is point-based rather than triangle-based. See also [member params_point_size].
</member>
<member name="flags_vertex_lighting" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] lighting is calculated per vertex rather than per pixel. This may increase performance on low-end devices. Default value: [code]false[/code].
+ If [code]true[/code], lighting is calculated per vertex rather than per pixel. This may increase performance on low-end devices. Default value: [code]false[/code].
</member>
<member name="flags_world_triplanar" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] triplanar mapping is calculated in world space rather than object local space. See also [member uv1_triplanar]. Default value: [code]false[/code].
+ If [code]true[/code], triplanar mapping is calculated in world space rather than object local space. See also [member uv1_triplanar]. Default value: [code]false[/code].
</member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic">
The reflectivity of the object's surface. The higher the value the more light is reflected.
@@ -139,7 +139,7 @@
<member name="metallic_texture_channel" type="int" setter="set_metallic_texture_channel" getter="get_metallic_texture_channel" enum="SpatialMaterial.TextureChannel">
</member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] normal mapping is enabled.
+ If [code]true[/code], normal mapping is enabled.
</member>
<member name="normal_scale" type="float" setter="set_normal_scale" getter="get_normal_scale">
The strength of the normal map's effect.
@@ -166,7 +166,7 @@
The algorithm used for diffuse light scattering. See [enum DiffuseMode].
</member>
<member name="params_grow" type="bool" setter="set_grow_enabled" getter="is_grow_enabled">
- If [code]true[/code] enables the vertex grow setting. See [member params_grow_amount].
+ If [code]true[/code], enables the vertex grow setting. See [member params_grow_amount].
</member>
<member name="params_grow_amount" type="float" setter="set_grow" getter="get_grow">
Grows object vertices in the direction of their normals.
@@ -185,7 +185,7 @@
The number of horizontal frames in the particle spritesheet. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
</member>
<member name="particles_anim_loop" type="bool" setter="set_particles_anim_loop" getter="get_particles_anim_loop">
- If [code]true[/code] particle animations are looped. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
+ If [code]true[/code], particle animations are looped. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
</member>
<member name="particles_anim_v_frames" type="int" setter="set_particles_anim_v_frames" getter="get_particles_anim_v_frames">
The number of vertical frames in the particle spritesheet. Only enabled when using [code]BillboardMode.BILLBOARD_PARTICLES[/code]. See [member params_billboard_mode].
@@ -193,10 +193,10 @@
<member name="proximity_fade_distance" type="float" setter="set_proximity_fade_distance" getter="get_proximity_fade_distance">
</member>
<member name="proximity_fade_enable" type="bool" setter="set_proximity_fade" getter="is_proximity_fade_enabled">
- If [code]true[/code] the proximity and distance fade effect is enabled. Default value: [code]false[/code].
+ If [code]true[/code], the proximity and distance fade effect is enabled. Default value: [code]false[/code].
</member>
<member name="refraction_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] the refraction effect is enabled. Distorts transparency based on light from behind the object. Default value: [code]false[/code].
+ If [code]true[/code], the refraction effect is enabled. Distorts transparency based on light from behind the object. Default value: [code]false[/code].
</member>
<member name="refraction_scale" type="float" setter="set_refraction" getter="get_refraction">
The strength of the refraction effect.
@@ -208,7 +208,7 @@
<member name="rim" type="float" setter="set_rim" getter="get_rim">
</member>
<member name="rim_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] rim effect is enabled. Default value: [code]false[/code].
+ If [code]true[/code], rim effect is enabled. Default value: [code]false[/code].
</member>
<member name="rim_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
@@ -223,7 +223,7 @@
<member name="roughness_texture_channel" type="int" setter="set_roughness_texture_channel" getter="get_roughness_texture_channel" enum="SpatialMaterial.TextureChannel">
</member>
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
+ If [code]true[/code], subsurface scattering is enabled. Emulates light that penetrates an object's surface, is scattered, and then emerges.
</member>
<member name="subsurf_scatter_strength" type="float" setter="set_subsurface_scattering_strength" getter="get_subsurface_scattering_strength">
The strength of the subsurface scattering effect.
@@ -234,7 +234,7 @@
The color used by the transmission effect. Represents the light passing through an object.
</member>
<member name="transmission_enabled" type="bool" setter="set_feature" getter="get_feature">
- If [code]true[/code] the transmission effect is enabled. Default value: [code]false[/code].
+ If [code]true[/code], the transmission effect is enabled. Default value: [code]false[/code].
</member>
<member name="transmission_texture" type="Texture" setter="set_texture" getter="get_texture">
</member>
@@ -255,10 +255,10 @@
<member name="uv2_triplanar_sharpness" type="float" setter="set_uv2_triplanar_blend_sharpness" getter="get_uv2_triplanar_blend_sharpness">
</member>
<member name="vertex_color_is_srgb" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the model's vertex colors are processed as sRGB mode. Default value: [code]false[/code].
+ If [code]true[/code], the model's vertex colors are processed as sRGB mode. Default value: [code]false[/code].
</member>
<member name="vertex_color_use_as_albedo" type="bool" setter="set_flag" getter="get_flag">
- If [code]true[/code] the vertex color is used as albedo color. Default value: [code]false[/code].
+ If [code]true[/code], the vertex color is used as albedo color. Default value: [code]false[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/Sprite.xml b/doc/classes/Sprite.xml
index 52650c7300..d1cdbffc6c 100644
--- a/doc/classes/Sprite.xml
+++ b/doc/classes/Sprite.xml
@@ -29,13 +29,13 @@
</methods>
<members>
<member name="centered" type="bool" setter="set_centered" getter="is_centered">
- If [code]true[/code] texture is centered. Default value: [code]true[/code].
+ If [code]true[/code], texture is centered. Default value: [code]true[/code].
</member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h">
- If [code]true[/code] texture is flipped horizontally. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped horizontally. Default value: [code]false[/code].
</member>
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v">
- If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped vertically. Default value: [code]false[/code].
</member>
<member name="frame" type="int" setter="set_frame" getter="get_frame">
Current frame to display from sprite sheet. [member vframes] or [member hframes] must be greater than 1.
@@ -50,10 +50,10 @@
The texture's drawing offset.
</member>
<member name="region_enabled" type="bool" setter="set_region" getter="is_region">
- If [code]true[/code] texture is cut from a larger atlas texture. See [code]region_rect[/code]. Default value: [code]false[/code].
+ If [code]true[/code], texture is cut from a larger atlas texture. See [code]region_rect[/code]. Default value: [code]false[/code].
</member>
<member name="region_filter_clip" type="bool" setter="set_region_filter_clip" getter="is_region_filter_clip_enabled">
- If [code]true[/code] the outermost pixels get blurred out.
+ If [code]true[/code], the outermost pixels get blurred out.
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect">
The region of the atlas texture to display. [member region_enabled] must be [code]true[/code].
diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml
index 2a65246dde..f43fa34785 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -20,7 +20,7 @@
The number of columns in the sprite sheet.
</member>
<member name="region_enabled" type="bool" setter="set_region" getter="is_region">
- If [code]true[/code] texture will be cut from a larger atlas texture. See [member region_rect]. Default value: [code]false[/code].
+ If [code]true[/code], texture will be cut from a larger atlas texture. See [member region_rect]. Default value: [code]false[/code].
</member>
<member name="region_rect" type="Rect2" setter="set_region_rect" getter="get_region_rect">
The region of the atlas texture to display. [member region_enabled] must be [code]true[/code].
diff --git a/doc/classes/SpriteBase3D.xml b/doc/classes/SpriteBase3D.xml
index fd4b583928..12d58808d5 100644
--- a/doc/classes/SpriteBase3D.xml
+++ b/doc/classes/SpriteBase3D.xml
@@ -31,16 +31,16 @@
The direction in which the front of the texture faces.
</member>
<member name="centered" type="bool" setter="set_centered" getter="is_centered">
- If [code]true[/code] texture will be centered. Default value: [code]true[/code].
+ If [code]true[/code], texture will be centered. Default value: [code]true[/code].
</member>
<member name="double_sided" type="bool" setter="set_draw_flag" getter="get_draw_flag">
- If [code]true[/code] texture can be seen from the back as well, if [code]false[/code], it is invisible when looking at it from behind. Default value: [code]true[/code].
+ If [code]true[/code], texture can be seen from the back as well, if [code]false[/code], it is invisible when looking at it from behind. Default value: [code]true[/code].
</member>
<member name="flip_h" type="bool" setter="set_flip_h" getter="is_flipped_h">
- If [code]true[/code] texture is flipped horizontally. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped horizontally. Default value: [code]false[/code].
</member>
<member name="flip_v" type="bool" setter="set_flip_v" getter="is_flipped_v">
- If [code]true[/code] texture is flipped vertically. Default value: [code]false[/code].
+ If [code]true[/code], texture is flipped vertically. Default value: [code]false[/code].
</member>
<member name="modulate" type="Color" setter="set_modulate" getter="get_modulate">
A color value that gets multiplied on, could be used for mood-coloring or to simulate the color of light.
@@ -55,10 +55,10 @@
The size of one pixel's width on the Sprite to scale it in 3D.
</member>
<member name="shaded" type="bool" setter="set_draw_flag" getter="get_draw_flag">
- If [code]true[/code] the [Light] in the [Environment] has effects on the Sprite. Default value: [code]false[/code].
+ If [code]true[/code], the [Light] in the [Environment] has effects on the Sprite. Default value: [code]false[/code].
</member>
<member name="transparent" type="bool" setter="set_draw_flag" getter="get_draw_flag">
- If [code]true[/code] the texture's transparency and the opacity are used to make those parts of the Sprite invisible. Default value: [code]true[/code].
+ If [code]true[/code], the texture's transparency and the opacity are used to make those parts of the Sprite invisible. Default value: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/classes/SpriteFrames.xml b/doc/classes/SpriteFrames.xml
index 0e11d797e4..e261b2112f 100644
--- a/doc/classes/SpriteFrames.xml
+++ b/doc/classes/SpriteFrames.xml
@@ -55,7 +55,7 @@
<argument index="0" name="anim" type="String">
</argument>
<description>
- If [code]true[/code] the given animation will loop.
+ If [code]true[/code], the given animation will loop.
</description>
</method>
<method name="get_animation_names" qualifiers="const">
@@ -100,7 +100,7 @@
<argument index="0" name="anim" type="String">
</argument>
<description>
- If [code]true[/code] the named animation exists.
+ If [code]true[/code], the named animation exists.
</description>
</method>
<method name="remove_animation">
@@ -142,7 +142,7 @@
<argument index="1" name="loop" type="bool">
</argument>
<description>
- If [code]true[/code] the animation will loop.
+ If [code]true[/code], the animation will loop.
</description>
</method>
<method name="set_animation_speed">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index 536165487d..dbef84fc15 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -439,6 +439,15 @@
Returns [code]true[/code] if this string contains a valid float.
</description>
</method>
+ <method name="is_valid_hex_number">
+ <return type="bool">
+ </return>
+ <argument index="0" name="with_prefix" type="bool" default="False">
+ </argument>
+ <description>
+ Returns [code]true[/code] if this string contains a valid hexadecimal number. If [code]with_prefix[/code] is [code]true[/code], then a validity of the hexadecimal number is determined by [code]0x[/code] prefix, for instance: [code]0xDEADC0DE[/code].
+ </description>
+ </method>
<method name="is_valid_html_color">
<return type="bool">
</return>
diff --git a/doc/classes/StyleBoxFlat.xml b/doc/classes/StyleBoxFlat.xml
index bf544d2b78..a162aa02b0 100644
--- a/doc/classes/StyleBoxFlat.xml
+++ b/doc/classes/StyleBoxFlat.xml
@@ -114,9 +114,9 @@
Border width for the top border.
</member>
<member name="corner_detail" type="int" setter="set_corner_detail" getter="get_corner_detail">
- This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value you should take the corner radius ([method set_corner_radius]) into account.
- For corner radius smaller than 10: 4-5 should be enough
- For corner radius smaller than 30: 8-12 should be enough
+ This sets the amount of vertices used for each corner. Higher values result in rounder corners but take more processing power to compute. When choosing a value you should take the corner radius ([method set_corner_radius_all]) into account.
+ For corner radius smaller than 10, 4-5 should be enough.
+ For corner radius smaller than 30, 8-12 should be enough.
</member>
<member name="corner_radius_bottom_left" type="int" setter="set_corner_radius" getter="get_corner_radius">
The corner radius of the bottom left corner. When set to 0 the corner is not rounded.
diff --git a/doc/classes/TabContainer.xml b/doc/classes/TabContainer.xml
index f17c10b31e..04285b62df 100644
--- a/doc/classes/TabContainer.xml
+++ b/doc/classes/TabContainer.xml
@@ -148,7 +148,7 @@
The alignment of all tabs in the tab container. See the [code]ALIGN_*[/code] constants for details.
</member>
<member name="tabs_visible" type="bool" setter="set_tabs_visible" getter="are_tabs_visible">
- If [code]true[/code] tabs are visible. If [code]false[/code] tabs' content and titles are hidden. Default value: [code]true[/code].
+ If [code]true[/code], tabs are visible. If [code]false[/code], tabs' content and titles are hidden. Default value: [code]true[/code].
</member>
</members>
<signals>
diff --git a/doc/classes/Tabs.xml b/doc/classes/Tabs.xml
index 350b49513d..de57250d8b 100644
--- a/doc/classes/Tabs.xml
+++ b/doc/classes/Tabs.xml
@@ -126,7 +126,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] enables selecting a tab with right mouse button.
+ If [code]true[/code], enables selecting a tab with right mouse button.
</description>
</method>
<method name="set_tab_disabled">
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index b2e3885ff2..e237cfa220 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -359,39 +359,39 @@
</methods>
<members>
<member name="breakpoint_gutter" type="bool" setter="set_breakpoint_gutter_enabled" getter="is_breakpoint_gutter_enabled">
- If [code]true[/code] the breakpoint gutter is visible.
+ If [code]true[/code], the breakpoint gutter is visible.
</member>
<member name="caret_blink" type="bool" setter="cursor_set_blink_enabled" getter="cursor_get_blink_enabled">
- If [code]true[/code] the caret (visual cursor) blinks.
+ If [code]true[/code], the caret (visual cursor) blinks.
</member>
<member name="caret_blink_speed" type="float" setter="cursor_set_blink_speed" getter="cursor_get_blink_speed">
Duration (in seconds) of a caret's blinking cycle.
</member>
<member name="caret_block_mode" type="bool" setter="cursor_set_block_mode" getter="cursor_is_block_mode">
- If [code]true[/code] the caret displays as a rectangle.
- If [code]false[/code] the caret displays as a bar.
+ If [code]true[/code], the caret displays as a rectangle.
+ If [code]false[/code], the caret displays as a bar.
</member>
<member name="caret_moving_by_right_click" type="bool" setter="set_right_click_moves_caret" getter="is_right_click_moving_caret">
- If [code]true[/code] a right click moves the cursor at the mouse position before displaying the context menu.
- If [code]false[/code] the context menu disregards mouse location.
+ If [code]true[/code], a right click moves the cursor at the mouse position before displaying the context menu.
+ If [code]false[/code], the context menu disregards mouse location.
</member>
<member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled">
- If [code]true[/code] a right click displays the context menu.
+ If [code]true[/code], a right click displays the context menu.
</member>
<member name="hiding_enabled" type="int" setter="set_hiding_enabled" getter="is_hiding_enabled">
</member>
<member name="highlight_all_occurrences" type="bool" setter="set_highlight_all_occurrences" getter="is_highlight_all_occurrences_enabled">
</member>
<member name="highlight_current_line" type="bool" setter="set_highlight_current_line" getter="is_highlight_current_line_enabled">
- If [code]true[/code] the line containing the cursor is highlighted.
+ If [code]true[/code], the line containing the cursor is highlighted.
</member>
<member name="override_selected_font_color" type="bool" setter="set_override_selected_font_color" getter="is_overriding_selected_font_color">
</member>
<member name="readonly" type="bool" setter="set_readonly" getter="is_readonly">
- If [code]true[/code] read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
+ If [code]true[/code], read-only mode is enabled. Existing text cannot be modified and new text cannot be added.
</member>
<member name="show_line_numbers" type="bool" setter="set_show_line_numbers" getter="is_show_line_numbers_enabled">
- If [code]true[/code] line numbers are displayed to the left of the text.
+ If [code]true[/code], line numbers are displayed to the left of the text.
</member>
<member name="smooth_scrolling" type="bool" setter="set_smooth_scroll_enable" getter="is_smooth_scroll_enabled">
</member>
diff --git a/doc/classes/TextureButton.xml b/doc/classes/TextureButton.xml
index 7e54ab9fe8..f61db22138 100644
--- a/doc/classes/TextureButton.xml
+++ b/doc/classes/TextureButton.xml
@@ -15,7 +15,7 @@
</methods>
<members>
<member name="expand" type="bool" setter="set_expand" getter="get_expand">
- If [code]true[/code] the texture stretches to the edges of the node's bounding rectangle using the [member stretch_mode]. If [code]false[/code] the texture will not scale with the node. Default value: [code]false[/code].
+ If [code]true[/code], the texture stretches to the edges of the node's bounding rectangle using the [member stretch_mode]. If [code]false[/code], the texture will not scale with the node. Default value: [code]false[/code].
</member>
<member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureButton.StretchMode">
Controls the texture's behavior when you resize the node's bounding rectangle, [b]only if[/b] [member expand] is [code]true[/code]. Set it to one of the [code]STRETCH_*[/code] constants. See the constants to learn more.
diff --git a/doc/classes/TextureProgress.xml b/doc/classes/TextureProgress.xml
index 3cbaf0429c..a98a2e9f74 100644
--- a/doc/classes/TextureProgress.xml
+++ b/doc/classes/TextureProgress.xml
@@ -17,7 +17,7 @@
The fill direction. Uses FILL_* constants.
</member>
<member name="nine_patch_stretch" type="bool" setter="set_nine_patch_stretch" getter="get_nine_patch_stretch">
- If [code]true[/code] Godot treats the bar's textures like [NinePatchRect]. Use [code]stretch_margin_*[/code], like [member stretch_margin_bottom], to set up the nine patch's 3x3 grid. Default value: [code]false[/code].
+ If [code]true[/code], Godot treats the bar's textures like [NinePatchRect]. Use [code]stretch_margin_*[/code], like [member stretch_margin_bottom], to set up the nine patch's 3x3 grid. Default value: [code]false[/code].
</member>
<member name="radial_center_offset" type="Vector2" setter="set_radial_center_offset" getter="get_radial_center_offset">
Offsets [member texture_progress] if [member fill_mode] is [code]FILL_CLOCKWISE[/code] or [code]FILL_COUNTER_CLOCKWISE[/code].
diff --git a/doc/classes/TextureRect.xml b/doc/classes/TextureRect.xml
index 95afc5d281..78065afcc9 100644
--- a/doc/classes/TextureRect.xml
+++ b/doc/classes/TextureRect.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="expand" type="bool" setter="set_expand" getter="has_expand">
- If [code]true[/code] the texture scales to fit its bounding rectangle. Default value: [code]false[/code].
+ If [code]true[/code], the texture scales to fit its bounding rectangle. Default value: [code]false[/code].
</member>
<member name="stretch_mode" type="int" setter="set_stretch_mode" getter="get_stretch_mode" enum="TextureRect.StretchMode">
Controls the texture's behavior when resizing the node's bounding rectangle. See [enum StretchMode].
diff --git a/doc/classes/TileMap.xml b/doc/classes/TileMap.xml
index 7034d75473..fb5a733ccd 100644
--- a/doc/classes/TileMap.xml
+++ b/doc/classes/TileMap.xml
@@ -37,6 +37,16 @@
Returns the tile index of the given cell.
</description>
</method>
+ <method name="get_cell_autotile_coord" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_cellv" qualifiers="const">
<return type="int">
</return>
@@ -257,7 +267,7 @@
Position for tile origin. Uses TILE_ORIGIN_* constants. Default value: TILE_ORIGIN_TOP_LEFT.
</member>
<member name="cell_y_sort" type="bool" setter="set_y_sort_mode" getter="is_y_sort_mode_enabled">
- If [code]true[/code] the TileMap's children will be drawn in order of their Y coordinate. Default value: [code]false[/code].
+ If [code]true[/code], the TileMap's children will be drawn in order of their Y coordinate. Default value: [code]false[/code].
</member>
<member name="collision_bounce" type="float" setter="set_collision_bounce" getter="get_collision_bounce">
Bounce value for static body collisions (see [code]collision_use_kinematic[/code]). Default value: 0.
@@ -272,7 +282,7 @@
The collision mask(s) for all colliders in the TileMap.
</member>
<member name="collision_use_kinematic" type="bool" setter="set_collision_use_kinematic" getter="get_collision_use_kinematic">
- If [code]true[/code] TileMap collisions will be handled as a kinematic body. If [code]false[/code] collisions will be handled as static body. Default value: [code]false[/code].
+ If [code]true[/code], TileMap collisions will be handled as a kinematic body. If [code]false[/code], collisions will be handled as static body. Default value: [code]false[/code].
</member>
<member name="mode" type="int" setter="set_mode" getter="get_mode" enum="TileMap.Mode">
The TileMap orientation mode. Uses MODE_* constants. Default value: MODE_SQUARE.
diff --git a/doc/classes/TileSet.xml b/doc/classes/TileSet.xml
index ffd15e8d8b..fadc6fbcb9 100644
--- a/doc/classes/TileSet.xml
+++ b/doc/classes/TileSet.xml
@@ -36,12 +36,66 @@
<description>
</description>
</method>
+ <method name="autotile_clear_bitmask_map">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Clears all bitmask info of the autotile.
+ </description>
+ </method>
+ <method name="autotile_get_bitmask">
+ <return type="int" enum="TileSet.AutotileBindings">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the bitmask of the subtile from an autotile given its coordinates.
+ The value is the sum of the values in [enum TileSet.AutotileBindings] present in the subtile (e.g. a value of 5 means the bitmask has bindings in both the top left and top right).
+ </description>
+ </method>
<method name="autotile_get_bitmask_mode" qualifiers="const">
<return type="int" enum="TileSet.BitmaskMode">
</return>
<argument index="0" name="id" type="int">
</argument>
<description>
+ Returns the [enum TileSet.BitmaskMode] of the autotile.
+ </description>
+ </method>
+ <method name="autotile_get_icon_coordinate" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Returns the subtile that's being used as an icon in an atlas/autotile given its coordinates.
+ The subtile defined as the icon will be used as a fallback when the atlas/autotile's bitmask info is incomplete. It will also be used to represent it in the TileSet editor.
+ </description>
+ </method>
+ <method name="autotile_get_light_occluder" qualifiers="const">
+ <return type="OccluderPolygon2D">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the light occluder of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_get_navigation_polygon" qualifiers="const">
+ <return type="NavigationPolygon">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the navigation polygon of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="autotile_get_size" qualifiers="const">
@@ -50,6 +104,53 @@
<argument index="0" name="id" type="int">
</argument>
<description>
+ Returns the size of the subtiles in an atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_get_spacing" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ Returns the spacing between subtiles of the atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_get_subtile_priority">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the priority of the subtile from an autotile given its coordinates.
+ When more than one subtile has the same bitmask value, one of them will be picked randomly for drawing. Its priority will define how often it will be picked.
+ </description>
+ </method>
+ <method name="autotile_get_z_index">
+ <return type="int">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Returns the drawing index of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_set_bitmask">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="bitmask" type="Vector2">
+ </argument>
+ <argument index="2" name="flag" type="int" enum="TileSet.AutotileBindings">
+ </argument>
+ <description>
+ Sets the bitmask of the subtile from an autotile given its coordinates.
+ The value is the sum of the values in [enum TileSet.AutotileBindings] present in the subtile (e.g. a value of 5 means the bitmask has bindings in both the top left and top right).
</description>
</method>
<method name="autotile_set_bitmask_mode">
@@ -60,6 +161,45 @@
<argument index="1" name="mode" type="int" enum="TileSet.BitmaskMode">
</argument>
<description>
+ Sets the [enum TileSet.BitmaskMode] of the autotile.
+ </description>
+ </method>
+ <method name="autotile_set_icon_coordinate">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the subtile that will be used as an icon in an atlas/autotile given its coordinates.
+ The subtile defined as the icon will be used as a fallback when the atlas/autotile's bitmask info is incomplete. It will also be used to represent it in the TileSet editor.
+ </description>
+ </method>
+ <method name="autotile_set_light_occluder">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="light_occluder" type="OccluderPolygon2D">
+ </argument>
+ <argument index="2" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the light occluder of the subtile from an atlas/autotile given its coordinates.
+ </description>
+ </method>
+ <method name="autotile_set_navigation_polygon">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="navigation_polygon" type="NavigationPolygon">
+ </argument>
+ <argument index="2" name="coord" type="Vector2">
+ </argument>
+ <description>
+ Sets the navigation polygon of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="autotile_set_size">
@@ -70,6 +210,45 @@
<argument index="1" name="size" type="Vector2">
</argument>
<description>
+ Sets the size of the subtiles in an atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_set_spacing">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="spacing" type="int">
+ </argument>
+ <description>
+ Sets the spacing between subtiles of the atlas/autotile.
+ </description>
+ </method>
+ <method name="autotile_set_subtile_priority">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <argument index="2" name="priority" type="int">
+ </argument>
+ <description>
+ Sets the priority of the subtile from an autotile given its coordinates.
+ When more than one subtile has the same bitmask value, one of them will be picked randomly for drawing. Its priority will define how often it will be picked.
+ </description>
+ </method>
+ <method name="autotile_set_z_index">
+ <return type="void">
+ </return>
+ <argument index="0" name="id" type="int">
+ </argument>
+ <argument index="1" name="coord" type="Vector2">
+ </argument>
+ <argument index="2" name="z_index" type="int">
+ </argument>
+ <description>
+ Sets the drawing index of the subtile from an atlas/autotile given its coordinates.
</description>
</method>
<method name="clear">
@@ -304,7 +483,7 @@
<argument index="0" name="id" type="int">
</argument>
<description>
- Returns the tile's [enum TileMode].
+ Returns the tile's [enum TileSet.TileMode].
</description>
</method>
<method name="tile_get_z_index" qualifiers="const">
@@ -508,7 +687,7 @@
<argument index="1" name="tilemode" type="int" enum="TileSet.TileMode">
</argument>
<description>
- Sets the tile's [enum TileMode].
+ Sets the tile's [enum TileSet.TileMode].
</description>
</method>
<method name="tile_set_z_index">
diff --git a/doc/classes/Timer.xml b/doc/classes/Timer.xml
index 65d638c4c0..ae0a3ad148 100644
--- a/doc/classes/Timer.xml
+++ b/doc/classes/Timer.xml
@@ -24,8 +24,8 @@
<argument index="0" name="time_sec" type="float" default="-1">
</argument>
<description>
- Starts the timer. Sets [code]wait_time[/code] to [code]time_sec[/code] if [code]time_sec[/code] &gt; 0. This also resets the remaining time to [code]wait_time[/code].
- Note: this method will not resume a paused timer. See [method set_paused].
+ Starts the timer. Sets [code]wait_time[/code] to [code]time_sec[/code] if [code]time_sec &gt; 0[/code]. This also resets the remaining time to [code]wait_time[/code].
+ Note: this method will not resume a paused timer. See [member paused].
</description>
</method>
<method name="stop">
@@ -38,13 +38,13 @@
</methods>
<members>
<member name="autostart" type="bool" setter="set_autostart" getter="has_autostart">
- If [code]true[/code] the timer will automatically start when entering the scene tree. Default value: [code]false[/code].
+ If [code]true[/code], the timer will automatically start when entering the scene tree. Default value: [code]false[/code].
</member>
<member name="one_shot" type="bool" setter="set_one_shot" getter="is_one_shot">
- If [code]true[/code] the timer will stop when reaching 0. If [code]false[/code] it will restart. Default value: [code]false[/code].
+ If [code]true[/code], the timer will stop when reaching 0. If [code]false[/code], it will restart. Default value: [code]false[/code].
</member>
<member name="paused" type="bool" setter="set_paused" getter="is_paused">
- If [code]true[/code] the timer is paused and will not process until it is unpaused again, even if [method start] is called.
+ If [code]true[/code], the timer is paused and will not process until it is unpaused again, even if [method start] is called.
</member>
<member name="process_mode" type="int" setter="set_timer_process_mode" getter="get_timer_process_mode" enum="Timer.TimerProcessMode">
Processing mode. See [enum TimerProcessMode].
diff --git a/doc/classes/TouchScreenButton.xml b/doc/classes/TouchScreenButton.xml
index 1b37ce95ba..6cc688d3c5 100644
--- a/doc/classes/TouchScreenButton.xml
+++ b/doc/classes/TouchScreenButton.xml
@@ -30,7 +30,7 @@
The button's texture for the normal state.
</member>
<member name="passby_press" type="bool" setter="set_passby_press" getter="is_passby_press_enabled">
- If [code]true[/code] passby presses are enabled.
+ If [code]true[/code], passby presses are enabled.
</member>
<member name="pressed" type="Texture" setter="set_texture_pressed" getter="get_texture_pressed">
The button's texture for the pressed state.
@@ -39,10 +39,10 @@
The button's shape.
</member>
<member name="shape_centered" type="bool" setter="set_shape_centered" getter="is_shape_centered">
- If [code]true[/code] the button's shape is centered.
+ If [code]true[/code], the button's shape is centered.
</member>
<member name="shape_visible" type="bool" setter="set_shape_visible" getter="is_shape_visible">
- If [code]true[/code] the button's shape is visible.
+ If [code]true[/code], the button's shape is visible.
</member>
<member name="visibility_mode" type="int" setter="set_visibility_mode" getter="get_visibility_mode" enum="TouchScreenButton.VisibilityMode">
The button's visibility mode. See [code]VISIBILITY_*[/code] constants.
diff --git a/doc/classes/TranslationLoaderPO.xml b/doc/classes/TranslationLoaderPO.xml
new file mode 100644
index 0000000000..58cf2f6572
--- /dev/null
+++ b/doc/classes/TranslationLoaderPO.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="TranslationLoaderPO" inherits="ResourceFormatLoader" category="Core" version="3.1">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <tutorials>
+ </tutorials>
+ <demos>
+ </demos>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml
index 1ad8166b91..d4a11247dc 100644
--- a/doc/classes/Tree.xml
+++ b/doc/classes/Tree.xml
@@ -184,7 +184,7 @@
<argument index="1" name="expand" type="bool">
</argument>
<description>
- If [code]true[/code] the column will have the "Expand" flag of [Control].
+ If [code]true[/code], the column will have the "Expand" flag of [Control].
</description>
</method>
<method name="set_column_min_width">
@@ -215,16 +215,16 @@
<argument index="0" name="visible" type="bool">
</argument>
<description>
- If [code]true[/code] column titles are visible.
+ If [code]true[/code], column titles are visible.
</description>
</method>
</methods>
<members>
<member name="allow_reselect" type="bool" setter="set_allow_reselect" getter="get_allow_reselect">
- If [code]true[/code] the currently selected cell may be selected again.
+ If [code]true[/code], the currently selected cell may be selected again.
</member>
<member name="allow_rmb_select" type="bool" setter="set_allow_rmb_select" getter="get_allow_rmb_select">
- If [code]true[/code] a right mouse button click can select items.
+ If [code]true[/code], a right mouse button click can select items.
</member>
<member name="columns" type="int" setter="set_columns" getter="get_columns">
The amount of columns.
@@ -233,10 +233,10 @@
The drop mode as an OR combination of flags. See [code]DROP_MODE_*[/code] constants. Once dropping is done, reverts to [code]DROP_MODE_DISABLED[/code]. Setting this during [method Control.can_drop_data] is recommended.
</member>
<member name="hide_folding" type="bool" setter="set_hide_folding" getter="is_folding_hidden">
- If [code]true[/code] the folding arrow is hidden.
+ If [code]true[/code], the folding arrow is hidden.
</member>
<member name="hide_root" type="bool" setter="set_hide_root" getter="is_root_hidden">
- If [code]true[/code] the tree's root is hidden.
+ If [code]true[/code], the tree's root is hidden.
</member>
<member name="select_mode" type="int" setter="set_select_mode" getter="get_select_mode" enum="Tree.SelectMode">
Allow single or multiple selection. See the [code]SELECT_*[/code] constants.
diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml
index b4227b34be..209e5a8bd0 100644
--- a/doc/classes/TreeItem.xml
+++ b/doc/classes/TreeItem.xml
@@ -352,7 +352,7 @@
<argument index="1" name="checked" type="bool">
</argument>
<description>
- If [code]true[/code] the column [code]column[/code] is checked.
+ If [code]true[/code], the column [code]column[/code] is checked.
</description>
</method>
<method name="set_custom_as_button">
@@ -411,7 +411,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] column [code]column[/code] is editable.
+ If [code]true[/code], column [code]column[/code] is editable.
</description>
</method>
<method name="set_expand_right">
@@ -422,7 +422,7 @@
<argument index="1" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] column [code]column[/code] is expanded to the right.
+ If [code]true[/code], column [code]column[/code] is expanded to the right.
</description>
</method>
<method name="set_icon">
@@ -502,7 +502,7 @@
<argument index="1" name="selectable" type="bool">
</argument>
<description>
- If [code]true[/code] the given column is selectable.
+ If [code]true[/code], the given column is selectable.
</description>
</method>
<method name="set_text">
@@ -540,13 +540,13 @@
</methods>
<members>
<member name="collapsed" type="bool" setter="set_collapsed" getter="is_collapsed">
- If [code]true[/code] the TreeItem is collapsed.
+ If [code]true[/code], the TreeItem is collapsed.
</member>
<member name="custom_minimum_height" type="int" setter="set_custom_minimum_height" getter="get_custom_minimum_height">
The custom minimum height.
</member>
<member name="disable_folding" type="bool" setter="set_disable_folding" getter="is_folding_disabled">
- If [code]true[/code] folding is disabled for this TreeItem.
+ If [code]true[/code], folding is disabled for this TreeItem.
</member>
</members>
<constants>
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index e792835605..b902821fb2 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -346,7 +346,7 @@
The tween's speed multiplier. For example, set it to [code]1.0[/code] for normal speed, [code]2.0[/code] for two times normal speed, or [code]0.5[/code] for half of the normal speed. A value of [code]0[/code] pauses the animation, but see also [method set_active] or [method stop_all] for this.
</member>
<member name="repeat" type="bool" setter="set_repeat" getter="is_repeat">
- If [code]true[/code] the tween loops.
+ If [code]true[/code], the tween loops.
</member>
</members>
<signals>
diff --git a/doc/classes/VideoPlayer.xml b/doc/classes/VideoPlayer.xml
index 9ffa3aa52b..c4c129b0f6 100644
--- a/doc/classes/VideoPlayer.xml
+++ b/doc/classes/VideoPlayer.xml
@@ -52,7 +52,7 @@
The embedded audio track to play.
</member>
<member name="autoplay" type="bool" setter="set_autoplay" getter="has_autoplay">
- If [code]true[/code] playback starts when the scene loads. Default value: [code]false[/code].
+ If [code]true[/code], playback starts when the scene loads. Default value: [code]false[/code].
</member>
<member name="buffering_msec" type="int" setter="set_buffering_msec" getter="get_buffering_msec">
Amount of time in milliseconds to store in buffer while playing.
@@ -61,10 +61,10 @@
Audio bus to use for sound playback.
</member>
<member name="expand" type="bool" setter="set_expand" getter="has_expand">
- If [code]true[/code] the video scales to the control size. Default value: [code]true[/code].
+ If [code]true[/code], the video scales to the control size. Default value: [code]true[/code].
</member>
<member name="paused" type="bool" setter="set_paused" getter="is_paused">
- If [code]true[/code] the video is paused.
+ If [code]true[/code], the video is paused.
</member>
<member name="stream" type="VideoStream" setter="set_stream" getter="get_stream">
</member>
diff --git a/doc/classes/Viewport.xml b/doc/classes/Viewport.xml
index 4706651c6e..880dc43c90 100644
--- a/doc/classes/Viewport.xml
+++ b/doc/classes/Viewport.xml
@@ -178,7 +178,7 @@
<argument index="0" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the size override affects stretch as well.
+ If [code]true[/code], the size override affects stretch as well.
</description>
</method>
<method name="unhandled_input">
@@ -208,13 +208,13 @@
</methods>
<members>
<member name="arvr" type="bool" setter="set_use_arvr" getter="use_arvr">
- If [code]true[/code] the viewport will be used in AR/VR process. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will be used in AR/VR process. Default value: [code]false[/code].
</member>
<member name="audio_listener_enable_2d" type="bool" setter="set_as_audio_listener_2d" getter="is_audio_listener_2d">
- If [code]true[/code] the viewport will process 2D audio streams. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will process 2D audio streams. Default value: [code]false[/code].
</member>
<member name="audio_listener_enable_3d" type="bool" setter="set_as_audio_listener" getter="is_audio_listener">
- If [code]true[/code] the viewport will process 3D audio streams. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will process 3D audio streams. Default value: [code]false[/code].
</member>
<member name="canvas_transform" type="Transform2D" setter="set_canvas_transform" getter="get_canvas_transform">
The canvas transform of the viewport, useful for changing the on-screen positions of all child [CanvasItem]s. This is relative to the global canvas transform of the viewport.
@@ -223,33 +223,33 @@
The overlay mode for test rendered geometry in debug purposes. Default value: [code]DEBUG_DRAW_DISABLED[/code].
</member>
<member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled">
- If [code]true[/code] the viewport will disable 3D rendering. For actual disabling use [code]usage[/code]. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will disable 3D rendering. For actual disabling use [code]usage[/code]. Default value: [code]false[/code].
</member>
<member name="global_canvas_transform" type="Transform2D" setter="set_global_canvas_transform" getter="get_global_canvas_transform">
The global canvas transform of the viewport. The canvas transform is relative to this.
</member>
<member name="gui_disable_input" type="bool" setter="set_disable_input" getter="is_input_disabled">
- If [code]true[/code] the viewport will not receive input event. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will not receive input event. Default value: [code]false[/code].
</member>
<member name="gui_snap_controls_to_pixels" type="bool" setter="set_snap_controls_to_pixels" getter="is_snap_controls_to_pixels_enabled">
- If [code]true[/code] the GUI controls on the viewport will lay pixel perfectly. Default value: [code]true[/code].
+ If [code]true[/code], the GUI controls on the viewport will lay pixel perfectly. Default value: [code]true[/code].
</member>
<member name="handle_input_locally" type="bool" setter="set_handle_input_locally" getter="is_handling_input_locally">
</member>
<member name="hdr" type="bool" setter="set_hdr" getter="get_hdr">
- If [code]true[/code] the viewport rendering will receive benefits from High Dynamic Range algorithm. Default value: [code]true[/code].
+ If [code]true[/code], the viewport rendering will receive benefits from High Dynamic Range algorithm. Default value: [code]true[/code].
</member>
<member name="keep_3d_linear" type="bool" setter="set_keep_3d_linear" getter="get_keep_3d_linear">
- If [code]true[/code] the result after 3D rendering will not have a linear to sRGB color conversion applied. This is important when the viewport is used as a render target where the result is used as a texture on a 3D object rendered in another viewport. It is also important if the viewport is used to create data that is not color based (noise, heightmaps, pickmaps, etc.). Do not enable this when the viewport is used as a texture on a 2D object or if the viewport is your final output.
+ If [code]true[/code], the result after 3D rendering will not have a linear to sRGB color conversion applied. This is important when the viewport is used as a render target where the result is used as a texture on a 3D object rendered in another viewport. It is also important if the viewport is used to create data that is not color based (noise, heightmaps, pickmaps, etc.). Do not enable this when the viewport is used as a texture on a 2D object or if the viewport is your final output.
</member>
<member name="msaa" type="int" setter="set_msaa" getter="get_msaa" enum="Viewport.MSAA">
The multisample anti-aliasing mode. Default value: [code]MSAA_DISABLED[/code].
</member>
<member name="own_world" type="bool" setter="set_use_own_world" getter="is_using_own_world">
- If [code]true[/code] the viewport will use [World] defined in [code]world[/code] property. Default value: [code]false[/code].
+ If [code]true[/code], the viewport will use [World] defined in [code]world[/code] property. Default value: [code]false[/code].
</member>
<member name="physics_object_picking" type="bool" setter="set_physics_object_picking" getter="get_physics_object_picking">
- If [code]true[/code] the objects rendered by viewport become subjects of mouse picking process. Default value: [code]false[/code].
+ If [code]true[/code], the objects rendered by viewport become subjects of mouse picking process. Default value: [code]false[/code].
</member>
<member name="render_target_clear_mode" type="int" setter="set_clear_mode" getter="get_clear_mode" enum="Viewport.ClearMode">
The clear mode when viewport used as a render target. Default value: [code]CLEAR_MODE_ALWAYS[/code].
@@ -258,7 +258,7 @@
The update mode when viewport used as a render target. Default value: [code]UPDATE_WHEN_VISIBLE[/code].
</member>
<member name="render_target_v_flip" type="bool" setter="set_vflip" getter="get_vflip">
- If [code]true[/code] the result of rendering will be flipped vertically. Default value: [code]false[/code].
+ If [code]true[/code], the result of rendering will be flipped vertically. Default value: [code]false[/code].
</member>
<member name="shadow_atlas_quad_0" type="int" setter="set_shadow_atlas_quadrant_subdiv" getter="get_shadow_atlas_quadrant_subdiv" enum="Viewport.ShadowAtlasQuadrantSubdiv">
The subdivision amount of first quadrant on shadow atlas. Default value: [code]SHADOW_ATLAS_QUADRANT_SUBDIV_4[/code].
@@ -279,7 +279,7 @@
The width and height of viewport.
</member>
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background">
- If [code]true[/code] the viewport should render its background as transparent. Default value: [code]false[/code].
+ If [code]true[/code], the viewport should render its background as transparent. Default value: [code]false[/code].
</member>
<member name="usage" type="int" setter="set_usage" getter="get_usage" enum="Viewport.Usage">
The rendering mode of viewport. Default value: [code]USAGE_3D[/code].
diff --git a/doc/classes/ViewportContainer.xml b/doc/classes/ViewportContainer.xml
index dde429440d..e022b8fa90 100644
--- a/doc/classes/ViewportContainer.xml
+++ b/doc/classes/ViewportContainer.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled">
- If [code]true[/code] the viewport will be scaled to the control's size. Default value:[code]false[/code].
+ If [code]true[/code], the viewport will be scaled to the control's size. Default value:[code]false[/code].
</member>
<member name="stretch_shrink" type="int" setter="set_stretch_shrink" getter="get_stretch_shrink">
</member>
diff --git a/doc/classes/VisibilityEnabler.xml b/doc/classes/VisibilityEnabler.xml
index 5f0a4ef0f4..fc6ceac5de 100644
--- a/doc/classes/VisibilityEnabler.xml
+++ b/doc/classes/VisibilityEnabler.xml
@@ -14,10 +14,10 @@
</methods>
<members>
<member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [RigidBody] nodes will be paused.
+ If [code]true[/code], [RigidBody] nodes will be paused.
</member>
<member name="pause_animations" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [AnimationPlayer] nodes will be paused.
+ If [code]true[/code], [AnimationPlayer] nodes will be paused.
</member>
</members>
<constants>
diff --git a/doc/classes/VisibilityEnabler2D.xml b/doc/classes/VisibilityEnabler2D.xml
index eab9bd1991..8d393fc138 100644
--- a/doc/classes/VisibilityEnabler2D.xml
+++ b/doc/classes/VisibilityEnabler2D.xml
@@ -14,22 +14,22 @@
</methods>
<members>
<member name="freeze_bodies" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [RigidBody2D] nodes will be paused.
+ If [code]true[/code], [RigidBody2D] nodes will be paused.
</member>
<member name="pause_animated_sprites" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [AnimatedSprite] nodes will be paused.
+ If [code]true[/code], [AnimatedSprite] nodes will be paused.
</member>
<member name="pause_animations" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [AnimationPlayer] nodes will be paused.
+ If [code]true[/code], [AnimationPlayer] nodes will be paused.
</member>
<member name="pause_particles" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] [Particles2D] nodes will be paused.
+ If [code]true[/code], [Particles2D] nodes will be paused.
</member>
<member name="physics_process_parent" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] the parent's [method Node._physics_process] will be stopped.
+ If [code]true[/code], the parent's [method Node._physics_process] will be stopped.
</member>
<member name="process_parent" type="bool" setter="set_enabler" getter="is_enabler_enabled">
- If [code]true[/code] the parent's [method Node._process] will be stopped.
+ If [code]true[/code], the parent's [method Node._process] will be stopped.
</member>
</members>
<constants>
diff --git a/doc/classes/VisibilityNotifier.xml b/doc/classes/VisibilityNotifier.xml
index 95da708420..16329d1d0d 100644
--- a/doc/classes/VisibilityNotifier.xml
+++ b/doc/classes/VisibilityNotifier.xml
@@ -15,7 +15,7 @@
<return type="bool">
</return>
<description>
- If [code]true[/code] the bounding box is on the screen.
+ If [code]true[/code], the bounding box is on the screen.
</description>
</method>
</methods>
diff --git a/doc/classes/VisibilityNotifier2D.xml b/doc/classes/VisibilityNotifier2D.xml
index aaaa9b63bb..c60591cce6 100644
--- a/doc/classes/VisibilityNotifier2D.xml
+++ b/doc/classes/VisibilityNotifier2D.xml
@@ -15,7 +15,7 @@
<return type="bool">
</return>
<description>
- If [code]true[/code] the bounding rectangle is on the screen.
+ If [code]true[/code], the bounding rectangle is on the screen.
</description>
</method>
</methods>
diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml
index d2bc56001c..62dfb73b2d 100644
--- a/doc/classes/VisualServer.xml
+++ b/doc/classes/VisualServer.xml
@@ -1188,6 +1188,16 @@
<description>
</description>
</method>
+ <method name="environment_set_sky_orientation">
+ <return type="void">
+ </return>
+ <argument index="0" name="env" type="RID">
+ </argument>
+ <argument index="1" name="orientation" type="Basis">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="environment_set_ssao">
<return type="void">
</return>
@@ -3103,7 +3113,7 @@
</return>
<argument index="0" name="scenario" type="RID">
</argument>
- <argument index="1" name="p_size" type="int">
+ <argument index="1" name="size" type="int">
</argument>
<argument index="2" name="subdiv" type="int">
</argument>
@@ -3494,7 +3504,7 @@
<argument index="0" name="shrink" type="bool">
</argument>
<description>
- If [code]true[/code] sets internal processes to shrink all image data to half the size.
+ If [code]true[/code], sets internal processes to shrink all image data to half the size.
</description>
</method>
<method name="texture_set_size_override">
@@ -3517,7 +3527,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- If [code]true[/code] the image will be stored in the texture's images array if overwritten.
+ If [code]true[/code], the image will be stored in the texture's images array if overwritten.
</description>
</method>
<method name="viewport_attach_camera">
@@ -3610,7 +3620,7 @@
<argument index="1" name="active" type="bool">
</argument>
<description>
- If [code]true[/code] sets the viewport active, else sets it inactive.
+ If [code]true[/code], sets the viewport active, else sets it inactive.
</description>
</method>
<method name="viewport_set_canvas_stacking">
@@ -3672,7 +3682,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- If [code]true[/code] a viewport's 3D rendering is disabled.
+ If [code]true[/code], a viewport's 3D rendering is disabled.
</description>
</method>
<method name="viewport_set_disable_environment">
@@ -3683,7 +3693,7 @@
<argument index="1" name="disabled" type="bool">
</argument>
<description>
- If [code]true[/code] rendering of a viewport's environment is disabled.
+ If [code]true[/code], rendering of a viewport's environment is disabled.
</description>
</method>
<method name="viewport_set_global_canvas_transform">
@@ -3705,7 +3715,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the viewport renders to hdr.
+ If [code]true[/code], the viewport renders to hdr.
</description>
</method>
<method name="viewport_set_hide_canvas">
@@ -3716,7 +3726,7 @@
<argument index="1" name="hidden" type="bool">
</argument>
<description>
- If [code]true[/code] the viewport's canvas is not rendered.
+ If [code]true[/code], the viewport's canvas is not rendered.
</description>
</method>
<method name="viewport_set_hide_scenario">
@@ -3808,7 +3818,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the viewport renders its background as transparent.
+ If [code]true[/code], the viewport renders its background as transparent.
</description>
</method>
<method name="viewport_set_update_mode">
@@ -3841,7 +3851,7 @@
<argument index="1" name="use_arvr" type="bool">
</argument>
<description>
- If [code]true[/code] the viewport uses augmented or virtual reality technologies. See [ARVRInterface].
+ If [code]true[/code], the viewport uses augmented or virtual reality technologies. See [ARVRInterface].
</description>
</method>
<method name="viewport_set_vflip">
@@ -3852,7 +3862,7 @@
<argument index="1" name="enabled" type="bool">
</argument>
<description>
- If [code]true[/code] the viewport's rendering is flipped vertically.
+ If [code]true[/code], the viewport's rendering is flipped vertically.
</description>
</method>
</methods>
diff --git a/doc/classes/WindowDialog.xml b/doc/classes/WindowDialog.xml
index f7f2d10fcd..51931444fc 100644
--- a/doc/classes/WindowDialog.xml
+++ b/doc/classes/WindowDialog.xml
@@ -21,7 +21,7 @@
</methods>
<members>
<member name="resizable" type="bool" setter="set_resizable" getter="get_resizable">
- If [code]true[/code] the user can resize the window. Default value: [code]false[/code].
+ If [code]true[/code], the user can resize the window. Default value: [code]false[/code].
</member>
<member name="window_title" type="String" setter="set_title" getter="get_title">
The text displayed in the window's title bar.
diff --git a/doc/classes/YSort.xml b/doc/classes/YSort.xml
index 45ae8645b1..e9233ff079 100644
--- a/doc/classes/YSort.xml
+++ b/doc/classes/YSort.xml
@@ -14,7 +14,7 @@
</methods>
<members>
<member name="sort_enabled" type="bool" setter="set_sort_enabled" getter="is_sort_enabled">
- If [code]true[/code] child nodes are sorted, otherwise sorting is disabled. Default: [code]true[/code].
+ If [code]true[/code], child nodes are sorted, otherwise sorting is disabled. Default: [code]true[/code].
</member>
</members>
<constants>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 9e83dfb55e..25edd49ba5 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -1,73 +1,107 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
-import codecs
import sys
import os
import re
import xml.etree.ElementTree as ET
+from collections import defaultdict
-input_list = []
-cur_file = ""
+# Uncomment to do type checks. I have it commented out so it works below Python 3.5
+#from typing import List, Dict, TextIO, Tuple, Iterable, Optional, DefaultDict
+
+input_list = [] # type: List[str]
+current_reading_class = ""
+class_names = [] # type: List[str]
+classes = {} # type: Dict[str, ET.Element]
# http(s)://docs.godotengine.org/<langcode>/<tag>/path/to/page.html(#fragment-tag)
-godot_docs_pattern = re.compile('^http(?:s)?:\/\/docs\.godotengine\.org\/(?:[a-zA-Z0-9\.\-_]*)\/(?:[a-zA-Z0-9\.\-_]*)\/(.*)\.html(#.*)?$')
+GODOT_DOCS_PATTERN = re.compile(r'^http(?:s)?://docs\.godotengine\.org/(?:[a-zA-Z0-9.\-_]*)/(?:[a-zA-Z0-9.\-_]*)/(.*)\.html(#.*)?$')
+
-for arg in sys.argv[1:]:
- if arg.endswith(os.sep):
- arg = arg[:-1]
- input_list.append(arg)
+def main(): # type: () -> None
+ global current_reading_class
+ for arg in sys.argv[1:]:
+ if arg.endswith(os.sep):
+ arg = arg[:-1]
+ input_list.append(arg)
-if len(input_list) < 1:
- print('usage: makerst.py <path to folders> and/or <path to .xml files> (order of arguments irrelevant)')
- print('example: makerst.py "../../modules/" "../classes" path_to/some_class.xml')
- sys.exit(0)
+ if len(input_list) < 1:
+ print('usage: makerst.py <path to folders> and/or <path to .xml files> (order of arguments irrelevant)')
+ print('example: makerst.py "../../modules/" "../classes" path_to/some_class.xml')
+ sys.exit(1)
+ file_list = [] # type: List[str]
-def validate_tag(elem, tag):
- if elem.tag != tag:
- print("Tag mismatch, expected '" + tag + "', got " + elem.tag)
- sys.exit(255)
+ for path in input_list:
+ if os.path.basename(path) == 'modules':
+ for subdir, dirs, _ in os.walk(path):
+ if 'doc_classes' in dirs:
+ doc_dir = os.path.join(subdir, 'doc_classes')
+ class_file_names = [f for f in os.listdir(doc_dir) if f.endswith('.xml')]
+ file_list += [os.path.join(doc_dir, f) for f in class_file_names]
+ elif os.path.isdir(path):
+ file_list += [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml')]
+
+ elif os.path.isfile(path):
+ if not path.endswith(".xml"):
+ print("Got non-.xml file '{}' in input, skipping.".format(path))
+ continue
-class_names = []
-classes = {}
+ file_list.append(path)
-def ul_string(str, ul):
- str += "\n"
- for i in range(len(str) - 1):
- str += ul
- str += "\n"
- return str
+ for cur_file in file_list:
+ try:
+ tree = ET.parse(cur_file)
+ except ET.ParseError as e:
+ print("Parse error reading file '{}': {}".format(cur_file, e))
+ sys.exit(1)
+ doc = tree.getroot()
+
+ if 'version' not in doc.attrib:
+ print("Version missing from 'doc'")
+ sys.exit(255)
+
+ name = doc.attrib["name"]
+ if name in classes:
+ continue
+ class_names.append(name)
+ classes[name] = doc
-def make_class_list(class_list, columns):
- f = codecs.open('class_list.rst', 'wb', 'utf-8')
- prev = 0
- col_max = len(class_list) / columns + 1
+ class_names.sort()
+
+ # Don't make class list for Sphinx, :toctree: handles it
+ # make_class_list(class_names, 2)
+
+ for c in class_names:
+ current_reading_class = c
+ make_rst_class(classes[c])
+
+
+def make_class_list(class_list, columns): # type: (List[str], int) -> None
+ # This function is no longer used.
+ f = open('class_list.rst', 'w', encoding='utf-8')
+ col_max = len(class_list) // columns + 1
print(('col max is ', col_max))
- col_count = 0
- row_count = 0
- last_initial = ''
- fit_columns = []
+ fit_columns = [] # type: List[List[str]]
- for n in range(0, columns):
- fit_columns += [[]]
+ for _ in range(0, columns):
+ fit_columns.append([])
- indexers = []
+ indexers = [] # type List[str]
last_initial = ''
- idx = 0
- for n in class_list:
- col = idx / col_max
+ for (idx, name) in enumerate(class_list):
+ col = idx // col_max
if col >= columns:
col = columns - 1
- fit_columns[col] += [n]
+ fit_columns[col].append(name)
idx += 1
- if n[:1] != last_initial:
- indexers += [n]
- last_initial = n[:1]
+ if name[:1] != last_initial:
+ indexers.append(name)
+ last_initial = name[:1]
row_max = 0
f.write("\n")
@@ -111,7 +145,7 @@ def make_class_list(class_list, columns):
f.close()
-def rstize_text(text, cclass):
+def rstize_text(text, cclass): # type: (str, str) -> str
# Linebreak + tabs in the XML should become two line breaks unless in a "codeblock"
pos = 0
while True:
@@ -209,7 +243,7 @@ def rstize_text(text, cclass):
escape_post = False
- if tag_text in class_names:
+ if tag_text in classes:
tag_text = make_type(tag_text)
escape_post = True
else: # command
@@ -228,17 +262,15 @@ def rstize_text(text, cclass):
elif inside_code:
tag_text = '[' + tag_text + ']'
elif cmd.find('html') == 0:
- cmd = tag_text[:space_pos]
param = tag_text[space_pos + 1:]
tag_text = param
elif cmd.find('method') == 0 or cmd.find('member') == 0 or cmd.find('signal') == 0:
- cmd = tag_text[:space_pos]
param = tag_text[space_pos + 1:]
if param.find('.') != -1:
ss = param.split('.')
if len(ss) > 2:
- sys.exit("Bad reference: '" + param + "' in file: " + cur_file)
+ sys.exit("Bad reference: '" + param + "' in class: " + current_reading_class)
(class_param, method_param) = ss
tag_text = ':ref:`' + class_param + '.' + method_param + '<class_' + class_param + '_' + method_param + '>`'
else:
@@ -309,15 +341,15 @@ def rstize_text(text, cclass):
return text
-def format_table(f, pp):
+def format_table(f, pp): # type: (TextIO, Iterable[Tuple[str, ...]]) -> None
longest_t = 0
longest_s = 0
for s in pp:
sl = len(s[0])
- if (sl > longest_s):
+ if sl > longest_s:
longest_s = sl
tl = len(s[1])
- if (tl > longest_t):
+ if tl > longest_t:
longest_t = tl
sep = "+"
@@ -330,25 +362,24 @@ def format_table(f, pp):
f.write(sep)
for s in pp:
rt = s[0]
- while (len(rt) < longest_s):
+ while len(rt) < longest_s:
rt += " "
st = s[1]
- while (len(st) < longest_t):
+ while len(st) < longest_t:
st += " "
f.write("| " + rt + " | " + st + " |\n")
f.write(sep)
f.write('\n')
-def make_type(t):
- global class_names
- if t in class_names:
+def make_type(t): # type: (str) -> str
+ if t in classes:
return ':ref:`' + t + '<class_' + t + '>`'
+ print("Warning: unresolved type reference '{}' in class '{}'".format(t, current_reading_class))
return t
-def make_enum(t):
- global class_names
+def make_enum(t): # type: (str) -> str
p = t.find(".")
# Global enums such as Error are relative to @GlobalScope.
if p >= 0:
@@ -368,39 +399,41 @@ def make_enum(t):
def make_method(
- f,
- cname,
- method_data,
- declare,
- event=False,
- pp=None
-):
- if (declare or pp is None):
+ f, # type: TextIO
+ cname, # type: str
+ method_data, # type: ET.Element
+ declare, # type: bool
+ event=False, # type: bool
+ pp=None # type: Optional[List[Tuple[str, str]]]
+): # type: (...) -> None
+ if declare or pp is None:
t = '- '
else:
t = ""
- ret_type = 'void'
+ argidx = [] # type: List[int]
args = list(method_data)
- mdata = {}
- mdata['argidx'] = []
- for a in args:
- if a.tag == 'return':
+ mdata = {} # type: Dict[int, ET.Element]
+ for arg in args:
+ if arg.tag == 'return':
idx = -1
- elif a.tag == 'argument':
- idx = int(a.attrib['index'])
+ elif arg.tag == 'argument':
+ idx = int(arg.attrib['index'])
else:
continue
- mdata['argidx'].append(idx)
- mdata[idx] = a
+ argidx.append(idx)
+ mdata[idx] = arg
if not event:
- if -1 in mdata['argidx']:
+ if -1 in argidx:
if 'enum' in mdata[-1].attrib:
t += make_enum(mdata[-1].attrib['enum'])
else:
- t += make_type(mdata[-1].attrib['type'])
+ if mdata[-1].attrib['type'] == 'void':
+ t += 'void'
+ else:
+ t += make_type(mdata[-1].attrib['type'])
else:
t += 'void'
t += ' '
@@ -412,8 +445,7 @@ def make_method(
s = ':ref:`' + method_data.attrib['name'] + '<class_' + cname + "_" + method_data.attrib['name'] + '>` '
s += '**(**'
- argfound = False
- for a in mdata['argidx']:
+ for a in argidx:
arg = mdata[a]
if a < 0:
continue
@@ -439,8 +471,8 @@ def make_method(
if 'qualifiers' in method_data.attrib:
s += ' ' + method_data.attrib['qualifiers']
- if (not declare):
- if (pp != None):
+ if not declare:
+ if pp is not None:
pp.append((t, s))
else:
f.write("- " + t + " " + s + "\n")
@@ -449,12 +481,12 @@ def make_method(
def make_properties(
- f,
- cname,
- prop_data,
- description=False,
- pp=None
-):
+ f, # type: TextIO
+ cname, # type: str
+ prop_data, # type: ET.Element
+ description=False, # type: bool
+ pp=None # type: Optional[List[Tuple[str, str]]]
+): # type: (...) -> None
t = ""
if 'enum' in prop_data.attrib:
t += make_enum(prop_data.attrib['enum'])
@@ -471,7 +503,7 @@ def make_properties(
else:
s = ':ref:`' + prop_data.attrib['name'] + '<class_' + cname + "_" + prop_data.attrib['name'] + '>`'
- if (pp != None):
+ if pp is not None:
pp.append((t, s))
elif description:
f.write('- ' + t + ' ' + s + '\n\n')
@@ -479,14 +511,14 @@ def make_properties(
format_table(f, setget)
-def make_heading(title, underline):
- return title + '\n' + underline * len(title) + "\n\n"
+def make_heading(title, underline): # type: (str, str) -> str
+ return title + '\n' + (underline * len(title)) + "\n\n"
-def make_rst_class(node):
+def make_rst_class(node): # type: (ET.Element) -> None
name = node.attrib['name']
- f = codecs.open("class_" + name.lower() + '.rst', 'wb', 'utf-8')
+ f = open("class_" + name.lower() + '.rst', 'w', encoding='utf-8')
# Warn contributors not to edit this file directly
f.write(".. Generated automatically by doc/tools/makerst.py in Godot's source tree.\n")
@@ -502,31 +534,31 @@ def make_rst_class(node):
inh = node.attrib['inherits'].strip()
f.write('**Inherits:** ')
first = True
- while (inh in classes):
- if (not first):
+ while inh in classes:
+ if not first:
f.write(" **<** ")
else:
first = False
f.write(make_type(inh))
inode = classes[inh]
- if ('inherits' in inode.attrib):
+ if 'inherits' in inode.attrib:
inh = inode.attrib['inherits'].strip()
else:
- inh = None
+ break
f.write("\n\n")
# Descendents
inherited = []
- for cn in classes:
+ for cn in class_names:
c = classes[cn]
if 'inherits' in c.attrib:
- if (c.attrib['inherits'].strip() == name):
+ if c.attrib['inherits'].strip() == name:
inherited.append(c.attrib['name'])
- if (len(inherited)):
+ if len(inherited):
f.write('**Inherited By:** ')
for i in range(len(inherited)):
- if (i > 0):
+ if i > 0:
f.write(", ")
f.write(make_type(inherited[i]))
f.write("\n\n")
@@ -538,46 +570,46 @@ def make_rst_class(node):
# Brief description
f.write(make_heading('Brief Description', '-'))
briefd = node.find('brief_description')
- if briefd != None:
+ if briefd is not None and briefd.text is not None:
f.write(rstize_text(briefd.text.strip(), name) + "\n\n")
# Properties overview
members = node.find('members')
- if members != None and len(list(members)) > 0:
+ if members is not None and len(list(members)) > 0:
f.write(make_heading('Properties', '-'))
- ml = []
- for m in list(members):
+ ml = [] # type: List[Tuple[str, str]]
+ for m in members:
make_properties(f, name, m, False, ml)
format_table(f, ml)
# Methods overview
methods = node.find('methods')
- if methods != None and len(list(methods)) > 0:
+ if methods is not None and len(list(methods)) > 0:
f.write(make_heading('Methods', '-'))
ml = []
- for m in list(methods):
+ for m in methods:
make_method(f, name, m, False, False, ml)
format_table(f, ml)
# Theme properties
theme_items = node.find('theme_items')
- if theme_items != None and len(list(theme_items)) > 0:
+ if theme_items is not None and len(list(theme_items)) > 0:
f.write(make_heading('Theme Properties', '-'))
ml = []
- for m in list(theme_items):
+ for m in theme_items:
make_properties(f, name, m, False, ml)
format_table(f, ml)
# Signals
events = node.find('signals')
- if events != None and len(list(events)) > 0:
+ if events is not None and len(list(events)) > 0:
f.write(make_heading('Signals', '-'))
- for m in list(events):
+ for m in events:
f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n")
make_method(f, name, m, True, True)
f.write('\n')
d = m.find('description')
- if d is None or d.text.strip() == '':
+ if d is None or d.text is None or d.text.strip() == '':
continue
f.write(rstize_text(d.text.strip(), name))
f.write("\n\n")
@@ -585,13 +617,15 @@ def make_rst_class(node):
# Constants and enums
constants = node.find('constants')
consts = []
- enum_names = set()
- enums = []
- if constants != None and len(list(constants)) > 0:
- for c in list(constants):
+ enum_names = []
+ enums = defaultdict(list) # type: DefaultDict[str, List[ET.Element]]
+ if constants is not None and len(list(constants)) > 0:
+ for c in constants:
if 'enum' in c.attrib:
- enum_names.add(c.attrib['enum'])
- enums.append(c)
+ ename = c.attrib['enum']
+ if ename not in enums:
+ enum_names.append(ename)
+ enums[ename].append(c)
else:
consts.append(c)
@@ -601,43 +635,42 @@ def make_rst_class(node):
for e in enum_names:
f.write(".. _enum_" + name + "_" + e + ":\n\n")
f.write("enum **" + e + "**:\n\n")
- for c in enums:
- if c.attrib['enum'] != e:
- continue
+ for c in enums[e]:
s = '- '
s += '**' + c.attrib['name'] + '**'
if 'value' in c.attrib:
s += ' = **' + c.attrib['value'] + '**'
- if c.text.strip() != '':
+ if c.text is not None and c.text.strip() != '':
s += ' --- ' + rstize_text(c.text.strip(), name)
f.write(s + '\n\n')
# Constants
if len(consts) > 0:
f.write(make_heading('Constants', '-'))
- for c in list(consts):
+ for c in consts:
s = '- '
s += '**' + c.attrib['name'] + '**'
if 'value' in c.attrib:
s += ' = **' + c.attrib['value'] + '**'
- if c.text.strip() != '':
+ if c.text is not None and c.text.strip() != '':
s += ' --- ' + rstize_text(c.text.strip(), name)
f.write(s + '\n\n')
# Class description
descr = node.find('description')
- if descr != None and descr.text.strip() != '':
+ if descr is not None and descr.text is not None and descr.text.strip() != '':
f.write(make_heading('Description', '-'))
f.write(rstize_text(descr.text.strip(), name) + "\n\n")
# Online tutorials
- global godot_docs_pattern
tutorials = node.find('tutorials')
- if tutorials != None and len(tutorials) > 0:
+ if tutorials is not None and len(tutorials) > 0:
f.write(make_heading('Tutorials', '-'))
for t in tutorials:
+ if t.text is None:
+ continue
link = t.text.strip()
- match = godot_docs_pattern.search(link);
+ match = GODOT_DOCS_PATTERN.search(link)
if match:
groups = match.groups()
if match.lastindex == 2:
@@ -658,63 +691,28 @@ def make_rst_class(node):
# Property descriptions
members = node.find('members')
- if members != None and len(list(members)) > 0:
+ if members is not None and len(list(members)) > 0:
f.write(make_heading('Property Descriptions', '-'))
- for m in list(members):
+ for m in members:
f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n")
make_properties(f, name, m, True)
- if m.text.strip() != '':
+ if m.text is not None and m.text.strip() != '':
f.write(rstize_text(m.text.strip(), name))
f.write('\n\n')
# Method descriptions
methods = node.find('methods')
- if methods != None and len(list(methods)) > 0:
+ if methods is not None and len(list(methods)) > 0:
f.write(make_heading('Method Descriptions', '-'))
- for m in list(methods):
+ for m in methods:
f.write(".. _class_" + name + "_" + m.attrib['name'] + ":\n\n")
make_method(f, name, m, True)
f.write('\n')
d = m.find('description')
- if d is None or d.text.strip() == '':
+ if d is None or d.text is None or d.text.strip() == '':
continue
f.write(rstize_text(d.text.strip(), name))
f.write("\n\n")
-
-file_list = []
-
-for path in input_list:
- if os.path.basename(path) == 'modules':
- for subdir, dirs, _ in os.walk(path):
- if 'doc_classes' in dirs:
- doc_dir = os.path.join(subdir, 'doc_classes')
- class_file_names = [f for f in os.listdir(doc_dir) if f.endswith('.xml')]
- file_list += [os.path.join(doc_dir, f) for f in class_file_names]
- elif not os.path.isfile(path):
- file_list += [os.path.join(path, f) for f in os.listdir(path) if f.endswith('.xml')]
- elif os.path.isfile(path) and path.endswith('.xml'):
- file_list.append(path)
-
-for cur_file in file_list:
- tree = ET.parse(cur_file)
- doc = tree.getroot()
-
- if 'version' not in doc.attrib:
- print("Version missing from 'doc'")
- sys.exit(255)
-
- version = doc.attrib['version']
- if doc.attrib['name'] in class_names:
- continue
- class_names.append(doc.attrib['name'])
- classes[doc.attrib['name']] = doc
-
-class_names.sort()
-
-# Don't make class list for Sphinx, :toctree: handles it
-# make_class_list(class_names, 2)
-
-for cn in class_names:
- c = classes[cn]
- make_rst_class(c)
+if __name__ == '__main__':
+ main()
diff --git a/drivers/gles2/rasterizer_canvas_gles2.cpp b/drivers/gles2/rasterizer_canvas_gles2.cpp
index e6be0f57fc..f3fc356879 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.cpp
+++ b/drivers/gles2/rasterizer_canvas_gles2.cpp
@@ -67,6 +67,12 @@ void RasterizerCanvasGLES2::_set_uniforms() {
state.canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
}
+
+ if (state.using_skeleton) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TRANSFORM, state.skeleton_transform);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TRANSFORM_INVERSE, state.skeleton_transform_inverse);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SKELETON_TEXTURE_SIZE, state.skeleton_texture_size);
+ }
}
void RasterizerCanvasGLES2::canvas_begin() {
@@ -140,6 +146,7 @@ void RasterizerCanvasGLES2::canvas_end() {
}
state.using_texture_rect = false;
+ state.using_skeleton = false;
state.using_ninepatch = false;
}
@@ -186,13 +193,46 @@ RasterizerStorageGLES2::Texture *RasterizerCanvasGLES2::_bind_canvas_texture(con
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
}
- return tex_return;
-}
+ if (p_normal_map == state.current_normal) {
+ //do none
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
+
+ } else if (p_normal_map.is_valid()) {
+
+ RasterizerStorageGLES2::Texture *normal_map = storage->texture_owner.getornull(p_normal_map);
+
+ if (!normal_map) {
+ state.current_normal = RID();
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
+
+ } else {
+
+ normal_map = normal_map->get_ptr();
+
+ if (normal_map->redraw_if_visible) { //check before proxy, because this is usually used with proxies
+ VisualServerRaster::redraw_request();
+ }
+
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
+ glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
+ state.current_normal = p_normal_map;
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, true);
+ }
+
+ } else {
-void RasterizerCanvasGLES2::_set_texture_rect_mode(bool p_enable, bool p_ninepatch) {
+ state.current_normal = RID();
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::USE_DEFAULT_NORMAL, false);
+ }
+
+ return tex_return;
}
-void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
+void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights, const int *p_bones) {
glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
@@ -226,6 +266,22 @@ void RasterizerCanvasGLES2::_draw_polygon(const int *p_indices, int p_index_coun
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
}
+ if (p_weights && p_bones) {
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(float) * 4 * p_vertex_count, p_weights);
+ glEnableVertexAttribArray(VS::ARRAY_WEIGHTS);
+ glVertexAttribPointer(VS::ARRAY_WEIGHTS, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 4, ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(float) * 4 * p_vertex_count;
+
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(int) * 4 * p_vertex_count, p_bones);
+ glEnableVertexAttribArray(VS::ARRAY_BONES);
+ glVertexAttribPointer(VS::ARRAY_BONES, 4, GL_UNSIGNED_INT, GL_FALSE, sizeof(int) * 4, ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(int) * 4 * p_vertex_count;
+
+ } else {
+ glDisableVertexAttribArray(VS::ARRAY_WEIGHTS);
+ glDisableVertexAttribArray(VS::ARRAY_BONES);
+ }
+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
@@ -334,6 +390,16 @@ void RasterizerCanvasGLES2::_draw_gui_primitive(int p_points, const Vector2 *p_v
glBindBuffer(GL_ARRAY_BUFFER, 0);
}
+static const GLenum gl_primitive[] = {
+ GL_POINTS,
+ GL_LINES,
+ GL_LINE_STRIP,
+ GL_LINE_LOOP,
+ GL_TRIANGLES,
+ GL_TRIANGLE_STRIP,
+ GL_TRIANGLE_FAN
+};
+
void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material) {
int command_count = p_item->commands.size();
@@ -758,9 +824,190 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size);
}
- _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
+ _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1, polygon->weights.ptr(), polygon->bones.ptr());
+ } break;
+ case Item::Command::TYPE_MESH: {
+
+ Item::CommandMesh *mesh = static_cast<Item::CommandMesh *>(command);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
+
+ if (state.canvas_shader.bind()) {
+ _set_uniforms();
+ state.canvas_shader.use_material((void *)p_material);
+ }
+
+ RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(mesh->texture, mesh->normal_map);
+
+ if (texture) {
+ Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ }
+
+ RasterizerStorageGLES2::Mesh *mesh_data = storage->mesh_owner.getornull(mesh->mesh);
+ if (mesh_data) {
+
+ for (int j = 0; j < mesh_data->surfaces.size(); j++) {
+ RasterizerStorageGLES2::Surface *s = mesh_data->surfaces[j];
+ // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
+
+ glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id);
+
+ if (s->index_array_len > 0) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
+ }
+
+ for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
+ if (s->attribs[i].enabled) {
+ glEnableVertexAttribArray(i);
+ glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, (uint8_t *)0 + s->attribs[i].offset);
+ } else {
+ glDisableVertexAttribArray(i);
+ switch (i) {
+ case VS::ARRAY_NORMAL: {
+ glVertexAttrib4f(VS::ARRAY_NORMAL, 0.0, 0.0, 1, 1);
+ } break;
+ case VS::ARRAY_COLOR: {
+ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
+
+ } break;
+ default: {}
+ }
+ }
+ }
+
+ if (s->index_array_len > 0) {
+ glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
+ } else {
+ glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
+ }
+ }
+
+ for (int i = 1; i < VS::ARRAY_MAX - 1; i++) {
+ glDisableVertexAttribArray(i);
+ }
+ }
+
} break;
+ case Item::Command::TYPE_MULTIMESH: {
+ Item::CommandMultiMesh *mmesh = static_cast<Item::CommandMultiMesh *>(command);
+ RasterizerStorageGLES2::MultiMesh *multi_mesh = storage->multimesh_owner.getornull(mmesh->multimesh);
+
+ if (!multi_mesh)
+ break;
+
+ RasterizerStorageGLES2::Mesh *mesh_data = storage->mesh_owner.getornull(multi_mesh->mesh);
+
+ if (!mesh_data)
+ break;
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_INSTANCE_CUSTOM, multi_mesh->custom_data_format != VS::MULTIMESH_CUSTOM_DATA_NONE);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_INSTANCING, true);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, false);
+
+ if (state.canvas_shader.bind()) {
+ _set_uniforms();
+ state.canvas_shader.use_material((void *)p_material);
+ }
+
+ RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(mmesh->texture, mmesh->normal_map);
+
+ if (texture) {
+ Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ }
+
+ //reset shader and force rebind
+
+ int amount = MIN(multi_mesh->size, multi_mesh->visible_instances);
+
+ if (amount == -1) {
+ amount = multi_mesh->size;
+ }
+
+ int stride = multi_mesh->color_floats + multi_mesh->custom_data_floats + multi_mesh->xform_floats;
+
+ int color_ofs = multi_mesh->xform_floats;
+ int custom_data_ofs = color_ofs + multi_mesh->color_floats;
+
+ // drawing
+
+ const float *base_buffer = multi_mesh->data.ptr();
+
+ for (int j = 0; j < mesh_data->surfaces.size(); j++) {
+ RasterizerStorageGLES2::Surface *s = mesh_data->surfaces[j];
+ // materials are ignored in 2D meshes, could be added but many things (ie, lighting mode, reading from screen, etc) would break as they are not meant be set up at this point of drawing
+
+ //bind buffers for mesh surface
+ glBindBuffer(GL_ARRAY_BUFFER, s->vertex_id);
+
+ if (s->index_array_len > 0) {
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
+ }
+
+ for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
+ if (s->attribs[i].enabled) {
+ glEnableVertexAttribArray(i);
+ glVertexAttribPointer(s->attribs[i].index, s->attribs[i].size, s->attribs[i].type, s->attribs[i].normalized, s->attribs[i].stride, (uint8_t *)0 + s->attribs[i].offset);
+ } else {
+ glDisableVertexAttribArray(i);
+ switch (i) {
+ case VS::ARRAY_NORMAL: {
+ glVertexAttrib4f(VS::ARRAY_NORMAL, 0.0, 0.0, 1, 1);
+ } break;
+ case VS::ARRAY_COLOR: {
+ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
+
+ } break;
+ default: {}
+ }
+ }
+ }
+
+ for (int i = 0; i < amount; i++) {
+ const float *buffer = base_buffer + i * stride;
+
+ {
+
+ glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 0, &buffer[0]);
+ glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 1, &buffer[4]);
+ if (multi_mesh->transform_format == VS::MULTIMESH_TRANSFORM_3D) {
+ glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 2, &buffer[8]);
+ } else {
+ glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 2, 0.0, 0.0, 1.0, 0.0);
+ }
+ }
+
+ if (multi_mesh->color_floats) {
+ if (multi_mesh->color_format == VS::MULTIMESH_COLOR_8BIT) {
+ uint8_t *color_data = (uint8_t *)(buffer + color_ofs);
+ glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 3, color_data[0] / 255.0, color_data[1] / 255.0, color_data[2] / 255.0, color_data[3] / 255.0);
+ } else {
+ glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 3, buffer + color_ofs);
+ }
+ }
+
+ if (multi_mesh->custom_data_floats) {
+ if (multi_mesh->custom_data_format == VS::MULTIMESH_CUSTOM_DATA_8BIT) {
+ uint8_t *custom_data = (uint8_t *)(buffer + custom_data_ofs);
+ glVertexAttrib4f(INSTANCE_ATTRIB_BASE + 4, custom_data[0] / 255.0, custom_data[1] / 255.0, custom_data[2] / 255.0, custom_data[3] / 255.0);
+ } else {
+ glVertexAttrib4fv(INSTANCE_ATTRIB_BASE + 4, buffer + custom_data_ofs);
+ }
+ }
+
+ if (s->index_array_len > 0) {
+ glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
+ } else {
+ glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
+ }
+ }
+ }
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_INSTANCE_CUSTOM, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_INSTANCING, false);
+
+ } break;
case Item::Command::TYPE_POLYLINE: {
Item::CommandPolyLine *pline = static_cast<Item::CommandPolyLine *>(command);
@@ -880,6 +1127,8 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
RasterizerStorageGLES2::Shader *shader_cache = NULL;
bool rebind_shader = true;
+ bool prev_use_skeleton = false;
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SKELETON, false);
state.current_tex = RID();
state.current_tex_ptr = NULL;
@@ -921,6 +1170,37 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
}
+ RasterizerStorageGLES2::Skeleton *skeleton = NULL;
+
+ {
+ //skeleton handling
+ if (ci->skeleton.is_valid() && storage->skeleton_owner.owns(ci->skeleton)) {
+ skeleton = storage->skeleton_owner.get(ci->skeleton);
+ if (!skeleton->use_2d) {
+ skeleton = NULL;
+ } else {
+ state.skeleton_transform = p_base_transform * skeleton->base_transform_2d;
+ state.skeleton_transform_inverse = state.skeleton_transform.affine_inverse();
+ state.skeleton_texture_size = Vector2(skeleton->size * 2, 0);
+ }
+ }
+
+ bool use_skeleton = skeleton != NULL;
+ if (prev_use_skeleton != use_skeleton) {
+ rebind_shader = true;
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SKELETON, use_skeleton);
+ prev_use_skeleton = use_skeleton;
+ }
+
+ if (skeleton) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
+ glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
+ state.using_skeleton = true;
+ } else {
+ state.using_skeleton = false;
+ }
+ }
+
Item *material_owner = ci->material_owner ? ci->material_owner : ci;
RID material = material_owner->material;
@@ -1008,7 +1288,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
}
int blend_mode = shader_cache ? shader_cache->canvas_item.blend_mode : RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX;
- bool unshaded = (shader_cache && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX);
+ bool unshaded = shader_cache && (shader_cache->canvas_item.light_mode == RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_UNSHADED || (blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX && blend_mode != RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA));
bool reclip = false;
if (last_blend_mode != blend_mode) {
@@ -1053,10 +1333,164 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
_set_uniforms();
- _canvas_item_render_commands(p_item_list, NULL, reclip, material_ptr);
+ if (unshaded || (state.uniforms.final_modulate.a > 0.001 && (!shader_cache || shader_cache->canvas_item.light_mode != RasterizerStorageGLES2::Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY) && !ci->light_masked))
+ _canvas_item_render_commands(p_item_list, NULL, reclip, material_ptr);
rebind_shader = true; // hacked in for now.
+ if ((blend_mode == RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_MIX || blend_mode == RasterizerStorageGLES2::Shader::CanvasItem::BLEND_MODE_PMALPHA) && p_light && !unshaded) {
+
+ Light *light = p_light;
+ bool light_used = false;
+ VS::CanvasLightMode mode = VS::CANVAS_LIGHT_MODE_ADD;
+ state.uniforms.final_modulate = ci->final_modulate; // remove the canvas modulate
+
+ while (light) {
+
+ if (ci->light_mask & light->item_mask && p_z >= light->z_min && p_z <= light->z_max && ci->global_rect_cache.intersects_transformed(light->xform_cache, light->rect_cache)) {
+
+ //intersects this light
+
+ if (!light_used || mode != light->mode) {
+
+ mode = light->mode;
+
+ switch (mode) {
+
+ case VS::CANVAS_LIGHT_MODE_ADD: {
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+ } break;
+ case VS::CANVAS_LIGHT_MODE_SUB: {
+ glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+ } break;
+ case VS::CANVAS_LIGHT_MODE_MIX:
+ case VS::CANVAS_LIGHT_MODE_MASK: {
+ glBlendEquation(GL_FUNC_ADD);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ } break;
+ }
+ }
+
+ if (!light_used) {
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, true);
+ light_used = true;
+ }
+
+ bool has_shadow = light->shadow_buffer.is_valid() && ci->light_mask & light->item_shadow_mask;
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, has_shadow);
+ if (has_shadow) {
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_USE_GRADIENT, light->shadow_gradient_length > 0);
+ switch (light->shadow_filter) {
+
+ case VS::CANVAS_LIGHT_FILTER_NONE: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_NEAREST, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF3: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF3, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF5: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF5, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF7: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF7, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF9: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF9, true); break;
+ case VS::CANVAS_LIGHT_FILTER_PCF13: state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF13, true); break;
+ }
+ }
+
+ bool light_rebind = state.canvas_shader.bind();
+
+ if (light_rebind) {
+
+ _set_uniforms();
+ }
+
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX, light->light_shader_xform);
+ Transform2D basis_inverse = light->light_shader_xform.affine_inverse().orthonormalized();
+ basis_inverse[2] = Vector2();
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_MATRIX_INVERSE, basis_inverse);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_LOCAL_MATRIX, light->xform_cache.affine_inverse());
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_COLOR, light->color * light->energy);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_POS, light->light_shader_pos);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_HEIGHT, light->height);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_OUTSIDE_ALPHA, light->mode == VS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0);
+
+ if (has_shadow) {
+ RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(light->shadow_buffer);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
+ glBindTexture(GL_TEXTURE_2D, cls->distance);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX, light->shadow_matrix_cache);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR, light->shadow_color);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOWPIXEL_SIZE, (1.0 / light->shadow_buffer_size) * (1.0 + light->shadow_smooth));
+ if (light->radius_cache == 0) {
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_GRADIENT, 0.0);
+ } else {
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_GRADIENT, light->shadow_gradient_length / (light->radius_cache * 1.1));
+ }
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_DISTANCE_MULT, light->radius_cache * 1.1);
+
+ /*canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_MATRIX,light->shadow_matrix_cache);
+ canvas_shader.set_uniform(CanvasShaderGLES2::SHADOW_ESM_MULTIPLIER,light->shadow_esm_mult);
+ canvas_shader.set_uniform(CanvasShaderGLES2::LIGHT_SHADOW_COLOR,light->shadow_color);*/
+ }
+
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
+ RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(light->texture);
+ if (!t) {
+ glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
+ } else {
+ t = t->get_ptr();
+
+ glBindTexture(t->target, t->tex_id);
+ }
+
+ glActiveTexture(GL_TEXTURE0);
+ _canvas_item_render_commands(p_item_list, NULL, reclip, material_ptr); //redraw using light
+ }
+
+ light = light->next_ptr;
+ }
+
+ if (light_used) {
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_LIGHTING, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SHADOWS, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_NEAREST, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF3, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF5, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF7, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF9, false);
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::SHADOW_FILTER_PCF13, false);
+
+ state.canvas_shader.bind();
+
+ last_blend_mode = -1;
+
+ /*
+ //this is set again, so it should not be needed anyway?
+ state.canvas_item_modulate = unshaded ? ci->final_modulate : Color(
+ ci->final_modulate.r * p_modulate.r,
+ ci->final_modulate.g * p_modulate.g,
+ ci->final_modulate.b * p_modulate.b,
+ ci->final_modulate.a * p_modulate.a );
+
+
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::MODELVIEW_MATRIX,state.final_transform);
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::EXTRA_MATRIX,Transform2D());
+ state.canvas_shader.set_uniform(CanvasShaderGLES2::FINAL_MODULATE,state.canvas_item_modulate);
+
+ glBlendEquation(GL_FUNC_ADD);
+
+ if (storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ } else {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+
+ //@TODO RESET canvas_blend_mode
+ */
+ }
+ }
+
if (reclip) {
glEnable(GL_SCISSOR_TEST);
int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
@@ -1071,14 +1505,129 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
if (current_clip) {
glDisable(GL_SCISSOR_TEST);
}
+
+ state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_SKELETON, false);
}
void RasterizerCanvasGLES2::canvas_debug_viewport_shadows(Light *p_lights_with_shadow) {
}
void RasterizerCanvasGLES2::canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {
-}
+ RasterizerStorageGLES2::CanvasLightShadow *cls = storage->canvas_light_shadow_owner.get(p_buffer);
+ ERR_FAIL_COND(!cls);
+
+ glDisable(GL_BLEND);
+ glDisable(GL_SCISSOR_TEST);
+ glDisable(GL_DITHER);
+ glDisable(GL_CULL_FACE);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ glDepthMask(true);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
+
+ state.canvas_shadow_shader.set_conditional(CanvasShadowShaderGLES2::USE_RGBA_SHADOWS, storage->config.use_rgba_2d_shadows);
+ state.canvas_shadow_shader.bind();
+
+ glViewport(0, 0, cls->size, cls->height);
+ glClearDepth(1.0f);
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ VS::CanvasOccluderPolygonCullMode cull = VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED;
+
+ for (int i = 0; i < 4; i++) {
+
+ //make sure it remains orthogonal, makes easy to read angle later
+
+ Transform light;
+ light.origin[0] = p_light_xform[2][0];
+ light.origin[1] = p_light_xform[2][1];
+ light.basis[0][0] = p_light_xform[0][0];
+ light.basis[0][1] = p_light_xform[1][0];
+ light.basis[1][0] = p_light_xform[0][1];
+ light.basis[1][1] = p_light_xform[1][1];
+
+ //light.basis.scale(Vector3(to_light.elements[0].length(),to_light.elements[1].length(),1));
+
+ //p_near=1;
+ CameraMatrix projection;
+ {
+ real_t fov = 90;
+ real_t nearp = p_near;
+ real_t farp = p_far;
+ real_t aspect = 1.0;
+
+ real_t ymax = nearp * Math::tan(Math::deg2rad(fov * 0.5));
+ real_t ymin = -ymax;
+ real_t xmin = ymin * aspect;
+ real_t xmax = ymax * aspect;
+
+ projection.set_frustum(xmin, xmax, ymin, ymax, nearp, farp);
+ }
+
+ Vector3 cam_target = Basis(Vector3(0, 0, Math_PI * 2 * (i / 4.0))).xform(Vector3(0, 1, 0));
+ projection = projection * CameraMatrix(Transform().looking_at(cam_target, Vector3(0, 0, -1)).affine_inverse());
+
+ state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::PROJECTION_MATRIX, projection);
+ state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::LIGHT_MATRIX, light);
+ state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::DISTANCE_NORM, 1.0 / p_far);
+
+ if (i == 0)
+ *p_xform_cache = projection;
+
+ glViewport(0, (cls->height / 4) * i, cls->size, cls->height / 4);
+
+ LightOccluderInstance *instance = p_occluders;
+
+ while (instance) {
+
+ RasterizerStorageGLES2::CanvasOccluder *cc = storage->canvas_occluder_owner.get(instance->polygon_buffer);
+ if (!cc || cc->len == 0 || !(p_light_mask & instance->light_mask)) {
+
+ instance = instance->next;
+ continue;
+ }
+
+ state.canvas_shadow_shader.set_uniform(CanvasShadowShaderGLES2::WORLD_MATRIX, instance->xform_cache);
+ if (cull != instance->cull_cache) {
+
+ cull = instance->cull_cache;
+ switch (cull) {
+ case VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED: {
+
+ glDisable(GL_CULL_FACE);
+
+ } break;
+ case VS::CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE: {
+
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT);
+ } break;
+ case VS::CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE: {
+
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_BACK);
+
+ } break;
+ }
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id);
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id);
+
+ glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0);
+
+ instance = instance->next;
+ }
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+}
void RasterizerCanvasGLES2::reset_canvas() {
glDisable(GL_CULL_FACE);
@@ -1094,7 +1643,7 @@ void RasterizerCanvasGLES2::reset_canvas() {
}
// bind the back buffer to a texture so shaders can use it.
- // It should probably use texture unit -3 (as GLES3 does as well) but currently that's buggy.
+ // It should probably use texture unit -3 (as GLES2 does as well) but currently that's buggy.
// keeping this for now as there's nothing else that uses texture unit 2
// TODO ^
if (storage->frame.current_rt) {
@@ -1264,6 +1813,8 @@ void RasterizerCanvasGLES2::initialize() {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
+ state.canvas_shadow_shader.init();
+
state.canvas_shader.init();
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_TEXTURE_RECT, true);
diff --git a/drivers/gles2/rasterizer_canvas_gles2.h b/drivers/gles2/rasterizer_canvas_gles2.h
index cf1c239b6e..b6c11491ff 100644
--- a/drivers/gles2/rasterizer_canvas_gles2.h
+++ b/drivers/gles2/rasterizer_canvas_gles2.h
@@ -36,12 +36,16 @@
#include "shaders/canvas.glsl.gen.h"
#include "shaders/lens_distorted.glsl.gen.h"
-// #include "shaders/canvas_shadow.glsl.gen.h"
+#include "shaders/canvas_shadow.glsl.gen.h"
class RasterizerSceneGLES2;
class RasterizerCanvasGLES2 : public RasterizerCanvas {
public:
+ enum {
+ INSTANCE_ATTRIB_BASE = 8,
+ };
+
struct Uniforms {
Transform projection_matrix;
@@ -70,11 +74,16 @@ public:
Uniforms uniforms;
bool canvas_texscreen_used;
CanvasShaderGLES2 canvas_shader;
- // CanvasShadowShaderGLES3 canvas_shadow_shader;
+ CanvasShadowShaderGLES2 canvas_shadow_shader;
LensDistortedShaderGLES2 lens_shader;
bool using_texture_rect;
bool using_ninepatch;
+ bool using_skeleton;
+
+ Transform2D skeleton_transform;
+ Transform2D skeleton_transform_inverse;
+ Vector2i skeleton_texture_size;
RID current_tex;
RID current_normal;
@@ -99,10 +108,8 @@ public:
virtual void canvas_begin();
virtual void canvas_end();
- _FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable, bool p_ninepatch = false);
-
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
- _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
+ _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor, const float *p_weights = NULL, const int *p_bones = NULL);
_FORCE_INLINE_ void _draw_generic(GLuint p_primitive, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip, RasterizerStorageGLES2::Material *p_material);
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index e68d0f1cc5..30d515cec5 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -56,6 +56,8 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
#define _DEPTH_COMPONENT24_OES 0x81A6
+#define _RED_OES 0x1903
+
void RasterizerStorageGLES2::bind_quad_array() const {
glBindBuffer(GL_ARRAY_BUFFER, resources.quadie);
glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 4, 0);
@@ -1138,6 +1140,7 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
case VS::SHADER_CANVAS_ITEM: {
+ p_shader->canvas_item.light_mode = Shader::CanvasItem::LIGHT_MODE_NORMAL;
p_shader->canvas_item.blend_mode = Shader::CanvasItem::BLEND_MODE_MIX;
p_shader->canvas_item.uses_screen_texture = false;
@@ -1150,8 +1153,8 @@ void RasterizerStorageGLES2::_update_shader(Shader *p_shader) const {
shaders.actions_canvas.render_mode_values["blend_mul"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_MUL);
shaders.actions_canvas.render_mode_values["blend_premul_alpha"] = Pair<int *, int>(&p_shader->canvas_item.blend_mode, Shader::CanvasItem::BLEND_MODE_PMALPHA);
- // shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
- // shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
+ shaders.actions_canvas.render_mode_values["unshaded"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_UNSHADED);
+ shaders.actions_canvas.render_mode_values["light_only"] = Pair<int *, int>(&p_shader->canvas_item.light_mode, Shader::CanvasItem::LIGHT_MODE_LIGHT_ONLY);
shaders.actions_canvas.usage_flag_pointers["SCREEN_UV"] = &p_shader->canvas_item.uses_screen_uv;
shaders.actions_canvas.usage_flag_pointers["SCREEN_PIXEL_SIZE"] = &p_shader->canvas_item.uses_screen_uv;
@@ -2938,9 +2941,9 @@ void RasterizerStorageGLES2::skeleton_allocate(RID p_skeleton, int p_bones, bool
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
#ifdef GLES_OVER_GL
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_bones * 3, 1, 0, GL_RGBA, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, p_bones * (skeleton->use_2d ? 2 : 3), 1, 0, GL_RGBA, GL_FLOAT, NULL);
#else
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_bones * 3, 1, 0, GL_RGBA, GL_FLOAT, NULL);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, p_bones * (skeleton->use_2d ? 2 : 3), 1, 0, GL_RGBA, GL_FLOAT, NULL);
#endif
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@@ -3074,6 +3077,11 @@ Transform2D RasterizerStorageGLES2::skeleton_bone_get_transform_2d(RID p_skeleto
}
void RasterizerStorageGLES2::skeleton_set_base_transform_2d(RID p_skeleton, const Transform2D &p_base_transform) {
+
+ Skeleton *skeleton = skeleton_owner.getornull(p_skeleton);
+ ERR_FAIL_COND(!skeleton);
+
+ skeleton->base_transform_2d = p_base_transform;
}
void RasterizerStorageGLES2::_update_skeleton_transform_buffer(const PoolVector<float> &p_data, size_t p_size) {
@@ -3106,7 +3114,7 @@ void RasterizerStorageGLES2::update_dirty_skeletons() {
if (skeleton->size) {
glBindTexture(GL_TEXTURE_2D, skeleton->tex_id);
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, skeleton->size * 3, 1, GL_RGBA, GL_FLOAT, skeleton->bone_data.ptr());
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, skeleton->size * (skeleton->use_2d ? 2 : 3), 1, GL_RGBA, GL_FLOAT, skeleton->bone_data.ptr());
}
for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) {
@@ -4096,6 +4104,7 @@ RID RasterizerStorageGLES2::render_target_create() {
Texture *t = memnew(Texture);
+ t->type = VS::TEXTURE_TYPE_2D;
t->flags = 0;
t->width = 0;
t->height = 0;
@@ -4193,16 +4202,158 @@ void RasterizerStorageGLES2::render_target_set_msaa(RID p_render_target, VS::Vie
/* CANVAS SHADOW */
RID RasterizerStorageGLES2::canvas_light_shadow_buffer_create(int p_width) {
- return RID();
+
+ CanvasLightShadow *cls = memnew(CanvasLightShadow);
+ if (p_width > config.max_texture_size)
+ p_width = config.max_texture_size;
+
+ cls->size = p_width;
+ cls->height = 16;
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenFramebuffers(1, &cls->fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
+
+ glGenRenderbuffers(1, &cls->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, cls->depth);
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, cls->size, cls->height);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, cls->depth);
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
+
+ glGenTextures(1, &cls->distance);
+ glBindTexture(GL_TEXTURE_2D, cls->distance);
+ if (config.use_rgba_2d_shadows) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, cls->size, cls->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ } else {
+#ifdef GLES_OVER_GL
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, cls->size, cls->height, 0, _RED_OES, GL_FLOAT, NULL);
+#else
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_FLOAT, cls->size, cls->height, 0, _RED_OES, GL_FLOAT, NULL);
+#endif
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, cls->distance, 0);
+
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ //printf("errnum: %x\n",status);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES2::system_fbo);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ memdelete(cls);
+ ERR_FAIL_COND_V(status != GL_FRAMEBUFFER_COMPLETE, RID());
+ }
+
+ return canvas_light_shadow_owner.make_rid(cls);
}
/* LIGHT SHADOW MAPPING */
RID RasterizerStorageGLES2::canvas_light_occluder_create() {
- return RID();
+
+ CanvasOccluder *co = memnew(CanvasOccluder);
+ co->index_id = 0;
+ co->vertex_id = 0;
+ co->len = 0;
+
+ return canvas_occluder_owner.make_rid(co);
}
void RasterizerStorageGLES2::canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines) {
+
+ CanvasOccluder *co = canvas_occluder_owner.get(p_occluder);
+ ERR_FAIL_COND(!co);
+
+ co->lines = p_lines;
+
+ if (p_lines.size() != co->len) {
+
+ if (co->index_id)
+ glDeleteBuffers(1, &co->index_id);
+ if (co->vertex_id)
+ glDeleteBuffers(1, &co->vertex_id);
+
+ co->index_id = 0;
+ co->vertex_id = 0;
+ co->len = 0;
+ }
+
+ if (p_lines.size()) {
+
+ PoolVector<float> geometry;
+ PoolVector<uint16_t> indices;
+ int lc = p_lines.size();
+
+ geometry.resize(lc * 6);
+ indices.resize(lc * 3);
+
+ PoolVector<float>::Write vw = geometry.write();
+ PoolVector<uint16_t>::Write iw = indices.write();
+
+ PoolVector<Vector2>::Read lr = p_lines.read();
+
+ const int POLY_HEIGHT = 16384;
+
+ for (int i = 0; i < lc / 2; i++) {
+
+ vw[i * 12 + 0] = lr[i * 2 + 0].x;
+ vw[i * 12 + 1] = lr[i * 2 + 0].y;
+ vw[i * 12 + 2] = POLY_HEIGHT;
+
+ vw[i * 12 + 3] = lr[i * 2 + 1].x;
+ vw[i * 12 + 4] = lr[i * 2 + 1].y;
+ vw[i * 12 + 5] = POLY_HEIGHT;
+
+ vw[i * 12 + 6] = lr[i * 2 + 1].x;
+ vw[i * 12 + 7] = lr[i * 2 + 1].y;
+ vw[i * 12 + 8] = -POLY_HEIGHT;
+
+ vw[i * 12 + 9] = lr[i * 2 + 0].x;
+ vw[i * 12 + 10] = lr[i * 2 + 0].y;
+ vw[i * 12 + 11] = -POLY_HEIGHT;
+
+ iw[i * 6 + 0] = i * 4 + 0;
+ iw[i * 6 + 1] = i * 4 + 1;
+ iw[i * 6 + 2] = i * 4 + 2;
+
+ iw[i * 6 + 3] = i * 4 + 2;
+ iw[i * 6 + 4] = i * 4 + 3;
+ iw[i * 6 + 5] = i * 4 + 0;
+ }
+
+ //if same buffer len is being set, just use BufferSubData to avoid a pipeline flush
+
+ if (!co->vertex_id) {
+ glGenBuffers(1, &co->vertex_id);
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
+ } else {
+
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, lc * 6 * sizeof(real_t), vw.ptr());
+ }
+
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+
+ if (!co->index_id) {
+
+ glGenBuffers(1, &co->index_id);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
+ } else {
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, lc * 3 * sizeof(uint16_t), iw.ptr());
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
+
+ co->len = lc;
+ }
}
VS::InstanceType RasterizerStorageGLES2::get_base_type(RID p_rid) const {
@@ -4415,6 +4566,30 @@ bool RasterizerStorageGLES2::free(RID p_rid) {
lightmap_capture_data_owner.free(p_rid);
memdelete(lightmap_capture);
return true;
+
+ } else if (canvas_occluder_owner.owns(p_rid)) {
+
+ CanvasOccluder *co = canvas_occluder_owner.get(p_rid);
+ if (co->index_id)
+ glDeleteBuffers(1, &co->index_id);
+ if (co->vertex_id)
+ glDeleteBuffers(1, &co->vertex_id);
+
+ canvas_occluder_owner.free(p_rid);
+ memdelete(co);
+
+ return true;
+
+ } else if (canvas_light_shadow_owner.owns(p_rid)) {
+
+ CanvasLightShadow *cls = canvas_light_shadow_owner.get(p_rid);
+ glDeleteFramebuffers(1, &cls->fbo);
+ glDeleteRenderbuffers(1, &cls->depth);
+ glDeleteTextures(1, &cls->distance);
+ canvas_light_shadow_owner.free(p_rid);
+ memdelete(cls);
+
+ return true;
} else {
return false;
}
@@ -4468,10 +4643,20 @@ void RasterizerStorageGLES2::initialize() {
config.keep_original_textures = false;
config.shrink_textures_x2 = false;
+#ifdef GLES_OVER_GL
+ config.float_texture_supported = true;
+ config.s3tc_supported = true;
+ config.etc1_supported = false;
+#else
config.float_texture_supported = config.extensions.has("GL_ARB_texture_float") || config.extensions.has("GL_OES_texture_float");
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_s3tc");
config.etc1_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture");
-
+#endif
+#ifdef GLES_OVER_GL
+ config.use_rgba_2d_shadows = false;
+#else
+ config.use_rgba_2d_shadows = !(config.float_texture_supported && config.extensions.has("GL_EXT_texture_rg"));
+#endif
frame.count = 0;
frame.delta = 0;
frame.current_rt = NULL;
diff --git a/drivers/gles2/rasterizer_storage_gles2.h b/drivers/gles2/rasterizer_storage_gles2.h
index ec7616b9f3..b7c175e186 100644
--- a/drivers/gles2/rasterizer_storage_gles2.h
+++ b/drivers/gles2/rasterizer_storage_gles2.h
@@ -76,6 +76,8 @@ public:
bool keep_original_textures;
bool force_vertex_shading;
+
+ bool use_rgba_2d_shadows;
} config;
struct Resources {
@@ -86,6 +88,7 @@ public:
GLuint aniso_tex;
GLuint radical_inverse_vdc_cache_tex;
+ bool use_rgba_2d_shadows;
GLuint quadie;
@@ -261,6 +264,7 @@ public:
alloc_width(0),
alloc_height(0),
format(Image::FORMAT_L8),
+ type(VS::TEXTURE_TYPE_2D),
target(0),
data_size(0),
total_data_size(0),
@@ -400,7 +404,6 @@ public:
int blend_mode;
- /*
enum LightMode {
LIGHT_MODE_NORMAL,
LIGHT_MODE_UNSHADED,
@@ -408,7 +411,6 @@ public:
};
int light_mode;
- */
bool uses_screen_texture;
bool uses_screen_uv;
@@ -837,6 +839,8 @@ public:
SelfList<Skeleton> update_list;
Set<RasterizerScene::InstanceBase *> instances;
+ Transform2D base_transform_2d;
+
Skeleton() :
use_2d(false),
size(0),
@@ -1161,10 +1165,31 @@ public:
/* CANVAS SHADOW */
+ struct CanvasLightShadow : public RID_Data {
+
+ int size;
+ int height;
+ GLuint fbo;
+ GLuint depth;
+ GLuint distance; //for older devices
+ };
+
+ RID_Owner<CanvasLightShadow> canvas_light_shadow_owner;
+
virtual RID canvas_light_shadow_buffer_create(int p_width);
/* LIGHT SHADOW MAPPING */
+ struct CanvasOccluder : public RID_Data {
+
+ GLuint vertex_id; // 0 means, unconfigured
+ GLuint index_id; // 0 means, unconfigured
+ PoolVector<Vector2> lines;
+ int len;
+ };
+
+ RID_Owner<CanvasOccluder> canvas_occluder_owner;
+
virtual RID canvas_light_occluder_create();
virtual void canvas_light_occluder_set_polylines(RID p_occluder, const PoolVector<Vector2> &p_lines);
diff --git a/drivers/gles2/shaders/SCsub b/drivers/gles2/shaders/SCsub
index d959d3f740..085c43319c 100644
--- a/drivers/gles2/shaders/SCsub
+++ b/drivers/gles2/shaders/SCsub
@@ -6,7 +6,7 @@ if 'GLES2_GLSL' in env['BUILDERS']:
env.GLES2_GLSL('copy.glsl');
# env.GLES2_GLSL('resolve.glsl');
env.GLES2_GLSL('canvas.glsl');
-# env.GLES2_GLSL('canvas_shadow.glsl');
+ env.GLES2_GLSL('canvas_shadow.glsl');
env.GLES2_GLSL('scene.glsl');
env.GLES2_GLSL('cubemap_filter.glsl');
env.GLES2_GLSL('cube_to_dp.glsl');
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 87a615ade1..2292e3e068 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -11,12 +12,40 @@ precision mediump int;
uniform highp mat4 projection_matrix;
/* clang-format on */
+
+#include "stdlib.glsl"
+
uniform highp mat4 modelview_matrix;
uniform highp mat4 extra_matrix;
attribute highp vec2 vertex; // attrib:0
attribute vec4 color_attrib; // attrib:3
attribute vec2 uv_attrib; // attrib:4
+#ifdef USE_SKELETON
+attribute highp vec4 bone_indices; // attrib:6
+attribute highp vec4 bone_weights; // attrib:7
+#endif
+
+#ifdef USE_INSTANCING
+
+attribute highp vec4 instance_xform0; //attrib:8
+attribute highp vec4 instance_xform1; //attrib:9
+attribute highp vec4 instance_xform2; //attrib:10
+attribute highp vec4 instance_color; //attrib:11
+
+#ifdef USE_INSTANCE_CUSTOM
+attribute highp vec4 instance_custom_data; //attrib:12
+#endif
+
+#endif
+
+#ifdef USE_SKELETON
+uniform highp sampler2D skeleton_texture; // texunit:-3
+uniform highp ivec2 skeleton_texture_size;
+uniform highp mat4 skeleton_transform;
+uniform highp mat4 skeleton_transform_inverse;
+#endif
+
varying vec2 uv_interp;
varying vec4 color_interp;
@@ -31,6 +60,35 @@ uniform vec4 src_rect;
uniform highp float time;
+#ifdef USE_LIGHTING
+
+// light matrices
+uniform highp mat4 light_matrix;
+uniform highp mat4 light_matrix_inverse;
+uniform highp mat4 light_local_matrix;
+uniform highp mat4 shadow_matrix;
+uniform highp vec4 light_color;
+uniform highp vec4 light_shadow_color;
+uniform highp vec2 light_pos;
+uniform highp float shadowpixel_size;
+uniform highp float shadow_gradient;
+uniform highp float light_height;
+uniform highp float light_outside_alpha;
+uniform highp float shadow_distance_mult;
+
+varying vec4 light_uv_interp;
+varying vec2 transformed_light_uv;
+varying vec4 local_rot;
+
+#ifdef USE_SHADOWS
+varying highp vec2 pos;
+#endif
+
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
+#endif
+
/* clang-format off */
VERTEX_SHADER_GLOBALS
@@ -50,6 +108,16 @@ void main() {
vec4 color = color_attrib;
+#ifdef USE_INSTANCING
+ mat4 extra_matrix_instance = extra_matrix * transpose(mat4(instance_xform0, instance_xform1, instance_xform2, vec4(0.0, 0.0, 0.0, 1.0)));
+ color *= instance_color;
+ vec4 instance_custom = instance_custom_data;
+
+#else
+ mat4 extra_matrix_instance = extra_matrix;
+ vec4 instance_custom = vec4(0.0);
+#endif
+
#ifdef USE_TEXTURE_RECT
if (dst_rect.z < 0.0) { // Transpose is encoded as negative dst_rect.z
@@ -73,8 +141,6 @@ void main() {
vec4 outvec = vec4(vertex.xy, 0.0, 1.0);
uv_interp = uv_attrib;
-
-
#endif
{
@@ -87,7 +153,7 @@ VERTEX_SHADER_CODE
}
#if !defined(SKIP_TRANSFORM_USED)
- outvec = extra_matrix * outvec;
+ outvec = extra_matrix_instance * outvec;
outvec = modelview_matrix * outvec;
#endif
@@ -97,13 +163,63 @@ VERTEX_SHADER_CODE
outvec.xy = floor(outvec + 0.5).xy;
#endif
+#ifdef USE_SKELETON
+
+ // look up transform from the "pose texture"
+ if (bone_weights != vec4(0.0)) {
+
+ highp mat4 bone_transform = mat4(0.0);
+
+ for (int i = 0; i < 4; i++) {
+ ivec2 tex_ofs = ivec2(int(bone_indices[i]) * 2, 0);
+
+ highp mat4 b = mat4(
+ texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(0, 0)),
+ texel2DFetch(skeleton_texture, skeleton_texture_size, tex_ofs + ivec2(1, 0)),
+ vec4(0.0, 0.0, 1.0, 0.0),
+ vec4(0.0, 0.0, 0.0, 1.0));
+
+ bone_transform += b * bone_weights[i];
+ }
+
+ mat4 bone_matrix = skeleton_transform * transpose(bone_transform) * skeleton_transform_inverse;
+
+ outvec = bone_matrix * outvec;
+
+ }
+
+
+#endif
+
+
gl_Position = projection_matrix * outvec;
+
+#ifdef USE_LIGHTING
+
+ light_uv_interp.xy = (light_matrix * outvec).xy;
+ light_uv_interp.zw = (light_local_matrix * outvec).xy;
+
+ transformed_light_uv = (mat3(light_matrix_inverse) * vec3(light_uv_interp.zw, 0.0)).xy; //for normal mapping
+
+#ifdef USE_SHADOWS
+ pos = outvec.xy;
+#endif
+
+ local_rot.xy = normalize((modelview_matrix * (extra_matrix_instance * vec4(1.0, 0.0, 0.0, 0.0))).xy);
+ local_rot.zw = normalize((modelview_matrix * (extra_matrix_instance * vec4(0.0, 1.0, 0.0, 0.0))).xy);
+#ifdef USE_TEXTURE_RECT
+ local_rot.xy *= sign(src_rect.z);
+ local_rot.zw *= sign(src_rect.w);
+#endif
+
+#endif
}
/* clang-format off */
[fragment]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -125,7 +241,7 @@ uniform vec4 final_modulate;
#ifdef SCREEN_TEXTURE_USED
-uniform sampler2D screen_texture; // texunit:-3
+uniform sampler2D screen_texture; // texunit:-4
#endif
@@ -135,6 +251,40 @@ uniform vec2 screen_pixel_size;
#endif
+#ifdef USE_LIGHTING
+
+uniform highp mat4 light_matrix;
+uniform highp mat4 light_local_matrix;
+uniform highp mat4 shadow_matrix;
+uniform highp vec4 light_color;
+uniform highp vec4 light_shadow_color;
+uniform highp vec2 light_pos;
+uniform highp float shadowpixel_size;
+uniform highp float shadow_gradient;
+uniform highp float light_height;
+uniform highp float light_outside_alpha;
+uniform highp float shadow_distance_mult;
+
+uniform lowp sampler2D light_texture; // texunit:-4
+varying vec4 light_uv_interp;
+varying vec2 transformed_light_uv;
+
+varying vec4 local_rot;
+
+#ifdef USE_SHADOWS
+
+uniform highp sampler2D shadow_texture; // texunit:-5
+varying highp vec2 pos;
+
+#endif
+
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
+#endif
+
+uniform bool use_default_normal;
+
/* clang-format off */
FRAGMENT_SHADER_GLOBALS
@@ -153,15 +303,236 @@ void main() {
#ifdef SCREEN_UV_USED
vec2 screen_uv = gl_FragCoord.xy * screen_pixel_size;
#endif
+
+ vec3 normal;
+
+#if defined(NORMAL_USED)
+
+ bool normal_used = true;
+#else
+ bool normal_used = false;
+#endif
+
+ if (use_default_normal) {
+ normal.xy = texture2D(normal_texture, uv_interp).xy * 2.0 - 1.0;
+ normal.z = sqrt(1.0 - dot(normal.xy, normal.xy));
+ normal_used = true;
+ } else {
+ normal = vec3(0.0, 0.0, 1.0);
+ }
+
{
+ float normal_depth = 1.0;
+
+#if defined(NORMALMAP_USED)
+ vec3 normal_map = vec3(0.0, 0.0, 1.0);
+ normal_used = true;
+#endif
+
/* clang-format off */
FRAGMENT_SHADER_CODE
/* clang-format on */
- }
+#if defined(NORMALMAP_USED)
+ normal = mix(vec3(0.0, 0.0, 1.0), normal_map * vec3(2.0, -2.0, 1.0) - vec3(1.0, -1.0, 0.0), normal_depth);
+#endif
+ }
color *= final_modulate;
+#ifdef USE_LIGHTING
+
+ vec2 light_vec = transformed_light_uv;
+
+ if (normal_used) {
+ normal.xy = mat2(local_rot.xy, local_rot.zw) * normal.xy;
+ }
+
+ float att = 1.0;
+
+ vec2 light_uv = light_uv_interp.xy;
+ vec4 light = texture2D(light_texture, light_uv);
+
+ if (any(lessThan(light_uv_interp.xy, vec2(0.0, 0.0))) || any(greaterThanEqual(light_uv_interp.xy, vec2(1.0, 1.0)))) {
+ color.a *= light_outside_alpha; //invisible
+
+ } else {
+ float real_light_height = light_height;
+ vec4 real_light_color = light_color;
+ vec4 real_light_shadow_color = light_shadow_color;
+
+#if defined(USE_LIGHT_SHADER_CODE)
+ //light is written by the light shader
+ light_compute(
+ light,
+ light_vec,
+ real_light_height,
+ real_light_color,
+ light_uv,
+ real_light_shadow_color,
+ normal,
+ uv,
+#if defined(SCREEN_UV_USED)
+ screen_uv,
+#endif
+ color);
+#endif
+
+ light *= real_light_color;
+
+ if (normal_used) {
+ vec3 light_normal = normalize(vec3(light_vec, -real_light_height));
+ light *= max(dot(-light_normal, normal), 0.0);
+ }
+
+ color *= light;
+
+#ifdef USE_SHADOWS
+ light_vec = light_uv_interp.zw; //for shadows
+ float angle_to_light = -atan(light_vec.x, light_vec.y);
+ float PI = 3.14159265358979323846264;
+ /*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
+ float ang*/
+
+ float su, sz;
+
+ float abs_angle = abs(angle_to_light);
+ vec2 point;
+ float sh;
+ if (abs_angle < 45.0 * PI / 180.0) {
+ point = light_vec;
+ sh = 0.0 + (1.0 / 8.0);
+ } else if (abs_angle > 135.0 * PI / 180.0) {
+ point = -light_vec;
+ sh = 0.5 + (1.0 / 8.0);
+ } else if (angle_to_light > 0.0) {
+
+ point = vec2(light_vec.y, -light_vec.x);
+ sh = 0.25 + (1.0 / 8.0);
+ } else {
+
+ point = vec2(-light_vec.y, light_vec.x);
+ sh = 0.75 + (1.0 / 8.0);
+ }
+
+ highp vec4 s = shadow_matrix * vec4(point, 0.0, 1.0);
+ s.xyz /= s.w;
+ su = s.x * 0.5 + 0.5;
+ sz = s.z * 0.5 + 0.5;
+ //sz=lightlength(light_vec);
+
+ highp float shadow_attenuation = 0.0;
+
+#ifdef USE_RGBA_SHADOWS
+
+#define SHADOW_DEPTH(m_tex, m_uv) dot(texture2D((m_tex), (m_uv)), vec4(1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1))
+
+#else
+
+#define SHADOW_DEPTH(m_tex, m_uv) (texture2D((m_tex), (m_uv)).r)
+
+#endif
+
+#ifdef SHADOW_USE_GRADIENT
+
+#define SHADOW_TEST(m_ofs) \
+ { \
+ highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \
+ shadow_attenuation += 1.0 - smoothstep(sd, sd + shadow_gradient, sz); \
+ }
+
+#else
+
+#define SHADOW_TEST(m_ofs) \
+ { \
+ highp float sd = SHADOW_DEPTH(shadow_texture, vec2(m_ofs, sh)); \
+ shadow_attenuation += step(sz, sd); \
+ }
+
+#endif
+
+#ifdef SHADOW_FILTER_NEAREST
+
+ SHADOW_TEST(su);
+
+#endif
+
+#ifdef SHADOW_FILTER_PCF3
+
+ SHADOW_TEST(su + shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su - shadowpixel_size);
+ shadow_attenuation /= 3.0;
+
+#endif
+
+#ifdef SHADOW_FILTER_PCF5
+
+ SHADOW_TEST(su + shadowpixel_size * 2.0);
+ SHADOW_TEST(su + shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su - shadowpixel_size);
+ SHADOW_TEST(su - shadowpixel_size * 2.0);
+ shadow_attenuation /= 5.0;
+
+#endif
+
+#ifdef SHADOW_FILTER_PCF7
+
+ SHADOW_TEST(su + shadowpixel_size * 3.0);
+ SHADOW_TEST(su + shadowpixel_size * 2.0);
+ SHADOW_TEST(su + shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su - shadowpixel_size);
+ SHADOW_TEST(su - shadowpixel_size * 2.0);
+ SHADOW_TEST(su - shadowpixel_size * 3.0);
+ shadow_attenuation /= 7.0;
+
+#endif
+
+#ifdef SHADOW_FILTER_PCF9
+
+ SHADOW_TEST(su + shadowpixel_size * 4.0);
+ SHADOW_TEST(su + shadowpixel_size * 3.0);
+ SHADOW_TEST(su + shadowpixel_size * 2.0);
+ SHADOW_TEST(su + shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su - shadowpixel_size);
+ SHADOW_TEST(su - shadowpixel_size * 2.0);
+ SHADOW_TEST(su - shadowpixel_size * 3.0);
+ SHADOW_TEST(su - shadowpixel_size * 4.0);
+ shadow_attenuation /= 9.0;
+
+#endif
+
+#ifdef SHADOW_FILTER_PCF13
+
+ SHADOW_TEST(su + shadowpixel_size * 6.0);
+ SHADOW_TEST(su + shadowpixel_size * 5.0);
+ SHADOW_TEST(su + shadowpixel_size * 4.0);
+ SHADOW_TEST(su + shadowpixel_size * 3.0);
+ SHADOW_TEST(su + shadowpixel_size * 2.0);
+ SHADOW_TEST(su + shadowpixel_size);
+ SHADOW_TEST(su);
+ SHADOW_TEST(su - shadowpixel_size);
+ SHADOW_TEST(su - shadowpixel_size * 2.0);
+ SHADOW_TEST(su - shadowpixel_size * 3.0);
+ SHADOW_TEST(su - shadowpixel_size * 4.0);
+ SHADOW_TEST(su - shadowpixel_size * 5.0);
+ SHADOW_TEST(su - shadowpixel_size * 6.0);
+ shadow_attenuation /= 13.0;
+
+#endif
+
+ //color *= shadow_attenuation;
+ color = mix(real_light_shadow_color, color, shadow_attenuation);
+//use shadows
+#endif
+ }
+
+//use lighting
+#endif
+
gl_FragColor = color;
}
diff --git a/drivers/gles2/shaders/canvas_shadow.glsl b/drivers/gles2/shaders/canvas_shadow.glsl
index e3c8140e31..d39212826e 100644
--- a/drivers/gles2/shaders/canvas_shadow.glsl
+++ b/drivers/gles2/shaders/canvas_shadow.glsl
@@ -1,15 +1,24 @@
/* clang-format off */
[vertex]
+#ifdef USE_GLES_OVER_GL
+#define lowp
+#define mediump
+#define highp
+#else
+precision highp float;
+precision highp int;
+#endif
+
+attribute highp vec3 vertex; // attrib:0
+
uniform highp mat4 projection_matrix;
/* clang-format on */
uniform highp mat4 light_matrix;
uniform highp mat4 world_matrix;
uniform highp float distance_norm;
-layout(location = 0) in highp vec3 vertex;
-
-out highp vec4 position_interp;
+varying highp vec4 position_interp;
void main() {
@@ -20,31 +29,29 @@ void main() {
/* clang-format off */
[fragment]
-in highp vec4 position_interp;
-/* clang-format on */
-
-#ifdef USE_RGBA_SHADOWS
-
-layout(location = 0) out lowp vec4 distance_buf;
-
+#ifdef USE_GLES_OVER_GL
+#define lowp
+#define mediump
+#define highp
#else
-
-layout(location = 0) out highp float distance_buf;
-
+precision mediump float;
+precision mediump int;
#endif
+varying highp vec4 position_interp;
+/* clang-format on */
+
void main() {
- highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; //bias;
+ highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0; // bias
#ifdef USE_RGBA_SHADOWS
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
- distance_buf = comp;
+ gl_FragColor = comp;
#else
- distance_buf = depth;
-
+ gl_FragColor = vec4(depth);
#endif
}
diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl
index 97a24212a5..f3c2a7eec4 100644
--- a/drivers/gles2/shaders/copy.glsl
+++ b/drivers/gles2/shaders/copy.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -56,6 +57,7 @@ void main() {
#define M_PI 3.14159265359
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
diff --git a/drivers/gles2/shaders/cube_to_dp.glsl b/drivers/gles2/shaders/cube_to_dp.glsl
index 3d24c36336..cb4b3f6dec 100644
--- a/drivers/gles2/shaders/cube_to_dp.glsl
+++ b/drivers/gles2/shaders/cube_to_dp.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -25,6 +26,7 @@ void main() {
[fragment]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
diff --git a/drivers/gles2/shaders/cubemap_filter.glsl b/drivers/gles2/shaders/cubemap_filter.glsl
index b1553c7cd5..06274a7698 100644
--- a/drivers/gles2/shaders/cubemap_filter.glsl
+++ b/drivers/gles2/shaders/cubemap_filter.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -32,6 +33,7 @@ void main() {
#endif
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
diff --git a/drivers/gles2/shaders/lens_distorted.glsl b/drivers/gles2/shaders/lens_distorted.glsl
index efa35adf7d..81898a75a5 100644
--- a/drivers/gles2/shaders/lens_distorted.glsl
+++ b/drivers/gles2/shaders/lens_distorted.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -29,6 +30,7 @@ void main() {
[fragment]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl
index aba283970a..5cdf4ff04d 100644
--- a/drivers/gles2/shaders/scene.glsl
+++ b/drivers/gles2/shaders/scene.glsl
@@ -2,6 +2,7 @@
[vertex]
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -653,6 +654,7 @@ VERTEX_SHADER_CODE
#endif
#ifdef USE_GLES_OVER_GL
+#define lowp
#define mediump
#define highp
#else
@@ -1091,7 +1093,6 @@ void light_compute(
inout vec3 diffuse_light,
inout vec3 specular_light) {
-
//this makes lights behave closer to linear, but then addition of lights looks bad
//better left disabled
@@ -1253,7 +1254,7 @@ LIGHT_SHADER_CODE
float YdotH = dot(B, H);
float D = D_GGX_anisotropic(cNdotH, ax, ay, XdotH, YdotH, cNdotH);
//float G = G_GGX_anisotropic_2cos(cNdotL, ax, ay, XdotH, YdotH) * G_GGX_anisotropic_2cos(cNdotV, ax, ay, XdotH, YdotH);
- float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL))
+ float G = V_GGX_anisotropic(ax, ay, dot(T, V), dot(T, L), dot(B, V), dot(B, L), cNdotV, cNdotL);
#else
float alpha = roughness * roughness;
@@ -1914,7 +1915,6 @@ FRAGMENT_SHADER_CODE
#ifdef USE_SHADOW
{
highp vec4 splane = shadow_coord;
- splane.xyz /= splane.w;
float shadow = sample_shadow(light_shadow_atlas, splane);
light_att *= shadow;
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 4166cb8361..8b02458983 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -862,7 +862,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
}
- int amount = MAX(multi_mesh->size, multi_mesh->visible_instances);
+ int amount = MIN(multi_mesh->size, multi_mesh->visible_instances);
+
+ if (amount == -1) {
+ amount = multi_mesh->size;
+ }
for (int j = 0; j < mesh_data->surfaces.size(); j++) {
RasterizerStorageGLES3::Surface *s = mesh_data->surfaces[j];
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 2b038fcc0e..84d3d80e0e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1995,7 +1995,8 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
actions = &shaders.actions_particles;
actions->uniforms = &p_shader->uniforms;
} break;
- case VS::SHADER_MAX: break; // Can't happen, but silences warning
+ case VS::SHADER_MAX:
+ break; // Can't happen, but silences warning
}
Error err = shaders.compiler.compile(p_shader->mode, p_shader->code, actions, p_shader->path, gen_code);
@@ -7019,6 +7020,7 @@ RID RasterizerStorageGLES3::render_target_create() {
Texture *t = memnew(Texture);
+ t->type = VS::TEXTURE_TYPE_2D;
t->flags = 0;
t->width = 0;
t->height = 0;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 958086f6c7..bd234d7fbe 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -291,6 +291,7 @@ public:
width(0),
height(0),
format(Image::FORMAT_L8),
+ type(VS::TEXTURE_TYPE_2D),
target(GL_TEXTURE_2D),
data_size(0),
compressed(false),
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index ff273e4e9f..8b1f18ccbd 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -2028,7 +2028,7 @@ FRAGMENT_SHADER_CODE
//apply fog
if (fog_depth_enabled) {
- float fog_far = fog_depth_end > 0 ? fog_depth_end : z_far;
+ float fog_far = fog_depth_end > 0.0 ? fog_depth_end : z_far;
float fog_z = smoothstep(fog_depth_begin, fog_far, length(vertex));
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 949609bb9a..b39be64bef 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -55,10 +55,12 @@
#include <iphlpapi.h>
#endif // MINGW hack
#endif
-#else
+#else // UNIX
#include <netdb.h>
#ifdef ANDROID_ENABLED
-#include "platform/android/ifaddrs_android.h"
+// We could drop this file once we up our API level to 24,
+// where the NDK's ifaddrs.h supports to needed getifaddrs.
+#include "thirdparty/misc/ifaddrs-android.h"
#else
#ifdef __FreeBSD__
#include <sys/types.h>
@@ -201,7 +203,7 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
#endif
-#else
+#else // UNIX
void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
diff --git a/drivers/unix/os_unix.cpp b/drivers/unix/os_unix.cpp
index 279274734f..12a1263042 100644
--- a/drivers/unix/os_unix.cpp
+++ b/drivers/unix/os_unix.cpp
@@ -202,6 +202,12 @@ uint64_t OS_Unix::get_system_time_secs() const {
return uint64_t(tv_now.tv_sec);
}
+uint64_t OS_Unix::get_system_time_msecs() const {
+ struct timeval tv_now;
+ gettimeofday(&tv_now, NULL);
+ return uint64_t(tv_now.tv_sec * 1000 + tv_now.tv_usec / 1000);
+}
+
OS::Date OS_Unix::get_date(bool utc) const {
time_t t = time(NULL);
diff --git a/drivers/unix/os_unix.h b/drivers/unix/os_unix.h
index b702454603..94a8d040cd 100644
--- a/drivers/unix/os_unix.h
+++ b/drivers/unix/os_unix.h
@@ -84,6 +84,7 @@ public:
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
+ virtual uint64_t get_system_time_msecs() const;
virtual void delay_usec(uint32_t p_usec) const;
virtual uint64_t get_ticks_usec() const;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 05081d2639..46a4dea13f 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -1129,8 +1129,11 @@ void CodeTextEditor::set_edit_state(const Variant &p_state) {
void CodeTextEditor::set_error(const String &p_error) {
error->set_text(p_error);
- error->set_tooltip(p_error);
- error->set_visible(p_error != "");
+ if (p_error != "") {
+ error->set_default_cursor_shape(CURSOR_POINTING_HAND);
+ } else {
+ error->set_default_cursor_shape(CURSOR_ARROW);
+ }
}
void CodeTextEditor::set_error_pos(int p_line, int p_column) {
@@ -1138,10 +1141,12 @@ void CodeTextEditor::set_error_pos(int p_line, int p_column) {
error_column = p_column;
}
-void CodeTextEditor::_error_pressed() {
- text_editor->cursor_set_line(error_line);
- text_editor->cursor_set_column(error_column);
- text_editor->center_viewport_to_cursor();
+void CodeTextEditor::goto_error() {
+ if (error->get_text() != "") {
+ text_editor->cursor_set_line(error_line);
+ text_editor->cursor_set_column(error_column);
+ text_editor->center_viewport_to_cursor();
+ }
}
void CodeTextEditor::_update_font() {
@@ -1204,7 +1209,6 @@ void CodeTextEditor::_bind_methods() {
ClassDB::bind_method("_code_complete_timer_timeout", &CodeTextEditor::_code_complete_timer_timeout);
ClassDB::bind_method("_complete_request", &CodeTextEditor::_complete_request);
ClassDB::bind_method("_font_resize_timeout", &CodeTextEditor::_font_resize_timeout);
- ClassDB::bind_method("_error_pressed", &CodeTextEditor::_error_pressed);
ADD_SIGNAL(MethodInfo("validate_script"));
ADD_SIGNAL(MethodInfo("load_theme_settings"));
@@ -1254,19 +1258,14 @@ CodeTextEditor::CodeTextEditor() {
error_line = 0;
error_column = 0;
- Control *error_box = memnew(Control);
- status_bar->add_child(error_box);
- error_box->set_v_size_flags(SIZE_EXPAND_FILL);
- error_box->set_h_size_flags(SIZE_EXPAND_FILL);
- error_box->set_clip_contents(true);
-
- error = memnew(LinkButton);
- error_box->add_child(error);
- error->set_anchors_and_margins_preset(Control::PRESET_CENTER_LEFT);
- error->set_underline_mode(LinkButton::UNDERLINE_MODE_ON_HOVER);
+ error = memnew(Label);
+ status_bar->add_child(error);
+ error->set_autowrap(true);
+ error->set_valign(Label::VALIGN_CENTER);
+ error->set_h_size_flags(SIZE_EXPAND_FILL); //required for it to display, given now it's clipping contents, do not touch
error->add_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor"));
error->add_font_override("font", EditorNode::get_singleton()->get_gui_base()->get_font("status_source", "EditorFonts"));
- error->connect("pressed", this, "_error_pressed");
+ error->set_mouse_filter(MOUSE_FILTER_STOP);
find_replace_bar->connect("error", error, "set_text");
status_bar->add_child(memnew(Label)); //to keep the height if the other labels are not visible
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 2d233c61c6..7be8ddc111 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -36,7 +36,6 @@
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
-#include "scene/gui/link_button.h"
#include "scene/gui/text_edit.h"
#include "scene/gui/tool_button.h"
#include "scene/main/timer.h"
@@ -152,13 +151,12 @@ class CodeTextEditor : public VBoxContainer {
Label *info;
Timer *idle;
Timer *code_complete_timer;
- bool enable_complete_timer;
Timer *font_resize_timer;
int font_resize_val;
real_t font_size;
- LinkButton *error;
+ Label *error;
int error_line;
int error_column;
@@ -174,7 +172,6 @@ class CodeTextEditor : public VBoxContainer {
void _zoom_out();
void _zoom_changed();
void _reset_zoom();
- void _error_pressed();
CodeTextEditorCodeCompleteFunc code_complete_func;
void *code_complete_ud;
@@ -221,9 +218,11 @@ public:
void update_line_and_column() { _line_col_changed(); }
TextEdit *get_text_edit() { return text_editor; }
FindReplaceBar *get_find_replace_bar() { return find_replace_bar; }
+ Label *get_error_label() const { return error; }
Label *get_warning_label() const { return warning_label; }
Label *get_warning_count_label() const { return warning_count_label; }
virtual void apply_code() {}
+ void goto_error();
void set_code_complete_func(CodeTextEditorCodeCompleteFunc p_code_complete_func, void *p_ud);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 3bd7678746..f035e5a8a1 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -3145,6 +3145,7 @@ void EditorNode::register_editor_types() {
ClassDB::register_class<EditorFileDialog>();
ClassDB::register_virtual_class<EditorSettings>();
ClassDB::register_class<EditorSpatialGizmo>();
+ ClassDB::register_class<EditorSpatialGizmoPlugin>();
ClassDB::register_virtual_class<EditorResourcePreview>();
ClassDB::register_class<EditorResourcePreviewGenerator>();
ClassDB::register_virtual_class<EditorFileSystem>();
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 403db4b8ba..0b3d375d79 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -273,7 +273,7 @@ void EditorInterface::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_resource_filesystem"), &EditorInterface::get_resource_file_system);
ClassDB::bind_method(D_METHOD("get_editor_viewport"), &EditorInterface::get_editor_viewport);
ClassDB::bind_method(D_METHOD("make_mesh_previews", "meshes", "preview_size"), &EditorInterface::_make_mesh_previews);
- ClassDB::bind_method(D_METHOD("select_file", "p_file"), &EditorInterface::select_file);
+ ClassDB::bind_method(D_METHOD("select_file", "file"), &EditorInterface::select_file);
ClassDB::bind_method(D_METHOD("get_selected_path"), &EditorInterface::get_selected_path);
ClassDB::bind_method(D_METHOD("set_plugin_enabled", "plugin", "enabled"), &EditorInterface::set_plugin_enabled);
@@ -682,6 +682,14 @@ void EditorPlugin::remove_export_plugin(const Ref<EditorExportPlugin> &p_exporte
EditorExport::get_singleton()->remove_export_plugin(p_exporter);
}
+void EditorPlugin::add_spatial_gizmo_plugin(const Ref<EditorSpatialGizmoPlugin> &p_gizmo_plugin) {
+ SpatialEditor::get_singleton()->add_gizmo_plugin(p_gizmo_plugin);
+}
+
+void EditorPlugin::remove_spatial_gizmo_plugin(const Ref<EditorSpatialGizmoPlugin> &p_gizmo_plugin) {
+ SpatialEditor::get_singleton()->remove_gizmo_plugin(p_gizmo_plugin);
+}
+
void EditorPlugin::add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin) {
EditorInspector::add_inspector_plugin(p_plugin);
}
@@ -802,6 +810,8 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_scene_import_plugin", "scene_importer"), &EditorPlugin::remove_scene_import_plugin);
ClassDB::bind_method(D_METHOD("add_export_plugin", "plugin"), &EditorPlugin::add_export_plugin);
ClassDB::bind_method(D_METHOD("remove_export_plugin", "plugin"), &EditorPlugin::remove_export_plugin);
+ ClassDB::bind_method(D_METHOD("add_spatial_gizmo_plugin", "plugin"), &EditorPlugin::add_spatial_gizmo_plugin);
+ ClassDB::bind_method(D_METHOD("remove_spatial_gizmo_plugin", "plugin"), &EditorPlugin::remove_spatial_gizmo_plugin);
ClassDB::bind_method(D_METHOD("add_inspector_plugin", "plugin"), &EditorPlugin::add_inspector_plugin);
ClassDB::bind_method(D_METHOD("remove_inspector_plugin", "plugin"), &EditorPlugin::remove_inspector_plugin);
ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled);
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 5f060a4e96..0a66e29e2d 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -53,6 +53,7 @@ class EditorExport;
class EditorSettings;
class EditorImportPlugin;
class EditorExportPlugin;
+class EditorSpatialGizmoPlugin;
class EditorResourcePreview;
class EditorFileSystem;
class EditorToolAddons;
@@ -219,6 +220,9 @@ public:
void add_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
void remove_export_plugin(const Ref<EditorExportPlugin> &p_exporter);
+ void add_spatial_gizmo_plugin(const Ref<EditorSpatialGizmoPlugin> &p_gizmo_plugin);
+ void remove_spatial_gizmo_plugin(const Ref<EditorSpatialGizmoPlugin> &p_gizmo_plugin);
+
void add_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin);
void remove_inspector_plugin(const Ref<EditorInspectorPlugin> &p_plugin);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index eacf2ee1b4..8a2206d06c 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -994,6 +994,14 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
graphsbposition->set_draw_center(false);
graphsbposition->set_border_color_all(error_color);
graphsbposition->set_shadow_color(error_color * Color(1.0, 1.0, 1.0, 0.2));
+ Ref<StyleBoxFlat> smgraphsb = make_flat_stylebox(Color(mv, mv, mv, 0.7), gn_margin_side, 24, gn_margin_side, 5);
+ smgraphsb->set_border_width_all(border_width);
+ smgraphsb->set_border_color_all(Color(mv2, mv2, mv2, 0.9));
+ Ref<StyleBoxFlat> smgraphsbselected = make_flat_stylebox(Color(mv, mv, mv, 0.9), gn_margin_side, 24, gn_margin_side, 5);
+ smgraphsbselected->set_border_width_all(border_width);
+ smgraphsbselected->set_border_color_all(Color(accent_color.r, accent_color.g, accent_color.b, 0.9));
+ smgraphsbselected->set_shadow_size(8 * EDSCALE);
+ smgraphsbselected->set_shadow_color(shadow_color);
if (use_gn_headers) {
graphsb->set_border_width(MARGIN_TOP, 24 * EDSCALE);
@@ -1008,6 +1016,8 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) {
theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected);
theme->set_stylebox("breakpoint", "GraphNode", graphsbbreakpoint);
theme->set_stylebox("position", "GraphNode", graphsbposition);
+ theme->set_stylebox("state_machine_frame", "GraphNode", smgraphsb);
+ theme->set_stylebox("state_machine_selectedframe", "GraphNode", smgraphsbselected);
Color default_node_color = Color(mv2, mv2, mv2);
theme->set_color("title_color", "GraphNode", default_node_color);
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
index c1c1183692..fbb5bf9342 100644
--- a/editor/import/editor_import_plugin.cpp
+++ b/editor/import/editor_import_plugin.cpp
@@ -165,5 +165,5 @@ void EditorImportPlugin::_bind_methods() {
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::REAL, "get_priority"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "get_import_order"));
ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "get_option_visibility", PropertyInfo(Variant::STRING, "option"), PropertyInfo(Variant::DICTIONARY, "options")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "import", PropertyInfo(Variant::STRING, "source_file"), PropertyInfo(Variant::STRING, "save_path"), PropertyInfo(Variant::DICTIONARY, "options"), PropertyInfo(Variant::ARRAY, "r_platform_variants"), PropertyInfo(Variant::ARRAY, "r_gen_files")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "import", PropertyInfo(Variant::STRING, "source_file"), PropertyInfo(Variant::STRING, "save_path"), PropertyInfo(Variant::DICTIONARY, "options"), PropertyInfo(Variant::ARRAY, "platform_variants"), PropertyInfo(Variant::ARRAY, "gen_files")));
}
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index c237d2e854..ae118e3e01 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -45,6 +45,7 @@ uint32_t EditorOBJImporter::get_import_flags() const {
static Error _parse_material_library(const String &p_path, Map<String, Ref<SpatialMaterial> > &material_map, List<String> *r_missing_deps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
+ ERR_EXPLAIN(vformat("Couldn't open MTL file '%s', it may not exist or not be readable.", p_path));
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
Ref<SpatialMaterial> current;
@@ -206,7 +207,7 @@ static Error _parse_material_library(const String &p_path, Map<String, Ref<Spati
static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p_single_mesh, bool p_generate_tangents, bool p_optimize, Vector3 p_scale_mesh, List<String> *r_missing_deps) {
FileAccessRef f = FileAccess::open(p_path, FileAccess::READ);
-
+ ERR_EXPLAIN(vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
Ref<ArrayMesh> mesh;
@@ -217,11 +218,6 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh> > &r_meshes, bool p
bool flip_faces = false;
int mesh_flags = p_optimize ? Mesh::ARRAY_COMPRESS_DEFAULT : 0;
- //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;
diff --git a/editor/plugins/animation_blend_tree_editor_plugin.cpp b/editor/plugins/animation_blend_tree_editor_plugin.cpp
index 1e5a116f47..2dbf349271 100644
--- a/editor/plugins/animation_blend_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_blend_tree_editor_plugin.cpp
@@ -134,6 +134,7 @@ void AnimationNodeBlendTreeEditor::_update_graph() {
node->set_offset(blend_tree->get_node_position(E->get()) * EDSCALE);
node->set_title(agnode->get_caption());
+ node->set_human_readable_collision_renaming(false);
node->set_name(E->get());
int base = 0;
diff --git a/editor/plugins/animation_state_machine_editor.cpp b/editor/plugins/animation_state_machine_editor.cpp
index ee30294fe7..427b4eebee 100644
--- a/editor/plugins/animation_state_machine_editor.cpp
+++ b/editor/plugins/animation_state_machine_editor.cpp
@@ -572,8 +572,8 @@ void AnimationNodeStateMachineEditor::_state_machine_draw() {
Ref<AnimationNodeStateMachinePlayback> playback = AnimationTreeEditor::get_singleton()->get_tree()->get(AnimationTreeEditor::get_singleton()->get_base_path() + "playback");
- Ref<StyleBox> style = get_stylebox("frame", "GraphNode");
- Ref<StyleBox> style_selected = get_stylebox("selectedframe", "GraphNode");
+ Ref<StyleBox> style = get_stylebox("state_machine_frame", "GraphNode");
+ Ref<StyleBox> style_selected = get_stylebox("state_machine_selectedframe", "GraphNode");
Ref<Font> font = get_font("title_font", "GraphNode");
Color font_color = get_color("title_color", "GraphNode");
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index df6c40ed02..6e0e609aa8 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -563,7 +563,7 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
Ref<PathSpatialGizmoPlugin> gizmo_plugin;
gizmo_plugin.instance();
- SpatialEditor::get_singleton()->register_gizmo_plugin(gizmo_plugin);
+ SpatialEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin);
sep = memnew(VSeparator);
sep->hide();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 85237f64d9..f6ec217ce0 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -280,6 +280,13 @@ void ScriptTextEditor::_toggle_warning_pannel(const Ref<InputEvent> &p_event) {
}
}
+void ScriptTextEditor::_error_pressed(const Ref<InputEvent> &p_event) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ code_editor->goto_error();
+ }
+}
+
void ScriptTextEditor::_warning_clicked(Variant p_line) {
if (p_line.get_type() == Variant::INT) {
code_editor->get_text_edit()->cursor_set_line(p_line.operator int64_t());
@@ -1101,6 +1108,7 @@ void ScriptTextEditor::_bind_methods() {
ClassDB::bind_method("_lookup_symbol", &ScriptTextEditor::_lookup_symbol);
ClassDB::bind_method("_text_edit_gui_input", &ScriptTextEditor::_text_edit_gui_input);
ClassDB::bind_method("_toggle_warning_pannel", &ScriptTextEditor::_toggle_warning_pannel);
+ ClassDB::bind_method("_error_pressed", &ScriptTextEditor::_error_pressed);
ClassDB::bind_method("_warning_clicked", &ScriptTextEditor::_warning_clicked);
ClassDB::bind_method("_color_changed", &ScriptTextEditor::_color_changed);
@@ -1437,6 +1445,7 @@ ScriptTextEditor::ScriptTextEditor() {
warnings_panel->set_focus_mode(FOCUS_CLICK);
warnings_panel->hide();
+ code_editor->get_error_label()->connect("gui_input", this, "_error_pressed");
code_editor->get_warning_label()->connect("gui_input", this, "_toggle_warning_pannel");
code_editor->get_warning_count_label()->connect("gui_input", this, "_toggle_warning_pannel");
warnings_panel->connect("meta_clicked", this, "_warning_clicked");
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 837201a947..7a9d531e1c 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -126,6 +126,7 @@ protected:
void _load_theme_settings();
void _set_theme_for_script();
void _toggle_warning_pannel(const Ref<InputEvent> &p_event);
+ void _error_pressed(const Ref<InputEvent> &p_event);
void _warning_clicked(Variant p_line);
void _notification(int p_what);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 4fe278d005..3fd38d1da3 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -4831,9 +4831,9 @@ struct _GizmoPluginComparator {
}
};
-void SpatialEditor::_init_gizmos_menu() {
- _register_all_gizmos();
+void SpatialEditor::_update_gizmos_menu() {
+ gizmos_menu->clear();
gizmo_plugins.sort_custom<_GizmoPluginComparator>();
for (int i = 0; i < gizmo_plugins.size(); ++i) {
@@ -5137,7 +5137,8 @@ void SpatialEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- _init_gizmos_menu();
+ _register_all_gizmos();
+ _update_gizmos_menu();
_init_indicators();
}
@@ -5273,27 +5274,27 @@ void SpatialEditor::_node_removed(Node *p_node) {
}
void SpatialEditor::_register_all_gizmos() {
- register_gizmo_plugin(Ref<CameraSpatialGizmoPlugin>(memnew(CameraSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<LightSpatialGizmoPlugin>(memnew(LightSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<AudioStreamPlayer3DSpatialGizmoPlugin>(memnew(AudioStreamPlayer3DSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<MeshInstanceSpatialGizmoPlugin>(memnew(MeshInstanceSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<SoftBodySpatialGizmoPlugin>(memnew(SoftBodySpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<Sprite3DSpatialGizmoPlugin>(memnew(Sprite3DSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<SkeletonSpatialGizmoPlugin>(memnew(SkeletonSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<Position3DSpatialGizmoPlugin>(memnew(Position3DSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<RayCastSpatialGizmoPlugin>(memnew(RayCastSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<SpringArmSpatialGizmoPlugin>(memnew(SpringArmSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
- register_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
- register_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
- register_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
- register_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
- register_gizmo_plugin(Ref<CollisionShapeSpatialGizmoPlugin>(memnew(CollisionShapeSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<CollisionPolygonSpatialGizmoPlugin>(memnew(CollisionPolygonSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<NavigationMeshSpatialGizmoPlugin>(memnew(NavigationMeshSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<JointSpatialGizmoPlugin>(memnew(JointSpatialGizmoPlugin)));
- register_gizmo_plugin(Ref<PhysicalBoneSpatialGizmoPlugin>(memnew(PhysicalBoneSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<CameraSpatialGizmoPlugin>(memnew(CameraSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<LightSpatialGizmoPlugin>(memnew(LightSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<AudioStreamPlayer3DSpatialGizmoPlugin>(memnew(AudioStreamPlayer3DSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<MeshInstanceSpatialGizmoPlugin>(memnew(MeshInstanceSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<SoftBodySpatialGizmoPlugin>(memnew(SoftBodySpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<Sprite3DSpatialGizmoPlugin>(memnew(Sprite3DSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<SkeletonSpatialGizmoPlugin>(memnew(SkeletonSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<Position3DSpatialGizmoPlugin>(memnew(Position3DSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<RayCastSpatialGizmoPlugin>(memnew(RayCastSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<SpringArmSpatialGizmoPlugin>(memnew(SpringArmSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<VehicleWheelSpatialGizmoPlugin>(memnew(VehicleWheelSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<VisibilityNotifierGizmoPlugin>(memnew(VisibilityNotifierGizmoPlugin)));
+ add_gizmo_plugin(Ref<ParticlesGizmoPlugin>(memnew(ParticlesGizmoPlugin)));
+ add_gizmo_plugin(Ref<ReflectionProbeGizmoPlugin>(memnew(ReflectionProbeGizmoPlugin)));
+ add_gizmo_plugin(Ref<GIProbeGizmoPlugin>(memnew(GIProbeGizmoPlugin)));
+ add_gizmo_plugin(Ref<BakedIndirectLightGizmoPlugin>(memnew(BakedIndirectLightGizmoPlugin)));
+ add_gizmo_plugin(Ref<CollisionShapeSpatialGizmoPlugin>(memnew(CollisionShapeSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<CollisionPolygonSpatialGizmoPlugin>(memnew(CollisionPolygonSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<NavigationMeshSpatialGizmoPlugin>(memnew(NavigationMeshSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<JointSpatialGizmoPlugin>(memnew(JointSpatialGizmoPlugin)));
+ add_gizmo_plugin(Ref<PhysicalBoneSpatialGizmoPlugin>(memnew(PhysicalBoneSpatialGizmoPlugin)));
}
void SpatialEditor::_bind_methods() {
@@ -5730,8 +5731,15 @@ void SpatialEditorPlugin::snap_cursor_to_plane(const Plane &p_plane) {
spatial_editor->snap_cursor_to_plane(p_plane);
}
-void SpatialEditor::register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref) {
- gizmo_plugins.push_back(ref);
+void SpatialEditor::add_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin) {
+ gizmo_plugins.push_back(p_plugin);
+ _update_gizmos_menu();
+ SpatialEditor::get_singleton()->update_all_gizmos();
+}
+
+void SpatialEditor::remove_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin) {
+ gizmo_plugins.erase(p_plugin);
+ _update_gizmos_menu();
}
SpatialEditorPlugin::SpatialEditorPlugin(EditorNode *p_node) {
@@ -5857,11 +5865,11 @@ void EditorSpatialGizmoPlugin::add_material(const String &p_name, Ref<SpatialMat
materials[p_name].push_back(p_material);
}
-Ref<SpatialMaterial> EditorSpatialGizmoPlugin::get_material(const String &p_name, EditorSpatialGizmo *p_gizmo) {
+Ref<SpatialMaterial> EditorSpatialGizmoPlugin::get_material(const String &p_name, const Ref<EditorSpatialGizmo> &p_gizmo) {
ERR_FAIL_COND_V(!materials.has(p_name), Ref<SpatialMaterial>());
ERR_FAIL_COND_V(materials[p_name].size() == 0, Ref<SpatialMaterial>());
- if (p_gizmo == NULL) return materials[p_name][0];
+ if (p_gizmo.is_null()) return materials[p_name][0];
int index = (p_gizmo->is_selected() ? 1 : 0) + (p_gizmo->is_editable() ? 2 : 0);
@@ -5876,8 +5884,19 @@ Ref<SpatialMaterial> EditorSpatialGizmoPlugin::get_material(const String &p_name
return mat;
}
+String EditorSpatialGizmoPlugin::get_name() const {
+ if (get_script_instance() && get_script_instance()->has_method("get_name")) {
+ return get_script_instance()->call("get_name");
+ }
+ return TTR("Name-less gizmo");
+}
+
Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::get_gizmo(Spatial *p_spatial) {
+ if (get_script_instance() && get_script_instance()->has_method("get_gizmo")) {
+ return get_script_instance()->call("get_gizmo", p_spatial);
+ }
+
Ref<EditorSpatialGizmo> ref = create_gizmo(p_spatial);
if (ref.is_null()) return ref;
@@ -5890,22 +5909,109 @@ Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::get_gizmo(Spatial *p_spatial)
return ref;
}
+void EditorSpatialGizmoPlugin::_bind_methods() {
+#define GIZMO_REF PropertyInfo(Variant::OBJECT, "gizmo", PROPERTY_HINT_RESOURCE_TYPE, "EditorSpatialGizmo")
+
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "has_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial")));
+ BIND_VMETHOD(MethodInfo(GIZMO_REF, "create_gizmo", PropertyInfo(Variant::OBJECT, "spatial", PROPERTY_HINT_RESOURCE_TYPE, "Spatial")));
+
+ ClassDB::bind_method(D_METHOD("create_material", "name", "color", "billboard", "on_top", "use_vertex_color"), &EditorSpatialGizmoPlugin::create_material, DEFVAL(false), DEFVAL(false), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("create_icon_material", "name", "texture", "on_top", "color"), &EditorSpatialGizmoPlugin::create_icon_material, DEFVAL(false), DEFVAL(Color(1, 1, 1, 1)));
+ ClassDB::bind_method(D_METHOD("create_handle_material", "name", "billboard"), &EditorSpatialGizmoPlugin::create_handle_material, DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("add_material", "name", "material"), &EditorSpatialGizmoPlugin::add_material);
+
+ ClassDB::bind_method(D_METHOD("get_material", "name", "gizmo"), &EditorSpatialGizmoPlugin::get_material); //, DEFVAL(Ref<EditorSpatialGizmo>()));
+
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "get_name"));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_be_hidden"));
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_selectable_when_hidden"));
+
+ BIND_VMETHOD(MethodInfo("redraw", GIZMO_REF));
+ BIND_VMETHOD(MethodInfo(Variant::STRING, "get_handle_name", GIZMO_REF, PropertyInfo(Variant::INT, "index")));
+
+ MethodInfo hvget(Variant::NIL, "get_handle_value", GIZMO_REF, PropertyInfo(Variant::INT, "index"));
+ hvget.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT;
+ BIND_VMETHOD(hvget);
+
+ BIND_VMETHOD(MethodInfo("set_handle", GIZMO_REF, PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::VECTOR2, "point")));
+ MethodInfo cm = MethodInfo("commit_handle", GIZMO_REF, PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::NIL, "restore"), PropertyInfo(Variant::BOOL, "cancel"));
+ cm.default_arguments.push_back(false);
+ BIND_VMETHOD(cm);
+
+ BIND_VMETHOD(MethodInfo(Variant::BOOL, "is_gizmo_handle_highlighted", GIZMO_REF, PropertyInfo(Variant::INT, "index")));
+
+#undef GIZMO_REF
+}
+
bool EditorSpatialGizmoPlugin::has_gizmo(Spatial *p_spatial) {
+ if (get_script_instance() && get_script_instance()->has_method("has_gizmo")) {
+ return get_script_instance()->call("has_gizmo", p_spatial);
+ }
return false;
}
Ref<EditorSpatialGizmo> EditorSpatialGizmoPlugin::create_gizmo(Spatial *p_spatial) {
+ if (get_script_instance() && get_script_instance()->has_method("create_gizmo")) {
+ return get_script_instance()->call("create_gizmo", p_spatial);
+ }
+
Ref<EditorSpatialGizmo> ref;
if (has_gizmo(p_spatial)) ref.instance();
return ref;
}
bool EditorSpatialGizmoPlugin::can_be_hidden() const {
+ if (get_script_instance() && get_script_instance()->has_method("can_be_hidden")) {
+ return get_script_instance()->call("can_be_hidden");
+ }
return true;
}
bool EditorSpatialGizmoPlugin::is_selectable_when_hidden() const {
+ if (get_script_instance() && get_script_instance()->has_method("is_selectable_when_hidden")) {
+ return get_script_instance()->call("is_selectable_when_hidden");
+ }
+ return false;
+}
+
+void EditorSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
+ if (get_script_instance() && get_script_instance()->has_method("redraw")) {
+ Ref<EditorSpatialGizmo> ref(p_gizmo);
+ get_script_instance()->call("redraw", ref);
+ }
+}
+
+String EditorSpatialGizmoPlugin::get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ if (get_script_instance() && get_script_instance()->has_method("get_handle_name")) {
+ return get_script_instance()->call("get_handle_name", p_gizmo, p_idx);
+ }
+ return "";
+}
+
+Variant EditorSpatialGizmoPlugin::get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ if (get_script_instance() && get_script_instance()->has_method("get_handle_value")) {
+ return get_script_instance()->call("get_handle_value", p_gizmo, p_idx);
+ }
+ return Variant();
+}
+
+void EditorSpatialGizmoPlugin::set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {
+ if (get_script_instance() && get_script_instance()->has_method("set_handle")) {
+ get_script_instance()->call("set_handle", p_gizmo, p_idx, p_camera, p_point);
+ }
+}
+
+void EditorSpatialGizmoPlugin::commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel) {
+ if (get_script_instance() && get_script_instance()->has_method("commit_handle")) {
+ get_script_instance()->call("commit_handle", p_gizmo, p_idx, p_restore, p_cancel);
+ }
+}
+
+bool EditorSpatialGizmoPlugin::is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const {
+ if (get_script_instance() && get_script_instance()->has_method("is_gizmo_handle_highlighted")) {
+ return get_script_instance()->call("is_gizmo_handle_highlighted", p_gizmo, p_idx);
+ }
return false;
}
@@ -5925,4 +6031,9 @@ EditorSpatialGizmoPlugin::EditorSpatialGizmoPlugin() {
}
EditorSpatialGizmoPlugin::~EditorSpatialGizmoPlugin() {
+ for (int i = 0; i < current_gizmos.size(); ++i) {
+ current_gizmos[i]->set_plugin(NULL);
+ current_gizmos[i]->get_spatial_node()->set_gizmo(NULL);
+ }
+ SpatialEditor::get_singleton()->update_all_gizmos();
}
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index c515a4aaf9..3b057fa840 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -615,7 +615,7 @@ private:
void _instance_scene();
void _init_indicators();
- void _init_gizmos_menu();
+ void _update_gizmos_menu();
void _init_grid();
void _finish_indicators();
void _finish_grid();
@@ -710,7 +710,8 @@ public:
return viewports[p_idx];
}
- void register_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> ref);
+ void add_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin);
+ void remove_gizmo_plugin(Ref<EditorSpatialGizmoPlugin> p_plugin);
void edit(Spatial *p_spatial);
void clear();
@@ -764,6 +765,7 @@ private:
HashMap<String, Vector<Ref<SpatialMaterial> > > materials;
protected:
+ static void _bind_methods();
virtual bool has_gizmo(Spatial *p_spatial);
virtual Ref<EditorSpatialGizmo> create_gizmo(Spatial *p_spatial);
@@ -773,18 +775,18 @@ public:
void create_handle_material(const String &p_name, bool p_billboard = false);
void add_material(const String &p_name, Ref<SpatialMaterial> p_material);
- Ref<SpatialMaterial> get_material(const String &p_name, EditorSpatialGizmo *p_gizmo = NULL);
+ Ref<SpatialMaterial> get_material(const String &p_name, const Ref<EditorSpatialGizmo> &p_gizmo = Ref<EditorSpatialGizmo>());
- virtual String get_name() const = 0;
+ virtual String get_name() const;
virtual bool can_be_hidden() const;
virtual bool is_selectable_when_hidden() const;
- virtual void redraw(EditorSpatialGizmo *p_gizmo) {}
- virtual String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const { return ""; }
- virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const { return Variant(); }
- virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point) {}
- virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false) {}
- virtual bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int idx) const { return false; }
+ virtual void redraw(EditorSpatialGizmo *p_gizmo);
+ virtual String get_handle_name(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ virtual Variant get_handle_value(EditorSpatialGizmo *p_gizmo, int p_idx) const;
+ virtual void set_handle(EditorSpatialGizmo *p_gizmo, int p_idx, Camera *p_camera, const Point2 &p_point);
+ virtual void commit_handle(EditorSpatialGizmo *p_gizmo, int p_idx, const Variant &p_restore, bool p_cancel = false);
+ virtual bool is_gizmo_handle_highlighted(const EditorSpatialGizmo *p_gizmo, int p_idx) const;
Ref<EditorSpatialGizmo> get_gizmo(Spatial *p_spatial);
void set_state(int p_state);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index d3a3289a18..b56c0bbc1b 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -516,6 +516,12 @@ void TileMapEditor::_update_palette() {
manual_palette->set_current(selected);
manual_palette->show();
}
+
+ if (sel_tile != TileMap::INVALID_CELL && tileset->tile_get_tile_mode(sel_tile) == TileSet::AUTO_TILE) {
+ manual_button->show();
+ } else {
+ manual_button->hide();
+ }
}
void TileMapEditor::_pick_tile(const Point2 &p_pos) {
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index cab9a4297d..297cf6754c 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -165,6 +165,11 @@ void TileSetEditor::_import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_
_import_node(p_scene, p_library);
}
+void TileSetEditor::_undo_redo_import_scene(Node *p_scene, bool p_merge) {
+
+ _import_scene(p_scene, tileset, p_merge);
+}
+
Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bool p_merge) {
_import_scene(p_base_scene, ml, p_merge);
@@ -173,6 +178,7 @@ Error TileSetEditor::update_library_file(Node *p_base_scene, Ref<TileSet> ml, bo
void TileSetEditor::_bind_methods() {
+ ClassDB::bind_method("_undo_redo_import_scene", &TileSetEditor::_undo_redo_import_scene);
ClassDB::bind_method("_on_tileset_toolbar_button_pressed", &TileSetEditor::_on_tileset_toolbar_button_pressed);
ClassDB::bind_method("_on_textures_added", &TileSetEditor::_on_textures_added);
ClassDB::bind_method("_on_tileset_toolbar_confirm", &TileSetEditor::_on_tileset_toolbar_confirm);
@@ -190,9 +196,16 @@ void TileSetEditor::_bind_methods() {
ClassDB::bind_method("_set_snap_step", &TileSetEditor::_set_snap_step);
ClassDB::bind_method("_set_snap_off", &TileSetEditor::_set_snap_off);
ClassDB::bind_method("_set_snap_sep", &TileSetEditor::_set_snap_sep);
+ ClassDB::bind_method("_validate_current_tile_id", &TileSetEditor::_validate_current_tile_id);
ClassDB::bind_method("_zoom_in", &TileSetEditor::_zoom_in);
ClassDB::bind_method("_zoom_out", &TileSetEditor::_zoom_out);
ClassDB::bind_method("_zoom_reset", &TileSetEditor::_zoom_reset);
+ ClassDB::bind_method("_select_edited_shape_coord", &TileSetEditor::_select_edited_shape_coord);
+
+ ClassDB::bind_method("edit", &TileSetEditor::edit);
+ ClassDB::bind_method("add_texture", &TileSetEditor::add_texture);
+ ClassDB::bind_method("remove_texture", &TileSetEditor::remove_texture);
+ ClassDB::bind_method("update_texture_list_icon", &TileSetEditor::update_texture_list_icon);
}
void TileSetEditor::_notification(int p_what) {
@@ -244,6 +257,7 @@ void TileSetEditor::_notification(int p_what) {
TileSetEditor::TileSetEditor(EditorNode *p_editor) {
editor = p_editor;
+ undo_redo = editor->get_undo_redo();
current_tile = -1;
VBoxContainer *left_container = memnew(VBoxContainer);
@@ -375,19 +389,6 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
tools[SHAPE_DELETE]->connect("pressed", this, "_on_tool_clicked", varray(SHAPE_DELETE));
toolbar->add_child(tools[SHAPE_DELETE]);
- separator_grid = memnew(VSeparator);
- toolbar->add_child(separator_grid);
- tools[SHAPE_KEEP_INSIDE_TILE] = memnew(ToolButton);
- tools[SHAPE_KEEP_INSIDE_TILE]->set_toggle_mode(true);
- tools[SHAPE_KEEP_INSIDE_TILE]->set_pressed(true);
- tools[SHAPE_KEEP_INSIDE_TILE]->set_tooltip(TTR("Keep polygon inside region Rect."));
- toolbar->add_child(tools[SHAPE_KEEP_INSIDE_TILE]);
- tools[TOOL_GRID_SNAP] = memnew(ToolButton);
- tools[TOOL_GRID_SNAP]->set_toggle_mode(true);
- tools[TOOL_GRID_SNAP]->set_tooltip(TTR("Enable snap and show grid (configurable via the Inspector)."));
- tools[TOOL_GRID_SNAP]->connect("toggled", this, "_on_grid_snap_toggled");
- toolbar->add_child(tools[TOOL_GRID_SNAP]);
-
spin_priority = memnew(SpinBox);
spin_priority->set_min(1);
spin_priority->set_max(255);
@@ -406,6 +407,19 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
spin_z_index->hide();
toolbar->add_child(spin_z_index);
+ separator_grid = memnew(VSeparator);
+ toolbar->add_child(separator_grid);
+ tools[SHAPE_KEEP_INSIDE_TILE] = memnew(ToolButton);
+ tools[SHAPE_KEEP_INSIDE_TILE]->set_toggle_mode(true);
+ tools[SHAPE_KEEP_INSIDE_TILE]->set_pressed(true);
+ tools[SHAPE_KEEP_INSIDE_TILE]->set_tooltip(TTR("Keep polygon inside region Rect."));
+ toolbar->add_child(tools[SHAPE_KEEP_INSIDE_TILE]);
+ tools[TOOL_GRID_SNAP] = memnew(ToolButton);
+ tools[TOOL_GRID_SNAP]->set_toggle_mode(true);
+ tools[TOOL_GRID_SNAP]->set_tooltip(TTR("Enable snap and show grid (configurable via the Inspector)."));
+ tools[TOOL_GRID_SNAP]->connect("toggled", this, "_on_grid_snap_toggled");
+ toolbar->add_child(tools[TOOL_GRID_SNAP]);
+
Control *separator = memnew(Control);
separator->set_h_size_flags(SIZE_EXPAND_FILL);
toolbar->add_child(separator);
@@ -481,7 +495,7 @@ TileSetEditor::TileSetEditor(EditorNode *p_editor) {
//---------------
helper = memnew(TilesetEditorContext(this));
- tile_names_opacity = 0;
+ tile_names_visible = false;
// config scale
max_scale = 10.0f;
@@ -502,7 +516,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
} break;
case TOOL_TILESET_REMOVE_TEXTURE: {
if (get_current_texture().is_valid()) {
- cd->set_text(TTR("Remove selected texture and ALL TILES which use it?"));
+ cd->set_text(TTR("Remove selected texture? This will remove all tiles which use it."));
cd->popup_centered(Size2(300, 60));
} else {
err_dialog->set_text(TTR("You haven't selected a texture to remove."));
@@ -511,7 +525,7 @@ void TileSetEditor::_on_tileset_toolbar_button_pressed(int p_index) {
} break;
case TOOL_TILESET_CREATE_SCENE: {
- cd->set_text(TTR("Create from scene?"));
+ cd->set_text(TTR("Create from scene? This will overwrite all current tiles."));
cd->popup_centered(Size2(300, 60));
} break;
case TOOL_TILESET_MERGE_SCENE: {
@@ -528,14 +542,18 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
RID current_rid = get_current_texture()->get_rid();
List<int> ids;
tileset->get_tile_list(&ids);
+
+ undo_redo->create_action(TTR("Remove Texture"));
for (List<int>::Element *E = ids.front(); E; E = E->next()) {
if (tileset->tile_get_texture(E->get())->get_rid() == current_rid) {
- tileset->remove_tile(E->get());
+ undo_redo->add_do_method(tileset.ptr(), "remove_tile", E->get());
+ _undo_tile_removal(E->get());
}
}
- texture_list->remove_item(texture_list->find_metadata(current_rid));
- texture_map.erase(current_rid);
- _on_texture_list_selected(-1);
+ undo_redo->add_do_method(this, "remove_texture", get_current_texture());
+ undo_redo->add_undo_method(this, "add_texture", get_current_texture());
+ undo_redo->add_undo_method(this, "update_texture_list_icon");
+ undo_redo->commit_action();
} break;
case TOOL_TILESET_MERGE_SCENE:
case TOOL_TILESET_CREATE_SCENE: {
@@ -544,9 +562,19 @@ void TileSetEditor::_on_tileset_toolbar_confirm() {
Node *scene = en->get_edited_scene();
if (!scene)
break;
- _import_scene(scene, tileset, option == TOOL_TILESET_MERGE_SCENE);
- edit(tileset);
+ List<int> ids;
+ tileset->get_tile_list(&ids);
+
+ undo_redo->create_action(TTR(option == TOOL_TILESET_MERGE_SCENE ? "Merge Tileset from Scene" : "Create Tileset from Scene"));
+ undo_redo->add_do_method(this, "_undo_redo_import_scene", scene, option == TOOL_TILESET_MERGE_SCENE);
+ undo_redo->add_undo_method(tileset.ptr(), "clear");
+ for (List<int>::Element *E = ids.front(); E; E = E->next()) {
+ _undo_tile_removal(E->get());
+ }
+ undo_redo->add_do_method(this, "edit", tileset);
+ undo_redo->add_undo_method(this, "edit", tileset);
+ undo_redo->commit_action();
} break;
}
}
@@ -580,9 +608,7 @@ void TileSetEditor::_on_textures_added(const PoolStringArray &p_paths) {
if (texture_map.has(t->get_rid())) {
invalid_count++;
} else {
- texture_list->add_item(t->get_path().get_file());
- texture_map.insert(t->get_rid(), t);
- texture_list->set_item_metadata(texture_list->get_item_count() - 1, t->get_rid());
+ add_texture(t);
}
}
@@ -631,8 +657,8 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
spin_z_index->hide();
} break;
case EDITMODE_COLLISION:
- case EDITMODE_NAVIGATION:
- case EDITMODE_OCCLUSION: {
+ case EDITMODE_OCCLUSION:
+ case EDITMODE_NAVIGATION: {
tools[TOOL_SELECT]->show();
separator_bitmask->hide();
@@ -653,7 +679,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
spin_priority->hide();
spin_z_index->hide();
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
} break;
case EDITMODE_BITMASK: {
tools[TOOL_SELECT]->show();
@@ -667,9 +693,7 @@ void TileSetEditor::_on_edit_mode_changed(int p_edit_mode) {
separator_delete->hide();
tools[SHAPE_DELETE]->hide();
- separator_grid->hide();
tools[SHAPE_KEEP_INSIDE_TILE]->hide();
- tools[TOOL_GRID_SNAP]->hide();
tools[TOOL_SELECT]->set_pressed(true);
tools[TOOL_SELECT]->set_tooltip(TTR("LMB: Set bit on.\nRMB: Set bit off.\nClick on another Tile to edit it."));
@@ -874,6 +898,9 @@ void TileSetEditor::_on_workspace_draw() {
draw_edited_region_subdivision();
} else {
int t_id = get_current_tile();
+ if (t_id < 0)
+ return;
+
Rect2i region;
if (draw_edited_region)
region = edited_region;
@@ -902,17 +929,16 @@ void TileSetEditor::_on_workspace_draw() {
}
void TileSetEditor::_on_workspace_process() {
- float a = tile_names_opacity;
- if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
- a += get_tree()->get_idle_process_time() * 2;
- } else {
- a -= get_tree()->get_idle_process_time() * 2;
- }
- a = CLAMP(a, 0, 1);
- if (a != tile_names_opacity)
+ if (Input::get_singleton()->is_key_pressed(KEY_ALT) || tools[VISIBLE_INFO]->is_pressed()) {
+ if (!tile_names_visible) {
+ tile_names_visible = true;
+ workspace_overlay->update();
+ }
+ } else if (tile_names_visible) {
+ tile_names_visible = false;
workspace_overlay->update();
- tile_names_opacity = a;
+ }
}
void TileSetEditor::_on_workspace_overlay_draw() {
@@ -924,7 +950,7 @@ void TileSetEditor::_on_workspace_overlay_draw() {
const Color COLOR_SINGLE = Color(0.988281, 0.909323, 0.266373);
const Color COLOR_ATLAS = Color(0.78653, 0.812835, 0.832031);
- if (tile_names_opacity > 0) {
+ if (tile_names_visible) {
RID current_texture_rid = get_current_texture()->get_rid();
List<int> *tiles = new List<int>();
tileset->get_tile_list(tiles);
@@ -941,13 +967,12 @@ void TileSetEditor::_on_workspace_overlay_draw() {
c = COLOR_AUTOTILE;
else if (tileset->tile_get_tile_mode(t_id) == TileSet::ATLAS_TILE)
c = COLOR_ATLAS;
- c.a = tile_names_opacity;
String tile_id_name = String::num(t_id, 0) + ": " + tileset->tile_get_name(t_id);
Ref<Font> font = get_font("font", "Label");
region.set_size(font->get_string_size(tile_id_name));
workspace_overlay->draw_rect(region, c);
region.position.y += region.size.y - 2;
- c = Color(0.1, 0.1, 0.1, tile_names_opacity);
+ c = Color(0.1, 0.1, 0.1);
workspace_overlay->draw_string(font, region.position, tile_id_name, c);
}
}
@@ -965,7 +990,6 @@ void TileSetEditor::_on_workspace_overlay_draw() {
}
}
-#define MIN_DISTANCE_SQUARED 6
void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if (tileset.is_null() || !get_current_texture().is_valid())
@@ -1044,29 +1068,49 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
edited_region.position -= WORKSPACE_MARGIN;
if (!edited_region.has_no_area()) {
if (get_current_tile() >= 0 && workspace_mode == WORKSPACE_EDIT) {
- tileset->tile_set_region(get_current_tile(), edited_region);
+ undo_redo->create_action(TTR("Set Tile Region"));
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_region", get_current_tile(), edited_region);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_region", get_current_tile(), tileset->tile_get_region(get_current_tile()));
+ edited_region = Rect2();
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
} else {
int t_id = tileset->get_last_unused_tile_id();
- tileset->create_tile(t_id);
- tileset->tile_set_texture(t_id, get_current_texture());
- tileset->tile_set_region(t_id, edited_region);
- tileset->tile_set_name(t_id, get_current_texture()->get_path().get_file() + " " + String::num(t_id, 0));
+ undo_redo->create_action(TTR("Create Tile"));
+ undo_redo->add_do_method(tileset.ptr(), "create_tile", t_id);
+ undo_redo->add_undo_method(tileset.ptr(), "remove_tile", t_id);
+ undo_redo->add_undo_method(this, "_validate_current_tile_id");
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_texture", t_id, get_current_texture());
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_region", t_id, edited_region);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_name", t_id, get_current_texture()->get_path().get_file() + " " + String::num(t_id, 0));
if (workspace_mode != WORKSPACE_CREATE_SINGLE) {
- tileset->autotile_set_size(t_id, snap_step);
- tileset->autotile_set_spacing(t_id, snap_separation.x);
- tileset->tile_set_tile_mode(t_id, workspace_mode == WORKSPACE_CREATE_AUTOTILE ? TileSet::AUTO_TILE : TileSet::ATLAS_TILE);
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_size", t_id, snap_step);
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_spacing", t_id, snap_separation.x);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_tile_mode", t_id, workspace_mode == WORKSPACE_CREATE_AUTOTILE ? TileSet::AUTO_TILE : TileSet::ATLAS_TILE);
}
- set_current_tile(t_id);
tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
edit_mode = EDITMODE_COLLISION;
+ edited_region = Rect2();
+
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
+
+ set_current_tile(t_id);
_on_workspace_mode_changed(WORKSPACE_EDIT);
}
+ } else {
+ edited_region = Rect2();
+ workspace->update();
+ workspace_overlay->update();
}
- edited_region = Rect2();
- workspace->update();
- workspace_overlay->update();
return;
}
} else if (mm.is_valid()) {
@@ -1079,8 +1123,8 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- if (workspace_mode == WORKSPACE_EDIT) {
+ if (workspace_mode == WORKSPACE_EDIT) {
if (get_current_tile() >= 0) {
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
@@ -1089,13 +1133,12 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && current_tile_region.has_point(mb->get_position())) {
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
- tileset->autotile_set_icon_coordinate(get_current_tile(), coord);
- Rect2 region = tileset->tile_get_region(get_current_tile());
- region.size = size;
- coord.x *= (spacing + size.x);
- coord.y *= (spacing + size.y);
- region.position += coord;
- workspace->update();
+ undo_redo->create_action(TTR("Set Tile Icon"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_icon_coordinate", get_current_tile(), coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_icon_coordinate", get_current_tile(), tileset->autotile_get_icon_coordinate(get_current_tile()));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
}
} break;
@@ -1153,14 +1196,22 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+
+ uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+ uint16_t new_mask = old_mask;
if (erasing) {
- mask &= ~bit;
+ new_mask &= ~bit;
} else {
- mask |= bit;
+ new_mask |= bit;
+ }
+ if (old_mask != new_mask) {
+ undo_redo->create_action(TTR("Edit Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, old_mask);
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
- tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
- workspace->update();
}
} else {
if ((erasing && mb->get_button_index() == BUTTON_RIGHT) || (!erasing && mb->get_button_index() == BUTTON_LEFT)) {
@@ -1216,14 +1267,22 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
}
- uint16_t mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+
+ uint16_t old_mask = tileset->autotile_get_bitmask(get_current_tile(), coord);
+ uint16_t new_mask = old_mask;
if (erasing) {
- mask &= ~bit;
+ new_mask &= ~bit;
} else {
- mask |= bit;
+ new_mask |= bit;
+ }
+ if (old_mask != new_mask) {
+ undo_redo->create_action(TTR("Edit Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, new_mask);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), coord, old_mask);
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
- tileset->autotile_set_bitmask(get_current_tile(), coord, mask);
- workspace->update();
}
}
} break;
@@ -1238,13 +1297,14 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
shape_anchor.x *= (size.x + spacing);
shape_anchor.y *= (size.y + spacing);
}
+ const real_t grab_threshold = EDITOR_GET("editors/poly_editor/point_grab_radius");
shape_anchor += current_tile_region.position;
if (tools[TOOL_SELECT]->is_pressed()) {
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
if (edit_mode != EDITMODE_PRIORITY && current_shape.size() > 0) {
for (int i = 0; i < current_shape.size(); i++) {
- if ((current_shape[i] - mb->get_position()).length_squared() <= MIN_DISTANCE_SQUARED) {
+ if ((current_shape[i] - mb->get_position()).length_squared() <= grab_threshold) {
dragging_point = i;
workspace->update();
return;
@@ -1255,20 +1315,7 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
Vector2 coord((int)((mb->get_position().x - current_tile_region.position.x) / (spacing + size.x)), (int)((mb->get_position().y - current_tile_region.position.y) / (spacing + size.y)));
if (edited_shape_coord != coord) {
edited_shape_coord = coord;
- edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord);
- edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord);
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
- bool found_collision_shape = false;
- for (int i = 0; i < sd.size(); i++) {
- if (sd[i].autotile_coord == coord) {
- edited_collision_shape = sd[i].shape;
- found_collision_shape = true;
- break;
- }
- }
- if (!found_collision_shape)
- edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
}
}
workspace->update();
@@ -1287,9 +1334,12 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
points.push_back(p - shape_anchor);
}
- edited_collision_shape->set_points(points);
-
- workspace->update();
+ undo_redo->create_action(TTR("Edit Collision Polygon"));
+ undo_redo->add_do_method(edited_collision_shape.ptr(), "set_points", points);
+ undo_redo->add_undo_method(edited_collision_shape.ptr(), "set_points", edited_collision_shape->get_points());
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} else if (edit_mode == EDITMODE_OCCLUSION) {
if (dragging_point >= 0) {
@@ -1304,9 +1354,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
w = PoolVector<Vector2>::Write();
- edited_occlusion_shape->set_polygon(polygon);
- workspace->update();
+ undo_redo->create_action(TTR("Edit Occlusion Polygon"));
+ undo_redo->add_do_method(edited_occlusion_shape.ptr(), "set_polygon", polygon);
+ undo_redo->add_undo_method(edited_occlusion_shape.ptr(), "set_polygon", edited_occlusion_shape->get_polygon());
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} else if (edit_mode == EDITMODE_NAVIGATION) {
if (dragging_point >= 0) {
@@ -1323,10 +1377,15 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
w = PoolVector<Vector2>::Write();
- edited_navigation_shape->set_vertices(polygon);
- edited_navigation_shape->add_polygon(indices);
- workspace->update();
+ undo_redo->create_action(TTR("Edit Navigation Polygon"));
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "set_vertices", polygon);
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "set_vertices", edited_navigation_shape->get_vertices());
+ undo_redo->add_do_method(edited_navigation_shape.ptr(), "add_polygon", indices);
+ undo_redo->add_undo_method(edited_navigation_shape.ptr(), "add_polygon", edited_navigation_shape->get_polygon(0));
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
}
}
@@ -1337,14 +1396,13 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
}
}
} else if (tools[SHAPE_NEW_POLYGON]->is_pressed()) {
-
if (mb.is_valid()) {
if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
Vector2 pos = mb->get_position();
pos = snap_point(pos);
if (creating_shape) {
if (current_shape.size() > 0) {
- if ((pos - current_shape[0]).length_squared() <= MIN_DISTANCE_SQUARED) {
+ if ((pos - current_shape[0]).length_squared() <= grab_threshold) {
if (current_shape.size() > 2) {
close_shape(shape_anchor);
workspace->update();
@@ -1355,60 +1413,16 @@ void TileSetEditor::_on_workspace_input(const Ref<InputEvent> &p_ie) {
current_shape.push_back(pos);
workspace->update();
} else {
- int t_id = get_current_tile();
- if (t_id >= 0) {
- if (edit_mode == EDITMODE_COLLISION) {
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(t_id);
- for (int i = 0; i < sd.size(); i++) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE || sd[i].autotile_coord == edited_shape_coord) {
- Ref<ConvexPolygonShape2D> shape = sd[i].shape;
-
- if (!shape.is_null()) {
- sd.remove(i);
- tileset->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- workspace->update();
- }
- break;
- }
- }
- } else if (edit_mode == EDITMODE_OCCLUSION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Map<Vector2, Ref<OccluderPolygon2D> > map = tileset->autotile_get_light_oclusion_map(t_id);
- for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
- break;
- }
- }
- } else
- tileset->tile_set_light_occluder(t_id, Ref<OccluderPolygon2D>());
-
- edited_occlusion_shape = Ref<OccluderPolygon2D>();
- workspace->update();
- } else if (edit_mode == EDITMODE_NAVIGATION) {
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
- Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id);
- for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
- if (E->key() == edited_shape_coord) {
- tileset->autotile_set_navigation_polygon(t_id, Ref<NavigationPolygon>(), edited_shape_coord);
- break;
- }
- }
- } else
- tileset->tile_set_navigation_polygon(t_id, Ref<NavigationPolygon>());
- edited_navigation_shape = Ref<NavigationPolygon>();
- workspace->update();
- }
- }
-
creating_shape = true;
current_shape.resize(0);
current_shape.push_back(snap_point(pos));
+ workspace->update();
}
- } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT && current_shape.size() > 2) {
+ } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_RIGHT) {
if (creating_shape) {
- close_shape(shape_anchor);
+ creating_shape = false;
+ _select_edited_shape_coord();
+ workspace->update();
}
}
} else if (mm.is_valid()) {
@@ -1428,14 +1442,27 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
if (p_tool == BITMASK_COPY) {
bitmask_map_copy = tileset->autotile_get_bitmask_map(get_current_tile());
} else if (p_tool == BITMASK_PASTE) {
- tileset->autotile_clear_bitmask_map(get_current_tile());
+ undo_redo->create_action(TTR("Paste Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
for (Map<Vector2, uint16_t>::Element *E = bitmask_map_copy.front(); E; E = E->next()) {
- tileset->autotile_set_bitmask(get_current_tile(), E->key(), E->value());
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
}
- workspace->update();
+ for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
+ }
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
} else if (p_tool == BITMASK_CLEAR) {
- tileset->autotile_clear_bitmask_map(get_current_tile());
- workspace->update();
+ undo_redo->create_action(TTR("Clear Tile Bitmask"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_clear_bitmask_map", get_current_tile());
+ for (Map<Vector2, uint16_t>::Element *E = tileset->autotile_get_bitmask_map(get_current_tile()).front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", get_current_tile(), E->key(), E->value());
+ }
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
} else if (p_tool == SHAPE_DELETE) {
if (creating_shape) {
creating_shape = false;
@@ -1444,11 +1471,17 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
} else {
switch (edit_mode) {
case EDITMODE_REGION: {
- if (workspace_mode == WORKSPACE_EDIT && get_current_tile() >= 0) {
- tileset->remove_tile(get_current_tile());
- set_current_tile(-1);
- workspace->update();
- workspace_overlay->update();
+ int t_id = get_current_tile();
+ if (workspace_mode == WORKSPACE_EDIT && t_id >= 0) {
+ undo_redo->create_action(TTR("Remove Tile"));
+ undo_redo->add_do_method(tileset.ptr(), "remove_tile", t_id);
+ _undo_tile_removal(t_id);
+ undo_redo->add_do_method(this, "_validate_current_tile_id");
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->add_do_method(workspace_overlay, "update");
+ undo_redo->add_undo_method(workspace_overlay, "update");
+ undo_redo->commit_action();
}
tool_workspacemode[WORKSPACE_EDIT]->set_pressed(true);
workspace_mode = WORKSPACE_EDIT;
@@ -1456,37 +1489,50 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
} break;
case EDITMODE_COLLISION: {
if (!edited_collision_shape.is_null()) {
- Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
- int index = -1;
+ // Necessary to get the version that returns a Array instead of a Vector.
+ Array sd = tileset->call("tile_get_shapes", get_current_tile());
for (int i = 0; i < sd.size(); i++) {
- if (sd[i].shape == edited_collision_shape) {
- index = i;
+ if (sd[i].get("shape") == edited_collision_shape) {
+ undo_redo->create_action(TTR("Remove Collision Polygon"));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate());
+ sd.remove(i);
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
break;
}
}
- if (index >= 0) {
- sd.remove(index);
- tileset->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape = Ref<Shape2D>();
- current_shape.resize(0);
- workspace->update();
+ }
+ } break;
+ case EDITMODE_OCCLUSION: {
+ if (!edited_occlusion_shape.is_null()) {
+ undo_redo->create_action(TTR("Remove Occlusion Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), Ref<OccluderPolygon2D>());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), tileset->tile_get_light_occluder(get_current_tile()));
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord), edited_shape_coord);
}
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} break;
case EDITMODE_NAVIGATION: {
if (!edited_navigation_shape.is_null()) {
- tileset->autotile_set_navigation_polygon(get_current_tile(), Ref<NavigationPolygon>(), edited_shape_coord);
- edited_navigation_shape = Ref<NavigationPolygon>();
- current_shape.resize(0);
- workspace->update();
- }
- } break;
- case EDITMODE_OCCLUSION: {
- if (!edited_occlusion_shape.is_null()) {
- tileset->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
- edited_occlusion_shape = Ref<OccluderPolygon2D>();
- current_shape.resize(0);
- workspace->update();
+ undo_redo->create_action(TTR("Remove Navigation Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), Ref<NavigationPolygon>());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), tileset->tile_get_navigation_polygon(get_current_tile()));
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), Ref<NavigationPolygon>(), edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ }
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
} break;
default: {}
@@ -1503,13 +1549,27 @@ void TileSetEditor::_on_tool_clicked(int p_tool) {
}
void TileSetEditor::_on_priority_changed(float val) {
- tileset->autotile_set_subtile_priority(get_current_tile(), edited_shape_coord, (int)val);
- workspace->update();
+ if ((int)val == tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord))
+ return;
+
+ undo_redo->create_action(TTR("Edit Tile Priority"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_subtile_priority", get_current_tile(), edited_shape_coord, (int)val);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_subtile_priority", get_current_tile(), edited_shape_coord, tileset->autotile_get_subtile_priority(get_current_tile(), edited_shape_coord));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
void TileSetEditor::_on_z_index_changed(float val) {
- tileset->autotile_set_z_index(get_current_tile(), edited_shape_coord, (int)val);
- workspace->update();
+ if ((int)val == tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord))
+ return;
+
+ undo_redo->create_action(TTR("Edit Tile Z Index"));
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_z_index", get_current_tile(), edited_shape_coord, (int)val);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_z_index", get_current_tile(), edited_shape_coord, tileset->autotile_get_z_index(get_current_tile(), edited_shape_coord));
+ undo_redo->add_do_method(workspace, "update");
+ undo_redo->add_undo_method(workspace, "update");
+ undo_redo->commit_action();
}
void TileSetEditor::_on_grid_snap_toggled(bool p_val) {
@@ -1535,6 +1595,63 @@ void TileSetEditor::_set_snap_sep(Vector2 p_val) {
workspace->update();
}
+void TileSetEditor::_validate_current_tile_id() {
+ if (get_current_tile() >= 0 && !tileset->has_tile(get_current_tile()))
+ set_current_tile(-1);
+}
+
+void TileSetEditor::_select_edited_shape_coord() {
+ select_coord(edited_shape_coord);
+}
+
+void TileSetEditor::_undo_tile_removal(int p_id) {
+ undo_redo->add_undo_method(tileset.ptr(), "create_tile", p_id);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_name", p_id, tileset->tile_get_name(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_normal_map", p_id, tileset->tile_get_normal_map(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_texture_offset", p_id, tileset->tile_get_texture_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_material", p_id, tileset->tile_get_material(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_modulate", p_id, tileset->tile_get_modulate(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_occluder_offset", p_id, tileset->tile_get_occluder_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon_offset", p_id, tileset->tile_get_navigation_polygon_offset(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shape_offset", p_id, 0, tileset->tile_get_shape_offset(p_id, 0));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shape_transform", p_id, 0, tileset->tile_get_shape_transform(p_id, 0));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_z_index", p_id, tileset->tile_get_z_index(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_texture", p_id, tileset->tile_get_texture(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_region", p_id, tileset->tile_get_region(p_id));
+ // Necessary to get the version that returns a Array instead of a Vector.
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", p_id, tileset->call("tile_get_shapes", p_id));
+ if (tileset->tile_get_tile_mode(p_id) == TileSet::SINGLE_TILE) {
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", p_id, tileset->tile_get_light_occluder(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", p_id, tileset->tile_get_navigation_polygon(p_id));
+ } else {
+ Map<Vector2, Ref<OccluderPolygon2D> > oclusion_map = tileset->autotile_get_light_oclusion_map(p_id);
+ for (Map<Vector2, Ref<OccluderPolygon2D> >::Element *E = oclusion_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", p_id, E->value(), E->key());
+ }
+ Map<Vector2, Ref<NavigationPolygon> > navigation_map = tileset->autotile_get_navigation_map(p_id);
+ for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = navigation_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", p_id, E->value(), E->key());
+ }
+ Map<Vector2, uint16_t> bitmask_map = tileset->autotile_get_bitmask_map(p_id);
+ for (Map<Vector2, uint16_t>::Element *E = bitmask_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask", p_id, E->key(), E->value());
+ }
+ Map<Vector2, int> priority_map = tileset->autotile_get_priority_map(p_id);
+ for (Map<Vector2, int>::Element *E = priority_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_subtile_priority", p_id, E->key(), E->value());
+ }
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_icon_coordinate", p_id, tileset->autotile_get_icon_coordinate(p_id));
+ Map<Vector2, int> z_map = tileset->autotile_get_z_index_map(p_id);
+ for (Map<Vector2, int>::Element *E = z_map.front(); E; E = E->next()) {
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_z_index", p_id, E->key(), E->value());
+ }
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_tile_mode", p_id, tileset->tile_get_tile_mode(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_size", p_id, tileset->autotile_get_size(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_spacing", p_id, tileset->autotile_get_spacing(p_id));
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_bitmask_mode", p_id, tileset->autotile_get_bitmask_mode(p_id));
+ }
+}
+
void TileSetEditor::_zoom_in() {
float scale = workspace->get_scale().x;
if (scale < max_scale) {
@@ -1545,7 +1662,6 @@ void TileSetEditor::_zoom_in() {
}
}
void TileSetEditor::_zoom_out() {
-
float scale = workspace->get_scale().x;
if (scale > min_scale) {
scale /= scale_ratio;
@@ -1770,7 +1886,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_collision_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_collision_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1784,11 +1900,14 @@ void TileSetEditor::draw_polygon_shapes() {
if (polygon.size() > 2) {
workspace->draw_polygon(polygon, colors);
}
+
if (coord == edited_shape_coord || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::SINGLE_TILE) {
- for (int j = 0; j < shape->get_points().size() - 1; j++) {
- workspace->draw_line(shape->get_points()[j] + anchor, shape->get_points()[j + 1] + anchor, c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
-
if (shape == edited_collision_shape) {
draw_handles = true;
}
@@ -1807,16 +1926,25 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Color> colors;
Vector2 anchor = WORKSPACE_MARGIN;
anchor += tileset->tile_get_region(get_current_tile()).position;
- for (int j = 0; j < shape->get_polygon().size(); j++) {
- polygon.push_back(shape->get_polygon()[j] + anchor);
- colors.push_back(c_bg);
+ if (!creating_shape && shape == edited_occlusion_shape && current_shape.size() > 2) {
+ for (int j = 0; j < current_shape.size(); j++) {
+ polygon.push_back(current_shape[j]);
+ colors.push_back(c_bg);
+ }
+ } else {
+ for (int j = 0; j < shape->get_polygon().size(); j++) {
+ polygon.push_back(shape->get_polygon()[j] + anchor);
+ colors.push_back(c_bg);
+ }
}
workspace->draw_polygon(polygon, colors);
- for (int j = 0; j < shape->get_polygon().size() - 1; j++) {
- workspace->draw_line(shape->get_polygon()[j] + anchor, shape->get_polygon()[j + 1] + anchor, c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1] + anchor, shape->get_polygon()[0] + anchor, c_border, 1, true);
if (shape == edited_occlusion_shape) {
draw_handles = true;
}
@@ -1845,7 +1973,7 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_occlusion_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_occlusion_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
@@ -1857,11 +1985,14 @@ void TileSetEditor::draw_polygon_shapes() {
}
}
workspace->draw_polygon(polygon, colors);
+
if (coord == edited_shape_coord) {
- for (int j = 0; j < shape->get_polygon().size() - 1; j++) {
- workspace->draw_line(shape->get_polygon()[j] + anchor, shape->get_polygon()[j + 1] + anchor, c_border, 1, true);
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
+ }
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
}
- workspace->draw_line(shape->get_polygon()[shape->get_polygon().size() - 1] + anchor, shape->get_polygon()[0] + anchor, c_border, 1, true);
if (shape == edited_occlusion_shape) {
draw_handles = true;
}
@@ -1882,24 +2013,30 @@ void TileSetEditor::draw_polygon_shapes() {
Vector<Color> colors;
Vector2 anchor = WORKSPACE_MARGIN;
anchor += tileset->tile_get_region(get_current_tile()).position;
- PoolVector<Vector2> vertices = shape->get_vertices();
- for (int j = 0; j < shape->get_polygon(0).size(); j++) {
- polygon.push_back(vertices[shape->get_polygon(0)[j]] + anchor);
- colors.push_back(c_bg);
+ if (!creating_shape && shape == edited_navigation_shape && current_shape.size() > 2) {
+ for (int j = 0; j < current_shape.size(); j++) {
+ polygon.push_back(current_shape[j]);
+ colors.push_back(c_bg);
+ }
+ } else {
+ PoolVector<Vector2> vertices = shape->get_vertices();
+ for (int j = 0; j < shape->get_polygon(0).size(); j++) {
+ polygon.push_back(vertices[shape->get_polygon(0)[j]] + anchor);
+ colors.push_back(c_bg);
+ }
}
workspace->draw_polygon(polygon, colors);
- if (shape->get_polygon_count() > 0) {
- PoolVector<Vector2> vertices = shape->get_vertices();
- for (int j = 0; j < shape->get_polygon(0).size() - 1; j++) {
- workspace->draw_line(vertices[shape->get_polygon(0)[j]] + anchor, vertices[shape->get_polygon(0)[j + 1]] + anchor, c_border, 1, true);
- }
- if (shape == edited_navigation_shape) {
- draw_handles = true;
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
}
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
+ }
+ if (shape == edited_navigation_shape) {
+ draw_handles = true;
}
}
-
} else {
Map<Vector2, Ref<NavigationPolygon> > map = tileset->autotile_get_navigation_map(t_id);
for (Map<Vector2, Ref<NavigationPolygon> >::Element *E = map.front(); E; E = E->next()) {
@@ -1924,12 +2061,12 @@ void TileSetEditor::draw_polygon_shapes() {
}
Vector<Vector2> polygon;
Vector<Color> colors;
- if (shape == edited_navigation_shape && current_shape.size() > 2) {
+ if (!creating_shape && shape == edited_navigation_shape && current_shape.size() > 2) {
for (int j = 0; j < current_shape.size(); j++) {
polygon.push_back(current_shape[j]);
colors.push_back(c_bg);
}
- } else if (shape->get_polygon_count() > 0) {
+ } else {
PoolVector<Vector2> vertices = shape->get_vertices();
for (int j = 0; j < shape->get_polygon(0).size(); j++) {
polygon.push_back(vertices[shape->get_polygon(0)[j]] + anchor);
@@ -1937,15 +2074,16 @@ void TileSetEditor::draw_polygon_shapes() {
}
}
workspace->draw_polygon(polygon, colors);
+
if (coord == edited_shape_coord) {
- if (shape->get_polygon_count() > 0) {
- PoolVector<Vector2> vertices = shape->get_vertices();
- for (int j = 0; j < shape->get_polygon(0).size() - 1; j++) {
- workspace->draw_line(vertices[shape->get_polygon(0)[j]] + anchor, vertices[shape->get_polygon(0)[j + 1]] + anchor, c_border, 1, true);
- }
- if (shape == edited_navigation_shape) {
- draw_handles = true;
+ if (!creating_shape) {
+ for (int j = 0; j < polygon.size() - 1; j++) {
+ workspace->draw_line(polygon[j], polygon[j + 1], c_border, 1, true);
}
+ workspace->draw_line(polygon[polygon.size() - 1], polygon[0], c_border, 1, true);
+ }
+ if (shape == edited_navigation_shape) {
+ draw_handles = true;
}
}
}
@@ -1954,11 +2092,13 @@ void TileSetEditor::draw_polygon_shapes() {
} break;
default: {}
}
+
if (creating_shape) {
for (int j = 0; j < current_shape.size() - 1; j++) {
workspace->draw_line(current_shape[j], current_shape[j + 1], Color(0, 1, 1), 1, true);
}
workspace->draw_line(current_shape[current_shape.size() - 1], snap_point(workspace->get_local_mouse_position()), Color(0, 1, 1), 1, true);
+ draw_handles = true;
}
}
@@ -1987,16 +2127,29 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_points(segments);
+ undo_redo->create_action(TTR("Create Collision Polygon"));
+ // Necessary to get the version that returns a Array instead of a Vector.
+ Array sd = tileset->call("tile_get_shapes", get_current_tile());
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd.duplicate());
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].get("shape") == edited_collision_shape) {
+ sd.remove(i);
+ break;
+ }
+ }
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_shapes", get_current_tile(), sd);
if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->tile_add_shape(get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
+ undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D(), false, edited_shape_coord);
else
- tileset->tile_add_shape(get_current_tile(), shape, Transform2D());
-
- edited_collision_shape = shape;
+ undo_redo->add_do_method(tileset.ptr(), "tile_add_shape", get_current_tile(), shape, Transform2D());
+ tools[TOOL_SELECT]->set_pressed(true);
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
+ } else {
+ tools[TOOL_SELECT]->set_pressed(true);
+ workspace->update();
}
-
- tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
} else if (edit_mode == EDITMODE_OCCLUSION) {
Ref<OccluderPolygon2D> shape = memnew(OccluderPolygon2D);
@@ -2011,13 +2164,18 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
w = PoolVector<Vector2>::Write();
shape->set_polygon(polygon);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->autotile_set_light_occluder(get_current_tile(), shape, edited_shape_coord);
- else
- tileset->tile_set_light_occluder(get_current_tile(), shape);
- edited_occlusion_shape = shape;
+ undo_redo->create_action(TTR("Create Occlusion Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), shape, edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_light_occluder", get_current_tile(), tileset->autotile_get_light_occluder(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), shape);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_light_occluder", get_current_tile(), tileset->tile_get_light_occluder(get_current_tile()));
+ }
tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
} else if (edit_mode == EDITMODE_NAVIGATION) {
Ref<NavigationPolygon> shape = memnew(NavigationPolygon);
@@ -2035,13 +2193,18 @@ void TileSetEditor::close_shape(const Vector2 &shape_anchor) {
shape->set_vertices(polygon);
shape->add_polygon(indices);
- if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE)
- tileset->autotile_set_navigation_polygon(get_current_tile(), shape, edited_shape_coord);
- else
- tileset->tile_set_navigation_polygon(get_current_tile(), shape);
- edited_navigation_shape = shape;
+ undo_redo->create_action(TTR("Create Navigation Polygon"));
+ if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ undo_redo->add_do_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), shape, edited_shape_coord);
+ undo_redo->add_undo_method(tileset.ptr(), "autotile_set_navigation_polygon", get_current_tile(), tileset->autotile_get_navigation_polygon(get_current_tile(), edited_shape_coord), edited_shape_coord);
+ } else {
+ undo_redo->add_do_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), shape);
+ undo_redo->add_undo_method(tileset.ptr(), "tile_set_navigation_polygon", get_current_tile(), tileset->tile_get_navigation_polygon(get_current_tile()));
+ }
tools[TOOL_SELECT]->set_pressed(true);
- workspace->update();
+ undo_redo->add_do_method(this, "_select_edited_shape_coord");
+ undo_redo->add_undo_method(this, "_select_edited_shape_coord");
+ undo_redo->commit_action();
}
tileset->_change_notify("");
}
@@ -2086,6 +2249,23 @@ void TileSetEditor::select_coord(const Vector2 &coord) {
}
}
} else {
+ Vector<TileSet::ShapeData> sd = tileset->tile_get_shapes(get_current_tile());
+ bool found_collision_shape = false;
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].autotile_coord == coord) {
+ if (edited_collision_shape != sd[i].shape)
+ edited_collision_shape = sd[i].shape;
+ found_collision_shape = true;
+ break;
+ }
+ }
+ if (!found_collision_shape)
+ edited_collision_shape = Ref<ConvexPolygonShape2D>(NULL);
+ if (edited_occlusion_shape != tileset->autotile_get_light_occluder(get_current_tile(), coord))
+ edited_occlusion_shape = tileset->autotile_get_light_occluder(get_current_tile(), coord);
+ if (edited_navigation_shape != tileset->autotile_get_navigation_polygon(get_current_tile(), coord))
+ edited_navigation_shape = tileset->autotile_get_navigation_polygon(get_current_tile(), coord);
+
int spacing = tileset->autotile_get_spacing(get_current_tile());
Vector2 size = tileset->autotile_get_size(get_current_tile());
Vector2 shape_anchor = coord;
@@ -2156,6 +2336,24 @@ Vector2 TileSetEditor::snap_point(const Vector2 &point) {
return p;
}
+void TileSetEditor::add_texture(Ref<Texture> p_texture) {
+ texture_list->add_item(p_texture->get_path().get_file());
+ texture_map.insert(p_texture->get_rid(), p_texture);
+ texture_list->set_item_metadata(texture_list->get_item_count() - 1, p_texture->get_rid());
+}
+
+void TileSetEditor::remove_texture(Ref<Texture> p_texture) {
+ texture_list->remove_item(texture_list->find_metadata(p_texture->get_rid()));
+ texture_map.erase(p_texture->get_rid());
+
+ _validate_current_tile_id();
+
+ if (!get_current_texture().is_valid()) {
+ _on_texture_list_selected(-1);
+ workspace_overlay->update();
+ }
+}
+
void TileSetEditor::update_texture_list() {
Ref<Texture> selected_texture = get_current_texture();
@@ -2172,9 +2370,7 @@ void TileSetEditor::update_texture_list() {
}
if (!texture_map.has(tileset->tile_get_texture(E->get())->get_rid())) {
- texture_list->add_item(tileset->tile_get_texture(E->get())->get_path().get_file());
- texture_map.insert(tileset->tile_get_texture(E->get())->get_rid(), tileset->tile_get_texture(E->get()));
- texture_list->set_item_metadata(texture_list->get_item_count() - 1, tileset->tile_get_texture(E->get())->get_rid());
+ add_texture(tileset->tile_get_texture(E->get()));
}
}
for (int i = 0; i < ids_to_remove.size(); i++) {
@@ -2188,7 +2384,9 @@ void TileSetEditor::update_texture_list() {
} else if (get_current_texture().is_valid()) {
_on_texture_list_selected(texture_list->find_metadata(get_current_texture()->get_rid()));
} else {
+ _validate_current_tile_id();
_on_texture_list_selected(-1);
+ workspace_overlay->update();
}
update_texture_list_icon();
helper->_change_notify("");
@@ -2260,11 +2458,11 @@ void TileSetEditor::update_workspace_tile_mode() {
tool_editmode[EDITMODE_BITMASK]->hide();
tool_editmode[EDITMODE_PRIORITY]->hide();
tool_editmode[EDITMODE_Z_INDEX]->hide();
- } else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE || tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
+ } else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::AUTO_TILE) {
if (edit_mode == EDITMODE_ICON)
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
else
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
} else if (tileset->tile_get_tile_mode(get_current_tile()) == TileSet::ATLAS_TILE) {
if (tool_editmode[EDITMODE_PRIORITY]->is_pressed() || tool_editmode[EDITMODE_BITMASK]->is_pressed()) {
tool_editmode[EDITMODE_COLLISION]->set_pressed(true);
@@ -2273,7 +2471,7 @@ void TileSetEditor::update_workspace_tile_mode() {
if (edit_mode == EDITMODE_ICON)
select_coord(tileset->autotile_get_icon_coordinate(get_current_tile()));
else
- select_coord(edited_shape_coord);
+ _select_edited_shape_coord();
tool_editmode[EDITMODE_BITMASK]->hide();
tool_editmode[EDITMODE_PRIORITY]->hide();
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 276e23f9ee..e4e01750bd 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -94,6 +94,7 @@ class TileSetEditor : public HSplitContainer {
Ref<TileSet> tileset;
TilesetEditorContext *helper;
EditorNode *editor;
+ UndoRedo *undo_redo;
ConfirmationDialog *cd;
AcceptDialog *err_dialog;
@@ -107,7 +108,7 @@ class TileSetEditor : public HSplitContainer {
bool creating_shape;
int dragging_point;
- float tile_names_opacity;
+ bool tile_names_visible;
Vector2 region_from;
Rect2 edited_region;
bool draw_edited_region;
@@ -151,10 +152,14 @@ class TileSetEditor : public HSplitContainer {
void update_texture_list();
void update_texture_list_icon();
+ void add_texture(Ref<Texture> p_texture);
+ void remove_texture(Ref<Texture> p_texture);
+
Ref<Texture> get_current_texture();
static void _import_node(Node *p_node, Ref<TileSet> p_library);
static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge);
+ void _undo_redo_import_scene(Node *p_scene, bool p_merge);
protected:
static void _bind_methods();
@@ -186,6 +191,10 @@ private:
void _set_snap_off(Vector2 p_val);
void _set_snap_sep(Vector2 p_val);
+ void _validate_current_tile_id();
+ void _select_edited_shape_coord();
+ void _undo_tile_removal(int p_id);
+
void _zoom_in();
void _zoom_out();
void _zoom_reset();
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index ac728e8d7c..c92efd401d 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -447,13 +447,14 @@ private:
ProjectSettings::CustomMap edited_settings;
edited_settings["application/config/name"] = project_name->get_text();
- if (current->save_custom(dir.plus_file("/project.godot"), edited_settings, Vector<String>(), true)) {
+ if (current->save_custom(dir.plus_file("project.godot"), edited_settings, Vector<String>(), true) != OK) {
set_message(TTR("Couldn't edit project.godot in project path."), MESSAGE_ERROR);
}
}
hide();
- emit_signal("project_renamed");
+ emit_signal("projects_updated");
+
} else {
if (mode == MODE_IMPORT) {
@@ -474,12 +475,12 @@ private:
initial_settings["application/config/icon"] = "res://icon.png";
initial_settings["rendering/environment/default_environment"] = "res://default_env.tres";
- if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("/project.godot"), initial_settings, Vector<String>(), false)) {
+ if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
} else {
- ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+ ResourceSaver::save(dir.plus_file("icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
- FileAccess *f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
+ FileAccess *f = FileAccess::open(dir.plus_file("default_env.tres"), FileAccess::WRITE);
if (!f) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
} else {
@@ -587,7 +588,7 @@ private:
dialog_error->popup_centered_minsize();
} else if (!project_path->get_text().ends_with(".zip")) {
- dialog_error->set_text(TTR("Package Installed Successfully!"));
+ dialog_error->set_text(TTR("Package installed successfully!"));
dialog_error->popup_centered_minsize();
}
}
@@ -651,7 +652,7 @@ protected:
ClassDB::bind_method("_install_path_selected", &ProjectDialog::_install_path_selected);
ClassDB::bind_method("_browse_install_path", &ProjectDialog::_browse_install_path);
ADD_SIGNAL(MethodInfo("project_created"));
- ADD_SIGNAL(MethodInfo("project_renamed"));
+ ADD_SIGNAL(MethodInfo("projects_updated"));
}
public:
@@ -852,6 +853,7 @@ public:
fdialog->connect("file_selected", this, "_file_selected");
fdialog_install->connect("dir_selected", this, "_install_path_selected");
fdialog_install->connect("file_selected", this, "_install_path_selected");
+
set_hide_on_ok(false);
mode = MODE_NEW;
@@ -864,15 +866,17 @@ struct ProjectItem {
String project;
String path;
String conf;
+ int config_version;
uint64_t last_modified;
bool favorite;
bool grayed;
bool ordered_latest_modification;
ProjectItem() {}
- ProjectItem(const String &p_project, const String &p_path, const String &p_conf, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) {
+ ProjectItem(const String &p_project, const String &p_path, const String &p_conf, int p_config_version, uint64_t p_last_modified, bool p_favorite = false, bool p_grayed = false, const bool p_ordered_latest_modification = true) {
project = p_project;
path = p_path;
conf = p_conf;
+ config_version = p_config_version;
last_modified = p_last_modified;
favorite = p_favorite;
grayed = p_grayed;
@@ -982,7 +986,7 @@ void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
_update_project_buttons();
if (mb->is_doubleclick())
- _open_project(); //open if doubleclicked
+ _open_selected_projects_ask(); //open if doubleclicked
}
}
@@ -1004,7 +1008,7 @@ void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
case KEY_ENTER: {
- _open_project();
+ _open_selected_projects_ask();
} break;
case KEY_DELETE: {
@@ -1187,6 +1191,7 @@ void ProjectManager::_load_recent_projects() {
String project = _name.get_slice("/", 1);
String conf = path.plus_file("project.godot");
+ int config_version = 0; // Assume 0 until we know better
bool favorite = (_name.begins_with("favorite_projects/")) ? true : false;
bool grayed = false;
@@ -1204,7 +1209,7 @@ void ProjectManager::_load_recent_projects() {
grayed = true;
}
- ProjectItem item(project, path, conf, last_modified, favorite, grayed, set_ordered_latest_modification);
+ ProjectItem item(project, path, conf, config_version, last_modified, favorite, grayed, set_ordered_latest_modification);
if (favorite)
favorite_projects.push_back(item);
else
@@ -1231,14 +1236,11 @@ void ProjectManager::_load_recent_projects() {
String project = item.project;
String path = item.path;
String conf = item.conf;
- bool is_favorite = item.favorite;
- bool is_grayed = item.grayed;
Ref<ConfigFile> cf = memnew(ConfigFile);
Error cf_err = cf->load(conf);
String project_name = TTR("Unnamed Project");
-
if (cf_err == OK && cf->has_section_key("application", "config/name")) {
project_name = static_cast<String>(cf->get_value("application", "config/name")).xml_unescape();
}
@@ -1247,8 +1249,16 @@ void ProjectManager::_load_recent_projects() {
continue;
Ref<Texture> icon;
- if (cf_err == OK && cf->has_section_key("application", "config/icon")) {
- String appicon = cf->get_value("application", "config/icon");
+ String main_scene;
+
+ if (cf_err == OK) {
+ item.config_version = (int)cf->get_value("", "config_version", 0);
+ if (item.config_version > ProjectSettings::CONFIG_VERSION) {
+ // Comes from an incompatible (more recent) Godot version, grey it out
+ item.grayed = true;
+ }
+
+ String appicon = cf->get_value("application", "config/icon", "");
if (appicon != "") {
Ref<Image> img;
img.instance();
@@ -1262,21 +1272,19 @@ void ProjectManager::_load_recent_projects() {
icon = it;
}
}
+
+ main_scene = cf->get_value("application", "run/main_scene", "");
}
if (icon.is_null()) {
icon = get_icon("DefaultProjectIcon", "EditorIcons");
}
- String main_scene;
- if (cf_err == OK && cf->has_section_key("application", "run/main_scene")) {
- main_scene = cf->get_value("application", "run/main_scene");
- } else {
- main_scene = "";
- }
-
selected_list_copy.erase(project);
+ bool is_favorite = item.favorite;
+ bool is_grayed = item.grayed;
+
HBoxContainer *hb = memnew(HBoxContainer);
hb->set_meta("name", project);
hb->set_meta("main_scene", main_scene);
@@ -1354,7 +1362,7 @@ void ProjectManager::_load_recent_projects() {
tabs->set_current_tab(0);
}
-void ProjectManager::_on_project_renamed() {
+void ProjectManager::_on_projects_updated() {
_load_recent_projects();
}
@@ -1374,7 +1382,7 @@ void ProjectManager::_on_project_created(const String &dir) {
_load_recent_projects();
_update_scroll_position(dir);
}
- _open_project();
+ _open_selected_projects_ask();
}
void ProjectManager::_update_scroll_position(const String &dir) {
@@ -1396,14 +1404,18 @@ void ProjectManager::_update_scroll_position(const String &dir) {
}
}
-void ProjectManager::_open_project_confirm() {
+void ProjectManager::_confirm_update_settings() {
+ _open_selected_projects();
+}
- for (Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
+void ProjectManager::_open_selected_projects() {
+
+ for (const Map<String, String>::Element *E = selected_list.front(); E; E = E->next()) {
const String &selected = E->key();
String path = EditorSettings::get_singleton()->get("projects/" + selected);
- String conf = path + "/project.godot";
+ String conf = path.plus_file("project.godot");
if (!FileAccess::exists(conf)) {
- dialog_error->set_text(TTR("Can't open project"));
+ dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
dialog_error->popup_centered_minsize();
return;
}
@@ -1431,7 +1443,7 @@ void ProjectManager::_open_project_confirm() {
get_tree()->quit();
}
-void ProjectManager::_open_project() {
+void ProjectManager::_open_selected_projects_ask() {
if (selected_list.size() < 1) {
return;
@@ -1440,9 +1452,40 @@ void ProjectManager::_open_project() {
if (selected_list.size() > 1) {
multi_open_ask->set_text(TTR("Are you sure to open more than one project?"));
multi_open_ask->popup_centered_minsize();
- } else {
- _open_project_confirm();
+ return;
+ }
+
+ // Update the project settings or don't open
+ String path = EditorSettings::get_singleton()->get("projects/" + selected_list.front()->key());
+ String conf = path.plus_file("project.godot");
+
+ // FIXME: We already parse those in _load_recent_projects, we could instead make
+ // its `projects` list global and reuse its parsed metadata here.
+ Ref<ConfigFile> cf = memnew(ConfigFile);
+ Error cf_err = cf->load(conf);
+
+ if (cf_err != OK) {
+ dialog_error->set_text(vformat(TTR("Can't open project at '%s'."), path));
+ dialog_error->popup_centered_minsize();
+ return;
+ }
+
+ int config_version = (int)cf->get_value("", "config_version", 0);
+ // Check if we need to convert project settings from an earlier engine version
+ if (config_version < ProjectSettings::CONFIG_VERSION) {
+ ask_update_settings->set_text(vformat(TTR("The following project settings file was generated by an older engine version, and needs to be converted for this version:\n\n%s\n\nDo you want to convert it?\nWarning: You will not be able to open the project with previous versions of the engine anymore."), conf));
+ ask_update_settings->popup_centered_minsize();
+ return;
+ }
+ // Check if the file was generated by a newer, incompatible engine version
+ if (config_version > ProjectSettings::CONFIG_VERSION) {
+ dialog_error->set_text(vformat(TTR("Can't open project at '%s'.") + "\n" + TTR("The project settings were created by a newer engine version, whose settings are not compatible with this version."), path));
+ dialog_error->popup_centered_minsize();
+ return;
}
+
+ // Open if the project is up-to-date
+ _open_selected_projects();
}
void ProjectManager::_run_project_confirm() {
@@ -1687,8 +1730,8 @@ void ProjectManager::_scan_multiple_folders(PoolStringArray p_files) {
void ProjectManager::_bind_methods() {
- ClassDB::bind_method("_open_project", &ProjectManager::_open_project);
- ClassDB::bind_method("_open_project_confirm", &ProjectManager::_open_project_confirm);
+ ClassDB::bind_method("_open_selected_projects_ask", &ProjectManager::_open_selected_projects_ask);
+ ClassDB::bind_method("_open_selected_projects", &ProjectManager::_open_selected_projects);
ClassDB::bind_method("_run_project", &ProjectManager::_run_project);
ClassDB::bind_method("_run_project_confirm", &ProjectManager::_run_project_confirm);
ClassDB::bind_method("_show_project", &ProjectManager::_show_project);
@@ -1703,7 +1746,7 @@ void ProjectManager::_bind_methods() {
ClassDB::bind_method("_restart_confirm", &ProjectManager::_restart_confirm);
ClassDB::bind_method("_exit_dialog", &ProjectManager::_exit_dialog);
ClassDB::bind_method("_load_recent_projects", &ProjectManager::_load_recent_projects);
- ClassDB::bind_method("_on_project_renamed", &ProjectManager::_on_project_renamed);
+ ClassDB::bind_method("_on_projects_updated", &ProjectManager::_on_projects_updated);
ClassDB::bind_method("_on_project_created", &ProjectManager::_on_project_created);
ClassDB::bind_method("_update_scroll_position", &ProjectManager::_update_scroll_position);
ClassDB::bind_method("_panel_draw", &ProjectManager::_panel_draw);
@@ -1713,6 +1756,7 @@ void ProjectManager::_bind_methods() {
ClassDB::bind_method("_install_project", &ProjectManager::_install_project);
ClassDB::bind_method("_files_dropped", &ProjectManager::_files_dropped);
ClassDB::bind_method("_open_asset_library", &ProjectManager::_open_asset_library);
+ ClassDB::bind_method("_confirm_update_settings", &ProjectManager::_confirm_update_settings);
ClassDB::bind_method(D_METHOD("_scan_multiple_folders", "files"), &ProjectManager::_scan_multiple_folders);
}
@@ -1890,7 +1934,7 @@ ProjectManager::ProjectManager() {
Button *open = memnew(Button);
open->set_text(TTR("Edit"));
tree_vb->add_child(open);
- open->connect("pressed", this, "_open_project");
+ open->connect("pressed", this, "_open_selected_projects_ask");
open_btn = open;
Button *run = memnew(Button);
@@ -1997,38 +2041,37 @@ ProjectManager::ProjectManager() {
language_restart_ask->get_ok()->set_text(TTR("Restart Now"));
language_restart_ask->get_ok()->connect("pressed", this, "_restart_confirm");
language_restart_ask->get_cancel()->set_text(TTR("Continue"));
-
gui_base->add_child(language_restart_ask);
erase_ask = memnew(ConfirmationDialog);
erase_ask->get_ok()->set_text(TTR("Remove"));
erase_ask->get_ok()->connect("pressed", this, "_erase_project_confirm");
-
gui_base->add_child(erase_ask);
multi_open_ask = memnew(ConfirmationDialog);
multi_open_ask->get_ok()->set_text(TTR("Edit"));
- multi_open_ask->get_ok()->connect("pressed", this, "_open_project_confirm");
-
+ multi_open_ask->get_ok()->connect("pressed", this, "_open_selected_projects");
gui_base->add_child(multi_open_ask);
multi_run_ask = memnew(ConfirmationDialog);
multi_run_ask->get_ok()->set_text(TTR("Run"));
multi_run_ask->get_ok()->connect("pressed", this, "_run_project_confirm");
-
gui_base->add_child(multi_run_ask);
multi_scan_ask = memnew(ConfirmationDialog);
multi_scan_ask->get_ok()->set_text(TTR("Scan"));
-
gui_base->add_child(multi_scan_ask);
+ ask_update_settings = memnew(ConfirmationDialog);
+ ask_update_settings->get_ok()->connect("pressed", this, "_confirm_update_settings");
+ gui_base->add_child(ask_update_settings);
+
OS::get_singleton()->set_low_processor_usage_mode(true);
npdialog = memnew(ProjectDialog);
gui_base->add_child(npdialog);
- npdialog->connect("project_renamed", this, "_on_project_renamed");
+ npdialog->connect("projects_updated", this, "_on_projects_updated");
npdialog->connect("project_created", this, "_on_project_created");
_load_recent_projects();
diff --git a/editor/project_manager.h b/editor/project_manager.h
index e0a0932cf8..84248090f8 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -49,43 +49,41 @@ class ProjectManager : public Control {
Button *rename_btn;
Button *run_btn;
- FileDialog *scan_dir;
-
EditorAssetLibrary *asset_library;
ProjectListFilter *project_filter;
ProjectListFilter *project_order_filter;
+ FileDialog *scan_dir;
ConfirmationDialog *language_restart_ask;
ConfirmationDialog *erase_ask;
ConfirmationDialog *multi_open_ask;
ConfirmationDialog *multi_run_ask;
ConfirmationDialog *multi_scan_ask;
+ ConfirmationDialog *ask_update_settings;
+ ConfirmationDialog *open_templates;
AcceptDialog *run_error_diag;
AcceptDialog *dialog_error;
ProjectDialog *npdialog;
+
ScrollContainer *scroll;
VBoxContainer *scroll_children;
- Map<String, String> selected_list; // name -> main_scene
- String last_clicked;
- bool importing;
-
HBoxContainer *projects_hb;
-
TabContainer *tabs;
OptionButton *language_btn;
-
Control *gui_base;
- ConfirmationDialog *open_templates;
+ Map<String, String> selected_list; // name -> main_scene
+ String last_clicked;
+ bool importing;
void _open_asset_library();
void _scan_projects();
void _run_project();
void _run_project_confirm();
- void _open_project();
- void _open_project_confirm();
+ void _open_selected_projects();
+ void _open_selected_projects_ask();
void _show_project(const String &p_path);
void _import_project();
void _new_project();
@@ -98,9 +96,11 @@ class ProjectManager : public Control {
void _exit_dialog();
void _scan_begin(const String &p_base);
+ void _confirm_update_settings();
+
void _load_recent_projects();
void _on_project_created(const String &dir);
- void _on_project_renamed();
+ void _on_projects_updated();
void _update_scroll_position(const String &dir);
void _scan_dir(DirAccess *da, float pos, float total, List<String> *r_projects);
diff --git a/main/main.cpp b/main/main.cpp
index f6902ffe23..da9c2c3198 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -1029,8 +1029,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
message_queue = memnew(MessageQueue);
- ProjectSettings::get_singleton()->register_global_defaults();
-
if (p_second_phase)
return setup2();
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 0117bb375f..3dc9f3fce5 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -304,6 +304,7 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
m_result->shape = cp.m_index1;
B_TO_G(cp.getPositionWorldOnB(), m_result->point);
+ B_TO_G(cp.m_normalWorldOnB, m_result->normal);
m_rest_info_bt_point = cp.getPositionWorldOnB();
m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
} else {
diff --git a/modules/bullet/shape_bullet.cpp b/modules/bullet/shape_bullet.cpp
index 2027d8e1eb..55dcd9c323 100644
--- a/modules/bullet/shape_bullet.cpp
+++ b/modules/bullet/shape_bullet.cpp
@@ -487,7 +487,7 @@ void HeightMapShapeBullet::set_data(const Variant &p_data) {
PoolByteArray im_data = l_image->get_data();
- l_heights.resize(l_image->get_width() * l_image->get_width());
+ l_heights.resize(l_image->get_width() * l_image->get_height());
PoolRealArray::Write w = l_heights.write();
PoolByteArray::Read r = im_data.read();
diff --git a/modules/csg/csg_gizmos.cpp b/modules/csg/csg_gizmos.cpp
index 5864d02615..0d600166b6 100644
--- a/modules/csg/csg_gizmos.cpp
+++ b/modules/csg/csg_gizmos.cpp
@@ -356,5 +356,5 @@ void CSGShapeSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
EditorPluginCSG::EditorPluginCSG(EditorNode *p_editor) {
Ref<CSGShapeSpatialGizmoPlugin> gizmo_plugin = Ref<CSGShapeSpatialGizmoPlugin>(memnew(CSGShapeSpatialGizmoPlugin));
- SpatialEditor::get_singleton()->register_gizmo_plugin(gizmo_plugin);
+ SpatialEditor::get_singleton()->add_gizmo_plugin(gizmo_plugin);
}
diff --git a/modules/gridmap/doc_classes/GridMap.xml b/modules/gridmap/doc_classes/GridMap.xml
index 9b9088dd82..dd2628a7fd 100644
--- a/modules/gridmap/doc_classes/GridMap.xml
+++ b/modules/gridmap/doc_classes/GridMap.xml
@@ -192,13 +192,13 @@
</methods>
<members>
<member name="cell_center_x" type="bool" setter="set_center_x" getter="get_center_x">
- If [code]true[/code] grid items are centered on the X axis.
+ If [code]true[/code], grid items are centered on the X axis.
</member>
<member name="cell_center_y" type="bool" setter="set_center_y" getter="get_center_y">
- If [code]true[/code] grid items are centered on the Y axis.
+ If [code]true[/code], grid items are centered on the Y axis.
</member>
<member name="cell_center_z" type="bool" setter="set_center_z" getter="get_center_z">
- If [code]true[/code] grid items are centered on the Z axis.
+ If [code]true[/code], grid items are centered on the Z axis.
</member>
<member name="cell_octant_size" type="int" setter="set_octant_size" getter="get_octant_size">
The size of each octant measured in number of cells. This applies to all three axis.
diff --git a/modules/mono/config.py b/modules/mono/config.py
index 189699cca8..a81ecfce70 100644
--- a/modules/mono/config.py
+++ b/modules/mono/config.py
@@ -142,7 +142,9 @@ def configure(env):
copy_file(mono_bin_path, 'bin', mono_dll_name + '.dll')
else:
- sharedlib_ext = '.dylib' if sys.platform == 'darwin' else '.so'
+ is_apple = (sys.platform == 'darwin' or "osxcross" in env)
+
+ sharedlib_ext = '.dylib' if is_apple else '.so'
mono_root = ''
mono_lib_path = ''
@@ -154,7 +156,7 @@ def configure(env):
if os.getenv('MONO64_PREFIX'):
mono_root = os.getenv('MONO64_PREFIX')
- if not mono_root and sys.platform == 'darwin':
+ if not mono_root and is_apple:
# Try with some known directories under OSX
hint_dirs = ['/Library/Frameworks/Mono.framework/Versions/Current', '/usr/local/var/homebrew/linked/mono']
for hint_dir in hint_dirs:
@@ -190,14 +192,14 @@ def configure(env):
if mono_static:
mono_lib_file = os.path.join(mono_lib_path, 'lib' + mono_lib + '.a')
- if sys.platform == 'darwin':
+ if is_apple:
env.Append(LINKFLAGS=['-Wl,-force_load,' + mono_lib_file])
else:
env.Append(LINKFLAGS=['-Wl,-whole-archive', mono_lib_file, '-Wl,-no-whole-archive'])
else:
env.Append(LIBS=[mono_lib])
- if sys.platform == 'darwin':
+ if is_apple:
env.Append(LIBS=['iconv', 'pthread'])
else:
env.Append(LIBS=['m', 'rt', 'dl', 'pthread'])
diff --git a/modules/mono/editor/godotsharp_editor.cpp b/modules/mono/editor/godotsharp_editor.cpp
index cce86efbf5..a1f4bb3c4c 100644
--- a/modules/mono/editor/godotsharp_editor.cpp
+++ b/modules/mono/editor/godotsharp_editor.cpp
@@ -251,6 +251,14 @@ Error GodotSharpEditor::open_in_external_editor(const Ref<Script> &p_script, int
// Try to search it again if it wasn't found last time or if it was removed from its location
vscode_path = path_which("code");
}
+ if (vscode_path.empty() || !FileAccess::exists(vscode_path)) {
+ // On some Linux distro the executable has the name vscode
+ vscode_path = path_which("vscode");
+ }
+ if (vscode_path.empty() || !FileAccess::exists(vscode_path)) {
+ // Executable name when installing VSCode directly from MS on Linux
+ vscode_path = path_which("visual-studio-code");
+ }
List<String> args;
diff --git a/modules/mono/glue/Managed/Files/Color.cs b/modules/mono/glue/Managed/Files/Color.cs
index fc5bb010a9..88fa3323c2 100644
--- a/modules/mono/glue/Managed/Files/Color.cs
+++ b/modules/mono/glue/Managed/Files/Color.cs
@@ -104,17 +104,26 @@ namespace Godot
}
}
- private static readonly Color black = new Color(0f, 0f, 0f);
-
- public Color Black
+ public static Color ColorN(string name, float alpha = 1f)
{
- get
+ name = name.Replace(" ", String.Empty);
+ name = name.Replace("-", String.Empty);
+ name = name.Replace("_", String.Empty);
+ name = name.Replace("'", String.Empty);
+ name = name.Replace(".", String.Empty);
+ name = name.ToLower();
+
+ if (!Colors.namedColors.ContainsKey(name))
{
- return black;
+ throw new ArgumentOutOfRangeException($"Invalid Color Name: {name}");
}
+
+ Color color = Colors.namedColors[name];
+ color.a = alpha;
+ return color;
}
- public float this [int index]
+ public float this[int index]
{
get
{
@@ -380,7 +389,7 @@ namespace Godot
return txt;
}
- // Constructors
+ // Constructors
public Color(float r, float g, float b, float a = 1.0f)
{
this.r = r;
diff --git a/modules/mono/glue/Managed/Files/Colors.cs b/modules/mono/glue/Managed/Files/Colors.cs
new file mode 100644
index 0000000000..bc2a1a3bd7
--- /dev/null
+++ b/modules/mono/glue/Managed/Files/Colors.cs
@@ -0,0 +1,303 @@
+using System;
+using System.Collections.Generic;
+
+namespace Godot
+{
+ public static class Colors
+ {
+ // Color names and values are derived from core/color_names.inc
+ internal static readonly Dictionary<string, Color> namedColors = new Dictionary<string, Color> {
+ {"aliceblue", new Color(0.94f, 0.97f, 1.00f)},
+ {"antiquewhite", new Color(0.98f, 0.92f, 0.84f)},
+ {"aqua", new Color(0.00f, 1.00f, 1.00f)},
+ {"aquamarine", new Color(0.50f, 1.00f, 0.83f)},
+ {"azure", new Color(0.94f, 1.00f, 1.00f)},
+ {"beige", new Color(0.96f, 0.96f, 0.86f)},
+ {"bisque", new Color(1.00f, 0.89f, 0.77f)},
+ {"black", new Color(0.00f, 0.00f, 0.00f)},
+ {"blanchedalmond", new Color(1.00f, 0.92f, 0.80f)},
+ {"blue", new Color(0.00f, 0.00f, 1.00f)},
+ {"blueviolet", new Color(0.54f, 0.17f, 0.89f)},
+ {"brown", new Color(0.65f, 0.16f, 0.16f)},
+ {"burlywood", new Color(0.87f, 0.72f, 0.53f)},
+ {"cadetblue", new Color(0.37f, 0.62f, 0.63f)},
+ {"chartreuse", new Color(0.50f, 1.00f, 0.00f)},
+ {"chocolate", new Color(0.82f, 0.41f, 0.12f)},
+ {"coral", new Color(1.00f, 0.50f, 0.31f)},
+ {"cornflower", new Color(0.39f, 0.58f, 0.93f)},
+ {"cornsilk", new Color(1.00f, 0.97f, 0.86f)},
+ {"crimson", new Color(0.86f, 0.08f, 0.24f)},
+ {"cyan", new Color(0.00f, 1.00f, 1.00f)},
+ {"darkblue", new Color(0.00f, 0.00f, 0.55f)},
+ {"darkcyan", new Color(0.00f, 0.55f, 0.55f)},
+ {"darkgoldenrod", new Color(0.72f, 0.53f, 0.04f)},
+ {"darkgray", new Color(0.66f, 0.66f, 0.66f)},
+ {"darkgreen", new Color(0.00f, 0.39f, 0.00f)},
+ {"darkkhaki", new Color(0.74f, 0.72f, 0.42f)},
+ {"darkmagenta", new Color(0.55f, 0.00f, 0.55f)},
+ {"darkolivegreen", new Color(0.33f, 0.42f, 0.18f)},
+ {"darkorange", new Color(1.00f, 0.55f, 0.00f)},
+ {"darkorchid", new Color(0.60f, 0.20f, 0.80f)},
+ {"darkred", new Color(0.55f, 0.00f, 0.00f)},
+ {"darksalmon", new Color(0.91f, 0.59f, 0.48f)},
+ {"darkseagreen", new Color(0.56f, 0.74f, 0.56f)},
+ {"darkslateblue", new Color(0.28f, 0.24f, 0.55f)},
+ {"darkslategray", new Color(0.18f, 0.31f, 0.31f)},
+ {"darkturquoise", new Color(0.00f, 0.81f, 0.82f)},
+ {"darkviolet", new Color(0.58f, 0.00f, 0.83f)},
+ {"deeppink", new Color(1.00f, 0.08f, 0.58f)},
+ {"deepskyblue", new Color(0.00f, 0.75f, 1.00f)},
+ {"dimgray", new Color(0.41f, 0.41f, 0.41f)},
+ {"dodgerblue", new Color(0.12f, 0.56f, 1.00f)},
+ {"firebrick", new Color(0.70f, 0.13f, 0.13f)},
+ {"floralwhite", new Color(1.00f, 0.98f, 0.94f)},
+ {"forestgreen", new Color(0.13f, 0.55f, 0.13f)},
+ {"fuchsia", new Color(1.00f, 0.00f, 1.00f)},
+ {"gainsboro", new Color(0.86f, 0.86f, 0.86f)},
+ {"ghostwhite", new Color(0.97f, 0.97f, 1.00f)},
+ {"gold", new Color(1.00f, 0.84f, 0.00f)},
+ {"goldenrod", new Color(0.85f, 0.65f, 0.13f)},
+ {"gray", new Color(0.75f, 0.75f, 0.75f)},
+ {"green", new Color(0.00f, 1.00f, 0.00f)},
+ {"greenyellow", new Color(0.68f, 1.00f, 0.18f)},
+ {"honeydew", new Color(0.94f, 1.00f, 0.94f)},
+ {"hotpink", new Color(1.00f, 0.41f, 0.71f)},
+ {"indianred", new Color(0.80f, 0.36f, 0.36f)},
+ {"indigo", new Color(0.29f, 0.00f, 0.51f)},
+ {"ivory", new Color(1.00f, 1.00f, 0.94f)},
+ {"khaki", new Color(0.94f, 0.90f, 0.55f)},
+ {"lavender", new Color(0.90f, 0.90f, 0.98f)},
+ {"lavenderblush", new Color(1.00f, 0.94f, 0.96f)},
+ {"lawngreen", new Color(0.49f, 0.99f, 0.00f)},
+ {"lemonchiffon", new Color(1.00f, 0.98f, 0.80f)},
+ {"lightblue", new Color(0.68f, 0.85f, 0.90f)},
+ {"lightcoral", new Color(0.94f, 0.50f, 0.50f)},
+ {"lightcyan", new Color(0.88f, 1.00f, 1.00f)},
+ {"lightgoldenrod", new Color(0.98f, 0.98f, 0.82f)},
+ {"lightgray", new Color(0.83f, 0.83f, 0.83f)},
+ {"lightgreen", new Color(0.56f, 0.93f, 0.56f)},
+ {"lightpink", new Color(1.00f, 0.71f, 0.76f)},
+ {"lightsalmon", new Color(1.00f, 0.63f, 0.48f)},
+ {"lightseagreen", new Color(0.13f, 0.70f, 0.67f)},
+ {"lightskyblue", new Color(0.53f, 0.81f, 0.98f)},
+ {"lightslategray", new Color(0.47f, 0.53f, 0.60f)},
+ {"lightsteelblue", new Color(0.69f, 0.77f, 0.87f)},
+ {"lightyellow", new Color(1.00f, 1.00f, 0.88f)},
+ {"lime", new Color(0.00f, 1.00f, 0.00f)},
+ {"limegreen", new Color(0.20f, 0.80f, 0.20f)},
+ {"linen", new Color(0.98f, 0.94f, 0.90f)},
+ {"magenta", new Color(1.00f, 0.00f, 1.00f)},
+ {"maroon", new Color(0.69f, 0.19f, 0.38f)},
+ {"mediumaquamarine", new Color(0.40f, 0.80f, 0.67f)},
+ {"mediumblue", new Color(0.00f, 0.00f, 0.80f)},
+ {"mediumorchid", new Color(0.73f, 0.33f, 0.83f)},
+ {"mediumpurple", new Color(0.58f, 0.44f, 0.86f)},
+ {"mediumseagreen", new Color(0.24f, 0.70f, 0.44f)},
+ {"mediumslateblue", new Color(0.48f, 0.41f, 0.93f)},
+ {"mediumspringgreen", new Color(0.00f, 0.98f, 0.60f)},
+ {"mediumturquoise", new Color(0.28f, 0.82f, 0.80f)},
+ {"mediumvioletred", new Color(0.78f, 0.08f, 0.52f)},
+ {"midnightblue", new Color(0.10f, 0.10f, 0.44f)},
+ {"mintcream", new Color(0.96f, 1.00f, 0.98f)},
+ {"mistyrose", new Color(1.00f, 0.89f, 0.88f)},
+ {"moccasin", new Color(1.00f, 0.89f, 0.71f)},
+ {"navajowhite", new Color(1.00f, 0.87f, 0.68f)},
+ {"navyblue", new Color(0.00f, 0.00f, 0.50f)},
+ {"oldlace", new Color(0.99f, 0.96f, 0.90f)},
+ {"olive", new Color(0.50f, 0.50f, 0.00f)},
+ {"olivedrab", new Color(0.42f, 0.56f, 0.14f)},
+ {"orange", new Color(1.00f, 0.65f, 0.00f)},
+ {"orangered", new Color(1.00f, 0.27f, 0.00f)},
+ {"orchid", new Color(0.85f, 0.44f, 0.84f)},
+ {"palegoldenrod", new Color(0.93f, 0.91f, 0.67f)},
+ {"palegreen", new Color(0.60f, 0.98f, 0.60f)},
+ {"paleturquoise", new Color(0.69f, 0.93f, 0.93f)},
+ {"palevioletred", new Color(0.86f, 0.44f, 0.58f)},
+ {"papayawhip", new Color(1.00f, 0.94f, 0.84f)},
+ {"peachpuff", new Color(1.00f, 0.85f, 0.73f)},
+ {"peru", new Color(0.80f, 0.52f, 0.25f)},
+ {"pink", new Color(1.00f, 0.75f, 0.80f)},
+ {"plum", new Color(0.87f, 0.63f, 0.87f)},
+ {"powderblue", new Color(0.69f, 0.88f, 0.90f)},
+ {"purple", new Color(0.63f, 0.13f, 0.94f)},
+ {"rebeccapurple", new Color(0.40f, 0.20f, 0.60f)},
+ {"red", new Color(1.00f, 0.00f, 0.00f)},
+ {"rosybrown", new Color(0.74f, 0.56f, 0.56f)},
+ {"royalblue", new Color(0.25f, 0.41f, 0.88f)},
+ {"saddlebrown", new Color(0.55f, 0.27f, 0.07f)},
+ {"salmon", new Color(0.98f, 0.50f, 0.45f)},
+ {"sandybrown", new Color(0.96f, 0.64f, 0.38f)},
+ {"seagreen", new Color(0.18f, 0.55f, 0.34f)},
+ {"seashell", new Color(1.00f, 0.96f, 0.93f)},
+ {"sienna", new Color(0.63f, 0.32f, 0.18f)},
+ {"silver", new Color(0.75f, 0.75f, 0.75f)},
+ {"skyblue", new Color(0.53f, 0.81f, 0.92f)},
+ {"slateblue", new Color(0.42f, 0.35f, 0.80f)},
+ {"slategray", new Color(0.44f, 0.50f, 0.56f)},
+ {"snow", new Color(1.00f, 0.98f, 0.98f)},
+ {"springgreen", new Color(0.00f, 1.00f, 0.50f)},
+ {"steelblue", new Color(0.27f, 0.51f, 0.71f)},
+ {"tan", new Color(0.82f, 0.71f, 0.55f)},
+ {"teal", new Color(0.00f, 0.50f, 0.50f)},
+ {"thistle", new Color(0.85f, 0.75f, 0.85f)},
+ {"tomato", new Color(1.00f, 0.39f, 0.28f)},
+ {"turquoise", new Color(0.25f, 0.88f, 0.82f)},
+ {"violet", new Color(0.93f, 0.51f, 0.93f)},
+ {"webgreen", new Color(0.00f, 0.50f, 0.00f)},
+ {"webgray", new Color(0.50f, 0.50f, 0.50f)},
+ {"webmaroon", new Color(0.50f, 0.00f, 0.00f)},
+ {"webpurple", new Color(0.50f, 0.00f, 0.50f)},
+ {"wheat", new Color(0.96f, 0.87f, 0.70f)},
+ {"white", new Color(1.00f, 1.00f, 1.00f)},
+ {"whitesmoke", new Color(0.96f, 0.96f, 0.96f)},
+ {"yellow", new Color(1.00f, 1.00f, 0.00f)},
+ {"yellowgreen", new Color(0.60f, 0.80f, 0.20f)},
+ };
+
+ public static Color AliceBlue { get { return namedColors["aliceblue"]; } }
+ public static Color AntiqueWhite { get { return namedColors["antiquewhite"]; } }
+ public static Color Aqua { get { return namedColors["aqua"]; } }
+ public static Color Aquamarine { get { return namedColors["aquamarine"]; } }
+ public static Color Azure { get { return namedColors["azure"]; } }
+ public static Color Beige { get { return namedColors["beige"]; } }
+ public static Color Bisque { get { return namedColors["bisque"]; } }
+ public static Color Black { get { return namedColors["black"]; } }
+ public static Color BlanchedAlmond { get { return namedColors["blanchedalmond"]; } }
+ public static Color Blue { get { return namedColors["blue"]; } }
+ public static Color BlueViolet { get { return namedColors["blueviolet"]; } }
+ public static Color Brown { get { return namedColors["brown"]; } }
+ public static Color BurlyWood { get { return namedColors["burlywood"]; } }
+ public static Color CadetBlue { get { return namedColors["cadetblue"]; } }
+ public static Color Chartreuse { get { return namedColors["chartreuse"]; } }
+ public static Color Chocolate { get { return namedColors["chocolate"]; } }
+ public static Color Coral { get { return namedColors["coral"]; } }
+ public static Color Cornflower { get { return namedColors["cornflower"]; } }
+ public static Color Cornsilk { get { return namedColors["cornsilk"]; } }
+ public static Color Crimson { get { return namedColors["crimson"]; } }
+ public static Color Cyan { get { return namedColors["cyan"]; } }
+ public static Color DarkBlue { get { return namedColors["darkblue"]; } }
+ public static Color DarkCyan { get { return namedColors["darkcyan"]; } }
+ public static Color DarkGoldenrod { get { return namedColors["darkgoldenrod"]; } }
+ public static Color DarkGray { get { return namedColors["darkgray"]; } }
+ public static Color DarkGreen { get { return namedColors["darkgreen"]; } }
+ public static Color DarkKhaki { get { return namedColors["darkkhaki"]; } }
+ public static Color DarkMagenta { get { return namedColors["darkmagenta"]; } }
+ public static Color DarkOliveGreen { get { return namedColors["darkolivegreen"]; } }
+ public static Color DarkOrange { get { return namedColors["darkorange"]; } }
+ public static Color DarkOrchid { get { return namedColors["darkorchid"]; } }
+ public static Color DarkRed { get { return namedColors["darkred"]; } }
+ public static Color DarkSalmon { get { return namedColors["darksalmon"]; } }
+ public static Color DarkSeagreen { get { return namedColors["darkseagreen"]; } }
+ public static Color DarkSlateBlue { get { return namedColors["darkslateblue"]; } }
+ public static Color DarkSlateGray { get { return namedColors["darkslategray"]; } }
+ public static Color DarkTurquoise { get { return namedColors["darkturquoise"]; } }
+ public static Color DarkViolet { get { return namedColors["darkviolet"]; } }
+ public static Color DeepPink { get { return namedColors["deeppink"]; } }
+ public static Color DeepSkyBlue { get { return namedColors["deepskyblue"]; } }
+ public static Color DimGray { get { return namedColors["dimgray"]; } }
+ public static Color DodgerBlue { get { return namedColors["dodgerblue"]; } }
+ public static Color Firebrick { get { return namedColors["firebrick"]; } }
+ public static Color FloralWhite { get { return namedColors["floralwhite"]; } }
+ public static Color ForestGreen { get { return namedColors["forestgreen"]; } }
+ public static Color Fuchsia { get { return namedColors["fuchsia"]; } }
+ public static Color Gainsboro { get { return namedColors["gainsboro"]; } }
+ public static Color GhostWhite { get { return namedColors["ghostwhite"]; } }
+ public static Color Gold { get { return namedColors["gold"]; } }
+ public static Color Goldenrod { get { return namedColors["goldenrod"]; } }
+ public static Color Gray { get { return namedColors["gray"]; } }
+ public static Color Green { get { return namedColors["green"]; } }
+ public static Color GreenYellow { get { return namedColors["greenyellow"]; } }
+ public static Color Honeydew { get { return namedColors["honeydew"]; } }
+ public static Color HotPink { get { return namedColors["hotpink"]; } }
+ public static Color IndianRed { get { return namedColors["indianred"]; } }
+ public static Color Indigo { get { return namedColors["indigo"]; } }
+ public static Color Ivory { get { return namedColors["ivory"]; } }
+ public static Color Khaki { get { return namedColors["khaki"]; } }
+ public static Color Lavender { get { return namedColors["lavender"]; } }
+ public static Color LavenderBlush { get { return namedColors["lavenderblush"]; } }
+ public static Color LawnGreen { get { return namedColors["lawngreen"]; } }
+ public static Color LemonChiffon { get { return namedColors["lemonchiffon"]; } }
+ public static Color LightBlue { get { return namedColors["lightblue"]; } }
+ public static Color LightCoral { get { return namedColors["lightcoral"]; } }
+ public static Color LightCyan { get { return namedColors["lightcyan"]; } }
+ public static Color LightGoldenrod { get { return namedColors["lightgoldenrod"]; } }
+ public static Color LightGray { get { return namedColors["lightgray"]; } }
+ public static Color LightGreen { get { return namedColors["lightgreen"]; } }
+ public static Color LightPink { get { return namedColors["lightpink"]; } }
+ public static Color LightSalmon { get { return namedColors["lightsalmon"]; } }
+ public static Color LightSeaGreen { get { return namedColors["lightseagreen"]; } }
+ public static Color LightSkyBlue { get { return namedColors["lightskyblue"]; } }
+ public static Color LightSlateGray { get { return namedColors["lightslategray"]; } }
+ public static Color LightSteelBlue { get { return namedColors["lightsteelblue"]; } }
+ public static Color LightYellow { get { return namedColors["lightyellow"]; } }
+ public static Color Lime { get { return namedColors["lime"]; } }
+ public static Color Limegreen { get { return namedColors["limegreen"]; } }
+ public static Color Linen { get { return namedColors["linen"]; } }
+ public static Color Magenta { get { return namedColors["magenta"]; } }
+ public static Color Maroon { get { return namedColors["maroon"]; } }
+ public static Color MediumAquamarine { get { return namedColors["mediumaquamarine"]; } }
+ public static Color MediumBlue { get { return namedColors["mediumblue"]; } }
+ public static Color MediumOrchid { get { return namedColors["mediumorchid"]; } }
+ public static Color MediumPurple { get { return namedColors["mediumpurple"]; } }
+ public static Color MediumSeaGreen { get { return namedColors["mediumseagreen"]; } }
+ public static Color MediumSlateBlue { get { return namedColors["mediumslateblue"]; } }
+ public static Color MediumSpringGreen { get { return namedColors["mediumspringgreen"]; } }
+ public static Color MediumTurquoise { get { return namedColors["mediumturquoise"]; } }
+ public static Color MediumVioletRed { get { return namedColors["mediumvioletred"]; } }
+ public static Color MidnightBlue { get { return namedColors["midnightblue"]; } }
+ public static Color MintCream { get { return namedColors["mintcream"]; } }
+ public static Color MistyRose { get { return namedColors["mistyrose"]; } }
+ public static Color Moccasin { get { return namedColors["moccasin"]; } }
+ public static Color NavajoWhite { get { return namedColors["navajowhite"]; } }
+ public static Color NavyBlue { get { return namedColors["navyblue"]; } }
+ public static Color OldLace { get { return namedColors["oldlace"]; } }
+ public static Color Olive { get { return namedColors["olive"]; } }
+ public static Color OliveDrab { get { return namedColors["olivedrab"]; } }
+ public static Color Orange { get { return namedColors["orange"]; } }
+ public static Color OrangeRed { get { return namedColors["orangered"]; } }
+ public static Color Orchid { get { return namedColors["orchid"]; } }
+ public static Color PaleGoldenrod { get { return namedColors["palegoldenrod"]; } }
+ public static Color PaleGreen { get { return namedColors["palegreen"]; } }
+ public static Color PaleTurquoise { get { return namedColors["paleturquoise"]; } }
+ public static Color PaleVioletRed { get { return namedColors["palevioletred"]; } }
+ public static Color PapayaWhip { get { return namedColors["papayawhip"]; } }
+ public static Color PeachPuff { get { return namedColors["peachpuff"]; } }
+ public static Color Peru { get { return namedColors["peru"]; } }
+ public static Color Pink { get { return namedColors["pink"]; } }
+ public static Color Plum { get { return namedColors["plum"]; } }
+ public static Color PowderBlue { get { return namedColors["powderblue"]; } }
+ public static Color Purple { get { return namedColors["purple"]; } }
+ public static Color RebeccaPurple { get { return namedColors["rebeccapurple"]; } }
+ public static Color Red { get { return namedColors["red"]; } }
+ public static Color RosyBrown { get { return namedColors["rosybrown"]; } }
+ public static Color RoyalBlue { get { return namedColors["royalblue"]; } }
+ public static Color SaddleBrown { get { return namedColors["saddlebrown"]; } }
+ public static Color Salmon { get { return namedColors["salmon"]; } }
+ public static Color SandyBrown { get { return namedColors["sandybrown"]; } }
+ public static Color SeaGreen { get { return namedColors["seagreen"]; } }
+ public static Color SeaShell { get { return namedColors["seashell"]; } }
+ public static Color Sienna { get { return namedColors["sienna"]; } }
+ public static Color Silver { get { return namedColors["silver"]; } }
+ public static Color SkyBlue { get { return namedColors["skyblue"]; } }
+ public static Color SlateBlue { get { return namedColors["slateblue"]; } }
+ public static Color SlateGray { get { return namedColors["slategray"]; } }
+ public static Color Snow { get { return namedColors["snow"]; } }
+ public static Color SpringGreen { get { return namedColors["springgreen"]; } }
+ public static Color SteelBlue { get { return namedColors["steelblue"]; } }
+ public static Color Tan { get { return namedColors["tan"]; } }
+ public static Color Teal { get { return namedColors["teal"]; } }
+ public static Color Thistle { get { return namedColors["thistle"]; } }
+ public static Color Tomato { get { return namedColors["tomato"]; } }
+ public static Color Turquoise { get { return namedColors["turquoise"]; } }
+ public static Color Violet { get { return namedColors["violet"]; } }
+ public static Color WebGreen { get { return namedColors["webgreen"]; } }
+ public static Color WebGray { get { return namedColors["webgray"]; } }
+ public static Color WebMaroon { get { return namedColors["webmaroon"]; } }
+ public static Color WebPurple { get { return namedColors["webpurple"]; } }
+ public static Color Wheat { get { return namedColors["wheat"]; } }
+ public static Color White { get { return namedColors["white"]; } }
+ public static Color WhiteSmoke { get { return namedColors["whitesmoke"]; } }
+ public static Color Yellow { get { return namedColors["yellow"]; } }
+ public static Color YellowGreen { get { return namedColors["yellowgreen"]; } }
+ }
+}
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
index 63f0781028..81f61c1d4d 100644
--- a/modules/tinyexr/image_loader_tinyexr.cpp
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -131,7 +131,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
Image::Format format;
int output_channels = 0;
- if (idxA > 0) {
+ if (idxA != -1) {
imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
format = Image::FORMAT_RGBAH;
@@ -187,7 +187,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
const float *b_channel_start = reinterpret_cast<const float *>(tile.images[idxB]);
const float *a_channel_start = NULL;
- if (idxA > 0) {
+ if (idxA != -1) {
a_channel_start = reinterpret_cast<const float *>(tile.images[idxA]);
}
@@ -216,7 +216,7 @@ Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_f
*row_w++ = Math::make_half_float(color.g);
*row_w++ = Math::make_half_float(color.b);
- if (idxA > 0) {
+ if (idxA != -1) {
*row_w++ = Math::make_half_float(*a_channel++);
}
}
diff --git a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
index 399ba8ef5d..ac3aec6c14 100644
--- a/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
+++ b/modules/visual_script/doc_classes/VisualScriptBuiltinFunc.xml
@@ -154,7 +154,7 @@
Return the lesser of the two numbers, also known as their minimum.
</constant>
<constant name="LOGIC_CLAMP" value="46" enum="BuiltinFunc">
- Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to `min(max(input, range_low), range_high)`
+ Return the input clamped inside the given range, ensuring the result is never outside it. Equivalent to [code]min(max(input, range_low), range_high)[/code].
</constant>
<constant name="LOGIC_NEAREST_PO2" value="47" enum="BuiltinFunc">
Return the nearest power of 2 to the input.
diff --git a/modules/visual_script/doc_classes/VisualScriptCondition.xml b/modules/visual_script/doc_classes/VisualScriptCondition.xml
index 353898c93a..4657436c8f 100644
--- a/modules/visual_script/doc_classes/VisualScriptCondition.xml
+++ b/modules/visual_script/doc_classes/VisualScriptCondition.xml
@@ -4,7 +4,7 @@
A Visual Script node which branches the flow.
</brief_description>
<description>
- A Visual Script node that checks a [bool] input port. If [code]true[/code] it will exit via the “true” sequence port. If [code]false[/code] it will exit via the "false" sequence port. After exiting either, it exits via the “done” port. Sequence ports may be left disconnected.
+ A Visual Script node that checks a [bool] input port. If [code]true[/code], it will exit via the “true” sequence port. If [code]false[/code], it will exit via the "false" sequence port. After exiting either, it exits via the “done” port. Sequence ports may be left disconnected.
[b]Input Ports:[/b]
- Sequence: [code]if (cond) is[/code]
- Data (boolean): [code]cond[/code]
diff --git a/modules/visual_script/doc_classes/VisualScriptReturn.xml b/modules/visual_script/doc_classes/VisualScriptReturn.xml
index 6095520eff..0ca3e3b612 100644
--- a/modules/visual_script/doc_classes/VisualScriptReturn.xml
+++ b/modules/visual_script/doc_classes/VisualScriptReturn.xml
@@ -19,7 +19,7 @@
</methods>
<members>
<member name="return_enabled" type="bool" setter="set_enable_return_value" getter="is_return_value_enabled">
- If [code]true[/code] the [code]return[/code] input port is available.
+ If [code]true[/code], the [code]return[/code] input port is available.
</member>
<member name="return_type" type="int" setter="set_return_type" getter="get_return_type" enum="Variant.Type">
The return value's data type.
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index 98e38b9027..df75dca310 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -271,7 +271,7 @@ if env["platform"] == 'uwp':
else:
import platform
is_x11_or_server_arm = ((env["platform"] == 'x11' or env["platform"] == 'server') and (platform.machine().startswith('arm') or platform.machine().startswith('aarch')))
- is_ios_x86 = (env["platform"] == 'iphone' and env["ios_sim"])
+ is_ios_x86 = (env["platform"] == 'iphone' and ("arch" in env and env["arch"].startswith('x86')))
is_android_x86 = (env["platform"] == 'android' and env["android_arch"] == 'x86')
if is_android_x86:
cpu_bits = '32'
@@ -350,7 +350,7 @@ if webm_multithread:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_mt)
if webm_cpu_x86:
- is_clang_or_gcc = ('gcc' in os.path.basename(env["CC"])) or ('clang' in os.path.basename(env["CC"])) or ("OSXCROSS_ROOT" in os.environ)
+ is_clang_or_gcc = ('gcc' in os.path.basename(env["CC"])) or ('clang' in os.path.basename(env["CC"])) or ("osxcross" in env)
env_libvpx_mmx = env_libvpx.Clone()
if cpu_bits == '32' and is_clang_or_gcc:
@@ -379,6 +379,9 @@ if webm_cpu_x86:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_x86_64asm)
elif webm_cpu_arm:
env_libvpx.add_source_files(env.modules_sources, libvpx_sources_arm)
+ if env["platform"] == 'android':
+ env_libvpx.Append(CPPPATH=[libvpx_dir + "third_party/android"])
+ env_libvpx.add_source_files(env.modules_sources, [libvpx_dir + "third_party/android/cpu-features.c"])
env_libvpx_neon = env_libvpx.Clone()
if env["platform"] == 'android' and env["android_arch"] == 'armv6':
diff --git a/modules/websocket/doc_classes/WebSocketClient.xml b/modules/websocket/doc_classes/WebSocketClient.xml
index b3ea535495..6b73b80350 100644
--- a/modules/websocket/doc_classes/WebSocketClient.xml
+++ b/modules/websocket/doc_classes/WebSocketClient.xml
@@ -25,7 +25,7 @@
</argument>
<description>
Connect to the given URL requesting one of the given [code]protocols[/code] as sub-protocol.
- If [code]true[/code] is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI]. Note: connections to non Godot servers will not work, and [signal data_received] will not be emitted when this option is true.
+ If [code]true[/code], is passed as [code]gd_mp_api[/code], the client will behave like a network peer for the [MultiplayerAPI]. Note: connections to non Godot servers will not work, and [signal data_received] will not be emitted when this option is true.
</description>
</method>
<method name="disconnect_from_host">
diff --git a/modules/websocket/emws_client.cpp b/modules/websocket/emws_client.cpp
index 82a577790e..522b810721 100644
--- a/modules/websocket/emws_client.cpp
+++ b/modules/websocket/emws_client.cpp
@@ -205,8 +205,8 @@ int EMWSClient::get_max_packet_size() const {
}
EMWSClient::EMWSClient() {
- _in_buf_size = GLOBAL_GET(WSC_IN_BUF);
- _in_pkt_size = GLOBAL_GET(WSC_IN_PKT);
+ _in_buf_size = nearest_shift((int)GLOBAL_GET(WSC_IN_BUF) - 1) + 10;
+ _in_pkt_size = nearest_shift((int)GLOBAL_GET(WSC_IN_PKT) - 1);
_is_connecting = false;
_peer = Ref<EMWSPeer>(memnew(EMWSPeer));
/* clang-format off */
diff --git a/platform/android/SCsub b/platform/android/SCsub
index fb0ec75b16..ad682b9324 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -21,11 +21,6 @@ android_files = [
# 'power_android.cpp'
]
-thirdparty_files = [
- 'ifaddrs_android.cpp',
- 'cpu-features.c',
-]
-
env_android = env.Clone()
if env['target'] == "profile":
env_android.Append(CPPFLAGS=['-DPROFILER_ENABLED'])
@@ -36,14 +31,10 @@ for x in android_files:
env_thirdparty = env_android.Clone()
env_thirdparty.disable_warnings()
-for x in thirdparty_files:
- android_objects.append(env_thirdparty.SharedObject(x))
-
-prog = None
+android_objects.append(env_thirdparty.SharedObject('#thirdparty/misc/ifaddrs-android.cc'))
abspath = env.Dir(".").abspath
-
with open_utf8(abspath + "/build.gradle.template", "r") as gradle_basein:
gradle_text = gradle_basein.read()
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 7f8d50b8ab..bfe737f138 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1157,6 +1157,9 @@ public:
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), ""));
}
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), ""));
@@ -1417,12 +1420,15 @@ public:
err += "OpenJDK 8 jarsigner not configured in the Editor Settings.\n";
}
- String dk = EditorSettings::get_singleton()->get("export/android/debug_keystore");
+ String dk = p_preset->get("keystore/debug");
if (!FileAccess::exists(dk)) {
- valid = false;
- err += "Debug keystore not configured in the Editor Settings.\n";
+ dk = EditorSettings::get_singleton()->get("export/android/debug_keystore");
+ if (!FileAccess::exists(dk)) {
+ valid = false;
+ err += "Debug keystore not configured in the Editor Settings nor in the preset.\n";
+ }
}
bool apk_expansion = p_preset->get("apk_expansion/enable");
@@ -1772,9 +1778,17 @@ public:
String password;
String user;
if (p_debug) {
- keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore");
- password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
- user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
+
+ keystore = p_preset->get("keystore/debug");
+ password = p_preset->get("keystore/debug_password");
+ user = p_preset->get("keystore/debug_user");
+
+ if (keystore.empty()) {
+
+ keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore");
+ password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass");
+ user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user");
+ }
ep.step("Signing debug APK...", 103);
diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp
deleted file mode 100644
index efeb8598e5..0000000000
--- a/platform/android/globals/global_defaults.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*************************************************************************/
-/* global_defaults.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 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 "global_defaults.h"
-#include "core/project_settings.h"
-
-void register_android_global_defaults() {
-}
diff --git a/platform/android/globals/global_defaults.h b/platform/android/globals/global_defaults.h
deleted file mode 100644
index 99da2dd527..0000000000
--- a/platform/android/globals/global_defaults.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************/
-/* global_defaults.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_android_global_defaults();
diff --git a/platform/android/ifaddrs_android.cpp b/platform/android/ifaddrs_android.cpp
deleted file mode 100644
index f6d5cdbe77..0000000000
--- a/platform/android/ifaddrs_android.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * libjingle
- * Copyright 2012, Google Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
- * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "ifaddrs_android.h"
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <netinet/in.h>
-#include <net/if.h>
-#include <unistd.h>
-#include <errno.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-
-struct netlinkrequest {
- nlmsghdr header;
- ifaddrmsg msg;
-};
-
-namespace {
-const int kMaxReadSize = 4096;
-}
-
-static int set_ifname(struct ifaddrs* ifaddr, int interface) {
- char buf[IFNAMSIZ] = {0};
- char* name = if_indextoname(interface, buf);
- if (name == NULL) {
- return -1;
- }
- ifaddr->ifa_name = new char[strlen(name) + 1];
- strncpy(ifaddr->ifa_name, name, strlen(name) + 1);
- return 0;
-}
-
-static int set_flags(struct ifaddrs* ifaddr) {
- int fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd == -1) {
- return -1;
- }
- ifreq ifr;
- memset(&ifr, 0, sizeof(ifr));
- strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
- int rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
- close(fd);
- if (rc == -1) {
- return -1;
- }
- ifaddr->ifa_flags = ifr.ifr_flags;
- return 0;
-}
-
-static int set_addresses(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* data,
- size_t len) {
- if (msg->ifa_family == AF_INET) {
- sockaddr_in* sa = new sockaddr_in;
- sa->sin_family = AF_INET;
- memcpy(&sa->sin_addr, data, len);
- ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa);
- } else if (msg->ifa_family == AF_INET6) {
- sockaddr_in6* sa = new sockaddr_in6;
- sa->sin6_family = AF_INET6;
- sa->sin6_scope_id = msg->ifa_index;
- memcpy(&sa->sin6_addr, data, len);
- ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa);
- } else {
- return -1;
- }
- return 0;
-}
-
-static int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) {
- char* prefix = NULL;
- if (family == AF_INET) {
- sockaddr_in* mask = new sockaddr_in;
- mask->sin_family = AF_INET;
- memset(&mask->sin_addr, 0, sizeof(in_addr));
- ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask);
- if (prefixlen > 32) {
- prefixlen = 32;
- }
- prefix = reinterpret_cast<char*>(&mask->sin_addr);
- } else if (family == AF_INET6) {
- sockaddr_in6* mask = new sockaddr_in6;
- mask->sin6_family = AF_INET6;
- memset(&mask->sin6_addr, 0, sizeof(in6_addr));
- ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask);
- if (prefixlen > 128) {
- prefixlen = 128;
- }
- prefix = reinterpret_cast<char*>(&mask->sin6_addr);
- } else {
- return -1;
- }
- for (int i = 0; i < (prefixlen / 8); i++) {
- *prefix++ = 0xFF;
- }
- char remainder = 0xff;
- remainder <<= (8 - prefixlen % 8);
- *prefix = remainder;
- return 0;
-}
-
-static int populate_ifaddrs(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* bytes,
- size_t len) {
- if (set_ifname(ifaddr, msg->ifa_index) != 0) {
- return -1;
- }
- if (set_flags(ifaddr) != 0) {
- return -1;
- }
- if (set_addresses(ifaddr, msg, bytes, len) != 0) {
- return -1;
- }
- if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) {
- return -1;
- }
- return 0;
-}
-
-int getifaddrs(struct ifaddrs** result) {
- int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
- if (fd < 0) {
- return -1;
- }
- netlinkrequest ifaddr_request;
- memset(&ifaddr_request, 0, sizeof(ifaddr_request));
- ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
- ifaddr_request.header.nlmsg_type = RTM_GETADDR;
- ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(ifaddrmsg));
- ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0);
- if (static_cast<size_t>(count) != ifaddr_request.header.nlmsg_len) {
- close(fd);
- return -1;
- }
- struct ifaddrs* start = NULL;
- struct ifaddrs* current = NULL;
- char buf[kMaxReadSize];
- ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0);
- while (amount_read > 0) {
- nlmsghdr* header = reinterpret_cast<nlmsghdr*>(&buf[0]);
- size_t header_size = static_cast<size_t>(amount_read);
- for ( ; NLMSG_OK(header, header_size);
- header = NLMSG_NEXT(header, header_size)) {
- switch (header->nlmsg_type) {
- case NLMSG_DONE:
- // Success. Return.
- *result = start;
- close(fd);
- return 0;
- case NLMSG_ERROR:
- close(fd);
- freeifaddrs(start);
- return -1;
- case RTM_NEWADDR: {
- ifaddrmsg* address_msg =
- reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(header));
- rtattr* rta = IFA_RTA(address_msg);
- ssize_t payload_len = IFA_PAYLOAD(header);
- while (RTA_OK(rta, payload_len)) {
- if (rta->rta_type == IFA_ADDRESS) {
- int family = address_msg->ifa_family;
- if (family == AF_INET || family == AF_INET6) {
- ifaddrs* newest = new ifaddrs;
- memset(newest, 0, sizeof(ifaddrs));
- if (current) {
- current->ifa_next = newest;
- } else {
- start = newest;
- }
- if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta),
- RTA_PAYLOAD(rta)) != 0) {
- freeifaddrs(start);
- *result = NULL;
- return -1;
- }
- current = newest;
- }
- }
- rta = RTA_NEXT(rta, payload_len);
- }
- break;
- }
- }
- }
- amount_read = recv(fd, &buf, kMaxReadSize, 0);
- }
- close(fd);
- freeifaddrs(start);
- return -1;
-}
-
-void freeifaddrs(struct ifaddrs* addrs) {
- struct ifaddrs* last = NULL;
- struct ifaddrs* cursor = addrs;
- while (cursor) {
- delete[] cursor->ifa_name;
- delete cursor->ifa_addr;
- delete cursor->ifa_netmask;
- last = cursor;
- cursor = cursor->ifa_next;
- delete last;
- }
-}
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index debf051eda..d5540fe8db 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -23,7 +23,7 @@ ios_lib = env_ios.add_library('iphone', iphone_lib)
def combine_libs(target=None, source=None, env=None):
lib_path = target[0].srcnode().abspath
- if ("OSXCROSS_IOS" in os.environ):
+ if "osxcross" in env:
libtool = '$IPHONEPATH/usr/bin/${ios_triple}libtool'
else:
libtool = "$IPHONEPATH/usr/bin/libtool"
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 4608770c09..20fb4428dd 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -29,7 +29,6 @@ def get_opts():
BoolVariable('icloud', 'Support for iCloud', True),
BoolVariable('ios_exceptions', 'Enable exceptions', False),
('ios_triple', 'Triple for ios toolchain', ''),
- BoolVariable('ios_sim', 'Build simulator binary', False),
]
@@ -64,10 +63,7 @@ def configure(env):
env.Append(LINKFLAGS=['-flto'])
## Architecture
- if env["ios_sim"] and not ("arch" in env):
- env["arch"] = "x86"
-
- if env["arch"] == "x86": # i386, simulator
+ if env["arch"] == "x86": # i386
env["bits"] = "32"
elif env["arch"] == "x86_64":
env["bits"] = "64"
@@ -80,6 +76,10 @@ def configure(env):
## Compiler configuration
+ # Save this in environment for use by other modules
+ if "OSXCROSS_IOS" in os.environ:
+ env["osxcross"] = True
+
env['ENV']['PATH'] = env['IPHONEPATH'] + "/Developer/usr/bin/:" + env['ENV']['PATH']
compiler_path = '$IPHONEPATH/usr/bin/${ios_triple}'
diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp
deleted file mode 100644
index 423f50995e..0000000000
--- a/platform/iphone/globals/global_defaults.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*************************************************************************/
-/* global_defaults.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 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 "global_defaults.h"
-#include "core/project_settings.h"
-
-void register_iphone_global_defaults() {
-}
diff --git a/platform/iphone/globals/global_defaults.h b/platform/iphone/globals/global_defaults.h
deleted file mode 100644
index 3e3c220f4a..0000000000
--- a/platform/iphone/globals/global_defaults.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************/
-/* global_defaults.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-
-void register_iphone_global_defaults();
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 051836b66d..6eee8f204f 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -72,7 +72,11 @@ def configure(env):
## Compiler configuration
- if "OSXCROSS_ROOT" not in os.environ: # regular native build
+ # Save this in environment for use by other modules
+ if "OSXCROSS_ROOT" in os.environ:
+ env["osxcross"] = True
+
+ if not "osxcross" in env: # regular native build
env.Append(CCFLAGS=['-arch', 'x86_64'])
env.Append(LINKFLAGS=['-arch', 'x86_64'])
if (env["macports_clang"] != 'no'):
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index e1cbbcc66b..dff87b2c5d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -2142,8 +2142,13 @@ uint64_t OS_Windows::get_unix_time() const {
uint64_t OS_Windows::get_system_time_secs() const {
- const uint64_t WINDOWS_TICK = 10000000;
- const uint64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
+ return get_system_time_msecs() / 1000;
+}
+
+uint64_t OS_Windows::get_system_time_msecs() const {
+
+ const uint64_t WINDOWS_TICK = 10000;
+ const uint64_t MSEC_TO_UNIX_EPOCH = 11644473600000LL;
SYSTEMTIME st;
GetSystemTime(&st);
@@ -2154,7 +2159,7 @@ uint64_t OS_Windows::get_system_time_secs() const {
ret <<= 32;
ret |= ft.dwLowDateTime;
- return (uint64_t)(ret / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
+ return (uint64_t)(ret / WINDOWS_TICK - MSEC_TO_UNIX_EPOCH);
}
void OS_Windows::delay_usec(uint32_t p_usec) const {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index d09ade4daa..e12e465dd3 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -254,6 +254,7 @@ public:
virtual TimeZoneInfo get_time_zone_info() const;
virtual uint64_t get_unix_time() const;
virtual uint64_t get_system_time_secs() const;
+ virtual uint64_t get_system_time_msecs() const;
virtual bool can_draw() const;
virtual Error set_cwd(const String &p_cwd);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index ee76a90019..37886861e0 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -840,7 +840,7 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
Map<PosKey, Cell>::Element *E = tile_map.find(p);
if (E != NULL) {
int id = get_cell(p_x, p_y);
- if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE || tile_set->tile_get_tile_mode(id) == TileSet::ATLAS_TILE) {
+ if (tile_set->tile_get_tile_mode(id) == TileSet::AUTO_TILE) {
uint16_t mask = 0;
if (tile_set->autotile_get_bitmask_mode(id) == TileSet::BITMASK_2X2) {
if (tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x, p_y - 1)) && tile_set->is_tile_bound(id, get_cell(p_x - 1, p_y))) {
@@ -904,7 +904,8 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
PosKey qk(p_x / _get_quadrant_size(), p_y / _get_quadrant_size());
Map<PosKey, Quadrant>::Element *Q = quadrant_map.find(qk);
_make_quadrant_dirty(Q);
- } else {
+
+ } else if (tile_set->tile_get_tile_mode(id) == TileSet::SINGLE_TILE) {
E->get().autotile_coord_x = 0;
E->get().autotile_coord_y = 0;
}
@@ -1630,6 +1631,8 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_cell_y_flipped", "x", "y"), &TileMap::is_cell_y_flipped);
ClassDB::bind_method(D_METHOD("is_cell_transposed", "x", "y"), &TileMap::is_cell_transposed);
+ ClassDB::bind_method(D_METHOD("get_cell_autotile_coord", "x", "y"), &TileMap::get_cell_autotile_coord);
+
ClassDB::bind_method(D_METHOD("fix_invalid_tiles"), &TileMap::fix_invalid_tiles);
ClassDB::bind_method(D_METHOD("clear"), &TileMap::clear);
diff --git a/scene/3d/mesh_instance.cpp b/scene/3d/mesh_instance.cpp
index cf0317cd58..02fab8c50b 100644
--- a/scene/3d/mesh_instance.cpp
+++ b/scene/3d/mesh_instance.cpp
@@ -138,6 +138,8 @@ void MeshInstance::set_mesh(const Ref<Mesh> &p_mesh) {
set_base(RID());
}
+ update_gizmo();
+
_change_notify();
}
Ref<Mesh> MeshInstance::get_mesh() const {
diff --git a/scene/3d/spatial.cpp b/scene/3d/spatial.cpp
index dc09392713..d612a50c06 100644
--- a/scene/3d/spatial.cpp
+++ b/scene/3d/spatial.cpp
@@ -32,6 +32,7 @@
#include "core/engine.h"
#include "core/message_queue.h"
+#include "scene/main/scene_tree.h"
#include "scene/main/viewport.h"
#include "scene/scene_string_names.h"
@@ -401,6 +402,8 @@ void Spatial::update_gizmo() {
if (!is_inside_world())
return;
if (!data.gizmo.is_valid())
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, SceneStringNames::get_singleton()->_spatial_editor_group, SceneStringNames::get_singleton()->_request_gizmo, this);
+ if (!data.gizmo.is_valid())
return;
if (data.gizmo_dirty)
return;
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index eee3213fe7..81f5cf3318 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -1277,7 +1277,7 @@ void GraphEdit::_bind_methods() {
ADD_SIGNAL(MethodInfo("connection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot")));
ADD_SIGNAL(MethodInfo("disconnection_request", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::STRING, "to"), PropertyInfo(Variant::INT, "to_slot")));
- ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "p_position")));
+ ADD_SIGNAL(MethodInfo("popup_request", PropertyInfo(Variant::VECTOR2, "position")));
ADD_SIGNAL(MethodInfo("duplicate_nodes_request"));
ADD_SIGNAL(MethodInfo("node_selected", PropertyInfo(Variant::OBJECT, "node", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("connection_to_empty", PropertyInfo(Variant::STRING, "from"), PropertyInfo(Variant::INT, "from_slot"), PropertyInfo(Variant::VECTOR2, "release_position")));
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index b1849b7e69..003b30e035 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1108,9 +1108,10 @@ void TextEdit::_notification(int p_what) {
if (cursor.column == last_wrap_column + j && cursor.line == line && cursor_wrap_index == line_wrap_index) {
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
+ cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
if (insert_mode) {
- cursor_pos.y += (get_row_height() - 3);
+ cursor_pos.y += (cache.font->get_height() - 3);
}
int caret_w = (str[j] == '\t') ? cache.font->get_char_size(' ').width : char_w;
@@ -1155,7 +1156,8 @@ void TextEdit::_notification(int p_what) {
#else
caret_w = (block_caret) ? caret_w : 2;
#endif
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
+
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color);
}
}
}
@@ -1198,9 +1200,10 @@ void TextEdit::_notification(int p_what) {
if (cursor.column == last_wrap_column + str.length() && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) {
cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y);
+ cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2;
if (insert_mode) {
- cursor_pos.y += (get_row_height() - 3);
+ cursor_pos.y += (cache.font->get_height() - 3);
}
if (ime_text.length() > 0) {
int ofs = 0;
@@ -1245,7 +1248,8 @@ void TextEdit::_notification(int p_what) {
#else
int caret_w = (block_caret) ? char_w : 2;
#endif
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, get_row_height())), cache.caret_color);
+
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(cursor_pos, Size2i(caret_w, cache.font->get_height())), cache.caret_color);
}
}
}
@@ -1289,7 +1293,7 @@ void TextEdit::_notification(int p_what) {
if (cursor_pos.y + get_row_height() + th > get_size().height) {
completion_rect.position.y = cursor_pos.y - th;
} else {
- completion_rect.position.y = cursor_pos.y + get_row_height() + csb->get_offset().y;
+ completion_rect.position.y = cursor_pos.y + get_row_height() + csb->get_offset().y - cache.font->get_height();
completion_below = true;
}
@@ -1323,7 +1327,8 @@ void TextEdit::_notification(int p_what) {
text_color = color_regions[j].color;
}
}
- draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent()), completion_options[l], text_color, completion_rect.size.width);
+ int yofs = (get_row_height() - cache.font->get_height()) / 2;
+ draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent() + yofs), completion_options[l], text_color, completion_rect.size.width);
}
if (scrollw) {
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 479b035f86..f22c2e260d 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -1419,7 +1419,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
while (c) {
- if (cache.draw_relationship_lines == 1 && (!hide_root || c->parent != root)) {
+ if (cache.draw_relationship_lines > 0 && (!hide_root || c->parent != root)) {
int root_ofs = children_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin);
int parent_ofs = p_pos.x + ((p_item->disable_folding || hide_folding) ? cache.hseparation : cache.item_margin);
Point2i root_pos = Point2i(root_ofs, children_pos.y + label_h / 2) - cache.offset + p_draw_ofs;
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp
index 587ab73dce..722df01677 100644
--- a/scene/resources/bit_mask.cpp
+++ b/scene/resources/bit_mask.cpp
@@ -602,7 +602,7 @@ void BitMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_bit", "position", "bit"), &BitMap::set_bit);
ClassDB::bind_method(D_METHOD("get_bit", "position"), &BitMap::get_bit);
- ClassDB::bind_method(D_METHOD("set_bit_rect", "p_rect", "bit"), &BitMap::set_bit_rect);
+ ClassDB::bind_method(D_METHOD("set_bit_rect", "rect", "bit"), &BitMap::set_bit_rect);
ClassDB::bind_method(D_METHOD("get_true_bit_count"), &BitMap::get_true_bit_count);
ClassDB::bind_method(D_METHOD("get_size"), &BitMap::get_size);
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 4f4d375481..a378c517ed 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -2067,7 +2067,7 @@ void TextureLayered::create(uint32_t p_width, uint32_t p_height, uint32_t p_dept
width = p_width;
height = p_height;
depth = p_depth;
-
+ format = p_format;
flags = p_flags;
}
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 8a24d4bab1..089100bf40 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -507,6 +507,13 @@ int TileSet::autotile_get_subtile_priority(int p_id, const Vector2 &p_coord) {
return 1;
}
+const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
+
+ static Map<Vector2, int> dummy;
+ ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
+ return tile_map[p_id].autotile_data.priority_map;
+}
+
void TileSet::autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index) {
ERR_FAIL_COND(!tile_map.has(p_id));
@@ -524,11 +531,11 @@ int TileSet::autotile_get_z_index(int p_id, const Vector2 &p_coord) {
return 0;
}
-const Map<Vector2, int> &TileSet::autotile_get_priority_map(int p_id) const {
+const Map<Vector2, int> &TileSet::autotile_get_z_index_map(int p_id) const {
static Map<Vector2, int> dummy;
ERR_FAIL_COND_V(!tile_map.has(p_id), dummy);
- return tile_map[p_id].autotile_data.priority_map;
+ return tile_map[p_id].autotile_data.z_index_map;
}
void TileSet::autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag) {
@@ -986,8 +993,23 @@ void TileSet::clear() {
void TileSet::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile);
+ ClassDB::bind_method(D_METHOD("autotile_clear_bitmask_map", "id"), &TileSet::autotile_clear_bitmask_map);
+ ClassDB::bind_method(D_METHOD("autotile_set_icon_coordinate", "id", "coord"), &TileSet::autotile_set_icon_coordinate);
+ ClassDB::bind_method(D_METHOD("autotile_get_icon_coordinate", "id"), &TileSet::autotile_get_icon_coordinate);
+ ClassDB::bind_method(D_METHOD("autotile_set_subtile_priority", "id", "coord", "priority"), &TileSet::autotile_set_subtile_priority);
+ ClassDB::bind_method(D_METHOD("autotile_get_subtile_priority", "id", "coord"), &TileSet::autotile_get_subtile_priority);
+ ClassDB::bind_method(D_METHOD("autotile_set_z_index", "id", "coord", "z_index"), &TileSet::autotile_set_z_index);
+ ClassDB::bind_method(D_METHOD("autotile_get_z_index", "id", "coord"), &TileSet::autotile_get_z_index);
+ ClassDB::bind_method(D_METHOD("autotile_set_light_occluder", "id", "light_occluder", "coord"), &TileSet::autotile_set_light_occluder);
+ ClassDB::bind_method(D_METHOD("autotile_get_light_occluder", "id", "coord"), &TileSet::autotile_get_light_occluder);
+ ClassDB::bind_method(D_METHOD("autotile_set_navigation_polygon", "id", "navigation_polygon", "coord"), &TileSet::autotile_set_navigation_polygon);
+ ClassDB::bind_method(D_METHOD("autotile_get_navigation_polygon", "id", "coord"), &TileSet::autotile_get_navigation_polygon);
+ ClassDB::bind_method(D_METHOD("autotile_set_bitmask", "id", "bitmask", "flag"), &TileSet::autotile_set_bitmask);
+ ClassDB::bind_method(D_METHOD("autotile_get_bitmask", "id", "coord"), &TileSet::autotile_get_bitmask);
ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "id", "mode"), &TileSet::autotile_set_bitmask_mode);
ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode", "id"), &TileSet::autotile_get_bitmask_mode);
+ ClassDB::bind_method(D_METHOD("autotile_set_spacing", "id", "spacing"), &TileSet::autotile_set_spacing);
+ ClassDB::bind_method(D_METHOD("autotile_get_spacing", "id"), &TileSet::autotile_get_spacing);
ClassDB::bind_method(D_METHOD("autotile_set_size", "id", "size"), &TileSet::autotile_set_size);
ClassDB::bind_method(D_METHOD("autotile_get_size", "id"), &TileSet::autotile_get_size);
ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name);
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 2ab771b1b0..3992c675fd 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -175,6 +175,7 @@ public:
void autotile_set_z_index(int p_id, const Vector2 &p_coord, int p_z_index);
int autotile_get_z_index(int p_id, const Vector2 &p_coord);
+ const Map<Vector2, int> &autotile_get_z_index_map(int p_id) const;
void autotile_set_bitmask(int p_id, Vector2 p_coord, uint16_t p_flag);
uint16_t autotile_get_bitmask(int p_id, Vector2 p_coord);
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 45310ec4b3..0eb22c2520 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -1079,6 +1079,7 @@ Physics2DDirectBodyState *Physics2DServerSW::body_get_direct_state(RID p_body) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, NULL);
+ ERR_FAIL_COND_V(!body->get_space(), NULL);
if (body->get_space()->is_locked()) {
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 1acec7ccaf..628ffb71f3 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -525,7 +525,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
bool exponent_found = false;
bool hexa_found = false;
bool sign_found = false;
- bool minus_exponent_found = false;
bool float_suffix_found = false;
String str;
@@ -557,8 +556,6 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (sign_found)
return _make_token(TK_ERROR, "Invalid numeric constant");
sign_found = true;
- if (GETCHAR(i) == '-')
- minus_exponent_found = true;
} else
break;
@@ -571,7 +568,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
if (hexa_found) {
//hex integers eg."0xFF" or "0x12AB", etc - NOT supported yet
return _make_token(TK_ERROR, "Invalid (hexadecimal) numeric constant - Not supported");
- } else if (period_found || float_suffix_found) {
+ } else if (period_found || exponent_found || float_suffix_found) {
//floats
if (period_found) {
if (float_suffix_found) {
@@ -614,7 +611,7 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
char_idx += str.length();
Token tk;
- if (period_found || minus_exponent_found || float_suffix_found)
+ if (period_found || exponent_found || float_suffix_found)
tk.type = TK_REAL_CONSTANT;
else
tk.type = TK_INT_CONSTANT;
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index a92e4efcd6..acc6774019 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -1924,7 +1924,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("scenario_create"), &VisualServer::scenario_create);
ClassDB::bind_method(D_METHOD("scenario_set_debug", "scenario", "debug_mode"), &VisualServer::scenario_set_debug);
ClassDB::bind_method(D_METHOD("scenario_set_environment", "scenario", "environment"), &VisualServer::scenario_set_environment);
- ClassDB::bind_method(D_METHOD("scenario_set_reflection_atlas_size", "scenario", "p_size", "subdiv"), &VisualServer::scenario_set_reflection_atlas_size);
+ ClassDB::bind_method(D_METHOD("scenario_set_reflection_atlas_size", "scenario", "size", "subdiv"), &VisualServer::scenario_set_reflection_atlas_size);
ClassDB::bind_method(D_METHOD("scenario_set_fallback_environment", "scenario", "environment"), &VisualServer::scenario_set_fallback_environment);
#ifndef _3D_DISABLED
diff --git a/thirdparty/README.md b/thirdparty/README.md
index e63e1fc109..5e42436f32 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -31,7 +31,7 @@ Files extracted from upstream source:
## certs
- Upstream: Mozilla, via https://apps.fedoraproject.org/packages/ca-certificates
-- Version: 2018.2.22
+- Version: 2018.2.26
- License: MPL 2.0
File extracted from a recent Fedora install:
@@ -229,6 +229,9 @@ TODO.
Important: File `libvpx/vpx_dsp/x86/vpx_subpixel_8t_intrin_avx2.c` has
Godot-made change marked with `// -- GODOT --` comments.
+The files `libvpx/third_party/android/cpu-features.{c,h}` were copied
+from the Android NDK r18.
+
## libwebp
@@ -337,6 +340,10 @@ Collection of single-file libraries used in Godot components.
* Upstream: http://www.efgh.com/software/md5.htm
* Version: TBD, might not be latest from above URL
* License: RSA Message-Digest License
+- `open-simplex-noise.{c,h}`
+ * Upstream: https://github.com/smcameron/open-simplex-noise-in-c
+ * Version: git (0d555e7, 2015)
+ * License: Unlicense
- `pcg.{cpp,h}`
* Upstream: http://www.pcg-random.org
* Version: minimal C implementation, http://www.pcg-random.org/download.html
@@ -354,11 +361,6 @@ Collection of single-file libraries used in Godot components.
* Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.cpp`)
* Version: TBD, class was renamed
* License: MIT
-- `open-simplex-noise.{c,h}`
- * Upstream: https://github.com/smcameron/open-simplex-noise-in-c
- * Version: git (0d555e7, 2015)
- * License: Unlicense
-
### modules
@@ -371,6 +373,13 @@ Collection of single-file libraries used in Godot components.
* Version: ?
* License: BSD
+### platform
+
+- `ifaddrs-android.{cc,h}`
+ * Upstream: https://chromium.googlesource.com/external/webrtc/stable/talk/+/master/base/ifaddrs-android.h
+ * Version: 5976650 (2013)
+ * License: BSD-3-Clause
+
### scene
- `easing_equations.cpp`
diff --git a/thirdparty/certs/ca-certificates.crt b/thirdparty/certs/ca-certificates.crt
index 01dd29097e..613456b6d3 100644
--- a/thirdparty/certs/ca-certificates.crt
+++ b/thirdparty/certs/ca-certificates.crt
@@ -695,55 +695,6 @@ kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
l7+ijrRU
-----END CERTIFICATE-----
-# Certplus Root CA G1
------BEGIN CERTIFICATE-----
-MIIFazCCA1OgAwIBAgISESBVg+QtPlRWhS2DN7cs3EYRMA0GCSqGSIb3DQEBDQUA
-MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
-dHBsdXMgUm9vdCBDQSBHMTAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBa
-MD4xCzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2Vy
-dHBsdXMgUm9vdCBDQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-ANpQh7bauKk+nWT6VjOaVj0W5QOVsjQcmm1iBdTYj+eJZJ+622SLZOZ5KmHNr49a
-iZFluVj8tANfkT8tEBXgfs+8/H9DZ6itXjYj2JizTfNDnjl8KvzsiNWI7nC9hRYt
-6kuJPKNxQv4c/dMcLRC4hlTqQ7jbxofaqK6AJc96Jh2qkbBIb6613p7Y1/oA/caP
-0FG7Yn2ksYyy/yARujVjBYZHYEMzkPZHogNPlk2dT8Hq6pyi/jQu3rfKG3akt62f
-6ajUeD94/vI4CTYd0hYCyOwqaK/1jpTvLRN6HkJKHRUxrgwEV/xhc/MxVoYxgKDE
-EW4wduOU8F8ExKyHcomYxZ3MVwia9Az8fXoFOvpHgDm2z4QTd28n6v+WZxcIbekN
-1iNQMLAVdBM+5S//Ds3EC0pd8NgAM0lm66EYfFkuPSi5YXHLtaW6uOrc4nBvCGrc
-h2c0798wct3zyT8j/zXhviEpIDCB5BmlIOklynMxdCm+4kLV87ImZsdo/Rmz5yCT
-mehd4F6H50boJZwKKSTUzViGUkAksnsPmBIgJPaQbEfIDbsYIC7Z/fyL8inqh3SV
-4EJQeIQEQWGw9CEjjy3LKCHyamz0GqbFFLQ3ZU+V/YDI+HLlJWvEYLF7bY5KinPO
-WftwenMGE9nTdDckQQoRb5fc5+R+ob0V8rqHDz1oihYHAgMBAAGjYzBhMA4GA1Ud
-DwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSowcCbkahDFXxd
-Bie0KlHYlwuBsTAfBgNVHSMEGDAWgBSowcCbkahDFXxdBie0KlHYlwuBsTANBgkq
-hkiG9w0BAQ0FAAOCAgEAnFZvAX7RvUz1isbwJh/k4DgYzDLDKTudQSk0YcbX8ACh
-66Ryj5QXvBMsdbRX7gp8CXrc1cqh0DQT+Hern+X+2B50ioUHj3/MeXrKls3N/U/7
-/SMNkPX0XtPGYX2eEeAC7gkE2Qfdpoq3DIMku4NQkv5gdRE+2J2winq14J2by5BS
-S7CTKtQ+FjPlnsZlFT5kOwQ/2wyPX1wdaR+v8+khjPPvl/aatxm2hHSco1S1cE5j
-2FddUyGbQJJD+tZ3VTNPZNX70Cxqjm0lpu+F6ALEUz65noe8zDUa3qHpimOHZR4R
-Kttjd5cUvpoUmRGywO6wT/gUITJDT5+rosuoD6o7BlXGEilXCNQ314cnrUlZp5Gr
-RHpejXDbl85IULFzk/bwg2D5zfHhMf1bfHEhYxQUqq/F3pN+aLHsIqKqkHWetUNy
-6mSjhEv9DKgma3GX7lZjZuhCVPnHHd/Qj1vfyDBviP4NxDMcU6ij/UgQ8uQKTuEV
-V/xuZDDCVRHc6qnNSlSsKWNEz0pAoNZoWRsz+e86i9sgktxChL8Bq4fA1SCC28a5
-g4VCXA9DO2pJNdWY9BW/+mGBDAkgGNLQFwzLSABQ6XaCjGTXOqAHVcweMcDvOrRl
-++O/QmueD6i9a5jc2NvLi6Td11n0bt3+qsOR0C5CB8AMTVPNJLFMWx5R9N/pkvo=
------END CERTIFICATE-----
-
-# Certplus Root CA G2
------BEGIN CERTIFICATE-----
-MIICHDCCAaKgAwIBAgISESDZkc6uo+jF5//pAq/Pc7xVMAoGCCqGSM49BAMDMD4x
-CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
-dXMgUm9vdCBDQSBHMjAeFw0xNDA1MjYwMDAwMDBaFw0zODAxMTUwMDAwMDBaMD4x
-CzAJBgNVBAYTAkZSMREwDwYDVQQKDAhDZXJ0cGx1czEcMBoGA1UEAwwTQ2VydHBs
-dXMgUm9vdCBDQSBHMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABM0PW1aC3/BFGtat
-93nwHcmsltaeTpwftEIRyoa/bfuFo8XlGVzX7qY/aWfYeOKmycTbLXku54uNAm8x
-Ik0G42ByRZ0OQneezs/lf4WbGOT8zC5y0xaTTsqZY1yhBSpsBqNjMGEwDgYDVR0P
-AQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNqDYwJ5jtpMxjwj
-FNiPwyCrKGBZMB8GA1UdIwQYMBaAFNqDYwJ5jtpMxjwjFNiPwyCrKGBZMAoGCCqG
-SM49BAMDA2gAMGUCMHD+sAvZ94OX7PNVHdTcswYO/jOYnYs5kGuUIe22113WTNch
-p+e/IQ8rzfcq3IUHnQIxAIYUFuXcsGXCwI4Un78kFmjlvPl5adytRSv3tjFzzAal
-U5ORGpOucGpnutee5WEaXw==
------END CERTIFICATE-----
-
# Certum Trusted Network CA
-----BEGIN CERTIFICATE-----
MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
@@ -1679,6 +1630,40 @@ Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
WD9f
-----END CERTIFICATE-----
+# GlobalSign Root CA - R6
+-----BEGIN CERTIFICATE-----
+MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEg
+MB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2Jh
+bFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQx
+MjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjET
+MBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCAiIwDQYJ
+KoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQssgrRI
+xutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1k
+ZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxD
+aNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJw
+LnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0pPbzlUoSB239jLKJz9CgYXfIWHSw
+1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+azayOeSsJDa38O+2HBNX
+k7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05OWgtH8wY2
+SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/h
+bguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4n
+WUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpY
+rZxCRXluDocZXFSxZba/jJvcE+kNb7gu3GduyYsRtYQUigAZcIN5kZeR1Bonvzce
+MgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTAD
+AQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNVHSMEGDAWgBSu
+bAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN
+nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGt
+Ixg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr61
+55wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLj
+vUYAGm0CuiVdjaExUd1URhxN25mW7xocBFymFe944Hn+Xds+qkxV/ZoVqW/hpvvf
+cDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr3TsTjxKM4kEaSHpz
+oHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB10jZp
+nOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfs
+pA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+v
+JJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R
+8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfLRVpOoERIyNiwmcUVhAn21klJwGW4
+5hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA=
+-----END CERTIFICATE-----
+
# Global Chambersign Root - 2008
-----BEGIN CERTIFICATE-----
MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
@@ -2175,88 +2160,21 @@ aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic
Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM=
-----END CERTIFICATE-----
-# OpenTrust Root CA G1
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESCzkFU5fX82bWTCp59rY45nMA0GCSqGSIb3DQEBCwUA
-MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
-ZW5UcnVzdCBSb290IENBIEcxMB4XDTE0MDUyNjA4NDU1MFoXDTM4MDExNTAwMDAw
-MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
-T3BlblRydXN0IFJvb3QgQ0EgRzEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQD4eUbalsUwXopxAy1wpLuwxQjczeY1wICkES3d5oeuXT2R0odsN7faYp6b
-wiTXj/HbpqbfRm9RpnHLPhsxZ2L3EVs0J9V5ToybWL0iEA1cJwzdMOWo010hOHQX
-/uMftk87ay3bfWAfjH1MBcLrARYVmBSO0ZB3Ij/swjm4eTrwSSTilZHcYTSSjFR0
-77F9jAHiOH3BX2pfJLKOYheteSCtqx234LSWSE9mQxAGFiQD4eCcjsZGT44ameGP
-uY4zbGneWK2gDqdkVBFpRGZPTBKnjix9xNRbxQA0MMHZmf4yzgeEtE7NCv82TWLx
-p2NX5Ntqp66/K7nJ5rInieV+mhxNaMbBGN4zK1FGSxyO9z0M+Yo0FMT7MzUj8czx
-Kselu7Cizv5Ta01BG2Yospb6p64KTrk5M0ScdMGTHPjgniQlQ/GbI4Kq3ywgsNw2
-TgOzfALU5nsaqocTvz6hdLubDuHAk5/XpGbKuxs74zD0M1mKB3IDVedzagMxbm+W
-G+Oin6+Sx+31QrclTDsTBM8clq8cIqPQqwWyTBIjUtz9GVsnnB47ev1CI9sjgBPw
-vFEVVJSmdz7QdFG9URQIOTfLHzSpMJ1ShC5VkLG631UAC9hWLbFJSXKAqWLXwPYY
-EQRVzXR7z2FwefR7LFxckvzluFqrTJOVoSfupb7PcSNCupt2LQIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUl0YhVyE1
-2jZVx/PxN3DlCPaTKbYwHwYDVR0jBBgwFoAUl0YhVyE12jZVx/PxN3DlCPaTKbYw
-DQYJKoZIhvcNAQELBQADggIBAB3dAmB84DWn5ph76kTOZ0BP8pNuZtQ5iSas000E
-PLuHIT839HEl2ku6q5aCgZG27dmxpGWX4m9kWaSW7mDKHyP7Rbr/jyTwyqkxf3kf
-gLMtMrpkZ2CvuVnN35pJ06iCsfmYlIrM4LvgBBuZYLFGZdwIorJGnkSI6pN+VxbS
-FXJfLkur1J1juONI5f6ELlgKn0Md/rcYkoZDSw6cMoYsYPXpSOqV7XAp8dUv/TW0
-V8/bhUiZucJvbI/NeJWsZCj9VrDDb8O+WVLhX4SPgPL0DTatdrOjteFkdjpY3H1P
-XlZs5VVZV6Xf8YpmMIzUUmI4d7S+KNfKNsSbBfD4Fdvb8e80nR14SohWZ25g/4/I
-i+GOvUKpMwpZQhISKvqxnUOOBZuZ2mKtVzazHbYNeS2WuOvyDEsMpZTGMKcmGS3t
-TAZQMPH9WD25SxdfGbRqhFS0OE85og2WaMMolP3tLR9Ka0OWLpABEPs4poEL0L91
-09S5zvE/bw4cHjdx5RiHdRk/ULlepEU0rbDK5uUTdg8xFKmOLZTW1YVNcxVPS/Ky
-Pu1svf0OnWZzsD2097+o4BGkxK51CUpjAEggpsadCwmKtODmzj7HPiY46SvepghJ
-AwSQiumPv+i2tCqjI40cHLI5kqiPAlxAOXXUc0ECd97N4EOH1uS6SsNsEn/+KuYj
-1oxx
------END CERTIFICATE-----
-
-# OpenTrust Root CA G2
------BEGIN CERTIFICATE-----
-MIIFbzCCA1egAwIBAgISESChaRu/vbm9UpaPI+hIvyYRMA0GCSqGSIb3DQEBDQUA
-MEAxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9w
-ZW5UcnVzdCBSb290IENBIEcyMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAw
-MFowQDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwU
-T3BlblRydXN0IFJvb3QgQ0EgRzIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
-AoICAQDMtlelM5QQgTJT32F+D3Y5z1zCU3UdSXqWON2ic2rxb95eolq5cSG+Ntmh
-/LzubKh8NBpxGuga2F8ORAbtp+Dz0mEL4DKiltE48MLaARf85KxP6O6JHnSrT78e
-CbY2albz4e6WiWYkBuTNQjpK3eCasMSCRbP+yatcfD7J6xcvDH1urqWPyKwlCm/6
-1UWY0jUJ9gNDlP7ZvyCVeYCYitmJNbtRG6Q3ffyZO6v/v6wNj0OxmXsWEH4db0fE
-FY8ElggGQgT4hNYdvJGmQr5J1WqIP7wtUdGejeBSzFfdNTVY27SPJIjki9/ca1TS
-gSuyzpJLHB9G+h3Ykst2Z7UJmQnlrBcUVXDGPKBWCgOz3GIZ38i1MH/1PCZ1Eb3X
-G7OHngevZXHloM8apwkQHZOJZlvoPGIytbU6bumFAYueQ4xncyhZW+vj3CzMpSZy
-YhK05pyDRPZRpOLAeiRXyg6lPzq1O4vldu5w5pLeFlwoW5cZJ5L+epJUzpM5ChaH
-vGOz9bGTXOBut9Dq+WIyiET7vycotjCVXRIouZW+j1MY5aIYFuJWpLIsEPUdN6b4
-t/bQWVyJ98LVtZR00dX+G7bw5tYee9I8y6jj9RjzIR9u701oBnstXW5DiabA+aC/
-gh7PU3+06yzbXfZqfUAkBXKJOAGTy3HCOV0GEfZvePg3DTmEJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUajn6QiL3
-5okATV59M4PLuG53hq8wHwYDVR0jBBgwFoAUajn6QiL35okATV59M4PLuG53hq8w
-DQYJKoZIhvcNAQENBQADggIBAJjLq0A85TMCl38th6aP1F5Kr7ge57tx+4BkJamz
-Gj5oXScmp7oq4fBXgwpkTx4idBvpkF/wrM//T2h6OKQQbA2xx6R3gBi2oihEdqc0
-nXGEL8pZ0keImUEiyTCYYW49qKgFbdEfwFFEVn8nNQLdXpgKQuswv42hm1GqO+qT
-RmTFAHneIWv2V6CG1wZy7HBGS4tz3aAhdT7cHcCP009zHIXZ/n9iyJVvttN7jLpT
-wm+bREx50B1ws9efAvSyB7DH5fitIw6mVskpEndI2S9G/Tvw/HRwkqWOOAgfZDC2
-t0v7NqwQjqBSM2OdAzVWxWm9xiNaJ5T2pBL4LTM8oValX9YZ6e18CL13zSdkzJTa
-TkZQh+D5wVOAHrut+0dSixv9ovneDiK3PTNZbNTe9ZUGMg1RGUFcPk8G97krgCf2
-o6p6fAbhQ8MTOWIaNr3gKC6UAuQpLmBVrkA9sHSSXvAgZJY/X0VdiLWK2gKgW0VU
-3jg9CcCoSmVGFvyqv1ROTVu+OEO3KMqLM6oaJbolXCkvW0pujOotnCr2BXbgd5eA
-iN1nE28daCSLT7d0geX0YJ96Vdc+N9oWaz53rK4YcJUIeSkDiv7BO7M/Gg+kO14f
-WKGVyasvc0rQLW6aWQ9VGHgtPFGml4vmu7JwqkwR3v98KzfUetF3NI/n+UL3PIEM
-S1IK
------END CERTIFICATE-----
-
-# OpenTrust Root CA G3
------BEGIN CERTIFICATE-----
-MIICITCCAaagAwIBAgISESDm+Ez8JLC+BUCs2oMbNGA/MAoGCCqGSM49BAMDMEAx
-CzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlPcGVuVHJ1c3QxHTAbBgNVBAMMFE9wZW5U
-cnVzdCBSb290IENBIEczMB4XDTE0MDUyNjAwMDAwMFoXDTM4MDExNTAwMDAwMFow
-QDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCU9wZW5UcnVzdDEdMBsGA1UEAwwUT3Bl
-blRydXN0IFJvb3QgQ0EgRzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARK7liuTcpm
-3gY6oxH84Bjwbhy6LTAMidnW7ptzg6kjFYwvWYpa3RTqnVkrQ7cG7DK2uu5Bta1d
-oYXM6h0UZqNnfkbilPPntlahFVmhTzeXuSIevRHr9LIfXsMUmuXZl5mjYzBhMA4G
-A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRHd8MUi2I5
-DMlv4VBN0BBY3JWIbTAfBgNVHSMEGDAWgBRHd8MUi2I5DMlv4VBN0BBY3JWIbTAK
-BggqhkjOPQQDAwNpADBmAjEAj6jcnboMBBf6Fek9LykBl7+BFjNAk2z8+e2AcG+q
-j9uEwov1NcoG3GRvaBbhj5G5AjEA2Euly8LQCGzpGPta3U1fJAuwACEl74+nBCZx
-4nxp5V2a+EEfOzmTk51V6s2N8fvB
+# OISTE WISeKey Global Root GC CA
+-----BEGIN CERTIFICATE-----
+MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw
+CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91
+bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg
+Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ
+BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu
+ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS
+b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni
+eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W
+p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E
+BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T
+rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV
+57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg
+Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9
-----END CERTIFICATE-----
# QuoVadis Root CA
@@ -3302,33 +3220,6 @@ jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
ZetX2fNXlrtIzYE=
-----END CERTIFICATE-----
-# TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı H5
------BEGIN CERTIFICATE-----
-MIIEJzCCAw+gAwIBAgIHAI4X/iQggTANBgkqhkiG9w0BAQsFADCBsTELMAkGA1UE
-BhMCVFIxDzANBgNVBAcMBkFua2FyYTFNMEsGA1UECgxEVMOcUktUUlVTVCBCaWxn
-aSDEsGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkg
-QS7Fni4xQjBABgNVBAMMOVTDnFJLVFJVU1QgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSBINTAeFw0xMzA0MzAwODA3MDFaFw0yMzA0
-MjgwODA3MDFaMIGxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMU0wSwYD
-VQQKDERUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
-dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjFCMEAGA1UEAww5VMOcUktUUlVTVCBF
-bGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIEg1MIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApCUZ4WWe60ghUEoI5RHwWrom
-/4NZzkQqL/7hzmAD/I0Dpe3/a6i6zDQGn1k19uwsu537jVJp45wnEFPzpALFp/kR
-Gml1bsMdi9GYjZOHp3GXDSHHmflS0yxjXVW86B8BSLlg/kJK9siArs1mep5Fimh3
-4khon6La8eHBEJ/rPCmBp+EyCNSgBbGM+42WAA4+Jd9ThiI7/PS98wl+d+yG6w8z
-5UNP9FR1bSmZLmZaQ9/LXMrI5Tjxfjs1nQ/0xVqhzPMggCTTV+wVunUlm+hkS7M0
-hO8EuPbJbKoCPrZV4jI3X/xml1/N1p7HIL9Nxqw/dV8c7TKcfGkAaZHjIxhT6QID
-AQABo0IwQDAdBgNVHQ4EFgQUVpkHHtOsDGlktAxQR95DLL4gwPswDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAJ5FdnsX
-SDLyOIspve6WSk6BGLFRRyDN0GSxDsnZAdkJzsiZ3GglE9Rc8qPoBP5yCccLqh0l
-VX6Wmle3usURehnmp349hQ71+S4pL+f5bFgWV1Al9j4uPqrtd3GqqpmWRgqujuwq
-URawXs3qZwQcWDD1YIq9pr1N5Za0/EKJAWv2cMhQOQwt1WbZyNKzMrcbGW3LM/nf
-peYVhDfwwvJllpKQd/Ct9JDpEXjXk4nAPQu6KfTomZ1yju2dL+6SfaHx/126M2CF
-Yv4HAqGEVka+lgqaE9chTLd8B59OTj+RdPsnnRHM3eaxynFNExc5JsUpISuTKWqW
-+qtB4Uu2NQvAmxU=
------END CERTIFICATE-----
-
# USERTrust ECC Certification Authority
-----BEGIN CERTIFICATE-----
MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDEL
diff --git a/platform/android/cpu-features.c b/thirdparty/libvpx/third_party/android/cpu-features.c
index 9cdadd5407..e2bd749b01 100644
--- a/platform/android/cpu-features.c
+++ b/thirdparty/libvpx/third_party/android/cpu-features.c
@@ -28,6 +28,10 @@
/* ChangeLog for this library:
*
+ * NDK r10e?: Add MIPS MSA feature.
+ *
+ * NDK r10: Support for 64-bit CPUs (Intel, ARM & MIPS).
+ *
* NDK r8d: Add android_setCpu().
*
* NDK r8c: Add new ARM CPU features: VFPv2, VFP_D32, VFP_FP16,
@@ -57,20 +61,17 @@
* NDK r4: Initial release
*/
-#if defined(__le32__)
-
-// When users enter this, we should only provide interface and
-// libportable will give the implementations.
-
-#else // !__le32__
+#include "cpu-features.h"
-#include <sys/system_properties.h>
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
#include <pthread.h>
-#include "cpu-features.h"
#include <stdio.h>
#include <stdlib.h>
-#include <fcntl.h>
-#include <errno.h>
+#include <string.h>
+#include <sys/system_properties.h>
+#include <unistd.h>
static pthread_once_t g_once;
static int g_inited;
@@ -82,15 +83,7 @@ static int g_cpuCount;
static uint32_t g_cpuIdArm;
#endif
-static const int android_cpufeatures_debug = 0;
-
-#ifdef __arm__
-# define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_ARM
-#elif defined __i386__
-# define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_X86
-#else
-# define DEFAULT_CPU_FAMILY ANDROID_CPU_FAMILY_UNKNOWN
-#endif
+static const int android_cpufeatures_debug = 0;
#define D(...) \
do { \
@@ -118,6 +111,25 @@ static __inline__ void x86_cpuid(int func, int values[4])
values[2] = c;
values[3] = d;
}
+#elif defined(__x86_64__)
+static __inline__ void x86_cpuid(int func, int values[4])
+{
+ int64_t a, b, c, d;
+ /* We need to preserve ebx since we're compiling PIC code */
+ /* this means we can't use "=b" for the second output register */
+ __asm__ __volatile__ ( \
+ "push %%rbx\n"
+ "cpuid\n" \
+ "mov %%rbx, %1\n"
+ "pop %%rbx\n"
+ : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
+ : "a" (func) \
+ );
+ values[0] = a;
+ values[1] = b;
+ values[2] = c;
+ values[3] = d;
+}
#endif
/* Get the size of a file by reading it until the end. This is needed
@@ -127,7 +139,8 @@ static __inline__ void x86_cpuid(int func, int values[4])
static int
get_file_size(const char* pathname)
{
- int fd, result = 0;
+
+ int fd, result = 0;
char buffer[256];
fd = open(pathname, O_RDONLY);
@@ -187,6 +200,7 @@ read_file(const char* pathname, char* buffer, size_t buffsize)
return count;
}
+#ifdef __arm__
/* Extract the content of a the first occurence of a given field in
* the content of /proc/cpuinfo and return it as a heap-allocated
* string that must be freed by the caller.
@@ -199,7 +213,7 @@ extract_cpuinfo_field(const char* buffer, int buflen, const char* field)
int fieldlen = strlen(field);
const char* bufend = buffer + buflen;
char* result = NULL;
- int len, ignore;
+ int len;
const char *p, *q;
/* Look for first field occurence, and ensures it starts the line. */
@@ -272,6 +286,7 @@ has_list_item(const char* list, const char* item)
}
return 0;
}
+#endif /* __arm__ */
/* Parse a number starting from 'input', but not going further
* than 'limit'. Return the value into '*result'.
@@ -316,11 +331,13 @@ parse_decimal(const char* input, const char* limit, int* result)
return parse_number(input, limit, 10, result);
}
+#ifdef __arm__
static const char*
parse_hexadecimal(const char* input, const char* limit, int* result)
{
return parse_number(input, limit, 16, result);
}
+#endif /* __arm__ */
/* This small data type is used to represent a CPU list / mask, as read
* from sysfs on Linux. See http://www.kernel.org/doc/Documentation/cputopology.txt
@@ -432,6 +449,18 @@ cpulist_read_from(CpuList* list, const char* filename)
cpulist_parse(list, file, filelen);
}
+#if defined(__aarch64__)
+// see <uapi/asm/hwcap.h> kernel header
+#define HWCAP_FP (1 << 0)
+#define HWCAP_ASIMD (1 << 1)
+#define HWCAP_AES (1 << 3)
+#define HWCAP_PMULL (1 << 4)
+#define HWCAP_SHA1 (1 << 5)
+#define HWCAP_SHA2 (1 << 6)
+#define HWCAP_CRC32 (1 << 7)
+#endif
+
+#if defined(__arm__)
// See <asm/hwcap.h> kernel header.
#define HWCAP_VFP (1 << 6)
@@ -443,27 +472,84 @@ cpulist_read_from(CpuList* list, const char* filename)
#define HWCAP_IDIVA (1 << 17)
#define HWCAP_IDIVT (1 << 18)
+// see <uapi/asm/hwcap.h> kernel header
+#define HWCAP2_AES (1 << 0)
+#define HWCAP2_PMULL (1 << 1)
+#define HWCAP2_SHA1 (1 << 2)
+#define HWCAP2_SHA2 (1 << 3)
+#define HWCAP2_CRC32 (1 << 4)
+
+// This is the list of 32-bit ARMv7 optional features that are _always_
+// supported by ARMv8 CPUs, as mandated by the ARM Architecture Reference
+// Manual.
+#define HWCAP_SET_FOR_ARMV8 \
+ ( HWCAP_VFP | \
+ HWCAP_NEON | \
+ HWCAP_VFPv3 | \
+ HWCAP_VFPv4 | \
+ HWCAP_IDIVA | \
+ HWCAP_IDIVT )
+#endif
+
+#if defined(__mips__)
+// see <uapi/asm/hwcap.h> kernel header
+#define HWCAP_MIPS_R6 (1 << 0)
+#define HWCAP_MIPS_MSA (1 << 1)
+#endif
+
+#if defined(__arm__) || defined(__aarch64__) || defined(__mips__)
+
#define AT_HWCAP 16
+#define AT_HWCAP2 26
+
+// Probe the system's C library for a 'getauxval' function and call it if
+// it exits, or return 0 for failure. This function is available since API
+// level 20.
+//
+// This code does *NOT* check for '__ANDROID_API__ >= 20' to support the
+// edge case where some NDK developers use headers for a platform that is
+// newer than the one really targetted by their application.
+// This is typically done to use newer native APIs only when running on more
+// recent Android versions, and requires careful symbol management.
+//
+// Note that getauxval() can't really be re-implemented here, because
+// its implementation does not parse /proc/self/auxv. Instead it depends
+// on values that are passed by the kernel at process-init time to the
+// C runtime initialization layer.
+static uint32_t
+get_elf_hwcap_from_getauxval(int hwcap_type) {
+ typedef unsigned long getauxval_func_t(unsigned long);
+
+ dlerror();
+ void* libc_handle = dlopen("libc.so", RTLD_NOW);
+ if (!libc_handle) {
+ D("Could not dlopen() C library: %s\n", dlerror());
+ return 0;
+ }
+
+ uint32_t ret = 0;
+ getauxval_func_t* func = (getauxval_func_t*)
+ dlsym(libc_handle, "getauxval");
+ if (!func) {
+ D("Could not find getauxval() in C library\n");
+ } else {
+ // Note: getauxval() returns 0 on failure. Doesn't touch errno.
+ ret = (uint32_t)(*func)(hwcap_type);
+ }
+ dlclose(libc_handle);
+ return ret;
+}
+#endif
#if defined(__arm__)
-/* Compute the ELF HWCAP flags.
- */
+// Parse /proc/self/auxv to extract the ELF HW capabilities bitmap for the
+// current CPU. Note that this file is not accessible from regular
+// application processes on some Android platform releases.
+// On success, return new ELF hwcaps, or 0 on failure.
static uint32_t
-get_elf_hwcap(const char* cpuinfo, int cpuinfo_len)
-{
- /* IMPORTANT:
- * Accessing /proc/self/auxv doesn't work anymore on all
- * platform versions. More specifically, when running inside
- * a regular application process, most of /proc/self/ will be
- * non-readable, including /proc/self/auxv. This doesn't
- * happen however if the application is debuggable, or when
- * running under the "shell" UID, which is why this was not
- * detected appropriately.
- */
-#if 0
- uint32_t result = 0;
+get_elf_hwcap_from_proc_self_auxv(void) {
const char filepath[] = "/proc/self/auxv";
- int fd = open(filepath, O_RDONLY);
+ int fd = TEMP_FAILURE_RETRY(open(filepath, O_RDONLY));
if (fd < 0) {
D("Could not open %s: %s\n", filepath, strerror(errno));
return 0;
@@ -471,11 +557,10 @@ get_elf_hwcap(const char* cpuinfo, int cpuinfo_len)
struct { uint32_t tag; uint32_t value; } entry;
+ uint32_t result = 0;
for (;;) {
- int ret = read(fd, (char*)&entry, sizeof entry);
+ int ret = TEMP_FAILURE_RETRY(read(fd, (char*)&entry, sizeof entry));
if (ret < 0) {
- if (errno == EINTR)
- continue;
D("Error while reading %s: %s\n", filepath, strerror(errno));
break;
}
@@ -489,12 +574,33 @@ get_elf_hwcap(const char* cpuinfo, int cpuinfo_len)
}
close(fd);
return result;
-#else
- // Recreate ELF hwcaps by parsing /proc/cpuinfo Features tag.
+}
+
+/* Compute the ELF HWCAP flags from the content of /proc/cpuinfo.
+ * This works by parsing the 'Features' line, which lists which optional
+ * features the device's CPU supports, on top of its reference
+ * architecture.
+ */
+static uint32_t
+get_elf_hwcap_from_proc_cpuinfo(const char* cpuinfo, int cpuinfo_len) {
uint32_t hwcaps = 0;
+ long architecture = 0;
+ char* cpuArch = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "CPU architecture");
+ if (cpuArch) {
+ architecture = strtol(cpuArch, NULL, 10);
+ free(cpuArch);
+
+ if (architecture >= 8L) {
+ // This is a 32-bit ARM binary running on a 64-bit ARM64 kernel.
+ // The 'Features' line only lists the optional features that the
+ // device's CPU supports, compared to its reference architecture
+ // which are of no use for this process.
+ D("Faking 32-bit ARM HWCaps on ARMv%ld CPU\n", architecture);
+ return HWCAP_SET_FOR_ARMV8;
+ }
+ }
char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
-
if (cpuFeatures != NULL) {
D("Found cpuFeatures = '%s'\n", cpuFeatures);
@@ -520,7 +626,6 @@ get_elf_hwcap(const char* cpuinfo, int cpuinfo_len)
free(cpuFeatures);
}
return hwcaps;
-#endif
}
#endif /* __arm__ */
@@ -609,9 +714,6 @@ android_cpuInit(void)
#ifdef __arm__
{
- char* features = NULL;
- char* architecture = NULL;
-
/* Extract architecture from the "CPU Architecture" field.
* The list is well-known, unlike the the output of
* the 'Processor' field which can vary greatly.
@@ -632,10 +734,7 @@ android_cpuInit(void)
/* read the initial decimal number, ignore the rest */
archNumber = strtol(cpuArch, &end, 10);
- /* Here we assume that ARMv8 will be upwards compatible with v7
- * in the future. Unfortunately, there is no 'Features' field to
- * indicate that Thumb-2 is supported.
- */
+ /* Note that ARMv8 is upwards compatible with ARMv7. */
if (end > cpuArch && archNumber >= 7) {
hasARMv7 = 1;
}
@@ -676,7 +775,19 @@ android_cpuInit(void)
}
/* Extract the list of CPU features from ELF hwcaps */
- uint32_t hwcaps = get_elf_hwcap(cpuinfo, cpuinfo_len);
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
+ if (!hwcaps) {
+ D("Parsing /proc/self/auxv to extract ELF hwcaps!\n");
+ hwcaps = get_elf_hwcap_from_proc_self_auxv();
+ }
+ if (!hwcaps) {
+ // Parsing /proc/self/auxv will fail from regular application
+ // processes on some Android platform versions, when this happens
+ // parse proc/cpuinfo instead.
+ D("Parsing /proc/cpuinfo to extract ELF hwcaps!\n");
+ hwcaps = get_elf_hwcap_from_proc_cpuinfo(cpuinfo, cpuinfo_len);
+ }
if (hwcaps != 0) {
int has_vfp = (hwcaps & HWCAP_VFP);
@@ -737,6 +848,27 @@ android_cpuInit(void)
g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_iWMMXt;
}
+ /* Extract the list of CPU features from ELF hwcaps2 */
+ uint32_t hwcaps2 = 0;
+ hwcaps2 = get_elf_hwcap_from_getauxval(AT_HWCAP2);
+ if (hwcaps2 != 0) {
+ int has_aes = (hwcaps2 & HWCAP2_AES);
+ int has_pmull = (hwcaps2 & HWCAP2_PMULL);
+ int has_sha1 = (hwcaps2 & HWCAP2_SHA1);
+ int has_sha2 = (hwcaps2 & HWCAP2_SHA2);
+ int has_crc32 = (hwcaps2 & HWCAP2_CRC32);
+
+ if (has_aes)
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_AES;
+ if (has_pmull)
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_PMULL;
+ if (has_sha1)
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA1;
+ if (has_sha2)
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_SHA2;
+ if (has_crc32)
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_CRC32;
+ }
/* Extract the cpuid value from various fields */
// The CPUID value is broken up in several entries in /proc/cpuinfo.
// This table is used to rebuild it from the entries.
@@ -806,10 +938,64 @@ android_cpuInit(void)
g_cpuFeatures |= entry->or_flags;
}
+ // Special case: The emulator-specific Android 4.2 kernel fails
+ // to report support for the 32-bit ARM IDIV instruction.
+ // Technically, this is a feature of the virtual CPU implemented
+ // by the emulator. Note that it could also support Thumb IDIV
+ // in the future, and this will have to be slightly updated.
+ char* hardware = extract_cpuinfo_field(cpuinfo,
+ cpuinfo_len,
+ "Hardware");
+ if (hardware) {
+ if (!strcmp(hardware, "Goldfish") &&
+ g_cpuIdArm == 0x4100c080 &&
+ (g_cpuFamily & ANDROID_CPU_ARM_FEATURE_ARMv7) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_ARM_FEATURE_IDIV_ARM;
+ }
+ free(hardware);
+ }
}
#endif /* __arm__ */
+#ifdef __aarch64__
+ {
+ /* Extract the list of CPU features from ELF hwcaps */
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
+ if (hwcaps != 0) {
+ int has_fp = (hwcaps & HWCAP_FP);
+ int has_asimd = (hwcaps & HWCAP_ASIMD);
+ int has_aes = (hwcaps & HWCAP_AES);
+ int has_pmull = (hwcaps & HWCAP_PMULL);
+ int has_sha1 = (hwcaps & HWCAP_SHA1);
+ int has_sha2 = (hwcaps & HWCAP_SHA2);
+ int has_crc32 = (hwcaps & HWCAP_CRC32);
+
+ if(has_fp == 0) {
+ D("ERROR: Floating-point unit missing, but is required by Android on AArch64 CPUs\n");
+ }
+ if(has_asimd == 0) {
+ D("ERROR: ASIMD unit missing, but is required by Android on AArch64 CPUs\n");
+ }
-#ifdef __i386__
+ if (has_fp)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_FP;
+ if (has_asimd)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_ASIMD;
+ if (has_aes)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_AES;
+ if (has_pmull)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_PMULL;
+ if (has_sha1)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA1;
+ if (has_sha2)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_SHA2;
+ if (has_crc32)
+ g_cpuFeatures |= ANDROID_CPU_ARM64_FEATURE_CRC32;
+ }
+ }
+#endif /* __aarch64__ */
+
+#if defined(__i386__) || defined(__x86_64__)
int regs[4];
/* According to http://en.wikipedia.org/wiki/CPUID */
@@ -829,10 +1015,50 @@ android_cpuInit(void)
if ((regs[2] & (1 << 23)) != 0) {
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_POPCNT;
}
+ if ((regs[2] & (1 << 19)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_1;
+ }
+ if ((regs[2] & (1 << 20)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SSE4_2;
+ }
if (vendorIsIntel && (regs[2] & (1 << 22)) != 0) {
g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_MOVBE;
}
+ if ((regs[2] & (1 << 25)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AES_NI;
+ }
+ if ((regs[2] & (1 << 28)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX;
+ }
+ if ((regs[2] & (1 << 30)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_RDRAND;
+ }
+
+ x86_cpuid(7, regs);
+ if ((regs[1] & (1 << 5)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_AVX2;
+ }
+ if ((regs[1] & (1 << 29)) != 0) {
+ g_cpuFeatures |= ANDROID_CPU_X86_FEATURE_SHA_NI;
+ }
+
+
#endif
+#if defined( __mips__)
+ { /* MIPS and MIPS64 */
+ /* Extract the list of CPU features from ELF hwcaps */
+ uint32_t hwcaps = 0;
+ hwcaps = get_elf_hwcap_from_getauxval(AT_HWCAP);
+ if (hwcaps != 0) {
+ int has_r6 = (hwcaps & HWCAP_MIPS_R6);
+ int has_msa = (hwcaps & HWCAP_MIPS_MSA);
+ if (has_r6)
+ g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_R6;
+ if (has_msa)
+ g_cpuFeatures |= ANDROID_CPU_MIPS_FEATURE_MSA;
+ }
+ }
+#endif /* __mips__ */
free(cpuinfo);
}
@@ -1085,5 +1311,3 @@ android_setCpuArm(int cpu_count, uint64_t cpu_features, uint32_t cpu_id)
* ARCH_NEON_FP16 (+EXT_FP16)
*
*/
-
-#endif // defined(__le32__)
diff --git a/platform/android/cpu-features.h b/thirdparty/libvpx/third_party/android/cpu-features.h
index 01b7fe207c..1e9724197a 100644
--- a/platform/android/cpu-features.h
+++ b/thirdparty/libvpx/third_party/android/cpu-features.h
@@ -33,6 +33,9 @@
__BEGIN_DECLS
+/* A list of valid values returned by android_getCpuFamily().
+ * They describe the CPU Architecture of the current process.
+ */
typedef enum {
ANDROID_CPU_FAMILY_UNKNOWN = 0,
ANDROID_CPU_FAMILY_ARM,
@@ -46,11 +49,24 @@ typedef enum {
} AndroidCpuFamily;
-/* Return family of the device's CPU */
-extern AndroidCpuFamily android_getCpuFamily(void);
+/* Return the CPU family of the current process.
+ *
+ * Note that this matches the bitness of the current process. I.e. when
+ * running a 32-bit binary on a 64-bit capable CPU, this will return the
+ * 32-bit CPU family value.
+ */
+extern AndroidCpuFamily android_getCpuFamily(void);
+
+/* Return a bitmap describing a set of optional CPU features that are
+ * supported by the current device's CPU. The exact bit-flags returned
+ * depend on the value returned by android_getCpuFamily(). See the
+ * documentation for the ANDROID_CPU_*_FEATURE_* flags below for details.
+ */
+extern uint64_t android_getCpuFeatures(void);
-/* The list of feature flags for ARM CPUs that can be recognized by the
- * library. Value details are:
+/* The list of feature flags for ANDROID_CPU_FAMILY_ARM that can be
+ * recognized by the library (see note below for 64-bit ARM). Value details
+ * are:
*
* VFPv2:
* CPU supports the VFPv2 instruction set. Many, but not all, ARMv6 CPUs
@@ -106,6 +122,27 @@ extern AndroidCpuFamily android_getCpuFamily(void);
* ARM CPU. This is only available on a few XScale-based CPU designs
* sold by Marvell. Pretty rare in practice.
*
+ * AES:
+ * CPU supports AES instructions. These instructions are only
+ * available for 32-bit applications running on ARMv8 CPU.
+ *
+ * CRC32:
+ * CPU supports CRC32 instructions. These instructions are only
+ * available for 32-bit applications running on ARMv8 CPU.
+ *
+ * SHA2:
+ * CPU supports SHA2 instructions. These instructions are only
+ * available for 32-bit applications running on ARMv8 CPU.
+ *
+ * SHA1:
+ * CPU supports SHA1 instructions. These instructions are only
+ * available for 32-bit applications running on ARMv8 CPU.
+ *
+ * PMULL:
+ * CPU supports 64-bit PMULL and PMULL2 instructions. These
+ * instructions are only available for 32-bit applications
+ * running on ARMv8 CPU.
+ *
* If you want to tell the compiler to generate code that targets one of
* the feature set above, you should probably use one of the following
* flags (for more details, see technical note at the end of this file):
@@ -153,6 +190,13 @@ extern AndroidCpuFamily android_getCpuFamily(void);
*
* -mcpu=iwmmxt
* Allows the use of iWMMXt instrinsics with GCC.
+ *
+ * IMPORTANT NOTE: These flags should only be tested when
+ * android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM, i.e. this is a
+ * 32-bit process.
+ *
+ * When running a 64-bit ARM process on an ARMv8 CPU,
+ * android_getCpuFeatures() will return a different set of bitflags
*/
enum {
ANDROID_CPU_ARM_FEATURE_ARMv7 = (1 << 0),
@@ -167,19 +211,84 @@ enum {
ANDROID_CPU_ARM_FEATURE_IDIV_ARM = (1 << 9),
ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2 = (1 << 10),
ANDROID_CPU_ARM_FEATURE_iWMMXt = (1 << 11),
+ ANDROID_CPU_ARM_FEATURE_AES = (1 << 12),
+ ANDROID_CPU_ARM_FEATURE_PMULL = (1 << 13),
+ ANDROID_CPU_ARM_FEATURE_SHA1 = (1 << 14),
+ ANDROID_CPU_ARM_FEATURE_SHA2 = (1 << 15),
+ ANDROID_CPU_ARM_FEATURE_CRC32 = (1 << 16),
+};
+
+/* The bit flags corresponding to the output of android_getCpuFeatures()
+ * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_ARM64. Value details
+ * are:
+ *
+ * FP:
+ * CPU has Floating-point unit.
+ *
+ * ASIMD:
+ * CPU has Advanced SIMD unit.
+ *
+ * AES:
+ * CPU supports AES instructions.
+ *
+ * CRC32:
+ * CPU supports CRC32 instructions.
+ *
+ * SHA2:
+ * CPU supports SHA2 instructions.
+ *
+ * SHA1:
+ * CPU supports SHA1 instructions.
+ *
+ * PMULL:
+ * CPU supports 64-bit PMULL and PMULL2 instructions.
+ */
+enum {
+ ANDROID_CPU_ARM64_FEATURE_FP = (1 << 0),
+ ANDROID_CPU_ARM64_FEATURE_ASIMD = (1 << 1),
+ ANDROID_CPU_ARM64_FEATURE_AES = (1 << 2),
+ ANDROID_CPU_ARM64_FEATURE_PMULL = (1 << 3),
+ ANDROID_CPU_ARM64_FEATURE_SHA1 = (1 << 4),
+ ANDROID_CPU_ARM64_FEATURE_SHA2 = (1 << 5),
+ ANDROID_CPU_ARM64_FEATURE_CRC32 = (1 << 6),
};
+/* The bit flags corresponding to the output of android_getCpuFeatures()
+ * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_X86 or
+ * ANDROID_CPU_FAMILY_X86_64.
+ */
enum {
ANDROID_CPU_X86_FEATURE_SSSE3 = (1 << 0),
ANDROID_CPU_X86_FEATURE_POPCNT = (1 << 1),
ANDROID_CPU_X86_FEATURE_MOVBE = (1 << 2),
+ ANDROID_CPU_X86_FEATURE_SSE4_1 = (1 << 3),
+ ANDROID_CPU_X86_FEATURE_SSE4_2 = (1 << 4),
+ ANDROID_CPU_X86_FEATURE_AES_NI = (1 << 5),
+ ANDROID_CPU_X86_FEATURE_AVX = (1 << 6),
+ ANDROID_CPU_X86_FEATURE_RDRAND = (1 << 7),
+ ANDROID_CPU_X86_FEATURE_AVX2 = (1 << 8),
+ ANDROID_CPU_X86_FEATURE_SHA_NI = (1 << 9),
+};
+
+/* The bit flags corresponding to the output of android_getCpuFeatures()
+ * when android_getCpuFamily() returns ANDROID_CPU_FAMILY_MIPS
+ * or ANDROID_CPU_FAMILY_MIPS64. Values are:
+ *
+ * R6:
+ * CPU executes MIPS Release 6 instructions natively, and
+ * supports obsoleted R1..R5 instructions only via kernel traps.
+ *
+ * MSA:
+ * CPU supports Mips SIMD Architecture instructions.
+ */
+enum {
+ ANDROID_CPU_MIPS_FEATURE_R6 = (1 << 0),
+ ANDROID_CPU_MIPS_FEATURE_MSA = (1 << 1),
};
-extern uint64_t android_getCpuFeatures(void);
-#define android_getCpuFeaturesExt android_getCpuFeatures
/* Return the number of CPU cores detected on this device. */
-extern int android_getCpuCount(void);
+extern int android_getCpuCount(void);
/* The following is used to force the CPU count and features
* mask in sandboxed processes. Under 4.1 and higher, these processes
diff --git a/thirdparty/misc/ifaddrs-android.cc b/thirdparty/misc/ifaddrs-android.cc
new file mode 100644
index 0000000000..1f8835b829
--- /dev/null
+++ b/thirdparty/misc/ifaddrs-android.cc
@@ -0,0 +1,221 @@
+/*
+ * libjingle
+ * Copyright 2012, Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ifaddrs-android.h"
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/utsname.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <unistd.h>
+#include <errno.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+struct netlinkrequest {
+ nlmsghdr header;
+ ifaddrmsg msg;
+};
+namespace {
+const int kMaxReadSize = 4096;
+};
+int set_ifname(struct ifaddrs* ifaddr, int interface) {
+ char buf[IFNAMSIZ] = {0};
+ char* name = if_indextoname(interface, buf);
+ if (name == NULL) {
+ return -1;
+ }
+ ifaddr->ifa_name = new char[strlen(name) + 1];
+ strncpy(ifaddr->ifa_name, name, strlen(name) + 1);
+ return 0;
+}
+int set_flags(struct ifaddrs* ifaddr) {
+ int fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ return -1;
+ }
+ ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, ifaddr->ifa_name, IFNAMSIZ - 1);
+ int rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ close(fd);
+ if (rc == -1) {
+ return -1;
+ }
+ ifaddr->ifa_flags = ifr.ifr_flags;
+ return 0;
+}
+int set_addresses(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* data,
+ size_t len) {
+ if (msg->ifa_family == AF_INET) {
+ sockaddr_in* sa = new sockaddr_in;
+ sa->sin_family = AF_INET;
+ memcpy(&sa->sin_addr, data, len);
+ ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa);
+ } else if (msg->ifa_family == AF_INET6) {
+ sockaddr_in6* sa = new sockaddr_in6;
+ sa->sin6_family = AF_INET6;
+ sa->sin6_scope_id = msg->ifa_index;
+ memcpy(&sa->sin6_addr, data, len);
+ ifaddr->ifa_addr = reinterpret_cast<sockaddr*>(sa);
+ } else {
+ return -1;
+ }
+ return 0;
+}
+int make_prefixes(struct ifaddrs* ifaddr, int family, int prefixlen) {
+ char* prefix = NULL;
+ if (family == AF_INET) {
+ sockaddr_in* mask = new sockaddr_in;
+ mask->sin_family = AF_INET;
+ memset(&mask->sin_addr, 0, sizeof(in_addr));
+ ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask);
+ if (prefixlen > 32) {
+ prefixlen = 32;
+ }
+ prefix = reinterpret_cast<char*>(&mask->sin_addr);
+ } else if (family == AF_INET6) {
+ sockaddr_in6* mask = new sockaddr_in6;
+ mask->sin6_family = AF_INET6;
+ memset(&mask->sin6_addr, 0, sizeof(in6_addr));
+ ifaddr->ifa_netmask = reinterpret_cast<sockaddr*>(mask);
+ if (prefixlen > 128) {
+ prefixlen = 128;
+ }
+ prefix = reinterpret_cast<char*>(&mask->sin6_addr);
+ } else {
+ return -1;
+ }
+ for (int i = 0; i < (prefixlen / 8); i++) {
+ *prefix++ = 0xFF;
+ }
+ char remainder = 0xff;
+ remainder <<= (8 - prefixlen % 8);
+ *prefix = remainder;
+ return 0;
+}
+int populate_ifaddrs(struct ifaddrs* ifaddr, ifaddrmsg* msg, void* bytes,
+ size_t len) {
+ if (set_ifname(ifaddr, msg->ifa_index) != 0) {
+ return -1;
+ }
+ if (set_flags(ifaddr) != 0) {
+ return -1;
+ }
+ if (set_addresses(ifaddr, msg, bytes, len) != 0) {
+ return -1;
+ }
+ if (make_prefixes(ifaddr, msg->ifa_family, msg->ifa_prefixlen) != 0) {
+ return -1;
+ }
+ return 0;
+}
+int getifaddrs(struct ifaddrs** result) {
+ int fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if (fd < 0) {
+ return -1;
+ }
+ netlinkrequest ifaddr_request;
+ memset(&ifaddr_request, 0, sizeof(ifaddr_request));
+ ifaddr_request.header.nlmsg_flags = NLM_F_ROOT | NLM_F_REQUEST;
+ ifaddr_request.header.nlmsg_type = RTM_GETADDR;
+ ifaddr_request.header.nlmsg_len = NLMSG_LENGTH(sizeof(ifaddrmsg));
+ ssize_t count = send(fd, &ifaddr_request, ifaddr_request.header.nlmsg_len, 0);
+ if (static_cast<size_t>(count) != ifaddr_request.header.nlmsg_len) {
+ close(fd);
+ return -1;
+ }
+ struct ifaddrs* start = NULL;
+ struct ifaddrs* current = NULL;
+ char buf[kMaxReadSize];
+ ssize_t amount_read = recv(fd, &buf, kMaxReadSize, 0);
+ while (amount_read > 0) {
+ nlmsghdr* header = reinterpret_cast<nlmsghdr*>(&buf[0]);
+ size_t header_size = static_cast<size_t>(amount_read);
+ for ( ; NLMSG_OK(header, header_size);
+ header = NLMSG_NEXT(header, header_size)) {
+ switch (header->nlmsg_type) {
+ case NLMSG_DONE:
+ // Success. Return.
+ *result = start;
+ close(fd);
+ return 0;
+ case NLMSG_ERROR:
+ close(fd);
+ freeifaddrs(start);
+ return -1;
+ case RTM_NEWADDR: {
+ ifaddrmsg* address_msg =
+ reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(header));
+ rtattr* rta = IFA_RTA(address_msg);
+ ssize_t payload_len = IFA_PAYLOAD(header);
+ while (RTA_OK(rta, payload_len)) {
+ if (rta->rta_type == IFA_ADDRESS) {
+ int family = address_msg->ifa_family;
+ if (family == AF_INET || family == AF_INET6) {
+ ifaddrs* newest = new ifaddrs;
+ memset(newest, 0, sizeof(ifaddrs));
+ if (current) {
+ current->ifa_next = newest;
+ } else {
+ start = newest;
+ }
+ if (populate_ifaddrs(newest, address_msg, RTA_DATA(rta),
+ RTA_PAYLOAD(rta)) != 0) {
+ freeifaddrs(start);
+ *result = NULL;
+ return -1;
+ }
+ current = newest;
+ }
+ }
+ rta = RTA_NEXT(rta, payload_len);
+ }
+ break;
+ }
+ }
+ }
+ amount_read = recv(fd, &buf, kMaxReadSize, 0);
+ }
+ close(fd);
+ freeifaddrs(start);
+ return -1;
+}
+void freeifaddrs(struct ifaddrs* addrs) {
+ struct ifaddrs* last = NULL;
+ struct ifaddrs* cursor = addrs;
+ while (cursor) {
+ delete[] cursor->ifa_name;
+ delete cursor->ifa_addr;
+ delete cursor->ifa_netmask;
+ last = cursor;
+ cursor = cursor->ifa_next;
+ delete last;
+ }
+}
diff --git a/platform/android/ifaddrs_android.h b/thirdparty/misc/ifaddrs-android.h
index 539fa40455..6e204af26f 100644
--- a/platform/android/ifaddrs_android.h
+++ b/thirdparty/misc/ifaddrs-android.h
@@ -33,13 +33,13 @@
// about every network interface available on the host.
// See 'man getifaddrs' on Linux or OS X (nb: it is not a POSIX function).
struct ifaddrs {
- struct ifaddrs* ifa_next;
- char* ifa_name;
- unsigned int ifa_flags;
- struct sockaddr* ifa_addr;
- struct sockaddr* ifa_netmask;
- // Real ifaddrs has broadcast, point to point and data members.
- // We don't need them (yet?).
+ struct ifaddrs* ifa_next;
+ char* ifa_name;
+ unsigned int ifa_flags;
+ struct sockaddr* ifa_addr;
+ struct sockaddr* ifa_netmask;
+ // Real ifaddrs has broadcast, point to point and data members.
+ // We don't need them (yet?).
};
int getifaddrs(struct ifaddrs** result);
void freeifaddrs(struct ifaddrs* addrs);