summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml6
-rw-r--r--core/error_list.h2
-rw-r--r--core/global_constants.cpp1
-rw-r--r--core/math/camera_matrix.cpp1
-rw-r--r--core/object.h5
-rw-r--r--core/os/dir_access.cpp3
-rw-r--r--core/os/file_access.h2
-rw-r--r--core/resource.cpp29
-rw-r--r--core/resource.h1
-rw-r--r--core/ustring.cpp2
-rw-r--r--doc/classes/@GlobalScope.xml3
-rw-r--r--doc/classes/Animation.xml2
-rw-r--r--doc/classes/AnimationPlayer.xml78
-rw-r--r--doc/classes/Area.xml12
-rw-r--r--doc/classes/CenterContainer.xml1
-rw-r--r--doc/classes/ColorPickerButton.xml5
-rw-r--r--doc/classes/CurveTexture.xml4
-rw-r--r--doc/classes/EditorFileDialog.xml44
-rw-r--r--doc/classes/NetworkedMultiplayerPeer.xml30
-rw-r--r--doc/classes/PackedScene.xml10
-rw-r--r--doc/classes/SceneState.xml24
-rw-r--r--doc/classes/WindowDialog.xml2
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp5
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp52
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h11
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp24
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h23
-rw-r--r--drivers/gles3/shader_gles3.cpp6
-rw-r--r--drivers/gles3/shaders/scene.glsl6
-rw-r--r--drivers/unix/rw_lock_posix.cpp2
-rw-r--r--drivers/unix/stream_peer_tcp_posix.cpp4
-rw-r--r--drivers/wasapi/audio_driver_wasapi.cpp84
-rw-r--r--drivers/wasapi/audio_driver_wasapi.h2
-rw-r--r--editor/doc/doc_data.cpp2
-rw-r--r--editor/editor_about.cpp13
-rw-r--r--editor/editor_about.h6
-rw-r--r--editor/editor_audio_buses.cpp4
-rw-r--r--editor/editor_data.cpp4
-rw-r--r--editor/editor_export.cpp12
-rw-r--r--editor/editor_file_dialog.cpp9
-rw-r--r--editor/editor_node.cpp15
-rw-r--r--editor/editor_profiler.cpp6
-rw-r--r--editor/editor_settings.cpp1
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_text_editor.cpp26
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp10
-rw-r--r--editor/plugins/spatial_editor_plugin.h3
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp105
-rw-r--r--editor/plugins/tile_map_editor_plugin.h2
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp56
-rw-r--r--editor/project_manager.cpp5
-rw-r--r--editor/property_editor.cpp41
-rw-r--r--editor/property_editor.h17
-rw-r--r--editor/script_editor_debugger.cpp2
-rw-r--r--editor/settings_config_dialog.cpp6
-rw-r--r--editor/translations/README.md7
-rw-r--r--modules/bullet/bullet_physics_server.cpp2
-rw-r--r--modules/gdnative/gdnative/basis.cpp2
-rw-r--r--modules/gdnative/gdnative/quat.cpp2
-rw-r--r--modules/gdnative/gdnative/vector2.cpp2
-rw-r--r--modules/gdnative/gdnative/vector3.cpp2
-rw-r--r--modules/gdnative/gdnative_api.json8
-rw-r--r--modules/gdnative/include/gdnative/basis.h2
-rw-r--r--modules/gdnative/include/gdnative/gdnative.h2
-rw-r--r--modules/gdnative/include/gdnative/quat.h2
-rw-r--r--modules/gdnative/include/gdnative/vector2.h2
-rw-r--r--modules/gdnative/include/gdnative/vector3.h2
-rw-r--r--modules/gdnative/register_types.cpp22
-rw-r--r--modules/mono/csharp_script.cpp4
-rw-r--r--modules/mono/glue/cs_files/Error.cs3
-rw-r--r--modules/opus/audio_stream_opus.cpp2
-rw-r--r--modules/squish/image_compress_squish.cpp2
-rw-r--r--modules/visual_script/visual_script_nodes.cpp8
-rw-r--r--modules/vorbis/audio_stream_ogg_vorbis.cpp2
-rw-r--r--platform/android/build.gradle.template2
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java18
-rw-r--r--platform/iphone/os_iphone.cpp4
-rw-r--r--platform/iphone/os_iphone.h2
-rw-r--r--platform/osx/os_osx.h1
-rw-r--r--platform/osx/os_osx.mm2
-rw-r--r--platform/server/os_server.h1
-rw-r--r--platform/windows/os_windows.cpp22
-rw-r--r--platform/windows/stream_peer_winsock.cpp4
-rw-r--r--scene/2d/particles_2d.cpp2
-rw-r--r--scene/2d/tile_map.cpp48
-rw-r--r--scene/2d/tile_map.h4
-rw-r--r--scene/animation/animation_player.cpp14
-rw-r--r--scene/gui/file_dialog.cpp8
-rw-r--r--scene/gui/rich_text_label.cpp11
-rw-r--r--scene/main/node.cpp2
-rw-r--r--scene/main/scene_tree.cpp4
-rw-r--r--scene/main/viewport.cpp10
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/register_scene_types.cpp1
-rw-r--r--scene/resources/default_theme/default_theme.cpp3
-rw-r--r--scene/resources/default_theme/icon_parent_folder.pngbin0 -> 329 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/material.cpp6
-rw-r--r--scene/resources/material.h3
-rw-r--r--scene/resources/packed_scene.cpp8
-rw-r--r--scene/resources/primitive_meshes.cpp2
-rw-r--r--scene/resources/texture.cpp69
-rw-r--r--scene/resources/texture.h27
-rw-r--r--servers/visual/rasterizer.h2
-rw-r--r--servers/visual/visual_server_raster.h2
-rw-r--r--servers/visual/visual_server_scene.cpp33
-rw-r--r--servers/visual/visual_server_scene.h1
-rw-r--r--servers/visual/visual_server_wrap_mt.h2
-rw-r--r--servers/visual_server.h2
109 files changed, 843 insertions, 396 deletions
diff --git a/.travis.yml b/.travis.yml
index acab89e516..2c4eda9105 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,9 +30,9 @@ matrix:
- env: GODOT_TARGET=android TOOLS=no CACHE_NAME=${GODOT_TARGET}-gcc
os: linux
compiler: gcc
- - env: GODOT_TARGET=osx TOOLS=yes CACHE_NAME=${GODOT_TARGET}-clang-tools
- os: osx
- compiler: clang
+ #- env: GODOT_TARGET=osx TOOLS=yes CACHE_NAME=${GODOT_TARGET}-clang-tools
+ # os: osx
+ # compiler: clang
#- env: GODOT_TARGET=iphone TOOLS=no CACHE_NAME=${GODOT_TARGET}-clang
# os: osx
# compiler: clang
diff --git a/core/error_list.h b/core/error_list.h
index 50d248b3d0..9a36b27aab 100644
--- a/core/error_list.h
+++ b/core/error_list.h
@@ -87,8 +87,6 @@ enum Error {
ERR_HELP, ///< user requested help!!
ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
- ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though
- ERR_WTF = ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
};
#endif
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 48101c8cf1..fb432b85db 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -491,7 +491,6 @@ void register_global_constants() {
BIND_GLOBAL_ENUM_CONSTANT(ERR_BUSY);
BIND_GLOBAL_ENUM_CONSTANT(ERR_HELP); ///< user requested help!!
BIND_GLOBAL_ENUM_CONSTANT(ERR_BUG); ///< a bug in the software certainly happened ), due to a double check failing or unexpected behavior.
- BIND_GLOBAL_ENUM_CONSTANT(ERR_WTF);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_NONE);
BIND_GLOBAL_ENUM_CONSTANT(PROPERTY_HINT_RANGE);
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index c5f1d57441..42d2d0373a 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -140,6 +140,7 @@ void CameraMatrix::set_for_hmd(int p_eye, real_t p_aspect, real_t p_intraocular_
real_t add = ((f1 + f2) * (p_oversample - 1.0)) / 2.0;
f1 += add;
f2 += add;
+ f3 *= p_oversample;
// always apply KEEP_WIDTH aspect ratio
f3 *= p_aspect;
diff --git a/core/object.h b/core/object.h
index 3ac699f978..0a0c781649 100644
--- a/core/object.h
+++ b/core/object.h
@@ -1,4 +1,4 @@
-/*************************************************************************/
+/*************************************************************************/
/* object.h */
/*************************************************************************/
/* This file is part of: */
@@ -109,10 +109,11 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 17,
PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 18,
PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 19,
+ PROPERTY_USAGE_INTERNAL = 1 << 20,
PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNATIONALIZED,
- PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK,
+ PROPERTY_USAGE_NOEDITOR = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_NETWORK | PROPERTY_USAGE_INTERNAL,
};
#define ADD_SIGNAL(m_signal) ClassDB::add_signal(get_class_static(), m_signal)
diff --git a/core/os/dir_access.cpp b/core/os/dir_access.cpp
index 6d4b46f4da..e19c8e8ea5 100644
--- a/core/os/dir_access.cpp
+++ b/core/os/dir_access.cpp
@@ -333,6 +333,9 @@ Error DirAccess::copy(String p_from, String p_to, int chmod_flags) {
if (err == OK && chmod_flags != -1) {
fdst->close();
err = fdst->_chmod(p_to, chmod_flags);
+ // If running on a platform with no chmod support (i.e., Windows), don't fail
+ if (err == ERR_UNAVAILABLE)
+ err = OK;
}
memdelete(fsrc);
diff --git a/core/os/file_access.h b/core/os/file_access.h
index 455dd1ea99..6fda3d9668 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -141,7 +141,7 @@ public:
virtual Error reopen(const String &p_path, int p_mode_flags); ///< does not change the AccessType
- virtual Error _chmod(const String &p_path, int p_mod) { return FAILED; }
+ virtual Error _chmod(const String &p_path, int p_mod) { return ERR_UNAVAILABLE; }
static FileAccess *create(AccessType p_access); /// Create a file access (for the current platform) this is the only portable way of accessing files.
static FileAccess *create_for_path(const String &p_path);
diff --git a/core/resource.cpp b/core/resource.cpp
index 78e20bada4..d339eb78ad 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -184,6 +184,35 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res
return Ref<Resource>(r);
}
+void Resource::configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache) {
+
+ print_line("configure for local: " + get_class());
+ List<PropertyInfo> plist;
+ get_property_list(&plist);
+
+ local_scene = p_for_scene;
+
+ for (List<PropertyInfo>::Element *E = plist.front(); E; E = E->next()) {
+
+ if (!(E->get().usage & PROPERTY_USAGE_STORAGE))
+ continue;
+ Variant p = get(E->get().name);
+ if (p.get_type() == Variant::OBJECT) {
+
+ RES sr = p;
+ if (sr.is_valid()) {
+
+ if (sr->is_local_to_scene()) {
+ if (!remap_cache.has(sr)) {
+ sr->configure_for_local_scene(p_for_scene, remap_cache);
+ remap_cache[sr] = sr;
+ }
+ }
+ }
+ }
+ }
+}
+
Ref<Resource> Resource::duplicate(bool p_subresources) const {
List<PropertyInfo> plist;
diff --git a/core/resource.h b/core/resource.h
index 7dc3b67291..19714a68d1 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -108,6 +108,7 @@ public:
virtual Ref<Resource> duplicate(bool p_subresources = false) const;
Ref<Resource> duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache);
+ void configure_for_local_scene(Node *p_for_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache);
void set_local_to_scene(bool p_enable);
bool is_local_to_scene() const;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index a86fb46c8a..3a0708851e 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -3380,8 +3380,6 @@ bool String::is_valid_float() const {
from++;
}
- //this was pulled out of my ass, i wonder if it's correct...
-
bool exponent_found = false;
bool period_found = false;
bool sign_found = false;
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 5655578459..deddaffdc6 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -1190,9 +1190,6 @@
<constant name="ERR_BUG" value="47" enum="Error">
Bug error
</constant>
- <constant name="ERR_WTF" value="49" enum="Error">
- WTF error (something probably went really wrong)
- </constant>
<constant name="PROPERTY_HINT_NONE" value="0" enum="PropertyHint">
No hint for edited property.
</constant>
diff --git a/doc/classes/Animation.xml b/doc/classes/Animation.xml
index ac547d20b7..c3933443a0 100644
--- a/doc/classes/Animation.xml
+++ b/doc/classes/Animation.xml
@@ -157,6 +157,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns [code]true[/code] if the track at [code]idx[/code] wraps the interpolation loop. Default value: [code]true[/code].
</description>
</method>
<method name="track_get_interpolation_type" qualifiers="const">
@@ -311,6 +312,7 @@
<argument index="1" name="interpolation" type="bool">
</argument>
<description>
+ 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/AnimationPlayer.xml b/doc/classes/AnimationPlayer.xml
index e724f24498..09ace05bfb 100644
--- a/doc/classes/AnimationPlayer.xml
+++ b/doc/classes/AnimationPlayer.xml
@@ -19,7 +19,7 @@
<argument index="1" name="animation" type="Animation">
</argument>
<description>
- Add an animation resource to the player, which will be later referenced by the "name" argument.
+ Adds [code]animation[/code] to the player accessible with the key [code]name[/code].
</description>
</method>
<method name="advance">
@@ -28,7 +28,7 @@
<argument index="0" name="delta" type="float">
</argument>
<description>
- Used to skip ahead or skip back in an animation. Delta is the time in seconds to skip.
+ Shifts position in the animation timeline. Delta is the time in seconds to shift.
</description>
</method>
<method name="animation_get_next" qualifiers="const">
@@ -37,7 +37,7 @@
<argument index="0" name="anim_from" type="String">
</argument>
<description>
- Return the name of the next animation in the queue.
+ Returns the name of the next animation in the queue.
</description>
</method>
<method name="animation_set_next">
@@ -48,21 +48,21 @@
<argument index="1" name="anim_to" type="String">
</argument>
<description>
- Set the name of an animation that will be played after.
+ Triggers the [code]anim_to[/code] animation when the [code]anim_from[/code] animation completes.
</description>
</method>
<method name="clear_caches">
<return type="void">
</return>
<description>
- The animation player creates caches for faster access to the nodes it will animate. However, if a specific node is removed, it may not notice it, so clear_caches will force the player to search for the nodes again.
+ [code]AnimationPlayer[/code] caches animated nodes. It may not notice if a node disappears, so clear_caches forces it to update the cache again.
</description>
</method>
<method name="clear_queue">
<return type="void">
</return>
<description>
- If animations are queued to play, clear them.
+ Clears all queued, unplayed animations.
</description>
</method>
<method name="find_animation" qualifiers="const">
@@ -71,7 +71,7 @@
<argument index="0" name="animation" type="Animation">
</argument>
<description>
- Find an animation name by resource.
+ Returns the name of [code]animation[/code] or empty string if not found.
</description>
</method>
<method name="get_animation" qualifiers="const">
@@ -80,21 +80,21 @@
<argument index="0" name="name" type="String">
</argument>
<description>
- Get an [Animation] resource by requesting a name.
+ Returns the [Animation] with key [code]name[/code] or [code]null[/code] if not found.
</description>
</method>
<method name="get_animation_list" qualifiers="const">
<return type="PoolStringArray">
</return>
<description>
- Get the list of names of the animations stored in the player.
+ Returns the list of stored animation names.
</description>
</method>
<method name="get_autoplay" qualifiers="const">
<return type="String">
</return>
<description>
- Return the name of the animation that will be automatically played when the scene is loaded.
+ Returns the name of the animation played when the scene loads.
</description>
</method>
<method name="get_blend_time" qualifiers="const">
@@ -105,35 +105,28 @@
<argument index="1" name="anim_to" type="String">
</argument>
<description>
- Get the blend time between two animations, referenced by their names.
+ Get the blend time (in seconds) between two animations, referenced by their names.
</description>
</method>
<method name="get_current_animation" qualifiers="const">
<return type="String">
</return>
<description>
- Return the name of the animation being played.
+ Returns the name of the currently playing animation.
</description>
</method>
- <method name="get_current_animation_length" qualifiers="const">
+ <method name="get_anim_length" qualifiers="const">
<return type="float">
</return>
<description>
- Get the length (in seconds) of the currently being played animation.
+ Get the length (in seconds) of the currently playing animation.
</description>
</method>
- <method name="get_current_animation_position" qualifiers="const">
+ <method name="get_anim_position" qualifiers="const">
<return type="float">
</return>
<description>
- Get the position (in seconds) of the currently being played animation.
- </description>
- </method>
- <method name="get_position" qualifiers="const">
- <return type="float">
- </return>
- <description>
- Return the playback position (in seconds) in an animation channel (or channel 0 if none is provided).
+ Get the position (in seconds) of the currently playing animation.
</description>
</method>
<method name="get_speed_scale" qualifiers="const">
@@ -149,21 +142,21 @@
<argument index="0" name="name" type="String">
</argument>
<description>
- Request whether an [Animation] name exist within the player.
+ Returns [code]true[/code] if the [code]AnimationPlayer[/code] stores an [Animation] with key [code]name[/code].
</description>
</method>
<method name="is_active" qualifiers="const">
<return type="bool">
</return>
<description>
- Return true if the player is active.
+ Returns true if the player is active.
</description>
</method>
<method name="is_playing" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether an animation is playing.
+ Returns [code]true[/code] if playing an animation.
</description>
</method>
<method name="play">
@@ -178,7 +171,7 @@
<argument index="3" name="from_end" type="bool" default="false">
</argument>
<description>
- Play a given animation by the animation name. Custom speed and blend times can be set. If custom speed is negative (-1), 'from_end' being true can play the animation backwards.
+ Play the animation with key [code]name[/code]. Custom speed and blend times can be set. If custom speed is negative (-1), 'from_end' being true can play the animation backwards.
</description>
</method>
<method name="play_backwards">
@@ -189,7 +182,7 @@
<argument index="1" name="custom_blend" type="float" default="-1">
</argument>
<description>
- Play a given animation by the animation name in reverse.
+ Play the animation with key [code]name[/code] in reverse.
</description>
</method>
<method name="queue">
@@ -207,7 +200,7 @@
<argument index="0" name="name" type="String">
</argument>
<description>
- Remove an animation from the player (by supplying the same name used to add it).
+ Remove the animation with key [code]name[/code].
</description>
</method>
<method name="rename_animation">
@@ -218,7 +211,7 @@
<argument index="1" name="newname" type="String">
</argument>
<description>
- Rename an existing animation.
+ Rename an existing animation with key [code]name[/code] to [code]newname[/code].
</description>
</method>
<method name="seek">
@@ -229,7 +222,7 @@
<argument index="1" name="update" type="bool" default="false">
</argument>
<description>
- Seek the animation to a given position in time (in seconds). If 'update' is true, the animation will be updated too, otherwise it will be updated at process time.
+ Seek the animation to the [code]seconds[/code] point in time (in seconds). If 'update' is true, the animation updates too, otherwise it updates at process time.
</description>
</method>
<method name="set_active">
@@ -287,7 +280,7 @@
<argument index="0" name="reset" type="bool" default="true">
</argument>
<description>
- Stop the currently playing animation.
+ Stop the currently playing animation. If [code]reset[/code] is [code]true[/code], the anim position is reset to [code]0[/code].
</description>
</method>
<method name="stop_all">
@@ -300,10 +293,25 @@
</methods>
<members>
<member name="playback_default_blend_time" type="float" setter="set_default_blend_time" getter="get_default_blend_time">
+ The default time in which to blend animations. Ranges from 0 to 4096 with 0.01 precision. Default value: [code]0[/code].
</member>
<member name="playback_process_mode" type="int" setter="set_animation_process_mode" getter="get_animation_process_mode" enum="AnimationPlayer.AnimationProcessMode">
+ The process notification in which to update animations. Default value: [enum ANIMATION_PROCESS_IDLE].
</member>
<member name="root_node" type="NodePath" setter="set_root" getter="get_root">
+ The node from which node path references will travel. Default value: [code]".."[/code].
+ </member>
+ <member name="autoplay" type="String" setter="set_autoplay" getter="get_autoplay">
+ The name of the animation to play when the scene loads. Default value: [code]""[/code].
+ </member>
+ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale">
+ The speed scaling ratio in a given animation channel (or channel 0 if none is provided). Default value: [code]1[/code].
+ </member>
+ <member name="active" type="bool" setter="set_active" getter="is_active">
+ If [code]true[/code] updates animations in response to process-related notifications. Default value: [code]true[/code].
+ </member>
+ <member name="current_anim" type="String" setter="set_current_anim" getter="get_current_anim">
+ The name of the current animation. If already playing, restarts the animation. Ensure [member active] is [code]true[/code] to simulate [method play]. Default value: [code]""[/code].
</member>
</members>
<signals>
@@ -313,21 +321,21 @@
<argument index="1" name="new_name" type="String">
</argument>
<description>
- If the currently being played animation changes, this signal will notify of such change.
+ Emitted when the [Animation] with key [member current_anim] is modified.
</description>
</signal>
<signal name="animation_finished">
<argument index="0" name="name" type="String">
</argument>
<description>
- Notifies when an animation finished playing.
+ Emitted when an animation finishes.
</description>
</signal>
<signal name="animation_started">
<argument index="0" name="name" type="String">
</argument>
<description>
- Notifies when an animation starts playing.
+ Emitted when an animation starts.
</description>
</signal>
</signals>
diff --git a/doc/classes/Area.xml b/doc/classes/Area.xml
index f58aa3cc0a..b74e767fd2 100644
--- a/doc/classes/Area.xml
+++ b/doc/classes/Area.xml
@@ -17,7 +17,7 @@
<argument index="0" name="bit" type="int">
</argument>
<description>
- Return an individual bit on the layer mask.
+ Returns an individual bit on the layer mask.
</description>
</method>
<method name="get_collision_mask_bit" qualifiers="const">
@@ -26,7 +26,7 @@
<argument index="0" name="bit" type="int">
</argument>
<description>
- Return an individual bit on the collision mask.
+ Returns an individual bit on the collision mask.
</description>
</method>
<method name="get_overlapping_areas" qualifiers="const">
@@ -69,7 +69,7 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
- Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier.
+ Set/clear individual bits on the layer mask. This simplifies editing this [code]Area[code]'s layers.
</description>
</method>
<method name="set_collision_mask_bit">
@@ -80,7 +80,7 @@
<argument index="1" name="value" type="bool">
</argument>
<description>
- Set/clear individual bits on the collision mask. This makes selecting the areas scanned easier.
+ Set/clear individual bits on the collision mask. This simplifies editing which [code]Area[/code] layers this [code]Area[/code] scans.
</description>
</method>
</methods>
@@ -125,12 +125,16 @@
The area's priority. Higher priority areas are processed first. Default value: 0.
</member>
<member name="reverb_bus_amount" type="float" setter="set_reverb_amount" getter="get_reverb_amount">
+ 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.
</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.
</member>
<member name="reverb_bus_uniformity" type="float" setter="set_reverb_uniformity" getter="get_reverb_uniformity">
+ 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.
diff --git a/doc/classes/CenterContainer.xml b/doc/classes/CenterContainer.xml
index 0db18aed53..6235a3fec4 100644
--- a/doc/classes/CenterContainer.xml
+++ b/doc/classes/CenterContainer.xml
@@ -14,6 +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].
</member>
</members>
<constants>
diff --git a/doc/classes/ColorPickerButton.xml b/doc/classes/ColorPickerButton.xml
index c538f66779..c8a4b850d0 100644
--- a/doc/classes/ColorPickerButton.xml
+++ b/doc/classes/ColorPickerButton.xml
@@ -15,13 +15,16 @@
<return type="ColorPicker">
</return>
<description>
+ Returns the [code]ColorPicker[/code] that this [code]ColorPickerButton[/code] toggles.
</description>
</method>
</methods>
<members>
<member name="color" type="Color" setter="set_pick_color" getter="get_pick_color">
+ 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].
</member>
</members>
<signals>
@@ -29,7 +32,7 @@
<argument index="0" name="color" type="Color">
</argument>
<description>
- Emitted when the color is changed.
+ Emitted when the color changes.
</description>
</signal>
</signals>
diff --git a/doc/classes/CurveTexture.xml b/doc/classes/CurveTexture.xml
index 73126de4aa..f62da8a135 100644
--- a/doc/classes/CurveTexture.xml
+++ b/doc/classes/CurveTexture.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="CurveTexture" inherits="Texture" category="Core" version="3.0-beta">
<brief_description>
+ A texture that shows a curve.
</brief_description>
<description>
+ Renders a given [Curve] provided to it. Simplifies the task of drawing curves and/or saving them as image files.
</description>
<tutorials>
</tutorials>
@@ -12,8 +14,10 @@
</methods>
<members>
<member name="curve" type="Curve" setter="set_curve" getter="get_curve">
+ The [code]curve[/code] rendered onto the texture.
</member>
<member name="width" type="int" setter="set_width" getter="get_width">
+ The width of the texture.
</member>
</members>
<constants>
diff --git a/doc/classes/EditorFileDialog.xml b/doc/classes/EditorFileDialog.xml
index e893d92840..4529a473c6 100644
--- a/doc/classes/EditorFileDialog.xml
+++ b/doc/classes/EditorFileDialog.xml
@@ -15,12 +15,15 @@
<argument index="0" name="filter" type="String">
</argument>
<description>
+ Adds a comma-delimited file extension filter option to the [code]EditorFileDialog[/code] with an optional semi-colon-delimited label.
+ Example: "*.tscn, *.scn; Scenes", results in filter text "Scenes (*.tscn, *.scn)".
</description>
</method>
<method name="clear_filters">
<return type="void">
</return>
<description>
+ Removes all filters except for "All Files (*)".
</description>
</method>
<method name="get_access" qualifiers="const">
@@ -63,12 +66,14 @@
<return type="VBoxContainer">
</return>
<description>
+ Returns the [code]VBoxContainer[/code] used to display the file system.
</description>
</method>
<method name="invalidate">
<return type="void">
</return>
<description>
+ Notify the [code]EditorFileDialog[/code] that its view of the data is no longer accurate. Updates the view contents on next view update.
</description>
</method>
<method name="is_overwrite_warning_disabled" qualifiers="const">
@@ -148,46 +153,85 @@
</description>
</method>
</methods>
+ <members>
+ <member name="access" type="int" enum="EditorFileDialog.Access" setter="set_access" getter="get_access">
+ The location from which the user may select a file, including [code]res://[/code], [code]user://[/code], and the local file system.
+ </member>
+ <member name="display_mode" type="int" enum="EditorFileDialog.DisplayMode" setter="set_display_mode" getter="get_display_mode">
+ The view format in which the [code]EditorFileDialog[/code] displays resources to the user.
+ </member>
+ <member name="mode" type="int" enum="EditorFileDialog.Mode" setter="set_mode" getter="get_mode">
+ The purpose of the [code]EditorFileDialog[/code]. Changes allowed behaviors.
+ </member>
+ <member name="current_dir" type="String" setter="set_current_dir" getter="get_current_dir">
+ The currently occupied directory.
+ </member>
+ <member name="current_file" type="String" setter="set_current_file" getter="get_current_file">
+ The currently selected file.
+ </member>
+ <member name="current_path" type="String" setter="set_current_path" getter="get_current_path">
+ The file system path in the address bar.
+ </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].
+ </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.
+ </member>
+ </members>
<signals>
<signal name="dir_selected">
<argument index="0" name="dir" type="String">
</argument>
<description>
+ Emitted when a directory is selected.
</description>
</signal>
<signal name="file_selected">
<argument index="0" name="path" type="String">
</argument>
<description>
+ Emitted when a file is selected.
</description>
</signal>
<signal name="files_selected">
<argument index="0" name="paths" type="PoolStringArray">
</argument>
<description>
+ Emitted when multiple files are selected.
</description>
</signal>
</signals>
<constants>
<constant name="MODE_OPEN_FILE" value="0" enum="Mode">
+ The [code]EditorFileDialog[/code] can select only one file. Accepting the window will open the file.
</constant>
<constant name="MODE_OPEN_FILES" value="1" enum="Mode">
+ The [code]EditorFileDialog[/code] can select multiple files. Accepting the window will open all files.
</constant>
<constant name="MODE_OPEN_DIR" value="2" enum="Mode">
+ The [code]EditorFileDialog[/code] can select only one directory. Accepting the window will open the directory.
</constant>
<constant name="MODE_OPEN_ANY" value="3" enum="Mode">
+ The [code]EditorFileDialog[/code] can select a file or directory. Accepting the window will open it.
</constant>
<constant name="MODE_SAVE_FILE" value="4" enum="Mode">
+ The [code]EditorFileDialog[/code] can select only one file. Accepting the window will save the file.
</constant>
<constant name="ACCESS_RESOURCES" value="0" enum="Access">
+ The [code]EditorFileDialog[/code] can only view [code]res://[/code] directory contents.
</constant>
<constant name="ACCESS_USERDATA" value="1" enum="Access">
+ The [code]EditorFileDialog[/code] can only view [code]user://[/code] directory contents.
</constant>
<constant name="ACCESS_FILESYSTEM" value="2" enum="Access">
+ The [code]EditorFileDialog[/code] can view the entire local file system.
</constant>
<constant name="DISPLAY_THUMBNAILS" value="0" enum="DisplayMode">
+ The [code]EditorFileDialog[/code] displays resources as thumbnails.
</constant>
<constant name="DISPLAY_LIST" value="1" enum="DisplayMode">
+ The [code]EditorFileDialog[/code] displays resources as a list of filenames.
</constant>
</constants>
</class>
diff --git a/doc/classes/NetworkedMultiplayerPeer.xml b/doc/classes/NetworkedMultiplayerPeer.xml
index 33ffce9cf9..a7350b3863 100644
--- a/doc/classes/NetworkedMultiplayerPeer.xml
+++ b/doc/classes/NetworkedMultiplayerPeer.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="NetworkedMultiplayerPeer" inherits="PacketPeer" category="Core" version="3.0-beta">
<brief_description>
+ A high-level network interface to simplify multiplayer interactions.
</brief_description>
<description>
+ Manages the connection to network peers. Assigns unique IDs to each client connected to the server.
</description>
<tutorials>
</tutorials>
@@ -13,31 +15,35 @@
<return type="int" enum="NetworkedMultiplayerPeer.ConnectionStatus">
</return>
<description>
+ Returns the current state of the connection. See [enum ConnectionStatus].
</description>
</method>
<method name="get_packet_peer" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the ID of the [code]NetworkedMultiplayerPeer[/code] who sent the most recent packet.
</description>
</method>
<method name="get_unique_id" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the ID of this [code]NetworkedMultiplayerPeer[/code].
</description>
</method>
<method name="is_refusing_new_connections" qualifiers="const">
<return type="bool">
</return>
<description>
- Return whether this [code]NetworkedMultiplayerPeer[/code] is refusing new connections.
+ Returns [code]true[/code] if this [code]NetworkedMultiplayerPeer[/code] refuses new connections. Default value: [code]false[/code].
</description>
</method>
<method name="poll">
<return type="void">
</return>
<description>
+ Waits up to 1 second to receive a new network event.
</description>
</method>
<method name="set_refuse_new_connections">
@@ -46,7 +52,7 @@
<argument index="0" name="enable" type="bool">
</argument>
<description>
- If [code]endable[/code] is true, this [code]NetworkedMultiplayerPeer[/code] will refuse new connections.
+ If [code]true[/code] this [code]NetworkedMultiplayerPeer[/code] refuses new connections. Default value: [code]false[/code].
</description>
</method>
<method name="set_target_peer">
@@ -55,6 +61,7 @@
<argument index="0" name="id" type="int">
</argument>
<description>
+ The peer to which packets will be sent. Default value: [code]0[/code].
</description>
</method>
<method name="set_transfer_mode">
@@ -63,56 +70,65 @@
<argument index="0" name="mode" type="int" enum="NetworkedMultiplayerPeer.TransferMode">
</argument>
<description>
+ The manner in which to send packets to the [code]target_peer[/code]. See [enum TransferMode].
</description>
</method>
</methods>
<signals>
<signal name="connection_failed">
<description>
- Emitted when failed to connect to server.
+ Emitted when a connection attempt fails.
</description>
</signal>
<signal name="connection_succeeded">
<description>
- Emitted when successfully connected to server.
+ Emitted when a connection attempt succeeds.
</description>
</signal>
<signal name="peer_connected">
<argument index="0" name="id" type="int">
</argument>
<description>
- Emitted by the server when a client is connected.
+ Emitted by the server when a client connects.
</description>
</signal>
<signal name="peer_disconnected">
<argument index="0" name="id" type="int">
</argument>
<description>
- Emitted by the server when a client is disconnected.
+ Emitted by the server when a client disconnects.
</description>
</signal>
<signal name="server_disconnected">
<description>
- Emitted by clients when server is disconnected.
+ Emitted by clients when the server disconnects.
</description>
</signal>
</signals>
<constants>
<constant name="TRANSFER_MODE_UNRELIABLE" value="0" enum="TransferMode">
+ Packets are sent via unordered UDP packets.
</constant>
<constant name="TRANSFER_MODE_UNRELIABLE_ORDERED" value="1" enum="TransferMode">
+ Packets are sent via ordered UDP packets.
</constant>
<constant name="TRANSFER_MODE_RELIABLE" value="2" enum="TransferMode">
+ Packets are sent via TCP packets.
</constant>
<constant name="CONNECTION_DISCONNECTED" value="0" enum="ConnectionStatus">
+ The ongoing connection disconnected.
</constant>
<constant name="CONNECTION_CONNECTING" value="1" enum="ConnectionStatus">
+ A connection attempt is ongoing.
</constant>
<constant name="CONNECTION_CONNECTED" value="2" enum="ConnectionStatus">
+ The connection attempt succeeded.
</constant>
<constant name="TARGET_PEER_BROADCAST" value="0">
+ Packets are sent to the server and then redistributed to other peers.
</constant>
<constant name="TARGET_PEER_SERVER" value="1">
+ Packets are sent to the server alone.
</constant>
</constants>
</class>
diff --git a/doc/classes/PackedScene.xml b/doc/classes/PackedScene.xml
index 3940995936..80ef3afdb1 100644
--- a/doc/classes/PackedScene.xml
+++ b/doc/classes/PackedScene.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="PackedScene" inherits="Resource" category="Core" version="3.0-beta">
<brief_description>
+ An abstraction of a serialized scene.
</brief_description>
<description>
+ A simplified interface to a scene file. Provides access to operations and checks that can be performed on the scene resource itself.
TODO: explain ownership, and that node does not need to own itself
</description>
<tutorials>
@@ -14,12 +16,14 @@
<return type="bool">
</return>
<description>
+ Returns [code]true[/code] if the scene file has nodes.
</description>
</method>
<method name="get_state">
<return type="SceneState">
</return>
<description>
+ Returns the [code]SceneState[/code] representing the scene file contents.
</description>
</method>
<method name="instance" qualifiers="const">
@@ -28,6 +32,7 @@
<argument index="0" name="edit_state" type="int" enum="PackedScene.GenEditState" default="0">
</argument>
<description>
+ Instantiates the scene's node hierarchy. Triggers child scene instantiation(s). Triggers the [enum Object.NOTIFICATION_INSTANCED] notification on the root node.
</description>
</method>
<method name="pack">
@@ -42,14 +47,19 @@
</methods>
<members>
<member name="_bundled" type="Dictionary" setter="_set_bundled_scene" getter="_get_bundled_scene">
+ A dictionary representation of the scene contents.
+ Available keys include "rnames" and "variants" for resources, "node_count", "nodes", "node_paths" for nodes, "editable_instances" for base scene children overrides, "conn_count" and "conns" for signal connections, and "version" for the format style of the PackedScene.
</member>
</members>
<constants>
<constant name="GEN_EDIT_STATE_DISABLED" value="0" enum="GenEditState">
+ If passed to [method instance], blocks edits to the scene state.
</constant>
<constant name="GEN_EDIT_STATE_INSTANCE" value="1" enum="GenEditState">
+ If passed to [method instance], provides local scene resources to the local scene. Requires tools compiled.
</constant>
<constant name="GEN_EDIT_STATE_MAIN" value="2" enum="GenEditState">
+ If passed to [method instance], provides local scene resources to the local scene. Only the main scene should receive the main edit state. Requires tools compiled.
</constant>
</constants>
</class>
diff --git a/doc/classes/SceneState.xml b/doc/classes/SceneState.xml
index 20ca43b71a..4fcaaa23dc 100644
--- a/doc/classes/SceneState.xml
+++ b/doc/classes/SceneState.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="SceneState" inherits="Reference" category="Core" version="3.0-beta">
<brief_description>
+ A script interface to a scene file's data.
</brief_description>
<description>
+ Maintains a list of resources, nodes, exported and overridden properties, and built-in scripts associated with a scene.
</description>
<tutorials>
</tutorials>
@@ -15,12 +17,14 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the list of bound parameters for the signal at [code]idx[/code].
</description>
</method>
<method name="get_connection_count" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the number of signal connections in the scene.
</description>
</method>
<method name="get_connection_flags" qualifiers="const">
@@ -29,6 +33,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the flags for the signal at [code]idx[/code]. See [Object]'s [code]CONNECT_*[/code] flags.
</description>
</method>
<method name="get_connection_method" qualifiers="const">
@@ -37,6 +42,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the method connected to the signal at [code]idx[/code].
</description>
</method>
<method name="get_connection_signal" qualifiers="const">
@@ -45,6 +51,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the name of the signal at [code]idx[/code].
</description>
</method>
<method name="get_connection_source" qualifiers="const">
@@ -53,6 +60,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the path to the node that owns the signal at [code]idx[/code], relative to the root node.
</description>
</method>
<method name="get_connection_target" qualifiers="const">
@@ -61,12 +69,14 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the path to the node that owns the method connected to the signal at [code]idx[/code], relative to the root node.
</description>
</method>
<method name="get_node_count" qualifiers="const">
<return type="int">
</return>
<description>
+ Returns the number of nodes in the scene.
</description>
</method>
<method name="get_node_groups" qualifiers="const">
@@ -75,6 +85,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the list of group names associated with the node at [code]idx[/code].
</description>
</method>
<method name="get_node_instance" qualifiers="const">
@@ -83,6 +94,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the scene for the node at [code]idx[/code] or [code]null[/code] if the node is not an instance.
</description>
</method>
<method name="get_node_instance_placeholder" qualifiers="const">
@@ -91,6 +103,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the path to the represented scene file if the node at [code]idx[/code] is an [InstancePlaceholder].
</description>
</method>
<method name="get_node_name" qualifiers="const">
@@ -99,6 +112,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the name of the node at [code]idx[/code].
</description>
</method>
<method name="get_node_owner_path" qualifiers="const">
@@ -107,6 +121,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the path to the owner of the node at [code]idx[/code], relative to the root node.
</description>
</method>
<method name="get_node_path" qualifiers="const">
@@ -117,6 +132,7 @@
<argument index="1" name="for_parent" type="bool" default="false">
</argument>
<description>
+ Returns the path to the node at [code]idx[/code].
</description>
</method>
<method name="get_node_property_count" qualifiers="const">
@@ -125,6 +141,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the number of exported or overridden properties for the node at [code]idx[/code].
</description>
</method>
<method name="get_node_property_name" qualifiers="const">
@@ -135,6 +152,7 @@
<argument index="1" name="prop_idx" type="int">
</argument>
<description>
+ Returns the name of the property at [code]prop_idx[/code] for the node at [code]idx[/code].
</description>
</method>
<method name="get_node_property_value" qualifiers="const">
@@ -145,6 +163,7 @@
<argument index="1" name="prop_idx" type="int">
</argument>
<description>
+ Returns the value of the property at [code]prop_idx[/code] for the node at [code]idx[/code].
</description>
</method>
<method name="get_node_type" qualifiers="const">
@@ -153,6 +172,7 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns the type of the node at [code]idx[/code].
</description>
</method>
<method name="is_node_instance_placeholder" qualifiers="const">
@@ -161,15 +181,19 @@
<argument index="0" name="idx" type="int">
</argument>
<description>
+ Returns [code]true[/code] if the node at [code]idx[/code] is an [InstancePlaceholder].
</description>
</method>
</methods>
<constants>
<constant name="GEN_EDIT_STATE_DISABLED" value="0" enum="GenEditState">
+ If passed to [method PackedScene.instance], blocks edits to the scene state.
</constant>
<constant name="GEN_EDIT_STATE_INSTANCE" value="1" enum="GenEditState">
+ If passed to [method PackedScene.instance], provides inherited scene resources to the local scene. Requires tools compiled.
</constant>
<constant name="GEN_EDIT_STATE_MAIN" value="2" enum="GenEditState">
+ If passed to [method PackedScene.instance], provides local scene resources to the local scene. Only the main scene should receive the main edit state. Requires tools compiled.
</constant>
</constants>
</class>
diff --git a/doc/classes/WindowDialog.xml b/doc/classes/WindowDialog.xml
index 41aa71b782..5bdcfe238d 100644
--- a/doc/classes/WindowDialog.xml
+++ b/doc/classes/WindowDialog.xml
@@ -21,8 +21,10 @@
</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].
</member>
<member name="window_title" type="String" setter="set_title" getter="get_title">
+ The text displayed in the window's title bar. Default value: "Save a File".
</member>
</members>
<constants>
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 5b3e43fc43..0839f930c9 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -208,6 +208,8 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
+ texture = texture->get_ptr();
+
if (texture->render_target)
texture->render_target->used_in_frame = true;
@@ -243,6 +245,7 @@ RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(con
} else {
+ normal_map = normal_map->get_ptr();
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
state.current_normal = p_normal_map;
@@ -1115,6 +1118,8 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
continue;
}
+ t = t->get_ptr();
+
if (storage->config.srgb_decode_supported && t->using_srgb) {
//no srgb in 2D
glTexParameteri(t->target, _TEXTURE_SRGB_DECODE_EXT, _SKIP_DECODE_EXT);
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index 02df170da1..3031b70f70 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -1235,6 +1235,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
} else {
+ t = t->get_ptr(); //resolve for proxies
#ifdef TOOLS_ENABLED
if (t->detect_3d) {
t->detect_3d(t->detect_3d_ud);
@@ -2164,7 +2165,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::USE_OPAQUE_PREPASS, false);
}
-void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass) {
+void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass, bool p_shadow_pass) {
RasterizerStorageGLES3::Material *m = NULL;
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
@@ -2196,17 +2197,17 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
ERR_FAIL_COND(!m);
- _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass, p_shadow_pass);
while (m->next_pass.is_valid()) {
m = storage->material_owner.getornull(m->next_pass);
if (!m || !m->shader || !m->shader->valid)
break;
- _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass);
+ _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_depth_pass, p_shadow_pass);
}
}
-void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass) {
+void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_shadow_pass) {
bool has_base_alpha = (p_material->shader->spatial.uses_alpha && !p_material->shader->spatial.uses_alpha_scissor) || p_material->shader->spatial.uses_screen_texture;
bool has_blend_alpha = p_material->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX;
@@ -2238,11 +2239,11 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
if (!p_material->shader->spatial.uses_alpha_scissor && !p_material->shader->spatial.writes_modelview_or_projection && !p_material->shader->spatial.uses_vertex && !p_material->shader->spatial.uses_discard && p_material->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS) {
//shader does not use discard and does not write a vertex position, use generic material
if (p_instance->cast_shadows == VS::SHADOW_CASTING_SETTING_DOUBLE_SIDED) {
- p_material = storage->material_owner.getptr(default_material_twosided);
+ p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material_twosided : default_material_twosided);
no_cull = true;
mirror = false;
} else {
- p_material = storage->material_owner.getptr(default_material);
+ p_material = storage->material_owner.getptr(!p_shadow_pass && p_material->shader->spatial.uses_world_coordinates ? default_worldcoord_material : default_material);
}
}
@@ -2280,13 +2281,15 @@ void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::G
}
e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
- e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
if (e->instance->gi_probe_instances.size()) {
e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
}
e->sort_key |= uint64_t(p_material->render_priority + 128) << RenderList::SORT_KEY_PRIORITY_SHIFT;
+ } else {
+ e->sort_key |= uint64_t(e->instance->depth_layer) << RenderList::SORT_KEY_OPAQUE_DEPTH_LAYER_SHIFT;
+ e->sort_key |= uint64_t(e->material->index) << RenderList::SORT_KEY_MATERIAL_INDEX_SHIFT;
}
/*
@@ -3060,7 +3063,7 @@ void RasterizerSceneGLES3::_copy_texture_to_front_buffer(GLuint p_texture) {
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false);
}
-void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass) {
+void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass) {
current_geometry_index = 0;
current_material_index = 0;
@@ -3085,7 +3088,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
int mat_idx = inst->materials[i].is_valid() ? i : -1;
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
- _add_geometry(s, inst, NULL, mat_idx, p_depth_pass);
+ _add_geometry(s, inst, NULL, mat_idx, p_depth_pass, p_shadow_pass);
}
//mesh->last_pass=frame;
@@ -3108,7 +3111,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
for (int i = 0; i < ssize; i++) {
RasterizerStorageGLES3::Surface *s = mesh->surfaces[i];
- _add_geometry(s, inst, multi_mesh, -1, p_depth_pass);
+ _add_geometry(s, inst, multi_mesh, -1, p_depth_pass, p_shadow_pass);
}
} break;
@@ -3117,7 +3120,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
RasterizerStorageGLES3::Immediate *immediate = storage->immediate_owner.getptr(inst->base);
ERR_CONTINUE(!immediate);
- _add_geometry(immediate, inst, NULL, -1, p_depth_pass);
+ _add_geometry(immediate, inst, NULL, -1, p_depth_pass, p_shadow_pass);
} break;
case VS::INSTANCE_PARTICLES: {
@@ -3139,7 +3142,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
for (int j = 0; j < ssize; j++) {
RasterizerStorageGLES3::Surface *s = mesh->surfaces[j];
- _add_geometry(s, inst, particles, -1, p_depth_pass);
+ _add_geometry(s, inst, particles, -1, p_depth_pass, p_shadow_pass);
}
}
@@ -4055,8 +4058,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
render_list.clear();
- _fill_render_list(p_cull_result, p_cull_count, true);
- render_list.sort_by_depth(false);
+ _fill_render_list(p_cull_result, p_cull_count, true, false);
+ render_list.sort_by_key(false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, true);
_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, 0, false, false, true, false, false);
state.scene_shader.set_conditional(SceneShaderGLES3::RENDER_DEPTH, false);
@@ -4086,11 +4089,10 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_setup_lights(p_light_cull_result, p_light_cull_count, p_cam_transform.affine_inverse(), p_cam_projection, p_shadow_atlas);
_setup_reflections(p_reflection_probe_cull_result, p_reflection_probe_cull_count, p_cam_transform.affine_inverse(), p_cam_projection, p_reflection_atlas, env);
- render_list.clear();
-
bool use_mrt = false;
- _fill_render_list(p_cull_result, p_cull_count, false);
+ render_list.clear();
+ _fill_render_list(p_cull_result, p_cull_count, false, false);
//
glEnable(GL_BLEND);
@@ -4593,10 +4595,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
}
- //todo hacer que se redibuje cuando corresponde
-
render_list.clear();
- _fill_render_list(p_cull_result, p_cull_count, true);
+ _fill_render_list(p_cull_result, p_cull_count, true, true);
render_list.sort_by_depth(false); //shadow is front to back for performance
@@ -4760,6 +4760,18 @@ void RasterizerSceneGLES3::initialize() {
default_material_twosided = storage->material_create();
storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
storage->material_set_shader(default_material_twosided, default_shader_twosided);
+
+ //default for shaders using world coordinates (typical for triplanar)
+
+ default_worldcoord_shader = storage->shader_create();
+ storage->shader_set_code(default_worldcoord_shader, "shader_type spatial; render_mode world_vertex_coords;\n");
+ default_worldcoord_material = storage->material_create();
+ storage->material_set_shader(default_worldcoord_material, default_worldcoord_shader);
+
+ default_worldcoord_shader_twosided = storage->shader_create();
+ default_worldcoord_material_twosided = storage->material_create();
+ storage->shader_set_code(default_worldcoord_shader_twosided, "shader_type spatial; render_mode cull_disabled,world_vertex_coords;\n");
+ storage->material_set_shader(default_worldcoord_material_twosided, default_worldcoord_shader_twosided);
}
{
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 69b43c7813..99c8044e2f 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -78,6 +78,11 @@ public:
RID default_shader;
RID default_shader_twosided;
+ RID default_worldcoord_material;
+ RID default_worldcoord_material_twosided;
+ RID default_worldcoord_shader;
+ RID default_worldcoord_shader_twosided;
+
RID default_overdraw_material;
RID default_overdraw_shader;
@@ -812,9 +817,9 @@ public:
void _render_list(RenderList::Element **p_elements, int p_element_count, const Transform &p_view_transform, const CameraMatrix &p_projection, GLuint p_base_env, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
- _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass);
+ _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_depth_pass,bool p_shadow_pass);
- _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass);
+ _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
@@ -827,7 +832,7 @@ public:
void _copy_to_front_buffer(Environment *env);
void _copy_texture_to_front_buffer(GLuint p_texture); //used for debug
- void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass);
+ void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
void _blur_effect_buffer();
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index fc9150ecdc..cba9f08537 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -1232,6 +1232,25 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
return texture_owner.make_rid(ctex);
}
+void RasterizerStorageGLES3::texture_set_proxy(RID p_texture, RID p_proxy) {
+
+ Texture *texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ if (texture->proxy) {
+ texture->proxy->proxy_owners.erase(texture);
+ texture->proxy = NULL;
+ }
+
+ if (p_proxy.is_valid()) {
+ Texture *proxy = texture_owner.get(p_proxy);
+ ERR_FAIL_COND(!proxy);
+ ERR_FAIL_COND(proxy == texture);
+ proxy->proxy_owners.insert(texture);
+ texture->proxy = proxy;
+ }
+}
+
RID RasterizerStorageGLES3::sky_create() {
Sky *sky = memnew(Sky);
@@ -1601,6 +1620,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.writes_modelview_or_projection = false;
+ p_shader->spatial.uses_world_coordinates = false;
shaders.actions_scene.render_mode_values["blend_add"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_ADD);
shaders.actions_scene.render_mode_values["blend_mix"] = Pair<int *, int>(&p_shader->spatial.blend_mode, Shader::Spatial::BLEND_MODE_MIX);
@@ -1621,9 +1641,10 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.render_mode_flags["vertex_lighting"] = &p_shader->spatial.uses_vertex_lighting;
+ shaders.actions_scene.render_mode_flags["world_vertex_coords"] = &p_shader->spatial.uses_world_coordinates;
+
shaders.actions_scene.usage_flag_pointers["ALPHA"] = &p_shader->spatial.uses_alpha;
shaders.actions_scene.usage_flag_pointers["ALPHA_SCISSOR"] = &p_shader->spatial.uses_alpha_scissor;
- shaders.actions_scene.usage_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
@@ -1632,6 +1653,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
+ shaders.actions_scene.write_flag_pointers["VERTEX"] = &p_shader->spatial.uses_vertex;
actions = &shaders.actions_scene;
actions->uniforms = &p_shader->uniforms;
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index 0ec110ab87..d5efd5307c 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -242,6 +242,9 @@ public:
struct Texture : public RID_Data {
+ Texture *proxy;
+ Set<Texture *> proxy_owners;
+
String path;
uint32_t flags;
int width, height;
@@ -301,6 +304,15 @@ public:
detect_srgb_ud = NULL;
detect_normal = NULL;
detect_normal_ud = NULL;
+ proxy = NULL;
+ }
+
+ _ALWAYS_INLINE_ Texture *get_ptr() {
+ if (proxy) {
+ return proxy; //->get_ptr(); only one level of indirection, else not inlining possible.
+ } else {
+ return this;
+ }
}
~Texture() {
@@ -309,6 +321,14 @@ public:
glDeleteTextures(1, &tex_id);
}
+
+ for (Set<Texture *>::Element *E = proxy_owners.front(); E; E = E->next()) {
+ E->get()->proxy = NULL;
+ }
+
+ if (proxy) {
+ proxy->proxy_owners.erase(this);
+ }
}
};
@@ -343,6 +363,8 @@ public:
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
+ virtual void texture_set_proxy(RID p_texture, RID p_proxy);
+
/* SKY API */
struct Sky : public RID_Data {
@@ -453,6 +475,7 @@ public:
bool uses_time;
bool writes_modelview_or_projection;
bool uses_vertex_lighting;
+ bool uses_world_coordinates;
} spatial;
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index d4ef256a33..9e234f5005 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -343,7 +343,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
glDeleteProgram(v.id);
v.id = 0;
- ERR_PRINT("NO LOG, WTF");
+ ERR_PRINT("Vertex shader compilation failed with empty log");
} else {
if (iloglen == 0) {
@@ -451,7 +451,7 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
glDeleteShader(v.vert_id);
glDeleteProgram(v.id);
v.id = 0;
- ERR_PRINT("NO LOG, WTF");
+ ERR_PRINT("Fragment shader compilation failed with empty log");
} else {
if (iloglen == 0) {
@@ -624,7 +624,7 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
feedbacks = p_feedback;
feedback_count = p_feedback_count;
- //split vertex and shader code (thank you, retarded shader compiler programmers from you know what company).
+ //split vertex and shader code (thank you, shader compiler programmers from you know what company).
{
String globals_tag = "\nVERTEX_SHADER_GLOBALS";
String material_tag = "\nMATERIAL_UNIFORMS";
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index b2b10fdb11..676541649c 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -263,6 +263,10 @@ uniform highp sampler2D skeleton_texture; //texunit:-1
out highp vec4 position_interp;
+// FIXME: This triggers a Mesa bug that breaks rendering, so disabled for now.
+// See GH-13450 and https://bugs.freedesktop.org/show_bug.cgi?id=100316
+//invariant gl_Position;
+
void main() {
highp vec4 vertex = vertex_attrib; // vec4(vertex_attrib.xyz * data_attrib.x,1.0);
@@ -1026,7 +1030,7 @@ LIGHT_SHADER_CODE
#if defined(LIGHT_USE_RIM)
- float rim_light = pow(1.0-cNdotV, (1.0-roughness)*16.0);
+ float rim_light = pow(max(0.0,1.0-cNdotV), max(0.0,(1.0-roughness)*16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
}
diff --git a/drivers/unix/rw_lock_posix.cpp b/drivers/unix/rw_lock_posix.cpp
index ab2d6495bd..00125809c0 100644
--- a/drivers/unix/rw_lock_posix.cpp
+++ b/drivers/unix/rw_lock_posix.cpp
@@ -39,7 +39,7 @@ void RWLockPosix::read_lock() {
int err = pthread_rwlock_rdlock(&rwlock);
if (err != 0) {
- perror("wtf: ");
+ perror("Acquiring lock failed");
}
ERR_FAIL_COND(err != 0);
}
diff --git a/drivers/unix/stream_peer_tcp_posix.cpp b/drivers/unix/stream_peer_tcp_posix.cpp
index 3bc2397e6f..e88a7d7de1 100644
--- a/drivers/unix/stream_peer_tcp_posix.cpp
+++ b/drivers/unix/stream_peer_tcp_posix.cpp
@@ -213,7 +213,7 @@ Error StreamPeerTCPPosix::write(const uint8_t *p_data, int p_bytes, int &r_sent,
if (errno != EAGAIN) {
- perror("shit?");
+ perror("Nothing sent");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
@@ -270,7 +270,7 @@ Error StreamPeerTCPPosix::read(uint8_t *p_buffer, int p_bytes, int &r_received,
if (errno != EAGAIN) {
- perror("shit?");
+ perror("Nothing read");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
diff --git a/drivers/wasapi/audio_driver_wasapi.cpp b/drivers/wasapi/audio_driver_wasapi.cpp
index 2c87fb58db..10b6a61b2d 100644
--- a/drivers/wasapi/audio_driver_wasapi.cpp
+++ b/drivers/wasapi/audio_driver_wasapi.cpp
@@ -74,21 +74,22 @@ Error AudioDriverWASAPI::init_device(bool reinit) {
ERR_FAIL_COND_V(hr != S_OK, ERR_CANT_OPEN);
// Since we're using WASAPI Shared Mode we can't control any of these, we just tag along
- channels = pwfex->nChannels;
+ wasapi_channels = pwfex->nChannels;
mix_rate = pwfex->nSamplesPerSec;
format_tag = pwfex->wFormatTag;
bits_per_sample = pwfex->wBitsPerSample;
- switch (channels) {
+ switch (wasapi_channels) {
case 2: // Stereo
case 4: // Surround 3.1
case 6: // Surround 5.1
case 8: // Surround 7.1
+ channels = wasapi_channels;
break;
default:
- ERR_PRINTS("WASAPI: Unsupported number of channels: " + itos(channels));
- ERR_FAIL_V(ERR_CANT_OPEN);
+ WARN_PRINTS("WASAPI: Unsupported number of channels: " + itos(wasapi_channels));
+ channels = 2;
break;
}
@@ -206,6 +207,35 @@ AudioDriver::SpeakerMode AudioDriverWASAPI::get_speaker_mode() const {
return get_speaker_mode_by_total_channels(channels);
}
+void AudioDriverWASAPI::write_sample(AudioDriverWASAPI *ad, BYTE *buffer, int i, int32_t sample) {
+ if (ad->format_tag == WAVE_FORMAT_PCM) {
+ switch (ad->bits_per_sample) {
+ case 8:
+ ((int8_t *)buffer)[i] = sample >> 24;
+ break;
+
+ case 16:
+ ((int16_t *)buffer)[i] = sample >> 16;
+ break;
+
+ case 24:
+ ((int8_t *)buffer)[i * 3 + 2] = sample >> 24;
+ ((int8_t *)buffer)[i * 3 + 1] = sample >> 16;
+ ((int8_t *)buffer)[i * 3 + 0] = sample >> 8;
+ break;
+
+ case 32:
+ ((int32_t *)buffer)[i] = sample;
+ break;
+ }
+ } else if (ad->format_tag == WAVE_FORMAT_IEEE_FLOAT) {
+ ((float *)buffer)[i] = (sample >> 16) / 32768.f;
+ } else {
+ ERR_PRINT("WASAPI: Unknown format tag");
+ ad->exit_thread = true;
+ }
+}
+
void AudioDriverWASAPI::thread_func(void *p_udata) {
AudioDriverWASAPI *ad = (AudioDriverWASAPI *)p_udata;
@@ -240,42 +270,21 @@ void AudioDriverWASAPI::thread_func(void *p_udata) {
if (hr == S_OK) {
// We're using WASAPI Shared Mode so we must convert the buffer
- if (ad->format_tag == WAVE_FORMAT_PCM) {
- switch (ad->bits_per_sample) {
- case 8:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int8_t *)buffer)[i] = ad->samples_in[buffer_idx++] >> 24;
- }
- break;
-
- case 16:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int16_t *)buffer)[i] = ad->samples_in[buffer_idx++] >> 16;
- }
- break;
-
- case 24:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- int32_t sample = ad->samples_in[buffer_idx++];
- ((int8_t *)buffer)[i * 3 + 2] = sample >> 24;
- ((int8_t *)buffer)[i * 3 + 1] = sample >> 16;
- ((int8_t *)buffer)[i * 3 + 0] = sample >> 8;
- }
- break;
-
- case 32:
- for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((int32_t *)buffer)[i] = ad->samples_in[buffer_idx++];
- }
- break;
- }
- } else if (ad->format_tag == WAVE_FORMAT_IEEE_FLOAT) {
+ if (ad->channels == ad->wasapi_channels) {
for (unsigned int i = 0; i < write_frames * ad->channels; i++) {
- ((float *)buffer)[i] = (ad->samples_in[buffer_idx++] >> 16) / 32768.f;
+ ad->write_sample(ad, buffer, i, ad->samples_in[buffer_idx++]);
}
} else {
- ERR_PRINT("WASAPI: Unknown format tag");
- ad->exit_thread = true;
+ for (unsigned int i = 0; i < write_frames; i++) {
+ for (unsigned int j = 0; j < MIN(ad->channels, ad->wasapi_channels); j++) {
+ ad->write_sample(ad, buffer, i * ad->wasapi_channels + j, ad->samples_in[buffer_idx++]);
+ }
+ if (ad->wasapi_channels > ad->channels) {
+ for (unsigned int j = ad->channels; j < ad->wasapi_channels; j++) {
+ ad->write_sample(ad, buffer, i * ad->wasapi_channels + j, 0);
+ }
+ }
+ }
}
hr = ad->render_client->ReleaseBuffer(write_frames, 0);
@@ -380,6 +389,7 @@ AudioDriverWASAPI::AudioDriverWASAPI() {
buffer_size = 0;
channels = 0;
+ wasapi_channels = 0;
mix_rate = 0;
buffer_frames = 0;
diff --git a/drivers/wasapi/audio_driver_wasapi.h b/drivers/wasapi/audio_driver_wasapi.h
index 87a2db724c..5921645f6e 100644
--- a/drivers/wasapi/audio_driver_wasapi.h
+++ b/drivers/wasapi/audio_driver_wasapi.h
@@ -55,6 +55,7 @@ class AudioDriverWASAPI : public AudioDriver {
unsigned int buffer_size;
unsigned int channels;
+ unsigned int wasapi_channels;
int mix_rate;
int buffer_frames;
@@ -62,6 +63,7 @@ class AudioDriverWASAPI : public AudioDriver {
mutable bool exit_thread;
bool active;
+ _FORCE_INLINE_ void write_sample(AudioDriverWASAPI *ad, BYTE *buffer, int i, int32_t sample);
static void thread_func(void *p_udata);
Error init_device(bool reinit = false);
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index 3a72f8e569..0bb059f425 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -235,7 +235,7 @@ void DocData::generate(bool p_basic_types) {
ClassDB::get_property_list(name, &properties, true);
for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY)
+ if (E->get().usage & PROPERTY_USAGE_GROUP || E->get().usage & PROPERTY_USAGE_CATEGORY || E->get().usage & PROPERTY_USAGE_INTERNAL)
continue;
PropertyDoc prop;
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index da41ea87ce..5f026abb6d 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -44,8 +44,8 @@ void EditorAbout::_notification(int p_what) {
case NOTIFICATION_THEME_CHANGED: {
Ref<Font> font = EditorNode::get_singleton()->get_gui_base()->get_font("source", "EditorFonts");
- _tpl_text->add_font_override("font", font);
- _license_text->add_font_override("font", font);
+ _tpl_text->add_font_override("normal_font", font);
+ _license_text->add_font_override("normal_font", font);
} break;
}
}
@@ -53,7 +53,6 @@ void EditorAbout::_notification(int p_what) {
void EditorAbout::_license_tree_selected() {
TreeItem *selected = _tpl_tree->get_selected();
- _tpl_text->select(0, 0, 0, 0);
_tpl_text->set_text(selected->get_metadata(0));
}
@@ -165,12 +164,10 @@ EditorAbout::EditorAbout() {
// License
- _license_text = memnew(TextEdit);
+ _license_text = memnew(RichTextLabel);
_license_text->set_name(TTR("License"));
_license_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
_license_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- _license_text->set_wrap(true);
- _license_text->set_readonly(true);
_license_text->set_text(String::utf8(about_license));
tc->add_child(_license_text);
@@ -239,11 +236,9 @@ EditorAbout::EditorAbout() {
tpl_ti_all->set_metadata(0, long_text);
tpl_hbc->add_child(_tpl_tree);
- _tpl_text = memnew(TextEdit);
+ _tpl_text = memnew(RichTextLabel);
_tpl_text->set_h_size_flags(Control::SIZE_EXPAND_FILL);
_tpl_text->set_v_size_flags(Control::SIZE_EXPAND_FILL);
- _tpl_text->set_wrap(true);
- _tpl_text->set_readonly(true);
tpl_hbc->add_child(_tpl_text);
_tpl_tree->connect("item_selected", this, "_license_tree_selected");
diff --git a/editor/editor_about.h b/editor/editor_about.h
index ce29027f05..fe40ce5f14 100644
--- a/editor/editor_about.h
+++ b/editor/editor_about.h
@@ -33,11 +33,11 @@
#include "scene/gui/control.h"
#include "scene/gui/dialogs.h"
#include "scene/gui/item_list.h"
+#include "scene/gui/rich_text_label.h"
#include "scene/gui/scroll_container.h"
#include "scene/gui/separator.h"
#include "scene/gui/split_container.h"
#include "scene/gui/tab_container.h"
-#include "scene/gui/text_edit.h"
#include "scene/gui/texture_rect.h"
#include "scene/gui/tree.h"
@@ -55,8 +55,8 @@ private:
ScrollContainer *_populate_list(const String &p_name, const List<String> &p_sections, const char **p_src[], const int p_flag_single_column = 0);
Tree *_tpl_tree;
- TextEdit *_license_text;
- TextEdit *_tpl_text;
+ RichTextLabel *_license_text;
+ RichTextLabel *_tpl_text;
TextureRect *_logo;
protected:
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index de64c11308..6e507fac9b 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -251,7 +251,7 @@ void EditorAudioBus::_volume_db_changed(float p_db) {
updating_bus = true;
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action("Change Audio Bus Volume", UndoRedo::MERGE_ENDS);
+ ur->create_action(TTR("Change Audio Bus Volume"), UndoRedo::MERGE_ENDS);
ur->add_do_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), p_db);
ur->add_undo_method(AudioServer::get_singleton(), "set_bus_volume_db", get_index(), AudioServer::get_singleton()->get_bus_volume_db(get_index()));
ur->add_do_method(buses, "_update_bus", get_index());
@@ -812,7 +812,7 @@ void EditorAudioBuses::_update_buses() {
EditorAudioBuses *EditorAudioBuses::register_editor() {
EditorAudioBuses *audio_buses = memnew(EditorAudioBuses);
- EditorNode::get_singleton()->add_bottom_panel_item("Audio", audio_buses);
+ EditorNode::get_singleton()->add_bottom_panel_item(TTR("Audio"), audio_buses);
return audio_buses;
}
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 443004f820..49d55e6305 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -690,9 +690,9 @@ Ref<Script> EditorData::get_scene_root_script(int p_idx) const {
String EditorData::get_scene_title(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, edited_scene.size(), String());
if (!edited_scene[p_idx].root)
- return "[empty]";
+ return TTR("[empty]");
if (edited_scene[p_idx].root->get_filename() == "")
- return "[unsaved]";
+ return TTR("[unsaved]");
bool show_ext = EDITOR_DEF("interface/scene_tabs/show_extension", false);
String name = edited_scene[p_idx].root->get_filename().get_file();
if (!show_ext) {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 8c8d9c4c79..fc73964764 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -743,6 +743,18 @@ Error EditorExportPlatform::export_project_files(const Ref<EditorExportPreset> &
custom_map["path_remap/remapped_paths"] = path_remaps;
}
+ // Store icon and splash images directly, they need to bypass the import system and be loaded as images
+ String icon = ProjectSettings::get_singleton()->get("application/config/icon");
+ String splash = ProjectSettings::get_singleton()->get("application/boot_splash/image");
+ if (icon != String() && FileAccess::exists(icon)) {
+ Vector<uint8_t> array = FileAccess::get_file_as_array(icon);
+ p_func(p_udata, icon, array, idx, total);
+ }
+ if (splash != String() && FileAccess::exists(splash)) {
+ Vector<uint8_t> array = FileAccess::get_file_as_array(splash);
+ p_func(p_udata, splash, array, idx, total);
+ }
+
String config_file = "project.binary";
String engine_cfb = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp" + config_file);
ProjectSettings::get_singleton()->save_custom(engine_cfb, custom_map, custom_list);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index eb5af2eaeb..6a5cbb88df 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -1232,6 +1232,15 @@ void EditorFileDialog::_bind_methods() {
ADD_SIGNAL(MethodInfo("files_selected", PropertyInfo(Variant::POOL_STRING_ARRAY, "paths")));
ADD_SIGNAL(MethodInfo("dir_selected", PropertyInfo(Variant::STRING, "dir")));
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User data,File system"), "set_access", "get_access");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "display_mode", PROPERTY_HINT_ENUM, "Thumbnails,List"), "set_display_mode", "get_display_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Open one,Open many,Open folder,Open any,Save"), "set_mode", "get_mode");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR), "set_current_dir", "get_current_dir");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_file", PROPERTY_HINT_FILE, "*"), "set_current_file", "get_current_file");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_path"), "set_current_path", "get_current_path");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_hidden_files"), "set_show_hidden_files", "is_showing_hidden_files");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_overwrite_warning"), "set_disable_overwrite_warning", "is_overwrite_warning_disabled");
+
BIND_ENUM_CONSTANT(MODE_OPEN_FILE);
BIND_ENUM_CONSTANT(MODE_OPEN_FILES);
BIND_ENUM_CONSTANT(MODE_OPEN_DIR);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index fbf6c86c35..31ed86d05a 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -1394,11 +1394,13 @@ void EditorNode::_property_editor_back() {
}
void EditorNode::_menu_collapseall() {
- property_editor->collapse_all_parent_nodes();
+
+ property_editor->collapse_all_folding();
}
void EditorNode::_menu_expandall() {
- property_editor->expand_all_parent_nodes();
+
+ property_editor->expand_all_folding();
}
void EditorNode::_save_default_environment() {
@@ -1495,7 +1497,7 @@ void EditorNode::_edit_current() {
if (FileAccess::exists(base_path + ".import")) {
editable_warning = TTR("This resource belongs to a scene that was imported, so it's not editable.\nPlease read the documentation relevant to importing scenes to better understand this workflow.");
} else {
- if (!get_edited_scene() || get_edited_scene()->get_filename() != base_path) {
+ if ((!get_edited_scene() || get_edited_scene()->get_filename() != base_path) && ResourceLoader::get_resource_type(base_path) == "PackedScene") {
editable_warning = TTR("This resource belongs to a scene that was instanced or inherited.\nChanges to it will not be kept when saving the current scene.");
}
}
@@ -1674,7 +1676,6 @@ void EditorNode::_resource_selected(const RES &p_res, const String &p_property)
void EditorNode::_run(bool p_current, const String &p_custom) {
if (editor_run.get_status() == EditorRun::STATUS_PLAY) {
-
play_button->set_pressed(!_playing_edited);
play_scene_button->set_pressed(_playing_edited);
return;
@@ -1806,6 +1807,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
play_button->set_pressed(true);
play_button->set_icon(gui_base->get_icon("Reload", "EditorIcons"));
}
+ stop_button->set_disabled(false);
_playing_edited = p_current;
}
@@ -2277,6 +2279,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
play_scene_button->set_icon(gui_base->get_icon("PlayScene", "EditorIcons"));
play_custom_scene_button->set_pressed(false);
play_custom_scene_button->set_icon(gui_base->get_icon("PlayCustom", "EditorIcons"));
+ stop_button->set_disabled(true);
+
if (bool(EDITOR_DEF("run/output/always_close_output_on_stop", true))) {
for (int i = 0; i < bottom_panel_items.size(); i++) {
if (bottom_panel_items[i].control == log) {
@@ -5264,6 +5268,7 @@ EditorNode::EditorNode() {
stop_button->set_icon(gui_base->get_icon("Stop", "EditorIcons"));
stop_button->connect("pressed", this, "_menu_option", make_binds(RUN_STOP));
stop_button->set_tooltip(TTR("Stop the scene."));
+ stop_button->set_disabled(true);
stop_button->set_shortcut(ED_SHORTCUT("editor/stop", TTR("Stop"), KEY_F8));
run_native = memnew(EditorRunNative);
@@ -5441,7 +5446,7 @@ EditorNode::EditorNode() {
property_editor->set_use_doc_hints(true);
property_editor->set_hide_script(false);
property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/editor/capitalize_properties", true)));
- property_editor->set_use_folding(bool(EDITOR_DEF("interface/editor/expand_all_properties", false)) == false);
+ property_editor->set_use_folding(!bool(EDITOR_DEF("interface/editor/disable_inspector_folding", false)));
property_editor->hide_top_label();
property_editor->register_text_enter(search_box);
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index 5d81fc6ea4..71c26244ee 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -670,13 +670,13 @@ EditorProfiler::EditorProfiler() {
variables->set_hide_root(true);
variables->set_columns(3);
variables->set_column_titles_visible(true);
- variables->set_column_title(0, "Name");
+ variables->set_column_title(0, TTR("Name"));
variables->set_column_expand(0, true);
variables->set_column_min_width(0, 60);
- variables->set_column_title(1, "Time");
+ variables->set_column_title(1, TTR("Time"));
variables->set_column_expand(1, false);
variables->set_column_min_width(1, 60 * EDSCALE);
- variables->set_column_title(2, "Calls");
+ variables->set_column_title(2, TTR("Calls"));
variables->set_column_expand(2, false);
variables->set_column_min_width(2, 60 * EDSCALE);
variables->connect("item_edited", this, "_item_edited");
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 638b23382d..2f73e459ed 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -416,6 +416,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["editors/3d/freelook/freelook_modifier_speed_factor"] = PropertyInfo(Variant::REAL, "editors/3d/freelook/freelook_modifier_speed_factor", PROPERTY_HINT_RANGE, "0.0, 10.0, 0.1");
_initial_set("editors/3d/freelook/freelook_speed_zoom_link", false);
+ _initial_set("editors/2d/guides_color", Color(0.6, 0.0, 0.8));
_initial_set("editors/2d/bone_width", 5);
_initial_set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9));
_initial_set("editors/2d/bone_color2", Color(0.75, 0.75, 0.75, 0.9));
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index d18e97fe83..ddcdb5a321 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2294,7 +2294,7 @@ void CanvasItemEditor::_draw_focus() {
void CanvasItemEditor::_draw_guides() {
- Color guide_color = Color(0.6, 0.0, 0.8);
+ Color guide_color = EditorSettings::get_singleton()->get("editors/2d/guides_color");
Transform2D xform = viewport_scrollable->get_transform() * transform;
// Guides already there
@@ -4314,7 +4314,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
show_grid = false;
show_helpers = false;
- show_rulers = false;
+ show_rulers = true;
show_guides = true;
zoom = 1;
grid_offset = Point2();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 214f24b386..3a443e1bf7 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -1039,6 +1039,18 @@ void ScriptTextEditor::_edit_option(int p_op) {
if (scr.is_null())
return;
+ String delimiter = "#";
+ List<String> comment_delimiters;
+ scr->get_language()->get_comment_delimiters(&comment_delimiters);
+
+ for (List<String>::Element *E = comment_delimiters.front(); E; E = E->next()) {
+ String script_delimiter = E->get();
+ if (script_delimiter.find(" ") == -1) {
+ delimiter = script_delimiter;
+ break;
+ }
+ }
+
tx->begin_complex_operation();
if (tx->is_selection_active()) {
int begin = tx->get_selection_from_line();
@@ -1051,7 +1063,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
// Check if all lines in the selected block are commented
bool is_commented = true;
for (int i = begin; i <= end; i++) {
- if (!tx->get_line(i).begins_with("#")) {
+ if (!tx->get_line(i).begins_with(delimiter)) {
is_commented = false;
break;
}
@@ -1060,12 +1072,12 @@ void ScriptTextEditor::_edit_option(int p_op) {
String line_text = tx->get_line(i);
if (line_text.strip_edges().empty()) {
- line_text = "#";
+ line_text = delimiter;
} else {
if (is_commented) {
- line_text = line_text.substr(1, line_text.length());
+ line_text = line_text.substr(delimiter.length(), line_text.length());
} else {
- line_text = "#" + line_text;
+ line_text = delimiter + line_text;
}
}
tx->set_line(i, line_text);
@@ -1074,10 +1086,10 @@ void ScriptTextEditor::_edit_option(int p_op) {
int begin = tx->cursor_get_line();
String line_text = tx->get_line(begin);
- if (line_text.begins_with("#"))
- line_text = line_text.substr(1, line_text.length());
+ if (line_text.begins_with(delimiter))
+ line_text = line_text.substr(delimiter.length(), line_text.length());
else
- line_text = "#" + line_text;
+ line_text = delimiter + line_text;
tx->set_line(begin, line_text);
}
tx->end_complex_operation();
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index 9fd41c1064..b855d2d4c4 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -3389,6 +3389,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
preview_camera->set_toggle_mode(true);
preview_camera->set_anchor_and_margin(MARGIN_LEFT, ANCHOR_END, -90 * EDSCALE);
preview_camera->set_anchor_and_margin(MARGIN_TOP, ANCHOR_BEGIN, 10 * EDSCALE);
+ preview_camera->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, -10 * EDSCALE);
+ preview_camera->set_h_grow_direction(GROW_DIRECTION_BEGIN);
preview_camera->set_text(TTR("preview"));
surface->add_child(preview_camera);
preview_camera->hide();
@@ -4751,9 +4753,9 @@ VSplitContainer *SpatialEditor::get_shader_split() {
return shader_split;
}
-HBoxContainer *SpatialEditor::get_palette_split() {
+HSplitContainer *SpatialEditor::get_palette_split() {
- return palette_split_container;
+ return palette_split;
}
void SpatialEditor::_request_gizmo(Object *p_obj) {
@@ -5044,10 +5046,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
palette_split->set_v_size_flags(SIZE_EXPAND_FILL);
vbc->add_child(palette_split);
- palette_split_container = memnew(HBoxContainer);
- palette_split_container->set_v_size_flags(SIZE_EXPAND_FILL);
- palette_split->add_child(palette_split_container);
-
shader_split = memnew(VSplitContainer);
shader_split->set_h_size_flags(SIZE_EXPAND_FILL);
palette_split->add_child(shader_split);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index ab26a70f7f..0c2571017b 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -413,7 +413,6 @@ private:
SpatialEditorViewport *viewports[VIEWPORTS_COUNT];
VSplitContainer *shader_split;
HSplitContainer *palette_split;
- HBoxContainer *palette_split_container;
/////
@@ -608,7 +607,7 @@ public:
void add_control_to_menu_panel(Control *p_control);
VSplitContainer *get_shader_split();
- HBoxContainer *get_palette_split();
+ HSplitContainer *get_palette_split();
Spatial *get_selected() { return selected; }
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index e552e24c17..4d06342fe0 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -123,12 +123,14 @@ void TileMapEditor::_menu_option(int p_option) {
return;
undo_redo->create_action(TTR("Erase Selection"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
- _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true);
+ _set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false);
}
}
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
selection_active = false;
@@ -171,7 +173,7 @@ void TileMapEditor::set_selected_tile(int p_tile) {
}
}
-void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose, bool p_with_undo) {
+void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h, bool p_flip_v, bool p_transpose) {
ERR_FAIL_COND(!node);
@@ -184,17 +186,8 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, int p_value, bool p_flip_h,
if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose)
return; //check that it's actually different
- if (p_with_undo) {
-
- undo_redo->add_do_method(node, "set_cellv", Point2(p_pos), p_value, p_flip_h, p_flip_v, p_transpose);
- undo_redo->add_do_method(node, "make_bitmask_area_dirty", Point2(p_pos));
- undo_redo->add_undo_method(node, "set_cellv", Point2(p_pos), prev_val, prev_flip_h, prev_flip_v, prev_transpose);
- undo_redo->add_undo_method(node, "make_bitmask_area_dirty", Point2(p_pos));
- } else {
-
- node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
- node->update_bitmask_area(Point2(p_pos));
- }
+ node->set_cell(p_pos.x, p_pos.y, p_value, p_flip_h, p_flip_v, p_transpose);
+ node->update_bitmask_area(Point2(p_pos));
}
void TileMapEditor::_text_entered(const String &p_text) {
@@ -404,6 +397,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
}
PoolVector<Vector2> points;
+ Vector<Vector2> non_preview_cache;
int count = 0;
int limit = 0;
@@ -432,8 +426,10 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
bucket_cache_visited[loc] = true;
bucket_cache.push_back(n);
} else {
- node->set_cellv(n, id, flip_h, flip_v, transpose);
+ if (non_preview_cache.find(n) >= 0)
+ continue;
points.push_back(n);
+ non_preview_cache.push_back(n);
}
bucket_queue.push_back(Point2i(n.x, n.y + 1));
@@ -462,9 +458,10 @@ void TileMapEditor::_fill_points(const PoolVector<Vector2> p_points, const Dicti
bool tr = p_op["transpose"];
for (int i = 0; i < len; i++) {
-
_set_cell(pr[i], id, xf, yf, tr);
+ node->make_bitmask_area_dirty(pr[i]);
}
+ node->update_dirty_bitmask();
}
void TileMapEditor::_erase_points(const PoolVector<Vector2> p_points) {
@@ -565,20 +562,19 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h
}
} else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_CENTER) {
- rect.position += node->get_cell_size() / 2;
- Vector2 s = r.size;
+ Size2 cell_size = node->get_cell_size();
- Vector2 center = (s / 2) - tile_ofs;
+ rect.position += tile_ofs;
if (p_flip_h)
- rect.position.x -= s.x - center.x;
+ rect.position.x -= cell_size.x / 2;
else
- rect.position.x -= center.x;
+ rect.position.x += cell_size.x / 2;
if (p_flip_v)
- rect.position.y -= s.y - center.y;
+ rect.position.y -= cell_size.y / 2;
else
- rect.position.y -= center.y;
+ rect.position.y += cell_size.y / 2;
}
rect.position = p_xform.xform(rect.position);
@@ -731,10 +727,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_PAINTING;
- paint_undo.clear();
- paint_undo[over_tile] = _get_op_from_cell(over_tile);
-
- _set_cell(over_tile, id, flip_h, flip_v, transpose);
+ undo_redo->create_action(TTR("Paint TileMap"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
}
} else if (tool == TOOL_PICKING) {
@@ -755,15 +749,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
int id = get_selected_tile();
- if (id != TileMap::INVALID_CELL && paint_undo.size()) {
-
- undo_redo->create_action(TTR("Paint TileMap"));
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ if (id != TileMap::INVALID_CELL) {
- Point2 p = E->key();
- undo_redo->add_do_method(node, "set_cellv", p, id, flip_h, flip_v, transpose);
- undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
paint_undo.clear();
@@ -775,10 +763,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (id != TileMap::INVALID_CELL) {
undo_redo->create_action(TTR("Line Draw"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- _set_cell(E->key(), id, flip_h, flip_v, transpose, true);
+ _set_cell(E->key(), id, flip_h, flip_v, transpose);
}
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
paint_undo.clear();
@@ -792,12 +782,14 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (id != TileMap::INVALID_CELL) {
undo_redo->create_action(TTR("Rectangle Paint"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
- _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
+ _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose);
}
}
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
canvas_item_editor->update();
@@ -807,10 +799,12 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Point2 ofs = over_tile - rectangle.position;
undo_redo->create_action(TTR("Duplicate"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose, true);
+ _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose);
}
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
copydata.clear();
@@ -823,28 +817,23 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else if (tool == TOOL_BUCKET) {
- Dictionary pop;
- pop["id"] = node->get_cell(over_tile.x, over_tile.y);
- pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
- pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
- pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
-
PoolVector<Vector2> points = _bucket_fill(over_tile);
if (points.size() == 0)
return false;
+ undo_redo->create_action(TTR("Bucket Fill"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
+
Dictionary op;
op["id"] = get_selected_tile();
op["flip_h"] = flip_h;
op["flip_v"] = flip_v;
op["transpose"] = transpose;
- undo_redo->create_action(TTR("Bucket Fill"));
-
- undo_redo->add_do_method(this, "_fill_points", points, op);
- undo_redo->add_undo_method(this, "_fill_points", points, pop);
+ _fill_points(points, op);
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
undo_redo->commit_action();
// We want to keep the bucket-tool active
@@ -886,6 +875,9 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
+ undo_redo->create_action(TTR("Erase TileMap"));
+ undo_redo->add_undo_method(node, "set", "tile_data", node->get("tile_data"));
+
if (mb->get_shift()) {
if (mb->get_control())
@@ -899,7 +891,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
tool = TOOL_ERASING;
- paint_undo[local] = _get_op_from_cell(local);
_set_cell(local, TileMap::INVALID_CELL);
}
@@ -909,18 +900,8 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
} else {
if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
- if (paint_undo.size()) {
- undo_redo->create_action(TTR("Erase TileMap"));
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
-
- Point2 p = E->key();
- undo_redo->add_do_method(node, "set_cellv", p, TileMap::INVALID_CELL, false, false, false);
- undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
-
- undo_redo->commit_action();
- paint_undo.clear();
- }
+ undo_redo->add_do_method(node, "set", "tile_data", node->get("tile_data"));
+ undo_redo->commit_action();
if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
canvas_item_editor->update();
@@ -1007,10 +988,6 @@ bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
Point2i pos = points[i];
- if (!paint_undo.has(pos)) {
- paint_undo[pos] = _get_op_from_cell(pos);
- }
-
_set_cell(pos, TileMap::INVALID_CELL);
}
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index ce58cc9708..b5f2618576 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -167,7 +167,7 @@ class TileMapEditor : public VBoxContainer {
void _update_palette();
void _menu_option(int p_option);
- void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false, bool p_with_undo = false);
+ void _set_cell(const Point2i &p_pos, int p_value, bool p_flip_h = false, bool p_flip_v = false, bool p_transpose = false);
void _canvas_mouse_enter();
void _canvas_mouse_exit();
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index bbed7ff98d..eb2faa1ab1 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -1015,21 +1015,47 @@ void AutotileEditor::_on_tool_clicked(int p_tool) {
tile_set->autotile_clear_bitmask_map(get_current_tile());
workspace->update();
} else if (p_tool == SHAPE_DELETE) {
- if (!edited_collision_shape.is_null()) {
- Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(get_current_tile());
- int index;
- for (int i = 0; i < sd.size(); i++) {
- if (sd[i].shape == edited_collision_shape) {
- index = i;
- break;
- }
- }
- if (index >= 0) {
- sd.remove(index);
- tile_set->tile_set_shapes(get_current_tile(), sd);
- edited_collision_shape.unref();
- current_shape.resize(0);
- workspace->update();
+ if (creating_shape) {
+ creating_shape = false;
+ current_shape.resize(0);
+ workspace->update();
+ } else {
+ switch (edit_mode) {
+ case EDITMODE_COLLISION: {
+ if (!edited_collision_shape.is_null()) {
+ Vector<TileSet::ShapeData> sd = tile_set->tile_get_shapes(get_current_tile());
+ int index;
+ for (int i = 0; i < sd.size(); i++) {
+ if (sd[i].shape == edited_collision_shape) {
+ index = i;
+ break;
+ }
+ }
+ if (index >= 0) {
+ sd.remove(index);
+ tile_set->tile_set_shapes(get_current_tile(), sd);
+ edited_collision_shape = Ref<ConcavePolygonShape2D>();
+ current_shape.resize(0);
+ workspace->update();
+ }
+ }
+ } break;
+ case EDITMODE_NAVIGATION: {
+ if (!edited_navigation_shape.is_null()) {
+ tile_set->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()) {
+ tile_set->autotile_set_light_occluder(get_current_tile(), Ref<OccluderPolygon2D>(), edited_shape_coord);
+ edited_occlusion_shape = Ref<OccluderPolygon2D>();
+ current_shape.resize(0);
+ workspace->update();
+ }
+ } break;
}
}
} else if (p_tool == ZOOM_OUT) {
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 43c7f33cbe..b4d89526b0 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -213,7 +213,7 @@ private:
}
String sp = p.simplify_path();
project_path->set_text(sp);
- set_message(TTR(" ")); // just so it does not disappear
+ set_message(" "); // just so it does not disappear
get_ok()->call_deferred("grab_focus");
}
@@ -508,7 +508,8 @@ public:
} else if (current->has_setting("application/config/name")) {
project_name->set_text(current->get("application/config/name"));
}
- project_name->grab_focus();
+
+ project_name->call_deferred("grab_focus");
create_dir->hide();
status_btn->hide();
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index d573a44cdd..11c7e07b6a 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -2665,18 +2665,14 @@ TreeItem *PropertyEditor::get_parent_node(String p_path, HashMap<String, TreeIte
item->set_editable(1, false);
item->set_selectable(1, subsection_selectable);
- if (use_folding || folding_behaviour != FB_UNDEFINED) { // Even if you disabled folding (expand all by default), you still can collapse all manually.
+ if (use_folding) { //
if (!obj->editor_is_section_unfolded(p_path)) {
updating_folding = true;
- if (folding_behaviour == FB_COLLAPSEALL)
- item->set_collapsed(true);
- else if (folding_behaviour == FB_EXPANDALL || is_expandall_enabled)
- item->set_collapsed(false);
- else
- item->set_collapsed(true);
+ item->set_collapsed(true);
updating_folding = false;
}
item->set_metadata(0, p_path);
+ foldable_property_cache.push_back(p_path);
}
if (item->get_parent() == root) {
@@ -2725,6 +2721,7 @@ void PropertyEditor::refresh() {
void PropertyEditor::update_tree() {
tree->clear();
+ foldable_property_cache.clear();
if (!obj)
return;
@@ -3081,7 +3078,7 @@ void PropertyEditor::update_tree() {
item->set_text(1, type + " ID: " + itos(id));
item->add_button(1, get_icon("EditResource", "EditorIcons"));
} else {
- item->set_text(1, "[Empty]");
+ item->set_text(1, TTR("[Empty]"));
}
if (has_icon(p.hint_string, "EditorIcons")) {
@@ -3733,7 +3730,7 @@ void PropertyEditor::_item_edited() {
_edit_set(name, item->get_text(1), refresh_all);
}
} break;
- // math types
+ // math types
case Variant::VECTOR3: {
@@ -4212,29 +4209,29 @@ void PropertyEditor::set_subsection_selectable(bool p_selectable) {
update_tree();
}
-bool PropertyEditor::is_expand_all_properties_enabled() const {
-
- return (use_folding == false);
-}
-
void PropertyEditor::set_use_folding(bool p_enable) {
use_folding = p_enable;
tree->set_hide_folding(false);
}
-void PropertyEditor::collapse_all_parent_nodes() {
-
- folding_behaviour = FB_COLLAPSEALL;
+void PropertyEditor::collapse_all_folding() {
+ if (!obj)
+ return;
+ for (List<String>::Element *E = foldable_property_cache.front(); E; E = E->next()) {
+ obj->editor_set_section_unfold(E->get(), false);
+ }
update_tree();
- folding_behaviour = FB_UNDEFINED;
}
-void PropertyEditor::expand_all_parent_nodes() {
+void PropertyEditor::expand_all_folding() {
- folding_behaviour = FB_EXPANDALL;
+ if (!obj)
+ return;
+ for (List<String>::Element *E = foldable_property_cache.front(); E; E = E->next()) {
+ obj->editor_set_section_unfold(E->get(), true);
+ }
update_tree();
- folding_behaviour = FB_UNDEFINED;
}
PropertyEditor::PropertyEditor() {
@@ -4309,8 +4306,6 @@ PropertyEditor::PropertyEditor() {
subsection_selectable = false;
property_selectable = false;
show_type_icons = false; // maybe one day will return.
- folding_behaviour = FB_UNDEFINED;
- is_expandall_enabled = bool(EDITOR_DEF("interface/editor/expand_all_properties", true));
}
PropertyEditor::~PropertyEditor() {
diff --git a/editor/property_editor.h b/editor/property_editor.h
index a337a05e46..bcabccc6fd 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -203,18 +203,9 @@ class PropertyEditor : public Control {
bool hide_script;
bool use_folding;
bool property_selectable;
- bool is_expandall_enabled;
-
bool updating_folding;
- enum FOLDING_BEHAVIOUR {
- FB_UNDEFINED,
- FB_COLLAPSEALL,
- FB_EXPANDALL,
- FB_EXPANDALL_FORCE
- };
- FOLDING_BEHAVIOUR folding_behaviour;
-
+ List<String> foldable_property_cache;
HashMap<String, String> pending;
String selected_property;
@@ -314,10 +305,8 @@ public:
void set_use_folding(bool p_enable);
- bool is_expand_all_properties_enabled() const;
-
- void collapse_all_parent_nodes();
- void expand_all_parent_nodes();
+ void collapse_all_folding();
+ void expand_all_folding();
PropertyEditor();
~PropertyEditor();
};
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 7705e4e1b9..a1c1ec3351 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -1853,7 +1853,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
inspect_scene_tree->connect("cell_selected", this, "_scene_tree_selected");
inspect_scene_tree->connect("item_collapsed", this, "_scene_tree_folded");
- auto_switch_remote_scene_tree = EDITOR_DEF("debugger/auto_switch_to_remote_scene_tree", true);
+ auto_switch_remote_scene_tree = EDITOR_DEF("debugger/auto_switch_to_remote_scene_tree", false);
inspect_scene_tree_timeout = EDITOR_DEF("debugger/remote_scene_tree_refresh_interval", 1.0);
inspect_edited_object_timeout = EDITOR_DEF("debugger/remote_inspect_refresh_interval", 0.2);
inspected_object_id = 0;
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 853761f689..fccd0c51aa 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -406,13 +406,13 @@ EditorSettingsDialog::EditorSettingsDialog() {
shortcut_clear_button->connect("pressed", this, "_clear_shortcut_search_box");
shortcuts = memnew(Tree);
- vbc->add_margin_child("Shortcut List:", shortcuts, true);
+ vbc->add_margin_child(TTR("Shortcut List:"), shortcuts, true);
shortcuts->set_columns(2);
shortcuts->set_hide_root(true);
//shortcuts->set_hide_folding(true);
shortcuts->set_column_titles_visible(true);
- shortcuts->set_column_title(0, "Name");
- shortcuts->set_column_title(1, "Binding");
+ shortcuts->set_column_title(0, TTR("Name"));
+ shortcuts->set_column_title(1, TTR("Binding"));
shortcuts->connect("button_pressed", this, "_shortcut_button_pressed");
press_a_key = memnew(ConfirmationDialog);
diff --git a/editor/translations/README.md b/editor/translations/README.md
index 351bc9e2d1..f30f4e61fb 100644
--- a/editor/translations/README.md
+++ b/editor/translations/README.md
@@ -16,5 +16,8 @@ Link if you missed it: https://hosted.weblate.org/projects/godot-engine/godot
## Adding new languages
If you want to translate for a language which is not featured yet on Weblate,
-open an issue on this repo to ask that the language is added, or contact
-Akien/@akien-mga directly on IRC (#godotengine channel on Freenode).
+you can add it (when logged in) by clicking the "Start new translation"
+button at the bottom of the page.
+
+Alternatively, you can use this
+[direct link](https://hosted.weblate.org/new-lang/godot-engine/godot/).
diff --git a/modules/bullet/bullet_physics_server.cpp b/modules/bullet/bullet_physics_server.cpp
index 7f95d16ba6..6e9ed0e318 100644
--- a/modules/bullet/bullet_physics_server.cpp
+++ b/modules/bullet/bullet_physics_server.cpp
@@ -798,7 +798,7 @@ bool BulletPhysicsServer::body_is_omitting_force_integration(RID p_body) const {
void BulletPhysicsServer::body_set_force_integration_callback(RID p_body, Object *p_receiver, const StringName &p_method, const Variant &p_udata) {
RigidBodyBullet *body = rigid_body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_force_integration_callback(p_receiver->get_instance_id(), p_method, p_udata);
+ body->set_force_integration_callback(p_receiver ? p_receiver->get_instance_id() : ObjectID(0), p_method, p_udata);
}
void BulletPhysicsServer::body_set_ray_pickable(RID p_body, bool p_enable) {
diff --git a/modules/gdnative/gdnative/basis.cpp b/modules/gdnative/gdnative/basis.cpp
index 39ca754dc7..7a65996036 100644
--- a/modules/gdnative/gdnative/basis.cpp
+++ b/modules/gdnative/gdnative/basis.cpp
@@ -221,7 +221,7 @@ godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godo
return raw_dest;
}
-godot_basis GDAPI godot_basis_operator_substract(const godot_basis *p_self, const godot_basis *p_b) {
+godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b) {
godot_basis raw_dest;
Basis *dest = (Basis *)&raw_dest;
const Basis *self = (const Basis *)p_self;
diff --git a/modules/gdnative/gdnative/quat.cpp b/modules/gdnative/gdnative/quat.cpp
index 2d012c069f..c308e5973d 100644
--- a/modules/gdnative/gdnative/quat.cpp
+++ b/modules/gdnative/gdnative/quat.cpp
@@ -181,7 +181,7 @@ godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_q
return raw_dest;
}
-godot_quat GDAPI godot_quat_operator_substract(const godot_quat *p_self, const godot_quat *p_b) {
+godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b) {
godot_quat raw_dest;
Quat *dest = (Quat *)&raw_dest;
const Quat *self = (const Quat *)p_self;
diff --git a/modules/gdnative/gdnative/vector2.cpp b/modules/gdnative/gdnative/vector2.cpp
index 7a5b29e0c4..7be08929b1 100644
--- a/modules/gdnative/gdnative/vector2.cpp
+++ b/modules/gdnative/gdnative/vector2.cpp
@@ -207,7 +207,7 @@ godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, cons
return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_operator_substract(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b) {
godot_vector2 raw_dest;
Vector2 *dest = (Vector2 *)&raw_dest;
const Vector2 *self = (const Vector2 *)p_self;
diff --git a/modules/gdnative/gdnative/vector3.cpp b/modules/gdnative/gdnative/vector3.cpp
index 11ffb3320b..0027d236f2 100644
--- a/modules/gdnative/gdnative/vector3.cpp
+++ b/modules/gdnative/gdnative/vector3.cpp
@@ -224,7 +224,7 @@ godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, cons
return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_substract(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b) {
godot_vector3 raw_dest;
Vector3 *dest = (Vector3 *)&raw_dest;
Vector3 *self = (Vector3 *)p_self;
diff --git a/modules/gdnative/gdnative_api.json b/modules/gdnative/gdnative_api.json
index 488ed93206..31f3b0b77b 100644
--- a/modules/gdnative/gdnative_api.json
+++ b/modules/gdnative/gdnative_api.json
@@ -387,7 +387,7 @@
]
},
{
- "name": "godot_vector2_operator_substract",
+ "name": "godot_vector2_operator_subtract",
"return_type": "godot_vector2",
"arguments": [
["const godot_vector2 *", "p_self"],
@@ -663,7 +663,7 @@
]
},
{
- "name": "godot_quat_operator_substract",
+ "name": "godot_quat_operator_subtract",
"return_type": "godot_quat",
"arguments": [
["const godot_quat *", "p_self"],
@@ -907,7 +907,7 @@
]
},
{
- "name": "godot_basis_operator_substract",
+ "name": "godot_basis_operator_subtract",
"return_type": "godot_basis",
"arguments": [
["const godot_basis *", "p_self"],
@@ -1142,7 +1142,7 @@
]
},
{
- "name": "godot_vector3_operator_substract",
+ "name": "godot_vector3_operator_subtract",
"return_type": "godot_vector3",
"arguments": [
["const godot_vector3 *", "p_self"],
diff --git a/modules/gdnative/include/gdnative/basis.h b/modules/gdnative/include/gdnative/basis.h
index 49ca765a01..4898eab24c 100644
--- a/modules/gdnative/include/gdnative/basis.h
+++ b/modules/gdnative/include/gdnative/basis.h
@@ -111,7 +111,7 @@ godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const god
godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b);
-godot_basis GDAPI godot_basis_operator_substract(const godot_basis *p_self, const godot_basis *p_b);
+godot_basis GDAPI godot_basis_operator_subtract(const godot_basis *p_self, const godot_basis *p_b);
godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b);
diff --git a/modules/gdnative/include/gdnative/gdnative.h b/modules/gdnative/include/gdnative/gdnative.h
index 6e69d43469..f7f5606428 100644
--- a/modules/gdnative/include/gdnative/gdnative.h
+++ b/modules/gdnative/include/gdnative/gdnative.h
@@ -115,8 +115,6 @@ typedef enum {
GODOT_ERR_HELP, ///< user requested help!!
GODOT_ERR_BUG, ///< a bug in the software certainly happened, due to a double check failing or unexpected behavior.
GODOT_ERR_PRINTER_ON_FIRE, /// the parallel port printer is engulfed in flames
- GODOT_ERR_OMFG_THIS_IS_VERY_VERY_BAD, ///< shit happens, has never been used, though
- GODOT_ERR_WTF = GODOT_ERR_OMFG_THIS_IS_VERY_VERY_BAD ///< short version of the above
} godot_error;
////// bool
diff --git a/modules/gdnative/include/gdnative/quat.h b/modules/gdnative/include/gdnative/quat.h
index acae6e3e90..2be9d8849d 100644
--- a/modules/gdnative/include/gdnative/quat.h
+++ b/modules/gdnative/include/gdnative/quat.h
@@ -98,7 +98,7 @@ godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const go
godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b);
-godot_quat GDAPI godot_quat_operator_substract(const godot_quat *p_self, const godot_quat *p_b);
+godot_quat GDAPI godot_quat_operator_subtract(const godot_quat *p_self, const godot_quat *p_b);
godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b);
diff --git a/modules/gdnative/include/gdnative/vector2.h b/modules/gdnative/include/gdnative/vector2.h
index 07105abaf2..4d1117e3aa 100644
--- a/modules/gdnative/include/gdnative/vector2.h
+++ b/modules/gdnative/include/gdnative/vector2.h
@@ -106,7 +106,7 @@ godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const god
godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b);
-godot_vector2 GDAPI godot_vector2_operator_substract(const godot_vector2 *p_self, const godot_vector2 *p_b);
+godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_self, const godot_vector2 *p_b);
godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b);
diff --git a/modules/gdnative/include/gdnative/vector3.h b/modules/gdnative/include/gdnative/vector3.h
index 3ed23778ec..135a13acc8 100644
--- a/modules/gdnative/include/gdnative/vector3.h
+++ b/modules/gdnative/include/gdnative/vector3.h
@@ -117,7 +117,7 @@ godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const god
godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b);
-godot_vector3 GDAPI godot_vector3_operator_substract(const godot_vector3 *p_self, const godot_vector3 *p_b);
+godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_self, const godot_vector3 *p_b);
godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b);
diff --git a/modules/gdnative/register_types.cpp b/modules/gdnative/register_types.cpp
index 34099bf528..365def75bc 100644
--- a/modules/gdnative/register_types.cpp
+++ b/modules/gdnative/register_types.cpp
@@ -103,16 +103,34 @@ static void actual_discoverer_handler() {
Set<String> file_paths = get_gdnative_singletons(dir);
+ bool changed = false;
+ Array current_files = ProjectSettings::get_singleton()->get("gdnative/singletons");
Array files;
files.resize(file_paths.size());
int i = 0;
for (Set<String>::Element *E = file_paths.front(); E; i++, E = E->next()) {
+ if (!current_files.has(E->get())) {
+ changed = true;
+ }
files.set(i, E->get());
}
- ProjectSettings::get_singleton()->set("gdnative/singletons", files);
+ // Check for removed files
+ if (!changed) {
+ for (int i = 0; i < current_files.size(); i++) {
+ if (!file_paths.has(current_files[i])) {
+ changed = true;
+ break;
+ }
+ }
+ }
- ProjectSettings::get_singleton()->save();
+ if (changed) {
+
+ ProjectSettings::get_singleton()->set("gdnative/singletons", files);
+
+ ProjectSettings::get_singleton()->save();
+ }
}
static GDNativeSingletonDiscover *discoverer = NULL;
diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp
index dfa5e720ae..6fbc309fa3 100644
--- a/modules/mono/csharp_script.cpp
+++ b/modules/mono/csharp_script.cpp
@@ -1332,7 +1332,7 @@ bool CSharpScript::_update_exports() {
while (top && top != native) {
const Vector<GDMonoField *> &fields = top->get_all_fields();
- for (int i = 0; i < fields.size(); i++) {
+ for (int i = fields.size() - 1; i >= 0; i--) {
GDMonoField *field = fields[i];
if (field->is_static()) {
@@ -1382,7 +1382,7 @@ bool CSharpScript::_update_exports() {
PropertyInfo prop_info = PropertyInfo(type, name, hint, hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_SCRIPT_VARIABLE);
member_info[cname] = prop_info;
- exported_members_cache.push_back(prop_info);
+ exported_members_cache.push_front(prop_info);
if (tmp_object) {
exported_members_defval_cache[cname] = GDMonoMarshal::mono_object_to_variant(field->get_value(tmp_object));
diff --git a/modules/mono/glue/cs_files/Error.cs b/modules/mono/glue/cs_files/Error.cs
index 3f4a92603d..dee4b88f74 100644
--- a/modules/mono/glue/cs_files/Error.cs
+++ b/modules/mono/glue/cs_files/Error.cs
@@ -42,7 +42,6 @@ namespace Godot
ERR_CYCLIC_LINK = 40,
ERR_BUSY = 44,
ERR_HELP = 46,
- ERR_BUG = 47,
- ERR_WTF = 49
+ ERR_BUG = 47
}
}
diff --git a/modules/opus/audio_stream_opus.cpp b/modules/opus/audio_stream_opus.cpp
index 06eab4c94d..5742102dae 100644
--- a/modules/opus/audio_stream_opus.cpp
+++ b/modules/opus/audio_stream_opus.cpp
@@ -62,7 +62,7 @@ int AudioStreamPlaybackOpus::_op_seek_func(void *_stream, opus_int64 _offset, in
fa->seek_end(_offset);
} break;
default: {
- ERR_PRINT("BUG, wtf was whence set to?\n");
+ ERR_PRINT("Opus seek function failure: Unexpected value in _whence\n");
}
}
int ret = fa->eof_reached() ? -1 : 0;
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 072f18b990..ac436c3c26 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -64,7 +64,7 @@ void image_decompress_squish(Image *p_image) {
} else if (p_image->get_format() == Image::FORMAT_RGTC_RG) {
squish_flags = squish::kBc5;
} else {
- print_line("wtf askd to decompress.. " + itos(p_image->get_format()));
+ print_line("Can't decompress unknown format: " + itos(p_image->get_format()));
ERR_FAIL_COND(true);
return;
}
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 95ad7256b3..5f98951bec 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -390,7 +390,7 @@ PropertyInfo VisualScriptOperator::get_input_value_port_info(int p_idx) const {
{ Variant::NIL, Variant::NIL }, //OP_GREATER_EQUAL,
//mathematic
{ Variant::NIL, Variant::NIL }, //OP_ADD,
- { Variant::NIL, Variant::NIL }, //OP_SUBSTRACT,
+ { Variant::NIL, Variant::NIL }, //OP_SUBTRACT,
{ Variant::NIL, Variant::NIL }, //OP_MULTIPLY,
{ Variant::NIL, Variant::NIL }, //OP_DIVIDE,
{ Variant::NIL, Variant::NIL }, //OP_NEGATE,
@@ -433,7 +433,7 @@ PropertyInfo VisualScriptOperator::get_output_value_port_info(int p_idx) const {
Variant::BOOL, //OP_GREATER_EQUAL,
//mathematic
Variant::NIL, //OP_ADD,
- Variant::NIL, //OP_SUBSTRACT,
+ Variant::NIL, //OP_SUBTRACT,
Variant::NIL, //OP_MULTIPLY,
Variant::NIL, //OP_DIVIDE,
Variant::NIL, //OP_NEGATE,
@@ -474,7 +474,7 @@ static const char *op_names[] = {
"GreaterEq", //OP_GREATER_EQUAL,
//mathematic
"Add", //OP_ADD,
- "Subtract", //OP_SUBSTRACT,
+ "Subtract", //OP_SUBTRACT,
"Multiply", //OP_MULTIPLY,
"Divide", //OP_DIVIDE,
"Negate", //OP_NEGATE,
@@ -514,7 +514,7 @@ String VisualScriptOperator::get_text() const {
L"A \u2265 B", //OP_GREATER_EQUAL,
//mathematic
L"A + B", //OP_ADD,
- L"A - B", //OP_SUBSTRACT,
+ L"A - B", //OP_SUBTRACT,
L"A x B", //OP_MULTIPLY,
L"A \u00F7 B", //OP_DIVIDE,
L"\u00AC A", //OP_NEGATE,
diff --git a/modules/vorbis/audio_stream_ogg_vorbis.cpp b/modules/vorbis/audio_stream_ogg_vorbis.cpp
index 9fb6fa8197..03c0bfb1c2 100644
--- a/modules/vorbis/audio_stream_ogg_vorbis.cpp
+++ b/modules/vorbis/audio_stream_ogg_vorbis.cpp
@@ -64,7 +64,7 @@ int AudioStreamPlaybackOGGVorbis::_ov_seek_func(void *_f, ogg_int64_t offs, int
fa->seek_end(offs);
} else {
- ERR_PRINT("BUG, wtf was whence set to?\n");
+ ERR_PRINT("Vorbis seek function failure: Unexpected value in _whence\n");
}
int ret = fa->eof_reached() ? -1 : 0;
//printf("returning %i\n",ret);
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 11c49fbb50..4a44d1c5f9 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -31,7 +31,7 @@ android {
disable 'MissingTranslation'
}
- compileSdkVersion 24
+ compileSdkVersion 26
buildToolsVersion "26.0.1"
useLibrary 'org.apache.http.legacy'
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 41dcba5c2c..4daf06142d 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -970,7 +970,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
boolean indeterminate;
switch (newState) {
case IDownloaderClient.STATE_IDLE:
- Log.d("GODOT", "STATE IDLE");
+ Log.d("GODOT", "DOWNLOAD STATE IDLE");
// STATE_IDLE means the service is listening, so it's
// safe to start making calls via mRemoteService.
paused = false;
@@ -978,13 +978,13 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
break;
case IDownloaderClient.STATE_CONNECTING:
case IDownloaderClient.STATE_FETCHING_URL:
- Log.d("GODOT", "STATE CONNECTION / FETCHING URL");
+ Log.d("GODOT", "DOWNLOAD STATE CONNECTION / FETCHING URL");
showDashboard = true;
paused = false;
indeterminate = true;
break;
case IDownloaderClient.STATE_DOWNLOADING:
- Log.d("GODOT", "STATE DOWNLOADING");
+ Log.d("GODOT", "DOWNLOAD STATE DOWNLOADING");
paused = false;
showDashboard = true;
indeterminate = false;
@@ -994,14 +994,14 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
case IDownloaderClient.STATE_FAILED:
case IDownloaderClient.STATE_FAILED_FETCHING_URL:
case IDownloaderClient.STATE_FAILED_UNLICENSED:
- Log.d("GODOT", "MANY TYPES OF FAILING");
+ Log.d("GODOT", "DOWNLOAD STATE: FAILED, CANCELLED, UNLICENSED OR FAILED TO FETCH URL");
paused = true;
showDashboard = false;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
- Log.d("GODOT", "PAUSED FOR SOME STUPID REASON");
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY MISSING CELLULAR PERMISSION");
showDashboard = false;
paused = true;
indeterminate = false;
@@ -1009,18 +1009,18 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
break;
case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
- Log.d("GODOT", "PAUSED BY STUPID USER");
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY USER");
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_ROAMING:
case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
- Log.d("GODOT", "PAUSED BY ROAMING WTF!?");
+ Log.d("GODOT", "DOWNLOAD STATE: PAUSED BY ROAMING OR SDCARD UNAVAILABLE");
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_COMPLETED:
- Log.d("GODOT", "COMPLETED");
+ Log.d("GODOT", "DOWNLOAD STATE: COMPLETED");
showDashboard = false;
paused = false;
indeterminate = false;
@@ -1028,7 +1028,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
initializeGodot();
return;
default:
- Log.d("GODOT", "DEFAULT ????");
+ Log.d("GODOT", "DOWNLOAD STATE: DEFAULT");
paused = true;
indeterminate = true;
showDashboard = true;
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index fbe3bd310d..f06657cd7b 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -394,12 +394,12 @@ void OSIPhone::alert(const String &p_alert, const String &p_title) {
iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
}
-Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle) {
+Error OSIPhone::open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path) {
if (p_path.length() == 0) {
p_library_handle = RTLD_SELF;
return OK;
}
- return OS_Unix::open_dynamic_library(p_path, p_library_handle);
+ return OS_Unix::open_dynamic_library(p_path, p_library_handle, p_also_set_library_path);
}
Error OSIPhone::close_dynamic_library(void *p_library_handle) {
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 1ef673765a..3f989b49be 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -155,7 +155,7 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false);
virtual Error close_dynamic_library(void *p_library_handle);
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional = false);
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 9a740a7bea..6543ca7dd2 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -43,7 +43,6 @@
#include "servers/visual_server.h"
#include <ApplicationServices/ApplicationServices.h>
-//bitch
#undef CursorShape
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 781e8de1ab..732ec910c0 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -1483,7 +1483,7 @@ void OS_OSX::make_rendering_thread() {
Error OS_OSX::shell_open(String p_uri) {
- [[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[NSString stringWithUTF8String:p_uri.utf8().get_data()]]];
+ [[NSWorkspace sharedWorkspace] openURL:[[NSURL alloc] initWithString:[[NSString stringWithUTF8String:p_uri.utf8().get_data()] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]]];
return OK;
}
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 03f7c2a6c8..40b10c019f 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -38,7 +38,6 @@
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
-//bitch
#undef CursorShape
/**
@author Juan Linietsky <reduzio@gmail.com>
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index d4612783c7..9bcbb6ddb6 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -69,8 +69,26 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001;
#define WM_TOUCH 576
#endif
+static String format_error_message(DWORD id) {
+
+ LPWSTR messageBuffer = NULL;
+ size_t size = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, id, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
+
+ String msg = "Error "+itos(id)+": "+String(messageBuffer,size);
+
+ LocalFree(messageBuffer);
+
+ return msg;
+
+}
+
+
+
extern HINSTANCE godot_hinstance;
+
+
void RedirectIOToConsole() {
int hConHandle;
@@ -1597,14 +1615,14 @@ Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_han
cookie = AddDllDirectory(p_path.get_base_dir().c_str());
}
- p_library_handle = (void *)LoadLibraryExW(p_path.c_str(),NULL,p_also_set_library_path ? LOAD_LIBRARY_SEARCH_USER_DIRS : 0);
+ p_library_handle = (void *)LoadLibraryExW(p_path.c_str(), NULL, p_also_set_library_path ? LOAD_LIBRARY_SEARCH_DEFAULT_DIRS : 0);
if (p_also_set_library_path) {
RemoveDllDirectory(cookie);
}
if (!p_library_handle) {
- ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError()));
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + format_error_message(GetLastError()));
ERR_FAIL_V(ERR_CANT_OPEN);
}
return OK;
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
index a9d9cb9373..8b83215325 100644
--- a/platform/windows/stream_peer_winsock.cpp
+++ b/platform/windows/stream_peer_winsock.cpp
@@ -141,7 +141,7 @@ Error StreamPeerWinsock::write(const uint8_t *p_data, int p_bytes, int &r_sent,
if (WSAGetLastError() != WSAEWOULDBLOCK) {
- perror("shit?");
+ perror("Nothing sent");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
@@ -197,7 +197,7 @@ Error StreamPeerWinsock::read(uint8_t *p_buffer, int p_bytes, int &r_received, b
if (WSAGetLastError() != WSAEWOULDBLOCK) {
- perror("shit?");
+ perror("Nothing read");
disconnect_from_host();
ERR_PRINT("Server disconnected!\n");
return FAILED;
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index aee5d89150..7d53557216 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -291,7 +291,7 @@ void Particles2D::_notification(int p_what) {
texture_rid = texture->get_rid();
RID normal_rid;
if (normal_map.is_valid())
- normal_rid = texture->get_rid();
+ normal_rid = normal_map->get_rid();
VS::get_singleton()->canvas_item_add_particles(get_canvas_item(), particles, texture_rid, normal_rid, h_frames, v_frames);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 2329ce8644..c0d0a6e011 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -215,6 +215,9 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const
if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT)
offset.y += cell_size.y;
+ else if (tile_origin == TILE_ORIGIN_CENTER) {
+ offset += cell_size / 2;
+ }
if (s.y > s.x) {
if ((p_cell.flip_h && (p_cell.flip_v || p_cell.transpose)) || (p_cell.flip_v && !p_cell.transpose))
@@ -235,6 +238,8 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const
xform.elements[1].x = -xform.elements[1].x;
if (tile_origin == TILE_ORIGIN_TOP_LEFT || tile_origin == TILE_ORIGIN_BOTTOM_LEFT)
offset.x = s.x - offset.x;
+ else if (tile_origin == TILE_ORIGIN_CENTER)
+ offset.x = s.x - offset.x / 2;
}
if (p_cell.flip_v) {
xform.elements[0].y = -xform.elements[0].y;
@@ -242,10 +247,9 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const
if (tile_origin == TILE_ORIGIN_TOP_LEFT)
offset.y = s.y - offset.y;
else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
- if (p_cell.transpose)
- offset.y += s.y;
- else
- offset.y -= s.y;
+ offset.y += s.y;
+ } else if (tile_origin == TILE_ORIGIN_CENTER) {
+ offset.y += s.y;
}
}
xform.elements[2].x += offset.x;
@@ -429,20 +433,18 @@ void TileMap::_update_dirty_quadrants() {
}
} else if (tile_origin == TILE_ORIGIN_CENTER) {
- rect.position += tcenter;
- Vector2 center = (s / 2) - tile_ofs;
- center_ofs = tcenter - (s / 2);
+ rect.position += tile_ofs;
if (c.flip_h)
- rect.position.x -= s.x - center.x;
+ rect.position.x -= cell_size.x / 2;
else
- rect.position.x -= center.x;
+ rect.position.x += cell_size.x / 2;
if (c.flip_v)
- rect.position.y -= s.y - center.y;
+ rect.position.y -= cell_size.y / 2;
else
- rect.position.y -= center.y;
+ rect.position.y += cell_size.y / 2;
}
Ref<Texture> normal_map = tile_set->tile_get_normal_map(c.id);
@@ -714,7 +716,7 @@ void TileMap::set_cell(int p_x, int p_y, int p_tile, bool p_flip_x, bool p_flip_
} else {
ERR_FAIL_COND(!Q); // quadrant should exist...
- if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose)
+ if (E->get().id == p_tile && E->get().flip_h == p_flip_x && E->get().flip_v == p_flip_y && E->get().transpose == p_transpose && E->get().autotile_coord_x == (uint16_t)p_autotile_coord.x && E->get().autotile_coord_y == (uint16_t)p_autotile_coord.y)
return; //nothing changed
}
@@ -739,7 +741,7 @@ int TileMap::get_cellv(const Vector2 &p_pos) const {
void TileMap::make_bitmask_area_dirty(const Vector2 &p_pos) {
for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) {
- for (int y = p_pos.y - 1; x <= p_pos.y + 1; y++) {
+ for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) {
PosKey p(x, y);
if (dirty_bitmask.find(p) == NULL) {
dirty_bitmask.push_back(p);
@@ -808,6 +810,10 @@ void TileMap::update_cell_bitmask(int p_x, int p_y) {
Vector2 coord = tile_set->autotile_get_subtile_for_bitmask(id, mask, this, Vector2(p_x, p_y));
E->get().autotile_coord_x = (int)coord.x;
E->get().autotile_coord_y = (int)coord.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 {
E->get().autotile_coord_x = 0;
E->get().autotile_coord_y = 0;
@@ -868,28 +874,31 @@ bool TileMap::is_cell_transposed(int p_x, int p_y) const {
return E->get().transpose;
}
-int TileMap::get_cell_autotile_coord_x(int p_x, int p_y) const {
+void TileMap::set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord) {
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
if (!E)
- return 0;
+ return;
- return E->get().autotile_coord_x;
+ Cell c = E->get();
+ c.autotile_coord_x = p_coord.x;
+ c.autotile_coord_y = p_coord.y;
+ tile_map[pk] = c;
}
-int TileMap::get_cell_autotile_coord_y(int p_x, int p_y) const {
+Vector2 TileMap::get_cell_autotile_coord(int p_x, int p_y) const {
PosKey pk(p_x, p_y);
const Map<PosKey, Cell>::Element *E = tile_map.find(pk);
if (!E)
- return 0;
+ return Vector2();
- return E->get().autotile_coord_y;
+ return Vector2(E->get().autotile_coord_x, E->get().autotile_coord_y);
}
void TileMap::_recreate_quadrants() {
@@ -961,6 +970,7 @@ void TileMap::_set_tile_data(const PoolVector<int> &p_data) {
int offset = (format == FORMAT_2_1_5) ? 3 : 2;
+ clear();
for (int i = 0; i < c; i += offset) {
const uint8_t *ptr = (const uint8_t *)&r[i];
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index a0ca2e6a35..8eecf48df2 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -241,8 +241,8 @@ public:
bool is_cell_x_flipped(int p_x, int p_y) const;
bool is_cell_y_flipped(int p_x, int p_y) const;
bool is_cell_transposed(int p_x, int p_y) const;
- int get_cell_autotile_coord_x(int p_x, int p_y) const;
- int get_cell_autotile_coord_y(int p_x, int p_y) const;
+ void set_cell_autotile_coord(int p_x, int p_y, const Vector2 &p_coord);
+ Vector2 get_cell_autotile_coord(int p_x, int p_y) const;
void set_cellv(const Vector2 &p_pos, int p_tile, bool p_flip_x = false, bool p_flip_y = false, bool p_transpose = false);
int get_cellv(const Vector2 &p_pos) const;
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index 206f3ccca2..f3e750d0da 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1324,7 +1324,9 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_root"), &AnimationPlayer::get_root);
ClassDB::bind_method(D_METHOD("seek", "seconds", "update"), &AnimationPlayer::seek, DEFVAL(false));
- ClassDB::bind_method(D_METHOD("get_position"), &AnimationPlayer::get_current_animation_position);
+ ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
+ ClassDB::bind_method(D_METHOD("get_anim_position"), &AnimationPlayer::get_current_animation_position);
+ ClassDB::bind_method(D_METHOD("get_anim_length"), &AnimationPlayer::get_current_animation_length);
ClassDB::bind_method(D_METHOD("find_animation", "animation"), &AnimationPlayer::find_animation);
@@ -1333,15 +1335,15 @@ void AnimationPlayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_animation_process_mode", "mode"), &AnimationPlayer::set_animation_process_mode);
ClassDB::bind_method(D_METHOD("get_animation_process_mode"), &AnimationPlayer::get_animation_process_mode);
- ClassDB::bind_method(D_METHOD("get_current_animation_position"), &AnimationPlayer::get_current_animation_position);
- ClassDB::bind_method(D_METHOD("get_current_animation_length"), &AnimationPlayer::get_current_animation_length);
-
- ClassDB::bind_method(D_METHOD("advance", "delta"), &AnimationPlayer::advance);
-
ADD_GROUP("Playback Options", "playback_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "playback_process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_animation_process_mode", "get_animation_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "playback_default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), "set_default_blend_time", "get_default_blend_time");
+
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "root_node"), "set_root", "get_root");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "autoplay"), "set_autoplay", "get_autoplay");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed_scale"), "set_speed_scale", "get_speed_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "active"), "set_active", "is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_anim"), "set_current_anim", "get_current_anim");
ADD_SIGNAL(MethodInfo("animation_finished", PropertyInfo(Variant::STRING, "name")));
ADD_SIGNAL(MethodInfo("animation_changed", PropertyInfo(Variant::STRING, "old_name"), PropertyInfo(Variant::STRING, "new_name")));
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 9bfb70bf42..8af499fd96 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -47,13 +47,7 @@ void FileDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
refresh->set_icon(get_icon("reload"));
- dir_up->set_icon(get_icon("ArrowUp", "EditorIcons"));
- }
-
- if (p_what == NOTIFICATION_DRAW) {
-
- //RID ci = get_canvas_item();
- //get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
+ dir_up->set_icon(get_icon("parent_folder"));
}
if (p_what == NOTIFICATION_POPUP_HIDE) {
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index 124c268c8a..9cf4c105b4 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -793,6 +793,17 @@ void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
selection.click = item;
selection.click_char = line;
+
+ // Erase previous selection.
+ if (selection.active) {
+ selection.from = NULL;
+ selection.from_char = NULL;
+ selection.to = NULL;
+ selection.to_char = NULL;
+ selection.active = false;
+
+ update();
+ }
}
}
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index d8baa7834d..cae368aeca 100644
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -2121,7 +2121,7 @@ Node *Node::_duplicate(int p_flags, Map<const Node *, Node *> *r_duplimap) const
for (int i = 0; i < N->get()->get_child_count(); ++i) {
// Skip nodes not really belonging to the instanced hierarchy; they'll be processed normally later
- if (get_child(i)->data.owner != this)
+ if (N->get()->get_child(i)->data.owner != this)
continue;
node_tree.push_back(N->get()->get_child(i));
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index f74bf161f0..5ee286c2d5 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -418,12 +418,12 @@ void SceneTree::input_event(const Ref<InputEvent> &p_event) {
if (!input_handled) {
call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_unhandled_input", ev); //special one for GUI, as controls use their own process check
- input_handled = true;
_flush_ugc();
+ // input_handled = true; - no reason to set this as handled
root_lock--;
//MessageQueue::get_singleton()->flush(); //flushing here causes UI and other places slowness
} else {
- input_handled = true;
+ // input_handled = true; - no reason to set this as handled
root_lock--;
}
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 1fc2d4b16e..d864b0f763 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -69,6 +69,8 @@ void ViewportTexture::setup_local_to_scene() {
ERR_FAIL_COND(!vp);
vp->viewport_textures.insert(this);
+
+ VS::get_singleton()->texture_set_proxy(proxy, vp->texture_rid);
}
void ViewportTexture::set_viewport_path_in_scene(const NodePath &p_path) {
@@ -105,8 +107,8 @@ Size2 ViewportTexture::get_size() const {
}
RID ViewportTexture::get_rid() const {
- ERR_FAIL_COND_V(!vp, RID());
- return vp->texture_rid;
+ //ERR_FAIL_COND_V(!vp, RID());
+ return proxy;
}
bool ViewportTexture::has_alpha() const {
@@ -147,6 +149,7 @@ ViewportTexture::ViewportTexture() {
vp = NULL;
set_local_to_scene(true);
+ proxy = VS::get_singleton()->texture_create();
}
ViewportTexture::~ViewportTexture() {
@@ -154,6 +157,8 @@ ViewportTexture::~ViewportTexture() {
if (vp) {
vp->viewport_textures.erase(this);
}
+
+ VS::get_singleton()->free(proxy);
}
/////////////////////////////////////
@@ -2813,6 +2818,7 @@ Viewport::Viewport() {
default_texture.instance();
default_texture->vp = const_cast<Viewport *>(this);
viewport_textures.insert(default_texture.ptr());
+ VS::get_singleton()->texture_set_proxy(default_texture->proxy, texture_rid);
//internal_listener = SpatialSoundServer::get_singleton()->listener_create();
audio_listener = false;
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 6bbd4b26b5..0835e3f69a 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -59,6 +59,8 @@ class ViewportTexture : public Texture {
friend class Viewport;
Viewport *vp;
+ RID proxy;
+
protected:
static void _bind_methods();
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index c99bc3c9ef..d6557f508e 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -529,6 +529,7 @@ void register_scene_types() {
ClassDB::register_class<LargeTexture>();
ClassDB::register_class<CurveTexture>();
ClassDB::register_class<GradientTexture>();
+ ClassDB::register_class<ProxyTexture>();
ClassDB::register_class<CubeMap>();
ClassDB::register_class<Animation>();
ClassDB::register_virtual_class<Font>();
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 36988e0c4c..819d16f61f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -257,6 +257,8 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// LinkButton
+ theme->set_stylebox("focus", "LinkButton", focus);
+
theme->set_font("font", "LinkButton", default_font);
theme->set_color("font_color", "LinkButton", control_font_color);
@@ -556,6 +558,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const
// File Dialog
theme->set_icon("reload", "FileDialog", make_icon(icon_reload_png));
+ theme->set_icon("parent_folder", "FileDialog", make_icon(icon_parent_folder_png));
// Popup
diff --git a/scene/resources/default_theme/icon_parent_folder.png b/scene/resources/default_theme/icon_parent_folder.png
new file mode 100644
index 0000000000..47fee1ad81
--- /dev/null
+++ b/scene/resources/default_theme/icon_parent_folder.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index 38e5f58b0d..255bb4c6dd 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -174,6 +174,10 @@ static const unsigned char icon_folder_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x8f, 0xc1, 0xd, 0x80, 0x30, 0x8, 0x45, 0x9f, 0x9d, 0x84, 0x39, 0x4c, 0x3b, 0xbd, 0x75, 0x8f, 0x32, 0x9, 0x5e, 0xec, 0xa5, 0x9, 0xa4, 0xc6, 0x26, 0x5e, 0x7c, 0x17, 0xe, 0xc0, 0xe3, 0x3, 0x5f, 0xb3, 0x1, 0xb4, 0xd6, 0x4e, 0x60, 0x77, 0x66, 0xaa, 0x88, 0x14, 0x4f, 0x90, 0xee, 0xea, 0x2d, 0x3, 0xe4, 0x28, 0x41, 0x8a, 0x9a, 0x1d, 0x55, 0x75, 0x25, 0xfd, 0x5, 0x9b, 0x11, 0xd, 0x54, 0x11, 0x29, 0x53, 0x9, 0x1c, 0x32, 0x4c, 0xbe, 0x10, 0xf1, 0xb, 0x16, 0xa, 0xea, 0xd3, 0x45, 0x33, 0x3b, 0xde, 0x1e, 0x5f, 0xc3, 0x5, 0x1f, 0xc5, 0x12, 0x2c, 0xc5, 0x88, 0xe1, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char icon_parent_folder_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc4, 0x0, 0x0, 0xe, 0xc4, 0x1, 0x95, 0x2b, 0xe, 0x1b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x0, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x90, 0xbd, 0x6a, 0x2, 0x51, 0x10, 0x46, 0xcf, 0x8c, 0xbb, 0xaf, 0x10, 0xdb, 0xcb, 0x2e, 0x4b, 0x40, 0xf2, 0x14, 0x51, 0x8b, 0x3c, 0x70, 0x44, 0x48, 0x48, 0x15, 0x4c, 0x61, 0x67, 0xd2, 0x4, 0x96, 0xb, 0x5b, 0x89, 0x58, 0x59, 0xee, 0x8f, 0x3b, 0x36, 0xbb, 0x8d, 0x78, 0xa3, 0x92, 0x4a, 0x4f, 0xf9, 0xcd, 0xcc, 0x99, 0x61, 0xe0, 0xe6, 0x91, 0x50, 0xc1, 0x7b, 0x3f, 0x54, 0xd5, 0x39, 0x60, 0x6d, 0xdb, 0xbe, 0x24, 0x49, 0xb2, 0xb9, 0x58, 0x90, 0xe7, 0xf9, 0x43, 0x1c, 0xc7, 0xef, 0x66, 0xf6, 0xd4, 0x45, 0xbf, 0xc0, 0xb3, 0x73, 0x6e, 0x7d, 0x56, 0x70, 0x62, 0xb8, 0xe7, 0xa4, 0x44, 0x8f, 0xcf, 0x8e, 0xa2, 0xe8, 0xa3, 0x1b, 0xfe, 0xee, 0x62, 0x13, 0x91, 0x1f, 0xe0, 0x11, 0x78, 0xf3, 0xde, 0xf, 0x83, 0x2, 0x55, 0x9d, 0x1, 0x23, 0x60, 0xd5, 0x34, 0xcd, 0xb4, 0xcf, 0xab, 0xaa, 0x1a, 0x77, 0xc2, 0x91, 0xaa, 0xbe, 0x6, 0x5, 0xc0, 0xe, 0xf8, 0x2a, 0xcb, 0x72, 0x92, 0xa6, 0xe9, 0xb6, 0xf, 0xb3, 0x2c, 0xdb, 0xd6, 0x75, 0x3d, 0x11, 0x91, 0x25, 0x50, 0xfe, 0xf9, 0x83, 0x1e, 0x33, 0x93, 0xa2, 0x28, 0xf6, 0x80, 0x39, 0xe7, 0x6, 0xa1, 0xbe, 0xe3, 0xb, 0xae, 0x26, 0x28, 0x10, 0x11, 0x3, 0x16, 0x22, 0xf2, 0xf9, 0xdf, 0x25, 0xf7, 0xce, 0x1, 0x9e, 0x13, 0x48, 0xe9, 0x87, 0xc5, 0x3a, 0xd2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char icon_play_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0xf2, 0x80, 0x11, 0x99, 0xf3, 0xe0, 0xc1, 0x83, 0xc3, 0xc, 0xc, 0xc, 0xc2, 0xc, 0xc, 0xc, 0xa5, 0xa, 0xa, 0xa, 0x5b, 0xc9, 0x31, 0xe0, 0x3f, 0x5c, 0x82, 0x91, 0x71, 0x27, 0x3, 0x3, 0x43, 0x91, 0xbc, 0xbc, 0xfc, 0x35, 0x7c, 0x6, 0x30, 0xe1, 0x92, 0xf8, 0xff, 0xff, 0xbf, 0xfb, 0xff, 0xff, 0xff, 0x2f, 0x3e, 0x78, 0xf0, 0x60, 0xca, 0x93, 0x27, 0x4f, 0x84, 0x49, 0x76, 0x1, 0x1a, 0xf8, 0xc0, 0xc8, 0xc8, 0xd8, 0xf1, 0xeb, 0xd7, 0xaf, 0x9, 0xaa, 0xaa, 0xaa, 0x3f, 0x89, 0x72, 0x1, 0x1a, 0x10, 0xf8, 0xff, 0xff, 0x7f, 0x7, 0x2b, 0x2b, 0xeb, 0x1e, 0x74, 0x9, 0x62, 0xd, 0xc0, 0x9, 0x88, 0x35, 0xe0, 0x3d, 0x23, 0x23, 0x63, 0xc5, 0xef, 0xdf, 0xbf, 0x5d, 0xd0, 0x25, 0x58, 0x8, 0x68, 0xfc, 0xc3, 0xc0, 0xc0, 0x30, 0x93, 0x85, 0x85, 0xa5, 0x5e, 0x46, 0x46, 0xe6, 0x2d, 0x36, 0x5, 0x38, 0xd, 0x20, 0x36, 0x1a, 0xd1, 0xd, 0x38, 0xc2, 0x0, 0x4d, 0x48, 0xf2, 0xf2, 0xf2, 0x44, 0x25, 0xa4, 0x61, 0x0, 0x0, 0x1e, 0x57, 0x33, 0x3c, 0xcc, 0xe7, 0x34, 0x69, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 79f642a09b..15710f4c14 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -689,6 +689,10 @@ void SpatialMaterial::_update_shader() {
}
}
+ if (flags[FLAG_ALBEDO_TEXTURE_FORCE_SRGB]) {
+ code += "\talbedo_tex.rgb = mix(pow((albedo_tex.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)),vec3(2.4)),albedo_tex.rgb.rgb * (1.0 / 12.92),lessThan(albedo_tex.rgb,vec3(0.04045)));\n";
+ }
+
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
code += "\talbedo_tex *= COLOR;\n";
}
@@ -1833,6 +1837,7 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_use_point_size"), "set_flag", "get_flag", FLAG_USE_POINT_SIZE);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_world_triplanar"), "set_flag", "get_flag", FLAG_TRIPLANAR_USE_WORLD);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_fixed_size"), "set_flag", "get_flag", FLAG_FIXED_SIZE);
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_albedo_tex_force_srgb"), "set_flag", "get_flag", FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
ADD_GROUP("Vertex Color", "vertex_color");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_use_as_albedo"), "set_flag", "get_flag", FLAG_ALBEDO_FROM_VERTEX_COLOR);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "vertex_color_is_srgb"), "set_flag", "get_flag", FLAG_SRGB_VERTEX_COLOR);
@@ -2019,6 +2024,7 @@ void SpatialMaterial::_bind_methods() {
BIND_ENUM_CONSTANT(FLAG_AO_ON_UV2);
BIND_ENUM_CONSTANT(FLAG_USE_ALPHA_SCISSOR);
BIND_ENUM_CONSTANT(FLAG_TRIPLANAR_USE_WORLD);
+ BIND_ENUM_CONSTANT(FLAG_ALBEDO_TEXTURE_FORCE_SRGB);
BIND_ENUM_CONSTANT(FLAG_MAX);
BIND_ENUM_CONSTANT(DIFFUSE_BURLEY);
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 877d4dfd41..374ec853dc 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -181,6 +181,7 @@ public:
FLAG_TRIPLANAR_USE_WORLD,
FLAG_AO_ON_UV2,
FLAG_USE_ALPHA_SCISSOR,
+ FLAG_ALBEDO_TEXTURE_FORCE_SRGB,
FLAG_MAX
};
@@ -229,7 +230,7 @@ private:
uint64_t blend_mode : 2;
uint64_t depth_draw_mode : 2;
uint64_t cull_mode : 2;
- uint64_t flags : 12;
+ uint64_t flags : 13;
uint64_t detail_blend_mode : 2;
uint64_t diffuse_mode : 3;
uint64_t specular_mode : 2;
diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp
index 5d6f44dfef..3a5cb7da2e 100644
--- a/scene/resources/packed_scene.cpp
+++ b/scene/resources/packed_scene.cpp
@@ -177,7 +177,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
node = Object::cast_to<Node>(obj);
} else {
- print_line("wtf class is disabled for: " + itos(n.type));
+ print_line("Class is disabled for: " + itos(n.type));
print_line("name: " + String(snames[n.type]));
}
@@ -232,11 +232,11 @@ Node *SceneState::instance(GenEditState p_edit_state) const {
Node *base = i == 0 ? node : ret_nodes[0];
if (p_edit_state == GEN_EDIT_STATE_MAIN) {
-
- res->local_scene = base;
- resources_local_to_scene[res] = res;
+ //for the main scene, use the resource as is
+ res->configure_for_local_scene(base, resources_local_to_scene);
} else {
+ //for instances, a copy must be made
Node *base = i == 0 ? node : ret_nodes[0];
Ref<Resource> local_dupe = res->duplicate_for_local_scene(base, resources_local_to_scene);
resources_local_to_scene[res] = local_dupe;
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
index 3b80db291c..2e8f9cbb33 100644
--- a/scene/resources/primitive_meshes.cpp
+++ b/scene/resources/primitive_meshes.cpp
@@ -164,7 +164,7 @@ void PrimitiveMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_mesh_arrays"), &PrimitiveMesh::get_mesh_arrays);
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "SpatialMaterial,ShaderMaterial"), "set_material", "get_material");
}
void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 162edd0d1c..987d6c5f6a 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -1601,3 +1601,72 @@ int GradientTexture::get_width() const {
Ref<Image> GradientTexture::get_data() const {
return VisualServer::get_singleton()->texture_get_data(texture);
}
+
+//////////////////////////////////////
+
+void ProxyTexture::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_base", "base"), &ProxyTexture::set_base);
+ ClassDB::bind_method(D_METHOD("get_base"), &ProxyTexture::get_base);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "base", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_base", "get_base");
+}
+
+void ProxyTexture::set_base(const Ref<Texture> &p_texture) {
+
+ base = p_texture;
+ if (base.is_valid()) {
+ VS::get_singleton()->texture_set_proxy(proxy, base->get_rid());
+ } else {
+ VS::get_singleton()->texture_set_proxy(proxy, RID());
+ }
+}
+
+Ref<Texture> ProxyTexture::get_base() const {
+
+ return base;
+}
+
+int ProxyTexture::get_width() const {
+
+ if (base.is_valid())
+ return base->get_width();
+ return 1;
+}
+int ProxyTexture::get_height() const {
+
+ if (base.is_valid())
+ return base->get_height();
+ return 1;
+}
+RID ProxyTexture::get_rid() const {
+
+ return proxy;
+}
+
+bool ProxyTexture::has_alpha() const {
+
+ if (base.is_valid())
+ return base->has_alpha();
+ return false;
+}
+
+void ProxyTexture::set_flags(uint32_t p_flags) {
+}
+
+uint32_t ProxyTexture::get_flags() const {
+
+ if (base.is_valid())
+ return base->get_flags();
+ return 0;
+}
+
+ProxyTexture::ProxyTexture() {
+
+ proxy = VS::get_singleton()->texture_create();
+}
+
+ProxyTexture::~ProxyTexture() {
+
+ VS::get_singleton()->free(proxy);
+}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index ee54156647..76c0195ef9 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -493,4 +493,31 @@ public:
virtual ~GradientTexture();
};
+class ProxyTexture : public Texture {
+ GDCLASS(ProxyTexture, Texture)
+
+private:
+ RID proxy;
+ Ref<Texture> base;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_base(const Ref<Texture> &p_texture);
+ Ref<Texture> get_base() const;
+
+ virtual int get_width() const;
+ virtual int get_height() const;
+ virtual RID get_rid() const;
+
+ virtual bool has_alpha() const;
+
+ virtual void set_flags(uint32_t p_flags);
+ virtual uint32_t get_flags() const;
+
+ ProxyTexture();
+ ~ProxyTexture();
+};
+
#endif
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index 2499551607..4bb34af241 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -193,6 +193,8 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
+ virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
+
/* SKY API */
virtual RID sky_create() = 0;
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index f34951f452..91542625e0 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -168,6 +168,8 @@ public:
BIND1(textures_keep_original, bool)
+ BIND2(texture_set_proxy, RID, RID)
+
/* SKY API */
BIND0R(RID, sky_create)
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index 69827b330d..72fb1df94b 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -303,6 +303,23 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
VSG::storage->instance_remove_dependency(instance->base, instance);
+ if (instance->base_type == VS::INSTANCE_GI_PROBE) {
+ //if gi probe is baking, wait until done baking, else race condition may happen when removing it
+ //from octree
+ InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
+
+ //make sure probes are done baking
+ while (!probe_bake_list.empty()) {
+ OS::get_singleton()->delay_usec(1);
+ }
+ //make sure this one is done baking
+
+ while (gi_probe->dynamic.updating_stage == GI_UPDATE_STAGE_LIGHTING) {
+ //wait until bake is done if it's baking
+ OS::get_singleton()->delay_usec(1);
+ }
+ }
+
if (scenario && instance->octree_id) {
scenario->octree.erase(instance->octree_id); //make dependencies generated by the octree go away
instance->octree_id = 0;
@@ -331,10 +348,6 @@ void VisualServerScene::instance_set_base(RID p_instance, RID p_base) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
- while (gi_probe->dynamic.updating_stage == GI_UPDATE_STAGE_LIGHTING) {
- //wait until bake is done if it's baking
- OS::get_singleton()->delay_usec(1);
- }
if (gi_probe->update_element.in_list()) {
gi_probe_update_list.remove(&gi_probe->update_element);
}
@@ -2589,7 +2602,15 @@ void VisualServerScene::_bake_gi_probe(Instance *p_gi_probe) {
}
//send back to main thread to update un little chunks
+ if (probe_bake_mutex) {
+ probe_bake_mutex->lock();
+ }
+
probe_data->dynamic.updating_stage = GI_UPDATE_STAGE_UPLOADING;
+
+ if (probe_bake_mutex) {
+ probe_bake_mutex->unlock();
+ }
}
bool VisualServerScene::_check_gi_probe(Instance *p_gi_probe) {
@@ -2722,11 +2743,11 @@ void VisualServerScene::render_probes() {
case GI_UPDATE_STAGE_CHECK: {
if (_check_gi_probe(instance_probe) || force_lighting) {
- //send to lighting thread
- probe->dynamic.updating_stage = GI_UPDATE_STAGE_LIGHTING;
+//send to lighting thread
#ifndef NO_THREADS
probe_bake_mutex->lock();
+ probe->dynamic.updating_stage = GI_UPDATE_STAGE_LIGHTING;
probe_bake_list.push_back(instance_probe);
probe_bake_mutex->unlock();
probe_bake_sem->post();
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 9af5ffb74d..bc5d266113 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -438,6 +438,7 @@ public:
: update_element(this) {
invalid = true;
base_version = 0;
+ dynamic.updating_stage = GI_UPDATE_STAGE_CHECK;
}
};
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
index d1069a410c..1c3b34d16f 100644
--- a/servers/visual/visual_server_wrap_mt.h
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -100,6 +100,8 @@ public:
FUNC1(textures_keep_original, bool)
+ FUNC2(texture_set_proxy, RID, RID)
+
/* SKY API */
FUNCRID(sky)
diff --git a/servers/visual_server.h b/servers/visual_server.h
index 9df389999a..350097c1b5 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -141,6 +141,8 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
+ virtual void texture_set_proxy(RID p_proxy, RID p_base) = 0;
+
/* SKY API */
virtual RID sky_create() = 0;