summaryrefslogtreecommitdiff
path: root/scene/resources
diff options
context:
space:
mode:
Diffstat (limited to 'scene/resources')
-rw-r--r--scene/resources/animation.cpp25
-rw-r--r--scene/resources/animation.h4
-rw-r--r--scene/resources/audio_stream_sample.cpp3
-rw-r--r--scene/resources/curve.cpp40
-rw-r--r--scene/resources/default_theme/default_theme.cpp12
-rw-r--r--scene/resources/default_theme/default_theme.h3
-rwxr-xr-xscene/resources/default_theme/make_header.py5
-rw-r--r--scene/resources/default_theme/theme_data.h4
-rw-r--r--scene/resources/default_theme/toggle_off_disabled.pngbin1676 -> 932 bytes
-rw-r--r--scene/resources/default_theme/toggle_on_disabled.pngbin1698 -> 1039 bytes
-rw-r--r--scene/resources/dynamic_font.cpp23
-rw-r--r--scene/resources/environment.cpp10
-rw-r--r--scene/resources/font.cpp11
-rw-r--r--scene/resources/font.h3
-rw-r--r--scene/resources/material.cpp26
-rw-r--r--scene/resources/material.h9
-rw-r--r--scene/resources/mesh.cpp23
-rw-r--r--scene/resources/mesh.h3
-rw-r--r--scene/resources/mesh_data_tool.cpp3
-rw-r--r--scene/resources/packed_scene.cpp13
-rw-r--r--scene/resources/particles_material.cpp30
-rw-r--r--scene/resources/particles_material.h7
-rw-r--r--scene/resources/primitive_meshes.cpp16
-rw-r--r--scene/resources/primitive_meshes.h15
-rw-r--r--scene/resources/resource_format_text.cpp8
-rw-r--r--scene/resources/room.h3
-rw-r--r--scene/resources/skin.cpp102
-rw-r--r--scene/resources/skin.h54
-rw-r--r--scene/resources/style_box.cpp11
-rw-r--r--scene/resources/style_box.h4
-rw-r--r--scene/resources/text_file.cpp5
-rw-r--r--scene/resources/texture.cpp6
-rw-r--r--scene/resources/texture.h4
-rw-r--r--scene/resources/theme.cpp30
-rw-r--r--scene/resources/theme.h9
-rw-r--r--scene/resources/tile_set.cpp18
-rw-r--r--scene/resources/visual_shader.cpp282
-rw-r--r--scene/resources/visual_shader.h63
-rw-r--r--scene/resources/visual_shader_nodes.cpp632
-rw-r--r--scene/resources/visual_shader_nodes.h163
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
index d65a9d8e64..250cd29b66 100644
--- a/scene/resources/default_theme/toggle_off_disabled.png
+++ b/scene/resources/default_theme/toggle_off_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/toggle_on_disabled.png b/scene/resources/default_theme/toggle_on_disabled.png
index ca4dbe211f..b1dacbaf32 100644
--- a/scene/resources/default_theme/toggle_on_disabled.png
+++ b/scene/resources/default_theme/toggle_on_disabled.png
Binary files differ
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