diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/path_2d.cpp | 59 | ||||
-rw-r--r-- | scene/2d/path_2d.h | 1 | ||||
-rw-r--r-- | scene/2d/tile_map.cpp | 4 | ||||
-rw-r--r-- | scene/2d/tile_map.h | 2 | ||||
-rw-r--r-- | scene/2d/touch_screen_button.cpp | 4 | ||||
-rw-r--r-- | scene/3d/camera_3d.cpp | 11 | ||||
-rw-r--r-- | scene/3d/light_3d.cpp | 14 | ||||
-rw-r--r-- | scene/3d/light_3d.h | 3 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 69 | ||||
-rw-r--r-- | scene/animation/animation_tree.cpp | 4 | ||||
-rw-r--r-- | scene/debugger/scene_debugger.cpp | 4 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 2 | ||||
-rw-r--r-- | scene/gui/scroll_bar.cpp | 2 | ||||
-rw-r--r-- | scene/gui/scroll_container.cpp | 4 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 19 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 2 | ||||
-rw-r--r-- | scene/main/window.cpp | 14 | ||||
-rw-r--r-- | scene/main/window.h | 3 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 16 | ||||
-rw-r--r-- | scene/resources/curve.cpp | 2 | ||||
-rw-r--r-- | scene/resources/material.cpp | 9 | ||||
-rw-r--r-- | scene/resources/shape_2d.cpp | 5 | ||||
-rw-r--r-- | scene/resources/shape_3d.cpp | 5 |
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); } |