diff options
Diffstat (limited to 'scene/resources')
51 files changed, 2667 insertions, 733 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index b8edd70712..92103f3b1d 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -2633,6 +2633,7 @@ void Animation::_bind_methods() { ClassDB::bind_method(D_METHOD("value_track_get_update_mode", "track_idx"), &Animation::value_track_get_update_mode); ClassDB::bind_method(D_METHOD("value_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_value_track_get_key_indices); + ClassDB::bind_method(D_METHOD("value_track_interpolate", "track_idx", "time_sec"), &Animation::value_track_interpolate); ClassDB::bind_method(D_METHOD("method_track_get_key_indices", "track_idx", "time_sec", "delta"), &Animation::_method_track_get_key_indices); ClassDB::bind_method(D_METHOD("method_track_get_name", "track_idx", "key_idx"), &Animation::method_track_get_name); diff --git a/scene/resources/box_shape_3d.cpp b/scene/resources/box_shape_3d.cpp index 69339faf76..e1c8a377c0 100644 --- a/scene/resources/box_shape_3d.cpp +++ b/scene/resources/box_shape_3d.cpp @@ -31,7 +31,7 @@ #include "box_shape_3d.h" #include "servers/physics_server_3d.h" -Vector<Vector3> BoxShape3D::get_debug_mesh_lines() { +Vector<Vector3> BoxShape3D::get_debug_mesh_lines() const { Vector<Vector3> lines; AABB aabb; aabb.position = -get_extents(); diff --git a/scene/resources/box_shape_3d.h b/scene/resources/box_shape_3d.h index 99b6410799..fe634ce568 100644 --- a/scene/resources/box_shape_3d.h +++ b/scene/resources/box_shape_3d.h @@ -46,7 +46,7 @@ public: void set_extents(const Vector3 &p_extents); Vector3 get_extents() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; BoxShape3D(); diff --git a/scene/resources/capsule_shape_3d.cpp b/scene/resources/capsule_shape_3d.cpp index 28fc0d470c..9d1355eec6 100644 --- a/scene/resources/capsule_shape_3d.cpp +++ b/scene/resources/capsule_shape_3d.cpp @@ -31,7 +31,7 @@ #include "capsule_shape_3d.h" #include "servers/physics_server_3d.h" -Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() { +Vector<Vector3> CapsuleShape3D::get_debug_mesh_lines() const { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/capsule_shape_3d.h b/scene/resources/capsule_shape_3d.h index a638618c48..432ca5654e 100644 --- a/scene/resources/capsule_shape_3d.h +++ b/scene/resources/capsule_shape_3d.h @@ -49,7 +49,7 @@ public: void set_height(float p_height); float get_height() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; CapsuleShape3D(); diff --git a/scene/resources/concave_polygon_shape_3d.cpp b/scene/resources/concave_polygon_shape_3d.cpp index 7315945c03..7cbafcbc4d 100644 --- a/scene/resources/concave_polygon_shape_3d.cpp +++ b/scene/resources/concave_polygon_shape_3d.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server_3d.h" -Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() { +Vector<Vector3> ConcavePolygonShape3D::get_debug_mesh_lines() const { Set<DrawEdge> edges; Vector<Vector3> data = get_faces(); diff --git a/scene/resources/concave_polygon_shape_3d.h b/scene/resources/concave_polygon_shape_3d.h index a3c10adce2..c17765b9ef 100644 --- a/scene/resources/concave_polygon_shape_3d.h +++ b/scene/resources/concave_polygon_shape_3d.h @@ -65,7 +65,7 @@ public: void set_faces(const Vector<Vector3> &p_faces); Vector<Vector3> get_faces() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; ConcavePolygonShape3D(); diff --git a/scene/resources/convex_polygon_shape_3d.cpp b/scene/resources/convex_polygon_shape_3d.cpp index affeb05a8f..29549e1114 100644 --- a/scene/resources/convex_polygon_shape_3d.cpp +++ b/scene/resources/convex_polygon_shape_3d.cpp @@ -32,7 +32,7 @@ #include "core/math/quick_hull.h" #include "servers/physics_server_3d.h" -Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() { +Vector<Vector3> ConvexPolygonShape3D::get_debug_mesh_lines() const { Vector<Vector3> points = get_points(); if (points.size() > 3) { diff --git a/scene/resources/convex_polygon_shape_3d.h b/scene/resources/convex_polygon_shape_3d.h index 43d8b90740..f436d2f5d4 100644 --- a/scene/resources/convex_polygon_shape_3d.h +++ b/scene/resources/convex_polygon_shape_3d.h @@ -46,7 +46,7 @@ public: void set_points(const Vector<Vector3> &p_points); Vector<Vector3> get_points() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; ConvexPolygonShape3D(); diff --git a/scene/resources/cylinder_shape_3d.cpp b/scene/resources/cylinder_shape_3d.cpp index 44786d6025..ad64541247 100644 --- a/scene/resources/cylinder_shape_3d.cpp +++ b/scene/resources/cylinder_shape_3d.cpp @@ -31,7 +31,7 @@ #include "cylinder_shape_3d.h" #include "servers/physics_server_3d.h" -Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() { +Vector<Vector3> CylinderShape3D::get_debug_mesh_lines() const { float radius = get_radius(); float height = get_height(); diff --git a/scene/resources/cylinder_shape_3d.h b/scene/resources/cylinder_shape_3d.h index 2564a04a97..e579e1f7cf 100644 --- a/scene/resources/cylinder_shape_3d.h +++ b/scene/resources/cylinder_shape_3d.h @@ -48,7 +48,7 @@ public: void set_height(float p_height); float get_height() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; CylinderShape3D(); diff --git a/scene/resources/default_theme/bookmark.png b/scene/resources/default_theme/bookmark.png Binary files differnew file mode 100644 index 0000000000..9718cf53b6 --- /dev/null +++ b/scene/resources/default_theme/bookmark.png diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 9008f6d5b9..f65f78b332 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -382,8 +382,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_icon("tab", "TextEdit", make_icon(tab_png)); theme->set_icon("space", "TextEdit", make_icon(space_png)); - theme->set_icon("folded", "TextEdit", make_icon(arrow_right_png)); - theme->set_icon("fold", "TextEdit", make_icon(arrow_down_png)); theme->set_font("font", "TextEdit", Ref<Font>()); @@ -398,16 +396,11 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color_readonly", "TextEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); theme->set_color("selection_color", "TextEdit", font_color_selection); theme->set_color("mark_color", "TextEdit", Color(1.0, 0.4, 0.4, 0.4)); - theme->set_color("bookmark_color", "TextEdit", Color(0.08, 0.49, 0.98)); - theme->set_color("breakpoint_color", "TextEdit", Color(0.8, 0.8, 0.4, 0.2)); - theme->set_color("executing_line_color", "TextEdit", Color(0.2, 0.8, 0.2, 0.4)); theme->set_color("code_folding_color", "TextEdit", Color(0.8, 0.8, 0.8, 0.8)); theme->set_color("current_line_color", "TextEdit", Color(0.25, 0.25, 0.26, 0.8)); theme->set_color("caret_color", "TextEdit", control_font_color); theme->set_color("caret_background_color", "TextEdit", Color(0, 0, 0)); theme->set_color("brace_mismatch_color", "TextEdit", Color(1, 0.2, 0.2)); - theme->set_color("line_number_color", "TextEdit", Color(0.67, 0.67, 0.67, 0.4)); - theme->set_color("safe_line_number_color", "TextEdit", Color(0.67, 0.78, 0.67, 0.6)); theme->set_color("word_highlighted_color", "TextEdit", Color(0.8, 0.9, 0.9, 0.15)); theme->set_constant("completion_lines", "TextEdit", 7); @@ -415,6 +408,50 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("completion_scroll_width", "TextEdit", 3); theme->set_constant("line_spacing", "TextEdit", 4 * scale); + // CodeEdit + theme->set_stylebox("normal", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0)); + theme->set_stylebox("focus", "CodeEdit", focus); + theme->set_stylebox("read_only", "CodeEdit", make_stylebox(tree_bg_disabled_png, 4, 4, 4, 4, 0, 0, 0, 0)); + theme->set_stylebox("completion", "CodeEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3, 0, 0, 0, 0)); + + theme->set_icon("tab", "CodeEdit", make_icon(tab_png)); + theme->set_icon("space", "CodeEdit", make_icon(space_png)); + theme->set_icon("breakpoint", "CodeEdit", make_icon(graph_port_png)); + theme->set_icon("bookmark", "CodeEdit", make_icon(bookmark_png)); + theme->set_icon("executing_line", "CodeEdit", make_icon(arrow_right_png)); + theme->set_icon("can_fold", "CodeEdit", make_icon(arrow_down_png)); + theme->set_icon("folded", "CodeEdit", make_icon(arrow_right_png)); + + theme->set_font("font", "CodeEdit", Ref<Font>()); + + theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); + theme->set_color("completion_background_color", "CodeEdit", Color(0.17, 0.16, 0.2)); + theme->set_color("completion_selected_color", "CodeEdit", Color(0.26, 0.26, 0.27)); + theme->set_color("completion_existing_color", "CodeEdit", Color(0.87, 0.87, 0.87, 0.13)); + theme->set_color("completion_scroll_color", "CodeEdit", control_font_color_pressed); + theme->set_color("completion_font_color", "CodeEdit", Color(0.67, 0.67, 0.67)); + theme->set_color("font_color", "CodeEdit", control_font_color); + theme->set_color("font_color_selected", "CodeEdit", Color(0, 0, 0)); + theme->set_color("font_color_readonly", "CodeEdit", Color(control_font_color.r, control_font_color.g, control_font_color.b, 0.5f)); + theme->set_color("selection_color", "CodeEdit", font_color_selection); + theme->set_color("mark_color", "CodeEdit", Color(1.0, 0.4, 0.4, 0.4)); + theme->set_color("bookmark_color", "CodeEdit", Color(0.5, 0.64, 1, 0.8)); + theme->set_color("breakpoint_color", "CodeEdit", Color(0.9, 0.29, 0.3)); + theme->set_color("executing_line_color", "CodeEdit", Color(0.98, 0.89, 0.27)); + theme->set_color("code_folding_color", "CodeEdit", Color(0.8, 0.8, 0.8, 0.8)); + theme->set_color("current_line_color", "CodeEdit", Color(0.25, 0.25, 0.26, 0.8)); + theme->set_color("caret_color", "CodeEdit", control_font_color); + theme->set_color("caret_background_color", "CodeEdit", Color(0, 0, 0)); + theme->set_color("brace_mismatch_color", "CodeEdit", Color(1, 0.2, 0.2)); + theme->set_color("line_number_color", "CodeEdit", Color(0.67, 0.67, 0.67, 0.4)); + theme->set_color("safe_line_number_color", "CodeEdit", Color(0.67, 0.78, 0.67, 0.6)); + theme->set_color("word_highlighted_color", "CodeEdit", Color(0.8, 0.9, 0.9, 0.15)); + + theme->set_constant("completion_lines", "CodeEdit", 7); + theme->set_constant("completion_max_width", "CodeEdit", 50); + theme->set_constant("completion_scroll_width", "CodeEdit", 3); + theme->set_constant("line_spacing", "CodeEdit", 4 * scale); + Ref<Texture2D> empty_icon = memnew(ImageTexture); // HScrollBar diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index edcdb90db9..a15efb593a 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -10,6 +10,10 @@ static const unsigned char arrow_right_png[] = { 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x4, 0x0, 0x0, 0x0, 0xfc, 0x7c, 0x94, 0x6c, 0x0, 0x0, 0x0, 0x2e, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x63, 0x20, 0x17, 0x3c, 0xf8, 0xf, 0x82, 0xf7, 0x13, 0x70, 0x48, 0x3c, 0xf8, 0xf2, 0x50, 0x1b, 0x43, 0x2, 0xa, 0xaf, 0xbe, 0xe0, 0xc6, 0x2e, 0xf1, 0xff, 0xe1, 0x7c, 0x12, 0x24, 0x10, 0x46, 0x11, 0xb6, 0x1c, 0xe1, 0x5c, 0xa, 0x0, 0x0, 0xe0, 0x14, 0x48, 0xb1, 0x3d, 0x1b, 0x7a, 0xf0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; +static const unsigned char bookmark_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, 0x4, 0x73, 0x42, 0x49, 0x54, 0x8, 0x8, 0x8, 0x8, 0x7c, 0x8, 0x64, 0x88, 0x0, 0x0, 0x0, 0x57, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0xa, 0xc0, 0x30, 0xc, 0x3, 0xa5, 0xd0, 0xff, 0x7f, 0x59, 0x1d, 0x8a, 0x42, 0x8, 0x9, 0x95, 0xc9, 0xd2, 0xa1, 0x9a, 0x8c, 0xf1, 0xdd, 0x62, 0x1b, 0x38, 0xc, 0x87, 0x5a, 0x5, 0xae, 0x79, 0xde, 0x2, 0x1, 0x80, 0x94, 0x39, 0x48, 0x76, 0x49, 0x17, 0xa4, 0xf0, 0x24, 0x61, 0x2b, 0x51, 0x8b, 0xfc, 0x82, 0xcf, 0xb, 0x48, 0x7a, 0xdf, 0x75, 0x81, 0xf, 0xe5, 0x29, 0xf7, 0x92, 0x6b, 0x3, 0x1a, 0x1e, 0xda, 0x7c, 0x3d, 0x77, 0x21, 0x7b, 0xa8, 0x74, 0x2e, 0xcb, 0xd, 0xc8, 0x75, 0x13, 0x28, 0x9, 0xed, 0xc2, 0xc8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 +}; + static const unsigned char button_disabled_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, 0xc7, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x6c, 0xd0, 0x81, 0x66, 0x43, 0x31, 0x14, 0x87, 0xf1, 0xf, 0x5, 0x17, 0xb8, 0x28, 0x2e, 0x8, 0x71, 0xf3, 0x6, 0x19, 0xb6, 0xb9, 0xcb, 0xac, 0x95, 0xa4, 0xb7, 0xad, 0x6a, 0xd5, 0x68, 0x5f, 0xe4, 0x3e, 0x76, 0x1e, 0xe1, 0xbf, 0x21, 0xa6, 0xab, 0xf8, 0x1, 0x7c, 0x9c, 0x73, 0xe, 0xac, 0xe8, 0xe8, 0x19, 0x30, 0x58, 0xc6, 0xca, 0x62, 0x18, 0xe8, 0xe9, 0x58, 0x41, 0xc7, 0x1a, 0x87, 0x27, 0x10, 0x49, 0xe4, 0x5f, 0x89, 0x48, 0xc0, 0xe3, 0x58, 0xd3, 0x41, 0x8f, 0xb, 0xcb, 0xbd, 0x7c, 0xeb, 0xbf, 0x7b, 0x9, 0xb, 0x8e, 0x1e, 0x6, 0xfc, 0xad, 0x64, 0x6d, 0xb5, 0x79, 0xb0, 0x55, 0xd6, 0xad, 0xe0, 0x19, 0xc0, 0x10, 0xae, 0xda, 0x34, 0x5c, 0x45, 0xc0, 0x80, 0x25, 0x5e, 0xf4, 0xd5, 0x70, 0x11, 0x11, 0xb, 0x23, 0xe9, 0xac, 0xcf, 0x86, 0xb3, 0x48, 0x8c, 0x30, 0x92, 0x4f, 0xa, 0xd, 0x27, 0x91, 0x6b, 0x70, 0xd4, 0x47, 0xc3, 0xf1, 0x2f, 0x48, 0x7, 0x4d, 0xd, 0x87, 0x3a, 0xc2, 0x12, 0x67, 0xbd, 0x37, 0xcc, 0x75, 0x49, 0x43, 0xd8, 0xe9, 0xad, 0x61, 0x57, 0xcf, 0x1c, 0xf0, 0xfb, 0x32, 0xe9, 0xf5, 0xc9, 0xa4, 0x7d, 0x7d, 0x54, 0x8f, 0x7b, 0x59, 0xe6, 0x92, 0x14, 0x1f, 0x24, 0xcd, 0x3f, 0x7b, 0x6b, 0xa, 0xe, 0x6a, 0x82, 0x91, 0x45, 0x30, 0xba, 0x1, 0x4a, 0x51, 0xc4, 0x35, 0x1f, 0xe5, 0xa1, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 99f87dd6ed..bc983c1d7e 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -239,7 +239,7 @@ float DynamicFontAtSize::get_underline_thickness() const { return underline_thickness; } -const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { +const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFontAtSize::_find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { const Character *chr = char_map.getptr(p_char); ERR_FAIL_COND_V(!chr, (Pair<const Character *, DynamicFontAtSize *>(nullptr, nullptr))); @@ -271,7 +271,7 @@ const Pair<const DynamicFontAtSize::Character *, DynamicFontAtSize *> DynamicFon return Pair<const Character *, DynamicFontAtSize *>(chr, const_cast<DynamicFontAtSize *>(this)); } -Size2 DynamicFontAtSize::get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { +Size2 DynamicFontAtSize::get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const { if (!valid) { return Size2(1, 1); } @@ -297,7 +297,7 @@ String DynamicFontAtSize::get_available_chars() const { FT_ULong charcode = FT_Get_First_Char(face, &gindex); while (gindex != 0) { if (charcode != 0) { - chars += CharType(charcode); + chars += char32_t(charcode); } charcode = FT_Get_Next_Char(face, charcode, &gindex); } @@ -305,7 +305,7 @@ String DynamicFontAtSize::get_available_chars() const { return chars; } -float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const { +float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only, bool p_outline) const { if (!valid) { return 0; } @@ -560,7 +560,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b return chr; } -DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(CharType p_char) { +DynamicFontAtSize::Character DynamicFontAtSize::_make_outline_char(char32_t p_char) { Character ret = Character::not_found(); if (FT_Load_Char(face, p_char, FT_LOAD_NO_BITMAP | (font->force_autohinter ? FT_LOAD_FORCE_AUTOHINT : 0)) != 0) { @@ -596,7 +596,7 @@ cleanup_stroker: return ret; } -void DynamicFontAtSize::_update_char(CharType p_char) { +void DynamicFontAtSize::_update_char(char32_t p_char) { if (char_map.has(p_char)) { return; } @@ -849,7 +849,7 @@ float DynamicFont::get_underline_thickness() const { return data_at_size->get_underline_thickness(); } -Size2 DynamicFont::get_char_size(CharType p_char, CharType p_next) const { +Size2 DynamicFont::get_char_size(char32_t p_char, char32_t p_next) const { if (!data_at_size.is_valid()) { return Size2(1, 1); } @@ -891,7 +891,7 @@ bool DynamicFont::has_outline() const { return outline_cache_id.outline_size > 0; } -float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { +float DynamicFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const { const Ref<DynamicFontAtSize> &font_at_size = p_outline && outline_cache_id.outline_size > 0 ? outline_data_at_size : data_at_size; if (!font_at_size.is_valid()) { diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index e8637e7e34..a881e21da8 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -159,17 +159,17 @@ class DynamicFontAtSize : public Reference { int y; }; - const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(CharType p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; - Character _make_outline_char(CharType p_char); + const Pair<const Character *, DynamicFontAtSize *> _find_char_with_font(char32_t p_char, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; + Character _make_outline_char(char32_t p_char); TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height); Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance); static unsigned long _ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count); static void _ft_stream_close(FT_Stream stream); - HashMap<CharType, Character> char_map; + HashMap<char32_t, Character> char_map; - _FORCE_INLINE_ void _update_char(CharType p_char); + _FORCE_INLINE_ void _update_char(char32_t p_char); friend class DynamicFontData; Ref<DynamicFontData> font; @@ -188,10 +188,10 @@ public: float get_underline_position() const; float get_underline_thickness() const; - Size2 get_char_size(CharType p_char, CharType p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; + Size2 get_char_size(char32_t p_char, char32_t p_next, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks) const; String get_available_chars() const; - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const; + float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, const Vector<Ref<DynamicFontAtSize>> &p_fallbacks, bool p_advance_only = false, bool p_outline = false) const; void set_texture_flags(uint32_t p_flags); void update_oversampling(); @@ -277,14 +277,14 @@ public: virtual float get_underline_position() const override; virtual float get_underline_thickness() const override; - virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const override; + virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override; String get_available_chars() const; virtual bool is_distance_field_hint() const override; virtual bool has_outline() const override; - virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override; + virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override; SelfList<DynamicFont> font_list; diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 94629a77b9..f4edab07b5 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -44,6 +44,9 @@ void Environment::set_background(BGMode p_bg) { bg_mode = p_bg; RS::get_singleton()->environment_set_background(environment, RS::EnvironmentBG(p_bg)); _change_notify(); + if (bg_mode != BG_SKY) { + set_fog_aerial_perspective(0.0); + } } Environment::BGMode Environment::get_background() const { @@ -134,6 +137,7 @@ Color Environment::get_ambient_light_color() const { void Environment::set_ambient_source(AmbientSource p_source) { ambient_source = p_source; _update_ambient_light(); + _change_notify(); } Environment::AmbientSource Environment::get_ambient_source() const { @@ -161,6 +165,7 @@ float Environment::get_ambient_light_sky_contribution() const { void Environment::set_reflection_source(ReflectionSource p_source) { reflection_source = p_source; _update_ambient_light(); + _change_notify(); } Environment::ReflectionSource Environment::get_reflection_source() const { @@ -576,22 +581,28 @@ bool Environment::is_glow_enabled() const { return glow_enabled; } -void Environment::set_glow_level_enabled(int p_level, bool p_enabled) { +void Environment::set_glow_level(int p_level, float p_intensity) { ERR_FAIL_INDEX(p_level, RS::MAX_GLOW_LEVELS); - if (p_enabled) { - glow_levels |= (1 << p_level); - } else { - glow_levels &= ~(1 << p_level); - } + glow_levels.write[p_level] = p_intensity; _update_glow(); } -bool Environment::is_glow_level_enabled(int p_level) const { +float Environment::get_glow_level(int p_level) const { ERR_FAIL_INDEX_V(p_level, RS::MAX_GLOW_LEVELS, false); - return glow_levels & (1 << p_level); + return glow_levels[p_level]; +} + +void Environment::set_glow_normalized(bool p_normalized) { + glow_normalize_levels = p_normalized; + + _update_glow(); +} + +bool Environment::is_glow_normalized() const { + return glow_normalize_levels; } void Environment::set_glow_intensity(float p_intensity) { @@ -668,10 +679,24 @@ float Environment::get_glow_hdr_luminance_cap() const { } void Environment::_update_glow() { + Vector<float> normalized_levels; + if (glow_normalize_levels) { + normalized_levels.resize(7); + float size = 0.0; + for (int i = 0; i < glow_levels.size(); i++) { + size += glow_levels[i]; + } + for (int i = 0; i < glow_levels.size(); i++) { + normalized_levels.write[i] = glow_levels[i] / size; + } + } else { + normalized_levels = glow_levels; + } + RS::get_singleton()->environment_set_glow( environment, glow_enabled, - glow_levels, + normalized_levels, glow_intensity, glow_strength, glow_mix, @@ -694,150 +719,137 @@ bool Environment::is_fog_enabled() const { return fog_enabled; } -void Environment::set_fog_color(const Color &p_color) { - fog_color = p_color; +void Environment::set_fog_light_color(const Color &p_light_color) { + fog_light_color = p_light_color; _update_fog(); } - -Color Environment::get_fog_color() const { - return fog_color; +Color Environment::get_fog_light_color() const { + return fog_light_color; } - -void Environment::set_fog_sun_color(const Color &p_color) { - fog_sun_color = p_color; +void Environment::set_fog_light_energy(float p_amount) { + fog_light_energy = p_amount; _update_fog(); } - -Color Environment::get_fog_sun_color() const { - return fog_sun_color; +float Environment::get_fog_light_energy() const { + return fog_light_energy; } - -void Environment::set_fog_sun_amount(float p_amount) { - fog_sun_amount = p_amount; +void Environment::set_fog_sun_scatter(float p_amount) { + fog_sun_scatter = p_amount; _update_fog(); } - -float Environment::get_fog_sun_amount() const { - return fog_sun_amount; +float Environment::get_fog_sun_scatter() const { + return fog_sun_scatter; } - -void Environment::_update_fog() { - RS::get_singleton()->environment_set_fog( - environment, - fog_enabled, - fog_color, - fog_sun_color, - fog_sun_amount); +void Environment::set_fog_density(float p_amount) { + fog_density = p_amount; + _update_fog(); } - -void Environment::set_fog_depth_enabled(bool p_enabled) { - fog_depth_enabled = p_enabled; - _update_fog_depth(); +float Environment::get_fog_density() const { + return fog_density; } - -bool Environment::is_fog_depth_enabled() const { - return fog_depth_enabled; +void Environment::set_fog_height(float p_amount) { + fog_height = p_amount; + _update_fog(); } - -void Environment::set_fog_depth_begin(float p_distance) { - fog_depth_begin = p_distance; - _update_fog_depth(); +float Environment::get_fog_height() const { + return fog_height; } - -float Environment::get_fog_depth_begin() const { - return fog_depth_begin; +void Environment::set_fog_height_density(float p_amount) { + fog_height_density = p_amount; + _update_fog(); } - -void Environment::set_fog_depth_end(float p_distance) { - fog_depth_end = p_distance; - _update_fog_depth(); +float Environment::get_fog_height_density() const { + return fog_height_density; } -float Environment::get_fog_depth_end() const { - return fog_depth_end; +void Environment::set_fog_aerial_perspective(float p_aerial_perspective) { + fog_aerial_perspective = p_aerial_perspective; + _update_fog(); } - -void Environment::set_fog_depth_curve(float p_curve) { - fog_depth_curve = p_curve; - _update_fog_depth(); +float Environment::get_fog_aerial_perspective() const { + return fog_aerial_perspective; } -float Environment::get_fog_depth_curve() const { - return fog_depth_curve; +void Environment::_update_fog() { + RS::get_singleton()->environment_set_fog( + environment, + fog_enabled, + fog_light_color, + fog_light_energy, + fog_sun_scatter, + fog_density, + fog_height, + fog_height_density, + fog_aerial_perspective); } -void Environment::set_fog_transmit_enabled(bool p_enabled) { - fog_transmit_enabled = p_enabled; - _update_fog_depth(); -} +// Volumetric Fog -bool Environment::is_fog_transmit_enabled() const { - return fog_transmit_enabled; +void Environment::_update_volumetric_fog() { + RS::get_singleton()->environment_set_volumetric_fog(environment, volumetric_fog_enabled, volumetric_fog_density, volumetric_fog_light, volumetric_fog_light_energy, volumetric_fog_length, volumetric_fog_detail_spread, volumetric_fog_gi_inject, RS::EnvVolumetricFogShadowFilter(volumetric_fog_shadow_filter)); } -void Environment::set_fog_transmit_curve(float p_curve) { - fog_transmit_curve = p_curve; - _update_fog_depth(); +void Environment::set_volumetric_fog_enabled(bool p_enable) { + volumetric_fog_enabled = p_enable; + _update_volumetric_fog(); + _change_notify(); } -float Environment::get_fog_transmit_curve() const { - return fog_transmit_curve; +bool Environment::is_volumetric_fog_enabled() const { + return volumetric_fog_enabled; } - -void Environment::_update_fog_depth() { - RS::get_singleton()->environment_set_fog_depth( - environment, - fog_depth_enabled, - fog_depth_begin, - fog_depth_end, - fog_depth_curve, - fog_transmit_enabled, - fog_transmit_curve); +void Environment::set_volumetric_fog_density(float p_density) { + p_density = CLAMP(p_density, 0.0000001, 1.0); + volumetric_fog_density = p_density; + _update_volumetric_fog(); } - -void Environment::set_fog_height_enabled(bool p_enabled) { - fog_height_enabled = p_enabled; - _update_fog_height(); +float Environment::get_volumetric_fog_density() const { + return volumetric_fog_density; } - -bool Environment::is_fog_height_enabled() const { - return fog_height_enabled; +void Environment::set_volumetric_fog_light(Color p_color) { + volumetric_fog_light = p_color; + _update_volumetric_fog(); } - -void Environment::set_fog_height_min(float p_distance) { - fog_height_min = p_distance; - _update_fog_height(); +Color Environment::get_volumetric_fog_light() const { + return volumetric_fog_light; } - -float Environment::get_fog_height_min() const { - return fog_height_min; +void Environment::set_volumetric_fog_light_energy(float p_begin) { + volumetric_fog_light_energy = p_begin; + _update_volumetric_fog(); } - -void Environment::set_fog_height_max(float p_distance) { - fog_height_max = p_distance; - _update_fog_height(); +float Environment::get_volumetric_fog_light_energy() const { + return volumetric_fog_light_energy; } - -float Environment::get_fog_height_max() const { - return fog_height_max; +void Environment::set_volumetric_fog_length(float p_length) { + volumetric_fog_length = p_length; + _update_volumetric_fog(); +} +float Environment::get_volumetric_fog_length() const { + return volumetric_fog_length; +} +void Environment::set_volumetric_fog_detail_spread(float p_detail_spread) { + volumetric_fog_detail_spread = p_detail_spread; + _update_volumetric_fog(); +} +float Environment::get_volumetric_fog_detail_spread() const { + return volumetric_fog_detail_spread; } -void Environment::set_fog_height_curve(float p_distance) { - fog_height_curve = p_distance; - _update_fog_height(); +void Environment::set_volumetric_fog_gi_inject(float p_gi_inject) { + volumetric_fog_gi_inject = p_gi_inject; + _update_volumetric_fog(); +} +float Environment::get_volumetric_fog_gi_inject() const { + return volumetric_fog_gi_inject; } -float Environment::get_fog_height_curve() const { - return fog_height_curve; +void Environment::set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter) { + volumetric_fog_shadow_filter = p_filter; + _update_volumetric_fog(); } -void Environment::_update_fog_height() { - RS::get_singleton()->environment_set_fog_height( - environment, - fog_height_enabled, - fog_height_min, - fog_height_max, - fog_height_curve); +Environment::VolumetricFogShadowFilter Environment::get_volumetric_fog_shadow_filter() const { + return volumetric_fog_shadow_filter; } // Adjustment @@ -907,6 +919,12 @@ void Environment::_validate_property(PropertyInfo &property) const { } } + if (property.name == "fog_aerial_perspective") { + if (bg_mode != BG_SKY) { + property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; + } + } + if (property.name == "glow_intensity" && glow_blend_mode == GLOW_BLEND_MODE_MIX) { property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL; } @@ -935,6 +953,7 @@ void Environment::_validate_property(PropertyInfo &property) const { static const char *hide_prefixes[] = { "fog_", + "volumetric_fog_", "auto_exposure_", "ss_reflections_", "ssao_", @@ -1181,8 +1200,10 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_glow_enabled", "enabled"), &Environment::set_glow_enabled); ClassDB::bind_method(D_METHOD("is_glow_enabled"), &Environment::is_glow_enabled); - ClassDB::bind_method(D_METHOD("set_glow_level_enabled", "idx", "enabled"), &Environment::set_glow_level_enabled); - ClassDB::bind_method(D_METHOD("is_glow_level_enabled", "idx"), &Environment::is_glow_level_enabled); + ClassDB::bind_method(D_METHOD("set_glow_level", "idx", "intensity"), &Environment::set_glow_level); + ClassDB::bind_method(D_METHOD("get_glow_level", "idx"), &Environment::get_glow_level); + ClassDB::bind_method(D_METHOD("set_glow_normalized", "normalize"), &Environment::set_glow_normalized); + ClassDB::bind_method(D_METHOD("is_glow_normalized"), &Environment::is_glow_normalized); ClassDB::bind_method(D_METHOD("set_glow_intensity", "intensity"), &Environment::set_glow_intensity); ClassDB::bind_method(D_METHOD("get_glow_intensity"), &Environment::get_glow_intensity); ClassDB::bind_method(D_METHOD("set_glow_strength", "strength"), &Environment::set_glow_strength); @@ -1202,13 +1223,14 @@ void Environment::_bind_methods() { ADD_GROUP("Glow", "glow_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_enabled"), "set_glow_enabled", "is_glow_enabled"); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/1"), "set_glow_level_enabled", "is_glow_level_enabled", 0); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/2"), "set_glow_level_enabled", "is_glow_level_enabled", 1); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/3"), "set_glow_level_enabled", "is_glow_level_enabled", 2); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/4"), "set_glow_level_enabled", "is_glow_level_enabled", 3); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/5"), "set_glow_level_enabled", "is_glow_level_enabled", 4); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/6"), "set_glow_level_enabled", "is_glow_level_enabled", 5); - ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "glow_levels/7"), "set_glow_level_enabled", "is_glow_level_enabled", 6); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/1", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 0); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/2", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 1); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/3", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 2); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/4", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 3); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/5", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 4); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/6", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 5); + ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "glow_levels/7", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_glow_level", "get_glow_level", 6); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_normalized"), "set_glow_normalized", "is_glow_normalized"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_intensity", PROPERTY_HINT_RANGE, "0.0,8.0,0.01"), "set_glow_intensity", "get_glow_intensity"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_strength", PROPERTY_HINT_RANGE, "0.0,2.0,0.01"), "set_glow_strength", "get_glow_strength"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "glow_mix", PROPERTY_HINT_RANGE, "0.0,1.0,0.001"), "set_glow_mix", "get_glow_mix"); @@ -1222,52 +1244,62 @@ void Environment::_bind_methods() { ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled); ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled); - ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color); - ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color); - ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color); - ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color); - ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount); - ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount); - - ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled); - ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled); - ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin); - ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin); - ClassDB::bind_method(D_METHOD("set_fog_depth_end", "distance"), &Environment::set_fog_depth_end); - ClassDB::bind_method(D_METHOD("get_fog_depth_end"), &Environment::get_fog_depth_end); - ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve); - ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve); - ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled); - ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled); - ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve); - ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve); - - ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled); - ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled); - ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min); - ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min); - ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max); - ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max); - ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve); - ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve); + ClassDB::bind_method(D_METHOD("set_fog_light_color", "light_color"), &Environment::set_fog_light_color); + ClassDB::bind_method(D_METHOD("get_fog_light_color"), &Environment::get_fog_light_color); + ClassDB::bind_method(D_METHOD("set_fog_light_energy", "light_energy"), &Environment::set_fog_light_energy); + ClassDB::bind_method(D_METHOD("get_fog_light_energy"), &Environment::get_fog_light_energy); + ClassDB::bind_method(D_METHOD("set_fog_sun_scatter", "sun_scatter"), &Environment::set_fog_sun_scatter); + ClassDB::bind_method(D_METHOD("get_fog_sun_scatter"), &Environment::get_fog_sun_scatter); + + ClassDB::bind_method(D_METHOD("set_fog_density", "density"), &Environment::set_fog_density); + ClassDB::bind_method(D_METHOD("get_fog_density"), &Environment::get_fog_density); + + ClassDB::bind_method(D_METHOD("set_fog_height", "height"), &Environment::set_fog_height); + ClassDB::bind_method(D_METHOD("get_fog_height"), &Environment::get_fog_height); + + ClassDB::bind_method(D_METHOD("set_fog_height_density", "height_density"), &Environment::set_fog_height_density); + ClassDB::bind_method(D_METHOD("get_fog_height_density"), &Environment::get_fog_height_density); + + ClassDB::bind_method(D_METHOD("set_fog_aerial_perspective", "aerial_perspective"), &Environment::set_fog_aerial_perspective); + ClassDB::bind_method(D_METHOD("get_fog_aerial_perspective"), &Environment::get_fog_aerial_perspective); ADD_GROUP("Fog", "fog_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color"); - ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount"); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_end", PROPERTY_HINT_RANGE, "0,4000,0.1,or_greater"), "set_fog_depth_end", "get_fog_depth_end"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve"); - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve"); - - ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_min", "get_fog_height_min"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1,or_lesser,or_greater"), "set_fog_height_max", "get_fog_height_max"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_light_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_fog_light_color", "get_fog_light_color"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01,or_greater"), "set_fog_light_energy", "get_fog_light_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_sun_scatter", PROPERTY_HINT_RANGE, "0,1,0.01,or_greater"), "set_fog_sun_scatter", "get_fog_sun_scatter"); + + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_density", PROPERTY_HINT_RANGE, "0,16,0.0001"), "set_fog_density", "get_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_aerial_perspective", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_fog_aerial_perspective", "get_fog_aerial_perspective"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height", PROPERTY_HINT_RANGE, "-1024,1024,0.01,or_lesser,or_greater"), "set_fog_height", "get_fog_height"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "fog_height_density", PROPERTY_HINT_RANGE, "0,128,0.001,or_greater"), "set_fog_height_density", "get_fog_height_density"); + + ClassDB::bind_method(D_METHOD("set_volumetric_fog_enabled", "enabled"), &Environment::set_volumetric_fog_enabled); + ClassDB::bind_method(D_METHOD("is_volumetric_fog_enabled"), &Environment::is_volumetric_fog_enabled); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_light", "color"), &Environment::set_volumetric_fog_light); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_light"), &Environment::get_volumetric_fog_light); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_density", "density"), &Environment::set_volumetric_fog_density); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_density"), &Environment::get_volumetric_fog_density); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_light_energy", "begin"), &Environment::set_volumetric_fog_light_energy); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_light_energy"), &Environment::get_volumetric_fog_light_energy); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_length", "length"), &Environment::set_volumetric_fog_length); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_length"), &Environment::get_volumetric_fog_length); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_detail_spread", "detail_spread"), &Environment::set_volumetric_fog_detail_spread); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_detail_spread"), &Environment::get_volumetric_fog_detail_spread); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_gi_inject", "gi_inject"), &Environment::set_volumetric_fog_gi_inject); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_gi_inject"), &Environment::get_volumetric_fog_gi_inject); + ClassDB::bind_method(D_METHOD("set_volumetric_fog_shadow_filter", "shadow_filter"), &Environment::set_volumetric_fog_shadow_filter); + ClassDB::bind_method(D_METHOD("get_volumetric_fog_shadow_filter"), &Environment::get_volumetric_fog_shadow_filter); + + ADD_GROUP("Volumetric Fog", "volumetric_fog_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "volumetric_fog_enabled"), "set_volumetric_fog_enabled", "is_volumetric_fog_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_density", PROPERTY_HINT_RANGE, "0,1,0.0001,or_greater"), "set_volumetric_fog_density", "get_volumetric_fog_density"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "volumetric_fog_light", PROPERTY_HINT_COLOR_NO_ALPHA), "set_volumetric_fog_light", "get_volumetric_fog_light"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_light_energy", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_light_energy", "get_volumetric_fog_light_energy"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_gi_inject", PROPERTY_HINT_EXP_RANGE, "0.00,16,0.01"), "set_volumetric_fog_gi_inject", "get_volumetric_fog_gi_inject"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_length", PROPERTY_HINT_RANGE, "0,1024,0.01,or_greater"), "set_volumetric_fog_length", "get_volumetric_fog_length"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "volumetric_fog_detail_spread", PROPERTY_HINT_EXP_EASING, "0.01,16,0.01"), "set_volumetric_fog_detail_spread", "get_volumetric_fog_detail_spread"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "volumetric_fog_shadow_filter", PROPERTY_HINT_ENUM, "Disabled,Low,Medium,High"), "set_volumetric_fog_shadow_filter", "get_volumetric_fog_shadow_filter"); // Adjustment @@ -1331,12 +1363,27 @@ void Environment::_bind_methods() { BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_DISABLED); BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_75_PERCENT); BIND_ENUM_CONSTANT(SDFGI_Y_SCALE_50_PERCENT); + + BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED); + BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_LOW); + BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM); + BIND_ENUM_CONSTANT(VOLUMETRIC_FOG_SHADOW_FILTER_HIGH); } Environment::Environment() { environment = RS::get_singleton()->environment_create(); set_camera_feed_id(bg_camera_feed_id); + + glow_levels.resize(7); + glow_levels.write[0] = 0.0; + glow_levels.write[1] = 0.0; + glow_levels.write[2] = 1.0; + glow_levels.write[3] = 0.0; + glow_levels.write[4] = 1.0; + glow_levels.write[5] = 0.0; + glow_levels.write[6] = 0.0; + _update_ambient_light(); _update_tonemap(); _update_ssr(); @@ -1344,10 +1391,8 @@ Environment::Environment() { _update_sdfgi(); _update_glow(); _update_fog(); - _update_fog_depth(); - _update_fog_height(); _update_adjustment(); - + _update_volumetric_fog(); _change_notify(); } diff --git a/scene/resources/environment.h b/scene/resources/environment.h index f334d22115..9b7247b58d 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -97,6 +97,13 @@ public: GLOW_BLEND_MODE_MIX, }; + enum VolumetricFogShadowFilter { + VOLUMETRIC_FOG_SHADOW_FILTER_DISABLED, + VOLUMETRIC_FOG_SHADOW_FILTER_LOW, + VOLUMETRIC_FOG_SHADOW_FILTER_MEDIUM, + VOLUMETRIC_FOG_SHADOW_FILTER_HIGH, + }; + private: RID environment; @@ -164,7 +171,8 @@ private: // Glow bool glow_enabled = false; - int glow_levels = (1 << 2) | (1 << 4); + Vector<float> glow_levels; + bool glow_normalize_levels = false; float glow_intensity = 0.8; float glow_strength = 1.0; float glow_mix = 0.05; @@ -177,24 +185,26 @@ private: // Fog bool fog_enabled = false; - Color fog_color = Color(0.5, 0.6, 0.7); - Color fog_sun_color = Color(1.0, 0.9, 0.7); - float fog_sun_amount = 0.0; - void _update_fog(); + Color fog_light_color = Color(0.5, 0.6, 0.7); + float fog_light_energy = 1.0; + float fog_sun_scatter = 0.0; + float fog_density = 0.001; + float fog_height = 0.0; + float fog_height_density = 0.0; //can be negative to invert effect + float fog_aerial_perspective = 0.0; - bool fog_depth_enabled = true; - float fog_depth_begin = 10.0; - float fog_depth_end = 100.0; - float fog_depth_curve = 1.0; - bool fog_transmit_enabled = false; - float fog_transmit_curve = 1.0; - void _update_fog_depth(); + void _update_fog(); - bool fog_height_enabled = false; - float fog_height_min = 10.0; - float fog_height_max = 0.0; - float fog_height_curve = 1.0; - void _update_fog_height(); + // Volumetric Fog + bool volumetric_fog_enabled = false; + float volumetric_fog_density = 0.01; + Color volumetric_fog_light = Color(0.0, 0.0, 0.0); + float volumetric_fog_light_energy = 1.0; + float volumetric_fog_length = 64.0; + float volumetric_fog_detail_spread = 2.0; + VolumetricFogShadowFilter volumetric_fog_shadow_filter = VOLUMETRIC_FOG_SHADOW_FILTER_LOW; + float volumetric_fog_gi_inject = 0.0; + void _update_volumetric_fog(); // Adjustment bool adjustment_enabled = false; @@ -324,8 +334,10 @@ public: // Glow void set_glow_enabled(bool p_enabled); bool is_glow_enabled() const; - void set_glow_level_enabled(int p_level, bool p_enabled); - bool is_glow_level_enabled(int p_level) const; + void set_glow_level(int p_level, float p_intensity); + float get_glow_level(int p_level) const; + void set_glow_normalized(bool p_normalized); + bool is_glow_normalized() const; void set_glow_intensity(float p_intensity); float get_glow_intensity() const; void set_glow_strength(float p_strength); @@ -344,36 +356,42 @@ public: float get_glow_hdr_luminance_cap() const; // Fog + void set_fog_enabled(bool p_enabled); bool is_fog_enabled() const; - void set_fog_color(const Color &p_color); - Color get_fog_color() const; - void set_fog_sun_color(const Color &p_color); - Color get_fog_sun_color() const; - void set_fog_sun_amount(float p_amount); - float get_fog_sun_amount() const; - - void set_fog_depth_enabled(bool p_enabled); - bool is_fog_depth_enabled() const; - void set_fog_depth_begin(float p_distance); - float get_fog_depth_begin() const; - void set_fog_depth_end(float p_distance); - float get_fog_depth_end() const; - void set_fog_depth_curve(float p_curve); - float get_fog_depth_curve() const; - void set_fog_transmit_enabled(bool p_enabled); - bool is_fog_transmit_enabled() const; - void set_fog_transmit_curve(float p_curve); - float get_fog_transmit_curve() const; - - void set_fog_height_enabled(bool p_enabled); - bool is_fog_height_enabled() const; - void set_fog_height_min(float p_distance); - float get_fog_height_min() const; - void set_fog_height_max(float p_distance); - float get_fog_height_max() const; - void set_fog_height_curve(float p_distance); - float get_fog_height_curve() const; + void set_fog_light_color(const Color &p_light_color); + Color get_fog_light_color() const; + void set_fog_light_energy(float p_amount); + float get_fog_light_energy() const; + void set_fog_sun_scatter(float p_amount); + float get_fog_sun_scatter() const; + + void set_fog_density(float p_amount); + float get_fog_density() const; + void set_fog_height(float p_amount); + float get_fog_height() const; + void set_fog_height_density(float p_amount); + float get_fog_height_density() const; + void set_fog_aerial_perspective(float p_aerial_perspective); + float get_fog_aerial_perspective() const; + + // Volumetric Fog + void set_volumetric_fog_enabled(bool p_enable); + bool is_volumetric_fog_enabled() const; + void set_volumetric_fog_density(float p_density); + float get_volumetric_fog_density() const; + void set_volumetric_fog_light(Color p_color); + Color get_volumetric_fog_light() const; + void set_volumetric_fog_light_energy(float p_begin); + float get_volumetric_fog_light_energy() const; + void set_volumetric_fog_length(float p_length); + float get_volumetric_fog_length() const; + void set_volumetric_fog_detail_spread(float p_detail_spread); + float get_volumetric_fog_detail_spread() const; + void set_volumetric_fog_shadow_filter(VolumetricFogShadowFilter p_filter); + VolumetricFogShadowFilter get_volumetric_fog_shadow_filter() const; + void set_volumetric_fog_gi_inject(float p_gi_inject); + float get_volumetric_fog_gi_inject() const; // Adjustment void set_adjustment_enabled(bool p_enabled); @@ -399,5 +417,6 @@ VARIANT_ENUM_CAST(Environment::SSAOBlur) VARIANT_ENUM_CAST(Environment::SDFGICascades) VARIANT_ENUM_CAST(Environment::SDFGIYScale) VARIANT_ENUM_CAST(Environment::GlowBlendMode) +VARIANT_ENUM_CAST(Environment::VolumetricFogShadowFilter) #endif // ENVIRONMENT_H diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index ccab88a153..b75657c2c2 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -31,7 +31,6 @@ #include "font.h" #include "core/io/resource_loader.h" -#include "core/method_bind_ext.gen.inc" #include "core/os/file_access.h" void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate, const Color &p_outline_modulate) const { @@ -125,7 +124,7 @@ void BitmapFont::_set_chars(const Vector<int> &p_chars) { Vector<int> BitmapFont::_get_chars() const { Vector<int> chars; - const CharType *key = nullptr; + const char32_t *key = nullptr; while ((key = char_map.next(key))) { const Character *c = char_map.getptr(*key); @@ -272,7 +271,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) { } } } else if (type == "char") { - CharType idx = 0; + char32_t idx = 0; if (keys.has("id")) { idx = keys["id"].to_int(); } @@ -313,7 +312,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) { add_char(idx, texture, rect, ofs, advance); } else if (type == "kerning") { - CharType first = 0, second = 0; + char32_t first = 0, second = 0; int k = 0; if (keys.has("first")) { @@ -385,10 +384,10 @@ int BitmapFont::get_character_count() const { return char_map.size(); }; -Vector<CharType> BitmapFont::get_char_keys() const { - Vector<CharType> chars; +Vector<char32_t> BitmapFont::get_char_keys() const { + Vector<char32_t> chars; chars.resize(char_map.size()); - const CharType *ct = nullptr; + const char32_t *ct = nullptr; int count = 0; while ((ct = char_map.next(ct))) { chars.write[count++] = *ct; @@ -397,7 +396,7 @@ Vector<CharType> BitmapFont::get_char_keys() const { return chars; }; -BitmapFont::Character BitmapFont::get_character(CharType p_char) const { +BitmapFont::Character BitmapFont::get_character(char32_t p_char) const { if (!char_map.has(p_char)) { ERR_FAIL_V(Character()); }; @@ -405,7 +404,7 @@ BitmapFont::Character BitmapFont::get_character(CharType p_char) const { return char_map[p_char]; }; -void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { +void BitmapFont::add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance) { if (p_advance < 0) { p_advance = p_rect.size.width; } @@ -420,7 +419,7 @@ void BitmapFont::add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rec char_map[p_char] = c; } -void BitmapFont::add_kerning_pair(CharType p_A, CharType p_B, int p_kerning) { +void BitmapFont::add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning) { KerningPairKey kpk; kpk.A = p_A; kpk.B = p_B; @@ -444,7 +443,7 @@ Vector<BitmapFont::KerningPairKey> BitmapFont::get_kerning_pair_keys() const { return ret; } -int BitmapFont::get_kerning_pair(CharType p_A, CharType p_B) const { +int BitmapFont::get_kerning_pair(char32_t p_A, char32_t p_B) const { KerningPairKey kpk; kpk.A = p_A; kpk.B = p_B; @@ -482,7 +481,7 @@ Size2 Font::get_string_size(const String &p_string) const { if (l == 0) { return Size2(0, get_height()); } - const CharType *sptr = &p_string[0]; + const char32_t *sptr = &p_string[0]; for (int i = 0; i < l; i++) { w += get_char_size(sptr[i], sptr[i + 1]).width; @@ -534,7 +533,7 @@ Ref<BitmapFont> BitmapFont::get_fallback() const { return fallback; } -float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next, const Color &p_modulate, bool p_outline) const { +float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next, const Color &p_modulate, bool p_outline) const { const Character *c = char_map.getptr(p_char); if (!c) { @@ -556,7 +555,7 @@ float BitmapFont::draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_c return get_char_size(p_char, p_next).width; } -Size2 BitmapFont::get_char_size(CharType p_char, CharType p_next) const { +Size2 BitmapFont::get_char_size(char32_t p_char, char32_t p_next) const { const Character *c = char_map.getptr(p_char); if (!c) { diff --git a/scene/resources/font.h b/scene/resources/font.h index e6b296800b..c739520da3 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -49,7 +49,7 @@ public: virtual float get_underline_position() const = 0; virtual float get_underline_thickness() const = 0; - virtual Size2 get_char_size(CharType p_char, CharType p_next = 0) const = 0; + virtual Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const = 0; Size2 get_string_size(const String &p_string) const; Size2 get_wordwrap_string_size(const String &p_string, float p_width) const; @@ -59,7 +59,7 @@ public: void draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate = Color(1, 1, 1), const Color &p_outline_modulate = Color(1, 1, 1)) const; virtual bool has_outline() const { return false; } - virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0; + virtual float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const = 0; void update_changes(); Font(); @@ -74,8 +74,8 @@ class FontDrawer { struct PendingDraw { RID canvas_item; Point2 pos; - CharType chr; - CharType next; + char32_t chr; + char32_t next; Color modulate; }; @@ -88,7 +88,7 @@ public: has_outline = p_font->has_outline(); } - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1)) { + float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1)) { if (has_outline) { PendingDraw draw = { p_canvas_item, p_pos, p_char, p_next, p_modulate }; pending_draws.push_back(draw); @@ -137,7 +137,7 @@ public: }; private: - HashMap<CharType, Character> char_map; + HashMap<char32_t, Character> char_map; Map<KerningPairKey, int> kerning_map; float height; @@ -169,20 +169,20 @@ public: float get_underline_thickness() const override; void add_texture(const Ref<Texture2D> &p_texture); - void add_char(CharType p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1); + void add_char(char32_t p_char, int p_texture_idx, const Rect2 &p_rect, const Size2 &p_align, float p_advance = -1); int get_character_count() const; - Vector<CharType> get_char_keys() const; - Character get_character(CharType p_char) const; + Vector<char32_t> get_char_keys() const; + Character get_character(char32_t p_char) const; int get_texture_count() const; Ref<Texture2D> get_texture(int p_idx) const; - void add_kerning_pair(CharType p_A, CharType p_B, int p_kerning); - int get_kerning_pair(CharType p_A, CharType p_B) const; + void add_kerning_pair(char32_t p_A, char32_t p_B, int p_kerning); + int get_kerning_pair(char32_t p_A, char32_t p_B) const; Vector<KerningPairKey> get_kerning_pair_keys() const; - Size2 get_char_size(CharType p_char, CharType p_next = 0) const override; + Size2 get_char_size(char32_t p_char, char32_t p_next = 0) const override; void set_fallback(const Ref<BitmapFont> &p_fallback); Ref<BitmapFont> get_fallback() const; @@ -192,7 +192,7 @@ public: void set_distance_field_hint(bool p_distance_field); bool is_distance_field_hint() const override; - float draw_char(RID p_canvas_item, const Point2 &p_pos, CharType p_char, CharType p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override; + float draw_char(RID p_canvas_item, const Point2 &p_pos, char32_t p_char, char32_t p_next = 0, const Color &p_modulate = Color(1, 1, 1), bool p_outline = false) const override; BitmapFont(); ~BitmapFont(); diff --git a/scene/resources/gradient.cpp b/scene/resources/gradient.cpp index d271c906ff..b720653f91 100644 --- a/scene/resources/gradient.cpp +++ b/scene/resources/gradient.cpp @@ -129,7 +129,7 @@ void Gradient::add_point(float p_offset, const Color &p_color) { void Gradient::remove_point(int p_index) { ERR_FAIL_INDEX(p_index, points.size()); - ERR_FAIL_COND(points.size() <= 2); + ERR_FAIL_COND(points.size() <= 1); points.remove(p_index); emit_signal(CoreStringNames::get_singleton()->changed); } @@ -141,32 +141,29 @@ void Gradient::set_points(Vector<Gradient::Point> &p_points) { } void Gradient::set_offset(int pos, const float offset) { - ERR_FAIL_COND(pos < 0); - if (points.size() <= pos) { - points.resize(pos + 1); - } + ERR_FAIL_INDEX(pos, points.size()); + _update_sorting(); points.write[pos].offset = offset; is_sorted = false; emit_signal(CoreStringNames::get_singleton()->changed); } -float Gradient::get_offset(int pos) const { +float Gradient::get_offset(int pos) { ERR_FAIL_INDEX_V(pos, points.size(), 0.0); + _update_sorting(); return points[pos].offset; } void Gradient::set_color(int pos, const Color &color) { - ERR_FAIL_COND(pos < 0); - if (points.size() <= pos) { - points.resize(pos + 1); - is_sorted = false; - } + ERR_FAIL_INDEX(pos, points.size()); + _update_sorting(); points.write[pos].color = color; emit_signal(CoreStringNames::get_singleton()->changed); } -Color Gradient::get_color(int pos) const { +Color Gradient::get_color(int pos) { ERR_FAIL_INDEX_V(pos, points.size(), Color()); + _update_sorting(); return points[pos].color; } diff --git a/scene/resources/gradient.h b/scene/resources/gradient.h index d40dcc8d44..6518b13ee8 100644 --- a/scene/resources/gradient.h +++ b/scene/resources/gradient.h @@ -49,6 +49,12 @@ public: private: Vector<Point> points; bool is_sorted; + _FORCE_INLINE_ void _update_sorting() { + if (!is_sorted) { + points.sort(); + is_sorted = true; + } + } protected: static void _bind_methods(); @@ -64,10 +70,10 @@ public: Vector<Point> &get_points(); void set_offset(int pos, const float offset); - float get_offset(int pos) const; + float get_offset(int pos); void set_color(int pos, const Color &color); - Color get_color(int pos) const; + Color get_color(int pos); void set_offsets(const Vector<float> &p_offsets); Vector<float> get_offsets() const; @@ -80,10 +86,7 @@ public: return Color(0, 0, 0, 1); } - if (!is_sorted) { - points.sort(); - is_sorted = true; - } + _update_sorting(); //binary search int low = 0; diff --git a/scene/resources/height_map_shape_3d.cpp b/scene/resources/height_map_shape_3d.cpp index e112c6b436..2ae47bcf3c 100644 --- a/scene/resources/height_map_shape_3d.cpp +++ b/scene/resources/height_map_shape_3d.cpp @@ -31,7 +31,7 @@ #include "height_map_shape_3d.h" #include "servers/physics_server_3d.h" -Vector<Vector3> HeightMapShape3D::get_debug_mesh_lines() { +Vector<Vector3> HeightMapShape3D::get_debug_mesh_lines() const { Vector<Vector3> points; if ((map_width != 0) && (map_depth != 0)) { diff --git a/scene/resources/height_map_shape_3d.h b/scene/resources/height_map_shape_3d.h index c5715a57b1..9ee8b49689 100644 --- a/scene/resources/height_map_shape_3d.h +++ b/scene/resources/height_map_shape_3d.h @@ -54,7 +54,7 @@ public: void set_map_data(PackedFloat32Array p_new); PackedFloat32Array get_map_data() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; HeightMapShape3D(); diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 10f0a040d0..e9606e03e6 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -872,7 +872,6 @@ Array ArrayMesh::_get_surfaces() const { ret.push_back(data); } - print_line("Saving surfaces: " + itos(ret.size())); return ret; } diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index fd1fa1b48f..b0a30a5627 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -209,7 +209,6 @@ public: void surface_update_region(int p_surface, int p_offset, const Vector<uint8_t> &p_data); int get_surface_count() const override; - void surface_remove(int p_idx); void clear_surfaces(); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 7b78398669..450e2c16e3 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -28,8 +28,8 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef GRID_THEME_H -#define GRID_THEME_H +#ifndef MESH_LIBRARY_H +#define MESH_LIBRARY_H #include "core/map.h" #include "core/resource.h" @@ -96,4 +96,4 @@ public: ~MeshLibrary(); }; -#endif // CUBE_GRID_THEME_H +#endif // MESH_LIBRARY_H diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index cb201bc539..5e8bfd9387 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -848,7 +848,7 @@ Error SceneState::pack(Node *p_scene) { Map<Node *, int> node_map; Map<Node *, int> nodepath_map; - //if using scene inheritance, pack the scene it inherits from + // If using scene inheritance, pack the scene it inherits from. if (scene->get_scene_inherited_state().is_valid()) { String path = scene->get_scene_inherited_state()->get_path(); Ref<PackedScene> instance = ResourceLoader::load(path); @@ -856,8 +856,8 @@ Error SceneState::pack(Node *p_scene) { base_scene_idx = _vm_get_variant(instance, variant_map); } } - //instanced, only direct sub-scnes are supported of course + // Instanced, only direct sub-scenes are supported of course. Error err = _parse_node(scene, scene, -1, name_map, variant_map, node_map, nodepath_map); if (err) { clear(); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index fc92a721db..a286184aee 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -91,13 +91,16 @@ void ParticlesMaterial::init_shaders() { shader_names->emission_texture_normal = "emission_texture_normal"; shader_names->emission_texture_color = "emission_texture_color"; - shader_names->trail_divisor = "trail_divisor"; - shader_names->trail_size_modifier = "trail_size_modifier"; - shader_names->trail_color_modifier = "trail_color_modifier"; - shader_names->gravity = "gravity"; shader_names->lifetime_randomness = "lifetime_randomness"; + + shader_names->sub_emitter_frequency = "sub_emitter_frequency"; + shader_names->sub_emitter_amount_at_end = "sub_emitter_amount_at_end"; + shader_names->sub_emitter_keep_velocity = "sub_emitter_keep_velocity"; + + shader_names->collision_friction = "collision_friction"; + shader_names->collision_bounce = "collision_bounce"; } void ParticlesMaterial::finish_shaders() { @@ -136,6 +139,10 @@ void ParticlesMaterial::_update_shader() { String code = "shader_type particles;\n"; + if (collision_scale) { + code += "render_mode collision_use_scale;\n"; + } + code += "uniform vec3 direction;\n"; code += "uniform float spread;\n"; code += "uniform float flatness;\n"; @@ -192,9 +199,17 @@ void ParticlesMaterial::_update_shader() { } } - code += "uniform vec4 color_value : hint_color;\n"; + if (sub_emitter_mode != SUB_EMITTER_DISABLED) { + if (sub_emitter_mode == SUB_EMITTER_CONSTANT) { + code += "uniform float sub_emitter_frequency;\n"; + } + if (sub_emitter_mode == SUB_EMITTER_AT_END) { + code += "uniform int sub_emitter_amount_at_end;\n"; + } + code += "uniform bool sub_emitter_keep_velocity;\n"; + } - code += "uniform int trail_divisor;\n"; + code += "uniform vec4 color_value : hint_color;\n"; code += "uniform vec3 gravity;\n"; @@ -239,12 +254,9 @@ void ParticlesMaterial::_update_shader() { code += "uniform sampler2D anim_offset_texture;\n"; } - if (trail_size_modifier.is_valid()) { - code += "uniform sampler2D trail_size_modifier;\n"; - } - - if (trail_color_modifier.is_valid()) { - code += "uniform sampler2D trail_color_modifier;\n"; + if (collision_enabled) { + code += "uniform float collision_friction;\n"; + code += "uniform float collision_bounce;\n"; } //need a random function @@ -277,8 +289,8 @@ void ParticlesMaterial::_update_shader() { code += "}\n"; code += "\n"; - code += "void vertex() {\n"; - code += " uint base_number = NUMBER / uint(trail_divisor);\n"; + code += "void compute() {\n"; + code += " uint base_number = NUMBER;\n"; code += " uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n"; code += " float angle_rand = rand_from_seed(alt_seed);\n"; code += " float scale_rand = rand_from_seed(alt_seed);\n"; @@ -293,17 +305,7 @@ void ParticlesMaterial::_update_shader() { code += " ivec2 emission_tex_size = textureSize(emission_texture_points, 0);\n"; code += " ivec2 emission_tex_ofs = ivec2(point % emission_tex_size.x, point / emission_tex_size.x);\n"; } - code += " bool restart = false;\n"; - code += " if (CUSTOM.y > CUSTOM.w) {\n"; - code += " restart = true;\n"; - code += " }\n\n"; - code += " if (RESTART || restart) {\n"; - - if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { - code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n"; - } else { - code += " float tex_linear_velocity = 0.0;\n"; - } + code += " if (RESTART) {\n"; if (tex_parameters[PARAM_ANGLE].is_valid()) { code += " float tex_angle = textureLod(angle_texture, vec2(0.0, 0.0), 0.0).r;\n"; @@ -319,25 +321,34 @@ void ParticlesMaterial::_update_shader() { code += " float spread_rad = spread * degree_to_rad;\n"; + code += " if (RESTART_VELOCITY) {\n"; + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { + code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n"; + } else { + code += " float tex_linear_velocity = 0.0;\n"; + } + if (flags[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"; - code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + 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"; + code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } else { //initiate velocity spread in 3D - code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; - code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; - code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n"; - code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n"; - code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; - code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; - code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; - code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; - code += " vec_direction = normalize(vec_direction);\n"; - code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " angle1_rad += direction.z != 0.0 ? atan(direction.x, direction.z) : sign(direction.x) * (pi / 2.0);\n"; + code += " angle2_rad += direction.z != 0.0 ? atan(direction.y, abs(direction.z)) : (direction.x != 0.0 ? atan(direction.y, abs(direction.x)) : sign(direction.y) * (pi / 2.0));\n"; + code += " vec3 direction_xz = vec3(sin(angle1_rad), 0.0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3(0.0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " direction_yz.z = direction_yz.z / max(0.0001,sqrt(abs(direction_yz.z))); // better uniform distribution\n"; + code += " vec3 vec_direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " vec_direction = normalize(vec_direction);\n"; + code += " VELOCITY = vec_direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; } + code += " }\n"; code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n"; code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle @@ -345,35 +356,38 @@ void ParticlesMaterial::_update_shader() { code += " CUSTOM.w = (1.0 - lifetime_randomness * rand_from_seed(alt_seed));\n"; code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random);\n"; // animation offset (0-1) + code += " if (RESTART_POSITION) {\n"; + switch (emission_shape) { case EMISSION_SHAPE_POINT: { - //do none + //do none, identity (will later be multiplied by emission transform) + code += " TRANSFORM = mat4(vec4(1,0,0,0),vec4(0,1,0,0),vec4(0,0,1,0),vec4(0,0,0,1));\n"; } break; case EMISSION_SHAPE_SPHERE: { - code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n"; - code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n"; - code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n"; - code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n"; + code += " float s = rand_from_seed(alt_seed) * 2.0 - 1.0;\n"; + code += " float t = rand_from_seed(alt_seed) * 2.0 * pi;\n"; + code += " float radius = emission_sphere_radius * sqrt(1.0 - s * s);\n"; + code += " TRANSFORM[3].xyz = vec3(radius * cos(t), radius * sin(t), emission_sphere_radius * s);\n"; } break; case EMISSION_SHAPE_BOX: { - code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n"; + code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n"; } break; case EMISSION_SHAPE_POINTS: case EMISSION_SHAPE_DIRECTED_POINTS: { - code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n"; + 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]) { - 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"; - code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; + 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"; + code += " if (RESTART_VELOCITY) VELOCITY.xy = rotm * VELOCITY.xy;\n"; } else { - code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n"; - code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n"; - code += " vec3 tangent = normalize(cross(v0, normal));\n"; - code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; - code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n"; + code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n"; + code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0);\n"; + code += " vec3 tangent = normalize(cross(v0, normal));\n"; + code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; + code += " if (RESTART_VELOCITY) VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n"; } } } break; @@ -381,12 +395,14 @@ void ParticlesMaterial::_update_shader() { break; } } - code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; - code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; + + code += " if (RESTART_VELOCITY) VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; + code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; if (flags[FLAG_DISABLE_Z]) { - code += " VELOCITY.z = 0.0;\n"; - code += " TRANSFORM[3].z = 0.0;\n"; + code += " VELOCITY.z = 0.0;\n"; + code += " TRANSFORM[3].z = 0.0;\n"; } + code += " }\n"; code += " } else {\n"; @@ -472,6 +488,10 @@ void ParticlesMaterial::_update_shader() { code += " vec3 crossDiff = cross(normalize(diff), normalize(gravity));\n"; code += " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; } + if (attractor_interaction_enabled) { + code += " force += ATTRACTOR_FORCE;\n\n"; + } + code += " // apply attractor forces\n"; code += " VELOCITY += force * DELTA;\n"; code += " // orbit velocity\n"; @@ -540,11 +560,6 @@ void ParticlesMaterial::_update_shader() { if (emission_color_texture.is_valid() && (emission_shape == EMISSION_SHAPE_POINTS || emission_shape == EMISSION_SHAPE_DIRECTED_POINTS)) { code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n"; } - if (trail_color_modifier.is_valid()) { - code += " if (trail_divisor > 1) {\n"; - code += " COLOR *= textureLod(trail_color_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0);\n"; - code += " }\n"; - } code += "\n"; if (flags[FLAG_DISABLE_Z]) { @@ -592,11 +607,6 @@ void ParticlesMaterial::_update_shader() { code += " if (base_scale < 0.000001) {\n"; code += " base_scale = 0.000001;\n"; code += " }\n"; - if (trail_size_modifier.is_valid()) { - code += " if (trail_divisor > 1) {\n"; - code += " base_scale *= textureLod(trail_size_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0).r;\n"; - code += " }\n"; - } code += " TRANSFORM[0].xyz *= base_scale;\n"; code += " TRANSFORM[1].xyz *= base_scale;\n"; @@ -605,6 +615,41 @@ void ParticlesMaterial::_update_shader() { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } + if (collision_enabled) { + code += " if (COLLIDED) {\n"; + code += " TRANSFORM[3].xyz+=COLLISION_NORMAL * COLLISION_DEPTH;\n"; + code += " VELOCITY -= COLLISION_NORMAL * dot(COLLISION_NORMAL, VELOCITY) * (1.0 + collision_bounce);\n"; + code += " VELOCITY = mix(VELOCITY,vec3(0.0),collision_friction * DELTA * 100.0);\n"; + code += " }\n"; + } + if (sub_emitter_mode != SUB_EMITTER_DISABLED) { + code += " int emit_count = 0;\n"; + switch (sub_emitter_mode) { + case SUB_EMITTER_CONSTANT: { + code += " float interval_from = CUSTOM.y * LIFETIME - DELTA;\n"; + code += " float interval_rem = sub_emitter_frequency - mod(interval_from,sub_emitter_frequency);\n"; + code += " if (DELTA >= interval_rem) emit_count = 1;\n"; + } break; + case SUB_EMITTER_AT_COLLISION: { + //not implemented yet + code += " if (COLLIDED) emit_count = 1;\n"; + } break; + case SUB_EMITTER_AT_END: { + //not implemented yet + code += " float unit_delta = DELTA/LIFETIME;\n"; + code += " float end_time = CUSTOM.w * 0.95;\n"; // if we do at the end we might miss it, as it can just get deactivated by emitter + code += " if (CUSTOM.y < end_time && (CUSTOM.y + unit_delta) >= end_time) emit_count = sub_emitter_amount_at_end;\n"; + } break; + default: { + } + } + code += " for(int i=0;i<emit_count;i++) {\n"; + code += " uint flags = FLAG_EMIT_POSITION|FLAG_EMIT_ROT_SCALE;\n"; + code += " if (sub_emitter_keep_velocity) flags|=FLAG_EMIT_VELOCITY;\n"; + code += " emit_particle(TRANSFORM,VELOCITY,vec4(0.0),vec4(0.0),flags);\n"; + code += " }"; + } + code += " if (CUSTOM.y > CUSTOM.w) {"; code += " ACTIVE = false;\n"; code += " }\n"; @@ -951,41 +996,6 @@ int ParticlesMaterial::get_emission_point_count() const { return emission_point_count; } -void ParticlesMaterial::set_trail_divisor(int p_divisor) { - trail_divisor = p_divisor; - RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor); -} - -int ParticlesMaterial::get_trail_divisor() const { - return trail_divisor; -} - -void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) { - trail_size_modifier = p_trail_size_modifier; - - Ref<CurveTexture> curve = trail_size_modifier; - if (curve.is_valid()) { - curve->ensure_default_setup(); - } - - RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_size_modifier, curve); - _queue_shader_change(); -} - -Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const { - return trail_size_modifier; -} - -void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) { - trail_color_modifier = p_trail_color_modifier; - RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, p_trail_color_modifier); - _queue_shader_change(); -} - -Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const { - return trail_color_modifier; -} - void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { gravity = p_gravity; Vector3 gset = gravity; @@ -1038,11 +1048,99 @@ void ParticlesMaterial::_validate_property(PropertyInfo &property) const { property.usage = 0; } + if (property.name == "sub_emitter_frequency" && sub_emitter_mode != SUB_EMITTER_CONSTANT) { + property.usage = 0; + } + + if (property.name == "sub_emitter_amount_at_end" && sub_emitter_mode != SUB_EMITTER_AT_END) { + property.usage = 0; + } + if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { property.usage = 0; } } +void ParticlesMaterial::set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode) { + sub_emitter_mode = p_sub_emitter_mode; + _queue_shader_change(); + _change_notify(); +} + +ParticlesMaterial::SubEmitterMode ParticlesMaterial::get_sub_emitter_mode() const { + return sub_emitter_mode; +} + +void ParticlesMaterial::set_sub_emitter_frequency(float p_frequency) { + sub_emitter_frequency = p_frequency; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_frequency, 1.0 / p_frequency); //pas delta instead of frequency, since its easier to compute +} +float ParticlesMaterial::get_sub_emitter_frequency() const { + return sub_emitter_frequency; +} + +void ParticlesMaterial::set_sub_emitter_amount_at_end(int p_amount) { + sub_emitter_amount_at_end = p_amount; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_amount_at_end, p_amount); +} + +int ParticlesMaterial::get_sub_emitter_amount_at_end() const { + return sub_emitter_amount_at_end; +} + +void ParticlesMaterial::set_sub_emitter_keep_velocity(bool p_enable) { + sub_emitter_keep_velocity = p_enable; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->sub_emitter_keep_velocity, p_enable); +} +bool ParticlesMaterial::get_sub_emitter_keep_velocity() const { + return sub_emitter_keep_velocity; +} + +void ParticlesMaterial::set_attractor_interaction_enabled(bool p_enable) { + attractor_interaction_enabled = p_enable; + _queue_shader_change(); +} + +bool ParticlesMaterial::is_attractor_interaction_enabled() const { + return attractor_interaction_enabled; +} + +void ParticlesMaterial::set_collision_enabled(bool p_enabled) { + collision_enabled = p_enabled; + _queue_shader_change(); +} + +bool ParticlesMaterial::is_collision_enabled() const { + return collision_enabled; +} + +void ParticlesMaterial::set_collision_use_scale(bool p_scale) { + collision_scale = p_scale; + _queue_shader_change(); +} + +bool ParticlesMaterial::is_collision_using_scale() const { + return collision_scale; +} + +void ParticlesMaterial::set_collision_friction(float p_friction) { + collision_friction = p_friction; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->collision_friction, p_friction); +} + +float ParticlesMaterial::get_collision_friction() const { + return collision_friction; +} + +void ParticlesMaterial::set_collision_bounce(float p_bounce) { + collision_bounce = p_bounce; + RenderingServer::get_singleton()->material_set_param(_get_material(), shader_names->collision_bounce, p_bounce); +} + +float ParticlesMaterial::get_collision_bounce() const { + return collision_bounce; +} + Shader::Mode ParticlesMaterial::get_shader_mode() const { return Shader::MODE_PARTICLES; } @@ -1096,27 +1194,42 @@ void ParticlesMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count); ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count); - ClassDB::bind_method(D_METHOD("set_trail_divisor", "divisor"), &ParticlesMaterial::set_trail_divisor); - ClassDB::bind_method(D_METHOD("get_trail_divisor"), &ParticlesMaterial::get_trail_divisor); - - ClassDB::bind_method(D_METHOD("set_trail_size_modifier", "texture"), &ParticlesMaterial::set_trail_size_modifier); - ClassDB::bind_method(D_METHOD("get_trail_size_modifier"), &ParticlesMaterial::get_trail_size_modifier); - - ClassDB::bind_method(D_METHOD("set_trail_color_modifier", "texture"), &ParticlesMaterial::set_trail_color_modifier); - ClassDB::bind_method(D_METHOD("get_trail_color_modifier"), &ParticlesMaterial::get_trail_color_modifier); - ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); ClassDB::bind_method(D_METHOD("set_lifetime_randomness", "randomness"), &ParticlesMaterial::set_lifetime_randomness); ClassDB::bind_method(D_METHOD("get_lifetime_randomness"), &ParticlesMaterial::get_lifetime_randomness); + ClassDB::bind_method(D_METHOD("get_sub_emitter_mode"), &ParticlesMaterial::get_sub_emitter_mode); + ClassDB::bind_method(D_METHOD("set_sub_emitter_mode", "mode"), &ParticlesMaterial::set_sub_emitter_mode); + + ClassDB::bind_method(D_METHOD("get_sub_emitter_frequency"), &ParticlesMaterial::get_sub_emitter_frequency); + ClassDB::bind_method(D_METHOD("set_sub_emitter_frequency", "hz"), &ParticlesMaterial::set_sub_emitter_frequency); + + ClassDB::bind_method(D_METHOD("get_sub_emitter_amount_at_end"), &ParticlesMaterial::get_sub_emitter_amount_at_end); + ClassDB::bind_method(D_METHOD("set_sub_emitter_amount_at_end", "amount"), &ParticlesMaterial::set_sub_emitter_amount_at_end); + + ClassDB::bind_method(D_METHOD("get_sub_emitter_keep_velocity"), &ParticlesMaterial::get_sub_emitter_keep_velocity); + ClassDB::bind_method(D_METHOD("set_sub_emitter_keep_velocity", "enable"), &ParticlesMaterial::set_sub_emitter_keep_velocity); + + ClassDB::bind_method(D_METHOD("set_attractor_interaction_enabled", "enabled"), &ParticlesMaterial::set_attractor_interaction_enabled); + ClassDB::bind_method(D_METHOD("is_attractor_interaction_enabled"), &ParticlesMaterial::is_attractor_interaction_enabled); + + ClassDB::bind_method(D_METHOD("set_collision_enabled", "enabled"), &ParticlesMaterial::set_collision_enabled); + ClassDB::bind_method(D_METHOD("is_collision_enabled"), &ParticlesMaterial::is_collision_enabled); + + ClassDB::bind_method(D_METHOD("set_collision_use_scale", "radius"), &ParticlesMaterial::set_collision_use_scale); + ClassDB::bind_method(D_METHOD("is_collision_using_scale"), &ParticlesMaterial::is_collision_using_scale); + + ClassDB::bind_method(D_METHOD("set_collision_friction", "friction"), &ParticlesMaterial::set_collision_friction); + ClassDB::bind_method(D_METHOD("get_collision_friction"), &ParticlesMaterial::get_collision_friction); + + ClassDB::bind_method(D_METHOD("set_collision_bounce", "bounce"), &ParticlesMaterial::set_collision_bounce); + ClassDB::bind_method(D_METHOD("get_collision_bounce"), &ParticlesMaterial::get_collision_bounce); + ADD_GROUP("Time", ""); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "lifetime_randomness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_lifetime_randomness", "get_lifetime_randomness"); - ADD_GROUP("Trail", "trail_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier"); - ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier"); + ADD_GROUP("Emission Shape", "emission_"); ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius"); @@ -1186,6 +1299,20 @@ void ParticlesMaterial::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::FLOAT, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); + ADD_GROUP("Sub Emitter", "sub_emitter_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_mode", PROPERTY_HINT_ENUM, "Disabled,Constant,AtEnd,AtCollision"), "set_sub_emitter_mode", "get_sub_emitter_mode"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "sub_emitter_frequency", PROPERTY_HINT_RANGE, "0.01,100,0.01"), "set_sub_emitter_frequency", "get_sub_emitter_frequency"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "sub_emitter_amount_at_end", PROPERTY_HINT_RANGE, "1,32,1"), "set_sub_emitter_amount_at_end", "get_sub_emitter_amount_at_end"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "sub_emitter_keep_velocity"), "set_sub_emitter_keep_velocity", "get_sub_emitter_keep_velocity"); + + ADD_GROUP("Attractor Interaction", "attractor_interaction_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "attractor_interaction_enabled"), "set_attractor_interaction_enabled", "is_attractor_interaction_enabled"); + ADD_GROUP("Collision", "collision_"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_enabled"), "set_collision_enabled", "is_collision_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_scale"), "set_collision_use_scale", "is_collision_using_scale"); + BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY); BIND_ENUM_CONSTANT(PARAM_ORBIT_VELOCITY); @@ -1211,6 +1338,12 @@ void ParticlesMaterial::_bind_methods() { BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); BIND_ENUM_CONSTANT(EMISSION_SHAPE_MAX); + + BIND_ENUM_CONSTANT(SUB_EMITTER_DISABLED); + BIND_ENUM_CONSTANT(SUB_EMITTER_CONSTANT); + BIND_ENUM_CONSTANT(SUB_EMITTER_AT_END); + BIND_ENUM_CONSTANT(SUB_EMITTER_AT_COLLISION); + BIND_ENUM_CONSTANT(SUB_EMITTER_MAX); } ParticlesMaterial::ParticlesMaterial() : @@ -1233,11 +1366,21 @@ ParticlesMaterial::ParticlesMaterial() : set_emission_shape(EMISSION_SHAPE_POINT); set_emission_sphere_radius(1); set_emission_box_extents(Vector3(1, 1, 1)); - set_trail_divisor(1); set_gravity(Vector3(0, -9.8, 0)); set_lifetime_randomness(0); emission_point_count = 1; + set_sub_emitter_mode(SUB_EMITTER_DISABLED); + set_sub_emitter_frequency(4); + set_sub_emitter_amount_at_end(1); + set_sub_emitter_keep_velocity(false); + + set_attractor_interaction_enabled(true); + set_collision_enabled(true); + set_collision_bounce(0.0); + set_collision_friction(0.0); + set_collision_use_scale(false); + for (int i = 0; i < PARAM_MAX; i++) { set_param_randomness(Parameter(i), 0); } diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 1c1b6c92f9..7aca708889 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -34,12 +34,18 @@ #ifndef PARTICLES_MATERIAL_H #define PARTICLES_MATERIAL_H +/* + TODO: +-Path following +-Emitter positions deformable by bones +-Proper trails +*/ + class ParticlesMaterial : public Material { GDCLASS(ParticlesMaterial, Material); public: enum Parameter { - PARAM_INITIAL_LINEAR_VELOCITY, PARAM_ANGULAR_VELOCITY, PARAM_ORBIT_VELOCITY, @@ -71,6 +77,14 @@ public: EMISSION_SHAPE_MAX }; + enum SubEmitterMode { + SUB_EMITTER_DISABLED, + SUB_EMITTER_CONSTANT, + SUB_EMITTER_AT_END, + SUB_EMITTER_AT_COLLISION, + SUB_EMITTER_MAX + }; + private: union MaterialKey { struct { @@ -78,10 +92,12 @@ private: uint32_t texture_color : 1; uint32_t flags : 4; uint32_t emission_shape : 2; - uint32_t trail_size_texture : 1; - uint32_t trail_color_texture : 1; uint32_t invalid_key : 1; uint32_t has_emission_color : 1; + uint32_t sub_emitter : 2; + uint32_t attractor_enabled : 1; + uint32_t collision_enabled : 1; + uint32_t collision_scale : 1; }; uint32_t key; @@ -116,9 +132,11 @@ private: mk.texture_color = color_ramp.is_valid() ? 1 : 0; mk.emission_shape = emission_shape; - mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0; - mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0; mk.has_emission_color = emission_shape >= EMISSION_SHAPE_POINTS && emission_color_texture.is_valid(); + mk.sub_emitter = sub_emitter_mode; + mk.collision_enabled = collision_enabled; + mk.attractor_enabled = attractor_interaction_enabled; + mk.collision_scale = collision_scale; return mk; } @@ -178,13 +196,16 @@ private: StringName emission_texture_normal; StringName emission_texture_color; - StringName trail_divisor; - StringName trail_size_modifier; - StringName trail_color_modifier; - StringName gravity; StringName lifetime_randomness; + + StringName sub_emitter_frequency; + StringName sub_emitter_amount_at_end; + StringName sub_emitter_keep_velocity; + + StringName collision_friction; + StringName collision_bounce; }; static ShaderNames *shader_names; @@ -218,17 +239,22 @@ private: bool anim_loop; - int trail_divisor; - - Ref<CurveTexture> trail_size_modifier; - Ref<GradientTexture> trail_color_modifier; - Vector3 gravity; float lifetime_randomness; + SubEmitterMode sub_emitter_mode; + float sub_emitter_frequency; + int sub_emitter_amount_at_end; + bool sub_emitter_keep_velocity; //do not save emission points here + bool attractor_interaction_enabled; + bool collision_enabled; + bool collision_scale; + float collision_friction; + float collision_bounce; + protected: static void _bind_methods(); virtual void _validate_property(PropertyInfo &property) const override; @@ -277,25 +303,43 @@ public: Ref<Texture2D> get_emission_color_texture() const; int get_emission_point_count() const; - void set_trail_divisor(int p_divisor); - int get_trail_divisor() const; - - void set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier); - Ref<CurveTexture> get_trail_size_modifier() const; - - void set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier); - Ref<GradientTexture> get_trail_color_modifier() const; - void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; void set_lifetime_randomness(float p_lifetime); float get_lifetime_randomness() const; + void set_attractor_interaction_enabled(bool p_enable); + bool is_attractor_interaction_enabled() const; + + void set_collision_enabled(bool p_enabled); + bool is_collision_enabled() const; + + void set_collision_use_scale(bool p_scale); + bool is_collision_using_scale() const; + + void set_collision_friction(float p_friction); + float get_collision_friction() const; + + void set_collision_bounce(float p_bounce); + float get_collision_bounce() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); + void set_sub_emitter_mode(SubEmitterMode p_sub_emitter_mode); + SubEmitterMode get_sub_emitter_mode() const; + + void set_sub_emitter_frequency(float p_frequency); + float get_sub_emitter_frequency() const; + + void set_sub_emitter_amount_at_end(int p_amount); + int get_sub_emitter_amount_at_end() const; + + void set_sub_emitter_keep_velocity(bool p_enable); + bool get_sub_emitter_keep_velocity() const; + RID get_shader_rid() const; virtual Shader::Mode get_shader_mode() const override; @@ -307,5 +351,6 @@ public: VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) VARIANT_ENUM_CAST(ParticlesMaterial::Flags) VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) +VARIANT_ENUM_CAST(ParticlesMaterial::SubEmitterMode) #endif // PARTICLES_MATERIAL_H diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp index 2a5cd1101a..59bf8c0e13 100644 --- a/scene/resources/physics_material.cpp +++ b/scene/resources/physics_material.cpp @@ -43,9 +43,9 @@ void PhysicsMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_absorbent", "absorbent"), &PhysicsMaterial::set_absorbent); ClassDB::bind_method(D_METHOD("is_absorbent"), &PhysicsMaterial::is_absorbent); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction"), "set_friction", "get_friction"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_friction", "get_friction"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rough"), "set_rough", "is_rough"); - ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce"), "set_bounce", "get_bounce"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_bounce", "get_bounce"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "absorbent"), "set_absorbent", "is_absorbent"); } diff --git a/scene/resources/ray_shape_3d.cpp b/scene/resources/ray_shape_3d.cpp index 17205a500a..39df4c22f9 100644 --- a/scene/resources/ray_shape_3d.cpp +++ b/scene/resources/ray_shape_3d.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server_3d.h" -Vector<Vector3> RayShape3D::get_debug_mesh_lines() { +Vector<Vector3> RayShape3D::get_debug_mesh_lines() const { Vector<Vector3> points; points.push_back(Vector3()); points.push_back(Vector3(0, 0, get_length())); diff --git a/scene/resources/ray_shape_3d.h b/scene/resources/ray_shape_3d.h index 6d974a0a4c..a1a6702564 100644 --- a/scene/resources/ray_shape_3d.h +++ b/scene/resources/ray_shape_3d.h @@ -48,7 +48,7 @@ public: void set_slips_on_slope(bool p_active); bool get_slips_on_slope() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; RayShape3D(); diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 93db8b725f..ba39593690 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -572,7 +572,7 @@ Error ResourceLoaderText::load() { } } - if (progress) { + if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } } @@ -640,7 +640,7 @@ Error ResourceLoaderText::load() { return error; } else { error = OK; - if (progress) { + if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } @@ -674,7 +674,7 @@ Error ResourceLoaderText::load() { resource_current++; - if (progress) { + if (progress && resources_total > 0) { *progress = resource_current / float(resources_total); } @@ -1763,6 +1763,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } for (int i = 0; i < state->get_connection_count(); i++) { + if (i == 0) { + f->store_line(""); + } + String connstr = "[connection"; connstr += " signal=\"" + String(state->get_connection_signal(i)) + "\""; connstr += " from=\"" + String(state->get_connection_source(i).simplified()) + "\""; @@ -1786,7 +1790,10 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r Vector<NodePath> editable_instances = state->get_editable_instances(); for (int i = 0; i < editable_instances.size(); i++) { - f->store_line("\n[editable path=\"" + editable_instances[i].operator String() + "\"]"); + if (i == 0) { + f->store_line(""); + } + f->store_line("[editable path=\"" + editable_instances[i].operator String() + "\"]"); } } diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index 4249542567..92f0353abf 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -142,8 +142,6 @@ void Shader::_bind_methods() { ClassDB::bind_method(D_METHOD("has_param", "name"), &Shader::has_param); - //ClassDB::bind_method(D_METHOD("get_param_list"),&Shader::get_fragment_code); - ADD_PROPERTY(PropertyInfo(Variant::STRING, "code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_code", "get_code"); BIND_ENUM_CONSTANT(MODE_SPATIAL); diff --git a/scene/resources/shape_3d.h b/scene/resources/shape_3d.h index 8a78b41461..eb9607e3a6 100644 --- a/scene/resources/shape_3d.h +++ b/scene/resources/shape_3d.h @@ -56,7 +56,7 @@ public: virtual RID get_rid() const override { return shape; } Ref<ArrayMesh> get_debug_mesh(); - virtual Vector<Vector3> get_debug_mesh_lines() = 0; // { return Vector<Vector3>(); } + virtual Vector<Vector3> get_debug_mesh_lines() const = 0; // { return Vector<Vector3>(); } /// Returns the radius of a sphere that fully enclose this shape virtual real_t get_enclosing_radius() const = 0; diff --git a/scene/resources/sphere_shape_3d.cpp b/scene/resources/sphere_shape_3d.cpp index d24998ff18..fd33387df6 100644 --- a/scene/resources/sphere_shape_3d.cpp +++ b/scene/resources/sphere_shape_3d.cpp @@ -31,7 +31,7 @@ #include "sphere_shape_3d.h" #include "servers/physics_server_3d.h" -Vector<Vector3> SphereShape3D::get_debug_mesh_lines() { +Vector<Vector3> SphereShape3D::get_debug_mesh_lines() const { float r = get_radius(); Vector<Vector3> points; diff --git a/scene/resources/sphere_shape_3d.h b/scene/resources/sphere_shape_3d.h index 78d45b5058..5cad67aea5 100644 --- a/scene/resources/sphere_shape_3d.h +++ b/scene/resources/sphere_shape_3d.h @@ -46,7 +46,7 @@ public: void set_radius(float p_radius); float get_radius() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override; SphereShape3D(); diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index eb65f10ec9..cdb0ec5111 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -245,6 +245,7 @@ void StyleBoxTexture::set_region_rect(const Rect2 &p_region_rect) { region_rect = p_region_rect; emit_changed(); + _change_notify("region"); } Rect2 StyleBoxTexture::get_region_rect() const { @@ -910,7 +911,7 @@ void StyleBoxFlat::_bind_methods() { ADD_GROUP("Shadow", "shadow_"); ADD_PROPERTY(PropertyInfo(Variant::COLOR, "shadow_color"), "set_shadow_color", "get_shadow_color"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size"), "set_shadow_size", "get_shadow_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_size", PROPERTY_HINT_RANGE, "0,100,1,or_greater"), "set_shadow_size", "get_shadow_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "shadow_offset"), "set_shadow_offset", "get_shadow_offset"); ADD_GROUP("Anti Aliasing", "anti_aliasing_"); diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 1a2dcc84bb..ff14a5a292 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -30,8 +30,6 @@ #include "surface_tool.h" -#include "core/method_bind_ext.gen.inc" - #define _VERTEX_SNAP 0.0001 #define EQ_VERTEX_DIST 0.00001 diff --git a/scene/resources/syntax_highlighter.cpp b/scene/resources/syntax_highlighter.cpp index abf7235fd6..e7b49892d8 100644 --- a/scene/resources/syntax_highlighter.cpp +++ b/scene/resources/syntax_highlighter.cpp @@ -53,13 +53,13 @@ Dictionary SyntaxHighlighter::get_line_syntax_highlighting(int p_line) { return color_map; } -void SyntaxHighlighter::_line_edited_from(int p_line) { +void SyntaxHighlighter::_lines_edited_from(int p_from_line, int p_to_line) { if (highlighting_cache.size() < 1) { return; } int cache_size = highlighting_cache.back()->key(); - for (int i = p_line - 1; i <= cache_size; i++) { + for (int i = MIN(p_from_line, p_to_line) - 1; i <= cache_size; i++) { if (highlighting_cache.has(i)) { highlighting_cache.erase(i); } @@ -93,7 +93,7 @@ void SyntaxHighlighter::update_cache() { void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) { if (text_edit && ObjectDB::get_instance(text_edit_instance_id)) { - text_edit->disconnect("line_edited_from", callable_mp(this, &SyntaxHighlighter::_line_edited_from)); + text_edit->disconnect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from)); } text_edit = p_text_edit; @@ -101,7 +101,7 @@ void SyntaxHighlighter::set_text_edit(TextEdit *p_text_edit) { return; } text_edit_instance_id = text_edit->get_instance_id(); - text_edit->connect("line_edited_from", callable_mp(this, &SyntaxHighlighter::_line_edited_from)); + text_edit->connect("lines_edited_from", callable_mp(this, &SyntaxHighlighter::_lines_edited_from)); update_cache(); } @@ -125,11 +125,11 @@ void SyntaxHighlighter::_bind_methods() { //////////////////////////////////////////////////////////////////////////////// -static bool _is_char(CharType c) { +static bool _is_char(char32_t c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; } -static bool _is_hex_symbol(CharType c) { +static bool _is_hex_symbol(char32_t c) { return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); } @@ -149,6 +149,13 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { color_region_cache[p_line] = -1; int in_region = -1; if (p_line != 0) { + int prev_region_line = p_line - 1; + while (prev_region_line > 0 && !color_region_cache.has(prev_region_line)) { + prev_region_line--; + } + for (int i = prev_region_line; i < p_line - 1; i++) { + get_line_syntax_highlighting(i); + } if (!color_region_cache.has(p_line - 1)) { get_line_syntax_highlighting(p_line - 1); } @@ -158,6 +165,10 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { const String &str = text_edit->get_line(p_line); const int line_length = str.length(); Color prev_color; + + if (in_region != -1 && str.length() == 0) { + color_region_cache[p_line] = in_region; + } for (int j = 0; j < line_length; j++) { Dictionary highlighter_info; @@ -191,7 +202,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { /* search the line */ bool match = true; - const CharType *start_key = color_regions[c].start_key.c_str(); + const char32_t *start_key = color_regions[c].start_key.get_data(); for (int k = 0; k < start_key_length; k++) { if (start_key[k] != str[from + k]) { match = false; @@ -225,18 +236,16 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { /* if we are in one find the end key */ if (in_region != -1) { - /* check there is enough room */ - int chars_left = line_length - from; - int end_key_length = color_regions[in_region].end_key.length(); - if (chars_left < end_key_length) { - continue; - } - /* search the line */ int region_end_index = -1; - const CharType *end_key = color_regions[in_region].start_key.c_str(); + int end_key_length = color_regions[in_region].end_key.length(); + const char32_t *end_key = color_regions[in_region].end_key.get_data(); for (; from < line_length; from++) { - if (!is_a_symbol) { + if (line_length - from < end_key_length) { + break; + } + + if (!is_symbol(str[from])) { continue; } @@ -245,9 +254,10 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { continue; } + region_end_index = from; for (int k = 0; k < end_key_length; k++) { - if (end_key[k] == str[from + k]) { - region_end_index = from; + if (end_key[k] != str[from + k]) { + region_end_index = -1; break; } } @@ -261,7 +271,7 @@ Dictionary CodeHighlighter::_get_line_syntax_highlighting(int p_line) { highlighter_info["color"] = color_regions[in_region].color; color_map[j] = highlighter_info; - j = from; + j = from + (end_key_length - 1); if (region_end_index == -1) { color_region_cache[p_line] = in_region; } @@ -480,16 +490,20 @@ void CodeHighlighter::add_color_region(const String &p_start_key, const String & } } + int at = 0; for (int i = 0; i < color_regions.size(); i++) { ERR_FAIL_COND_MSG(color_regions[i].start_key == p_start_key, "color region with start key '" + p_start_key + "' already exists."); + if (p_start_key.length() < color_regions[i].start_key.length()) { + at++; + } } ColorRegion color_region; color_region.color = p_color; color_region.start_key = p_start_key; color_region.end_key = p_end_key; - color_region.line_only = p_line_only; - color_regions.push_back(color_region); + color_region.line_only = p_line_only || p_end_key == ""; + color_regions.insert(at, color_region); clear_highlighting_cache(); } diff --git a/scene/resources/syntax_highlighter.h b/scene/resources/syntax_highlighter.h index 40a8870b45..720227a256 100644 --- a/scene/resources/syntax_highlighter.h +++ b/scene/resources/syntax_highlighter.h @@ -40,7 +40,7 @@ class SyntaxHighlighter : public Resource { private: Map<int, Dictionary> highlighting_cache; - void _line_edited_from(int p_line); + void _lines_edited_from(int p_from_line, int p_to_line); protected: ObjectID text_edit_instance_id; // For validity check diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 5681613c04..6291d2dddb 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -32,7 +32,6 @@ #include "core/core_string_names.h" #include "core/io/image_loader.h" -#include "core/method_bind_ext.gen.inc" #include "core/os/os.h" #include "mesh.h" #include "scene/resources/bit_map.h" @@ -791,8 +790,312 @@ String ResourceFormatLoaderStreamTexture2D::get_resource_type(const String &p_pa return ""; } +//////////////////////////////////// + +TypedArray<Image> Texture3D::_get_data() const { + Vector<Ref<Image>> data = get_data(); + + TypedArray<Image> ret; + ret.resize(data.size()); + for (int i = 0; i < data.size(); i++) { + ret[i] = data[i]; + } + return ret; +} + +void Texture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_format"), &Texture3D::get_format); + ClassDB::bind_method(D_METHOD("get_width"), &Texture3D::get_width); + ClassDB::bind_method(D_METHOD("get_height"), &Texture3D::get_height); + ClassDB::bind_method(D_METHOD("get_depth"), &Texture3D::get_depth); + ClassDB::bind_method(D_METHOD("has_mipmaps"), &Texture3D::has_mipmaps); + ClassDB::bind_method(D_METHOD("get_data"), &Texture3D::_get_data); +} ////////////////////////////////////////// +Image::Format ImageTexture3D::get_format() const { + return format; +} +int ImageTexture3D::get_width() const { + return width; +} +int ImageTexture3D::get_height() const { + return height; +} +int ImageTexture3D::get_depth() const { + return depth; +} +bool ImageTexture3D::has_mipmaps() const { + return mipmaps; +} + +Error ImageTexture3D::_create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data) { + Vector<Ref<Image>> images; + images.resize(p_data.size()); + for (int i = 0; i < images.size(); i++) { + images.write[i] = p_data[i]; + } + return create(p_format, p_width, p_height, p_depth, p_mipmaps, images); +} + +void ImageTexture3D::_update(const TypedArray<Image> &p_data) { + Vector<Ref<Image>> images; + images.resize(p_data.size()); + for (int i = 0; i < images.size(); i++) { + images.write[i] = p_data[i]; + } + return update(images); +} + +Error ImageTexture3D::create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data) { + RID tex = RenderingServer::get_singleton()->texture_3d_create(p_format, p_width, p_height, p_depth, p_mipmaps, p_data); + ERR_FAIL_COND_V(tex.is_null(), ERR_CANT_CREATE); + + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_replace(texture, tex); + } + + return OK; +} + +void ImageTexture3D::update(const Vector<Ref<Image>> &p_data) { + ERR_FAIL_COND(!texture.is_valid()); + RenderingServer::get_singleton()->texture_3d_update(texture, p_data); +} + +Vector<Ref<Image>> ImageTexture3D::get_data() const { + ERR_FAIL_COND_V(!texture.is_valid(), Vector<Ref<Image>>()); + return RS::get_singleton()->texture_3d_get(texture); +} + +RID ImageTexture3D::get_rid() const { + if (!texture.is_valid()) { + texture = RS::get_singleton()->texture_3d_placeholder_create(); + } + return texture; +} +void ImageTexture3D::set_path(const String &p_path, bool p_take_over) { + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + Resource::set_path(p_path, p_take_over); +} + +void ImageTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("create", "format", "width", "height", "depth", "use_mipmaps", "data"), &ImageTexture3D::_create); + ClassDB::bind_method(D_METHOD("update", "data"), &ImageTexture3D::_update); +} + +ImageTexture3D::ImageTexture3D() { +} + +ImageTexture3D::~ImageTexture3D() { + if (texture.is_valid()) { + RS::get_singleton()->free(texture); + } +} + +//////////////////////////////////////////// + +void StreamTexture3D::set_path(const String &p_path, bool p_take_over) { + if (texture.is_valid()) { + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + Resource::set_path(p_path, p_take_over); +} + +Image::Format StreamTexture3D::get_format() const { + return format; +} + +Error StreamTexture3D::_load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps) { + FileAccessRef f = FileAccess::open(p_path, FileAccess::READ); + ERR_FAIL_COND_V(!f, ERR_CANT_OPEN); + + uint8_t header[4]; + f->get_buffer(header, 4); + ERR_FAIL_COND_V(header[0] != 'G' || header[1] != 'S' || header[2] != 'T' || header[3] != 'L', ERR_FILE_UNRECOGNIZED); + + //stored as stream textures (used for lossless and lossy compression) + uint32_t version = f->get_32(); + + if (version > FORMAT_VERSION) { + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Stream texture file is too new."); + } + + r_depth = f->get_32(); //depth + f->get_32(); //ignored (mode) + f->get_32(); // ignored (data format) + + f->get_32(); //ignored + int mipmaps = f->get_32(); + f->get_32(); //ignored + f->get_32(); //ignored + + r_mipmaps = mipmaps != 0; + + r_data.clear(); + + for (int i = 0; i < (r_depth + mipmaps); i++) { + Ref<Image> image = StreamTexture2D::load_image_from_file(f, 0); + ERR_FAIL_COND_V(image.is_null() || image->empty(), ERR_CANT_OPEN); + if (i == 0) { + r_format = image->get_format(); + r_width = image->get_width(); + r_height = image->get_height(); + } + r_data.push_back(image); + } + + return OK; +} + +Error StreamTexture3D::load(const String &p_path) { + Vector<Ref<Image>> data; + + int tw, th, td; + Image::Format tfmt; + bool tmm; + + Error err = _load_data(p_path, data, tfmt, tw, th, td, tmm); + if (err) { + return err; + } + + if (texture.is_valid()) { + RID new_texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data); + RS::get_singleton()->texture_replace(texture, new_texture); + } else { + texture = RS::get_singleton()->texture_3d_create(tfmt, tw, th, td, tmm, data); + } + + w = tw; + h = th; + d = td; + mipmaps = tmm; + format = tfmt; + + path_to_file = p_path; + + if (get_path() == String()) { + //temporarily set path if no path set for resource, helps find errors + RenderingServer::get_singleton()->texture_set_path(texture, p_path); + } + + _change_notify(); + emit_changed(); + return OK; +} + +String StreamTexture3D::get_load_path() const { + return path_to_file; +} + +int StreamTexture3D::get_width() const { + return w; +} + +int StreamTexture3D::get_height() const { + return h; +} + +int StreamTexture3D::get_depth() const { + return d; +} + +bool StreamTexture3D::has_mipmaps() const { + return mipmaps; +} + +RID StreamTexture3D::get_rid() const { + if (!texture.is_valid()) { + texture = RS::get_singleton()->texture_3d_placeholder_create(); + } + return texture; +} + +Vector<Ref<Image>> StreamTexture3D::get_data() const { + if (texture.is_valid()) { + return RS::get_singleton()->texture_3d_get(texture); + } else { + return Vector<Ref<Image>>(); + } +} + +void StreamTexture3D::reload_from_file() { + String path = get_path(); + if (!path.is_resource_file()) { + return; + } + + path = ResourceLoader::path_remap(path); //remap for translation + path = ResourceLoader::import_remap(path); //remap for import + if (!path.is_resource_file()) { + return; + } + + load(path); +} + +void StreamTexture3D::_validate_property(PropertyInfo &property) const { +} + +void StreamTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("load", "path"), &StreamTexture3D::load); + ClassDB::bind_method(D_METHOD("get_load_path"), &StreamTexture3D::get_load_path); + + ADD_PROPERTY(PropertyInfo(Variant::STRING, "load_path", PROPERTY_HINT_FILE, "*.stex"), "load", "get_load_path"); +} + +StreamTexture3D::StreamTexture3D() { + format = Image::FORMAT_MAX; + w = 0; + h = 0; + d = 0; + mipmaps = false; +} + +StreamTexture3D::~StreamTexture3D() { + if (texture.is_valid()) { + RS::get_singleton()->free(texture); + } +} + +///////////////////////////// + +RES ResourceFormatLoaderStreamTexture3D::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) { + Ref<StreamTexture3D> st; + st.instance(); + Error err = st->load(p_path); + if (r_error) { + *r_error = err; + } + if (err != OK) { + return RES(); + } + + return st; +} + +void ResourceFormatLoaderStreamTexture3D::get_recognized_extensions(List<String> *p_extensions) const { + p_extensions->push_back("stex3d"); +} + +bool ResourceFormatLoaderStreamTexture3D::handles_type(const String &p_type) const { + return p_type == "StreamTexture3D"; +} + +String ResourceFormatLoaderStreamTexture3D::get_resource_type(const String &p_path) const { + if (p_path.get_extension().to_lower() == "stex3d") { + return "StreamTexture3D"; + } + return ""; +} + +//////////////////////////////////////////// + int AtlasTexture::get_width() const { if (region.size.width == 0) { if (atlas.is_valid()) { diff --git a/scene/resources/texture.h b/scene/resources/texture.h index d439d34c95..eebbf4f233 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -515,6 +515,122 @@ public: virtual String get_resource_type(const String &p_path) const; }; +class Texture3D : public Texture { + GDCLASS(Texture3D, Texture); + +protected: + static void _bind_methods(); + + TypedArray<Image> _get_data() const; + +public: + virtual Image::Format get_format() const = 0; + virtual int get_width() const = 0; + virtual int get_height() const = 0; + virtual int get_depth() const = 0; + virtual bool has_mipmaps() const = 0; + virtual Vector<Ref<Image>> get_data() const = 0; +}; + +class ImageTexture3D : public Texture3D { + GDCLASS(ImageTexture3D, Texture3D); + + mutable RID texture; + + Image::Format format = Image::FORMAT_MAX; + int width = 1; + int height = 1; + int depth = 1; + bool mipmaps = false; + +protected: + static void _bind_methods(); + + Error _create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const TypedArray<Image> &p_data); + void _update(const TypedArray<Image> &p_data); + +public: + virtual Image::Format get_format() const override; + virtual int get_width() const override; + virtual int get_height() const override; + virtual int get_depth() const override; + virtual bool has_mipmaps() const override; + + Error create(Image::Format p_format, int p_width, int p_height, int p_depth, bool p_mipmaps, const Vector<Ref<Image>> &p_data); + void update(const Vector<Ref<Image>> &p_data); + virtual Vector<Ref<Image>> get_data() const override; + + virtual RID get_rid() const override; + virtual void set_path(const String &p_path, bool p_take_over = false) override; + + ImageTexture3D(); + ~ImageTexture3D(); +}; + +class StreamTexture3D : public Texture3D { + GDCLASS(StreamTexture3D, Texture3D); + +public: + enum DataFormat { + DATA_FORMAT_IMAGE, + DATA_FORMAT_LOSSLESS, + DATA_FORMAT_LOSSY, + DATA_FORMAT_BASIS_UNIVERSAL, + }; + + enum { + FORMAT_VERSION = 1 + }; + + enum FormatBits { + FORMAT_MASK_IMAGE_FORMAT = (1 << 20) - 1, + FORMAT_BIT_LOSSLESS = 1 << 20, + FORMAT_BIT_LOSSY = 1 << 21, + FORMAT_BIT_STREAM = 1 << 22, + FORMAT_BIT_HAS_MIPMAPS = 1 << 23, + }; + +private: + Error _load_data(const String &p_path, Vector<Ref<Image>> &r_data, Image::Format &r_format, int &r_width, int &r_height, int &r_depth, bool &r_mipmaps); + String path_to_file; + mutable RID texture; + Image::Format format; + int w, h, d; + bool mipmaps; + + virtual void reload_from_file() override; + +protected: + static void _bind_methods(); + void _validate_property(PropertyInfo &property) const override; + +public: + Image::Format get_format() const override; + Error load(const String &p_path); + String get_load_path() const; + + int get_width() const override; + int get_height() const override; + int get_depth() const override; + virtual bool has_mipmaps() const override; + virtual RID get_rid() const override; + + virtual void set_path(const String &p_path, bool p_take_over) override; + + virtual Vector<Ref<Image>> get_data() const override; + + StreamTexture3D(); + ~StreamTexture3D(); +}; + +class ResourceFormatLoaderStreamTexture3D : 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(List<String> *p_extensions) const; + virtual bool handles_type(const String &p_type) const; + virtual String get_resource_type(const String &p_path) const; +}; + class CurveTexture : public Texture2D { GDCLASS(CurveTexture, Texture2D); RES_BASE_EXTENSION("curvetex") @@ -632,11 +748,12 @@ class AnimatedTexture : public Texture2D { //use readers writers lock for this, since its far more times read than written to RWLock *rw_lock; -private: +public: enum { MAX_FRAMES = 256 }; +private: RID proxy_ph; RID proxy; diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index 6992360df7..84b067d1e2 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -40,7 +40,7 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { if (slash == -1) { return false; } - int id = String::to_int(n.c_str(), slash); + int id = String::to_int(n.get_data(), slash); if (!tile_map.has(id)) { create_tile(id); @@ -216,7 +216,7 @@ bool TileSet::_get(const StringName &p_name, Variant &r_ret) const { if (slash == -1) { return false; } - int id = String::to_int(n.c_str(), slash); + int id = String::to_int(n.get_data(), slash); ERR_FAIL_COND_V(!tile_map.has(id), false); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 8236f9a9e3..81851a9127 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -63,6 +63,48 @@ bool VisualShaderNode::is_port_separator(int p_index) const { return false; } +bool VisualShaderNode::is_output_port_connected(int p_port) const { + if (connected_output_ports.has(p_port)) { + return connected_output_ports[p_port] > 0; + } + return false; +} + +void VisualShaderNode::set_output_port_connected(int p_port, bool p_connected) { + if (p_connected) { + connected_output_ports[p_port]++; + } else { + connected_output_ports[p_port]--; + } +} + +bool VisualShaderNode::is_input_port_connected(int p_port) const { + if (connected_input_ports.has(p_port)) { + return connected_input_ports[p_port]; + } + return false; +} + +void VisualShaderNode::set_input_port_connected(int p_port, bool p_connected) { + connected_input_ports[p_port] = p_connected; +} + +bool VisualShaderNode::is_generate_input_var(int p_port) const { + return true; +} + +bool VisualShaderNode::is_code_generated() const { + return true; +} + +bool VisualShaderNode::is_show_prop_names() const { + return false; +} + +bool VisualShaderNode::is_use_prop_slots() const { + return false; +} + Vector<VisualShader::DefaultTextureParam> VisualShaderNode::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { return Vector<VisualShader::DefaultTextureParam>(); } @@ -134,8 +176,6 @@ void VisualShaderNode::_bind_methods() { } VisualShaderNode::VisualShaderNode() { - port_preview = -1; - simple_decl = true; } ///////////////////////////////////////////////////////// @@ -281,6 +321,14 @@ VisualShaderNodeCustom::VisualShaderNodeCustom() { ///////////////////////////////////////////////////////// +void VisualShader::set_shader_type(Type p_type) { + current_type = p_type; +} + +VisualShader::Type VisualShader::get_shader_type() const { + return current_type; +} + void VisualShader::set_version(const String &p_version) { version = p_version; } @@ -429,6 +477,7 @@ void VisualShader::remove_node(Type p_type, int p_id) { g->connections.erase(E); if (E->get().from_node == p_id) { g->nodes[E->get().to_node].prev_connected_nodes.erase(p_id); + g->nodes[E->get().to_node].node->set_input_port_connected(E->get().to_port, false); } } E = N; @@ -526,6 +575,8 @@ void VisualShader::connect_nodes_forced(Type p_type, int p_from_node, int p_from c.to_port = p_to_port; g->connections.push_back(c); g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node); + g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true); + g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true); _queue_update(); } @@ -557,6 +608,8 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, c.to_port = p_to_port; g->connections.push_back(c); g->nodes[p_to_node].prev_connected_nodes.push_back(p_from_node); + g->nodes[p_from_node].node->set_output_port_connected(p_from_port, true); + g->nodes[p_to_node].node->set_input_port_connected(p_to_port, true); _queue_update(); return OK; @@ -570,6 +623,8 @@ void VisualShader::disconnect_nodes(Type p_type, int p_from_node, int p_from_por if (E->get().from_node == p_from_node && E->get().from_port == p_from_port && E->get().to_node == p_to_node && E->get().to_port == p_to_port) { g->connections.erase(E); g->nodes[p_to_node].prev_connected_nodes.erase(p_from_node); + g->nodes[p_from_node].node->set_output_port_connected(p_from_port, false); + g->nodes[p_to_node].node->set_input_port_connected(p_to_port, false); _queue_update(); return; } @@ -875,8 +930,12 @@ VisualShader::RenderModeEnums VisualShader::render_mode_enums[] = { static const char *type_string[VisualShader::TYPE_MAX] = { "vertex", "fragment", - "light" + "light", + "emit", + "process", + "end" }; + bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { String name = p_name; if (name == "mode") { @@ -933,7 +992,7 @@ bool VisualShader::_set(const StringName &p_name, const Variant &p_value) { set_node_position(type, id, p_value); return true; } else if (what == "size") { - ((VisualShaderNodeGroupBase *)get_node(type, id).ptr())->set_size(p_value); + ((VisualShaderNodeResizableBase *)get_node(type, id).ptr())->set_size(p_value); return true; } else if (what == "input_ports") { ((VisualShaderNodeGroupBase *)get_node(type, id).ptr())->set_inputs(p_value); @@ -1000,7 +1059,7 @@ bool VisualShader::_get(const StringName &p_name, Variant &r_ret) const { r_ret = get_node_position(type, id); return true; } else if (what == "size") { - r_ret = ((VisualShaderNodeGroupBase *)get_node(type, id).ptr())->get_size(); + r_ret = ((VisualShaderNodeResizableBase *)get_node(type, id).ptr())->get_size(); return true; } else if (what == "input_ports") { r_ret = ((VisualShaderNodeGroupBase *)get_node(type, id).ptr())->get_inputs(); @@ -1105,6 +1164,38 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui // then this node + Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node); + for (int i = 0; i < params.size(); i++) { + def_tex_params.push_back(params[i]); + } + + Ref<VisualShaderNodeInput> input = vsnode; + bool skip_global = input.is_valid() && for_preview; + + if (!skip_global) { + Ref<VisualShaderNodeUniform> uniform = vsnode; + if (!uniform.is_valid() || !uniform->is_global_code_generated()) { + global_code += vsnode->generate_global(get_mode(), type, node); + } + + String class_name = vsnode->get_class_name(); + if (class_name == "VisualShaderNodeCustom") { + class_name = vsnode->get_script_instance()->get_script()->get_path(); + } + if (!r_classes.has(class_name)) { + global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node); + for (int i = 0; i < TYPE_MAX; i++) { + global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); + } + r_classes.insert(class_name); + } + } + + if (!vsnode->is_code_generated()) { // just generate globals and ignore locals + processed.insert(node); + return OK; + } + code += "// " + vsnode->get_caption() + ":" + itos(node) + "\n"; Vector<String> input_vars; @@ -1163,6 +1254,10 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui inputs[i] = "int(" + src_var + ")"; } } else { + if (!vsnode->is_generate_input_var(i)) { + continue; + } + Variant defval = vsnode->get_input_port_default_value(i); if (defval.get_type() == Variant::FLOAT) { float val = defval; @@ -1255,36 +1350,25 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } } - Vector<VisualShader::DefaultTextureParam> params = vsnode->get_default_texture_parameters(type, node); - for (int i = 0; i < params.size(); i++) { - def_tex_params.push_back(params[i]); - } + code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); - Ref<VisualShaderNodeInput> input = vsnode; - bool skip_global = input.is_valid() && for_preview; + code += "\n"; // + processed.insert(node); - if (!skip_global) { - global_code += vsnode->generate_global(get_mode(), type, node); + return OK; +} - String class_name = vsnode->get_class_name(); - if (class_name == "VisualShaderNodeCustom") { - class_name = vsnode->get_script_instance()->get_script()->get_path(); - } - if (!r_classes.has(class_name)) { - global_code_per_node += vsnode->generate_global_per_node(get_mode(), type, node); - for (int i = 0; i < TYPE_MAX; i++) { - global_code_per_func[Type(i)] += vsnode->generate_global_per_func(get_mode(), Type(i), node); +bool VisualShader::has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const { + if (!ShaderTypes::get_singleton()->get_functions(p_mode).has(p_func_name)) { + if (p_mode == RenderingServer::ShaderMode::SHADER_PARTICLES) { + if (p_func_name == "emit" || p_func_name == "process" || p_func_name == "end") { + return true; } - r_classes.insert(class_name); } + return false; } - code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); - - code += "\n"; // - processed.insert(node); - - return OK; + return true; } void VisualShader::_update_shader() const { @@ -1310,10 +1394,19 @@ void VisualShader::_update_shader() const { { //fill render mode enums int idx = 0; + bool specular = false; while (render_mode_enums[idx].string) { if (shader_mode == render_mode_enums[idx].mode) { - if (modes.has(render_mode_enums[idx].string)) { - int which = modes[render_mode_enums[idx].string]; + if (shader_mode == Shader::MODE_SPATIAL) { + if (String(render_mode_enums[idx].string) == "specular") { + specular = true; + } + } + if (modes.has(render_mode_enums[idx].string) || specular) { + int which = 0; + if (modes.has(render_mode_enums[idx].string)) { + which = modes[render_mode_enums[idx].string]; + } int count = 0; for (int i = 0; i < ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode)).size(); i++) { String mode = ShaderTypes::get_singleton()->get_modes(RenderingServer::ShaderMode(shader_mode))[i]; @@ -1349,11 +1442,14 @@ void VisualShader::_update_shader() const { global_code += "render_mode " + render_mode + ";\n\n"; } - static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" }; + static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light", "emit", "process", "end" }; String global_expressions; + Set<String> used_uniform_names; + List<VisualShaderNodeUniform *> uniforms; + for (int i = 0, index = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } @@ -1367,11 +1463,31 @@ void VisualShader::_update_shader() const { expr += "\n"; global_expressions += expr; } + Ref<VisualShaderNodeUniformRef> uniform_ref = Object::cast_to<VisualShaderNodeUniformRef>(E->get().node.ptr()); + if (uniform_ref.is_valid()) { + used_uniform_names.insert(uniform_ref->get_uniform_name()); + } + Ref<VisualShaderNodeUniform> uniform = Object::cast_to<VisualShaderNodeUniform>(E->get().node.ptr()); + if (uniform.is_valid()) { + uniforms.push_back(uniform.ptr()); + } } } + for (int i = 0; i < uniforms.size(); i++) { + VisualShaderNodeUniform *uniform = uniforms[i]; + if (used_uniform_names.has(uniform->get_uniform_name())) { + global_code += uniform->generate_global(get_mode(), Type(i), -1); + const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(true); + } else { + const_cast<VisualShaderNodeUniform *>(uniform)->set_global_code_generated(false); + } + } + + Map<int, String> code_map; + for (int i = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } @@ -1379,6 +1495,8 @@ void VisualShader::_update_shader() const { VMap<ConnectionKey, const List<Connection>::Element *> input_connections; VMap<ConnectionKey, const List<Connection>::Element *> output_connections; + StringBuilder func_code; + for (const List<Connection>::Element *E = graph[i].connections.front(); E; E = E->next()) { ConnectionKey from_key; from_key.node = E->get().from_node; @@ -1392,14 +1510,30 @@ void VisualShader::_update_shader() const { input_connections.insert(to_key, E); } - - code += "\nvoid " + String(func_name[i]) + "() {\n"; + if (shader_mode != Shader::MODE_PARTICLES) { + func_code += "\nvoid " + String(func_name[i]) + "() {\n"; + } + insertion_pos.insert(i, code.get_string_length() + func_code.get_string_length()); Set<int> processed; - Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); + Error err = _write_node(Type(i), global_code, global_code_per_node, global_code_per_func, func_code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false, classes); ERR_FAIL_COND(err != OK); - insertion_pos.insert(i, code.get_string_length()); + if (shader_mode == Shader::MODE_PARTICLES) { + code_map.insert(i, func_code); + } else { + func_code += "}\n"; + code += func_code; + } + } + + if (shader_mode == Shader::MODE_PARTICLES) { + code += "\nvoid compute() {\n"; + code += "\tif (RESTART) {\n"; + code += code_map[TYPE_EMIT]; + code += "\t} else {\n"; + code += code_map[TYPE_PROCESS]; + code += "\t}\n"; code += "}\n"; } @@ -1410,7 +1544,7 @@ void VisualShader::_update_shader() const { final_code += global_expressions; String tcode = code; for (int i = 0; i < TYPE_MAX; i++) { - if (!ShaderTypes::get_singleton()->get_functions(RenderingServer::ShaderMode(shader_mode)).has(func_name[i])) { + if (!has_func_name(RenderingServer::ShaderMode(shader_mode), func_name[i])) { continue; } tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]); @@ -1489,9 +1623,14 @@ void VisualShader::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "graph_offset", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_graph_offset", "get_graph_offset"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_version", "get_version"); + ADD_PROPERTY_DEFAULT("code", ""); // Inherited from Shader, prevents showing default code as override in docs. + BIND_ENUM_CONSTANT(TYPE_VERTEX); BIND_ENUM_CONSTANT(TYPE_FRAGMENT); BIND_ENUM_CONSTANT(TYPE_LIGHT); + BIND_ENUM_CONSTANT(TYPE_EMIT); + BIND_ENUM_CONSTANT(TYPE_PROCESS); + BIND_ENUM_CONSTANT(TYPE_END); BIND_ENUM_CONSTANT(TYPE_MAX); BIND_CONSTANT(NODE_ID_INVALID); @@ -1499,8 +1638,6 @@ void VisualShader::_bind_methods() { } VisualShader::VisualShader() { - shader_mode = Shader::MODE_SPATIAL; - for (int i = 0; i < TYPE_MAX; i++) { Ref<VisualShaderNodeOutput> output; output.instance(); @@ -1509,8 +1646,6 @@ VisualShader::VisualShader() { graph[i].nodes[NODE_ID_OUTPUT].node = output; graph[i].nodes[NODE_ID_OUTPUT].position = Vector2(400, 150); } - - dirty = true; } /////////////////////////////////////////////////////////// @@ -1577,6 +1712,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { 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" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "metallic", "METALLIC" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "world", "WORLD_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_camera", "INV_CAMERA_MATRIX" }, @@ -1633,22 +1769,50 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { 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" }, - // Particles, Vertex - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, - - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, - - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + // Particles, Emit + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, Process + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, + + // Particles, End + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "restart", "float(RESTART ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "active", "float(ACTIVE ? 1.0 : 0.0)" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "delta", "DELTA" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "lifetime", "LIFETIME" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR_INT, "index", "INDEX" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "emission_transform", "EMISSION_TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, // Sky, Fragment { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "at_cubemap_pass", "AT_CUBEMAP_PASS" }, @@ -1950,10 +2114,218 @@ void VisualShaderNodeInput::_bind_methods() { } VisualShaderNodeInput::VisualShaderNodeInput() { - input_name = "[None]"; - // changed when set - shader_type = VisualShader::TYPE_MAX; - shader_mode = Shader::MODE_MAX; +} + +////////////// UniformRef + +List<VisualShaderNodeUniformRef::Uniform> uniforms; + +void VisualShaderNodeUniformRef::add_uniform(const String &p_name, UniformType p_type) { + uniforms.push_back({ p_name, p_type }); +} + +void VisualShaderNodeUniformRef::clear_uniforms() { + uniforms.clear(); +} + +bool VisualShaderNodeUniformRef::has_uniform(const String &p_name) { + for (List<VisualShaderNodeUniformRef::Uniform>::Element *E = uniforms.front(); E; E = E->next()) { + if (E->get().name == p_name) { + return true; + } + } + return false; +} + +String VisualShaderNodeUniformRef::get_caption() const { + return "UniformRef"; +} + +int VisualShaderNodeUniformRef::get_input_port_count() const { + return 0; +} + +VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_input_port_type(int p_port) const { + return PortType::PORT_TYPE_SCALAR; +} + +String VisualShaderNodeUniformRef::get_input_port_name(int p_port) const { + return ""; +} + +int VisualShaderNodeUniformRef::get_output_port_count() const { + switch (uniform_type) { + case UniformType::UNIFORM_TYPE_FLOAT: + return 1; + case UniformType::UNIFORM_TYPE_INT: + return 1; + case UniformType::UNIFORM_TYPE_BOOLEAN: + return 1; + case UniformType::UNIFORM_TYPE_VECTOR: + return 1; + case UniformType::UNIFORM_TYPE_TRANSFORM: + return 1; + case UniformType::UNIFORM_TYPE_COLOR: + return 2; + case UniformType::UNIFORM_TYPE_SAMPLER: + return 1; + default: + break; + } + return 1; +} + +VisualShaderNodeUniformRef::PortType VisualShaderNodeUniformRef::get_output_port_type(int p_port) const { + switch (uniform_type) { + case UniformType::UNIFORM_TYPE_FLOAT: + return PortType::PORT_TYPE_SCALAR; + case UniformType::UNIFORM_TYPE_INT: + return PortType::PORT_TYPE_SCALAR_INT; + case UniformType::UNIFORM_TYPE_BOOLEAN: + return PortType::PORT_TYPE_BOOLEAN; + case UniformType::UNIFORM_TYPE_VECTOR: + return PortType::PORT_TYPE_VECTOR; + case UniformType::UNIFORM_TYPE_TRANSFORM: + return PortType::PORT_TYPE_TRANSFORM; + case UniformType::UNIFORM_TYPE_COLOR: + if (p_port == 0) { + return PortType::PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_SCALAR; + } + break; + case UniformType::UNIFORM_TYPE_SAMPLER: + return PortType::PORT_TYPE_SAMPLER; + default: + break; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeUniformRef::get_output_port_name(int p_port) const { + switch (uniform_type) { + case UniformType::UNIFORM_TYPE_FLOAT: + return ""; + case UniformType::UNIFORM_TYPE_INT: + return ""; + case UniformType::UNIFORM_TYPE_BOOLEAN: + return ""; + case UniformType::UNIFORM_TYPE_VECTOR: + return ""; + case UniformType::UNIFORM_TYPE_TRANSFORM: + return ""; + case UniformType::UNIFORM_TYPE_COLOR: + if (p_port == 0) { + return "rgb"; + } else if (p_port == 1) { + return "alpha"; + } + break; + case UniformType::UNIFORM_TYPE_SAMPLER: + return ""; + break; + default: + break; + } + return ""; +} + +void VisualShaderNodeUniformRef::set_uniform_name(const String &p_name) { + uniform_name = p_name; + if (uniform_name != "[None]") { + uniform_type = get_uniform_type_by_name(uniform_name); + } else { + uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + } + emit_changed(); +} + +String VisualShaderNodeUniformRef::get_uniform_name() const { + return uniform_name; +} + +int VisualShaderNodeUniformRef::get_uniforms_count() const { + return uniforms.size(); +} + +String VisualShaderNodeUniformRef::get_uniform_name_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < uniforms.size()) { + return uniforms[p_idx].name; + } + return ""; +} + +VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_name(const String &p_name) const { + for (int i = 0; i < uniforms.size(); i++) { + if (uniforms[i].name == p_name) { + return uniforms[i].type; + } + } + return UniformType::UNIFORM_TYPE_FLOAT; +} + +VisualShaderNodeUniformRef::UniformType VisualShaderNodeUniformRef::get_uniform_type_by_index(int p_idx) const { + if (p_idx >= 0 && p_idx < uniforms.size()) { + return uniforms[p_idx].type; + } + return UniformType::UNIFORM_TYPE_FLOAT; +} + +String VisualShaderNodeUniformRef::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + switch (uniform_type) { + case UniformType::UNIFORM_TYPE_FLOAT: + if (uniform_name == "[None]") { + return "\t" + p_output_vars[0] + " = 0.0;\n"; + } + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + case UniformType::UNIFORM_TYPE_INT: + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + case UniformType::UNIFORM_TYPE_BOOLEAN: + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + case UniformType::UNIFORM_TYPE_VECTOR: + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + case UniformType::UNIFORM_TYPE_TRANSFORM: + return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; + case UniformType::UNIFORM_TYPE_COLOR: { + String code = "\t" + p_output_vars[0] + " = " + get_uniform_name() + ".rgb;\n"; + code += "\t" + p_output_vars[1] + " = " + get_uniform_name() + ".a;\n"; + return code; + } break; + case UniformType::UNIFORM_TYPE_SAMPLER: + break; + default: + break; + } + return ""; +} + +void VisualShaderNodeUniformRef::_set_uniform_type(int p_uniform_type) { + uniform_type = (UniformType)p_uniform_type; +} + +int VisualShaderNodeUniformRef::_get_uniform_type() const { + return (int)uniform_type; +} + +void VisualShaderNodeUniformRef::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniformRef::set_uniform_name); + ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniformRef::get_uniform_name); + + ClassDB::bind_method(D_METHOD("_set_uniform_type", "type"), &VisualShaderNodeUniformRef::_set_uniform_type); + ClassDB::bind_method(D_METHOD("_get_uniform_type"), &VisualShaderNodeUniformRef::_get_uniform_type); + + ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "uniform_name", PROPERTY_HINT_ENUM, ""), "set_uniform_name", "get_uniform_name"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "uniform_type", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_uniform_type", "_get_uniform_type"); +} + +Vector<StringName> VisualShaderNodeUniformRef::get_editable_properties() const { + Vector<StringName> props; + props.push_back("uniform_name"); + props.push_back("uniform_type"); + return props; +} + +VisualShaderNodeUniformRef::VisualShaderNodeUniformRef() { } //////////////////////////////////////////// @@ -2012,13 +2384,30 @@ const VisualShaderNodeOutput::Port VisualShaderNodeOutput::ports[] = { // Canvas Item, Light { 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" }, - // Particles, Vertex - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, - { Shader::MODE_PARTICLES, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + // Particles, Emit + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_EMIT, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + // Particles, Process + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_PROCESS, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, + // Particles, End + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "COLOR.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "velocity", "VELOCITY" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_VECTOR, "custom", "CUSTOM.rgb" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_SCALAR, "custom_alpha", "CUSTOM.a" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_TRANSFORM, "transform", "TRANSFORM" }, + { Shader::MODE_PARTICLES, VisualShader::TYPE_END, VisualShaderNode::PORT_TYPE_BOOLEAN, "active", "ACTIVE" }, // Sky, Fragment { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "color", "COLOR" }, { Shader::MODE_SKY, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "alpha", "ALPHA" }, @@ -2149,6 +2538,14 @@ VisualShaderNodeUniform::Qualifier VisualShaderNodeUniform::get_qualifier() cons return qualifier; } +void VisualShaderNodeUniform::set_global_code_generated(bool p_enabled) { + global_code_generated = p_enabled; +} + +bool VisualShaderNodeUniform::is_global_code_generated() const { + return global_code_generated; +} + void VisualShaderNodeUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_uniform_name", "name"), &VisualShaderNodeUniform::set_uniform_name); ClassDB::bind_method(D_METHOD("get_uniform_name"), &VisualShaderNodeUniform::get_uniform_name); @@ -2198,23 +2595,39 @@ Vector<StringName> VisualShaderNodeUniform::get_editable_properties() const { } VisualShaderNodeUniform::VisualShaderNodeUniform() { - qualifier = QUAL_NONE; } -////////////// GroupBase - -String VisualShaderNodeGroupBase::get_caption() const { - return "Group"; -} +////////////// ResizeableBase -void VisualShaderNodeGroupBase::set_size(const Vector2 &p_size) { +void VisualShaderNodeResizableBase::set_size(const Vector2 &p_size) { size = p_size; } -Vector2 VisualShaderNodeGroupBase::get_size() const { +Vector2 VisualShaderNodeResizableBase::get_size() const { return size; } +void VisualShaderNodeResizableBase::set_allow_v_resize(bool p_enabled) { + allow_v_resize = p_enabled; +} + +bool VisualShaderNodeResizableBase::is_allow_v_resize() const { + return allow_v_resize; +} + +void VisualShaderNodeResizableBase::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeResizableBase::set_size); + ClassDB::bind_method(D_METHOD("get_size"), &VisualShaderNodeResizableBase::get_size); + + ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); +} + +VisualShaderNodeResizableBase::VisualShaderNodeResizableBase() { + set_allow_v_resize(true); +} + +////////////// GroupBase + void VisualShaderNodeGroupBase::set_inputs(const String &p_inputs) { if (inputs == p_inputs) { return; @@ -2330,6 +2743,7 @@ void VisualShaderNodeGroupBase::add_input_port(int p_id, int p_type, const Strin } _apply_port_changes(); + emit_changed(); } void VisualShaderNodeGroupBase::remove_input_port(int p_id) { @@ -2354,6 +2768,7 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) { } _apply_port_changes(); + emit_changed(); } int VisualShaderNodeGroupBase::get_input_port_count() const { @@ -2398,6 +2813,7 @@ void VisualShaderNodeGroupBase::add_output_port(int p_id, int p_type, const Stri } _apply_port_changes(); + emit_changed(); } void VisualShaderNodeGroupBase::remove_output_port(int p_id) { @@ -2422,6 +2838,7 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) { } _apply_port_changes(); + emit_changed(); } int VisualShaderNodeGroupBase::get_output_port_count() const { @@ -2468,6 +2885,7 @@ void VisualShaderNodeGroupBase::set_input_port_type(int p_id, int p_type) { inputs = inputs.insert(index, itos(p_type)); _apply_port_changes(); + emit_changed(); } VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_input_port_type(int p_id) const { @@ -2503,6 +2921,7 @@ void VisualShaderNodeGroupBase::set_input_port_name(int p_id, const String &p_na inputs = inputs.insert(index, p_name); _apply_port_changes(); + emit_changed(); } String VisualShaderNodeGroupBase::get_input_port_name(int p_id) const { @@ -2538,6 +2957,7 @@ void VisualShaderNodeGroupBase::set_output_port_type(int p_id, int p_type) { outputs = outputs.insert(index, itos(p_type)); _apply_port_changes(); + emit_changed(); } VisualShaderNodeGroupBase::PortType VisualShaderNodeGroupBase::get_output_port_type(int p_id) const { @@ -2573,6 +2993,7 @@ void VisualShaderNodeGroupBase::set_output_port_name(int p_id, const String &p_n outputs = outputs.insert(index, p_name); _apply_port_changes(); + emit_changed(); } String VisualShaderNodeGroupBase::get_output_port_name(int p_id) const { @@ -2633,9 +3054,6 @@ bool VisualShaderNodeGroupBase::is_editable() const { } void VisualShaderNodeGroupBase::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size); - ClassDB::bind_method(D_METHOD("get_size"), &VisualShaderNodeGroupBase::get_size); - ClassDB::bind_method(D_METHOD("set_inputs", "inputs"), &VisualShaderNodeGroupBase::set_inputs); ClassDB::bind_method(D_METHOD("get_inputs"), &VisualShaderNodeGroupBase::get_inputs); @@ -2663,8 +3081,6 @@ void VisualShaderNodeGroupBase::_bind_methods() { ClassDB::bind_method(D_METHOD("get_free_input_port_id"), &VisualShaderNodeGroupBase::get_free_input_port_id); ClassDB::bind_method(D_METHOD("get_free_output_port_id"), &VisualShaderNodeGroupBase::get_free_output_port_id); - - ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size"); } String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { @@ -2672,10 +3088,6 @@ String VisualShaderNodeGroupBase::generate_code(Shader::Mode p_mode, VisualShade } VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() { - size = Size2(0, 0); - inputs = ""; - outputs = ""; - editable = false; simple_decl = false; } @@ -2687,6 +3099,7 @@ String VisualShaderNodeExpression::get_caption() const { void VisualShaderNodeExpression::set_expression(const String &p_expression) { expression = p_expression; + emit_changed(); } String VisualShaderNodeExpression::get_expression() const { @@ -2800,7 +3213,6 @@ void VisualShaderNodeExpression::_bind_methods() { } VisualShaderNodeExpression::VisualShaderNodeExpression() { - expression = ""; set_editable(true); } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index dbb8d1d28c..e3d8dae032 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -50,6 +50,9 @@ public: TYPE_VERTEX, TYPE_FRAGMENT, TYPE_LIGHT, + TYPE_EMIT, + TYPE_PROCESS, + TYPE_END, TYPE_MAX }; @@ -66,6 +69,8 @@ public: }; private: + Type current_type; + struct Node { Ref<VisualShaderNode> node; Vector2 position; @@ -77,7 +82,7 @@ private: List<Connection> connections; } graph[TYPE_MAX]; - Shader::Mode shader_mode; + Shader::Mode shader_mode = Shader::MODE_SPATIAL; mutable String previous_code; Array _get_node_connections(Type p_type) const; @@ -94,7 +99,7 @@ private: static RenderModeEnums render_mode_enums[]; - volatile mutable bool dirty; + volatile mutable bool dirty = true; void _queue_update(); union ConnectionKey { @@ -111,6 +116,7 @@ private: Error _write_node(Type p_type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<DefaultTextureParam> &def_tex_params, const VMap<ConnectionKey, const List<Connection>::Element *> &input_connections, const VMap<ConnectionKey, const List<Connection>::Element *> &output_connections, int node, Set<int> &processed, bool for_preview, Set<StringName> &r_classes) const; void _input_type_changed(Type p_type, int p_id); + bool has_func_name(RenderingServer::ShaderMode p_mode, const String &p_func_name) const; protected: virtual void _update_shader() const override; @@ -120,6 +126,10 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; +public: // internal methods + void set_shader_type(Type p_type); + Type get_shader_type() const; + public: void set_version(const String &p_version); String get_version() const; @@ -179,12 +189,14 @@ VARIANT_ENUM_CAST(VisualShader::Type) class VisualShaderNode : public Resource { GDCLASS(VisualShaderNode, Resource); - int port_preview; + int port_preview = -1; Map<int, Variant> default_input_values; + Map<int, bool> connected_input_ports; + Map<int, int> connected_output_ports; protected: - bool simple_decl; + bool simple_decl = true; static void _bind_methods(); public: @@ -222,6 +234,16 @@ public: virtual bool is_port_separator(int p_index) const; + bool is_output_port_connected(int p_port) const; + void set_output_port_connected(int p_port, bool p_connected); + bool is_input_port_connected(int p_port) const; + void set_input_port_connected(int p_port, bool p_connected); + virtual bool is_generate_input_var(int p_port) const; + + virtual bool is_code_generated() const; + virtual bool is_show_prop_names() const; + virtual bool is_use_prop_slots() const; + virtual Vector<StringName> get_editable_properties() const; virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; @@ -278,8 +300,8 @@ class VisualShaderNodeInput : public VisualShaderNode { GDCLASS(VisualShaderNodeInput, VisualShaderNode); friend class VisualShader; - VisualShader::Type shader_type; - Shader::Mode shader_mode; + VisualShader::Type shader_type = VisualShader::TYPE_MAX; + Shader::Mode shader_mode = Shader::MODE_MAX; struct Port { Shader::Mode mode; @@ -292,7 +314,7 @@ class VisualShaderNodeInput : public VisualShaderNode { static const Port ports[]; static const Port preview_ports[]; - String input_name; + String input_name = "[None]"; protected: static void _bind_methods(); @@ -376,8 +398,9 @@ public: }; private: - String uniform_name; - Qualifier qualifier; + String uniform_name = ""; + Qualifier qualifier = QUAL_NONE; + bool global_code_generated = false; protected: static void _bind_methods(); @@ -390,6 +413,9 @@ public: void set_qualifier(Qualifier p_qual); Qualifier get_qualifier() const; + void set_global_code_generated(bool p_enabled); + bool is_global_code_generated() const; + virtual bool is_qualifier_supported(Qualifier p_qual) const = 0; virtual Vector<StringName> get_editable_properties() const override; @@ -400,17 +426,96 @@ public: VARIANT_ENUM_CAST(VisualShaderNodeUniform::Qualifier) -class VisualShaderNodeGroupBase : public VisualShaderNode { - GDCLASS(VisualShaderNodeGroupBase, VisualShaderNode); +class VisualShaderNodeUniformRef : public VisualShaderNode { + GDCLASS(VisualShaderNodeUniformRef, VisualShaderNode); + +public: + enum UniformType { + UNIFORM_TYPE_FLOAT, + UNIFORM_TYPE_INT, + UNIFORM_TYPE_BOOLEAN, + UNIFORM_TYPE_VECTOR, + UNIFORM_TYPE_TRANSFORM, + UNIFORM_TYPE_COLOR, + UNIFORM_TYPE_SAMPLER, + }; + + struct Uniform { + String name; + UniformType type; + }; + +private: + String uniform_name = "[None]"; + UniformType uniform_type = UniformType::UNIFORM_TYPE_FLOAT; + +protected: + static void _bind_methods(); + +public: + static void add_uniform(const String &p_name, UniformType p_type); + static void clear_uniforms(); + static bool has_uniform(const String &p_name); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + void set_uniform_name(const String &p_name); + String get_uniform_name() const; + + void _set_uniform_type(int p_uniform_type); + int _get_uniform_type() const; + + int get_uniforms_count() const; + String get_uniform_name_by_index(int p_idx) const; + UniformType get_uniform_type_by_name(const String &p_name) const; + UniformType get_uniform_type_by_index(int p_idx) const; + + virtual Vector<StringName> get_editable_properties() const override; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; + + VisualShaderNodeUniformRef(); +}; + +class VisualShaderNodeResizableBase : public VisualShaderNode { + GDCLASS(VisualShaderNodeResizableBase, VisualShaderNode); + +protected: + Vector2 size = Size2(0, 0); + bool allow_v_resize = true; + +protected: + static void _bind_methods(); + +public: + void set_size(const Vector2 &p_size); + Vector2 get_size() const; + + bool is_allow_v_resize() const; + void set_allow_v_resize(bool p_enabled); + + VisualShaderNodeResizableBase(); +}; + +class VisualShaderNodeGroupBase : public VisualShaderNodeResizableBase { + GDCLASS(VisualShaderNodeGroupBase, VisualShaderNodeResizableBase); private: void _apply_port_changes(); protected: - Vector2 size; - String inputs; - String outputs; - bool editable; + String inputs = ""; + String outputs = ""; + bool editable = false; struct Port { PortType type; @@ -425,11 +530,6 @@ protected: static void _bind_methods(); public: - virtual String get_caption() const override; - - void set_size(const Vector2 &p_size); - Vector2 get_size() const; - void set_inputs(const String &p_inputs); String get_inputs() const; @@ -478,7 +578,7 @@ class VisualShaderNodeExpression : public VisualShaderNodeGroupBase { GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase); protected: - String expression; + String expression = ""; static void _bind_methods(); diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 88f5287831..704d1b2ea8 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -87,7 +87,6 @@ void VisualShaderNodeFloatConstant::_bind_methods() { } VisualShaderNodeFloatConstant::VisualShaderNodeFloatConstant() { - constant = 0.0; } ////////////// Scalar(Int) @@ -147,7 +146,6 @@ void VisualShaderNodeIntConstant::_bind_methods() { } VisualShaderNodeIntConstant::VisualShaderNodeIntConstant() { - constant = 0; } ////////////// Boolean @@ -207,7 +205,6 @@ void VisualShaderNodeBooleanConstant::_bind_methods() { } VisualShaderNodeBooleanConstant::VisualShaderNodeBooleanConstant() { - constant = false; } ////////////// Color @@ -271,7 +268,6 @@ void VisualShaderNodeColorConstant::_bind_methods() { } VisualShaderNodeColorConstant::VisualShaderNodeColorConstant() { - constant = Color(1, 1, 1, 1); } ////////////// Vector @@ -456,7 +452,7 @@ String VisualShaderNodeTexture::get_output_port_name(int p_port) const { String VisualShaderNodeTexture::get_input_port_default_hint(int p_port) const { if (p_port == 0) { - return "UV.xy"; + return "default"; } return ""; } @@ -495,15 +491,22 @@ String VisualShaderNodeTexture::generate_global(Shader::Mode p_mode, VisualShade } String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String default_uv; + if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + default_uv = "UV.xy"; + } else { + default_uv = "vec2(0.0)"; + } + if (source == SOURCE_TEXTURE) { String id = make_unique_id(p_type, p_id, "tex"); String code; if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\tvec4 " + id + "_read = texture(" + id + ", UV.xy);\n"; + code += "\tvec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { - code += "\tvec4 " + id + "_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; + code += "\tvec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { @@ -529,9 +532,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", UV.xy);\n"; + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { - code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { @@ -553,9 +556,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String() || p_for_preview) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, UV.xy, 0.0 );\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", 0.0 );\n"; } else { - code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 _tex_read = textureLod(SCREEN_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { @@ -576,9 +579,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = texture(TEXTURE , UV.xy);\n"; + code += "\t\tvec4 _tex_read = texture(TEXTURE, " + default_uv + ");\n"; } else { - code += "\t\tvec4 _tex_read = textureLod(TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 _tex_read = textureLod(TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { @@ -599,9 +602,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 _tex_read = texture(NORMAL_TEXTURE, UV.xy);\n"; + code += "\t\tvec4 _tex_read = texture(NORMAL_TEXTURE, " + default_uv + ");\n"; } else { - code += "\t\tvec4 _tex_read = textureLod(NORMAL_TEXTURE, UV.xy, " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 _tex_read = textureLod(NORMAL_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { @@ -632,9 +635,9 @@ String VisualShaderNodeTexture::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tfloat _depth = texture(DEPTH_TEXTURE, UV.xy).r;\n"; + code += "\t\tfloat _depth = texture(DEPTH_TEXTURE, " + default_uv + ").r;\n"; } else { - code += "\t\tfloat _depth = textureLod(DEPTH_TEXTURE, UV.xy, " + p_input_vars[1] + ").r;\n"; + code += "\t\tfloat _depth = textureLod(DEPTH_TEXTURE, " + default_uv + ", " + p_input_vars[1] + ").r;\n"; } } else if (p_input_vars[1] == String()) { @@ -777,8 +780,90 @@ void VisualShaderNodeTexture::_bind_methods() { } VisualShaderNodeTexture::VisualShaderNodeTexture() { - texture_type = TYPE_DATA; - source = SOURCE_TEXTURE; +} + +////////////// Curve + +String VisualShaderNodeCurveTexture::get_caption() const { + return "CurveTexture"; +} + +int VisualShaderNodeCurveTexture::get_input_port_count() const { + return 1; +} + +VisualShaderNodeCurveTexture::PortType VisualShaderNodeCurveTexture::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeCurveTexture::get_input_port_name(int p_port) const { + return String(); +} + +int VisualShaderNodeCurveTexture::get_output_port_count() const { + return 1; +} + +VisualShaderNodeCurveTexture::PortType VisualShaderNodeCurveTexture::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeCurveTexture::get_output_port_name(int p_port) const { + return String(); +} + +void VisualShaderNodeCurveTexture::set_texture(Ref<CurveTexture> p_texture) { + texture = p_texture; + emit_changed(); +} + +Ref<CurveTexture> VisualShaderNodeCurveTexture::get_texture() const { + return texture; +} + +Vector<StringName> VisualShaderNodeCurveTexture::get_editable_properties() const { + Vector<StringName> props; + props.push_back("texture"); + return props; +} + +String VisualShaderNodeCurveTexture::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return "uniform sampler2D " + make_unique_id(p_type, p_id, "curve") + ";\n"; +} + +String VisualShaderNodeCurveTexture::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + if (p_input_vars[0] == String()) { + return "\t" + p_output_vars[0] + " = 0.0;\n"; + } + String id = make_unique_id(p_type, p_id, "curve"); + String code; + code += "\t" + p_output_vars[0] + " = texture(" + id + ", vec2(" + p_input_vars[0] + ", 0.0)).r;\n"; + return code; +} + +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeCurveTexture::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { + VisualShader::DefaultTextureParam dtp; + dtp.name = make_unique_id(p_type, p_id, "curve"); + dtp.param = texture; + Vector<VisualShader::DefaultTextureParam> ret; + ret.push_back(dtp); + return ret; +} + +void VisualShaderNodeCurveTexture::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "texture"), &VisualShaderNodeCurveTexture::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeCurveTexture::get_texture); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_texture", "get_texture"); +} + +bool VisualShaderNodeCurveTexture::is_use_prop_slots() const { + return true; +} + +VisualShaderNodeCurveTexture::VisualShaderNodeCurveTexture() { + simple_decl = true; + allow_v_resize = false; } ////////////// Sample3D @@ -825,12 +910,19 @@ String VisualShaderNodeSample3D::get_output_port_name(int p_port) const { String VisualShaderNodeSample3D::get_input_port_default_hint(int p_port) const { if (p_port == 0) { - return "vec3(UV.xy, 0.0)"; + return "default"; } return ""; } String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String default_uv; + if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + default_uv = "vec3(UV, 0.0)"; + } else { + default_uv = "vec3(0.0)"; + } + String code; if (source == SOURCE_TEXTURE || source == SOURCE_PORT) { String id; @@ -843,9 +935,9 @@ String VisualShaderNodeSample3D::generate_code(Shader::Mode p_mode, VisualShader if (id != String()) { if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", vec3(UV.xy, 0.0));\n"; + code += "\t\tvec4 " + id + "_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { - code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", vec3(UV.xy, 0.0), " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 " + id + "_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod @@ -898,7 +990,6 @@ String VisualShaderNodeSample3D::get_warning(Shader::Mode p_mode, VisualShader:: } VisualShaderNodeSample3D::VisualShaderNodeSample3D() { - source = SOURCE_TEXTURE; simple_decl = false; } @@ -958,6 +1049,64 @@ void VisualShaderNodeTexture2DArray::_bind_methods() { VisualShaderNodeTexture2DArray::VisualShaderNodeTexture2DArray() { } + +////////////// Texture3D + +String VisualShaderNodeTexture3D::get_caption() const { + return "Texture3D"; +} + +String VisualShaderNodeTexture3D::get_input_port_name(int p_port) const { + if (p_port == 2) { + return "sampler3D"; + } + return VisualShaderNodeSample3D::get_input_port_name(p_port); +} + +Vector<VisualShader::DefaultTextureParam> VisualShaderNodeTexture3D::get_default_texture_parameters(VisualShader::Type p_type, int p_id) const { + VisualShader::DefaultTextureParam dtp; + dtp.name = make_unique_id(p_type, p_id, "tex3d"); + dtp.param = texture; + Vector<VisualShader::DefaultTextureParam> ret; + ret.push_back(dtp); + return ret; +} + +String VisualShaderNodeTexture3D::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + if (source == SOURCE_TEXTURE) { + return "uniform sampler3D " + make_unique_id(p_type, p_id, "tex3d") + ";\n"; + } + return String(); +} + +void VisualShaderNodeTexture3D::set_texture(Ref<Texture3D> p_value) { + texture = p_value; + emit_changed(); +} + +Ref<Texture3D> VisualShaderNodeTexture3D::get_texture() const { + return texture; +} + +Vector<StringName> VisualShaderNodeTexture3D::get_editable_properties() const { + Vector<StringName> props; + props.push_back("source"); + if (source == SOURCE_TEXTURE) { + props.push_back("texture"); + } + return props; +} + +void VisualShaderNodeTexture3D::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_texture", "value"), &VisualShaderNodeTexture3D::set_texture); + ClassDB::bind_method(D_METHOD("get_texture"), &VisualShaderNodeTexture3D::get_texture); + + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture3D"), "set_texture", "get_texture"); +} + +VisualShaderNodeTexture3D::VisualShaderNodeTexture3D() { +} + ////////////// Cubemap String VisualShaderNodeCubemap::get_caption() const { @@ -1034,6 +1183,13 @@ String VisualShaderNodeCubemap::generate_global(Shader::Mode p_mode, VisualShade } String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String default_uv; + if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + default_uv = "vec3(UV, 0.0)"; + } else { + default_uv = "vec3(0.0)"; + } + String code; String id; if (source == SOURCE_TEXTURE) { @@ -1057,9 +1213,9 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 " + id + "_read = texture(" + id + " , vec3(UV, 0.0));\n"; + code += "\t\tvec4 " + id + "_read = texture(" + id + ", " + default_uv + ");\n"; } else { - code += "\t\tvec4 " + id + "_read = textureLod(" + id + " , vec3(UV, 0.0)" + " , " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 " + id + "_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + " );\n"; } } else if (p_input_vars[1] == String()) { @@ -1077,7 +1233,7 @@ String VisualShaderNodeCubemap::generate_code(Shader::Mode p_mode, VisualShader: String VisualShaderNodeCubemap::get_input_port_default_hint(int p_port) const { if (p_port == 0) { - return "vec3(UV, 0.0)"; + return "default"; } return ""; } @@ -1143,8 +1299,6 @@ void VisualShaderNodeCubemap::_bind_methods() { } VisualShaderNodeCubemap::VisualShaderNodeCubemap() { - texture_type = TYPE_DATA; - source = SOURCE_TEXTURE; simple_decl = false; } @@ -1250,7 +1404,6 @@ void VisualShaderNodeFloatOp::_bind_methods() { } VisualShaderNodeFloatOp::VisualShaderNodeFloatOp() { - op = OP_ADD; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); } @@ -1345,7 +1498,6 @@ void VisualShaderNodeIntOp::_bind_methods() { } VisualShaderNodeIntOp::VisualShaderNodeIntOp() { - op = OP_ADD; set_input_port_default_value(0, 0); set_input_port_default_value(1, 0); } @@ -1460,7 +1612,6 @@ void VisualShaderNodeVectorOp::_bind_methods() { } VisualShaderNodeVectorOp::VisualShaderNodeVectorOp() { - op = OP_ADD; set_input_port_default_value(0, Vector3()); set_input_port_default_value(1, Vector3()); } @@ -1628,7 +1779,6 @@ void VisualShaderNodeColorOp::_bind_methods() { } VisualShaderNodeColorOp::VisualShaderNodeColorOp() { - op = OP_SCREEN; set_input_port_default_value(0, Vector3()); set_input_port_default_value(1, Vector3()); } @@ -1703,7 +1853,6 @@ void VisualShaderNodeTransformMult::_bind_methods() { } VisualShaderNodeTransformMult::VisualShaderNodeTransformMult() { - op = OP_AxB; set_input_port_default_value(0, Transform()); set_input_port_default_value(1, Transform()); } @@ -1778,7 +1927,6 @@ void VisualShaderNodeTransformVecMult::_bind_methods() { } VisualShaderNodeTransformVecMult::VisualShaderNodeTransformVecMult() { - op = OP_AxB; set_input_port_default_value(0, Transform()); set_input_port_default_value(1, Vector3()); } @@ -1908,7 +2056,6 @@ void VisualShaderNodeFloatFunc::_bind_methods() { } VisualShaderNodeFloatFunc::VisualShaderNodeFloatFunc() { - func = FUNC_SIGN; set_input_port_default_value(0, 0.0); } @@ -2003,7 +2150,6 @@ void VisualShaderNodeIntFunc::_bind_methods() { } VisualShaderNodeIntFunc::VisualShaderNodeIntFunc() { - func = FUNC_SIGN; set_input_port_default_value(0, 0); } @@ -2169,7 +2315,6 @@ void VisualShaderNodeVectorFunc::_bind_methods() { } VisualShaderNodeVectorFunc::VisualShaderNodeVectorFunc() { - func = FUNC_NORMALIZE; set_input_port_default_value(0, Vector3()); } @@ -2256,9 +2401,8 @@ void VisualShaderNodeColorFunc::_bind_methods() { } VisualShaderNodeColorFunc::VisualShaderNodeColorFunc() { - func = FUNC_GRAYSCALE; - set_input_port_default_value(0, Vector3()); simple_decl = false; + set_input_port_default_value(0, Vector3()); } ////////////// Transform Func @@ -2328,7 +2472,6 @@ void VisualShaderNodeTransformFunc::_bind_methods() { } VisualShaderNodeTransformFunc::VisualShaderNodeTransformFunc() { - func = FUNC_INVERSE; set_input_port_default_value(0, Transform()); } @@ -2516,7 +2659,6 @@ void VisualShaderNodeScalarDerivativeFunc::_bind_methods() { } VisualShaderNodeScalarDerivativeFunc::VisualShaderNodeScalarDerivativeFunc() { - func = FUNC_SUM; set_input_port_default_value(0, 0.0); } @@ -2589,7 +2731,6 @@ void VisualShaderNodeVectorDerivativeFunc::_bind_methods() { } VisualShaderNodeVectorDerivativeFunc::VisualShaderNodeVectorDerivativeFunc() { - func = FUNC_SUM; set_input_port_default_value(0, Vector3()); } @@ -3435,18 +3576,33 @@ String VisualShaderNodeFloatUniform::get_output_port_name(int p_port) const { } String VisualShaderNodeFloatUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = ""; if (hint == HINT_RANGE) { - return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; + code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - return _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n"; + code += _get_qual_str() + "uniform float " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ")"; + } else { + code += _get_qual_str() + "uniform float " + get_uniform_name(); + } + if (default_value_enabled) { + code += " = " + rtos(default_value); } - return _get_qual_str() + "uniform float " + get_uniform_name() + ";\n"; + code += ";\n"; + return code; } String VisualShaderNodeFloatUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } +bool VisualShaderNodeFloatUniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeFloatUniform::is_use_prop_slots() const { + return true; +} + void VisualShaderNodeFloatUniform::set_hint(Hint p_hint) { hint = p_hint; emit_changed(); @@ -3483,6 +3639,24 @@ float VisualShaderNodeFloatUniform::get_step() const { return hint_range_step; } +void VisualShaderNodeFloatUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeFloatUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeFloatUniform::set_default_value(float p_value) { + default_value = p_value; + emit_changed(); +} + +float VisualShaderNodeFloatUniform::get_default_value() const { + return default_value; +} + void VisualShaderNodeFloatUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeFloatUniform::set_hint); ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeFloatUniform::get_hint); @@ -3496,10 +3670,18 @@ void VisualShaderNodeFloatUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeFloatUniform::set_step); ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeFloatUniform::get_step); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeFloatUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeFloatUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeFloatUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeFloatUniform::get_default_value); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "min"), "set_min", "get_min"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max"), "set_max", "get_max"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "step"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "default_value"), "set_default_value", "get_default_value"); BIND_ENUM_CONSTANT(HINT_NONE); BIND_ENUM_CONSTANT(HINT_RANGE); @@ -3520,14 +3702,14 @@ Vector<StringName> VisualShaderNodeFloatUniform::get_editable_properties() const if (hint == HINT_RANGE_STEP) { props.push_back("step"); } + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } return props; } VisualShaderNodeFloatUniform::VisualShaderNodeFloatUniform() { - hint = HINT_NONE; - hint_range_min = 0.0; - hint_range_max = 1.0; - hint_range_step = 0.1; } ////////////// Integer Uniform @@ -3561,18 +3743,33 @@ String VisualShaderNodeIntUniform::get_output_port_name(int p_port) const { } String VisualShaderNodeIntUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = ""; if (hint == HINT_RANGE) { - return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ");\n"; + code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ")"; } else if (hint == HINT_RANGE_STEP) { - return _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + rtos(hint_range_min) + ", " + rtos(hint_range_max) + ", " + rtos(hint_range_step) + ");\n"; + code += _get_qual_str() + "uniform int " + get_uniform_name() + " : hint_range(" + itos(hint_range_min) + ", " + itos(hint_range_max) + ", " + itos(hint_range_step) + ")"; + } else { + code += _get_qual_str() + "uniform int " + get_uniform_name(); + } + if (default_value_enabled) { + code += " = " + itos(default_value); } - return _get_qual_str() + "uniform int " + get_uniform_name() + ";\n"; + code += ";\n"; + return code; } String VisualShaderNodeIntUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } +bool VisualShaderNodeIntUniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeIntUniform::is_use_prop_slots() const { + return true; +} + void VisualShaderNodeIntUniform::set_hint(Hint p_hint) { hint = p_hint; emit_changed(); @@ -3609,6 +3806,24 @@ int VisualShaderNodeIntUniform::get_step() const { return hint_range_step; } +void VisualShaderNodeIntUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeIntUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeIntUniform::set_default_value(int p_value) { + default_value = p_value; + emit_changed(); +} + +int VisualShaderNodeIntUniform::get_default_value() const { + return default_value; +} + void VisualShaderNodeIntUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hint", "hint"), &VisualShaderNodeIntUniform::set_hint); ClassDB::bind_method(D_METHOD("get_hint"), &VisualShaderNodeIntUniform::get_hint); @@ -3622,10 +3837,18 @@ void VisualShaderNodeIntUniform::_bind_methods() { ClassDB::bind_method(D_METHOD("set_step", "value"), &VisualShaderNodeIntUniform::set_step); ClassDB::bind_method(D_METHOD("get_step"), &VisualShaderNodeIntUniform::get_step); + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeIntUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeIntUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeIntUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeIntUniform::get_default_value); + ADD_PROPERTY(PropertyInfo(Variant::INT, "hint", PROPERTY_HINT_ENUM, "None,Range,Range+Step"), "set_hint", "get_hint"); ADD_PROPERTY(PropertyInfo(Variant::INT, "min"), "set_min", "get_min"); ADD_PROPERTY(PropertyInfo(Variant::INT, "max"), "set_max", "get_max"); ADD_PROPERTY(PropertyInfo(Variant::INT, "step"), "set_step", "get_step"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "default_value"), "set_default_value", "get_default_value"); BIND_ENUM_CONSTANT(HINT_NONE); BIND_ENUM_CONSTANT(HINT_RANGE); @@ -3646,14 +3869,14 @@ Vector<StringName> VisualShaderNodeIntUniform::get_editable_properties() const { if (hint == HINT_RANGE_STEP) { props.push_back("step"); } + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } return props; } VisualShaderNodeIntUniform::VisualShaderNodeIntUniform() { - hint = HINT_NONE; - hint_range_min = 0; - hint_range_max = 100; - hint_range_step = 1; } ////////////// Boolean Uniform @@ -3686,18 +3909,73 @@ String VisualShaderNodeBooleanUniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } +void VisualShaderNodeBooleanUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeBooleanUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeBooleanUniform::set_default_value(bool p_value) { + default_value = p_value; + emit_changed(); +} + +bool VisualShaderNodeBooleanUniform::get_default_value() const { + return default_value; +} + String VisualShaderNodeBooleanUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - return _get_qual_str() + "uniform bool " + get_uniform_name() + ";\n"; + String code = _get_qual_str() + "uniform bool " + get_uniform_name(); + if (default_value_enabled) { + if (default_value) { + code += " = true"; + } else { + code += " = false"; + } + } + code += ";\n"; + return code; } String VisualShaderNodeBooleanUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } +bool VisualShaderNodeBooleanUniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeBooleanUniform::is_use_prop_slots() const { + return true; +} + +void VisualShaderNodeBooleanUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeBooleanUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeBooleanUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeBooleanUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeBooleanUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value"), "set_default_value", "get_default_value"); +} + bool VisualShaderNodeBooleanUniform::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } +Vector<StringName> VisualShaderNodeBooleanUniform::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeBooleanUniform::VisualShaderNodeBooleanUniform() { } @@ -3731,8 +4009,31 @@ String VisualShaderNodeColorUniform::get_output_port_name(int p_port) const { return p_port == 0 ? "color" : "alpha"; //no output port means the editor will be used as port } +void VisualShaderNodeColorUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeColorUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeColorUniform::set_default_value(const Color &p_value) { + default_value = p_value; + emit_changed(); +} + +Color VisualShaderNodeColorUniform::get_default_value() const { + return default_value; +} + String VisualShaderNodeColorUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - return _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : hint_color;\n"; + String code = _get_qual_str() + "uniform vec4 " + get_uniform_name() + " : hint_color"; + if (default_value_enabled) { + code += vformat(" = vec4(%.6f, %.6f, %.6f, %.6f)", default_value.r, default_value.g, default_value.b, default_value.a); + } + code += ";\n"; + return code; } String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { @@ -3741,10 +4042,34 @@ String VisualShaderNodeColorUniform::generate_code(Shader::Mode p_mode, VisualSh return code; } +bool VisualShaderNodeColorUniform::is_show_prop_names() const { + return true; +} + +void VisualShaderNodeColorUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeColorUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeColorUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeColorUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeColorUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_value"), "set_default_value", "get_default_value"); +} + bool VisualShaderNodeColorUniform::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } +Vector<StringName> VisualShaderNodeColorUniform::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeColorUniform::VisualShaderNodeColorUniform() { } @@ -3778,18 +4103,69 @@ String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } +void VisualShaderNodeVec3Uniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeVec3Uniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeVec3Uniform::set_default_value(const Vector3 &p_value) { + default_value = p_value; + emit_changed(); +} + +Vector3 VisualShaderNodeVec3Uniform::get_default_value() const { + return default_value; +} + String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - return _get_qual_str() + "uniform vec3 " + get_uniform_name() + ";\n"; + String code = _get_qual_str() + "uniform vec3 " + get_uniform_name(); + if (default_value_enabled) { + code += vformat(" = vec3(%.6f, %.6f, %.6f)", default_value.x, default_value.y, default_value.z); + } + code += ";\n"; + return code; } String VisualShaderNodeVec3Uniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } +void VisualShaderNodeVec3Uniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeVec3Uniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeVec3Uniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeVec3Uniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeVec3Uniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "default_value"), "set_default_value", "get_default_value"); +} + +bool VisualShaderNodeVec3Uniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeVec3Uniform::is_use_prop_slots() const { + return true; +} + bool VisualShaderNodeVec3Uniform::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } +Vector<StringName> VisualShaderNodeVec3Uniform::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeVec3Uniform::VisualShaderNodeVec3Uniform() { } @@ -3823,18 +4199,73 @@ String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const return ""; //no output port means the editor will be used as port } +void VisualShaderNodeTransformUniform::set_default_value_enabled(bool p_enabled) { + default_value_enabled = p_enabled; + emit_changed(); +} + +bool VisualShaderNodeTransformUniform::is_default_value_enabled() const { + return default_value_enabled; +} + +void VisualShaderNodeTransformUniform::set_default_value(const Transform &p_value) { + default_value = p_value; + emit_changed(); +} + +Transform VisualShaderNodeTransformUniform::get_default_value() const { + return default_value; +} + String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { - return _get_qual_str() + "uniform mat4 " + get_uniform_name() + ";\n"; + String code = _get_qual_str() + "uniform mat4 " + get_uniform_name(); + if (default_value_enabled) { + Vector3 row0 = default_value.basis.get_row(0); + Vector3 row1 = default_value.basis.get_row(1); + Vector3 row2 = default_value.basis.get_row(2); + Vector3 origin = default_value.origin; + code += " = mat4(" + vformat("vec4(%.6f, %.6f, %.6f, 0.0)", row0.x, row0.y, row0.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row1.x, row1.y, row1.z) + vformat(", vec4(%.6f, %.6f, %.6f, 0.0)", row2.x, row2.y, row2.z) + vformat(", vec4(%.6f, %.6f, %.6f, 1.0)", origin.x, origin.y, origin.z) + ")"; + } + code += ";\n"; + return code; } String VisualShaderNodeTransformUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { return "\t" + p_output_vars[0] + " = " + get_uniform_name() + ";\n"; } +void VisualShaderNodeTransformUniform::_bind_methods() { + ClassDB::bind_method(D_METHOD("set_default_value_enabled", "enabled"), &VisualShaderNodeTransformUniform::set_default_value_enabled); + ClassDB::bind_method(D_METHOD("is_default_value_enabled"), &VisualShaderNodeTransformUniform::is_default_value_enabled); + + ClassDB::bind_method(D_METHOD("set_default_value", "value"), &VisualShaderNodeTransformUniform::set_default_value); + ClassDB::bind_method(D_METHOD("get_default_value"), &VisualShaderNodeTransformUniform::get_default_value); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "default_value_enabled"), "set_default_value_enabled", "is_default_value_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "default_value"), "set_default_value", "get_default_value"); +} + +bool VisualShaderNodeTransformUniform::is_show_prop_names() const { + return true; +} + +bool VisualShaderNodeTransformUniform::is_use_prop_slots() const { + return true; +} + bool VisualShaderNodeTransformUniform::is_qualifier_supported(Qualifier p_qual) const { return true; // all qualifiers are supported } +Vector<StringName> VisualShaderNodeTransformUniform::get_editable_properties() const { + Vector<StringName> props = VisualShaderNodeUniform::get_editable_properties(); + props.push_back("default_value_enabled"); + if (default_value_enabled) { + props.push_back("default_value"); + } + return props; +} + VisualShaderNodeTransformUniform::VisualShaderNodeTransformUniform() { } @@ -3915,14 +4346,25 @@ String VisualShaderNodeTextureUniform::generate_global(Shader::Mode p_mode, Visu return code; } +bool VisualShaderNodeTextureUniform::is_code_generated() const { + return is_output_port_connected(0) || is_output_port_connected(1); // rgb or alpha +} + String VisualShaderNodeTextureUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + String default_uv; + if (p_mode != Shader::MODE_PARTICLES && p_mode != Shader::MODE_SKY) { + default_uv = "UV.xy"; + } else { + default_uv = "vec2(0.0)"; + } + String id = get_uniform_name(); String code = "\t{\n"; if (p_input_vars[0] == String()) { // Use UV by default. if (p_input_vars[1] == String()) { - code += "\t\tvec4 n_tex_read = texture(" + id + ", UV.xy);\n"; + code += "\t\tvec4 n_tex_read = texture(" + id + ", " + default_uv + ");\n"; } else { - code += "\t\tvec4 n_tex_read = textureLod(" + id + ", UV.xy, " + p_input_vars[1] + ");\n"; + code += "\t\tvec4 n_tex_read = textureLod(" + id + ", " + default_uv + ", " + p_input_vars[1] + ");\n"; } } else if (p_input_vars[1] == String()) { //no lod @@ -3983,7 +4425,7 @@ void VisualShaderNodeTextureUniform::_bind_methods() { String VisualShaderNodeTextureUniform::get_input_port_default_hint(int p_port) const { if (p_port == 0) { - return "UV.xy"; + return "default"; } return ""; } @@ -4001,8 +4443,6 @@ bool VisualShaderNodeTextureUniform::is_qualifier_supported(Qualifier p_qual) co } VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { - texture_type = TYPE_DATA; - color_default = COLOR_DEFAULT_WHITE; simple_decl = false; } @@ -4075,13 +4515,13 @@ String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mod String code = "\t{\n"; if (p_input_vars[0] == String() && p_input_vars[1] == String()) { - code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal, triplanar_pos );\n"; + code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, triplanar_pos);\n"; } else if (p_input_vars[0] != String() && p_input_vars[1] == String()) { - code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", triplanar_pos );\n"; + code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", triplanar_pos);\n"; } else if (p_input_vars[0] == String() && p_input_vars[1] != String()) { - code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", triplanar_power_normal," + p_input_vars[1] + " );\n"; + code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", triplanar_power_normal, " + p_input_vars[1] + ");\n"; } else { - code += "\t\tvec4 n_tex_read = triplanar_texture( " + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n"; + code += "\t\tvec4 n_tex_read = triplanar_texture(" + id + ", " + p_input_vars[0] + ", " + p_input_vars[1] + ");\n"; } code += "\t\t" + p_output_vars[0] + " = n_tex_read.rgb;\n"; @@ -4171,6 +4611,74 @@ String VisualShaderNodeTexture2DArrayUniform::generate_code(Shader::Mode p_mode, VisualShaderNodeTexture2DArrayUniform::VisualShaderNodeTexture2DArrayUniform() { } +////////////// Texture3D Uniform + +String VisualShaderNodeTexture3DUniform::get_caption() const { + return "Texture3DUniform"; +} + +int VisualShaderNodeTexture3DUniform::get_output_port_count() const { + return 1; +} + +VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_output_port_type(int p_port) const { + return PORT_TYPE_SAMPLER; +} + +String VisualShaderNodeTexture3DUniform::get_output_port_name(int p_port) const { + return "sampler3D"; +} + +int VisualShaderNodeTexture3DUniform::get_input_port_count() const { + return 0; +} + +VisualShaderNodeTexture3DUniform::PortType VisualShaderNodeTexture3DUniform::get_input_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTexture3DUniform::get_input_port_name(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture3DUniform::get_input_port_default_hint(int p_port) const { + return ""; +} + +String VisualShaderNodeTexture3DUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + String code = _get_qual_str() + "uniform sampler3D " + get_uniform_name(); + + switch (texture_type) { + case TYPE_DATA: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black;\n"; + else + code += ";\n"; + break; + case TYPE_COLOR: + if (color_default == COLOR_DEFAULT_BLACK) + code += " : hint_black_albedo;\n"; + else + code += " : hint_albedo;\n"; + break; + case TYPE_NORMALMAP: + code += " : hint_normal;\n"; + break; + case TYPE_ANISO: + code += " : hint_aniso;\n"; + break; + } + + return code; +} + +String VisualShaderNodeTexture3DUniform::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + return String(); +} + +VisualShaderNodeTexture3DUniform::VisualShaderNodeTexture3DUniform() { +} + ////////////// Cubemap Uniform String VisualShaderNodeCubemapUniform::get_caption() const { @@ -4307,13 +4815,13 @@ String VisualShaderNodeIf::generate_code(Shader::Mode p_mode, VisualShader::Type } VisualShaderNodeIf::VisualShaderNodeIf() { + simple_decl = false; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, CMP_EPSILON); set_input_port_default_value(3, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(4, Vector3(0.0, 0.0, 0.0)); set_input_port_default_value(5, Vector3(0.0, 0.0, 0.0)); - simple_decl = false; } ////////////// Switch @@ -4372,10 +4880,10 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: } VisualShaderNodeSwitch::VisualShaderNodeSwitch() { + simple_decl = false; set_input_port_default_value(0, false); set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); - simple_decl = false; } ////////////// Switch(scalar) @@ -4453,6 +4961,13 @@ String VisualShaderNodeFresnel::get_output_port_name(int p_port) const { return "result"; } +bool VisualShaderNodeFresnel::is_generate_input_var(int p_port) const { + if (p_port == 2) { + return false; + } + return true; +} + String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { String normal; String view; @@ -4467,7 +4982,15 @@ String VisualShaderNodeFresnel::generate_code(Shader::Mode p_mode, VisualShader: view = p_input_vars[1]; } - return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n"; + if (is_input_port_connected(2)) { + return "\t" + p_output_vars[0] + " = " + p_input_vars[2] + " ? (pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ")) : (pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + "));\n"; + } else { + if (get_input_port_default_value(2)) { + return "\t" + p_output_vars[0] + " = pow(clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n"; + } else { + return "\t" + p_output_vars[0] + " = pow(1.0 - clamp(dot(" + normal + ", " + view + "), 0.0, 1.0), " + p_input_vars[3] + ");\n"; + } + } } String VisualShaderNodeFresnel::get_input_port_default_hint(int p_port) const { @@ -4551,7 +5074,6 @@ void VisualShaderNodeIs::_bind_methods() { } VisualShaderNodeIs::VisualShaderNodeIs() { - func = FUNC_IS_INF; set_input_port_default_value(0, 0.0); } @@ -4787,9 +5309,6 @@ void VisualShaderNodeCompare::_bind_methods() { } VisualShaderNodeCompare::VisualShaderNodeCompare() { - ctype = CTYPE_SCALAR; - func = FUNC_EQUAL; - condition = COND_ALL; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, CMP_EPSILON); @@ -4806,7 +5325,7 @@ int VisualShaderNodeMultiplyAdd::get_input_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_input_port_type(int p_port) const { - if (type == TYPE_SCALAR) { + if (op_type == OP_TYPE_SCALAR) { return PORT_TYPE_SCALAR; } return PORT_TYPE_VECTOR; @@ -4828,7 +5347,7 @@ int VisualShaderNodeMultiplyAdd::get_output_port_count() const { } VisualShaderNodeMultiplyAdd::PortType VisualShaderNodeMultiplyAdd::get_output_port_type(int p_port) const { - if (type == TYPE_SCALAR) { + if (op_type == OP_TYPE_SCALAR) { return PORT_TYPE_SCALAR; } else { return PORT_TYPE_VECTOR; @@ -4843,10 +5362,10 @@ String VisualShaderNodeMultiplyAdd::generate_code(Shader::Mode p_mode, VisualSha return "\t" + p_output_vars[0] + " = fma(" + p_input_vars[0] + ", " + p_input_vars[1] + ", " + p_input_vars[2] + ");\n"; } -void VisualShaderNodeMultiplyAdd::set_type(Type p_type) { - ERR_FAIL_INDEX((int)p_type, TYPE_MAX); - if (p_type != type) { - if (p_type == TYPE_SCALAR) { +void VisualShaderNodeMultiplyAdd::set_op_type(OpType p_op_type) { + ERR_FAIL_INDEX((int)p_op_type, OP_TYPE_MAX); + if (p_op_type != op_type) { + if (p_op_type == OP_TYPE_SCALAR) { set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); @@ -4856,33 +5375,32 @@ void VisualShaderNodeMultiplyAdd::set_type(Type p_type) { set_input_port_default_value(2, Vector3(0.0, 0.0, 0.0)); } } - type = p_type; + op_type = p_op_type; emit_changed(); } -VisualShaderNodeMultiplyAdd::Type VisualShaderNodeMultiplyAdd::get_type() const { - return type; +VisualShaderNodeMultiplyAdd::OpType VisualShaderNodeMultiplyAdd::get_op_type() const { + return op_type; } Vector<StringName> VisualShaderNodeMultiplyAdd::get_editable_properties() const { Vector<StringName> props; - props.push_back("type"); + props.push_back("op_type"); return props; } void VisualShaderNodeMultiplyAdd::_bind_methods() { - ClassDB::bind_method(D_METHOD("set_type", "type"), &VisualShaderNodeMultiplyAdd::set_type); - ClassDB::bind_method(D_METHOD("get_type"), &VisualShaderNodeMultiplyAdd::get_type); + ClassDB::bind_method(D_METHOD("set_op_type", "type"), &VisualShaderNodeMultiplyAdd::set_op_type); + ClassDB::bind_method(D_METHOD("get_op_type"), &VisualShaderNodeMultiplyAdd::get_op_type); - ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_type", "get_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "op_type", PROPERTY_HINT_ENUM, "Scalar,Vector"), "set_op_type", "get_op_type"); - BIND_ENUM_CONSTANT(TYPE_SCALAR); - BIND_ENUM_CONSTANT(TYPE_VECTOR); - BIND_ENUM_CONSTANT(TYPE_MAX); + BIND_ENUM_CONSTANT(OP_TYPE_SCALAR); + BIND_ENUM_CONSTANT(OP_TYPE_VECTOR); + BIND_ENUM_CONSTANT(OP_TYPE_MAX); } VisualShaderNodeMultiplyAdd::VisualShaderNodeMultiplyAdd() { - type = TYPE_SCALAR; set_input_port_default_value(0, 0.0); set_input_port_default_value(1, 0.0); set_input_port_default_value(2, 0.0); diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 13a132c60e..d4d6540baf 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -39,7 +39,7 @@ class VisualShaderNodeFloatConstant : public VisualShaderNode { GDCLASS(VisualShaderNodeFloatConstant, VisualShaderNode); - float constant; + float constant = 0.0f; protected: static void _bind_methods(); @@ -69,7 +69,7 @@ public: class VisualShaderNodeIntConstant : public VisualShaderNode { GDCLASS(VisualShaderNodeIntConstant, VisualShaderNode); - int constant; + int constant = 0; protected: static void _bind_methods(); @@ -99,7 +99,7 @@ public: class VisualShaderNodeBooleanConstant : public VisualShaderNode { GDCLASS(VisualShaderNodeBooleanConstant, VisualShaderNode); - bool constant; + bool constant = false; protected: static void _bind_methods(); @@ -129,7 +129,7 @@ public: class VisualShaderNodeColorConstant : public VisualShaderNode { GDCLASS(VisualShaderNodeColorConstant, VisualShaderNode); - Color constant; + Color constant = Color(1, 1, 1, 1); protected: static void _bind_methods(); @@ -240,8 +240,8 @@ public: }; private: - Source source; - TextureType texture_type; + Source source = SOURCE_TEXTURE; + TextureType texture_type = TYPE_DATA; protected: static void _bind_methods(); @@ -284,6 +284,39 @@ VARIANT_ENUM_CAST(VisualShaderNodeTexture::Source) /////////////////////////////////////// +class VisualShaderNodeCurveTexture : public VisualShaderNodeResizableBase { + GDCLASS(VisualShaderNodeCurveTexture, VisualShaderNodeResizableBase); + Ref<CurveTexture> texture; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_texture(Ref<CurveTexture> p_value); + Ref<CurveTexture> get_texture() const; + + virtual Vector<StringName> get_editable_properties() const override; + virtual bool is_use_prop_slots() const override; + + VisualShaderNodeCurveTexture(); +}; + +/////////////////////////////////////// + class VisualShaderNodeSample3D : public VisualShaderNode { GDCLASS(VisualShaderNodeSample3D, VisualShaderNode); @@ -294,7 +327,7 @@ public: }; protected: - Source source; + Source source = SOURCE_TEXTURE; static void _bind_methods(); @@ -343,6 +376,29 @@ public: VisualShaderNodeTexture2DArray(); }; +class VisualShaderNodeTexture3D : public VisualShaderNodeSample3D { + GDCLASS(VisualShaderNodeTexture3D, VisualShaderNodeSample3D); + Ref<Texture3D> texture; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const override; + + virtual String get_input_port_name(int p_port) const override; + + virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + + void set_texture(Ref<Texture3D> p_value); + Ref<Texture3D> get_texture() const; + + virtual Vector<StringName> get_editable_properties() const override; + + VisualShaderNodeTexture3D(); +}; + class VisualShaderNodeCubemap : public VisualShaderNode { GDCLASS(VisualShaderNodeCubemap, VisualShaderNode); Ref<Cubemap> cube_map; @@ -360,8 +416,8 @@ public: }; private: - Source source; - TextureType texture_type; + Source source = SOURCE_TEXTURE; + TextureType texture_type = TYPE_DATA; protected: static void _bind_methods(); @@ -421,7 +477,7 @@ public: }; protected: - Operator op; + Operator op = OP_ADD; static void _bind_methods(); @@ -463,7 +519,7 @@ public: }; protected: - Operator op; + Operator op = OP_ADD; static void _bind_methods(); @@ -510,7 +566,7 @@ public: }; protected: - Operator op; + Operator op = OP_ADD; static void _bind_methods(); @@ -556,7 +612,7 @@ public: }; protected: - Operator op; + Operator op = OP_SCREEN; static void _bind_methods(); @@ -599,7 +655,7 @@ public: }; protected: - Operator op; + Operator op = OP_AxB; static void _bind_methods(); @@ -642,7 +698,7 @@ public: }; protected: - Operator op; + Operator op = OP_AxB; static void _bind_methods(); @@ -713,7 +769,7 @@ public: }; protected: - Function func; + Function func = FUNC_SIGN; static void _bind_methods(); @@ -756,7 +812,7 @@ public: }; protected: - Function func; + Function func = FUNC_SIGN; static void _bind_methods(); @@ -830,7 +886,7 @@ public: }; protected: - Function func; + Function func = FUNC_NORMALIZE; static void _bind_methods(); @@ -871,7 +927,7 @@ public: }; protected: - Function func; + Function func = FUNC_GRAYSCALE; static void _bind_methods(); @@ -912,7 +968,7 @@ public: }; protected: - Function func; + Function func = FUNC_INVERSE; static void _bind_methods(); @@ -1067,7 +1123,7 @@ public: }; protected: - Function func; + Function func = FUNC_SUM; static void _bind_methods(); @@ -1107,7 +1163,7 @@ public: }; protected: - Function func; + Function func = FUNC_SUM; static void _bind_methods(); @@ -1482,10 +1538,12 @@ public: }; private: - Hint hint; - float hint_range_min; - float hint_range_max; - float hint_range_step; + Hint hint = HINT_NONE; + float hint_range_min = 0.0f; + float hint_range_max = 1.0f; + float hint_range_step = 0.1f; + bool default_value_enabled = false; + float default_value = 0.0f; protected: static void _bind_methods(); @@ -1504,6 +1562,9 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + virtual bool is_use_prop_slots() const override; + void set_hint(Hint p_hint); Hint get_hint() const; @@ -1516,6 +1577,12 @@ public: void set_step(float p_value); float get_step() const; + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(float p_value); + float get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; virtual Vector<StringName> get_editable_properties() const override; @@ -1536,10 +1603,12 @@ public: }; private: - Hint hint; - int hint_range_min; - int hint_range_max; - int hint_range_step; + Hint hint = HINT_NONE; + int hint_range_min = 0; + int hint_range_max = 100; + int hint_range_step = 1; + bool default_value_enabled = false; + int default_value = 0; protected: static void _bind_methods(); @@ -1558,6 +1627,9 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + virtual bool is_use_prop_slots() const override; + void set_hint(Hint p_hint); Hint get_hint() const; @@ -1570,6 +1642,12 @@ public: void set_step(int p_value); int get_step() const; + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(int p_value); + int get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; virtual Vector<StringName> get_editable_properties() const override; @@ -1584,6 +1662,13 @@ VARIANT_ENUM_CAST(VisualShaderNodeIntUniform::Hint) class VisualShaderNodeBooleanUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeBooleanUniform, VisualShaderNodeUniform); +private: + bool default_value_enabled = false; + bool default_value = false; + +protected: + static void _bind_methods(); + public: virtual String get_caption() const override; @@ -1598,8 +1683,19 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + virtual bool is_use_prop_slots() const override; + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(bool p_value); + bool get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; + virtual Vector<StringName> get_editable_properties() const override; + VisualShaderNodeBooleanUniform(); }; @@ -1608,6 +1704,13 @@ public: class VisualShaderNodeColorUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeColorUniform, VisualShaderNodeUniform); +private: + bool default_value_enabled = false; + Color default_value = Color(1.0, 1.0, 1.0, 1.0); + +protected: + static void _bind_methods(); + public: virtual String get_caption() const override; @@ -1622,8 +1725,18 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Color &p_value); + Color get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; + virtual Vector<StringName> get_editable_properties() const override; + VisualShaderNodeColorUniform(); }; @@ -1632,6 +1745,13 @@ public: class VisualShaderNodeVec3Uniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeVec3Uniform, VisualShaderNodeUniform); +private: + bool default_value_enabled = false; + Vector3 default_value; + +protected: + static void _bind_methods(); + public: virtual String get_caption() const override; @@ -1646,8 +1766,19 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + virtual bool is_use_prop_slots() const override; + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Vector3 &p_value); + Vector3 get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; + virtual Vector<StringName> get_editable_properties() const override; + VisualShaderNodeVec3Uniform(); }; @@ -1656,6 +1787,13 @@ public: class VisualShaderNodeTransformUniform : public VisualShaderNodeUniform { GDCLASS(VisualShaderNodeTransformUniform, VisualShaderNodeUniform); +private: + bool default_value_enabled = false; + Transform default_value = Transform(1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0); + +protected: + static void _bind_methods(); + public: virtual String get_caption() const override; @@ -1670,8 +1808,19 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_show_prop_names() const override; + virtual bool is_use_prop_slots() const override; + + void set_default_value_enabled(bool p_enabled); + bool is_default_value_enabled() const; + + void set_default_value(const Transform &p_value); + Transform get_default_value() const; + bool is_qualifier_supported(Qualifier p_qual) const override; + virtual Vector<StringName> get_editable_properties() const override; + VisualShaderNodeTransformUniform(); }; @@ -1694,8 +1843,8 @@ public: }; protected: - TextureType texture_type; - ColorDefault color_default; + TextureType texture_type = TYPE_DATA; + ColorDefault color_default = COLOR_DEFAULT_WHITE; protected: static void _bind_methods(); @@ -1715,6 +1864,8 @@ public: virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + virtual bool is_code_generated() const override; + Vector<StringName> get_editable_properties() const override; void set_texture_type(TextureType p_type); @@ -1777,6 +1928,29 @@ public: /////////////////////////////////////// +class VisualShaderNodeTexture3DUniform : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeTexture3DUniform, VisualShaderNodeTextureUniform); + +public: + virtual String get_caption() const override; + + virtual int get_input_port_count() const override; + virtual PortType get_input_port_type(int p_port) const override; + virtual String get_input_port_name(int p_port) const override; + + virtual int get_output_port_count() const override; + virtual PortType get_output_port_type(int p_port) const override; + virtual String get_output_port_name(int p_port) const override; + + virtual String get_input_port_default_hint(int p_port) const override; + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const override; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + VisualShaderNodeTexture3DUniform(); +}; + +/////////////////////////////////////// + class VisualShaderNodeCubemapUniform : public VisualShaderNodeTextureUniform { GDCLASS(VisualShaderNodeCubemapUniform, VisualShaderNodeTextureUniform); @@ -1875,6 +2049,7 @@ public: virtual String get_output_port_name(int p_port) const override; virtual String get_input_port_default_hint(int p_port) const override; + virtual bool is_generate_input_var(int p_port) const override; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; VisualShaderNodeFresnel(); @@ -1894,7 +2069,7 @@ public: }; protected: - Function func; + Function func = FUNC_IS_INF; protected: static void _bind_methods(); @@ -1953,9 +2128,9 @@ public: }; protected: - ComparisonType ctype; - Function func; - Condition condition; + ComparisonType ctype = CTYPE_SCALAR; + Function func = FUNC_EQUAL; + Condition condition = COND_ALL; protected: static void _bind_methods(); @@ -1996,14 +2171,14 @@ class VisualShaderNodeMultiplyAdd : public VisualShaderNode { GDCLASS(VisualShaderNodeMultiplyAdd, VisualShaderNode); public: - enum Type { - TYPE_SCALAR, - TYPE_VECTOR, - TYPE_MAX, + enum OpType { + OP_TYPE_SCALAR, + OP_TYPE_VECTOR, + OP_TYPE_MAX, }; protected: - Type type; + OpType op_type = OP_TYPE_SCALAR; protected: static void _bind_methods(); @@ -2021,14 +2196,14 @@ public: virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty - void set_type(Type p_type); - Type get_type() const; + void set_op_type(OpType p_type); + OpType get_op_type() const; virtual Vector<StringName> get_editable_properties() const override; VisualShaderNodeMultiplyAdd(); }; -VARIANT_ENUM_CAST(VisualShaderNodeMultiplyAdd::Type) +VARIANT_ENUM_CAST(VisualShaderNodeMultiplyAdd::OpType) #endif // VISUAL_SHADER_NODES_H diff --git a/scene/resources/world_margin_shape_3d.cpp b/scene/resources/world_margin_shape_3d.cpp index d613413b33..0936fcc657 100644 --- a/scene/resources/world_margin_shape_3d.cpp +++ b/scene/resources/world_margin_shape_3d.cpp @@ -32,7 +32,7 @@ #include "servers/physics_server_3d.h" -Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() { +Vector<Vector3> WorldMarginShape3D::get_debug_mesh_lines() const { Plane p = get_plane(); Vector<Vector3> points; diff --git a/scene/resources/world_margin_shape_3d.h b/scene/resources/world_margin_shape_3d.h index c920dc513c..8099592d80 100644 --- a/scene/resources/world_margin_shape_3d.h +++ b/scene/resources/world_margin_shape_3d.h @@ -45,7 +45,7 @@ public: void set_plane(Plane p_plane); Plane get_plane() const; - virtual Vector<Vector3> get_debug_mesh_lines() override; + virtual Vector<Vector3> get_debug_mesh_lines() const override; virtual real_t get_enclosing_radius() const override { // Should be infinite? return 0; |