diff options
Diffstat (limited to 'scene')
21 files changed, 216 insertions, 130 deletions
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp index 4b866fc6de..822f1b58fd 100644 --- a/scene/2d/camera_2d.cpp +++ b/scene/2d/camera_2d.cpp @@ -877,7 +877,7 @@ void Camera2D::_bind_methods() { ClassDB::bind_method(D_METHOD("is_margin_drawing_enabled"), &Camera2D::is_margin_drawing_enabled); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset", PROPERTY_HINT_NONE, "suffix:px"), "set_offset", "get_offset"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed TopLeft,Drag Center"), "set_anchor_mode", "get_anchor_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "anchor_mode", PROPERTY_HINT_ENUM, "Fixed Top Left,Drag Center"), "set_anchor_mode", "get_anchor_mode"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ignore_rotation"), "set_ignore_rotation", "is_ignoring_rotation"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "zoom", PROPERTY_HINT_LINK), "set_zoom", "get_zoom"); diff --git a/scene/2d/skeleton_2d.cpp b/scene/2d/skeleton_2d.cpp index 69e0414855..fe21c7f21b 100644 --- a/scene/2d/skeleton_2d.cpp +++ b/scene/2d/skeleton_2d.cpp @@ -635,36 +635,47 @@ Bone2D *Skeleton2D::get_bone(int p_idx) { } void Skeleton2D::_notification(int p_what) { - if (p_what == NOTIFICATION_READY) { - if (bone_setup_dirty) { - _update_bone_setup(); - } - if (transform_dirty) { - _update_transform(); - } - request_ready(); - } + switch (p_what) { + case NOTIFICATION_READY: { + if (bone_setup_dirty) { + _update_bone_setup(); + } + if (transform_dirty) { + _update_transform(); + } + request_ready(); + } break; - if (p_what == NOTIFICATION_TRANSFORM_CHANGED) { - RS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform()); - } else if (p_what == NOTIFICATION_INTERNAL_PROCESS) { - if (modification_stack.is_valid()) { - execute_modifications(get_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_process); - } - } else if (p_what == NOTIFICATION_INTERNAL_PHYSICS_PROCESS) { - if (modification_stack.is_valid()) { - execute_modifications(get_physics_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_physics_process); - } - } -#ifdef TOOLS_ENABLED - else if (p_what == NOTIFICATION_DRAW) { - if (Engine::get_singleton()->is_editor_hint()) { + case NOTIFICATION_TRANSFORM_CHANGED: { + RS::get_singleton()->skeleton_set_base_transform_2d(skeleton, get_global_transform()); + } break; + + case NOTIFICATION_INTERNAL_PROCESS: { if (modification_stack.is_valid()) { - modification_stack->draw_editor_gizmos(); + execute_modifications(get_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_process); } - } - } + } break; + + case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: { + if (modification_stack.is_valid()) { + execute_modifications(get_physics_process_delta_time(), SkeletonModificationStack2D::EXECUTION_MODE::execution_mode_physics_process); + } + } break; + + case NOTIFICATION_POST_ENTER_TREE: { + set_modification_stack(modification_stack); + } break; + +#ifdef TOOLS_ENABLED + case NOTIFICATION_DRAW: { + if (Engine::get_singleton()->is_editor_hint()) { + if (modification_stack.is_valid()) { + modification_stack->draw_editor_gizmos(); + } + } + } break; #endif // TOOLS_ENABLED + } } RID Skeleton2D::get_skeleton() const { @@ -692,7 +703,7 @@ void Skeleton2D::set_modification_stack(Ref<SkeletonModificationStack2D> p_stack set_physics_process_internal(false); } modification_stack = p_stack; - if (modification_stack.is_valid()) { + if (modification_stack.is_valid() && is_inside_tree()) { modification_stack->set_skeleton(this); modification_stack->setup(); diff --git a/scene/3d/physics/character_body_3d.cpp b/scene/3d/physics/character_body_3d.cpp index b13c279234..dda3ea9cca 100644 --- a/scene/3d/physics/character_body_3d.cpp +++ b/scene/3d/physics/character_body_3d.cpp @@ -232,7 +232,7 @@ void CharacterBody3D::_move_and_slide_grounded(double p_delta, bool p_was_on_flo } else { // Travel is too high to be safely canceled, we take it into account. result.travel = result.travel.slide(up_direction); - motion = motion.normalized() * result.travel.length(); + motion = result.remainder; } set_global_transform(gt); // Determines if you are on the ground, and limits the possibility of climbing on the walls because of the approximations. diff --git a/scene/3d/xr_body_modifier_3d.cpp b/scene/3d/xr_body_modifier_3d.cpp index 8aec3e856e..cf73882a7b 100644 --- a/scene/3d/xr_body_modifier_3d.cpp +++ b/scene/3d/xr_body_modifier_3d.cpp @@ -312,7 +312,7 @@ void XRBodyModifier3D::_process_modification() { } } -void XRBodyModifier3D::_tracker_changed(const StringName &p_tracker_name, const Ref<XRBodyTracker> &p_tracker) { +void XRBodyModifier3D::_tracker_changed(const StringName &p_tracker_name, XRServer::TrackerType p_tracker_type) { if (tracker_name == p_tracker_name) { _get_joint_data(); } @@ -327,18 +327,18 @@ void XRBodyModifier3D::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: { XRServer *xr_server = XRServer::get_singleton(); if (xr_server) { - xr_server->connect("body_tracker_added", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); - xr_server->connect("body_tracker_updated", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); - xr_server->connect("body_tracker_removed", callable_mp(this, &XRBodyModifier3D::_tracker_changed).bind(Ref<XRBodyTracker>())); + xr_server->connect("tracker_added", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); + xr_server->connect("tracker_updated", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); + xr_server->connect("tracker_removed", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); } _get_joint_data(); } break; case NOTIFICATION_EXIT_TREE: { XRServer *xr_server = XRServer::get_singleton(); if (xr_server) { - xr_server->disconnect("body_tracker_added", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); - xr_server->disconnect("body_tracker_updated", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); - xr_server->disconnect("body_tracker_removed", callable_mp(this, &XRBodyModifier3D::_tracker_changed).bind(Ref<XRBodyTracker>())); + xr_server->disconnect("tracker_added", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); + xr_server->disconnect("tracker_updated", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); + xr_server->disconnect("tracker_removed", callable_mp(this, &XRBodyModifier3D::_tracker_changed)); } for (int i = 0; i < XRBodyTracker::JOINT_MAX; i++) { joints[i].bone = -1; diff --git a/scene/3d/xr_body_modifier_3d.h b/scene/3d/xr_body_modifier_3d.h index 9ff0cd7207..78d70146ee 100644 --- a/scene/3d/xr_body_modifier_3d.h +++ b/scene/3d/xr_body_modifier_3d.h @@ -86,7 +86,7 @@ private: JointData joints[XRBodyTracker::JOINT_MAX]; void _get_joint_data(); - void _tracker_changed(const StringName &p_tracker_name, const Ref<XRBodyTracker> &p_tracker); + void _tracker_changed(const StringName &p_tracker_name, XRServer::TrackerType p_tracker_type); }; VARIANT_BITFIELD_CAST(XRBodyModifier3D::BodyUpdate) diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index 1b960a9b62..d035515b51 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -336,7 +336,8 @@ void GraphNode::_notification(int p_what) { int width = get_size().width - sb_panel->get_minimum_size().x; - if (get_child_count() > 0) { + // Take the HboxContainer child into account. + if (get_child_count(false) > 0) { int slot_index = 0; for (const KeyValue<int, Slot> &E : slot_table) { if (E.key < 0 || E.key >= slot_y_cache.size()) { @@ -647,6 +648,7 @@ void GraphNode::_port_pos_update() { left_port_cache.clear(); right_port_cache.clear(); int vertical_ofs = titlebar_hbox->get_size().height + sb_titlebar->get_minimum_size().height + sb_panel->get_margin(SIDE_TOP); + int slot_index = 0; for (int i = 0; i < get_child_count(false); i++) { Control *child = Object::cast_to<Control>(get_child(i, false)); @@ -656,27 +658,28 @@ void GraphNode::_port_pos_update() { Size2i size = child->get_rect().size; - if (slot_table.has(i)) { - if (slot_table[i].enable_left) { + if (slot_table.has(slot_index)) { + if (slot_table[slot_index].enable_left) { PortCache port_cache; port_cache.pos = Point2i(edgeofs, vertical_ofs + size.height / 2); - port_cache.type = slot_table[i].type_left; - port_cache.color = slot_table[i].color_left; - port_cache.slot_index = child->get_index(false); + port_cache.type = slot_table[slot_index].type_left; + port_cache.color = slot_table[slot_index].color_left; + port_cache.slot_index = slot_index; left_port_cache.push_back(port_cache); } - if (slot_table[i].enable_right) { + if (slot_table[slot_index].enable_right) { PortCache port_cache; port_cache.pos = Point2i(get_size().width - edgeofs, vertical_ofs + size.height / 2); - port_cache.type = slot_table[i].type_right; - port_cache.color = slot_table[i].color_right; - port_cache.slot_index = child->get_index(false); + port_cache.type = slot_table[slot_index].type_right; + port_cache.color = slot_table[slot_index].color_right; + port_cache.slot_index = slot_index; right_port_cache.push_back(port_cache); } } vertical_ofs += separation; vertical_ofs += size.height; + slot_index++; } port_pos_dirty = false; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 260956a775..9b991972be 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -276,6 +276,7 @@ Size2 PopupMenu::_get_contents_minimum_size() const { } } + minsize.height = Math::ceil(minsize.height); // Ensures enough height at fractional content scales to prevent the v_scroll_bar from showing. return minsize; } @@ -2832,9 +2833,9 @@ void PopupMenu::popup(const Rect2i &p_bounds) { if (!is_embedded()) { float win_scale = get_parent_visible_window()->get_content_scale_factor(); set_content_scale_factor(win_scale); - Size2 minsize = get_contents_minimum_size(); - minsize.height += 0.5 * win_scale; // Ensures enough height at fractional content scales to prevent the v_scroll_bar from showing. - set_min_size(minsize * win_scale); + Size2 minsize = get_contents_minimum_size() * win_scale; + minsize.height = Math::ceil(minsize.height); // Ensures enough height at fractional content scales to prevent the v_scroll_bar from showing. + set_min_size(minsize); // `height` is truncated here by the cast to Size2i for Window.min_size. set_size(Vector2(0, 0)); // Shrinkwraps to min size. } Popup::popup(p_bounds); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 05f44891f6..e2feb59a8c 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -794,6 +794,22 @@ Ref<Texture2D> TabContainer::get_tab_icon(int p_tab) const { return tab_bar->get_tab_icon(p_tab); } +void TabContainer::set_tab_icon_max_width(int p_tab, int p_width) { + if (tab_bar->get_tab_icon_max_width(p_tab) == p_width) { + return; + } + + tab_bar->set_tab_icon_max_width(p_tab, p_width); + + _update_margins(); + _repaint(); + queue_redraw(); +} + +int TabContainer::get_tab_icon_max_width(int p_tab) const { + return tab_bar->get_tab_icon_max_width(p_tab); +} + void TabContainer::set_tab_disabled(int p_tab, bool p_disabled) { if (tab_bar->is_tab_disabled(p_tab) == p_disabled) { return; @@ -990,6 +1006,8 @@ void TabContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("get_tab_tooltip", "tab_idx"), &TabContainer::get_tab_tooltip); ClassDB::bind_method(D_METHOD("set_tab_icon", "tab_idx", "icon"), &TabContainer::set_tab_icon); ClassDB::bind_method(D_METHOD("get_tab_icon", "tab_idx"), &TabContainer::get_tab_icon); + ClassDB::bind_method(D_METHOD("set_tab_icon_max_width", "tab_idx", "width"), &TabContainer::set_tab_icon_max_width); + ClassDB::bind_method(D_METHOD("get_tab_icon_max_width", "tab_idx"), &TabContainer::get_tab_icon_max_width); ClassDB::bind_method(D_METHOD("set_tab_disabled", "tab_idx", "disabled"), &TabContainer::set_tab_disabled); ClassDB::bind_method(D_METHOD("is_tab_disabled", "tab_idx"), &TabContainer::is_tab_disabled); ClassDB::bind_method(D_METHOD("set_tab_hidden", "tab_idx", "hidden"), &TabContainer::set_tab_hidden); diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h index c11d9824e7..e00bc780d4 100644 --- a/scene/gui/tab_container.h +++ b/scene/gui/tab_container.h @@ -161,6 +161,9 @@ public: void set_tab_icon(int p_tab, const Ref<Texture2D> &p_icon); Ref<Texture2D> get_tab_icon(int p_tab) const; + void set_tab_icon_max_width(int p_tab, int p_width); + int get_tab_icon_max_width(int p_tab) const; + void set_tab_disabled(int p_tab, bool p_disabled); bool is_tab_disabled(int p_tab) const; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 0bb77a92f2..39fba72e09 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -752,16 +752,15 @@ void TextEdit::_notification(int p_what) { // Draw the minimap. // Add visual feedback when dragging or hovering the visible area rectangle. - float viewport_alpha; + Color viewport_color = theme_cache.caret_color; if (dragging_minimap) { - viewport_alpha = 0.25; + viewport_color.a = 0.25; } else if (hovering_minimap) { - viewport_alpha = 0.175; + viewport_color.a = 0.175; } else { - viewport_alpha = 0.1; + viewport_color.a = 0.1; } - const Color viewport_color = (theme_cache.background_color.get_v() < 0.5) ? Color(1, 1, 1, viewport_alpha) : Color(0, 0, 0, viewport_alpha); if (rtl) { RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(size.width - (xmargin_end + 2) - minimap_width, viewport_offset_y, minimap_width, viewport_height), viewport_color); } else { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 982473deee..b17d345f1f 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -379,8 +379,8 @@ void TreeItem::set_text_overrun_behavior(int p_column, TextServer::OverrunBehavi cells.write[p_column].text_buf->set_text_overrun_behavior(p_behavior); cells.write[p_column].dirty = true; - _changed_notify(p_column); cells.write[p_column].cached_minimum_size_dirty = true; + _changed_notify(p_column); } TextServer::OverrunBehavior TreeItem::get_text_overrun_behavior(int p_column) const { @@ -1512,7 +1512,9 @@ Size2 TreeItem::get_minimum_size(int p_column) { const TreeItem::Cell &cell = cells[p_column]; if (cell.cached_minimum_size_dirty) { - Size2 size; + Size2 size = Size2( + parent_tree->theme_cache.inner_item_margin_left + parent_tree->theme_cache.inner_item_margin_right, + parent_tree->theme_cache.inner_item_margin_top + parent_tree->theme_cache.inner_item_margin_bottom); // Text. if (!cell.text.is_empty()) { @@ -1520,7 +1522,9 @@ Size2 TreeItem::get_minimum_size(int p_column) { parent_tree->update_item_cell(this, p_column); } Size2 text_size = cell.text_buf->get_size(); - size.width += text_size.width; + if (get_text_overrun_behavior(p_column) == TextServer::OVERRUN_NO_TRIMMING) { + size.width += text_size.width; + } size.height = MAX(size.height, text_size.height); } @@ -1539,13 +1543,10 @@ Size2 TreeItem::get_minimum_size(int p_column) { Ref<Texture2D> texture = cell.buttons[i].texture; if (texture.is_valid()) { Size2 button_size = texture->get_size() + parent_tree->theme_cache.button_pressed->get_minimum_size(); - size.width += button_size.width; + size.width += button_size.width + parent_tree->theme_cache.button_margin; size.height = MAX(size.height, button_size.height); } } - if (cell.buttons.size() >= 2) { - size.width += (cell.buttons.size() - 1) * parent_tree->theme_cache.button_margin; - } cells.write[p_column].cached_minimum_size = size; cells.write[p_column].cached_minimum_size_dirty = false; @@ -4394,17 +4395,23 @@ void Tree::_update_all() { } Size2 Tree::get_minimum_size() const { - if (h_scroll_enabled && v_scroll_enabled) { - return Size2(); - } else { - Vector2 min_size = get_internal_min_size(); - Ref<StyleBox> bg = theme_cache.panel_style; - if (bg.is_valid()) { - min_size.x += bg->get_margin(SIDE_LEFT) + bg->get_margin(SIDE_RIGHT); - min_size.y += bg->get_margin(SIDE_TOP) + bg->get_margin(SIDE_BOTTOM); - } - return Vector2(h_scroll_enabled ? 0 : min_size.x, v_scroll_enabled ? 0 : min_size.y); + Vector2 min_size = Vector2(0, _get_title_button_height()); + + if (theme_cache.panel_style.is_valid()) { + min_size += theme_cache.panel_style->get_minimum_size(); + } + + Vector2 content_min_size = get_internal_min_size(); + if (h_scroll_enabled) { + content_min_size.x = 0; + min_size.y += h_scroll->get_combined_minimum_size().height; + } + if (v_scroll_enabled) { + min_size.x += v_scroll->get_combined_minimum_size().width; + content_min_size.y = 0; } + + return min_size + content_min_size; } TreeItem *Tree::create_item(TreeItem *p_parent, int p_index) { @@ -4582,6 +4589,7 @@ void Tree::set_hide_root(bool p_enabled) { hide_root = p_enabled; queue_redraw(); + update_minimum_size(); } bool Tree::is_root_hidden() const { @@ -4730,31 +4738,33 @@ int Tree::get_column_minimum_width(int p_column) const { min_width = MAX(theme_cache.font->get_string_size(columns[p_column].xl_title, HORIZONTAL_ALIGNMENT_LEFT, -1, theme_cache.font_size).width + padding, min_width); } - if (!columns[p_column].clip_content) { - int depth = 0; - TreeItem *next; - for (TreeItem *item = get_root(); item; item = next) { - next = item->get_next_visible(); - // Compute the depth in tree. - if (next && p_column == 0) { - if (next->get_parent() == item) { - depth += 1; - } else { - TreeItem *common_parent = item->get_parent(); - while (common_parent != next->get_parent() && common_parent) { - common_parent = common_parent->get_parent(); - depth -= 1; + if (root && !columns[p_column].clip_content) { + int depth = 1; + + TreeItem *last = nullptr; + TreeItem *first = hide_root ? root->get_next_visible() : root; + for (TreeItem *item = first; item; last = item, item = item->get_next_visible()) { + // Get column indentation. + int indent; + if (p_column == 0) { + if (last) { + if (item->parent == last) { + depth += 1; + } else if (item->parent != last->parent) { + depth = hide_root ? 0 : 1; + for (TreeItem *iter = item->parent; iter; iter = iter->parent) { + depth += 1; + } } } + indent = theme_cache.item_margin * depth; + } else { + indent = theme_cache.h_separation; } // Get the item minimum size. Size2 item_size = item->get_minimum_size(p_column); - if (p_column == 0) { - item_size.width += theme_cache.item_margin * depth; - } else { - item_size.width += theme_cache.h_separation; - } + item_size.width += indent; // Check if the item is wider. min_width = MAX(min_width, item_size.width); @@ -4968,6 +4978,7 @@ void Tree::set_column_titles_visible(bool p_show) { show_column_titles = p_show; queue_redraw(); + update_minimum_size(); } bool Tree::are_column_titles_visible() const { diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d.cpp index 4e7563fdc3..5450f544c3 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d.cpp @@ -233,6 +233,11 @@ void SkeletonModification2D::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "execution_mode", PROPERTY_HINT_ENUM, "process,physics_process"), "set_execution_mode", "get_execution_mode"); } +void SkeletonModification2D::reset_state() { + stack = nullptr; + is_setup = false; +} + SkeletonModification2D::SkeletonModification2D() { stack = nullptr; is_setup = false; diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d.h b/scene/resources/2d/skeleton/skeleton_modification_2d.h index 413b860a99..6a6f1bb39b 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d.h +++ b/scene/resources/2d/skeleton/skeleton_modification_2d.h @@ -57,6 +57,8 @@ protected: bool _print_execution_error(bool p_condition, String p_message); + virtual void reset_state() override; + GDVIRTUAL1(_execute, double) GDVIRTUAL1(_setup_modification, Ref<SkeletonModificationStack2D>) GDVIRTUAL0(_draw_editor_gizmo) diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_ccdik.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_ccdik.cpp index 1ad8d0eccc..051c4eabc0 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_ccdik.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_ccdik.cpp @@ -266,7 +266,9 @@ void SkeletonModification2DCCDIK::_draw_editor_gizmo() { void SkeletonModification2DCCDIK::update_target_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + } return; } @@ -287,7 +289,9 @@ void SkeletonModification2DCCDIK::update_target_cache() { void SkeletonModification2DCCDIK::update_tip_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update tip cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update tip cache: modification is not properly setup!"); + } return; } @@ -309,7 +313,9 @@ void SkeletonModification2DCCDIK::update_tip_cache() { void SkeletonModification2DCCDIK::ccdik_joint_update_bone2d_cache(int p_joint_idx) { ERR_FAIL_INDEX_MSG(p_joint_idx, ccdik_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update CCDIK Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update CCDIK Bone2D cache: modification is not properly setup!"); + } return; } @@ -390,7 +396,6 @@ void SkeletonModification2DCCDIK::set_ccdik_joint_bone_index(int p_joint_idx, in ccdik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } } else { - WARN_PRINT("Cannot verify the CCDIK joint " + itos(p_joint_idx) + " bone index for this modification..."); ccdik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_fabrik.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_fabrik.cpp index dd1c4a91d5..16a6166878 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_fabrik.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_fabrik.cpp @@ -289,13 +289,21 @@ void SkeletonModification2DFABRIK::_setup_modification(SkeletonModificationStack if (stack != nullptr) { is_setup = true; + + if (stack->skeleton) { + for (int i = 0; i < fabrik_data_chain.size(); i++) { + fabrik_joint_update_bone2d_cache(i); + } + } update_target_cache(); } } void SkeletonModification2DFABRIK::update_target_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + } return; } @@ -317,7 +325,9 @@ void SkeletonModification2DFABRIK::update_target_cache() { void SkeletonModification2DFABRIK::fabrik_joint_update_bone2d_cache(int p_joint_idx) { ERR_FAIL_INDEX_MSG(p_joint_idx, fabrik_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update FABRIK Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update FABRIK Bone2D cache: modification is not properly setup!"); + } return; } @@ -389,7 +399,6 @@ void SkeletonModification2DFABRIK::set_fabrik_joint_bone_index(int p_joint_idx, fabrik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } } else { - WARN_PRINT("Cannot verify the FABRIK joint " + itos(p_joint_idx) + " bone index for this modification..."); fabrik_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_jiggle.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_jiggle.cpp index 2ace9577e4..b7200b49c4 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_jiggle.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_jiggle.cpp @@ -254,6 +254,8 @@ void SkeletonModification2DJiggle::_setup_modification(SkeletonModificationStack Bone2D *bone2d_node = stack->skeleton->get_bone(bone_idx); jiggle_data_chain.write[i].dynamic_position = bone2d_node->get_global_position(); } + + jiggle_joint_update_bone2d_cache(i); } } @@ -263,7 +265,9 @@ void SkeletonModification2DJiggle::_setup_modification(SkeletonModificationStack void SkeletonModification2DJiggle::update_target_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + } return; } @@ -285,7 +289,9 @@ void SkeletonModification2DJiggle::update_target_cache() { void SkeletonModification2DJiggle::jiggle_joint_update_bone2d_cache(int p_joint_idx) { ERR_FAIL_INDEX_MSG(p_joint_idx, jiggle_data_chain.size(), "Cannot update bone2d cache: joint index out of range!"); if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update Jiggle " + itos(p_joint_idx) + " Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update Jiggle " + itos(p_joint_idx) + " Bone2D cache: modification is not properly setup!"); + } return; } @@ -425,7 +431,6 @@ void SkeletonModification2DJiggle::set_jiggle_joint_bone_index(int p_joint_idx, jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } } else { - WARN_PRINT("Cannot verify the Jiggle joint " + itos(p_joint_idx) + " bone index for this modification..."); jiggle_data_chain.write[p_joint_idx].bone_idx = p_bone_idx; } diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_lookat.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_lookat.cpp index 8f6f6bc4ae..cd4ca8e090 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_lookat.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_lookat.cpp @@ -200,7 +200,9 @@ void SkeletonModification2DLookAt::_draw_editor_gizmo() { void SkeletonModification2DLookAt::update_bone2d_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update Bone2D cache: modification is not properly setup!"); + } return; } @@ -256,7 +258,6 @@ void SkeletonModification2DLookAt::set_bone_index(int p_bone_idx) { bone_idx = p_bone_idx; } } else { - WARN_PRINT("Cannot verify the bone index for this modification..."); bone_idx = p_bone_idx; } @@ -265,7 +266,9 @@ void SkeletonModification2DLookAt::set_bone_index(int p_bone_idx) { void SkeletonModification2DLookAt::update_target_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + } return; } diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp index 61e5aed150..aa8d7d0b3b 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_physicalbones.cpp @@ -153,7 +153,7 @@ void SkeletonModification2DPhysicalBones::_setup_modification(SkeletonModificati void SkeletonModification2DPhysicalBones::_physical_bone_update_cache(int p_joint_idx) { ERR_FAIL_INDEX_MSG(p_joint_idx, physical_bone_chain.size(), "Cannot update PhysicalBone2D cache: joint index out of range!"); if (!is_setup || !stack) { - if (!stack) { + if (is_setup) { ERR_PRINT_ONCE("Cannot update PhysicalBone2D cache: modification is not properly setup!"); } return; diff --git a/scene/resources/2d/skeleton/skeleton_modification_2d_twoboneik.cpp b/scene/resources/2d/skeleton/skeleton_modification_2d_twoboneik.cpp index c3366d5c36..41e4ea828e 100644 --- a/scene/resources/2d/skeleton/skeleton_modification_2d_twoboneik.cpp +++ b/scene/resources/2d/skeleton/skeleton_modification_2d_twoboneik.cpp @@ -250,7 +250,9 @@ void SkeletonModification2DTwoBoneIK::_draw_editor_gizmo() { void SkeletonModification2DTwoBoneIK::update_target_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update target cache: modification is not properly setup!"); + } return; } @@ -271,7 +273,9 @@ void SkeletonModification2DTwoBoneIK::update_target_cache() { void SkeletonModification2DTwoBoneIK::update_joint_one_bone2d_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update joint one Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update joint one Bone2D cache: modification is not properly setup!"); + } return; } @@ -299,7 +303,9 @@ void SkeletonModification2DTwoBoneIK::update_joint_one_bone2d_cache() { void SkeletonModification2DTwoBoneIK::update_joint_two_bone2d_cache() { if (!is_setup || !stack) { - ERR_PRINT_ONCE("Cannot update joint two Bone2D cache: modification is not properly setup!"); + if (is_setup) { + ERR_PRINT_ONCE("Cannot update joint two Bone2D cache: modification is not properly setup!"); + } return; } @@ -400,7 +406,6 @@ void SkeletonModification2DTwoBoneIK::set_joint_one_bone_idx(int p_bone_idx) { joint_one_bone_idx = p_bone_idx; } } else { - WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint one..."); joint_one_bone_idx = p_bone_idx; } @@ -425,7 +430,6 @@ void SkeletonModification2DTwoBoneIK::set_joint_two_bone_idx(int p_bone_idx) { joint_two_bone_idx = p_bone_idx; } } else { - WARN_PRINT("TwoBoneIK: Cannot verify the joint bone index for joint two..."); joint_two_bone_idx = p_bone_idx; } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index c72327e464..6005172c11 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -266,7 +266,7 @@ private: _FORCE_INLINE_ void _track_get_key_indices_in_range(const Vector<T> &p_array, double from_time, double to_time, List<int> *p_indices, bool p_is_backward) const; double length = 1.0; - real_t step = 0.1; + real_t step = 1.0 / 30; LoopMode loop_mode = LOOP_NONE; void _track_update_hash(int p_track); diff --git a/scene/resources/particle_process_material.cpp b/scene/resources/particle_process_material.cpp index 30b90841e3..685625ab72 100644 --- a/scene/resources/particle_process_material.cpp +++ b/scene/resources/particle_process_material.cpp @@ -741,26 +741,33 @@ void ParticleProcessMaterial::_update_shader() { code += "vec3 get_random_direction_from_spread(inout uint alt_seed, float spread_angle){\n"; code += " float pi = 3.14159;\n"; code += " float degree_to_rad = pi / 180.0;\n"; - code += " vec3 velocity = vec3(0.);\n"; code += " float spread_rad = spread_angle * degree_to_rad;\n"; - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; - code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; - code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; - code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; - code += " vec3 spread_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; - code += " vec3 direction_nrm = length(direction) > 0.0 ? normalize(direction) : vec3(0.0, 0.0, 1.0);\n"; - code += " // rotate spread to direction\n"; - code += " vec3 binormal = cross(vec3(0.0, 1.0, 0.0), direction_nrm);\n"; - code += " if (length(binormal) < 0.0001) {\n"; - code += " // direction is parallel to Y. Choose Z as the binormal.\n"; - code += " binormal = vec3(0.0, 0.0, 1.0);\n"; - code += " }\n"; - code += " binormal = normalize(binormal);\n"; - code += " vec3 normal = cross(binormal, direction_nrm);\n"; - code += " spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;\n"; - code += " return spread_direction;\n"; - + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + // Spread calculation for 2D. + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " angle1_rad += direction.x != 0.0 ? atan(direction.y, direction.x) : sign(direction.y) * (pi / 2.0);\n"; + code += " vec3 spread_direction = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; + code += " return spread_direction;\n"; + } else { + // Spread calculation for 3D. + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; + code += " vec3 spread_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " vec3 direction_nrm = length(direction) > 0.0 ? normalize(direction) : vec3(0.0, 0.0, 1.0);\n"; + code += " // rotate spread to direction\n"; + code += " vec3 binormal = cross(vec3(0.0, 1.0, 0.0), direction_nrm);\n"; + code += " if (length(binormal) < 0.0001) {\n"; + code += " // direction is parallel to Y. Choose Z as the binormal.\n"; + code += " binormal = vec3(0.0, 0.0, 1.0);\n"; + code += " }\n"; + code += " binormal = normalize(binormal);\n"; + code += " vec3 normal = cross(binormal, direction_nrm);\n"; + code += " spread_direction = binormal * spread_direction.x + normal * spread_direction.y + direction_nrm * spread_direction.z;\n"; + code += " return normalize(spread_direction);\n"; + } code += "}\n"; code += "vec3 process_radial_displacement(DynamicsParameters param, float lifetime, inout uint alt_seed, mat4 transform, mat4 emission_transform, float delta){\n"; |
