summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
Diffstat (limited to 'scene')
-rw-r--r--scene/2d/path_2d.cpp59
-rw-r--r--scene/2d/path_2d.h1
-rw-r--r--scene/2d/tile_map.cpp4
-rw-r--r--scene/2d/tile_map.h2
-rw-r--r--scene/2d/touch_screen_button.cpp4
-rw-r--r--scene/3d/camera_3d.cpp11
-rw-r--r--scene/3d/light_3d.cpp14
-rw-r--r--scene/3d/light_3d.h3
-rw-r--r--scene/animation/animation_player.cpp69
-rw-r--r--scene/animation/animation_tree.cpp4
-rw-r--r--scene/debugger/scene_debugger.cpp4
-rw-r--r--scene/gui/popup_menu.cpp2
-rw-r--r--scene/gui/scroll_bar.cpp2
-rw-r--r--scene/gui/scroll_container.cpp4
-rw-r--r--scene/gui/text_edit.cpp19
-rw-r--r--scene/gui/tree.cpp2
-rw-r--r--scene/main/window.cpp14
-rw-r--r--scene/main/window.h3
-rw-r--r--scene/register_scene_types.cpp16
-rw-r--r--scene/resources/curve.cpp2
-rw-r--r--scene/resources/material.cpp9
-rw-r--r--scene/resources/shape_2d.cpp5
-rw-r--r--scene/resources/shape_3d.cpp5
23 files changed, 169 insertions, 89 deletions
diff --git a/scene/2d/path_2d.cpp b/scene/2d/path_2d.cpp
index b68a8fb031..823b8d56e3 100644
--- a/scene/2d/path_2d.cpp
+++ b/scene/2d/path_2d.cpp
@@ -106,18 +106,57 @@ void Path2D::_notification(int p_what) {
#else
const real_t line_width = get_tree()->get_debug_paths_width();
#endif
- _cached_draw_pts.resize(curve->get_point_count() * 8);
- int count = 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->sample(i, frac);
- _cached_draw_pts.set(count++, p);
+ real_t interval = 10;
+ const real_t length = curve->get_baked_length();
+
+ if (length > CMP_EPSILON) {
+ const int sample_count = int(length / interval) + 2;
+ interval = length / (sample_count - 1); // Recalculate real interval length.
+
+ Vector<Transform2D> frames;
+ frames.resize(sample_count);
+
+ {
+ Transform2D *w = frames.ptrw();
+
+ for (int i = 0; i < sample_count; i++) {
+ w[i] = curve->sample_baked_with_rotation(i * interval, false);
+ }
}
- }
- draw_polyline(_cached_draw_pts, get_tree()->get_debug_paths_color(), line_width, true);
+ const Transform2D *r = frames.ptr();
+ // Draw curve segments
+ {
+ PackedVector2Array v2p;
+ v2p.resize(sample_count);
+ Vector2 *w = v2p.ptrw();
+
+ for (int i = 0; i < sample_count; i++) {
+ w[i] = r[i].get_origin();
+ }
+ draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width, false);
+ }
+
+ // Draw fish bones
+ {
+ PackedVector2Array v2p;
+ v2p.resize(3);
+ Vector2 *w = v2p.ptrw();
+
+ for (int i = 0; i < sample_count; i++) {
+ const Vector2 p = r[i].get_origin();
+ const Vector2 side = r[i].columns[0];
+ const Vector2 forward = r[i].columns[1];
+
+ // Fish Bone.
+ w[0] = p + (side - forward) * 5;
+ w[1] = p;
+ w[2] = p + (-side - forward) * 5;
+
+ draw_polyline(v2p, get_tree()->get_debug_paths_color(), line_width * 0.5, false);
+ }
+ }
+ }
} break;
}
}
diff --git a/scene/2d/path_2d.h b/scene/2d/path_2d.h
index 5e436fb9f6..935717605a 100644
--- a/scene/2d/path_2d.h
+++ b/scene/2d/path_2d.h
@@ -38,7 +38,6 @@ class Path2D : public Node2D {
GDCLASS(Path2D, Node2D);
Ref<Curve2D> curve;
- Vector<Vector2> _cached_draw_pts;
void _curve_changed();
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 0159e9f313..4d4ea2b26d 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -3838,7 +3838,7 @@ void TileMap::set_texture_repeat(CanvasItem::TextureRepeat p_texture_repeat) {
}
}
-TypedArray<Vector2i> TileMap::get_surrounding_tiles(Vector2i coords) {
+TypedArray<Vector2i> TileMap::get_surrounding_cells(Vector2i coords) {
if (!tile_set.is_valid()) {
return TypedArray<Vector2i>();
}
@@ -4012,7 +4012,7 @@ void TileMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("force_update", "layer"), &TileMap::force_update, DEFVAL(-1));
- ClassDB::bind_method(D_METHOD("get_surrounding_tiles", "coords"), &TileMap::get_surrounding_tiles);
+ ClassDB::bind_method(D_METHOD("get_surrounding_cells", "coords"), &TileMap::get_surrounding_cells);
ClassDB::bind_method(D_METHOD("get_used_cells", "layer"), &TileMap::get_used_cells);
ClassDB::bind_method(D_METHOD("get_used_rect"), &TileMap::get_used_rect);
diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h
index 68a5d3c80b..19f0e5a553 100644
--- a/scene/2d/tile_map.h
+++ b/scene/2d/tile_map.h
@@ -400,7 +400,7 @@ public:
void force_update(int p_layer = -1);
// Helpers?
- TypedArray<Vector2i> get_surrounding_tiles(Vector2i coords);
+ 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());
// Virtual function to modify the TileData at runtime
diff --git a/scene/2d/touch_screen_button.cpp b/scene/2d/touch_screen_button.cpp
index a02f322ef1..e99821e9b9 100644
--- a/scene/2d/touch_screen_button.cpp
+++ b/scene/2d/touch_screen_button.cpp
@@ -100,7 +100,7 @@ void TouchScreenButton::_notification(int p_what) {
if (!is_inside_tree()) {
return;
}
- if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->is_touchscreen_available() && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
return;
}
@@ -137,7 +137,7 @@ void TouchScreenButton::_notification(int p_what) {
} break;
case NOTIFICATION_ENTER_TREE: {
- if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id())) && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
+ if (!Engine::get_singleton()->is_editor_hint() && !!DisplayServer::get_singleton()->is_touchscreen_available() && visibility == VISIBILITY_TOUCHSCREEN_ONLY) {
return;
}
queue_redraw();
diff --git a/scene/3d/camera_3d.cpp b/scene/3d/camera_3d.cpp
index 304e56326d..2a50575749 100644
--- a/scene/3d/camera_3d.cpp
+++ b/scene/3d/camera_3d.cpp
@@ -112,6 +112,12 @@ void Camera3D::_notification(int p_what) {
if (current || first_camera) {
viewport->_camera_3d_set(this);
}
+
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ viewport->connect(SNAME("size_changed"), callable_mp((Node3D *)this, &Camera3D::update_gizmos));
+ }
+#endif
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
@@ -133,6 +139,11 @@ void Camera3D::_notification(int p_what) {
}
if (viewport) {
+#ifdef TOOLS_ENABLED
+ if (Engine::get_singleton()->is_editor_hint()) {
+ viewport->disconnect(SNAME("size_changed"), callable_mp((Node3D *)this, &Camera3D::update_gizmos));
+ }
+#endif
viewport->_camera_3d_remove(this);
viewport = nullptr;
}
diff --git a/scene/3d/light_3d.cpp b/scene/3d/light_3d.cpp
index 198dba7811..3f43e718b8 100644
--- a/scene/3d/light_3d.cpp
+++ b/scene/3d/light_3d.cpp
@@ -461,7 +461,7 @@ Light3D::Light3D(RenderingServer::LightType p_type) {
set_param(PARAM_SHADOW_PANCAKE_SIZE, 20.0);
set_param(PARAM_SHADOW_OPACITY, 1.0);
set_param(PARAM_SHADOW_BLUR, 1.0);
- set_param(PARAM_SHADOW_BIAS, 0.03);
+ set_param(PARAM_SHADOW_BIAS, 0.1);
set_param(PARAM_SHADOW_NORMAL_BIAS, 1.0);
set_param(PARAM_TRANSMITTANCE_BIAS, 0.05);
set_param(PARAM_SHADOW_FADE_START, 1);
@@ -571,8 +571,8 @@ DirectionalLight3D::DirectionalLight3D() :
Light3D(RenderingServer::LIGHT_DIRECTIONAL) {
set_param(PARAM_SHADOW_MAX_DISTANCE, 100);
set_param(PARAM_SHADOW_FADE_START, 0.8);
- // Increase the default shadow bias to better suit most scenes.
- set_param(PARAM_SHADOW_BIAS, 0.1);
+ // Increase the default shadow normal bias to better suit most scenes.
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 2.0);
set_param(PARAM_INTENSITY, 100000.0); // Specified in Lux, approximate mid-day sun.
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
blend_splits = false;
@@ -614,8 +614,6 @@ void OmniLight3D::_bind_methods() {
OmniLight3D::OmniLight3D() :
Light3D(RenderingServer::LIGHT_OMNI) {
set_shadow_mode(SHADOW_CUBE);
- // Increase the default shadow biases to better suit most scenes.
- set_param(PARAM_SHADOW_BIAS, 0.2);
}
PackedStringArray SpotLight3D::get_configuration_warnings() const {
@@ -639,3 +637,9 @@ void SpotLight3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle", PROPERTY_HINT_RANGE, "0,180,0.01,degrees"), "set_param", "get_param", PARAM_SPOT_ANGLE);
ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "spot_angle_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), "set_param", "get_param", PARAM_SPOT_ATTENUATION);
}
+
+SpotLight3D::SpotLight3D() :
+ Light3D(RenderingServer::LIGHT_SPOT) {
+ // Decrease the default shadow bias to better suit most scenes.
+ set_param(PARAM_SHADOW_BIAS, 0.03);
+}
diff --git a/scene/3d/light_3d.h b/scene/3d/light_3d.h
index 84d214030b..d2dfa32aac 100644
--- a/scene/3d/light_3d.h
+++ b/scene/3d/light_3d.h
@@ -233,8 +233,7 @@ protected:
public:
PackedStringArray get_configuration_warnings() const override;
- SpotLight3D() :
- Light3D(RenderingServer::LIGHT_SPOT) {}
+ SpotLight3D();
};
#endif // LIGHT_3D_H
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index f7baa7facc..4800a83255 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -1001,6 +1001,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData *p_anim, double
void AnimationPlayer::_animation_process_data(PlaybackData &cd, double p_delta, float p_blend, bool p_seeked, bool p_started) {
double delta = p_delta * speed_scale * cd.speed_scale;
double next_pos = cd.pos + delta;
+ bool backwards = signbit(delta); // Negative zero means playing backwards too.
real_t len = cd.from->animation->get_length();
Animation::LoopedFlag looped_flag = Animation::LOOPED_FLAG_NONE;
@@ -1012,23 +1013,7 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, double p_delta,
} else if (next_pos > len) {
next_pos = len;
}
-
- bool backwards = signbit(delta); // Negative zero means playing backwards too
- delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here)
-
- if (&cd == &playback.current) {
- if (!backwards && cd.pos <= len && next_pos == len) {
- //playback finished
- end_reached = true;
- end_notify = cd.pos < len; // Notify only if not already at the end
- }
-
- if (backwards && cd.pos >= 0 && next_pos == 0) {
- //playback finished
- end_reached = true;
- end_notify = cd.pos > 0; // Notify only if not already at the beginning
- }
- }
+ delta = next_pos - cd.pos; // Fix delta (after determination of backwards because negative zero is lost here).
} break;
case Animation::LOOP_LINEAR: {
@@ -1057,8 +1042,28 @@ void AnimationPlayer::_animation_process_data(PlaybackData &cd, double p_delta,
break;
}
- _animation_process_animation(cd.from, cd.pos, next_pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started, looped_flag);
+ double prev_pos = cd.pos; // The animation may be changed during process, so it is safer that the state is changed before process.
cd.pos = next_pos;
+
+ AnimationData *prev_from = cd.from;
+ _animation_process_animation(cd.from, prev_pos, cd.pos, delta, p_blend, &cd == &playback.current, p_seeked, p_started, looped_flag);
+
+ // End detection.
+ if (cd.from->animation->get_loop_mode() == Animation::LOOP_NONE) {
+ if (prev_from != playback.current.from) {
+ return; // Animation has been changed in the process (may be caused by method track), abort process.
+ }
+ if (!backwards && prev_pos <= len && next_pos == len) {
+ // Playback finished.
+ end_reached = true;
+ end_notify = prev_pos < len; // Notify only if not already at the end.
+ }
+ if (backwards && prev_pos >= 0 && next_pos == 0) {
+ // Playback finished.
+ end_reached = true;
+ end_notify = prev_pos > 0; // Notify only if not already at the beginning.
+ }
+ }
}
void AnimationPlayer::_animation_process2(double p_delta, bool p_started) {
@@ -1066,23 +1071,25 @@ void AnimationPlayer::_animation_process2(double p_delta, bool p_started) {
accum_pass++;
- _animation_process_data(c.current, p_delta, 1.0f, c.seeked, p_started);
+ bool seeked = c.seeked; // The animation may be changed during process, so it is safer that the state is changed before process.
if (p_delta != 0) {
c.seeked = false;
}
+ _animation_process_data(c.current, p_delta, 1.0f, seeked, p_started);
+
List<Blend>::Element *prev = nullptr;
for (List<Blend>::Element *E = c.blend.back(); E; E = prev) {
Blend &b = E->get();
float blend = b.blend_left / b.blend_time;
- _animation_process_data(b.data, p_delta, blend, false, false);
-
b.blend_left -= Math::absf(speed_scale * p_delta);
-
prev = E->prev();
if (b.blend_left < 0) {
c.blend.erase(E);
}
+ // The effect of animation changes during blending is unknown...
+ // In that case, we recommends to use method call mode "deferred", not "immediate".
+ _animation_process_data(b.data, p_delta, blend, false, false);
}
}
@@ -1123,8 +1130,6 @@ void AnimationPlayer::_animation_update_transforms() {
}
}
- cache_update_size = 0;
-
for (int i = 0; i < cache_update_prop_size; i++) {
TrackNodeCache::PropertyAnim *pa = cache_update_prop[i];
@@ -1186,29 +1191,35 @@ void AnimationPlayer::_animation_update_transforms() {
}
}
- cache_update_prop_size = 0;
-
for (int i = 0; i < cache_update_bezier_size; i++) {
TrackNodeCache::BezierAnim *ba = cache_update_bezier[i];
ERR_CONTINUE(ba->accum_pass != accum_pass);
ba->object->set_indexed(ba->bezier_property, ba->bezier_accum);
}
-
- cache_update_bezier_size = 0;
}
void AnimationPlayer::_animation_process(double p_delta) {
if (playback.current.from) {
end_reached = false;
end_notify = false;
- _animation_process2(p_delta, playback.started);
+ bool started = playback.started; // The animation may be changed during process, so it is safer that the state is changed before process.
if (playback.started) {
playback.started = false;
}
+ cache_update_size = 0;
+ cache_update_prop_size = 0;
+ cache_update_bezier_size = 0;
+
+ AnimationData *prev_from = playback.current.from;
+ _animation_process2(p_delta, started);
+ if (prev_from != playback.current.from) {
+ return; // Animation has been changed in the process (may be caused by method track), abort process.
+ }
_animation_update_transforms();
+
if (end_reached) {
if (queued.size()) {
String old = playback.assigned;
diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp
index bd9b918900..c2d584b52f 100644
--- a/scene/animation/animation_tree.cpp
+++ b/scene/animation/animation_tree.cpp
@@ -1031,7 +1031,9 @@ void AnimationTree::_process_graph(double p_delta) {
}
NodePath path = a->track_get_path(i);
- ERR_CONTINUE(!track_cache.has(path));
+ if (!track_cache.has(path)) {
+ continue; // No path, but avoid error spamming.
+ }
TrackCache *track = track_cache[path];
ERR_CONTINUE(!state.track_map.has(path));
diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp
index 35ba49563c..28eedcbe13 100644
--- a/scene/debugger/scene_debugger.cpp
+++ b/scene/debugger/scene_debugger.cpp
@@ -220,8 +220,12 @@ void SceneDebugger::_save_node(ObjectID id, const String &p_path) {
Node *node = Object::cast_to<Node>(ObjectDB::get_instance(id));
ERR_FAIL_COND(!node);
+#ifdef TOOLS_ENABLED
HashMap<const Node *, Node *> duplimap;
Node *copy = node->duplicate_from_editor(duplimap);
+#else
+ Node *copy = node->duplicate();
+#endif
// Handle Unique Nodes.
for (int i = 0; i < copy->get_child_count(false); i++) {
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index ab74979777..5d8e106e26 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -221,7 +221,7 @@ void PopupMenu::_activate_submenu(int p_over, bool p_by_keyboard) {
Rect2 safe_area = this_rect;
safe_area.position.y += items[p_over]._ofs_cache + scroll_offset + theme_cache.panel_style->get_offset().height - theme_cache.v_separation / 2;
- safe_area.size.y = items[p_over]._height_cache;
+ safe_area.size.y = items[p_over]._height_cache + theme_cache.v_separation;
DisplayServer::get_singleton()->window_set_popup_safe_rect(submenu_popup->get_window_id(), safe_area);
// Make the position of the parent popup relative to submenu popup.
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 6899178885..a44ddff507 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -550,7 +550,7 @@ void ScrollBar::_drag_node_input(const Ref<InputEvent> &p_input) {
drag_node_accum = Vector2();
last_drag_node_accum = Vector2();
drag_node_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
- drag_node_touching = DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
+ drag_node_touching = DisplayServer::get_singleton()->is_touchscreen_available();
drag_node_touching_deaccel = false;
time_since_motion = 0;
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 531226f938..73d30b7568 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -164,8 +164,8 @@ void ScrollContainer::gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
- bool screen_is_touchscreen = DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
- if (!screen_is_touchscreen) {
+ bool is_touchscreen_available = DisplayServer::get_singleton()->is_touchscreen_available();
+ if (!is_touchscreen_available) {
return;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index e7d704a281..a96d85dffa 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1108,8 +1108,9 @@ void TextEdit::_notification(int p_what) {
int start = TS->shaped_text_get_range(rid).x;
if (!clipped && !search_text.is_empty()) { // Search highhlight
int search_text_col = _get_column_pos_of_word(search_text, str, search_flags, 0);
+ int search_text_len = search_text.length();
while (search_text_col != -1) {
- Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text.length() + start);
+ Vector<Vector2> sel = TS->shaped_text_get_selection(rid, search_text_col + start, search_text_col + search_text_len + start);
for (int j = 0; j < sel.size(); j++) {
Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
@@ -1125,14 +1126,15 @@ void TextEdit::_notification(int p_what) {
draw_rect(rect, search_result_border_color, false);
}
- search_text_col = _get_column_pos_of_word(search_text, str, search_flags, search_text_col + 1);
+ search_text_col = _get_column_pos_of_word(search_text, str, search_flags, search_text_col + search_text_len);
}
}
if (!clipped && highlight_all_occurrences && !only_whitespaces_highlighted && !highlighted_text.is_empty()) { // Highlight
int highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
+ int highlighted_text_len = highlighted_text.length();
while (highlighted_text_col != -1) {
- Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text.length() + start);
+ Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_text_col + start, highlighted_text_col + highlighted_text_len + start);
for (int j = 0; j < sel.size(); j++) {
Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
@@ -1147,15 +1149,16 @@ void TextEdit::_notification(int p_what) {
draw_rect(rect, word_highlighted_color);
}
- highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_text_col + 1);
+ highlighted_text_col = _get_column_pos_of_word(highlighted_text, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_text_col + highlighted_text_len);
}
}
if (!clipped && lookup_symbol_word.length() != 0) { // Highlight word
if (is_ascii_char(lookup_symbol_word[0]) || lookup_symbol_word[0] == '_' || lookup_symbol_word[0] == '.') {
- int highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
- while (highlighted_word_col != -1) {
- Vector<Vector2> sel = TS->shaped_text_get_selection(rid, highlighted_word_col + start, highlighted_word_col + lookup_symbol_word.length() + start);
+ int lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, 0);
+ int lookup_symbol_word_len = lookup_symbol_word.length();
+ while (lookup_symbol_word_col != -1) {
+ Vector<Vector2> sel = TS->shaped_text_get_selection(rid, lookup_symbol_word_col + start, lookup_symbol_word_col + lookup_symbol_word_len + start);
for (int j = 0; j < sel.size(); j++) {
Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y + (line_spacing / 2), sel[j].y - sel[j].x, row_height);
if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) {
@@ -1172,7 +1175,7 @@ void TextEdit::_notification(int p_what) {
draw_rect(rect, color);
}
- highlighted_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, highlighted_word_col + 1);
+ lookup_symbol_word_col = _get_column_pos_of_word(lookup_symbol_word, str, SEARCH_MATCH_CASE | SEARCH_WHOLE_WORDS, lookup_symbol_word_col + lookup_symbol_word_len);
}
}
}
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index c0990211aa..3996d2d65d 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -3671,7 +3671,7 @@ void Tree::gui_input(const Ref<InputEvent> &p_event) {
drag_accum = 0;
//last_drag_accum=0;
drag_from = v_scroll->get_value();
- drag_touching = DisplayServer::get_singleton()->screen_is_touchscreen(DisplayServer::get_singleton()->window_get_current_screen(get_viewport()->get_window_id()));
+ drag_touching = DisplayServer::get_singleton()->is_touchscreen_available();
drag_touching_deaccel = false;
if (drag_touching) {
set_physics_process_internal(true);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index aff2c594d9..73436b1658 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -106,9 +106,16 @@ void Window::reset_size() {
set_size(Size2i());
}
-Size2i Window::get_real_size() const {
+Point2i Window::get_position_with_decorations() const {
if (window_id != DisplayServer::INVALID_WINDOW_ID) {
- return DisplayServer::get_singleton()->window_get_real_size(window_id);
+ return DisplayServer::get_singleton()->window_get_position_with_decorations(window_id);
+ }
+ return position;
+}
+
+Size2i Window::get_size_with_decorations() const {
+ if (window_id != DisplayServer::INVALID_WINDOW_ID) {
+ return DisplayServer::get_singleton()->window_get_size_with_decorations(window_id);
}
return size;
}
@@ -1655,7 +1662,8 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_size"), &Window::get_size);
ClassDB::bind_method(D_METHOD("reset_size"), &Window::reset_size);
- ClassDB::bind_method(D_METHOD("get_real_size"), &Window::get_real_size);
+ ClassDB::bind_method(D_METHOD("get_position_with_decorations"), &Window::get_position_with_decorations);
+ ClassDB::bind_method(D_METHOD("get_size_with_decorations"), &Window::get_size_with_decorations);
ClassDB::bind_method(D_METHOD("set_max_size", "max_size"), &Window::set_max_size);
ClassDB::bind_method(D_METHOD("get_max_size"), &Window::get_max_size);
diff --git a/scene/main/window.h b/scene/main/window.h
index 03597b309a..48ce9041a4 100644
--- a/scene/main/window.h
+++ b/scene/main/window.h
@@ -198,7 +198,8 @@ public:
Size2i get_size() const;
void reset_size();
- Size2i get_real_size() const;
+ Point2i get_position_with_decorations() const;
+ Size2i get_size_with_decorations() const;
void set_max_size(const Size2i &p_max_size);
Size2i get_max_size() const;
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index ee45a8ea6f..58147b159a 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -827,14 +827,14 @@ void register_scene_types() {
GDREGISTER_CLASS(ConvexPolygonShape3D);
GDREGISTER_CLASS(ConcavePolygonShape3D);
- ClassDB::register_class<SkeletonModificationStack3D>();
- ClassDB::register_class<SkeletonModification3D>();
- ClassDB::register_class<SkeletonModification3DLookAt>();
- ClassDB::register_class<SkeletonModification3DCCDIK>();
- ClassDB::register_class<SkeletonModification3DFABRIK>();
- ClassDB::register_class<SkeletonModification3DJiggle>();
- ClassDB::register_class<SkeletonModification3DTwoBoneIK>();
- ClassDB::register_class<SkeletonModification3DStackHolder>();
+ GDREGISTER_CLASS(SkeletonModificationStack3D);
+ GDREGISTER_CLASS(SkeletonModification3D);
+ GDREGISTER_CLASS(SkeletonModification3DLookAt);
+ GDREGISTER_CLASS(SkeletonModification3DCCDIK);
+ GDREGISTER_CLASS(SkeletonModification3DFABRIK);
+ GDREGISTER_CLASS(SkeletonModification3DJiggle);
+ GDREGISTER_CLASS(SkeletonModification3DTwoBoneIK);
+ GDREGISTER_CLASS(SkeletonModification3DStackHolder);
OS::get_singleton()->yield(); // may take time to init
#endif // _3D_DISABLED
diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp
index fa7a1f3dbf..bc2149a8c6 100644
--- a/scene/resources/curve.cpp
+++ b/scene/resources/curve.cpp
@@ -941,7 +941,7 @@ Transform2D Curve2D::_sample_posture(Interval p_interval) const {
const Vector2 forward = forward_begin.slerp(forward_end, frac).normalized();
const Vector2 side = Vector2(-forward.y, forward.x);
- return Transform2D(forward, side, Vector2(0.0, 0.0));
+ return Transform2D(side, forward, Vector2(0.0, 0.0));
}
Vector2 Curve2D::sample_baked(real_t p_offset, bool p_cubic) const {
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index e457b2d377..a16d2c2072 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -1252,15 +1252,16 @@ void BaseMaterial3D::_update_shader() {
}
if (distance_fade != DISTANCE_FADE_DISABLED) {
+ // Use the slightly more expensive circular fade (distance to the object) instead of linear
+ // (Z distance), so that the fade is always the same regardless of the camera angle.
if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) {
if (!RenderingServer::get_singleton()->is_low_end()) {
code += " {\n";
if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) {
- code += " float fade_distance = abs((VIEW_MATRIX * MODEL_MATRIX[3]).z);\n";
-
+ code += " float fade_distance = length((VIEW_MATRIX * MODEL_MATRIX[3]));\n";
} else {
- code += " float fade_distance = -VERTEX.z;\n";
+ code += " float fade_distance = length(VERTEX);\n";
}
// Use interleaved gradient noise, which is fast but still looks good.
code += " const vec3 magic = vec3(0.06711056f, 0.00583715f, 52.9829189f);";
@@ -1274,7 +1275,7 @@ void BaseMaterial3D::_update_shader() {
}
} else {
- code += " ALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n";
+ code += " ALPHA *= clamp(smoothstep(distance_fade_min, distance_fade_max, length(VERTEX)), 0.0, 1.0);\n";
}
}
diff --git a/scene/resources/shape_2d.cpp b/scene/resources/shape_2d.cpp
index 413670d23e..87c6c36ee9 100644
--- a/scene/resources/shape_2d.cpp
+++ b/scene/resources/shape_2d.cpp
@@ -124,7 +124,6 @@ Shape2D::Shape2D(const RID &p_rid) {
}
Shape2D::~Shape2D() {
- if (PhysicsServer2D::get_singleton() != nullptr) {
- PhysicsServer2D::get_singleton()->free(shape);
- }
+ ERR_FAIL_NULL(PhysicsServer2D::get_singleton());
+ PhysicsServer2D::get_singleton()->free(shape);
}
diff --git a/scene/resources/shape_3d.cpp b/scene/resources/shape_3d.cpp
index 44f21d2a48..7992ba9fd4 100644
--- a/scene/resources/shape_3d.cpp
+++ b/scene/resources/shape_3d.cpp
@@ -128,7 +128,6 @@ Shape3D::Shape3D(RID p_shape) :
shape(p_shape) {}
Shape3D::~Shape3D() {
- if (PhysicsServer3D::get_singleton() != nullptr) {
- PhysicsServer3D::get_singleton()->free(shape);
- }
+ ERR_FAIL_NULL(PhysicsServer3D::get_singleton());
+ PhysicsServer3D::get_singleton()->free(shape);
}