diff options
Diffstat (limited to 'scene')
37 files changed, 382 insertions, 178 deletions
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index c9ba51bafb..173214dfe4 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -955,6 +955,7 @@ void TileMap::update_bitmask_region(const Vector2 &p_start, const Vector2 &p_end void TileMap::update_cell_bitmask(int p_x, int p_y) { + ERR_FAIL_COND_MSG(tile_set.is_null(), "Cannot update cell bitmask if Tileset is not open."); PosKey p(p_x, p_y); Map<PosKey, Cell>::Element *E = tile_map.find(p); if (E != NULL) { diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index ffe011e5f7..96b62b97f9 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -35,8 +35,8 @@ #include "core/os/os.h" #ifdef TOOLS_ENABLED -#include "editor_scale.h" -#include "editor_settings.h" +#include "editor/editor_scale.h" +#include "editor/editor_settings.h" #endif #include "scene/main/viewport.h" diff --git a/scene/gui/grid_container.cpp b/scene/gui/grid_container.cpp index d304a37f82..154e67b6f3 100644 --- a/scene/gui/grid_container.cpp +++ b/scene/gui/grid_container.cpp @@ -44,7 +44,7 @@ void GridContainer::_notification(int p_what) { int hsep = get_constant("hseparation"); int vsep = get_constant("vseparation"); int max_col = MIN(get_child_count(), columns); - int max_row = get_child_count() / columns; + int max_row = ceil((float)get_child_count() / (float)columns); // Compute the per-column/per-row data. int valid_controls_index = 0; diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp index 4d06bee0d4..1a0539effa 100644 --- a/scene/gui/item_list.cpp +++ b/scene/gui/item_list.cpp @@ -926,7 +926,7 @@ void ItemList::_notification(int p_what) { current_columns = max_columns; while (true) { - //repeat util all fits + //repeat until all fits bool all_fit = true; Vector2 ofs; int col = 0; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index a7c6c5ccab..08faaf7d45 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -79,7 +79,7 @@ Size2 PopupMenu::get_minimum_size() const { if (items[i].checkable_type) has_check = true; - String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text; + String text = items[i].xl_text; size.width += font->get_string_size(text).width; if (i > 0) size.height += vseparation; @@ -519,7 +519,7 @@ void PopupMenu::_notification(int p_what) { hover->draw(ci, Rect2(item_ofs + Point2(-hseparation, -vseparation / 2), Size2(get_size().width - style->get_minimum_size().width + hseparation * 2, h + vseparation))); } - String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text; + String text = items[i].xl_text; item_ofs.x += items[i].h_ofs; if (items[i].separator) { @@ -627,63 +627,50 @@ void PopupMenu::_notification(int p_what) { } } -void PopupMenu::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { +/* Methods to add items with or without icon, checkbox, shortcut. + * Be sure to keep them in sync when adding new properties in the Item struct. + */ - Item item; - item.icon = p_icon; - item.text = p_label; - item.xl_text = tr(p_label); +#define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \ + item.text = p_label; \ + item.xl_text = tr(p_label); \ + item.id = p_id == -1 ? items.size() : p_id; \ item.accel = p_accel; - item.id = p_id; - items.push_back(item); - update(); - minimum_size_changed(); -} + void PopupMenu::add_item(const String &p_label, int p_id, uint32_t p_accel) { Item item; - item.text = p_label; - item.xl_text = tr(p_label); - item.accel = p_accel; - item.id = p_id == -1 ? items.size() : p_id; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, int p_id) { +void PopupMenu::add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { Item item; - item.text = p_label; - item.xl_text = tr(p_label); - item.id = p_id; - item.submenu = p_submenu; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); + item.icon = p_icon; items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { +void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel) { Item item; - item.icon = p_icon; - item.text = p_label; - item.xl_text = tr(p_label); - item.accel = p_accel; - item.id = p_id; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel) { +void PopupMenu::add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { Item item; - item.text = p_label; - item.xl_text = tr(p_label); - item.accel = p_accel; - item.id = p_id == -1 ? items.size() : p_id; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); + item.icon = p_icon; item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); @@ -692,63 +679,59 @@ void PopupMenu::add_check_item(const String &p_label, int p_id, uint32_t p_accel void PopupMenu::add_radio_check_item(const String &p_label, int p_id, uint32_t p_accel) { - add_check_item(p_label, p_id, p_accel); - items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + Item item; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); + item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + items.push_back(item); update(); minimum_size_changed(); } void PopupMenu::add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id, uint32_t p_accel) { - add_icon_check_item(p_icon, p_label, p_id, p_accel); - items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + Item item; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); + item.icon = p_icon; + item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { - - ERR_FAIL_COND(p_shortcut.is_null()); - - _ref_shortcut(p_shortcut); +void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_id, uint32_t p_accel) { Item item; - item.id = p_id; - item.icon = p_icon; - item.shortcut = p_shortcut; - item.shortcut_is_global = p_global; + ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel); + item.max_states = p_max_states; + item.state = p_default_state; items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { - - ERR_FAIL_COND(p_shortcut.is_null()); +#define ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global) \ + ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid ShortCut."); \ + _ref_shortcut(p_shortcut); \ + item.text = p_shortcut->get_name(); \ + item.xl_text = tr(item.text); \ + item.id = p_id == -1 ? items.size() : p_id; \ + item.shortcut = p_shortcut; \ + item.shortcut_is_global = p_global; - _ref_shortcut(p_shortcut); +void PopupMenu::add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; - item.id = p_id; - item.shortcut = p_shortcut; - item.shortcut_is_global = p_global; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { - - ERR_FAIL_COND(p_shortcut.is_null()); - - _ref_shortcut(p_shortcut); +void PopupMenu::add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; - item.id = p_id; - item.shortcut = p_shortcut; - item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); item.icon = p_icon; - item.shortcut_is_global = p_global; items.push_back(item); update(); minimum_size_changed(); @@ -756,14 +739,19 @@ void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<Sh void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { - ERR_FAIL_COND(p_shortcut.is_null()); + Item item; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); + item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; + items.push_back(item); + update(); + minimum_size_changed(); +} - _ref_shortcut(p_shortcut); +void PopupMenu::add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { Item item; - item.id = p_id; - item.shortcut = p_shortcut; - item.shortcut_is_global = p_global; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); + item.icon = p_icon; item.checkable_type = Item::CHECKABLE_TYPE_CHECK_BOX; items.push_back(item); update(); @@ -772,26 +760,42 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bo void PopupMenu::add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { - add_check_shortcut(p_shortcut, p_id, p_global); - items.write[items.size() - 1].checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + Item item; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); + item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + items.push_back(item); update(); minimum_size_changed(); } -void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_id, uint32_t p_accel) { +void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id, bool p_global) { + + Item item; + ITEM_SETUP_WITH_SHORTCUT(p_shortcut, p_id, p_global); + item.icon = p_icon; + item.checkable_type = Item::CHECKABLE_TYPE_RADIO_BUTTON; + items.push_back(item); + update(); + minimum_size_changed(); +} + +void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, int p_id) { Item item; item.text = p_label; item.xl_text = tr(p_label); - item.accel = p_accel; - item.id = p_id; - item.max_states = p_max_states; - item.state = p_default_state; + item.id = p_id == -1 ? items.size() : p_id; + item.submenu = p_submenu; items.push_back(item); update(); minimum_size_changed(); } +#undef ITEM_SETUP_WITH_ACCEL +#undef ITEM_SETUP_WITH_SHORTCUT + +/* Methods to modify existing items. */ + void PopupMenu::set_item_text(int p_idx, const String &p_text) { ERR_FAIL_INDEX(p_idx, items.size()); @@ -1380,18 +1384,24 @@ void PopupMenu::clear_autohide_areas() { void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("_gui_input"), &PopupMenu::_gui_input); - ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_item, DEFVAL(-1), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_item", "label", "id", "accel"), &PopupMenu::add_item, DEFVAL(-1), DEFVAL(0)); - ClassDB::bind_method(D_METHOD("add_icon_check_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_check_item, DEFVAL(-1), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_icon_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_item, DEFVAL(-1), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_check_item", "label", "id", "accel"), &PopupMenu::add_check_item, DEFVAL(-1), DEFVAL(0)); + ClassDB::bind_method(D_METHOD("add_icon_check_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_check_item, DEFVAL(-1), DEFVAL(0)); ClassDB::bind_method(D_METHOD("add_radio_check_item", "label", "id", "accel"), &PopupMenu::add_radio_check_item, DEFVAL(-1), DEFVAL(0)); - ClassDB::bind_method(D_METHOD("add_submenu_item", "label", "submenu", "id"), &PopupMenu::add_submenu_item, DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("add_icon_radio_check_item", "texture", "label", "id", "accel"), &PopupMenu::add_icon_radio_check_item, DEFVAL(-1), DEFVAL(0)); + + ClassDB::bind_method(D_METHOD("add_multistate_item", "label", "max_states", "default_state", "id", "accel"), &PopupMenu::add_multistate_item, DEFVAL(0), DEFVAL(-1), DEFVAL(0)); - ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_shortcut", "shortcut", "id", "global"), &PopupMenu::add_shortcut, DEFVAL(-1), DEFVAL(false)); - ClassDB::bind_method(D_METHOD("add_icon_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_check_shortcut, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_icon_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_check_shortcut, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_icon_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_check_shortcut, DEFVAL(-1), DEFVAL(false)); ClassDB::bind_method(D_METHOD("add_radio_check_shortcut", "shortcut", "id", "global"), &PopupMenu::add_radio_check_shortcut, DEFVAL(-1), DEFVAL(false)); + ClassDB::bind_method(D_METHOD("add_icon_radio_check_shortcut", "texture", "shortcut", "id", "global"), &PopupMenu::add_icon_radio_check_shortcut, DEFVAL(-1), DEFVAL(false)); + + ClassDB::bind_method(D_METHOD("add_submenu_item", "label", "submenu", "id"), &PopupMenu::add_submenu_item, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("set_item_text", "idx", "text"), &PopupMenu::set_item_text); ClassDB::bind_method(D_METHOD("set_item_icon", "idx", "icon"), &PopupMenu::set_item_icon); diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index 8bfe8fc607..8c33178b09 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -120,21 +120,23 @@ protected: static void _bind_methods(); public: - void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); - void add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); + void add_icon_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); + void add_icon_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_radio_check_item(const String &p_label, int p_id = -1, uint32_t p_accel = 0); void add_icon_radio_check_item(const Ref<Texture> &p_icon, const String &p_label, int p_id = -1, uint32_t p_accel = 0); - void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1); - void add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_multistate_item(const String &p_label, int p_max_states, int p_default_state = 0, int p_id = -1, uint32_t p_accel = 0); + void add_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); void add_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); void add_radio_check_shortcut(const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); + void add_icon_radio_check_shortcut(const Ref<Texture> &p_icon, const Ref<ShortCut> &p_shortcut, int p_id = -1, bool p_global = false); - void add_multistate_item(const String &p_label, int p_max_states, int p_default_state, int p_id = -1, uint32_t p_accel = 0); + void add_submenu_item(const String &p_label, const String &p_submenu, int p_id = -1); void set_item_text(int p_idx, const String &p_text); void set_item_icon(int p_idx, const Ref<Texture> &p_icon); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index e2bb4e3e91..a22ddb265b 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1271,7 +1271,8 @@ void TextEdit::_notification(int p_what) { } // Loop through characters in one line. - for (int j = 0; j < str.length(); j++) { + int j = 0; + for (; j < str.length(); j++) { if (syntax_coloring) { if (color_map.has(last_wrap_column + j)) { @@ -1501,7 +1502,7 @@ void TextEdit::_notification(int p_what) { } } - if (cursor.column == last_wrap_column + str.length() && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) { + if (cursor.column == (last_wrap_column + j) && cursor.line == line && cursor_wrap_index == line_wrap_index && (char_ofs + char_margin) >= xmargin_beg) { cursor_pos = Point2i(char_ofs + char_margin + ofs_x, ofs_y); cursor_pos.y += (get_row_height() - cache.font->get_height()) / 2; @@ -4070,6 +4071,7 @@ void TextEdit::_insert_text_at_cursor(const String &p_text) { int new_column, new_line; _insert_text(cursor.line, cursor.column, p_text, &new_line, &new_column); + _update_scrollbars(); cursor_set_line(new_line); cursor_set_column(new_column); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 39c5759871..52ef225364 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1465,18 +1465,19 @@ void Viewport::_gui_show_tooltip() { rp->add_child(gui.tooltip_popup); gui.tooltip_popup->force_parent_owned(); gui.tooltip_popup->set_as_toplevel(true); - //gui.tooltip_popup->hide(); + if (gui.tooltip) // Avoids crash when rapidly switching controls. + gui.tooltip_popup->set_scale(gui.tooltip->get_global_transform().get_scale()); Point2 tooltip_offset = ProjectSettings::get_singleton()->get("display/mouse_cursor/tooltip_position_offset"); Rect2 r(gui.tooltip_pos + tooltip_offset, gui.tooltip_popup->get_minimum_size()); Rect2 vr = gui.tooltip_popup->get_viewport_rect(); - if (r.size.x + r.position.x > vr.size.x) - r.position.x = vr.size.x - r.size.x; + if (r.size.x * gui.tooltip_popup->get_scale().x + r.position.x > vr.size.x) + r.position.x = vr.size.x - r.size.x * gui.tooltip_popup->get_scale().x; else if (r.position.x < 0) r.position.x = 0; - if (r.size.y + r.position.y > vr.size.y) - r.position.y = vr.size.y - r.size.y; + if (r.size.y * gui.tooltip_popup->get_scale().y + r.position.y > vr.size.y) + r.position.y = vr.size.y - r.size.y * gui.tooltip_popup->get_scale().y; else if (r.position.y < 0) r.position.y = 0; diff --git a/scene/resources/bit_map.cpp b/scene/resources/bit_map.cpp index e4a64a1de1..b5354bc3e2 100644 --- a/scene/resources/bit_map.cpp +++ b/scene/resources/bit_map.cpp @@ -197,16 +197,14 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) | 4 | 8 | <- current pixel (curx,cury) +---+---+ */ - //NOTE: due to the way we pick points from texture, rect needs to be smaller, otherwise it goes outside 1 pixel - Rect2i fixed_rect = Rect2i(rect.position, rect.size - Size2i(2, 2)); Point2i tl = Point2i(curx - 1, cury - 1); - sv += (fixed_rect.has_point(tl) && get_bit(tl)) ? 1 : 0; + sv += (rect.has_point(tl) && get_bit(tl)) ? 1 : 0; Point2i tr = Point2i(curx, cury - 1); - sv += (fixed_rect.has_point(tr) && get_bit(tr)) ? 2 : 0; + sv += (rect.has_point(tr) && get_bit(tr)) ? 2 : 0; Point2i bl = Point2i(curx - 1, cury); - sv += (fixed_rect.has_point(bl) && get_bit(bl)) ? 4 : 0; + sv += (rect.has_point(bl) && get_bit(bl)) ? 4 : 0; Point2i br = Point2i(curx, cury); - sv += (fixed_rect.has_point(br) && get_bit(br)) ? 8 : 0; + sv += (rect.has_point(br) && get_bit(br)) ? 8 : 0; ERR_FAIL_COND_V(sv == 0 || sv == 15, Vector<Vector2>()); } @@ -300,15 +298,15 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) +---+---+ | 4 | | +---+---+ - this normally go RIGHT, but if its coming from UP, it should go LEFT + this normally go RIGHT, but if its coming from RIGHT, it should go LEFT */ if (case6s.has(Point2i(curx, cury))) { - //found, so we go down, and delete from case6s; + //found, so we go left, and delete from case6s; stepx = -1; stepy = 0; case6s.erase(Point2i(curx, cury)); } else { - //not found, we go up, and add to case6s; + //not found, we go right, and add to case6s; stepx = 1; stepy = 0; case6s.insert(Point2i(curx, cury)); @@ -510,12 +508,19 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl for (int j = r.position.x; j < r.position.x + r.size.width; j++) { if (!fill->get_bit(Point2(j, i)) && get_bit(Point2(j, i))) { + fill_bits(this, fill, Point2i(j, i), r); + Vector<Vector2> polygon = _march_square(r, Point2i(j, i)); print_verbose("BitMap: Pre reduce: " + itos(polygon.size())); polygon = reduce(polygon, r, p_epsilon); print_verbose("BitMap: Post reduce: " + itos(polygon.size())); + + if (polygon.size() < 3) { + print_verbose("Invalid polygon, skipped"); + continue; + } + polygons.push_back(polygon); - fill_bits(this, fill, Point2i(j, i), r); } } } @@ -525,6 +530,13 @@ Vector<Vector<Vector2> > BitMap::clip_opaque_to_polygons(const Rect2 &p_rect, fl void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { + if (p_pixels == 0) { + return; + } + + bool bit_value = (p_pixels > 0) ? true : false; + p_pixels = Math::abs(p_pixels); + Rect2i r = Rect2i(0, 0, width, height).clip(p_rect); Ref<BitMap> copy; @@ -534,7 +546,7 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { for (int i = r.position.y; i < r.position.y + r.size.height; i++) { for (int j = r.position.x; j < r.position.x + r.size.width; j++) { - if (copy->get_bit(Point2(j, i))) + if (bit_value == get_bit(Point2(j, i))) continue; bool found = false; @@ -542,16 +554,21 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { for (int y = i - p_pixels; y <= i + p_pixels; y++) { for (int x = j - p_pixels; x <= j + p_pixels; x++) { - if (x < p_rect.position.x || x >= p_rect.position.x + p_rect.size.x) - continue; - if (y < p_rect.position.y || y >= p_rect.position.y + p_rect.size.y) - continue; + bool outside = false; + + if ((x < p_rect.position.x) || (x >= p_rect.position.x + p_rect.size.x) || (y < p_rect.position.y) || (y >= p_rect.position.y + p_rect.size.y)) { + // outside of rectangle counts as bit not set + if (!bit_value) + outside = true; + else + continue; + } float d = Point2(j, i).distance_to(Point2(x, y)) - CMP_EPSILON; if (d > p_pixels) continue; - if (copy->get_bit(Point2(x, y))) { + if (outside || (bit_value == copy->get_bit(Point2(x, y)))) { found = true; break; } @@ -561,12 +578,17 @@ void BitMap::grow_mask(int p_pixels, const Rect2 &p_rect) { } if (found) { - set_bit(Point2(j, i), true); + set_bit(Point2(j, i), bit_value); } } } } +void BitMap::shrink_mask(int p_pixels, const Rect2 &p_rect) { + + grow_mask(-p_pixels, p_rect); +} + Array BitMap::_opaque_to_polygons_bind(const Rect2 &p_rect, float p_epsilon) const { Vector<Vector<Vector2> > result = clip_opaque_to_polygons(p_rect, p_epsilon); diff --git a/scene/resources/bit_map.h b/scene/resources/bit_map.h index daf24affb1..b062dd7376 100644 --- a/scene/resources/bit_map.h +++ b/scene/resources/bit_map.h @@ -67,6 +67,7 @@ public: void resize(const Size2 &p_new_size); void grow_mask(int p_pixels, const Rect2 &p_rect); + void shrink_mask(int p_pixels, const Rect2 &p_rect); void blit(const Vector2 &p_pos, const Ref<BitMap> &p_bitmap); Ref<Image> convert_to_image() const; diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp index d819e9f776..c6fe14e55e 100644 --- a/scene/resources/box_shape.cpp +++ b/scene/resources/box_shape.cpp @@ -31,7 +31,7 @@ #include "box_shape.h" #include "servers/physics_server.h" -Vector<Vector3> BoxShape::_gen_debug_mesh_lines() { +Vector<Vector3> BoxShape::get_debug_mesh_lines() { Vector<Vector3> lines; AABB aabb; diff --git a/scene/resources/box_shape.h b/scene/resources/box_shape.h index 42d54310a8..0bce929aee 100644 --- a/scene/resources/box_shape.h +++ b/scene/resources/box_shape.h @@ -42,12 +42,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + BoxShape(); }; diff --git a/scene/resources/capsule_shape.cpp b/scene/resources/capsule_shape.cpp index 669b261bfe..1ec3bd7158 100644 --- a/scene/resources/capsule_shape.cpp +++ b/scene/resources/capsule_shape.cpp @@ -31,7 +31,7 @@ #include "capsule_shape.h" #include "servers/physics_server.h" -Vector<Vector3> CapsuleShape::_gen_debug_mesh_lines() { +Vector<Vector3> CapsuleShape::get_debug_mesh_lines() { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/capsule_shape.h b/scene/resources/capsule_shape.h index 6bca53f783..befbc1dcd5 100644 --- a/scene/resources/capsule_shape.h +++ b/scene/resources/capsule_shape.h @@ -44,14 +44,14 @@ protected: virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_radius(float p_radius); float get_radius() const; void set_height(float p_height); float get_height() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + CapsuleShape(); }; diff --git a/scene/resources/concave_polygon_shape.cpp b/scene/resources/concave_polygon_shape.cpp index b4cc38c8c0..dbc07ef591 100644 --- a/scene/resources/concave_polygon_shape.cpp +++ b/scene/resources/concave_polygon_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> ConcavePolygonShape::_gen_debug_mesh_lines() { +Vector<Vector3> ConcavePolygonShape::get_debug_mesh_lines() { Set<DrawEdge> edges; diff --git a/scene/resources/concave_polygon_shape.h b/scene/resources/concave_polygon_shape.h index 1b8ddfc308..57362a29be 100644 --- a/scene/resources/concave_polygon_shape.h +++ b/scene/resources/concave_polygon_shape.h @@ -61,12 +61,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_faces(const PoolVector<Vector3> &p_faces); PoolVector<Vector3> get_faces() const; + Vector<Vector3> get_debug_mesh_lines(); + ConcavePolygonShape(); }; diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index 499688a185..af459ec311 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -32,7 +32,7 @@ #include "core/math/quick_hull.h" #include "servers/physics_server.h" -Vector<Vector3> ConvexPolygonShape::_gen_debug_mesh_lines() { +Vector<Vector3> ConvexPolygonShape::get_debug_mesh_lines() { PoolVector<Vector3> points = get_points(); diff --git a/scene/resources/convex_polygon_shape.h b/scene/resources/convex_polygon_shape.h index 5c192476d3..e6daf1bef4 100644 --- a/scene/resources/convex_polygon_shape.h +++ b/scene/resources/convex_polygon_shape.h @@ -43,12 +43,12 @@ protected: virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_points(const PoolVector<Vector3> &p_points); PoolVector<Vector3> get_points() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + ConvexPolygonShape(); }; diff --git a/scene/resources/cylinder_shape.cpp b/scene/resources/cylinder_shape.cpp index f60f7ab376..c1a0a0ac5d 100644 --- a/scene/resources/cylinder_shape.cpp +++ b/scene/resources/cylinder_shape.cpp @@ -31,7 +31,7 @@ #include "cylinder_shape.h" #include "servers/physics_server.h" -Vector<Vector3> CylinderShape::_gen_debug_mesh_lines() { +Vector<Vector3> CylinderShape::get_debug_mesh_lines() { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/cylinder_shape.h b/scene/resources/cylinder_shape.h index 58a4f5a817..411c1515ed 100644 --- a/scene/resources/cylinder_shape.h +++ b/scene/resources/cylinder_shape.h @@ -43,14 +43,14 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_radius(float p_radius); float get_radius() const; void set_height(float p_height); float get_height() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + CylinderShape(); }; diff --git a/scene/resources/height_map_shape.cpp b/scene/resources/height_map_shape.cpp index f763700d52..214706626d 100644 --- a/scene/resources/height_map_shape.cpp +++ b/scene/resources/height_map_shape.cpp @@ -31,7 +31,7 @@ #include "height_map_shape.h" #include "servers/physics_server.h" -Vector<Vector3> HeightMapShape::_gen_debug_mesh_lines() { +Vector<Vector3> HeightMapShape::get_debug_mesh_lines() { Vector<Vector3> points; if ((map_width != 0) && (map_depth != 0)) { diff --git a/scene/resources/height_map_shape.h b/scene/resources/height_map_shape.h index b062f4e893..4cf2a76213 100644 --- a/scene/resources/height_map_shape.h +++ b/scene/resources/height_map_shape.h @@ -46,8 +46,6 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_map_width(int p_new); int get_map_width() const; @@ -56,6 +54,8 @@ public: void set_map_data(PoolRealArray p_new); PoolRealArray get_map_data() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + HeightMapShape(); }; diff --git a/scene/resources/plane_shape.cpp b/scene/resources/plane_shape.cpp index 08f6ccd764..d3274ec5f8 100644 --- a/scene/resources/plane_shape.cpp +++ b/scene/resources/plane_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> PlaneShape::_gen_debug_mesh_lines() { +Vector<Vector3> PlaneShape::get_debug_mesh_lines() { Plane p = get_plane(); Vector<Vector3> points; diff --git a/scene/resources/plane_shape.h b/scene/resources/plane_shape.h index 87c367cfde..f853d1966b 100644 --- a/scene/resources/plane_shape.h +++ b/scene/resources/plane_shape.h @@ -42,12 +42,12 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); - public: void set_plane(Plane p_plane); Plane get_plane() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + PlaneShape(); }; #endif // PLANE_SHAPE_H diff --git a/scene/resources/ray_shape.cpp b/scene/resources/ray_shape.cpp index 0acfffdc06..5a696aee23 100644 --- a/scene/resources/ray_shape.cpp +++ b/scene/resources/ray_shape.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server.h" -Vector<Vector3> RayShape::_gen_debug_mesh_lines() { +Vector<Vector3> RayShape::get_debug_mesh_lines() { Vector<Vector3> points; points.push_back(Vector3()); diff --git a/scene/resources/ray_shape.h b/scene/resources/ray_shape.h index 89fc34051c..fee7475c69 100644 --- a/scene/resources/ray_shape.h +++ b/scene/resources/ray_shape.h @@ -41,7 +41,6 @@ class RayShape : public Shape { protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_length(float p_length); @@ -50,6 +49,8 @@ public: void set_slips_on_slope(bool p_active); bool get_slips_on_slope() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + RayShape(); }; #endif // RAY_SHAPE_H diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index 6ba46f066c..3500fdb4bc 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -37,7 +37,7 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform) { - Vector<Vector3> toadd = _gen_debug_mesh_lines(); + Vector<Vector3> toadd = get_debug_mesh_lines(); if (toadd.size()) { @@ -64,7 +64,7 @@ Ref<ArrayMesh> Shape::get_debug_mesh() { if (debug_mesh_cache.is_valid()) return debug_mesh_cache; - Vector<Vector3> lines = _gen_debug_mesh_lines(); + Vector<Vector3> lines = get_debug_mesh_lines(); debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh)); diff --git a/scene/resources/shape.h b/scene/resources/shape.h index ba763eaab1..2743fd0c65 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -50,13 +50,13 @@ protected: _FORCE_INLINE_ RID get_shape() const { return shape; } Shape(RID p_shape); - virtual Vector<Vector3> _gen_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } virtual void _update_shape(); public: virtual RID get_rid() const { return shape; } Ref<ArrayMesh> get_debug_mesh(); + virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform); diff --git a/scene/resources/sphere_shape.cpp b/scene/resources/sphere_shape.cpp index af89413ced..019bc9189a 100644 --- a/scene/resources/sphere_shape.cpp +++ b/scene/resources/sphere_shape.cpp @@ -31,7 +31,7 @@ #include "sphere_shape.h" #include "servers/physics_server.h" -Vector<Vector3> SphereShape::_gen_debug_mesh_lines() { +Vector<Vector3> SphereShape::get_debug_mesh_lines() { float r = get_radius(); diff --git a/scene/resources/sphere_shape.h b/scene/resources/sphere_shape.h index 682928e885..679882fe23 100644 --- a/scene/resources/sphere_shape.h +++ b/scene/resources/sphere_shape.h @@ -42,12 +42,13 @@ protected: static void _bind_methods(); virtual void _update_shape(); - virtual Vector<Vector3> _gen_debug_mesh_lines(); public: void set_radius(float p_radius); float get_radius() const; + virtual Vector<Vector3> get_debug_mesh_lines(); + SphereShape(); }; diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 4453032f67..9ee7c2936e 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -40,16 +40,22 @@ bool StyleBox::test_mask(const Point2 &p_point, const Rect2 &p_rect) const { void StyleBox::set_default_margin(Margin p_margin, float p_value) { + ERR_FAIL_INDEX((int)p_margin, 4); + margin[p_margin] = p_value; emit_changed(); } float StyleBox::get_default_margin(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0); + return margin[p_margin]; } float StyleBox::get_margin(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0); + if (margin[p_margin] < 0) return get_style_margin(p_margin); else @@ -157,11 +163,15 @@ void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) { } float StyleBoxTexture::get_margin_size(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0); + return margin[p_margin]; } float StyleBoxTexture::get_style_margin(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0); + return margin[p_margin]; } @@ -250,6 +260,7 @@ Rect2 StyleBoxTexture::get_region_rect() const { void StyleBoxTexture::set_h_axis_stretch_mode(AxisStretchMode p_mode) { + ERR_FAIL_INDEX((int)p_mode, 3); axis_h = p_mode; emit_changed(); } @@ -261,6 +272,7 @@ StyleBoxTexture::AxisStretchMode StyleBoxTexture::get_h_axis_stretch_mode() cons void StyleBoxTexture::set_v_axis_stretch_mode(AxisStretchMode p_mode) { + ERR_FAIL_INDEX((int)p_mode, 3); axis_v = p_mode; emit_changed(); } @@ -391,11 +403,13 @@ int StyleBoxFlat::get_border_width_min() const { } void StyleBoxFlat::set_border_width(Margin p_margin, int p_width) { + ERR_FAIL_INDEX((int)p_margin, 4); border_width[p_margin] = p_width; emit_changed(); } int StyleBoxFlat::get_border_width(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0); return border_width[p_margin]; } @@ -437,15 +451,19 @@ int StyleBoxFlat::get_corner_radius_min() const { void StyleBoxFlat::set_corner_radius(const Corner p_corner, const int radius) { + ERR_FAIL_INDEX((int)p_corner, 4); corner_radius[p_corner] = radius; emit_changed(); } int StyleBoxFlat::get_corner_radius(const Corner p_corner) const { + + ERR_FAIL_INDEX_V((int)p_corner, 4, 0); return corner_radius[p_corner]; } void StyleBoxFlat::set_expand_margin_size(Margin p_expand_margin, float p_size) { + ERR_FAIL_INDEX((int)p_expand_margin, 4); expand_margin[p_expand_margin] = p_size; emit_changed(); } @@ -468,6 +486,7 @@ void StyleBoxFlat::set_expand_margin_size_all(float p_expand_margin_size) { float StyleBoxFlat::get_expand_margin_size(Margin p_expand_margin) const { + ERR_FAIL_INDEX_V((int)p_expand_margin, 4, 0.0); return expand_margin[p_expand_margin]; } void StyleBoxFlat::set_draw_center(bool p_enabled) { @@ -814,6 +833,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { } float StyleBoxFlat::get_style_margin(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, 0.0); return border_width[p_margin]; } void StyleBoxFlat::_bind_methods() { @@ -997,6 +1017,7 @@ void StyleBoxLine::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "vertical"), "set_vertical", "is_vertical"); } float StyleBoxLine::get_style_margin(Margin p_margin) const { + ERR_FAIL_INDEX_V((int)p_margin, 4, thickness); return thickness; } Size2 StyleBoxLine::get_center_size() const { diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 58bbf86241..bd6835f816 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1349,7 +1349,6 @@ void VisualShader::_bind_methods() { ClassDB::bind_method(D_METHOD("get_valid_node_id", "type"), &VisualShader::get_valid_node_id); ClassDB::bind_method(D_METHOD("remove_node", "type", "id"), &VisualShader::remove_node); - ClassDB::bind_method(D_METHOD("rebuild"), &VisualShader::rebuild); ClassDB::bind_method(D_METHOD("is_node_connection", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection); ClassDB::bind_method(D_METHOD("can_connect_nodes", "type", "from_node", "from_port", "to_node", "to_port"), &VisualShader::is_node_connection); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 8b6b659836..4f73316404 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -353,6 +353,7 @@ public: class VisualShaderNodeUniform : public VisualShaderNode { GDCLASS(VisualShaderNodeUniform, VisualShaderNode); +private: String uniform_name; protected: diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 2e58c512b8..a7df736c78 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -386,7 +386,7 @@ String VisualShaderNodeTexture::get_input_port_name(int p_port) const { case 1: return "lod"; case 2: - return "sampler"; + return "sampler2D"; default: return ""; } @@ -453,7 +453,12 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code; if (p_input_vars[0] == String()) { // Use UV by default. - code += "\tvec4 " + id + "_read = texture( " + id + " , UV.xy );\n"; + if (p_input_vars[1] == String()) { + code += "\tvec4 " + id + "_read = texture( " + id + " , UV.xy );\n"; + } else { + code += "\tvec4 " + id + "_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + } + } else if (p_input_vars[1] == String()) { //no lod code += "\tvec4 " + id + "_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; @@ -468,13 +473,18 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (source == SOURCE_PORT) { String id = p_input_vars[2]; + String code; if (id == String()) { code += "\tvec4 " + id + "_tex_read = vec4(0.0);\n"; } else { if (p_input_vars[0] == String()) { // Use UV by default. - code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + if (p_input_vars[1] == String()) { + code += "\tvec4 " + id + "_tex_read = texture( " + id + " , UV.xy );\n"; + } else { + code += "\tvec4 " + id + "_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + } } else if (p_input_vars[1] == String()) { //no lod @@ -494,11 +504,15 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code = "\t{\n"; if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy, 0.0 );\n"; + if (p_input_vars[1] == String()) { + code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy , 0.0 );\n"; + } else { + code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , UV.xy , " + p_input_vars[1] + ");\n"; + } } else if (p_input_vars[1] == String()) { //no lod - code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy, 0.0 );\n"; + code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy , 0.0 );\n"; } else { code += "\t\tvec4 _tex_read = textureLod( SCREEN_TEXTURE , " + p_input_vars[0] + ".xy , " + p_input_vars[1] + " );\n"; } @@ -514,7 +528,11 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. - code += "\t\tvec4 _tex_read = texture( TEXTURE , UV.xy );\n"; + if (p_input_vars[1] == String()) { + code += "\t\tvec4 _tex_read = texture( TEXTURE , UV.xy );\n"; + } else { + code += "\t\tvec4 _tex_read = textureLod( TEXTURE , UV.xy , " + p_input_vars[1] + " );\n"; + } } else if (p_input_vars[1] == String()) { //no lod @@ -534,7 +552,11 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. - code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , UV.xy );\n"; + if (p_input_vars[1] == String()) { + code += "\t\tvec4 _tex_read = texture( NORMAL_TEXTURE , UV.xy );\n"; + } else { + code += "\t\tvec4 _tex_read = textureLod( NORMAL_TEXTURE , UV.xy , " + p_input_vars[1] + " );\n"; + } } else if (p_input_vars[1] == String()) { //no lod @@ -564,7 +586,11 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. - code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , UV.xy ).r;\n"; + if (p_input_vars[1] == String()) { + code += "\t\tfloat _depth = texture( DEPTH_TEXTURE , UV.xy ).r;\n"; + } else { + code += "\t\tfloat _depth = textureLod( DEPTH_TEXTURE , UV.xy , " + p_input_vars[1] + " ).r;\n"; + } } else if (p_input_vars[1] == String()) { //no lod @@ -704,15 +730,33 @@ String VisualShaderNodeCubeMap::get_caption() const { } int VisualShaderNodeCubeMap::get_input_port_count() const { - return 2; + return 3; } VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + switch (p_port) { + case 0: + return PORT_TYPE_VECTOR; + case 1: + return PORT_TYPE_SCALAR; + case 2: + return PORT_TYPE_SAMPLER; + default: + return PORT_TYPE_SCALAR; + } } String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { - return p_port == 0 ? "uv" : "lod"; + switch (p_port) { + case 0: + return "uv"; + case 1: + return "lod"; + case 2: + return "samplerCube"; + default: + return ""; + } } int VisualShaderNodeCubeMap::get_output_port_count() const { @@ -738,22 +782,44 @@ Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCubeMap::get_default_t String VisualShaderNodeCubeMap::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - String u = "uniform sampler2DCube " + make_unique_id(p_type, p_id, "cube"); - switch (texture_type) { - case TYPE_DATA: break; - case TYPE_COLOR: u += " : hint_albedo"; break; - case TYPE_NORMALMAP: u += " : hint_normal"; break; + if (source == SOURCE_TEXTURE) { + String u = "uniform samplerCube " + make_unique_id(p_type, p_id, "cube"); + switch (texture_type) { + case TYPE_DATA: break; + case TYPE_COLOR: u += " : hint_albedo"; break; + case TYPE_NORMALMAP: u += " : hint_normal"; break; + } + return u + ";"; } - return u + ";"; + return String(); } String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { - String id = make_unique_id(p_type, p_id, "cube"); String code; - if (p_input_vars[0] == String()) { //none bound, do nothing + String id; + if (source == SOURCE_TEXTURE) { + id = make_unique_id(p_type, p_id, "cube"); + } else if (source == SOURCE_PORT) { + id = p_input_vars[2]; + } else { + return String(); + } + if (id == String()) { code += "\tvec4 " + id + "_read = vec4(0.0);\n"; + code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; + code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n"; + return code; + } + + if (p_input_vars[0] == String()) { // Use UV by default. + + if (p_input_vars[1] == String()) { + code += "\tvec4 " + id + "_read = texture( " + id + " , vec3( UV, 0.0 ) );\n"; + } else { + code += "\tvec4 " + id + "_read = textureLod( " + id + " , vec3( UV, 0.0 )" + " , " + p_input_vars[1] + " );\n"; + } } else if (p_input_vars[1] == String()) { //no lod @@ -761,12 +827,29 @@ String VisualShaderNodeCubeMap::generate_code(Shader::Mode p_mode, VisualShader: } else { code += "\tvec4 " + id + "_read = textureLod( " + id + " , " + p_input_vars[0] + " , " + p_input_vars[1] + " );\n"; } - code += "\t" + p_output_vars[0] + " = " + id + "_read.rgb;\n"; code += "\t" + p_output_vars[1] + " = " + id + "_read.a;\n"; + return code; } +String VisualShaderNodeCubeMap::get_input_port_default_hint(int p_port) const { + if (p_port == 0) { + return "vec3(UV, 0.0)"; + } + return ""; +} + +void VisualShaderNodeCubeMap::set_source(Source p_source) { + source = p_source; + emit_changed(); + emit_signal("editor_refresh_request"); +} + +VisualShaderNodeCubeMap::Source VisualShaderNodeCubeMap::get_source() const { + return source; +} + void VisualShaderNodeCubeMap::set_cube_map(Ref<CubeMap> p_value) { cube_map = p_value; @@ -789,22 +872,32 @@ VisualShaderNodeCubeMap::TextureType VisualShaderNodeCubeMap::get_texture_type() Vector<StringName> VisualShaderNodeCubeMap::get_editable_properties() const { Vector<StringName> props; - props.push_back("cube_map"); - props.push_back("texture_type"); + props.push_back("source"); + if (source == SOURCE_TEXTURE) { + props.push_back("cube_map"); + props.push_back("texture_type"); + } return props; } void VisualShaderNodeCubeMap::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_source", "value"), &VisualShaderNodeCubeMap::set_source); + ClassDB::bind_method(D_METHOD("get_source"), &VisualShaderNodeCubeMap::get_source); + ClassDB::bind_method(D_METHOD("set_cube_map", "value"), &VisualShaderNodeCubeMap::set_cube_map); ClassDB::bind_method(D_METHOD("get_cube_map"), &VisualShaderNodeCubeMap::get_cube_map); ClassDB::bind_method(D_METHOD("set_texture_type", "value"), &VisualShaderNodeCubeMap::set_texture_type); ClassDB::bind_method(D_METHOD("get_texture_type"), &VisualShaderNodeCubeMap::get_texture_type); + ADD_PROPERTY(PropertyInfo(Variant::INT, "source", PROPERTY_HINT_ENUM, "Texture,SamplerPort"), "set_source", "get_source"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "cube_map", PROPERTY_HINT_RESOURCE_TYPE, "CubeMap"), "set_cube_map", "get_cube_map"); ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_type", PROPERTY_HINT_ENUM, "Data,Color,Normalmap"), "set_texture_type", "get_texture_type"); + BIND_ENUM_CONSTANT(SOURCE_TEXTURE); + BIND_ENUM_CONSTANT(SOURCE_PORT); + BIND_ENUM_CONSTANT(TYPE_DATA); BIND_ENUM_CONSTANT(TYPE_COLOR); BIND_ENUM_CONSTANT(TYPE_NORMALMAP); @@ -3101,7 +3194,7 @@ String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { case 1: return "alpha"; case 2: - return "sampler"; + return "sampler2D"; default: return ""; } @@ -3135,8 +3228,11 @@ String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, Visual String id = get_uniform_name(); String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. - - code += "\t\tvec4 n_tex_read = texture( " + id + " , UV.xy );\n"; + if (p_input_vars[1] == String()) { + code += "\t\tvec4 n_tex_read = texture( " + id + " , UV.xy );\n"; + } else { + code += "\t\tvec4 n_tex_read = textureLod( " + id + " , UV.xy , " + p_input_vars[1] + " );\n"; + } } else if (p_input_vars[1] == String()) { //no lod code += "\t\tvec4 n_tex_read = texture( " + id + " , " + p_input_vars[0] + ".xy );\n"; @@ -3314,28 +3410,55 @@ String VisualShaderNodeCubeMapUniform::get_caption() const { return "CubeMapUniform"; } +int VisualShaderNodeCubeMapUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SAMPLER; +} + +String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { + return "samplerCube"; +} + int VisualShaderNodeCubeMapUniform::get_input_port_count() const { - return 2; + return 0; } VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; + return PORT_TYPE_SCALAR; } String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { - return p_port == 0 ? "normal" : "lod"; + return ""; } -int VisualShaderNodeCubeMapUniform::get_output_port_count() const { - return 2; +String VisualShaderNodeCubeMapUniform::get_input_port_default_hint(int p_port) const { + return ""; } -VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const { - return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; -} +String VisualShaderNodeCubeMapUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = "uniform samplerCube " + get_uniform_name(); -String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { - return p_port == 0 ? "rgb" : "alpha"; + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black;\n"; + else + code += ";\n"; + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black_albedo;\n"; + else + code += " : hint_albedo;\n"; + break; + case TYPE_NORMALMAP: code += " : hint_normal;\n"; break; + case TYPE_ANISO: code += " : hint_aniso;\n"; break; + } + + return code; } String VisualShaderNodeCubeMapUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index d5ee990191..339e59bda9 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -259,6 +259,11 @@ class VisualShaderNodeCubeMap : public VisualShaderNode { Ref<CubeMap> cube_map; public: + enum Source { + SOURCE_TEXTURE, + SOURCE_PORT + }; + enum TextureType { TYPE_DATA, TYPE_COLOR, @@ -266,6 +271,7 @@ public: }; private: + Source source; TextureType texture_type; protected: @@ -277,6 +283,7 @@ public: virtual int get_input_port_count() const; virtual PortType get_input_port_type(int p_port) const; virtual String get_input_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; virtual int get_output_port_count() const; virtual PortType get_output_port_type(int p_port) const; @@ -286,6 +293,9 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + void set_source(Source p_source); + Source get_source() const; + void set_cube_map(Ref<CubeMap> p_value); Ref<CubeMap> get_cube_map() const; @@ -298,6 +308,7 @@ public: }; VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::TextureType) +VARIANT_ENUM_CAST(VisualShaderNodeCubeMap::Source) /////////////////////////////////////// /// OPS @@ -1412,7 +1423,7 @@ public: COLOR_DEFAULT_BLACK }; -private: +protected: TextureType texture_type; ColorDefault color_default; @@ -1471,8 +1482,8 @@ public: /////////////////////////////////////// -class VisualShaderNodeCubeMapUniform : public VisualShaderNode { - GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNode); +class VisualShaderNodeCubeMapUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNodeTextureUniform); public: virtual String get_caption() const; @@ -1485,6 +1496,8 @@ public: virtual PortType get_output_port_type(int p_port) const; virtual String get_output_port_name(int p_port) const; + virtual String get_input_port_default_hint(int p_port) const; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty VisualShaderNodeCubeMapUniform(); diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index 0ca5d7eb36..2c22f45f9d 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -332,7 +332,9 @@ World::World() { PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/3d/default_gravity", 9.8)); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/3d/default_gravity_vector", Vector3(0, -1, 0))); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/3d/default_linear_damp", 0.1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/3d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); PhysicsServer::get_singleton()->area_set_param(space, PhysicsServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/3d/default_angular_damp", 0.1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/3d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/3d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); #ifdef _3D_DISABLED indexer = NULL; diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index 13b45f58dc..b5743ad416 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -394,7 +394,9 @@ World2D::World2D() { Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY, GLOBAL_DEF("physics/2d/default_gravity", 98)); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_GRAVITY_VECTOR, GLOBAL_DEF("physics/2d/default_gravity_vector", Vector2(0, 1))); Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_LINEAR_DAMP, GLOBAL_DEF("physics/2d/default_linear_damp", 0.1)); - Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_linear_damp", PropertyInfo(Variant::REAL, "physics/2d/default_linear_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); + Physics2DServer::get_singleton()->area_set_param(space, Physics2DServer::AREA_PARAM_ANGULAR_DAMP, GLOBAL_DEF("physics/2d/default_angular_damp", 1.0)); + ProjectSettings::get_singleton()->set_custom_property_info("physics/2d/default_angular_damp", PropertyInfo(Variant::REAL, "physics/2d/default_angular_damp", PROPERTY_HINT_RANGE, "-1,100,0.001,or_greater")); indexer = memnew(SpatialIndexer2D); } |