summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/canvas_group.cpp2
-rw-r--r--scene/2d/gpu_particles_2d.cpp6
-rw-r--r--scene/2d/navigation_agent_2d.cpp6
-rw-r--r--scene/2d/tile_map.cpp42
-rw-r--r--scene/2d/tile_map.h20
-rw-r--r--scene/3d/mesh_instance_3d.cpp19
-rw-r--r--scene/3d/mesh_instance_3d.h1
-rw-r--r--scene/3d/navigation_agent_3d.cpp6
-rw-r--r--scene/animation/animation_tree.cpp2
-rw-r--r--scene/gui/control.cpp6
-rw-r--r--scene/gui/item_list.cpp1
-rw-r--r--scene/gui/rich_text_label.cpp7
-rw-r--r--scene/gui/text_edit.cpp2
-rw-r--r--scene/main/multiplayer_peer.h4
-rw-r--r--scene/register_scene_types.cpp2
-rw-r--r--scene/resources/curve.cpp52
-rw-r--r--scene/resources/curve.h2
-rw-r--r--scene/resources/resource_format_text.cpp26
18 files changed, 146 insertions, 60 deletions
diff --git a/scene/2d/canvas_group.cpp b/scene/2d/canvas_group.cpp
index d4182f85a7..0ada703837 100644
--- a/scene/2d/canvas_group.cpp
+++ b/scene/2d/canvas_group.cpp
@@ -47,7 +47,7 @@ void CanvasGroup::set_clear_margin(real_t p_clear_margin) {
ERR_FAIL_COND(p_clear_margin < 0.0);
clear_margin = p_clear_margin;
- RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_TRANSPARENT, clear_margin, true, clear_margin, use_mipmaps);
+ RS::get_singleton()->canvas_item_set_canvas_group_mode(get_canvas_item(), RS::CANVAS_GROUP_MODE_TRANSPARENT, clear_margin, true, fit_margin, use_mipmaps);
queue_redraw();
}
diff --git a/scene/2d/gpu_particles_2d.cpp b/scene/2d/gpu_particles_2d.cpp
index c8f5d7f5a6..ccbc080768 100644
--- a/scene/2d/gpu_particles_2d.cpp
+++ b/scene/2d/gpu_particles_2d.cpp
@@ -625,6 +625,8 @@ void GPUParticles2D::_bind_methods() {
ADD_PROPERTY_DEFAULT("emitting", true); // Workaround for doctool in headless mode, as dummy rasterizer always returns false.
ADD_PROPERTY(PropertyInfo(Variant::INT, "amount", PROPERTY_HINT_RANGE, "1,1000000,1,exp"), "set_amount", "get_amount");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "sub_emitter", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "GPUParticles2D"), "set_sub_emitter", "get_sub_emitter");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticleProcessMaterial"), "set_process_material", "get_process_material");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
ADD_GROUP("Time", "");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime", PROPERTY_HINT_RANGE, "0.01,600.0,0.01,or_greater,suffix:s"), "set_lifetime", "get_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "one_shot"), "set_one_shot", "get_one_shot");
@@ -646,10 +648,6 @@ void GPUParticles2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "trail_lifetime", PROPERTY_HINT_RANGE, "0.01,10,0.01,or_greater,suffix:s"), "set_trail_lifetime", "get_trail_lifetime");
ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_sections", PROPERTY_HINT_RANGE, "2,128,1"), "set_trail_sections", "get_trail_sections");
ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_section_subdivisions", PROPERTY_HINT_RANGE, "1,1024,1"), "set_trail_section_subdivisions", "get_trail_section_subdivisions");
- ADD_GROUP("Process Material", "process_");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "process_material", PROPERTY_HINT_RESOURCE_TYPE, "ShaderMaterial,ParticleProcessMaterial"), "set_process_material", "get_process_material");
- ADD_GROUP("Textures", "");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
BIND_ENUM_CONSTANT(DRAW_ORDER_INDEX);
BIND_ENUM_CONSTANT(DRAW_ORDER_LIFETIME);
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index 1a62c9bb6c..904b6564bd 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -197,9 +197,9 @@ NavigationAgent2D::~NavigationAgent2D() {
void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) {
avoidance_enabled = p_enabled;
if (avoidance_enabled) {
- NavigationServer2D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ NavigationServer2D::get_singleton()->agent_set_callback(agent, get_instance_id(), "_avoidance_done");
} else {
- NavigationServer2D::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ NavigationServer2D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
}
}
@@ -209,7 +209,7 @@ bool NavigationAgent2D::get_avoidance_enabled() const {
void NavigationAgent2D::set_agent_parent(Node *p_agent_parent) {
// remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map
- NavigationServer2D::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ NavigationServer2D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
if (Object::cast_to<Node2D>(p_agent_parent) != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
agent_parent = Object::cast_to<Node2D>(p_agent_parent);
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 8b27dbe3db..3ae7a0b34d 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -358,7 +358,7 @@ TileMap::TerrainConstraint::TerrainConstraint(const TileMap *p_tile_map, const V
terrain = p_terrain;
}
-Vector2i TileMap::transform_coords_layout(Vector2i p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout) {
+Vector2i TileMap::transform_coords_layout(const Vector2i &p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout) {
// Transform to stacked layout.
Vector2i output = p_coords;
if (p_offset_axis == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
@@ -755,6 +755,7 @@ void TileMap::set_y_sort_enabled(bool p_enable) {
_clear_internals();
_recreate_internals();
emit_signal(SNAME("changed"));
+ update_configuration_warnings();
}
Vector2i TileMap::_coords_to_quadrant_coords(int p_layer, const Vector2i &p_coords) const {
@@ -1342,7 +1343,7 @@ void TileMap::_rendering_draw_quadrant_debug(TileMapQuadrant *p_quadrant) {
}
}
-void TileMap::draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override) {
+void TileMap::draw_tile(RID p_canvas_item, const Vector2i &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame, Color p_modulation, const TileData *p_tile_data_override) {
ERR_FAIL_COND(!p_tile_set.is_valid());
ERR_FAIL_COND(!p_tile_set->has_source(p_atlas_source_id));
ERR_FAIL_COND(!p_tile_set->get_source(p_atlas_source_id)->has_tile(p_atlas_coords));
@@ -2186,7 +2187,7 @@ Ref<TileMapPattern> TileMap::get_pattern(int p_layer, TypedArray<Vector2i> p_coo
return output;
}
-Vector2i TileMap::map_pattern(Vector2i p_position_in_tilemap, Vector2i p_coords_in_pattern, Ref<TileMapPattern> p_pattern) {
+Vector2i TileMap::map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern) {
ERR_FAIL_COND_V(p_pattern.is_null(), Vector2i());
ERR_FAIL_COND_V(!p_pattern->has_cell(p_coords_in_pattern), Vector2i());
@@ -2210,7 +2211,7 @@ Vector2i TileMap::map_pattern(Vector2i p_position_in_tilemap, Vector2i p_coords_
return output;
}
-void TileMap::set_pattern(int p_layer, Vector2i p_position, const Ref<TileMapPattern> p_pattern) {
+void TileMap::set_pattern(int p_layer, const Vector2i &p_position, const Ref<TileMapPattern> p_pattern) {
ERR_FAIL_INDEX(p_layer, (int)layers.size());
ERR_FAIL_COND(!tile_set.is_valid());
@@ -2221,7 +2222,7 @@ void TileMap::set_pattern(int p_layer, Vector2i p_position, const Ref<TileMapPat
}
}
-TileSet::TerrainsPattern TileMap::_get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, RBSet<TerrainConstraint> p_constraints, TileSet::TerrainsPattern p_current_pattern) {
+TileSet::TerrainsPattern TileMap::_get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, TileSet::TerrainsPattern p_current_pattern) {
if (!tile_set.is_valid()) {
return TileSet::TerrainsPattern();
}
@@ -2234,7 +2235,7 @@ TileSet::TerrainsPattern TileMap::_get_best_terrain_pattern_for_constraints(int
// Check the center bit constraint
TerrainConstraint terrain_constraint = TerrainConstraint(this, p_position, terrain_pattern.get_terrain());
- RBSet<TerrainConstraint>::Element *in_set_constraint_element = p_constraints.find(terrain_constraint);
+ const RBSet<TerrainConstraint>::Element *in_set_constraint_element = p_constraints.find(terrain_constraint);
if (in_set_constraint_element) {
if (in_set_constraint_element->get().get_terrain() != terrain_constraint.get_terrain()) {
score += in_set_constraint_element->get().get_priority();
@@ -2281,7 +2282,7 @@ TileSet::TerrainsPattern TileMap::_get_best_terrain_pattern_for_constraints(int
return min_score_pattern;
}
-RBSet<TileMap::TerrainConstraint> TileMap::_get_terrain_constraints_from_added_pattern(Vector2i p_position, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern) const {
+RBSet<TileMap::TerrainConstraint> TileMap::_get_terrain_constraints_from_added_pattern(const Vector2i &p_position, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern) const {
if (!tile_set.is_valid()) {
return RBSet<TerrainConstraint>();
}
@@ -2389,7 +2390,7 @@ RBSet<TileMap::TerrainConstraint> TileMap::_get_terrain_constraints_from_painted
return constraints;
}
-HashMap<Vector2i, TileSet::TerrainsPattern> TileMap::terrain_fill_constraints(int p_layer, const Vector<Vector2i> &p_to_replace, int p_terrain_set, const RBSet<TerrainConstraint> p_constraints) {
+HashMap<Vector2i, TileSet::TerrainsPattern> TileMap::terrain_fill_constraints(int p_layer, const Vector<Vector2i> &p_to_replace, int p_terrain_set, const RBSet<TerrainConstraint> &p_constraints) {
if (!tile_set.is_valid()) {
return HashMap<Vector2i, TileSet::TerrainsPattern>();
}
@@ -3841,7 +3842,7 @@ void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
}
}
-TypedArray<Vector2i> TileMap::get_surrounding_cells(Vector2i coords) {
+TypedArray<Vector2i> TileMap::get_surrounding_cells(const Vector2i &coords) {
if (!tile_set.is_valid()) {
return TypedArray<Vector2i>();
}
@@ -3879,7 +3880,7 @@ TypedArray<Vector2i> TileMap::get_surrounding_cells(Vector2i coords) {
return around;
}
-void TileMap::draw_cells_outline(Control *p_control, RBSet<Vector2i> p_cells, Color p_color, Transform2D p_transform) {
+void TileMap::draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_cells, Color p_color, Transform2D p_transform) {
if (!tile_set.is_valid()) {
return;
}
@@ -3958,6 +3959,22 @@ PackedStringArray TileMap::get_configuration_warnings() const {
}
}
+ if (tile_set.is_valid() && tile_set->get_tile_shape() == TileSet::TILE_SHAPE_ISOMETRIC) {
+ bool warn = !is_y_sort_enabled();
+ if (!warn) {
+ for (int layer = 0; layer < (int)layers.size(); layer++) {
+ if (!layers[layer].y_sort_enabled) {
+ warn = true;
+ break;
+ }
+ }
+ }
+
+ if (warn) {
+ warnings.push_back(RTR("Isometric TileSet will likely not look as intended without Y-sort enabled for the TileMap and all of its layers."));
+ }
+ }
+
return warnings;
}
@@ -4054,6 +4071,7 @@ void TileMap::_tile_set_changed() {
_tile_set_changed_deferred_update_needed = true;
instantiated_scenes.clear();
call_deferred(SNAME("_tile_set_changed_deferred_update"));
+ update_configuration_warnings();
}
void TileMap::_tile_set_changed_deferred_update() {
@@ -4072,5 +4090,9 @@ TileMap::TileMap() {
}
TileMap::~TileMap() {
+ if (tile_set.is_valid()) {
+ tile_set->disconnect("changed", callable_mp(this, &TileMap::_tile_set_changed));
+ }
+
_clear_internals();
}
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 19f0e5a553..6f71636e47 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -155,7 +155,7 @@ public:
priority = p_priority;
}
- int get_priority() {
+ int get_priority() const {
return priority;
}
@@ -268,8 +268,8 @@ private:
void _scenes_draw_quadrant_debug(TileMapQuadrant *p_quadrant);
// Terrains.
- TileSet::TerrainsPattern _get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, RBSet<TerrainConstraint> p_constraints, TileSet::TerrainsPattern p_current_pattern);
- RBSet<TerrainConstraint> _get_terrain_constraints_from_added_pattern(Vector2i p_position, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern) const;
+ TileSet::TerrainsPattern _get_best_terrain_pattern_for_constraints(int p_terrain_set, const Vector2i &p_position, const RBSet<TerrainConstraint> &p_constraints, TileSet::TerrainsPattern p_current_pattern);
+ RBSet<TerrainConstraint> _get_terrain_constraints_from_added_pattern(const Vector2i &p_position, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern) const;
RBSet<TerrainConstraint> _get_terrain_constraints_from_painted_cells_list(int p_layer, const RBSet<Vector2i> &p_painted, int p_terrain_set, bool p_ignore_empty_terrains) const;
// Set and get tiles from data arrays.
@@ -291,7 +291,7 @@ protected:
static void _bind_methods();
public:
- static Vector2i transform_coords_layout(Vector2i p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout);
+ static Vector2i transform_coords_layout(const Vector2i &p_coords, TileSet::TileOffsetAxis p_offset_axis, TileSet::TileLayout p_from_layout, TileSet::TileLayout p_to_layout);
enum {
INVALID_CELL = -1
@@ -307,7 +307,7 @@ public:
void set_quadrant_size(int p_size);
int get_quadrant_size() const;
- static void draw_tile(RID p_canvas_item, Vector2i p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, Vector2i p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr);
+ static void draw_tile(RID p_canvas_item, const Vector2i &p_position, const Ref<TileSet> p_tile_set, int p_atlas_source_id, const Vector2i &p_atlas_coords, int p_alternative_tile, int p_frame = -1, Color p_modulation = Color(1.0, 1.0, 1.0, 1.0), const TileData *p_tile_data_override = nullptr);
// Layers management.
int get_layers_count() const;
@@ -350,11 +350,11 @@ public:
// Patterns.
Ref<TileMapPattern> get_pattern(int p_layer, TypedArray<Vector2i> p_coords_array);
- Vector2i map_pattern(Vector2i p_position_in_tilemap, Vector2i p_coords_in_pattern, Ref<TileMapPattern> p_pattern);
- void set_pattern(int p_layer, Vector2i p_position, const Ref<TileMapPattern> p_pattern);
+ Vector2i map_pattern(const Vector2i &p_position_in_tilemap, const Vector2i &p_coords_in_pattern, Ref<TileMapPattern> p_pattern);
+ void set_pattern(int p_layer, const Vector2i &p_position, const Ref<TileMapPattern> p_pattern);
// Terrains.
- HashMap<Vector2i, TileSet::TerrainsPattern> terrain_fill_constraints(int p_layer, const Vector<Vector2i> &p_to_replace, int p_terrain_set, const RBSet<TerrainConstraint> p_constraints); // Not exposed.
+ HashMap<Vector2i, TileSet::TerrainsPattern> terrain_fill_constraints(int p_layer, const Vector<Vector2i> &p_to_replace, int p_terrain_set, const RBSet<TerrainConstraint> &p_constraints); // Not exposed.
HashMap<Vector2i, TileSet::TerrainsPattern> terrain_fill_connect(int p_layer, const Vector<Vector2i> &p_coords_array, int p_terrain_set, int p_terrain, bool p_ignore_empty_terrains = true); // Not exposed.
HashMap<Vector2i, TileSet::TerrainsPattern> terrain_fill_path(int p_layer, const Vector<Vector2i> &p_coords_array, int p_terrain_set, int p_terrain, bool p_ignore_empty_terrains = true); // Not exposed.
HashMap<Vector2i, TileSet::TerrainsPattern> terrain_fill_pattern(int p_layer, const Vector<Vector2i> &p_coords_array, int p_terrain_set, TileSet::TerrainsPattern p_terrains_pattern, bool p_ignore_empty_terrains = true); // Not exposed.
@@ -400,8 +400,8 @@ public:
void force_update(int p_layer = -1);
// Helpers?
- TypedArray<Vector2i> get_surrounding_cells(Vector2i coords);
- void draw_cells_outline(Control *p_control, RBSet<Vector2i> p_cells, Color p_color, Transform2D p_transform = Transform2D());
+ TypedArray<Vector2i> get_surrounding_cells(const Vector2i &coords);
+ void draw_cells_outline(Control *p_control, const RBSet<Vector2i> &p_cells, Color p_color, Transform2D p_transform = Transform2D());
// Virtual function to modify the TileData at runtime
GDVIRTUAL2R(bool, _use_tile_data_runtime_update, int, Vector2i);
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index 88b1c340d8..10f3ab5c79 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -52,11 +52,22 @@ bool MeshInstance3D::_set(const StringName &p_name, const Variant &p_value) {
if (p_name.operator String().begins_with("surface_material_override/")) {
int idx = p_name.operator String().get_slicec('/', 1).to_int();
- if (idx >= surface_override_materials.size() || idx < 0) {
+
+ // This is a bit of a hack to ensure compatibility with older material
+ // overrides that start indexing at 0.
+ // We assume that idx 0 is always read first, if its not, this won't work.
+ if (idx == 0) {
+ old_surface_index = true;
+ }
+ if (old_surface_index) {
+ idx++;
+ }
+
+ if (idx > surface_override_materials.size() || idx < 0) {
return false;
}
- set_surface_override_material(idx, p_value);
+ set_surface_override_material(idx - 1, p_value);
return true;
}
@@ -75,7 +86,7 @@ bool MeshInstance3D::_get(const StringName &p_name, Variant &r_ret) const {
}
if (p_name.operator String().begins_with("surface_material_override/")) {
- int idx = p_name.operator String().get_slicec('/', 1).to_int();
+ int idx = p_name.operator String().get_slicec('/', 1).to_int() - 1;
if (idx >= surface_override_materials.size() || idx < 0) {
return false;
}
@@ -98,7 +109,7 @@ void MeshInstance3D::_get_property_list(List<PropertyInfo> *p_list) const {
}
if (mesh.is_valid()) {
- for (int i = 0; i < mesh->get_surface_count(); i++) {
+ for (int i = 1; i <= mesh->get_surface_count(); i++) {
p_list->push_back(PropertyInfo(Variant::OBJECT, vformat("%s/%d", PNAME("surface_material_override"), i), PROPERTY_HINT_RESOURCE_TYPE, "BaseMaterial3D,ShaderMaterial", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_DEFERRED_SET_RESOURCE));
}
}
diff --git a/scene/3d/mesh_instance_3d.h b/scene/3d/mesh_instance_3d.h
index caf7d25616..9e6dbaf160 100644
--- a/scene/3d/mesh_instance_3d.h
+++ b/scene/3d/mesh_instance_3d.h
@@ -57,6 +57,7 @@ protected:
bool _set(const StringName &p_name, const Variant &p_value);
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
+ bool old_surface_index = false;
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 36350d251e..e907b9f66f 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -204,9 +204,9 @@ NavigationAgent3D::~NavigationAgent3D() {
void NavigationAgent3D::set_avoidance_enabled(bool p_enabled) {
avoidance_enabled = p_enabled;
if (avoidance_enabled) {
- NavigationServer3D::get_singleton()->agent_set_callback(agent, this, "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, get_instance_id(), "_avoidance_done");
} else {
- NavigationServer3D::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
}
}
@@ -216,7 +216,7 @@ bool NavigationAgent3D::get_avoidance_enabled() const {
void NavigationAgent3D::set_agent_parent(Node *p_agent_parent) {
// remove agent from any avoidance map before changing parent or there will be leftovers on the RVO map
- NavigationServer3D::get_singleton()->agent_set_callback(agent, nullptr, "_avoidance_done");
+ NavigationServer3D::get_singleton()->agent_set_callback(agent, ObjectID(), "_avoidance_done");
if (Object::cast_to<Node3D>(p_agent_parent) != nullptr) {
// place agent on navigation map first or else the RVO agent callback creation fails silently later
agent_parent = Object::cast_to<Node3D>(p_agent_parent);
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index fbc85bd5e1..b06a21dea9 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1759,7 +1759,7 @@ void AnimationTree::_setup_animation_player() {
AnimationPlayer *new_player = nullptr;
if (!animation_player.is_empty()) {
- new_player = Object::cast_to<AnimationPlayer>(get_node(animation_player));
+ new_player = Object::cast_to<AnimationPlayer>(get_node_or_null(animation_player));
if (new_player && !new_player->is_connected("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed))) {
new_player->connect("animation_list_changed", callable_mp(this, &AnimationTree::_animation_player_changed));
}
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 50ffc0509c..68af7af5d4 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -1563,6 +1563,12 @@ void Control::set_custom_minimum_size(const Size2 &p_custom) {
if (p_custom == data.custom_minimum_size) {
return;
}
+
+ if (isnan(p_custom.x) || isnan(p_custom.y)) {
+ // Prevent infinite loop.
+ return;
+ }
+
data.custom_minimum_size = p_custom;
update_minimum_size();
}
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 82f089735d..c44feddd38 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -1550,6 +1550,7 @@ bool ItemList::get_allow_reselect() const {
}
void ItemList::set_icon_scale(real_t p_scale) {
+ ERR_FAIL_COND(!Math::is_finite(p_scale));
icon_scale = p_scale;
}
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index f26e05518e..d9f76a6fa6 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -150,7 +150,12 @@ RichTextLabel::Item *RichTextLabel::_get_item_at_pos(RichTextLabel::Item *p_item
return it;
}
} break;
- case ITEM_IMAGE:
+ case ITEM_IMAGE: {
+ offset += 1;
+ if (offset > p_position) {
+ return it;
+ }
+ } break;
case ITEM_TABLE: {
offset += 1;
} break;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index a96d85dffa..6d9e8a90c2 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -680,7 +680,7 @@ void TextEdit::_notification(int p_what) {
}
}
- bool draw_placeholder = text.size() == 1 && text[0].length() == 0;
+ bool draw_placeholder = text.size() == 1 && text[0].is_empty() && ime_text.is_empty();
// Get the highlighted words.
String highlighted_text = get_selected_text(0);
diff --git a/scene/main/multiplayer_peer.h b/scene/main/multiplayer_peer.h
index 4b5909538e..fa6b11e5db 100644
--- a/scene/main/multiplayer_peer.h
+++ b/scene/main/multiplayer_peer.h
@@ -112,11 +112,11 @@ protected:
public:
/* PacketPeer extension */
virtual Error get_packet(const uint8_t **r_buffer, int &r_buffer_size) override; ///< buffer is GONE after next get_packet
- GDVIRTUAL2R(Error, _get_packet, GDNativeConstPtr<const uint8_t *>, GDNativePtr<int>);
+ GDVIRTUAL2R(Error, _get_packet, GDExtensionConstPtr<const uint8_t *>, GDExtensionPtr<int>);
GDVIRTUAL0R(PackedByteArray, _get_packet_script); // For GDScript.
virtual Error put_packet(const uint8_t *p_buffer, int p_buffer_size) override;
- GDVIRTUAL2R(Error, _put_packet, GDNativeConstPtr<const uint8_t>, int);
+ GDVIRTUAL2R(Error, _put_packet, GDExtensionConstPtr<const uint8_t>, int);
GDVIRTUAL1R(Error, _put_packet_script, PackedByteArray); // For GDScript.
EXBIND0RC(int, get_available_packet_count);
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 58147b159a..043895b591 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -31,7 +31,7 @@
#include "register_scene_types.h"
#include "core/config/project_settings.h"
-#include "core/extension/native_extension_manager.h"
+#include "core/extension/gdextension_manager.h"
#include "core/object/class_db.h"
#include "core/os/os.h"
#include "scene/2d/animated_sprite_2d.h"
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index bc2149a8c6..b0a63bb7fa 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -790,6 +790,19 @@ void Curve2D::_bake_segment2d_even_length(RBMap<real_t, Vector2> &r_bake, real_t
}
}
+Vector2 Curve2D::_calculate_tangent(const Vector2 &p_begin, const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t) {
+ // Handle corner cases.
+ if (Math::is_zero_approx(p_t - 0.0f) && p_control_1.is_equal_approx(p_begin)) {
+ return (p_end - p_begin).normalized();
+ }
+
+ if (Math::is_zero_approx(p_t - 1.0f) && p_control_2.is_equal_approx(p_end)) {
+ return (p_end - p_begin).normalized();
+ }
+
+ return p_begin.bezier_derivative(p_control_1, p_control_2, p_end, p_t).normalized();
+}
+
void Curve2D::_bake() const {
if (!baked_cache_dirty) {
return;
@@ -835,19 +848,19 @@ void Curve2D::_bake() const {
// Collect positions and sample tilts and tangents for each baked points.
bpw[0] = points[0].position;
- bfw[0] = points[0].position.bezier_derivative(points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0).normalized();
+ bfw[0] = _calculate_tangent(points[0].position, points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0);
int pidx = 0;
for (int i = 0; i < points.size() - 1; i++) {
for (const KeyValue<real_t, Vector2> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
- bfw[pidx] = points[i].position.bezier_derivative(points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, E.key).normalized();
+ bfw[pidx] = _calculate_tangent(points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, E.key);
}
pidx++;
bpw[pidx] = points[i + 1].position;
- bfw[pidx] = points[i].position.bezier_derivative(points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, 1.0).normalized();
+ bfw[pidx] = _calculate_tangent(points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, 1.0);
}
// Recalculate the baked distances.
@@ -1031,10 +1044,11 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const {
real_t nearest_dist = -1.0f;
for (int i = 0; i < pc - 1; i++) {
+ const real_t interval = baked_dist_cache[i + 1] - baked_dist_cache[i];
Vector2 origin = r[i];
- Vector2 direction = (r[i + 1] - origin) / bake_interval;
+ Vector2 direction = (r[i + 1] - origin) / interval;
- real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, interval);
Vector2 proj = origin + direction * d;
real_t dist = proj.distance_squared_to(p_to_point);
@@ -1070,10 +1084,13 @@ real_t Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
real_t offset = 0.0f;
for (int i = 0; i < pc - 1; i++) {
+ offset = baked_dist_cache[i];
+
+ const real_t interval = baked_dist_cache[i + 1] - baked_dist_cache[i];
Vector2 origin = r[i];
- Vector2 direction = (r[i + 1] - origin) / bake_interval;
+ Vector2 direction = (r[i + 1] - origin) / interval;
- real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, bake_interval);
+ real_t d = CLAMP((p_to_point - origin).dot(direction), 0.0f, interval);
Vector2 proj = origin + direction * d;
real_t dist = proj.distance_squared_to(p_to_point);
@@ -1082,8 +1099,6 @@ real_t Curve2D::get_closest_offset(const Vector2 &p_to_point) const {
nearest = offset + d;
nearest_dist = dist;
}
-
- offset += bake_interval;
}
return nearest;
@@ -1480,6 +1495,19 @@ void Curve3D::_bake_segment3d_even_length(RBMap<real_t, Vector3> &r_bake, real_t
}
}
+Vector3 Curve3D::_calculate_tangent(const Vector3 &p_begin, const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t) {
+ // Handle corner cases.
+ if (Math::is_zero_approx(p_t - 0.0f) && p_control_1.is_equal_approx(p_begin)) {
+ return (p_end - p_begin).normalized();
+ }
+
+ if (Math::is_zero_approx(p_t - 1.0f) && p_control_2.is_equal_approx(p_end)) {
+ return (p_end - p_begin).normalized();
+ }
+
+ return p_begin.bezier_derivative(p_control_1, p_control_2, p_end, p_t).normalized();
+}
+
void Curve3D::_bake() const {
if (!baked_cache_dirty) {
return;
@@ -1539,7 +1567,7 @@ void Curve3D::_bake() const {
// Collect positions and sample tilts and tangents for each baked points.
bpw[0] = points[0].position;
- bfw[0] = points[0].position.bezier_derivative(points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0).normalized();
+ bfw[0] = _calculate_tangent(points[0].position, points[0].position + points[0].out, points[1].position + points[1].in, points[1].position, 0.0);
btw[0] = points[0].tilt;
int pidx = 0;
@@ -1547,13 +1575,13 @@ void Curve3D::_bake() const {
for (const KeyValue<real_t, Vector3> &E : midpoints[i]) {
pidx++;
bpw[pidx] = E.value;
- bfw[pidx] = points[i].position.bezier_derivative(points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, E.key).normalized();
+ bfw[pidx] = _calculate_tangent(points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, E.key);
btw[pidx] = Math::lerp(points[i].tilt, points[i + 1].tilt, E.key);
}
pidx++;
bpw[pidx] = points[i + 1].position;
- bfw[pidx] = points[i].position.bezier_derivative(points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, 1.0).normalized();
+ bfw[pidx] = _calculate_tangent(points[i].position, points[i].position + points[i].out, points[i + 1].position + points[i + 1].in, points[i + 1].position, 1.0);
btw[pidx] = points[i + 1].tilt;
}
diff --git a/scene/resources/curve.h b/scene/resources/curve.h
index ea3ceabb14..26608c47cd 100644
--- a/scene/resources/curve.h
+++ b/scene/resources/curve.h
@@ -178,6 +178,7 @@ class Curve2D : public Resource {
void mark_dirty();
+ static Vector2 _calculate_tangent(const Vector2 &p_begin, const Vector2 &p_control_1, const Vector2 &p_control_2, const Vector2 &p_end, const real_t p_t);
void _bake() const;
real_t bake_interval = 5.0;
@@ -261,6 +262,7 @@ class Curve3D : public Resource {
void mark_dirty();
+ static Vector3 _calculate_tangent(const Vector3 &p_begin, const Vector3 &p_control_1, const Vector3 &p_control_2, const Vector3 &p_end, const real_t p_t);
void _bake() const;
struct Interval {
diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp
index 36e4a8ea37..092f672cba 100644
--- a/scene/resources/resource_format_text.cpp
+++ b/scene/resources/resource_format_text.cpp
@@ -836,7 +836,8 @@ void ResourceLoaderText::set_translation_remapped(bool p_remapped) {
translation_remapped = p_remapped;
}
-ResourceLoaderText::ResourceLoaderText() {}
+ResourceLoaderText::ResourceLoaderText() :
+ stream(false) {}
void ResourceLoaderText::get_dependencies(Ref<FileAccess> p_f, List<String> *p_dependencies, bool p_add_types) {
open(p_f);
@@ -981,15 +982,26 @@ Error ResourceLoaderText::rename_dependencies(Ref<FileAccess> p_f, const String
f->seek(tag_end);
- uint8_t c = f->get_8();
- if (c == '\n' && !f->eof_reached()) {
- // Skip first newline character since we added one
- c = f->get_8();
+ const uint32_t buffer_size = 2048;
+ uint8_t *buffer = (uint8_t *)alloca(buffer_size);
+ uint32_t num_read;
+
+ num_read = f->get_buffer(buffer, buffer_size);
+ ERR_FAIL_COND_V_MSG(num_read == UINT32_MAX, ERR_CANT_CREATE, "Failed to allocate memory for buffer.");
+ ERR_FAIL_COND_V(num_read == 0, ERR_FILE_CORRUPT);
+
+ if (*buffer == '\n') {
+ // Skip first newline character since we added one.
+ if (num_read > 1) {
+ fw->store_buffer(buffer + 1, num_read - 1);
+ }
+ } else {
+ fw->store_buffer(buffer, num_read);
}
while (!f->eof_reached()) {
- fw->store_8(c);
- c = f->get_8();
+ num_read = f->get_buffer(buffer, buffer_size);
+ fw->store_buffer(buffer, num_read);
}
bool all_ok = fw->get_error() == OK;