summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/tile_map.cpp83
-rw-r--r--scene/3d/mesh_instance_3d.cpp3
-rw-r--r--scene/3d/skeleton_ik_3d.cpp2
-rw-r--r--scene/animation/tween.cpp35
-rw-r--r--scene/animation/tween.h6
-rw-r--r--scene/gui/code_edit.cpp30
-rw-r--r--scene/gui/code_edit.h2
-rw-r--r--scene/gui/text_edit.cpp15
-rw-r--r--scene/gui/text_edit.h3
-rw-r--r--scene/gui/tree.cpp11
-rw-r--r--scene/main/scene_tree.cpp4
-rw-r--r--scene/main/viewport.cpp11
-rw-r--r--scene/main/viewport.h2
-rw-r--r--scene/resources/mesh.cpp8
-rw-r--r--scene/resources/mesh.h35
-rw-r--r--scene/resources/texture.cpp24
-rw-r--r--scene/resources/texture.h2
-rw-r--r--scene/resources/tile_set.cpp36
-rw-r--r--scene/resources/tile_set.h2
19 files changed, 185 insertions, 129 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 0eb424b32c..e899b9a8ef 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -2857,50 +2857,57 @@ void TileMap::draw_cells_outline(Control *p_control, Set<Vector2i> p_cells, Colo
// Create a set.
Vector2i tile_size = tile_set->get_tile_size();
- Vector<Vector2> uvs;
+ Vector<Vector2> polygon = tile_set->get_tile_shape_polygon();
+ TileSet::TileShape shape = tile_set->get_tile_shape();
- if (tile_set->get_tile_shape() == TileSet::TILE_SHAPE_SQUARE) {
- uvs.append(Vector2(1.0, 0.0));
- uvs.append(Vector2(1.0, 1.0));
- uvs.append(Vector2(0.0, 1.0));
- uvs.append(Vector2(0.0, 0.0));
- } else {
- float overlap = 0.0;
- switch (tile_set->get_tile_shape()) {
- case TileSet::TILE_SHAPE_ISOMETRIC:
- overlap = 0.5;
- break;
- case TileSet::TILE_SHAPE_HEXAGON:
- overlap = 0.25;
- break;
- case TileSet::TILE_SHAPE_HALF_OFFSET_SQUARE:
- overlap = 0.0;
- break;
- default:
- break;
- }
- uvs.append(Vector2(1.0, overlap));
- uvs.append(Vector2(1.0, 1.0 - overlap));
- uvs.append(Vector2(0.5, 1.0));
- uvs.append(Vector2(0.0, 1.0 - overlap));
- uvs.append(Vector2(0.0, overlap));
- uvs.append(Vector2(0.5, 0.0));
- if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
- for (int i = 0; i < uvs.size(); i++) {
- uvs.write[i] = Vector2(uvs[i].y, uvs[i].x);
- }
- }
+ for (Set<Vector2i>::Element *E = p_cells.front(); E; E = E->next()) {
+ Vector2 center = map_to_world(E->get());
+
+#define DRAW_SIDE_IF_NEEDED(side, polygon_index_from, polygon_index_to) \
+ if (!p_cells.has(get_neighbor_cell(E->get(), side))) { \
+ Vector2 from = p_transform.xform(center + polygon[polygon_index_from] * tile_size); \
+ Vector2 to = p_transform.xform(center + polygon[polygon_index_to] * tile_size); \
+ p_control->draw_line(from, to, p_color); \
}
- for (Set<Vector2i>::Element *E = p_cells.front(); E; E = E->next()) {
- Vector2 top_left = map_to_world(E->get()) - tile_size / 2;
- TypedArray<Vector2i> surrounding_tiles = get_surrounding_tiles(E->get());
- for (int i = 0; i < surrounding_tiles.size(); i++) {
- if (!p_cells.has(surrounding_tiles[i])) {
- p_control->draw_line(p_transform.xform(top_left + uvs[i] * tile_size), p_transform.xform(top_left + uvs[(i + 1) % uvs.size()] * tile_size), p_color);
+ if (shape == TileSet::TILE_SHAPE_SQUARE) {
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_RIGHT_SIDE, 1, 2);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE, 2, 3);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_LEFT_SIDE, 3, 0);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_SIDE, 0, 1);
+ } else {
+ if (tile_set->get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_HORIZONTAL) {
+ if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 2, 3);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 5, 0);
+ } else {
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 2, 3);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_LEFT_SIDE, 1, 2);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 5, 0);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_RIGHT_SIDE, 4, 5);
+ }
+ } else {
+ if (shape == TileSet::TILE_SHAPE_ISOMETRIC) {
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 5, 0);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 2, 3);
+ } else {
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_RIGHT_SIDE, 3, 4);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_SIDE, 4, 5);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_BOTTOM_LEFT_SIDE, 5, 0);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_LEFT_SIDE, 0, 1);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_SIDE, 1, 2);
+ DRAW_SIDE_IF_NEEDED(TileSet::CELL_NEIGHBOR_TOP_RIGHT_SIDE, 2, 3);
+ }
}
}
}
+#undef DRAW_SIDE_IF_NEEDED
}
TypedArray<String> TileMap::get_configuration_warnings() const {
diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp
index de6925244a..7e7db57af3 100644
--- a/scene/3d/mesh_instance_3d.cpp
+++ b/scene/3d/mesh_instance_3d.cpp
@@ -274,7 +274,8 @@ Node *MeshInstance3D::create_multiple_convex_collisions_node() {
return nullptr;
}
- Vector<Ref<Shape3D>> shapes = mesh->convex_decompose();
+ Mesh::ConvexDecompositionSettings settings;
+ Vector<Ref<Shape3D>> shapes = mesh->convex_decompose(settings);
if (!shapes.size()) {
return nullptr;
}
diff --git a/scene/3d/skeleton_ik_3d.cpp b/scene/3d/skeleton_ik_3d.cpp
index a891566633..466f67afb8 100644
--- a/scene/3d/skeleton_ik_3d.cpp
+++ b/scene/3d/skeleton_ik_3d.cpp
@@ -542,7 +542,7 @@ Transform3D SkeletonIK3D::_get_target_transform() {
target_node_override = Object::cast_to<Node3D>(get_node(target_node_path_override));
}
- if (target_node_override) {
+ if (target_node_override && target_node_override->is_inside_tree()) {
return target_node_override->get_global_transform();
} else {
return target;
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 542011618d..3018fd3ae6 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -36,6 +36,10 @@ void Tweener::set_tween(Ref<Tween> p_tween) {
tween = p_tween;
}
+void Tweener::clear_tween() {
+ tween.unref();
+}
+
void Tweener::_bind_methods() {
ADD_SIGNAL(MethodInfo("finished"));
}
@@ -53,7 +57,7 @@ void Tween::start_tweeners() {
Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, float p_duration) {
ERR_FAIL_NULL_V(p_target, nullptr);
- ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+ ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration));
@@ -62,7 +66,7 @@ Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property
}
Ref<IntervalTweener> Tween::tween_interval(float p_time) {
- ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+ ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
Ref<IntervalTweener> tweener = memnew(IntervalTweener(p_time));
@@ -71,7 +75,7 @@ Ref<IntervalTweener> Tween::tween_interval(float p_time) {
}
Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
- ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+ ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
Ref<CallbackTweener> tweener = memnew(CallbackTweener(p_callback));
@@ -80,7 +84,7 @@ Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
}
Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float p_to, float p_duration) {
- ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
+ ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
Ref<MethodTweener> tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration));
@@ -88,9 +92,7 @@ Ref<MethodTweener> Tween::tween_method(Callable p_callback, float p_from, float
return tweener;
}
-Ref<Tween> Tween::append(Ref<Tweener> p_tweener) {
- ERR_FAIL_COND_V_MSG(invalid, nullptr, "Tween was created outside the scene tree, can't use Tweeners.");
- ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
+void Tween::append(Ref<Tweener> p_tweener) {
p_tweener->set_tween(this);
if (parallel_enabled) {
@@ -102,8 +104,6 @@ Ref<Tween> Tween::append(Ref<Tweener> p_tweener) {
tweeners.resize(current_step + 1);
tweeners.write[current_step].push_back(p_tweener);
-
- return this;
}
void Tween::stop() {
@@ -117,7 +117,7 @@ void Tween::pause() {
}
void Tween::play() {
- ERR_FAIL_COND_MSG(invalid, "Tween invalid, can't play.");
+ ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree.");
ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state.");
running = true;
}
@@ -132,11 +132,22 @@ bool Tween::is_running() {
}
void Tween::set_valid(bool p_valid) {
- invalid = !p_valid;
+ valid = p_valid;
}
bool Tween::is_valid() {
- return invalid;
+ return valid;
+}
+
+void Tween::clear() {
+ valid = false;
+
+ for (List<Ref<Tweener>> &step : tweeners) {
+ for (Ref<Tweener> &tweener : step) {
+ tweener->clear_tween();
+ }
+ }
+ tweeners.clear();
}
Ref<Tween> Tween::bind_node(Node *p_node) {
diff --git a/scene/animation/tween.h b/scene/animation/tween.h
index 947cdb7c2d..953d573539 100644
--- a/scene/animation/tween.h
+++ b/scene/animation/tween.h
@@ -43,6 +43,7 @@ public:
virtual void set_tween(Ref<Tween> p_tween);
virtual void start() = 0;
virtual bool step(float &r_delta) = 0;
+ void clear_tween();
protected:
static void _bind_methods();
@@ -111,7 +112,7 @@ private:
bool started = false;
bool running = true;
bool dead = false;
- bool invalid = true;
+ bool valid = false;
bool default_parallel = false;
bool parallel_enabled = false;
@@ -128,7 +129,7 @@ public:
Ref<IntervalTweener> tween_interval(float p_time);
Ref<CallbackTweener> tween_callback(Callable p_callback);
Ref<MethodTweener> tween_method(Callable p_callback, float p_from, float p_to, float p_duration);
- Ref<Tween> append(Ref<Tweener> p_tweener);
+ void append(Ref<Tweener> p_tweener);
bool custom_step(float p_delta);
void stop();
@@ -139,6 +140,7 @@ public:
bool is_running();
void set_valid(bool p_valid);
bool is_valid();
+ void clear();
Ref<Tween> bind_node(Node *p_node);
Ref<Tween> set_process_mode(TweenProcessMode p_mode);
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index d05762b6c0..3beff57027 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.cpp
@@ -654,7 +654,7 @@ void CodeEdit::_backspace_internal() {
// For space indentation we need to do a simple unindent if there are no chars to the left, acting in the
// same way as tabs.
if (indent_using_spaces && cc != 0) {
- if (get_first_non_whitespace_column(cl) > cc) {
+ if (get_first_non_whitespace_column(cl) >= cc) {
prev_column = cc - _calculate_spaces_till_next_left_indent(cc);
prev_line = cl;
}
@@ -987,10 +987,10 @@ void CodeEdit::_new_line(bool p_split_current_line, bool p_above) {
/* No need to move the brace below if we are not taking the text with us. */
if (p_split_current_line) {
brace_indent = true;
- ins += "\n" + ins.substr(1, ins.length() - 2);
+ ins += "\n" + ins.substr(indent_text.size(), ins.length() - 2);
} else {
brace_indent = false;
- ins = "\n" + ins.substr(1, ins.length() - 2);
+ ins = "\n" + ins.substr(indent_text.size(), ins.length() - 2);
}
}
}
@@ -1407,9 +1407,14 @@ void CodeEdit::fold_line(int p_line) {
int in_string = (in_comment == -1) ? is_in_string(p_line) : -1;
if (in_string != -1 || in_comment != -1) {
end_line = get_delimiter_end_position(p_line, get_line(p_line).size() - 1).y;
- /* End line is the same therefore we have a block. */
+ /* End line is the same therefore we have a block of single line delimiters. */
if (end_line == p_line) {
for (int i = p_line + 1; i <= line_count; i++) {
+ if (i == line_count) {
+ end_line = line_count;
+ break;
+ }
+
if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
end_line = i - 1;
break;
@@ -1617,7 +1622,8 @@ Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const {
}
/* Region was found on this line and is not a multiline continuation. */
- if (start_position.x != -1 && start_position.x != get_line(p_line).length() + 1) {
+ int line_length = get_line(p_line).length();
+ if (start_position.x != -1 && line_length > 0 && start_position.x != line_length + 1) {
start_position.y = p_line;
return start_position;
}
@@ -1636,7 +1642,8 @@ Point2 CodeEdit::get_delimiter_start_position(int p_line, int p_column) const {
start_position.x = delimiter_cache[i].back()->key();
/* Make sure it's not a multiline continuation. */
- if (start_position.x != get_line(i).length() + 1) {
+ line_length = get_line(i).length();
+ if (line_length > 0 && start_position.x != line_length + 1) {
break;
}
}
@@ -2562,7 +2569,10 @@ int CodeEdit::_is_in_delimiter(int p_line, int p_column, DelimiterType p_type) c
}
void CodeEdit::_add_delimiter(const String &p_start_key, const String &p_end_key, bool p_line_only, DelimiterType p_type) {
- if (p_start_key.length() > 0) {
+ // If we are the editor allow "null" as a valid start key, otherwise users cannot add delimiters via the inspector.
+ if (!(Engine::get_singleton()->is_editor_hint() && p_start_key == "null")) {
+ ERR_FAIL_COND_MSG(p_start_key.is_empty(), "delimiter start key cannot be empty");
+
for (int i = 0; i < p_start_key.length(); i++) {
ERR_FAIL_COND_MSG(!is_symbol(p_start_key[i]), "delimiter must start with a symbol");
}
@@ -2627,7 +2637,11 @@ void CodeEdit::_set_delimiters(const TypedArray<String> &p_delimiters, Delimiter
_clear_delimiters(p_type);
for (int i = 0; i < p_delimiters.size(); i++) {
- String key = p_delimiters[i].is_null() ? "" : p_delimiters[i];
+ String key = p_delimiters[i];
+
+ if (key.is_empty()) {
+ continue;
+ }
const String start_key = key.get_slice(" ", 0);
const String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String();
diff --git a/scene/gui/code_edit.h b/scene/gui/code_edit.h
index 4fbb5194e6..740548d559 100644
--- a/scene/gui/code_edit.h
+++ b/scene/gui/code_edit.h
@@ -248,7 +248,6 @@ private:
void _text_changed();
protected:
- void gui_input(const Ref<InputEvent> &p_gui_input) override;
void _notification(int p_what);
static void _bind_methods();
@@ -265,6 +264,7 @@ protected:
public:
/* General overrides */
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
virtual CursorShape get_cursor_shape(const Point2 &p_pos = Point2i()) const override;
/* Indent management */
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index f64c07df76..06dfc31621 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -2610,10 +2610,10 @@ void TextEdit::set_text(const String &p_text) {
set_caret_column(0);
begin_complex_operation();
+ deselect();
_remove_text(0, 0, MAX(0, get_line_count() - 1), MAX(get_line(MAX(get_line_count() - 1, 0)).size() - 1, 0));
insert_text_at_caret(p_text);
end_complex_operation();
- selection.active = false;
}
set_caret_line(0);
@@ -2731,6 +2731,8 @@ void TextEdit::insert_line_at(int p_at, const String &p_text) {
}
void TextEdit::insert_text_at_caret(const String &p_text) {
+ begin_complex_operation();
+
delete_selection();
int new_column, new_line;
@@ -2740,6 +2742,8 @@ void TextEdit::insert_text_at_caret(const String &p_text) {
set_caret_line(new_line, false);
set_caret_column(new_column);
update();
+
+ end_complex_operation();
}
void TextEdit::remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column) {
@@ -3024,13 +3028,20 @@ void TextEdit::menu_option(int p_option) {
/* Versioning */
void TextEdit::begin_complex_operation() {
_push_current_op();
- next_operation_is_complex = true;
+ if (complex_operation_count == 0) {
+ next_operation_is_complex = true;
+ }
+ complex_operation_count++;
}
void TextEdit::end_complex_operation() {
_push_current_op();
ERR_FAIL_COND(undo_stack.size() == 0);
+ complex_operation_count = MAX(complex_operation_count - 1, 0);
+ if (complex_operation_count > 0) {
+ return;
+ }
if (undo_stack.back()->get().chain_forward) {
undo_stack.back()->get().chain_forward = false;
return;
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index e996bba983..b1226f2aff 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -304,6 +304,7 @@ private:
bool undo_enabled = true;
int undo_stack_max_size = 50;
+ int complex_operation_count = 0;
bool next_operation_is_complex = false;
TextOperation current_op;
@@ -545,7 +546,6 @@ private:
protected:
void _notification(int p_what);
- virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
static void _bind_methods();
@@ -594,6 +594,7 @@ protected:
public:
/* General overrides. */
+ virtual void gui_input(const Ref<InputEvent> &p_gui_input) override;
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;
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index cb990892ed..c4dfbc0d4e 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2339,13 +2339,22 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, int
cache.click_type = Cache::CLICK_NONE;
return -1;
}
+
+ // Make sure the click is correct.
+ Point2 click_pos = get_global_mouse_position() - get_global_position();
+ if (!get_item_at_position(click_pos)) {
+ pressed_button = -1;
+ cache.click_type = Cache::CLICK_NONE;
+ return -1;
+ }
+
pressed_button = j;
cache.click_type = Cache::CLICK_BUTTON;
cache.click_index = j;
cache.click_id = c.buttons[j].id;
cache.click_item = p_item;
cache.click_column = col;
- cache.click_pos = get_global_mouse_position() - get_global_position();
+ cache.click_pos = click_pos;
update();
//emit_signal(SNAME("button_pressed"));
return -1;
diff --git a/scene/main/scene_tree.cpp b/scene/main/scene_tree.cpp
index bef7ecb462..e1b1b356a9 100644
--- a/scene/main/scene_tree.cpp
+++ b/scene/main/scene_tree.cpp
@@ -544,7 +544,7 @@ void SceneTree::process_tweens(float p_delta, bool p_physics) {
}
if (!E->get()->step(p_delta)) {
- E->get()->set_valid(false);
+ E->get()->clear();
tweens.erase(E);
}
if (E == L) {
@@ -1337,7 +1337,7 @@ SceneTree::SceneTree() {
current_scene = nullptr;
const int msaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/msaa", 0);
- ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)")));
+ ProjectSettings::get_singleton()->set_custom_property_info("rendering/anti_aliasing/quality/msaa", PropertyInfo(Variant::INT, "rendering/anti_aliasing/quality/msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")));
root->set_msaa(Viewport::MSAA(msaa_mode));
const int ssaa_mode = GLOBAL_DEF("rendering/anti_aliasing/quality/screen_space_aa", 0);
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index eea5ca9895..fb86d37280 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -823,7 +823,9 @@ Rect2 Viewport::get_visible_rect() const {
}
void Viewport::_update_listener_2d() {
- AudioServer::get_singleton()->notify_listener_changed();
+ if (AudioServer::get_singleton()) {
+ AudioServer::get_singleton()->notify_listener_changed();
+ }
}
void Viewport::set_as_audio_listener_2d(bool p_enable) {
@@ -3063,7 +3065,9 @@ bool Viewport::is_audio_listener_3d() const {
}
void Viewport::_update_listener_3d() {
- AudioServer::get_singleton()->notify_listener_changed();
+ if (AudioServer::get_singleton()) {
+ AudioServer::get_singleton()->notify_listener_changed();
+ }
}
void Viewport::_listener_transform_3d_changed_notify() {
@@ -3594,7 +3598,7 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_transforms_to_pixel"), "set_snap_2d_transforms_to_pixel", "is_snap_2d_transforms_to_pixel_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "snap_2d_vertices_to_pixel"), "set_snap_2d_vertices_to_pixel", "is_snap_2d_vertices_to_pixel_enabled");
ADD_GROUP("Rendering", "");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Fast),4× (Average),8× (Slow),16× (Slower)")), "set_msaa", "get_msaa");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, String::utf8("Disabled (Fastest),2× (Average),4× (Slow),8× (Slowest)")), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::INT, "screen_space_aa", PROPERTY_HINT_ENUM, "Disabled (Fastest),FXAA (Fast)"), "set_screen_space_aa", "get_screen_space_aa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_debanding"), "set_use_debanding", "is_using_debanding");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_occlusion_culling"), "set_use_occlusion_culling", "is_using_occlusion_culling");
@@ -3646,7 +3650,6 @@ void Viewport::_bind_methods() {
BIND_ENUM_CONSTANT(MSAA_2X);
BIND_ENUM_CONSTANT(MSAA_4X);
BIND_ENUM_CONSTANT(MSAA_8X);
- BIND_ENUM_CONSTANT(MSAA_16X);
BIND_ENUM_CONSTANT(MSAA_MAX);
BIND_ENUM_CONSTANT(SCREEN_SPACE_AA_DISABLED);
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index 06efd27073..bfb52c4b98 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -113,7 +113,7 @@ public:
MSAA_2X,
MSAA_4X,
MSAA_8X,
- MSAA_16X,
+ // 16x MSAA is not supported due to its high cost and driver bugs.
MSAA_MAX
};
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index 71d0c69d55..1edc3ff38b 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -224,7 +224,9 @@ Vector<Face3> Mesh::get_faces() const {
Ref<Shape3D> Mesh::create_convex_shape(bool p_clean, bool p_simplify) const {
if (p_simplify) {
- Vector<Ref<Shape3D>> decomposed = convex_decompose(1);
+ ConvexDecompositionSettings settings;
+ settings.max_convex_hulls = 1;
+ Vector<Ref<Shape3D>> decomposed = convex_decompose(settings);
if (decomposed.size() == 1) {
return decomposed[0];
} else {
@@ -565,12 +567,12 @@ void Mesh::clear_cache() const {
debug_lines.clear();
}
-Vector<Ref<Shape3D>> Mesh::convex_decompose(int p_max_convex_hulls) const {
+Vector<Ref<Shape3D>> Mesh::convex_decompose(const ConvexDecompositionSettings &p_settings) const {
ERR_FAIL_COND_V(!convex_composition_function, Vector<Ref<Shape3D>>());
const Vector<Face3> faces = get_faces();
- Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_max_convex_hulls);
+ const Vector<Vector<Face3>> decomposed = convex_composition_function(faces, p_settings);
Vector<Ref<Shape3D>> ret;
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index aa4ed1cb13..4d0ee0f247 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -160,11 +160,42 @@ public:
Size2i get_lightmap_size_hint() const;
void clear_cache() const;
- typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, int p_max_convex_hulls);
+ struct ConvexDecompositionSettings {
+ enum Mode : int {
+ CONVEX_DECOMPOSITION_MODE_VOXEL = 0,
+ CONVEX_DECOMPOSITION_MODE_TETRAHEDRON
+ };
+
+ /// Maximum concavity. [Range: 0.0 -> 1.0]
+ real_t max_concavity = 1.0;
+ /// Controls the bias toward clipping along symmetry planes. [Range: 0.0 -> 1.0]
+ real_t symmetry_planes_clipping_bias = 0.05;
+ /// Controls the bias toward clipping along revolution axes. [Range: 0.0 -> 1.0]
+ real_t revolution_axes_clipping_bias = 0.05;
+ real_t min_volume_per_convex_hull = 0.0001;
+ /// Maximum number of voxels generated during the voxelization stage.
+ uint32_t resolution = 10'000;
+ uint32_t max_num_vertices_per_convex_hull = 32;
+ /// Controls the granularity of the search for the "best" clipping plane.
+ /// [Range: 1 -> 16]
+ uint32_t plane_downsampling = 4;
+ /// Controls the precision of the convex-hull generation process during the
+ /// clipping plane selection stage.
+ /// [Range: 1 -> 16]
+ uint32_t convexhull_downsampling = 4;
+ /// enable/disable normalizing the mesh before applying the convex decomposition.
+ bool normalize_mesh = false;
+ Mode mode = CONVEX_DECOMPOSITION_MODE_VOXEL;
+ bool convexhull_approximation = true;
+ /// This is the maximum number of convex hulls to produce from the merge operation.
+ uint32_t max_convex_hulls = 1;
+ bool project_hull_vertices = true;
+ };
+ typedef Vector<Vector<Face3>> (*ConvexDecompositionFunc)(const Vector<Face3> &p_faces, const ConvexDecompositionSettings &p_settings);
static ConvexDecompositionFunc convex_composition_function;
- Vector<Ref<Shape3D>> convex_decompose(int p_max_convex_hulls = -1) const;
+ Vector<Ref<Shape3D>> convex_decompose(const ConvexDecompositionSettings &p_settings) const;
virtual int get_builtin_bind_pose_count() const;
virtual Transform3D get_builtin_bind_pose(int p_index) const;
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index 063a13efc0..3dc32632cc 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -131,25 +131,6 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
}
-void ImageTexture::_reload_hook(const RID &p_hook) {
- String path = get_path();
- if (!path.is_resource_file()) {
- return;
- }
-
- Ref<Image> img;
- img.instantiate();
- Error err = ImageLoader::load_image(path, img);
-
- ERR_FAIL_COND_MSG(err != OK, "Cannot load image from path '" + path + "'.");
-
- RID new_texture = RenderingServer::get_singleton()->texture_2d_create(img);
- RenderingServer::get_singleton()->texture_replace(texture, new_texture);
-
- notify_property_list_changed();
- emit_changed();
-}
-
void ImageTexture::create_from_image(const Ref<Image> &p_image) {
ERR_FAIL_COND_MSG(p_image.is_null() || p_image->is_empty(), "Invalid image");
w = p_image->get_width();
@@ -192,10 +173,6 @@ void ImageTexture::update(const Ref<Image> &p_image) {
image_stored = true;
}
-void ImageTexture::_resource_path_changed() {
- String path = get_path();
-}
-
Ref<Image> ImageTexture::get_image() const {
if (image_stored) {
return RenderingServer::get_singleton()->texture_2d_get(texture);
@@ -303,7 +280,6 @@ void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("update", "image"), &ImageTexture::update);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
- ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
}
ImageTexture::ImageTexture() {}
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index f6b991c335..93f4e2de5a 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -98,8 +98,6 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
- void _reload_hook(const RID &p_hook);
- virtual void _resource_path_changed() override;
static void _bind_methods();
public:
diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp
index e288e18f33..918fc3fe9c 100644
--- a/scene/resources/tile_set.cpp
+++ b/scene/resources/tile_set.cpp
@@ -982,10 +982,10 @@ void TileSet::clear_tile_proxies() {
Vector<Vector2> TileSet::get_tile_shape_polygon() {
Vector<Vector2> points;
if (tile_shape == TileSet::TILE_SHAPE_SQUARE) {
- points.append(Vector2(0.0, 0.0));
- points.append(Vector2(1.0, 0.0));
- points.append(Vector2(1.0, 1.0));
- points.append(Vector2(0.0, 1.0));
+ points.append(Vector2(-0.5, -0.5));
+ points.append(Vector2(0.5, -0.5));
+ points.append(Vector2(0.5, 0.5));
+ points.append(Vector2(-0.5, 0.5));
} else {
float overlap = 0.0;
switch (tile_shape) {
@@ -1002,31 +1002,24 @@ Vector<Vector2> TileSet::get_tile_shape_polygon() {
break;
}
- points.append(Vector2(0.5, 0.0));
- points.append(Vector2(0.0, overlap));
- points.append(Vector2(0.0, 1.0 - overlap));
- points.append(Vector2(0.5, 1.0));
- points.append(Vector2(1.0, 1.0 - overlap));
- points.append(Vector2(1.0, overlap));
- points.append(Vector2(0.5, 0.0));
+ points.append(Vector2(0.0, -0.5));
+ points.append(Vector2(-0.5, overlap - 0.5));
+ points.append(Vector2(-0.5, 0.5 - overlap));
+ points.append(Vector2(0.0, 0.5));
+ points.append(Vector2(0.5, 0.5 - overlap));
+ points.append(Vector2(0.5, overlap - 0.5));
if (get_tile_offset_axis() == TileSet::TILE_OFFSET_AXIS_VERTICAL) {
for (int i = 0; i < points.size(); i++) {
points.write[i] = Vector2(points[i].y, points[i].x);
}
}
}
- for (int i = 0; i < points.size(); i++) {
- points.write[i] = points[i] * tile_size - tile_size / 2;
- }
return points;
}
-void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p_color, bool p_filled, Ref<Texture2D> p_texture) {
+void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled, Ref<Texture2D> p_texture) {
if (tile_meshes_dirty) {
Vector<Vector2> uvs = get_tile_shape_polygon();
- for (int i = 0; i < uvs.size(); i++) {
- uvs.write[i] = (uvs[i] + tile_size / 2) / tile_size;
- }
Vector<Color> colors;
colors.resize(uvs.size());
@@ -1056,13 +1049,10 @@ void TileSet::draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p
tile_meshes_dirty = false;
}
- Transform2D xform;
- xform.scale(p_region.size);
- xform.set_origin(p_region.get_position());
if (p_filled) {
- p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, xform, p_color);
+ p_canvas_item->draw_mesh(tile_filled_mesh, p_texture, p_transform, p_color);
} else {
- p_canvas_item->draw_mesh(tile_lines_mesh, Ref<Texture2D>(), xform, p_color);
+ p_canvas_item->draw_mesh(tile_lines_mesh, Ref<Texture2D>(), p_transform, p_color);
}
}
diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h
index 3baf022dc0..ba7207241a 100644
--- a/scene/resources/tile_set.h
+++ b/scene/resources/tile_set.h
@@ -385,7 +385,7 @@ public:
// Helpers
Vector<Vector2> get_tile_shape_polygon();
- void draw_tile_shape(CanvasItem *p_canvas_item, Rect2 p_region, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
+ void draw_tile_shape(CanvasItem *p_canvas_item, Transform2D p_transform, Color p_color, bool p_filled = false, Ref<Texture2D> p_texture = Ref<Texture2D>());
Vector<Point2> get_terrain_bit_polygon(int p_terrain_set, TileSet::CellNeighbor p_bit);
void draw_terrains(CanvasItem *p_canvas_item, Transform2D p_transform, const TileData *p_tile_data);