diff options
Diffstat (limited to 'scene/resources')
40 files changed, 1454 insertions, 228 deletions
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 64051fe304..985b38f913 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1667,8 +1667,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Vector2 pb = p_post_b; return a.cubic_interpolate(b, pa, pb, p_c); - - } break; + } case Variant::RECT2: { Rect2 a = p_a; @@ -1679,8 +1678,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a return Rect2( a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c), a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c)); - - } break; + } case Variant::VECTOR3: { Vector3 a = p_a; @@ -1689,8 +1687,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Vector3 pb = p_post_b; return a.cubic_interpolate(b, pa, pb, p_c); - - } break; + } case Variant::QUAT: { Quat a = p_a; @@ -1699,8 +1696,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a Quat pb = p_post_b; return a.cubic_slerp(b, pa, pb, p_c); - - } break; + } case Variant::AABB: { AABB a = p_a; @@ -1711,14 +1707,12 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a return AABB( a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c), a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c)); - } break; + } default: { return _interpolate(p_a, p_b, p_c); } } - - return Variant(); } float Animation::_cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const { @@ -2876,9 +2870,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.loc; const Vector3 &v2 = t2.value.loc; - if (Math::is_zero_approx(v0.distance_to(v2))) { + if (v0 == v2) { //0 and 2 are close, let's see if 1 is close - if (!Math::is_zero_approx(v0.distance_to(v1))) { + if (v0 != v1) { //not close, not optimizable return false; } @@ -2965,9 +2959,9 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons const Vector3 &v1 = t1.value.scale; const Vector3 &v2 = t2.value.scale; - if (Math::is_zero_approx(v0.distance_to(v2))) { + if (v0 == v2) { //0 and 2 are close, let's see if 1 is close - if (!Math::is_zero_approx(v0.distance_to(v1))) { + if (v0 != v1) { //not close, not optimizable return false; } @@ -3028,7 +3022,6 @@ bool Animation::_transform_track_optimize_key(const TKey<TransformKey> &t0, cons //this could be done as a second pass and would be //able to optimize more erase = false; - } else { } } } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 6fff77d746..d59dfab2c8 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -32,9 +32,7 @@ #define ANIMATION_H #include "core/resource.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ + class Animation : public Resource { GDCLASS(Animation, Resource); diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index 4b3e392013..5b61654c5d 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -564,7 +564,8 @@ Error AudioStreamSample::save_to_wav(const String &p_path) { file->store_32(sub_chunk_2_size); //Subchunk2Size // Add data - PoolVector<uint8_t>::Read read_data = get_data().read(); + PoolVector<uint8_t> data = get_data(); + PoolVector<uint8_t>::Read read_data = data.read(); switch (format) { case AudioStreamSample::FORMAT_8_BITS: for (unsigned int i = 0; i < data_bytes; i++) { diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index cb710dde43..bb14cf3ab1 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -765,10 +765,7 @@ Vector2 Curve2D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D."); - ERR_FAIL_V(Vector2()); - } + ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D."); if (pc == 1) return baked_point_cache.get(0); @@ -831,10 +828,7 @@ Vector2 Curve2D::get_closest_point(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D."); - ERR_FAIL_V(Vector2()); - } + ERR_FAIL_COND_V_MSG(pc == 0, Vector2(), "No points in Curve2D."); if (pc == 1) return baked_point_cache.get(0); @@ -870,10 +864,7 @@ float Curve2D::get_closest_offset(const Vector2 &p_to_point) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve2D."); - ERR_FAIL_V(0.0f); - } + ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve2D."); if (pc == 1) return 0.0f; @@ -1336,10 +1327,7 @@ Vector3 Curve3D::interpolate_baked(float p_offset, bool p_cubic) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D."); - ERR_FAIL_V(Vector3()); - } + ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D."); if (pc == 1) return baked_point_cache.get(0); @@ -1381,10 +1369,7 @@ float Curve3D::interpolate_baked_tilt(float p_offset) const { //validate// int pc = baked_tilt_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No tilts in Curve3D."); - ERR_FAIL_V(0); - } + ERR_FAIL_COND_V_MSG(pc == 0, 0, "No tilts in Curve3D."); if (pc == 1) return baked_tilt_cache.get(0); @@ -1420,10 +1405,7 @@ Vector3 Curve3D::interpolate_baked_up_vector(float p_offset, bool p_apply_tilt) //validate// // curve may not have baked up vectors int count = baked_up_vector_cache.size(); - if (count == 0) { - ERR_EXPLAIN("No up vectors in Curve3D."); - ERR_FAIL_V(Vector3(0, 1, 0)); - } + ERR_FAIL_COND_V_MSG(count == 0, Vector3(0, 1, 0), "No up vectors in Curve3D."); if (count == 1) return baked_up_vector_cache.get(0); @@ -1491,10 +1473,7 @@ Vector3 Curve3D::get_closest_point(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D."); - ERR_FAIL_V(Vector3()); - } + ERR_FAIL_COND_V_MSG(pc == 0, Vector3(), "No points in Curve3D."); if (pc == 1) return baked_point_cache.get(0); @@ -1530,10 +1509,7 @@ float Curve3D::get_closest_offset(const Vector3 &p_to_point) const { //validate// int pc = baked_point_cache.size(); - if (pc == 0) { - ERR_EXPLAIN("No points in Curve3D."); - ERR_FAIL_V(0.0f); - } + ERR_FAIL_COND_V_MSG(pc == 0, 0.0f, "No points in Curve3D."); if (pc == 1) return 0.0f; diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index fb0fb4f8e3..f68dc9af38 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -611,6 +611,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_font("title_font", "GraphNode", default_font); theme->set_color("title_color", "GraphNode", Color(0, 0, 0, 1)); theme->set_color("close_color", "GraphNode", Color(0, 0, 0, 1)); + theme->set_color("resizer_color", "GraphNode", Color(0, 0, 0, 1)); theme->set_constant("title_offset", "GraphNode", 20 * scale); theme->set_constant("close_offset", "GraphNode", 18 * scale); theme->set_constant("port_offset", "GraphNode", 3 * scale); @@ -656,7 +657,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_constant("hseparation", "Tree", 4 * scale); theme->set_constant("vseparation", "Tree", 4 * scale); - theme->set_constant("guide_width", "Tree", 2 * scale); theme->set_constant("item_margin", "Tree", 12 * scale); theme->set_constant("button_margin", "Tree", 4 * scale); theme->set_constant("draw_relationship_lines", "Tree", 0); @@ -760,6 +760,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // FileDialog theme->set_icon("folder", "FileDialog", make_icon(icon_folder_png)); + theme->set_color("folder_icon_modulate", "FileDialog", Color(1, 1, 1)); theme->set_color("files_disabled", "FileDialog", Color(0, 0, 0, 0.7)); // colorPicker @@ -892,8 +893,9 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { void clear_default_theme() { - Theme::set_default(Ref<Theme>()); - Theme::set_default_icon(Ref<Texture>()); - Theme::set_default_style(Ref<StyleBox>()); - Theme::set_default_font(Ref<Font>()); + Theme::set_project_default(NULL); + Theme::set_default(NULL); + Theme::set_default_icon(NULL); + Theme::set_default_style(NULL); + Theme::set_default_font(NULL); } diff --git a/scene/resources/default_theme/default_theme.h b/scene/resources/default_theme/default_theme.h index cbf0cc1b79..e7d80ffb3d 100644 --- a/scene/resources/default_theme/default_theme.h +++ b/scene/resources/default_theme/default_theme.h @@ -32,9 +32,6 @@ #define DEFAULT_THEME_H #include "scene/resources/theme.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const Ref<Font> &large_font, Ref<Texture> &default_icon, Ref<StyleBox> &default_style, float p_scale); void make_default_theme(bool p_hidpi, Ref<Font> p_font); diff --git a/scene/resources/default_theme/make_header.py b/scene/resources/default_theme/make_header.py index bd5a723b23..cf0ccf1c3a 100755 --- a/scene/resources/default_theme/make_header.py +++ b/scene/resources/default_theme/make_header.py @@ -1,9 +1,14 @@ #!/usr/bin/env python import glob +import os enc = "utf-8" +# Change to the directory where the script is located, +# so that the script can be run from any location +os.chdir(os.path.dirname(os.path.realpath(__file__))) + # Generate include files f = open("theme_data.h", "wb") diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h index cf37c57407..11904b7aff 100644 --- a/scene/resources/default_theme/theme_data.h +++ b/scene/resources/default_theme/theme_data.h @@ -339,7 +339,7 @@ static const unsigned char toggle_off_png[] = { }; static const unsigned char toggle_off_disabled_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x3c, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x4e, 0xe8, 0x1b, 0x92, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x6, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x58, 0x47, 0xed, 0x59, 0x4b, 0x6f, 0x1b, 0x55, 0x14, 0x3e, 0xb6, 0xc7, 0x8e, 0xed, 0xf1, 0x2b, 0x7e, 0x84, 0xb8, 0x49, 0x8a, 0x48, 0x36, 0x55, 0x37, 0x48, 0x5d, 0x64, 0xc1, 0x3a, 0x42, 0x82, 0x14, 0x89, 0x56, 0x14, 0x16, 0x48, 0xfc, 0x1, 0xca, 0x1f, 0x40, 0x20, 0x81, 0x90, 0xf8, 0x1, 0xd0, 0x25, 0x8b, 0x8a, 0x25, 0xa0, 0x82, 0x8a, 0x10, 0x12, 0x42, 0x8, 0x29, 0x5d, 0x15, 0xa9, 0x12, 0x8b, 0x4a, 0x20, 0x51, 0x50, 0x1b, 0xcb, 0x79, 0xf8, 0xed, 0x8c, 0xdf, 0xe3, 0x31, 0xe7, 0xbb, 0x99, 0xeb, 0x4c, 0x26, 0x33, 0xb6, 0x13, 0xbb, 0xb4, 0x42, 0xbd, 0xd2, 0xc9, 0x24, 0x77, 0xee, 0x39, 0x73, 0xbf, 0x7b, 0x1e, 0xf7, 0x9c, 0x13, 0xa2, 0x67, 0xe3, 0xd9, 0x9, 0xfc, 0xaf, 0x4e, 0xc0, 0x33, 0x21, 0x1a, 0xac, 0x93, 0x4, 0x96, 0x49, 0xf9, 0x26, 0x14, 0x7f, 0xe6, 0x65, 0x3, 0x93, 0x13, 0x4f, 0x49, 0x23, 0x85, 0x8d, 0xdb, 0xb8, 0x97, 0xb9, 0x41, 0x7e, 0xb, 0xf9, 0xcc, 0xb9, 0x71, 0xbc, 0x67, 0x46, 0x31, 0x21, 0x23, 0x0, 0x1a, 0x4c, 0x7d, 0xa6, 0x9e, 0x85, 0x30, 0x7, 0x72, 0x1c, 0x6e, 0x9b, 0xc6, 0x3c, 0x80, 0x5, 0x98, 0x22, 0x4c, 0x9, 0x93, 0x62, 0xfc, 0xc, 0x99, 0xe0, 0x71, 0x10, 0x4f, 0xa, 0xb4, 0x4, 0xb, 0xa0, 0x2d, 0xa6, 0x3a, 0x53, 0xd5, 0x24, 0x8d, 0x9f, 0x5d, 0xf3, 0x20, 0xa4, 0x5, 0xc, 0xc1, 0x3b, 0x6d, 0x18, 0x40, 0x14, 0x13, 0x68, 0x86, 0x9f, 0xcb, 0xe9, 0xf4, 0x73, 0xd7, 0x22, 0x91, 0xd8, 0x6b, 0x8a, 0xe2, 0xe3, 0xbf, 0x3d, 0x78, 0xe7, 0xe1, 0x31, 0xa1, 0x22, 0x1e, 0xcf, 0xb2, 0xc1, 0x40, 0x60, 0xe1, 0x1f, 0x3, 0x5d, 0xd7, 0xfb, 0x5, 0x4d, 0xab, 0x7f, 0x5f, 0x2c, 0xee, 0x7d, 0xcd, 0x73, 0x39, 0xa6, 0x2, 0x13, 0x80, 0xeb, 0x76, 0x6d, 0xdb, 0x77, 0xd, 0xb0, 0xd0, 0x6a, 0x9c, 0xe9, 0x7c, 0x22, 0x91, 0xba, 0x92, 0x4c, 0xa6, 0xdf, 0xf3, 0x7a, 0x3d, 0x91, 0x23, 0x7c, 0x56, 0x16, 0x37, 0xd0, 0x27, 0xe, 0xf6, 0x70, 0x6f, 0xc2, 0x20, 0x60, 0x6d, 0xb3, 0x37, 0xe, 0x1c, 0x80, 0x61, 0x18, 0x5a, 0xb9, 0x5c, 0xfc, 0xbc, 0x5a, 0x2d, 0x7d, 0xcb, 0x1f, 0x79, 0xc4, 0x54, 0x33, 0xb5, 0x3d, 0x34, 0x71, 0xfb, 0xee, 0x1, 0x76, 0x9e, 0x69, 0x35, 0x9b, 0x5d, 0x7e, 0x5f, 0x55, 0x23, 0x9b, 0x0, 0xea, 0xf7, 0x7b, 0x29, 0x99, 0x4c, 0x52, 0x34, 0x1a, 0xa5, 0xb9, 0xb9, 0x39, 0xf2, 0x7a, 0xb1, 0x61, 0xe7, 0xc1, 0xc7, 0x4d, 0xb5, 0x5a, 0x8d, 0xa, 0x85, 0x2, 0xf5, 0x60, 0x70, 0xc3, 0x21, 0xf, 0x1, 0xdf, 0xc6, 0x67, 0xdd, 0x65, 0x4c, 0x63, 0x13, 0x0, 0xde, 0x68, 0x1c, 0xfc, 0xb0, 0xb3, 0x93, 0xfb, 0x94, 0xe5, 0xfc, 0xcd, 0x54, 0x31, 0x41, 0x8b, 0xd, 0x48, 0xc0, 0xd2, 0x67, 0xa1, 0xd9, 0xb5, 0x73, 0xe7, 0x56, 0x3e, 0x9, 0x87, 0xd5, 0x97, 0x61, 0xb6, 0xe9, 0x74, 0x42, 0x80, 0x5, 0x88, 0x6a, 0xb5, 0x4a, 0xdd, 0x8e, 0x21, 0x74, 0x65, 0x1f, 0x10, 0xa0, 0x70, 0x68, 0xb, 0x6, 0x83, 0xe2, 0x60, 0x40, 0xa5, 0x52, 0x89, 0xca, 0xc5, 0x9a, 0x43, 0x4, 0x91, 0xda, 0x9e, 0x6, 0x9a, 0x3b, 0x2f, 0x40, 0x37, 0x9b, 0xda, 0x4f, 0xf9, 0xfc, 0xf6, 0x87, 0xbc, 0xea, 0x81, 0xa9, 0x69, 0x4, 0xb7, 0x1, 0x2, 0x13, 0x6, 0x8e, 0x3b, 0xc8, 0x94, 0x9d, 0x9f, 0x4f, 0xbf, 0x1d, 0x8f, 0x27, 0xde, 0x1, 0xd8, 0x6c, 0x36, 0x43, 0xaa, 0xaa, 0x52, 0x3e, 0x9f, 0x67, 0xb0, 0xd, 0xea, 0xf7, 0x9d, 0xa0, 0x1e, 0x7d, 0xd8, 0x60, 0xe5, 0x75, 0xbb, 0x3a, 0x1d, 0x1c, 0x34, 0xa9, 0xdd, 0x6e, 0x88, 0x83, 0xa, 0x86, 0x2, 0xd4, 0xd4, 0x9a, 0xb6, 0x43, 0x7a, 0xbc, 0xfe, 0x8f, 0xbd, 0xfb, 0xfd, 0x81, 0x35, 0x0, 0x6d, 0xb5, 0x9a, 0x7f, 0xf2, 0xb3, 0xc1, 0x4, 0x7f, 0x1e, 0x48, 0xbb, 0xc2, 0x13, 0xd1, 0x78, 0x39, 0x99, 0x4c, 0x5d, 0x87, 0x19, 0x27, 0x93, 0x31, 0xa, 0x85, 0x42, 0x94, 0xcb, 0xe5, 0xa8, 0xd5, 0xc2, 0xda, 0xd3, 0x8d, 0x46, 0xa3, 0x2b, 0x78, 0x21, 0x23, 0x91, 0x8c, 0xfe, 0xe7, 0xe1, 0x1c, 0xa0, 0xe7, 0xe7, 0x53, 0xef, 0xf2, 0xae, 0x57, 0x4c, 0x6c, 0x50, 0xae, 0x47, 0x46, 0xf, 0xdc, 0xb3, 0xf1, 0x4c, 0x66, 0xf1, 0x2d, 0xe, 0x50, 0xa1, 0x0, 0x7, 0xe2, 0x54, 0x2a, 0x45, 0x3b, 0x3b, 0x3b, 0x36, 0x3f, 0x3c, 0x1d, 0x68, 0xf8, 0xf0, 0xee, 0xee, 0xae, 0x90, 0xe5, 0x53, 0x46, 0x5b, 0xc7, 0xe9, 0x24, 0x4f, 0xb6, 0xda, 0xeb, 0xf5, 0x85, 0x18, 0xd3, 0x9b, 0xc0, 0x6, 0x8f, 0x3, 0x97, 0xb8, 0x62, 0x98, 0x0, 0x38, 0xa1, 0xaa, 0xd1, 0x4d, 0x4c, 0x46, 0x93, 0x11, 0x76, 0xfc, 0xc6, 0x99, 0x34, 0x6b, 0xdf, 0x4a, 0xb3, 0xd9, 0x63, 0x7f, 0x6a, 0x52, 0x3c, 0x1e, 0x67, 0x9f, 0xc6, 0x75, 0xe9, 0x3c, 0x7a, 0xbd, 0x36, 0xad, 0xaf, 0xaf, 0xd3, 0xc5, 0x8b, 0x17, 0xa8, 0xd3, 0xe9, 0xd0, 0xd6, 0xd6, 0x1d, 0xda, 0xdb, 0x2b, 0xb1, 0x85, 0x4, 0xe8, 0xea, 0xd5, 0xd7, 0x8f, 0x31, 0xdd, 0xba, 0xf5, 0xdd, 0x89, 0xb9, 0xdb, 0xb7, 0x7f, 0x64, 0x57, 0x3a, 0x38, 0x21, 0x1c, 0x81, 0x97, 0xe3, 0xe7, 0x17, 0xfc, 0x62, 0x8f, 0xa9, 0x63, 0x5, 0x1c, 0xe3, 0x7b, 0x36, 0xd, 0xfc, 0xb1, 0x58, 0x8c, 0xca, 0xe5, 0xf2, 0x64, 0xc7, 0x38, 0xc1, 0x2a, 0x4d, 0xd3, 0x84, 0x3f, 0x8f, 0x2, 0xbc, 0xb1, 0xb1, 0x21, 0x80, 0xde, 0xbc, 0xf9, 0x25, 0x7, 0xca, 0x34, 0x5d, 0xbe, 0xfc, 0xaa, 0xf8, 0x1d, 0x80, 0x31, 0xac, 0x80, 0x9c, 0xe6, 0xdc, 0xb6, 0xa1, 0x28, 0xa, 0x72, 0x9, 0x24, 0x4c, 0x2, 0xab, 0xf4, 0x61, 0xd8, 0x37, 0x82, 0x96, 0x50, 0x7b, 0x20, 0xc0, 0x81, 0x86, 0xb5, 0x32, 0xab, 0x1, 0x59, 0x90, 0x39, 0x4a, 0xbb, 0xcb, 0xcb, 0xe7, 0xe8, 0xfe, 0xfd, 0x3f, 0x38, 0xd8, 0x4, 0xf9, 0x46, 0xd0, 0xe8, 0xc1, 0x83, 0x7f, 0x68, 0x75, 0x75, 0x55, 0xb0, 0xec, 0xef, 0x97, 0x4e, 0xb0, 0x3a, 0xcd, 0x39, 0xcb, 0x17, 0x89, 0x12, 0xb2, 0x43, 0xe1, 0xc3, 0x2, 0x20, 0x7e, 0x91, 0x13, 0xf8, 0x83, 0x4f, 0x85, 0xf4, 0x63, 0x77, 0xe8, 0x74, 0xd0, 0x21, 0xb, 0x32, 0xdd, 0x6, 0x2c, 0xa, 0x0, 0xac, 0x26, 0x59, 0x2c, 0x16, 0x84, 0xa6, 0x8b, 0xc5, 0x22, 0x47, 0xfe, 0xe, 0x5d, 0xba, 0xf4, 0xa2, 0x60, 0xbf, 0x77, 0xef, 0x77, 0xd2, 0xf5, 0xce, 0x89, 0x39, 0x27, 0x73, 0x16, 0xc0, 0xe, 0x33, 0xa6, 0x61, 0xa6, 0x23, 0x77, 0x21, 0x73, 0x53, 0x21, 0x14, 0xc9, 0x3, 0xee, 0xd4, 0xe3, 0x89, 0xc3, 0xd9, 0x41, 0x43, 0x16, 0x64, 0xba, 0xd, 0x45, 0x99, 0xa3, 0x85, 0x85, 0x94, 0xb8, 0xbb, 0xe5, 0xc6, 0xa3, 0xd1, 0x98, 0x0, 0x25, 0x7, 0x80, 0xca, 0x77, 0xd2, 0xa4, 0xad, 0x73, 0x6e, 0xb2, 0xcd, 0x14, 0x14, 0xd9, 0x8e, 0x88, 0x9a, 0xd2, 0xa4, 0x71, 0x29, 0x73, 0x12, 0x3e, 0xe0, 0x5d, 0xd, 0xf8, 0x43, 0x5d, 0xa, 0x87, 0xc3, 0x67, 0x47, 0x68, 0xe3, 0x84, 0x2c, 0xc8, 0x74, 0x1b, 0x0, 0x2, 0xd, 0x27, 0x12, 0x51, 0xb1, 0x4, 0xc0, 0xd7, 0xd6, 0x5e, 0x10, 0xda, 0x9d, 0x7e, 0x0, 0x93, 0x28, 0x30, 0x44, 0xe2, 0x1, 0xd, 0x3, 0x39, 0xc, 0xf8, 0x40, 0xd7, 0x8d, 0x82, 0xdf, 0xef, 0xcb, 0xd6, 0xeb, 0x75, 0x91, 0x70, 0xd4, 0x6a, 0xb3, 0xf1, 0xe3, 0x48, 0x24, 0x42, 0x90, 0x39, 0x6a, 0xdc, 0xb9, 0xb3, 0x45, 0x9b, 0x9b, 0xaf, 0xd0, 0x85, 0xb, 0x1a, 0x47, 0xf4, 0x88, 0xf0, 0x61, 0x19, 0xa5, 0xa7, 0x1, 0xcd, 0x96, 0x85, 0x42, 0x2, 0x1f, 0x17, 0x89, 0x87, 0x35, 0xd3, 0xa, 0x70, 0x76, 0xb2, 0xc0, 0xa9, 0xe1, 0xa5, 0x7e, 0x5b, 0xa7, 0xcc, 0x62, 0x86, 0xaf, 0x25, 0x8d, 0x4d, 0xd1, 0xb5, 0xb4, 0x9c, 0x68, 0x1f, 0xe1, 0xb0, 0x5f, 0xdc, 0xc3, 0xb8, 0x8f, 0xd, 0xc3, 0x3d, 0xc3, 0xe2, 0x8a, 0x87, 0xb6, 0xb7, 0xf3, 0xc4, 0x55, 0xf, 0xdd, 0xbd, 0xfb, 0x1b, 0xe7, 0x0, 0xfb, 0x42, 0x7e, 0xab, 0xd5, 0x10, 0xa6, 0xdd, 0xeb, 0xf5, 0x87, 0x56, 0xe2, 0x34, 0xe7, 0x6e, 0x3d, 0xb5, 0xaf, 0x38, 0xcd, 0xfc, 0x85, 0xdf, 0xe3, 0xda, 0xd1, 0x25, 0x60, 0x61, 0xde, 0xfc, 0xa2, 0xc0, 0xa9, 0xe5, 0x35, 0xc3, 0x33, 0x60, 0xaf, 0x33, 0x28, 0x93, 0xc9, 0x88, 0xd, 0x20, 0x65, 0x3c, 0xcb, 0xf0, 0xb3, 0x94, 0xa5, 0xa5, 0x25, 0xaa, 0x54, 0x2a, 0xd4, 0xe4, 0xcc, 0x6b, 0xdc, 0x80, 0xd9, 0xd7, 0xeb, 0x7, 0x34, 0x18, 0x1c, 0x1d, 0x8c, 0xcf, 0xa7, 0x70, 0x4e, 0xd0, 0x3a, 0xe6, 0x12, 0x4e, 0x73, 0x4e, 0xb2, 0xd, 0xa3, 0xdf, 0xca, 0xe5, 0x1e, 0x7e, 0xc0, 0xef, 0x1e, 0x32, 0x21, 0xbd, 0x34, 0xac, 0x80, 0x45, 0x46, 0xcf, 0x41, 0x4d, 0xf, 0x85, 0xc2, 0x2f, 0xb5, 0xdb, 0x5d, 0x2e, 0x4, 0x2, 0xe2, 0xfe, 0xec, 0x74, 0x9a, 0xa7, 0xd6, 0xb4, 0xaa, 0x6, 0x38, 0x17, 0xcf, 0x72, 0x4e, 0xdd, 0xa6, 0x52, 0xa1, 0xea, 0x58, 0x70, 0x8c, 0x3b, 0x80, 0x69, 0xde, 0x23, 0x58, 0x55, 0x2a, 0xc5, 0xcf, 0x38, 0x97, 0xfe, 0x95, 0xe5, 0x20, 0x18, 0xe0, 0xc4, 0x87, 0x26, 0xd, 0xd9, 0xa2, 0x5d, 0xc2, 0xb, 0x76, 0x82, 0xc1, 0xd0, 0xf3, 0x7e, 0xbf, 0x7f, 0x4d, 0xe3, 0xa4, 0x5f, 0x51, 0xbc, 0xb4, 0xb8, 0xb8, 0x28, 0x9e, 0xb8, 0xe, 0xc, 0x97, 0x2, 0x42, 0xa4, 0x6b, 0xac, 0x51, 0x55, 0xd, 0xf2, 0x75, 0x32, 0x2f, 0xac, 0x43, 0x94, 0x89, 0x7b, 0x65, 0xf7, 0x7e, 0xcb, 0x34, 0x88, 0x46, 0xf0, 0xca, 0x6a, 0x69, 0x7f, 0x7f, 0xf7, 0x6, 0x2f, 0x43, 0x43, 0x40, 0x68, 0x17, 0x2c, 0x6e, 0xf5, 0x30, 0x97, 0x88, 0xe7, 0x3f, 0xe2, 0xe8, 0xba, 0x81, 0x6b, 0x4c, 0x51, 0x3c, 0xc2, 0xf, 0xa7, 0xab, 0x87, 0x1f, 0x13, 0x3a, 0x9b, 0xd8, 0x43, 0xb0, 0x8d, 0x9f, 0xf3, 0xf9, 0x47, 0x1f, 0xf3, 0xab, 0xbf, 0x98, 0x1c, 0xeb, 0x61, 0xc9, 0x26, 0x3b, 0x1e, 0xe8, 0x61, 0x9d, 0xe7, 0x6a, 0xe3, 0xa, 0xd3, 0x75, 0x9f, 0xcf, 0xcb, 0x95, 0x94, 0xac, 0x61, 0xad, 0x25, 0xb4, 0xf5, 0x6b, 0xe3, 0x8a, 0x3, 0xc9, 0x6f, 0x97, 0x33, 0xbb, 0x83, 0xe8, 0xf7, 0xfb, 0x1a, 0x9b, 0xf1, 0x8d, 0x4a, 0x65, 0xd8, 0xf1, 0x40, 0x9f, 0xb, 0xa6, 0xec, 0xd8, 0xf1, 0xb0, 0x82, 0x46, 0x31, 0x81, 0x72, 0x91, 0x73, 0x6b, 0x5a, 0xe1, 0x9e, 0xd6, 0x1b, 0x66, 0x4f, 0x6b, 0x1, 0xd9, 0xd9, 0x93, 0xee, 0x67, 0xc9, 0x8d, 0x1e, 0x26, 0x15, 0xa2, 0xa7, 0xb5, 0x6f, 0xf6, 0xb4, 0xbe, 0xe1, 0x89, 0x6d, 0xd3, 0x67, 0xd1, 0xd3, 0xc2, 0x75, 0x7b, 0x2c, 0xe4, 0x8e, 0xeb, 0x5a, 0xce, 0x31, 0x83, 0xca, 0x4, 0x8d, 0xa3, 0xf5, 0x63, 0xef, 0x5a, 0xce, 0x4e, 0x3d, 0xa7, 0x97, 0x4, 0x20, 0xd6, 0xae, 0x25, 0x4c, 0x17, 0x1a, 0x85, 0xbf, 0x22, 0x45, 0x13, 0x89, 0x86, 0x5d, 0xec, 0xa8, 0xd6, 0x3, 0xde, 0xc9, 0x1c, 0x1b, 0x9, 0xa, 0xb2, 0x7f, 0x68, 0x5e, 0x24, 0xe1, 0x26, 0x9d, 0x7e, 0x9b, 0xb3, 0xe3, 0x90, 0x8d, 0x77, 0xd9, 0x97, 0x86, 0xe9, 0x22, 0xb9, 0x90, 0x40, 0x1d, 0x7d, 0x6c, 0xd2, 0x5e, 0x8b, 0x4, 0xf8, 0x34, 0x0, 0xb5, 0x1f, 0x99, 0xf5, 0xbf, 0xe, 0xe3, 0x2, 0xc9, 0xec, 0x8e, 0xfb, 0x99, 0xa4, 0xa7, 0xf4, 0x4, 0xfe, 0x5, 0x72, 0xf1, 0x9c, 0xca, 0xa6, 0xf4, 0x2a, 0x9a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0xfc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x14, 0x17, 0x20, 0x20, 0x25, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x13, 0x22, 0x22, 0x27, 0x24, 0x24, 0x28, 0x25, 0x25, 0x28, 0x25, 0x25, 0x29, 0x25, 0x25, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x19, 0x1c, 0x2b, 0x26, 0x2c, 0x40, 0x40, 0x44, 0x4e, 0x4e, 0x52, 0x1a, 0x1a, 0x1d, 0x32, 0x32, 0x37, 0x2c, 0x26, 0x2c, 0x26, 0x25, 0x2a, 0x27, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x2f, 0x26, 0x2d, 0x12, 0x12, 0x14, 0x23, 0x23, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x15, 0x18, 0x20, 0x20, 0x25, 0x20, 0x20, 0x24, 0x5b, 0x5b, 0x5f, 0x84, 0x84, 0x87, 0x77, 0x77, 0x7a, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x69, 0x69, 0x6c, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x27, 0x15, 0x15, 0x18, 0x23, 0x23, 0x28, 0x12, 0x12, 0x14, 0x0, 0x0, 0x0, 0x1a, 0x1a, 0x1e, 0x0, 0x0, 0x0, 0x11, 0x11, 0x13, 0x22, 0x22, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x71, 0xb, 0x1b, 0xbb, 0x0, 0x0, 0x0, 0x54, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x98, 0xe5, 0xfa, 0xfe, 0xff, 0xff, 0x8, 0x17, 0x35, 0x86, 0xf3, 0xff, 0xff, 0xff, 0xff, 0x7, 0x3a, 0xb4, 0xff, 0xff, 0xff, 0xb9, 0xff, 0xff, 0xff, 0xff, 0xb, 0x28, 0x8a, 0xff, 0x8b, 0xf6, 0x45, 0x5, 0x9b, 0xe6, 0xff, 0xff, 0xff, 0xff, 0xe6, 0x37, 0xf, 0xff, 0xfb, 0x4c, 0xfe, 0x4e, 0x4f, 0x50, 0xfb, 0x9c, 0xf6, 0x8c, 0x3b, 0xbb, 0x3c, 0x87, 0xf3, 0x53, 0x14, 0xd4, 0x6d, 0x6c, 0xf9, 0x0, 0x0, 0x2, 0x3, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0xdd, 0x55, 0x85, 0x9a, 0xe2, 0x30, 0x18, 0xbc, 0x7a, 0x8b, 0xbb, 0x7b, 0x2, 0xbb, 0x4d, 0x36, 0xb8, 0x3b, 0xeb, 0xae, 0xef, 0xff, 0x2e, 0x47, 0x48, 0x3f, 0xa0, 0x7a, 0xae, 0x83, 0x56, 0xfe, 0xe9, 0xfc, 0xfe, 0xe9, 0x6f, 0x2, 0xc7, 0xb, 0x82, 0xf8, 0x45, 0x8, 0x2, 0xcf, 0x39, 0x9a, 0xf3, 0xa2, 0x24, 0x2b, 0xaa, 0xe6, 0xfb, 0x2, 0x34, 0x55, 0x91, 0x25, 0x91, 0xb7, 0x3f, 0x5d, 0xf4, 0xab, 0x81, 0x60, 0x28, 0x1c, 0x89, 0xc6, 0x3c, 0x11, 0x8d, 0x84, 0x43, 0xc1, 0x80, 0xea, 0x17, 0x2d, 0x2a, 0xf8, 0x78, 0x22, 0x99, 0x4a, 0x67, 0xb2, 0xb9, 0x7c, 0xe1, 0xb, 0xc8, 0xe7, 0xb2, 0x99, 0x74, 0x2a, 0x99, 0x88, 0xf3, 0x26, 0xfb, 0x62, 0xa9, 0x5c, 0xa9, 0xd6, 0x0, 0x80, 0x10, 0xb2, 0xfb, 0x20, 0x5, 0x80, 0x75, 0xe8, 0x48, 0x52, 0xad, 0x94, 0x4b, 0xc5, 0x23, 0x6, 0xae, 0xa1, 0x9d, 0x9c, 0xd6, 0x80, 0x8e, 0xf0, 0x1e, 0x48, 0xdf, 0xb1, 0xd4, 0x81, 0x8b, 0x8e, 0xd3, 0x13, 0xad, 0xc1, 0x1d, 0xfc, 0x57, 0x82, 0x67, 0x35, 0x48, 0x30, 0x6a, 0xb6, 0x76, 0x97, 0x5b, 0x3a, 0x41, 0x98, 0xb4, 0x77, 0x4a, 0xdc, 0x3c, 0x39, 0xb, 0x2a, 0xfb, 0x38, 0xf0, 0x9d, 0x6e, 0xaf, 0x6, 0x11, 0xea, 0x1f, 0xdf, 0x41, 0x10, 0x6a, 0x7b, 0xc6, 0x62, 0xd0, 0xed, 0xf0, 0x6, 0x81, 0x58, 0xa, 0xd, 0x1, 0xa1, 0xa2, 0x8f, 0xa1, 0x23, 0xd2, 0xf2, 0x62, 0x18, 0x8e, 0x4a, 0x63, 0x26, 0x81, 0x93, 0x2, 0x13, 0xa0, 0xe3, 0xbe, 0xf5, 0xe, 0x82, 0x3d, 0x25, 0x14, 0x26, 0x1, 0x89, 0x11, 0xf0, 0x72, 0x70, 0xba, 0x15, 0x60, 0xbf, 0x3, 0x11, 0xe3, 0xcf, 0x6c, 0xbe, 0x58, 0xa2, 0x42, 0x7f, 0xb1, 0xc5, 0xee, 0x8b, 0x9d, 0x5f, 0xad, 0x37, 0xcc, 0x7, 0x41, 0x9, 0x65, 0x21, 0xbd, 0xd9, 0x8a, 0x3d, 0xe9, 0xf9, 0x7c, 0x46, 0x16, 0xb3, 0x3e, 0x35, 0xa4, 0x5f, 0x6, 0x2e, 0x46, 0x8a, 0xc0, 0x8, 0xd4, 0xcb, 0x2b, 0x88, 0x75, 0x3b, 0x81, 0x8e, 0xd, 0x1, 0xd4, 0x68, 0x8e, 0xfa, 0xe7, 0x94, 0xe0, 0x7c, 0x4f, 0x90, 0xbf, 0x56, 0x45, 0x46, 0x50, 0xba, 0xa9, 0x41, 0xec, 0x10, 0xb0, 0x96, 0x41, 0xd0, 0x3f, 0xdf, 0x7e, 0xe1, 0x79, 0xff, 0xfc, 0xfc, 0x9c, 0x6c, 0xbf, 0xf6, 0x14, 0xb7, 0x25, 0x83, 0x40, 0xd, 0xd7, 0x3c, 0x15, 0x90, 0x9d, 0x2, 0xec, 0xae, 0x40, 0x9, 0xdd, 0x1, 0xef, 0x18, 0xa0, 0x2, 0x59, 0xda, 0x5c, 0xd8, 0xc7, 0x80, 0x97, 0xd7, 0x5f, 0xc8, 0x42, 0x7f, 0x79, 0xbe, 0x9c, 0x17, 0x2c, 0x4, 0xfb, 0x2c, 0xd0, 0x3a, 0xb8, 0xff, 0x42, 0x1d, 0x10, 0x5a, 0x95, 0x33, 0x44, 0xd8, 0x97, 0x81, 0xfb, 0xa4, 0xc4, 0xed, 0x2b, 0xf1, 0x1, 0xfe, 0x40, 0x25, 0xd2, 0x5e, 0x18, 0x7c, 0x7b, 0x2f, 0x3c, 0xd2, 0x5e, 0xf8, 0x72, 0x37, 0x16, 0xbe, 0xdc, 0x8d, 0x6c, 0x1e, 0x3c, 0x3d, 0xd7, 0x40, 0xdb, 0x32, 0xf, 0xbc, 0xec, 0x9f, 0x5f, 0xf6, 0xf3, 0x80, 0x4d, 0x24, 0x2d, 0xf8, 0xfa, 0x6, 0xea, 0x80, 0xd, 0x24, 0x68, 0x0, 0x6c, 0x5f, 0x8e, 0xf6, 0xd5, 0xd7, 0xa0, 0x56, 0x34, 0xcf, 0xb4, 0x86, 0x92, 0xc, 0xa5, 0x33, 0x17, 0xf9, 0xc2, 0x17, 0x91, 0xbf, 0xc8, 0xa4, 0x43, 0x49, 0xa5, 0xc1, 0x5b, 0xa7, 0x72, 0x47, 0xd, 0xac, 0x47, 0xd7, 0xef, 0xb1, 0x2f, 0xe0, 0xfd, 0x7a, 0xb4, 0xe, 0xa8, 0x1d, 0x91, 0xb3, 0x6f, 0x95, 0xb1, 0xb4, 0xf9, 0x28, 0x7d, 0x79, 0x2f, 0x94, 0x3e, 0x36, 0xd2, 0x98, 0xe7, 0x5c, 0x36, 0x93, 0xf8, 0x15, 0xa0, 0x9b, 0xe9, 0xff, 0xc2, 0x67, 0x14, 0xf4, 0xa5, 0xb3, 0x35, 0x5e, 0x63, 0x97, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char toggle_on_png[] = { @@ -347,7 +347,7 @@ static const unsigned char toggle_on_png[] = { }; static const unsigned char toggle_on_disabled_png[] = { - 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0xa2, 0x9d, 0x7e, 0x84, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x12, 0x0, 0x0, 0xb, 0x12, 0x1, 0xd2, 0xdd, 0x7e, 0xfc, 0x0, 0x0, 0x6, 0x54, 0x49, 0x44, 0x41, 0x54, 0x68, 0x43, 0xed, 0x59, 0x4b, 0x6f, 0x1b, 0x55, 0x14, 0x3e, 0x71, 0xfc, 0x9a, 0xd8, 0x4e, 0x9c, 0x38, 0x6e, 0x62, 0xe7, 0x21, 0xb5, 0x6e, 0x51, 0xd5, 0x5, 0xa8, 0xac, 0x93, 0x14, 0x89, 0x22, 0x84, 0xba, 0x60, 0x53, 0xb1, 0x29, 0x12, 0x42, 0xa0, 0xfe, 0x1, 0x7e, 0x1, 0x7b, 0xb6, 0x6c, 0xaa, 0x82, 0xa8, 0xc4, 0x96, 0x5f, 0x50, 0x21, 0x55, 0x34, 0x1b, 0x4a, 0x17, 0x65, 0x51, 0x9, 0x85, 0x3c, 0x9b, 0xb4, 0x4d, 0xfd, 0x76, 0xfc, 0x7e, 0xf3, 0x7d, 0x37, 0x33, 0xc6, 0x76, 0xed, 0xcc, 0x38, 0x4e, 0x52, 0x21, 0x7a, 0xa4, 0xa3, 0xc9, 0x4c, 0xee, 0x3d, 0xf7, 0xbc, 0xee, 0xb9, 0xdf, 0x3d, 0x16, 0x79, 0x4b, 0x6f, 0x3d, 0xf0, 0xbf, 0xf6, 0xc0, 0xc8, 0x80, 0xd6, 0x73, 0xbc, 0xc1, 0x9c, 0x3a, 0xe8, 0xfc, 0x1, 0x97, 0xb3, 0x3c, 0xbc, 0xa9, 0x8f, 0xe4, 0xd3, 0x60, 0x4b, 0x93, 0xad, 0x1a, 0x60, 0x83, 0x34, 0xb2, 0xa3, 0x8d, 0x47, 0xf5, 0x6f, 0x56, 0x65, 0x58, 0x52, 0xe8, 0x18, 0x83, 0x68, 0x70, 0x3, 0x5c, 0x7, 0x57, 0xdb, 0x98, 0xdf, 0xc8, 0x47, 0x92, 0x99, 0xf2, 0xfc, 0x3f, 0xd, 0x75, 0x82, 0xbd, 0x60, 0xbf, 0xce, 0xe3, 0x78, 0x6a, 0xba, 0x33, 0xe8, 0x18, 0x33, 0x39, 0x66, 0x7a, 0x1c, 0xf7, 0xff, 0x86, 0xf1, 0x34, 0xbc, 0x8, 0x3e, 0x0, 0xa7, 0x75, 0xce, 0xe1, 0x59, 0xd1, 0x1d, 0x63, 0x64, 0xc8, 0x6b, 0xeb, 0x1c, 0xa5, 0x38, 0xd, 0xb3, 0xeb, 0x86, 0x7, 0xf1, 0x9c, 0xf7, 0xf9, 0x26, 0x96, 0xc1, 0x1f, 0x39, 0x9d, 0xce, 0xb, 0x36, 0xdb, 0xe8, 0xb8, 0xcd, 0x66, 0xd3, 0x46, 0x40, 0xc7, 0xd5, 0xfe, 0x24, 0xe6, 0x35, 0x41, 0x8d, 0x46, 0xa3, 0xd8, 0x68, 0xd4, 0xf, 0x2a, 0x95, 0xca, 0x66, 0x36, 0x9b, 0xb9, 0xf, 0x7e, 0x8, 0xd9, 0x7b, 0xe0, 0x18, 0x98, 0x8e, 0xa8, 0xf5, 0xcb, 0x86, 0x7e, 0xca, 0xd3, 0x78, 0x46, 0x7d, 0x2, 0xbc, 0x38, 0x36, 0xe6, 0x5d, 0x9, 0x4, 0x82, 0xb7, 0x5d, 0x2e, 0xf7, 0x3b, 0x6f, 0xd8, 0x5e, 0x53, 0x9f, 0xc1, 0x1f, 0x52, 0x2e, 0x97, 0xd6, 0x12, 0x89, 0xd8, 0x9d, 0x42, 0x21, 0xf7, 0x1b, 0x26, 0x3c, 0x3, 0x67, 0xf4, 0x6c, 0x78, 0x6d, 0x4b, 0xf4, 0x72, 0x0, 0xbf, 0xd1, 0xf8, 0x49, 0xf0, 0x85, 0xc9, 0xc9, 0xe9, 0xcf, 0xa7, 0xa6, 0xa6, 0xbf, 0x42, 0xb4, 0xf9, 0xed, 0x4c, 0x49, 0xd3, 0xec, 0x32, 0x3b, 0x3b, 0x2b, 0x93, 0x93, 0x93, 0xa2, 0x69, 0x9a, 0x40, 0x87, 0xbe, 0xeb, 0xd7, 0x6a, 0x35, 0x89, 0xc7, 0xe3, 0xb2, 0xb7, 0xb7, 0x27, 0xc5, 0x62, 0x4d, 0x90, 0x15, 0x95, 0x64, 0x32, 0xfe, 0x43, 0x2a, 0x15, 0xff, 0x19, 0x93, 0x36, 0xc1, 0x29, 0xdd, 0x9, 0x1d, 0xdb, 0xa1, 0xdb, 0x1, 0xc6, 0x9e, 0x67, 0xe4, 0x23, 0x53, 0x53, 0xc1, 0xaf, 0x61, 0xfc, 0xd7, 0x67, 0x9e, 0xe6, 0xb6, 0x51, 0x59, 0x98, 0xb, 0xca, 0xcc, 0xcc, 0x8c, 0x24, 0x12, 0x9, 0x65, 0x58, 0x36, 0x87, 0x6d, 0xde, 0xec, 0x51, 0xd3, 0xb0, 0x3, 0x35, 0xb7, 0x4d, 0x3c, 0x1e, 0x8f, 0xf8, 0xfd, 0x7e, 0xe5, 0xac, 0xfd, 0xfd, 0x7d, 0xd9, 0x7d, 0x1e, 0x93, 0x66, 0xbd, 0xd6, 0x84, 0x13, 0xee, 0x26, 0x93, 0xb1, 0xbb, 0xb0, 0x67, 0x43, 0xcf, 0x4, 0x16, 0xcb, 0x96, 0x13, 0x58, 0xe0, 0xda, 0x89, 0x2e, 0x76, 0x83, 0x43, 0x1e, 0x8f, 0xef, 0xe3, 0x60, 0x70, 0xe6, 0x1b, 0x78, 0xbd, 0x7b, 0xcc, 0xe9, 0x66, 0x1, 0x96, 0x8b, 0x9c, 0x9f, 0x93, 0x89, 0x89, 0x9, 0xd9, 0xdc, 0xdc, 0x84, 0x31, 0x9, 0xa9, 0x54, 0xb8, 0x85, 0xfb, 0xd5, 0xb1, 0xa6, 0xd4, 0x6a, 0xd, 0x29, 0x14, 0xca, 0x92, 0x4c, 0x66, 0xf0, 0xcc, 0x4a, 0x28, 0x14, 0x12, 0xaf, 0xc7, 0x2d, 0xa9, 0x4c, 0x7e, 0xc4, 0xed, 0x72, 0xbd, 0x57, 0xa9, 0x94, 0xb7, 0xaa, 0xd5, 0xca, 0x2e, 0x84, 0xe4, 0xc1, 0x1d, 0xc2, 0xba, 0x8d, 0xe3, 0x3b, 0x2b, 0xfd, 0xa5, 0x50, 0x68, 0xfe, 0x5b, 0x87, 0xc3, 0x11, 0x38, 0x5d, 0x6b, 0xbb, 0xa4, 0x23, 0x9a, 0xe1, 0x50, 0x40, 0x45, 0x71, 0x6d, 0x6d, 0x4d, 0x72, 0xb9, 0xf2, 0xc0, 0xcb, 0x97, 0x4a, 0x55, 0x39, 0x38, 0x48, 0x29, 0x27, 0x8c, 0xda, 0x9a, 0x92, 0xcb, 0x97, 0x6c, 0x28, 0xda, 0x91, 0x4c, 0x26, 0xc5, 0x7a, 0xc0, 0x6d, 0x40, 0xa1, 0x2d, 0x6f, 0xb6, 0x6f, 0x2a, 0xa6, 0x3f, 0xcf, 0xf9, 0x89, 0xf1, 0x71, 0xff, 0xa, 0xa, 0xde, 0xf9, 0x81, 0x57, 0x1f, 0x72, 0x82, 0xcb, 0x39, 0xa2, 0x14, 0xdf, 0xd9, 0xd9, 0x51, 0xfb, 0xf8, 0xb8, 0xc4, 0xb9, 0x94, 0x11, 0xe, 0x87, 0x85, 0x32, 0x69, 0xb, 0x6c, 0x5a, 0xa6, 0x6d, 0x60, 0x9e, 0x6c, 0x2d, 0xea, 0xe5, 0x0, 0xbf, 0xd7, 0x3b, 0x7e, 0xdd, 0xea, 0xe2, 0x73, 0x73, 0x61, 0xb9, 0x7a, 0xf5, 0x5d, 0xb9, 0x75, 0xeb, 0x33, 0xb9, 0x79, 0xf3, 0x53, 0xec, 0xdb, 0xc3, 0xa4, 0xd1, 0x34, 0xa7, 0xfa, 0x66, 0x43, 0x14, 0x8c, 0xf7, 0x6b, 0xd7, 0x96, 0x8e, 0x14, 0x1b, 0xc, 0x6, 0x11, 0xbd, 0x3, 0x49, 0xa7, 0x99, 0xa9, 0xc3, 0x11, 0x65, 0x64, 0x32, 0x19, 0xa1, 0x4c, 0x92, 0xd7, 0xeb, 0xa3, 0x4d, 0x2c, 0xec, 0x2c, 0xe6, 0xad, 0xda, 0xd7, 0xcb, 0x1, 0xe3, 0x48, 0x19, 0xcb, 0xd1, 0xbf, 0x78, 0xf1, 0x2, 0x3c, 0xec, 0x92, 0x7, 0xf, 0x56, 0xe5, 0xfe, 0xfd, 0x5f, 0xe5, 0xfa, 0xf5, 0xf, 0x85, 0x4e, 0x31, 0x68, 0x79, 0x99, 0x8e, 0xb7, 0x46, 0x4c, 0xfd, 0x74, 0x9a, 0x38, 0xe6, 0x64, 0x88, 0xb2, 0x28, 0x93, 0xe4, 0x74, 0xba, 0x22, 0x78, 0x10, 0xc0, 0x31, 0x3, 0x7a, 0x3a, 0x80, 0xe3, 0x58, 0x3, 0xdc, 0x4, 0x39, 0x56, 0x54, 0xa0, 0xa1, 0xf3, 0xf3, 0x61, 0x79, 0xfa, 0xf4, 0x2f, 0x79, 0xfe, 0xfc, 0x5, 0x3c, 0x9e, 0x93, 0x8d, 0x8d, 0x2d, 0x44, 0xfd, 0x70, 0x76, 0x34, 0x9a, 0x40, 0x4, 0x2, 0x2a, 0x1b, 0xac, 0x10, 0x8f, 0xba, 0x7c, 0x7e, 0xf8, 0xe8, 0x1b, 0x6b, 0x51, 0x16, 0x65, 0x2a, 0xc3, 0x46, 0xed, 0xac, 0x6d, 0x7c, 0xa1, 0x8d, 0x7d, 0x1d, 0xa0, 0x8e, 0x41, 0x22, 0x3c, 0x2b, 0xa, 0xe3, 0x88, 0x51, 0x46, 0x66, 0xb3, 0xd9, 0xd6, 0xf0, 0x78, 0x3c, 0x26, 0xd3, 0xd3, 0xd3, 0xea, 0x1d, 0xd5, 0x57, 0x9e, 0x3c, 0xf9, 0x53, 0x96, 0x96, 0xac, 0x65, 0x1, 0x8a, 0xae, 0x14, 0x8a, 0xa6, 0xf0, 0xdd, 0x8a, 0x6a, 0x6a, 0xc, 0x65, 0x51, 0x26, 0x49, 0xc7, 0x31, 0xaf, 0xc1, 0xf6, 0x6e, 0x64, 0xa1, 0xb0, 0x35, 0xd0, 0x14, 0xb1, 0xb5, 0x29, 0xd9, 0xed, 0x2e, 0x39, 0x77, 0x2e, 0x20, 0x3e, 0x9f, 0xaf, 0x35, 0xd6, 0xe7, 0x1b, 0x57, 0x86, 0x1b, 0xb4, 0xbe, 0xbe, 0xcd, 0xf4, 0x93, 0xcb, 0x97, 0x2f, 0x9b, 0xca, 0xab, 0x56, 0xab, 0x32, 0xa6, 0xf5, 0x7, 0x3b, 0xa6, 0x2, 0xba, 0x6, 0x50, 0x16, 0x65, 0x92, 0x8, 0x8c, 0xf8, 0x0, 0x77, 0x9c, 0xa7, 0xdd, 0xab, 0x11, 0x24, 0x14, 0xeb, 0xf5, 0x9a, 0xa5, 0x8d, 0xc8, 0xc8, 0x33, 0x3, 0xfc, 0xfe, 0x43, 0x7, 0xd0, 0x11, 0x91, 0xc8, 0x79, 0x5, 0x5c, 0xda, 0xe9, 0xf1, 0xe3, 0xdf, 0xe5, 0xca, 0x15, 0x73, 0x7, 0x14, 0x8b, 0x45, 0x5, 0x68, 0x4e, 0x8a, 0x28, 0x8b, 0x32, 0x49, 0xba, 0x4d, 0x7c, 0xe9, 0x0, 0x42, 0xed, 0x47, 0x2, 0x3d, 0x43, 0x77, 0x65, 0x71, 0xa9, 0xd8, 0x70, 0x38, 0x9c, 0xe7, 0xac, 0x28, 0xb2, 0xba, 0xfa, 0x50, 0x6e, 0xdc, 0xf8, 0x4, 0x11, 0xce, 0x1, 0xbc, 0x78, 0x55, 0xd, 0x78, 0xf5, 0x2a, 0xd1, 0xb1, 0xef, 0xf9, 0x4e, 0x47, 0x99, 0x51, 0x2a, 0x95, 0x52, 0x68, 0x2e, 0x16, 0xb3, 0xe4, 0x7f, 0x33, 0x71, 0x4a, 0x16, 0x65, 0x92, 0x90, 0x95, 0x44, 0x82, 0xbc, 0x2d, 0x1e, 0x9, 0x84, 0xd4, 0x25, 0x8, 0xd0, 0xd7, 0x87, 0x63, 0x63, 0xc5, 0x74, 0x5, 0x4a, 0xab, 0xd5, 0x65, 0x77, 0xf7, 0x5, 0x40, 0xcb, 0x81, 0x3c, 0x7a, 0xf4, 0x87, 0xbc, 0x7c, 0x19, 0x55, 0xd3, 0x8, 0x63, 0xa3, 0xd1, 0x7d, 0x14, 0xb5, 0xc3, 0x8, 0x6c, 0x6f, 0x6f, 0x22, 0x1a, 0x85, 0xd6, 0x7b, 0x2f, 0xd9, 0xe5, 0x72, 0x51, 0x16, 0x16, 0x16, 0x30, 0x2e, 0x27, 0x4, 0x34, 0xc3, 0x90, 0xdf, 0xef, 0x51, 0x38, 0x60, 0x6b, 0x6b, 0xb, 0xd1, 0x6f, 0xc2, 0x11, 0x89, 0x7b, 0xb8, 0x24, 0x3d, 0x82, 0xcc, 0xa4, 0xee, 0x4, 0x25, 0xbe, 0x17, 0xcc, 0xb5, 0x61, 0x60, 0x11, 0xe, 0x58, 0xb6, 0xdb, 0xed, 0x87, 0x67, 0x88, 0x9, 0x21, 0x63, 0x70, 0x7e, 0x67, 0xa5, 0xd9, 0xfc, 0xf7, 0x6a, 0xc1, 0xed, 0x61, 0x18, 0xcf, 0xe9, 0xfc, 0x5f, 0xfb, 0x7b, 0x2f, 0x91, 0x75, 0xec, 0xd0, 0x11, 0x6c, 0x53, 0x2a, 0x4e, 0x34, 0x47, 0x88, 0x7b, 0x1c, 0xe2, 0x25, 0x2a, 0x12, 0x89, 0x20, 0x13, 0x5f, 0x49, 0x3a, 0x53, 0xe0, 0xed, 0x70, 0x2b, 0x1a, 0x7d, 0xf9, 0x3d, 0x64, 0xed, 0x80, 0x79, 0xcc, 0xb4, 0x4, 0xf7, 0x72, 0x0, 0xb7, 0xc2, 0x8, 0x6e, 0x57, 0x39, 0xdc, 0x7, 0x3e, 0x40, 0x36, 0x9c, 0x5c, 0x55, 0xb2, 0x60, 0x4d, 0x36, 0x5f, 0x56, 0x38, 0x9e, 0x88, 0xb0, 0x54, 0xca, 0x43, 0xf9, 0xc1, 0x32, 0x81, 0x91, 0xa7, 0xf1, 0xb9, 0x5c, 0x4e, 0x9e, 0xed, 0x45, 0xa5, 0x51, 0xaf, 0xd5, 0x62, 0xb1, 0xfd, 0xef, 0x70, 0x17, 0x60, 0xf4, 0x59, 0x9c, 0x58, 0xc, 0xfb, 0x5e, 0x86, 0xa8, 0xa2, 0x6a, 0x2f, 0x61, 0x42, 0x86, 0xc6, 0x6b, 0xda, 0xd8, 0xfb, 0x67, 0x7a, 0x1b, 0xc4, 0x7d, 0x3e, 0x5, 0x3c, 0xe1, 0x74, 0xd8, 0x64, 0x71, 0x71, 0x11, 0x20, 0xcb, 0x81, 0x14, 0xae, 0x48, 0xa5, 0x6a, 0xe8, 0xdc, 0xde, 0x96, 0xc4, 0xdf, 0x88, 0x8f, 0xa6, 0x8d, 0xaa, 0x42, 0x1c, 0xe, 0xcf, 0x2, 0x84, 0xcd, 0xa1, 0x86, 0xc4, 0x64, 0xfb, 0xd9, 0xbe, 0xba, 0xd, 0x22, 0xf5, 0x7f, 0x44, 0x36, 0xfd, 0x2, 0x9b, 0xd8, 0x20, 0xe9, 0x88, 0x3e, 0x8d, 0x35, 0xeb, 0x7, 0x44, 0xd0, 0x8, 0xf9, 0xd2, 0xef, 0xf, 0x7c, 0x81, 0x73, 0xb4, 0x3, 0x43, 0x5b, 0x8, 0xe6, 0xd0, 0x43, 0x86, 0xec, 0x7, 0xd4, 0xd2, 0xe9, 0xc4, 0x3d, 0x34, 0x46, 0x7e, 0x82, 0x22, 0xeb, 0x60, 0x4b, 0xfd, 0x0, 0x43, 0x69, 0xa3, 0x23, 0x44, 0xf4, 0xb4, 0xe8, 0xf1, 0x78, 0x57, 0xd0, 0x1b, 0xb8, 0xed, 0x76, 0x6b, 0x97, 0x86, 0xb6, 0xea, 0xc, 0x4, 0x94, 0x4a, 0xc5, 0xbf, 0xd1, 0x3, 0xb8, 0x93, 0xcf, 0xb7, 0x3a, 0x42, 0x3c, 0x56, 0xc, 0x1c, 0xd0, 0xa1, 0x81, 0x59, 0x4f, 0x90, 0x30, 0x8a, 0xcd, 0x50, 0x42, 0xbb, 0x5, 0xf4, 0x3, 0x97, 0xf4, 0x9e, 0xe0, 0x45, 0x42, 0xcb, 0x37, 0xd1, 0x25, 0xea, 0xe5, 0x3f, 0x82, 0x1c, 0x9e, 0xf3, 0x28, 0xc6, 0xeb, 0x7a, 0x4f, 0x70, 0x15, 0xe3, 0x78, 0xff, 0xe7, 0x9e, 0x67, 0x4f, 0x90, 0x85, 0xa4, 0x67, 0x45, 0x35, 0x6b, 0x68, 0x1a, 0x1d, 0x22, 0x17, 0x4, 0x10, 0xa1, 0x30, 0x23, 0x78, 0x32, 0x74, 0x77, 0x85, 0xcf, 0x20, 0xae, 0x7d, 0x97, 0xa0, 0x61, 0xed, 0x5d, 0x61, 0xa6, 0x3a, 0x23, 0xce, 0xfd, 0x4e, 0x48, 0xda, 0x1, 0x7c, 0xba, 0xa5, 0x98, 0x39, 0x80, 0xe3, 0x8d, 0xaa, 0xc3, 0x13, 0x83, 0x75, 0x80, 0x37, 0x1b, 0x66, 0x86, 0x71, 0xa9, 0xb0, 0x22, 0xe3, 0x34, 0x1d, 0x64, 0xfc, 0x10, 0x62, 0xfc, 0x2e, 0xc0, 0x54, 0x27, 0xd8, 0x31, 0xc, 0xef, 0xdb, 0x12, 0x37, 0x8c, 0x1b, 0x44, 0xb9, 0xae, 0x12, 0x3c, 0xc8, 0xd4, 0x53, 0x1f, 0xdb, 0xfe, 0xab, 0xd0, 0x91, 0x46, 0x9f, 0xba, 0x26, 0x6f, 0x17, 0xf8, 0xf, 0x79, 0xe0, 0x1f, 0xd, 0x80, 0x80, 0xb4, 0xad, 0xe9, 0x2a, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 + 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x1, 0x53, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd, 0xf, 0x1a, 0x1a, 0x1e, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0xc, 0x1d, 0x1d, 0x21, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x23, 0x23, 0x28, 0x2e, 0x2e, 0x2e, 0x46, 0x46, 0x46, 0x57, 0x57, 0x57, 0x60, 0x60, 0x60, 0x62, 0x62, 0x62, 0x5e, 0x5e, 0x5e, 0x4a, 0x4a, 0x4a, 0x12, 0x12, 0x15, 0x25, 0x27, 0x2d, 0x42, 0x42, 0x42, 0x59, 0x59, 0x59, 0x32, 0x32, 0x32, 0x25, 0x26, 0x2d, 0x25, 0x25, 0x2b, 0x25, 0x26, 0x2c, 0x39, 0x39, 0x39, 0x49, 0x49, 0x49, 0x5a, 0x5a, 0x5a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb, 0xd, 0x23, 0x23, 0x28, 0x48, 0x48, 0x48, 0x54, 0x54, 0x54, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0xb, 0xb, 0xd, 0x1e, 0x1e, 0x22, 0x25, 0x26, 0x2b, 0x3f, 0x3f, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0x2c, 0x2c, 0x2c, 0x58, 0x58, 0x58, 0x1a, 0x1a, 0x1e, 0x40, 0x40, 0x44, 0x56, 0x56, 0x58, 0x80, 0x80, 0x80, 0x79, 0x79, 0x79, 0x3c, 0x3c, 0x3d, 0x2e, 0x2e, 0x30, 0x27, 0x27, 0x29, 0x64, 0x64, 0x66, 0x41, 0x41, 0x41, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x5d, 0x5f, 0x34, 0x34, 0x36, 0x52, 0x52, 0x52, 0x3a, 0x3a, 0x3a, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x32, 0x32, 0x37, 0x42, 0x42, 0x44, 0x6a, 0x6a, 0x6d, 0x5b, 0x5b, 0x5b, 0x2f, 0x2f, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x49, 0x4a, 0x0, 0x0, 0x0, 0x50, 0x50, 0x51, 0x70, 0x70, 0x74, 0xe, 0xe, 0x10, 0xb, 0xb, 0xd, 0x0, 0x0, 0x0, 0x13, 0x13, 0x15, 0x0, 0x0, 0x0, 0xb, 0xb, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xbd, 0xb, 0x85, 0x35, 0x0, 0x0, 0x0, 0x71, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x80, 0xc5, 0xe7, 0xf5, 0xfe, 0xff, 0x8, 0x17, 0x35, 0x73, 0xd9, 0xff, 0x7, 0x3a, 0x96, 0xf9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x9a, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xb, 0x28, 0x76, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x77, 0xde, 0xff, 0xff, 0x45, 0x5, 0x82, 0xff, 0xff, 0xc6, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc6, 0x37, 0xf, 0xff, 0xff, 0xff, 0xff, 0xe9, 0x4c, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4e, 0x4f, 0xff, 0x50, 0xff, 0xff, 0x83, 0x78, 0x3b, 0x9c, 0x3c, 0x74, 0xda, 0x53, 0x14, 0x49, 0x96, 0x6e, 0xf, 0x0, 0x0, 0x1, 0xfa, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x62, 0x18, 0x5e, 0x0, 0xd0, 0x5c, 0x39, 0x28, 0x49, 0x12, 0xc0, 0x60, 0xb8, 0xda, 0xdd, 0xcb, 0x31, 0x33, 0xb6, 0x6d, 0xdb, 0x5e, 0xdb, 0xd6, 0xfb, 0x17, 0x4e, 0x7d, 0x37, 0xe6, 0xf9, 0x2b, 0x23, 0x7f, 0x9c, 0x20, 0x28, 0x86, 0xe1, 0xb, 0xc1, 0x30, 0x14, 0x99, 0x6a, 0x8e, 0xe2, 0x4, 0x49, 0xd1, 0xcc, 0xda, 0x2, 0x18, 0x9a, 0x22, 0x9, 0x1c, 0x9d, 0xf4, 0x8e, 0xaf, 0xd3, 0x1b, 0x9b, 0x5b, 0xdb, 0x1c, 0x2e, 0x6f, 0x2e, 0x5c, 0xce, 0xf6, 0xd6, 0xe6, 0x6, 0xbd, 0x8e, 0x8f, 0x45, 0x81, 0xf2, 0x5, 0x42, 0x91, 0x58, 0x22, 0x95, 0xc9, 0x61, 0x1, 0x72, 0x99, 0x54, 0x22, 0x16, 0x9, 0x5, 0x7c, 0x74, 0xc4, 0x5e, 0xa1, 0x54, 0xa9, 0x35, 0x5a, 0x58, 0x12, 0xad, 0x46, 0xad, 0x52, 0x2a, 0x86, 0x14, 0x10, 0x1d, 0xa3, 0x37, 0x18, 0x61, 0x1e, 0x26, 0xb3, 0xc5, 0x6a, 0x63, 0xb1, 0x3b, 0x4c, 0x60, 0x34, 0xe8, 0x19, 0x1d, 0x32, 0xc8, 0x9f, 0xda, 0x74, 0xce, 0x8d, 0xdd, 0xe5, 0xf6, 0x98, 0xbd, 0x3e, 0xff, 0x57, 0x2, 0xa6, 0x60, 0x28, 0xec, 0x76, 0xc9, 0x9d, 0x9b, 0x54, 0xbf, 0xe, 0x68, 0x24, 0x1a, 0x8b, 0xcf, 0xb5, 0x4f, 0x24, 0x53, 0x30, 0x44, 0x3a, 0x99, 0x70, 0xc5, 0x33, 0xd1, 0xc8, 0x8f, 0x24, 0x70, 0xe5, 0x56, 0x16, 0xe6, 0x90, 0xcb, 0x27, 0x4d, 0x63, 0x9, 0x25, 0xf3, 0xb9, 0x6c, 0x41, 0x59, 0x64, 0x43, 0x40, 0x88, 0x8d, 0x12, 0xcc, 0xa3, 0x5c, 0x49, 0xc3, 0x18, 0x69, 0x4f, 0x19, 0x4a, 0x1b, 0x4, 0x2b, 0x80, 0x92, 0x9b, 0x55, 0xe8, 0x53, 0xab, 0x37, 0x9a, 0x2d, 0x68, 0x37, 0x3a, 0xd0, 0xee, 0x2, 0x4b, 0xcf, 0x1, 0x13, 0x38, 0x7a, 0xb0, 0xb3, 0xbb, 0xc7, 0xe6, 0x80, 0x51, 0x5b, 0x52, 0xe8, 0xd3, 0xdd, 0xaf, 0x1d, 0x34, 0x6a, 0xed, 0x46, 0x77, 0x20, 0x70, 0x78, 0x4, 0x13, 0x1c, 0x1d, 0xc2, 0x71, 0x81, 0xc2, 0x58, 0x1, 0xfa, 0x44, 0x36, 0x8, 0xa0, 0x71, 0xa, 0xb0, 0x7f, 0xd6, 0x3e, 0x6f, 0xb6, 0xfb, 0x2, 0x17, 0x97, 0x30, 0xc1, 0xe5, 0x5, 0x18, 0xaf, 0x68, 0x9c, 0x15, 0x50, 0x5e, 0xf, 0x7a, 0xd8, 0x3e, 0x7, 0x80, 0x9b, 0x7a, 0xbb, 0x7b, 0x73, 0xde, 0x17, 0xb0, 0xfa, 0x60, 0x2, 0x9f, 0x15, 0xe0, 0x56, 0xf9, 0x5d, 0x80, 0xde, 0x1e, 0xc, 0xd1, 0xe9, 0xd7, 0x8, 0xea, 0x77, 0xed, 0x2e, 0xdc, 0xd7, 0x97, 0x8e, 0x80, 0xda, 0x3a, 0x86, 0x3e, 0xe7, 0x67, 0x70, 0xda, 0x6c, 0xb5, 0xbb, 0xd0, 0x6a, 0x2c, 0x5b, 0x3, 0x94, 0xdc, 0xad, 0x42, 0x9f, 0x76, 0xf3, 0xbc, 0x59, 0x87, 0xaf, 0xe1, 0x9f, 0x2f, 0xd5, 0x5, 0x76, 0xe, 0x1e, 0x60, 0xc0, 0xe9, 0x59, 0x7, 0xa0, 0xd6, 0x2, 0xe8, 0xb4, 0xe6, 0xcf, 0xc1, 0x83, 0x90, 0x40, 0x7e, 0x79, 0x12, 0xfb, 0xbb, 0x90, 0x59, 0x7d, 0x17, 0x1e, 0xd9, 0x5d, 0xf8, 0xd5, 0x6d, 0xec, 0xdf, 0x83, 0xa7, 0xe7, 0xf8, 0x2a, 0xf7, 0x20, 0xfe, 0xfc, 0xc2, 0xde, 0x83, 0xfe, 0x45, 0x62, 0x36, 0x5f, 0xdf, 0x60, 0x69, 0xde, 0x5e, 0x37, 0x19, 0xc5, 0xe8, 0x4d, 0xd3, 0x51, 0xc2, 0x2d, 0xb1, 0xe4, 0xd8, 0x8, 0xb, 0x31, 0x1e, 0x4b, 0xc4, 0x5b, 0x42, 0x4a, 0x87, 0x8e, 0x5f, 0xe5, 0x8, 0xbd, 0xb1, 0x5b, 0xb8, 0x7a, 0xe7, 0x2d, 0xe0, 0xfd, 0xaa, 0xb0, 0xbb, 0x41, 0x47, 0x70, 0x64, 0xf2, 0xab, 0x14, 0x89, 0xbd, 0xf, 0xe5, 0xe2, 0xbf, 0xa0, 0xfc, 0xd8, 0x23, 0x8a, 0x28, 0x32, 0xe3, 0x33, 0xe1, 0x4b, 0xc0, 0x7e, 0xa6, 0xff, 0x87, 0xcf, 0xb, 0x94, 0xb9, 0x37, 0x3c, 0xc6, 0xd8, 0xcd, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 }; static const unsigned char tooltip_bg_png[] = { diff --git a/scene/resources/default_theme/toggle_off_disabled.png b/scene/resources/default_theme/toggle_off_disabled.png Binary files differindex d65a9d8e64..250cd29b66 100644 --- a/scene/resources/default_theme/toggle_off_disabled.png +++ b/scene/resources/default_theme/toggle_off_disabled.png diff --git a/scene/resources/default_theme/toggle_on_disabled.png b/scene/resources/default_theme/toggle_on_disabled.png Binary files differindex ca4dbe211f..b1dacbaf32 100644 --- a/scene/resources/default_theme/toggle_on_disabled.png +++ b/scene/resources/default_theme/toggle_on_disabled.png diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 8ee9879055..2364a4a8a3 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -118,8 +118,7 @@ Error DynamicFontAtSize::_load() { int error = FT_Init_FreeType(&library); - ERR_EXPLAIN(TTR("Error initializing FreeType.")); - ERR_FAIL_COND_V(error != 0, ERR_CANT_CREATE); + ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType."); // FT_OPEN_STREAM is extremely slow only on Android. if (OS::get_singleton()->get_name() == "Android" && font->font_mem == NULL && font->font_path != String()) { @@ -177,32 +176,23 @@ Error DynamicFontAtSize::_load() { error = FT_Open_Face(library, &fargs, 0, &face); } else { - ERR_EXPLAIN("DynamicFont uninitialized"); - ERR_FAIL_V(ERR_UNCONFIGURED); + ERR_FAIL_V_MSG(ERR_UNCONFIGURED, "DynamicFont uninitialized."); } //error = FT_New_Face( library, src_path.utf8().get_data(),0,&face ); if (error == FT_Err_Unknown_File_Format) { - ERR_EXPLAIN(TTR("Unknown font format.")); + ERR_EXPLAIN("Unknown font format."); FT_Done_FreeType(library); } else if (error) { - ERR_EXPLAIN(TTR("Error loading font.")); + ERR_EXPLAIN("Error loading font."); FT_Done_FreeType(library); } ERR_FAIL_COND_V(error, ERR_FILE_CANT_OPEN); - /*error = FT_Set_Char_Size(face,0,64*size,512,512); - - if ( error ) { - FT_Done_FreeType( library ); - ERR_EXPLAIN(TTR("Invalid font size.")); - ERR_FAIL_COND_V( error, ERR_INVALID_PARAMETER ); - }*/ - if (FT_HAS_COLOR(face)) { int best_match = 0; int diff = ABS(id.size - ((int64_t)face->available_sizes[0].width)); @@ -494,7 +484,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b int byte = i * bitmap.pitch + (j >> 3); int bit = 1 << (7 - (j % 8)); wr[ofs + 0] = 255; //grayscale as 1 - wr[ofs + 1] = bitmap.buffer[byte] & bit ? 255 : 0; + wr[ofs + 1] = (bitmap.buffer[byte] & bit) ? 255 : 0; } break; case FT_PIXEL_MODE_GRAY: wr[ofs + 0] = 255; //grayscale as 1 @@ -509,8 +499,7 @@ DynamicFontAtSize::Character DynamicFontAtSize::_bitmap_to_character(FT_Bitmap b } break; // TODO: FT_PIXEL_MODE_LCD default: - ERR_EXPLAIN("Font uses unsupported pixel format: " + itos(bitmap.pixel_mode)); - ERR_FAIL_V(Character::not_found()); + ERR_FAIL_V_MSG(Character::not_found(), "Font uses unsupported pixel format: " + itos(bitmap.pixel_mode) + "."); break; } } diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 7c3867beaa..afb7f1102b 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -1047,8 +1047,8 @@ void Environment::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled"); ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_min", "get_fog_height_min"); - ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_max", "get_fog_height_max"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "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::REAL, "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::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve"); ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper); @@ -1399,15 +1399,15 @@ Environment::Environment() : fog_depth_enabled = true; fog_depth_begin = 10; - fog_depth_end = 0; + fog_depth_end = 100; fog_depth_curve = 1; fog_transmit_enabled = false; fog_transmit_curve = 1; fog_height_enabled = false; - fog_height_min = 0; - fog_height_max = 100; + fog_height_min = 10; + fog_height_max = 0; fog_height_curve = 1; set_fog_color(Color(0.5, 0.6, 0.7)); diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 627397f0ab..cff77acdd7 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -133,6 +133,7 @@ PoolVector<int> BitmapFont::_get_chars() const { while ((key = char_map.next(key))) { const Character *c = char_map.getptr(*key); + ERR_FAIL_COND_V(!c, PoolVector<int>()); chars.push_back(*key); chars.push_back(c->texture_idx); chars.push_back(c->rect.position.x); @@ -201,10 +202,7 @@ Error BitmapFont::create_from_fnt(const String &p_file) { FileAccess *f = FileAccess::open(p_file, FileAccess::READ); - if (!f) { - ERR_EXPLAIN("Can't open font: " + p_file); - ERR_FAIL_V(ERR_FILE_NOT_FOUND); - } + ERR_FAIL_COND_V_MSG(!f, ERR_FILE_NOT_FOUND, "Can't open font: " + p_file + "."); clear(); @@ -531,10 +529,7 @@ Size2 Font::get_wordwrap_string_size(const String &p_string, float p_width) cons void BitmapFont::set_fallback(const Ref<BitmapFont> &p_fallback) { for (Ref<BitmapFont> fallback_child = p_fallback; fallback_child != NULL; fallback_child = fallback_child->get_fallback()) { - if (fallback_child == this) { - ERR_EXPLAIN("Can't set as fallback one of its parents to prevent crashes due to recursive loop."); - ERR_FAIL_COND(fallback_child == this); - } + ERR_FAIL_COND_MSG(fallback_child == this, "Can't set as fallback one of its parents to prevent crashes due to recursive loop."); } fallback = p_fallback; diff --git a/scene/resources/font.h b/scene/resources/font.h index 436ed43c42..9b99b85d22 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -34,9 +34,6 @@ #include "core/map.h" #include "core/resource.h" #include "scene/resources/texture.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ class Font : public Resource { diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 197ff14b38..0de462d616 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -39,10 +39,7 @@ void Material::set_next_pass(const Ref<Material> &p_pass) { for (Ref<Material> pass_child = p_pass; pass_child != NULL; pass_child = pass_child->get_next_pass()) { - if (pass_child == this) { - ERR_EXPLAIN("Can't set as next_pass one of its parents to prevent crashes due to recursive loop."); - ERR_FAIL_COND(pass_child == this); - } + ERR_FAIL_COND_MSG(pass_child == this, "Can't set as next_pass one of its parents to prevent crashes due to recursive loop."); } if (next_pass == p_pass) @@ -691,9 +688,9 @@ void SpatialMaterial::_update_shader() { code += "\tTANGENT+= vec3(1.0,0.0,0.0) * abs(NORMAL.z);\n"; code += "\tTANGENT = normalize(TANGENT);\n"; - code += "\tBINORMAL = vec3(0.0,1.0,0.0) * abs(NORMAL.x);\n"; - code += "\tBINORMAL+= vec3(0.0,0.0,-1.0) * abs(NORMAL.y);\n"; - code += "\tBINORMAL+= vec3(0.0,1.0,0.0) * abs(NORMAL.z);\n"; + code += "\tBINORMAL = vec3(0.0,-1.0,0.0) * abs(NORMAL.x);\n"; + code += "\tBINORMAL+= vec3(0.0,0.0,1.0) * abs(NORMAL.y);\n"; + code += "\tBINORMAL+= vec3(0.0,-1.0,0.0) * abs(NORMAL.z);\n"; code += "\tBINORMAL = normalize(BINORMAL);\n"; } @@ -1775,7 +1772,7 @@ SpatialMaterial::TextureChannel SpatialMaterial::get_refraction_texture_channel( return refraction_texture_channel; } -RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass) { +RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard, bool p_billboard_y) { int version = 0; if (p_shaded) @@ -1788,6 +1785,10 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, version |= 8; if (p_double_sided) version |= 16; + if (p_billboard) + version |= 32; + if (p_billboard_y) + version |= 64; if (materials_for_2d[version].is_valid()) { return materials_for_2d[version]->get_rid(); @@ -1803,6 +1804,11 @@ RID SpatialMaterial::get_material_rid_for_2d(bool p_shaded, bool p_transparent, material->set_flag(FLAG_SRGB_VERTEX_COLOR, true); material->set_flag(FLAG_ALBEDO_FROM_VERTEX_COLOR, true); material->set_flag(FLAG_USE_ALPHA_SCISSOR, p_cut_alpha); + if (p_billboard) { + material->set_billboard_mode(BILLBOARD_ENABLED); + } else if (p_billboard_y) { + material->set_billboard_mode(BILLBOARD_FIXED_Y); + } materials_for_2d[version] = material; @@ -2353,8 +2359,8 @@ SpatialMaterial::SpatialMaterial() : set_ao_light_affect(0.0); - set_metallic_texture_channel(TEXTURE_CHANNEL_BLUE); - set_roughness_texture_channel(TEXTURE_CHANNEL_GREEN); + set_metallic_texture_channel(TEXTURE_CHANNEL_RED); + set_roughness_texture_channel(TEXTURE_CHANNEL_RED); set_ao_texture_channel(TEXTURE_CHANNEL_RED); set_refraction_texture_channel(TEXTURE_CHANNEL_RED); diff --git a/scene/resources/material.h b/scene/resources/material.h index 17e52527b3..2423d6d48b 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -37,9 +37,6 @@ #include "scene/resources/texture.h" #include "servers/visual/shader_language.h" #include "servers/visual_server.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ class Material : public Resource { @@ -440,9 +437,7 @@ private: _FORCE_INLINE_ void _validate_feature(const String &text, Feature feature, PropertyInfo &property) const; - enum { - MAX_MATERIALS_FOR_2D = 32 - }; + static const int MAX_MATERIALS_FOR_2D = 128; static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff @@ -629,7 +624,7 @@ public: static void finish_shaders(); static void flush_changes(); - static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass); + static RID get_material_rid_for_2d(bool p_shaded, bool p_transparent, bool p_double_sided, bool p_cut_alpha, bool p_opaque_prepass, bool p_billboard = false, bool p_billboard_y = false); RID get_shader_rid() const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index aff274cd21..4afb07cb6f 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -883,10 +883,7 @@ int ArrayMesh::get_surface_count() const { void ArrayMesh::add_blend_shape(const StringName &p_name) { - if (surfaces.size()) { - ERR_EXPLAIN("Can't add a shape key count if surfaces are already created."); - ERR_FAIL_COND(surfaces.size()); - } + ERR_FAIL_COND_MSG(surfaces.size(), "Can't add a shape key count if surfaces are already created."); StringName name = p_name; @@ -914,10 +911,7 @@ StringName ArrayMesh::get_blend_shape_name(int p_index) const { } void ArrayMesh::clear_blend_shapes() { - if (surfaces.size()) { - ERR_EXPLAIN("Can't set shape key count if surfaces are already created."); - ERR_FAIL_COND(surfaces.size()); - } + ERR_FAIL_COND_MSG(surfaces.size(), "Can't set shape key count if surfaces are already created."); blend_shapes.clear(); } @@ -1109,8 +1103,7 @@ struct ArrayMeshLightmapSurface { Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texel_size) { ERR_FAIL_COND_V(!array_mesh_lightmap_unwrap_callback, ERR_UNCONFIGURED); - ERR_EXPLAIN("Can't unwrap mesh with blend shapes"); - ERR_FAIL_COND_V(blend_shapes.size() != 0, ERR_UNAVAILABLE); + ERR_FAIL_COND_V_MSG(blend_shapes.size() != 0, ERR_UNAVAILABLE, "Can't unwrap mesh with blend shapes."); Vector<float> vertices; Vector<float> normals; @@ -1124,15 +1117,9 @@ Error ArrayMesh::lightmap_unwrap(const Transform &p_base_transform, float p_texe ArrayMeshLightmapSurface s; s.primitive = surface_get_primitive_type(i); - if (s.primitive != Mesh::PRIMITIVE_TRIANGLES) { - ERR_EXPLAIN("Only triangles are supported for lightmap unwrap"); - ERR_FAIL_V(ERR_UNAVAILABLE); - } + ERR_FAIL_COND_V_MSG(s.primitive != Mesh::PRIMITIVE_TRIANGLES, ERR_UNAVAILABLE, "Only triangles are supported for lightmap unwrap."); s.format = surface_get_format(i); - if (!(s.format & ARRAY_FORMAT_NORMAL)) { - ERR_EXPLAIN("Normals are required for lightmap unwrap"); - ERR_FAIL_V(ERR_UNAVAILABLE); - } + ERR_FAIL_COND_V_MSG(!(s.format & ARRAY_FORMAT_NORMAL), ERR_UNAVAILABLE, "Normals are required for lightmap unwrap."); Array arrays = surface_get_arrays(i); s.material = surface_get_material(i); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index b38791b9a6..6b6ee8a209 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -37,9 +37,6 @@ #include "scene/resources/material.h" #include "scene/resources/shape.h" #include "servers/visual_server.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ class Mesh : public Resource { GDCLASS(Mesh, Resource); diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 7cd765fb5d..0c39c3cbb1 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -165,11 +165,12 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf e.vertex[0] = edge.x; e.vertex[1] = edge.y; edges.push_back(e); + v[j]->edges.push_back(face.edges[j]); + v[(j + 1) % 3]->edges.push_back(face.edges[j]); } edges.write[face.edges[j]].faces.push_back(fidx); v[j]->faces.push_back(fidx); - v[j]->edges.push_back(face.edges[j]); } faces.push_back(face); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 99286668ce..7d62873bbd 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -92,8 +92,7 @@ Node *SceneState::instance(GenEditState p_edit_state) const { if (i > 0) { - ERR_EXPLAIN(vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name])); - ERR_FAIL_COND_V(n.parent == -1, NULL); + ERR_FAIL_COND_V_MSG(n.parent == -1, NULL, vformat("Invalid scene: node %s does not specify its parent node.", snames[n.name])); NODE_FROM_ID(nparent, n.parent); #ifdef DEBUG_ENABLED if (!nparent && (n.parent & FLAG_ID_IS_PATH)) { @@ -1093,10 +1092,7 @@ void SceneState::set_bundled_scene(const Dictionary &p_dictionary) { if (p_dictionary.has("version")) version = p_dictionary["version"]; - if (version > PACK_VERSION) { - ERR_EXPLAIN("Save format version too new!"); - ERR_FAIL(); - } + ERR_FAIL_COND_MSG(version > PACK_VERSION, "Save format version too new."); PoolVector<String> snames = p_dictionary["names"]; if (snames.size()) { @@ -1690,10 +1686,7 @@ bool PackedScene::can_instance() const { Node *PackedScene::instance(GenEditState p_edit_state) const { #ifndef TOOLS_ENABLED - if (p_edit_state != GEN_EDIT_STATE_DISABLED) { - ERR_EXPLAIN("Edit state is only for editors, does not work without tools compiled"); - ERR_FAIL_COND_V(p_edit_state != GEN_EDIT_STATE_DISABLED, NULL); - } + ERR_FAIL_COND_V_MSG(p_edit_state != GEN_EDIT_STATE_DISABLED, NULL, "Edit state is only for editors, does not work without tools compiled."); #endif Node *s = state->instance((SceneState::GenEditState)p_edit_state); diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp index b4818755b4..dc6ef2b49c 100644 --- a/scene/resources/particles_material.cpp +++ b/scene/resources/particles_material.cpp @@ -101,6 +101,8 @@ void ParticlesMaterial::init_shaders() { shader_names->trail_color_modifier = "trail_color_modifier"; shader_names->gravity = "gravity"; + + shader_names->lifetime_randomness = "lifetime_randomness"; } void ParticlesMaterial::finish_shaders() { @@ -173,6 +175,7 @@ void ParticlesMaterial::_update_shader() { code += "uniform float hue_variation_random;\n"; code += "uniform float anim_speed_random;\n"; code += "uniform float anim_offset_random;\n"; + code += "uniform float lifetime_randomness;\n"; switch (emission_shape) { case EMISSION_SHAPE_POINT: { @@ -285,7 +288,11 @@ 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 += " if (RESTART) {\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"; @@ -325,6 +332,7 @@ void ParticlesMaterial::_update_shader() { 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 code += " CUSTOM.y = 0.0;\n"; // phase + code += " CUSTOM.w = LIFETIME * (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) switch (emission_shape) { @@ -576,6 +584,9 @@ void ParticlesMaterial::_update_shader() { code += " VELOCITY.z = 0.0;\n"; code += " TRANSFORM[3].z = 0.0;\n"; } + code += " if (CUSTOM.y > CUSTOM.w) {"; + code += " ACTIVE = false;\n"; + code += " }\n"; code += "}\n"; code += "\n"; @@ -1014,6 +1025,17 @@ Vector3 ParticlesMaterial::get_gravity() const { return gravity; } +void ParticlesMaterial::set_lifetime_randomness(float p_lifetime) { + + lifetime_randomness = p_lifetime; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->lifetime_randomness, lifetime_randomness); +} + +float ParticlesMaterial::get_lifetime_randomness() const { + + return lifetime_randomness; +} + RID ParticlesMaterial::get_shader_rid() const { ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); @@ -1118,6 +1140,11 @@ void ParticlesMaterial::_bind_methods() { 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); + + ADD_GROUP("Time", ""); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "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"); @@ -1240,6 +1267,7 @@ ParticlesMaterial::ParticlesMaterial() : 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; for (int i = 0; i < PARAM_MAX; i++) { diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h index 7f11bd794b..6fe381db0a 100644 --- a/scene/resources/particles_material.h +++ b/scene/resources/particles_material.h @@ -185,6 +185,8 @@ private: StringName trail_color_modifier; StringName gravity; + + StringName lifetime_randomness; }; static ShaderNames *shader_names; @@ -225,6 +227,8 @@ private: Vector3 gravity; + float lifetime_randomness; + //do not save emission points here protected: @@ -287,6 +291,9 @@ public: void set_gravity(const Vector3 &p_gravity); Vector3 get_gravity() const; + void set_lifetime_randomness(float p_lifetime); + float get_lifetime_randomness() const; + static void init_shaders(); static void finish_shaders(); static void flush_changes(); diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 74a493d3b5..24fdaafbe1 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -1572,3 +1572,19 @@ SphereMesh::SphereMesh() { rings = 32; is_hemisphere = false; } + +/** + PointMesh +*/ + +void PointMesh::_create_mesh_array(Array &p_arr) const { + PoolVector<Vector3> faces; + faces.resize(1); + faces.set(0, Vector3(0.0, 0.0, 0.0)); + + p_arr[VS::ARRAY_VERTEX] = faces; +} + +PointMesh::PointMesh() { + primitive_type = PRIMITIVE_POINTS; +} diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h index 312899c028..fad49f9642 100644 --- a/scene/resources/primitive_meshes.h +++ b/scene/resources/primitive_meshes.h @@ -322,4 +322,19 @@ public: SphereMesh(); }; +/** + A single point for use in particle systems +*/ + +class PointMesh : public PrimitiveMesh { + + GDCLASS(PointMesh, PrimitiveMesh) + +protected: + virtual void _create_mesh_array(Array &p_arr) const; + +public: + PointMesh(); +}; + #endif diff --git a/scene/resources/resource_format_text.cpp b/scene/resources/resource_format_text.cpp index 12bf007bb1..1c41f30a94 100644 --- a/scene/resources/resource_format_text.cpp +++ b/scene/resources/resource_format_text.cpp @@ -1366,13 +1366,10 @@ String ResourceFormatSaverTextInstance::_write_resource(const RES &res) { String path = relative_paths ? local_path.path_to_file(res->get_path()) : res->get_path(); return "Resource( \"" + path + "\" )"; } else { - ERR_EXPLAIN("Resource was not pre cached for the resource section, bug?"); - ERR_FAIL_V("null"); + ERR_FAIL_V_MSG("null", "Resource was not pre cached for the resource section, bug?"); //internal resource } } - - return "null"; } void ResourceFormatSaverTextInstance::_find_resources(const Variant &p_variant, bool p_main) { @@ -1514,8 +1511,6 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } } - ERR_FAIL_COND_V(err != OK, err); - { String title = packed_scene.is_valid() ? "[gd_scene " : "[gd_resource "; if (packed_scene.is_null()) @@ -1718,6 +1713,7 @@ Error ResourceFormatSaverTextInstance::save(const String &p_path, const RES &p_r } if (groups.size()) { + groups.sort_custom<StringName::AlphCompare>(); String sgroups = " groups=[\n"; for (int j = 0; j < groups.size(); j++) { sgroups += "\"" + String(groups[j]).c_escape() + "\",\n"; diff --git a/scene/resources/room.h b/scene/resources/room.h index 8990056f46..2c53ea1aed 100644 --- a/scene/resources/room.h +++ b/scene/resources/room.h @@ -33,9 +33,6 @@ #include "core/math/bsp_tree.h" #include "core/resource.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ // FIXME: left for reference but will be removed when portals are reimplemented using Area #if 0 diff --git a/scene/resources/skin.cpp b/scene/resources/skin.cpp new file mode 100644 index 0000000000..8446e2f249 --- /dev/null +++ b/scene/resources/skin.cpp @@ -0,0 +1,102 @@ +#include "skin.h" + +void Skin::set_bind_count(int p_size) { + ERR_FAIL_COND(p_size < 0); + binds.resize(p_size); + binds_ptr = binds.ptrw(); + bind_count = p_size; + emit_changed(); +} + +void Skin::add_bind(int p_bone, const Transform &p_pose) { + uint32_t index = bind_count; + set_bind_count(bind_count + 1); + set_bind_bone(index, p_bone); + set_bind_pose(index, p_pose); +} + +void Skin::set_bind_bone(int p_index, int p_bone) { + ERR_FAIL_INDEX(p_index, bind_count); + binds_ptr[p_index].bone = p_bone; + emit_changed(); +} + +void Skin::set_bind_pose(int p_index, const Transform &p_pose) { + ERR_FAIL_INDEX(p_index, bind_count); + binds_ptr[p_index].pose = p_pose; + emit_changed(); +} + +void Skin::clear_binds() { + binds.clear(); + binds_ptr = nullptr; + bind_count = 0; + emit_changed(); +} + +bool Skin::_set(const StringName &p_name, const Variant &p_value) { + String name = p_name; + if (name == "bind_count") { + set_bind_count(p_value); + return true; + } else if (name.begins_with("bind/")) { + int index = name.get_slicec('/', 1).to_int(); + String what = name.get_slicec('/', 2); + if (what == "bone") { + set_bind_bone(index, p_value); + return true; + } else if (what == "pose") { + set_bind_pose(index, p_value); + return true; + } + } + return false; +} + +bool Skin::_get(const StringName &p_name, Variant &r_ret) const { + + String name = p_name; + if (name == "bind_count") { + r_ret = get_bind_count(); + return true; + } else if (name.begins_with("bind/")) { + int index = name.get_slicec('/', 1).to_int(); + String what = name.get_slicec('/', 2); + if (what == "bone") { + r_ret = get_bind_bone(index); + return true; + } else if (what == "pose") { + r_ret = get_bind_pose(index); + return true; + } + } + return false; +} +void Skin::_get_property_list(List<PropertyInfo> *p_list) const { + p_list->push_back(PropertyInfo(Variant::INT, "bind_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater")); + for (int i = 0; i < get_bind_count(); i++) { + p_list->push_back(PropertyInfo(Variant::INT, "bind/" + itos(i) + "/bone", PROPERTY_HINT_RANGE, "0,16384,1,or_greater")); + p_list->push_back(PropertyInfo(Variant::TRANSFORM, "bind/" + itos(i) + "/pose")); + } +} + +void Skin::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_bind_count", "bind_count"), &Skin::set_bind_count); + ClassDB::bind_method(D_METHOD("get_bind_count"), &Skin::get_bind_count); + + ClassDB::bind_method(D_METHOD("add_bind", "bone", "pose"), &Skin::add_bind); + + ClassDB::bind_method(D_METHOD("set_bind_pose", "bind_index", "pose"), &Skin::set_bind_pose); + ClassDB::bind_method(D_METHOD("get_bind_pose", "bind_index"), &Skin::get_bind_pose); + + ClassDB::bind_method(D_METHOD("set_bind_bone", "bind_index", "bone"), &Skin::set_bind_bone); + ClassDB::bind_method(D_METHOD("get_bind_bone", "bind_index"), &Skin::get_bind_bone); + + ClassDB::bind_method(D_METHOD("clear_binds"), &Skin::clear_binds); +} + +Skin::Skin() { + bind_count = 0; + binds_ptr = nullptr; +} diff --git a/scene/resources/skin.h b/scene/resources/skin.h new file mode 100644 index 0000000000..a7e55bfa89 --- /dev/null +++ b/scene/resources/skin.h @@ -0,0 +1,54 @@ +#ifndef SKIN_H +#define SKIN_H + +#include "core/resource.h" + +class Skin : public Resource { + GDCLASS(Skin, Resource) + + struct Bind { + int bone; + Transform pose; + }; + + Vector<Bind> binds; + + Bind *binds_ptr; + int bind_count; + +protected: + bool _set(const StringName &p_name, const Variant &p_value); + bool _get(const StringName &p_name, Variant &r_ret) const; + void _get_property_list(List<PropertyInfo> *p_list) const; + + static void _bind_methods(); + +public: + void set_bind_count(int p_size); + inline int get_bind_count() const { return bind_count; } + + void add_bind(int p_bone, const Transform &p_pose); + + void set_bind_bone(int p_index, int p_bone); + void set_bind_pose(int p_index, const Transform &p_pose); + + inline int get_bind_bone(int p_index) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_INDEX_V(p_index, bind_count, -1); +#endif + return binds_ptr[p_index].bone; + } + + inline Transform get_bind_pose(int p_index) const { +#ifdef DEBUG_ENABLED + ERR_FAIL_INDEX_V(p_index, bind_count, Transform()); +#endif + return binds_ptr[p_index].pose; + } + + void clear_binds(); + + Skin(); +}; + +#endif // SKIN_H diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp index 5dd429fa75..4453032f67 100644 --- a/scene/resources/style_box.cpp +++ b/scene/resources/style_box.cpp @@ -713,6 +713,7 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { Vector<Point2> verts; Vector<int> indices; Vector<Color> colors; + Vector<Point2> uvs; //DRAW SHADOW if (draw_shadow) { @@ -799,9 +800,17 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const { } } + //COMPUTE UV COORDINATES + Rect2 uv_rect = style_rect.grow(aa_on ? aa_size : 0); + uvs.resize(verts.size()); + for (int i = 0; i < verts.size(); i++) { + uvs.write[i].x = (verts[i].x - uv_rect.position.x) / uv_rect.size.width; + uvs.write[i].y = (verts[i].y - uv_rect.position.y) / uv_rect.size.height; + } + //DRAWING VisualServer *vs = VisualServer::get_singleton(); - vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors); + vs->canvas_item_add_triangle_array(p_canvas_item, indices, verts, colors, uvs); } float StyleBoxFlat::get_style_margin(Margin p_margin) const { diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index c3965fe076..d02e107480 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -34,9 +34,7 @@ #include "core/resource.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ + class CanvasItem; class StyleBox : public Resource { diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index 37bdd691b4..b84f3f1f9e 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -67,10 +67,7 @@ Error TextFile::load_text(const String &p_path) { w[len] = 0; String s; - if (s.parse_utf8((const char *)w.ptr())) { - ERR_EXPLAIN("Script '" + p_path + "' contains invalid unicode (utf-8), so it was not loaded. Please ensure that scripts are saved in valid utf-8 unicode."); - ERR_FAIL_V(ERR_INVALID_DATA); - } + ERR_FAIL_COND_V_MSG(s.parse_utf8((const char *)w.ptr()), ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode."); text = s; path = p_path; return OK; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index a5e9351753..e44b17584b 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -2351,8 +2351,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String texarr.instance(); lt = texarr; } else { - ERR_EXPLAIN("Unrecognized layered texture extension"); - ERR_FAIL_V(RES()); + ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture extension."); } FileAccess *f = FileAccess::open(p_path, FileAccess::READ); @@ -2373,8 +2372,7 @@ RES ResourceFormatLoaderTextureLayered::load(const String &p_path, const String } } else { - ERR_EXPLAIN("Unrecognized layered texture file format: " + String((const char *)header)); - ERR_FAIL_V(RES()); + ERR_FAIL_V_MSG(RES(), "Unrecognized layered texture file format: " + String((const char *)header) + "."); } int tw = f->get_32(); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index eb7a9ff25c..e535f7544a 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -42,10 +42,6 @@ #include "servers/camera_server.h" #include "servers/visual_server.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ - class Texture : public Resource { GDCLASS(Texture, Resource); diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index 69258bc834..ae18be1695 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -32,8 +32,6 @@ #include "core/os/file_access.h" #include "core/print_string.h" -Ref<Theme> Theme::default_theme; - void Theme::_emit_theme_changed() { emit_changed(); @@ -186,11 +184,6 @@ void Theme::_get_property_list(List<PropertyInfo> *p_list) const { } } -Ref<Theme> Theme::get_default() { - - return default_theme; -} - void Theme::set_default_theme_font(const Ref<Font> &p_default_font) { if (default_theme_font == p_default_font) @@ -215,14 +208,31 @@ Ref<Font> Theme::get_default_theme_font() const { return default_theme_font; } +Ref<Theme> Theme::project_default_theme; +Ref<Theme> Theme::default_theme; +Ref<Texture> Theme::default_icon; +Ref<StyleBox> Theme::default_style; +Ref<Font> Theme::default_font; + +Ref<Theme> Theme::get_default() { + + return default_theme; +} + void Theme::set_default(const Ref<Theme> &p_default) { default_theme = p_default; } -Ref<Texture> Theme::default_icon; -Ref<StyleBox> Theme::default_style; -Ref<Font> Theme::default_font; +Ref<Theme> Theme::get_project_default() { + + return project_default_theme; +} + +void Theme::set_project_default(const Ref<Theme> &p_project_default) { + + project_default_theme = p_project_default; +} void Theme::set_default_icon(const Ref<Texture> &p_icon) { diff --git a/scene/resources/theme.h b/scene/resources/theme.h index fb59073cbe..187694de65 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -38,15 +38,11 @@ #include "scene/resources/style_box.h" #include "scene/resources/texture.h" -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ class Theme : public Resource { GDCLASS(Theme, Resource); RES_BASE_EXTENSION("theme"); - static Ref<Theme> default_theme; void _emit_theme_changed(); HashMap<StringName, HashMap<StringName, Ref<Texture> > > icon_map; @@ -61,6 +57,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List<PropertyInfo> *p_list) const; + static Ref<Theme> project_default_theme; + static Ref<Theme> default_theme; static Ref<Texture> default_icon; static Ref<StyleBox> default_style; static Ref<Font> default_font; @@ -137,6 +135,9 @@ public: static Ref<Theme> get_default(); static void set_default(const Ref<Theme> &p_default); + static Ref<Theme> get_project_default(); + static void set_project_default(const Ref<Theme> &p_project_default); + static void set_default_icon(const Ref<Texture> &p_icon); static void set_default_style(const Ref<StyleBox> &p_style); static void set_default_font(const Ref<Font> &p_font); diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index bd5ce91e77..24122a8d99 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -148,15 +148,20 @@ bool TileSet::_set(const StringName &p_name, const Variant &p_value) { } } } else if (what == "shape") - tile_set_shape(id, 0, p_value); + for (int i = 0; i < tile_get_shape_count(id); i++) + tile_set_shape(id, i, p_value); else if (what == "shape_offset") - tile_set_shape_offset(id, 0, p_value); + for (int i = 0; i < tile_get_shape_count(id); i++) + tile_set_shape_offset(id, i, p_value); else if (what == "shape_transform") - tile_set_shape_transform(id, 0, p_value); + for (int i = 0; i < tile_get_shape_count(id); i++) + tile_set_shape_transform(id, i, p_value); else if (what == "shape_one_way") - tile_set_shape_one_way(id, 0, p_value); + for (int i = 0; i < tile_get_shape_count(id); i++) + tile_set_shape_one_way(id, i, p_value); else if (what == "shape_one_way_margin") - tile_set_shape_one_way_margin(id, 0, p_value); + for (int i = 0; i < tile_get_shape_count(id); i++) + tile_set_shape_one_way_margin(id, i, p_value); else if (what == "shapes") _tile_set_shapes(id, p_value); else if (what == "occluder") @@ -1001,8 +1006,7 @@ void TileSet::_tile_set_shapes(int p_id, const Array &p_shapes) { s.autotile_coord = default_autotile_coord; } else { - ERR_EXPLAIN("Expected an array of objects or dictionaries for tile_set_shapes"); - ERR_CONTINUE(true); + ERR_CONTINUE_MSG(true, "Expected an array of objects or dictionaries for tile_set_shapes."); } shapes_data.push_back(s); diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index 7265c9b457..f5ea6adc85 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -67,6 +67,14 @@ String VisualShaderNode::generate_global(Shader::Mode p_mode, VisualShader::Type return String(); } +String VisualShaderNode::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return String(); +} + +String VisualShaderNode::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return String(); +} + Vector<StringName> VisualShaderNode::get_editable_properties() const { return Vector<StringName>(); } @@ -109,6 +117,12 @@ void VisualShaderNode::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "output_port_for_preview"), "set_output_port_for_preview", "get_output_port_for_preview"); ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "default_input_values", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_default_input_values", "_get_default_input_values"); ADD_SIGNAL(MethodInfo("editor_refresh_request")); + + BIND_ENUM_CONSTANT(PORT_TYPE_SCALAR); + BIND_ENUM_CONSTANT(PORT_TYPE_VECTOR); + BIND_ENUM_CONSTANT(PORT_TYPE_BOOLEAN); + BIND_ENUM_CONSTANT(PORT_TYPE_TRANSFORM); + BIND_ENUM_CONSTANT(PORT_TYPE_ICON_COLOR); } VisualShaderNode::VisualShaderNode() { @@ -117,6 +131,147 @@ VisualShaderNode::VisualShaderNode() { ///////////////////////////////////////////////////////// +void VisualShaderNodeCustom::update_ports() { + ERR_FAIL_COND(!get_script_instance()); + + input_ports.clear(); + if (get_script_instance()->has_method("_get_input_port_count")) { + int input_port_count = (int)get_script_instance()->call("_get_input_port_count"); + bool has_name = get_script_instance()->has_method("_get_input_port_name"); + bool has_type = get_script_instance()->has_method("_get_input_port_type"); + for (int i = 0; i < input_port_count; i++) { + Port port; + if (has_name) { + port.name = (String)get_script_instance()->call("_get_input_port_name", i); + } else { + port.name = "in" + itos(i); + } + if (has_type) { + port.type = (int)get_script_instance()->call("_get_input_port_type", i); + } else { + port.type = (int)PortType::PORT_TYPE_SCALAR; + } + input_ports.push_back(port); + } + } + output_ports.clear(); + if (get_script_instance()->has_method("_get_output_port_count")) { + int output_port_count = (int)get_script_instance()->call("_get_output_port_count"); + bool has_name = get_script_instance()->has_method("_get_output_port_name"); + bool has_type = get_script_instance()->has_method("_get_output_port_type"); + for (int i = 0; i < output_port_count; i++) { + Port port; + if (has_name) { + port.name = (String)get_script_instance()->call("_get_output_port_name", i); + } else { + port.name = "out" + itos(i); + } + if (has_type) { + port.type = (int)get_script_instance()->call("_get_output_port_type", i); + } else { + port.type = (int)PortType::PORT_TYPE_SCALAR; + } + output_ports.push_back(port); + } + } +} + +String VisualShaderNodeCustom::get_caption() const { + ERR_FAIL_COND_V(!get_script_instance(), ""); + if (get_script_instance()->has_method("_get_name")) { + return (String)get_script_instance()->call("_get_name"); + } + return "Unnamed"; +} + +int VisualShaderNodeCustom::get_input_port_count() const { + return input_ports.size(); +} + +VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_input_port_type(int p_port) const { + ERR_FAIL_INDEX_V(p_port, input_ports.size(), PORT_TYPE_SCALAR); + return (PortType)input_ports[p_port].type; +} + +String VisualShaderNodeCustom::get_input_port_name(int p_port) const { + ERR_FAIL_INDEX_V(p_port, input_ports.size(), ""); + return input_ports[p_port].name; +} + +int VisualShaderNodeCustom::get_output_port_count() const { + return output_ports.size(); +} + +VisualShaderNodeCustom::PortType VisualShaderNodeCustom::get_output_port_type(int p_port) const { + ERR_FAIL_INDEX_V(p_port, output_ports.size(), PORT_TYPE_SCALAR); + return (PortType)output_ports[p_port].type; +} + +String VisualShaderNodeCustom::get_output_port_name(int p_port) const { + ERR_FAIL_INDEX_V(p_port, output_ports.size(), ""); + return output_ports[p_port].name; +} + +String VisualShaderNodeCustom::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 { + + ERR_FAIL_COND_V(!get_script_instance(), ""); + ERR_FAIL_COND_V(!get_script_instance()->has_method("_get_code"), ""); + Array input_vars; + for (int i = 0; i < get_input_port_count(); i++) { + input_vars.push_back(p_input_vars[i]); + } + Array output_vars; + for (int i = 0; i < get_output_port_count(); i++) { + output_vars.push_back(p_output_vars[i]); + } + String code = "\t{\n"; + String _code = (String)get_script_instance()->call("_get_code", input_vars, output_vars, (int)p_mode, (int)p_type); + bool nend = _code.ends_with("\n"); + _code = _code.insert(0, "\t\t"); + _code = _code.replace("\n", "\n\t\t"); + code += _code; + if (!nend) { + code += "\n\t}"; + } else { + code.remove(code.size() - 1); + code += "}"; + } + return code; +} + +String VisualShaderNodeCustom::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + ERR_FAIL_COND_V(!get_script_instance(), ""); + if (get_script_instance()->has_method("_get_global_code")) { + String code = "// " + get_caption() + "\n"; + code += (String)get_script_instance()->call("_get_global_code", (int)p_mode); + code += "\n"; + return code; + } + return ""; +} + +void VisualShaderNodeCustom::_bind_methods() { + + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_name")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_description")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_category")); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_subcategory")); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_return_icon_type")); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_count")); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_input_port_type", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_input_port_name", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_count")); + BIND_VMETHOD(MethodInfo(Variant::INT, "_get_output_port_type", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_output_port_name", PropertyInfo(Variant::INT, "port"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_code", PropertyInfo(Variant::ARRAY, "input_vars"), PropertyInfo(Variant::ARRAY, "output_vars"), PropertyInfo(Variant::INT, "mode"), PropertyInfo(Variant::INT, "type"))); + BIND_VMETHOD(MethodInfo(Variant::STRING, "_get_global_code", PropertyInfo(Variant::INT, "mode"))); +} + +VisualShaderNodeCustom::VisualShaderNodeCustom() { +} + +///////////////////////////////////////////////////////// + void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, const Vector2 &p_position, int p_id) { ERR_FAIL_COND(p_node.is_null()); ERR_FAIL_COND(p_id < 2); @@ -142,6 +297,11 @@ void VisualShader::add_node(Type p_type, const Ref<VisualShaderNode> &p_node, co n.node->connect("changed", this, "_queue_update"); + Ref<VisualShaderNodeCustom> custom = n.node; + if (custom.is_valid()) { + custom->update_ports(); + } + g->nodes[p_id] = n; _queue_update(); @@ -299,11 +459,7 @@ Error VisualShader::connect_nodes(Type p_type, int p_from_node, int p_from_port, VisualShaderNode::PortType from_port_type = g->nodes[p_from_node].node->get_output_port_type(p_from_port); VisualShaderNode::PortType to_port_type = g->nodes[p_to_node].node->get_input_port_type(p_to_port); - if (!is_port_types_compatible(from_port_type, to_port_type)) { - ERR_EXPLAIN("Incompatible port types (scalar/vec/bool) with transform"); - ERR_FAIL_V(ERR_INVALID_PARAMETER); - return ERR_INVALID_PARAMETER; - } + ERR_FAIL_COND_V_MSG(!is_port_types_compatible(from_port_type, to_port_type), ERR_INVALID_PARAMETER, "Incompatible port types (scalar/vec/bool) with transform."); for (List<Connection>::Element *E = g->connections.front(); E; E = E->next()) { @@ -449,10 +605,32 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port ERR_FAIL_COND_V(node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_TRANSFORM, String()); StringBuilder global_code; + StringBuilder global_code_per_node; + Map<Type, StringBuilder> global_code_per_func; StringBuilder code; + Set<StringName> classes; global_code += String() + "shader_type canvas_item;\n"; + String global_expressions; + for (int i = 0, index = 0; i < TYPE_MAX; i++) { + for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { + Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr()); + if (global_expression.is_valid()) { + + String expr = ""; + expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; + expr += global_expression->generate_global(get_mode(), Type(i), -1); + expr = expr.replace("\n", "\n\t"); + expr += "\n"; + global_expressions += expr; + } + } + } + + global_code += "\n"; + global_code += global_expressions; + //make it faster to go around through shader VMap<ConnectionKey, const List<Connection>::Element *> input_connections; VMap<ConnectionKey, const List<Connection>::Element *> output_connections; @@ -474,7 +652,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port code += "\nvoid fragment() {\n"; Set<int> processed; - Error err = _write_node(p_type, global_code, code, default_tex_params, input_connections, output_connections, p_node, processed, true); + Error err = _write_node(p_type, global_code, global_code_per_node, global_code_per_func, code, default_tex_params, input_connections, output_connections, p_node, processed, true, classes); ERR_FAIL_COND_V(err != OK, String()); if (node->get_output_port_type(p_port) == VisualShaderNode::PORT_TYPE_SCALAR) { @@ -489,6 +667,7 @@ String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port //set code secretly global_code += "\n\n"; String final_code = global_code; + final_code += global_code_per_node; final_code += code; return final_code; } @@ -833,7 +1012,7 @@ void VisualShader::_get_property_list(List<PropertyInfo> *p_list) const { } } -Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &code, Vector<VisualShader::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) const { +Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBuilder &global_code_per_node, Map<Type, StringBuilder> &global_code_per_func, StringBuilder &code, Vector<VisualShader::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 { const Ref<VisualShaderNode> vsnode = graph[type].nodes[node].node; @@ -850,7 +1029,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui continue; } - Error err = _write_node(type, global_code, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview); + Error err = _write_node(type, global_code, global_code_per_node, global_code_per_func, code, def_tex_params, input_connections, output_connections, from_node, processed, for_preview, r_classes); if (err) return err; } @@ -904,7 +1083,7 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui } else if (defval.get_type() == Variant::BOOL) { bool val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); - code += "\nbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n"; + code += "\tbool " + inputs[i] + " = " + (val ? "true" : "false") + ";\n"; } else if (defval.get_type() == Variant::VECTOR3) { Vector3 val = defval; inputs[i] = "n_in" + itos(node) + "p" + itos(i); @@ -957,10 +1136,18 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui bool skip_global = input.is_valid() && for_preview; if (!skip_global) { + global_code += vsnode->generate_global(get_mode(), type, node); + + if (!r_classes.has(vsnode->get_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(vsnode->get_class_name()); + } } - //handle normally code += vsnode->generate_code(get_mode(), type, node, inputs, outputs, for_preview); code += "\n"; // @@ -976,8 +1163,12 @@ void VisualShader::_update_shader() const { dirty = false; StringBuilder global_code; + StringBuilder global_code_per_node; + Map<Type, StringBuilder> global_code_per_func; StringBuilder code; Vector<VisualShader::DefaultTextureParam> default_tex_params; + Set<StringName> classes; + List<int> insertion_pos; static const char *shader_mode_str[Shader::MODE_MAX] = { "spatial", "canvas_item", "particles" }; global_code += String() + "shader_type " + shader_mode_str[shader_mode] + ";\n"; @@ -1033,6 +1224,22 @@ void VisualShader::_update_shader() const { static const char *func_name[TYPE_MAX] = { "vertex", "fragment", "light" }; + String global_expressions; + for (int i = 0, index = 0; i < TYPE_MAX; i++) { + for (Map<int, Node>::Element *E = graph[i].nodes.front(); E; E = E->next()) { + Ref<VisualShaderNodeGlobalExpression> global_expression = Object::cast_to<VisualShaderNodeGlobalExpression>(E->get().node.ptr()); + if (global_expression.is_valid()) { + + String expr = ""; + expr += "// " + global_expression->get_caption() + ":" + itos(index++) + "\n"; + expr += global_expression->generate_global(get_mode(), Type(i), -1); + expr = expr.replace("\n", "\n\t"); + expr += "\n"; + global_expressions += expr; + } + } + } + for (int i = 0; i < TYPE_MAX; i++) { //make it faster to go around through shader @@ -1056,8 +1263,9 @@ void VisualShader::_update_shader() const { code += "\nvoid " + String(func_name[i]) + "() {\n"; Set<int> processed; - Error err = _write_node(Type(i), global_code, code, default_tex_params, input_connections, output_connections, NODE_ID_OUTPUT, processed, false); + 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); ERR_FAIL_COND(err != OK); + insertion_pos.push_back(code.get_string_length()); code += "}\n"; } @@ -1065,11 +1273,22 @@ void VisualShader::_update_shader() const { //set code secretly global_code += "\n\n"; String final_code = global_code; - final_code += code; + final_code += global_code_per_node; + final_code += global_expressions; + String tcode = code; + for (int i = 0; i < TYPE_MAX; i++) { + tcode = tcode.insert(insertion_pos[i], global_code_per_func[Type(i)]); + } + final_code += tcode; + const_cast<VisualShader *>(this)->set_code(final_code); for (int i = 0; i < default_tex_params.size(); i++) { const_cast<VisualShader *>(this)->set_default_texture_param(default_tex_params[i].name, default_tex_params[i].param); } + if (previous_code != final_code) { + const_cast<VisualShader *>(this)->emit_signal("changed"); + } + previous_code = final_code; } void VisualShader::_queue_update() { @@ -1180,6 +1399,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, // Spatial, Fragment { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, @@ -1204,6 +1424,8 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_FRAGMENT, VisualShaderNode::PORT_TYPE_BOOLEAN, "front_facing", "FRONT_FACING" }, // Spatial, Light { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "fragcoord", "FRAGCOORD.xyz" }, @@ -1225,6 +1447,7 @@ const VisualShaderNodeInput::Port VisualShaderNodeInput::ports[] = { { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_TRANSFORM, "inv_projection", "INV_PROJECTION_MATRIX" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_SCALAR, "time", "TIME" }, { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_VECTOR, "viewport_size", "vec3(VIEWPORT_SIZE, 0.0)" }, + { Shader::MODE_SPATIAL, VisualShader::TYPE_LIGHT, VisualShaderNode::PORT_TYPE_BOOLEAN, "output_is_srgb", "OUTPUT_IS_SRGB" }, // Canvas Item, Vertex { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "vertex", "vec3(VERTEX,0.0)" }, { Shader::MODE_CANVAS_ITEM, VisualShader::TYPE_VERTEX, VisualShaderNode::PORT_TYPE_VECTOR, "uv", "vec3(UV,0.0)" }, @@ -2154,6 +2377,14 @@ void VisualShaderNodeGroupBase::_apply_port_changes() { } } +void VisualShaderNodeGroupBase::set_editable(bool p_enabled) { + editable = p_enabled; +} + +bool VisualShaderNodeGroupBase::is_editable() const { + return editable; +} + void VisualShaderNodeGroupBase::_bind_methods() { ClassDB::bind_method(D_METHOD("set_size", "size"), &VisualShaderNodeGroupBase::set_size); @@ -2189,6 +2420,11 @@ void VisualShaderNodeGroupBase::_bind_methods() { ClassDB::bind_method(D_METHOD("set_control", "control", "index"), &VisualShaderNodeGroupBase::set_control); ClassDB::bind_method(D_METHOD("get_control", "index"), &VisualShaderNodeGroupBase::get_control); + + ClassDB::bind_method(D_METHOD("set_editable", "enabled"), &VisualShaderNodeGroupBase::set_editable); + ClassDB::bind_method(D_METHOD("is_editable"), &VisualShaderNodeGroupBase::is_editable); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "editable"), "set_editable", "is_editable"); } 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 { @@ -2199,6 +2435,7 @@ VisualShaderNodeGroupBase::VisualShaderNodeGroupBase() { size = Size2(0, 0); inputs = ""; outputs = ""; + editable = false; } ////////////// Expression @@ -2229,8 +2466,11 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad static Vector<String> pre_symbols; if (pre_symbols.empty()) { pre_symbols.push_back("\t"); + pre_symbols.push_back(","); + pre_symbols.push_back(";"); pre_symbols.push_back("{"); pre_symbols.push_back("["); + pre_symbols.push_back("]"); pre_symbols.push_back("("); pre_symbols.push_back(" "); pre_symbols.push_back("-"); @@ -2245,11 +2485,12 @@ String VisualShaderNodeExpression::generate_code(Shader::Mode p_mode, VisualShad static Vector<String> post_symbols; if (post_symbols.empty()) { - post_symbols.push_back("\0"); post_symbols.push_back("\t"); post_symbols.push_back("\n"); + post_symbols.push_back(","); post_symbols.push_back(";"); post_symbols.push_back("}"); + post_symbols.push_back("["); post_symbols.push_back("]"); post_symbols.push_back(")"); post_symbols.push_back(" "); @@ -2324,4 +2565,19 @@ void VisualShaderNodeExpression::_bind_methods() { VisualShaderNodeExpression::VisualShaderNodeExpression() { expression = ""; + set_editable(true); +} + +////////////// Global Expression + +String VisualShaderNodeGlobalExpression::get_caption() const { + return "GlobalExpression"; +} + +String VisualShaderNodeGlobalExpression::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + return expression; +} + +VisualShaderNodeGlobalExpression::VisualShaderNodeGlobalExpression() { + set_editable(false); } diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 83db51b1b0..45beb8e6ca 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -73,6 +73,7 @@ private: } graph[TYPE_MAX]; Shader::Mode shader_mode; + mutable String previous_code; Array _get_node_connections(Type p_type) const; @@ -103,7 +104,7 @@ private: } }; - Error _write_node(Type p_type, StringBuilder &global_code, 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) const; + 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); @@ -183,7 +184,7 @@ public: PORT_TYPE_VECTOR, PORT_TYPE_BOOLEAN, PORT_TYPE_TRANSFORM, - PORT_TYPE_COLOR // just a hint for node tree icons, do not use it as actual port type ! + PORT_TYPE_ICON_COLOR // just a hint for node tree icons, do not use it as actual port type ! }; virtual String get_caption() const = 0; @@ -208,12 +209,52 @@ public: virtual Vector<VisualShader::DefaultTextureParam> get_default_texture_parameters(VisualShader::Type p_type, int p_id) const; virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const = 0; //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 String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; VisualShaderNode(); }; + +VARIANT_ENUM_CAST(VisualShaderNode::PortType) + +class VisualShaderNodeCustom : public VisualShaderNode { + GDCLASS(VisualShaderNodeCustom, VisualShaderNode); + + struct Port { + String name; + int type; + }; + + List<Port> input_ports; + List<Port> output_ports; + + friend class VisualShaderEditor; + +protected: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + +protected: + 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; + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + + static void _bind_methods(); + +public: + VisualShaderNodeCustom(); + void update_ports(); +}; + ///// class VisualShaderNodeInput : public VisualShaderNode { @@ -331,6 +372,7 @@ protected: Vector2 size; String inputs; String outputs; + bool editable; struct Port { PortType type; @@ -386,6 +428,9 @@ public: void set_control(Control *p_control, int p_index); Control *get_control(int p_index); + void set_editable(bool p_enabled); + bool is_editable() const; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; VisualShaderNodeGroupBase(); @@ -394,10 +439,9 @@ public: class VisualShaderNodeExpression : public VisualShaderNodeGroupBase { GDCLASS(VisualShaderNodeExpression, VisualShaderNodeGroupBase); -private: +protected: String expression; -protected: static void _bind_methods(); public: @@ -413,4 +457,15 @@ public: VisualShaderNodeExpression(); }; +class VisualShaderNodeGlobalExpression : public VisualShaderNodeExpression { + GDCLASS(VisualShaderNodeGlobalExpression, VisualShaderNodeExpression); + +public: + virtual String get_caption() const; + + virtual String generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + + VisualShaderNodeGlobalExpression(); +}; + #endif // VISUAL_SHADER_H diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 746edc65b0..b7173b157e 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -29,6 +29,7 @@ /*************************************************************************/ #include "visual_shader_nodes.h" + ////////////// Scalar String VisualShaderNodeScalarConstant::get_caption() const { @@ -38,9 +39,11 @@ String VisualShaderNodeScalarConstant::get_caption() const { int VisualShaderNodeScalarConstant::get_input_port_count() const { return 0; } + VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const { return String(); } @@ -48,9 +51,11 @@ String VisualShaderNodeScalarConstant::get_input_port_name(int p_port) const { int VisualShaderNodeScalarConstant::get_output_port_count() const { return 1; } + VisualShaderNodeScalarConstant::PortType VisualShaderNodeScalarConstant::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarConstant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -158,9 +163,11 @@ String VisualShaderNodeColorConstant::get_caption() const { int VisualShaderNodeColorConstant::get_input_port_count() const { return 0; } + VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const { return String(); } @@ -168,9 +175,11 @@ String VisualShaderNodeColorConstant::get_input_port_name(int p_port) const { int VisualShaderNodeColorConstant::get_output_port_count() const { return 2; } + VisualShaderNodeColorConstant::PortType VisualShaderNodeColorConstant::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeColorConstant::get_output_port_name(int p_port) const { return p_port == 0 ? "" : "alpha"; //no output port means the editor will be used as port } @@ -222,9 +231,11 @@ String VisualShaderNodeVec3Constant::get_caption() const { int VisualShaderNodeVec3Constant::get_input_port_count() const { return 0; } + VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const { return String(); } @@ -232,9 +243,11 @@ String VisualShaderNodeVec3Constant::get_input_port_name(int p_port) const { int VisualShaderNodeVec3Constant::get_output_port_count() const { return 1; } + VisualShaderNodeVec3Constant::PortType VisualShaderNodeVec3Constant::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVec3Constant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -280,9 +293,11 @@ String VisualShaderNodeTransformConstant::get_caption() const { int VisualShaderNodeTransformConstant::get_input_port_count() const { return 0; } + VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const { return String(); } @@ -290,9 +305,11 @@ String VisualShaderNodeTransformConstant::get_input_port_name(int p_port) const int VisualShaderNodeTransformConstant::get_output_port_count() const { return 1; } + VisualShaderNodeTransformConstant::PortType VisualShaderNodeTransformConstant::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformConstant::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -346,9 +363,11 @@ String VisualShaderNodeTexture::get_caption() const { int VisualShaderNodeTexture::get_input_port_count() const { return 2; } + VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_input_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeTexture::get_input_port_name(int p_port) const { return p_port == 0 ? "uv" : "lod"; } @@ -356,11 +375,13 @@ String VisualShaderNodeTexture::get_input_port_name(int p_port) const { int VisualShaderNodeTexture::get_output_port_count() const { return 2; } + VisualShaderNodeTexture::PortType VisualShaderNodeTexture::get_output_port_type(int p_port) const { if (p_port == 0 && source == SOURCE_DEPTH) return PORT_TYPE_SCALAR; return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeTexture::get_output_port_name(int p_port) const { if (p_port == 0 && source == SOURCE_DEPTH) return "depth"; @@ -632,9 +653,11 @@ String VisualShaderNodeCubeMap::get_caption() const { int VisualShaderNodeCubeMap::get_input_port_count() const { return 2; } + VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_input_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { return p_port == 0 ? "uv" : "lod"; } @@ -642,9 +665,11 @@ String VisualShaderNodeCubeMap::get_input_port_name(int p_port) const { int VisualShaderNodeCubeMap::get_output_port_count() const { return 2; } + VisualShaderNodeCubeMap::PortType VisualShaderNodeCubeMap::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeCubeMap::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } @@ -735,6 +760,7 @@ void VisualShaderNodeCubeMap::_bind_methods() { VisualShaderNodeCubeMap::VisualShaderNodeCubeMap() { texture_type = TYPE_DATA; } + ////////////// Scalar Op String VisualShaderNodeScalarOp::get_caption() const { @@ -744,9 +770,11 @@ String VisualShaderNodeScalarOp::get_caption() const { int VisualShaderNodeScalarOp::get_input_port_count() const { return 2; } + VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -754,9 +782,11 @@ String VisualShaderNodeScalarOp::get_input_port_name(int p_port) const { int VisualShaderNodeScalarOp::get_output_port_count() const { return 1; } + VisualShaderNodeScalarOp::PortType VisualShaderNodeScalarOp::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } @@ -832,9 +862,11 @@ String VisualShaderNodeVectorOp::get_caption() const { int VisualShaderNodeVectorOp::get_input_port_count() const { return 2; } + VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -842,9 +874,11 @@ String VisualShaderNodeVectorOp::get_input_port_name(int p_port) const { int VisualShaderNodeVectorOp::get_output_port_count() const { return 1; } + VisualShaderNodeVectorOp::PortType VisualShaderNodeVectorOp::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } @@ -924,9 +958,11 @@ String VisualShaderNodeColorOp::get_caption() const { int VisualShaderNodeColorOp::get_input_port_count() const { return 2; } + VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeColorOp::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -934,9 +970,11 @@ String VisualShaderNodeColorOp::get_input_port_name(int p_port) const { int VisualShaderNodeColorOp::get_output_port_count() const { return 1; } + VisualShaderNodeColorOp::PortType VisualShaderNodeColorOp::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeColorOp::get_output_port_name(int p_port) const { return "op"; //no output port means the editor will be used as port } @@ -1072,9 +1110,11 @@ String VisualShaderNodeTransformMult::get_caption() const { int VisualShaderNodeTransformMult::get_input_port_count() const { return 2; } + VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_input_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -1082,9 +1122,11 @@ String VisualShaderNodeTransformMult::get_input_port_name(int p_port) const { int VisualShaderNodeTransformMult::get_output_port_count() const { return 1; } + VisualShaderNodeTransformMult::PortType VisualShaderNodeTransformMult::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformMult::get_output_port_name(int p_port) const { return "mult"; //no output port means the editor will be used as port } @@ -1147,9 +1189,11 @@ String VisualShaderNodeTransformVecMult::get_caption() const { int VisualShaderNodeTransformVecMult::get_input_port_count() const { return 2; } + VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_input_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_TRANSFORM : PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -1157,9 +1201,11 @@ String VisualShaderNodeTransformVecMult::get_input_port_name(int p_port) const { int VisualShaderNodeTransformVecMult::get_output_port_count() const { return 1; } + VisualShaderNodeTransformVecMult::PortType VisualShaderNodeTransformVecMult::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformVecMult::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -1221,9 +1267,11 @@ String VisualShaderNodeScalarFunc::get_caption() const { int VisualShaderNodeScalarFunc::get_input_port_count() const { return 1; } + VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const { return ""; } @@ -1231,9 +1279,11 @@ String VisualShaderNodeScalarFunc::get_input_port_name(int p_port) const { int VisualShaderNodeScalarFunc::get_output_port_count() const { return 1; } + VisualShaderNodeScalarFunc::PortType VisualShaderNodeScalarFunc::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -1350,9 +1400,11 @@ String VisualShaderNodeVectorFunc::get_caption() const { int VisualShaderNodeVectorFunc::get_input_port_count() const { return 1; } + VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const { return ""; } @@ -1360,9 +1412,11 @@ String VisualShaderNodeVectorFunc::get_input_port_name(int p_port) const { int VisualShaderNodeVectorFunc::get_output_port_count() const { return 1; } + VisualShaderNodeVectorFunc::PortType VisualShaderNodeVectorFunc::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorFunc::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -1675,9 +1729,11 @@ String VisualShaderNodeDotProduct::get_caption() const { int VisualShaderNodeDotProduct::get_input_port_count() const { return 2; } + VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const { return p_port == 0 ? "a" : "b"; } @@ -1685,9 +1741,11 @@ String VisualShaderNodeDotProduct::get_input_port_name(int p_port) const { int VisualShaderNodeDotProduct::get_output_port_count() const { return 1; } + VisualShaderNodeDotProduct::PortType VisualShaderNodeDotProduct::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeDotProduct::get_output_port_name(int p_port) const { return "dot"; } @@ -1710,9 +1768,11 @@ String VisualShaderNodeVectorLen::get_caption() const { int VisualShaderNodeVectorLen::get_input_port_count() const { return 1; } + VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const { return ""; } @@ -1720,9 +1780,11 @@ String VisualShaderNodeVectorLen::get_input_port_name(int p_port) const { int VisualShaderNodeVectorLen::get_output_port_count() const { return 1; } + VisualShaderNodeVectorLen::PortType VisualShaderNodeVectorLen::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeVectorLen::get_output_port_name(int p_port) const { return "length"; } @@ -1745,7 +1807,7 @@ int VisualShaderNodeDeterminant::get_input_port_count() const { return 1; } -VisualShaderNodeScalarClamp::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const { +VisualShaderNodeDeterminant::PortType VisualShaderNodeDeterminant::get_input_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } @@ -1872,7 +1934,7 @@ int VisualShaderNodeVectorDerivativeFunc::get_output_port_count() const { return 1; } -VisualShaderNodeScalarDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const { +VisualShaderNodeVectorDerivativeFunc::PortType VisualShaderNodeVectorDerivativeFunc::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } @@ -2078,7 +2140,7 @@ int VisualShaderNodeOuterProduct::get_input_port_count() const { return 2; } -VisualShaderNodeFaceForward::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const { +VisualShaderNodeOuterProduct::PortType VisualShaderNodeOuterProduct::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } @@ -2106,7 +2168,7 @@ String VisualShaderNodeOuterProduct::get_output_port_name(int p_port) const { } String VisualShaderNodeOuterProduct::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] + " = outerProduct( " + p_input_vars[0] + ", " + p_input_vars[1] + " );\n"; + return "\t" + p_output_vars[0] + " = outerProduct( vec4(" + p_input_vars[0] + ", 0.0), vec4(" + p_input_vars[1] + ", 0.0) );\n"; } VisualShaderNodeOuterProduct::VisualShaderNodeOuterProduct() { @@ -2143,7 +2205,7 @@ int VisualShaderNodeVectorScalarStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const { +VisualShaderNodeVectorScalarStep::PortType VisualShaderNodeVectorScalarStep::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } @@ -2234,7 +2296,7 @@ int VisualShaderNodeVectorSmoothStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const { +VisualShaderNodeVectorSmoothStep::PortType VisualShaderNodeVectorSmoothStep::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } @@ -2285,7 +2347,7 @@ int VisualShaderNodeVectorScalarSmoothStep::get_output_port_count() const { return 1; } -VisualShaderNodeVectorClamp::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const { +VisualShaderNodeVectorScalarSmoothStep::PortType VisualShaderNodeVectorScalarSmoothStep::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } @@ -2399,34 +2461,38 @@ VisualShaderNodeVectorRefract::VisualShaderNodeVectorRefract() { set_input_port_default_value(2, 0.0); } -////////////// Scalar Interp +////////////// Scalar Mix String VisualShaderNodeScalarInterp::get_caption() const { - return "Mix"; + return "ScalarMix"; } int VisualShaderNodeScalarInterp::get_input_port_count() const { return 3; } + VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarInterp::get_input_port_name(int p_port) const { if (p_port == 0) { return "a"; } else if (p_port == 1) { return "b"; } else { - return "c"; + return "weight"; } } int VisualShaderNodeScalarInterp::get_output_port_count() const { return 1; } + VisualShaderNodeScalarInterp::PortType VisualShaderNodeScalarInterp::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarInterp::get_output_port_name(int p_port) const { return "mix"; } @@ -2437,38 +2503,42 @@ String VisualShaderNodeScalarInterp::generate_code(Shader::Mode p_mode, VisualSh VisualShaderNodeScalarInterp::VisualShaderNodeScalarInterp() { set_input_port_default_value(0, 0.0); - set_input_port_default_value(1, 0.0); - set_input_port_default_value(2, 0.0); + set_input_port_default_value(1, 1.0); + set_input_port_default_value(2, 0.5); } -////////////// Vector Interp +////////////// Vector Mix String VisualShaderNodeVectorInterp::get_caption() const { - return "Mix"; + return "VectorMix"; } int VisualShaderNodeVectorInterp::get_input_port_count() const { return 3; } + VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorInterp::get_input_port_name(int p_port) const { if (p_port == 0) { return "a"; } else if (p_port == 1) { return "b"; } else { - return "c"; + return "weight"; } } int VisualShaderNodeVectorInterp::get_output_port_count() const { return 1; } + VisualShaderNodeVectorInterp::PortType VisualShaderNodeVectorInterp::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorInterp::get_output_port_name(int p_port) const { return "mix"; } @@ -2478,12 +2548,61 @@ String VisualShaderNodeVectorInterp::generate_code(Shader::Mode p_mode, VisualSh } VisualShaderNodeVectorInterp::VisualShaderNodeVectorInterp() { - set_input_port_default_value(0, Vector3()); - set_input_port_default_value(1, Vector3()); - set_input_port_default_value(2, Vector3()); + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(2, Vector3(0.5, 0.5, 0.5)); +} + +////////////// Vector Mix (by scalar) + +String VisualShaderNodeVectorScalarMix::get_caption() const { + return "VectorScalarMix"; +} + +int VisualShaderNodeVectorScalarMix::get_input_port_count() const { + return 3; +} + +VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_input_port_type(int p_port) const { + if (p_port == 2) + return PORT_TYPE_SCALAR; + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeVectorScalarMix::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "a"; + } else if (p_port == 1) { + return "b"; + } else { + return "weight"; + } +} + +int VisualShaderNodeVectorScalarMix::get_output_port_count() const { + return 1; +} + +VisualShaderNodeVectorScalarMix::PortType VisualShaderNodeVectorScalarMix::get_output_port_type(int p_port) const { + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeVectorScalarMix::get_output_port_name(int p_port) const { + return "mix"; +} + +String VisualShaderNodeVectorScalarMix::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] + " = mix( " + p_input_vars[0] + " , " + p_input_vars[1] + " , " + p_input_vars[2] + " );\n"; +} + +VisualShaderNodeVectorScalarMix::VisualShaderNodeVectorScalarMix() { + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(1, Vector3(1.0, 1.0, 1.0)); + set_input_port_default_value(2, 0.5); } ////////////// Vector Compose + String VisualShaderNodeVectorCompose::get_caption() const { return "VectorCompose"; } @@ -2491,9 +2610,11 @@ String VisualShaderNodeVectorCompose::get_caption() const { int VisualShaderNodeVectorCompose::get_input_port_count() const { return 3; } + VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const { if (p_port == 0) { return "x"; @@ -2507,9 +2628,11 @@ String VisualShaderNodeVectorCompose::get_input_port_name(int p_port) const { int VisualShaderNodeVectorCompose::get_output_port_count() const { return 1; } + VisualShaderNodeVectorCompose::PortType VisualShaderNodeVectorCompose::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorCompose::get_output_port_name(int p_port) const { return "vec"; } @@ -2534,9 +2657,11 @@ String VisualShaderNodeTransformCompose::get_caption() const { int VisualShaderNodeTransformCompose::get_input_port_count() const { return 4; } + VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const { if (p_port == 0) { return "x"; @@ -2552,9 +2677,11 @@ String VisualShaderNodeTransformCompose::get_input_port_name(int p_port) const { int VisualShaderNodeTransformCompose::get_output_port_count() const { return 1; } + VisualShaderNodeTransformCompose::PortType VisualShaderNodeTransformCompose::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformCompose::get_output_port_name(int p_port) const { return "xform"; } @@ -2579,9 +2706,11 @@ String VisualShaderNodeVectorDecompose::get_caption() const { int VisualShaderNodeVectorDecompose::get_input_port_count() const { return 1; } + VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const { return "vec"; } @@ -2589,9 +2718,11 @@ String VisualShaderNodeVectorDecompose::get_input_port_name(int p_port) const { int VisualShaderNodeVectorDecompose::get_output_port_count() const { return 3; } + VisualShaderNodeVectorDecompose::PortType VisualShaderNodeVectorDecompose::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeVectorDecompose::get_output_port_name(int p_port) const { if (p_port == 0) { return "x"; @@ -2623,9 +2754,11 @@ String VisualShaderNodeTransformDecompose::get_caption() const { int VisualShaderNodeTransformDecompose::get_input_port_count() const { return 1; } + VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_input_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const { return "xform"; } @@ -2633,9 +2766,11 @@ String VisualShaderNodeTransformDecompose::get_input_port_name(int p_port) const int VisualShaderNodeTransformDecompose::get_output_port_count() const { return 4; } + VisualShaderNodeTransformDecompose::PortType VisualShaderNodeTransformDecompose::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformDecompose::get_output_port_name(int p_port) const { if (p_port == 0) { return "x"; @@ -2670,9 +2805,11 @@ String VisualShaderNodeScalarUniform::get_caption() const { int VisualShaderNodeScalarUniform::get_input_port_count() const { return 0; } + VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_input_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const { return String(); } @@ -2680,9 +2817,11 @@ String VisualShaderNodeScalarUniform::get_input_port_name(int p_port) const { int VisualShaderNodeScalarUniform::get_output_port_count() const { return 1; } + VisualShaderNodeScalarUniform::PortType VisualShaderNodeScalarUniform::get_output_port_type(int p_port) const { return PORT_TYPE_SCALAR; } + String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } @@ -2690,6 +2829,7 @@ String VisualShaderNodeScalarUniform::get_output_port_name(int p_port) const { String VisualShaderNodeScalarUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { return "uniform float " + get_uniform_name() + ";\n"; } + String VisualShaderNodeScalarUniform::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"; } @@ -2747,9 +2887,11 @@ String VisualShaderNodeColorUniform::get_caption() const { int VisualShaderNodeColorUniform::get_input_port_count() const { return 0; } + VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const { return String(); } @@ -2757,9 +2899,11 @@ String VisualShaderNodeColorUniform::get_input_port_name(int p_port) const { int VisualShaderNodeColorUniform::get_output_port_count() const { return 2; } + VisualShaderNodeColorUniform::PortType VisualShaderNodeColorUniform::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + 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 } @@ -2787,9 +2931,11 @@ String VisualShaderNodeVec3Uniform::get_caption() const { int VisualShaderNodeVec3Uniform::get_input_port_count() const { return 0; } + VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const { return String(); } @@ -2797,12 +2943,15 @@ String VisualShaderNodeVec3Uniform::get_input_port_name(int p_port) const { int VisualShaderNodeVec3Uniform::get_output_port_count() const { return 1; } + VisualShaderNodeVec3Uniform::PortType VisualShaderNodeVec3Uniform::get_output_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeVec3Uniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } + String VisualShaderNodeVec3Uniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { return "uniform vec3 " + get_uniform_name() + ";\n"; } @@ -2823,9 +2972,11 @@ String VisualShaderNodeTransformUniform::get_caption() const { int VisualShaderNodeTransformUniform::get_input_port_count() const { return 0; } + VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_input_port_type(int p_port) const { return PORT_TYPE_VECTOR; } + String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const { return String(); } @@ -2833,12 +2984,15 @@ String VisualShaderNodeTransformUniform::get_input_port_name(int p_port) const { int VisualShaderNodeTransformUniform::get_output_port_count() const { return 1; } + VisualShaderNodeTransformUniform::PortType VisualShaderNodeTransformUniform::get_output_port_type(int p_port) const { return PORT_TYPE_TRANSFORM; } + String VisualShaderNodeTransformUniform::get_output_port_name(int p_port) const { return ""; //no output port means the editor will be used as port } + String VisualShaderNodeTransformUniform::generate_global(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { return "uniform mat4 " + get_uniform_name() + ";\n"; } @@ -2859,9 +3013,11 @@ String VisualShaderNodeTextureUniform::get_caption() const { int VisualShaderNodeTextureUniform::get_input_port_count() const { return 2; } + VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_input_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { return p_port == 0 ? "uv" : "lod"; } @@ -2869,9 +3025,11 @@ String VisualShaderNodeTextureUniform::get_input_port_name(int p_port) const { int VisualShaderNodeTextureUniform::get_output_port_count() const { return 2; } + VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniform::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeTextureUniform::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } @@ -2933,6 +3091,7 @@ void VisualShaderNodeTextureUniform::set_color_default(ColorDefault p_default) { color_default = p_default; emit_changed(); } + VisualShaderNodeTextureUniform::ColorDefault VisualShaderNodeTextureUniform::get_color_default() const { return color_default; } @@ -2968,6 +3127,98 @@ VisualShaderNodeTextureUniform::VisualShaderNodeTextureUniform() { color_default = COLOR_DEFAULT_WHITE; } +////////////// Texture Uniform (Triplanar) + +String VisualShaderNodeTextureUniformTriplanar::get_caption() const { + return "TextureUniformTriplanar"; +} + +int VisualShaderNodeTextureUniformTriplanar::get_input_port_count() const { + return 2; +} + +VisualShaderNodeTextureUniform::PortType VisualShaderNodeTextureUniformTriplanar::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_VECTOR; + } else if (p_port == 1) { + return PORT_TYPE_VECTOR; + } + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeTextureUniformTriplanar::get_input_port_name(int p_port) const { + if (p_port == 0) { + return "weights"; + } else if (p_port == 1) { + return "pos"; + } + return ""; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + code += "// TRIPLANAR FUNCTION GLOBAL CODE\n"; + code += "\tvec4 triplanar_texture(sampler2D p_sampler, vec3 p_weights, vec3 p_triplanar_pos) {\n"; + code += "\t\tvec4 samp = vec4(0.0);\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xy) * p_weights.z;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.xz) * p_weights.y;\n"; + code += "\t\tsamp += texture(p_sampler, p_triplanar_pos.zy * vec2(-1.0, 1.0)) * p_weights.x;\n"; + code += "\t\treturn samp;\n"; + code += "\t}\n"; + code += "\n"; + code += "\tuniform vec3 triplanar_scale = vec3(1.0, 1.0, 1.0);\n"; + code += "\tuniform vec3 triplanar_offset;\n"; + code += "\tuniform float triplanar_sharpness = 0.5;\n"; + code += "\n"; + code += "\tvarying vec3 triplanar_power_normal;\n"; + code += "\tvarying vec3 triplanar_pos;\n"; + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const { + + String code; + + if (p_type == VisualShader::TYPE_VERTEX) { + + code += "\t// TRIPLANAR FUNCTION VERTEX CODE\n"; + code += "\t\ttriplanar_power_normal = pow(abs(NORMAL), vec3(triplanar_sharpness));\n"; + code += "\t\ttriplanar_power_normal /= dot(triplanar_power_normal, vec3(1.0));\n"; + code += "\t\ttriplanar_pos = VERTEX * triplanar_scale + triplanar_offset;\n"; + code += "\t\ttriplanar_pos *= vec3(1.0, -1.0, 1.0);\n"; + } + + return code; +} + +String VisualShaderNodeTextureUniformTriplanar::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const { + + String id = get_uniform_name(); + 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"; + } 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"; + } 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"; + } else { + 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"; + code += "\t\t" + p_output_vars[1] + " = n_tex_read.a;\n"; + code += "\t}\n"; + + return code; +} + +VisualShaderNodeTextureUniformTriplanar::VisualShaderNodeTextureUniformTriplanar() { +} + ////////////// CubeMap Uniform String VisualShaderNodeCubeMapUniform::get_caption() const { @@ -2977,9 +3228,11 @@ String VisualShaderNodeCubeMapUniform::get_caption() const { int VisualShaderNodeCubeMapUniform::get_input_port_count() const { return 2; } + VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_input_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { return p_port == 0 ? "normal" : "lod"; } @@ -2987,9 +3240,11 @@ String VisualShaderNodeCubeMapUniform::get_input_port_name(int p_port) const { int VisualShaderNodeCubeMapUniform::get_output_port_count() const { return 2; } + VisualShaderNodeCubeMapUniform::PortType VisualShaderNodeCubeMapUniform::get_output_port_type(int p_port) const { return p_port == 0 ? PORT_TYPE_VECTOR : PORT_TYPE_SCALAR; } + String VisualShaderNodeCubeMapUniform::get_output_port_name(int p_port) const { return p_port == 0 ? "rgb" : "alpha"; } @@ -3079,7 +3334,7 @@ VisualShaderNodeIf::VisualShaderNodeIf() { ////////////// Switch String VisualShaderNodeSwitch::get_caption() const { - return "Switch"; + return "VectorSwitch"; } int VisualShaderNodeSwitch::get_input_port_count() const { @@ -3134,10 +3389,33 @@ String VisualShaderNodeSwitch::generate_code(Shader::Mode p_mode, VisualShader:: VisualShaderNodeSwitch::VisualShaderNodeSwitch() { set_input_port_default_value(0, false); - set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + 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)); } +////////////// Switch(scalar) + +String VisualShaderNodeScalarSwitch::get_caption() const { + return "ScalarSwitch"; +} + +VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_input_port_type(int p_port) const { + if (p_port == 0) { + return PORT_TYPE_BOOLEAN; + } + return PORT_TYPE_SCALAR; +} + +VisualShaderNodeScalarSwitch::PortType VisualShaderNodeScalarSwitch::get_output_port_type(int p_port) const { + return PORT_TYPE_SCALAR; +} + +VisualShaderNodeScalarSwitch::VisualShaderNodeScalarSwitch() { + set_input_port_default_value(0, false); + set_input_port_default_value(1, 1.0); + set_input_port_default_value(2, 0.0); +} + ////////////// Fresnel String VisualShaderNodeFresnel::get_caption() const { @@ -3200,3 +3478,317 @@ VisualShaderNodeFresnel::VisualShaderNodeFresnel() { set_input_port_default_value(2, false); set_input_port_default_value(3, 1.0); } + +////////////// Is + +String VisualShaderNodeIs::get_caption() const { + + return "Is"; +} + +int VisualShaderNodeIs::get_input_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_input_port_type(int p_port) const { + + return PORT_TYPE_SCALAR; +} + +String VisualShaderNodeIs::get_input_port_name(int p_port) const { + + return ""; +} + +int VisualShaderNodeIs::get_output_port_count() const { + + return 1; +} + +VisualShaderNodeIs::PortType VisualShaderNodeIs::get_output_port_type(int p_port) const { + + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeIs::get_output_port_name(int p_port) const { + + return ""; +} + +String VisualShaderNodeIs::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 { + + static const char *funcs[FUNC_IS_NAN + 1] = { + "isinf($)", + "isnan($)" + }; + + String code; + code += "\t" + p_output_vars[0] + "=" + String(funcs[func]).replace("$", p_input_vars[0]) + ";\n"; + return code; +} + +void VisualShaderNodeIs::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeIs::Function VisualShaderNodeIs::get_function() const { + + return func; +} + +Vector<StringName> VisualShaderNodeIs::get_editable_properties() const { + + Vector<StringName> props; + props.push_back("function"); + return props; +} + +void VisualShaderNodeIs::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeIs::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeIs::get_function); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Inf,NaN"), "set_function", "get_function"); + + BIND_ENUM_CONSTANT(FUNC_IS_INF); + BIND_ENUM_CONSTANT(FUNC_IS_NAN); +} + +VisualShaderNodeIs::VisualShaderNodeIs() { + + func = FUNC_IS_INF; + set_input_port_default_value(0, 0.0); +} + +////////////// Compare + +String VisualShaderNodeCompare::get_caption() const { + + return "Compare"; +} + +int VisualShaderNodeCompare::get_input_port_count() const { + + if (ctype == CTYPE_SCALAR && (func == FUNC_EQUAL || func == FUNC_NOT_EQUAL)) { + return 3; + } + return 2; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_input_port_type(int p_port) const { + + if (p_port == 2) + return PORT_TYPE_SCALAR; + switch (ctype) { + case CTYPE_SCALAR: + return PORT_TYPE_SCALAR; + case CTYPE_VECTOR: + return PORT_TYPE_VECTOR; + case CTYPE_BOOLEAN: + return PORT_TYPE_BOOLEAN; + case CTYPE_TRANSFORM: + return PORT_TYPE_TRANSFORM; + } + return PORT_TYPE_VECTOR; +} + +String VisualShaderNodeCompare::get_input_port_name(int p_port) const { + if (p_port == 0) + return "a"; + else if (p_port == 1) + return "b"; + else if (p_port == 2) + return "tolerance"; + return ""; +} + +int VisualShaderNodeCompare::get_output_port_count() const { + return 1; +} + +VisualShaderNodeCompare::PortType VisualShaderNodeCompare::get_output_port_type(int p_port) const { + return PORT_TYPE_BOOLEAN; +} + +String VisualShaderNodeCompare::get_output_port_name(int p_port) const { + if (p_port == 0) + return "result"; + return ""; +} + +String VisualShaderNodeCompare::get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const { + + if (ctype == CTYPE_BOOLEAN || ctype == CTYPE_TRANSFORM) { + if (func > FUNC_NOT_EQUAL) { + return TTR("Invalid comparison function for that type."); + } + } + + return ""; +} + +String VisualShaderNodeCompare::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 { + + static const char *ops[FUNC_LESS_THAN_EQUAL + 1] = { + "==", + "!=", + ">", + ">=", + "<", + "<=", + }; + + static const char *funcs[FUNC_LESS_THAN_EQUAL + 1] = { + "equal($)", + "notEqual($)", + "greaterThan($)", + "greaterThanEqual($)", + "lessThan($)", + "lessThanEqual($)", + }; + + static const char *conds[COND_ANY + 1] = { + "all($)", + "any($)", + }; + + String code; + switch (ctype) { + case CTYPE_SCALAR: + if (func == FUNC_EQUAL) { + code += "\t" + p_output_vars[0] + "=(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else if (func == FUNC_NOT_EQUAL) { + code += "\t" + p_output_vars[0] + "=!(abs(" + p_input_vars[0] + "-" + p_input_vars[1] + ")<" + p_input_vars[2] + ");"; + } else { + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + } + break; + + case CTYPE_VECTOR: + code += "\t{\n"; + code += "\t\tbvec3 _bv=" + String(funcs[func]).replace("$", p_input_vars[0] + ", " + p_input_vars[1]) + ";\n"; + code += "\t\t" + p_output_vars[0] + "=" + String(conds[condition]).replace("$", "_bv") + ";\n"; + code += "\t}\n"; + break; + + case CTYPE_BOOLEAN: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + case CTYPE_TRANSFORM: + if (func > FUNC_NOT_EQUAL) + return "\t" + p_output_vars[0] + "=false;\n"; + code += "\t" + p_output_vars[0] + "=" + (p_input_vars[0] + "$" + p_input_vars[1]).replace("$", ops[func]) + ";\n"; + break; + + default: + break; + } + return code; +} + +void VisualShaderNodeCompare::set_comparsion_type(ComparsionType p_type) { + + ctype = p_type; + + switch (ctype) { + case CTYPE_SCALAR: + set_input_port_default_value(0, 0.0); + set_input_port_default_value(1, 0.0); + break; + case CTYPE_VECTOR: + set_input_port_default_value(0, Vector3(0.0, 0.0, 0.0)); + set_input_port_default_value(1, Vector3(0.0, 0.0, 0.0)); + break; + case CTYPE_BOOLEAN: + set_input_port_default_value(0, false); + set_input_port_default_value(1, false); + break; + case CTYPE_TRANSFORM: + set_input_port_default_value(0, Transform()); + set_input_port_default_value(1, Transform()); + break; + } + emit_changed(); +} + +VisualShaderNodeCompare::ComparsionType VisualShaderNodeCompare::get_comparsion_type() const { + + return ctype; +} + +void VisualShaderNodeCompare::set_function(Function p_func) { + + func = p_func; + emit_changed(); +} + +VisualShaderNodeCompare::Function VisualShaderNodeCompare::get_function() const { + + return func; +} + +void VisualShaderNodeCompare::set_condition(Condition p_cond) { + + condition = p_cond; + emit_changed(); +} + +VisualShaderNodeCompare::Condition VisualShaderNodeCompare::get_condition() const { + + return condition; +} + +Vector<StringName> VisualShaderNodeCompare::get_editable_properties() const { + Vector<StringName> props; + props.push_back("type"); + props.push_back("function"); + if (ctype == CTYPE_VECTOR) + props.push_back("condition"); + return props; +} + +void VisualShaderNodeCompare::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_comparsion_type", "type"), &VisualShaderNodeCompare::set_comparsion_type); + ClassDB::bind_method(D_METHOD("get_comparsion_type"), &VisualShaderNodeCompare::get_comparsion_type); + + ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeCompare::set_function); + ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeCompare::get_function); + + ClassDB::bind_method(D_METHOD("set_condition", "condition"), &VisualShaderNodeCompare::set_condition); + ClassDB::bind_method(D_METHOD("get_condition"), &VisualShaderNodeCompare::get_condition); + + ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, "Scalar,Vector,Boolean,Transform"), "set_comparsion_type", "get_comparsion_type"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "a == b,a != b,a > b,a >= b,a < b,a <= b"), "set_function", "get_function"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "condition", PROPERTY_HINT_ENUM, "All,Any"), "set_condition", "get_condition"); + + BIND_ENUM_CONSTANT(CTYPE_SCALAR); + BIND_ENUM_CONSTANT(CTYPE_VECTOR); + BIND_ENUM_CONSTANT(CTYPE_BOOLEAN); + BIND_ENUM_CONSTANT(CTYPE_TRANSFORM); + + BIND_ENUM_CONSTANT(FUNC_EQUAL); + BIND_ENUM_CONSTANT(FUNC_NOT_EQUAL); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN); + BIND_ENUM_CONSTANT(FUNC_GREATER_THAN_EQUAL); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN); + BIND_ENUM_CONSTANT(FUNC_LESS_THAN_EQUAL); + + BIND_ENUM_CONSTANT(COND_ALL); + BIND_ENUM_CONSTANT(COND_ANY); +} + +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); +} diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 235714f697..0c6e060353 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1171,6 +1171,27 @@ public: }; /////////////////////////////////////// + +class VisualShaderNodeVectorScalarMix : public VisualShaderNode { + GDCLASS(VisualShaderNodeVectorScalarMix, VisualShaderNode); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + VisualShaderNodeVectorScalarMix(); +}; + +/////////////////////////////////////// /// COMPOSE /////////////////////////////////////// @@ -1425,6 +1446,25 @@ VARIANT_ENUM_CAST(VisualShaderNodeTextureUniform::ColorDefault) /////////////////////////////////////// +class VisualShaderNodeTextureUniformTriplanar : public VisualShaderNodeTextureUniform { + GDCLASS(VisualShaderNodeTextureUniformTriplanar, VisualShaderNodeTextureUniform); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual String generate_global_per_node(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_global_per_func(Shader::Mode p_mode, VisualShader::Type p_type, int p_id) const; + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + VisualShaderNodeTextureUniformTriplanar(); +}; + +/////////////////////////////////////// + class VisualShaderNodeCubeMapUniform : public VisualShaderNode { GDCLASS(VisualShaderNodeCubeMapUniform, VisualShaderNode); @@ -1490,6 +1530,18 @@ public: VisualShaderNodeSwitch(); }; +class VisualShaderNodeScalarSwitch : public VisualShaderNodeSwitch { + GDCLASS(VisualShaderNodeScalarSwitch, VisualShaderNodeSwitch); + +public: + virtual String get_caption() const; + + virtual PortType get_input_port_type(int p_port) const; + virtual PortType get_output_port_type(int p_port) const; + + VisualShaderNodeScalarSwitch(); +}; + /////////////////////////////////////// /// FRESNEL /////////////////////////////////////// @@ -1513,4 +1565,115 @@ public: VisualShaderNodeFresnel(); }; +/////////////////////////////////////// +/// Is +/////////////////////////////////////// + +class VisualShaderNodeIs : public VisualShaderNode { + GDCLASS(VisualShaderNodeIs, VisualShaderNode); + +public: + enum Function { + FUNC_IS_INF, + FUNC_IS_NAN, + }; + +protected: + Function func; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_function(Function p_func); + Function get_function() const; + + virtual Vector<StringName> get_editable_properties() const; + + VisualShaderNodeIs(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeIs::Function) + +/////////////////////////////////////// +/// Compare +/////////////////////////////////////// + +class VisualShaderNodeCompare : public VisualShaderNode { + GDCLASS(VisualShaderNodeCompare, VisualShaderNode); + +public: + enum ComparsionType { + CTYPE_SCALAR, + CTYPE_VECTOR, + CTYPE_BOOLEAN, + CTYPE_TRANSFORM + }; + + enum Function { + FUNC_EQUAL, + FUNC_NOT_EQUAL, + FUNC_GREATER_THAN, + FUNC_GREATER_THAN_EQUAL, + FUNC_LESS_THAN, + FUNC_LESS_THAN_EQUAL, + }; + + enum Condition { + COND_ALL, + COND_ANY, + }; + +protected: + ComparsionType ctype; + Function func; + Condition condition; + +protected: + static void _bind_methods(); + +public: + virtual String get_caption() const; + + virtual int get_input_port_count() const; + virtual PortType get_input_port_type(int p_port) const; + virtual String get_input_port_name(int p_port) const; + + virtual int get_output_port_count() const; + virtual PortType get_output_port_type(int p_port) const; + virtual String get_output_port_name(int p_port) const; + + virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const; //if no output is connected, the output var passed will be empty. if no input is connected and input is NIL, the input var passed will be empty + + void set_comparsion_type(ComparsionType p_type); + ComparsionType get_comparsion_type() const; + + void set_function(Function p_func); + Function get_function() const; + + void set_condition(Condition p_cond); + Condition get_condition() const; + + virtual Vector<StringName> get_editable_properties() const; + virtual String get_warning(Shader::Mode p_mode, VisualShader::Type p_type) const; + + VisualShaderNodeCompare(); +}; + +VARIANT_ENUM_CAST(VisualShaderNodeCompare::ComparsionType) +VARIANT_ENUM_CAST(VisualShaderNodeCompare::Function) +VARIANT_ENUM_CAST(VisualShaderNodeCompare::Condition) + #endif // VISUAL_SHADER_NODES_H |