diff options
Diffstat (limited to 'scene/resources')
33 files changed, 1294 insertions, 684 deletions
diff --git a/scene/resources/SCsub b/scene/resources/SCsub index 3a86b22835..f4dc7a46fb 100644 --- a/scene/resources/SCsub +++ b/scene/resources/SCsub @@ -2,6 +2,25 @@ Import("env") -env.add_source_files(env.scene_sources, "*.cpp") +# Thirdparty code + +thirdparty_obj = [] + +thirdparty_sources = "#thirdparty/misc/mikktspace.c" + +env_thirdparty = env.Clone() +env_thirdparty.disable_warnings() +env_thirdparty.add_source_files(thirdparty_obj, thirdparty_sources) +env.scene_sources += thirdparty_obj + +# Godot source files + +scene_obj = [] + +env.add_source_files(scene_obj, "*.cpp") +env.scene_sources += scene_obj + +# Needed to force rebuilding the scene files when the thirdparty code is updated. +env.Depends(scene_obj, thirdparty_obj) SConscript("default_theme/SCsub") diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index b2aad97d3b..a7a02361a9 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -810,8 +810,8 @@ int Animation::transform_track_insert_key(int p_track, float p_time, const Vecto return ret; } -void Animation::track_remove_key_at_position(int p_track, float p_pos) { - int idx = track_find_key(p_track, p_pos, true); +void Animation::track_remove_key_at_time(int p_track, float p_time) { + int idx = track_find_key(p_track, p_time, true); ERR_FAIL_COND(idx < 0); track_remove_key(p_track, idx); } @@ -2608,7 +2608,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("transform_track_insert_key", "track_idx", "time", "location", "rotation", "scale"), &Animation::transform_track_insert_key); ClassDB::bind_method(D_METHOD("track_insert_key", "track_idx", "time", "key", "transition"), &Animation::track_insert_key, DEFVAL(1)); ClassDB::bind_method(D_METHOD("track_remove_key", "track_idx", "key_idx"), &Animation::track_remove_key); - ClassDB::bind_method(D_METHOD("track_remove_key_at_position", "track_idx", "position"), &Animation::track_remove_key_at_position); + ClassDB::bind_method(D_METHOD("track_remove_key_at_time", "track_idx", "time"), &Animation::track_remove_key_at_time); ClassDB::bind_method(D_METHOD("track_set_key_value", "track_idx", "key", "value"), &Animation::track_set_key_value); ClassDB::bind_method(D_METHOD("track_set_key_transition", "track_idx", "key_idx", "transition"), &Animation::track_set_key_transition); ClassDB::bind_method(D_METHOD("track_set_key_time", "track_idx", "key_idx", "time"), &Animation::track_set_key_time); diff --git a/scene/resources/animation.h b/scene/resources/animation.h index c52431f5f6..060d1fe2d9 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -293,7 +293,7 @@ public: void track_set_key_time(int p_track, int p_key_idx, float p_time); int track_find_key(int p_track, float p_time, bool p_exact = false) const; void track_remove_key(int p_track, int p_idx); - void track_remove_key_at_position(int p_track, float p_pos); + void track_remove_key_at_time(int p_track, float p_time); int track_get_key_count(int p_track) const; Variant track_get_key_value(int p_track, int p_key_idx) const; float track_get_key_time(int p_track, int p_key_idx) const; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 1d92ed4830..2de28b5e5c 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -77,6 +77,17 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl return style; } +static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) { + Ref<StyleBoxFlat> style(memnew(StyleBoxFlat)); + style->set_bg_color(p_color); + style->set_default_margin(MARGIN_LEFT, p_margin_left * scale); + style->set_default_margin(MARGIN_RIGHT, p_margin_right * scale); + style->set_default_margin(MARGIN_BOTTOM, p_margin_bottom * scale); + style->set_default_margin(MARGIN_TOP, p_margin_top * scale); + + return style; +} + static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left, float p_top, float p_right, float p_botton) { p_sbox->set_expand_margin_size(MARGIN_LEFT, p_left * scale); p_sbox->set_expand_margin_size(MARGIN_TOP, p_top * scale); @@ -97,6 +108,25 @@ static Ref<Texture2D> make_icon(T p_src) { return texture; } +static Ref<Texture2D> flip_icon(Ref<Texture2D> p_texture, bool p_flip_y = false, bool p_flip_x = false) { + if (!p_flip_y && !p_flip_x) { + return p_texture; + } + + Ref<ImageTexture> texture(memnew(ImageTexture)); + Ref<Image> img = p_texture->get_data(); + + if (p_flip_y) { + img->flip_y(); + } + if (p_flip_x) { + img->flip_x(); + } + + texture->create_from_image(img); + return texture; +} + static Ref<StyleBox> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1) { Ref<StyleBox> style(memnew(StyleBoxEmpty)); @@ -571,6 +601,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color_accel", "PopupMenu", Color(0.7, 0.7, 0.7, 0.8)); theme->set_color("font_color_disabled", "PopupMenu", Color(0.4, 0.4, 0.4, 0.8)); theme->set_color("font_color_hover", "PopupMenu", control_font_color); + theme->set_color("font_color_separator", "PopupMenu", control_font_color); theme->set_constant("hseparation", "PopupMenu", 4 * scale); theme->set_constant("vseparation", "PopupMenu", 4 * scale); @@ -802,6 +833,12 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("bold_italics_font", "RichTextLabel", Ref<Font>()); theme->set_font("mono_font", "RichTextLabel", Ref<Font>()); + theme->set_font_size("normal_font_size", "RichTextLabel", -1); + theme->set_font_size("bold_font_size", "RichTextLabel", -1); + theme->set_font_size("italics_font_size", "RichTextLabel", -1); + theme->set_font_size("bold_italics_font_size", "RichTextLabel", -1); + theme->set_font_size("mono_font_size", "RichTextLabel", -1); + theme->set_color("default_color", "RichTextLabel", Color(1, 1, 1)); theme->set_color("font_color_selected", "RichTextLabel", font_color_selection); theme->set_color("selection_color", "RichTextLabel", Color(0.1, 0.1, 1, 0.8)); @@ -816,6 +853,9 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("table_hseparation", "RichTextLabel", 3 * scale); theme->set_constant("table_vseparation", "RichTextLabel", 3 * scale); + theme->set_color("table_odd_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color("table_even_row_bg", "RichTextLabel", Color(0, 0, 0, 0)); + theme->set_color("table_border", "RichTextLabel", Color(0, 0, 0, 0)); // Containers theme->set_stylebox("bg", "VSplitContainer", make_stylebox(vsplit_bg_png, 1, 1, 1, 1)); @@ -844,6 +884,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("reset", "GraphEdit", make_icon(icon_zoom_reset_png)); theme->set_icon("more", "GraphEdit", make_icon(icon_zoom_more_png)); theme->set_icon("snap", "GraphEdit", make_icon(icon_snap_grid_png)); + theme->set_icon("minimap", "GraphEdit", make_icon(icon_grid_minimap_png)); theme->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 4, 4, 4, 5)); theme->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05)); theme->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2)); @@ -857,6 +898,19 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("port_grab_distance_horizontal", "GraphEdit", 48 * scale); theme->set_constant("port_grab_distance_vertical", "GraphEdit", 6 * scale); + theme->set_stylebox("bg", "GraphEditMinimap", make_flat_stylebox(Color(0.24, 0.24, 0.24), 0, 0, 0, 0)); + Ref<StyleBoxFlat> style_minimap_camera = make_flat_stylebox(Color(0.65, 0.65, 0.65, 0.2), 0, 0, 0, 0); + style_minimap_camera->set_border_color(Color(0.65, 0.65, 0.65, 0.45)); + style_minimap_camera->set_border_width_all(1); + theme->set_stylebox("camera", "GraphEditMinimap", style_minimap_camera); + Ref<StyleBoxFlat> style_minimap_node = make_flat_stylebox(Color(1, 1, 1), 0, 0, 0, 0); + style_minimap_node->set_corner_radius_all(2); + theme->set_stylebox("node", "GraphEditMinimap", style_minimap_node); + + Ref<Texture2D> resizer_icon = make_icon(window_resizer_png); + theme->set_icon("resizer", "GraphEditMinimap", flip_icon(resizer_icon, true, true)); + theme->set_color("resizer_color", "GraphEditMinimap", Color(1, 1, 1, 0.85)); + // Theme default_icon = make_icon(error_icon_png); diff --git a/scene/resources/default_theme/icon_grid_minimap.png b/scene/resources/default_theme/icon_grid_minimap.png Binary files differnew file mode 100644 index 0000000000..00a6179d5e --- /dev/null +++ b/scene/resources/default_theme/icon_grid_minimap.png diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index 7765348f80..b905c9db69 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -166,6 +166,10 @@ static const unsigned char icon_folder_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x6, 0x78, 0x70, 0xf4, 0xc1, 0x7f, 0x24, 0x78, 0x18, 0x53, 0xc1, 0x7f, 0x54, 0x48, 0x50, 0xc1, 0x43, 0x1b, 0xbc, 0xa, 0x50, 0xad, 0x23, 0xa4, 0xe0, 0xff, 0x70, 0x52, 0x70, 0x18, 0x97, 0xf4, 0xfd, 0x43, 0xd4, 0x88, 0x4a, 0x0, 0x5a, 0xcb, 0x18, 0xab, 0x5e, 0xd9, 0x1a, 0x53, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char icon_grid_minimap_png[] = { + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xe, 0xc3, 0x0, 0x0, 0xe, 0xc3, 0x1, 0xc7, 0x6f, 0xa8, 0x64, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6f, 0x66, 0x74, 0x77, 0x61, 0x72, 0x65, 0x0, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x6e, 0x6b, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2e, 0x6f, 0x72, 0x67, 0x9b, 0xee, 0x3c, 0x1a, 0x0, 0x0, 0x2, 0xd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x75, 0x93, 0x31, 0x68, 0x14, 0x51, 0x10, 0x86, 0xbf, 0xd9, 0xd, 0xbb, 0xde, 0x76, 0x82, 0x21, 0xf8, 0xe0, 0xbc, 0x5d, 0x8b, 0x80, 0x69, 0x6c, 0xd2, 0x5a, 0x6a, 0x91, 0xc3, 0xd2, 0x46, 0x22, 0x8, 0x9, 0x89, 0x70, 0x85, 0x10, 0x41, 0xd, 0x24, 0x45, 0xb0, 0xb, 0x68, 0x11, 0x14, 0x24, 0x10, 0x22, 0x62, 0x21, 0x41, 0xe, 0x4b, 0x21, 0xa4, 0xb7, 0x49, 0x17, 0xb1, 0x8, 0xb9, 0xdd, 0xc7, 0x86, 0x33, 0x21, 0xe1, 0x3a, 0x8f, 0x64, 0x61, 0x6f, 0x2c, 0xbc, 0x3b, 0x36, 0xb9, 0xdc, 0xc0, 0x2b, 0xde, 0xcc, 0xfc, 0xf3, 0xff, 0xfc, 0xcc, 0x48, 0xa3, 0xd1, 0x78, 0x20, 0x22, 0x13, 0xbe, 0xef, 0xaf, 0xdf, 0xac, 0xd7, 0x1f, 0xe1, 0x38, 0xd3, 0xa8, 0x2a, 0xf0, 0x45, 0x6a, 0xb5, 0xcf, 0x5c, 0x11, 0xcd, 0x66, 0x33, 0x38, 0x3f, 0x3f, 0x9f, 0x13, 0x91, 0x7d, 0xb1, 0xd6, 0x6e, 0xaa, 0xea, 0xd3, 0xe0, 0xe8, 0xe8, 0xde, 0xe8, 0xee, 0xee, 0x37, 0xc0, 0xe9, 0xf6, 0x75, 0xf0, 0xfd, 0x9, 0x99, 0x9d, 0x6d, 0x15, 0x81, 0x59, 0x96, 0x3d, 0x3, 0x5e, 0x2, 0x63, 0x22, 0xf2, 0x69, 0xa4, 0x57, 0x1c, 0xdd, 0xdb, 0xfb, 0x5b, 0x0, 0x3, 0x38, 0x67, 0x41, 0x30, 0x11, 0xc7, 0xf1, 0x13, 0x0, 0x11, 0x71, 0xb2, 0x2c, 0x7b, 0xd8, 0xad, 0xad, 0x2, 0x6f, 0xb9, 0x0, 0x38, 0x3c, 0xfc, 0x5, 0x9c, 0xf6, 0xff, 0x22, 0x27, 0x27, 0xe3, 0xe3, 0x7f, 0xa, 0x3, 0x67, 0x45, 0xe4, 0xbb, 0xe7, 0x79, 0xb7, 0xc3, 0x30, 0x7c, 0xd7, 0x67, 0xe9, 0xe3, 0x67, 0x66, 0x5c, 0x60, 0x1, 0x50, 0x40, 0x51, 0x7d, 0x71, 0x6b, 0x72, 0xf2, 0x20, 0x8a, 0xa2, 0xf9, 0x28, 0x8a, 0xe6, 0x1, 0x3a, 0x9d, 0xce, 0x4f, 0x63, 0x4c, 0x3b, 0x4d, 0xd3, 0xd2, 0xc0, 0x80, 0x3c, 0xcf, 0xf, 0x92, 0xa9, 0xa9, 0x31, 0x60, 0x5, 0x58, 0x91, 0x5a, 0xed, 0xc7, 0x15, 0xfe, 0x95, 0xac, 0xb5, 0xcf, 0xf3, 0x3c, 0x3f, 0xe8, 0x25, 0x46, 0xa, 0xc5, 0xd, 0x11, 0x59, 0xb3, 0xd5, 0xea, 0x1b, 0xa0, 0x95, 0x54, 0xab, 0x5b, 0x97, 0xd1, 0x22, 0xb2, 0xa6, 0xaa, 0x6d, 0x60, 0xd, 0x58, 0xba, 0xa0, 0x20, 0xc, 0xc3, 0x65, 0xd7, 0x75, 0x23, 0xe0, 0x2e, 0xb0, 0x1, 0x5c, 0xbf, 0xf4, 0x0, 0xbe, 0xba, 0xae, 0x1b, 0x85, 0x61, 0xb8, 0x3c, 0xa0, 0x20, 0x4d, 0xd3, 0x52, 0xb9, 0x5c, 0x6e, 0xc5, 0x71, 0xbc, 0x23, 0x22, 0xd3, 0x61, 0x18, 0xde, 0x2f, 0xb2, 0x27, 0x49, 0xa2, 0xaa, 0xba, 0x53, 0x2e, 0x97, 0x5b, 0x69, 0x9a, 0x96, 0xf2, 0x3c, 0x1f, 0xf0, 0xc0, 0x5a, 0x6b, 0x5f, 0x1, 0x25, 0x86, 0x84, 0xe3, 0x38, 0x9e, 0xb5, 0x76, 0x2e, 0xcf, 0xf3, 0xfd, 0x1, 0x5, 0x22, 0xb2, 0xa1, 0xaa, 0x4b, 0x22, 0x72, 0xad, 0xcb, 0x38, 0xe0, 0x81, 0xaa, 0x7e, 0x0, 0xce, 0x44, 0xe4, 0xbd, 0xaa, 0xbe, 0xbe, 0xa0, 0xa0, 0x52, 0xa9, 0x2c, 0x7a, 0x9e, 0x17, 0x1, 0x3d, 0xe0, 0x55, 0x1e, 0x6c, 0x79, 0x9e, 0x17, 0x55, 0x2a, 0x95, 0xc5, 0x1, 0x5, 0xcd, 0x66, 0x33, 0x30, 0xc6, 0x9c, 0xc6, 0x71, 0xbc, 0x2d, 0x22, 0x8f, 0x87, 0x78, 0xb0, 0x6d, 0x8c, 0x39, 0xed, 0xae, 0x74, 0xdf, 0x83, 0x3a, 0x70, 0x9c, 0x65, 0x59, 0x23, 0x49, 0x92, 0x5, 0x11, 0x9, 0x86, 0x79, 0x20, 0x22, 0x41, 0x92, 0x24, 0xb, 0x59, 0x96, 0x35, 0x80, 0x63, 0xa0, 0x2e, 0x3d, 0xf6, 0xc2, 0x91, 0xdc, 0x0, 0x5c, 0x55, 0x5d, 0xbf, 0x4, 0x9e, 0x3, 0x72, 0xfe, 0xaf, 0xfb, 0xaa, 0xe7, 0x79, 0x1f, 0x8d, 0x31, 0x6d, 0x29, 0x36, 0xf5, 0xce, 0x14, 0xb8, 0x33, 0x44, 0xc4, 0x6f, 0xdf, 0xf7, 0xd7, 0x8d, 0x31, 0xed, 0x5e, 0xe2, 0x1f, 0xb, 0x5c, 0xe2, 0xcb, 0xd, 0x9b, 0x69, 0xcb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char icon_parent_folder_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0xa0, 0x33, 0xb8, 0x27, 0xfe, 0xe0, 0xfc, 0x83, 0x73, 0xf7, 0xc4, 0x71, 0x48, 0xdf, 0x11, 0x7b, 0x78, 0xe9, 0xc1, 0x3f, 0x20, 0xbc, 0xfe, 0x40, 0x12, 0x8f, 0x34, 0x4c, 0x9, 0xa6, 0xe1, 0x57, 0x80, 0x12, 0x17, 0x81, 0xf8, 0x2f, 0x58, 0xe1, 0x15, 0x34, 0x8b, 0x1e, 0x9c, 0x5, 0xa, 0x5e, 0xb8, 0x23, 0x6, 0x52, 0x70, 0x5b, 0x14, 0xac, 0xf0, 0xc, 0xaa, 0x82, 0x7d, 0xf, 0x8e, 0xde, 0x14, 0xf9, 0xcf, 0x8, 0x52, 0xc0, 0xc0, 0x70, 0x5b, 0xf4, 0xe1, 0xc9, 0x7, 0x47, 0xb1, 0xb8, 0x3, 0xaa, 0x0, 0xa, 0x48, 0x52, 0x80, 0xb0, 0xea, 0xc8, 0xc3, 0x83, 0xc, 0x83, 0xe, 0x0, 0x0, 0xb8, 0x27, 0x55, 0x4c, 0xbe, 0xc0, 0xd2, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index bacdb6be54..1eb78a3679 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -31,6 +31,7 @@ #include "environment.h" #include "core/config/project_settings.h" +#include "core/core_string_names.h" #include "servers/rendering_server.h" #include "texture.h" @@ -590,7 +591,7 @@ void Environment::set_glow_level(int p_level, float p_intensity) { } float Environment::get_glow_level(int p_level) const { - ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, false); + ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, 0.0); return glow_levels[p_level]; } @@ -891,23 +892,38 @@ float Environment::get_adjustment_saturation() const { return adjustment_saturation; } -void Environment::set_adjustment_color_correction(const Ref<Texture2D> &p_ramp) { - adjustment_color_correction = p_ramp; +void Environment::set_adjustment_color_correction(Ref<Texture> p_color_correction) { + adjustment_color_correction = p_color_correction; + Ref<GradientTexture> grad_tex = p_color_correction; + if (grad_tex.is_valid()) { + if (!grad_tex->is_connected(CoreStringNames::get_singleton()->changed, callable_mp(this, &Environment::_update_adjustment))) { + grad_tex->connect(CoreStringNames::get_singleton()->changed, callable_mp(this, &Environment::_update_adjustment)); + } + } + Ref<Texture2D> adjustment_texture_2d = adjustment_color_correction; + if (adjustment_texture_2d.is_valid()) { + use_1d_color_correction = true; + } else { + use_1d_color_correction = false; + } _update_adjustment(); } -Ref<Texture2D> Environment::get_adjustment_color_correction() const { +Ref<Texture> Environment::get_adjustment_color_correction() const { return adjustment_color_correction; } void Environment::_update_adjustment() { + RID color_correction = adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID(); + RS::get_singleton()->environment_set_adjustment( environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, - adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID()); + use_1d_color_correction, + color_correction); } // Private methods, constructor and destructor @@ -1319,7 +1335,7 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_brightness", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_brightness", "get_adjustment_brightness"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_contrast", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_contrast", "get_adjustment_contrast"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_adjustment_color_correction", "get_adjustment_color_correction"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D,Texture3D"), "set_adjustment_color_correction", "get_adjustment_color_correction"); // Constants diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 23c7f5180c..106ba92bfe 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -211,7 +211,8 @@ private: float adjustment_brightness = 1.0; float adjustment_contrast = 1.0; float adjustment_saturation = 1.0; - Ref<Texture2D> adjustment_color_correction; + bool use_1d_color_correction = true; + Ref<Texture> adjustment_color_correction; void _update_adjustment(); protected: @@ -402,8 +403,8 @@ public: float get_adjustment_contrast() const; void set_adjustment_saturation(float p_saturation); float get_adjustment_saturation() const; - void set_adjustment_color_correction(const Ref<Texture2D> &p_ramp); - Ref<Texture2D> get_adjustment_color_correction() const; + void set_adjustment_color_correction(Ref<Texture> p_color_correction); + Ref<Texture> get_adjustment_color_correction() const; Environment(); ~Environment(); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index da35137a09..791f260c0e 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -53,6 +53,11 @@ void FontData::_bind_methods() { ClassDB::bind_method(D_METHOD("set_antialiased", "antialiased"), &FontData::set_antialiased); ClassDB::bind_method(D_METHOD("get_antialiased"), &FontData::get_antialiased); + ClassDB::bind_method(D_METHOD("get_variation_list"), &FontData::get_variation_list); + + ClassDB::bind_method(D_METHOD("set_variation", "tag", "value"), &FontData::set_variation); + ClassDB::bind_method(D_METHOD("get_variation", "tag"), &FontData::get_variation); + ClassDB::bind_method(D_METHOD("set_hinting", "hinting"), &FontData::set_hinting); ClassDB::bind_method(D_METHOD("get_hinting"), &FontData::get_hinting); @@ -115,6 +120,11 @@ bool FontData::_set(const StringName &p_name, const Variant &p_value) { set_script_support_override(scr, p_value); return true; } + if (str.begins_with("variation/")) { + String name = str.get_slicec('/', 1); + set_variation(name, p_value); + return true; + } return false; } @@ -137,6 +147,12 @@ bool FontData::_get(const StringName &p_name, Variant &r_ret) const { r_ret = get_script_support_override(scr); return true; } + if (str.begins_with("variation/")) { + String name = str.get_slicec('/', 1); + + r_ret = get_variation(name); + return true; + } return false; } @@ -153,6 +169,12 @@ void FontData::_get_property_list(List<PropertyInfo> *p_list) const { p_list->push_back(PropertyInfo(Variant::BOOL, "script_support_override/" + scr_over[i], PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE)); } p_list->push_back(PropertyInfo(Variant::NIL, "script_support_override/_new", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); + + Dictionary variations = get_variation_list(); + for (const Variant *ftr = variations.next(nullptr); ftr != nullptr; ftr = variations.next(ftr)) { + Vector3i v = variations[*ftr]; + p_list->push_back(PropertyInfo(Variant::FLOAT, "variation/" + TS->tag_to_name(*ftr), PROPERTY_HINT_RANGE, itos(v.x) + "," + itos(v.y), PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_STORAGE)); + } } RID FontData::get_rid() const { @@ -239,6 +261,26 @@ float FontData::get_underline_thickness(int p_size) const { return TS->font_get_underline_thickness(rid, (p_size < 0) ? base_size : p_size); } +Dictionary FontData::get_variation_list() const { + if (rid == RID()) { + return Dictionary(); + } + return TS->font_get_variation_list(rid); +} + +void FontData::set_variation(const String &p_name, double p_value) { + ERR_FAIL_COND(rid == RID()); + TS->font_set_variation(rid, p_name, p_value); + emit_changed(); +} + +double FontData::get_variation(const String &p_name) const { + if (rid == RID()) { + return 0; + } + return TS->font_get_variation(rid, p_name); +} + void FontData::set_antialiased(bool p_antialiased) { ERR_FAIL_COND(rid == RID()); TS->font_set_antialiased(rid, p_antialiased); @@ -472,6 +514,32 @@ void Font::_data_changed() { bool Font::_set(const StringName &p_name, const Variant &p_value) { String str = p_name; +#ifndef DISABLE_DEPRECATED + if (str == "font_data") { // Compatibility, DynamicFont main data + Ref<FontData> fd = p_value; + if (fd.is_valid()) { + add_data(fd); + return true; + } + return false; + } else if (str.begins_with("fallback/")) { // Compatibility, DynamicFont fallback data + Ref<FontData> fd = p_value; + if (fd.is_valid()) { + add_data(fd); + return true; + } + return false; + } else if (str == "fallback") { // Compatibility, BitmapFont fallback + Ref<Font> f = p_value; + if (f.is_valid()) { + for (int i = 0; i < f->get_data_count(); i++) { + add_data(f->get_data(i)); + } + return true; + } + return false; + } +#endif /* DISABLE_DEPRECATED */ if (str.begins_with("data/")) { int idx = str.get_slicec('/', 1).to_int(); Ref<FontData> fd = p_value; @@ -595,41 +663,41 @@ Dictionary Font::get_feature_list() const { float Font::get_height(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_height(p_size); + ret = MAX(ret, data[i]->get_height(p_size)); } - return (ret / data.size()) + spacing_top + spacing_bottom; + return ret + spacing_top + spacing_bottom; } float Font::get_ascent(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_ascent(p_size); + ret = MAX(ret, data[i]->get_ascent(p_size)); } - return (ret / data.size()) + spacing_top; + return ret + spacing_top; } float Font::get_descent(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_descent(p_size); + ret = MAX(ret, data[i]->get_descent(p_size)); } - return (ret / data.size()) + spacing_bottom; + return ret + spacing_bottom; } float Font::get_underline_position(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_underline_position(p_size); + ret = MAX(ret, data[i]->get_underline_position(p_size)); } - return (ret / data.size()); + return ret; } float Font::get_underline_thickness(int p_size) const { float ret = 0.f; for (int i = 0; i < data.size(); i++) { - ret += data[i]->get_underline_thickness(p_size); + ret = MAX(ret, data[i]->get_underline_thickness(p_size)); } - return (ret / data.size()); + return ret; } int Font::get_spacing(int p_type) const { @@ -899,6 +967,23 @@ RES ResourceFormatLoaderFont::load(const String &p_path, const String &p_origina return dfont; } +void ResourceFormatLoaderFont::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { +#ifndef DISABLE_DEPRECATED + if (p_type == "DynamicFontData") { + p_extensions->push_back("ttf"); + p_extensions->push_back("otf"); + p_extensions->push_back("woff"); + return; + } + if (p_type == "BitmapFont") { // BitmapFont (*.font, *fnt) is handled by ResourceFormatLoaderCompatFont + return; + } +#endif /* DISABLE_DEPRECATED */ + if (p_type == "" || handles_type(p_type)) { + get_recognized_extensions(p_extensions); + } +} + void ResourceFormatLoaderFont::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("ttf"); p_extensions->push_back("otf"); @@ -918,3 +1003,45 @@ String ResourceFormatLoaderFont::get_resource_type(const String &p_path) const { } return ""; } + +#ifndef DISABLE_DEPRECATED + +RES ResourceFormatLoaderCompatFont::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress, bool p_no_cache) { + if (r_error) { + *r_error = ERR_FILE_CANT_OPEN; + } + + Ref<FontData> dfont; + dfont.instance(); + dfont->load_resource(p_path); + + Ref<Font> font; + font.instance(); + font->add_data(dfont); + + if (r_error) { + *r_error = OK; + } + + return font; +} + +void ResourceFormatLoaderCompatFont::get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const { + if (p_type == "BitmapFont") { + p_extensions->push_back("font"); + p_extensions->push_back("fnt"); + } +} + +void ResourceFormatLoaderCompatFont::get_recognized_extensions(List<String> *p_extensions) const { +} + +bool ResourceFormatLoaderCompatFont::handles_type(const String &p_type) const { + return (p_type == "Font"); +} + +String ResourceFormatLoaderCompatFont::get_resource_type(const String &p_path) const { + return ""; +} + +#endif /* DISABLE_DEPRECATED */ diff --git a/scene/resources/font.h b/scene/resources/font.h index 226979c4a0..fe28e1aea5 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -68,6 +68,10 @@ public: float get_descent(int p_size) const; Dictionary get_feature_list() const; + Dictionary get_variation_list() const; + + void set_variation(const String &p_name, double p_value); + double get_variation(const String &p_name) const; float get_underline_position(int p_size) const; float get_underline_thickness(int p_size) const; @@ -198,9 +202,23 @@ VARIANT_ENUM_CAST(Font::SpacingType); class ResourceFormatLoaderFont : public ResourceFormatLoader { public: virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; + virtual void get_recognized_extensions(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; + +#ifndef DISABLE_DEPRECATED + +class ResourceFormatLoaderCompatFont : public ResourceFormatLoader { +public: + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, bool p_no_cache = false); + virtual void get_recognized_extensions_for_type(const String &p_type, List<String> *p_extensions) const; virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; }; -#endif +#endif /* DISABLE_DEPRECATED */ + +#endif /* FONT_H */ diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 35c967ce27..6e08af23f5 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -2417,10 +2417,10 @@ void BaseMaterial3D::_bind_methods() { ADD_GROUP("Height", "heightmap_"); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "heightmap_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_heightmap_scale", "get_heightmap_scale"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "heightmap_scale", PROPERTY_HINT_RANGE, "-16,16,0.001"), "set_heightmap_scale", "get_heightmap_scale"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_deep_parallax"), "set_heightmap_deep_parallax", "is_heightmap_deep_parallax_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_min_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_min_layers", "get_heightmap_deep_parallax_min_layers"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "heightmap_max_layers", PROPERTY_HINT_RANGE, "1,64,1"), "set_heightmap_deep_parallax_max_layers", "get_heightmap_deep_parallax_max_layers"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_tangent"), "set_heightmap_deep_parallax_flip_tangent", "get_heightmap_deep_parallax_flip_tangent"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "heightmap_flip_binormal"), "set_heightmap_deep_parallax_flip_binormal", "get_heightmap_deep_parallax_flip_binormal"); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "heightmap_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture", TEXTURE_HEIGHTMAP); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 97c0c7a81d..f1c05b8014 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -157,7 +157,7 @@ void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { bool Mesh::surface_is_softbody_friendly(int p_idx) const { const uint32_t surface_format = surface_get_format(p_idx); - return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE && (!(surface_format & Mesh::ARRAY_COMPRESS_NORMAL))); + return (surface_format & Mesh::ARRAY_FLAG_USE_DYNAMIC_UPDATE); } Vector<Face3> Mesh::get_faces() const { @@ -480,8 +480,30 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLES); BIND_ENUM_CONSTANT(PRIMITIVE_TRIANGLE_STRIP); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); - BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); + BIND_ENUM_CONSTANT(ARRAY_VERTEX); + BIND_ENUM_CONSTANT(ARRAY_NORMAL); + BIND_ENUM_CONSTANT(ARRAY_TANGENT); + BIND_ENUM_CONSTANT(ARRAY_COLOR); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV); + BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM3); + BIND_ENUM_CONSTANT(ARRAY_BONES); + BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); + BIND_ENUM_CONSTANT(ARRAY_INDEX); + BIND_ENUM_CONSTANT(ARRAY_MAX); + + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(ARRAY_CUSTOM_MAX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); @@ -489,31 +511,31 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3); BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_COLOR); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_INDEX); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_BLEND_SHAPE_MASK); - BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_BASE); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM0_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM1_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM2_SHIFT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM3_SHIFT); - BIND_ENUM_CONSTANT(ARRAY_COMPRESS_DEFAULT); + BIND_ENUM_CONSTANT(ARRAY_FORMAT_CUSTOM_MASK); + BIND_ENUM_CONSTANT(ARRAY_COMPRESS_FLAGS_BASE); - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_2D_VERTICES); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_DYNAMIC_UPDATE); + BIND_ENUM_CONSTANT(ARRAY_FLAG_USE_8_BONE_WEIGHTS); + + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_NORMALIZED); + BIND_ENUM_CONSTANT(BLEND_SHAPE_MODE_RELATIVE); } void Mesh::clear_cache() const { @@ -560,11 +582,50 @@ Vector<Ref<Shape3D>> Mesh::convex_decompose() const { Mesh::Mesh() { } +#if 0 static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, uint32_t p_format, uint32_t p_elements) { - bool vertex_16bit = p_format & ((1 << (Mesh::ARRAY_VERTEX + Mesh::ARRAY_COMPRESS_BASE))); - bool has_bones = (p_format & Mesh::ARRAY_FORMAT_BONES); - bool bone_8 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_INDEX << 2)); - bool weight_32 = has_bones && !(p_format & (Mesh::ARRAY_COMPRESS_TEX_UV2 << 2)); + enum ArrayType { + OLD_ARRAY_VERTEX = 0, + OLD_ARRAY_NORMAL = 1, + OLD_ARRAY_TANGENT = 2, + OLD_ARRAY_COLOR = 3, + OLD_ARRAY_TEX_UV = 4, + OLD_ARRAY_TEX_UV2 = 5, + OLD_ARRAY_BONES = 6, + OLD_ARRAY_WEIGHTS = 7, + OLD_ARRAY_INDEX = 8, + OLD_ARRAY_MAX = 9 + }; + + enum ArrayFormat { + /* OLD_ARRAY FORMAT FLAGS */ + OLD_ARRAY_FORMAT_VERTEX = 1 << OLD_ARRAY_VERTEX, // mandatory + OLD_ARRAY_FORMAT_NORMAL = 1 << OLD_ARRAY_NORMAL, + OLD_ARRAY_FORMAT_TANGENT = 1 << OLD_ARRAY_TANGENT, + OLD_ARRAY_FORMAT_COLOR = 1 << OLD_ARRAY_COLOR, + OLD_ARRAY_FORMAT_TEX_UV = 1 << OLD_ARRAY_TEX_UV, + OLD_ARRAY_FORMAT_TEX_UV2 = 1 << OLD_ARRAY_TEX_UV2, + OLD_ARRAY_FORMAT_BONES = 1 << OLD_ARRAY_BONES, + OLD_ARRAY_FORMAT_WEIGHTS = 1 << OLD_ARRAY_WEIGHTS, + OLD_ARRAY_FORMAT_INDEX = 1 << OLD_ARRAY_INDEX, + + OLD_ARRAY_COMPRESS_BASE = (OLD_ARRAY_INDEX + 1), + OLD_ARRAY_COMPRESS_NORMAL = 1 << (OLD_ARRAY_NORMAL + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TANGENT = 1 << (OLD_ARRAY_TANGENT + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_COLOR = 1 << (OLD_ARRAY_COLOR + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV = 1 << (OLD_ARRAY_TEX_UV + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_TEX_UV2 = 1 << (OLD_ARRAY_TEX_UV2 + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_INDEX = 1 << (OLD_ARRAY_INDEX + OLD_ARRAY_COMPRESS_BASE), + OLD_ARRAY_COMPRESS_DEFAULT = OLD_ARRAY_COMPRESS_NORMAL | OLD_ARRAY_COMPRESS_TANGENT | OLD_ARRAY_COMPRESS_COLOR | OLD_ARRAY_COMPRESS_TEX_UV | OLD_ARRAY_COMPRESS_TEX_UV2, + + OLD_ARRAY_FLAG_USE_2D_VERTICES = OLD_ARRAY_COMPRESS_INDEX << 1, + OLD_ARRAY_FLAG_USE_DYNAMIC_UPDATE = OLD_ARRAY_COMPRESS_INDEX << 3, + }; + + bool vertex_16bit = p_format & ((1 << (OLD_ARRAY_VERTEX + OLD_ARRAY_COMPRESS_BASE))); + bool has_bones = (p_format & OLD_ARRAY_FORMAT_BONES); + bool bone_8 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_INDEX << 2)); + bool weight_32 = has_bones && !(p_format & (OLD_ARRAY_COMPRESS_TEX_UV2 << 2)); print_line("convert vertex16: " + itos(vertex_16bit) + " convert bone 8 " + itos(bone_8) + " convert weight 32 " + itos(weight_32)); @@ -572,7 +633,7 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return p_src; } - bool vertex_2d = (p_format & (Mesh::ARRAY_COMPRESS_INDEX << 1)); + bool vertex_2d = (p_format & (OLD_ARRAY_COMPRESS_INDEX << 1)); uint32_t src_stride = p_src.size() / p_elements; uint32_t dst_stride = src_stride + (vertex_16bit ? 4 : 0) + (bone_8 ? 4 : 0) - (weight_32 ? 8 : 0); @@ -671,25 +732,11 @@ static Vector<uint8_t> _fix_array_compatibility(const Vector<uint8_t> &p_src, ui return ret; } +#endif bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; - if (p_name == "blend_shape/names") { - Vector<String> sk = p_value; - int sz = sk.size(); - const String *r = sk.ptr(); - for (int i = 0; i < sz; i++) { - add_blend_shape(r[i]); - } - return true; - } - - if (p_name == "blend_shape/mode") { - set_blend_shape_mode(BlendShapeMode(int(p_value))); - return true; - } - if (sname.begins_with("surface_")) { int sl = sname.find("/"); if (sl == -1) { @@ -727,6 +774,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { add_surface_from_arrays(PrimitiveType(int(d["primitive"])), d["arrays"], d["morph_arrays"]); } else if (d.has("array_data")) { +#if 0 //print_line("array data (old style"); //older format (3.x) Vector<uint8_t> array_data = d["array_data"]; @@ -793,6 +841,7 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { } add_surface(format, PrimitiveType(primitive), array_data, vertex_count, array_index_data, index_count, aabb, blend_shapes, bone_aabb); +#endif } else { ERR_FAIL_V(false); } @@ -811,6 +860,28 @@ bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { return false; } +void ArrayMesh::_set_blend_shape_names(const PackedStringArray &p_names) { + ERR_FAIL_COND(surfaces.size() > 0); + + blend_shapes.resize(p_names.size()); + for (int i = 0; i < p_names.size(); i++) { + blend_shapes.write[i] = p_names[i]; + } + + if (mesh.is_valid()) { + RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); + } +} + +PackedStringArray ArrayMesh::_get_blend_shape_names() const { + PackedStringArray sarr; + sarr.resize(blend_shapes.size()); + for (int i = 0; i < blend_shapes.size(); i++) { + sarr.write[i] = blend_shapes[i]; + } + return sarr; +} + Array ArrayMesh::_get_surfaces() const { if (mesh.is_null()) { return Array(); @@ -824,6 +895,12 @@ Array ArrayMesh::_get_surfaces() const { data["primitive"] = surface.primitive; data["vertex_data"] = surface.vertex_data; data["vertex_count"] = surface.vertex_count; + if (surface.skin_data.size()) { + data["skin_data"] = surface.skin_data; + } + if (surface.attribute_data.size()) { + data["attribute_data"] = surface.attribute_data; + } data["aabb"] = surface.aabb; if (surface.index_count) { data["index_data"] = surface.index_data; @@ -848,9 +925,8 @@ Array ArrayMesh::_get_surfaces() const { data["bone_aabbs"] = bone_aabbs; } - Array blend_shapes; - for (int j = 0; j < surface.blend_shapes.size(); j++) { - blend_shapes.push_back(surface.blend_shapes[j]); + if (surface.blend_shape_data.size()) { + data["blend_shapes"] = surface.blend_shape_data; } if (surfaces[i].material.is_valid()) { @@ -875,6 +951,7 @@ void ArrayMesh::_create_if_empty() const { if (!mesh.is_valid()) { mesh = RS::get_singleton()->mesh_create(); RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); + RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); } } @@ -896,6 +973,12 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { surface.primitive = RS::PrimitiveType(int(d["primitive"])); surface.vertex_data = d["vertex_data"]; surface.vertex_count = d["vertex_count"]; + if (d.has("attribute_data")) { + surface.attribute_data = d["attribute_data"]; + } + if (d.has("skin_data")) { + surface.skin_data = d["skin_data"]; + } surface.aabb = d["aabb"]; if (d.has("index_data")) { @@ -923,10 +1006,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { } if (d.has("blend_shapes")) { - Array blend_shapes; - for (int j = 0; j < blend_shapes.size(); j++) { - surface.blend_shapes.push_back(blend_shapes[j]); - } + surface.blend_shape_data = d["blend_shapes"]; } Ref<Material> material; @@ -946,15 +1026,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { if (d.has("2d")) { _2d = d["2d"]; } - /* - print_line("format: " + itos(surface.format)); - print_line("aabb: " + surface.aabb); - print_line("array size: " + itos(surface.vertex_data.size())); - print_line("vertex count: " + itos(surface.vertex_count)); - print_line("index size: " + itos(surface.index_data.size())); - print_line("index count: " + itos(surface.index_count)); - print_line("primitive: " + itos(surface.primitive)); -*/ + surface_data.push_back(surface); surface_materials.push_back(material); surface_names.push_back(name); @@ -970,7 +1042,7 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { } else { // if mesh does not exist (first time this is loaded, most likely), // we can create it with a single call, which is a lot more efficient and thread friendly - mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data); + mesh = RS::get_singleton()->mesh_create_from_surfaces(surface_data, blend_shapes.size()); RS::get_singleton()->mesh_set_blend_shape_mode(mesh, (RS::BlendShapeMode)blend_shape_mode); } @@ -982,7 +1054,6 @@ void ArrayMesh::_set_surfaces(const Array &p_surfaces) { s.aabb = surface_data[i].aabb; if (i == 0) { aabb = s.aabb; - blend_shapes.resize(surface_data[i].blend_shapes.size()); } else { aabb.merge_with(s.aabb); } @@ -1006,18 +1077,7 @@ bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const { } String sname = p_name; - - if (p_name == "blend_shape/names") { - Vector<String> sk; - for (int i = 0; i < blend_shapes.size(); i++) { - sk.push_back(blend_shapes[i]); - } - r_ret = sk; - return true; - } else if (p_name == "blend_shape/mode") { - r_ret = get_blend_shape_mode(); - return true; - } else if (sname.begins_with("surface_")) { + if (sname.begins_with("surface_")) { int sl = sname.find("/"); if (sl == -1) { return false; @@ -1040,11 +1100,6 @@ void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const { return; } - if (blend_shapes.size()) { - p_list->push_back(PropertyInfo(Variant::PACKED_STRING_ARRAY, "blend_shape/names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL)); - p_list->push_back(PropertyInfo(Variant::INT, "blend_shape/mode", PROPERTY_HINT_ENUM, "Normalized,Relative")); - } - for (int i = 0; i < surfaces.size(); i++) { p_list->push_back(PropertyInfo(Variant::STRING, "surface_" + itos(i + 1) + "/name", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR)); if (surfaces[i].is_2d) { @@ -1070,7 +1125,7 @@ void ArrayMesh::_recompute_aabb() { #ifndef _MSC_VER #warning need to add binding to add_surface using future MeshSurfaceData object #endif -void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes, const Vector<AABB> &p_bone_aabb, const Vector<RS::SurfaceData::LOD> &p_lods) { +void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data, const Vector<AABB> &p_bone_aabbs, const Vector<RS::SurfaceData::LOD> &p_lods) { _create_if_empty(); Surface s; @@ -1090,10 +1145,12 @@ void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const sd.aabb = p_aabb; sd.vertex_count = p_vertex_count; sd.vertex_data = p_array; + sd.attribute_data = p_attribute_array; + sd.skin_data = p_skin_array; sd.index_count = p_index_count; sd.index_data = p_index_array; - sd.blend_shapes = p_blend_shapes; - sd.bone_aabbs = p_bone_aabb; + sd.blend_shape_data = p_blend_shape_data; + sd.bone_aabbs = p_bone_aabbs; sd.lods = p_lods; RenderingServer::get_singleton()->mesh_add_surface(mesh, sd); @@ -1111,15 +1168,17 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & Error err = RS::get_singleton()->mesh_create_surface_data_from_arrays(&surface, (RenderingServer::PrimitiveType)p_primitive, p_arrays, p_blend_shapes, p_lods, p_flags); ERR_FAIL_COND(err != OK); - /* print_line("format: " + itos(surface.format)); + /* Debug code. + print_line("format: " + itos(surface.format)); print_line("aabb: " + surface.aabb); print_line("array size: " + itos(surface.vertex_data.size())); print_line("vertex count: " + itos(surface.vertex_count)); print_line("index size: " + itos(surface.index_data.size())); print_line("index count: " + itos(surface.index_count)); print_line("primitive: " + itos(surface.primitive)); -*/ - add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shapes, surface.bone_aabbs, surface.lods); + */ + + add_surface(surface.format, PrimitiveType(surface.primitive), surface.vertex_data, surface.attribute_data, surface.skin_data, surface.vertex_count, surface.index_data, surface.index_count, surface.aabb, surface.blend_shape_data, surface.bone_aabbs, surface.lods); } Array ArrayMesh::surface_get_arrays(int p_surface) const { @@ -1155,7 +1214,10 @@ void ArrayMesh::add_blend_shape(const StringName &p_name) { } blend_shapes.push_back(name); - //RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); + + if (mesh.is_valid()) { + RS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size()); + } } int ArrayMesh::get_blend_shape_count() const { @@ -1171,6 +1233,10 @@ void ArrayMesh::clear_blend_shapes() { ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created."); blend_shapes.clear(); + + if (mesh.is_valid()) { + RS::get_singleton()->mesh_set_blend_shape_count(mesh, 0); + } } void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) { @@ -1308,7 +1374,7 @@ bool (*array_mesh_lightmap_unwrap_callback)(float p_texel_size, const float *p_v struct ArrayMeshLightmapSurface { Ref<Material> material; - Vector<SurfaceTool::Vertex> vertices; + LocalVector<SurfaceTool::Vertex> vertices; Mesh::PrimitiveType primitive; uint32_t format; }; @@ -1349,7 +1415,7 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach Array arrays = surface_get_arrays(i); s.material = surface_get_material(i); - s.vertices = SurfaceTool::create_vertex_array_from_triangle_arrays(arrays); + SurfaceTool::create_vertex_array_from_triangle_arrays(arrays, s.vertices); Vector<Vector3> rvertices = arrays[Mesh::ARRAY_VERTEX]; int vc = rvertices.size(); @@ -1452,29 +1518,29 @@ Error ArrayMesh::lightmap_unwrap_cached(int *&r_cache_data, unsigned int &r_cach SurfaceTool::Vertex v = lightmap_surfaces[surface].vertices[uv_indices[gen_vertices[gen_indices[i + j]]].second]; if (lightmap_surfaces[surface].format & ARRAY_FORMAT_COLOR) { - surfaces_tools.write[surface]->add_color(v.color); + surfaces_tools.write[surface]->set_color(v.color); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TEX_UV) { - surfaces_tools.write[surface]->add_uv(v.uv); + surfaces_tools.write[surface]->set_uv(v.uv); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_NORMAL) { - surfaces_tools.write[surface]->add_normal(v.normal); + surfaces_tools.write[surface]->set_normal(v.normal); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_TANGENT) { Plane t; t.normal = v.tangent; t.d = v.binormal.dot(v.normal.cross(v.tangent)) < 0 ? -1 : 1; - surfaces_tools.write[surface]->add_tangent(t); + surfaces_tools.write[surface]->set_tangent(t); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_BONES) { - surfaces_tools.write[surface]->add_bones(v.bones); + surfaces_tools.write[surface]->set_bones(v.bones); } if (lightmap_surfaces[surface].format & ARRAY_FORMAT_WEIGHTS) { - surfaces_tools.write[surface]->add_weights(v.weights); + surfaces_tools.write[surface]->set_weights(v.weights); } Vector2 uv2(gen_uvs[gen_indices[i + j] * 2 + 0], gen_uvs[gen_indices[i + j] * 2 + 1]); - surfaces_tools.write[surface]->add_uv2(uv2); + surfaces_tools.write[surface]->set_uv2(uv2); surfaces_tools.write[surface]->add_vertex(v.vertex); } @@ -1507,7 +1573,7 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode); ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); - ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "lods", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(Dictionary()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("clear_surfaces"), &ArrayMesh::clear_surfaces); ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); @@ -1530,36 +1596,16 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb); ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb); + ClassDB::bind_method(D_METHOD("_set_blend_shape_names", "blend_shape_names"), &ArrayMesh::_set_blend_shape_names); + ClassDB::bind_method(D_METHOD("_get_blend_shape_names"), &ArrayMesh::_get_blend_shape_names); + ClassDB::bind_method(D_METHOD("_set_surfaces", "surfaces"), &ArrayMesh::_set_surfaces); ClassDB::bind_method(D_METHOD("_get_surfaces"), &ArrayMesh::_get_surfaces); + ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "_blend_shape_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_blend_shape_names", "_get_blend_shape_names"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_surfaces", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_surfaces", "_get_surfaces"); ADD_PROPERTY(PropertyInfo(Variant::INT, "blend_shape_mode", PROPERTY_HINT_ENUM, "Normalized,Relative"), "set_blend_shape_mode", "get_blend_shape_mode"); ADD_PROPERTY(PropertyInfo(Variant::AABB, "custom_aabb", PROPERTY_HINT_NONE, ""), "set_custom_aabb", "get_custom_aabb"); - - BIND_CONSTANT(NO_INDEX_ARRAY); - BIND_CONSTANT(ARRAY_WEIGHTS_SIZE); - - BIND_ENUM_CONSTANT(ARRAY_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_COLOR); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_BONES); - BIND_ENUM_CONSTANT(ARRAY_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_INDEX); - BIND_ENUM_CONSTANT(ARRAY_MAX); - - BIND_ENUM_CONSTANT(ARRAY_FORMAT_VERTEX); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_NORMAL); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TANGENT); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_COLOR); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_TEX_UV2); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_BONES); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_WEIGHTS); - BIND_ENUM_CONSTANT(ARRAY_FORMAT_INDEX); } void ArrayMesh::reload_from_file() { diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 642ae7e1b0..b7f60bf814 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -53,7 +53,10 @@ public: NO_INDEX_ARRAY = RenderingServer::NO_INDEX_ARRAY, ARRAY_WEIGHTS_SIZE = RenderingServer::ARRAY_WEIGHTS_SIZE }; - + enum BlendShapeMode { + BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, + BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, + }; enum ArrayType { ARRAY_VERTEX = RenderingServer::ARRAY_VERTEX, ARRAY_NORMAL = RenderingServer::ARRAY_NORMAL, @@ -61,6 +64,10 @@ public: ARRAY_COLOR = RenderingServer::ARRAY_COLOR, ARRAY_TEX_UV = RenderingServer::ARRAY_TEX_UV, ARRAY_TEX_UV2 = RenderingServer::ARRAY_TEX_UV2, + ARRAY_CUSTOM0 = RenderingServer::ARRAY_CUSTOM0, + ARRAY_CUSTOM1 = RenderingServer::ARRAY_CUSTOM1, + ARRAY_CUSTOM2 = RenderingServer::ARRAY_CUSTOM2, + ARRAY_CUSTOM3 = RenderingServer::ARRAY_CUSTOM3, ARRAY_BONES = RenderingServer::ARRAY_BONES, ARRAY_WEIGHTS = RenderingServer::ARRAY_WEIGHTS, ARRAY_INDEX = RenderingServer::ARRAY_INDEX, @@ -68,30 +75,47 @@ public: }; + enum ArrayCustomFormat { + ARRAY_CUSTOM_RGBA8_UNORM, + ARRAY_CUSTOM_RGBA8_SNORM, + ARRAY_CUSTOM_RG_HALF, + ARRAY_CUSTOM_RGBA_HALF, + ARRAY_CUSTOM_R_FLOAT, + ARRAY_CUSTOM_RG_FLOAT, + ARRAY_CUSTOM_RGB_FLOAT, + ARRAY_CUSTOM_RGBA_FLOAT, + ARRAY_CUSTOM_MAX + }; + enum ArrayFormat { - /* ARRAY FORMAT FLAGS */ - ARRAY_FORMAT_VERTEX = 1 << ARRAY_VERTEX, // mandatory - ARRAY_FORMAT_NORMAL = 1 << ARRAY_NORMAL, - ARRAY_FORMAT_TANGENT = 1 << ARRAY_TANGENT, - ARRAY_FORMAT_COLOR = 1 << ARRAY_COLOR, - ARRAY_FORMAT_TEX_UV = 1 << ARRAY_TEX_UV, - ARRAY_FORMAT_TEX_UV2 = 1 << ARRAY_TEX_UV2, - ARRAY_FORMAT_BONES = 1 << ARRAY_BONES, - ARRAY_FORMAT_WEIGHTS = 1 << ARRAY_WEIGHTS, - ARRAY_FORMAT_INDEX = 1 << ARRAY_INDEX, - - ARRAY_COMPRESS_BASE = (ARRAY_INDEX + 1), - ARRAY_COMPRESS_NORMAL = 1 << (ARRAY_NORMAL + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TANGENT = 1 << (ARRAY_TANGENT + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_COLOR = 1 << (ARRAY_COLOR + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV = 1 << (ARRAY_TEX_UV + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_TEX_UV2 = 1 << (ARRAY_TEX_UV2 + ARRAY_COMPRESS_BASE), - ARRAY_COMPRESS_INDEX = 1 << (ARRAY_INDEX + ARRAY_COMPRESS_BASE), - - ARRAY_FLAG_USE_2D_VERTICES = ARRAY_COMPRESS_INDEX << 1, - ARRAY_FLAG_USE_DYNAMIC_UPDATE = ARRAY_COMPRESS_INDEX << 3, - - ARRAY_COMPRESS_DEFAULT = ARRAY_COMPRESS_NORMAL | ARRAY_COMPRESS_TANGENT | ARRAY_COMPRESS_COLOR | ARRAY_COMPRESS_TEX_UV | ARRAY_COMPRESS_TEX_UV2 + ARRAY_FORMAT_VERTEX = RS::ARRAY_FORMAT_VERTEX, + ARRAY_FORMAT_NORMAL = RS::ARRAY_FORMAT_NORMAL, + ARRAY_FORMAT_TANGENT = RS::ARRAY_FORMAT_TANGENT, + ARRAY_FORMAT_COLOR = RS::ARRAY_FORMAT_COLOR, + ARRAY_FORMAT_TEX_UV = RS::ARRAY_FORMAT_TEX_UV, + ARRAY_FORMAT_TEX_UV2 = RS::ARRAY_FORMAT_TEX_UV2, + ARRAY_FORMAT_CUSTOM0 = RS::ARRAY_FORMAT_CUSTOM0, + ARRAY_FORMAT_CUSTOM1 = RS::ARRAY_FORMAT_CUSTOM1, + ARRAY_FORMAT_CUSTOM2 = RS::ARRAY_FORMAT_CUSTOM2, + ARRAY_FORMAT_CUSTOM3 = RS::ARRAY_FORMAT_CUSTOM3, + ARRAY_FORMAT_BONES = RS::ARRAY_FORMAT_BONES, + ARRAY_FORMAT_WEIGHTS = RS::ARRAY_FORMAT_WEIGHTS, + ARRAY_FORMAT_INDEX = RS::ARRAY_FORMAT_INDEX, + + ARRAY_FORMAT_BLEND_SHAPE_MASK = RS::ARRAY_FORMAT_BLEND_SHAPE_MASK, + + ARRAY_FORMAT_CUSTOM_BASE = RS::ARRAY_FORMAT_CUSTOM_BASE, + ARRAY_FORMAT_CUSTOM0_SHIFT = RS::ARRAY_FORMAT_CUSTOM0_SHIFT, + ARRAY_FORMAT_CUSTOM1_SHIFT = RS::ARRAY_FORMAT_CUSTOM1_SHIFT, + ARRAY_FORMAT_CUSTOM2_SHIFT = RS::ARRAY_FORMAT_CUSTOM2_SHIFT, + ARRAY_FORMAT_CUSTOM3_SHIFT = RS::ARRAY_FORMAT_CUSTOM3_SHIFT, + + ARRAY_FORMAT_CUSTOM_MASK = RS::ARRAY_FORMAT_CUSTOM_MASK, + ARRAY_COMPRESS_FLAGS_BASE = RS::ARRAY_COMPRESS_FLAGS_BASE, + + ARRAY_FLAG_USE_2D_VERTICES = RS::ARRAY_FLAG_USE_2D_VERTICES, + ARRAY_FLAG_USE_DYNAMIC_UPDATE = RS::ARRAY_FLAG_USE_DYNAMIC_UPDATE, + ARRAY_FLAG_USE_8_BONE_WEIGHTS = RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS, }; @@ -104,11 +128,6 @@ public: PRIMITIVE_MAX = RenderingServer::PRIMITIVE_MAX, }; - enum BlendShapeMode { - BLEND_SHAPE_MODE_NORMALIZED = RS::BLEND_SHAPE_MODE_NORMALIZED, - BLEND_SHAPE_MODE_RELATIVE = RS::BLEND_SHAPE_MODE_RELATIVE, - }; - virtual int get_surface_count() const = 0; virtual int surface_get_array_len(int p_idx) const = 0; virtual int surface_get_array_index_len(int p_idx) const = 0; @@ -152,6 +171,9 @@ class ArrayMesh : public Mesh { GDCLASS(ArrayMesh, Mesh); RES_BASE_EXTENSION("mesh"); + PackedStringArray _get_blend_shape_names() const; + void _set_blend_shape_names(const PackedStringArray &p_names); + Array _get_surfaces() const; void _set_surfaces(const Array &p_data); @@ -187,9 +209,9 @@ protected: static void _bind_methods(); public: - void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = ARRAY_COMPRESS_DEFAULT); + void add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes = Array(), const Dictionary &p_lods = Dictionary(), uint32_t p_flags = 0); - void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<Vector<uint8_t>> &p_blend_shapes = Vector<Vector<uint8_t>>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); + void add_surface(uint32_t p_format, PrimitiveType p_primitive, const Vector<uint8_t> &p_array, const Vector<uint8_t> &p_attribute_array, const Vector<uint8_t> &p_skin_array, int p_vertex_count, const Vector<uint8_t> &p_index_array, int p_index_count, const AABB &p_aabb, const Vector<uint8_t> &p_blend_shape_data = Vector<uint8_t>(), const Vector<AABB> &p_bone_aabbs = Vector<AABB>(), const Vector<RS::SurfaceData::LOD> &p_lods = Vector<RS::SurfaceData::LOD>()); Array surface_get_arrays(int p_surface) const override; Array surface_get_blend_shape_arrays(int p_surface) const override; @@ -244,6 +266,7 @@ public: VARIANT_ENUM_CAST(Mesh::ArrayType); VARIANT_ENUM_CAST(Mesh::ArrayFormat); +VARIANT_ENUM_CAST(Mesh::ArrayCustomFormat); VARIANT_ENUM_CAST(Mesh::PrimitiveType); VARIANT_ENUM_CAST(Mesh::BlendShapeMode); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 5ce253f970..09674f3465 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -1481,16 +1481,6 @@ int SceneState::add_name(const StringName &p_name) { return names.size() - 1; } -int SceneState::find_name(const StringName &p_name) const { - for (int i = 0; i < names.size(); i++) { - if (names[i] == p_name) { - return i; - } - } - - return -1; -} - int SceneState::add_value(const Variant &p_value) { variants.push_back(p_value); return variants.size() - 1; diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index b8b3f84ecc..fce3891507 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -172,7 +172,6 @@ public: //build API int add_name(const StringName &p_name); - int find_name(const StringName &p_name) const; int add_value(const Variant &p_value); int add_node_path(const NodePath &p_path); int add_node(int p_parent, int p_owner, int p_type, int p_name, int p_instance, int p_index); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index a286184aee..e2f96c54cb 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -329,7 +329,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { 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 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; @@ -377,7 +377,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n"; if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " mat2 rotm;"; code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n"; code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n"; @@ -398,7 +398,7 @@ void ParticlesMaterial::_update_shader() { code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -413,7 +413,7 @@ void ParticlesMaterial::_update_shader() { code += " float tex_linear_velocity = 0.0;\n"; } - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) { code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; } else { @@ -471,7 +471,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 force = gravity;\n"; code += " vec3 pos = TRANSFORM[3].xyz;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " pos.z = 0.0;\n"; } code += " // apply linear acceleration\n"; @@ -481,7 +481,7 @@ void ParticlesMaterial::_update_shader() { code += " vec3 diff = pos - org;\n"; code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);\n"; code += " // apply tangential acceleration;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; } else { @@ -495,7 +495,7 @@ void ParticlesMaterial::_update_shader() { code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; code += " // orbit velocity\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n"; code += " if (orbit_amount != 0.0) {\n"; code += " float ang = orbit_amount * DELTA * pi * 2.0;\n"; @@ -562,8 +562,8 @@ void ParticlesMaterial::_update_shader() { } code += "\n"; - if (flags[FLAG_DISABLE_Z]) { - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -579,7 +579,7 @@ void ParticlesMaterial::_update_shader() { } else { // orient particle Y towards velocity - if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + if (particle_flags[PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY]) { code += " if (length(VELOCITY) > 0.0) {\n"; code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; code += " } else {\n"; @@ -598,7 +598,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n"; } // turn particle by rotation in Y - if (flags[FLAG_ROTATE_Y]) { + if (particle_flags[PARTICLE_FLAG_ROTATE_Y]) { code += " TRANSFORM = TRANSFORM * mat4(vec4(cos(CUSTOM.x), 0.0, -sin(CUSTOM.x), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(sin(CUSTOM.x), 0.0, cos(CUSTOM.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } } @@ -611,7 +611,7 @@ void ParticlesMaterial::_update_shader() { code += " TRANSFORM[0].xyz *= base_scale;\n"; code += " TRANSFORM[1].xyz *= base_scale;\n"; code += " TRANSFORM[2].xyz *= base_scale;\n"; - if (flags[FLAG_DISABLE_Z]) { + if (particle_flags[PARTICLE_FLAG_DISABLE_Z]) { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } @@ -916,18 +916,18 @@ Ref<Texture2D> ParticlesMaterial::get_color_ramp() const { return color_ramp; } -void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) { - ERR_FAIL_INDEX(p_flag, FLAG_MAX); - flags[p_flag] = p_enable; +void ParticlesMaterial::set_particle_flag(ParticleFlags p_particle_flag, bool p_enable) { + ERR_FAIL_INDEX(p_particle_flag, PARTICLE_FLAG_MAX); + particle_flags[p_particle_flag] = p_enable; _queue_shader_change(); - if (p_flag == FLAG_DISABLE_Z) { + if (p_particle_flag == PARTICLE_FLAG_DISABLE_Z) { _change_notify(); } } -bool ParticlesMaterial::get_flag(Flags p_flag) const { - ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); - return flags[p_flag]; +bool ParticlesMaterial::get_particle_flag(ParticleFlags p_particle_flag) const { + ERR_FAIL_INDEX_V(p_particle_flag, PARTICLE_FLAG_MAX, false); + return particle_flags[p_particle_flag]; } void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { @@ -1056,7 +1056,7 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } - if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { + if (property.name.begins_with("orbit_") && !particle_flags[PARTICLE_FLAG_DISABLE_Z]) { property.usage = 0; } } @@ -1170,8 +1170,8 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); - ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &ParticlesMaterial::set_flag); - ClassDB::bind_method(D_METHOD("get_flag", "flag"), &ParticlesMaterial::get_flag); + ClassDB::bind_method(D_METHOD("set_particle_flag", "particle_flag", "enable"), &ParticlesMaterial::set_particle_flag); + ClassDB::bind_method(D_METHOD("get_particle_flag", "particle_flag"), &ParticlesMaterial::get_particle_flag); ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape); ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape); @@ -1238,10 +1238,10 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_normal_texture", "get_emission_normal_texture"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_emission_color_texture", "get_emission_color_texture"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count"); - ADD_GROUP("Flags", "flag_"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); + ADD_GROUP("ParticleFlags", "particle_flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_align_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_rotate_y"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_ROTATE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "particle_flag_disable_z"), "set_particle_flag", "get_particle_flag", PARTICLE_FLAG_DISABLE_Z); ADD_GROUP("Direction", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "direction"), "set_direction", "get_direction"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); @@ -1327,10 +1327,10 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); BIND_ENUM_CONSTANT(PARAM_MAX); - BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); - BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); - BIND_ENUM_CONSTANT(FLAG_DISABLE_Z); - BIND_ENUM_CONSTANT(FLAG_MAX); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_ROTATE_Y); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_DISABLE_Z); + BIND_ENUM_CONSTANT(PARTICLE_FLAG_MAX); BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); @@ -1385,8 +1385,8 @@ ParticlesMaterial::ParticlesMaterial() : set_param_randomness(Parameter(i), 0); } - for (int i = 0; i < FLAG_MAX; i++) { - flags[i] = false; + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + particle_flags[i] = false; } set_color(Color(1, 1, 1, 1)); diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 12fa53ef29..7e8f05b706 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -61,11 +61,11 @@ public: PARAM_MAX }; - enum Flags { - FLAG_ALIGN_Y_TO_VELOCITY, - FLAG_ROTATE_Y, - FLAG_DISABLE_Z, - FLAG_MAX + enum ParticleFlags { + PARTICLE_FLAG_ALIGN_Y_TO_VELOCITY, + PARTICLE_FLAG_ROTATE_Y, + PARTICLE_FLAG_DISABLE_Z, + PARTICLE_FLAG_MAX }; enum EmissionShape { @@ -90,7 +90,7 @@ private: struct { uint32_t texture_mask : 16; uint32_t texture_color : 1; - uint32_t flags : 4; + uint32_t particle_flags : 4; uint32_t emission_shape : 2; uint32_t invalid_key : 1; uint32_t has_emission_color : 1; @@ -124,9 +124,9 @@ private: mk.texture_mask |= (1 << i); } } - for (int i = 0; i < FLAG_MAX; i++) { - if (flags[i]) { - mk.flags |= (1 << i); + for (int i = 0; i < PARTICLE_FLAG_MAX; i++) { + if (particle_flags[i]) { + mk.particle_flags |= (1 << i); } } @@ -227,7 +227,7 @@ private: Color color; Ref<Texture2D> color_ramp; - bool flags[FLAG_MAX]; + bool particle_flags[PARTICLE_FLAG_MAX]; EmissionShape emission_shape; float emission_sphere_radius; @@ -284,8 +284,8 @@ public: void set_color_ramp(const Ref<Texture2D> &p_texture); Ref<Texture2D> get_color_ramp() const; - void set_flag(Flags p_flag, bool p_enable); - bool get_flag(Flags p_flag) const; + void set_particle_flag(ParticleFlags p_particle_flag, bool p_enable); + bool get_particle_flag(ParticleFlags p_particle_flag) const; void set_emission_shape(EmissionShape p_shape); void set_emission_sphere_radius(float p_radius); @@ -349,7 +349,7 @@ public: }; VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) -VARIANT_ENUM_CAST(ParticlesMaterial::Flags) +VARIANT_ENUM_CAST(ParticlesMaterial::ParticleFlags) VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode) diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 8d9c5f07b2..06e181cb99 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -148,7 +148,7 @@ Array PrimitiveMesh::surface_get_blend_shape_arrays(int p_surface) const { uint32_t PrimitiveMesh::surface_get_format(int p_idx) const { ERR_FAIL_INDEX_V(p_idx, 1, 0); - return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX | RS::ARRAY_COMPRESS_DEFAULT; + return RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL | RS::ARRAY_FORMAT_TANGENT | RS::ARRAY_FORMAT_TEX_UV | RS::ARRAY_FORMAT_INDEX; } Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const { @@ -477,10 +477,10 @@ CapsuleMesh::CapsuleMesh() { } /** - CubeMesh + BoxMesh */ -void CubeMesh::_create_mesh_array(Array &p_arr) const { +void BoxMesh::_create_mesh_array(Array &p_arr) const { int i, j, prevrow, thisrow, point; float x, y, z; float onethird = 1.0 / 3.0; @@ -672,16 +672,16 @@ void CubeMesh::_create_mesh_array(Array &p_arr) const { p_arr[RS::ARRAY_INDEX] = indices; } -void CubeMesh::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_size", "size"), &CubeMesh::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &CubeMesh::get_size); +void BoxMesh::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &BoxMesh::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &BoxMesh::get_size); - ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &CubeMesh::set_subdivide_width); - ClassDB::bind_method(D_METHOD("get_subdivide_width"), &CubeMesh::get_subdivide_width); - ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &CubeMesh::set_subdivide_height); - ClassDB::bind_method(D_METHOD("get_subdivide_height"), &CubeMesh::get_subdivide_height); - ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &CubeMesh::set_subdivide_depth); - ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &CubeMesh::get_subdivide_depth); + ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &BoxMesh::set_subdivide_width); + ClassDB::bind_method(D_METHOD("get_subdivide_width"), &BoxMesh::get_subdivide_width); + ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &BoxMesh::set_subdivide_height); + ClassDB::bind_method(D_METHOD("get_subdivide_height"), &BoxMesh::get_subdivide_height); + ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &BoxMesh::set_subdivide_depth); + ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &BoxMesh::get_subdivide_depth); ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_width", "get_subdivide_width"); @@ -689,43 +689,43 @@ void CubeMesh::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_subdivide_depth", "get_subdivide_depth"); } -void CubeMesh::set_size(const Vector3 &p_size) { +void BoxMesh::set_size(const Vector3 &p_size) { size = p_size; _request_update(); } -Vector3 CubeMesh::get_size() const { +Vector3 BoxMesh::get_size() const { return size; } -void CubeMesh::set_subdivide_width(const int p_divisions) { +void BoxMesh::set_subdivide_width(const int p_divisions) { subdivide_w = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_width() const { +int BoxMesh::get_subdivide_width() const { return subdivide_w; } -void CubeMesh::set_subdivide_height(const int p_divisions) { +void BoxMesh::set_subdivide_height(const int p_divisions) { subdivide_h = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_height() const { +int BoxMesh::get_subdivide_height() const { return subdivide_h; } -void CubeMesh::set_subdivide_depth(const int p_divisions) { +void BoxMesh::set_subdivide_depth(const int p_divisions) { subdivide_d = p_divisions > 0 ? p_divisions : 0; _request_update(); } -int CubeMesh::get_subdivide_depth() const { +int BoxMesh::get_subdivide_depth() const { return subdivide_d; } -CubeMesh::CubeMesh() { +BoxMesh::BoxMesh() { // defaults size = Vector3(2.0, 2.0, 2.0); subdivide_w = 0; diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index f0ae611b5e..02aea9c5c8 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -130,10 +130,10 @@ public: }; /** - Similar to test cube but with subdivision support and different texture coordinates + A box */ -class CubeMesh : public PrimitiveMesh { - GDCLASS(CubeMesh, PrimitiveMesh); +class BoxMesh : public PrimitiveMesh { + GDCLASS(BoxMesh, PrimitiveMesh); private: Vector3 size; @@ -158,7 +158,7 @@ public: void set_subdivide_depth(const int p_divisions); int get_subdivide_depth() const; - CubeMesh(); + BoxMesh(); }; /** diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index cf8be8fe15..58645dbe65 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -704,7 +704,6 @@ ResourceLoaderText::ResourceLoaderText() { resources_total = 0; resource_current = 0; - use_sub_threads = false; progress = nullptr; lines = false; diff --git a/scene/resources/sky_material.cpp b/scene/resources/sky_material.cpp index 69e8e0b5bd..05bb13a1e0 100644 --- a/scene/resources/sky_material.cpp +++ b/scene/resources/sky_material.cpp @@ -568,7 +568,7 @@ PhysicalSkyMaterial::PhysicalSkyMaterial() { code += "\tCOLOR = pow(color, vec3(1.0 / (1.2 + (1.2 * sun_fade))));\n"; code += "\tCOLOR *= exposure;\n"; code += "\t// Make optional, eliminates banding\n"; - code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.008 * dither_strength;\n"; + code += "\tCOLOR += (hash(EYEDIR * 1741.9782) * 0.08 - 0.04) * 0.016 * dither_strength;\n"; code += "}\n"; shader = RS::get_singleton()->shader_create(); diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index a8bf44c5c0..14197c6c68 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -404,16 +404,6 @@ void StyleBoxFlat::set_corner_radius_individual(const int radius_top_left, const emit_changed(); } -int StyleBoxFlat::get_corner_radius_min() const { - int smallest = corner_radius[0]; - for (int i = 1; i < 4; i++) { - if (smallest > corner_radius[i]) { - smallest = corner_radius[i]; - } - } - return smallest; -} - void StyleBoxFlat::set_corner_radius(const Corner p_corner, const int radius) { ERR_FAIL_INDEX((int)p_corner, 4); corner_radius[p_corner] = radius; diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index a1237776c6..7dd806e840 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -184,7 +184,6 @@ public: //CORNER void set_corner_radius_all(int radius); void set_corner_radius_individual(const int radius_top_left, const int radius_top_right, const int radius_botton_right, const int radius_bottom_left); - int get_corner_radius_min() const; void set_corner_radius(Corner p_corner, const int radius); int get_corner_radius(Corner p_corner) const; diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index ff14a5a292..50308d641a 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -33,6 +33,9 @@ #define _VERTEX_SNAP 0.0001 #define EQ_VERTEX_DIST 0.00001 +SurfaceTool::OptimizeVertexCacheFunc SurfaceTool::optimize_vertex_cache_func = nullptr; +SurfaceTool::SimplifyFunc SurfaceTool::simplify_func = nullptr; + bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { if (vertex != p_vertex.vertex) { return false; @@ -74,6 +77,16 @@ bool SurfaceTool::Vertex::operator==(const Vertex &p_vertex) const { } } + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + if (custom[i] != p_vertex.custom[i]) { + return false; + } + } + + if (smooth_group != p_vertex.smooth_group) { + return false; + } + return true; } @@ -87,6 +100,8 @@ uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { h = hash_djb2_buffer((const uint8_t *)&p_vtx.color, sizeof(real_t) * 4, h); h = hash_djb2_buffer((const uint8_t *)p_vtx.bones.ptr(), p_vtx.bones.size() * sizeof(int), h); h = hash_djb2_buffer((const uint8_t *)p_vtx.weights.ptr(), p_vtx.weights.size() * sizeof(float), h); + h = hash_djb2_buffer((const uint8_t *)&p_vtx.custom[0], sizeof(Color) * RS::ARRAY_CUSTOM_COUNT, h); + h = hash_djb2_one_32(p_vtx.smooth_group, h); return h; } @@ -111,8 +126,13 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { vtx.bones = last_bones; vtx.tangent = last_tangent.normal; vtx.binormal = last_normal.cross(last_tangent.normal).normalized() * last_tangent.d; + vtx.smooth_group = last_smooth_group; + + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + vtx.custom[i] = last_custom[i]; + } - const int expected_vertices = 4; + const int expected_vertices = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; if ((format & Mesh::ARRAY_FORMAT_WEIGHTS || format & Mesh::ARRAY_FORMAT_BONES) && (vtx.weights.size() != expected_vertices || vtx.bones.size() != expected_vertices)) { //ensure vertices are the expected amount @@ -163,7 +183,7 @@ void SurfaceTool::add_vertex(const Vector3 &p_vertex) { format |= Mesh::ARRAY_FORMAT_VERTEX; } -void SurfaceTool::add_color(Color p_color) { +void SurfaceTool::set_color(Color p_color) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_COLOR)); @@ -172,7 +192,7 @@ void SurfaceTool::add_color(Color p_color) { last_color = p_color; } -void SurfaceTool::add_normal(const Vector3 &p_normal) { +void SurfaceTool::set_normal(const Vector3 &p_normal) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_NORMAL)); @@ -181,7 +201,7 @@ void SurfaceTool::add_normal(const Vector3 &p_normal) { last_normal = p_normal; } -void SurfaceTool::add_tangent(const Plane &p_tangent) { +void SurfaceTool::set_tangent(const Plane &p_tangent) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TANGENT)); @@ -189,7 +209,7 @@ void SurfaceTool::add_tangent(const Plane &p_tangent) { last_tangent = p_tangent; } -void SurfaceTool::add_uv(const Vector2 &p_uv) { +void SurfaceTool::set_uv(const Vector2 &p_uv) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV)); @@ -197,7 +217,7 @@ void SurfaceTool::add_uv(const Vector2 &p_uv) { last_uv = p_uv; } -void SurfaceTool::add_uv2(const Vector2 &p_uv2) { +void SurfaceTool::set_uv2(const Vector2 &p_uv2) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_TEX_UV2)); @@ -205,29 +225,45 @@ void SurfaceTool::add_uv2(const Vector2 &p_uv2) { last_uv2 = p_uv2; } -void SurfaceTool::add_bones(const Vector<int> &p_bones) { +void SurfaceTool::set_custom(int p_index, const Color &p_custom) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(!begun); + ERR_FAIL_COND(last_custom_format[p_index] == CUSTOM_MAX); + static const uint32_t mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + ERR_FAIL_COND(!first && !(format & mask[p_index])); + + if (first) { + format |= mask[p_index]; + format |= last_custom_format[p_index] << shift[p_index]; + } + last_custom[p_index] = p_custom; +} + +void SurfaceTool::set_bones(const Vector<int> &p_bones) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_BONES)); format |= Mesh::ARRAY_FORMAT_BONES; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_bones = p_bones; } -void SurfaceTool::add_weights(const Vector<float> &p_weights) { +void SurfaceTool::set_weights(const Vector<float> &p_weights) { ERR_FAIL_COND(!begun); ERR_FAIL_COND(!first && !(format & Mesh::ARRAY_FORMAT_WEIGHTS)); format |= Mesh::ARRAY_FORMAT_WEIGHTS; + if (skin_weights == SKIN_8_WEIGHTS) { + format |= Mesh::ARRAY_FLAG_USE_8_BONE_WEIGHTS; + } last_weights = p_weights; } -void SurfaceTool::add_smooth_group(bool p_smooth) { - ERR_FAIL_COND(!begun); - if (index_array.size()) { - smooth_groups[index_array.size()] = p_smooth; - } else { - smooth_groups[vertex_array.size()] = p_smooth; - } +void SurfaceTool::set_smooth_group(uint32_t p_group) { + last_smooth_group = p_group; } void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs, const Vector<Color> &p_colors, const Vector<Vector2> &p_uv2s, const Vector<Vector3> &p_normals, const Vector<Plane> &p_tangents) { @@ -238,15 +274,15 @@ void SurfaceTool::add_triangle_fan(const Vector<Vector3> &p_vertices, const Vect #define ADD_POINT(n) \ { \ if (p_colors.size() > n) \ - add_color(p_colors[n]); \ + set_color(p_colors[n]); \ if (p_uvs.size() > n) \ - add_uv(p_uvs[n]); \ + set_uv(p_uvs[n]); \ if (p_uv2s.size() > n) \ - add_uv2(p_uv2s[n]); \ + set_uv2(p_uv2s[n]); \ if (p_normals.size() > n) \ - add_normal(p_normals[n]); \ + set_normal(p_normals[n]); \ if (p_tangents.size() > n) \ - add_tangent(p_tangents[n]); \ + set_tangent(p_tangents[n]); \ add_vertex(p_vertices[n]); \ } @@ -284,9 +320,8 @@ Array SurfaceTool::commit_to_arrays() { array.resize(varr_len); Vector3 *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { - const Vertex &v = E->get(); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; switch (i) { case Mesh::ARRAY_VERTEX: { @@ -308,9 +343,8 @@ Array SurfaceTool::commit_to_arrays() { array.resize(varr_len); Vector2 *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { - const Vertex &v = E->get(); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; switch (i) { case Mesh::ARRAY_TEX_UV: { @@ -329,9 +363,8 @@ Array SurfaceTool::commit_to_arrays() { array.resize(varr_len * 4); float *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { - const Vertex &v = E->get(); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; w[idx + 0] = v.tangent.x; w[idx + 1] = v.tangent.y; @@ -350,27 +383,165 @@ Array SurfaceTool::commit_to_arrays() { array.resize(varr_len); Color *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx++) { - const Vertex &v = E->get(); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + w[idx] = v.color; } a[i] = array; } break; + case Mesh::ARRAY_CUSTOM0: + case Mesh::ARRAY_CUSTOM1: + case Mesh::ARRAY_CUSTOM2: + case Mesh::ARRAY_CUSTOM3: { + int fmt = i - Mesh::ARRAY_CUSTOM0; + switch (last_custom_format[fmt]) { + case CUSTOM_RGBA8_UNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = CLAMP(int32_t(c.r * 255.0), 0, 255); + w[idx * 4 + 1] = CLAMP(int32_t(c.g * 255.0), 0, 255); + w[idx * 4 + 2] = CLAMP(int32_t(c.b * 255.0), 0, 255); + w[idx * 4 + 3] = CLAMP(int32_t(c.a * 255.0), 0, 255); + } + + a[i] = array; + } break; + case CUSTOM_RGBA8_SNORM: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint8_t *w = array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = uint8_t(int8_t(CLAMP(int32_t(c.r * 127.0), -128, 127))); + w[idx * 4 + 1] = uint8_t(int8_t(CLAMP(int32_t(c.g * 127.0), -128, 127))); + w[idx * 4 + 2] = uint8_t(int8_t(CLAMP(int32_t(c.b * 127.0), -128, 127))); + w[idx * 4 + 3] = uint8_t(int8_t(CLAMP(int32_t(c.a * 127.0), -128, 127))); + } + + a[i] = array; + } break; + case CUSTOM_RG_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 4); + uint16_t *w = (uint16_t *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = Math::make_half_float(c.r); + w[idx * 2 + 1] = Math::make_half_float(c.g); + } + + a[i] = array; + } break; + case CUSTOM_RGBA_HALF: { + Vector<uint8_t> array; + array.resize(varr_len * 8); + uint16_t *w = (uint16_t *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = Math::make_half_float(c.r); + w[idx * 4 + 1] = Math::make_half_float(c.g); + w[idx * 4 + 2] = Math::make_half_float(c.b); + w[idx * 4 + 3] = Math::make_half_float(c.a); + } + + a[i] = array; + } break; + case CUSTOM_R_FLOAT: { + Vector<float> array; + array.resize(varr_len); + float *w = (float *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx] = c.r; + } + + a[i] = array; + } break; + case CUSTOM_RG_FLOAT: { + Vector<float> array; + array.resize(varr_len * 2); + float *w = (float *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 2 + 0] = c.r; + w[idx * 2 + 1] = c.g; + } + + a[i] = array; + } break; + case CUSTOM_RGB_FLOAT: { + Vector<float> array; + array.resize(varr_len * 3); + float *w = (float *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 3 + 0] = c.r; + w[idx * 3 + 1] = c.g; + w[idx * 3 + 2] = c.b; + } + + a[i] = array; + } break; + case CUSTOM_RGBA_FLOAT: { + Vector<float> array; + array.resize(varr_len * 4); + float *w = (float *)array.ptrw(); + + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + const Color &c = v.custom[idx]; + w[idx * 4 + 0] = c.r; + w[idx * 4 + 1] = c.g; + w[idx * 4 + 2] = c.b; + w[idx * 4 + 3] = c.a; + } + + a[i] = array; + } break; + default: { + } //unreachable but compiler warning anyway + } + } break; case Mesh::ARRAY_BONES: { + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; Vector<int> array; - array.resize(varr_len * 4); + array.resize(varr_len * count); int *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { - const Vertex &v = E->get(); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; - ERR_CONTINUE(v.bones.size() != 4); + ERR_CONTINUE(v.bones.size() != count); - for (int j = 0; j < 4; j++) { - w[idx + j] = v.bones[j]; + for (int j = 0; j < count; j++) { + w[idx * count + j] = v.bones[j]; } } @@ -379,16 +550,18 @@ Array SurfaceTool::commit_to_arrays() { } break; case Mesh::ARRAY_WEIGHTS: { Vector<float> array; - array.resize(varr_len * 4); + int count = skin_weights == SKIN_8_WEIGHTS ? 8 : 4; + + array.resize(varr_len * count); float *w = array.ptrw(); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next(), idx += 4) { - const Vertex &v = E->get(); - ERR_CONTINUE(v.weights.size() != 4); + for (uint32_t idx = 0; idx < vertex_array.size(); idx++) { + const Vertex &v = vertex_array[idx]; + + ERR_CONTINUE(v.weights.size() != count); - for (int j = 0; j < 4; j++) { - w[idx + j] = v.weights[j]; + for (int j = 0; j < count; j++) { + w[idx * count + j] = v.weights[j]; } } @@ -402,9 +575,8 @@ Array SurfaceTool::commit_to_arrays() { array.resize(index_array.size()); int *w = array.ptrw(); - int idx = 0; - for (List<int>::Element *E = index_array.front(); E; E = E->next(), idx++) { - w[idx] = E->get(); + for (uint32_t idx = 0; idx < index_array.size(); idx++) { + w[idx] = index_array[idx]; } a[i] = array; @@ -451,15 +623,16 @@ void SurfaceTool::index() { } HashMap<Vertex, int, VertexHasher> indices; - List<Vertex> new_vertices; + LocalVector<Vertex> old_vertex_array = vertex_array; + vertex_array.clear(); - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) { - int *idxptr = indices.getptr(E->get()); + for (uint32_t i = 0; i < old_vertex_array.size(); i++) { + int *idxptr = indices.getptr(old_vertex_array[i]); int idx; if (!idxptr) { idx = indices.size(); - new_vertices.push_back(E->get()); - indices[E->get()] = idx; + vertex_array.push_back(old_vertex_array[i]); + indices[old_vertex_array[i]] = idx; } else { idx = *idxptr; } @@ -467,9 +640,6 @@ void SurfaceTool::index() { index_array.push_back(idx); } - vertex_array.clear(); - vertex_array = new_vertices; - format |= Mesh::ARRAY_FORMAT_INDEX; } @@ -477,29 +647,26 @@ void SurfaceTool::deindex() { if (index_array.size() == 0) { return; //nothing to deindex } - Vector<Vertex> varr; - varr.resize(vertex_array.size()); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) { - varr.write[idx++] = E->get(); - } + + LocalVector<Vertex> old_vertex_array = vertex_array; vertex_array.clear(); - for (List<int>::Element *E = index_array.front(); E; E = E->next()) { - ERR_FAIL_INDEX(E->get(), varr.size()); - vertex_array.push_back(varr[E->get()]); + for (uint32_t i = 0; i < index_array.size(); i++) { + uint32_t index = index_array[i]; + ERR_FAIL_COND(index >= old_vertex_array.size()); + vertex_array.push_back(old_vertex_array[index]); } format &= ~Mesh::ARRAY_FORMAT_INDEX; index_array.clear(); } -void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { +void SurfaceTool::_create_list(const Ref<Mesh> &p_existing, int p_surface, LocalVector<Vertex> *r_vertex, LocalVector<int> *r_index, uint32_t &lformat) { Array arr = p_existing->surface_get_arrays(p_surface); ERR_FAIL_COND(arr.size() != RS::ARRAY_MAX); _create_list_from_arrays(arr, r_vertex, r_index, lformat); } -Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays) { - Vector<SurfaceTool::Vertex> ret; +void SurfaceTool::create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<SurfaceTool::Vertex> &ret, uint32_t *r_format) { + ret.clear(); Vector<Vector3> varr = p_arrays[RS::ARRAY_VERTEX]; Vector<Vector3> narr = p_arrays[RS::ARRAY_NORMAL]; @@ -509,10 +676,14 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array Vector<Vector2> uv2arr = p_arrays[RS::ARRAY_TEX_UV2]; Vector<int> barr = p_arrays[RS::ARRAY_BONES]; Vector<float> warr = p_arrays[RS::ARRAY_WEIGHTS]; + Vector<float> custom_float[RS::ARRAY_CUSTOM_COUNT]; int vc = varr.size(); if (vc == 0) { - return ret; + if (r_format) { + *r_format = 0; + } + return; } int lformat = 0; @@ -534,100 +705,40 @@ Vector<SurfaceTool::Vertex> SurfaceTool::create_vertex_array_from_triangle_array if (uv2arr.size()) { lformat |= RS::ARRAY_FORMAT_TEX_UV2; } - if (barr.size()) { + int wcount = 0; + if (barr.size() && warr.size()) { lformat |= RS::ARRAY_FORMAT_BONES; - } - if (warr.size()) { lformat |= RS::ARRAY_FORMAT_WEIGHTS; - } - for (int i = 0; i < vc; i++) { - Vertex v; - if (lformat & RS::ARRAY_FORMAT_VERTEX) { - v.vertex = varr[i]; - } - if (lformat & RS::ARRAY_FORMAT_NORMAL) { - v.normal = narr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TANGENT) { - Plane p(tarr[i * 4 + 0], tarr[i * 4 + 1], tarr[i * 4 + 2], tarr[i * 4 + 3]); - v.tangent = p.normal; - v.binormal = p.normal.cross(v.tangent).normalized() * p.d; - } - if (lformat & RS::ARRAY_FORMAT_COLOR) { - v.color = carr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV) { - v.uv = uvarr[i]; - } - if (lformat & RS::ARRAY_FORMAT_TEX_UV2) { - v.uv2 = uv2arr[i]; + wcount = barr.size() / varr.size(); + if (wcount == 8) { + lformat |= RS::ARRAY_FLAG_USE_8_BONE_WEIGHTS; } - if (lformat & RS::ARRAY_FORMAT_BONES) { - Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; - v.bones = b; - } - if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { - Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; - v.weights = w; - } - - ret.push_back(v); } - return ret; -} - -void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat) { - Vector<Vector3> varr = arr[RS::ARRAY_VERTEX]; - Vector<Vector3> narr = arr[RS::ARRAY_NORMAL]; - Vector<float> tarr = arr[RS::ARRAY_TANGENT]; - Vector<Color> carr = arr[RS::ARRAY_COLOR]; - Vector<Vector2> uvarr = arr[RS::ARRAY_TEX_UV]; - Vector<Vector2> uv2arr = arr[RS::ARRAY_TEX_UV2]; - Vector<int> barr = arr[RS::ARRAY_BONES]; - Vector<float> warr = arr[RS::ARRAY_WEIGHTS]; - - int vc = varr.size(); - if (vc == 0) { - return; - } - - lformat = 0; - if (varr.size()) { - lformat |= RS::ARRAY_FORMAT_VERTEX; - } - if (narr.size()) { - lformat |= RS::ARRAY_FORMAT_NORMAL; - } - if (tarr.size()) { - lformat |= RS::ARRAY_FORMAT_TANGENT; - } - if (carr.size()) { - lformat |= RS::ARRAY_FORMAT_COLOR; - } - if (uvarr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV; - } - if (uv2arr.size()) { - lformat |= RS::ARRAY_FORMAT_TEX_UV2; - } - if (barr.size()) { - lformat |= RS::ARRAY_FORMAT_BONES; - } if (warr.size()) { lformat |= RS::ARRAY_FORMAT_WEIGHTS; } + static const uint32_t custom_mask[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0, Mesh::ARRAY_FORMAT_CUSTOM1, Mesh::ARRAY_FORMAT_CUSTOM2, Mesh::ARRAY_FORMAT_CUSTOM3 }; + static const uint32_t custom_shift[RS::ARRAY_CUSTOM_COUNT] = { Mesh::ARRAY_FORMAT_CUSTOM0_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM1_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM2_SHIFT, Mesh::ARRAY_FORMAT_CUSTOM3_SHIFT }; + + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + ERR_CONTINUE_MSG(p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_BYTE_ARRAY, "Extracting Byte/Half formats is not supported"); + if (p_arrays[RS::ARRAY_CUSTOM0 + i].get_type() == Variant::PACKED_FLOAT32_ARRAY) { + lformat |= custom_mask[i]; + custom_float[i] = p_arrays[RS::ARRAY_CUSTOM0 + i]; + int fmt = custom_float[i].size() / varr.size(); + if (fmt == 1) { + lformat |= CUSTOM_R_FLOAT << custom_shift[i]; + } else if (fmt == 2) { + lformat |= CUSTOM_RG_FLOAT << custom_shift[i]; + } else if (fmt == 3) { + lformat |= CUSTOM_RGB_FLOAT << custom_shift[i]; + } else if (fmt == 4) { + lformat |= CUSTOM_RGBA_FLOAT << custom_shift[i]; + } + } + } for (int i = 0; i < vc; i++) { Vertex v; @@ -653,27 +764,44 @@ void SurfaceTool::_create_list_from_arrays(Array arr, List<Vertex> *r_vertex, Li } if (lformat & RS::ARRAY_FORMAT_BONES) { Vector<int> b; - b.resize(4); - b.write[0] = barr[i * 4 + 0]; - b.write[1] = barr[i * 4 + 1]; - b.write[2] = barr[i * 4 + 2]; - b.write[3] = barr[i * 4 + 3]; + b.resize(wcount); + for (int j = 0; j < wcount; j++) { + b.write[j] = barr[i * wcount + j]; + } v.bones = b; } if (lformat & RS::ARRAY_FORMAT_WEIGHTS) { Vector<float> w; - w.resize(4); - w.write[0] = warr[i * 4 + 0]; - w.write[1] = warr[i * 4 + 1]; - w.write[2] = warr[i * 4 + 2]; - w.write[3] = warr[i * 4 + 3]; + w.resize(wcount); + for (int j = 0; j < wcount; j++) { + w.write[j] = warr[i * wcount + j]; + } v.weights = w; } - r_vertex->push_back(v); + for (int j = 0; j < RS::ARRAY_CUSTOM_COUNT; j++) { + if (lformat & custom_mask[j]) { + int cc = custom_float[j].size() / varr.size(); + for (int k = 0; k < cc; k++) { + v.custom[j][k] = custom_float[j][i * cc + k]; + } + } + } + + ret.push_back(v); } + if (r_format) { + *r_format = lformat; + } +} + +void SurfaceTool::_create_list_from_arrays(Array arr, LocalVector<Vertex> *r_vertex, LocalVector<int> *r_index, uint32_t &lformat) { + create_vertex_array_from_triangle_arrays(arr, *r_vertex, &lformat); + ERR_FAIL_COND(r_vertex->size() == 0); + //indices + r_index->clear(); Vector<int> idx = arr[RS::ARRAY_INDEX]; int is = idx.size(); @@ -725,15 +853,15 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const format = 0; } - int nformat; - List<Vertex> nvertices; - List<int> nindices; + uint32_t nformat; + LocalVector<Vertex> nvertices; + LocalVector<int> nindices; _create_list(p_existing, p_surface, &nvertices, &nindices, nformat); format |= nformat; int vfrom = vertex_array.size(); - for (List<Vertex>::Element *E = nvertices.front(); E; E = E->next()) { - Vertex v = E->get(); + for (uint32_t vi = 0; vi < nvertices.size(); vi++) { + Vertex v = nvertices[vi]; v.vertex = p_xform.xform(v.vertex); if (nformat & RS::ARRAY_FORMAT_NORMAL) { v.normal = p_xform.basis.xform(v.normal); @@ -746,8 +874,8 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const vertex_array.push_back(v); } - for (List<int>::Element *E = nindices.front(); E; E = E->next()) { - int dst_index = E->get() + vfrom; + for (uint32_t i = 0; i < nindices.size(); i++) { + int dst_index = nindices[i] + vfrom; index_array.push_back(dst_index); } if (index_array.size() % 3) { @@ -758,18 +886,18 @@ void SurfaceTool::append_from(const Ref<Mesh> &p_existing, int p_surface, const //mikktspace callbacks namespace { struct TangentGenerationContextUserData { - Vector<List<SurfaceTool::Vertex>::Element *> vertices; - Vector<List<int>::Element *> indices; + LocalVector<SurfaceTool::Vertex> *vertices; + LocalVector<int> *indices; }; } // namespace int SurfaceTool::mikktGetNumFaces(const SMikkTSpaceContext *pContext) { TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); - if (triangle_data.indices.size() > 0) { - return triangle_data.indices.size() / 3; + if (triangle_data.indices->size() > 0) { + return triangle_data.indices->size() / 3; } else { - return triangle_data.vertices.size() / 3; + return triangle_data.vertices->size() / 3; } } @@ -780,13 +908,13 @@ int SurfaceTool::mikktGetNumVerticesOfFace(const SMikkTSpaceContext *pContext, c void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvPosOut[], const int iFace, const int iVert) { TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); Vector3 v; - if (triangle_data.indices.size() > 0) { - int index = triangle_data.indices[iFace * 3 + iVert]->get(); - if (index < triangle_data.vertices.size()) { - v = triangle_data.vertices[index]->get().vertex; + if (triangle_data.indices->size() > 0) { + uint32_t index = triangle_data.indices->operator[](iFace * 3 + iVert); + if (index < triangle_data.vertices->size()) { + v = triangle_data.vertices->operator[](index).vertex; } } else { - v = triangle_data.vertices[iFace * 3 + iVert]->get().vertex; + v = triangle_data.vertices->operator[](iFace * 3 + iVert).vertex; } fvPosOut[0] = v.x; @@ -797,13 +925,13 @@ void SurfaceTool::mikktGetPosition(const SMikkTSpaceContext *pContext, float fvP void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNormOut[], const int iFace, const int iVert) { TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); Vector3 v; - if (triangle_data.indices.size() > 0) { - int index = triangle_data.indices[iFace * 3 + iVert]->get(); - if (index < triangle_data.vertices.size()) { - v = triangle_data.vertices[index]->get().normal; + if (triangle_data.indices->size() > 0) { + uint32_t index = triangle_data.indices->operator[](iFace * 3 + iVert); + if (index < triangle_data.vertices->size()) { + v = triangle_data.vertices->operator[](index).normal; } } else { - v = triangle_data.vertices[iFace * 3 + iVert]->get().normal; + v = triangle_data.vertices->operator[](iFace * 3 + iVert).normal; } fvNormOut[0] = v.x; @@ -814,13 +942,13 @@ void SurfaceTool::mikktGetNormal(const SMikkTSpaceContext *pContext, float fvNor void SurfaceTool::mikktGetTexCoord(const SMikkTSpaceContext *pContext, float fvTexcOut[], const int iFace, const int iVert) { TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); Vector2 v; - if (triangle_data.indices.size() > 0) { - int index = triangle_data.indices[iFace * 3 + iVert]->get(); - if (index < triangle_data.vertices.size()) { - v = triangle_data.vertices[index]->get().uv; + if (triangle_data.indices->size() > 0) { + uint32_t index = triangle_data.indices->operator[](iFace * 3 + iVert); + if (index < triangle_data.vertices->size()) { + v = triangle_data.vertices->operator[](index).uv; } } else { - v = triangle_data.vertices[iFace * 3 + iVert]->get().uv; + v = triangle_data.vertices->operator[](iFace * 3 + iVert).uv; } fvTexcOut[0] = v.x; @@ -831,13 +959,13 @@ void SurfaceTool::mikktSetTSpaceDefault(const SMikkTSpaceContext *pContext, cons const tbool bIsOrientationPreserving, const int iFace, const int iVert) { TangentGenerationContextUserData &triangle_data = *reinterpret_cast<TangentGenerationContextUserData *>(pContext->m_pUserData); Vertex *vtx = nullptr; - if (triangle_data.indices.size() > 0) { - int index = triangle_data.indices[iFace * 3 + iVert]->get(); - if (index < triangle_data.vertices.size()) { - vtx = &triangle_data.vertices[index]->get(); + if (triangle_data.indices->size() > 0) { + uint32_t index = triangle_data.indices->operator[](iFace * 3 + iVert); + if (index < triangle_data.vertices->size()) { + vtx = &triangle_data.vertices->operator[](index); } } else { - vtx = &triangle_data.vertices[iFace * 3 + iVert]->get(); + vtx = &triangle_data.vertices->operator[](iFace * 3 + iVert); } if (vtx != nullptr) { @@ -863,18 +991,12 @@ void SurfaceTool::generate_tangents() { msc.m_pInterface = &mkif; TangentGenerationContextUserData triangle_data; - triangle_data.vertices.resize(vertex_array.size()); - int idx = 0; - for (List<Vertex>::Element *E = vertex_array.front(); E; E = E->next()) { - triangle_data.vertices.write[idx++] = E; - E->get().binormal = Vector3(); - E->get().tangent = Vector3(); - } - triangle_data.indices.resize(index_array.size()); - idx = 0; - for (List<int>::Element *E = index_array.front(); E; E = E->next()) { - triangle_data.indices.write[idx++] = E; + triangle_data.vertices = &vertex_array; + for (uint32_t i = 0; i < vertex_array.size(); i++) { + vertex_array[i].binormal = Vector3(); + vertex_array[i].tangent = Vector3(); } + triangle_data.indices = &index_array; msc.m_pUserData = &triangle_data; bool res = genTangSpaceDefault(&msc); @@ -890,66 +1012,36 @@ void SurfaceTool::generate_normals(bool p_flip) { deindex(); - HashMap<Vertex, Vector3, VertexHasher> vertex_hash; + ERR_FAIL_COND((vertex_array.size() % 3) != 0); - int count = 0; - bool smooth = false; - if (smooth_groups.has(0)) { - smooth = smooth_groups[0]; - } + HashMap<Vertex, Vector3, VertexHasher> vertex_hash; - List<Vertex>::Element *B = vertex_array.front(); - for (List<Vertex>::Element *E = B; E;) { - List<Vertex>::Element *v[3]; - v[0] = E; - v[1] = v[0]->next(); - ERR_FAIL_COND(!v[1]); - v[2] = v[1]->next(); - ERR_FAIL_COND(!v[2]); - E = v[2]->next(); + for (uint32_t vi = 0; vi < vertex_array.size(); vi += 3) { + Vertex *v = &vertex_array[vi]; Vector3 normal; if (!p_flip) { - normal = Plane(v[0]->get().vertex, v[1]->get().vertex, v[2]->get().vertex).normal; - } else { - normal = Plane(v[2]->get().vertex, v[1]->get().vertex, v[0]->get().vertex).normal; - } - - if (smooth) { - for (int i = 0; i < 3; i++) { - Vector3 *lv = vertex_hash.getptr(v[i]->get()); - if (!lv) { - vertex_hash.set(v[i]->get(), normal); - } else { - (*lv) += normal; - } - } + normal = Plane(v[0].vertex, v[1].vertex, v[2].vertex).normal; } else { - for (int i = 0; i < 3; i++) { - v[i]->get().normal = normal; - } + normal = Plane(v[2].vertex, v[1].vertex, v[0].vertex).normal; } - count += 3; - - if (smooth_groups.has(count) || !E) { - if (vertex_hash.size()) { - while (B != E) { - Vector3 *lv = vertex_hash.getptr(B->get()); - if (lv) { - B->get().normal = lv->normalized(); - } - - B = B->next(); - } + for (int i = 0; i < 3; i++) { + Vector3 *lv = vertex_hash.getptr(v[i]); + if (!lv) { + vertex_hash.set(v[i], normal); } else { - B = E; + (*lv) += normal; } + } + } - vertex_hash.clear(); - if (E) { - smooth = smooth_groups[count]; - } + for (uint32_t vi = 0; vi < vertex_array.size(); vi++) { + Vector3 *lv = vertex_hash.getptr(vertex_array[vi]); + if (!lv) { + vertex_array[vi].normal = Vector3(); + } else { + vertex_array[vi].normal = lv->normalized(); } } @@ -957,7 +1049,6 @@ void SurfaceTool::generate_normals(bool p_flip) { if (was_indexed) { index(); - smooth_groups.clear(); } } @@ -973,22 +1064,97 @@ void SurfaceTool::clear() { last_weights.clear(); index_array.clear(); vertex_array.clear(); - smooth_groups.clear(); material.unref(); + last_smooth_group = 0; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } + skin_weights = SKIN_4_WEIGHTS; +} + +void SurfaceTool::set_skin_weight_count(SkinWeightCount p_weights) { + ERR_FAIL_COND(begun); + skin_weights = p_weights; +} +SurfaceTool::SkinWeightCount SurfaceTool::get_skin_weight_count() const { + return skin_weights; +} + +void SurfaceTool::set_custom_format(int p_index, CustomFormat p_format) { + ERR_FAIL_INDEX(p_index, RS::ARRAY_CUSTOM_COUNT); + ERR_FAIL_COND(begun); + last_custom_format[p_index] = p_format; +} +SurfaceTool::CustomFormat SurfaceTool::get_custom_format(int p_index) const { + ERR_FAIL_INDEX_V(p_index, RS::ARRAY_CUSTOM_COUNT, CUSTOM_MAX); + return last_custom_format[p_index]; +} +void SurfaceTool::optimize_indices_for_cache() { + ERR_FAIL_COND(optimize_vertex_cache_func == nullptr); + ERR_FAIL_COND(index_array.size() == 0); + + LocalVector old_index_array = index_array; + zeromem(index_array.ptr(), index_array.size() * sizeof(int)); + optimize_vertex_cache_func((unsigned int *)index_array.ptr(), (unsigned int *)old_index_array.ptr(), old_index_array.size(), vertex_array.size()); +} + +float SurfaceTool::get_max_axis_length() const { + ERR_FAIL_COND_V(vertex_array.size() == 0, 0); + + AABB aabb; + for (uint32_t i = 0; i < vertex_array.size(); i++) { + if (i == 0) { + aabb.position = vertex_array[i].vertex; + } else { + aabb.expand_to(vertex_array[i].vertex); + } + } + + return aabb.get_longest_axis_size(); +} +Vector<int> SurfaceTool::generate_lod(float p_threshold, int p_target_index_count) { + Vector<int> lod; + + ERR_FAIL_COND_V(simplify_func == nullptr, lod); + ERR_FAIL_COND_V(vertex_array.size() == 0, lod); + ERR_FAIL_COND_V(index_array.size() == 0, lod); + + lod.resize(index_array.size()); + LocalVector<float> vertices; //uses floats + vertices.resize(vertex_array.size() * 3); + for (uint32_t i = 0; i < vertex_array.size(); i++) { + vertices[i * 3 + 0] = vertex_array[i].vertex.x; + vertices[i * 3 + 1] = vertex_array[i].vertex.y; + vertices[i * 3 + 2] = vertex_array[i].vertex.z; + } + + float error; + uint32_t index_count = simplify_func((unsigned int *)lod.ptrw(), (unsigned int *)index_array.ptr(), index_array.size(), vertices.ptr(), vertex_array.size(), sizeof(float) * 3, p_target_index_count, p_threshold, &error); + ERR_FAIL_COND_V(index_count == 0, lod); + lod.resize(index_count); + + return lod; } void SurfaceTool::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_skin_weight_count", "count"), &SurfaceTool::set_skin_weight_count); + ClassDB::bind_method(D_METHOD("get_skin_weight_count"), &SurfaceTool::get_skin_weight_count); + + ClassDB::bind_method(D_METHOD("set_custom_format", "index", "format"), &SurfaceTool::set_custom_format); + ClassDB::bind_method(D_METHOD("get_custom_format", "index"), &SurfaceTool::get_custom_format); + ClassDB::bind_method(D_METHOD("begin", "primitive"), &SurfaceTool::begin); ClassDB::bind_method(D_METHOD("add_vertex", "vertex"), &SurfaceTool::add_vertex); - ClassDB::bind_method(D_METHOD("add_color", "color"), &SurfaceTool::add_color); - ClassDB::bind_method(D_METHOD("add_normal", "normal"), &SurfaceTool::add_normal); - ClassDB::bind_method(D_METHOD("add_tangent", "tangent"), &SurfaceTool::add_tangent); - ClassDB::bind_method(D_METHOD("add_uv", "uv"), &SurfaceTool::add_uv); - ClassDB::bind_method(D_METHOD("add_uv2", "uv2"), &SurfaceTool::add_uv2); - ClassDB::bind_method(D_METHOD("add_bones", "bones"), &SurfaceTool::add_bones); - ClassDB::bind_method(D_METHOD("add_weights", "weights"), &SurfaceTool::add_weights); - ClassDB::bind_method(D_METHOD("add_smooth_group", "smooth"), &SurfaceTool::add_smooth_group); + ClassDB::bind_method(D_METHOD("set_color", "color"), &SurfaceTool::set_color); + ClassDB::bind_method(D_METHOD("set_normal", "normal"), &SurfaceTool::set_normal); + ClassDB::bind_method(D_METHOD("set_tangent", "tangent"), &SurfaceTool::set_tangent); + ClassDB::bind_method(D_METHOD("set_uv", "uv"), &SurfaceTool::set_uv); + ClassDB::bind_method(D_METHOD("set_uv2", "uv2"), &SurfaceTool::set_uv2); + ClassDB::bind_method(D_METHOD("set_bones", "bones"), &SurfaceTool::set_bones); + ClassDB::bind_method(D_METHOD("set_weights", "weights"), &SurfaceTool::set_weights); + ClassDB::bind_method(D_METHOD("set_custom", "index", "custom"), &SurfaceTool::set_custom); + ClassDB::bind_method(D_METHOD("set_smooth_group", "index"), &SurfaceTool::set_smooth_group); ClassDB::bind_method(D_METHOD("add_triangle_fan", "vertices", "uvs", "colors", "uv2s", "normals", "tangents"), &SurfaceTool::add_triangle_fan, DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Color>()), DEFVAL(Vector<Vector2>()), DEFVAL(Vector<Vector3>()), DEFVAL(Vector<Plane>())); @@ -999,6 +1165,11 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("generate_normals", "flip"), &SurfaceTool::generate_normals, DEFVAL(false)); ClassDB::bind_method(D_METHOD("generate_tangents"), &SurfaceTool::generate_tangents); + ClassDB::bind_method(D_METHOD("optimize_indices_for_cache"), &SurfaceTool::optimize_indices_for_cache); + + ClassDB::bind_method(D_METHOD("get_max_axis_length"), &SurfaceTool::get_max_axis_length); + ClassDB::bind_method(D_METHOD("generate_lod", "nd_threshold", "target_index_count"), &SurfaceTool::generate_lod, DEFVAL(3)); + ClassDB::bind_method(D_METHOD("set_material", "material"), &SurfaceTool::set_material); ClassDB::bind_method(D_METHOD("clear"), &SurfaceTool::clear); @@ -1006,13 +1177,29 @@ void SurfaceTool::_bind_methods() { ClassDB::bind_method(D_METHOD("create_from", "existing", "surface"), &SurfaceTool::create_from); ClassDB::bind_method(D_METHOD("create_from_blend_shape", "existing", "surface", "blend_shape"), &SurfaceTool::create_from_blend_shape); ClassDB::bind_method(D_METHOD("append_from", "existing", "surface", "transform"), &SurfaceTool::append_from); - ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(Mesh::ARRAY_COMPRESS_DEFAULT)); + ClassDB::bind_method(D_METHOD("commit", "existing", "flags"), &SurfaceTool::commit, DEFVAL(Variant()), DEFVAL(0)); ClassDB::bind_method(D_METHOD("commit_to_arrays"), &SurfaceTool::commit_to_arrays); + + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_UNORM); + BIND_ENUM_CONSTANT(CUSTOM_RGBA8_SNORM); + BIND_ENUM_CONSTANT(CUSTOM_RG_HALF); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_HALF); + BIND_ENUM_CONSTANT(CUSTOM_R_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RG_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGB_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_RGBA_FLOAT); + BIND_ENUM_CONSTANT(CUSTOM_MAX); + BIND_ENUM_CONSTANT(SKIN_4_WEIGHTS); + BIND_ENUM_CONSTANT(SKIN_8_WEIGHTS); } SurfaceTool::SurfaceTool() { first = false; begun = false; + for (int i = 0; i < RS::ARRAY_CUSTOM_COUNT; i++) { + last_custom_format[i] = CUSTOM_MAX; + } primitive = Mesh::PRIMITIVE_LINES; + skin_weights = SKIN_4_WEIGHTS; format = 0; } diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index d7b255e695..0e60bfe389 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -31,8 +31,8 @@ #ifndef SURFACE_TOOL_H #define SURFACE_TOOL_H +#include "core/templates/local_vector.h" #include "scene/resources/mesh.h" - #include "thirdparty/misc/mikktspace.h" class SurfaceTool : public Reference { @@ -49,12 +49,36 @@ public: Vector2 uv2; Vector<int> bones; Vector<float> weights; + Color custom[RS::ARRAY_CUSTOM_COUNT]; + uint32_t smooth_group = 0; bool operator==(const Vertex &p_vertex) const; Vertex() {} }; + enum CustomFormat { + CUSTOM_RGBA8_UNORM = RS::ARRAY_CUSTOM_RGBA8_UNORM, + CUSTOM_RGBA8_SNORM = RS::ARRAY_CUSTOM_RGBA8_SNORM, + CUSTOM_RG_HALF = RS::ARRAY_CUSTOM_RG_HALF, + CUSTOM_RGBA_HALF = RS::ARRAY_CUSTOM_RGBA_HALF, + CUSTOM_R_FLOAT = RS::ARRAY_CUSTOM_R_FLOAT, + CUSTOM_RG_FLOAT = RS::ARRAY_CUSTOM_RG_FLOAT, + CUSTOM_RGB_FLOAT = RS::ARRAY_CUSTOM_RGB_FLOAT, + CUSTOM_RGBA_FLOAT = RS::ARRAY_CUSTOM_RGBA_FLOAT, + CUSTOM_MAX = RS::ARRAY_CUSTOM_MAX + }; + + enum SkinWeightCount { + SKIN_4_WEIGHTS, + SKIN_8_WEIGHTS + }; + + typedef void (*OptimizeVertexCacheFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, size_t vertex_count); + static OptimizeVertexCacheFunc optimize_vertex_cache_func; + typedef size_t (*SimplifyFunc)(unsigned int *destination, const unsigned int *indices, size_t index_count, const float *vertex_positions, size_t vertex_count, size_t vertex_positions_stride, size_t target_index_count, float target_error, float *r_error); + static SimplifyFunc simplify_func; + private: struct VertexHasher { static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx); @@ -71,12 +95,11 @@ private: bool begun; bool first; Mesh::PrimitiveType primitive; - int format; + uint32_t format; Ref<Material> material; //arrays - List<Vertex> vertex_array; - List<int> index_array; - Map<int, bool> smooth_groups; + LocalVector<Vertex> vertex_array; + LocalVector<int> index_array; //memory Color last_color; @@ -86,9 +109,16 @@ private: Vector<int> last_bones; Vector<float> last_weights; Plane last_tangent; + uint32_t last_smooth_group = 0; + + SkinWeightCount skin_weights; - void _create_list_from_arrays(Array arr, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); - void _create_list(const Ref<Mesh> &p_existing, int p_surface, List<Vertex> *r_vertex, List<int> *r_index, int &lformat); + Color last_custom[RS::ARRAY_CUSTOM_COUNT]; + + CustomFormat last_custom_format[RS::ARRAY_CUSTOM_COUNT]; + + void _create_list_from_arrays(Array arr, LocalVector<Vertex> *r_vertex, LocalVector<int> *r_index, uint32_t &lformat); + void _create_list(const Ref<Mesh> &p_existing, int p_surface, LocalVector<Vertex> *r_vertex, LocalVector<int> *r_index, uint32_t &lformat); //mikktspace callbacks static int mikktGetNumFaces(const SMikkTSpaceContext *pContext); @@ -103,17 +133,25 @@ protected: static void _bind_methods(); public: + void set_skin_weight_count(SkinWeightCount p_weights); + SkinWeightCount get_skin_weight_count() const; + + void set_custom_format(int p_index, CustomFormat p_format); + CustomFormat get_custom_format(int p_index) const; + void begin(Mesh::PrimitiveType p_primitive); + void set_color(Color p_color); + void set_normal(const Vector3 &p_normal); + void set_tangent(const Plane &p_tangent); + void set_uv(const Vector2 &p_uv); + void set_uv2(const Vector2 &p_uv2); + void set_custom(int p_index, const Color &p_custom); + void set_bones(const Vector<int> &p_bones); + void set_weights(const Vector<float> &p_weights); + void set_smooth_group(uint32_t p_group); + void add_vertex(const Vector3 &p_vertex); - void add_color(Color p_color); - void add_normal(const Vector3 &p_normal); - void add_tangent(const Plane &p_tangent); - void add_uv(const Vector2 &p_uv); - void add_uv2(const Vector2 &p_uv2); - void add_bones(const Vector<int> &p_bones); - void add_weights(const Vector<float> &p_weights); - void add_smooth_group(bool p_smooth); void add_triangle_fan(const Vector<Vector3> &p_vertices, const Vector<Vector2> &p_uvs = Vector<Vector2>(), const Vector<Color> &p_colors = Vector<Color>(), const Vector<Vector2> &p_uv2s = Vector<Vector2>(), const Vector<Vector3> &p_normals = Vector<Vector3>(), const Vector<Plane> &p_tangents = Vector<Plane>()); @@ -124,21 +162,28 @@ public: void generate_normals(bool p_flip = false); void generate_tangents(); + void optimize_indices_for_cache(); + float get_max_axis_length() const; + Vector<int> generate_lod(float p_threshold, int p_target_index_count = 3); + void set_material(const Ref<Material> &p_material); void clear(); - List<Vertex> &get_vertex_array() { return vertex_array; } + LocalVector<Vertex> &get_vertex_array() { return vertex_array; } void create_from_triangle_arrays(const Array &p_arrays); - static Vector<Vertex> create_vertex_array_from_triangle_arrays(const Array &p_arrays); + static void create_vertex_array_from_triangle_arrays(const Array &p_arrays, LocalVector<Vertex> &ret, uint32_t *r_format = nullptr); Array commit_to_arrays(); void create_from(const Ref<Mesh> &p_existing, int p_surface); void create_from_blend_shape(const Ref<Mesh> &p_existing, int p_surface, const String &p_blend_shape_name); void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform); - Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = Mesh::ARRAY_COMPRESS_DEFAULT); + Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>(), uint32_t p_flags = 0); SurfaceTool(); }; +VARIANT_ENUM_CAST(SurfaceTool::CustomFormat) +VARIANT_ENUM_CAST(SurfaceTool::SkinWeightCount) + #endif diff --git a/scene/resources/text_line.cpp b/scene/resources/text_line.cpp index 5a419bb232..cc9b6758b6 100644 --- a/scene/resources/text_line.cpp +++ b/scene/resources/text_line.cpp @@ -113,6 +113,8 @@ RID TextLine::get_rid() const { void TextLine::clear() { TS->shaped_text_clear(rid); + spacing_top = 0; + spacing_bottom = 0; } void TextLine::set_preserve_invalid(bool p_enabled) { @@ -166,6 +168,8 @@ void TextLine::set_bidi_override(const Vector<Vector2i> &p_override) { bool TextLine::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); dirty = true; return res; } @@ -233,17 +237,21 @@ float TextLine::get_width() const { Size2 TextLine::get_size() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_size(rid); + if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y); + } } float TextLine::get_line_ascent() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_ascent(rid); + return TS->shaped_text_get_ascent(rid) + spacing_top; } float TextLine::get_line_descent() const { const_cast<TextLine *>(this)->_shape(); - return TS->shaped_text_get_descent(rid); + return TS->shaped_text_get_descent(rid) + spacing_bottom; } float TextLine::get_line_width() const { @@ -291,10 +299,10 @@ void TextLine::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_color) co float clip_l; if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(rid); + ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.x - ofs.x); } else { - ofs.x += TS->shaped_text_get_ascent(rid); + ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.y - ofs.y); } return TS->shaped_text_draw(rid, p_canvas, ofs, clip_l, clip_l + width, p_color); @@ -330,10 +338,10 @@ void TextLine::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outline_si float clip_l; if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(rid); + ofs.y += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.x - ofs.x); } else { - ofs.x += TS->shaped_text_get_ascent(rid); + ofs.x += TS->shaped_text_get_ascent(rid) + spacing_top; clip_l = MAX(0, p_pos.y - ofs.y); } return TS->shaped_text_draw_outline(rid, p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color); @@ -347,6 +355,8 @@ int TextLine::hit_test(float p_coords) const { TextLine::TextLine(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, TextServer::Direction p_direction, TextServer::Orientation p_orientation) { rid = TS->create_shaped_text(p_direction, p_orientation); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); } diff --git a/scene/resources/text_line.h b/scene/resources/text_line.h index ffa06cc5c1..6ed3558bd9 100644 --- a/scene/resources/text_line.h +++ b/scene/resources/text_line.h @@ -40,6 +40,8 @@ class TextLine : public Reference { GDCLASS(TextLine, Reference); RID rid; + int spacing_top = 0; + int spacing_bottom = 0; bool dirty = true; diff --git a/scene/resources/text_paragraph.cpp b/scene/resources/text_paragraph.cpp index d4f96ff9e8..fd6dd071eb 100644 --- a/scene/resources/text_paragraph.cpp +++ b/scene/resources/text_paragraph.cpp @@ -140,6 +140,8 @@ RID TextParagraph::get_line_rid(int p_line) const { } void TextParagraph::clear() { + spacing_top = 0; + spacing_bottom = 0; for (int i = 0; i < lines.size(); i++) { TS->free(lines[i]); } @@ -187,6 +189,8 @@ TextServer::Orientation TextParagraph::get_orientation() const { bool TextParagraph::add_string(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language) { bool res = TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); dirty_lines = true; return res; } @@ -260,7 +264,11 @@ float TextParagraph::get_width() const { Size2 TextParagraph::get_non_wraped_size() const { const_cast<TextParagraph *>(this)->_shape_lines(); - return TS->shaped_text_get_size(rid); + if (TS->shaped_text_get_orientation(rid) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(rid).x, TS->shaped_text_get_size(rid).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(rid).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(rid).y); + } } Size2 TextParagraph::get_size() const { @@ -270,9 +278,9 @@ Size2 TextParagraph::get_size() const { Size2 lsize = TS->shaped_text_get_size(lines[i]); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { size.x = MAX(size.x, lsize.x); - size.y += lsize.y; + size.y += lsize.y + spacing_top + spacing_bottom; } else { - size.x += lsize.x; + size.x += lsize.x + spacing_top + spacing_bottom; size.y = MAX(size.y, lsize.y); } } @@ -297,9 +305,9 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const { for (int i = 0; i < p_line; i++) { Size2 lsize = TS->shaped_text_get_size(lines[i]); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { - xrect.position.y += lsize.y; + xrect.position.y += lsize.y + spacing_top + spacing_bottom; } else { - xrect.position.x += lsize.x; + xrect.position.x += lsize.x + spacing_top + spacing_bottom; } } return xrect; @@ -308,7 +316,11 @@ Rect2 TextParagraph::get_line_object_rect(int p_line, Variant p_key) const { Size2 TextParagraph::get_line_size(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), Size2()); - return TS->shaped_text_get_size(lines[p_line]); + if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { + return Size2(TS->shaped_text_get_size(lines[p_line]).x, TS->shaped_text_get_size(lines[p_line]).y + spacing_top + spacing_bottom); + } else { + return Size2(TS->shaped_text_get_size(lines[p_line]).x + spacing_top + spacing_bottom, TS->shaped_text_get_size(lines[p_line]).y); + } } Vector2i TextParagraph::get_line_range(int p_line) const { @@ -320,13 +332,13 @@ Vector2i TextParagraph::get_line_range(int p_line) const { float TextParagraph::get_line_ascent(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f); - return TS->shaped_text_get_ascent(lines[p_line]); + return TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } float TextParagraph::get_line_descent(int p_line) const { const_cast<TextParagraph *>(this)->_shape_lines(); ERR_FAIL_COND_V(p_line < 0 || p_line >= lines.size(), 0.f); - return TS->shaped_text_get_descent(lines[p_line]); + return TS->shaped_text_get_descent(lines[p_line]) + spacing_bottom; } float TextParagraph::get_line_width(int p_line) const { @@ -353,10 +365,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo for (int i = 0; i < lines.size(); i++) { if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_ascent(lines[i]); + ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_ascent(lines[i]); + ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } float length = TS->shaped_text_get_width(lines[i]); if (width > 0) { @@ -389,10 +401,10 @@ void TextParagraph::draw(RID p_canvas, const Vector2 &p_pos, const Color &p_colo TS->shaped_text_draw(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_color); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines[i]); + ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines[i]); + ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } } } @@ -403,10 +415,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli for (int i = 0; i < lines.size(); i++) { if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_ascent(lines[i]); + ofs.y += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_ascent(lines[i]); + ofs.x += TS->shaped_text_get_ascent(lines[i]) + spacing_top; } float length = TS->shaped_text_get_width(lines[i]); if (width > 0) { @@ -439,10 +451,10 @@ void TextParagraph::draw_outline(RID p_canvas, const Vector2 &p_pos, int p_outli TS->shaped_text_draw_outline(lines[i], p_canvas, ofs, clip_l, clip_l + width, p_outline_size, p_color); if (TS->shaped_text_get_orientation(lines[i]) == TextServer::ORIENTATION_HORIZONTAL) { ofs.x = p_pos.x; - ofs.y += TS->shaped_text_get_descent(lines[i]); + ofs.y += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } else { ofs.y = p_pos.y; - ofs.x += TS->shaped_text_get_descent(lines[i]); + ofs.x += TS->shaped_text_get_descent(lines[i]) + spacing_bottom; } } } @@ -462,10 +474,12 @@ int TextParagraph::hit_test(const Point2 &p_coords) const { if ((p_coords.y >= ofs.y) && (p_coords.y <= ofs.y + TS->shaped_text_get_size(lines[i]).y)) { return TS->shaped_text_hit_test_position(lines[i], p_coords.x); } + ofs.y += TS->shaped_text_get_size(lines[i]).y + spacing_bottom + spacing_top; } else { if ((p_coords.x >= ofs.x) && (p_coords.x <= ofs.x + TS->shaped_text_get_size(lines[i]).x)) { return TS->shaped_text_hit_test_position(lines[i], p_coords.y); } + ofs.y += TS->shaped_text_get_size(lines[i]).x + spacing_bottom + spacing_top; } } return TS->shaped_text_get_range(rid).y; @@ -477,9 +491,9 @@ void TextParagraph::draw_line(RID p_canvas, const Vector2 &p_pos, int p_line, co Vector2 ofs = p_pos; if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(lines[p_line]); + ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } else { - ofs.x += TS->shaped_text_get_ascent(lines[p_line]); + ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } return TS->shaped_text_draw(lines[p_line], p_canvas, ofs, -1, -1, p_color); } @@ -490,9 +504,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_ Vector2 ofs = p_pos; if (TS->shaped_text_get_orientation(lines[p_line]) == TextServer::ORIENTATION_HORIZONTAL) { - ofs.y += TS->shaped_text_get_ascent(lines[p_line]); + ofs.y += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } else { - ofs.x += TS->shaped_text_get_ascent(lines[p_line]); + ofs.x += TS->shaped_text_get_ascent(lines[p_line]) + spacing_top; } return TS->shaped_text_draw_outline(lines[p_line], p_canvas, ofs, -1, -1, p_outline_size, p_color); } @@ -500,8 +514,9 @@ void TextParagraph::draw_line_outline(RID p_canvas, const Vector2 &p_pos, int p_ TextParagraph::TextParagraph(const String &p_text, const Ref<Font> &p_fonts, int p_size, const Dictionary &p_opentype_features, const String &p_language, float p_width, TextServer::Direction p_direction, TextServer::Orientation p_orientation) { rid = TS->create_shaped_text(p_direction, p_orientation); TS->shaped_text_add_string(rid, p_text, p_fonts->get_rids(), p_size, p_opentype_features, p_language); + spacing_top = p_fonts->get_spacing(Font::SPACING_TOP); + spacing_bottom = p_fonts->get_spacing(Font::SPACING_BOTTOM); width = p_width; - dirty_lines = true; } TextParagraph::TextParagraph() { diff --git a/scene/resources/text_paragraph.h b/scene/resources/text_paragraph.h index 587bb6bfc1..f7f49e9058 100644 --- a/scene/resources/text_paragraph.h +++ b/scene/resources/text_paragraph.h @@ -41,6 +41,8 @@ class TextParagraph : public Reference { RID rid; Vector<RID> lines; + int spacing_top = 0; + int spacing_bottom = 0; bool dirty_lines = true; diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index d130470275..c8bfcdfab4 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -51,6 +51,21 @@ Vector<String> Theme::_get_icon_list(const String &p_node_type) const { return ilret; } +Vector<String> Theme::_get_icon_type_list() const { + Vector<String> ilret; + List<StringName> il; + + get_icon_type_list(&il); + ilret.resize(il.size()); + + int i = 0; + String *w = ilret.ptrw(); + for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { + w[i] = E->get(); + } + return ilret; +} + Vector<String> Theme::_get_stylebox_list(const String &p_node_type) const { Vector<String> ilret; List<StringName> il; @@ -66,11 +81,11 @@ Vector<String> Theme::_get_stylebox_list(const String &p_node_type) const { return ilret; } -Vector<String> Theme::_get_stylebox_types() const { +Vector<String> Theme::_get_stylebox_type_list() const { Vector<String> ilret; List<StringName> il; - get_stylebox_types(&il); + get_stylebox_type_list(&il); ilret.resize(il.size()); int i = 0; @@ -96,6 +111,21 @@ Vector<String> Theme::_get_font_list(const String &p_node_type) const { return ilret; } +Vector<String> Theme::_get_font_type_list() const { + Vector<String> ilret; + List<StringName> il; + + get_font_type_list(&il); + ilret.resize(il.size()); + + int i = 0; + String *w = ilret.ptrw(); + for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { + w[i] = E->get(); + } + return ilret; +} + Vector<String> Theme::_get_font_size_list(const String &p_node_type) const { Vector<String> ilret; List<StringName> il; @@ -126,6 +156,21 @@ Vector<String> Theme::_get_color_list(const String &p_node_type) const { return ilret; } +Vector<String> Theme::_get_color_type_list() const { + Vector<String> ilret; + List<StringName> il; + + get_color_type_list(&il); + ilret.resize(il.size()); + + int i = 0; + String *w = ilret.ptrw(); + for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { + w[i] = E->get(); + } + return ilret; +} + Vector<String> Theme::_get_constant_list(const String &p_node_type) const { Vector<String> ilret; List<StringName> il; @@ -141,7 +186,22 @@ Vector<String> Theme::_get_constant_list(const String &p_node_type) const { return ilret; } -Vector<String> Theme::_get_type_list(const String &p_node_type) const { +Vector<String> Theme::_get_constant_type_list() const { + Vector<String> ilret; + List<StringName> il; + + get_constant_type_list(&il); + ilret.resize(il.size()); + + int i = 0; + String *w = ilret.ptrw(); + for (List<StringName>::Element *E = il.front(); E; E = E->next(), i++) { + w[i] = E->get(); + } + return ilret; +} + +Vector<String> Theme::_get_type_list() const { Vector<String> ilret; List<StringName> il; @@ -421,48 +481,11 @@ void Theme::get_icon_list(StringName p_node_type, List<StringName> *p_list) cons } } -void Theme::set_shader(const StringName &p_name, const StringName &p_node_type, const Ref<Shader> &p_shader) { - bool new_value = !shader_map.has(p_node_type) || !shader_map[p_node_type].has(p_name); - - shader_map[p_node_type][p_name] = p_shader; - - if (new_value) { - _change_notify(); - emit_changed(); - } -} - -Ref<Shader> Theme::get_shader(const StringName &p_name, const StringName &p_node_type) const { - if (shader_map.has(p_node_type) && shader_map[p_node_type].has(p_name) && shader_map[p_node_type][p_name].is_valid()) { - return shader_map[p_node_type][p_name]; - } else { - return nullptr; - } -} - -bool Theme::has_shader(const StringName &p_name, const StringName &p_node_type) const { - return (shader_map.has(p_node_type) && shader_map[p_node_type].has(p_name) && shader_map[p_node_type][p_name].is_valid()); -} - -void Theme::clear_shader(const StringName &p_name, const StringName &p_node_type) { - ERR_FAIL_COND(!shader_map.has(p_node_type)); - ERR_FAIL_COND(!shader_map[p_node_type].has(p_name)); - - shader_map[p_node_type].erase(p_name); - _change_notify(); - emit_changed(); -} - -void Theme::get_shader_list(const StringName &p_node_type, List<StringName> *p_list) const { +void Theme::get_icon_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); - if (!shader_map.has(p_node_type)) { - return; - } - const StringName *key = nullptr; - - while ((key = shader_map[p_node_type].next(key))) { + while ((key = icon_map.next(key))) { p_list->push_back(*key); } } @@ -528,7 +551,7 @@ void Theme::get_stylebox_list(StringName p_node_type, List<StringName> *p_list) } } -void Theme::get_stylebox_types(List<StringName> *p_list) const { +void Theme::get_stylebox_type_list(List<StringName> *p_list) const { ERR_FAIL_NULL(p_list); const StringName *key = nullptr; @@ -599,6 +622,15 @@ void Theme::get_font_list(StringName p_node_type, List<StringName> *p_list) cons } } +void Theme::get_font_type_list(List<StringName> *p_list) const { + ERR_FAIL_NULL(p_list); + + const StringName *key = nullptr; + while ((key = font_map.next(key))) { + p_list->push_back(*key); + } +} + void Theme::set_font_size(const StringName &p_name, const StringName &p_node_type, int p_font_size) { bool new_value = !font_size_map.has(p_node_type) || !font_size_map[p_node_type].has(p_name); @@ -693,6 +725,15 @@ void Theme::get_color_list(StringName p_node_type, List<StringName> *p_list) con } } +void Theme::get_color_type_list(List<StringName> *p_list) const { + ERR_FAIL_NULL(p_list); + + const StringName *key = nullptr; + while ((key = color_map.next(key))) { + p_list->push_back(*key); + } +} + void Theme::set_constant(const StringName &p_name, const StringName &p_node_type, int p_constant) { bool new_value = !constant_map.has(p_node_type) || !constant_map[p_node_type].has(p_name); constant_map[p_node_type][p_name] = p_constant; @@ -738,6 +779,15 @@ void Theme::get_constant_list(StringName p_node_type, List<StringName> *p_list) } } +void Theme::get_constant_type_list(List<StringName> *p_list) const { + ERR_FAIL_NULL(p_list); + + const StringName *key = nullptr; + while ((key = constant_map.next(key))) { + p_list->push_back(*key); + } +} + void Theme::clear() { //these need disconnecting { @@ -782,7 +832,6 @@ void Theme::clear() { icon_map.clear(); style_map.clear(); font_map.clear(); - shader_map.clear(); color_map.clear(); constant_map.clear(); @@ -837,7 +886,6 @@ void Theme::copy_theme(const Ref<Theme> &p_other) { color_map = p_other->color_map; constant_map = p_other->constant_map; - shader_map = p_other->shader_map; _change_notify(); emit_changed(); @@ -888,19 +936,21 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("has_icon", "name", "node_type"), &Theme::has_icon); ClassDB::bind_method(D_METHOD("clear_icon", "name", "node_type"), &Theme::clear_icon); ClassDB::bind_method(D_METHOD("get_icon_list", "node_type"), &Theme::_get_icon_list); + ClassDB::bind_method(D_METHOD("get_icon_type_list"), &Theme::_get_icon_type_list); ClassDB::bind_method(D_METHOD("set_stylebox", "name", "node_type", "texture"), &Theme::set_stylebox); ClassDB::bind_method(D_METHOD("get_stylebox", "name", "node_type"), &Theme::get_stylebox); ClassDB::bind_method(D_METHOD("has_stylebox", "name", "node_type"), &Theme::has_stylebox); ClassDB::bind_method(D_METHOD("clear_stylebox", "name", "node_type"), &Theme::clear_stylebox); ClassDB::bind_method(D_METHOD("get_stylebox_list", "node_type"), &Theme::_get_stylebox_list); - ClassDB::bind_method(D_METHOD("get_stylebox_types"), &Theme::_get_stylebox_types); + ClassDB::bind_method(D_METHOD("get_stylebox_type_list"), &Theme::_get_stylebox_type_list); ClassDB::bind_method(D_METHOD("set_font", "name", "node_type", "font"), &Theme::set_font); ClassDB::bind_method(D_METHOD("get_font", "name", "node_type"), &Theme::get_font); ClassDB::bind_method(D_METHOD("has_font", "name", "node_type"), &Theme::has_font); ClassDB::bind_method(D_METHOD("clear_font", "name", "node_type"), &Theme::clear_font); ClassDB::bind_method(D_METHOD("get_font_list", "node_type"), &Theme::_get_font_list); + ClassDB::bind_method(D_METHOD("get_font_type_list"), &Theme::_get_font_type_list); ClassDB::bind_method(D_METHOD("set_font_size", "name", "node_type", "font_size"), &Theme::set_font_size); ClassDB::bind_method(D_METHOD("get_font_size", "name", "node_type"), &Theme::get_font_size); @@ -913,12 +963,14 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("has_color", "name", "node_type"), &Theme::has_color); ClassDB::bind_method(D_METHOD("clear_color", "name", "node_type"), &Theme::clear_color); ClassDB::bind_method(D_METHOD("get_color_list", "node_type"), &Theme::_get_color_list); + ClassDB::bind_method(D_METHOD("get_color_type_list"), &Theme::_get_color_type_list); ClassDB::bind_method(D_METHOD("set_constant", "name", "node_type", "constant"), &Theme::set_constant); ClassDB::bind_method(D_METHOD("get_constant", "name", "node_type"), &Theme::get_constant); ClassDB::bind_method(D_METHOD("has_constant", "name", "node_type"), &Theme::has_constant); ClassDB::bind_method(D_METHOD("clear_constant", "name", "node_type"), &Theme::clear_constant); ClassDB::bind_method(D_METHOD("get_constant_list", "node_type"), &Theme::_get_constant_list); + ClassDB::bind_method(D_METHOD("get_constant_type_list"), &Theme::_get_constant_type_list); ClassDB::bind_method(D_METHOD("clear"), &Theme::clear); @@ -928,7 +980,7 @@ void Theme::_bind_methods() { ClassDB::bind_method(D_METHOD("set_default_font_size", "font_size"), &Theme::set_default_theme_font_size); ClassDB::bind_method(D_METHOD("get_default_font_size"), &Theme::get_default_theme_font_size); - ClassDB::bind_method(D_METHOD("get_type_list", "node_type"), &Theme::_get_type_list); + ClassDB::bind_method(D_METHOD("get_type_list"), &Theme::_get_type_list); ClassDB::bind_method("copy_default_theme", &Theme::copy_default_theme); ClassDB::bind_method(D_METHOD("copy_theme", "other"), &Theme::copy_theme); diff --git a/scene/resources/theme.h b/scene/resources/theme.h index 4175e19112..ad05e0e2f5 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -34,7 +34,6 @@ #include "core/io/resource.h" #include "core/io/resource_loader.h" #include "scene/resources/font.h" -#include "scene/resources/shader.h" #include "scene/resources/style_box.h" #include "scene/resources/texture.h" @@ -48,18 +47,21 @@ class Theme : public Resource { HashMap<StringName, HashMap<StringName, Ref<StyleBox>>> style_map; HashMap<StringName, HashMap<StringName, Ref<Font>>> font_map; HashMap<StringName, HashMap<StringName, int>> font_size_map; - HashMap<StringName, HashMap<StringName, Ref<Shader>>> shader_map; HashMap<StringName, HashMap<StringName, Color>> color_map; HashMap<StringName, HashMap<StringName, int>> constant_map; Vector<String> _get_icon_list(const String &p_node_type) const; + Vector<String> _get_icon_type_list() const; Vector<String> _get_stylebox_list(const String &p_node_type) const; - Vector<String> _get_stylebox_types() const; + Vector<String> _get_stylebox_type_list() const; Vector<String> _get_font_list(const String &p_node_type) const; + Vector<String> _get_font_type_list() const; Vector<String> _get_font_size_list(const String &p_node_type) const; Vector<String> _get_color_list(const String &p_node_type) const; + Vector<String> _get_color_type_list() const; Vector<String> _get_constant_list(const String &p_node_type) const; - Vector<String> _get_type_list(const String &p_node_type) const; + Vector<String> _get_constant_type_list() const; + Vector<String> _get_type_list() const; protected: bool _set(const StringName &p_name, const Variant &p_value); @@ -101,25 +103,21 @@ public: bool has_icon(const StringName &p_name, const StringName &p_node_type) const; void clear_icon(const StringName &p_name, const StringName &p_node_type); void get_icon_list(StringName p_node_type, List<StringName> *p_list) const; - - void set_shader(const StringName &p_name, const StringName &p_node_type, const Ref<Shader> &p_shader); - Ref<Shader> get_shader(const StringName &p_name, const StringName &p_node_type) const; - bool has_shader(const StringName &p_name, const StringName &p_node_type) const; - void clear_shader(const StringName &p_name, const StringName &p_node_type); - void get_shader_list(const StringName &p_node_type, List<StringName> *p_list) const; + void get_icon_type_list(List<StringName> *p_list) const; void set_stylebox(const StringName &p_name, const StringName &p_node_type, const Ref<StyleBox> &p_style); Ref<StyleBox> get_stylebox(const StringName &p_name, const StringName &p_node_type) const; bool has_stylebox(const StringName &p_name, const StringName &p_node_type) const; void clear_stylebox(const StringName &p_name, const StringName &p_node_type); void get_stylebox_list(StringName p_node_type, List<StringName> *p_list) const; - void get_stylebox_types(List<StringName> *p_list) const; + void get_stylebox_type_list(List<StringName> *p_list) const; void set_font(const StringName &p_name, const StringName &p_node_type, const Ref<Font> &p_font); Ref<Font> get_font(const StringName &p_name, const StringName &p_node_type) const; bool has_font(const StringName &p_name, const StringName &p_node_type) const; void clear_font(const StringName &p_name, const StringName &p_node_type); void get_font_list(StringName p_node_type, List<StringName> *p_list) const; + void get_font_type_list(List<StringName> *p_list) const; void set_font_size(const StringName &p_name, const StringName &p_node_type, int p_font_size); int get_font_size(const StringName &p_name, const StringName &p_node_type) const; @@ -132,12 +130,14 @@ public: bool has_color(const StringName &p_name, const StringName &p_node_type) const; void clear_color(const StringName &p_name, const StringName &p_node_type); void get_color_list(StringName p_node_type, List<StringName> *p_list) const; + void get_color_type_list(List<StringName> *p_list) const; void set_constant(const StringName &p_name, const StringName &p_node_type, int p_constant); int get_constant(const StringName &p_name, const StringName &p_node_type) const; bool has_constant(const StringName &p_name, const StringName &p_node_type) const; void clear_constant(const StringName &p_name, const StringName &p_node_type); void get_constant_list(StringName p_node_type, List<StringName> *p_list) const; + void get_constant_type_list(List<StringName> *p_list) const; void get_type_list(List<StringName> *p_list) const; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 283d89e5cf..34129e35da 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -811,8 +811,12 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port #define IS_SYMBOL_CHAR(m_d) (((m_d) >= 'a' && (m_d) <= 'z') || ((m_d) >= 'A' && (m_d) <= 'Z') || ((m_d) >= '0' && (m_d) <= '9') || (m_d) == '_') -String VisualShader::validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const { - String name = p_name; +String VisualShader::validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const { + String name = p_port_name; + + if (name == String()) { + return String(); + } while (name.length() && !IS_INITIAL_CHAR(name[0])) { name = name.substr(1, name.length() - 1); @@ -830,29 +834,28 @@ String VisualShader::validate_port_name(const String &p_name, const List<String> } name = valid_name; + } else { + return String(); } - String valid_name = name; - bool is_equal = false; + List<String> input_names; + List<String> output_names; - for (int i = 0; i < p_input_ports.size(); i++) { - if (name == p_input_ports[i]) { - is_equal = true; - break; + for (int i = 0; i < p_node->get_input_port_count(); i++) { + if (!p_output && i == p_port_id) { + continue; } - } - - if (!is_equal) { - for (int i = 0; i < p_output_ports.size(); i++) { - if (name == p_output_ports[i]) { - is_equal = true; - break; - } + if (name == p_node->get_input_port_name(i)) { + return String(); } } - - if (is_equal) { - name = ""; + for (int i = 0; i < p_node->get_output_port_count(); i++) { + if (p_output && i == p_port_id) { + continue; + } + if (name == p_node->get_output_port_name(i)) { + return String(); + } } return name; @@ -1706,9 +1709,9 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "view", "VIEW" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "attenuation", "ATTENUATION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "attenuation", "ATTENUATION" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "albedo", "ALBEDO" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "backlight", "BACKLIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "diffuse", "DIFFUSE_LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular", "SPECULAR_LIGHT" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "roughness", "ROUGHNESS" }, @@ -1724,17 +1727,17 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX, 0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "point_size", "POINT_SIZE" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "projection", "PROJECTION_MATRIX" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "extra", "EXTRA_MATRIX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "canvas", "CANVAS_MATRIX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "screen", "SCREEN_MATRIX" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" }, // Canvas Item, Fragment { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, @@ -1745,29 +1748,34 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_pixel_size", "vec3(SCREEN_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "light_pass", "float(AT_LIGHT_PASS ? 1.0 : 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_light_pass", "AT_LIGHT_PASS" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "normal_texture", "NORMAL_TEXTURE" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "screen_texture", "SCREEN_TEXTURE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "specular_shininess_alpha", "SPECULAR_SHININESS.a" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SAMPLER, "specular_shininess_texture", "SPECULAR_SHININESS_TEXTURE" }, // Canvas Item, Light { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "NORMAL" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vec", "vec3(LIGHT_VEC, 0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_height", "LIGHT_HEIGHT" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light", "LIGHT.rgb" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_color", "LIGHT_COLOR.rgb" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_alpha", "LIGHT_COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_uv", "vec3(LIGHT_UV, 0.0)" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_COLOR.rgb" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "shadow_alpha", "SHADOW_COLOR.a" }, - { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_vec", "vec3(SHADOW_VEC, 0.0)" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "light_color_alpha", "LIGHT_COLOR.a" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_position", "LIGHT_POSITION" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "light_vertex", "LIGHT_VERTEX" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "shadow_color", "SHADOW_MODULATE.rgb" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "shadow_alpha", "SHADOW_MODULATE.a" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "screen_uv", "vec3(SCREEN_UV, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "texture_pixel_size", "vec3(TEXTURE_PIXEL_SIZE, 1.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "point_coord", "vec3(POINT_COORD, 0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SAMPLER, "texture", "TEXTURE" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "specular_shininess", "SPECULAR_SHININESS.rgb" }, + { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "specular_shininess_alpha", "SPECULAR_SHININESS.a" }, // Particles, Emit { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, @@ -1862,7 +1870,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::preview_ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "side", "1.0" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0,1.0, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(1.0, 1.0, 0.0)" }, // Spatial, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "normal", "vec3(0.0, 0.0, 1.0)" }, @@ -1954,7 +1962,7 @@ String VisualShaderNodeInput::generate_code(Shader::Mode p_mode, VisualShader::T code = "\t" + p_output_vars[0] + " = vec3(0.0);\n"; } break; case PORT_TYPE_TRANSFORM: { - code = "\t" + p_output_vars[0] + " = mat4( vec4(1.0,0.0,0.0,0.0), vec4(0.0,1.0,0.0,0.0), vec4(0.0,0.0,1.0,0.0), vec4(0.0,0.0,0.0,1.0) );\n"; + code = "\t" + p_output_vars[0] + " = mat4(vec4(1.0, 0.0, 0.0, 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; } break; case PORT_TYPE_BOOLEAN: { code = "\t" + p_output_vars[0] + " = false;\n"; @@ -2361,9 +2369,9 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "anisotropy", "ANISOTROPY" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "anisotropy_flow", "ANISOTROPY_FLOW:xy" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "subsurf_scatter", "SSS_STRENGTH" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "transmission", "TRANSMISSION" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "backlight", "BACKLIGHT" }, - { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_scissor", "ALPHA_SCISSOR" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha_scissor_threshold", "ALPHA_SCISSOR_THRESHOLD" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "ao_light_affect", "AO_LIGHT_AFFECT" }, // Spatial, Light @@ -2481,7 +2489,7 @@ String VisualShaderNodeOutput::get_output_port_name(int p_port) const { bool VisualShaderNodeOutput::is_port_separator(int p_index) const { if (shader_mode == Shader::MODE_SPATIAL && shader_type == VisualShader::TYPE_FRAGMENT) { String name = get_input_port_name(p_index); - return (name == "Normal" || name == "Rim" || name == "Alpha Scissor"); + return (name == "Normal" || name == "Rim" || name == "Alpha Scissor Threshold"); } return false; } @@ -2762,8 +2770,10 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) { inputs.erase(index, count); inputs_strings = inputs.split(";", false); + inputs = inputs.substr(0, index); + for (int i = p_id; i < inputs_strings.size(); i++) { - inputs = inputs.replace_first(inputs_strings[i].split(",")[0], itos(i)); + inputs += inputs_strings[i].replace_first(inputs_strings[i].split(",")[0], itos(i)) + ";"; } _apply_port_changes(); @@ -2832,8 +2842,10 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) { outputs.erase(index, count); outputs_strings = outputs.split(";", false); + outputs = outputs.substr(0, index); + for (int i = p_id; i < outputs_strings.size(); i++) { - outputs = outputs.replace_first(outputs_strings[i].split(",")[0], itos(i)); + outputs += outputs_strings[i].replace_first(outputs_strings[i].split(",")[0], itos(i)) + ";"; } _apply_port_changes(); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 41c4642ee3..a38c2886e2 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -175,7 +175,7 @@ public: String generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &r_default_tex_params) const; - String validate_port_name(const String &p_name, const List<String> &p_input_ports, const List<String> &p_output_ports) const; + String validate_port_name(const String &p_port_name, VisualShaderNode *p_node, int p_port_id, bool p_output) const; String validate_uniform_name(const String &p_name, const Ref<VisualShaderNodeUniform> &p_uniform) const; VisualShader(); |