summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--DONORS.md2
-rw-r--r--SConstruct5
-rw-r--r--core/math/a_star.cpp10
-rw-r--r--core/math/a_star.h4
-rw-r--r--core/math/aabb.cpp20
-rw-r--r--core/math/aabb.h30
-rw-r--r--core/math/audio_frame.h3
-rw-r--r--core/math/expression.cpp8
-rw-r--r--core/math/quaternion.h3
-rw-r--r--core/math/rect2.cpp10
-rw-r--r--core/math/rect2.h82
-rw-r--r--core/math/vector3.cpp8
-rw-r--r--core/math/vector3.h18
-rw-r--r--core/string/ustring.cpp6
-rw-r--r--core/string/ustring.h20
-rw-r--r--core/templates/local_vector.h6
-rw-r--r--core/templates/oa_hash_map.h3
-rw-r--r--core/templates/ordered_hash_map.h6
-rw-r--r--core/templates/vector.h3
-rw-r--r--core/templates/vmap.h3
-rw-r--r--core/variant/variant_call.cpp8
-rw-r--r--doc/classes/AABB.xml6
-rw-r--r--doc/classes/AStar.xml12
-rw-r--r--doc/classes/AStar2D.xml12
-rw-r--r--doc/classes/BaseMaterial3D.xml3
-rw-r--r--doc/classes/Camera3D.xml4
-rw-r--r--doc/classes/EditorNode3DGizmo.xml2
-rw-r--r--doc/classes/File.xml1
-rw-r--r--doc/classes/Line2D.xml2
-rw-r--r--doc/classes/Node.xml4
-rw-r--r--doc/classes/PhysicsServer3D.xml8
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/Rect2.xml1
-rw-r--r--doc/classes/Rect2i.xml1
-rw-r--r--doc/classes/SkeletonModification3DTwoBoneIK.xml2
-rw-r--r--doc/classes/Sprite3D.xml5
-rw-r--r--doc/classes/TextEdit.xml7
-rw-r--r--doc/classes/TranslationServer.xml2
-rw-r--r--doc/classes/Vector2.xml6
-rw-r--r--doc/classes/Vector3.xml18
-rw-r--r--doc/classes/VisualShaderNodeIntFunc.xml5
-rw-r--r--doc/classes/VisualShaderNodeIntOp.xml17
-rw-r--r--doc/classes/VoxelGIData.xml12
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp4
-rw-r--r--drivers/unix/file_access_unix.cpp3
-rw-r--r--drivers/windows/file_access_windows.cpp3
-rw-r--r--editor/audio_stream_preview.h3
-rw-r--r--editor/debugger/debug_adapter/debug_adapter_protocol.cpp41
-rw-r--r--editor/debugger/editor_debugger_inspector.cpp11
-rw-r--r--editor/editor_audio_buses.h3
-rw-r--r--editor/editor_data.cpp7
-rw-r--r--editor/editor_export.cpp5
-rw-r--r--editor/editor_file_dialog.cpp6
-rw-r--r--editor/localization_editor.cpp6
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp28
-rw-r--r--editor/plugins/curve_editor_plugin.cpp2
-rw-r--r--editor/plugins/node_3d_editor_gizmos.cpp4
-rw-r--r--editor/plugins/node_3d_editor_gizmos.h4
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp25
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp2
-rw-r--r--editor/plugins/theme_editor_preview.cpp6
-rw-r--r--editor/plugins/theme_editor_preview.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp6
-rw-r--r--editor/project_manager.cpp28
-rw-r--r--editor/scene_tree_dock.cpp3
-rw-r--r--main/SCsub13
-rw-r--r--main/main.cpp10
-rw-r--r--main/splash_editor.pngbin37471 -> 0 bytes
-rw-r--r--modules/bullet/godot_result_callbacks.cpp48
-rw-r--r--modules/bullet/godot_result_callbacks.h6
-rw-r--r--modules/gdscript/gdscript_function.h3
-rw-r--r--modules/gdscript/gdscript_parser.h3
-rw-r--r--modules/minimp3/audio_stream_mp3.cpp28
-rw-r--r--modules/minimp3/audio_stream_mp3.h2
-rw-r--r--modules/mono/editor/bindings_generator.h2
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs18
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs32
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs58
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs24
-rw-r--r--modules/mono/godotsharp_dirs.cpp3
-rw-r--r--modules/mono/mono_gc_handle.h3
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp11
-rw-r--r--modules/navigation/navigation_mesh_generator.cpp62
-rw-r--r--modules/navigation/navigation_mesh_generator.h8
-rw-r--r--platform/iphone/export/export_plugin.cpp5
-rw-r--r--platform/osx/export/export_plugin.cpp6
-rw-r--r--scene/2d/cpu_particles_2d.cpp2
-rw-r--r--scene/2d/path_2d.cpp14
-rw-r--r--scene/2d/path_2d.h1
-rw-r--r--scene/3d/cpu_particles_3d.cpp22
-rw-r--r--scene/3d/soft_dynamic_body_3d.cpp3
-rw-r--r--scene/3d/soft_dynamic_body_3d.h2
-rw-r--r--scene/3d/sprite_3d.cpp2
-rw-r--r--scene/gui/file_dialog.cpp20
-rw-r--r--scene/gui/line_edit.cpp18
-rw-r--r--scene/gui/scroll_container.h3
-rw-r--r--scene/gui/text_edit.cpp133
-rw-r--r--scene/gui/text_edit.h8
-rw-r--r--scene/main/viewport.cpp18
-rw-r--r--scene/register_scene_types.cpp14
-rw-r--r--scene/register_scene_types.h2
-rw-r--r--scene/resources/curve.cpp484
-rw-r--r--scene/resources/curve.h120
-rw-r--r--scene/resources/immediate_mesh.cpp3
-rw-r--r--scene/resources/immediate_mesh.h2
-rw-r--r--scene/resources/material.cpp15
-rw-r--r--scene/resources/particles_material.cpp2
-rw-r--r--scene/resources/visual_shader_nodes.cpp28
-rw-r--r--scene/resources/visual_shader_nodes.h6
-rw-r--r--scene/resources/visual_shader_particle_nodes.cpp157
-rw-r--r--scene/resources/visual_shader_particle_nodes.h1
-rw-r--r--servers/physics_server_2d.h3
-rw-r--r--servers/physics_server_3d.h3
-rw-r--r--servers/rendering/renderer_rd/shader_compiler_rd.cpp3
-rw-r--r--servers/rendering/rendering_device.cpp10
-rw-r--r--servers/rendering/shader_language.cpp131
-rw-r--r--servers/rendering/shader_language.h3
-rw-r--r--servers/rendering/shader_types.cpp30
-rw-r--r--servers/rendering/shader_warnings.cpp4
-rw-r--r--servers/rendering/shader_warnings.h2
-rw-r--r--servers/rendering_server.cpp62
-rw-r--r--servers/rendering_server.h57
-rw-r--r--tests/core/math/test_aabb.h21
-rw-r--r--tests/core/templates/test_oa_hash_map.cpp5
-rw-r--r--tests/scene/test_curve.h26
-rw-r--r--tests/servers/test_shader_lang.cpp2
-rw-r--r--thirdparty/README.md15
-rw-r--r--thirdparty/harfbuzz/src/hb-array.hh24
-rw-r--r--thirdparty/harfbuzz/src/hb-map.hh22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh22
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-common.hh10
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh21
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-layout.cc4
-rw-r--r--thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh31
-rw-r--r--thirdparty/harfbuzz/src/hb-sanitize.hh15
-rw-r--r--thirdparty/harfbuzz/src/hb-serialize.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-set.hh6
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.cc20
-rw-r--r--thirdparty/harfbuzz/src/hb-subset-plan.hh4
-rw-r--r--thirdparty/harfbuzz/src/hb-version.h4
-rw-r--r--thirdparty/minimp3/minimp3.h24
-rw-r--r--thirdparty/minimp3/minimp3_ex.h7
142 files changed, 1642 insertions, 969 deletions
diff --git a/DONORS.md b/DONORS.md
index 33a68650d9..f7026d9470 100644
--- a/DONORS.md
+++ b/DONORS.md
@@ -13,8 +13,6 @@ generous deed immortalized in the next stable release of Godot Engine.
## Platinum sponsors
Gamblify <https://www.gamblify.com>
- Heroic Labs <https://heroiclabs.com>
- Spiffcode <http://www.spiffcode.com>
## Gold sponsors
diff --git a/SConstruct b/SConstruct
index 83bd1560ff..1922e904d0 100644
--- a/SConstruct
+++ b/SConstruct
@@ -149,7 +149,7 @@ opts.Add(BoolVariable("disable_3d", "Disable 3D nodes for a smaller executable",
opts.Add(BoolVariable("disable_advanced_gui", "Disable advanced GUI nodes and behaviors", False))
opts.Add("disable_classes", "Disable given classes (comma separated)", "")
opts.Add(BoolVariable("modules_enabled_by_default", "If no, disable all modules except ones explicitly enabled", True))
-opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", False))
+opts.Add(BoolVariable("no_editor_splash", "Don't use the custom splash screen for the editor", True))
opts.Add("system_certs_path", "Use this path as SSL certificates default for editor (for package maintainers)", "")
opts.Add(BoolVariable("use_precise_math_checks", "Math checks use very precise epsilon (debug option)", False))
@@ -329,6 +329,9 @@ if env_base["target"] == "debug":
if env_base["use_precise_math_checks"]:
env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"])
+if not env_base.File("#main/splash_editor.png").exists():
+ # Force disabling editor splash if missing.
+ env_base["no_editor_splash"] = True
if env_base["no_editor_splash"]:
env_base.Append(CPPDEFINES=["NO_EDITOR_SPLASH"])
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index 8a44646ef9..bdceae4374 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -210,7 +210,7 @@ bool AStar::has_point(int p_id) const {
return points.has(p_id);
}
-Array AStar::get_points() {
+Array AStar::get_point_ids() {
Array point_list;
for (OAHashMap<int, Point *>::Iterator it = points.iter(); it.valid; it = points.next_iter(it)) {
@@ -539,7 +539,7 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar::is_point_disabled);
@@ -606,8 +606,8 @@ Vector<int> AStar2D::get_point_connections(int p_id) {
return astar.get_point_connections(p_id);
}
-Array AStar2D::get_points() {
- return astar.get_points();
+Array AStar2D::get_point_ids() {
+ return astar.get_point_ids();
}
void AStar2D::set_point_disabled(int p_id, bool p_disabled) {
@@ -859,7 +859,7 @@ void AStar2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar2D::remove_point);
ClassDB::bind_method(D_METHOD("has_point", "id"), &AStar2D::has_point);
ClassDB::bind_method(D_METHOD("get_point_connections", "id"), &AStar2D::get_point_connections);
- ClassDB::bind_method(D_METHOD("get_points"), &AStar2D::get_points);
+ ClassDB::bind_method(D_METHOD("get_point_ids"), &AStar2D::get_point_ids);
ClassDB::bind_method(D_METHOD("set_point_disabled", "id", "disabled"), &AStar2D::set_point_disabled, DEFVAL(true));
ClassDB::bind_method(D_METHOD("is_point_disabled", "id"), &AStar2D::is_point_disabled);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index 64fa32a325..ef6f22d228 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -138,7 +138,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
@@ -188,7 +188,7 @@ public:
void remove_point(int p_id);
bool has_point(int p_id) const;
Vector<int> get_point_connections(int p_id);
- Array get_points();
+ Array get_point_ids();
void set_point_disabled(int p_id, bool p_disabled = true);
bool is_point_disabled(int p_id) const;
diff --git a/core/math/aabb.cpp b/core/math/aabb.cpp
index f3e78c0080..83726f46b5 100644
--- a/core/math/aabb.cpp
+++ b/core/math/aabb.cpp
@@ -46,6 +46,11 @@ bool AABB::operator!=(const AABB &p_rval) const {
}
void AABB::merge_with(const AABB &p_aabb) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 beg_1, beg_2;
Vector3 end_1, end_2;
Vector3 min, max;
@@ -72,6 +77,11 @@ bool AABB::is_equal_approx(const AABB &p_aabb) const {
}
AABB AABB::intersection(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -104,6 +114,11 @@ AABB AABB::intersection(const AABB &p_aabb) const {
}
bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 c1, c2;
Vector3 end = position + size;
real_t near = -1e20;
@@ -147,6 +162,11 @@ bool AABB::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *
}
bool AABB::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vector3 *r_clip, Vector3 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
diff --git a/core/math/aabb.h b/core/math/aabb.h
index 02ce2501a0..81124002e2 100644
--- a/core/math/aabb.h
+++ b/core/math/aabb.h
@@ -132,6 +132,11 @@ public:
};
inline bool AABB::intersects(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x >= (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -155,6 +160,11 @@ inline bool AABB::intersects(const AABB &p_aabb) const {
}
inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (position.x > (p_aabb.position.x + p_aabb.size.x)) {
return false;
}
@@ -178,6 +188,11 @@ inline bool AABB::intersects_inclusive(const AABB &p_aabb) const {
}
inline bool AABB::encloses(const AABB &p_aabb) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0 || p_aabb.size.x < 0 || p_aabb.size.y < 0 || p_aabb.size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 src_min = position;
Vector3 src_max = position + size;
Vector3 dst_min = p_aabb.position;
@@ -288,6 +303,11 @@ bool AABB::inside_convex_shape(const Plane *p_planes, int p_plane_count) const {
}
bool AABB::has_point(const Vector3 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -311,6 +331,11 @@ bool AABB::has_point(const Vector3 &p_point) const {
}
inline void AABB::expand_to(const Vector3 &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
Vector3 begin = position;
Vector3 end = position + size;
@@ -377,6 +402,11 @@ inline real_t AABB::get_shortest_axis_size() const {
}
bool AABB::smits_intersect_ray(const Vector3 &p_from, const Vector3 &p_dir, real_t t0, real_t t1) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || size.z < 0)) {
+ ERR_PRINT("AABB size is negative, this is not supported. Use AABB.abs() to get an AABB with a positive size.");
+ }
+#endif
real_t divx = 1.0 / p_dir.x;
real_t divy = 1.0 / p_dir.y;
real_t divz = 1.0 / p_dir.z;
diff --git a/core/math/audio_frame.h b/core/math/audio_frame.h
index a5616b8d79..4a11b99fe8 100644
--- a/core/math/audio_frame.h
+++ b/core/math/audio_frame.h
@@ -124,10 +124,9 @@ struct AudioFrame {
r = p_frame.r;
}
- _ALWAYS_INLINE_ AudioFrame &operator=(const AudioFrame &p_frame) {
+ _ALWAYS_INLINE_ void operator=(const AudioFrame &p_frame) {
l = p_frame.l;
r = p_frame.r;
- return *this;
}
_ALWAYS_INLINE_ operator Vector2() const {
diff --git a/core/math/expression.cpp b/core/math/expression.cpp
index f366fd0499..fe277cff96 100644
--- a/core/math/expression.cpp
+++ b/core/math/expression.cpp
@@ -410,6 +410,14 @@ Error Expression::_get_token(Token &r_token) {
} else if (id == "self") {
r_token.type = TK_SELF;
} else {
+ for (int i = 0; i < Variant::VARIANT_MAX; i++) {
+ if (id == Variant::get_type_name(Variant::Type(i))) {
+ r_token.type = TK_BASIC_TYPE;
+ r_token.value = i;
+ return OK;
+ }
+ }
+
if (Variant::has_utility_function(id)) {
r_token.type = TK_BUILTIN_FUNC;
r_token.value = id;
diff --git a/core/math/quaternion.h b/core/math/quaternion.h
index d8d0c06672..457d167516 100644
--- a/core/math/quaternion.h
+++ b/core/math/quaternion.h
@@ -134,12 +134,11 @@ public:
w(p_q.w) {
}
- Quaternion &operator=(const Quaternion &p_q) {
+ void operator=(const Quaternion &p_q) {
x = p_q.x;
y = p_q.y;
z = p_q.z;
w = p_q.w;
- return *this;
}
Quaternion(const Vector3 &v0, const Vector3 &v1) // shortest arc
diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp
index f64bf560c8..0e6127b017 100644
--- a/core/math/rect2.cpp
+++ b/core/math/rect2.cpp
@@ -35,6 +35,11 @@ bool Rect2::is_equal_approx(const Rect2 &p_rect) const {
}
bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos, Point2 *r_normal) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t min = 0, max = 1;
int axis = 0;
real_t sign = 0;
@@ -95,6 +100,11 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
}
bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
//SAT intersection between local and transformed rect2
Vector2 xf_points[4] = {
diff --git a/core/math/rect2.h b/core/math/rect2.h
index 26e202589d..7029204cf1 100644
--- a/core/math/rect2.h
+++ b/core/math/rect2.h
@@ -49,6 +49,11 @@ struct Rect2 {
_FORCE_INLINE_ Vector2 get_center() const { return position + (size * 0.5); }
inline bool intersects(const Rect2 &p_rect, const bool p_include_borders = false) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_include_borders) {
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
@@ -81,6 +86,11 @@ struct Rect2 {
}
inline real_t distance_to(const Vector2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
real_t dist = 0.0;
bool inside = true;
@@ -117,6 +127,11 @@ struct Rect2 {
bool intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2 *r_pos = nullptr, Point2 *r_normal = nullptr) const;
inline bool encloses(const Rect2 &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) <= (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) <= (position.y + size.y));
@@ -147,7 +162,11 @@ struct Rect2 {
}
inline Rect2 merge(const Rect2 &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -161,6 +180,11 @@ struct Rect2 {
return new_rect;
}
inline bool has_point(const Point2 &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -183,6 +207,11 @@ struct Rect2 {
bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.grow_by(p_amount);
return g;
@@ -209,6 +238,11 @@ struct Rect2 {
}
inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Rect2 g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -225,7 +259,11 @@ struct Rect2 {
}
inline void expand_to(const Vector2 &p_vector) { //in place function for speed
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2 size is negative, this is not supported. Use Rect2.abs() to get a Rect2 with a positive size.");
+ }
+#endif
Vector2 begin = position;
Vector2 end = position + size;
@@ -349,6 +387,11 @@ struct Rect2i {
_FORCE_INLINE_ Vector2i get_center() const { return position + (size / 2); }
inline bool intersects(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (position.x > (p_rect.position.x + p_rect.size.width)) {
return false;
}
@@ -366,6 +409,11 @@ struct Rect2i {
}
inline bool encloses(const Rect2i &p_rect) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
@@ -389,14 +437,18 @@ struct Rect2i {
Point2i p_rect_end = p_rect.position + p_rect.size;
Point2i end = position + size;
- new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
- new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
+ new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
+ new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
return new_rect;
}
inline Rect2i merge(const Rect2i &p_rect) const { ///< return a merged rect
-
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0 || p_rect.size.x < 0 || p_rect.size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i new_rect;
new_rect.position.x = MIN(p_rect.position.x, position.x);
@@ -410,6 +462,11 @@ struct Rect2i {
return new_rect;
}
bool has_point(const Point2i &p_point) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
if (p_point.x < position.x) {
return false;
}
@@ -431,6 +488,11 @@ struct Rect2i {
bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_amount) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_amount;
g.position.y -= p_amount;
@@ -453,6 +515,11 @@ struct Rect2i {
}
inline Rect2i grow_individual(int p_left, int p_top, int p_right, int p_bottom) const {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Rect2i g = *this;
g.position.x -= p_left;
g.position.y -= p_top;
@@ -469,6 +536,11 @@ struct Rect2i {
}
inline void expand_to(const Point2i &p_vector) {
+#ifdef MATH_CHECKS
+ if (unlikely(size.x < 0 || size.y < 0)) {
+ ERR_PRINT("Rect2i size is negative, this is not supported. Use Rect2i.abs() to get a Rect2i with a positive size.");
+ }
+#endif
Point2i begin = position;
Point2i end = position + size;
diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp
index 42e3da0b27..b9bd04b8c1 100644
--- a/core/math/vector3.cpp
+++ b/core/math/vector3.cpp
@@ -108,10 +108,10 @@ Vector3 Vector3::move_toward(const Vector3 &p_to, const real_t p_delta) const {
return len <= p_delta || len < CMP_EPSILON ? p_to : v + vd / len * p_delta;
}
-Basis Vector3::outer(const Vector3 &p_b) const {
- Vector3 row0(x * p_b.x, x * p_b.y, x * p_b.z);
- Vector3 row1(y * p_b.x, y * p_b.y, y * p_b.z);
- Vector3 row2(z * p_b.x, z * p_b.y, z * p_b.z);
+Basis Vector3::outer(const Vector3 &p_with) const {
+ Vector3 row0(x * p_with.x, x * p_with.y, x * p_with.z);
+ Vector3 row1(y * p_with.x, y * p_with.y, y * p_with.z);
+ Vector3 row2(z * p_with.x, z * p_with.y, z * p_with.z);
return Basis(row0, row1, row2);
}
diff --git a/core/math/vector3.h b/core/math/vector3.h
index 02a56f684e..6c21968aae 100644
--- a/core/math/vector3.h
+++ b/core/math/vector3.h
@@ -128,9 +128,9 @@ struct Vector3 {
return n.normalized();
}
- _FORCE_INLINE_ Vector3 cross(const Vector3 &p_b) const;
- _FORCE_INLINE_ real_t dot(const Vector3 &p_b) const;
- Basis outer(const Vector3 &p_b) const;
+ _FORCE_INLINE_ Vector3 cross(const Vector3 &p_with) const;
+ _FORCE_INLINE_ real_t dot(const Vector3 &p_with) const;
+ Basis outer(const Vector3 &p_with) const;
_FORCE_INLINE_ Vector3 abs() const;
_FORCE_INLINE_ Vector3 floor() const;
@@ -199,17 +199,17 @@ struct Vector3 {
}
};
-Vector3 Vector3::cross(const Vector3 &p_b) const {
+Vector3 Vector3::cross(const Vector3 &p_with) const {
Vector3 ret(
- (y * p_b.z) - (z * p_b.y),
- (z * p_b.x) - (x * p_b.z),
- (x * p_b.y) - (y * p_b.x));
+ (y * p_with.z) - (z * p_with.y),
+ (z * p_with.x) - (x * p_with.z),
+ (x * p_with.y) - (y * p_with.x));
return ret;
}
-real_t Vector3::dot(const Vector3 &p_b) const {
- return x * p_b.x + y * p_b.y + z * p_b.z;
+real_t Vector3::dot(const Vector3 &p_with) const {
+ return x * p_with.x + y * p_with.y + z * p_with.z;
}
Vector3 Vector3::abs() const {
diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp
index 320aae2ba4..8d1f610578 100644
--- a/core/string/ustring.cpp
+++ b/core/string/ustring.cpp
@@ -130,9 +130,8 @@ Char16String &Char16String::operator+=(char16_t p_char) {
return *this;
}
-Char16String &Char16String::operator=(const char16_t *p_cstr) {
+void Char16String::operator=(const char16_t *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char16_t *Char16String::get_data() const {
@@ -186,9 +185,8 @@ CharString &CharString::operator+=(char p_char) {
return *this;
}
-CharString &CharString::operator=(const char *p_cstr) {
+void CharString::operator=(const char *p_cstr) {
copy_from(p_cstr);
- return *this;
}
const char *CharString::get_data() const {
diff --git a/core/string/ustring.h b/core/string/ustring.h
index f25c36f66c..396c996050 100644
--- a/core/string/ustring.h
+++ b/core/string/ustring.h
@@ -108,13 +108,10 @@ public:
_FORCE_INLINE_ Char16String() {}
_FORCE_INLINE_ Char16String(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ Char16String &operator=(const Char16String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const Char16String &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ Char16String(const char16_t *p_cstr) { copy_from(p_cstr); }
- Char16String &operator=(const char16_t *p_cstr);
+ void operator=(const char16_t *p_cstr);
bool operator<(const Char16String &p_right) const;
Char16String &operator+=(char16_t p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -152,13 +149,10 @@ public:
_FORCE_INLINE_ CharString() {}
_FORCE_INLINE_ CharString(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
- _FORCE_INLINE_ CharString &operator=(const CharString &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const CharString &p_str) { _cowdata._ref(p_str._cowdata); }
_FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
- CharString &operator=(const char *p_cstr);
+ void operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
@@ -442,11 +436,7 @@ public:
_FORCE_INLINE_ String() {}
_FORCE_INLINE_ String(const String &p_str) { _cowdata._ref(p_str._cowdata); }
-
- String &operator=(const String &p_str) {
- _cowdata._ref(p_str._cowdata);
- return *this;
- }
+ _FORCE_INLINE_ void operator=(const String &p_str) { _cowdata._ref(p_str._cowdata); }
Vector<uint8_t> to_ascii_buffer() const;
Vector<uint8_t> to_utf8_buffer() const;
diff --git a/core/templates/local_vector.h b/core/templates/local_vector.h
index 3854e1e94c..4ec08821f8 100644
--- a/core/templates/local_vector.h
+++ b/core/templates/local_vector.h
@@ -234,19 +234,17 @@ public:
data[i] = p_from.data[i];
}
}
- inline LocalVector &operator=(const LocalVector &p_from) {
+ inline void operator=(const LocalVector &p_from) {
resize(p_from.size());
for (U i = 0; i < p_from.count; i++) {
data[i] = p_from.data[i];
}
- return *this;
}
- inline LocalVector &operator=(const Vector<T> &p_from) {
+ inline void operator=(const Vector<T> &p_from) {
resize(p_from.size());
for (U i = 0; i < count; i++) {
data[i] = p_from[i];
}
- return *this;
}
_FORCE_INLINE_ ~LocalVector() {
diff --git a/core/templates/oa_hash_map.h b/core/templates/oa_hash_map.h
index 025cc30db4..9dab36e343 100644
--- a/core/templates/oa_hash_map.h
+++ b/core/templates/oa_hash_map.h
@@ -353,7 +353,7 @@ public:
(*this) = p_other;
}
- OAHashMap &operator=(const OAHashMap &p_other) {
+ void operator=(const OAHashMap &p_other) {
if (capacity != 0) {
clear();
}
@@ -363,7 +363,6 @@ public:
for (Iterator it = p_other.iter(); it.valid; it = p_other.next_iter(it)) {
set(*it.key, *it.value);
}
- return *this;
}
OAHashMap(uint32_t p_initial_capacity = 64) {
diff --git a/core/templates/ordered_hash_map.h b/core/templates/ordered_hash_map.h
index 4996b88190..928072bb18 100644
--- a/core/templates/ordered_hash_map.h
+++ b/core/templates/ordered_hash_map.h
@@ -85,11 +85,10 @@ public:
next_element(other.next_element) {
}
- Element &operator=(const Element &other) {
+ void operator=(const Element &other) {
list_element = other.list_element;
next_element = other.next_element;
prev_element = other.prev_element;
- return *this;
}
_FORCE_INLINE_ bool operator==(const Element &p_other) const {
@@ -145,9 +144,8 @@ public:
list_element(other.list_element) {
}
- ConstElement &operator=(const ConstElement &other) {
+ void operator=(const ConstElement &other) {
list_element = other.list_element;
- return *this;
}
ConstElement next() const {
diff --git a/core/templates/vector.h b/core/templates/vector.h
index a955d49101..376d5cbeff 100644
--- a/core/templates/vector.h
+++ b/core/templates/vector.h
@@ -132,9 +132,8 @@ public:
insert(i, p_val);
}
- inline Vector &operator=(const Vector &p_from) {
+ inline void operator=(const Vector &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
Vector<uint8_t> to_byte_array() const {
diff --git a/core/templates/vmap.h b/core/templates/vmap.h
index 2aa22f97cf..0ff105ccbf 100644
--- a/core/templates/vmap.h
+++ b/core/templates/vmap.h
@@ -193,9 +193,8 @@ public:
_FORCE_INLINE_ VMap() {}
_FORCE_INLINE_ VMap(const VMap &p_from) { _cowdata._ref(p_from._cowdata); }
- inline VMap &operator=(const VMap &p_from) {
+ inline void operator=(const VMap &p_from) {
_cowdata._ref(p_from._cowdata);
- return *this;
}
};
diff --git a/core/variant/variant_call.cpp b/core/variant/variant_call.cpp
index 34b8b782d2..b586757dcd 100644
--- a/core/variant/variant_call.cpp
+++ b/core/variant/variant_call.cpp
@@ -1471,7 +1471,7 @@ static void _register_variant_builtin_methods() {
bind_method(Vector2, angle, sarray(), varray());
bind_method(Vector2, angle_to, sarray("to"), varray());
bind_method(Vector2, angle_to_point, sarray("to"), varray());
- bind_method(Vector2, direction_to, sarray("b"), varray());
+ bind_method(Vector2, direction_to, sarray("to"), varray());
bind_method(Vector2, distance_to, sarray("to"), varray());
bind_method(Vector2, distance_squared_to, sarray("to"), varray());
bind_method(Vector2, length, sarray(), varray());
@@ -1551,9 +1551,9 @@ static void _register_variant_builtin_methods() {
bind_method(Vector3, max_axis, sarray(), varray());
bind_method(Vector3, angle_to, sarray("to"), varray());
bind_method(Vector3, signed_angle_to, sarray("to", "axis"), varray());
- bind_method(Vector3, direction_to, sarray("b"), varray());
- bind_method(Vector3, distance_to, sarray("b"), varray());
- bind_method(Vector3, distance_squared_to, sarray("b"), varray());
+ bind_method(Vector3, direction_to, sarray("to"), varray());
+ bind_method(Vector3, distance_to, sarray("to"), varray());
+ bind_method(Vector3, distance_squared_to, sarray("to"), varray());
bind_method(Vector3, length, sarray(), varray());
bind_method(Vector3, length_squared, sarray(), varray());
bind_method(Vector3, limit_length, sarray("length"), varray(1.0));
diff --git a/doc/classes/AABB.xml b/doc/classes/AABB.xml
index 170cfea6f9..bdf8a78dc3 100644
--- a/doc/classes/AABB.xml
+++ b/doc/classes/AABB.xml
@@ -6,6 +6,7 @@
<description>
[AABB] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses floating-point coordinates. The 2D counterpart to [AABB] is [Rect2].
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get an AABB with a positive size.
[b]Note:[/b] Unlike [Rect2], [AABB] does not have a variant that uses integer coordinates.
</description>
<tutorials>
@@ -157,14 +158,15 @@
<return type="bool" />
<argument index="0" name="point" type="Vector3" />
<description>
- Returns [code]true[/code] if the [AABB] contains a point.
+ Returns [code]true[/code] if the [AABB] contains a point. Points on the faces of the AABB are considered included, though float-point precision errors may impact the accuracy of such checks.
+ [b]Note:[/b] This method is not reliable for [AABB] with a [i]negative size[/i]. Use [method abs] to get a positive sized equivalent [AABB] to check for contained points.
</description>
</method>
<method name="intersection" qualifiers="const">
<return type="AABB" />
<argument index="0" name="with" type="AABB" />
<description>
- Returns the intersection between two [AABB]. An empty AABB (size 0,0,0) is returned on failure.
+ Returns the intersection between two [AABB]. An empty AABB (size [code](0, 0, 0)[/code]) is returned on failure.
</description>
</method>
<method name="intersects" qualifiers="const">
diff --git a/doc/classes/AStar.xml b/doc/classes/AStar.xml
index 11c0fc33b8..bbb5f6b8e3 100644
--- a/doc/classes/AStar.xml
+++ b/doc/classes/AStar.xml
@@ -244,6 +244,12 @@
Returns the number of points currently in the points pool.
</description>
</method>
+ <method name="get_point_ids">
+ <return type="Array" />
+ <description>
+ Returns an array of all point IDs.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PackedVector3Array" />
<argument index="0" name="from_id" type="int" />
@@ -267,12 +273,6 @@
Returns the weight scale of the point associated with the given [code]id[/code].
</description>
</method>
- <method name="get_points">
- <return type="Array" />
- <description>
- Returns an array of all points.
- </description>
- </method>
<method name="has_point" qualifiers="const">
<return type="bool" />
<argument index="0" name="id" type="int" />
diff --git a/doc/classes/AStar2D.xml b/doc/classes/AStar2D.xml
index 43e7d59665..dc821ebb8b 100644
--- a/doc/classes/AStar2D.xml
+++ b/doc/classes/AStar2D.xml
@@ -215,6 +215,12 @@
Returns the number of points currently in the points pool.
</description>
</method>
+ <method name="get_point_ids">
+ <return type="Array" />
+ <description>
+ Returns an array of all point IDs.
+ </description>
+ </method>
<method name="get_point_path">
<return type="PackedVector2Array" />
<argument index="0" name="from_id" type="int" />
@@ -238,12 +244,6 @@
Returns the weight scale of the point associated with the given [code]id[/code].
</description>
</method>
- <method name="get_points">
- <return type="Array" />
- <description>
- Returns an array of all points.
- </description>
- </method>
<method name="has_point" qualifiers="const">
<return type="bool" />
<argument index="0" name="id" type="int" />
diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml
index f0f49f89d5..aa2ffae48c 100644
--- a/doc/classes/BaseMaterial3D.xml
+++ b/doc/classes/BaseMaterial3D.xml
@@ -53,6 +53,7 @@
<argument index="1" name="texture" type="Texture2D" />
<description>
Sets the texture for the slot specified by [code]param[/code]. See [enum TextureParam] for available slots.
+ [b]Note:[/b] When setting a roughness or metallic texture on a material that has no texture assigned to those slots, [member roughness] or [member metallic] will automatically be set to [code]1.0[/code] to ensure correct appearance.
</description>
</method>
</methods>
@@ -229,6 +230,7 @@
</member>
<member name="metallic" type="float" setter="set_metallic" getter="get_metallic" default="0.0">
A high value makes the material appear more like a metal. Non-metals use their albedo as the diffuse color and add diffuse to the specular reflection. With non-metals, the reflection appears on top of the albedo color. Metals use their albedo as a multiplier to the specular reflection and set the diffuse color to black resulting in a tinted reflection. Materials work better when fully metal or fully non-metal, values between [code]0[/code] and [code]1[/code] should only be used for blending between metal and non-metal sections. To alter the amount of reflection use [member roughness].
+ [b]Note:[/b] [member metallic] is automatically set to [code]1.0[/code] when assigning a metallic texture using [method set_texture].
</member>
<member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" default="0.5">
Sets the size of the specular lobe. The specular lobe is the bright spot that is reflected from light sources.
@@ -301,6 +303,7 @@
</member>
<member name="roughness" type="float" setter="set_roughness" getter="get_roughness" default="1.0">
Surface reflection. A value of [code]0[/code] represents a perfect mirror while a value of [code]1[/code] completely blurs the reflection. See also [member metallic].
+ [b]Note:[/b] [member roughness] is automatically set to [code]1.0[/code] when assigning a roughness texture using [method set_texture].
</member>
<member name="roughness_texture" type="Texture2D" setter="set_texture" getter="get_texture">
Texture used to control the roughness per-pixel. Multiplied by [member roughness].
diff --git a/doc/classes/Camera3D.xml b/doc/classes/Camera3D.xml
index 06e2f83f05..772396befe 100644
--- a/doc/classes/Camera3D.xml
+++ b/doc/classes/Camera3D.xml
@@ -218,10 +218,10 @@
Disables [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] simulation (default).
</constant>
<constant name="DOPPLER_TRACKING_IDLE_STEP" value="1" enum="DopplerTracking">
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
+ Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
</constant>
<constant name="DOPPLER_TRACKING_PHYSICS_STEP" value="2" enum="DopplerTracking">
- Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how Audio is perceived (changing the Audio's [code]pitch shift[/code]).
+ Simulate [url=https://en.wikipedia.org/wiki/Doppler_effect]Doppler effect[/url] by tracking positions of objects that are changed in [code]_physics_process[/code]. Changes in the relative velocity of this camera compared to those objects affect how audio is perceived (changing the audio's [member AudioStreamPlayer3D.pitch_scale]).
</constant>
</constants>
</class>
diff --git a/doc/classes/EditorNode3DGizmo.xml b/doc/classes/EditorNode3DGizmo.xml
index c804bb70e0..60c329935a 100644
--- a/doc/classes/EditorNode3DGizmo.xml
+++ b/doc/classes/EditorNode3DGizmo.xml
@@ -135,7 +135,7 @@
</method>
<method name="add_mesh">
<return type="void" />
- <argument index="0" name="mesh" type="ArrayMesh" />
+ <argument index="0" name="mesh" type="Mesh" />
<argument index="1" name="material" type="Material" default="null" />
<argument index="2" name="transform" type="Transform3D" default="Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0)" />
<argument index="3" name="skeleton" type="SkinReference" default="null" />
diff --git a/doc/classes/File.xml b/doc/classes/File.xml
index 276c1f0223..0dac9a379a 100644
--- a/doc/classes/File.xml
+++ b/doc/classes/File.xml
@@ -417,6 +417,7 @@
<argument index="0" name="string" type="String" />
<description>
Appends [code]string[/code] to the file without a line return, encoding the text as UTF-8.
+ [b]Note:[/b] This method is intended to be used to write text files. The string is stored as a UTF-8 encoded buffer without string length or terminating zero, which means that it can't be loaded back easily. If you want to store a retrievable string in a binary file, consider using [method store_pascal_string] instead. For retrieving strings from a text file, you can use [code]get_buffer(length).get_string_from_utf8()[/code] (if you know the length) or [method get_as_text].
</description>
</method>
<method name="store_var">
diff --git a/doc/classes/Line2D.xml b/doc/classes/Line2D.xml
index 4d9abbbb19..5e673cc19b 100644
--- a/doc/classes/Line2D.xml
+++ b/doc/classes/Line2D.xml
@@ -82,7 +82,7 @@
The smoothness of the rounded joints and caps. This is only used if a cap or joint is set as round.
</member>
<member name="sharp_limit" type="float" setter="set_sharp_limit" getter="get_sharp_limit" default="2.0">
- The direction difference in radians between vector points. This value is only used if [code]joint mode[/code] is set to [constant LINE_JOINT_SHARP].
+ The direction difference in radians between vector points. This value is only used if [member joint_mode] is set to [constant LINE_JOINT_SHARP].
</member>
<member name="texture" type="Texture2D" setter="set_texture" getter="get_texture">
The texture used for the line's texture. Uses [code]texture_mode[/code] for drawing style.
diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml
index c75b2e305e..f1ab5e4843 100644
--- a/doc/classes/Node.xml
+++ b/doc/classes/Node.xml
@@ -261,7 +261,7 @@
<return type="Node" />
<argument index="0" name="path" type="NodePath" />
<description>
- Fetches a node. The [NodePath] can be either a relative path (from the current node) or an absolute path (in the scene tree) to a node. If the path does not exist, a [code]null instance[/code] is returned and an error is logged. Attempts to access methods on the return value will result in an "Attempt to call &lt;method&gt; on a null instance." error.
+ Fetches a node. The [NodePath] can be either a relative path (from the current node) or an absolute path (in the scene tree) to a node. If the path does not exist, [code]null[/code] is returned and an error is logged. Attempts to access methods on the return value will result in an "Attempt to call &lt;method&gt; on a null instance." error.
[b]Note:[/b] Fetching absolute paths only works when the node is inside the scene tree (see [method is_inside_tree]).
[b]Example:[/b] Assume your current node is Character and the following tree:
[codeblock]
@@ -322,7 +322,7 @@
<method name="get_parent" qualifiers="const">
<return type="Node" />
<description>
- Returns the parent node of the current node, or a [code]null instance[/code] if the node lacks a parent.
+ Returns the parent node of the current node, or [code]null[/code] if the node lacks a parent.
</description>
</method>
<method name="get_path" qualifiers="const">
diff --git a/doc/classes/PhysicsServer3D.xml b/doc/classes/PhysicsServer3D.xml
index dd8003be1d..ceb3e788d2 100644
--- a/doc/classes/PhysicsServer3D.xml
+++ b/doc/classes/PhysicsServer3D.xml
@@ -1152,16 +1152,16 @@
Maximum acceleration for the motor at the axes.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_LINEAR_LIMIT" value="0" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is linear motion possible within the given limits.
+ If set, linear motion is possible within the given limits.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_ANGULAR_LIMIT" value="1" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is rotational motion possible.
+ If set, rotational motion is possible.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_MOTOR" value="4" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is a rotational motor across these axes.
+ If set, there is a rotational motor across these axes.
</constant>
<constant name="G6DOF_JOINT_FLAG_ENABLE_LINEAR_MOTOR" value="5" enum="G6DOFJointAxisFlag">
- If [code]set[/code] there is a linear motor on this axis that targets a specific velocity.
+ If set, there is a linear motor on this axis that targets a specific velocity.
</constant>
<constant name="SHAPE_WORLD_BOUNDARY" value="0" enum="ShapeType">
The [Shape3D] is a [WorldBoundaryShape3D].
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 7fdac7ccd4..e0371a6a4a 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1576,7 +1576,7 @@
Default background clear color. Overridable per [Viewport] using its [Environment]. See [member Environment.background_mode] and [member Environment.background_color] in particular. To change this default color programmatically, use [method RenderingServer.set_default_clear_color].
</member>
<member name="rendering/environment/defaults/default_environment" type="String" setter="" getter="" default="&quot;&quot;">
- [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, it is best to delete [code]default_env.tres[/code], or to specify a different default environment here.
+ [Environment] that will be used as a fallback environment in case a scene does not specify its own environment. The default environment is loaded in at scene load time regardless of whether you have set an environment or not. If you do not rely on the fallback environment, you do not need to set this property.
</member>
<member name="rendering/environment/glow/upscale_mode" type="int" setter="" getter="" default="1">
Sets how the glow effect is upscaled before being copied onto the screen. Linear is faster, but looks blocky. Bicubic is slower but looks smooth.
diff --git a/doc/classes/Rect2.xml b/doc/classes/Rect2.xml
index 4dc3859ca5..65d1654c21 100644
--- a/doc/classes/Rect2.xml
+++ b/doc/classes/Rect2.xml
@@ -7,6 +7,7 @@
[Rect2] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses floating-point coordinates. If you need integer coordinates, use [Rect2i] instead.
The 3D counterpart to [Rect2] is [AABB].
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get a Rect2 with a positive size.
</description>
<tutorials>
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
diff --git a/doc/classes/Rect2i.xml b/doc/classes/Rect2i.xml
index d66b589ec1..5909784135 100644
--- a/doc/classes/Rect2i.xml
+++ b/doc/classes/Rect2i.xml
@@ -6,6 +6,7 @@
<description>
[Rect2i] consists of a position, a size, and several utility functions. It is typically used for fast overlap tests.
It uses integer coordinates. If you need floating-point coordinates, use [Rect2] instead.
+ Negative values for [member size] are not supported and will not work for most methods. Use [method abs] to get a Rect2i with a positive size.
</description>
<tutorials>
<link title="Math documentation index">$DOCS_URL/tutorials/math/index.html</link>
diff --git a/doc/classes/SkeletonModification3DTwoBoneIK.xml b/doc/classes/SkeletonModification3DTwoBoneIK.xml
index 80f8ba4e5b..0e83cd0b28 100644
--- a/doc/classes/SkeletonModification3DTwoBoneIK.xml
+++ b/doc/classes/SkeletonModification3DTwoBoneIK.xml
@@ -4,7 +4,7 @@
A modification that moves two bones to reach the target.
</brief_description>
<description>
- This [SkeletonModification3D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns and the lengths of the bones to figure out what rotation the bones currently have, and what rotation they need to make a complete triangle, where the first bone, the second bone, and the target form the three verticies of the triangle. Because the algorithm works by making a triangle, it can only opperate on two bones.
+ This [SkeletonModification3D] uses an algorithm typically called TwoBoneIK. This algorithm works by leveraging the law of cosigns and the lengths of the bones to figure out what rotation the bones currently have, and what rotation they need to make a complete triangle, where the first bone, the second bone, and the target form the three vertices of the triangle. Because the algorithm works by making a triangle, it can only opperate on two bones.
TwoBoneIK is great for arms, legs, and really any joints that can be represented by just two bones that bend to reach a target. This solver is more lightweight than [SkeletonModification3DFABRIK], but gives similar, natural looking results.
A [Node3D]-based node can be used to define the pole, or bend direction, allowing control over which direction the joint takes when bending to reach the target when the target is within reach.
</description>
diff --git a/doc/classes/Sprite3D.xml b/doc/classes/Sprite3D.xml
index 5a7fd537e0..4ad78429e9 100644
--- a/doc/classes/Sprite3D.xml
+++ b/doc/classes/Sprite3D.xml
@@ -36,5 +36,10 @@
Emitted when the [member frame] changes.
</description>
</signal>
+ <signal name="texture_changed">
+ <description>
+ Emitted when the [member texture] changes.
+ </description>
+ </signal>
</signals>
</class>
diff --git a/doc/classes/TextEdit.xml b/doc/classes/TextEdit.xml
index 16d8595b4e..d14f8a9b35 100644
--- a/doc/classes/TextEdit.xml
+++ b/doc/classes/TextEdit.xml
@@ -586,6 +586,13 @@
Returns whether the menu is visible. Use this instead of [code]get_menu().visible[/code] to improve performance (so the creation of the menu is avoided).
</description>
</method>
+ <method name="is_mouse_over_selection" qualifiers="const">
+ <return type="bool" />
+ <argument index="0" name="edges" type="bool" />
+ <description>
+ Returns whether the mouse is over selection. If [code]edges[/code] is [code]true[/code], the edges are considered part of the selection.
+ </description>
+ </method>
<method name="is_overtype_mode_enabled" qualifiers="const">
<return type="bool" />
<description>
diff --git a/doc/classes/TranslationServer.xml b/doc/classes/TranslationServer.xml
index 519e1cb041..a1b4404079 100644
--- a/doc/classes/TranslationServer.xml
+++ b/doc/classes/TranslationServer.xml
@@ -49,7 +49,7 @@
<argument index="0" name="locale" type="String" />
<description>
Returns the [Translation] instance based on the [code]locale[/code] passed in.
- It will return a [code]nullptr[/code] if there is no [Translation] instance that matches the [code]locale[/code].
+ It will return [code]null[/code] if there is no [Translation] instance that matches the [code]locale[/code].
</description>
</method>
<method name="pseudolocalize" qualifiers="const">
diff --git a/doc/classes/Vector2.xml b/doc/classes/Vector2.xml
index 431815e75a..15f7d2f9e3 100644
--- a/doc/classes/Vector2.xml
+++ b/doc/classes/Vector2.xml
@@ -125,16 +125,16 @@
</method>
<method name="direction_to" qualifiers="const">
<return type="Vector2" />
- <argument index="0" name="b" type="Vector2" />
+ <argument index="0" name="to" type="Vector2" />
<description>
- Returns the normalized vector pointing from this vector to [code]b[/code]. This is equivalent to using [code](b - a).normalized()[/code].
+ Returns the normalized vector pointing from this vector to [code]to[/code]. This is equivalent to using [code](b - a).normalized()[/code].
</description>
</method>
<method name="distance_squared_to" qualifiers="const">
<return type="float" />
<argument index="0" name="to" type="Vector2" />
<description>
- Returns the squared distance between this vector and [code]b[/code].
+ Returns the squared distance between this vector and [code]to[/code].
This method runs faster than [method distance_to], so prefer it if you need to compare vectors or need the squared distance for some formula.
</description>
</method>
diff --git a/doc/classes/Vector3.xml b/doc/classes/Vector3.xml
index 6d20cc85ea..6d87ce9ea8 100644
--- a/doc/classes/Vector3.xml
+++ b/doc/classes/Vector3.xml
@@ -86,7 +86,7 @@
<return type="Vector3" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the cross product of this vector and [code]b[/code].
+ Returns the cross product of this vector and [code]with[/code].
</description>
</method>
<method name="cubic_interpolate" qualifiers="const">
@@ -101,31 +101,31 @@
</method>
<method name="direction_to" qualifiers="const">
<return type="Vector3" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the normalized vector pointing from this vector to [code]b[/code]. This is equivalent to using [code](b - a).normalized()[/code].
+ Returns the normalized vector pointing from this vector to [code]to[/code]. This is equivalent to using [code](b - a).normalized()[/code].
</description>
</method>
<method name="distance_squared_to" qualifiers="const">
<return type="float" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the squared distance between this vector and [code]b[/code].
+ Returns the squared distance between this vector and [code]to[/code].
This method runs faster than [method distance_to], so prefer it if you need to compare vectors or need the squared distance for some formula.
</description>
</method>
<method name="distance_to" qualifiers="const">
<return type="float" />
- <argument index="0" name="b" type="Vector3" />
+ <argument index="0" name="to" type="Vector3" />
<description>
- Returns the distance between this vector and [code]b[/code].
+ Returns the distance between this vector and [code]to[/code].
</description>
</method>
<method name="dot" qualifiers="const">
<return type="float" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the dot product of this vector and [code]b[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player.
+ Returns the dot product of this vector and [code]with[/code]. This can be used to compare the angle between two vectors. For example, this can be used to determine whether an enemy is facing the player.
The dot product will be [code]0[/code] for a straight angle (90 degrees), greater than 0 for angles narrower than 90 degrees and lower than 0 for angles wider than 90 degrees.
When using unit (normalized) vectors, the result will always be between [code]-1.0[/code] (180 degree angle) when the vectors are facing opposite directions, and [code]1.0[/code] (0 degree angle) when the vectors are aligned.
[b]Note:[/b] [code]a.dot(b)[/code] is equivalent to [code]b.dot(a)[/code].
@@ -225,7 +225,7 @@
<return type="Basis" />
<argument index="0" name="with" type="Vector3" />
<description>
- Returns the outer product with [code]b[/code].
+ Returns the outer product with [code]with[/code].
</description>
</method>
<method name="posmod" qualifiers="const">
diff --git a/doc/classes/VisualShaderNodeIntFunc.xml b/doc/classes/VisualShaderNodeIntFunc.xml
index d2782efa96..316529a347 100644
--- a/doc/classes/VisualShaderNodeIntFunc.xml
+++ b/doc/classes/VisualShaderNodeIntFunc.xml
@@ -23,7 +23,10 @@
<constant name="FUNC_SIGN" value="2" enum="Function">
Extracts the sign of the parameter. Translates to [code]sign(x)[/code] in the Godot Shader Language.
</constant>
- <constant name="FUNC_MAX" value="3" enum="Function">
+ <constant name="FUNC_BITWISE_NOT" value="3" enum="Function">
+ Returns the result of bitwise [code]NOT[/code] operation on the integer. Translates to [code]~a[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="FUNC_MAX" value="4" enum="Function">
Represents the size of the [enum Function] enum.
</constant>
</constants>
diff --git a/doc/classes/VisualShaderNodeIntOp.xml b/doc/classes/VisualShaderNodeIntOp.xml
index e5fcafca81..c685592fd0 100644
--- a/doc/classes/VisualShaderNodeIntOp.xml
+++ b/doc/classes/VisualShaderNodeIntOp.xml
@@ -35,7 +35,22 @@
<constant name="OP_MIN" value="6" enum="Operator">
Returns the lesser of two numbers. Translates to [code]max(a, b)[/code] in the Godot Shader Language.
</constant>
- <constant name="OP_ENUM_SIZE" value="7" enum="Operator">
+ <constant name="OP_BITWISE_AND" value="7" enum="Operator">
+ Returns the result of bitwise [code]AND[/code] operation on the integer. Translates to [code]a &amp; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_OR" value="8" enum="Operator">
+ Returns the result of bitwise [code]OR[/code] operation for two integers. Translates to [code]a | b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_XOR" value="9" enum="Operator">
+ Returns the result of bitwise [code]XOR[/code] operation for two integers. Translates to [code]a ^ b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_LEFT_SHIFT" value="10" enum="Operator">
+ Returns the result of bitwise left shift operation on the integer. Translates to [code]a &lt;&lt; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_BITWISE_RIGHT_SHIFT" value="11" enum="Operator">
+ Returns the result of bitwise right shift operation on the integer. Translates to [code]a &gt;&gt; b[/code] in the Godot Shader Language.
+ </constant>
+ <constant name="OP_ENUM_SIZE" value="12" enum="Operator">
Represents the size of the [enum Operator] enum.
</constant>
</constants>
diff --git a/doc/classes/VoxelGIData.xml b/doc/classes/VoxelGIData.xml
index f0bd2a0601..36907c88ba 100644
--- a/doc/classes/VoxelGIData.xml
+++ b/doc/classes/VoxelGIData.xml
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="VoxelGIData" inherits="Resource" version="4.0">
<brief_description>
+ Contains baked voxel global illumination data for use in a [VoxelGI] node.
</brief_description>
<description>
+ [VoxelGIData] contains baked voxel global illumination for use in a [VoxelGI] node. [VoxelGIData] also offers several properties to adjust the final appearance of the global illumination. These properties can be adjusted at run-time without having to bake the [VoxelGI] node again.
+ [b]Note:[/b] To prevent text-based scene files ([code].tscn[/code]) from growing too much and becoming slow to load and save, always save [VoxelGIData] to an external binary resource file ([code].res[/code]) instead of embedding it within the scene. This can be done by clicking the dropdown arrow next to the [VoxelGIData] resource, choosing [b]Edit[/b], clicking the floppy disk icon at the top of the inspector then choosing [b]Save As...[/b].
</description>
<tutorials>
<link title="Third Person Shooter Demo">https://godotengine.org/asset-library/asset/678</link>
@@ -23,6 +26,8 @@
<method name="get_bounds" qualifiers="const">
<return type="AABB" />
<description>
+ Returns the bounds of the baked voxel data as an [AABB], which should match [member VoxelGI.extents] after being baked (which only contains the size as a [Vector3]).
+ [b]Note:[/b] If the extents were modified without baking the VoxelGI data, then the value of [method get_bounds] and [member VoxelGI.extents] will not match.
</description>
</method>
<method name="get_data_cells" qualifiers="const">
@@ -53,18 +58,25 @@
</methods>
<members>
<member name="bias" type="float" setter="set_bias" getter="get_bias" default="1.5">
+ The normal bias to use for indirect lighting and reflections. Higher values reduce self-reflections visible in non-rough materials, at the cost of more visible light leaking and flatter-looking indirect lighting. To prioritize hiding self-reflections over lighting quality, set [member bias] to [code]0.0[/code] and [member normal_bias] to a value between [code]1.0[/code] and [code]2.0[/code].
</member>
<member name="dynamic_range" type="float" setter="set_dynamic_range" getter="get_dynamic_range" default="4.0">
+ The dynamic range to use ([code]1.0[/code] represents a low dynamic range scene brightness). Higher values can be used to provide brighter indirect lighting, at the cost of more visible color banding in dark areas (both in indirect lighting and reflections). To avoid color banding, it's recommended to use the lowest value that does not result in visible light clipping.
</member>
<member name="energy" type="float" setter="set_energy" getter="get_energy" default="1.0">
+ The energy of the indirect lighting and reflections produced by the [VoxelGI] node. Higher values result in brighter indirect lighting. If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness.
</member>
<member name="interior" type="bool" setter="set_interior" getter="is_interior" default="false">
+ If [code]true[/code], [Environment] lighting is ignored by the [VoxelGI] node. If [code]false[/code], [Environment] lighting is taken into account by the [VoxelGI] node. [Environment] lighting updates in real-time, which means it can be changed without having to bake the [VoxelGI] node again.
</member>
<member name="normal_bias" type="float" setter="set_normal_bias" getter="get_normal_bias" default="0.0">
+ The normal bias to use for indirect lighting and reflections. Higher values reduce self-reflections visible in non-rough materials, at the cost of more visible light leaking and flatter-looking indirect lighting. See also [member bias]. To prioritize hiding self-reflections over lighting quality, set [member bias] to [code]0.0[/code] and [member normal_bias] to a value between [code]1.0[/code] and [code]2.0[/code].
</member>
<member name="propagation" type="float" setter="set_propagation" getter="get_propagation" default="0.7">
+ If indirect lighting looks too flat, try decreasing [member propagation] while increasing [member energy] at the same time. See also [member use_two_bounces] which influences the indirect lighting's effective brightness.
</member>
<member name="use_two_bounces" type="bool" setter="set_use_two_bounces" getter="is_using_two_bounces" default="false">
+ If [code]true[/code], performs two bounces of indirect lighting instead of one. This makes indirect lighting look more natural and brighter at a small performance cost. The second bounce is also visible in reflections. If the scene appears too bright after enabling [member use_two_bounces], adjust [member propagation] and [member energy].
</member>
</members>
</class>
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index f9443e11db..168080f2f1 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -758,6 +758,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += a + " - " + n + " * (" + a + " / " + n + "))";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
+
default: {
if (p_use_scope) {
code += "(";
diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp
index f07c654bd6..dc21d1d8e5 100644
--- a/drivers/unix/file_access_unix.cpp
+++ b/drivers/unix/file_access_unix.cpp
@@ -307,7 +307,8 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) {
if (!err) {
return flags.st_mtime;
} else {
- ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + p_file + ".");
+ print_verbose("Failed to get modified time for: " + p_file + "");
+ return 0;
};
}
diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp
index 035c44a28c..ff81622408 100644
--- a/drivers/windows/file_access_windows.cpp
+++ b/drivers/windows/file_access_windows.cpp
@@ -335,7 +335,8 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) {
if (rv == 0) {
return st.st_mtime;
} else {
- ERR_FAIL_V_MSG(0, "Failed to get modified time for: " + file + ".");
+ print_verbose("Failed to get modified time for: " + p_file + "");
+ return 0;
}
}
diff --git a/editor/audio_stream_preview.h b/editor/audio_stream_preview.h
index 9cf47fd51a..8b83235b35 100644
--- a/editor/audio_stream_preview.h
+++ b/editor/audio_stream_preview.h
@@ -66,14 +66,13 @@ class AudioStreamPreviewGenerator : public Node {
Thread *thread = nullptr;
// Needed for the bookkeeping of the Map
- Preview &operator=(const Preview &p_rhs) {
+ void operator=(const Preview &p_rhs) {
preview = p_rhs.preview;
base_stream = p_rhs.base_stream;
playback = p_rhs.playback;
generating.set_to(generating.is_set());
id = p_rhs.id;
thread = p_rhs.thread;
- return *this;
}
Preview(const Preview &p_rhs) {
preview = p_rhs.preview;
diff --git a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
index 2e0e6cb7c8..36fbf8adf1 100644
--- a/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
+++ b/editor/debugger/debug_adapter/debug_adapter_protocol.cpp
@@ -192,10 +192,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::VECTOR2I: {
int id = variable_id++;
Vector2 vec = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y;
x.name = "x";
y.name = "y";
- x.type = y.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR2 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
x.value = rtos(vec.x);
y.value = rtos(vec.y);
@@ -209,12 +211,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::RECT2I: {
int id = variable_id++;
Rect2 rect = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y, w, h;
x.name = "x";
y.name = "y";
w.name = "w";
h.name = "h";
- x.type = y.type = w.type = h.type = Variant::get_type_name(p_var.get_type() == Variant::RECT2 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
+ w.type = type_scalar;
+ h.type = type_scalar;
x.value = rtos(rect.position.x);
y.value = rtos(rect.position.y);
w.value = rtos(rect.size.x);
@@ -232,11 +238,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::VECTOR3I: {
int id = variable_id++;
Vector3 vec = p_var;
+ const String type_scalar = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT);
DAP::Variable x, y, z;
x.name = "x";
y.name = "y";
z.name = "z";
- x.type = y.type = z.type = Variant::get_type_name(p_var.get_type() == Variant::VECTOR3 ? Variant::FLOAT : Variant::INT);
+ x.type = type_scalar;
+ y.type = type_scalar;
+ z.type = type_scalar;
x.value = rtos(vec.x);
y.value = rtos(vec.y);
z.value = rtos(vec.z);
@@ -251,11 +260,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::TRANSFORM2D: {
int id = variable_id++;
Transform2D transform = p_var;
+ const String type_vec2 = Variant::get_type_name(Variant::VECTOR2);
DAP::Variable x, y, origin;
x.name = "x";
y.name = "y";
origin.name = "origin";
- x.type = y.type = origin.type = Variant::get_type_name(Variant::VECTOR2);
+ x.type = type_vec2;
+ y.type = type_vec2;
+ origin.type = type_vec2;
x.value = transform.elements[0];
y.value = transform.elements[1];
origin.value = transform.elements[2];
@@ -291,12 +303,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::QUATERNION: {
int id = variable_id++;
Quaternion quat = p_var;
+ const String type_float = Variant::get_type_name(Variant::FLOAT);
DAP::Variable x, y, z, w;
x.name = "x";
y.name = "y";
z.name = "z";
w.name = "w";
- x.type = y.type = z.type = w.type = Variant::get_type_name(Variant::FLOAT);
+ x.type = type_float;
+ y.type = type_float;
+ z.type = type_float;
+ w.type = type_float;
x.value = rtos(quat.x);
y.value = rtos(quat.y);
z.value = rtos(quat.z);
@@ -313,10 +329,12 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::AABB: {
int id = variable_id++;
AABB aabb = p_var;
+ const String type_vec3 = Variant::get_type_name(Variant::VECTOR3);
DAP::Variable position, size;
position.name = "position";
size.name = "size";
- position.type = size.type = Variant::get_type_name(Variant::VECTOR3);
+ position.type = type_vec3;
+ size.type = type_vec3;
position.value = aabb.position;
size.value = aabb.size;
position.variablesReference = parse_variant(aabb.position);
@@ -331,11 +349,14 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::BASIS: {
int id = variable_id++;
Basis basis = p_var;
+ const String type_vec2 = Variant::get_type_name(Variant::VECTOR2);
DAP::Variable x, y, z;
x.name = "x";
y.name = "y";
z.name = "z";
- x.type = y.type = z.type = Variant::get_type_name(Variant::VECTOR2);
+ x.type = type_vec2;
+ y.type = type_vec2;
+ z.type = type_vec2;
x.value = basis.elements[0];
y.value = basis.elements[1];
z.value = basis.elements[2];
@@ -372,12 +393,16 @@ int DebugAdapterProtocol::parse_variant(const Variant &p_var) {
case Variant::COLOR: {
int id = variable_id++;
Color color = p_var;
+ const String type_float = Variant::get_type_name(Variant::FLOAT);
DAP::Variable r, g, b, a;
r.name = "r";
g.name = "g";
b.name = "b";
a.name = "a";
- r.type = g.type = b.type = a.type = Variant::get_type_name(Variant::FLOAT);
+ r.type = type_float;
+ g.type = type_float;
+ b.type = type_float;
+ a.type = type_float;
r.value = rtos(color.r);
g.value = rtos(color.g);
b.value = rtos(color.b);
diff --git a/editor/debugger/editor_debugger_inspector.cpp b/editor/debugger/editor_debugger_inspector.cpp
index e53f66e72e..9346b8f1af 100644
--- a/editor/debugger/editor_debugger_inspector.cpp
+++ b/editor/debugger/editor_debugger_inspector.cpp
@@ -55,9 +55,14 @@ bool EditorDebuggerRemoteObject::_get(const StringName &p_name, Variant &r_ret)
}
void EditorDebuggerRemoteObject::_get_property_list(List<PropertyInfo> *p_list) const {
- p_list->clear(); //sorry, no want category
- for (const PropertyInfo &E : prop_list) {
- p_list->push_back(E);
+ p_list->clear(); // Sorry, no want category.
+ for (const PropertyInfo &prop : prop_list) {
+ if (prop.name == "script") {
+ // Skip the script property, it's always added by the non-virtual method.
+ continue;
+ }
+
+ p_list->push_back(prop);
}
}
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index e1aaa060c6..eb54bb3efb 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -230,11 +230,10 @@ private:
render_db_value = n.render_db_value;
}
- _FORCE_INLINE_ AudioNotch &operator=(const EditorAudioMeterNotches::AudioNotch &n) {
+ _FORCE_INLINE_ void operator=(const EditorAudioMeterNotches::AudioNotch &n) {
relative_position = n.relative_position;
db_value = n.db_value;
render_db_value = n.render_db_value;
- return *this;
}
_FORCE_INLINE_ AudioNotch() {}
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index a163b468e6..6fd8cb47ea 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -893,8 +893,13 @@ bool EditorData::script_class_is_parent(const String &p_class, const String &p_i
if (!ScriptServer::is_global_class(p_class)) {
return false;
}
- String base = script_class_get_base(p_class);
+
Ref<Script> script = script_class_load_script(p_class);
+ if (script.is_null()) {
+ return false;
+ }
+
+ String base = script_class_get_base(p_class);
Ref<Script> base_script = script->get_base_script();
while (p_inherits != base) {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 03d91ebcba..55a2c319fe 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -488,8 +488,8 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
String cur_dir_no_prefix = cur_dir.replace("res://", "");
Vector<String> dirs;
- String f;
- while ((f = da->get_next()) != "") {
+ String f = da->get_next();
+ while (!f.is_empty()) {
if (da->current_is_dir()) {
dirs.push_back(f);
} else {
@@ -506,6 +506,7 @@ void EditorExportPlatform::_edit_files_with_filter(DirAccess *da, const Vector<S
}
}
}
+ f = da->get_next();
}
da->list_dir_end();
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index bea5c99c1a..ec8651ac7c 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -761,10 +761,11 @@ void EditorFileDialog::update_file_list() {
List<String> files;
List<String> dirs;
- String item;
+ String item = dir_access->get_next();
- while ((item = dir_access->get_next()) != "") {
+ while (!item.is_empty()) {
if (item == "." || item == "..") {
+ item = dir_access->get_next();
continue;
}
@@ -775,6 +776,7 @@ void EditorFileDialog::update_file_list() {
dirs.push_back(item);
}
}
+ item = dir_access->get_next();
}
dirs.sort_custom<NaturalNoCaseComparator>();
diff --git a/editor/localization_editor.cpp b/editor/localization_editor.cpp
index 5c25e6aae9..7458f617c3 100644
--- a/editor/localization_editor.cpp
+++ b/editor/localization_editor.cpp
@@ -497,7 +497,7 @@ void LocalizationEditor::update_translations() {
TreeItem *t = translation_filter->create_item(root);
t->set_cell_mode(0, TreeItem::CELL_MODE_CHECK);
- t->set_text(0, n);
+ t->set_text(0, vformat("[%s] %s", l, n));
t->set_editable(0, true);
t->set_tooltip(0, l);
t->set_checked(0, is_checked);
@@ -537,7 +537,7 @@ void LocalizationEditor::update_translations() {
if (langnames.length() > 0) {
langnames += ",";
}
- langnames += names[i];
+ langnames += vformat("[%s] %s", langs[i], names[i]);
translation_locales_idxs_remap.write[l_idx] = i;
l_idx++;
}
@@ -546,7 +546,7 @@ void LocalizationEditor::update_translations() {
if (i > 0) {
langnames += ",";
}
- langnames += names[i];
+ langnames += vformat("[%s] %s", langs[i], names[i]);
}
}
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index b6722b9d48..aa46eef21f 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -2913,14 +2913,6 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 corner = Point2(begin.x, end.y);
Vector2 length_vector = (begin - end).abs() / zoom;
- bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x));
-
- viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3));
- if (draw_secondary_lines) {
- viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE));
- viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE));
- }
-
Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts"));
int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts"));
Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor"));
@@ -2936,8 +2928,24 @@ void CanvasItemEditor::_draw_ruler_tool() {
Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2);
text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5);
text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5);
+
+ if (begin.is_equal_approx(end)) {
+ viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons"));
+ viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2);
+ return;
+ }
+
viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color);
+ bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x));
+
+ viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3));
+ if (draw_secondary_lines) {
+ viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE));
+ viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE));
+ }
+
if (draw_secondary_lines) {
const real_t horizontal_angle_rad = length_vector.angle();
const real_t vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad;
@@ -5267,7 +5275,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
select_button->set_pressed(true);
select_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/select_mode", TTR("Select Mode"), Key::Q));
select_button->set_shortcut_context(this);
- select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
+ select_button->set_tooltip(keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Drag: Rotate selected node around pivot.") + "\n" + TTR("Alt+Drag: Move selected node.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("Alt+Drag: Scale selected node.") + "\n" + TTR("V: Set selected node's pivot position.") + "\n" + TTR("Alt+RMB: Show list of all nodes at position clicked, including locked.") + "\n" + keycode_get_string((Key)KeyModifierMask::CMD) + TTR("RMB: Add node at position clicked."));
hb->add_child(memnew(VSeparator));
@@ -5296,7 +5304,7 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
scale_button->connect("pressed", callable_mp(this, &CanvasItemEditor::_button_tool_select), make_binds(TOOL_SCALE));
scale_button->set_shortcut(ED_SHORTCUT("canvas_item_editor/scale_mode", TTR("Scale Mode"), Key::S));
scale_button->set_shortcut_context(this);
- scale_button->set_tooltip(TTR("Scale Mode"));
+ scale_button->set_tooltip(TTR("Shift: Scale proportionally."));
hb->add_child(memnew(VSeparator));
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index daf34903e6..d99d6709ad 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -460,7 +460,7 @@ void CurveEditor::remove_point(int index) {
Curve::Point p = _curve_ref->get_point(index);
ur.add_do_method(*_curve_ref, "remove_point", index);
- ur.add_undo_method(*_curve_ref, "add_point", p.pos, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
+ ur.add_undo_method(*_curve_ref, "add_point", p.position, p.left_tangent, p.right_tangent, p.left_mode, p.right_mode);
if (index == _selected_point) {
set_selected_point(-1);
diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp
index 154f9bd6b7..60ba98a706 100644
--- a/editor/plugins/node_3d_editor_gizmos.cpp
+++ b/editor/plugins/node_3d_editor_gizmos.cpp
@@ -244,8 +244,10 @@ void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden)
RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true);
}
-void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) {
+void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) {
ERR_FAIL_COND(!spatial_node);
+ ERR_FAIL_COND_MSG(!p_mesh.is_valid(), "EditorNode3DGizmo.add_mesh() requires a valid Mesh resource.");
+
Instance ins;
ins.mesh = p_mesh;
diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h
index 56e4ad5518..cf9a464b69 100644
--- a/editor/plugins/node_3d_editor_gizmos.h
+++ b/editor/plugins/node_3d_editor_gizmos.h
@@ -45,7 +45,7 @@ class EditorNode3DGizmo : public Node3DGizmo {
struct Instance {
RID instance;
- Ref<ArrayMesh> mesh;
+ Ref<Mesh> mesh;
Ref<Material> material;
Ref<SkinReference> skin_reference;
bool extra_margin = false;
@@ -95,7 +95,7 @@ protected:
public:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1));
- void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
+ void add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1));
diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp
index 0a8cfa3815..51086d47b7 100644
--- a/editor/plugins/node_3d_editor_plugin.cpp
+++ b/editor/plugins/node_3d_editor_plugin.cpp
@@ -4048,7 +4048,23 @@ bool Node3DEditorViewport::_create_instance(Node *parent, String &path, const Po
if (mesh != nullptr) {
MeshInstance3D *mesh_instance = memnew(MeshInstance3D);
mesh_instance->set_mesh(mesh);
- mesh_instance->set_name(path.get_file().get_basename());
+
+ // Adjust casing according to project setting. The file name is expected to be in snake_case, but will work for others.
+ String name = path.get_file().get_basename();
+ switch (ProjectSettings::get_singleton()->get("editor/node_naming/name_casing").operator int()) {
+ case NAME_CASING_PASCAL_CASE:
+ name = name.capitalize().replace(" ", "");
+ break;
+ case NAME_CASING_CAMEL_CASE:
+ name = name.capitalize().replace(" ", "");
+ name[0] = name.to_lower()[0];
+ break;
+ case NAME_CASING_SNAKE_CASE:
+ name = name.capitalize().replace(" ", "_").to_lower();
+ break;
+ }
+ mesh_instance->set_name(name);
+
instantiated_scene = mesh_instance;
} else {
if (!scene.is_valid()) { // invalid scene
@@ -4221,10 +4237,9 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_
if (root_node) {
target_node = root_node;
} else {
- accept->set_text(TTR("Cannot drag and drop into scene with no root node."));
- accept->popup_centered();
- _remove_preview();
- return;
+ // Create a root node so we can add child nodes to it.
+ EditorNode::get_singleton()->get_scene_tree_dock()->add_root_node(memnew(Node3D));
+ target_node = get_tree()->get_edited_scene_root();
}
} else {
accept->set_text(TTR("Cannot drag and drop into multiple selected nodes."));
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index 5f21c8c881..bb5ef0f6eb 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -964,6 +964,7 @@ void Skeleton3DEditor::select_bone(int p_idx) {
Skeleton3DEditor::~Skeleton3DEditor() {
if (skeleton) {
+ select_bone(-1);
#ifdef TOOLS_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));
@@ -973,6 +974,7 @@ Skeleton3DEditor::~Skeleton3DEditor() {
#endif
handles_mesh_instance->get_parent()->remove_child(handles_mesh_instance);
}
+ edit_mode_toggled(false);
handles_mesh_instance->queue_delete();
diff --git a/editor/plugins/theme_editor_preview.cpp b/editor/plugins/theme_editor_preview.cpp
index f13fcb005f..86b0fc0eaf 100644
--- a/editor/plugins/theme_editor_preview.cpp
+++ b/editor/plugins/theme_editor_preview.cpp
@@ -157,6 +157,7 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
emit_signal(SNAME("control_picked"), theme_type);
picker_button->set_pressed(false);
picker_overlay->set_visible(false);
+ return;
}
}
@@ -167,6 +168,9 @@ void ThemeEditorPreview::_gui_input_picker_overlay(const Ref<InputEvent> &p_even
hovered_control = _find_hovered_control(preview_content, mp);
picker_overlay->update();
}
+
+ // Forward input to the scroll container underneath to allow scrolling.
+ preview_container->gui_input(p_event);
}
void ThemeEditorPreview::_reset_picker_overlay() {
@@ -223,7 +227,7 @@ ThemeEditorPreview::ThemeEditorPreview() {
preview_body->set_v_size_flags(SIZE_EXPAND_FILL);
add_child(preview_body);
- ScrollContainer *preview_container = memnew(ScrollContainer);
+ preview_container = memnew(ScrollContainer);
preview_container->set_enable_v_scroll(true);
preview_container->set_enable_h_scroll(true);
preview_body->add_child(preview_container);
diff --git a/editor/plugins/theme_editor_preview.h b/editor/plugins/theme_editor_preview.h
index f973119257..73422b4fba 100644
--- a/editor/plugins/theme_editor_preview.h
+++ b/editor/plugins/theme_editor_preview.h
@@ -55,6 +55,7 @@
class ThemeEditorPreview : public VBoxContainer {
GDCLASS(ThemeEditorPreview, VBoxContainer);
+ ScrollContainer *preview_container;
ColorRect *preview_bg;
MarginContainer *preview_overlay;
Control *picker_overlay;
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index da73fc093c..44f2eaa2a1 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -4556,6 +4556,7 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR));
+ add_options.push_back(AddOption("BitwiseNOT", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the result of bitwise NOT (~a) operation on the integer."), VisualShaderNodeIntFunc::FUNC_BITWISE_NOT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
@@ -4595,6 +4596,11 @@ VisualShaderEditor::VisualShaderEditor() {
add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), VisualShaderNodeFloatOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), VisualShaderNodeIntOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseAND", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_AND, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseLeftShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_OR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseRightShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT));
+ add_options.push_back(AddOption("BitwiseXOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_XOR, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), VisualShaderNodeFloatOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR));
add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), VisualShaderNodeIntOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR_INT));
add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), VisualShaderNodeFloatOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR));
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 372a77f67d..7ae03b3072 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -102,7 +102,6 @@ private:
FileDialog *fdialog;
FileDialog *fdialog_install;
OptionButton *vcs_metadata_selection;
- CheckBox *create_default_environment;
String zip_path;
String zip_title;
AcceptDialog *dialog_error;
@@ -495,31 +494,10 @@ private:
initial_settings["application/config/name"] = project_name->get_text().strip_edges();
initial_settings["application/config/icon"] = "res://icon.png";
- if (create_default_environment->is_pressed()) {
- initial_settings["rendering/environment/defaults/default_environment"] = "res://default_env.tres";
- }
-
if (ProjectSettings::get_singleton()->save_custom(dir.plus_file("project.godot"), initial_settings, Vector<String>(), false) != OK) {
set_message(TTR("Couldn't create project.godot in project path."), MESSAGE_ERROR);
} else {
ResourceSaver::save(dir.plus_file("icon.png"), create_unscaled_default_project_icon());
- FileAccess *f;
- if (create_default_environment->is_pressed()) {
- f = FileAccess::open(dir.plus_file("default_env.tres"), FileAccess::WRITE);
- if (!f) {
- set_message(TTR("Couldn't create default_env.tres in project path."), MESSAGE_ERROR);
- } else {
- f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
- f->store_line("");
- f->store_line("[sub_resource type=\"Sky\" id=\"1\"]");
- f->store_line("");
- f->store_line("[resource]");
- f->store_line("background_mode = 2");
- f->store_line("sky = SubResource( \"1\" )");
- memdelete(f);
- }
- }
-
EditorVCSInterface::create_vcs_metadata_files(EditorVCSInterface::VCSMetadata(vcs_metadata_selection->get_selected()), dir);
}
} else if (mode == MODE_INSTALL) {
@@ -945,10 +923,6 @@ public:
Control *spacer = memnew(Control);
spacer->set_h_size_flags(Control::SIZE_EXPAND_FILL);
default_files_container->add_child(spacer);
- create_default_environment = memnew(CheckBox);
- create_default_environment->set_text("Create Default Environment");
- create_default_environment->set_pressed(true);
- default_files_container->add_child(create_default_environment);
fdialog = memnew(FileDialog);
fdialog->set_access(FileDialog::ACCESS_FILESYSTEM);
@@ -2743,7 +2717,7 @@ ProjectManager::ProjectManager() {
for (int i = 0; i < editor_languages.size(); i++) {
String lang = editor_languages[i];
String lang_name = TranslationServer::get_singleton()->get_locale_name(lang);
- language_btn->add_item(lang_name + " [" + lang + "]", i);
+ language_btn->add_item(vformat("[%s] %s", lang, lang_name), i);
language_btn->set_item_metadata(i, lang);
if (current_lang == lang) {
language_btn->select(i);
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index a03871f33c..cf89120beb 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -419,6 +419,9 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
if (!selected_item) {
selected_item = tree->get_root();
+ if (!selected_item) {
+ break;
+ }
}
bool collapsed = _is_collapsed_recursive(selected_item);
diff --git a/main/SCsub b/main/SCsub
index 87d64e48f9..79dc4bff15 100644
--- a/main/SCsub
+++ b/main/SCsub
@@ -20,12 +20,13 @@ env_main.CommandNoCache(
env.Run(main_builders.make_splash, "Building splash screen header."),
)
-env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
-env_main.CommandNoCache(
- "#main/splash_editor.gen.h",
- "#main/splash_editor.png",
- env.Run(main_builders.make_splash_editor, "Building editor splash screen header."),
-)
+if not env_main["no_editor_splash"]:
+ env_main.Depends("#main/splash_editor.gen.h", "#main/splash_editor.png")
+ env_main.CommandNoCache(
+ "#main/splash_editor.gen.h",
+ "#main/splash_editor.png",
+ env.Run(main_builders.make_splash_editor, "Building editor splash screen header."),
+ )
env_main.Depends("#main/app_icon.gen.h", "#main/app_icon.png")
env_main.CommandNoCache(
diff --git a/main/main.cpp b/main/main.cpp
index b4fbc1929c..c7b33f3f1b 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -56,7 +56,6 @@
#include "main/main_timer_sync.h"
#include "main/performance.h"
#include "main/splash.gen.h"
-#include "main/splash_editor.gen.h"
#include "modules/register_module_types.h"
#include "platform/register_platform_apis.h"
#include "scene/main/scene_tree.h"
@@ -86,6 +85,9 @@
#include "editor/editor_settings.h"
#include "editor/progress_dialog.h"
#include "editor/project_manager.h"
+#ifndef NO_EDITOR_SPLASH
+#include "main/splash_editor.gen.h"
+#endif
#endif
#include "modules/modules_enabled.gen.h" // For mono.
@@ -442,6 +444,9 @@ Error Main::test_setup() {
register_module_types();
register_driver_types();
+ // Theme needs modules to be initialized so that sub-resources can be loaded.
+ initialize_theme();
+
ERR_FAIL_COND_V(TextServerManager::get_singleton()->get_interface_count() == 0, ERR_CANT_CREATE);
TextServerManager::get_singleton()->set_primary_interface(TextServerManager::get_singleton()->get_interface(0));
@@ -1882,6 +1887,9 @@ Error Main::setup2(Thread::ID p_main_tid_override) {
register_platform_apis();
register_module_types();
+ // Theme needs modules to be initialized so that sub-resources can be loaded.
+ initialize_theme();
+
GLOBAL_DEF("display/mouse_cursor/custom_image", String());
GLOBAL_DEF("display/mouse_cursor/custom_image_hotspot", Vector2());
GLOBAL_DEF("display/mouse_cursor/tooltip_position_offset", Point2(10, 10));
diff --git a/main/splash_editor.png b/main/splash_editor.png
deleted file mode 100644
index 49af9fde22..0000000000
--- a/main/splash_editor.png
+++ /dev/null
Binary files differ
diff --git a/modules/bullet/godot_result_callbacks.cpp b/modules/bullet/godot_result_callbacks.cpp
index 1f962772e7..edb2bcb4c7 100644
--- a/modules/bullet/godot_result_callbacks.cpp
+++ b/modules/bullet/godot_result_callbacks.cpp
@@ -107,7 +107,14 @@ btScalar GodotAllConvexResultCallback::addSingleResult(btCollisionWorld::LocalCo
PhysicsDirectSpaceState3D::ShapeResult &result = m_results[count];
- result.shape = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) {
+ result.shape = convexResult.m_localShapeInfo->m_triangleIndex;
+ } else {
+ result.shape = 0;
+ }
+
result.rid = gObj->get_self();
result.collider_id = gObj->get_instance_id();
result.collider = result.collider_id.is_null() ? nullptr : ObjectDB::get_instance(result.collider_id);
@@ -171,11 +178,14 @@ bool GodotClosestConvexResultCallback::needsCollision(btBroadphaseProxy *proxy0)
}
btScalar GodotClosestConvexResultCallback::addSingleResult(btCollisionWorld::LocalConvexResult &convexResult, bool normalInWorldSpace) {
- if (convexResult.m_localShapeInfo) {
- m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is an odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (convexResult.m_localShapeInfo && convexResult.m_localShapeInfo->m_shapePart == -1) {
+ m_shapeId = convexResult.m_localShapeInfo->m_triangleIndex;
} else {
m_shapeId = 0;
}
+
return btCollisionWorld::ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace);
}
@@ -219,10 +229,22 @@ btScalar GodotAllContactResultCallback::addSingleResult(btManifoldPoint &cp, con
CollisionObjectBullet *colObj;
if (m_self_object == colObj0Wrap->getCollisionObject()) {
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
- result.shape = cp.m_index1;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) {
+ result.shape = cp.m_index1;
+ } else {
+ result.shape = 0;
+ }
} else {
colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
- result.shape = cp.m_index0;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) {
+ result.shape = cp.m_index0;
+ } else {
+ result.shape = 0;
+ }
}
result.collider_id = colObj->get_instance_id();
@@ -311,14 +333,26 @@ btScalar GodotRestInfoContactResultCallback::addSingleResult(btManifoldPoint &cp
CollisionObjectBullet *colObj;
if (m_self_object == colObj0Wrap->getCollisionObject()) {
colObj = static_cast<CollisionObjectBullet *>(colObj1Wrap->getCollisionObject()->getUserPointer());
- m_result->shape = cp.m_index1;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj1Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId1 == -1) {
+ m_result->shape = cp.m_index1;
+ } else {
+ m_result->shape = 0;
+ }
B_TO_G(cp.getPositionWorldOnB(), m_result->point);
B_TO_G(cp.m_normalWorldOnB, m_result->normal);
m_rest_info_bt_point = cp.getPositionWorldOnB();
m_rest_info_collision_object = colObj1Wrap->getCollisionObject();
} else {
colObj = static_cast<CollisionObjectBullet *>(colObj0Wrap->getCollisionObject()->getUserPointer());
- m_result->shape = cp.m_index0;
+ // Checking for compound shape because the index might be uninitialized otherwise.
+ // A partId of -1 indicates the index is a shape index and not a triangle index.
+ if (colObj0Wrap->getCollisionObject()->getCollisionShape()->isCompound() && cp.m_partId0 == -1) {
+ m_result->shape = cp.m_index0;
+ } else {
+ m_result->shape = 0;
+ }
B_TO_G(cp.m_normalWorldOnB * -1, m_result->normal);
m_rest_info_bt_point = cp.getPositionWorldOnA();
m_rest_info_collision_object = colObj0Wrap->getCollisionObject();
diff --git a/modules/bullet/godot_result_callbacks.h b/modules/bullet/godot_result_callbacks.h
index 96a649d77a..3dfa21aec8 100644
--- a/modules/bullet/godot_result_callbacks.h
+++ b/modules/bullet/godot_result_callbacks.h
@@ -70,8 +70,10 @@ public:
virtual bool needsCollision(btBroadphaseProxy *proxy0) const;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) {
- if (rayResult.m_localShapeInfo) {
- m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex; // "m_triangleIndex" Is a odd name but contains the compound shape ID
+ // Triangle index is an odd name but contains the compound shape ID.
+ // A shape part of -1 indicates the index is a shape index and not a triangle index.
+ if (rayResult.m_localShapeInfo && rayResult.m_localShapeInfo->m_shapePart == -1) {
+ m_shapeId = rayResult.m_localShapeInfo->m_triangleIndex;
} else {
m_shapeId = 0;
}
diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h
index 9d076a8e4c..e1ed71a268 100644
--- a/modules/gdscript/gdscript_function.h
+++ b/modules/gdscript/gdscript_function.h
@@ -192,7 +192,7 @@ public:
GDScriptDataType() = default;
- GDScriptDataType &operator=(const GDScriptDataType &p_other) {
+ void operator=(const GDScriptDataType &p_other) {
kind = p_other.kind;
has_type = p_other.has_type;
builtin_type = p_other.builtin_type;
@@ -203,7 +203,6 @@ public:
if (p_other.has_container_element_type()) {
set_container_element_type(p_other.get_container_element_type());
}
- return *this;
}
GDScriptDataType(const GDScriptDataType &p_other) {
diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h
index af9b973ada..2f05b4b948 100644
--- a/modules/gdscript/gdscript_parser.h
+++ b/modules/gdscript/gdscript_parser.h
@@ -203,7 +203,7 @@ public:
return !(this->operator==(p_other));
}
- DataType &operator=(const DataType &p_other) {
+ void operator=(const DataType &p_other) {
kind = p_other.kind;
type_source = p_other.type_source;
is_constant = p_other.is_constant;
@@ -221,7 +221,6 @@ public:
if (p_other.has_container_element_type()) {
set_container_element_type(p_other.get_container_element_type());
}
- return *this;
}
DataType() = default;
diff --git a/modules/minimp3/audio_stream_mp3.cpp b/modules/minimp3/audio_stream_mp3.cpp
index 49e9f5f97e..a9c1f0bb9a 100644
--- a/modules/minimp3/audio_stream_mp3.cpp
+++ b/modules/minimp3/audio_stream_mp3.cpp
@@ -125,7 +125,7 @@ AudioStreamPlaybackMP3::~AudioStreamPlaybackMP3() {
Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() {
Ref<AudioStreamPlaybackMP3> mp3s;
- ERR_FAIL_COND_V_MSG(data == nullptr, mp3s,
+ ERR_FAIL_COND_V_MSG(data.is_empty(), mp3s,
"This AudioStreamMP3 does not have an audio file assigned "
"to it. AudioStreamMP3 should not be created from the "
"inspector or with `.new()`. Instead, load an audio file.");
@@ -134,7 +134,7 @@ Ref<AudioStreamPlayback> AudioStreamMP3::instance_playback() {
mp3s->mp3_stream = Ref<AudioStreamMP3>(this);
mp3s->mp3d = (mp3dec_ex_t *)memalloc(sizeof(mp3dec_ex_t));
- int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, (const uint8_t *)data, data_len, MP3D_SEEK_TO_SAMPLE);
+ int errorcode = mp3dec_ex_open_buf(mp3s->mp3d, data.ptr(), data_len, MP3D_SEEK_TO_SAMPLE);
mp3s->frames_mixed = 0;
mp3s->active = false;
@@ -152,11 +152,7 @@ String AudioStreamMP3::get_stream_name() const {
}
void AudioStreamMP3::clear_data() {
- if (data) {
- memfree(data);
- data = nullptr;
- data_len = 0;
- }
+ data.clear();
}
void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
@@ -165,7 +161,7 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
mp3dec_ex_t mp3d;
int err = mp3dec_ex_open_buf(&mp3d, src_datar, src_data_len, MP3D_SEEK_TO_SAMPLE);
- ERR_FAIL_COND(err != 0);
+ ERR_FAIL_COND_MSG(err || mp3d.info.hz == 0, "Failed to decode mp3 file. Make sure it is a valid mp3 audio file.");
channels = mp3d.info.channels;
sample_rate = mp3d.info.hz;
@@ -175,23 +171,13 @@ void AudioStreamMP3::set_data(const Vector<uint8_t> &p_data) {
clear_data();
- data = memalloc(src_data_len);
- memcpy(data, src_datar, src_data_len);
+ data.resize(src_data_len);
+ memcpy(data.ptrw(), src_datar, src_data_len);
data_len = src_data_len;
}
Vector<uint8_t> AudioStreamMP3::get_data() const {
- Vector<uint8_t> vdata;
-
- if (data_len && data) {
- vdata.resize(data_len);
- {
- uint8_t *w = vdata.ptrw();
- memcpy(w, data, data_len);
- }
- }
-
- return vdata;
+ return data;
}
void AudioStreamMP3::set_loop(bool p_enable) {
diff --git a/modules/minimp3/audio_stream_mp3.h b/modules/minimp3/audio_stream_mp3.h
index 3c8bdd8c53..e3adfe683b 100644
--- a/modules/minimp3/audio_stream_mp3.h
+++ b/modules/minimp3/audio_stream_mp3.h
@@ -75,7 +75,7 @@ class AudioStreamMP3 : public AudioStream {
friend class AudioStreamPlaybackMP3;
- void *data = nullptr;
+ PackedByteArray data;
uint32_t data_len = 0;
float sample_rate = 1.0;
diff --git a/modules/mono/editor/bindings_generator.h b/modules/mono/editor/bindings_generator.h
index 51a27ee934..a7879e96c8 100644
--- a/modules/mono/editor/bindings_generator.h
+++ b/modules/mono/editor/bindings_generator.h
@@ -598,7 +598,7 @@ class BindingsGenerator {
private:
NameCache(const NameCache &);
- NameCache &operator=(const NameCache &);
+ void operator=(const NameCache &);
};
NameCache name_cache;
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
index 0c3331900a..30ecd22db7 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2.cs
@@ -184,13 +184,13 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product value.</returns>
- public real_t Cross(Vector2 b)
+ public real_t Cross(Vector2 with)
{
- return (x * b.y) - (y * b.x);
+ return (x * with.y) - (y * with.x);
}
/// <summary>
@@ -222,13 +222,13 @@ namespace Godot
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
+ /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
- public Vector2 DirectionTo(Vector2 b)
+ /// <param name="to">The other vector to point towards.</param>
+ /// <returns>The direction from this vector to <paramref name="to"/>.</returns>
+ public Vector2 DirectionTo(Vector2 to)
{
- return new Vector2(b.x - x, b.y - y).Normalized();
+ return new Vector2(to.x - x, to.y - y).Normalized();
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
index 6cac16d53b..3bbc2ae2ba 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector2i.cs
@@ -149,45 +149,45 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product vector.</returns>
- public int Cross(Vector2i b)
+ public int Cross(Vector2i with)
{
- return x * b.y - y * b.x;
+ return x * with.y - y * with.x;
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public int DistanceSquaredTo(Vector2i b)
+ public int DistanceSquaredTo(Vector2i to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector2i b)
+ public real_t DistanceTo(Vector2i to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public int Dot(Vector2i b)
+ public int Dot(Vector2i with)
{
- return x * b.x + y * b.y;
+ return x * with.x + y * with.y;
}
/// <summary>
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
index 63d9be0a6d..15acf88f62 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3.cs
@@ -170,17 +170,17 @@ namespace Godot
}
/// <summary>
- /// Returns the cross product of this vector and <paramref name="b"/>.
+ /// Returns the cross product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>The cross product vector.</returns>
- public Vector3 Cross(Vector3 b)
+ public Vector3 Cross(Vector3 with)
{
return new Vector3
(
- (y * b.z) - (z * b.y),
- (z * b.x) - (x * b.z),
- (x * b.y) - (y * b.x)
+ (y * with.z) - (z * with.y),
+ (z * with.x) - (x * with.z),
+ (x * with.y) - (y * with.x)
);
}
@@ -212,46 +212,46 @@ namespace Godot
}
/// <summary>
- /// Returns the normalized vector pointing from this vector to <paramref name="b"/>.
+ /// Returns the normalized vector pointing from this vector to <paramref name="to"/>.
/// </summary>
- /// <param name="b">The other vector to point towards.</param>
- /// <returns>The direction from this vector to <paramref name="b"/>.</returns>
- public Vector3 DirectionTo(Vector3 b)
+ /// <param name="to">The other vector to point towards.</param>
+ /// <returns>The direction from this vector to <paramref name="to"/>.</returns>
+ public Vector3 DirectionTo(Vector3 to)
{
- return new Vector3(b.x - x, b.y - y, b.z - z).Normalized();
+ return new Vector3(to.x - x, to.y - y, to.z - z).Normalized();
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public real_t DistanceSquaredTo(Vector3 b)
+ public real_t DistanceSquaredTo(Vector3 to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
/// <seealso cref="DistanceSquaredTo(Vector3)"/>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector3 b)
+ public real_t DistanceTo(Vector3 to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public real_t Dot(Vector3 b)
+ public real_t Dot(Vector3 with)
{
- return (x * b.x) + (y * b.y) + (z * b.z);
+ return (x * with.x) + (y * with.y) + (z * with.z);
}
/// <summary>
@@ -412,16 +412,16 @@ namespace Godot
}
/// <summary>
- /// Returns the outer product with <paramref name="b"/>.
+ /// Returns the outer product with <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector.</param>
+ /// <param name="with">The other vector.</param>
/// <returns>A <see cref="Basis"/> representing the outer product matrix.</returns>
- public Basis Outer(Vector3 b)
+ public Basis Outer(Vector3 with)
{
return new Basis(
- x * b.x, x * b.y, x * b.z,
- y * b.x, y * b.y, y * b.z,
- z * b.x, z * b.y, z * b.z
+ x * with.x, x * with.y, x * with.z,
+ y * with.x, y * with.y, y * with.z,
+ z * with.x, z * with.y, z * with.z
);
}
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
index 474876fc91..562f653fa8 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Vector3i.cs
@@ -124,36 +124,36 @@ namespace Godot
}
/// <summary>
- /// Returns the squared distance between this vector and <paramref name="b"/>.
+ /// Returns the squared distance between this vector and <paramref name="to"/>.
/// This method runs faster than <see cref="DistanceTo"/>, so prefer it if
/// you need to compare vectors or need the squared distance for some formula.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The squared distance between the two vectors.</returns>
- public int DistanceSquaredTo(Vector3i b)
+ public int DistanceSquaredTo(Vector3i to)
{
- return (b - this).LengthSquared();
+ return (to - this).LengthSquared();
}
/// <summary>
- /// Returns the distance between this vector and <paramref name="b"/>.
+ /// Returns the distance between this vector and <paramref name="to"/>.
/// </summary>
/// <seealso cref="DistanceSquaredTo(Vector3i)"/>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="to">The other vector to use.</param>
/// <returns>The distance between the two vectors.</returns>
- public real_t DistanceTo(Vector3i b)
+ public real_t DistanceTo(Vector3i to)
{
- return (b - this).Length();
+ return (to - this).Length();
}
/// <summary>
- /// Returns the dot product of this vector and <paramref name="b"/>.
+ /// Returns the dot product of this vector and <paramref name="with"/>.
/// </summary>
- /// <param name="b">The other vector to use.</param>
+ /// <param name="with">The other vector to use.</param>
/// <returns>The dot product of the two vectors.</returns>
- public int Dot(Vector3i b)
+ public int Dot(Vector3i with)
{
- return x * b.x + y * b.y + z * b.z;
+ return x * with.x + y * with.y + z * with.z;
}
/// <summary>
diff --git a/modules/mono/godotsharp_dirs.cpp b/modules/mono/godotsharp_dirs.cpp
index 24bd1ed492..2b4cc7fcc3 100644
--- a/modules/mono/godotsharp_dirs.cpp
+++ b/modules/mono/godotsharp_dirs.cpp
@@ -229,9 +229,6 @@ private:
#endif
}
- _GodotSharpDirs(const _GodotSharpDirs &);
- _GodotSharpDirs &operator=(const _GodotSharpDirs &);
-
public:
static _GodotSharpDirs &get_singleton() {
static _GodotSharpDirs singleton;
diff --git a/modules/mono/mono_gc_handle.h b/modules/mono/mono_gc_handle.h
index d0e51d159f..a18a4ce646 100644
--- a/modules/mono/mono_gc_handle.h
+++ b/modules/mono/mono_gc_handle.h
@@ -56,13 +56,12 @@ struct MonoGCHandleData {
void release();
- MonoGCHandleData &operator=(const MonoGCHandleData &p_other) {
+ void operator=(const MonoGCHandleData &p_other) {
#ifdef DEBUG_ENABLED
CRASH_COND(!is_released());
#endif
handle = p_other.handle;
type = p_other.type;
- return *this;
}
MonoGCHandleData(const MonoGCHandleData &) = default;
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index 179bbfb40c..bcdcd6623b 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -121,12 +121,10 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
ERR_FAIL_COND(da->list_dir_begin() != OK);
- String current;
- while ((current = da->get_next()).length()) {
- if (da->current_is_dir()) {
- continue;
- }
- if (!current.ends_with(".txt")) {
+ String current = da->get_next();
+ while (!current.is_empty()) {
+ if (da->current_is_dir() || !current.ends_with(".txt")) {
+ current = da->get_next();
continue;
}
@@ -135,6 +133,7 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) {
if (OS::get_singleton()->get_unix_time() - modified_time > MAX_SECS) {
da->remove(current);
}
+ current = da->get_next();
}
da->list_dir_end();
diff --git a/modules/navigation/navigation_mesh_generator.cpp b/modules/navigation/navigation_mesh_generator.cpp
index 05e040b518..0bce0fc9f0 100644
--- a/modules/navigation/navigation_mesh_generator.cpp
+++ b/modules/navigation/navigation_mesh_generator.cpp
@@ -36,6 +36,7 @@
#include "core/os/thread.h"
#include "scene/3d/collision_shape_3d.h"
#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/multimesh_instance_3d.h"
#include "scene/3d/physics_body_3d.h"
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/capsule_shape_3d.h"
@@ -63,17 +64,17 @@
NavigationMeshGenerator *NavigationMeshGenerator::singleton = nullptr;
-void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies) {
- p_verticies.push_back(p_vec3.x);
- p_verticies.push_back(p_vec3.y);
- p_verticies.push_back(p_vec3.z);
+void NavigationMeshGenerator::_add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices) {
+ p_vertices.push_back(p_vec3.x);
+ p_vertices.push_back(p_vec3.y);
+ p_vertices.push_back(p_vec3.z);
}
-void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int current_vertex_count;
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
- current_vertex_count = p_verticies.size() / 3;
+ current_vertex_count = p_vertices.size() / 3;
if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES) {
continue;
@@ -100,7 +101,7 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
const int *ir = mesh_indices.ptr();
for (int j = 0; j < mesh_vertices.size(); j++) {
- _add_vertex(p_xform.xform(vr[j]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j]), p_vertices);
}
for (int j = 0; j < face_count; j++) {
@@ -112,9 +113,9 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
} else {
face_count = mesh_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_verticies);
- _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_verticies);
+ _add_vertex(p_xform.xform(vr[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 2]), p_vertices);
+ _add_vertex(p_xform.xform(vr[j * 3 + 1]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 1));
@@ -124,14 +125,14 @@ void NavigationMeshGenerator::_add_mesh(const Ref<Mesh> &p_mesh, const Transform
}
}
-void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices) {
+void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices) {
int face_count = p_faces.size() / 3;
- int current_vertex_count = p_verticies.size() / 3;
+ int current_vertex_count = p_vertices.size() / 3;
for (int j = 0; j < face_count; j++) {
- _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_verticies);
- _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_verticies);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 0]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 1]), p_vertices);
+ _add_vertex(p_xform.xform(p_faces[j * 3 + 2]), p_vertices);
p_indices.push_back(current_vertex_count + (j * 3 + 0));
p_indices.push_back(current_vertex_count + (j * 3 + 2));
@@ -139,12 +140,27 @@ void NavigationMeshGenerator::_add_faces(const PackedVector3Array &p_faces, cons
}
}
-void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
+void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children) {
if (Object::cast_to<MeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
MeshInstance3D *mesh_instance = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mesh_instance->get_mesh();
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * mesh_instance->get_transform(), p_vertices, p_indices);
+ }
+ }
+
+ if (Object::cast_to<MultiMeshInstance3D>(p_node) && p_generate_from != NavigationMesh::PARSED_GEOMETRY_STATIC_COLLIDERS) {
+ MultiMeshInstance3D *multimesh_instance = Object::cast_to<MultiMeshInstance3D>(p_node);
+ Ref<MultiMesh> multimesh = multimesh_instance->get_multimesh();
+ Ref<Mesh> mesh = multimesh->get_mesh();
+ if (mesh.is_valid()) {
+ int n = multimesh->get_visible_instance_count();
+ if (n == -1) {
+ n = multimesh->get_instance_count();
+ }
+ for (int i = 0; i < n; i++) {
+ _add_mesh(mesh, p_accumulated_transform * multimesh->get_instance_transform(i), p_vertices, p_indices);
+ }
}
}
@@ -155,7 +171,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (!meshes.is_empty()) {
Ref<Mesh> mesh = meshes[1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * csg_shape->get_transform(), p_vertices, p_indices);
}
}
}
@@ -213,7 +229,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
ConcavePolygonShape3D *concave_polygon = Object::cast_to<ConcavePolygonShape3D>(*s);
if (concave_polygon) {
- _add_faces(concave_polygon->get_faces(), transform, p_verticies, p_indices);
+ _add_faces(concave_polygon->get_faces(), transform, p_vertices, p_indices);
}
ConvexPolygonShape3D *convex_polygon = Object::cast_to<ConvexPolygonShape3D>(*s);
@@ -236,12 +252,12 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
}
}
- _add_faces(faces, transform, p_verticies, p_indices);
+ _add_faces(faces, transform, p_vertices, p_indices);
}
}
if (mesh.is_valid()) {
- _add_mesh(mesh, transform, p_verticies, p_indices);
+ _add_mesh(mesh, transform, p_vertices, p_indices);
}
}
}
@@ -256,7 +272,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
for (int i = 0; i < meshes.size(); i += 2) {
Ref<Mesh> mesh = meshes[i + 1];
if (mesh.is_valid()) {
- _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_verticies, p_indices);
+ _add_mesh(mesh, p_accumulated_transform * xform * (Transform3D)meshes[i], p_vertices, p_indices);
}
}
}
@@ -269,7 +285,7 @@ void NavigationMeshGenerator::_parse_geometry(Transform3D p_accumulated_transfor
if (p_recurse_children) {
for (int i = 0; i < p_node->get_child_count(); i++) {
- _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_verticies, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
+ _parse_geometry(p_accumulated_transform, p_node->get_child(i), p_vertices, p_indices, p_generate_from, p_collision_mask, p_recurse_children);
}
}
}
diff --git a/modules/navigation/navigation_mesh_generator.h b/modules/navigation/navigation_mesh_generator.h
index 78f1329e3f..dac844c68e 100644
--- a/modules/navigation/navigation_mesh_generator.h
+++ b/modules/navigation/navigation_mesh_generator.h
@@ -49,10 +49,10 @@ class NavigationMeshGenerator : public Object {
protected:
static void _bind_methods();
- static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_verticies);
- static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_verticies, Vector<int> &p_indices);
- static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_verticies, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
+ static void _add_vertex(const Vector3 &p_vec3, Vector<float> &p_vertices);
+ static void _add_mesh(const Ref<Mesh> &p_mesh, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _add_faces(const PackedVector3Array &p_faces, const Transform3D &p_xform, Vector<float> &p_vertices, Vector<int> &p_indices);
+ static void _parse_geometry(Transform3D p_accumulated_transform, Node *p_node, Vector<float> &p_vertices, Vector<int> &p_indices, NavigationMesh::ParsedGeometryType p_generate_from, uint32_t p_collision_mask, bool p_recurse_children);
static void _convert_detail_mesh_to_native_navigation_mesh(const rcPolyMeshDetail *p_detail_mesh, Ref<NavigationMesh> p_nav_mesh);
static void _build_recast_navigation_mesh(
diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp
index 7450215cfb..0abd255c7c 100644
--- a/platform/iphone/export/export_plugin.cpp
+++ b/platform/iphone/export/export_plugin.cpp
@@ -728,10 +728,10 @@ Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref<EditorExp
Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata) {
Vector<String> dirs;
- String path;
String current_dir = p_da->get_current_dir();
p_da->list_dir_begin();
- while ((path = p_da->get_next()).length() != 0) {
+ String path = p_da->get_next();
+ while (!path.is_empty()) {
if (p_da->current_is_dir()) {
if (path != "." && path != "..") {
dirs.push_back(path);
@@ -743,6 +743,7 @@ Error EditorExportPlatformIOS::_walk_dir_recursive(DirAccess *p_da, FileHandler
return err;
}
}
+ path = p_da->get_next();
}
p_da->list_dir_end();
diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp
index a88f7bb332..36a2e5e205 100644
--- a/platform/osx/export/export_plugin.cpp
+++ b/platform/osx/export/export_plugin.cpp
@@ -960,9 +960,10 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
DirAccessRef da = DirAccess::open(dir);
da->list_dir_begin();
- String f;
- while ((f = da->get_next()) != "") {
+ String f = da->get_next();
+ while (!f.is_empty()) {
if (f == "." || f == "..") {
+ f = da->get_next();
continue;
}
if (da->is_link(f)) {
@@ -1065,6 +1066,7 @@ void EditorExportPlatformOSX::_zip_folder_recursive(zipFile &p_zip, const String
zipCloseFileInZip(p_zip);
}
+ f = da->get_next();
}
da->list_dir_end();
}
diff --git a/scene/2d/cpu_particles_2d.cpp b/scene/2d/cpu_particles_2d.cpp
index 80c17b6e88..8d997bb1f5 100644
--- a/scene/2d/cpu_particles_2d.cpp
+++ b/scene/2d/cpu_particles_2d.cpp
@@ -890,7 +890,7 @@ void CPUParticles2D::_particles_process(double p_delta) {
real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.rotation = Math::deg2rad(base_angle); //angle
- p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed));
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed));
}
//apply color
//apply hue rotation
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index ed30e871d7..40211f2a9b 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -100,16 +100,18 @@ void Path2D::_notification(int p_what) {
#endif
const Color color = Color(0.5, 0.6, 1.0, 0.7);
- for (int i = 0; i < curve->get_point_count(); i++) {
- Vector2 prev_p = curve->get_point_position(i);
+ _cached_draw_pts.resize(curve->get_point_count() * 8);
+ int count = 0;
- for (int j = 1; j <= 8; j++) {
- real_t frac = j / 8.0;
+ for (int i = 0; i < curve->get_point_count(); i++) {
+ for (int j = 0; j < 8; j++) {
+ real_t frac = j * (1.0 / 8.0);
Vector2 p = curve->interpolate(i, frac);
- draw_line(prev_p, p, color, line_width);
- prev_p = p;
+ _cached_draw_pts.set(count++, p);
}
}
+
+ draw_polyline(_cached_draw_pts, color, line_width, true);
}
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 3b12f025fc..7e8478283f 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -38,6 +38,7 @@ class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);
Ref<Curve2D> curve;
+ Vector<Vector2> _cached_draw_pts;
void _curve_changed();
diff --git a/scene/3d/cpu_particles_3d.cpp b/scene/3d/cpu_particles_3d.cpp
index d347d24c2c..b081142fbf 100644
--- a/scene/3d/cpu_particles_3d.cpp
+++ b/scene/3d/cpu_particles_3d.cpp
@@ -881,53 +881,53 @@ void CPUParticles3D::_particles_process(double p_delta) {
p.custom[1] = p.time / lifetime;
tv = p.time / p.lifetime;
- real_t tex_linear_velocity = 0.0;
+ real_t tex_linear_velocity = 1.0;
if (curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) {
tex_linear_velocity = curve_parameters[PARAM_INITIAL_LINEAR_VELOCITY]->interpolate(tv);
}
- real_t tex_orbit_velocity = 0.0;
+ real_t tex_orbit_velocity = 1.0;
if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) {
if (curve_parameters[PARAM_ORBIT_VELOCITY].is_valid()) {
tex_orbit_velocity = curve_parameters[PARAM_ORBIT_VELOCITY]->interpolate(tv);
}
}
- real_t tex_angular_velocity = 0.0;
+ real_t tex_angular_velocity = 1.0;
if (curve_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) {
tex_angular_velocity = curve_parameters[PARAM_ANGULAR_VELOCITY]->interpolate(tv);
}
- real_t tex_linear_accel = 0.0;
+ real_t tex_linear_accel = 1.0;
if (curve_parameters[PARAM_LINEAR_ACCEL].is_valid()) {
tex_linear_accel = curve_parameters[PARAM_LINEAR_ACCEL]->interpolate(tv);
}
- real_t tex_tangential_accel = 0.0;
+ real_t tex_tangential_accel = 1.0;
if (curve_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) {
tex_tangential_accel = curve_parameters[PARAM_TANGENTIAL_ACCEL]->interpolate(tv);
}
- real_t tex_radial_accel = 0.0;
+ real_t tex_radial_accel = 1.0;
if (curve_parameters[PARAM_RADIAL_ACCEL].is_valid()) {
tex_radial_accel = curve_parameters[PARAM_RADIAL_ACCEL]->interpolate(tv);
}
- real_t tex_damping = 0.0;
+ real_t tex_damping = 1.0;
if (curve_parameters[PARAM_DAMPING].is_valid()) {
tex_damping = curve_parameters[PARAM_DAMPING]->interpolate(tv);
}
- real_t tex_angle = 0.0;
+ real_t tex_angle = 1.0;
if (curve_parameters[PARAM_ANGLE].is_valid()) {
tex_angle = curve_parameters[PARAM_ANGLE]->interpolate(tv);
}
- real_t tex_anim_speed = 0.0;
+ real_t tex_anim_speed = 1.0;
if (curve_parameters[PARAM_ANIM_SPEED].is_valid()) {
tex_anim_speed = curve_parameters[PARAM_ANIM_SPEED]->interpolate(tv);
}
- real_t tex_anim_offset = 0.0;
+ real_t tex_anim_offset = 1.0;
if (curve_parameters[PARAM_ANIM_OFFSET].is_valid()) {
tex_anim_offset = curve_parameters[PARAM_ANIM_OFFSET]->interpolate(tv);
}
@@ -984,7 +984,7 @@ void CPUParticles3D::_particles_process(double p_delta) {
real_t base_angle = (tex_angle)*Math::lerp(parameters_min[PARAM_ANGLE], parameters_max[PARAM_ANGLE], p.angle_rand);
base_angle += p.custom[1] * lifetime * tex_angular_velocity * Math::lerp(parameters_min[PARAM_ANGULAR_VELOCITY], parameters_max[PARAM_ANGULAR_VELOCITY], rand_from_seed(alt_seed));
p.custom[0] = Math::deg2rad(base_angle); //angle
- p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + p.custom[1] * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle
+ p.custom[2] = tex_anim_offset * Math::lerp(parameters_min[PARAM_ANIM_OFFSET], parameters_max[PARAM_ANIM_OFFSET], p.anim_offset_rand) + tv * tex_anim_speed * Math::lerp(parameters_min[PARAM_ANIM_SPEED], parameters_max[PARAM_ANIM_SPEED], rand_from_seed(alt_seed)); //angle
}
//apply color
//apply hue rotation
diff --git a/scene/3d/soft_dynamic_body_3d.cpp b/scene/3d/soft_dynamic_body_3d.cpp
index 5546b88fb1..d9907430fc 100644
--- a/scene/3d/soft_dynamic_body_3d.cpp
+++ b/scene/3d/soft_dynamic_body_3d.cpp
@@ -100,12 +100,11 @@ SoftDynamicBody3D::PinnedPoint::PinnedPoint(const PinnedPoint &obj_tocopy) {
offset = obj_tocopy.offset;
}
-SoftDynamicBody3D::PinnedPoint &SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
+void SoftDynamicBody3D::PinnedPoint::operator=(const PinnedPoint &obj) {
point_index = obj.point_index;
spatial_attachment_path = obj.spatial_attachment_path;
spatial_attachment = obj.spatial_attachment;
offset = obj.offset;
- return *this;
}
void SoftDynamicBody3D::_update_pickable() {
diff --git a/scene/3d/soft_dynamic_body_3d.h b/scene/3d/soft_dynamic_body_3d.h
index 57e116aa05..daef9acac0 100644
--- a/scene/3d/soft_dynamic_body_3d.h
+++ b/scene/3d/soft_dynamic_body_3d.h
@@ -80,7 +80,7 @@ public:
PinnedPoint();
PinnedPoint(const PinnedPoint &obj_tocopy);
- PinnedPoint &operator=(const PinnedPoint &obj);
+ void operator=(const PinnedPoint &obj);
};
private:
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index 90af70e7c2..197a5c0f27 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -625,6 +625,7 @@ void Sprite3D::set_texture(const Ref<Texture2D> &p_texture) {
texture->connect(CoreStringNames::get_singleton()->changed, Callable(this, "_queue_update"));
}
_queue_update();
+ emit_signal(SceneStringNames::get_singleton()->texture_changed);
}
Ref<Texture2D> Sprite3D::get_texture() const {
@@ -780,6 +781,7 @@ void Sprite3D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_SIGNAL(MethodInfo("frame_changed"));
+ ADD_SIGNAL(MethodInfo("texture_changed"));
}
Sprite3D::Sprite3D() {
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 44853fc006..e3754c4d38 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -473,6 +473,13 @@ void FileDialog::update_file_list() {
dir_access->list_dir_begin();
+ if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
+ message->hide();
+ } else {
+ message->set_text(TTRC("You don't have permission to access contents of this folder."));
+ message->show();
+ }
+
TreeItem *root = tree->create_item();
Ref<Texture2D> folder = vbox->get_theme_icon(SNAME("folder"), SNAME("FileDialog"));
Ref<Texture2D> file_icon = vbox->get_theme_icon(SNAME("file"), SNAME("FileDialog"));
@@ -482,17 +489,11 @@ void FileDialog::update_file_list() {
List<String> dirs;
bool is_hidden;
- String item;
-
- if (dir_access->is_readable(dir_access->get_current_dir().utf8().get_data())) {
- message->hide();
- } else {
- message->set_text(TTRC("You don't have permission to access contents of this folder."));
- message->show();
- }
+ String item = dir_access->get_next();
- while ((item = dir_access->get_next()) != "") {
+ while (!item.is_empty()) {
if (item == "." || item == "..") {
+ item = dir_access->get_next();
continue;
}
@@ -505,6 +506,7 @@ void FileDialog::update_file_list() {
dirs.push_back(item);
}
}
+ item = dir_access->get_next();
}
dirs.sort_custom<NaturalNoCaseComparator>();
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 69b08fda3c..30a6f0fc9a 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -322,7 +322,7 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) {
deselect();
selection.start_column = caret_column;
selection.creating = true;
- } else if (selection.enabled) {
+ } else if (selection.enabled && !selection.double_click) {
selection.drag_attempt = true;
}
}
@@ -588,13 +588,19 @@ void LineEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
if (p_data.get_type() == Variant::STRING && is_editable()) {
set_caret_at_pixel_pos(p_point.x);
int caret_column_tmp = caret_column;
+ bool is_inside_sel = selection.enabled && caret_column >= selection.begin && caret_column <= selection.end;
+ if (Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ is_inside_sel = selection.enabled && caret_column > selection.begin && caret_column < selection.end;
+ }
if (selection.drag_attempt) {
selection.drag_attempt = false;
- if (caret_column < selection.begin || caret_column > selection.end) {
- if (caret_column_tmp > selection.end) {
- caret_column_tmp = caret_column_tmp - (selection.end - selection.begin);
+ if (!is_inside_sel) {
+ if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ if (caret_column_tmp > selection.end) {
+ caret_column_tmp = caret_column_tmp - (selection.end - selection.begin);
+ }
+ selection_delete();
}
- selection_delete();
set_caret_column(caret_column_tmp);
insert_text_at_caret(p_data);
@@ -975,7 +981,7 @@ void LineEdit::_notification(int p_what) {
if (is_drag_successful()) {
if (selection.drag_attempt) {
selection.drag_attempt = false;
- if (is_editable()) {
+ if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
selection_delete();
} else if (deselect_on_focus_loss_enabled) {
deselect();
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index 9f4ec558dc..9c87d07f66 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -68,7 +68,6 @@ class ScrollContainer : public Container {
protected:
Size2 get_minimum_size() const override;
- virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
void _gui_focus_changed(Control *p_control);
void _update_dimensions();
void _notification(int p_what);
@@ -80,6 +79,8 @@ protected:
void _update_scrollbar_position();
public:
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
+
void set_h_scroll(int p_pos);
int get_h_scroll() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 2cb9d10fca..dedcc266e0 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -39,6 +39,7 @@
#include "core/os/os.h"
#include "core/string/string_builder.h"
#include "core/string/translation.h"
+#include "label.h"
#include "scene/main/window.h"
@@ -1224,7 +1225,7 @@ void TextEdit::_notification(int p_what) {
if (caret.draw_pos.x >= xmargin_beg && caret.draw_pos.x < xmargin_end) {
caret.visible = true;
- if (draw_caret) {
+ if (draw_caret || drag_caret_force_displayed) {
if (caret_type == CaretType::CARET_TYPE_BLOCK || overtype_mode) {
//Block or underline caret, draw trailing carets at full height.
int h = font->get_height(font_size);
@@ -1391,7 +1392,7 @@ void TextEdit::_notification(int p_what) {
DisplayServer::get_singleton()->virtual_keyboard_hide();
}
- if (deselect_on_focus_loss_enabled) {
+ if (deselect_on_focus_loss_enabled && !selection.drag_attempt) {
deselect();
}
} break;
@@ -1411,6 +1412,30 @@ void TextEdit::_notification(int p_what) {
update();
}
} break;
+ case Control::NOTIFICATION_DRAG_BEGIN: {
+ selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
+ drag_action = true;
+ dragging_minimap = false;
+ dragging_selection = false;
+ can_drag_minimap = false;
+ click_select_held->stop();
+ } break;
+ case Control::NOTIFICATION_DRAG_END: {
+ if (is_drag_successful()) {
+ if (selection.drag_attempt) {
+ selection.drag_attempt = false;
+ if (is_editable() && !Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ delete_selection();
+ } else if (deselect_on_focus_loss_enabled) {
+ deselect();
+ }
+ }
+ } else {
+ selection.drag_attempt = false;
+ }
+ drag_action = false;
+ drag_caret_force_displayed = false;
+ } break;
}
}
@@ -1495,6 +1520,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
set_caret_line(row, false, false);
set_caret_column(col);
+ selection.drag_attempt = false;
if (mb->is_shift_pressed() && (caret.column != prev_col || caret.line != prev_line)) {
if (!selection.active) {
@@ -1538,6 +1564,9 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
update();
}
+ } else if (is_mouse_over_selection()) {
+ selection.selecting_mode = SelectionMode::SELECTION_MODE_NONE;
+ selection.drag_attempt = true;
} else {
selection.active = false;
selection.selecting_mode = SelectionMode::SELECTION_MODE_POINTER;
@@ -1551,6 +1580,7 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
if (!mb->is_double_click() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < triple_click_timeout && mb->get_position().distance_to(last_dblclk_pos) < triple_click_tolerance) {
// Triple-click select line.
selection.selecting_mode = SelectionMode::SELECTION_MODE_LINE;
+ selection.drag_attempt = false;
_update_selection_mode_line();
last_dblclk = 0;
} else if (mb->is_double_click() && text[caret.line].length()) {
@@ -1601,10 +1631,16 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
if (mb->get_button_index() == MouseButton::LEFT) {
+ if (selection.drag_attempt && is_mouse_over_selection()) {
+ selection.active = false;
+ }
dragging_minimap = false;
dragging_selection = false;
can_drag_minimap = false;
click_select_held->stop();
+ if (!drag_action) {
+ selection.drag_attempt = false;
+ }
if (DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_CLIPBOARD_PRIMARY)) {
DisplayServer::get_singleton()->clipboard_set_primary(get_selected_text());
}
@@ -1689,6 +1725,14 @@ void TextEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
hovered_gutter = current_hovered_gutter;
update();
}
+
+ if (drag_action && can_drop_data(mpos, get_viewport()->gui_get_drag_data())) {
+ drag_caret_force_displayed = true;
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ set_caret_line(pos.y, false);
+ set_caret_column(pos.x);
+ dragging_selection = true;
+ }
}
if (draw_minimap && !dragging_selection) {
@@ -2406,6 +2450,75 @@ bool TextEdit::is_text_field() const {
return true;
}
+Variant TextEdit::get_drag_data(const Point2 &p_point) {
+ if (selection.active && selection.drag_attempt) {
+ String t = get_selected_text();
+ Label *l = memnew(Label);
+ l->set_text(t);
+ set_drag_preview(l);
+ return t;
+ }
+
+ return Variant();
+}
+
+bool TextEdit::can_drop_data(const Point2 &p_point, const Variant &p_data) const {
+ bool drop_override = Control::can_drop_data(p_point, p_data); // In case user wants to drop custom data.
+ if (drop_override) {
+ return drop_override;
+ }
+
+ return is_editable() && p_data.get_type() == Variant::STRING;
+}
+
+void TextEdit::drop_data(const Point2 &p_point, const Variant &p_data) {
+ Control::drop_data(p_point, p_data);
+
+ if (p_data.get_type() == Variant::STRING && is_editable()) {
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ int caret_row_tmp = pos.y;
+ int caret_column_tmp = pos.x;
+ if (selection.drag_attempt) {
+ selection.drag_attempt = false;
+ if (!is_mouse_over_selection(!Input::get_singleton()->is_key_pressed(Key::CTRL))) {
+ begin_complex_operation();
+ if (!Input::get_singleton()->is_key_pressed(Key::CTRL)) {
+ if (caret_row_tmp > selection.to_line) {
+ caret_row_tmp = caret_row_tmp - (selection.to_line - selection.from_line);
+ } else if (caret_row_tmp == selection.to_line && caret_column_tmp >= selection.to_column) {
+ caret_column_tmp = caret_column_tmp - (selection.to_column - selection.from_column);
+ }
+ delete_selection();
+ } else {
+ deselect();
+ }
+
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ end_complex_operation();
+ }
+ } else if (is_mouse_over_selection()) {
+ caret_row_tmp = selection.from_line;
+ caret_column_tmp = selection.from_column;
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ grab_focus();
+ } else {
+ deselect();
+ set_caret_line(caret_row_tmp, true, false);
+ set_caret_column(caret_column_tmp);
+ insert_text_at_caret(p_data);
+ grab_focus();
+ }
+
+ if (caret_row_tmp != caret.line || caret_column_tmp != caret.column) {
+ select(caret_row_tmp, caret_column_tmp, caret.line, caret.column);
+ }
+ }
+}
+
Control::CursorShape TextEdit::get_cursor_shape(const Point2 &p_pos) const {
Point2i pos = get_line_column_at_pos(p_pos);
int row = pos.y;
@@ -3580,6 +3693,21 @@ bool TextEdit::is_dragging_cursor() const {
return dragging_selection || dragging_minimap;
}
+bool TextEdit::is_mouse_over_selection(bool p_edges) const {
+ if (!has_selection()) {
+ return false;
+ }
+ Point2i pos = get_line_column_at_pos(get_local_mouse_pos());
+ int row = pos.y;
+ int col = pos.x;
+ if (p_edges) {
+ if ((row == selection.from_line && col == selection.from_column) || (row == selection.to_line && col == selection.to_column)) {
+ return true;
+ }
+ }
+ return (row >= selection.from_line && row <= selection.to_line && (row > selection.from_line || col > selection.from_column) && (row < selection.to_line || col < selection.to_column));
+}
+
/* Caret */
void TextEdit::set_caret_type(CaretType p_type) {
caret_type = p_type;
@@ -4776,6 +4904,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_minimap_line_at_pos", "position"), &TextEdit::get_minimap_line_at_pos);
ClassDB::bind_method(D_METHOD("is_dragging_cursor"), &TextEdit::is_dragging_cursor);
+ ClassDB::bind_method(D_METHOD("is_mouse_over_selection", "edges"), &TextEdit::is_mouse_over_selection);
/* Caret. */
BIND_ENUM_CONSTANT(CARET_TYPE_LINE);
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 42b21cbe9c..a1b2ed59f5 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -375,6 +375,9 @@ private:
bool caret_mid_grapheme_enabled = false;
+ bool drag_action = false;
+ bool drag_caret_force_displayed = false;
+
void _emit_caret_changed();
void _reset_caret_blink_timer();
@@ -400,6 +403,7 @@ private:
int to_column = 0;
bool shiftclick_left = false;
+ bool drag_attempt = false;
} selection;
bool selecting_enabled = true;
@@ -611,6 +615,9 @@ public:
virtual Size2 get_minimum_size() const override;
virtual bool is_text_field() const override;
virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
+ virtual Variant get_drag_data(const Point2 &p_point) override;
+ virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override;
+ virtual void drop_data(const Point2 &p_point, const Variant &p_data) override;
virtual String get_tooltip(const Point2 &p_pos) const override;
void set_tooltip_request_func(Object *p_obj, const StringName &p_function, const Variant &p_udata);
@@ -731,6 +738,7 @@ public:
int get_minimap_line_at_pos(const Point2i &p_pos) const;
bool is_dragging_cursor() const;
+ bool is_mouse_over_selection(bool p_edges = true) const;
/* Caret */
void set_caret_type(CaretType p_type);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 621d5f765b..007e5d1173 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -396,14 +396,15 @@ void Viewport::_notification(int p_what) {
#ifndef _3D_DISABLED
PhysicsServer3D::get_singleton()->space_set_debug_contacts(find_world_3d()->get_space(), get_tree()->get_collision_debug_contact_count());
contact_3d_debug_multimesh = RenderingServer::get_singleton()->multimesh_create();
- RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, true);
+ RenderingServer::get_singleton()->multimesh_allocate_data(contact_3d_debug_multimesh, get_tree()->get_collision_debug_contact_count(), RS::MULTIMESH_TRANSFORM_3D, false);
RenderingServer::get_singleton()->multimesh_set_visible_instances(contact_3d_debug_multimesh, 0);
RenderingServer::get_singleton()->multimesh_set_mesh(contact_3d_debug_multimesh, get_tree()->get_debug_contact_mesh()->get_rid());
contact_3d_debug_instance = RenderingServer::get_singleton()->instance_create();
RenderingServer::get_singleton()->instance_set_base(contact_3d_debug_instance, contact_3d_debug_multimesh);
RenderingServer::get_singleton()->instance_set_scenario(contact_3d_debug_instance, find_world_3d()->get_scenario());
- //RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, true);
+ RenderingServer::get_singleton()->instance_geometry_set_flag(contact_3d_debug_instance, RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE, true);
#endif // _3D_DISABLED
+ set_physics_process_internal(true);
}
} break;
@@ -1868,14 +1869,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
Transform2D localizer = gui.drag_mouse_over->get_global_transform_with_canvas().affine_inverse();
gui.drag_mouse_over_pos = localizer.xform(viewport_pos);
- if ((mm->get_button_mask() & MouseButton::MASK_LEFT) != MouseButton::NONE) {
- bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
+ bool can_drop = _gui_drop(gui.drag_mouse_over, gui.drag_mouse_over_pos, true);
- if (!can_drop) {
- ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN;
- } else {
- ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP;
- }
+ if (!can_drop) {
+ ds_cursor_shape = DisplayServer::CURSOR_FORBIDDEN;
+ } else {
+ ds_cursor_shape = DisplayServer::CURSOR_CAN_DROP;
}
}
@@ -2043,6 +2042,7 @@ void Viewport::_gui_force_drag(Control *p_base, const Variant &p_data, Control *
if (p_control) {
_gui_set_drag_preview(p_base, p_control);
}
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
}
void Viewport::_gui_set_drag_preview(Control *p_base, Control *p_control) {
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 056ace5e4e..b1178b9263 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -1031,6 +1031,16 @@ void register_scene_types() {
GLOBAL_DEF_BASIC(vformat("layer_names/3d_navigation/layer_%d", i + 1), "");
}
+ if (RenderingServer::get_singleton()) {
+ ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed.
+ }
+
+ SceneDebugger::initialize();
+
+ NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
+}
+
+void initialize_theme() {
bool default_theme_hidpi = GLOBAL_DEF("gui/theme/use_hidpi", false);
ProjectSettings::get_singleton()->set_custom_property_info("gui/theme/use_hidpi", PropertyInfo(Variant::BOOL, "gui/theme/use_hidpi", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
String theme_path = GLOBAL_DEF_RST("gui/theme/custom", "");
@@ -1049,7 +1059,6 @@ void register_scene_types() {
// Always make the default theme to avoid invalid default font/icon/style in the given theme.
if (RenderingServer::get_singleton()) {
make_default_theme(default_theme_hidpi, font);
- ColorPicker::init_shaders(); // RenderingServer needs to exist for this to succeed.
}
if (theme_path != String()) {
@@ -1063,9 +1072,6 @@ void register_scene_types() {
ERR_PRINT("Error loading custom theme '" + theme_path + "'");
}
}
- SceneDebugger::initialize();
-
- NativeExtensionManager::get_singleton()->initialize_extensions(NativeExtension::INITIALIZATION_LEVEL_SCENE);
}
void unregister_scene_types() {
diff --git a/scene/register_scene_types.h b/scene/register_scene_types.h
index 1ff542eef8..32ab165fb3 100644
--- a/scene/register_scene_types.h
+++ b/scene/register_scene_types.h
@@ -34,4 +34,6 @@
void register_scene_types();
void unregister_scene_types();
+void initialize_theme();
+
#endif
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index b87639de6a..bf3efd7599 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -33,15 +33,15 @@
#include "core/core_string_names.h"
template <class T>
-static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control_2, T end) {
+static _FORCE_INLINE_ T _bezier_interp(real_t p_t, T p_start, T p_control_1, T p_control_2, T p_end) {
/* Formula from Wikipedia article on Bezier curves. */
- real_t omt = (1.0 - t);
+ real_t omt = (1.0 - p_t);
real_t omt2 = omt * omt;
real_t omt3 = omt2 * omt;
- real_t t2 = t * t;
- real_t t3 = t2 * t;
+ real_t t2 = p_t * p_t;
+ real_t t3 = t2 * p_t;
- return start * omt3 + control_1 * omt2 * t * 3.0 + control_2 * omt * t2 * 3.0 + end * t3;
+ return p_start * omt3 + p_control_1 * omt2 * p_t * 3.0 + p_control_2 * omt * t2 * 3.0 + p_end * t3;
}
const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
@@ -49,46 +49,46 @@ const char *Curve::SIGNAL_RANGE_CHANGED = "range_changed";
Curve::Curve() {
}
-int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, TangentMode left_mode, TangentMode right_mode) {
+int Curve::add_point(Vector2 p_position, real_t p_left_tangent, real_t p_right_tangent, TangentMode p_left_mode, TangentMode p_right_mode) {
// Add a point and preserve order
// Curve bounds is in 0..1
- if (p_pos.x > MAX_X) {
- p_pos.x = MAX_X;
- } else if (p_pos.x < MIN_X) {
- p_pos.x = MIN_X;
+ if (p_position.x > MAX_X) {
+ p_position.x = MAX_X;
+ } else if (p_position.x < MIN_X) {
+ p_position.x = MIN_X;
}
int ret = -1;
if (_points.size() == 0) {
- _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
} else if (_points.size() == 1) {
// TODO Is the `else` able to handle this block already?
- real_t diff = p_pos.x - _points[0].pos.x;
+ real_t diff = p_position.x - _points[0].position.x;
if (diff > 0) {
- _points.push_back(Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.push_back(Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 1;
} else {
- _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
}
} else {
- int i = get_index(p_pos.x);
+ int i = get_index(p_position.x);
- if (i == 0 && p_pos.x < _points[0].pos.x) {
+ if (i == 0 && p_position.x < _points[0].position.x) {
// Insert before anything else
- _points.insert(0, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(0, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = 0;
} else {
// Insert between i and i+1
++i;
- _points.insert(i, Point(p_pos, left_tangent, right_tangent, left_mode, right_mode));
+ _points.insert(i, Point(p_position, p_left_tangent, p_right_tangent, p_left_mode, p_right_mode));
ret = i;
}
}
@@ -100,7 +100,7 @@ int Curve::add_point(Vector2 p_pos, real_t left_tangent, real_t right_tangent, T
return ret;
}
-int Curve::get_index(real_t offset) const {
+int Curve::get_index(real_t p_offset) const {
// Lower-bound float binary search
int imin = 0;
@@ -109,13 +109,13 @@ int Curve::get_index(real_t offset) const {
while (imax - imin > 1) {
int m = (imin + imax) / 2;
- real_t a = _points[m].pos.x;
- real_t b = _points[m + 1].pos.x;
+ real_t a = _points[m].position.x;
+ real_t b = _points[m + 1].position.x;
- if (a < offset && b < offset) {
+ if (a < p_offset && b < p_offset) {
imin = m;
- } else if (a > offset) {
+ } else if (a > p_offset) {
imax = m;
} else {
@@ -124,7 +124,7 @@ int Curve::get_index(real_t offset) const {
}
// Will happen if the offset is out of bounds
- if (offset > _points[imax].pos.x) {
+ if (p_offset > _points[imax].position.x) {
return imax;
}
return imin;
@@ -134,7 +134,7 @@ void Curve::clean_dupes() {
bool dirty = false;
for (int i = 1; i < _points.size(); ++i) {
- real_t diff = _points[i - 1].pos.x - _points[i].pos.x;
+ real_t diff = _points[i - 1].position.x - _points[i].position.x;
if (diff <= CMP_EPSILON) {
_points.remove_at(i);
--i;
@@ -147,62 +147,62 @@ void Curve::clean_dupes() {
}
}
-void Curve::set_point_left_tangent(int i, real_t tangent) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].left_tangent = tangent;
- _points.write[i].left_mode = TANGENT_FREE;
+void Curve::set_point_left_tangent(int p_index, real_t p_tangent) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].left_tangent = p_tangent;
+ _points.write[p_index].left_mode = TANGENT_FREE;
mark_dirty();
}
-void Curve::set_point_right_tangent(int i, real_t tangent) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].right_tangent = tangent;
- _points.write[i].right_mode = TANGENT_FREE;
+void Curve::set_point_right_tangent(int p_index, real_t p_tangent) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].right_tangent = p_tangent;
+ _points.write[p_index].right_mode = TANGENT_FREE;
mark_dirty();
}
-void Curve::set_point_left_mode(int i, TangentMode p_mode) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].left_mode = p_mode;
- if (i > 0) {
+void Curve::set_point_left_mode(int p_index, TangentMode p_mode) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].left_mode = p_mode;
+ if (p_index > 0) {
if (p_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - _points[i].pos).normalized();
- _points.write[i].left_tangent = v.y / v.x;
+ Vector2 v = (_points[p_index - 1].position - _points[p_index].position).normalized();
+ _points.write[p_index].left_tangent = v.y / v.x;
}
}
mark_dirty();
}
-void Curve::set_point_right_mode(int i, TangentMode p_mode) {
- ERR_FAIL_INDEX(i, _points.size());
- _points.write[i].right_mode = p_mode;
- if (i + 1 < _points.size()) {
+void Curve::set_point_right_mode(int p_index, TangentMode p_mode) {
+ ERR_FAIL_INDEX(p_index, _points.size());
+ _points.write[p_index].right_mode = p_mode;
+ if (p_index + 1 < _points.size()) {
if (p_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - _points[i].pos).normalized();
- _points.write[i].right_tangent = v.y / v.x;
+ Vector2 v = (_points[p_index + 1].position - _points[p_index].position).normalized();
+ _points.write[p_index].right_tangent = v.y / v.x;
}
}
mark_dirty();
}
-real_t Curve::get_point_left_tangent(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), 0);
- return _points[i].left_tangent;
+real_t Curve::get_point_left_tangent(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), 0);
+ return _points[p_index].left_tangent;
}
-real_t Curve::get_point_right_tangent(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), 0);
- return _points[i].right_tangent;
+real_t Curve::get_point_right_tangent(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), 0);
+ return _points[p_index].right_tangent;
}
-Curve::TangentMode Curve::get_point_left_mode(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE);
- return _points[i].left_mode;
+Curve::TangentMode Curve::get_point_left_mode(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE);
+ return _points[p_index].left_mode;
}
-Curve::TangentMode Curve::get_point_right_mode(int i) const {
- ERR_FAIL_INDEX_V(i, _points.size(), TANGENT_FREE);
- return _points[i].right_mode;
+Curve::TangentMode Curve::get_point_right_mode(int p_index) const {
+ ERR_FAIL_INDEX_V(p_index, _points.size(), TANGENT_FREE);
+ return _points[p_index].right_mode;
}
void Curve::remove_point(int p_index) {
@@ -216,18 +216,18 @@ void Curve::clear_points() {
mark_dirty();
}
-void Curve::set_point_value(int p_index, real_t pos) {
+void Curve::set_point_value(int p_index, real_t p_position) {
ERR_FAIL_INDEX(p_index, _points.size());
- _points.write[p_index].pos.y = pos;
+ _points.write[p_index].position.y = p_position;
update_auto_tangents(p_index);
mark_dirty();
}
-int Curve::set_point_offset(int p_index, float offset) {
+int Curve::set_point_offset(int p_index, real_t p_offset) {
ERR_FAIL_INDEX_V(p_index, _points.size(), -1);
Point p = _points[p_index];
remove_point(p_index);
- int i = add_point(Vector2(offset, p.pos.y));
+ int i = add_point(Vector2(p_offset, p.position.y));
_points.write[i].left_tangent = p.left_tangent;
_points.write[i].right_tangent = p.right_tangent;
_points.write[i].left_mode = p.left_mode;
@@ -241,7 +241,7 @@ int Curve::set_point_offset(int p_index, float offset) {
Vector2 Curve::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, _points.size(), Vector2(0, 0));
- return _points[p_index].pos;
+ return _points[p_index].position;
}
Curve::Point Curve::get_point(int p_index) const {
@@ -249,35 +249,35 @@ Curve::Point Curve::get_point(int p_index) const {
return _points[p_index];
}
-void Curve::update_auto_tangents(int i) {
- Point &p = _points.write[i];
+void Curve::update_auto_tangents(int p_index) {
+ Point &p = _points.write[p_index];
- if (i > 0) {
+ if (p_index > 0) {
if (p.left_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - p.pos).normalized();
+ Vector2 v = (_points[p_index - 1].position - p.position).normalized();
p.left_tangent = v.y / v.x;
}
- if (_points[i - 1].right_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i - 1].pos - p.pos).normalized();
- _points.write[i - 1].right_tangent = v.y / v.x;
+ if (_points[p_index - 1].right_mode == TANGENT_LINEAR) {
+ Vector2 v = (_points[p_index - 1].position - p.position).normalized();
+ _points.write[p_index - 1].right_tangent = v.y / v.x;
}
}
- if (i + 1 < _points.size()) {
+ if (p_index + 1 < _points.size()) {
if (p.right_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - p.pos).normalized();
+ Vector2 v = (_points[p_index + 1].position - p.position).normalized();
p.right_tangent = v.y / v.x;
}
- if (_points[i + 1].left_mode == TANGENT_LINEAR) {
- Vector2 v = (_points[i + 1].pos - p.pos).normalized();
- _points.write[i + 1].left_tangent = v.y / v.x;
+ if (_points[p_index + 1].left_mode == TANGENT_LINEAR) {
+ Vector2 v = (_points[p_index + 1].position - p.position).normalized();
+ _points.write[p_index + 1].left_tangent = v.y / v.x;
}
}
}
#define MIN_Y_RANGE 0.01
-void Curve::set_min_value(float p_min) {
+void Curve::set_min_value(real_t p_min) {
if (_minmax_set_once & 0b11 && p_min > _max_value - MIN_Y_RANGE) {
_min_value = _max_value - MIN_Y_RANGE;
} else {
@@ -289,7 +289,7 @@ void Curve::set_min_value(float p_min) {
emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
-void Curve::set_max_value(float p_max) {
+void Curve::set_max_value(real_t p_max) {
if (_minmax_set_once & 0b11 && p_max < _min_value + MIN_Y_RANGE) {
_max_value = _min_value + MIN_Y_RANGE;
} else {
@@ -299,32 +299,32 @@ void Curve::set_max_value(float p_max) {
emit_signal(SNAME(SIGNAL_RANGE_CHANGED));
}
-real_t Curve::interpolate(real_t offset) const {
+real_t Curve::interpolate(real_t p_offset) const {
if (_points.size() == 0) {
return 0;
}
if (_points.size() == 1) {
- return _points[0].pos.y;
+ return _points[0].position.y;
}
- int i = get_index(offset);
+ int i = get_index(p_offset);
if (i == _points.size() - 1) {
- return _points[i].pos.y;
+ return _points[i].position.y;
}
- real_t local = offset - _points[i].pos.x;
+ real_t local = p_offset - _points[i].position.x;
if (i == 0 && local <= 0) {
- return _points[0].pos.y;
+ return _points[0].position.y;
}
return interpolate_local_nocheck(i, local);
}
-real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
- const Point a = _points[index];
- const Point b = _points[index + 1];
+real_t Curve::interpolate_local_nocheck(int p_index, real_t p_local_offset) const {
+ const Point a = _points[p_index];
+ const Point b = _points[p_index + 1];
/* Cubic bezier
*
@@ -341,16 +341,16 @@ real_t Curve::interpolate_local_nocheck(int index, real_t local_offset) const {
*/
// Control points are chosen at equal distances
- real_t d = b.pos.x - a.pos.x;
- if (Math::abs(d) <= CMP_EPSILON) {
- return b.pos.y;
+ real_t d = b.position.x - a.position.x;
+ if (Math::is_zero_approx(d)) {
+ return b.position.y;
}
- local_offset /= d;
+ p_local_offset /= d;
d /= 3.0;
- real_t yac = a.pos.y + d * a.right_tangent;
- real_t ybc = b.pos.y - d * b.left_tangent;
+ real_t yac = a.position.y + d * a.right_tangent;
+ real_t ybc = b.position.y - d * b.left_tangent;
- real_t y = _bezier_interp(local_offset, a.pos.y, yac, ybc, b.pos.y);
+ real_t y = _bezier_interp(p_local_offset, a.position.y, yac, ybc, b.position.y);
return y;
}
@@ -369,7 +369,7 @@ Array Curve::get_data() const {
const Point p = _points[j];
int i = j * ELEMS;
- output[i] = p.pos;
+ output[i] = p.position;
output[i + 1] = p.left_tangent;
output[i + 2] = p.right_tangent;
output[i + 3] = p.left_mode;
@@ -379,39 +379,39 @@ Array Curve::get_data() const {
return output;
}
-void Curve::set_data(Array input) {
+void Curve::set_data(const Array p_input) {
const unsigned int ELEMS = 5;
- ERR_FAIL_COND(input.size() % ELEMS != 0);
+ ERR_FAIL_COND(p_input.size() % ELEMS != 0);
_points.clear();
// Validate input
- for (int i = 0; i < input.size(); i += ELEMS) {
- ERR_FAIL_COND(input[i].get_type() != Variant::VECTOR2);
- ERR_FAIL_COND(!input[i + 1].is_num());
- ERR_FAIL_COND(input[i + 2].get_type() != Variant::FLOAT);
+ for (int i = 0; i < p_input.size(); i += ELEMS) {
+ ERR_FAIL_COND(p_input[i].get_type() != Variant::VECTOR2);
+ ERR_FAIL_COND(!p_input[i + 1].is_num());
+ ERR_FAIL_COND(p_input[i + 2].get_type() != Variant::FLOAT);
- ERR_FAIL_COND(input[i + 3].get_type() != Variant::INT);
- int left_mode = input[i + 3];
+ ERR_FAIL_COND(p_input[i + 3].get_type() != Variant::INT);
+ int left_mode = p_input[i + 3];
ERR_FAIL_COND(left_mode < 0 || left_mode >= TANGENT_MODE_COUNT);
- ERR_FAIL_COND(input[i + 4].get_type() != Variant::INT);
- int right_mode = input[i + 4];
+ ERR_FAIL_COND(p_input[i + 4].get_type() != Variant::INT);
+ int right_mode = p_input[i + 4];
ERR_FAIL_COND(right_mode < 0 || right_mode >= TANGENT_MODE_COUNT);
}
- _points.resize(input.size() / ELEMS);
+ _points.resize(p_input.size() / ELEMS);
for (int j = 0; j < _points.size(); ++j) {
Point &p = _points.write[j];
int i = j * ELEMS;
- p.pos = input[i];
- p.left_tangent = input[i + 1];
- p.right_tangent = input[i + 2];
+ p.position = p_input[i];
+ p.left_tangent = p_input[i + 1];
+ p.right_tangent = p_input[i + 2];
// TODO For some reason the compiler won't convert from Variant to enum
- int left_mode = input[i + 3];
- int right_mode = input[i + 4];
+ int left_mode = p_input[i + 3];
+ int right_mode = p_input[i + 4];
p.left_mode = (TangentMode)left_mode;
p.right_mode = (TangentMode)right_mode;
}
@@ -431,8 +431,8 @@ void Curve::bake() {
}
if (_points.size() != 0) {
- _baked_cache.write[0] = _points[0].pos.y;
- _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].pos.y;
+ _baked_cache.write[0] = _points[0].position.y;
+ _baked_cache.write[_baked_cache.size() - 1] = _points[_points.size() - 1].position.y;
}
_baked_cache_dirty = false;
@@ -445,7 +445,7 @@ void Curve::set_bake_resolution(int p_resolution) {
_baked_cache_dirty = true;
}
-real_t Curve::interpolate_baked(real_t offset) const {
+real_t Curve::interpolate_baked(real_t p_offset) const {
if (_baked_cache_dirty) {
// Last-second bake if not done already
const_cast<Curve *>(this)->bake();
@@ -456,13 +456,13 @@ real_t Curve::interpolate_baked(real_t offset) const {
if (_points.size() == 0) {
return 0;
}
- return _points[0].pos.y;
+ return _points[0].position.y;
} else if (_baked_cache.size() == 1) {
return _baked_cache[0];
}
// Get interpolation index
- real_t fi = offset * _baked_cache.size();
+ real_t fi = p_offset * _baked_cache.size();
int i = Math::floor(fi);
if (i < 0) {
i = 0;
@@ -481,7 +481,7 @@ real_t Curve::interpolate_baked(real_t offset) const {
}
}
-void Curve::ensure_default_setup(float p_min, float p_max) {
+void Curve::ensure_default_setup(real_t p_min, real_t p_max) {
if (_points.size() == 0 && _min_value == 0 && _max_value == 1) {
add_point(Vector2(0, 1));
add_point(Vector2(1, 1));
@@ -535,9 +535,9 @@ int Curve2D::get_point_count() const {
return points.size();
}
-void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
+void Curve2D::add_point(const Vector2 &p_position, const Vector2 &p_in, const Vector2 &p_out, int p_atpos) {
Point n;
- n.pos = p_pos;
+ n.position = p_position;
n.in = p_in;
n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) {
@@ -550,17 +550,17 @@ void Curve2D::add_point(const Vector2 &p_pos, const Vector2 &p_in, const Vector2
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve2D::set_point_position(int p_index, const Vector2 &p_pos) {
+void Curve2D::set_point_position(int p_index, const Vector2 &p_position) {
ERR_FAIL_INDEX(p_index, points.size());
- points.write[p_index].pos = p_pos;
+ points.write[p_index].position = p_position;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
Vector2 Curve2D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector2());
- return points[p_index].pos;
+ return points[p_index].position;
}
void Curve2D::set_point_in(int p_index, const Vector2 &p_in) {
@@ -604,19 +604,19 @@ void Curve2D::clear_points() {
}
}
-Vector2 Curve2D::interpolate(int p_index, float p_offset) const {
+Vector2 Curve2D::interpolate(int p_index, const real_t p_offset) const {
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector2());
if (p_index >= pc - 1) {
- return points[pc - 1].pos;
+ return points[pc - 1].position;
} else if (p_index < 0) {
- return points[0].pos;
+ return points[0].position;
}
- Vector2 p0 = points[p_index].pos;
+ Vector2 p0 = points[p_index].position;
Vector2 p1 = p0 + points[p_index].out;
- Vector2 p3 = points[p_index + 1].pos;
+ Vector2 p3 = points[p_index + 1].position;
Vector2 p2 = p3 + points[p_index + 1].in;
return _bezier_interp(p_offset, p0, p1, p2, p3);
@@ -632,15 +632,15 @@ Vector2 Curve2D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve2D::_bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const {
- float mp = p_begin + (p_end - p_begin) * 0.5;
+void Curve2D::_bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+ real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector2 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);
Vector2 na = (mid - beg).normalized();
Vector2 nb = (end - mid).normalized();
- float dp = na.dot(nb);
+ real_t dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
r_bake[mp] = mid;
@@ -668,47 +668,47 @@ void Curve2D::_bake() const {
if (points.size() == 1) {
baked_point_cache.resize(1);
- baked_point_cache.set(0, points[0].pos);
+ baked_point_cache.set(0, points[0].position);
baked_dist_cache.resize(1);
baked_dist_cache.set(0, 0.0);
return;
}
- Vector2 pos = points[0].pos;
- float dist = 0.0;
+ Vector2 position = points[0].position;
+ real_t dist = 0.0;
List<Vector2> pointlist;
- List<float> distlist;
+ List<real_t> distlist;
- pointlist.push_back(pos); //start always from origin
+ pointlist.push_back(position); //start always from origin
distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
- float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0.0;
+ real_t step = 0.1; // at least 10 substeps ought to be enough?
+ real_t p = 0.0;
while (p < 1.0) {
- float np = p + step;
+ real_t np = p + step;
if (np > 1.0) {
np = 1.0;
}
- Vector2 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- float d = pos.distance_to(npp);
+ Vector2 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ real_t d = position.distance_to(npp);
if (d > bake_interval) {
// OK! between P and NP there _has_ to be Something, let's go searching!
int iterations = 10; //lots of detail!
- float low = p;
- float hi = np;
- float mid = low + (hi - low) * 0.5;
+ real_t low = p;
+ real_t hi = np;
+ real_t mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
- npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- d = pos.distance_to(npp);
+ npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ d = position.distance_to(npp);
if (bake_interval < d) {
hi = mid;
@@ -718,11 +718,11 @@ void Curve2D::_bake() const {
mid = low + (hi - low) * 0.5;
}
- pos = npp;
+ position = npp;
p = mid;
dist += d;
- pointlist.push_back(pos);
+ pointlist.push_back(position);
distlist.push_back(dist);
} else {
p = np;
@@ -730,9 +730,9 @@ void Curve2D::_bake() const {
}
}
- Vector2 lastpos = points[points.size() - 1].pos;
+ Vector2 lastpos = points[points.size() - 1].position;
- float rem = pos.distance_to(lastpos);
+ real_t rem = position.distance_to(lastpos);
dist += rem;
baked_max_ofs = dist;
pointlist.push_back(lastpos);
@@ -742,7 +742,7 @@ void Curve2D::_bake() const {
baked_dist_cache.resize(distlist.size());
Vector2 *w = baked_point_cache.ptrw();
- float *wd = baked_dist_cache.ptrw();
+ real_t *wd = baked_dist_cache.ptrw();
for (int i = 0; i < pointlist.size(); i++) {
w[i] = pointlist[i];
@@ -750,7 +750,7 @@ void Curve2D::_bake() const {
}
}
-float Curve2D::get_baked_length() const {
+real_t Curve2D::get_baked_length() const {
if (baked_cache_dirty) {
_bake();
}
@@ -758,7 +758,7 @@ float Curve2D::get_baked_length() const {
return baked_max_ofs;
}
-Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
+Vector2 Curve2D::interpolate_baked(real_t p_offset, bool p_cubic) const {
if (baked_cache_dirty) {
_bake();
}
@@ -784,7 +784,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
int start = 0, end = bpc, idx = (end + start) / 2;
// binary search to find baked points
while (start < idx) {
- float offset = baked_dist_cache[idx];
+ real_t offset = baked_dist_cache[idx];
if (p_offset <= offset) {
end = idx;
} else {
@@ -793,13 +793,13 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const {
idx = (end + start) / 2;
}
- float offset_begin = baked_dist_cache[idx];
- float offset_end = baked_dist_cache[idx + 1];
+ real_t offset_begin = baked_dist_cache[idx];
+ real_t offset_end = baked_dist_cache[idx + 1];
- float idx_interval = offset_end - offset_begin;
+ real_t idx_interval = offset_end - offset_begin;
ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector2(), "failed to find baked segment");
- float frac = (p_offset - offset_begin) / idx_interval;
+ real_t frac = (p_offset - offset_begin) / idx_interval;
if (p_cubic) {
Vector2 pre = idx > 0 ? r[idx - 1] : r[idx];
@@ -818,13 +818,13 @@ PackedVector2Array Curve2D::get_baked_points() const {
return baked_point_cache;
}
-void Curve2D::set_bake_interval(float p_tolerance) {
+void Curve2D::set_bake_interval(real_t p_tolerance) {
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve2D::get_bake_interval() const {
+real_t Curve2D::get_bake_interval() const {
return bake_interval;
}
@@ -846,16 +846,16 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
const Vector2 *r = baked_point_cache.ptr();
Vector2 nearest;
- float nearest_dist = -1.0f;
+ real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) {
Vector2 origin = r[i];
Vector2 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector2 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = proj;
@@ -866,7 +866,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
return nearest;
}
-float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
+real_t Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
// Brute force method
if (baked_cache_dirty) {
@@ -883,18 +883,18 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
const Vector2 *r = baked_point_cache.ptr();
- float nearest = 0.0f;
- float nearest_dist = -1.0f;
- float offset = 0.0f;
+ real_t nearest = 0.0f;
+ real_t nearest_dist = -1.0f;
+ real_t offset = 0.0f;
for (int i = 0; i < pc - 1; i++) {
Vector2 origin = r[i];
Vector2 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector2 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = offset + d;
@@ -917,7 +917,7 @@ Dictionary Curve2D::_get_data() const {
for (int i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
- w[i * 3 + 2] = points[i].pos;
+ w[i * 3 + 2] = points[i].position;
}
dc["points"] = d;
@@ -937,42 +937,42 @@ void Curve2D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
- points.write[i].pos = r[i * 3 + 2];
+ points.write[i].position = r[i * 3 + 2];
}
baked_cache_dirty = true;
}
-PackedVector2Array Curve2D::tessellate(int p_max_stages, float p_tolerance) const {
+PackedVector2Array Curve2D::tessellate(int p_max_stages, real_t p_tolerance) const {
PackedVector2Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector2>> midpoints;
+ Vector<Map<real_t, Vector2>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment2d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment2d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
Vector2 *bpw = tess.ptrw();
- bpw[0] = points[0].pos;
+ bpw[0] = points[0].position;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (const KeyValue<float, Vector2> &E : midpoints[i]) {
+ for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
}
pidx++;
- bpw[pidx] = points[i + 1].pos;
+ bpw[pidx] = points[i + 1].position;
}
return tess;
@@ -1026,9 +1026,9 @@ int Curve3D::get_point_count() const {
return points.size();
}
-void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
+void Curve3D::add_point(const Vector3 &p_position, const Vector3 &p_in, const Vector3 &p_out, int p_atpos) {
Point n;
- n.pos = p_pos;
+ n.position = p_position;
n.in = p_in;
n.out = p_out;
if (p_atpos >= 0 && p_atpos < points.size()) {
@@ -1041,20 +1041,20 @@ void Curve3D::add_point(const Vector3 &p_pos, const Vector3 &p_in, const Vector3
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void Curve3D::set_point_position(int p_index, const Vector3 &p_pos) {
+void Curve3D::set_point_position(int p_index, const Vector3 &p_position) {
ERR_FAIL_INDEX(p_index, points.size());
- points.write[p_index].pos = p_pos;
+ points.write[p_index].position = p_position;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
Vector3 Curve3D::get_point_position(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), Vector3());
- return points[p_index].pos;
+ return points[p_index].position;
}
-void Curve3D::set_point_tilt(int p_index, float p_tilt) {
+void Curve3D::set_point_tilt(int p_index, real_t p_tilt) {
ERR_FAIL_INDEX(p_index, points.size());
points.write[p_index].tilt = p_tilt;
@@ -1062,7 +1062,7 @@ void Curve3D::set_point_tilt(int p_index, float p_tilt) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_point_tilt(int p_index) const {
+real_t Curve3D::get_point_tilt(int p_index) const {
ERR_FAIL_INDEX_V(p_index, points.size(), 0);
return points[p_index].tilt;
}
@@ -1108,19 +1108,19 @@ void Curve3D::clear_points() {
}
}
-Vector3 Curve3D::interpolate(int p_index, float p_offset) const {
+Vector3 Curve3D::interpolate(int p_index, real_t p_offset) const {
int pc = points.size();
ERR_FAIL_COND_V(pc == 0, Vector3());
if (p_index >= pc - 1) {
- return points[pc - 1].pos;
+ return points[pc - 1].position;
} else if (p_index < 0) {
- return points[0].pos;
+ return points[0].position;
}
- Vector3 p0 = points[p_index].pos;
+ Vector3 p0 = points[p_index].position;
Vector3 p1 = p0 + points[p_index].out;
- Vector3 p3 = points[p_index + 1].pos;
+ Vector3 p3 = points[p_index + 1].position;
Vector3 p2 = p3 + points[p_index + 1].in;
return _bezier_interp(p_offset, p0, p1, p2, p3);
@@ -1136,15 +1136,15 @@ Vector3 Curve3D::interpolatef(real_t p_findex) const {
return interpolate((int)p_findex, Math::fmod(p_findex, (real_t)1.0));
}
-void Curve3D::_bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const {
- float mp = p_begin + (p_end - p_begin) * 0.5;
+void Curve3D::_bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const {
+ real_t mp = p_begin + (p_end - p_begin) * 0.5;
Vector3 beg = _bezier_interp(p_begin, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 mid = _bezier_interp(mp, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 end = _bezier_interp(p_end, p_a, p_a + p_out, p_b + p_in, p_b);
Vector3 na = (mid - beg).normalized();
Vector3 nb = (end - mid).normalized();
- float dp = na.dot(nb);
+ real_t dp = na.dot(nb);
if (dp < Math::cos(Math::deg2rad(p_tol))) {
r_bake[mp] = mid;
@@ -1173,7 +1173,7 @@ void Curve3D::_bake() const {
if (points.size() == 1) {
baked_point_cache.resize(1);
- baked_point_cache.set(0, points[0].pos);
+ baked_point_cache.set(0, points[0].position);
baked_tilt_cache.resize(1);
baked_tilt_cache.set(0, points[0].tilt);
baked_dist_cache.resize(1);
@@ -1189,39 +1189,39 @@ void Curve3D::_bake() const {
return;
}
- Vector3 pos = points[0].pos;
- float dist = 0.0;
+ Vector3 position = points[0].position;
+ real_t dist = 0.0;
List<Plane> pointlist;
- List<float> distlist;
+ List<real_t> distlist;
- pointlist.push_back(Plane(pos, points[0].tilt));
+ pointlist.push_back(Plane(position, points[0].tilt));
distlist.push_back(0.0);
for (int i = 0; i < points.size() - 1; i++) {
- float step = 0.1; // at least 10 substeps ought to be enough?
- float p = 0.0;
+ real_t step = 0.1; // at least 10 substeps ought to be enough?
+ real_t p = 0.0;
while (p < 1.0) {
- float np = p + step;
+ real_t np = p + step;
if (np > 1.0) {
np = 1.0;
}
- Vector3 npp = _bezier_interp(np, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- float d = pos.distance_to(npp);
+ Vector3 npp = _bezier_interp(np, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ real_t d = position.distance_to(npp);
if (d > bake_interval) {
// OK! between P and NP there _has_ to be Something, let's go searching!
int iterations = 10; //lots of detail!
- float low = p;
- float hi = np;
- float mid = low + (hi - low) * 0.5;
+ real_t low = p;
+ real_t hi = np;
+ real_t mid = low + (hi - low) * 0.5;
for (int j = 0; j < iterations; j++) {
- npp = _bezier_interp(mid, points[i].pos, points[i].pos + points[i].out, points[i + 1].pos + points[i + 1].in, points[i + 1].pos);
- d = pos.distance_to(npp);
+ npp = _bezier_interp(mid, points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position);
+ d = position.distance_to(npp);
if (bake_interval < d) {
hi = mid;
@@ -1231,10 +1231,10 @@ void Curve3D::_bake() const {
mid = low + (hi - low) * 0.5;
}
- pos = npp;
+ position = npp;
p = mid;
Plane post;
- post.normal = pos;
+ post.normal = position;
post.d = Math::lerp(points[i].tilt, points[i + 1].tilt, mid);
dist += d;
@@ -1246,10 +1246,10 @@ void Curve3D::_bake() const {
}
}
- Vector3 lastpos = points[points.size() - 1].pos;
- float lastilt = points[points.size() - 1].tilt;
+ Vector3 lastpos = points[points.size() - 1].position;
+ real_t lastilt = points[points.size() - 1].tilt;
- float rem = pos.distance_to(lastpos);
+ real_t rem = position.distance_to(lastpos);
dist += rem;
baked_max_ofs = dist;
pointlist.push_back(Plane(lastpos, lastilt));
@@ -1266,7 +1266,7 @@ void Curve3D::_bake() const {
Vector3 *up_write = baked_up_vector_cache.ptrw();
baked_dist_cache.resize(pointlist.size());
- float *wd = baked_dist_cache.ptrw();
+ real_t *wd = baked_dist_cache.ptrw();
Vector3 sideways;
Vector3 up;
@@ -1288,7 +1288,7 @@ void Curve3D::_bake() const {
forward = idx > 0 ? (w[idx] - w[idx - 1]).normalized() : prev_forward;
- float y_dot = prev_up.dot(forward);
+ real_t y_dot = prev_up.dot(forward);
if (y_dot > (1.0f - CMP_EPSILON)) {
sideways = prev_sideways;
@@ -1315,7 +1315,7 @@ void Curve3D::_bake() const {
}
}
-float Curve3D::get_baked_length() const {
+real_t Curve3D::get_baked_length() const {
if (baked_cache_dirty) {
_bake();
}
@@ -1323,7 +1323,7 @@ float Curve3D::get_baked_length() const {
return baked_max_ofs;
}
-Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
+Vector3 Curve3D::interpolate_baked(real_t p_offset, bool p_cubic) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1349,7 +1349,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
int start = 0, end = bpc, idx = (end + start) / 2;
// binary search to find baked points
while (start < idx) {
- float offset = baked_dist_cache[idx];
+ real_t offset = baked_dist_cache[idx];
if (p_offset <= offset) {
end = idx;
} else {
@@ -1358,13 +1358,13 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
idx = (end + start) / 2;
}
- float offset_begin = baked_dist_cache[idx];
- float offset_end = baked_dist_cache[idx + 1];
+ real_t offset_begin = baked_dist_cache[idx];
+ real_t offset_end = baked_dist_cache[idx + 1];
- float idx_interval = offset_end - offset_begin;
+ real_t idx_interval = offset_end - offset_begin;
ERR_FAIL_COND_V_MSG(p_offset < offset_begin || p_offset > offset_end, Vector3(), "failed to find baked segment");
- float frac = (p_offset - offset_begin) / idx_interval;
+ real_t frac = (p_offset - offset_begin) / idx_interval;
if (p_cubic) {
Vector3 pre = idx > 0 ? r[idx - 1] : r[idx];
@@ -1375,7 +1375,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const {
}
}
-float Curve3D::interpolate_baked_tilt(float p_offset) const {
+real_t Curve3D::interpolate_baked_tilt(real_t p_offset) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1399,7 +1399,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
}
int idx = Math::floor((double)p_offset / (double)bake_interval);
- float frac = Math::fmod(p_offset, bake_interval);
+ real_t frac = Math::fmod(p_offset, bake_interval);
if (idx >= bpc - 1) {
return r[bpc - 1];
@@ -1414,7 +1414,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const {
return Math::lerp(r[idx], r[idx + 1], (real_t)frac);
}
-Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) const {
+Vector3 Curve3D::interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt) const {
if (baked_cache_dirty) {
_bake();
}
@@ -1432,10 +1432,10 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt)
const Vector3 *rp = baked_point_cache.ptr();
const real_t *rt = baked_tilt_cache.ptr();
- float offset = CLAMP(p_offset, 0.0f, baked_max_ofs);
+ real_t offset = CLAMP(p_offset, 0.0f, baked_max_ofs);
int idx = Math::floor((double)offset / (double)bake_interval);
- float frac = Math::fmod(offset, bake_interval) / bake_interval;
+ real_t frac = Math::fmod(offset, bake_interval) / bake_interval;
if (idx == count - 1) {
return p_apply_tilt ? r[idx].rotated((rp[idx] - rp[idx - 1]).normalized(), rt[idx]) : r[idx];
@@ -1503,16 +1503,16 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
const Vector3 *r = baked_point_cache.ptr();
Vector3 nearest;
- float nearest_dist = -1.0f;
+ real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) {
Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector3 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = proj;
@@ -1523,7 +1523,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const {
return nearest;
}
-float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
+real_t Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
// Brute force method
if (baked_cache_dirty) {
@@ -1540,18 +1540,18 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
const Vector3 *r = baked_point_cache.ptr();
- float nearest = 0.0f;
- float nearest_dist = -1.0f;
- float offset = 0.0f;
+ real_t nearest = 0.0f;
+ real_t nearest_dist = -1.0f;
+ real_t offset = 0.0f;
for (int i = 0; i < pc - 1; i++) {
Vector3 origin = r[i];
Vector3 direction = (r[i + 1] - origin) / bake_interval;
- float d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
Vector3 proj = origin + direction * d;
- float dist = proj.distance_squared_to(p_to_point);
+ real_t dist = proj.distance_squared_to(p_to_point);
if (nearest_dist < 0.0f || dist < nearest_dist) {
nearest = offset + d;
@@ -1564,13 +1564,13 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const {
return nearest;
}
-void Curve3D::set_bake_interval(float p_tolerance) {
+void Curve3D::set_bake_interval(real_t p_tolerance) {
bake_interval = p_tolerance;
baked_cache_dirty = true;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float Curve3D::get_bake_interval() const {
+real_t Curve3D::get_bake_interval() const {
return bake_interval;
}
@@ -1597,7 +1597,7 @@ Dictionary Curve3D::_get_data() const {
for (int i = 0; i < points.size(); i++) {
w[i * 3 + 0] = points[i].in;
w[i * 3 + 1] = points[i].out;
- w[i * 3 + 2] = points[i].pos;
+ w[i * 3 + 2] = points[i].position;
wt[i] = points[i].tilt;
}
@@ -1622,43 +1622,43 @@ void Curve3D::_set_data(const Dictionary &p_data) {
for (int i = 0; i < points.size(); i++) {
points.write[i].in = r[i * 3 + 0];
points.write[i].out = r[i * 3 + 1];
- points.write[i].pos = r[i * 3 + 2];
+ points.write[i].position = r[i * 3 + 2];
points.write[i].tilt = rt[i];
}
baked_cache_dirty = true;
}
-PackedVector3Array Curve3D::tessellate(int p_max_stages, float p_tolerance) const {
+PackedVector3Array Curve3D::tessellate(int p_max_stages, real_t p_tolerance) const {
PackedVector3Array tess;
if (points.size() == 0) {
return tess;
}
- Vector<Map<float, Vector3>> midpoints;
+ Vector<Map<real_t, Vector3>> midpoints;
midpoints.resize(points.size() - 1);
int pc = 1;
for (int i = 0; i < points.size() - 1; i++) {
- _bake_segment3d(midpoints.write[i], 0, 1, points[i].pos, points[i].out, points[i + 1].pos, points[i + 1].in, 0, p_max_stages, p_tolerance);
+ _bake_segment3d(midpoints.write[i], 0, 1, points[i].position, points[i].out, points[i + 1].position, points[i + 1].in, 0, p_max_stages, p_tolerance);
pc++;
pc += midpoints[i].size();
}
tess.resize(pc);
Vector3 *bpw = tess.ptrw();
- bpw[0] = points[0].pos;
+ bpw[0] = points[0].position;
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
- for (const KeyValue<float, Vector3> &E : midpoints[i]) {
+ for (const KeyValue<real_t, Vector3> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
}
pidx++;
- bpw[pidx] = points[i + 1].pos;
+ bpw[pidx] = points[i + 1].position;
}
return tess;
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index 5808fd6508..16facda85a 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -50,7 +50,7 @@ public:
};
struct Point {
- Vector2 pos;
+ Vector2 position;
real_t left_tangent = 0.0;
real_t right_tangent = 0.0;
TangentMode left_mode = TANGENT_FREE;
@@ -59,12 +59,12 @@ public:
Point() {
}
- Point(Vector2 p_pos,
+ Point(const Vector2 &p_position,
real_t p_left = 0.0,
real_t p_right = 0.0,
TangentMode p_left_mode = TANGENT_FREE,
TangentMode p_right_mode = TANGENT_FREE) {
- pos = p_pos;
+ position = p_position;
left_tangent = p_left;
right_tangent = p_right;
left_mode = p_left_mode;
@@ -76,7 +76,7 @@ public:
int get_point_count() const { return _points.size(); }
- int add_point(Vector2 p_pos,
+ int add_point(Vector2 p_position,
real_t left_tangent = 0,
real_t right_tangent = 0,
TangentMode left_mode = TANGENT_FREE,
@@ -85,34 +85,34 @@ public:
void remove_point(int p_index);
void clear_points();
- int get_index(real_t offset) const;
+ int get_index(real_t p_offset) const;
- void set_point_value(int p_index, real_t pos);
- int set_point_offset(int p_index, float offset);
+ void set_point_value(int p_index, real_t p_position);
+ int set_point_offset(int p_index, real_t p_offset);
Vector2 get_point_position(int p_index) const;
Point get_point(int p_index) const;
- float get_min_value() const { return _min_value; }
- void set_min_value(float p_min);
+ real_t get_min_value() const { return _min_value; }
+ void set_min_value(real_t p_min);
- float get_max_value() const { return _max_value; }
- void set_max_value(float p_max);
+ real_t get_max_value() const { return _max_value; }
+ void set_max_value(real_t p_max);
- real_t interpolate(real_t offset) const;
- real_t interpolate_local_nocheck(int index, real_t local_offset) const;
+ real_t interpolate(real_t p_offset) const;
+ real_t interpolate_local_nocheck(int p_index, real_t p_local_offset) const;
void clean_dupes();
- void set_point_left_tangent(int i, real_t tangent);
- void set_point_right_tangent(int i, real_t tangent);
- void set_point_left_mode(int i, TangentMode p_mode);
- void set_point_right_mode(int i, TangentMode p_mode);
+ void set_point_left_tangent(int p_index, real_t p_tangent);
+ void set_point_right_tangent(int p_index, real_t p_tangent);
+ void set_point_left_mode(int p_index, TangentMode p_mode);
+ void set_point_right_mode(int p_index, TangentMode p_mode);
- real_t get_point_left_tangent(int i) const;
- real_t get_point_right_tangent(int i) const;
- TangentMode get_point_left_mode(int i) const;
- TangentMode get_point_right_mode(int i) const;
+ real_t get_point_left_tangent(int p_index) const;
+ real_t get_point_right_tangent(int p_index) const;
+ TangentMode get_point_left_mode(int p_index) const;
+ TangentMode get_point_right_mode(int p_index) const;
void update_auto_tangents(int i);
@@ -122,9 +122,9 @@ public:
void bake();
int get_bake_resolution() const { return _bake_resolution; }
void set_bake_resolution(int p_resolution);
- real_t interpolate_baked(real_t offset) const;
+ real_t interpolate_baked(real_t p_offset) const;
- void ensure_default_setup(float p_min, float p_max);
+ void ensure_default_setup(real_t p_min, real_t p_max);
protected:
static void _bind_methods();
@@ -136,8 +136,8 @@ private:
bool _baked_cache_dirty = false;
Vector<real_t> _baked_cache;
int _bake_resolution = 100;
- float _min_value = 0.0;
- float _max_value = 1.0;
+ real_t _min_value = 0.0;
+ real_t _max_value = 1.0;
int _minmax_set_once = 0b00; // Encodes whether min and max have been set a first time, first bit for min and second for max.
};
@@ -149,26 +149,26 @@ class Curve2D : public Resource {
struct Point {
Vector2 in;
Vector2 out;
- Vector2 pos;
+ Vector2 position;
};
Vector<Point> points;
struct BakedPoint {
- float ofs = 0.0;
+ real_t ofs = 0.0;
Vector2 point;
};
mutable bool baked_cache_dirty = false;
mutable PackedVector2Array baked_point_cache;
- mutable PackedFloat32Array baked_dist_cache;
- mutable float baked_max_ofs = 0.0;
+ mutable Vector<real_t> baked_dist_cache;
+ mutable real_t baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval = 5.0;
+ real_t bake_interval = 5.0;
- void _bake_segment2d(Map<float, Vector2> &r_bake, float p_begin, float p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, float p_tol) const;
+ void _bake_segment2d(Map<real_t, Vector2> &r_bake, real_t p_begin, real_t p_end, const Vector2 &p_a, const Vector2 &p_out, const Vector2 &p_b, const Vector2 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
@@ -177,8 +177,8 @@ protected:
public:
int get_point_count() const;
- void add_point(const Vector2 &p_pos, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1);
- void set_point_position(int p_index, const Vector2 &p_pos);
+ void add_point(const Vector2 &p_position, const Vector2 &p_in = Vector2(), const Vector2 &p_out = Vector2(), int p_atpos = -1);
+ void set_point_position(int p_index, const Vector2 &p_position);
Vector2 get_point_position(int p_index) const;
void set_point_in(int p_index, const Vector2 &p_in);
Vector2 get_point_in(int p_index) const;
@@ -187,19 +187,19 @@ public:
void remove_point(int p_index);
void clear_points();
- Vector2 interpolate(int p_index, float p_offset) const;
+ Vector2 interpolate(int p_index, real_t p_offset) const;
Vector2 interpolatef(real_t p_findex) const;
- void set_bake_interval(float p_tolerance);
- float get_bake_interval() const;
+ void set_bake_interval(real_t p_tolerance);
+ real_t get_bake_interval() const;
- float get_baked_length() const;
- Vector2 interpolate_baked(float p_offset, bool p_cubic = false) const;
+ real_t get_baked_length() const;
+ Vector2 interpolate_baked(real_t p_offset, bool p_cubic = false) const;
PackedVector2Array get_baked_points() const; //useful for going through
Vector2 get_closest_point(const Vector2 &p_to_point) const;
- float get_closest_offset(const Vector2 &p_to_point) const;
+ real_t get_closest_offset(const Vector2 &p_to_point) const;
- PackedVector2Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector2Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display
Curve2D();
};
@@ -210,14 +210,14 @@ class Curve3D : public Resource {
struct Point {
Vector3 in;
Vector3 out;
- Vector3 pos;
- float tilt = 0.0;
+ Vector3 position;
+ real_t tilt = 0.0;
};
Vector<Point> points;
struct BakedPoint {
- float ofs = 0.0;
+ real_t ofs = 0.0;
Vector3 point;
};
@@ -225,15 +225,15 @@ class Curve3D : public Resource {
mutable PackedVector3Array baked_point_cache;
mutable Vector<real_t> baked_tilt_cache;
mutable PackedVector3Array baked_up_vector_cache;
- mutable PackedFloat32Array baked_dist_cache;
- mutable float baked_max_ofs = 0.0;
+ mutable Vector<real_t> baked_dist_cache;
+ mutable real_t baked_max_ofs = 0.0;
void _bake() const;
- float bake_interval = 0.2;
+ real_t bake_interval = 0.2;
bool up_vector_enabled = true;
- void _bake_segment3d(Map<float, Vector3> &r_bake, float p_begin, float p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, float p_tol) const;
+ void _bake_segment3d(Map<real_t, Vector3> &r_bake, real_t p_begin, real_t p_end, const Vector3 &p_a, const Vector3 &p_out, const Vector3 &p_b, const Vector3 &p_in, int p_depth, int p_max_depth, real_t p_tol) const;
Dictionary _get_data() const;
void _set_data(const Dictionary &p_data);
@@ -242,11 +242,11 @@ protected:
public:
int get_point_count() const;
- void add_point(const Vector3 &p_pos, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1);
- void set_point_position(int p_index, const Vector3 &p_pos);
+ void add_point(const Vector3 &p_position, const Vector3 &p_in = Vector3(), const Vector3 &p_out = Vector3(), int p_atpos = -1);
+ void set_point_position(int p_index, const Vector3 &p_position);
Vector3 get_point_position(int p_index) const;
- void set_point_tilt(int p_index, float p_tilt);
- float get_point_tilt(int p_index) const;
+ void set_point_tilt(int p_index, real_t p_tilt);
+ real_t get_point_tilt(int p_index) const;
void set_point_in(int p_index, const Vector3 &p_in);
Vector3 get_point_in(int p_index) const;
void set_point_out(int p_index, const Vector3 &p_out);
@@ -254,25 +254,25 @@ public:
void remove_point(int p_index);
void clear_points();
- Vector3 interpolate(int p_index, float p_offset) const;
+ Vector3 interpolate(int p_index, real_t p_offset) const;
Vector3 interpolatef(real_t p_findex) const;
- void set_bake_interval(float p_tolerance);
- float get_bake_interval() const;
+ void set_bake_interval(real_t p_tolerance);
+ real_t get_bake_interval() const;
void set_up_vector_enabled(bool p_enable);
bool is_up_vector_enabled() const;
- float get_baked_length() const;
- Vector3 interpolate_baked(float p_offset, bool p_cubic = false) const;
- float interpolate_baked_tilt(float p_offset) const;
- Vector3 interpolate_baked_up_vector(float p_offset, bool p_apply_tilt = false) const;
+ real_t get_baked_length() const;
+ Vector3 interpolate_baked(real_t p_offset, bool p_cubic = false) const;
+ real_t interpolate_baked_tilt(real_t p_offset) const;
+ Vector3 interpolate_baked_up_vector(real_t p_offset, bool p_apply_tilt = false) const;
PackedVector3Array get_baked_points() const; //useful for going through
Vector<real_t> get_baked_tilts() const; //useful for going through
PackedVector3Array get_baked_up_vectors() const;
Vector3 get_closest_point(const Vector3 &p_to_point) const;
- float get_closest_offset(const Vector3 &p_to_point) const;
+ real_t get_closest_offset(const Vector3 &p_to_point) const;
- PackedVector3Array tessellate(int p_max_stages = 5, float p_tolerance = 4) const; //useful for display
+ PackedVector3Array tessellate(int p_max_stages = 5, real_t p_tolerance = 4) const; //useful for display
Curve3D();
};
diff --git a/scene/resources/immediate_mesh.cpp b/scene/resources/immediate_mesh.cpp
index fe7124de9e..4f9a055bfb 100644
--- a/scene/resources/immediate_mesh.cpp
+++ b/scene/resources/immediate_mesh.cpp
@@ -144,6 +144,7 @@ void ImmediateMesh::surface_add_vertex_2d(const Vector2 &p_vertex) {
active_surface_data.vertex_2d = true;
}
+
void ImmediateMesh::surface_end() {
ERR_FAIL_COND_MSG(!surface_active, "Not creating any surface. Use surface_begin() to do it.");
ERR_FAIL_COND_MSG(!vertices.size(), "No vertices were added, surface can't be created.");
@@ -185,7 +186,7 @@ void ImmediateMesh::surface_end() {
vtx[2] = vertices[i].z;
}
if (i == 0) {
- aabb.position = vertices[i];
+ aabb = AABB(vertices[i], SMALL_VEC3); // Must have a bit of size.
} else {
aabb.expand_to(vertices[i]);
}
diff --git a/scene/resources/immediate_mesh.h b/scene/resources/immediate_mesh.h
index 6673ee6f3d..92bf91441d 100644
--- a/scene/resources/immediate_mesh.h
+++ b/scene/resources/immediate_mesh.h
@@ -75,6 +75,8 @@ class ImmediateMesh : public Mesh {
Vector<uint8_t> surface_vertex_create_cache;
Vector<uint8_t> surface_attribute_create_cache;
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
static void _bind_methods();
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 8399b14a56..00c109f1a6 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1658,13 +1658,28 @@ bool BaseMaterial3D::get_feature(Feature p_feature) const {
void BaseMaterial3D::set_texture(TextureParam p_param, const Ref<Texture2D> &p_texture) {
ERR_FAIL_INDEX(p_param, TEXTURE_MAX);
+
+ if (get_texture(TEXTURE_ROUGHNESS).is_null() && p_texture.is_valid() && p_param == TEXTURE_ROUGHNESS) {
+ // If no roughness texture is currently set, automatically set the recommended value
+ // for roughness when using a roughness map.
+ set_roughness(1.0);
+ }
+
+ if (get_texture(TEXTURE_METALLIC).is_null() && p_texture.is_valid() && p_param == TEXTURE_METALLIC) {
+ // If no metallic texture is currently set, automatically set the recommended value
+ // for metallic when using a metallic map.
+ set_metallic(1.0);
+ }
+
textures[p_param] = p_texture;
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
RS::get_singleton()->material_set_param(_get_material(), shader_names->texture_names[p_param], rid);
+
if (p_texture.is_valid() && p_param == TEXTURE_ALBEDO) {
RS::get_singleton()->material_set_param(_get_material(), shader_names->albedo_texture_size,
Vector2i(p_texture->get_width(), p_texture->get_height()));
}
+
notify_property_list_changed();
_queue_shader_change();
}
diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp
index e77f5a0be7..5ceb90d511 100644
--- a/scene/resources/particles_material.cpp
+++ b/scene/resources/particles_material.cpp
@@ -584,7 +584,7 @@ void ParticlesMaterial::_update_shader() {
code += " float base_angle = (tex_angle) * mix(initial_angle_min, initial_angle_max, rand_from_seed(alt_seed));\n";
code += " base_angle += CUSTOM.y * LIFETIME * (tex_angular_velocity) * mix(angular_velocity_min,angular_velocity_max, rand_from_seed(alt_seed));\n";
code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle
- code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + CUSTOM.y * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle
+ code += " CUSTOM.z = (tex_anim_offset) * mix(anim_offset_min, anim_offset_max, rand_from_seed(alt_seed)) + tv * tex_anim_speed * mix(anim_speed_min, anim_speed_max, rand_from_seed(alt_seed));\n"; // angle
// apply color
// apply hue rotation
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 951870fe34..e6870971d4 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -1647,6 +1647,21 @@ String VisualShaderNodeIntOp::generate_code(Shader::Mode p_mode, VisualShader::T
case OP_MIN:
code += "min(" + p_input_vars[0] + ", " + p_input_vars[1] + ");\n";
break;
+ case OP_BITWISE_AND:
+ code += p_input_vars[0] + " & " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_OR:
+ code += p_input_vars[0] + " | " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_XOR:
+ code += p_input_vars[0] + " ^ " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_LEFT_SHIFT:
+ code += p_input_vars[0] + " << " + p_input_vars[1] + ";\n";
+ break;
+ case OP_BITWISE_RIGHT_SHIFT:
+ code += p_input_vars[0] + " >> " + p_input_vars[1] + ";\n";
+ break;
default:
break;
}
@@ -1677,7 +1692,7 @@ void VisualShaderNodeIntOp::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_operator", "op"), &VisualShaderNodeIntOp::set_operator);
ClassDB::bind_method(D_METHOD("get_operator"), &VisualShaderNodeIntOp::get_operator);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min"), "set_operator", "get_operator");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "operator", PROPERTY_HINT_ENUM, "Add,Subtract,Multiply,Divide,Remainder,Max,Min,Bitwise AND,Bitwise OR,Bitwise XOR,Bitwise Left Shift,Bitwise Right Shift"), "set_operator", "get_operator");
BIND_ENUM_CONSTANT(OP_ADD);
BIND_ENUM_CONSTANT(OP_SUB);
@@ -1686,6 +1701,11 @@ void VisualShaderNodeIntOp::_bind_methods() {
BIND_ENUM_CONSTANT(OP_MOD);
BIND_ENUM_CONSTANT(OP_MAX);
BIND_ENUM_CONSTANT(OP_MIN);
+ BIND_ENUM_CONSTANT(OP_BITWISE_AND);
+ BIND_ENUM_CONSTANT(OP_BITWISE_OR);
+ BIND_ENUM_CONSTANT(OP_BITWISE_XOR);
+ BIND_ENUM_CONSTANT(OP_BITWISE_LEFT_SHIFT);
+ BIND_ENUM_CONSTANT(OP_BITWISE_RIGHT_SHIFT);
BIND_ENUM_CONSTANT(OP_ENUM_SIZE);
}
@@ -2333,7 +2353,8 @@ String VisualShaderNodeIntFunc::generate_code(Shader::Mode p_mode, VisualShader:
static const char *functions[FUNC_MAX] = {
"abs($)",
"-($)",
- "sign($)"
+ "sign($)",
+ "~($)"
};
return " " + p_output_vars[0] + " = " + String(functions[func]).replace("$", p_input_vars[0]) + ";\n";
@@ -2362,11 +2383,12 @@ void VisualShaderNodeIntFunc::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIntFunc::set_function);
ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIntFunc::get_function);
- ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign"), "set_function", "get_function");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Abs,Negate,Sign,Bitwise NOT"), "set_function", "get_function");
BIND_ENUM_CONSTANT(FUNC_ABS);
BIND_ENUM_CONSTANT(FUNC_NEGATE);
BIND_ENUM_CONSTANT(FUNC_SIGN);
+ BIND_ENUM_CONSTANT(FUNC_BITWISE_NOT);
BIND_ENUM_CONSTANT(FUNC_MAX);
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 2c952300fe..2f3400404c 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -579,6 +579,11 @@ public:
OP_MOD,
OP_MAX,
OP_MIN,
+ OP_BITWISE_AND,
+ OP_BITWISE_OR,
+ OP_BITWISE_XOR,
+ OP_BITWISE_LEFT_SHIFT,
+ OP_BITWISE_RIGHT_SHIFT,
OP_ENUM_SIZE,
};
@@ -882,6 +887,7 @@ public:
FUNC_ABS,
FUNC_NEGATE,
FUNC_SIGN,
+ FUNC_BITWISE_NOT,
FUNC_MAX,
};
diff --git a/scene/resources/visual_shader_particle_nodes.cpp b/scene/resources/visual_shader_particle_nodes.cpp
index 1a829968e3..a7c20b2cb9 100644
--- a/scene/resources/visual_shader_particle_nodes.cpp
+++ b/scene/resources/visual_shader_particle_nodes.cpp
@@ -318,26 +318,24 @@ String VisualShaderNodeParticleMeshEmitter::get_input_port_name(int p_port) cons
String VisualShaderNodeParticleMeshEmitter::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const {
String code;
- if (mesh.is_valid()) {
- if (is_output_port_connected(0)) { // position
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
- }
+ if (is_output_port_connected(0)) { // position
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_vx") + ";\n";
+ }
- if (is_output_port_connected(1)) { // normal
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
- }
+ if (is_output_port_connected(1)) { // normal
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_nm") + ";\n";
+ }
- if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
- }
+ if (is_output_port_connected(2) || is_output_port_connected(3)) { // color & alpha
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_col") + ";\n";
+ }
- if (is_output_port_connected(4)) { // uv
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
- }
+ if (is_output_port_connected(4)) { // uv
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv") + ";\n";
+ }
- if (is_output_port_connected(5)) { // uv2
- code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
- }
+ if (is_output_port_connected(5)) { // uv2
+ code += "uniform sampler2D " + make_unique_id(p_type, p_id, "mesh_uv2") + ";\n";
}
return code;
@@ -503,67 +501,97 @@ void VisualShaderNodeParticleMeshEmitter::_update_textures() {
Vector<Vector2> uvs;
Vector<Vector2> uvs2;
+ const int surface_count = mesh->get_surface_count();
+
if (use_all_surfaces) {
- for (int i = 0; i < max_surface_index; i++) {
+ for (int i = 0; i < surface_count; i++) {
+ const Array surface_arrays = mesh->surface_get_arrays(i);
+ const int surface_arrays_size = surface_arrays.size();
+
// position
- Array vertex_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_VERTEX];
- for (int j = 0; j < vertex_array.size(); j++) {
- vertices.push_back((Vector3)vertex_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
+ Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
+ for (int j = 0; j < vertex_array.size(); j++) {
+ vertices.push_back((Vector3)vertex_array[j]);
+ }
}
// normal
- Array normal_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_NORMAL];
- for (int j = 0; j < normal_array.size(); j++) {
- normals.push_back((Vector3)normal_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
+ Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
+ for (int j = 0; j < normal_array.size(); j++) {
+ normals.push_back((Vector3)normal_array[j]);
+ }
}
// color
- Array color_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_COLOR];
- for (int j = 0; j < color_array.size(); j++) {
- colors.push_back((Color)color_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_COLOR) {
+ Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
+ for (int j = 0; j < color_array.size(); j++) {
+ colors.push_back((Color)color_array[j]);
+ }
}
// uv
- Array uv_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV];
- for (int j = 0; j < uv_array.size(); j++) {
- uvs.push_back((Vector2)uv_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
+ Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
+ }
}
// uv2
- Array uv2_array = mesh->surface_get_arrays(i)[Mesh::ARRAY_TEX_UV2];
- for (int j = 0; j < uv2_array.size(); j++) {
- uvs2.push_back((Vector2)uv2_array[j]);
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
+ Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
+ }
}
}
} else {
- // position
- Array vertex_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_VERTEX];
- for (int i = 0; i < vertex_array.size(); i++) {
- vertices.push_back((Vector3)vertex_array[i]);
- }
+ if (surface_index >= 0 && surface_index < surface_count) {
+ const Array surface_arrays = mesh->surface_get_arrays(surface_index);
+ const int surface_arrays_size = surface_arrays.size();
- // normal
- Array normal_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_NORMAL];
- for (int i = 0; i < normal_array.size(); i++) {
- normals.push_back((Vector3)normal_array[i]);
- }
+ // position
+ if (surface_arrays_size > Mesh::ARRAY_VERTEX) {
+ Array vertex_array = surface_arrays[Mesh::ARRAY_VERTEX];
+ for (int i = 0; i < vertex_array.size(); i++) {
+ vertices.push_back((Vector3)vertex_array[i]);
+ }
+ }
- // color
- Array color_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_COLOR];
- for (int i = 0; i < color_array.size(); i++) {
- colors.push_back((Color)color_array[i]);
- }
+ // normal
+ if (surface_arrays_size > Mesh::ARRAY_NORMAL) {
+ Array normal_array = surface_arrays[Mesh::ARRAY_NORMAL];
+ for (int i = 0; i < normal_array.size(); i++) {
+ normals.push_back((Vector3)normal_array[i]);
+ }
+ }
- // uv
- Array uv_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV];
- for (int j = 0; j < uv_array.size(); j++) {
- uvs.push_back((Vector2)uv_array[j]);
- }
+ // color
+ if (surface_arrays_size > Mesh::ARRAY_COLOR) {
+ Array color_array = surface_arrays[Mesh::ARRAY_COLOR];
+ for (int i = 0; i < color_array.size(); i++) {
+ colors.push_back((Color)color_array[i]);
+ }
+ }
+
+ // uv
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV) {
+ Array uv_array = surface_arrays[Mesh::ARRAY_TEX_UV];
+ for (int j = 0; j < uv_array.size(); j++) {
+ uvs.push_back((Vector2)uv_array[j]);
+ }
+ }
- // uv2
- Array uv2_array = mesh->surface_get_arrays(surface_index)[Mesh::ARRAY_TEX_UV2];
- for (int j = 0; j < uv2_array.size(); j++) {
- uvs2.push_back((Vector2)uv2_array[j]);
+ // uv2
+ if (surface_arrays_size > Mesh::ARRAY_TEX_UV2) {
+ Array uv2_array = surface_arrays[Mesh::ARRAY_TEX_UV2];
+ for (int j = 0; j < uv2_array.size(); j++) {
+ uvs2.push_back((Vector2)uv2_array[j]);
+ }
+ }
}
}
@@ -579,12 +607,6 @@ void VisualShaderNodeParticleMeshEmitter::set_mesh(Ref<Mesh> p_mesh) {
return;
}
- if (p_mesh.is_valid()) {
- max_surface_index = p_mesh->get_surface_count();
- } else {
- max_surface_index = 0;
- }
-
if (mesh.is_valid()) {
Callable callable = callable_mp(this, &VisualShaderNodeParticleMeshEmitter::_update_textures);
@@ -623,7 +645,16 @@ bool VisualShaderNodeParticleMeshEmitter::is_use_all_surfaces() const {
}
void VisualShaderNodeParticleMeshEmitter::set_surface_index(int p_surface_index) {
- if (p_surface_index == surface_index || p_surface_index < 0 || p_surface_index >= max_surface_index) {
+ if (mesh.is_valid()) {
+ if (mesh->get_surface_count() > 0) {
+ p_surface_index = CLAMP(p_surface_index, 0, mesh->get_surface_count() - 1);
+ } else {
+ p_surface_index = 0;
+ }
+ } else if (p_surface_index < 0) {
+ p_surface_index = 0;
+ }
+ if (surface_index == p_surface_index) {
return;
}
surface_index = p_surface_index;
diff --git a/scene/resources/visual_shader_particle_nodes.h b/scene/resources/visual_shader_particle_nodes.h
index 79459432f1..ae7ea69225 100644
--- a/scene/resources/visual_shader_particle_nodes.h
+++ b/scene/resources/visual_shader_particle_nodes.h
@@ -111,7 +111,6 @@ class VisualShaderNodeParticleMeshEmitter : public VisualShaderNodeParticleEmitt
Ref<Mesh> mesh;
bool use_all_surfaces = true;
int surface_index = 0;
- int max_surface_index = 0;
Ref<ImageTexture> position_texture;
Ref<ImageTexture> normal_texture;
diff --git a/servers/physics_server_2d.h b/servers/physics_server_2d.h
index 2bff8f5dcb..c76ec5a5b1 100644
--- a/servers/physics_server_2d.h
+++ b/servers/physics_server_2d.h
@@ -758,10 +758,9 @@ class PhysicsServer2DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/physics_server_3d.h b/servers/physics_server_3d.h
index 89a7eeee96..bd5a3eb4b7 100644
--- a/servers/physics_server_3d.h
+++ b/servers/physics_server_3d.h
@@ -965,10 +965,9 @@ class PhysicsServer3DManager {
name(p_ci.name),
create_callback(p_ci.create_callback) {}
- ClassInfo &operator=(const ClassInfo &p_ci) {
+ void operator=(const ClassInfo &p_ci) {
name = p_ci.name;
create_callback = p_ci.create_callback;
- return *this;
}
};
diff --git a/servers/rendering/renderer_rd/shader_compiler_rd.cpp b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
index 77d3a2e766..b02b3d2723 100644
--- a/servers/rendering/renderer_rd/shader_compiler_rd.cpp
+++ b/servers/rendering/renderer_rd/shader_compiler_rd.cpp
@@ -1318,6 +1318,9 @@ String ShaderCompilerRD::_dump_node_code(const SL::Node *p_node, int p_level, Ge
code += ")";
} break;
+ case SL::OP_EMPTY: {
+ // Semicolon (or empty statement) - ignored.
+ } break;
default: {
if (p_use_scope) {
diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp
index dcbc5f5c8e..5602bb197b 100644
--- a/servers/rendering/rendering_device.cpp
+++ b/servers/rendering/rendering_device.cpp
@@ -185,9 +185,13 @@ Ref<RDShaderSPIRV> RenderingDevice::_shader_compile_spirv_from_source(const Ref<
String error;
ShaderStage stage = ShaderStage(i);
- Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, p_source->get_stage_source(stage), p_source->get_language(), &error, p_allow_cache);
- bytecode->set_stage_bytecode(stage, spirv);
- bytecode->set_stage_compile_error(stage, error);
+ String source = p_source->get_stage_source(stage);
+
+ if (!source.is_empty()) {
+ Vector<uint8_t> spirv = shader_compile_spirv_from_source(stage, source, p_source->get_language(), &error, p_allow_cache);
+ bytecode->set_stage_bytecode(stage, spirv);
+ bytecode->set_stage_compile_error(stage, error);
+ }
}
return bytecode;
}
diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp
index 50719ecfc3..f5e91d0423 100644
--- a/servers/rendering/shader_language.cpp
+++ b/servers/rendering/shader_language.cpp
@@ -88,7 +88,8 @@ String ShaderLanguage::get_operator_text(Operator p_op) {
"--",
"()",
"construct",
- "index" };
+ "index",
+ "empty" };
return op_names[p_op];
}
@@ -474,6 +475,10 @@ ShaderLanguage::Token ShaderLanguage::_get_token() {
case ':':
return _make_token(TK_COLON);
case '^':
+ if (GETCHAR(0) == '=') {
+ char_idx++;
+ return _make_token(TK_OP_ASSIGN_BIT_XOR);
+ }
return _make_token(TK_OP_BIT_XOR);
case '~':
return _make_token(TK_OP_BIT_INVERT);
@@ -4293,7 +4298,7 @@ ShaderLanguage::Node *ShaderLanguage::_parse_array_size(BlockNode *p_block, cons
return n;
}
-Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
+Error ShaderLanguage::_parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info) {
if (r_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
@@ -4305,7 +4310,7 @@ Error ShaderLanguage::_parse_global_array_size(int &r_array_size) {
if (tk.type != TK_INT_CONSTANT || ((int)tk.constant) <= 0) {
_set_tkpos(pos);
- Node *n = _parse_array_size(nullptr, FunctionInfo(), array_size);
+ Node *n = _parse_array_size(nullptr, p_function_info, array_size);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -5208,9 +5213,21 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
expression.push_back(e);
continue;
} else {
- _set_error("Expected expression, found: " + get_token_text(tk));
- return nullptr;
- //nothing
+ if (tk.type != TK_SEMICOLON) {
+ _set_error("Expected expression, found: " + get_token_text(tk));
+ return nullptr;
+ } else {
+#if DEBUG_ENABLED
+ if (check_warnings && HAS_WARNING(ShaderWarning::FORMATTING_ERROR_FLAG)) {
+ _add_line_warning(ShaderWarning::FORMATTING_ERROR, "Empty statement. Remove ';' to fix this warning.");
+ }
+#endif // DEBUG_ENABLED
+ _set_tkpos(prepos);
+
+ OperatorNode *func = alloc_node<OperatorNode>();
+ func->op = OP_EMPTY;
+ expr = func;
+ }
}
ERR_FAIL_COND_V(!expr, nullptr);
@@ -6386,7 +6403,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const FunctionInfo &p_fun
ArrayDeclarationNode::Declaration adecl;
if (tk.type != TK_IDENTIFIER && tk.type != TK_BRACKET_OPEN) {
- _set_error("Expected identifier or '[' after type.");
+ _set_error("Expected identifier or '[' after datatype.");
return ERR_PARSE_ERROR;
}
@@ -7446,6 +7463,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
ShaderNode::Uniform::Scope uniform_scope = ShaderNode::Uniform::SCOPE_LOCAL;
stages = &p_functions;
+ const FunctionInfo &constants = p_functions.has("constants") ? p_functions["constants"] : FunctionInfo();
while (tk.type != TK_EOF) {
switch (tk.type) {
@@ -7489,7 +7507,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_IDENTIFIER) {
st.name = tk.text;
- if (shader->structs.has(st.name)) {
+ if (shader->constants.has(st.name) || shader->structs.has(st.name)) {
_set_error("Redefinition of '" + String(st.name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7561,7 +7579,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
int array_size = 0;
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7588,7 +7606,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(member->array_size);
+ Error error = _parse_global_array_size(member->array_size, constants);
if (error != OK) {
return error;
}
@@ -7715,7 +7733,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(array_size);
+ Error error = _parse_global_array_size(array_size, constants);
if (error != OK) {
return error;
}
@@ -7730,7 +7748,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -7763,7 +7781,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- Error error = _parse_global_array_size(uniform2.array_size);
+ Error error = _parse_global_array_size(uniform2.array_size, constants);
if (error != OK) {
return error;
}
@@ -8017,7 +8035,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
return ERR_PARSE_ERROR;
}
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8113,7 +8131,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
DataPrecision precision = PRECISION_DEFAULT;
DataType type;
StringName name;
- int return_array_size = 0;
+ int array_size = 0;
if (tk.type == TK_CONST) {
is_constant = true;
@@ -8152,13 +8170,19 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
prev_pos = _get_tkpos();
tk = _get_token();
+ bool unknown_size = false;
+
if (tk.type == TK_BRACKET_OPEN) {
+ if (is_constant && RenderingServer::get_singleton()->is_low_end()) {
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
bool error = false;
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- return_array_size = (int)tk.constant;
- if (return_array_size > 0) {
+ array_size = (int)tk.constant;
+ if (array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8167,11 +8191,13 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
error = true;
}
+ } else if (tk.type == TK_BRACKET_CLOSE) {
+ unknown_size = true;
} else {
error = true;
}
if (error) {
- _set_error("Expected integer constant > 0");
+ _set_error("Expected integer constant > 0 or ']'");
return ERR_PARSE_ERROR;
}
@@ -8183,16 +8209,15 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
_get_completable_identifier(nullptr, COMPLETION_MAIN_FUNCTION, name);
if (name == StringName()) {
- _set_error("Expected function name after datatype");
- return ERR_PARSE_ERROR;
- }
-
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
- _set_error("Redefinition of '" + String(name) + "'");
+ if (is_constant) {
+ _set_error("Expected identifier or '[' after datatype.");
+ } else {
+ _set_error("Expected function name after datatype.");
+ }
return ERR_PARSE_ERROR;
}
- if (has_builtin(p_functions, name)) {
+ if (shader->structs.has(name) || _find_identifier(nullptr, false, constants, name) || has_builtin(p_functions, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8205,7 +8230,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
//variable
-
+ bool first = true;
while (true) {
ShaderNode::Constant constant;
constant.name = name;
@@ -8213,16 +8238,18 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.type_str = struct_name;
constant.precision = precision;
constant.initializer = nullptr;
- constant.array_size = 0;
-
- bool unknown_size = false;
+ constant.array_size = (first ? array_size : 0);
+ first = false;
if (tk.type == TK_BRACKET_OPEN) {
if (RenderingServer::get_singleton()->is_low_end()) {
- _set_error("Global const arrays are supported only on high-end platform!");
+ _set_error("Global const arrays are only supported on high-end platform!");
+ return ERR_PARSE_ERROR;
+ }
+ if (constant.array_size > 0 || unknown_size) {
+ _set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
-
tk = _get_token();
if (tk.type == TK_BRACKET_CLOSE) {
unknown_size = true;
@@ -8300,7 +8327,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
} else {
_set_tkpos(prev_pos);
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n || n->type != Node::TYPE_CONSTANT || n->get_datatype() != TYPE_INT) {
_set_error("Expected single integer constant > 0");
return ERR_PARSE_ERROR;
@@ -8381,7 +8408,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
if (tk.type == TK_PARENTHESIS_OPEN || curly) { // initialization
while (true) {
- Node *n = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *n = _parse_and_reduce_expression(nullptr, constants);
if (!n) {
return ERR_PARSE_ERROR;
}
@@ -8436,7 +8463,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
} else {
//variable created with assignment! must parse an expression
- Node *expr = _parse_and_reduce_expression(nullptr, FunctionInfo());
+ Node *expr = _parse_and_reduce_expression(nullptr, constants);
if (!expr) {
return ERR_PARSE_ERROR;
}
@@ -8452,7 +8479,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
constant.initializer = static_cast<ConstantNode *>(expr);
- if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), 0)) {
+ if (!_compare_datatypes(type, struct_name, 0, expr->get_datatype(), expr->get_datatype_name(), expr->get_array_size())) {
return ERR_PARSE_ERROR;
}
}
@@ -8483,7 +8510,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
name = tk.text;
- if (_find_identifier(nullptr, false, FunctionInfo(), name)) {
+ if (_find_identifier(nullptr, false, constants, name)) {
_set_error("Redefinition of '" + String(name) + "'");
return ERR_PARSE_ERROR;
}
@@ -8517,6 +8544,12 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
}
}
+ if (p_functions.has("constants")) { // Adds global constants: 'PI', 'TAU', 'E'
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ builtins.built_ins.insert(E.key, E.value);
+ }
+ }
+
ShaderNode::Function function;
function.callable = !p_functions.has(name);
@@ -8532,7 +8565,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
func_node->return_type = type;
func_node->return_struct_name = struct_name;
func_node->return_precision = precision;
- func_node->return_array_size = return_array_size;
+ func_node->return_array_size = array_size;
if (p_functions.has(name)) {
func_node->can_discard = p_functions[name].can_discard;
@@ -8586,7 +8619,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
StringName param_struct_name;
DataPrecision pprecision = PRECISION_DEFAULT;
bool use_precision = false;
- int array_size = 0;
+ int arg_array_size = 0;
if (is_token_precision(tk.type)) {
pprecision = get_token_precision(tk.type);
@@ -8637,9 +8670,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8691,7 +8724,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_BRACKET_OPEN) {
- if (array_size > 0) {
+ if (arg_array_size > 0) {
_set_error("Array size is already defined!");
return ERR_PARSE_ERROR;
}
@@ -8699,9 +8732,9 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
if (tk.type == TK_INT_CONSTANT) {
- array_size = (int)tk.constant;
+ arg_array_size = (int)tk.constant;
- if (array_size > 0) {
+ if (arg_array_size > 0) {
tk = _get_token();
if (tk.type != TK_BRACKET_CLOSE) {
_set_error("Expected ']'");
@@ -8721,7 +8754,7 @@ Error ShaderLanguage::_parse_shader(const Map<StringName, FunctionInfo> &p_funct
tk = _get_token();
}
- arg.array_size = array_size;
+ arg.array_size = arg_array_size;
func_node->arguments.push_back(arg);
if (tk.type == TK_COMMA) {
@@ -9067,6 +9100,16 @@ Error ShaderLanguage::complete(const String &p_code, const Map<StringName, Funct
}
}
+ if (p_functions.has("constants")) {
+ for (const KeyValue<StringName, BuiltInInfo> &E : p_functions["constants"].built_ins) {
+ ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
+ if (E.value.constant) {
+ kind = ScriptCodeCompletionOption::KIND_CONSTANT;
+ }
+ matches.insert(E.key, kind);
+ }
+ }
+
if (skip_function != StringName() && p_functions.has(skip_function)) {
for (const KeyValue<StringName, BuiltInInfo> &E : p_functions[skip_function].built_ins) {
ScriptCodeCompletionOption::Kind kind = ScriptCodeCompletionOption::KIND_MEMBER;
diff --git a/servers/rendering/shader_language.h b/servers/rendering/shader_language.h
index c82f71d10d..3de89a89a5 100644
--- a/servers/rendering/shader_language.h
+++ b/servers/rendering/shader_language.h
@@ -287,6 +287,7 @@ public:
OP_CONSTRUCT,
OP_STRUCT,
OP_INDEX,
+ OP_EMPTY,
OP_MAX
};
@@ -989,7 +990,7 @@ private:
bool _check_node_constness(const Node *p_node) const;
Node *_parse_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, int &r_array_size);
- Error _parse_global_array_size(int &r_array_size);
+ Error _parse_global_array_size(int &r_array_size, const FunctionInfo &p_function_info);
Error _parse_local_array_size(BlockNode *p_block, const FunctionInfo &p_function_info, ArrayDeclarationNode *p_node, ArrayDeclarationNode::Declaration *p_decl, int &r_array_size, bool &r_is_unknown_size);
Node *_parse_expression(BlockNode *p_block, const FunctionInfo &p_function_info);
diff --git a/servers/rendering/shader_types.cpp b/servers/rendering/shader_types.cpp
index 10786555db..359196e096 100644
--- a/servers/rendering/shader_types.cpp
+++ b/servers/rendering/shader_types.cpp
@@ -59,9 +59,9 @@ ShaderTypes::ShaderTypes() {
/*************** SPATIAL ***********************/
shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SPATIAL].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SPATIAL].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[RS::SHADER_SPATIAL].functions["vertex"].built_ins["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -241,9 +241,9 @@ ShaderTypes::ShaderTypes() {
/************ CANVAS ITEM **************************/
shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_CANVAS_ITEM].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_CANVAS_ITEM].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["VERTEX"] = ShaderLanguage::TYPE_VEC2;
shader_modes[RS::SHADER_CANVAS_ITEM].functions["vertex"].built_ins["UV"] = ShaderLanguage::TYPE_VEC2;
@@ -334,9 +334,9 @@ ShaderTypes::ShaderTypes() {
/************ PARTICLES **************************/
shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_PARTICLES].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_PARTICLES].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[RS::SHADER_PARTICLES].functions["start"].built_ins["VELOCITY"] = ShaderLanguage::TYPE_VEC3;
@@ -400,9 +400,9 @@ ShaderTypes::ShaderTypes() {
/************ SKY **************************/
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_SKY].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_SKY].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["RADIANCE"] = constt(ShaderLanguage::TYPE_SAMPLERCUBE);
shader_modes[RS::SHADER_SKY].functions["global"].built_ins["AT_HALF_RES_PASS"] = constt(ShaderLanguage::TYPE_BOOL);
@@ -446,9 +446,9 @@ ShaderTypes::ShaderTypes() {
/************ FOG **************************/
shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TIME"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
- shader_modes[RS::SHADER_FOG].functions["global"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["PI"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["TAU"] = constt(ShaderLanguage::TYPE_FLOAT);
+ shader_modes[RS::SHADER_FOG].functions["constants"].built_ins["E"] = constt(ShaderLanguage::TYPE_FLOAT);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["WORLD_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
shader_modes[RS::SHADER_FOG].functions["fog"].built_ins["OBJECT_POSITION"] = constt(ShaderLanguage::TYPE_VEC3);
diff --git a/servers/rendering/shader_warnings.cpp b/servers/rendering/shader_warnings.cpp
index 0b8476478c..bffae484a8 100644
--- a/servers/rendering/shader_warnings.cpp
+++ b/servers/rendering/shader_warnings.cpp
@@ -61,6 +61,8 @@ String ShaderWarning::get_message() const {
return vformat("The varying '%s' is declared but never used.", subject);
case UNUSED_LOCAL_VARIABLE:
return vformat("The local variable '%s' is declared but never used.", subject);
+ case FORMATTING_ERROR:
+ return subject;
default:
break;
}
@@ -82,6 +84,7 @@ String ShaderWarning::get_name_from_code(Code p_code) {
"UNUSED_UNIFORM",
"UNUSED_VARYING",
"UNUSED_LOCAL_VARIABLE",
+ "FORMATTING_ERROR",
};
static_assert((sizeof(names) / sizeof(*names)) == WARNING_MAX, "Amount of warning types don't match the amount of warning names.");
@@ -110,6 +113,7 @@ static void init_code_to_flags_map() {
code_to_flags_map->insert(ShaderWarning::UNUSED_UNIFORM, ShaderWarning::UNUSED_UNIFORM_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_VARYING, ShaderWarning::UNUSED_VARYING_FLAG);
code_to_flags_map->insert(ShaderWarning::UNUSED_LOCAL_VARIABLE, ShaderWarning::UNUSED_LOCAL_VARIABLE_FLAG);
+ code_to_flags_map->insert(ShaderWarning::FORMATTING_ERROR, ShaderWarning::FORMATTING_ERROR_FLAG);
}
ShaderWarning::CodeFlags ShaderWarning::get_flags_from_codemap(const Map<Code, bool> &p_map) {
diff --git a/servers/rendering/shader_warnings.h b/servers/rendering/shader_warnings.h
index db872d8fb1..18915fffd8 100644
--- a/servers/rendering/shader_warnings.h
+++ b/servers/rendering/shader_warnings.h
@@ -47,6 +47,7 @@ public:
UNUSED_UNIFORM,
UNUSED_VARYING,
UNUSED_LOCAL_VARIABLE,
+ FORMATTING_ERROR,
WARNING_MAX,
};
@@ -59,6 +60,7 @@ public:
UNUSED_UNIFORM_FLAG = 16U,
UNUSED_VARYING_FLAG = 32U,
UNUSED_LOCAL_VARIABLE_FLAG = 64U,
+ FORMATTING_ERROR_FLAG = 128U,
};
private:
diff --git a/servers/rendering_server.cpp b/servers/rendering_server.cpp
index 7a958546b6..a23911e81a 100644
--- a/servers/rendering_server.cpp
+++ b/servers/rendering_server.cpp
@@ -199,11 +199,11 @@ RID RenderingServer::_make_test_cube() {
normal_points[j][i % 3] = (i >= 3 ? -1 : 1);
}
- //tri 1
+ // Tri 1
ADD_VTX(0);
ADD_VTX(1);
ADD_VTX(2);
- //tri 2
+ // Tri 2
ADD_VTX(2);
ADD_VTX(3);
ADD_VTX(0);
@@ -317,9 +317,6 @@ RID RenderingServer::get_white_texture() {
return white_texture;
}
-#define SMALL_VEC2 Vector2(0.00001, 0.00001)
-#define SMALL_VEC3 Vector3(0.00001, 0.00001, 0.00001)
-
Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_t *p_offsets, uint32_t p_vertex_stride, uint32_t p_attrib_stride, uint32_t p_skin_stride, Vector<uint8_t> &r_vertex_array, Vector<uint8_t> &r_attrib_array, Vector<uint8_t> &r_skin_array, int p_vertex_array_len, Vector<uint8_t> &r_index_array, int p_index_array_len, AABB &r_aabb, Vector<AABB> &r_bone_aabb) {
uint8_t *vw = r_vertex_array.ptrw();
uint8_t *aw = r_attrib_array.ptrw();
@@ -333,7 +330,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
int max_bone = 0;
for (int ai = 0; ai < RS::ARRAY_MAX; ai++) {
- if (!(p_format & (1 << ai))) { // no array
+ if (!(p_format & (1 << ai))) { // No array
continue;
}
@@ -345,7 +342,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector2 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
Rect2 aabb;
{
@@ -355,7 +352,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
memcpy(&vw[p_offsets[ai] + i * p_vertex_stride], vector, sizeof(float) * 2);
if (i == 0) {
- aabb = Rect2(src[i], SMALL_VEC2); //must have a bit of size
+ aabb = Rect2(src[i], SMALL_VEC2); // Must have a bit of size.
} else {
aabb.expand_to(src[i]);
}
@@ -370,7 +367,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
const Vector3 *src = array.ptr();
- // setting vertices means regenerating the AABB
+ // Setting vertices means regenerating the AABB.
AABB aabb;
{
@@ -505,7 +502,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RGBA8_UNORM:
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF: {
- //size 4
+ // Size 4
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -520,7 +517,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
} break;
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 8
+ // Size 8
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_BYTE_ARRAY, ERR_INVALID_PARAMETER);
Vector<uint8_t> array = p_arrays[ai];
@@ -537,7 +534,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
case ARRAY_CUSTOM_RG_FLOAT:
case ARRAY_CUSTOM_RGB_FLOAT:
case ARRAY_CUSTOM_RGBA_FLOAT: {
- //RF
+ // RF
ERR_FAIL_COND_V(p_arrays[ai].get_type() != Variant::PACKED_FLOAT32_ARRAY, ERR_INVALID_PARAMETER);
Vector<float> array = p_arrays[ai];
@@ -646,7 +643,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
}
if (p_format & RS::ARRAY_FORMAT_BONES) {
- //create AABBs for each detected bone
+ // Create AABBs for each detected bone.
int total_bones = max_bone + 1;
bool first = r_bone_aabb.size() == 0;
@@ -657,7 +654,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
if (first) {
for (int i = 0; i < total_bones; i++) {
- r_bone_aabb.write[i].size = Vector3(-1, -1, -1); //negative means unused
+ r_bone_aabb.write[i].size = Vector3(-1, -1, -1); // Negative means unused.
}
}
@@ -686,7 +683,7 @@ Error RenderingServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint
ERR_FAIL_INDEX_V(idx, total_bones, ERR_INVALID_DATA);
if (bptr[idx].size.x < 0) {
- //first
+ // First
bptr[idx] = AABB(v, SMALL_VEC3);
any_valid = true;
} else {
@@ -749,7 +746,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
uint32_t *size_accum;
for (int i = 0; i < RS::ARRAY_MAX; i++) {
- r_offsets[i] = 0; //reset
+ r_offsets[i] = 0; // Reset
if (i == RS::ARRAY_VERTEX) {
size_accum = &r_vertex_element_size;
@@ -759,7 +756,7 @@ void RenderingServer::mesh_surface_make_offsets_from_format(uint32_t p_format, i
size_accum = &r_skin_element_size;
}
- if (!(p_format & (1 << i))) { // no array
+ if (!(p_format & (1 << i))) { // No array
continue;
}
@@ -873,7 +870,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
uint32_t format = 0;
- // validation
+ // Validation
int index_array_len = 0;
int array_len = 0;
@@ -921,10 +918,10 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
}
- ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // mandatory
+ ERR_FAIL_COND_V((format & RS::ARRAY_FORMAT_VERTEX) == 0, ERR_INVALID_PARAMETER); // Mandatory
if (p_blend_shapes.size()) {
- //validate format for morphs
+ // Validate format for morphs.
for (int i = 0; i < p_blend_shapes.size(); i++) {
uint32_t bsformat = 0;
Array arr = p_blend_shapes[i];
@@ -939,7 +936,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
}
for (uint32_t i = 0; i < RS::ARRAY_CUSTOM_COUNT; ++i) {
- // include custom array format type.
+ // Include custom array format type.
if (format & (1 << (ARRAY_CUSTOM0 + i))) {
format |= (RS::ARRAY_FORMAT_CUSTOM_MASK << (RS::ARRAY_FORMAT_CUSTOM_BASE + i * RS::ARRAY_FORMAT_CUSTOM_BITS)) & p_compress_format;
}
@@ -954,7 +951,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
mesh_surface_make_offsets_from_format(format, array_len, index_array_len, offsets, vertex_element_size, attrib_element_size, skin_element_size);
uint32_t mask = (1 << ARRAY_MAX) - 1;
- format |= (~mask) & p_compress_format; //make the full format
+ format |= (~mask) & p_compress_format; // Make the full format.
int vertex_array_size = vertex_element_size * array_len;
int attrib_array_size = attrib_element_size * array_len;
@@ -1010,13 +1007,13 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
Vector<int> indices = p_lods[E];
ERR_CONTINUE(indices.size() == 0);
uint32_t index_count = indices.size();
- ERR_CONTINUE(index_count >= (uint32_t)index_array_len); //should be smaller..
+ ERR_CONTINUE(index_count >= (uint32_t)index_array_len); // Should be smaller..
const int *r = indices.ptr();
Vector<uint8_t> data;
if (array_len <= 65536) {
- //16 bits indices
+ // 16 bits indices
data.resize(indices.size() * 2);
uint8_t *w = data.ptrw();
uint16_t *index_ptr = (uint16_t *)w;
@@ -1024,7 +1021,7 @@ Error RenderingServer::mesh_create_surface_data_from_arrays(SurfaceData *r_surfa
index_ptr[i] = r[i];
}
} else {
- //32 bits indices
+ // 32 bits indices
data.resize(indices.size() * 4);
uint8_t *w = data.ptrw();
uint32_t *index_ptr = (uint32_t *)w;
@@ -1204,7 +1201,7 @@ Array RenderingServer::_get_array_from_surface(uint32_t p_format, Vector<uint8_t
case ARRAY_CUSTOM_RGBA8_SNORM:
case ARRAY_CUSTOM_RG_HALF:
case ARRAY_CUSTOM_RGBA_HALF: {
- //size 4
+ // Size 4
int s = type == ARRAY_CUSTOM_RGBA_HALF ? 8 : 4;
Vector<uint8_t> arr;
arr.resize(p_vertex_len * s);
@@ -1472,12 +1469,12 @@ ShaderLanguage::DataType RenderingServer::global_variable_type_get_shader_dataty
case RS::GLOBAL_VAR_TYPE_SAMPLERCUBE:
return ShaderLanguage::TYPE_SAMPLERCUBE;
default:
- return ShaderLanguage::TYPE_MAX; //invalid or not found
+ return ShaderLanguage::TYPE_MAX; // Invalid or not found.
}
}
RenderingDevice *RenderingServer::get_rendering_device() const {
- // return the rendering device we're using globally
+ // Return the rendering device we're using globally.
return RenderingDevice::get_singleton();
}
@@ -2221,8 +2218,8 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(VIEWPORT_SCALING_3D_MODE_MAX);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_DISABLED);
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); //then goes to disabled); must be manually updated
- BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // default
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ONCE); // Then goes to disabled); must be manually updated.
+ BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_VISIBLE); // Default
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE);
BIND_ENUM_CONSTANT(VIEWPORT_UPDATE_ALWAYS);
@@ -2553,7 +2550,8 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("canvas_item_set_modulate", "item", "color"), &RenderingServer::canvas_item_set_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_self_modulate", "item", "color"), &RenderingServer::canvas_item_set_self_modulate);
ClassDB::bind_method(D_METHOD("canvas_item_set_draw_behind_parent", "item", "enabled"), &RenderingServer::canvas_item_set_draw_behind_parent);
- //primitives
+
+ /* Primitives */
ClassDB::bind_method(D_METHOD("canvas_item_add_line", "item", "from", "to", "color", "width"), &RenderingServer::canvas_item_add_line, DEFVAL(1.0));
ClassDB::bind_method(D_METHOD("canvas_item_add_polyline", "item", "points", "colors", "width", "antialiased"), &RenderingServer::canvas_item_add_polyline, DEFVAL(1.0), DEFVAL(false));
@@ -2704,7 +2702,7 @@ void RenderingServer::_bind_methods() {
BIND_ENUM_CONSTANT(GLOBAL_VAR_TYPE_MAX);
/* Free */
- ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // shouldn't conflict with Object::free()
+ ClassDB::bind_method(D_METHOD("free_rid", "rid"), &RenderingServer::free); // Shouldn't conflict with Object::free().
/* Misc */
diff --git a/servers/rendering_server.h b/servers/rendering_server.h
index 85f92bc003..230132651f 100644
--- a/servers/rendering_server.h
+++ b/servers/rendering_server.h
@@ -55,6 +55,9 @@ class RenderingServer : public Object {
RendererThreadPool *thread_pool = nullptr;
+ const Vector2 SMALL_VEC2 = Vector2(CMP_EPSILON, CMP_EPSILON);
+ const Vector3 SMALL_VEC3 = Vector3(CMP_EPSILON, CMP_EPSILON, CMP_EPSILON);
+
protected:
RID _make_test_cube();
void _free_internal_rids();
@@ -108,7 +111,7 @@ public:
virtual void texture_3d_update(RID p_texture, const Vector<Ref<Image>> &p_data) = 0;
virtual void texture_proxy_update(RID p_texture, RID p_proxy_to) = 0;
- //these two APIs can be used together or in combination with the others.
+ // These two APIs can be used together or in combination with the others.
virtual RID texture_2d_placeholder_create() = 0;
virtual RID texture_2d_layered_placeholder_create(TextureLayeredType p_layered_type) = 0;
virtual RID texture_3d_placeholder_create() = 0;
@@ -210,18 +213,18 @@ public:
enum ArrayType {
ARRAY_VERTEX = 0, // RG32F or RGB32F (depending on 2D bit)
- ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored
- ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal
+ ARRAY_NORMAL = 1, // A2B10G10R10, A is ignored.
+ ARRAY_TANGENT = 2, // A2B10G10R10, A flips sign of binormal.
ARRAY_COLOR = 3, // RGBA8
ARRAY_TEX_UV = 4, // RG32F
ARRAY_TEX_UV2 = 5, // RG32F
- ARRAY_CUSTOM0 = 6, // depends on ArrayCustomFormat
+ ARRAY_CUSTOM0 = 6, // Depends on ArrayCustomFormat.
ARRAY_CUSTOM1 = 7,
ARRAY_CUSTOM2 = 8,
ARRAY_CUSTOM3 = 9,
ARRAY_BONES = 10, // RGBA16UI (x2 if 8 weights)
ARRAY_WEIGHTS = 11, // RGBA16UNORM (x2 if 8 weights)
- ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF
+ ARRAY_INDEX = 12, // 16 or 32 bits depending on length > 0xFFFF.
ARRAY_MAX = 13
};
@@ -243,7 +246,7 @@ public:
enum ArrayFormat {
/* ARRAY FORMAT FLAGS */
- ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory
+ ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // Mandatory
ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL,
ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT,
ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR,
@@ -287,9 +290,9 @@ public:
PrimitiveType primitive = PRIMITIVE_MAX;
uint32_t format = 0;
- Vector<uint8_t> vertex_data; // vertex, normal, tangent (change with skinning, blendshape)
- Vector<uint8_t> attribute_data; // color,uv, uv2, custom0-3
- Vector<uint8_t> skin_data; // bone index, bone weight
+ Vector<uint8_t> vertex_data; // Vertex, Normal, Tangent (change with skinning, blendshape).
+ Vector<uint8_t> attribute_data; // Color, UV, UV2, Custom0-3.
+ Vector<uint8_t> skin_data; // Bone index, Bone weight.
uint32_t vertex_count = 0;
Vector<uint8_t> index_data;
uint32_t index_count = 0;
@@ -452,7 +455,7 @@ public:
virtual void light_set_bake_mode(RID p_light, LightBakeMode p_bake_mode) = 0;
virtual void light_set_max_sdfgi_cascade(RID p_light, uint32_t p_cascade) = 0;
- // omni light
+ // Omni light
enum LightOmniShadowMode {
LIGHT_OMNI_SHADOW_DUAL_PARABOLOID,
LIGHT_OMNI_SHADOW_CUBE,
@@ -460,7 +463,7 @@ public:
virtual void light_omni_set_shadow_mode(RID p_light, LightOmniShadowMode p_mode) = 0;
- // directional light
+ // Directional light
enum LightDirectionalShadowMode {
LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS,
@@ -671,7 +674,7 @@ public:
virtual AABB particles_get_current_aabb(RID p_particles) = 0;
- virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; //this is only used for 2D, in 3D it's automatic
+ virtual void particles_set_emission_transform(RID p_particles, const Transform3D &p_transform) = 0; // This is only used for 2D, in 3D it's automatic.
/* PARTICLES COLLISION API */
@@ -689,16 +692,16 @@ public:
virtual void particles_collision_set_collision_type(RID p_particles_collision, ParticlesCollisionType p_type) = 0;
virtual void particles_collision_set_cull_mask(RID p_particles_collision, uint32_t p_cull_mask) = 0;
- virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; //for spheres
- virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; //for non-spheres
+ virtual void particles_collision_set_sphere_radius(RID p_particles_collision, real_t p_radius) = 0; // For spheres.
+ virtual void particles_collision_set_box_extents(RID p_particles_collision, const Vector3 &p_extents) = 0; // For non-spheres.
virtual void particles_collision_set_attractor_strength(RID p_particles_collision, real_t p_strength) = 0;
virtual void particles_collision_set_attractor_directionality(RID p_particles_collision, real_t p_directionality) = 0;
virtual void particles_collision_set_attractor_attenuation(RID p_particles_collision, real_t p_curve) = 0;
- virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; //for SDF and vector field, heightfield is dynamic
+ virtual void particles_collision_set_field_texture(RID p_particles_collision, RID p_texture) = 0; // For SDF and vector field, heightfield is dynamic.
- virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; //for SDF and vector field
+ virtual void particles_collision_height_field_update(RID p_particles_collision) = 0; // For SDF and vector field.
- enum ParticlesCollisionHeightfieldResolution { //longest axis resolution
+ enum ParticlesCollisionHeightfieldResolution { // Longest axis resolution.
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_256,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_512,
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_1024,
@@ -708,7 +711,7 @@ public:
PARTICLES_COLLISION_HEIGHTFIELD_RESOLUTION_MAX,
};
- virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; //for SDF and vector field
+ virtual void particles_collision_set_height_field_resolution(RID p_particles_collision, ParticlesCollisionHeightfieldResolution p_resolution) = 0; // For SDF and vector field.
/* FOG VOLUME API */
@@ -750,7 +753,7 @@ public:
/* VIEWPORT API */
enum CanvasItemTextureFilter {
- CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_FILTER_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_FILTER_NEAREST,
CANVAS_ITEM_TEXTURE_FILTER_LINEAR,
CANVAS_ITEM_TEXTURE_FILTER_NEAREST_WITH_MIPMAPS,
@@ -761,7 +764,7 @@ public:
};
enum CanvasItemTextureRepeat {
- CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, //uses canvas item setting for draw command, uses global setting for canvas item
+ CANVAS_ITEM_TEXTURE_REPEAT_DEFAULT, // Uses canvas item setting for draw command, uses global setting for canvas item.
CANVAS_ITEM_TEXTURE_REPEAT_DISABLED,
CANVAS_ITEM_TEXTURE_REPEAT_ENABLED,
CANVAS_ITEM_TEXTURE_REPEAT_MIRROR,
@@ -791,8 +794,8 @@ public:
enum ViewportUpdateMode {
VIEWPORT_UPDATE_DISABLED,
- VIEWPORT_UPDATE_ONCE, //then goes to disabled, must be manually updated
- VIEWPORT_UPDATE_WHEN_VISIBLE, // default
+ VIEWPORT_UPDATE_ONCE, // Then goes to disabled, must be manually updated.
+ VIEWPORT_UPDATE_WHEN_VISIBLE, // Default
VIEWPORT_UPDATE_WHEN_PARENT_VISIBLE,
VIEWPORT_UPDATE_ALWAYS
};
@@ -1171,7 +1174,7 @@ public:
virtual void instance_set_ignore_culling(RID p_instance, bool p_enabled) = 0;
- // don't use these in a game!
+ // Don't use these in a game!
virtual Vector<ObjectID> instances_cull_aabb(const AABB &p_aabb, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_ray(const Vector3 &p_from, const Vector3 &p_to, RID p_scenario = RID()) const = 0;
virtual Vector<ObjectID> instances_cull_convex(const Vector<Plane> &p_convex, RID p_scenario = RID()) const = 0;
@@ -1245,7 +1248,7 @@ public:
virtual void canvas_texture_set_channel(RID p_canvas_texture, CanvasTextureChannel p_channel, RID p_texture) = 0;
virtual void canvas_texture_set_shading_parameters(RID p_canvas_texture, const Color &p_base_color, float p_shininess) = 0;
- //takes effect only for new draw commands
+ // Takes effect only for new draw commands.
virtual void canvas_texture_set_texture_filter(RID p_canvas_texture, CanvasItemTextureFilter p_filter) = 0;
virtual void canvas_texture_set_texture_repeat(RID p_canvas_texture, CanvasItemTextureRepeat p_repeat) = 0;
@@ -1443,7 +1446,7 @@ public:
/* FREE */
- virtual void free(RID p_rid) = 0; ///< free RIDs associated with the rendering server
+ virtual void free(RID p_rid) = 0; // Free RIDs associated with the rendering server.
/* EVENT QUEUING */
@@ -1529,7 +1532,7 @@ public:
virtual ~RenderingServer();
private:
- //binder helpers
+ // Binder helpers
RID _texture_2d_layered_create(const TypedArray<Image> &p_layers, TextureLayeredType p_layered_type);
RID _texture_3d_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data);
void _texture_3d_update(RID p_texture, const TypedArray<Image> &p_data);
@@ -1543,7 +1546,7 @@ private:
void _particles_set_trail_bind_poses(RID p_particles, const TypedArray<Transform3D> &p_bind_poses);
};
-// make variant understand the enums
+// Make variant understand the enums.
VARIANT_ENUM_CAST(RenderingServer::TextureLayeredType);
VARIANT_ENUM_CAST(RenderingServer::CubeMapLayer);
VARIANT_ENUM_CAST(RenderingServer::ShaderMode);
diff --git a/tests/core/math/test_aabb.h b/tests/core/math/test_aabb.h
index b838bed171..f5076ce1ed 100644
--- a/tests/core/math/test_aabb.h
+++ b/tests/core/math/test_aabb.h
@@ -349,14 +349,27 @@ TEST_CASE("[AABB] Has point") {
aabb.has_point(Vector3(2, 3, 0)),
"has_point() with contained point should return the expected value.");
CHECK_MESSAGE(
+ !aabb.has_point(Vector3(-20, 0, 0)),
+ "has_point() with non-contained point should return the expected value.");
+
+ CHECK_MESSAGE(
aabb.has_point(Vector3(-1.5, 3, 0)),
- "has_point() with contained point on negative edge should return the expected value.");
+ "has_point() with positive size should include point on near face (X axis).");
CHECK_MESSAGE(
aabb.has_point(Vector3(2.5, 3, 0)),
- "has_point() with contained point on positive edge should return the expected value.");
+ "has_point() with positive size should include point on far face (X axis).");
CHECK_MESSAGE(
- !aabb.has_point(Vector3(-20, 0, 0)),
- "has_point() with non-contained point should return the expected value.");
+ aabb.has_point(Vector3(0, 2, 0)),
+ "has_point() with positive size should include point on near face (Y axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 7, 0)),
+ "has_point() with positive size should include point on far face (Y axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 3, -2.5)),
+ "has_point() with positive size should include point on near face (Z axis).");
+ CHECK_MESSAGE(
+ aabb.has_point(Vector3(0, 3, 3.5)),
+ "has_point() with positive size should include point on far face (Z axis).");
}
TEST_CASE("[AABB] Expanding") {
diff --git a/tests/core/templates/test_oa_hash_map.cpp b/tests/core/templates/test_oa_hash_map.cpp
index 904c01642d..f7b2b7cdb0 100644
--- a/tests/core/templates/test_oa_hash_map.cpp
+++ b/tests/core/templates/test_oa_hash_map.cpp
@@ -55,7 +55,10 @@ struct CountedItem {
count++;
}
- CountedItem &operator=(const CountedItem &p_other) = default;
+ void operator=(const CountedItem &p_other) {
+ id = p_other.id;
+ count++;
+ }
~CountedItem() {
CRASH_COND(destroyed);
diff --git a/tests/scene/test_curve.h b/tests/scene/test_curve.h
index 60eafad460..4ee1a1c15c 100644
--- a/tests/scene/test_curve.h
+++ b/tests/scene/test_curve.h
@@ -219,35 +219,33 @@ TEST_CASE("[Curve] Custom curve with linear tangents") {
TEST_CASE("[Curve2D] Linear sampling should return exact value") {
Ref<Curve2D> curve = memnew(Curve2D);
- int len = 2048;
+ real_t len = 2048.0;
curve->add_point(Vector2(0, 0));
- curve->add_point(Vector2((float)len, 0));
+ curve->add_point(Vector2(len, 0));
- float baked_length = curve->get_baked_length();
- CHECK((float)len == baked_length);
+ real_t baked_length = curve->get_baked_length();
+ CHECK(len == baked_length);
for (int i = 0; i < len; i++) {
- float expected = (float)i;
- Vector2 pos = curve->interpolate_baked(expected);
- CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ Vector2 pos = curve->interpolate_baked(i);
+ CHECK_MESSAGE(pos.x == i, "interpolate_baked should return exact value");
}
}
TEST_CASE("[Curve3D] Linear sampling should return exact value") {
Ref<Curve3D> curve = memnew(Curve3D);
- int len = 2048;
+ real_t len = 2048.0;
curve->add_point(Vector3(0, 0, 0));
- curve->add_point(Vector3((float)len, 0, 0));
+ curve->add_point(Vector3(len, 0, 0));
- float baked_length = curve->get_baked_length();
- CHECK((float)len == baked_length);
+ real_t baked_length = curve->get_baked_length();
+ CHECK(len == baked_length);
for (int i = 0; i < len; i++) {
- float expected = (float)i;
- Vector3 pos = curve->interpolate_baked(expected);
- CHECK_MESSAGE(pos.x == expected, "interpolate_baked should return exact value");
+ Vector3 pos = curve->interpolate_baked(i);
+ CHECK_MESSAGE(pos.x == i, "interpolate_baked should return exact value");
}
}
diff --git a/tests/servers/test_shader_lang.cpp b/tests/servers/test_shader_lang.cpp
index 0591bf6adf..f4a32c6723 100644
--- a/tests/servers/test_shader_lang.cpp
+++ b/tests/servers/test_shader_lang.cpp
@@ -261,6 +261,8 @@ static String dump_node_code(SL::Node *p_node, int p_level) {
}
code += ")";
break;
+ case SL::OP_EMPTY:
+ break;
default: {
code = "(" + dump_node_code(onode->arguments[0], p_level) + _opstr(onode->op) + dump_node_code(onode->arguments[1], p_level) + ")";
break;
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 03e9885bd0..f8055ac3e7 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -201,7 +201,7 @@ Files extracted from upstream source:
## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz
-- Version: 3.1.1 (cd5c6cd0419ac5e4de975d6c476fb760bf06d2ce, 2021)
+- Version: 3.1.2 (8aed5c21a31eece6a9f3cd775fda8facb6c28b9b, 2021)
- License: MIT
Files extracted from upstream source:
@@ -359,6 +359,19 @@ instead of a combination of distance and attribute errors. Patches for both chan
found in the `patches` directory.
+## minimp3
+
+- Upstream: https://github.com/lieff/minimp3
+- Version: git (afb604c06bc8beb145fecd42c0ceb5bda8795144, 2021)
+- License: CC0 1.0
+
+Files extracted from upstream repository:
+
+- `minimp3.h`
+- `minimp3_ex.h`
+- `LICENSE`
+
+
## miniupnpc
- Upstream: https://github.com/miniupnp/miniupnp
diff --git a/thirdparty/harfbuzz/src/hb-array.hh b/thirdparty/harfbuzz/src/hb-array.hh
index dd61509b2e..0beffb078f 100644
--- a/thirdparty/harfbuzz/src/hb-array.hh
+++ b/thirdparty/harfbuzz/src/hb-array.hh
@@ -51,13 +51,19 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
* Constructors.
*/
hb_array_t () = default;
- hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
+ hb_array_t (const hb_array_t&) = default;
+ ~hb_array_t () = default;
+ hb_array_t& operator= (const hb_array_t&) = default;
+ hb_array_t& operator= (hb_array_t&&) = default;
+
+ constexpr hb_array_t (std::nullptr_t) : hb_array_t () {}
+ constexpr hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
template <unsigned int length_>
- hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
+ constexpr hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_array_t (const hb_array_t<U> &o) :
+ constexpr hb_array_t (const hb_array_t<U> &o) :
hb_iter_with_fallback_t<hb_array_t, Type&> (),
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
template <typename U,
@@ -303,13 +309,19 @@ struct hb_sorted_array_t :
static constexpr bool is_sorted_iterator = true;
hb_sorted_array_t () = default;
- hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
+ hb_sorted_array_t (const hb_sorted_array_t&) = default;
+ ~hb_sorted_array_t () = default;
+ hb_sorted_array_t& operator= (const hb_sorted_array_t&) = default;
+ hb_sorted_array_t& operator= (hb_sorted_array_t&&) = default;
+
+ constexpr hb_sorted_array_t (std::nullptr_t) : hb_sorted_array_t () {}
+ constexpr hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
template <unsigned int length_>
- hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
+ constexpr hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
- hb_sorted_array_t (const hb_array_t<U> &o) :
+ constexpr hb_sorted_array_t (const hb_array_t<U> &o) :
hb_iter_t<hb_sorted_array_t, Type&> (),
hb_array_t<Type> (o) {}
template <typename U,
diff --git a/thirdparty/harfbuzz/src/hb-map.hh b/thirdparty/harfbuzz/src/hb-map.hh
index bb4a0eb5d1..793dcf22ca 100644
--- a/thirdparty/harfbuzz/src/hb-map.hh
+++ b/thirdparty/harfbuzz/src/hb-map.hh
@@ -35,8 +35,10 @@
*/
template <typename K, typename V,
- K kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
- V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
+ typename k_invalid_t = K,
+ typename v_invalid_t = V,
+ k_invalid_t kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
+ v_invalid_t vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
struct hb_hashmap_t
{
static constexpr K INVALID_KEY = kINVALID;
@@ -62,8 +64,10 @@ struct hb_hashmap_t
hb_copy (o, *this);
}
- static_assert (std::is_integral<K>::value || hb_is_pointer (K), "");
- static_assert (std::is_integral<V>::value || hb_is_pointer (V), "");
+ static_assert (std::is_trivially_copyable<K>::value, "");
+ static_assert (std::is_trivially_copyable<V>::value, "");
+ static_assert (std::is_trivially_destructible<K>::value, "");
+ static_assert (std::is_trivially_destructible<V>::value, "");
struct item_t
{
@@ -348,19 +352,23 @@ struct hb_hashmap_t
struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
+ hb_codepoint_t,
+ hb_codepoint_t,
HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID>
{
using hashmap = hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
+ hb_codepoint_t,
+ hb_codepoint_t,
HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID>;
hb_map_t () = default;
~hb_map_t () = default;
- hb_map_t (hb_map_t& o) = default;
- hb_map_t& operator= (const hb_map_t& other) = default;
- hb_map_t& operator= (hb_map_t&& other) = default;
+ hb_map_t (hb_map_t&) = default;
+ hb_map_t& operator= (const hb_map_t&) = default;
+ hb_map_t& operator= (hb_map_t&&) = default;
hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
diff --git a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
index 03476faba7..a3c55fa8f4 100644
--- a/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-color-colr-table.hh
@@ -38,8 +38,8 @@
*/
#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
-#ifndef COLRV1_MAX_NESTING_LEVEL
-#define COLRV1_MAX_NESTING_LEVEL 100
+#ifndef HB_COLRV1_MAX_NESTING_LEVEL
+#define HB_COLRV1_MAX_NESTING_LEVEL 100
#endif
#ifndef COLRV1_ENABLE_SUBSETTING
@@ -102,7 +102,7 @@ struct hb_colrv1_closure_context_t :
hb_set_t *glyphs_,
hb_set_t *layer_indices_,
hb_set_t *palette_indices_,
- unsigned nesting_level_left_ = COLRV1_MAX_NESTING_LEVEL) :
+ unsigned nesting_level_left_ = HB_COLRV1_MAX_NESTING_LEVEL) :
base (base_),
glyphs (glyphs_),
layer_indices (layer_indices_),
@@ -985,7 +985,7 @@ struct ClipList
for (const hb_codepoint_t _ : gids.iter ())
{
if (_ == start_gid) continue;
-
+
offset = gid_offset_map.get (_);
if (_ == prev_gid + 1 && offset == prev_offset)
{
@@ -1027,7 +1027,7 @@ struct ClipList
const hb_set_t& glyphset = *c->plan->_glyphset;
const hb_map_t &glyph_map = *c->plan->glyph_map;
-
+
hb_map_t new_gid_offset_map;
hb_set_t new_gids;
for (const ClipRecord& record : clips.iter ())
@@ -1062,6 +1062,18 @@ struct ClipList
struct Paint
{
+
+ template <typename ...Ts>
+ bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
+ {
+ TRACE_SANITIZE (this);
+
+ if (unlikely (!c->check_start_recursion (HB_COLRV1_MAX_NESTING_LEVEL)))
+ return_trace (c->no_dispatch_return_value ());
+
+ return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
+ }
+
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
index 5d98278bed..882c3ae96f 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-common.hh
@@ -98,7 +98,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
struct hb_prune_langsys_context_t
{
hb_prune_langsys_context_t (const void *table_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
const hb_map_t *duplicate_feature_map_,
hb_set_t *new_collected_feature_indexes_)
:table (table_),
@@ -137,7 +137,7 @@ struct hb_prune_langsys_context_t
public:
const void *table;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
const hb_map_t *duplicate_feature_map;
hb_set_t *new_feature_indexes;
@@ -179,14 +179,14 @@ struct hb_subset_layout_context_t :
hb_subset_context_t *subset_context;
const hb_tag_t table_tag;
const hb_map_t *lookup_index_map;
- const hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map;
+ const hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map;
const hb_map_t *feature_index_map;
unsigned cur_script_index;
hb_subset_layout_context_t (hb_subset_context_t *c_,
hb_tag_t tag_,
hb_map_t *lookup_map_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map_,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map_,
hb_map_t *feature_index_map_) :
subset_context (c_),
table_tag (tag_),
@@ -1357,7 +1357,7 @@ struct Lookup
if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
return_trace (false);
- if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
+ if (unlikely (get_type () == TSubTable::Extension && subtables && !c->get_edit_count ()))
{
/* The spec says all subtables of an Extension lookup should
* have the same type, which shall not be the Extension type
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
index c0ed2bcc03..6bc06b50ed 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
@@ -163,7 +163,7 @@ struct hb_closure_context_t :
hb_set_t *glyphs_,
hb_set_t *cur_intersected_glyphs_,
hb_map_t *done_lookups_glyph_count_,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set_,
+ hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set_,
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
face (face_),
glyphs (glyphs_),
@@ -192,7 +192,7 @@ struct hb_closure_context_t :
private:
hb_map_t *done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> *done_lookups_glyph_set;
unsigned int lookup_count;
};
@@ -1642,9 +1642,8 @@ struct Rule
const hb_map_t *klass_map = nullptr) const
{
TRACE_SUBSET (this);
-
- const hb_array_t<const HBUINT16> input = inputZ.as_array ((inputCount ? inputCount - 1 : 0));
- if (!input.length) return_trace (false);
+ if (unlikely (!inputCount)) return_trace (false);
+ const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1);
const hb_map_t *mapping = klass_map == nullptr ? c->plan->glyph_map : klass_map;
if (!hb_all (input, mapping)) return_trace (false);
@@ -3631,7 +3630,7 @@ struct GSUBGPOS
}
void prune_langsys (const hb_map_t *duplicate_feature_map,
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *script_langsys_map,
+ hb_hashmap_t<unsigned, hb_set_t *> *script_langsys_map,
hb_set_t *new_feature_indexes /* OUT */) const
{
hb_prune_langsys_context_t c (this, script_langsys_map, duplicate_feature_map, new_feature_indexes);
@@ -3689,7 +3688,7 @@ struct GSUBGPOS
hb_map_t *duplicate_feature_map /* OUT */) const
{
if (feature_indices->is_empty ()) return;
- hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
+ hb_hashmap_t<hb_tag_t, hb_set_t *> unique_features;
//find out duplicate features after subset
for (unsigned i : feature_indices->iter ())
{
@@ -3784,8 +3783,12 @@ struct GSUBGPOS
// http://lists.freedesktop.org/archives/harfbuzz/2012-November/002660.html
continue;
- if (f.featureParams.is_null ()
- && !f.intersects_lookup_indexes (lookup_indices)
+
+ if (!f.featureParams.is_null () &&
+ tag == HB_TAG ('s', 'i', 'z', 'e'))
+ continue;
+
+ if (!f.intersects_lookup_indexes (lookup_indices)
#ifndef HB_NO_VAR
&& !alternate_feature_indices.has (i)
#endif
diff --git a/thirdparty/harfbuzz/src/hb-ot-layout.cc b/thirdparty/harfbuzz/src/hb-ot-layout.cc
index fbdedd0e20..4e1d23eba5 100644
--- a/thirdparty/harfbuzz/src/hb-ot-layout.cc
+++ b/thirdparty/harfbuzz/src/hb-ot-layout.cc
@@ -1493,7 +1493,7 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
{
hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::SubstLookup& l = face->table.GSUB->table->get_lookup (lookup_index);
@@ -1522,7 +1522,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
{
hb_set_t cur_intersected_glyphs;
hb_map_t done_lookups_glyph_count;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> done_lookups_glyph_set;
+ hb_hashmap_t<unsigned, hb_set_t *> done_lookups_glyph_set;
OT::hb_closure_context_t c (face, glyphs, &cur_intersected_glyphs, &done_lookups_glyph_count, &done_lookups_glyph_set);
const OT::GSUB& gsub = *face->table.GSUB->table;
diff --git a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
index 94450eb53a..504de2de74 100644
--- a/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
+++ b/thirdparty/harfbuzz/src/hb-ot-post-table-v2subset.hh
@@ -79,6 +79,7 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
post::accelerator_t _post;
_post.init (c->plan->source);
+ hb_hashmap_t<hb_bytes_t, unsigned, std::nullptr_t, unsigned, nullptr, (unsigned)-1> glyph_name_to_new_index;
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
{
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
@@ -90,22 +91,28 @@ HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
else
{
hb_bytes_t s = _post.find_glyph_name (old_gid);
- int standard_glyph_index = -1;
- for (unsigned i = 0; i < format1_names_length; i++)
+ new_index = glyph_name_to_new_index.get (s);
+ if (new_index == (unsigned)-1)
{
- if (s == format1_names (i))
+ int standard_glyph_index = -1;
+ for (unsigned i = 0; i < format1_names_length; i++)
{
- standard_glyph_index = i;
- break;
+ if (s == format1_names (i))
+ {
+ standard_glyph_index = i;
+ break;
+ }
}
+
+ if (standard_glyph_index == -1)
+ {
+ new_index = 258 + i;
+ i++;
+ }
+ else
+ { new_index = standard_glyph_index; }
+ glyph_name_to_new_index.set (s, new_index);
}
- if (standard_glyph_index == -1)
- {
- new_index = 258 + i;
- i++;
- }
- else
- { new_index = standard_glyph_index; }
old_new_index_map.set (old_index, new_index);
}
old_gid_new_index_map.set (old_gid, new_index);
diff --git a/thirdparty/harfbuzz/src/hb-sanitize.hh b/thirdparty/harfbuzz/src/hb-sanitize.hh
index 2e536c7a81..65c2772201 100644
--- a/thirdparty/harfbuzz/src/hb-sanitize.hh
+++ b/thirdparty/harfbuzz/src/hb-sanitize.hh
@@ -123,6 +123,7 @@ struct hb_sanitize_context_t :
hb_sanitize_context_t () :
start (nullptr), end (nullptr),
max_ops (0), max_subtables (0),
+ recursion_depth (0),
writable (false), edit_count (0),
blob (nullptr),
num_glyphs (65536),
@@ -205,6 +206,7 @@ struct hb_sanitize_context_t :
(unsigned) HB_SANITIZE_MAX_OPS_MAX);
this->edit_count = 0;
this->debug_depth = 0;
+ this->recursion_depth = 0;
DEBUG_MSG_LEVEL (SANITIZE, start, 0, +1,
"start [%p..%p] (%lu bytes)",
@@ -278,6 +280,18 @@ struct hb_sanitize_context_t :
return this->check_range (base, a, b, hb_static_size (T));
}
+ bool check_start_recursion (int max_depth)
+ {
+ if (unlikely (recursion_depth >= max_depth)) return false;
+ return ++recursion_depth;
+ }
+
+ bool end_recursion (bool result)
+ {
+ recursion_depth--;
+ return result;
+ }
+
template <typename Type>
bool check_struct (const Type *obj) const
{ return likely (this->check_range (obj, obj->min_size)); }
@@ -389,6 +403,7 @@ struct hb_sanitize_context_t :
const char *start, *end;
mutable int max_ops, max_subtables;
private:
+ int recursion_depth;
bool writable;
unsigned int edit_count;
hb_blob_t *blob;
diff --git a/thirdparty/harfbuzz/src/hb-serialize.hh b/thirdparty/harfbuzz/src/hb-serialize.hh
index 57689916f6..d22ae06087 100644
--- a/thirdparty/harfbuzz/src/hb-serialize.hh
+++ b/thirdparty/harfbuzz/src/hb-serialize.hh
@@ -652,7 +652,9 @@ struct hb_serialize_context_t
hb_vector_t<object_t *> packed;
/* Map view of packed objects. */
- hb_hashmap_t<const object_t *, objidx_t, nullptr, 0> packed_map;
+ hb_hashmap_t<const object_t *, objidx_t,
+ const object_t *, objidx_t,
+ nullptr, 0> packed_map;
};
#endif /* HB_SERIALIZE_HH */
diff --git a/thirdparty/harfbuzz/src/hb-set.hh b/thirdparty/harfbuzz/src/hb-set.hh
index 8841427189..af02e9e12b 100644
--- a/thirdparty/harfbuzz/src/hb-set.hh
+++ b/thirdparty/harfbuzz/src/hb-set.hh
@@ -157,9 +157,9 @@ struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
{
hb_set_t () = default;
~hb_set_t () = default;
- hb_set_t (hb_set_t& o) = default;
- hb_set_t& operator= (const hb_set_t& other) = default;
- hb_set_t& operator= (hb_set_t&& other) = default;
+ hb_set_t (hb_set_t&) = default;
+ hb_set_t& operator= (const hb_set_t&) = default;
+ hb_set_t& operator= (hb_set_t&&) = default;
hb_set_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.cc b/thirdparty/harfbuzz/src/hb-subset-plan.cc
index 1e195ff660..53f8664d92 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.cc
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.cc
@@ -41,7 +41,7 @@
#include "hb-ot-math-table.hh"
-typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
+typedef hb_hashmap_t<unsigned, hb_set_t *> script_langsys_map;
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
@@ -100,11 +100,23 @@ static void _collect_layout_indices (hb_face_t *face,
if (!features.alloc (table.get_feature_count () + 1))
return;
+ hb_set_t visited_features;
+ bool retain_all_features = true;
for (unsigned i = 0; i < table.get_feature_count (); i++)
{
hb_tag_t tag = table.get_feature_tag (i);
- if (tag && layout_features_to_retain->has (tag))
- features.push (tag);
+ if (!tag) continue;
+ if (!layout_features_to_retain->has (tag))
+ {
+ retain_all_features = false;
+ continue;
+ }
+
+ if (visited_features.has (tag))
+ continue;
+
+ features.push (tag);
+ visited_features.add (tag);
}
if (!features)
@@ -113,7 +125,7 @@ static void _collect_layout_indices (hb_face_t *face,
// The collect function needs a null element to signal end of the array.
features.push (0);
- if (features.get_size () == table.get_feature_count () + 1)
+ if (retain_all_features)
{
// Looking for all features, trigger the faster collection method.
layout_collect_func (face,
diff --git a/thirdparty/harfbuzz/src/hb-subset-plan.hh b/thirdparty/harfbuzz/src/hb-subset-plan.hh
index c30feeb42f..c0232480bf 100644
--- a/thirdparty/harfbuzz/src/hb-subset-plan.hh
+++ b/thirdparty/harfbuzz/src/hb-subset-plan.hh
@@ -84,8 +84,8 @@ struct hb_subset_plan_t
hb_map_t *gpos_lookups;
//active langsys we'd like to retain
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gsub_langsys;
- hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> *gpos_langsys;
+ hb_hashmap_t<unsigned, hb_set_t *> *gsub_langsys;
+ hb_hashmap_t<unsigned, hb_set_t *> *gpos_langsys;
//active features after removing redundant langsys and prune_features
hb_map_t *gsub_features;
diff --git a/thirdparty/harfbuzz/src/hb-version.h b/thirdparty/harfbuzz/src/hb-version.h
index 1a4f0bf62a..c9fefa1df6 100644
--- a/thirdparty/harfbuzz/src/hb-version.h
+++ b/thirdparty/harfbuzz/src/hb-version.h
@@ -53,14 +53,14 @@ HB_BEGIN_DECLS
*
* The micro component of the library version available at compile-time.
*/
-#define HB_VERSION_MICRO 1
+#define HB_VERSION_MICRO 2
/**
* HB_VERSION_STRING:
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "3.1.1"
+#define HB_VERSION_STRING "3.1.2"
/**
* HB_VERSION_ATLEAST:
diff --git a/thirdparty/minimp3/minimp3.h b/thirdparty/minimp3/minimp3.h
index 796cbc1f8e..3220ae1a85 100644
--- a/thirdparty/minimp3/minimp3.h
+++ b/thirdparty/minimp3/minimp3.h
@@ -881,12 +881,22 @@ static void L3_midside_stereo(float *left, int n)
int i = 0;
float *right = left + 576;
#if HAVE_SIMD
- if (have_simd()) for (; i < n - 3; i += 4)
+ if (have_simd())
{
- f4 vl = VLD(left + i);
- f4 vr = VLD(right + i);
- VSTORE(left + i, VADD(vl, vr));
- VSTORE(right + i, VSUB(vl, vr));
+ for (; i < n - 3; i += 4)
+ {
+ f4 vl = VLD(left + i);
+ f4 vr = VLD(right + i);
+ VSTORE(left + i, VADD(vl, vr));
+ VSTORE(right + i, VSUB(vl, vr));
+ }
+#ifdef __GNUC__
+ /* Workaround for spurious -Waggressive-loop-optimizations warning from gcc.
+ * For more info see: https://github.com/lieff/minimp3/issues/88
+ */
+ if (__builtin_constant_p(n % 4 == 0) && n % 4 == 0)
+ return;
+#endif
}
#endif /* HAVE_SIMD */
for (; i < n; i++)
@@ -1353,7 +1363,7 @@ static void mp3d_DCT_II(float *grbuf, int n)
} else
#endif /* HAVE_SIMD */
#ifdef MINIMP3_ONLY_SIMD
- {}
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else /* MINIMP3_ONLY_SIMD */
for (; k < n; k++)
{
@@ -1583,7 +1593,7 @@ static void mp3d_synth(float *xl, mp3d_sample_t *dstl, int nch, float *lins)
} else
#endif /* HAVE_SIMD */
#ifdef MINIMP3_ONLY_SIMD
- {}
+ {} /* for HAVE_SIMD=1, MINIMP3_ONLY_SIMD=1 case we do not need non-intrinsic "else" branch */
#else /* MINIMP3_ONLY_SIMD */
for (i = 14; i >= 0; i--)
{
diff --git a/thirdparty/minimp3/minimp3_ex.h b/thirdparty/minimp3/minimp3_ex.h
index e29dd15b2e..2871705df3 100644
--- a/thirdparty/minimp3/minimp3_ex.h
+++ b/thirdparty/minimp3/minimp3_ex.h
@@ -6,6 +6,7 @@
This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>.
*/
+#include <stddef.h>
#include "minimp3.h"
/* flags for mp3dec_ex_open_* functions */
@@ -128,8 +129,10 @@ int mp3dec_ex_open_w(mp3dec_ex_t *dec, const wchar_t *file_name, int flags);
#endif
#endif /*MINIMP3_EXT_H*/
-#ifdef MINIMP3_IMPLEMENTATION
+#if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_EX_IMPLEMENTATION_GUARD)
+#define _MINIMP3_EX_IMPLEMENTATION_GUARD
#include <limits.h>
+#include "minimp3.h"
static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
{
@@ -1391,4 +1394,4 @@ void mp3dec_ex_close(mp3dec_ex_t *dec)
}
#endif
-#endif /*MINIMP3_IMPLEMENTATION*/
+#endif /* MINIMP3_IMPLEMENTATION && !_MINIMP3_EX_IMPLEMENTATION_GUARD */