summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitattributes2
-rw-r--r--SConstruct24
-rw-r--r--core/string/optimized_translation.cpp5
-rw-r--r--core/typedefs.h4
-rw-r--r--core/variant/variant_internal.h4
-rw-r--r--doc/classes/Area2D.xml40
-rw-r--r--doc/classes/Area3D.xml40
-rw-r--r--doc/classes/Environment.xml2
-rw-r--r--doc/classes/RigidDynamicBody2D.xml20
-rw-r--r--doc/classes/RigidDynamicBody3D.xml20
-rw-r--r--editor/debugger/editor_visual_profiler.cpp4
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp396
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.h60
-rw-r--r--editor/plugins/tiles/tile_map_editor.cpp62
-rw-r--r--editor/plugins/tiles/tile_map_editor.h2
-rw-r--r--modules/fbx/data/fbx_mesh_data.cpp3
-rw-r--r--modules/gdscript/gdscript_analyzer.cpp30
-rw-r--r--modules/gdscript/gdscript_analyzer.h4
-rw-r--r--modules/gdscript/gdscript_compiler.cpp11
-rw-r--r--modules/gdscript/gdscript_vm.cpp4
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd19
-rw-r--r--modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out4
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd32
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd8
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out6
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd19
-rw-r--r--modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out3
-rw-r--r--modules/gltf/gltf_document.cpp89
-rw-r--r--modules/gltf/gltf_document.h2
-rw-r--r--platform/android/detect.py4
-rw-r--r--platform/android/java/app/config.gradle4
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.jarbin54329 -> 59203 bytes
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties5
-rwxr-xr-xplatform/android/java/gradlew53
-rw-r--r--platform/android/java/gradlew.bat47
-rw-r--r--platform/iphone/detect.py5
-rw-r--r--platform/iphone/export/export_plugin.cpp2
-rw-r--r--platform/javascript/detect.py2
-rw-r--r--platform/linuxbsd/detect.py2
-rw-r--r--platform/osx/detect.py2
-rw-r--r--platform/osx/export/export_plugin.cpp2
-rw-r--r--platform/uwp/detect.py2
-rw-r--r--platform/windows/detect.py4
-rw-r--r--platform/windows/display_server_windows.h2
-rw-r--r--scene/2d/area_2d.cpp8
-rw-r--r--scene/2d/physics_body_2d.cpp4
-rw-r--r--scene/3d/area_3d.cpp8
-rw-r--r--scene/3d/physics_body_3d.cpp4
-rw-r--r--scene/3d/skeleton_3d.cpp39
-rw-r--r--scene/3d/skeleton_3d.h1
-rw-r--r--scene/gui/texture_progress_bar.cpp12
-rw-r--r--scene/resources/environment.cpp2
-rw-r--r--scene/resources/tile_set.cpp4
-rw-r--r--servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp3
-rw-r--r--servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp3
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl6
-rw-r--r--thirdparty/README.md10
-rw-r--r--thirdparty/mbedtls/include/mbedtls/bn_mul.h6
-rw-r--r--thirdparty/mbedtls/patches/pr4948-fix-clang12-opt.patch36
61 files changed, 607 insertions, 606 deletions
diff --git a/.gitattributes b/.gitattributes
index 88c00855d8..45ea6c25e8 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,6 +5,8 @@ thirdparty/* linguist-vendored
# Normalize EOL for all files that Git considers text files
* text=auto eol=lf
+# Except for bat files, which are Windows only files
+*.bat eol=crlf
# The above only works properly for Git 2.10+, so for older versions
# we need to manually list the binary files we don't want modified.
diff --git a/SConstruct b/SConstruct
index b539dc59b7..83c89be5f9 100644
--- a/SConstruct
+++ b/SConstruct
@@ -1,7 +1,7 @@
#!/usr/bin/env python
EnsureSConsVersion(3, 0, 0)
-EnsurePythonVersion(3, 5)
+EnsurePythonVersion(3, 6)
# System
import atexit
@@ -308,21 +308,19 @@ env_base.Prepend(CPPPATH=["#"])
env_base.platform_exporters = platform_exporters
env_base.platform_apis = platform_apis
-if env_base["use_precise_math_checks"]:
- env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"])
+# Build type defines - more platform-specific ones can be in detect.py.
+if env_base["target"] == "release_debug" or env_base["target"] == "debug":
+ # DEBUG_ENABLED enables debugging *features* and debug-only code, which is intended
+ # to give *users* extra debugging information for their game development.
+ env_base.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env_base["target"] == "debug":
- env_base.Append(CPPDEFINES=["DEBUG_MEMORY_ALLOC", "DISABLE_FORCED_INLINE"])
-
- # The two options below speed up incremental builds, but reduce the certainty that all files
- # will properly be rebuilt. As such, we only enable them for debug (dev) builds, not release.
+ # DEV_ENABLED enables *engine developer* code which should only be compiled for those
+ # working on the engine itself.
+ env_base.Append(CPPDEFINES=["DEV_ENABLED"])
- # To decide whether to rebuild a file, use the MD5 sum only if the timestamp has changed.
- # https://scons.org/doc/production/HTML/scons-user/ch06.html#idm139837621851792
- env_base.Decider("MD5-timestamp")
- # Use cached implicit dependencies by default. Can be overridden by specifying `--implicit-deps-changed` in the command line.
- # https://scons.org/doc/production/HTML/scons-user/ch06s04.html
- env_base.SetOption("implicit_cache", 1)
+if env_base["use_precise_math_checks"]:
+ env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"])
if env_base["no_editor_splash"]:
env_base.Append(CPPDEFINES=["NO_EDITOR_SPLASH"])
diff --git a/core/string/optimized_translation.cpp b/core/string/optimized_translation.cpp
index 839b7a9c01..f8be564740 100644
--- a/core/string/optimized_translation.cpp
+++ b/core/string/optimized_translation.cpp
@@ -64,7 +64,6 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) {
int idx = 0;
int total_compression_size = 0;
- int total_string_size = 0;
for (const StringName &E : keys) {
//hash string
@@ -102,7 +101,6 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) {
compressed.write[idx] = ps;
total_compression_size += ps.compressed.size();
- total_string_size += src_s.size();
idx++;
}
@@ -147,15 +145,12 @@ void OptimizedTranslation::generate(const Ref<Translation> &p_from) {
uint32_t *btw = (uint32_t *)&btwb[0];
int btindex = 0;
- int collisions = 0;
for (int i = 0; i < size; i++) {
const Map<uint32_t, int> &t = table[i];
if (t.size() == 0) {
htw[i] = 0xFFFFFFFF; //nothing
continue;
- } else if (t.size() > 1) {
- collisions += t.size() - 1;
}
htw[i] = btindex;
diff --git a/core/typedefs.h b/core/typedefs.h
index dde254af23..8ca3d13e63 100644
--- a/core/typedefs.h
+++ b/core/typedefs.h
@@ -62,9 +62,9 @@
#endif
#endif
-// Should always inline, except in debug builds because it makes debugging harder.
+// Should always inline, except in dev builds because it makes debugging harder.
#ifndef _FORCE_INLINE_
-#ifdef DISABLE_FORCED_INLINE
+#ifdef DEV_ENABLED
#define _FORCE_INLINE_ inline
#else
#define _FORCE_INLINE_ _ALWAYS_INLINE_
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index 40c8a1bfde..37383ff2ec 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -1301,12 +1301,12 @@ struct VariantZeroAssigner<Signal> {
template <>
struct VariantZeroAssigner<Dictionary> {
- static _FORCE_INLINE_ void zero(Variant *v) {}
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_dictionary(v) = Dictionary(); }
};
template <>
struct VariantZeroAssigner<Array> {
- static _FORCE_INLINE_ void zero(Variant *v) {}
+ static _FORCE_INLINE_ void zero(Variant *v) { *VariantInternal::get_array(v) = Array(); }
};
template <>
diff --git a/doc/classes/Area2D.xml b/doc/classes/Area2D.xml
index 25f67f0571..ddfc3b1869 100644
--- a/doc/classes/Area2D.xml
+++ b/doc/classes/Area2D.xml
@@ -101,27 +101,27 @@
<signal name="area_shape_entered">
<argument index="0" name="area_rid" type="RID" />
<argument index="1" name="area" type="Area2D" />
- <argument index="2" name="area_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="area_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of another Area2D's [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code].
- [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]area_rid[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
[code]area[/code] the other Area2D.
- [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
+ [code]area_shape_index[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]area.shape_owner_get_owner(area_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="area_shape_exited">
<argument index="0" name="area_rid" type="RID" />
<argument index="1" name="area" type="Area2D" />
- <argument index="2" name="area_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="area_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of another Area2D's [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code].
- [code]area_id[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]area_rid[/code] the [RID] of the other Area2D's [CollisionObject2D] used by the [PhysicsServer2D].
[code]area[/code] the other Area2D.
- [code]area_shape[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
+ [code]area_shape_index[/code] the index of the [Shape2D] of the other Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]area.shape_owner_get_owner(area_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="body_entered">
@@ -141,27 +141,27 @@
<signal name="body_shape_entered">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node2D" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s enters one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
- [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body_rid[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
[code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap].
- [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
+ [code]body_shape_index[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node2D" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of a [PhysicsBody2D] or [TileMap]'s [Shape2D]s exits one of this Area2D's [Shape2D]s. Requires [member monitoring] to be set to [code]true[/code]. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
- [code]body_id[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body_rid[/code] the [RID] of the [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
[code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody2D] or [TileMap].
- [code]body_shape[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D].
+ [code]body_shape_index[/code] the index of the [Shape2D] of the [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this Area2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
</signals>
diff --git a/doc/classes/Area3D.xml b/doc/classes/Area3D.xml
index e91cfd79a1..896bfcd14e 100644
--- a/doc/classes/Area3D.xml
+++ b/doc/classes/Area3D.xml
@@ -120,27 +120,27 @@
<signal name="area_shape_entered">
<argument index="0" name="area_rid" type="RID" />
<argument index="1" name="area" type="Area3D" />
- <argument index="2" name="area_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="area_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
- [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]area_rid[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
[code]area[/code] the other Area3D.
- [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
+ [code]area_shape_index[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]area.shape_owner_get_owner(area_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="area_shape_exited">
<argument index="0" name="area_rid" type="RID" />
<argument index="1" name="area" type="Area3D" />
- <argument index="2" name="area_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="area_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of another Area3D's [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code].
- [code]area_id[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]area_rid[/code] the [RID] of the other Area3D's [CollisionObject3D] used by the [PhysicsServer3D].
[code]area[/code] the other Area3D.
- [code]area_shape[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
+ [code]area_shape_index[/code] the index of the [Shape3D] of the other Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]area.shape_owner_get_owner(area_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="body_entered">
@@ -160,27 +160,27 @@
<signal name="body_shape_entered">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node3D" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
- [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body_rid[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
[code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap].
- [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
+ [code]body_shape_index[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node3D" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of a [PhysicsBody3D] or [GridMap]'s [Shape3D]s enters one of this Area3D's [Shape3D]s. Requires [member monitoring] to be set to [code]true[/code]. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
- [code]body_id[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body_rid[/code] the [RID] of the [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
[code]body[/code] the [Node], if it exists in the tree, of the [PhysicsBody3D] or [GridMap].
- [code]body_shape[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D].
+ [code]body_shape_index[/code] the index of the [Shape3D] of the [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this Area3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
</signals>
diff --git a/doc/classes/Environment.xml b/doc/classes/Environment.xml
index 98b0de6ce1..80298a0319 100644
--- a/doc/classes/Environment.xml
+++ b/doc/classes/Environment.xml
@@ -101,8 +101,10 @@
If [code]true[/code], fog effects are enabled.
</member>
<member name="fog_height" type="float" setter="set_fog_height" getter="get_fog_height" default="0.0">
+ The height at which the height fog effect begins.
</member>
<member name="fog_height_density" type="float" setter="set_fog_height_density" getter="get_fog_height_density" default="0.0">
+ The density used to increase fog as height decreases. To make fog increase as height increases, use a negative value.
</member>
<member name="fog_light_color" type="Color" setter="set_fog_light_color" getter="get_fog_light_color" default="Color(0.5, 0.6, 0.7, 1)">
</member>
diff --git a/doc/classes/RigidDynamicBody2D.xml b/doc/classes/RigidDynamicBody2D.xml
index 9baed392eb..f503884192 100644
--- a/doc/classes/RigidDynamicBody2D.xml
+++ b/doc/classes/RigidDynamicBody2D.xml
@@ -174,27 +174,27 @@
<signal name="body_shape_entered">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of this RigidDynamicBody2D's [Shape2D]s collides with another [PhysicsBody2D] or [TileMap]'s [Shape2D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
- [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body_rid[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
[code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
- [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this RigidDynamicBody2D used by the [PhysicsServer2D].
+ [code]body_shape_index[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this RigidDynamicBody2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when the collision between one of this RigidDynamicBody2D's [Shape2D]s and another [PhysicsBody2D] or [TileMap]'s [Shape2D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [TileMap]s are detected if the [TileSet] has Collision [Shape2D]s.
- [code]body_id[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
+ [code]body_rid[/code] the [RID] of the other [PhysicsBody2D] or [TileSet]'s [CollisionObject2D] used by the [PhysicsServer2D].
[code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody2D] or [TileMap].
- [code]body_shape[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D].
- [code]local_shape[/code] the index of the [Shape2D] of this RigidDynamicBody2D used by the [PhysicsServer2D].
+ [code]body_shape_index[/code] the index of the [Shape2D] of the other [PhysicsBody2D] or [TileMap] used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape2D] of this RigidDynamicBody2D used by the [PhysicsServer2D]. Get the [CollisionShape2D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
</description>
</signal>
<signal name="sleeping_state_changed">
diff --git a/doc/classes/RigidDynamicBody3D.xml b/doc/classes/RigidDynamicBody3D.xml
index 7d1c7fecfa..6c8d190704 100644
--- a/doc/classes/RigidDynamicBody3D.xml
+++ b/doc/classes/RigidDynamicBody3D.xml
@@ -177,28 +177,28 @@
<signal name="body_shape_entered">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when one of this RigidDynamicBody3D's [Shape3D]s collides with another [PhysicsBody3D] or [GridMap]'s [Shape3D]s. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
- [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
+ [code]body_rid[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D].
[code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
- [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this RigidDynamicBody3D used by the [PhysicsServer3D].
+ [code]body_shape_index[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this RigidDynamicBody3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
[b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices.
</description>
</signal>
<signal name="body_shape_exited">
<argument index="0" name="body_rid" type="RID" />
<argument index="1" name="body" type="Node" />
- <argument index="2" name="body_shape" type="int" />
- <argument index="3" name="local_shape" type="int" />
+ <argument index="2" name="body_shape_index" type="int" />
+ <argument index="3" name="local_shape_index" type="int" />
<description>
Emitted when the collision between one of this RigidDynamicBody3D's [Shape3D]s and another [PhysicsBody3D] or [GridMap]'s [Shape3D]s ends. Requires [member contact_monitor] to be set to [code]true[/code] and [member contacts_reported] to be set high enough to detect all the collisions. [GridMap]s are detected if the [MeshLibrary] has Collision [Shape3D]s.
- [code]body_id[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. [GridMap]s are detected if the Meshes have [Shape3D]s.
+ [code]body_rid[/code] the [RID] of the other [PhysicsBody3D] or [MeshLibrary]'s [CollisionObject3D] used by the [PhysicsServer3D]. [GridMap]s are detected if the Meshes have [Shape3D]s.
[code]body[/code] the [Node], if it exists in the tree, of the other [PhysicsBody3D] or [GridMap].
- [code]body_shape[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D].
- [code]local_shape[/code] the index of the [Shape3D] of this RigidDynamicBody3D used by the [PhysicsServer3D].
+ [code]body_shape_index[/code] the index of the [Shape3D] of the other [PhysicsBody3D] or [GridMap] used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]body.shape_owner_get_owner(body_shape_index)[/code].
+ [code]local_shape_index[/code] the index of the [Shape3D] of this RigidDynamicBody3D used by the [PhysicsServer3D]. Get the [CollisionShape3D] node with [code]self.shape_owner_get_owner(local_shape_index)[/code].
[b]Note:[/b] Bullet physics cannot identify the shape index when using a [ConcavePolygonShape3D]. Don't use multiple [CollisionShape3D]s when using a [ConcavePolygonShape3D] with Bullet physics if you need shape indices.
</description>
</signal>
diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp
index f17ad0d36c..f25f18b7e4 100644
--- a/editor/debugger/editor_visual_profiler.cpp
+++ b/editor/debugger/editor_visual_profiler.cpp
@@ -370,8 +370,8 @@ void EditorVisualProfiler::_update_frame(bool p_focus_selected) {
float total_gpu = E->get_metadata(2);
total_cpu += cpu_time;
total_gpu += gpu_time;
- E->set_metadata(1, cpu_time);
- E->set_metadata(2, gpu_time);
+ E->set_metadata(1, total_cpu);
+ E->set_metadata(2, total_gpu);
}
category->set_icon(0, track_icon);
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index f9c46d35c4..708eaf2c46 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -49,276 +49,128 @@ void BoneTransformEditor::create_editors() {
section = memnew(EditorInspectorSection);
section->setup("trf_properties", label, this, section_color, true);
+ section->unfold();
add_child(section);
- enabled_checkbox = memnew(CheckBox(TTR("Pose Enabled")));
- enabled_checkbox->set_flat(true);
- enabled_checkbox->set_visible(toggle_enabled);
+ enabled_checkbox = memnew(EditorPropertyCheck());
+ enabled_checkbox->set_label("Pose Enabled");
+ enabled_checkbox->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
section->get_vbox()->add_child(enabled_checkbox);
- key_button = memnew(Button);
- key_button->set_text(TTR("Key Transform"));
- key_button->set_visible(keyable);
- key_button->set_icon(get_theme_icon(SNAME("Key"), SNAME("EditorIcons")));
- key_button->set_flat(true);
- section->get_vbox()->add_child(key_button);
-
- // Translation property.
- translation_property = memnew(EditorPropertyVector3());
- translation_property->setup(-10000, 10000, 0.001f, true);
- translation_property->set_label("Translation");
- translation_property->set_use_folding(true);
- translation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3));
- section->get_vbox()->add_child(translation_property);
+ // Position property.
+ position_property = memnew(EditorPropertyVector3());
+ position_property->setup(-10000, 10000, 0.001f, true);
+ position_property->set_label("Position");
+ position_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
+ section->get_vbox()->add_child(position_property);
// Rotation property.
- rotation_property = memnew(EditorPropertyVector3());
+ rotation_property = memnew(EditorPropertyQuaternion());
rotation_property->setup(-10000, 10000, 0.001f, true);
- rotation_property->set_label("Rotation Degrees");
- rotation_property->set_use_folding(true);
- rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3));
+ rotation_property->set_label("Rotation");
+ rotation_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
section->get_vbox()->add_child(rotation_property);
// Scale property.
scale_property = memnew(EditorPropertyVector3());
scale_property->setup(-10000, 10000, 0.001f, true);
scale_property->set_label("Scale");
- scale_property->set_use_folding(true);
- scale_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_vector3));
+ scale_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed));
section->get_vbox()->add_child(scale_property);
// Transform/Matrix section.
- transform_section = memnew(EditorInspectorSection);
- transform_section->setup("trf_properties_transform", "Matrix", this, section_color, true);
- section->get_vbox()->add_child(transform_section);
+ rest_section = memnew(EditorInspectorSection);
+ rest_section->setup("trf_properties_transform", "Rest", this, section_color, true);
+ section->get_vbox()->add_child(rest_section);
// Transform/Matrix property.
- transform_property = memnew(EditorPropertyTransform3D());
- transform_property->setup(-10000, 10000, 0.001f, true);
- transform_property->set_label("Transform");
- transform_property->set_use_folding(true);
- transform_property->connect("property_changed", callable_mp(this, &BoneTransformEditor::_value_changed_transform));
- transform_section->get_vbox()->add_child(transform_property);
+ rest_matrix = memnew(EditorPropertyTransform3D());
+ rest_matrix->setup(-10000, 10000, 0.001f, true);
+ rest_matrix->set_label("Transform");
+ rest_section->get_vbox()->add_child(rest_matrix);
}
void BoneTransformEditor::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
create_editors();
- key_button->connect("pressed", callable_mp(this, &BoneTransformEditor::_key_button_pressed));
- enabled_checkbox->connect("pressed", callable_mp(this, &BoneTransformEditor::_checkbox_pressed));
- [[fallthrough]];
- }
- case NOTIFICATION_SORT_CHILDREN: {
- const Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree"));
- int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree"));
-
- Point2 buffer;
- buffer.x += get_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
- buffer.y += font->get_height(font_size);
- buffer.y += get_theme_constant(SNAME("vseparation"), SNAME("Tree"));
-
- const float vector_height = translation_property->get_size().y;
- const float transform_height = transform_property->get_size().y;
- const float button_height = key_button->get_size().y;
-
- const float width = get_size().x - get_theme_constant(SNAME("inspector_margin"), SNAME("Editor"));
- Vector<Rect2> input_rects;
- if (keyable && section->get_vbox()->is_visible()) {
- input_rects.push_back(Rect2(key_button->get_position() + buffer, Size2(width, button_height)));
- } else {
- input_rects.push_back(Rect2(0, 0, 0, 0));
- }
-
- if (section->get_vbox()->is_visible()) {
- input_rects.push_back(Rect2(translation_property->get_position() + buffer, Size2(width, vector_height)));
- input_rects.push_back(Rect2(rotation_property->get_position() + buffer, Size2(width, vector_height)));
- input_rects.push_back(Rect2(scale_property->get_position() + buffer, Size2(width, vector_height)));
- input_rects.push_back(Rect2(transform_property->get_position() + buffer, Size2(width, transform_height)));
- } else {
- const int32_t start = input_rects.size();
- const int32_t empty_input_rect_elements = 4;
- const int32_t end = start + empty_input_rect_elements;
- for (int i = start; i < end; ++i) {
- input_rects.push_back(Rect2(0, 0, 0, 0));
- }
- }
-
- for (int32_t i = 0; i < input_rects.size(); i++) {
- background_rects[i] = input_rects[i];
- }
-
- update();
- break;
- }
- case NOTIFICATION_DRAW: {
- const Color dark_color = get_theme_color(SNAME("dark_color_2"), SNAME("Editor"));
-
- for (int i = 0; i < 5; ++i) {
- draw_rect(background_rects[i], dark_color);
- }
-
break;
}
}
}
-void BoneTransformEditor::_value_changed(const double p_value) {
- if (updating) {
- return;
- }
-
- Transform3D tform = compute_transform_from_vector3s();
- _change_transform(tform);
-}
-
-void BoneTransformEditor::_value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean) {
- if (updating) {
- return;
- }
- Transform3D tform = compute_transform_from_vector3s();
- _change_transform(tform);
-}
-
-Transform3D BoneTransformEditor::compute_transform_from_vector3s() const {
- // Convert rotation from degrees to radians.
- Vector3 prop_rotation = rotation_property->get_vector();
- prop_rotation.x = Math::deg2rad(prop_rotation.x);
- prop_rotation.y = Math::deg2rad(prop_rotation.y);
- prop_rotation.z = Math::deg2rad(prop_rotation.z);
-
- return Transform3D(
- Basis(prop_rotation, scale_property->get_vector()),
- translation_property->get_vector());
-}
-
-void BoneTransformEditor::_value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean) {
+void BoneTransformEditor::_value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
if (updating) {
return;
}
- _change_transform(p_transform);
-}
-
-void BoneTransformEditor::_change_transform(Transform3D p_new_transform) {
- if (property.get_slicec('/', 0) == "bones") {
+ if (skeleton) {
undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
- undo_redo->add_undo_property(skeleton, property, skeleton->get(property));
- undo_redo->add_do_property(skeleton, property, p_new_transform);
+ undo_redo->add_undo_property(skeleton, p_property, skeleton->get(p_property));
+ undo_redo->add_do_property(skeleton, p_property, p_value);
undo_redo->commit_action();
}
}
-void BoneTransformEditor::update_enabled_checkbox() {
- if (enabled_checkbox) {
- const String path = "bones/" + property.get_slicec('/', 1) + "/enabled";
- const bool is_enabled = skeleton->get(path);
- enabled_checkbox->set_pressed(is_enabled);
- }
-}
-
-void BoneTransformEditor::_update_properties() {
- if (updating) {
- return;
- }
-
- if (!skeleton) {
- return;
- }
-
- updating = true;
-
- Transform3D tform = skeleton->get(property);
- _update_transform_properties(tform);
-}
-
-void BoneTransformEditor::_update_transform_properties(Transform3D tform) {
- Basis rotation_basis = tform.get_basis();
- Vector3 rotation_radians = rotation_basis.get_rotation_euler();
- Vector3 rotation_degrees = Vector3(Math::rad2deg(rotation_radians.x), Math::rad2deg(rotation_radians.y), Math::rad2deg(rotation_radians.z));
- Vector3 translation = tform.get_origin();
- Vector3 scale = tform.basis.get_scale();
-
- translation_property->update_using_vector(translation);
- rotation_property->update_using_vector(rotation_degrees);
- scale_property->update_using_vector(scale);
- transform_property->update_using_transform(tform);
-
- update_enabled_checkbox();
- updating = false;
-}
-
BoneTransformEditor::BoneTransformEditor(Skeleton3D *p_skeleton) :
skeleton(p_skeleton) {
undo_redo = EditorNode::get_undo_redo();
}
void BoneTransformEditor::set_target(const String &p_prop) {
- property = p_prop;
-}
+ enabled_checkbox->set_object_and_property(skeleton, p_prop + "enabled");
+ enabled_checkbox->update_property();
-void BoneTransformEditor::set_keyable(const bool p_keyable) {
- keyable = p_keyable;
-}
+ position_property->set_object_and_property(skeleton, p_prop + "position");
+ position_property->update_property();
-void BoneTransformEditor::_update_key_button(const bool p_keyable) {
- bool is_keyable = keyable && p_keyable;
- if (key_button) {
- key_button->set_visible(is_keyable);
- }
-}
+ rotation_property->set_object_and_property(skeleton, p_prop + "rotation");
+ rotation_property->update_property();
-void BoneTransformEditor::set_properties_read_only(const bool p_readonly) {
- enabled_checkbox->set_disabled(p_readonly);
- enabled_checkbox->update();
-}
-
-void BoneTransformEditor::set_transform_read_only(const bool p_readonly) {
- translation_property->set_read_only(p_readonly);
- rotation_property->set_read_only(p_readonly);
- scale_property->set_read_only(p_readonly);
- transform_property->set_read_only(p_readonly);
- translation_property->update();
- rotation_property->update();
- scale_property->update();
- transform_property->update();
- _update_key_button(!p_readonly);
-}
-
-void BoneTransformEditor::set_toggle_enabled(const bool p_enabled) {
- toggle_enabled = p_enabled;
- if (enabled_checkbox) {
- enabled_checkbox->set_visible(p_enabled);
- }
-}
-
-void BoneTransformEditor::_key_button_pressed() {
- if (!skeleton) {
- return;
- }
-
- const BoneId bone_id = property.get_slicec('/', 1).to_int();
- const String name = skeleton->get_bone_name(bone_id);
-
- if (name.is_empty()) {
- return;
- }
+ scale_property->set_object_and_property(skeleton, p_prop + "scale");
+ scale_property->update_property();
- Transform3D tform = compute_transform_from_vector3s();
- AnimationPlayerEditor::get_singleton()->get_track_editor()->insert_transform_key(skeleton, name, tform);
+ rest_matrix->set_object_and_property(skeleton, p_prop + "rest");
+ rest_matrix->update_property();
}
-void BoneTransformEditor::_checkbox_pressed() {
+void BoneTransformEditor::_update_properties() {
if (!skeleton) {
return;
}
-
- const BoneId bone_id = property.get_slicec('/', 1).to_int();
- if (enabled_checkbox) {
- undo_redo->create_action(TTR("Set Pose Enabled"));
- bool enabled = skeleton->is_bone_enabled(bone_id);
- undo_redo->add_do_method(skeleton, "set_bone_enabled", bone_id, !enabled);
- undo_redo->add_undo_method(skeleton, "set_bone_enabled", bone_id, enabled);
- undo_redo->commit_action();
+ int selected = Skeleton3DEditor::get_singleton()->get_selected_bone();
+ List<PropertyInfo> props;
+ skeleton->get_property_list(&props);
+ for (const PropertyInfo &E : props) {
+ PackedStringArray spr = E.name.split("/");
+ if (spr.size() == 3 && spr[0] == "bones") {
+ if (spr[1].to_int() == selected) {
+ if (spr[2] == "enabled") {
+ enabled_checkbox->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
+ enabled_checkbox->update_property();
+ enabled_checkbox->update();
+ }
+ if (spr[2] == "position") {
+ position_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
+ position_property->update_property();
+ position_property->update();
+ }
+ if (spr[2] == "rotation") {
+ rotation_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
+ rotation_property->update_property();
+ rotation_property->update();
+ }
+ if (spr[2] == "scale") {
+ scale_property->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
+ scale_property->update_property();
+ scale_property->update();
+ }
+ if (spr[2] == "rest") {
+ rest_matrix->set_read_only(E.usage & PROPERTY_USAGE_READ_ONLY);
+ rest_matrix->update_property();
+ rest_matrix->update();
+ }
+ }
+ }
}
}
@@ -334,24 +186,6 @@ void Skeleton3DEditor::set_rest_options_enabled(const bool p_rest_options_enable
rest_options->get_popup()->set_item_disabled(REST_OPTION_POSE_TO_REST, !p_rest_options_enabled);
};
-void Skeleton3DEditor::_update_show_rest_only() {
- _update_pose_enabled(-1);
-}
-
-void Skeleton3DEditor::_update_pose_enabled(int p_bone) {
- if (!skeleton) {
- return;
- }
- if (pose_editor) {
- pose_editor->set_properties_read_only(skeleton->is_show_rest_only());
-
- if (selected_bone > 0) {
- pose_editor->set_transform_read_only(skeleton->is_show_rest_only() || !(skeleton->is_bone_enabled(selected_bone)));
- }
- }
- _update_gizmo_visible();
-}
-
void Skeleton3DEditor::_on_click_skeleton_option(int p_skeleton_option) {
if (!skeleton) {
return;
@@ -398,8 +232,13 @@ void Skeleton3DEditor::init_pose() {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
for (int i = 0; i < bone_len; i++) {
- ur->add_do_method(skeleton, "set_bone_pose", i, Transform3D());
- ur->add_undo_method(skeleton, "set_bone_pose", i, skeleton->get_bone_pose(i));
+ Transform3D rest = skeleton->get_bone_rest(i);
+ ur->add_do_method(skeleton, "set_bone_pose_position", i, rest.origin);
+ ur->add_do_method(skeleton, "set_bone_pose_rotation", i, rest.basis.get_rotation_quaternion());
+ ur->add_do_method(skeleton, "set_bone_pose_scale", i, rest.basis.get_scale());
+ ur->add_undo_method(skeleton, "set_bone_pose_position", i, skeleton->get_bone_pose_position(i));
+ ur->add_undo_method(skeleton, "set_bone_pose_rotation", i, skeleton->get_bone_pose_rotation(i));
+ ur->add_undo_method(skeleton, "set_bone_pose_scale", i, skeleton->get_bone_pose_scale(i));
}
ur->commit_action();
}
@@ -439,13 +278,9 @@ void Skeleton3DEditor::pose_to_rest() {
// Todo: Do method with multiple bone selection.
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- ur->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);
-
- ur->add_do_method(skeleton, "set_bone_pose", selected_bone, Transform3D());
- ur->add_undo_method(skeleton, "set_bone_pose", selected_bone, skeleton->get_bone_pose(selected_bone));
- ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone) * skeleton->get_bone_pose(selected_bone));
+ ur->create_action(TTR("Set Bone Rest"), UndoRedo::MERGE_ENDS);
+ ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_pose(selected_bone));
ur->add_undo_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone));
-
ur->commit_action();
}
@@ -630,18 +465,14 @@ void Skeleton3DEditor::_joint_tree_selection_changed() {
const int b_idx = path.get_slicec('/', 1).to_int();
const String bone_path = "bones/" + itos(b_idx) + "/";
- pose_editor->set_target(bone_path + "pose");
- rest_editor->set_target(bone_path + "rest");
-
- pose_editor->set_visible(true);
- rest_editor->set_visible(true);
-
+ pose_editor->set_target(bone_path);
selected_bone = b_idx;
}
}
+ pose_editor->set_visible(selected);
set_rest_options_enabled(selected);
_update_properties();
- _update_pose_enabled();
+ _update_gizmo_visible();
}
// May be not used with single select mode.
@@ -649,13 +480,10 @@ void Skeleton3DEditor::_joint_tree_rmb_select(const Vector2 &p_pos) {
}
void Skeleton3DEditor::_update_properties() {
- if (rest_editor) {
- rest_editor->_update_properties();
- }
if (pose_editor) {
pose_editor->_update_properties();
}
- _update_gizmo_transform();
+ Node3DEditor::get_singleton()->update_transform_gizmo();
}
void Skeleton3DEditor::update_joint_tree() {
@@ -782,17 +610,9 @@ void Skeleton3DEditor::create_editors() {
s_con->add_child(joint_tree);
pose_editor = memnew(BoneTransformEditor(skeleton));
- pose_editor->set_label(TTR("Bone Pose"));
- pose_editor->set_toggle_enabled(true);
- pose_editor->set_keyable(te->has_keying());
+ pose_editor->set_label(TTR("Bone Transform"));
pose_editor->set_visible(false);
add_child(pose_editor);
-
- rest_editor = memnew(BoneTransformEditor(skeleton));
- rest_editor->set_label(TTR("Bone Rest"));
- rest_editor->set_visible(false);
- add_child(rest_editor);
- rest_editor->set_transform_read_only(true);
}
void Skeleton3DEditor::_notification(int p_what) {
@@ -811,8 +631,8 @@ void Skeleton3DEditor::_notification(int p_what) {
#ifdef TOOLS_ENABLED
skeleton->connect("pose_updated", callable_mp(this, &Skeleton3DEditor::_draw_gizmo));
skeleton->connect("pose_updated", callable_mp(this, &Skeleton3DEditor::_update_properties));
- skeleton->connect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_update_pose_enabled));
- skeleton->connect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_show_rest_only));
+ skeleton->connect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed));
+ skeleton->connect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible));
#endif
break;
}
@@ -833,8 +653,6 @@ void Skeleton3DEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_node_removed"), &Skeleton3DEditor::_node_removed);
ClassDB::bind_method(D_METHOD("_joint_tree_selection_changed"), &Skeleton3DEditor::_joint_tree_selection_changed);
ClassDB::bind_method(D_METHOD("_joint_tree_rmb_select"), &Skeleton3DEditor::_joint_tree_rmb_select);
- ClassDB::bind_method(D_METHOD("_update_show_rest_only"), &Skeleton3DEditor::_update_show_rest_only);
- ClassDB::bind_method(D_METHOD("_update_pose_enabled"), &Skeleton3DEditor::_update_pose_enabled);
ClassDB::bind_method(D_METHOD("_update_properties"), &Skeleton3DEditor::_update_properties);
ClassDB::bind_method(D_METHOD("_on_click_skeleton_option"), &Skeleton3DEditor::_on_click_skeleton_option);
ClassDB::bind_method(D_METHOD("_on_click_rest_option"), &Skeleton3DEditor::_on_click_rest_option);
@@ -905,7 +723,9 @@ void Skeleton3DEditor::update_bone_original() {
if (skeleton->get_bone_count() == 0 || selected_bone == -1) {
return;
}
- bone_original = skeleton->get_bone_pose(selected_bone);
+ bone_original_position = skeleton->get_bone_pose_position(selected_bone);
+ bone_original_rotation = skeleton->get_bone_pose_rotation(selected_bone);
+ bone_original_scale = skeleton->get_bone_pose_scale(selected_bone);
}
void Skeleton3DEditor::_hide_handles() {
@@ -1033,8 +853,8 @@ void Skeleton3DEditor::select_bone(int p_idx) {
Skeleton3DEditor::~Skeleton3DEditor() {
if (skeleton) {
#ifdef TOOLS_ENABLED
- skeleton->disconnect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_show_rest_only));
- skeleton->disconnect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_update_pose_enabled));
+ skeleton->disconnect("show_rest_only_changed", callable_mp(this, &Skeleton3DEditor::_update_gizmo_visible));
+ skeleton->disconnect("bone_enabled_changed", callable_mp(this, &Skeleton3DEditor::_bone_enabled_changed));
skeleton->disconnect("pose_updated", callable_mp(this, &Skeleton3DEditor::_draw_gizmo));
skeleton->disconnect("pose_updated", callable_mp(this, &Skeleton3DEditor::_update_properties));
skeleton->set_transform_gizmo_visible(true);
@@ -1115,9 +935,9 @@ bool Skeleton3DEditorPlugin::handles(Object *p_object) const {
return p_object->is_class("Skeleton3D");
}
-void Skeleton3DEditor::_update_gizmo_transform() {
- Node3DEditor::get_singleton()->update_transform_gizmo();
-};
+void Skeleton3DEditor::_bone_enabled_changed(const int p_bone_id) {
+ _update_gizmo_visible();
+}
void Skeleton3DEditor::_update_gizmo_visible() {
_subgizmo_selection_change();
@@ -1272,7 +1092,7 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi
// Apply transform.
skeleton->set_bone_pose_position(p_id, t.origin);
- skeleton->set_bone_pose_rotation(p_id, t.basis.operator Quaternion());
+ skeleton->set_bone_pose_rotation(p_id, t.basis.get_rotation_quaternion());
skeleton->set_bone_pose_scale(p_id, t.basis.get_scale());
}
@@ -1281,12 +1101,30 @@ void Skeleton3DGizmoPlugin::commit_subgizmos(const EditorNode3DGizmo *p_gizmo, c
ERR_FAIL_COND(!skeleton);
Skeleton3DEditor *se = Skeleton3DEditor::get_singleton();
+ Node3DEditor *ne = Node3DEditor::get_singleton();
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
- for (int i = 0; i < p_ids.size(); i++) {
- ur->create_action(TTR("Set Bone Transform"));
- ur->add_do_method(skeleton, "set_bone_pose", p_ids[i], skeleton->get_bone_pose(p_ids[i]));
- ur->add_undo_method(skeleton, "set_bone_pose", p_ids[i], se->get_bone_original());
+ ur->create_action(TTR("Set Bone Transform"));
+ if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE) {
+ for (int i = 0; i < p_ids.size(); i++) {
+ ur->add_do_method(skeleton, "set_bone_pose_position", p_ids[i], skeleton->get_bone_pose_position(p_ids[i]));
+ ur->add_undo_method(skeleton, "set_bone_pose_position", p_ids[i], se->get_bone_original_position());
+ }
+ }
+ if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || ne->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE) {
+ for (int i = 0; i < p_ids.size(); i++) {
+ ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i]));
+ ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation());
+ }
+ }
+ if (ne->get_tool_mode() == Node3DEditor::TOOL_MODE_SCALE) {
+ for (int i = 0; i < p_ids.size(); i++) {
+ // If the axis is swapped by scaling, the rotation can be changed.
+ ur->add_do_method(skeleton, "set_bone_pose_rotation", p_ids[i], skeleton->get_bone_pose_rotation(p_ids[i]));
+ ur->add_undo_method(skeleton, "set_bone_pose_rotation", p_ids[i], se->get_bone_original_rotation());
+ ur->add_do_method(skeleton, "set_bone_pose_scale", p_ids[i], skeleton->get_bone_pose_scale(p_ids[i]));
+ ur->add_undo_method(skeleton, "set_bone_pose_scale", p_ids[i], se->get_bone_original_scale());
+ }
}
ur->commit_action();
}
diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h
index 2c21aab739..3b4dd362fb 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.h
+++ b/editor/plugins/skeleton_3d_editor_plugin.h
@@ -52,21 +52,22 @@ class BoneTransformEditor : public VBoxContainer {
EditorInspectorSection *section = nullptr;
- EditorPropertyVector3 *translation_property = nullptr;
- EditorPropertyVector3 *rotation_property = nullptr;
+ EditorPropertyCheck *enabled_checkbox = nullptr;
+ EditorPropertyVector3 *position_property = nullptr;
+ EditorPropertyQuaternion *rotation_property = nullptr;
EditorPropertyVector3 *scale_property = nullptr;
- EditorInspectorSection *transform_section = nullptr;
- EditorPropertyTransform3D *transform_property = nullptr;
+
+ EditorInspectorSection *rest_section = nullptr;
+ EditorPropertyTransform3D *rest_matrix = nullptr;
Rect2 background_rects[5];
Skeleton3D *skeleton;
- String property;
+ // String property;
UndoRedo *undo_redo;
- Button *key_button = nullptr;
- CheckBox *enabled_checkbox = nullptr;
+ // Button *key_button = nullptr;
bool keyable = false;
bool toggle_enabled = false;
@@ -76,20 +77,7 @@ class BoneTransformEditor : public VBoxContainer {
void create_editors();
- // Called when one of the EditorSpinSliders are changed.
- void _value_changed(const double p_value);
- // Called when the one of the EditorPropertyVector3 are updated.
- void _value_changed_vector3(const String p_property_name, const Vector3 p_vector, const StringName p_edited_property_name, const bool p_boolean);
- // Called when the transform_property is updated.
- void _value_changed_transform(const String p_property_name, const Transform3D p_transform, const StringName p_edited_property_name, const bool p_boolean);
- // Changes the transform to the given transform and updates the UI accordingly.
- void _change_transform(Transform3D p_new_transform);
- // Update it is truely keyable then.
- void _update_key_button(const bool p_keyable);
- // Creates a Transform using the EditorPropertyVector3 properties.
- Transform3D compute_transform_from_vector3s() const;
-
- void update_enabled_checkbox();
+ void _value_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing);
protected:
void _notification(int p_what);
@@ -102,23 +90,6 @@ public:
void set_label(const String &p_label) { label = p_label; }
void _update_properties();
- void _update_transform_properties(Transform3D p_transform);
-
- // Transform can be keyed, whether or not to show the button.
- void set_keyable(const bool p_keyable);
-
- // When rest mode, pose editor are diasbled.
- void set_properties_read_only(const bool p_readonly);
- void set_transform_read_only(const bool p_readonly);
-
- // Bone can be toggled enabled or disabled, whether or not to show the checkbox.
- void set_toggle_enabled(const bool p_enabled);
-
- // Key Transform Button pressed.
- void _key_button_pressed();
-
- // Bone Enabled Checkbox toggled.
- void _checkbox_pressed();
};
class Skeleton3DEditor : public VBoxContainer {
@@ -197,13 +168,12 @@ class Skeleton3DEditor : public VBoxContainer {
Ref<ShaderMaterial> handle_material;
Ref<Shader> handle_shader;
- Transform3D bone_original;
-
- void _update_pose_enabled(int p_bone = -1);
- void _update_show_rest_only();
+ Vector3 bone_original_position;
+ Quaternion bone_original_rotation;
+ Vector3 bone_original_scale;
- void _update_gizmo_transform();
void _update_gizmo_visible();
+ void _bone_enabled_changed(const int p_bone_id);
void _hide_handles();
@@ -237,7 +207,9 @@ public:
bool is_edit_mode() const { return edit_mode; }
void update_bone_original();
- Transform3D get_bone_original() { return bone_original; };
+ Vector3 get_bone_original_position() const { return bone_original_position; };
+ Quaternion get_bone_original_rotation() const { return bone_original_rotation; };
+ Vector3 get_bone_original_scale() const { return bone_original_scale; };
Skeleton3DEditor(EditorInspectorPluginSkeleton *e_plugin, EditorNode *p_editor, Skeleton3D *skeleton);
~Skeleton3DEditor();
diff --git a/editor/plugins/tiles/tile_map_editor.cpp b/editor/plugins/tiles/tile_map_editor.cpp
index c2e86f8b43..5ca39b82b2 100644
--- a/editor/plugins/tiles/tile_map_editor.cpp
+++ b/editor/plugins/tiles/tile_map_editor.cpp
@@ -456,7 +456,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
case DRAG_TYPE_PAINT: {
Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_last_mouse_pos, mpos);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
Vector2i coords = E.key;
@@ -473,7 +473,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!drag_modified.has(line[i])) {
Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed());
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
Vector2i coords = E.key;
@@ -501,8 +501,12 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * tile_map->get_global_transform();
Vector2 mpos = xform.affine_inverse().xform(mb->get_position());
- if (mb->get_button_index() == MOUSE_BUTTON_LEFT) {
+ if (mb->get_button_index() == MOUSE_BUTTON_LEFT || mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
if (mb->is_pressed()) {
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
+ rmb_erasing = true;
+ }
+
// Pressed
if (drag_type == DRAG_TYPE_CLIPBOARD_PASTE) {
// Do nothing.
@@ -524,18 +528,18 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
}
} else {
// Check if we are picking a tile.
- if (picker_button->is_pressed()) {
+ if (picker_button->is_pressed() || (Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
drag_type = DRAG_TYPE_PICK;
drag_start_mouse_pos = mpos;
} else {
// Paint otherwise.
- if (tool_buttons_group->get_pressed_button() == paint_tool_button) {
+ if (tool_buttons_group->get_pressed_button() == paint_tool_button && !Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT)) {
drag_type = DRAG_TYPE_PAINT;
drag_start_mouse_pos = mpos;
drag_modified.clear();
Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, mpos, mpos);
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
Vector2i coords = E.key;
@@ -545,11 +549,11 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
tile_map->set_cell(tile_map_layer, coords, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
}
_fix_invalid_tiles_in_tile_map_selection();
- } else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
+ } else if (tool_buttons_group->get_pressed_button() == line_tool_button || (tool_buttons_group->get_pressed_button() == paint_tool_button && Input::get_singleton()->is_key_pressed(KEY_SHIFT) && !Input::get_singleton()->is_key_pressed(KEY_CTRL))) {
drag_type = DRAG_TYPE_LINE;
drag_start_mouse_pos = mpos;
drag_modified.clear();
- } else if (tool_buttons_group->get_pressed_button() == rect_tool_button) {
+ } else if (tool_buttons_group->get_pressed_button() == rect_tool_button || (tool_buttons_group->get_pressed_button() == paint_tool_button && Input::get_singleton()->is_key_pressed(KEY_SHIFT) && Input::get_singleton()->is_key_pressed(KEY_CTRL))) {
drag_type = DRAG_TYPE_RECT;
drag_start_mouse_pos = mpos;
drag_modified.clear();
@@ -562,7 +566,7 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
if (!drag_modified.has(line[i])) {
Map<Vector2i, TileMapCell> to_draw = _draw_bucket_fill(line[i], bucket_continuous_checkbox->is_pressed());
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
Vector2i coords = E.key;
@@ -581,6 +585,9 @@ bool TileMapEditorTilesPlugin::forward_canvas_gui_input(const Ref<InputEvent> &p
} else {
// Released
_stop_dragging();
+ if (mb->get_button_index() == MOUSE_BUTTON_RIGHT) {
+ rmb_erasing = false;
+ }
}
CanvasItemEditor::get_singleton()->update_viewport();
@@ -687,13 +694,13 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
Vector2i coords = tile_map->map_pattern(tile_map->world_to_map(drag_last_mouse_pos - mouse_offset), clipboard_used_cells[i], tile_map_clipboard);
preview[coords] = TileMapCell(tile_map_clipboard->get_cell_source_id(clipboard_used_cells[i]), tile_map_clipboard->get_cell_atlas_coords(clipboard_used_cells[i]), tile_map_clipboard->get_cell_alternative_tile(clipboard_used_cells[i]));
}
- } else if (!picker_button->is_pressed()) {
+ } else if (!picker_button->is_pressed() && !(drag_type == DRAG_TYPE_NONE && Input::get_singleton()->is_key_pressed(KEY_CTRL) && !Input::get_singleton()->is_key_pressed(KEY_SHIFT))) {
bool expand_grid = false;
if (tool_buttons_group->get_pressed_button() == paint_tool_button && drag_type == DRAG_TYPE_NONE) {
// Preview for a single pattern.
preview = _draw_line(drag_last_mouse_pos, drag_last_mouse_pos, drag_last_mouse_pos);
expand_grid = true;
- } else if (tool_buttons_group->get_pressed_button() == line_tool_button) {
+ } else if (tool_buttons_group->get_pressed_button() == line_tool_button || drag_type == DRAG_TYPE_LINE) {
if (drag_type == DRAG_TYPE_NONE) {
// Preview for a single pattern.
preview = _draw_line(drag_last_mouse_pos, drag_last_mouse_pos, drag_last_mouse_pos);
@@ -703,12 +710,12 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
preview = _draw_line(drag_start_mouse_pos, drag_start_mouse_pos, drag_last_mouse_pos);
expand_grid = true;
}
- } else if (tool_buttons_group->get_pressed_button() == rect_tool_button && drag_type == DRAG_TYPE_RECT) {
- // Preview for a line pattern.
+ } else if (drag_type == DRAG_TYPE_RECT) {
+ // Preview for a rect pattern.
preview = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(drag_last_mouse_pos));
expand_grid = true;
} else if (tool_buttons_group->get_pressed_button() == bucket_tool_button && drag_type == DRAG_TYPE_NONE) {
- // Preview for a line pattern.
+ // Preview for a fill pattern.
preview = _draw_bucket_fill(tile_map->world_to_map(drag_last_mouse_pos), bucket_continuous_checkbox->is_pressed());
}
@@ -757,7 +764,7 @@ void TileMapEditorTilesPlugin::forward_canvas_draw_over_viewport(Control *p_over
Transform2D tile_xform;
tile_xform.set_origin(tile_map->map_to_world(E.key));
tile_xform.set_scale(tile_set->get_tile_size());
- if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
+ if (!_is_erasing() && random_tile_checkbox->is_pressed()) {
tile_set->draw_tile_shape(p_overlay, xform * tile_xform, Color(1.0, 1.0, 1.0, 0.5), true);
} else {
if (tile_set->has_source(E.value.source_id)) {
@@ -882,12 +889,12 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_line(Vector2 p_start_
// Get or create the pattern.
TileMapPattern erase_pattern;
erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
- TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
+ TileMapPattern *pattern = _is_erasing() ? &erase_pattern : selection_pattern;
Map<Vector2i, TileMapCell> output;
if (!pattern->is_empty()) {
// Paint the tiles on the tile map.
- if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
+ if (!_is_erasing() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
Vector<Vector2i> line = TileMapEditor::get_line(tile_map, tile_map->world_to_map(p_from_mouse_pos), tile_map->world_to_map(p_to_mouse_pos));
for (int i = 0; i < line.size(); i++) {
@@ -934,7 +941,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start
// Get or create the pattern.
TileMapPattern erase_pattern;
erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
- TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
+ TileMapPattern *pattern = _is_erasing() ? &erase_pattern : selection_pattern;
Map<Vector2i, TileMapCell> err_output;
ERR_FAIL_COND_V(pattern->is_empty(), err_output);
@@ -945,7 +952,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_rect(Vector2i p_start
Map<Vector2i, TileMapCell> output;
if (!pattern->is_empty()) {
- if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
+ if (!_is_erasing() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
for (int x = 0; x < rect.size.x; x++) {
for (int y = 0; y < rect.size.y; y++) {
@@ -993,7 +1000,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
// Get or create the pattern.
TileMapPattern erase_pattern;
erase_pattern.set_cell(Vector2i(0, 0), TileSet::INVALID_SOURCE, TileSetSource::INVALID_ATLAS_COORDS, TileSetSource::INVALID_TILE_ALTERNATIVE);
- TileMapPattern *pattern = erase_button->is_pressed() ? &erase_pattern : selection_pattern;
+ TileMapPattern *pattern = _is_erasing() ? &erase_pattern : selection_pattern;
if (!pattern->is_empty()) {
TileMapCell source = tile_map->get_cell(tile_map_layer, p_coords);
@@ -1017,7 +1024,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
(source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
- if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
+ if (!_is_erasing() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
output.insert(coords, _pick_random_tile(pattern));
} else {
@@ -1063,7 +1070,7 @@ Map<Vector2i, TileMapCell> TileMapEditorTilesPlugin::_draw_bucket_fill(Vector2i
source.get_atlas_coords() == tile_map->get_cell_atlas_coords(tile_map_layer, coords) &&
source.alternative_tile == tile_map->get_cell_alternative_tile(tile_map_layer, coords) &&
(source.source_id != TileSet::INVALID_SOURCE || boundaries.has_point(coords))) {
- if (!erase_button->is_pressed() && random_tile_checkbox->is_pressed()) {
+ if (!_is_erasing() && random_tile_checkbox->is_pressed()) {
// Paint a random tile.
output.insert(coords, _pick_random_tile(pattern));
} else {
@@ -1220,7 +1227,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
Map<Vector2i, TileMapCell> to_draw = _draw_line(drag_start_mouse_pos, drag_start_mouse_pos, mpos);
undo_redo->create_action(TTR("Paint tiles"));
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
@@ -1232,7 +1239,7 @@ void TileMapEditorTilesPlugin::_stop_dragging() {
Map<Vector2i, TileMapCell> to_draw = _draw_rect(tile_map->world_to_map(drag_start_mouse_pos), tile_map->world_to_map(mpos));
undo_redo->create_action(TTR("Paint tiles"));
for (const KeyValue<Vector2i, TileMapCell> &E : to_draw) {
- if (!erase_button->is_pressed() && E.value.source_id == TileSet::INVALID_SOURCE) {
+ if (!_is_erasing() && E.value.source_id == TileSet::INVALID_SOURCE) {
continue;
}
undo_redo->add_do_method(tile_map, "set_cell", tile_map_layer, E.key, E.value.source_id, E.value.get_atlas_coords(), E.value.alternative_tile);
@@ -1347,6 +1354,10 @@ void TileMapEditorTilesPlugin::_fix_invalid_tiles_in_tile_map_selection() {
}
}
+bool TileMapEditorTilesPlugin::_is_erasing() const {
+ return erase_button->is_pressed() || rmb_erasing;
+}
+
void TileMapEditorTilesPlugin::_update_selection_pattern_from_tilemap_selection() {
TileMap *tile_map = Object::cast_to<TileMap>(ObjectDB::get_instance(tile_map_id));
if (!tile_map) {
@@ -1830,6 +1841,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
paint_tool_button->set_toggle_mode(true);
paint_tool_button->set_button_group(tool_buttons_group);
paint_tool_button->set_shortcut(ED_SHORTCUT("tiles_editor/paint_tool", "Paint", KEY_D));
+ paint_tool_button->set_tooltip(TTR("Shift: Draw line.") + "\n" + TTR("Shift+Ctrl: Draw rectangle."));
paint_tool_button->connect("pressed", callable_mp(this, &TileMapEditorTilesPlugin::_update_toolbar));
tilemap_tiles_tools_buttons->add_child(paint_tool_button);
@@ -1870,6 +1882,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
picker_button->set_flat(true);
picker_button->set_toggle_mode(true);
picker_button->set_shortcut(ED_SHORTCUT("tiles_editor/picker", "Picker", KEY_P));
+ picker_button->set_tooltip(TTR("Alternatively hold Ctrl with other tools to pick tile."));
picker_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
tools_settings->add_child(picker_button);
@@ -1878,6 +1891,7 @@ TileMapEditorTilesPlugin::TileMapEditorTilesPlugin() {
erase_button->set_flat(true);
erase_button->set_toggle_mode(true);
erase_button->set_shortcut(ED_SHORTCUT("tiles_editor/eraser", "Eraser", KEY_E));
+ erase_button->set_tooltip(TTR("Alternatively use RMB to erase tiles."));
erase_button->connect("pressed", callable_mp(CanvasItemEditor::get_singleton(), &CanvasItemEditor::update_viewport));
tools_settings->add_child(erase_button);
diff --git a/editor/plugins/tiles/tile_map_editor.h b/editor/plugins/tiles/tile_map_editor.h
index a1ab3db318..5fbd9cada8 100644
--- a/editor/plugins/tiles/tile_map_editor.h
+++ b/editor/plugins/tiles/tile_map_editor.h
@@ -104,12 +104,14 @@ private:
Vector2 drag_start_mouse_pos;
Vector2 drag_last_mouse_pos;
Map<Vector2i, TileMapCell> drag_modified;
+ bool rmb_erasing = false;
TileMapCell _pick_random_tile(const TileMapPattern *p_pattern);
Map<Vector2i, TileMapCell> _draw_line(Vector2 p_start_drag_mouse_pos, Vector2 p_from_mouse_pos, Vector2 p_to_mouse_pos);
Map<Vector2i, TileMapCell> _draw_rect(Vector2i p_start_cell, Vector2i p_end_cell);
Map<Vector2i, TileMapCell> _draw_bucket_fill(Vector2i p_coords, bool p_contiguous);
void _stop_dragging();
+ bool _is_erasing() const;
///// Selection system. /////
Set<Vector2i> tile_map_selection;
diff --git a/modules/fbx/data/fbx_mesh_data.cpp b/modules/fbx/data/fbx_mesh_data.cpp
index 7343bf87af..e1eacc68b3 100644
--- a/modules/fbx/data/fbx_mesh_data.cpp
+++ b/modules/fbx/data/fbx_mesh_data.cpp
@@ -357,7 +357,6 @@ ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, c
mesh->set_blend_shape_mode(Mesh::BLEND_SHAPE_MODE_NORMALIZED);
// Add surfaces.
- int in_mesh_surface_id = 0;
for (const SurfaceId *surface_id = surfaces.next(nullptr); surface_id != nullptr; surface_id = surfaces.next(surface_id)) {
SurfaceData *surface = surfaces.getptr(*surface_id);
@@ -377,8 +376,6 @@ ImporterMeshInstance3D *FBXMeshData::create_fbx_mesh(const ImportState &state, c
} else {
mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES, mesh_array, blend_shapes);
}
-
- in_mesh_surface_id += 1;
}
ImporterMeshInstance3D *godot_mesh = memnew(ImporterMeshInstance3D);
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp
index 8bd288cf0f..47f81b455f 100644
--- a/modules/gdscript/gdscript_analyzer.cpp
+++ b/modules/gdscript/gdscript_analyzer.cpp
@@ -1069,7 +1069,7 @@ void GDScriptAnalyzer::resolve_node(GDScriptParser::Node *p_node) {
case GDScriptParser::Node::SUBSCRIPT:
case GDScriptParser::Node::TERNARY_OPERATOR:
case GDScriptParser::Node::UNARY_OPERATOR:
- reduce_expression(static_cast<GDScriptParser::ExpressionNode *>(p_node));
+ reduce_expression(static_cast<GDScriptParser::ExpressionNode *>(p_node), true);
break;
case GDScriptParser::Node::BREAK:
case GDScriptParser::Node::BREAKPOINT:
@@ -1658,7 +1658,7 @@ void GDScriptAnalyzer::resolve_return(GDScriptParser::ReturnNode *p_return) {
p_return->set_datatype(result);
}
-void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expression) {
+void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expression, bool p_is_root) {
// This one makes some magic happen.
if (p_expression == nullptr) {
@@ -1686,7 +1686,7 @@ void GDScriptAnalyzer::reduce_expression(GDScriptParser::ExpressionNode *p_expre
reduce_binary_op(static_cast<GDScriptParser::BinaryOpNode *>(p_expression));
break;
case GDScriptParser::Node::CALL:
- reduce_call(static_cast<GDScriptParser::CallNode *>(p_expression));
+ reduce_call(static_cast<GDScriptParser::CallNode *>(p_expression), p_is_root);
break;
case GDScriptParser::Node::CAST:
reduce_cast(static_cast<GDScriptParser::CastNode *>(p_expression));
@@ -1927,16 +1927,25 @@ void GDScriptAnalyzer::reduce_await(GDScriptParser::AwaitNode *p_await) {
p_await->set_datatype(await_type);
return;
}
+
+ GDScriptParser::DataType awaiting_type;
+
if (p_await->to_await->type == GDScriptParser::Node::CALL) {
reduce_call(static_cast<GDScriptParser::CallNode *>(p_await->to_await), true);
+ awaiting_type = p_await->to_await->get_datatype();
} else {
reduce_expression(p_await->to_await);
}
- p_await->is_constant = p_await->to_await->is_constant;
- p_await->reduced_value = p_await->to_await->reduced_value;
+ if (p_await->to_await->is_constant) {
+ p_await->is_constant = p_await->to_await->is_constant;
+ p_await->reduced_value = p_await->to_await->reduced_value;
- GDScriptParser::DataType awaiting_type = p_await->to_await->get_datatype();
+ awaiting_type = p_await->to_await->get_datatype();
+ } else {
+ awaiting_type.kind = GDScriptParser::DataType::VARIANT;
+ awaiting_type.type_source = GDScriptParser::DataType::UNDETECTED;
+ }
p_await->set_datatype(awaiting_type);
@@ -2056,7 +2065,7 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o
p_binary_op->set_datatype(result);
}
-void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_await) {
+void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_await, bool p_is_root) {
bool all_is_constant = true;
Map<int, GDScriptParser::ArrayNode *> arrays; // For array literal to potentially type when passing.
for (int i = 0; i < p_call->arguments.size(); i++) {
@@ -2415,7 +2424,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool is_awa
}
}
- if (call_type.is_coroutine && !is_await) {
+ if (call_type.is_coroutine && !p_is_await && !p_is_root) {
push_error(vformat(R"*(Function "%s()" is a coroutine, so it must be called with "await".)*", p_call->function_name), p_call->callee);
}
@@ -2683,6 +2692,11 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod
p_identifier->is_constant = false;
return;
} break;
+ case GDScriptParser::ClassNode::Member::CLASS: {
+ resolve_class_interface(member.m_class);
+ p_identifier->set_datatype(member.m_class->get_datatype());
+ return;
+ } break;
default:
break;
}
diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h
index 2e17e15452..ce4525190b 100644
--- a/modules/gdscript/gdscript_analyzer.h
+++ b/modules/gdscript/gdscript_analyzer.h
@@ -78,12 +78,12 @@ class GDScriptAnalyzer {
void resolve_return(GDScriptParser::ReturnNode *p_return);
// Reduction functions.
- void reduce_expression(GDScriptParser::ExpressionNode *p_expression);
+ void reduce_expression(GDScriptParser::ExpressionNode *p_expression, bool p_is_root = false);
void reduce_array(GDScriptParser::ArrayNode *p_array);
void reduce_assignment(GDScriptParser::AssignmentNode *p_assignment);
void reduce_await(GDScriptParser::AwaitNode *p_await);
void reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_op);
- void reduce_call(GDScriptParser::CallNode *p_call, bool is_await = false);
+ void reduce_call(GDScriptParser::CallNode *p_call, bool p_is_await = false, bool p_is_root = false);
void reduce_cast(GDScriptParser::CastNode *p_cast);
void reduce_dictionary(GDScriptParser::DictionaryNode *p_dictionary);
void reduce_get_node(GDScriptParser::GetNodeNode *p_get_node);
diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp
index 1f9aad40af..ab0fe5c37d 100644
--- a/modules/gdscript/gdscript_compiler.cpp
+++ b/modules/gdscript/gdscript_compiler.cpp
@@ -488,6 +488,9 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
const GDScriptParser::CallNode *call = static_cast<const GDScriptParser::CallNode *>(p_expression);
GDScriptDataType type = _gdtype_from_datatype(call->get_datatype());
GDScriptCodeGenerator::Address result = codegen.add_temporary(type);
+ GDScriptCodeGenerator::Address nil = GDScriptCodeGenerator::Address(GDScriptCodeGenerator::Address::NIL);
+
+ GDScriptCodeGenerator::Address return_addr = p_root ? nil : result;
Vector<GDScriptCodeGenerator::Address> arguments;
for (int i = 0; i < call->arguments.size(); i++) {
@@ -538,13 +541,13 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
if (within_await) {
gen->write_call_async(result, self, call->function_name, arguments);
} else {
- gen->write_call(result, self, call->function_name, arguments);
+ gen->write_call(return_addr, self, call->function_name, arguments);
}
} else {
if (within_await) {
gen->write_call_self_async(result, call->function_name, arguments);
} else {
- gen->write_call_self(result, call->function_name, arguments);
+ gen->write_call_self(return_addr, call->function_name, arguments);
}
}
} else if (callee->type == GDScriptParser::Node::SUBSCRIPT) {
@@ -579,12 +582,12 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code
gen->write_call_method_bind(result, base, method, arguments);
}
} else {
- gen->write_call(result, base, call->function_name, arguments);
+ gen->write_call(return_addr, base, call->function_name, arguments);
}
} else if (base.type.has_type && base.type.kind == GDScriptDataType::BUILTIN) {
gen->write_call_builtin_type(result, base, base.type.builtin_type, call->function_name, arguments);
} else {
- gen->write_call(result, base, call->function_name, arguments);
+ gen->write_call(return_addr, base, call->function_name, arguments);
}
if (base.mode == GDScriptCodeGenerator::Address::TEMPORARY) {
gen->pop_temporary();
diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp
index 1bc7ae086f..7018c339d7 100644
--- a/modules/gdscript/gdscript_vm.cpp
+++ b/modules/gdscript/gdscript_vm.cpp
@@ -2098,8 +2098,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a
}
if (result.get_type() != Variant::SIGNAL) {
+ // Not async, return immediately using the target from OPCODE_AWAIT_RESUME.
+ GET_VARIANT_PTR(target, 3);
+ *target = result;
ip += 4; // Skip OPCODE_AWAIT_RESUME and its data.
- // The stack pointer should be the same, so we don't need to set a return value.
is_signal = false;
} else {
sig = result;
diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd
new file mode 100644
index 0000000000..30e7deb05a
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.gd
@@ -0,0 +1,19 @@
+class A:
+ var x = 3
+
+class B:
+ var x = 4
+
+class C:
+ var x = 5
+
+class Test:
+ var a = A.new()
+ var b: B = B.new()
+ var c := C.new()
+
+func test():
+ var test_instance := Test.new()
+ prints(test_instance.a.x)
+ prints(test_instance.b.x)
+ prints(test_instance.c.x)
diff --git a/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out
new file mode 100644
index 0000000000..a078e62cc7
--- /dev/null
+++ b/modules/gdscript/tests/scripts/analyzer/features/class_from_parent.out
@@ -0,0 +1,4 @@
+GDTEST_OK
+3
+4
+5
diff --git a/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd
new file mode 100644
index 0000000000..18174eae67
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.gd
@@ -0,0 +1,32 @@
+# https://github.com/godotengine/godot/issues/48121
+
+func test():
+ var x := []
+ var y := []
+ x.push_back(y)
+ print("TEST ARRAY ADD TO SELF: " + str(len(y)))
+ x.clear()
+
+ x = Array()
+ y = Array()
+ x.push_back(y)
+ print("TEST ARRAY ADD TO SELF: " + str(len(y)))
+ x.clear()
+
+ x = Array().duplicate()
+ y = Array().duplicate()
+ x.push_back(y)
+ print("TEST ARRAY ADD TO SELF: " + str(len(y)))
+ x.clear()
+
+ x = [].duplicate()
+ y = [].duplicate()
+ x.push_back(y)
+ print("TEST ARRAY ADD TO SELF: " + str(len(y)))
+ x.clear()
+
+ x = Array()
+ y = Array()
+ x.push_back(y)
+ print("TEST ARRAY ADD TO SELF: " + str(len(y)))
+ x.clear()
diff --git a/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out
new file mode 100644
index 0000000000..f6b7d3cc39
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/arrays_arent_shared.out
@@ -0,0 +1,6 @@
+GDTEST_OK
+TEST ARRAY ADD TO SELF: 0
+TEST ARRAY ADD TO SELF: 0
+TEST ARRAY ADD TO SELF: 0
+TEST ARRAY ADD TO SELF: 0
+TEST ARRAY ADD TO SELF: 0
diff --git a/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd
new file mode 100644
index 0000000000..9da61ab184
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.gd
@@ -0,0 +1,8 @@
+# https://github.com/godotengine/godot/issues/50894
+
+func test():
+ print(await not_coroutine())
+
+
+func not_coroutine():
+ return "awaited"
diff --git a/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out
new file mode 100644
index 0000000000..c2ac488e9b
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/await_without_coroutine.out
@@ -0,0 +1,6 @@
+GDTEST_OK
+>> WARNING
+>> Line: 4
+>> REDUNDANT_AWAIT
+>> "await" keyword not needed in this case, because the expression isn't a coroutine nor a signal.
+awaited
diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd
new file mode 100644
index 0000000000..d5a5f8de64
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.gd
@@ -0,0 +1,19 @@
+# https://github.com/godotengine/godot/issues/48121
+
+func test():
+ var x := Dictionary()
+ var y := Dictionary()
+ y[0]=1
+ y[1]=1
+ y[2]=1
+ print("TEST OTHER DICTIONARY: " + str(len(x)))
+ x.clear()
+
+ x = Dictionary().duplicate()
+ y = Dictionary().duplicate()
+ y[0]=1
+ y[1]=1
+ y[2]=1
+ print("TEST OTHER DICTIONARY: " + str(len(x)))
+ x.clear()
+ return
diff --git a/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out
new file mode 100644
index 0000000000..0bf49f5934
--- /dev/null
+++ b/modules/gdscript/tests/scripts/runtime/features/dictionaries_arent_shared.out
@@ -0,0 +1,3 @@
+GDTEST_OK
+TEST OTHER DICTIONARY: 0
+TEST OTHER DICTIONARY: 0
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp
index 6fd542ca68..11f30be5a4 100644
--- a/modules/gltf/gltf_document.cpp
+++ b/modules/gltf/gltf_document.cpp
@@ -6192,11 +6192,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> state, Node *scene_roo
}
}
-GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, Transform3D p_bone_rest, int32_t p_track_i, GLTFNodeIndex p_node_i) {
-#ifndef _MSC_VER
-#warning this needs to be redone
-#endif
-#if 0
+GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state, GLTFAnimation::Track p_track, Ref<Animation> p_animation, int32_t p_track_i, GLTFNodeIndex p_node_i) {
Animation::InterpolationType interpolation = p_animation->track_get_interpolation_type(p_track_i);
GLTFAnimation::Interpolation gltf_interpolation = GLTFAnimation::INTERP_LINEAR;
@@ -6215,35 +6211,35 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
for (int32_t key_i = 0; key_i < key_count; key_i++) {
times.write[key_i] = p_animation->track_get_key_time(p_track_i, key_i);
}
-
-
- if (track_type == Animation::TYPE_TRANSFORM3D) {
- p_track.position_track.times = times;
- p_track.position_track.interpolation = gltf_interpolation;
- p_track.rotation_track.times = times;
- p_track.rotation_track.interpolation = gltf_interpolation;
+ if (track_type == Animation::TYPE_SCALE_3D) {
p_track.scale_track.times = times;
p_track.scale_track.interpolation = gltf_interpolation;
-
p_track.scale_track.values.resize(key_count);
- p_track.scale_track.interpolation = gltf_interpolation;
+ for (int32_t key_i = 0; key_i < key_count; key_i++) {
+ Vector3 scale;
+ Error err = p_animation->scale_track_get_key(p_track_i, key_i, &scale);
+ ERR_CONTINUE(err != OK);
+ p_track.scale_track.values.write[key_i] = scale;
+ }
+ } else if (track_type == Animation::TYPE_POSITION_3D) {
+ p_track.position_track.times = times;
p_track.position_track.values.resize(key_count);
p_track.position_track.interpolation = gltf_interpolation;
- p_track.rotation_track.values.resize(key_count);
- p_track.rotation_track.interpolation = gltf_interpolation;
for (int32_t key_i = 0; key_i < key_count; key_i++) {
Vector3 position;
+ Error err = p_animation->position_track_get_key(p_track_i, key_i, &position);
+ ERR_CONTINUE(err != OK);
+ p_track.position_track.values.write[key_i] = position;
+ }
+ } else if (track_type == Animation::TYPE_ROTATION_3D) {
+ p_track.rotation_track.times = times;
+ p_track.rotation_track.interpolation = gltf_interpolation;
+ p_track.rotation_track.values.resize(key_count);
+ for (int32_t key_i = 0; key_i < key_count; key_i++) {
Quaternion rotation;
- Vector3 scale;
- Error err = p_animation->transform_track_get_key(p_track_i, key_i, &position, &rotation, &scale);
+ Error err = p_animation->rotation_track_get_key(p_track_i, key_i, &rotation);
ERR_CONTINUE(err != OK);
- Transform3D xform;
- xform.basis.set_quaternion_scale(rotation, scale);
- xform.origin = position;
- xform = p_bone_rest * xform;
- p_track.position_track.values.write[key_i] = xform.get_origin();
- p_track.rotation_track.values.write[key_i] = xform.basis.get_rotation_quaternion();
- p_track.scale_track.values.write[key_i] = xform.basis.get_scale();
+ p_track.rotation_track.values.write[key_i] = rotation;
}
} else if (path.find(":transform") != -1) {
p_track.position_track.times = times;
@@ -6335,13 +6331,10 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
Vector3 bezier_track = p_track.scale_track.values[key_i];
if (path.find("/scale:x") != -1) {
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.x = p_bone_rest.affine_inverse().basis.get_scale().x * bezier_track.x;
} else if (path.find("/scale:y") != -1) {
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.y = p_bone_rest.affine_inverse().basis.get_scale().y * bezier_track.y;
} else if (path.find("/scale:z") != -1) {
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.z = p_bone_rest.affine_inverse().basis.get_scale().z * bezier_track.z;
}
p_track.scale_track.values.write[key_i] = bezier_track;
}
@@ -6364,19 +6357,15 @@ GLTFAnimation::Track GLTFDocument::_convert_animation_track(Ref<GLTFState> state
Vector3 bezier_track = p_track.position_track.values[key_i];
if (path.find("/position:x") != -1) {
bezier_track.x = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.x = p_bone_rest.affine_inverse().origin.x * bezier_track.x;
} else if (path.find("/position:y") != -1) {
bezier_track.y = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.y = p_bone_rest.affine_inverse().origin.y * bezier_track.y;
} else if (path.find("/position:z") != -1) {
bezier_track.z = p_animation->bezier_track_interpolate(p_track_i, key_i / BAKE_FPS);
- bezier_track.z = p_bone_rest.affine_inverse().origin.z * bezier_track.z;
}
p_track.position_track.values.write[key_i] = bezier_track;
}
}
}
-#endif
return p_track;
}
@@ -6403,7 +6392,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (position_track_i) {
track = position_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6419,7 +6408,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (rotation_degree_track_i) {
track = rotation_degree_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6435,7 +6424,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (scale_track_i) {
track = scale_track_i->get();
}
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
+ track = _convert_animation_track(state, track, animation, track_i, node_index);
gltf_animation->get_tracks().insert(node_index, track);
}
}
@@ -6446,7 +6435,7 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
for (const KeyValue<GLTFNodeIndex, Node *> &transform_track_i : state->scene_nodes) {
if (transform_track_i.value == node) {
GLTFAnimation::Track track;
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, transform_track_i.key);
+ track = _convert_animation_track(state, track, animation, track_i, transform_track_i.key);
gltf_animation->get_tracks().insert(transform_track_i.key, track);
}
}
@@ -6523,7 +6512,6 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
Ref<GLTFSkeleton> skeleton_gltf = state->skeletons[skeleton_gltf_i];
int32_t bone = skeleton->find_bone(suffix);
ERR_CONTINUE(bone == -1);
- Transform3D xform = skeleton->get_bone_rest(bone);
if (!skeleton_gltf->godot_bone_node.has(bone)) {
continue;
}
@@ -6533,27 +6521,24 @@ void GLTFDocument::_convert_animation(Ref<GLTFState> state, AnimationPlayer *ap,
if (property_track_i) {
track = property_track_i->get();
}
- track = _convert_animation_track(state, track, animation, xform, track_i, node_i);
+ track = _convert_animation_track(state, track, animation, track_i, node_i);
gltf_animation->get_tracks()[node_i] = track;
}
}
} else if (String(orig_track_path).find(":") == -1) {
ERR_CONTINUE(!ap->get_parent());
- for (int32_t node_i = 0; node_i < ap->get_parent()->get_child_count(); node_i++) {
- const Node *child = ap->get_parent()->get_child(node_i);
- const Node *node = child->get_node_or_null(orig_track_path);
- for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) {
- if (scene_node_i.value == node) {
- GLTFNodeIndex node_index = scene_node_i.key;
- Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_index);
- GLTFAnimation::Track track;
- if (node_track_i) {
- track = node_track_i->get();
- }
- track = _convert_animation_track(state, track, animation, Transform3D(), track_i, node_index);
- gltf_animation->get_tracks().insert(node_index, track);
- break;
+ Node *godot_node = ap->get_parent()->get_node_or_null(orig_track_path);
+ for (const KeyValue<GLTFNodeIndex, Node *> &scene_node_i : state->scene_nodes) {
+ if (scene_node_i.value == godot_node) {
+ GLTFNodeIndex node_i = scene_node_i.key;
+ Map<int, GLTFAnimation::Track>::Element *node_track_i = gltf_animation->get_tracks().find(node_i);
+ GLTFAnimation::Track track;
+ if (node_track_i) {
+ track = node_track_i->get();
}
+ track = _convert_animation_track(state, track, animation, track_i, node_i);
+ gltf_animation->get_tracks()[node_i] = track;
+ break;
}
}
}
diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h
index 7317c6a9a3..a1d82a4649 100644
--- a/modules/gltf/gltf_document.h
+++ b/modules/gltf/gltf_document.h
@@ -357,7 +357,7 @@ private:
String interpolation_to_string(const GLTFAnimation::Interpolation p_interp);
GLTFAnimation::Track _convert_animation_track(Ref<GLTFState> state,
GLTFAnimation::Track p_track,
- Ref<Animation> p_animation, Transform3D p_bone_rest,
+ Ref<Animation> p_animation,
int32_t p_track_i,
GLTFNodeIndex p_node_i);
Error _encode_buffer_bins(Ref<GLTFState> state, const String &p_path);
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 406f10de89..6f98dab2cc 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -197,12 +197,10 @@ def configure(env):
env.Append(CPPDEFINES=["NDEBUG"])
if can_vectorize:
env.Append(CCFLAGS=["-ftree-vectorize"])
- if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
elif env["target"] == "debug":
env.Append(LINKFLAGS=["-O0"])
env.Append(CCFLAGS=["-O0", "-g", "-fno-limit-debug-info"])
- env.Append(CPPDEFINES=["_DEBUG", "DEBUG_ENABLED"])
+ env.Append(CPPDEFINES=["_DEBUG"])
env.Append(CPPFLAGS=["-UNDEBUG"])
# Compiler configuration
diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle
index fcee54e493..3fafdf8573 100644
--- a/platform/android/java/app/config.gradle
+++ b/platform/android/java/app/config.gradle
@@ -1,12 +1,12 @@
ext.versions = [
- androidGradlePlugin: '4.2.2',
+ androidGradlePlugin: '7.0.3',
compileSdk : 30,
minSdk : 19,
targetSdk : 30,
buildTools : '30.0.3',
kotlinVersion : '1.5.10',
fragmentVersion : '1.3.6',
- javaVersion : 1.8,
+ javaVersion : 11,
ndkVersion : '21.4.7075529' // Also update 'platform/android/detect.py#get_project_ndk_version()' when this is updated.
]
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.jar b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
index f6b961fd5a..e708b1c023 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.jar
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index 74c5636f8a..ffed3a254e 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,5 @@
-#Wed Jun 23 23:42:22 PDT 2021
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionPath=wrapper/dists
-zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/platform/android/java/gradlew b/platform/android/java/gradlew
index cccdd3d517..4f906e0c81 100755
--- a/platform/android/java/gradlew
+++ b/platform/android/java/gradlew
@@ -1,5 +1,21 @@
#!/usr/bin/env sh
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS=""
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
-# For Cygwin, switch paths to Windows format before running java
-if $cygwin ; then
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
- i=$((i+1))
+ i=`expr $i + 1`
done
case $i in
- (0) set -- ;;
- (1) set -- "$args0" ;;
- (2) set -- "$args0" "$args1" ;;
- (3) set -- "$args0" "$args1" "$args2" ;;
- (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
-APP_ARGS=$(save "$@")
+APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
-# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
-if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
- cd "$(dirname "$0")"
-fi
-
exec "$JAVACMD" "$@"
diff --git a/platform/android/java/gradlew.bat b/platform/android/java/gradlew.bat
index 11cc30edb0..107acd32c4 100644
--- a/platform/android/java/gradlew.bat
+++ b/platform/android/java/gradlew.bat
@@ -1,7 +1,23 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
-@rem Gradle startup script for Windows
+@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-set DEFAULT_JVM_OPTS=
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
@rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
@@ -75,7 +80,7 @@ if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
-if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 05e24c5003..0d28aa2f06 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -53,12 +53,9 @@ def configure(env):
env.Append(CCFLAGS=["-Os", "-ftree-vectorize"])
env.Append(LINKFLAGS=["-Os"])
- if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
-
elif env["target"] == "debug":
env.Append(CCFLAGS=["-gdwarf-2", "-O0"])
- env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1), "DEBUG_ENABLED"])
+ env.Append(CPPDEFINES=["_DEBUG", ("DEBUG", 1)])
if env["use_lto"]:
env.Append(CCFLAGS=["-flto"])
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 69a8203e9f..a561da41c0 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -1427,7 +1427,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
}
bool found_library = false;
- int total_size = 0;
const String project_file = "godot_ios.xcodeproj/project.pbxproj";
Set<String> files_to_parse;
@@ -1523,7 +1522,6 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
file = file.replace("godot_ios", binary_name);
print_line("ADDING: " + file + " size: " + itos(data.size()));
- total_size += data.size();
/* write it into our folder structure */
file = dest_dir + file;
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index 173b558b6d..891ae419bd 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -77,11 +77,9 @@ def configure(env):
env.Append(LINKFLAGS=["-Os"])
if env["target"] == "release_debug":
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
# Retain function names for backtraces at the cost of file size.
env.Append(LINKFLAGS=["--profiling-funcs"])
else: # "debug"
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(CCFLAGS=["-O1", "-g"])
env.Append(LINKFLAGS=["-O1", "-g"])
env["use_assertions"] = True
diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py
index 8eb22c1c72..8e0adc079b 100644
--- a/platform/linuxbsd/detect.py
+++ b/platform/linuxbsd/detect.py
@@ -105,14 +105,12 @@ def configure(env):
env.Prepend(CCFLAGS=["-O2"])
elif env["optimize"] == "size": # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
env.Prepend(CCFLAGS=["-g3"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["-rdynamic"])
## Architecture
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 6b25daf05d..3f967781b2 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -57,13 +57,11 @@ def configure(env):
env.Prepend(CCFLAGS=["-O2"])
elif env["optimize"] == "size": # optimize for size
env.Prepend(CCFLAGS=["-Os"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
elif env["target"] == "debug":
env.Prepend(CCFLAGS=["-g3"])
- env.Prepend(CPPDEFINES=["DEBUG_ENABLED"])
env.Prepend(LINKFLAGS=["-Xlinker", "-no_deduplicate"])
## Architecture
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index 2404c20153..60a878d644 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -561,7 +561,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
// Now process our template.
bool found_binary = false;
- int total_size = 0;
Vector<String> dylibs_found;
while (ret == UNZ_OK && err == OK) {
@@ -649,7 +648,6 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p
}
print_line("ADDING: " + file + " size: " + itos(data.size()));
- total_size += data.size();
// Write it into our application bundle.
file = tmp_app_path_name.plus_file(file);
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index 28922a4f59..9c91378b22 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -64,14 +64,12 @@ def configure(env):
env.Append(CCFLAGS=["/MD"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env["optimize"] != "none":
env.Append(CCFLAGS=["/O2", "/Zi"])
elif env["target"] == "debug":
env.Append(CCFLAGS=["/Zi"])
env.Append(CCFLAGS=["/MDd"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/SUBSYSTEM:CONSOLE"])
env.AppendUnique(CPPDEFINES=["WINDOWS_SUBSYSTEM_CONSOLE"])
env.Append(LINKFLAGS=["/DEBUG"])
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 3961480d23..6752885f37 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -203,11 +203,9 @@ def configure_msvc(env, manual_msvc_config):
elif env["optimize"] == "size": # optimize for size
env.Append(CCFLAGS=["/O1"])
env.Append(LINKFLAGS=["/OPT:REF"])
- env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
elif env["target"] == "debug":
env.AppendUnique(CCFLAGS=["/Zi", "/FS", "/Od", "/EHsc"])
- env.AppendUnique(CPPDEFINES=["DEBUG_ENABLED"])
env.Append(LINKFLAGS=["/DEBUG"])
if env["debug_symbols"]:
@@ -351,7 +349,6 @@ def configure_mingw(env):
elif env["target"] == "release_debug":
env.Append(CCFLAGS=["-O2"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env["debug_symbols"]:
env.Prepend(CCFLAGS=["-g2"])
if env["optimize"] == "speed": # optimize for speed (default)
@@ -361,7 +358,6 @@ def configure_mingw(env):
elif env["target"] == "debug":
env.Append(CCFLAGS=["-g3"])
- env.Append(CPPDEFINES=["DEBUG_ENABLED"])
if env["windows_subsystem"] == "gui":
env.Append(LINKFLAGS=["-Wl,--subsystem,windows"])
diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h
index 6a90b28579..22c4f96a90 100644
--- a/platform/windows/display_server_windows.h
+++ b/platform/windows/display_server_windows.h
@@ -462,7 +462,7 @@ public:
virtual bool screen_is_touchscreen(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual void screen_set_orientation(ScreenOrientation p_orientation, int p_screen = SCREEN_OF_MAIN_WINDOW) override;
- ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const;
+ virtual ScreenOrientation screen_get_orientation(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
virtual void screen_set_keep_on(bool p_enable) override; //disable screensaver
virtual bool screen_is_kept_on() const override;
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 33b1c7bcce..fff9c47d4d 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -533,13 +533,13 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout);
ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout);
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node2D")));
- ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area2D")));
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index f493d97ceb..41288d646f 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -1000,8 +1000,8 @@ void RigidDynamicBody2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "applied_force"), "set_applied_force", "get_applied_force");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "applied_torque"), "set_applied_torque", "get_applied_torque");
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("sleeping_state_changed"));
diff --git a/scene/3d/area_3d.cpp b/scene/3d/area_3d.cpp
index 7e4c40ca0e..d411525707 100644
--- a/scene/3d/area_3d.cpp
+++ b/scene/3d/area_3d.cpp
@@ -649,13 +649,13 @@ void Area3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_reverb_uniformity", "amount"), &Area3D::set_reverb_uniformity);
ClassDB::bind_method(D_METHOD("get_reverb_uniformity"), &Area3D::get_reverb_uniformity);
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node3D")));
- ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("area_shape_entered", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("area_shape_exited", PropertyInfo(Variant::RID, "area_rid"), PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D"), PropertyInfo(Variant::INT, "area_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("area_entered", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
ADD_SIGNAL(MethodInfo("area_exited", PropertyInfo(Variant::OBJECT, "area", PROPERTY_HINT_RESOURCE_TYPE, "Area3D")));
diff --git a/scene/3d/physics_body_3d.cpp b/scene/3d/physics_body_3d.cpp
index 976bff4fbc..8cb348d6e3 100644
--- a/scene/3d/physics_body_3d.cpp
+++ b/scene/3d/physics_body_3d.cpp
@@ -1040,8 +1040,8 @@ void RigidDynamicBody3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "angular_velocity"), "set_angular_velocity", "get_angular_velocity");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater"), "set_angular_damp", "get_angular_damp");
- ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
- ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape"), PropertyInfo(Variant::INT, "local_shape")));
+ ADD_SIGNAL(MethodInfo("body_shape_entered", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
+ ADD_SIGNAL(MethodInfo("body_shape_exited", PropertyInfo(Variant::RID, "body_rid"), PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node"), PropertyInfo(Variant::INT, "body_shape_index"), PropertyInfo(Variant::INT, "local_shape_index")));
ADD_SIGNAL(MethodInfo("body_entered", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("body_exited", PropertyInfo(Variant::OBJECT, "body", PROPERTY_HINT_RESOURCE_TYPE, "Node")));
ADD_SIGNAL(MethodInfo("sleeping_state_changed"));
diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp
index 9b28d7aff8..14506fd9bd 100644
--- a/scene/3d/skeleton_3d.cpp
+++ b/scene/3d/skeleton_3d.cpp
@@ -171,6 +171,45 @@ void Skeleton3D::_get_property_list(List<PropertyInfo> *p_list) const {
"SkeletonModificationStack3D",
PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE | PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE));
#endif //_3D_DISABLED
+
+ for (PropertyInfo &E : *p_list) {
+ _validate_property(E);
+ }
+}
+
+void Skeleton3D::_validate_property(PropertyInfo &property) const {
+ PackedStringArray spr = property.name.split("/");
+ if (spr.size() == 3 && spr[0] == "bones") {
+ if (spr[2] == "rest") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (is_show_rest_only()) {
+ if (spr[2] == "enabled") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (spr[2] == "position") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (spr[2] == "rotation") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (spr[2] == "scale") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ } else if (!is_bone_enabled(spr[1].to_int())) {
+ if (spr[2] == "position") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (spr[2] == "rotation") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ if (spr[2] == "scale") {
+ property.usage |= PROPERTY_USAGE_READ_ONLY;
+ }
+ }
+ }
+
+ Node3D::_validate_property(property);
}
void Skeleton3D::_update_process_order() {
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index f3cf551af7..f7bc3df94e 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -153,6 +153,7 @@ protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_list) const;
+ virtual void _validate_property(PropertyInfo &property) const override;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/texture_progress_bar.cpp b/scene/gui/texture_progress_bar.cpp
index 35a098c6fd..fe11de128a 100644
--- a/scene/gui/texture_progress_bar.cpp
+++ b/scene/gui/texture_progress_bar.cpp
@@ -341,7 +341,11 @@ void TextureProgressBar::draw_nine_patch_stretched(const Ref<Texture2D> &p_textu
} break;
case FILL_BILINEAR_LEFT_AND_RIGHT: {
double center_mapped_from_real_width = (width_total * 0.5 - topleft.x) / max_middle_real_size * max_middle_texture_size + topleft.x;
- double drift_from_unscaled_center = (src_rect.size.x * 0.5 - center_mapped_from_real_width) * (last_section_size - first_section_size) / (bottomright.x - topleft.x);
+ double drift_from_unscaled_center = 0;
+ if (bottomright.y != topleft.y) { // To avoid division by zero.
+ drift_from_unscaled_center = (src_rect.size.x * 0.5 - center_mapped_from_real_width) * (last_section_size - first_section_size) / (bottomright.x - topleft.x);
+ }
+
src_rect.position.x += center_mapped_from_real_width + drift_from_unscaled_center - width_texture * 0.5;
src_rect.size.x = width_texture;
dst_rect.position.x += (width_total - width_filled) * 0.5;
@@ -351,7 +355,11 @@ void TextureProgressBar::draw_nine_patch_stretched(const Ref<Texture2D> &p_textu
} break;
case FILL_BILINEAR_TOP_AND_BOTTOM: {
double center_mapped_from_real_width = (width_total * 0.5 - topleft.y) / max_middle_real_size * max_middle_texture_size + topleft.y;
- double drift_from_unscaled_center = (src_rect.size.y * 0.5 - center_mapped_from_real_width) * (last_section_size - first_section_size) / (bottomright.y - topleft.y);
+ double drift_from_unscaled_center = 0;
+ if (bottomright.y != topleft.y) { // To avoid division by zero.
+ drift_from_unscaled_center = (src_rect.size.y * 0.5 - center_mapped_from_real_width) * (last_section_size - first_section_size) / (bottomright.y - topleft.y);
+ }
+
src_rect.position.y += center_mapped_from_real_width + drift_from_unscaled_center - width_texture * 0.5;
src_rect.size.y = width_texture;
dst_rect.position.y += (width_total - width_filled) * 0.5;
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 9a3f081a8b..be0d3a140e 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -1291,7 +1291,7 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater"), "set_fog_height", "get_fog_height");
- ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "0,128,0.001,or_greater"), "set_fog_height_density", "get_fog_height_density");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "-16,16,0.0001,or_lesser,or_greater"), "set_fog_height_density", "get_fog_height_density");
ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled);
ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled);
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index 275b430f2a..b988b2ab3e 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -3565,6 +3565,10 @@ bool TileSetAtlasSource::has_room_for_tile(Vector2i p_atlas_coords, Vector2i p_s
}
PackedVector2Array TileSetAtlasSource::get_tiles_to_be_removed_on_change(Ref<Texture2D> p_texture, Vector2i p_margins, Vector2i p_separation, Vector2i p_texture_region_size) {
+ ERR_FAIL_COND_V(p_margins.x < 0 || p_margins.y < 0, PackedVector2Array());
+ ERR_FAIL_COND_V(p_separation.x < 0 || p_separation.y < 0, PackedVector2Array());
+ ERR_FAIL_COND_V(p_texture_region_size.x <= 0 || p_texture_region_size.y <= 0, PackedVector2Array());
+
// Compute the new atlas grid size.
Size2 new_grid_size;
if (p_texture.is_valid()) {
diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
index 6a3b9726da..85ebf076cc 100644
--- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
+++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp
@@ -757,9 +757,6 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
- if (scene_state.ubo.fog_height_density >= 0.0001) {
- scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density;
- }
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
index 6937df85fb..5d80ae6212 100644
--- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
+++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp
@@ -1637,9 +1637,6 @@ void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data,
scene_state.ubo.fog_density = environment_get_fog_density(p_render_data->environment);
scene_state.ubo.fog_height = environment_get_fog_height(p_render_data->environment);
scene_state.ubo.fog_height_density = environment_get_fog_height_density(p_render_data->environment);
- if (scene_state.ubo.fog_height_density >= 0.0001) {
- scene_state.ubo.fog_height_density = 1.0 / scene_state.ubo.fog_height_density;
- }
scene_state.ubo.fog_aerial_perspective = environment_get_fog_aerial_perspective(p_render_data->environment);
Color fog_color = environment_get_fog_light_color(p_render_data->environment).to_linear();
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
index f0fb31a457..5261868155 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl
@@ -526,12 +526,12 @@ vec4 fog_process(vec3 vertex) {
float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density));
- if (abs(scene_data.fog_height_density) > 0.001) {
+ if (abs(scene_data.fog_height_density) >= 0.0001) {
float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y;
- float y_dist = scene_data.fog_height - y;
+ float y_dist = y - scene_data.fog_height;
- float vfog_amount = clamp(exp(y_dist * scene_data.fog_height_density), 0.0, 1.0);
+ float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density));
fog_amount = max(vfog_amount, fog_amount);
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
index 750ec5f00a..0ee68d5e10 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl
@@ -552,12 +552,12 @@ vec4 fog_process(vec3 vertex) {
float fog_amount = 1.0 - exp(min(0.0, -length(vertex) * scene_data.fog_density));
- if (abs(scene_data.fog_height_density) > 0.001) {
+ if (abs(scene_data.fog_height_density) >= 0.0001) {
float y = (scene_data.camera_matrix * vec4(vertex, 1.0)).y;
- float y_dist = scene_data.fog_height - y;
+ float y_dist = y - scene_data.fog_height;
- float vfog_amount = clamp(exp(y_dist * scene_data.fog_height_density), 0.0, 1.0);
+ float vfog_amount = 1.0 - exp(min(0.0, y_dist * scene_data.fog_height_density));
fog_amount = max(vfog_amount, fog_amount);
}
diff --git a/thirdparty/README.md b/thirdparty/README.md
index e7ceea6268..157622a2d1 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -347,11 +347,13 @@ File extracted from upstream release tarball:
- All `*.h` from `include/mbedtls/` to `thirdparty/mbedtls/include/mbedtls/`.
- All `*.c` from `library/` to `thirdparty/mbedtls/library/`.
- `LICENSE` and `apache-2.0.txt` files.
-- Applied the patch in `thirdparty/mbedtls/patches/1453.diff` (upstream PR:
+- Applied the patch in `patches/1453.diff` (upstream PR:
https://github.com/ARMmbed/mbedtls/pull/1453).
-- Applied the patch in `thirdparty/mbedtls/patches/padlock.diff`. This disables
- VIA padlock support which defines a symbol `unsupported` which clashes with
- a pre-defined symbol.
+- Applied the patch in `patches/padlock.diff`. This disables VIA padlock
+ support which defines a symbol `unsupported` which clashes with a
+ pre-defined symbol.
+- Applied the patch in `patches/pr4948-fix-clang12-opt.patch`. Upstream bugfix
+ from PR 4948 to fix a bug caused by Clang 12 optimizations.
- Added 2 files `godot_core_mbedtls_platform.c` and `godot_core_mbedtls_config.h`
providing configuration for light bundling with core.
diff --git a/thirdparty/mbedtls/include/mbedtls/bn_mul.h b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
index 6f1201bf50..f84f9650dd 100644
--- a/thirdparty/mbedtls/include/mbedtls/bn_mul.h
+++ b/thirdparty/mbedtls/include/mbedtls/bn_mul.h
@@ -256,9 +256,9 @@
"addq $8, %%rdi\n"
#define MULADDC_STOP \
- : "+c" (c), "+D" (d), "+S" (s) \
- : "b" (b) \
- : "rax", "rdx", "r8" \
+ : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
+ : "b" (b), "m" (*(const uint64_t (*)[16]) s) \
+ : "rax", "rdx", "r8" \
);
#endif /* AMD64 */
diff --git a/thirdparty/mbedtls/patches/pr4948-fix-clang12-opt.patch b/thirdparty/mbedtls/patches/pr4948-fix-clang12-opt.patch
new file mode 100644
index 0000000000..84c205a80f
--- /dev/null
+++ b/thirdparty/mbedtls/patches/pr4948-fix-clang12-opt.patch
@@ -0,0 +1,36 @@
+From 7c847235e8f0e0b877c505f19733b417bb65ff2e Mon Sep 17 00:00:00 2001
+From: Gilles Peskine <Gilles.Peskine@arm.com>
+Date: Tue, 14 Sep 2021 00:13:05 +0200
+Subject: [PATCH] x86_64 MULADDC assembly: add missing constraints about memory
+
+MULADDC_CORE reads from (%%rsi) and writes to (%%rdi). This fragment is
+repeated up to 16 times, and %%rsi and %%rdi are s and d on entry
+respectively. Hence the complete asm statement reads 16 64-bit words
+from memory starting at s, and writes 16 64-bit words starting at d.
+
+Without any declaration of modified memory, Clang 12 and Clang 13 generated
+non-working code for mbedtls_mpi_mod_exp. The constraints make the unit
+tests pass with Clang 12.
+
+Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
+---
+ include/mbedtls/bn_mul.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/mbedtls/bn_mul.h b/include/mbedtls/bn_mul.h
+index 6f1201bf50a..f84f9650ddc 100644
+--- a/include/mbedtls/bn_mul.h
++++ b/include/mbedtls/bn_mul.h
+@@ -256,9 +256,9 @@
+ "addq $8, %%rdi\n"
+
+ #define MULADDC_STOP \
+- : "+c" (c), "+D" (d), "+S" (s) \
+- : "b" (b) \
+- : "rax", "rdx", "r8" \
++ : "+c" (c), "+D" (d), "+S" (s), "+m" (*(uint64_t (*)[16]) d) \
++ : "b" (b), "m" (*(const uint64_t (*)[16]) s) \
++ : "rax", "rdx", "r8" \
+ );
+
+ #endif /* AMD64 */