diff options
Diffstat (limited to 'scene/resources')
70 files changed, 2062 insertions, 299 deletions
diff --git a/scene/resources/SCsub b/scene/resources/SCsub index 2ad90247a7..5e5b6f8fd5 100644 --- a/scene/resources/SCsub +++ b/scene/resources/SCsub @@ -4,6 +4,4 @@ Import('env') env.add_source_files(env.scene_sources, "*.cpp") -Export('env') - SConscript("default_theme/SCsub") diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 58e6db3f5e..80ad2ad739 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -30,7 +30,7 @@ #include "animation.h" -#include "geometry.h" +#include "core/math/geometry.h" #define ANIM_MIN_LENGTH 0.001 @@ -1442,7 +1442,7 @@ void Animation::track_set_key_transition(int p_track, int p_key_idx, float p_tra case TYPE_BEZIER: case TYPE_AUDIO: case TYPE_ANIMATION: { - // they dont use transition + // they don't use transition } break; } } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index a41e6ea5d7..6eec2c8bc7 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -31,7 +31,7 @@ #ifndef ANIMATION_H #define ANIMATION_H -#include "resource.h" +#include "core/resource.h" /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/scene/resources/audio_stream_sample.cpp b/scene/resources/audio_stream_sample.cpp index e6a4b01deb..9ee85b64b6 100644 --- a/scene/resources/audio_stream_sample.cpp +++ b/scene/resources/audio_stream_sample.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "audio_stream_sample.h" -#include "io/marshalls.h" -#include "os/file_access.h" +#include "core/io/marshalls.h" +#include "core/os/file_access.h" void AudioStreamPlaybackSample::start(float p_from_pos) { @@ -562,13 +562,13 @@ void AudioStreamSample::save_to_wav(String p_path) { PoolVector<uint8_t>::Read read_data = get_data().read(); switch (format) { case AudioStreamSample::FORMAT_8_BITS: - for (int i = 0; i < data_bytes; i++) { + for (unsigned int i = 0; i < data_bytes; i++) { uint8_t data_point = (read_data[i] + 128); file->store_8(data_point); } break; case AudioStreamSample::FORMAT_16_BITS: - for (int i = 0; i < data_bytes / 2; i++) { + for (unsigned int i = 0; i < data_bytes / 2; i++) { uint16_t data_point = decode_uint16(&read_data[i * 2]); file->store_16(data_point); } diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp index 5694099754..56b236d03b 100644 --- a/scene/resources/bit_mask.cpp +++ b/scene/resources/bit_mask.cpp @@ -30,7 +30,7 @@ #include "bit_mask.h" -#include "io/image_loader.h" +#include "core/io/image_loader.h" void BitMap::create(const Size2 &p_size) { @@ -183,7 +183,6 @@ Vector<Vector2> BitMap::_march_square(const Rect2i &rect, const Point2i &start) unsigned int count = 0; Set<Point2i> case9s; Set<Point2i> case6s; - int i; Vector<Vector2> _points; do { int sv = 0; diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h index 40f0bfb04a..04191a7774 100644 --- a/scene/resources/bit_mask.h +++ b/scene/resources/bit_mask.h @@ -31,9 +31,9 @@ #ifndef BIT_MASK_H #define BIT_MASK_H -#include "image.h" -#include "io/resource_loader.h" -#include "resource.h" +#include "core/image.h" +#include "core/io/resource_loader.h" +#include "core/resource.h" class BitMap : public Resource { diff --git a/scene/resources/bounds.h b/scene/resources/bounds.h index dfe2fe40c6..c86e15ae40 100644 --- a/scene/resources/bounds.h +++ b/scene/resources/bounds.h @@ -31,8 +31,8 @@ #ifndef BOUNDS_H #define BOUNDS_H -#include "bsp_tree.h" -#include "resource.h" +#include "core/math/bsp_tree.h" +#include "core/resource.h" class Bounds : public Resource { diff --git a/scene/resources/canvas.h b/scene/resources/canvas.h index dfdea82ca5..cd37ea3583 100644 --- a/scene/resources/canvas.h +++ b/scene/resources/canvas.h @@ -31,7 +31,7 @@ #ifndef CANVAS_H #define CANVAS_H -#include "resource.h" +#include "core/resource.h" class Canvas : public Resource { diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp index 4a43303d84..d5e8c17cbc 100644 --- a/scene/resources/color_ramp.cpp +++ b/scene/resources/color_ramp.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "color_ramp.h" -#include "core_string_names.h" +#include "core/core_string_names.h" //setter and getter names for property serialization #define COLOR_RAMP_GET_OFFSETS "get_offsets" diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h index 070ad7f0d3..88fa4beb7f 100644 --- a/scene/resources/color_ramp.h +++ b/scene/resources/color_ramp.h @@ -31,7 +31,7 @@ #ifndef SCENE_RESOURCES_COLOR_RAMP_H_ #define SCENE_RESOURCES_COLOR_RAMP_H_ -#include "resource.h" +#include "core/resource.h" class Gradient : public Resource { GDCLASS(Gradient, Resource); diff --git a/scene/resources/convex_polygon_shape.cpp b/scene/resources/convex_polygon_shape.cpp index fa9369d3bc..9d47bca5ed 100644 --- a/scene/resources/convex_polygon_shape.cpp +++ b/scene/resources/convex_polygon_shape.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "convex_polygon_shape.h" -#include "quick_hull.h" +#include "core/math/quick_hull.h" #include "servers/physics_server.h" Vector<Vector3> ConvexPolygonShape::_gen_debug_mesh_lines() { diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp index d061c4ea1e..f325af7ea4 100644 --- a/scene/resources/convex_polygon_shape_2d.cpp +++ b/scene/resources/convex_polygon_shape_2d.cpp @@ -30,7 +30,7 @@ #include "convex_polygon_shape_2d.h" -#include "geometry.h" +#include "core/math/geometry.h" #include "servers/physics_2d_server.h" #include "servers/visual_server.h" diff --git a/scene/resources/curve.cpp b/scene/resources/curve.cpp index d8989bf062..9188d890f7 100644 --- a/scene/resources/curve.cpp +++ b/scene/resources/curve.cpp @@ -30,7 +30,7 @@ #include "curve.h" -#include "core_string_names.h" +#include "core/core_string_names.h" template <class T> static _FORCE_INLINE_ T _bezier_interp(real_t t, T start, T control_1, T control_2, T end) { @@ -491,6 +491,7 @@ void Curve::ensure_default_setup(float p_min, float p_max) { void Curve::_bind_methods() { + ClassDB::bind_method(D_METHOD("get_point_count"), &Curve::get_point_count); ClassDB::bind_method(D_METHOD("add_point", "position", "left_tangent", "right_tangent", "left_mode", "right_mode"), &Curve::add_point, DEFVAL(0), DEFVAL(0), DEFVAL(TANGENT_FREE), DEFVAL(TANGENT_FREE)); ClassDB::bind_method(D_METHOD("remove_point", "index"), &Curve::remove_point); ClassDB::bind_method(D_METHOD("clear_points"), &Curve::clear_points); diff --git a/scene/resources/curve.h b/scene/resources/curve.h index 058c4f1bc2..234e3a6779 100644 --- a/scene/resources/curve.h +++ b/scene/resources/curve.h @@ -31,7 +31,7 @@ #ifndef CURVE_H #define CURVE_H -#include "resource.h" +#include "core/resource.h" // y(x) curve class Curve : public Resource { diff --git a/scene/resources/default_theme/SCsub b/scene/resources/default_theme/SCsub index bf9125be7f..b01e2fd54d 100644 --- a/scene/resources/default_theme/SCsub +++ b/scene/resources/default_theme/SCsub @@ -3,5 +3,3 @@ Import('env') env.add_source_files(env.scene_sources, "*.cpp") - -Export('env') diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index 0eee2ae393..4de47b2cb0 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -32,7 +32,7 @@ #include "scene/resources/theme.h" -#include "os/os.h" +#include "core/os/os.h" #include "theme_data.h" #include "font_hidpi.inc" @@ -120,41 +120,7 @@ static Ref<Texture> make_icon(T p_src) { return texture; } -static Ref<Shader> make_shader(const char *vertex_code, const char *fragment_code, const char *lighting_code) { - Ref<Shader> shader = (memnew(Shader())); - //shader->set_code(vertex_code, fragment_code, lighting_code); - - return shader; -} - -static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p_charcount, const int *p_chars, const Ref<Texture> &p_texture) { - - Ref<BitmapFont> font(memnew(BitmapFont)); - font->add_texture(p_texture); - - for (int i = 0; i < p_charcount; i++) { - - const int *c = &p_chars[i * 8]; - - int chr = c[0]; - Rect2 frect; - frect.position.x = c[1]; - frect.position.y = c[2]; - frect.size.x = c[3]; - frect.size.y = c[4]; - Point2 align(c[5], c[6] + p_valign); - int advance = c[7]; - - font->add_char(chr, 0, frect, align, advance); - } - - font->set_height(p_height); - font->set_ascent(p_ascent); - - return font; -} - -static Ref<BitmapFont> make_font2(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) { +static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_charcount, const int *p_char_rects, int p_kerning_count, const int *p_kernings, int p_w, int p_h, const unsigned char *p_img) { Ref<BitmapFont> font(memnew(BitmapFont)); @@ -209,8 +175,6 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const tex_cache = memnew(TexCacheMap); - //Ref<BitmapFont> default_font = make_font(_bi_font_normal_height,_bi_font_normal_ascent,_bi_font_normal_valign,_bi_font_normal_charcount,_bi_font_normal_characters,make_icon(font_normal_png)); - // Font Colors Color control_font_color = Color::html("e0e0e0"); @@ -364,6 +328,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("pressed", "CheckBox", cbx_empty); theme->set_stylebox("disabled", "CheckBox", cbx_empty); theme->set_stylebox("hover", "CheckBox", cbx_empty); + theme->set_stylebox("hover_pressed", "CheckBox", cbx_empty); theme->set_stylebox("focus", "CheckBox", cbx_focus); theme->set_icon("checked", "CheckBox", make_icon(checked_png)); @@ -376,6 +341,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color", "CheckBox", control_font_color); theme->set_color("font_color_pressed", "CheckBox", control_font_color_pressed); theme->set_color("font_color_hover", "CheckBox", control_font_color_hover); + theme->set_color("font_color_hover_pressed", "CheckBox", control_font_color_pressed); theme->set_color("font_color_disabled", "CheckBox", control_font_color_disabled); theme->set_constant("hseparation", "CheckBox", 4 * scale); @@ -393,6 +359,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_stylebox("pressed", "CheckButton", cb_empty); theme->set_stylebox("disabled", "CheckButton", cb_empty); theme->set_stylebox("hover", "CheckButton", cb_empty); + theme->set_stylebox("hover_pressed", "CheckButton", cb_empty); theme->set_stylebox("focus", "CheckButton", focus); theme->set_icon("on", "CheckButton", make_icon(toggle_on_png)); @@ -403,6 +370,7 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const theme->set_color("font_color", "CheckButton", control_font_color); theme->set_color("font_color_pressed", "CheckButton", control_font_color_pressed); theme->set_color("font_color_hover", "CheckButton", control_font_color_hover); + theme->set_color("font_color_hover_pressed", "CheckButton", control_font_color_pressed); theme->set_color("font_color_disabled", "CheckButton", control_font_color_disabled); theme->set_constant("hseparation", "CheckButton", 4 * scale); @@ -909,9 +877,9 @@ void make_default_theme(bool p_hidpi, Ref<Font> p_font) { if (p_font.is_valid()) { default_font = p_font; } else if (p_hidpi) { - default_font = make_font2(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data); + default_font = make_font(_hidpi_font_height, _hidpi_font_ascent, _hidpi_font_charcount, &_hidpi_font_charrects[0][0], _hidpi_font_kerning_pair_count, &_hidpi_font_kerning_pairs[0][0], _hidpi_font_img_width, _hidpi_font_img_height, _hidpi_font_img_data); } else { - default_font = make_font2(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data); + default_font = make_font(_lodpi_font_height, _lodpi_font_ascent, _lodpi_font_charcount, &_lodpi_font_charrects[0][0], _lodpi_font_kerning_pair_count, &_lodpi_font_kerning_pairs[0][0], _lodpi_font_img_width, _lodpi_font_img_height, _lodpi_font_img_data); } Ref<Font> large_font = default_font; fill_default_theme(t, default_font, large_font, default_icon, default_style, p_hidpi ? 2.0 : 1.0); diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp index 4df849df6a..0785d3bfc6 100644 --- a/scene/resources/dynamic_font.cpp +++ b/scene/resources/dynamic_font.cpp @@ -30,8 +30,8 @@ #ifdef FREETYPE_ENABLED #include "dynamic_font.h" -#include "os/file_access.h" -#include "os/os.h" +#include "core/os/file_access.h" +#include "core/os/os.h" #include FT_STROKER_H diff --git a/scene/resources/dynamic_font.h b/scene/resources/dynamic_font.h index f460bca2d4..afda48a566 100644 --- a/scene/resources/dynamic_font.h +++ b/scene/resources/dynamic_font.h @@ -32,10 +32,10 @@ #define DYNAMIC_FONT_H #ifdef FREETYPE_ENABLED -#include "io/resource_loader.h" -#include "os/mutex.h" -#include "os/thread_safe.h" -#include "pair.h" +#include "core/io/resource_loader.h" +#include "core/os/mutex.h" +#include "core/os/thread_safe.h" +#include "core/pair.h" #include "scene/resources/font.h" #include <ft2build.h> diff --git a/scene/resources/dynamic_font_stb.cpp b/scene/resources/dynamic_font_stb.cpp index be394e19c4..8cb2cc4983 100644 --- a/scene/resources/dynamic_font_stb.cpp +++ b/scene/resources/dynamic_font_stb.cpp @@ -33,7 +33,7 @@ #ifndef FREETYPE_ENABLED #define STB_TRUETYPE_IMPLEMENTATION -#include "os/file_access.h" +#include "core/os/file_access.h" void DynamicFontData::lock() { diff --git a/scene/resources/dynamic_font_stb.h b/scene/resources/dynamic_font_stb.h index feae29c0c2..e1ef72ea4f 100644 --- a/scene/resources/dynamic_font_stb.h +++ b/scene/resources/dynamic_font_stb.h @@ -33,8 +33,8 @@ #ifndef FREETYPE_ENABLED +#include "core/io/resource_loader.h" #include "font.h" -#include "io/resource_loader.h" #include "thirdparty/misc/stb_truetype.h" diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index d3da842b79..f4d5b8376b 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "environment.h" -#include "project_settings.h" +#include "core/project_settings.h" #include "servers/visual_server.h" #include "texture.h" diff --git a/scene/resources/environment.h b/scene/resources/environment.h index 7d66c7e60b..aab37719e0 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -31,7 +31,7 @@ #ifndef ENVIRONMENT_H #define ENVIRONMENT_H -#include "resource.h" +#include "core/resource.h" #include "scene/resources/sky_box.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp index 3dfde01320..b78b3a6ffb 100644 --- a/scene/resources/font.cpp +++ b/scene/resources/font.cpp @@ -31,8 +31,8 @@ #include "font.h" #include "core/io/resource_loader.h" +#include "core/method_bind_ext.gen.inc" #include "core/os/file_access.h" -#include "method_bind_ext.gen.inc" void Font::draw_halign(RID p_canvas_item, const Point2 &p_pos, HAlign p_align, float p_width, const String &p_text, const Color &p_modulate, const Color &p_outline_modulate) const { float length = get_string_size(p_text).width; @@ -178,6 +178,7 @@ PoolVector<int> BitmapFont::_get_kernings() const { void BitmapFont::_set_textures(const Vector<Variant> &p_textures) { + textures.clear(); for (int i = 0; i < p_textures.size(); i++) { Ref<Texture> tex = p_textures[i]; ERR_CONTINUE(!tex.is_valid()); diff --git a/scene/resources/font.h b/scene/resources/font.h index 4e295b6035..39e66a822d 100644 --- a/scene/resources/font.h +++ b/scene/resources/font.h @@ -31,8 +31,8 @@ #ifndef FONT_H #define FONT_H -#include "map.h" -#include "resource.h" +#include "core/map.h" +#include "core/resource.h" #include "scene/resources/texture.h" /** @author Juan Linietsky <reduzio@gmail.com> diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index b6d1916b2c..274c74a9a2 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -145,6 +145,31 @@ void ShaderMaterial::_get_property_list(List<PropertyInfo> *p_list) const { } } +bool ShaderMaterial::property_can_revert(const String &p_name) { + if (shader.is_valid()) { + + StringName pr = shader->remap_param(p_name); + if (pr) { + Variant default_value = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr); + Variant current_value; + _get(p_name, current_value); + return default_value.get_type() != Variant::NIL && default_value != current_value; + } + } + return false; +} + +Variant ShaderMaterial::property_get_revert(const String &p_name) { + Variant r_ret; + if (shader.is_valid()) { + StringName pr = shader->remap_param(p_name); + if (pr) { + r_ret = VisualServer::get_singleton()->material_get_param_default(_get_material(), pr); + } + } + return r_ret; +} + void ShaderMaterial::set_shader(const Ref<Shader> &p_shader) { if (shader.is_valid()) { @@ -190,6 +215,8 @@ void ShaderMaterial::_bind_methods() { ClassDB::bind_method(D_METHOD("set_shader_param", "param", "value"), &ShaderMaterial::set_shader_param); ClassDB::bind_method(D_METHOD("get_shader_param", "param"), &ShaderMaterial::get_shader_param); ClassDB::bind_method(D_METHOD("_shader_changed"), &ShaderMaterial::_shader_changed); + ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ShaderMaterial::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ShaderMaterial::property_get_revert); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shader", PROPERTY_HINT_RESOURCE_TYPE, "Shader"), "set_shader", "get_shader"); } @@ -400,10 +427,8 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_USE_VERTEX_LIGHTING]) { code += ",vertex_lighting"; } - bool using_world = false; if (flags[FLAG_TRIPLANAR_USE_WORLD] && (flags[FLAG_UV1_USE_TRIPLANAR] || flags[FLAG_UV2_USE_TRIPLANAR])) { code += ",world_vertex_coords"; - using_world = true; } if (flags[FLAG_DONT_RECEIVE_SHADOWS]) { code += ",shadows_disabled"; @@ -535,7 +560,9 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_SRGB_VERTEX_COLOR]) { - code += "\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; + code += "\tif (!OUTPUT_IS_SRGB) {\n"; + code += "\t\tCOLOR.rgb = mix( pow((COLOR.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), COLOR.rgb* (1.0 / 12.92), lessThan(COLOR.rgb,vec3(0.04045)) );\n"; + code += "\t}\n"; } if (flags[FLAG_USE_POINT_SIZE]) { @@ -583,11 +610,11 @@ void SpatialMaterial::_update_shader() { code += "\tMODELVIEW_MATRIX = INV_CAMERA_MATRIX * mat_world;\n"; //handle animation - code += "\tint particle_total_frames = particles_anim_h_frames * particles_anim_v_frames;\n"; - code += "\tint particle_frame = int(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; - code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0,particle_total_frames-1); else particle_frame=abs(particle_frame)%particle_total_frames;\n"; + code += "\tfloat particle_total_frames = float(particles_anim_h_frames * particles_anim_v_frames);\n"; + code += "\tfloat particle_frame = floor(INSTANCE_CUSTOM.z * float(particle_total_frames));\n"; + code += "\tif (particles_anim_loop) particle_frame=clamp(particle_frame,0.0,particle_total_frames-1.0); else particle_frame=mod(particle_frame,float(particle_total_frames));\n"; code += "\tUV /= vec2(float(particles_anim_h_frames),float(particles_anim_v_frames));\n"; - code += "\tUV += vec2(float(particle_frame % particles_anim_h_frames) / float(particles_anim_h_frames),float(particle_frame / particles_anim_h_frames) / float(particles_anim_v_frames));\n"; + code += "\tUV += vec2(mod(particle_frame,float(particles_anim_h_frames)) / float(particles_anim_h_frames),particle_frame / float(particles_anim_h_frames) / float(particles_anim_v_frames));\n"; } break; } @@ -790,7 +817,7 @@ void SpatialMaterial::_update_shader() { code += "\tALPHA = albedo.a * albedo_tex.a;\n"; } - if (proximity_fade_enabled) { + if (!VisualServer::get_singleton()->is_low_end() && proximity_fade_enabled) { code += "\tfloat depth_tex = textureLod(DEPTH_TEXTURE,SCREEN_UV,0.0).r;\n"; code += "\tvec4 world_pos = INV_PROJECTION_MATRIX * vec4(SCREEN_UV*2.0-1.0,depth_tex*2.0-1.0,1.0);\n"; code += "\tworld_pos.xyz/=world_pos.w;\n"; @@ -798,43 +825,45 @@ void SpatialMaterial::_update_shader() { } if (distance_fade != DISTANCE_FADE_DISABLED) { - if (distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER) { - - code += "\t{\n"; - if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { - code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n"; - - } else { - code += "\t\tfloat fade_distance=-VERTEX.z;\n"; + if ((distance_fade == DISTANCE_FADE_OBJECT_DITHER || distance_fade == DISTANCE_FADE_PIXEL_DITHER)) { + + if (!VisualServer::get_singleton()->is_low_end()) { + code += "\t{\n"; + if (distance_fade == DISTANCE_FADE_OBJECT_DITHER) { + code += "\t\tfloat fade_distance = abs((INV_CAMERA_MATRIX * WORLD_MATRIX[3]).z);\n"; + + } else { + code += "\t\tfloat fade_distance=-VERTEX.z;\n"; + } + + code += "\t\tfloat fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n"; + code += "\t\tint x = int(FRAGCOORD.x) % 4;\n"; + code += "\t\tint y = int(FRAGCOORD.y) % 4;\n"; + code += "\t\tint index = x + y * 4;\n"; + code += "\t\tfloat limit = 0.0;\n\n"; + code += "\t\tif (x < 8) {\n"; + code += "\t\t\tif (index == 0) limit = 0.0625;\n"; + code += "\t\t\tif (index == 1) limit = 0.5625;\n"; + code += "\t\t\tif (index == 2) limit = 0.1875;\n"; + code += "\t\t\tif (index == 3) limit = 0.6875;\n"; + code += "\t\t\tif (index == 4) limit = 0.8125;\n"; + code += "\t\t\tif (index == 5) limit = 0.3125;\n"; + code += "\t\t\tif (index == 6) limit = 0.9375;\n"; + code += "\t\t\tif (index == 7) limit = 0.4375;\n"; + code += "\t\t\tif (index == 8) limit = 0.25;\n"; + code += "\t\t\tif (index == 9) limit = 0.75;\n"; + code += "\t\t\tif (index == 10) limit = 0.125;\n"; + code += "\t\t\tif (index == 11) limit = 0.625;\n"; + code += "\t\t\tif (index == 12) limit = 1.0;\n"; + code += "\t\t\tif (index == 13) limit = 0.5;\n"; + code += "\t\t\tif (index == 14) limit = 0.875;\n"; + code += "\t\t\tif (index == 15) limit = 0.375;\n"; + code += "\t\t}\n\n"; + code += "\tif (fade < limit)\n"; + code += "\t\tdiscard;\n"; + code += "\t}\n\n"; } - code += "\t\tfloat fade=clamp(smoothstep(distance_fade_min,distance_fade_max,fade_distance),0.0,1.0);\n"; - code += "\t\tint x = int(FRAGCOORD.x) % 4;\n"; - code += "\t\tint y = int(FRAGCOORD.y) % 4;\n"; - code += "\t\tint index = x + y * 4;\n"; - code += "\t\tfloat limit = 0.0;\n\n"; - code += "\t\tif (x < 8) {\n"; - code += "\t\t\tif (index == 0) limit = 0.0625;\n"; - code += "\t\t\tif (index == 1) limit = 0.5625;\n"; - code += "\t\t\tif (index == 2) limit = 0.1875;\n"; - code += "\t\t\tif (index == 3) limit = 0.6875;\n"; - code += "\t\t\tif (index == 4) limit = 0.8125;\n"; - code += "\t\t\tif (index == 5) limit = 0.3125;\n"; - code += "\t\t\tif (index == 6) limit = 0.9375;\n"; - code += "\t\t\tif (index == 7) limit = 0.4375;\n"; - code += "\t\t\tif (index == 8) limit = 0.25;\n"; - code += "\t\t\tif (index == 9) limit = 0.75;\n"; - code += "\t\t\tif (index == 10) limit = 0.125;\n"; - code += "\t\t\tif (index == 11) limit = 0.625;\n"; - code += "\t\t\tif (index == 12) limit = 1.0;\n"; - code += "\t\t\tif (index == 13) limit = 0.5;\n"; - code += "\t\t\tif (index == 14) limit = 0.875;\n"; - code += "\t\t\tif (index == 15) limit = 0.375;\n"; - code += "\t\t}\n\n"; - code += "\tif (fade < limit)\n"; - code += "\t\tdiscard;\n"; - code += "\t}\n\n"; - } else { code += "\tALPHA*=clamp(smoothstep(distance_fade_min,distance_fade_max,-VERTEX.z),0.0,1.0);\n"; } @@ -924,7 +953,7 @@ void SpatialMaterial::_update_shader() { if (flags[FLAG_UV1_USE_TRIPLANAR]) { - code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal);\n"; + code += "\tvec4 detail_mask_tex = triplanar_texture(texture_detail_mask,uv1_power_normal,uv1_triplanar_pos);\n"; } else { code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n"; } @@ -1342,6 +1371,12 @@ void SpatialMaterial::_validate_feature(const String &text, Feature feature, Pro } } +void SpatialMaterial::_validate_high_end(const String &text, PropertyInfo &property) const { + if (property.name.begins_with(text)) { + property.usage |= PROPERTY_USAGE_HIGH_END_GFX; + } +} + void SpatialMaterial::_validate_property(PropertyInfo &property) const { _validate_feature("normal", FEATURE_NORMAL_MAPPING, property); _validate_feature("emission", FEATURE_EMISSION, property); @@ -1355,6 +1390,12 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const { _validate_feature("refraction", FEATURE_REFRACTION, property); _validate_feature("detail", FEATURE_DETAIL, property); + _validate_high_end("refraction", property); + _validate_high_end("subsurf_scatter", property); + _validate_high_end("anisotropy", property); + _validate_high_end("clearcoat", property); + _validate_high_end("depth", property); + if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) { property.usage = 0; } diff --git a/scene/resources/material.h b/scene/resources/material.h index f43d240a53..0154874ae4 100644 --- a/scene/resources/material.h +++ b/scene/resources/material.h @@ -31,10 +31,10 @@ #ifndef MATERIAL_H #define MATERIAL_H -#include "resource.h" +#include "core/resource.h" +#include "core/self_list.h" #include "scene/resources/shader.h" #include "scene/resources/texture.h" -#include "self_list.h" #include "servers/visual/shader_language.h" #include "servers/visual_server.h" /** @@ -85,6 +85,8 @@ 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; + bool property_can_revert(const String &p_name); + Variant property_get_revert(const String &p_name); static void _bind_methods(); @@ -440,6 +442,8 @@ private: static Ref<SpatialMaterial> materials_for_2d[MAX_MATERIALS_FOR_2D]; //used by Sprite3D and other stuff + void _validate_high_end(const String &text, PropertyInfo &property) const; + protected: static void _bind_methods(); void _validate_property(PropertyInfo &property) const; diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 042cf28fec..6cd701eb9a 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -30,18 +30,13 @@ #include "mesh.h" -#include "pair.h" +#include "core/pair.h" #include "scene/resources/concave_polygon_shape.h" #include "scene/resources/convex_polygon_shape.h" #include "surface_tool.h" #include <stdlib.h> -void Mesh::_clear_triangle_mesh() const { - - triangle_mesh.unref(); -} - Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { if (triangle_mesh.is_valid()) @@ -111,6 +106,11 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const { void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { + if (debug_lines.size() > 0) { + r_lines = debug_lines; + return; + } + Ref<TriangleMesh> tm = generate_triangle_mesh(); if (tm.is_null()) return; @@ -120,23 +120,25 @@ void Mesh::generate_debug_mesh_lines(Vector<Vector3> &r_lines) { const int triangles_num = tm->get_triangles().size(); PoolVector<Vector3> vertices = tm->get_vertices(); - r_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line + debug_lines.resize(tm->get_triangles().size() * 6); // 3 lines x 2 points each line PoolVector<int>::Read ind_r = triangle_indices.read(); PoolVector<Vector3>::Read ver_r = vertices.read(); for (int j = 0, x = 0, i = 0; i < triangles_num; j += 6, x += 3, ++i) { // Triangle line 1 - r_lines.write[j + 0] = ver_r[ind_r[x + 0]]; - r_lines.write[j + 1] = ver_r[ind_r[x + 1]]; + debug_lines.write[j + 0] = ver_r[ind_r[x + 0]]; + debug_lines.write[j + 1] = ver_r[ind_r[x + 1]]; // Triangle line 2 - r_lines.write[j + 2] = ver_r[ind_r[x + 1]]; - r_lines.write[j + 3] = ver_r[ind_r[x + 2]]; + debug_lines.write[j + 2] = ver_r[ind_r[x + 1]]; + debug_lines.write[j + 3] = ver_r[ind_r[x + 2]]; // Triangle line 3 - r_lines.write[j + 4] = ver_r[ind_r[x + 2]]; - r_lines.write[j + 5] = ver_r[ind_r[x + 0]]; + debug_lines.write[j + 4] = ver_r[ind_r[x + 2]]; + debug_lines.write[j + 5] = ver_r[ind_r[x + 0]]; } + + r_lines = debug_lines; } void Mesh::generate_debug_mesh_indices(Vector<Vector3> &r_points) { Ref<TriangleMesh> tm = generate_triangle_mesh(); @@ -482,6 +484,11 @@ void Mesh::_bind_methods() { ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "lightmap_size_hint"), "set_lightmap_size_hint", "get_lightmap_size_hint"); + ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count); + ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &Mesh::surface_get_arrays); + ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &Mesh::surface_get_blend_shape_arrays); + ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &Mesh::surface_get_material); + BIND_ENUM_CONSTANT(PRIMITIVE_POINTS); BIND_ENUM_CONSTANT(PRIMITIVE_LINES); BIND_ENUM_CONSTANT(PRIMITIVE_LINE_STRIP); @@ -531,53 +538,14 @@ void Mesh::_bind_methods() { BIND_ENUM_CONSTANT(ARRAY_MAX); } -void Mesh::clear_cache() { - _clear_triangle_mesh(); +void Mesh::clear_cache() const { + triangle_mesh.unref(); + debug_lines.clear(); } Mesh::Mesh() { } -static const char *_array_name[] = { - "vertex_array", - "normal_array", - "tangent_array", - "color_array", - "tex_uv_array", - "tex_uv2_array", - "bone_array", - "weights_array", - "index_array", - NULL -}; - -static const ArrayMesh::ArrayType _array_types[] = { - - ArrayMesh::ARRAY_VERTEX, - ArrayMesh::ARRAY_NORMAL, - ArrayMesh::ARRAY_TANGENT, - ArrayMesh::ARRAY_COLOR, - ArrayMesh::ARRAY_TEX_UV, - ArrayMesh::ARRAY_TEX_UV2, - ArrayMesh::ARRAY_BONES, - ArrayMesh::ARRAY_WEIGHTS, - ArrayMesh::ARRAY_INDEX -}; - -/* compatibility */ -static const int _format_translate[] = { - - ArrayMesh::ARRAY_FORMAT_VERTEX, - ArrayMesh::ARRAY_FORMAT_NORMAL, - ArrayMesh::ARRAY_FORMAT_TANGENT, - ArrayMesh::ARRAY_FORMAT_COLOR, - ArrayMesh::ARRAY_FORMAT_TEX_UV, - ArrayMesh::ARRAY_FORMAT_TEX_UV2, - ArrayMesh::ARRAY_FORMAT_BONES, - ArrayMesh::ARRAY_FORMAT_WEIGHTS, - ArrayMesh::ARRAY_FORMAT_INDEX, -}; - bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) { String sname = p_name; @@ -845,7 +813,7 @@ void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array & _recompute_aabb(); } - _clear_triangle_mesh(); + clear_cache(); _change_notify(); emit_changed(); } @@ -924,7 +892,7 @@ void ArrayMesh::surface_remove(int p_idx) { VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx); surfaces.remove(p_idx); - _clear_triangle_mesh(); + clear_cache(); _recompute_aabb(); _change_notify(); emit_changed(); @@ -1030,7 +998,7 @@ void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data else aabb.merge_with(s.aabb); - _clear_triangle_mesh(); + clear_cache(); surfaces.push_back(s); _change_notify(); @@ -1313,7 +1281,6 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode); ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT)); - ClassDB::bind_method(D_METHOD("get_surface_count"), &ArrayMesh::get_surface_count); ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove); ClassDB::bind_method(D_METHOD("surface_update_region", "surf_idx", "offset", "data"), &ArrayMesh::surface_update_region); ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len); @@ -1321,12 +1288,9 @@ void ArrayMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format); ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type); ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material"), &ArrayMesh::surface_set_material); - ClassDB::bind_method(D_METHOD("surface_get_material", "surf_idx"), &ArrayMesh::surface_get_material); ClassDB::bind_method(D_METHOD("surface_find_by_name", "name"), &ArrayMesh::surface_find_by_name); ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name); ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name); - ClassDB::bind_method(D_METHOD("surface_get_arrays", "surf_idx"), &ArrayMesh::surface_get_arrays); - ClassDB::bind_method(D_METHOD("surface_get_blend_shape_arrays", "surf_idx"), &ArrayMesh::surface_get_blend_shape_arrays); ClassDB::bind_method(D_METHOD("create_trimesh_shape"), &ArrayMesh::create_trimesh_shape); ClassDB::bind_method(D_METHOD("create_convex_shape"), &ArrayMesh::create_convex_shape); ClassDB::bind_method(D_METHOD("create_outline", "margin"), &ArrayMesh::create_outline); @@ -1374,6 +1338,7 @@ void ArrayMesh::reload_from_file() { VisualServer::get_singleton()->mesh_clear(mesh); surfaces.clear(); clear_blend_shapes(); + clear_cache(); Resource::reload_from_file(); diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h index 36bfca49f8..aebba09ef8 100644 --- a/scene/resources/mesh.h +++ b/scene/resources/mesh.h @@ -31,11 +31,11 @@ #ifndef MESH_H #define MESH_H -#include "resource.h" +#include "core/math/triangle_mesh.h" +#include "core/resource.h" #include "scene/resources/material.h" #include "scene/resources/shape.h" #include "servers/visual_server.h" -#include "triangle_mesh.h" /** @author Juan Linietsky <reduzio@gmail.com> */ @@ -44,11 +44,10 @@ class Mesh : public Resource { GDCLASS(Mesh, Resource); mutable Ref<TriangleMesh> triangle_mesh; //cached + mutable Vector<Vector3> debug_lines; Size2 lightmap_size_hint; protected: - void _clear_triangle_mesh() const; - static void _bind_methods(); public: @@ -146,7 +145,7 @@ public: void set_lightmap_size_hint(const Vector2 &p_size); Size2 get_lightmap_size_hint() const; - void clear_cache(); + void clear_cache() const; Mesh(); }; diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp index 6732303925..a5449e1fe8 100644 --- a/scene/resources/mesh_data_tool.cpp +++ b/scene/resources/mesh_data_tool.cpp @@ -79,9 +79,9 @@ Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surf if (arrays[Mesh::ARRAY_COLOR].get_type() != Variant::NIL) col = arrays[Mesh::ARRAY_COLOR].operator PoolVector<Color>().read(); - PoolVector<real_t>::Read bo; + PoolVector<int>::Read bo; if (arrays[Mesh::ARRAY_BONES].get_type() != Variant::NIL) - bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<real_t>().read(); + bo = arrays[Mesh::ARRAY_BONES].operator PoolVector<int>().read(); PoolVector<real_t>::Read we; if (arrays[Mesh::ARRAY_WEIGHTS].get_type() != Variant::NIL) @@ -194,7 +194,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { PoolVector<Vector2> u; PoolVector<Vector2> u2; PoolVector<Color> c; - PoolVector<real_t> b; + PoolVector<int> b; PoolVector<real_t> w; PoolVector<int> in; @@ -233,7 +233,7 @@ Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) { col = c.write(); } - PoolVector<real_t>::Write bo; + PoolVector<int>::Write bo; if (format & Mesh::ARRAY_FORMAT_BONES) { b.resize(vcount * 4); bo = b.write(); diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h index 69719960e2..3ce0cf9b66 100644 --- a/scene/resources/mesh_library.h +++ b/scene/resources/mesh_library.h @@ -31,9 +31,9 @@ #ifndef GRID_THEME_H #define GRID_THEME_H -#include "map.h" +#include "core/map.h" +#include "core/resource.h" #include "mesh.h" -#include "resource.h" #include "scene/3d/navigation_mesh.h" #include "shape.h" diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp index 4d0a14e3aa..e8e19fdb60 100644 --- a/scene/resources/multimesh.cpp +++ b/scene/resources/multimesh.cpp @@ -33,8 +33,6 @@ void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) { - int instance_count = get_instance_count(); - PoolVector<Vector3> xforms = p_array; int len = xforms.size(); ERR_FAIL_COND((len / 4) != instance_count); @@ -57,8 +55,6 @@ void MultiMesh::_set_transform_array(const PoolVector<Vector3> &p_array) { PoolVector<Vector3> MultiMesh::_get_transform_array() const { - int instance_count = get_instance_count(); - if (instance_count == 0) return PoolVector<Vector3>(); @@ -81,13 +77,11 @@ PoolVector<Vector3> MultiMesh::_get_transform_array() const { void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) { - int instance_count = get_instance_count(); - PoolVector<Color> colors = p_array; int len = colors.size(); - ERR_FAIL_COND(len != instance_count); if (len == 0) return; + ERR_FAIL_COND(len != instance_count); PoolVector<Color>::Read r = colors.read(); @@ -99,9 +93,7 @@ void MultiMesh::_set_color_array(const PoolVector<Color> &p_array) { PoolVector<Color> MultiMesh::_get_color_array() const { - int instance_count = get_instance_count(); - - if (instance_count == 0) + if (instance_count == 0 || color_format == COLOR_NONE) return PoolVector<Color>(); PoolVector<Color> colors; @@ -115,6 +107,37 @@ PoolVector<Color> MultiMesh::_get_color_array() const { return colors; } +void MultiMesh::_set_custom_data_array(const PoolVector<Color> &p_array) { + + PoolVector<Color> custom_datas = p_array; + int len = custom_datas.size(); + if (len == 0) + return; + ERR_FAIL_COND(len != instance_count); + + PoolVector<Color>::Read r = custom_datas.read(); + + for (int i = 0; i < len; i++) { + + set_instance_custom_data(i, r[i]); + } +} + +PoolVector<Color> MultiMesh::_get_custom_data_array() const { + + if (instance_count == 0 || custom_data_format == CUSTOM_DATA_NONE) + return PoolVector<Color>(); + + PoolVector<Color> custom_datas; + custom_datas.resize(instance_count); + + for (int i = 0; i < instance_count; i++) { + + custom_datas.set(i, get_instance_custom_data(i)); + } + + return custom_datas; +} void MultiMesh::set_mesh(const Ref<Mesh> &p_mesh) { mesh = p_mesh; @@ -130,12 +153,13 @@ Ref<Mesh> MultiMesh::get_mesh() const { } void MultiMesh::set_instance_count(int p_count) { - - VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format)); + ERR_FAIL_COND(p_count < 0); + VisualServer::get_singleton()->multimesh_allocate(multimesh, p_count, VS::MultimeshTransformFormat(transform_format), VS::MultimeshColorFormat(color_format), VS::MultimeshCustomDataFormat(custom_data_format)); + instance_count = p_count; } int MultiMesh::get_instance_count() const { - return VisualServer::get_singleton()->multimesh_get_instance_count(multimesh); + return instance_count; } void MultiMesh::set_instance_transform(int p_instance, const Transform &p_transform) { @@ -156,6 +180,15 @@ Color MultiMesh::get_instance_color(int p_instance) const { return VisualServer::get_singleton()->multimesh_instance_get_color(multimesh, p_instance); } +void MultiMesh::set_instance_custom_data(int p_instance, const Color &p_custom_data) { + + VisualServer::get_singleton()->multimesh_instance_set_custom_data(multimesh, p_instance, p_custom_data); +} +Color MultiMesh::get_instance_custom_data(int p_instance) const { + + return VisualServer::get_singleton()->multimesh_instance_get_custom_data(multimesh, p_instance); +} + AABB MultiMesh::get_aabb() const { return VisualServer::get_singleton()->multimesh_get_aabb(multimesh); @@ -168,6 +201,7 @@ RID MultiMesh::get_rid() const { void MultiMesh::set_color_format(ColorFormat p_color_format) { + ERR_FAIL_COND(instance_count > 0); color_format = p_color_format; } @@ -176,8 +210,20 @@ MultiMesh::ColorFormat MultiMesh::get_color_format() const { return color_format; } +void MultiMesh::set_custom_data_format(CustomDataFormat p_custom_data_format) { + + ERR_FAIL_COND(instance_count > 0); + custom_data_format = p_custom_data_format; +} + +MultiMesh::CustomDataFormat MultiMesh::get_custom_data_format() const { + + return custom_data_format; +} + void MultiMesh::set_transform_format(TransformFormat p_transform_format) { + ERR_FAIL_COND(instance_count > 0); transform_format = p_transform_format; } MultiMesh::TransformFormat MultiMesh::get_transform_format() const { @@ -191,6 +237,8 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_mesh"), &MultiMesh::get_mesh); ClassDB::bind_method(D_METHOD("set_color_format", "format"), &MultiMesh::set_color_format); ClassDB::bind_method(D_METHOD("get_color_format"), &MultiMesh::get_color_format); + ClassDB::bind_method(D_METHOD("set_custom_data_format", "format"), &MultiMesh::set_custom_data_format); + ClassDB::bind_method(D_METHOD("get_custom_data_format"), &MultiMesh::get_custom_data_format); ClassDB::bind_method(D_METHOD("set_transform_format", "format"), &MultiMesh::set_transform_format); ClassDB::bind_method(D_METHOD("get_transform_format"), &MultiMesh::get_transform_format); @@ -200,19 +248,25 @@ void MultiMesh::_bind_methods() { ClassDB::bind_method(D_METHOD("get_instance_transform", "instance"), &MultiMesh::get_instance_transform); ClassDB::bind_method(D_METHOD("set_instance_color", "instance", "color"), &MultiMesh::set_instance_color); ClassDB::bind_method(D_METHOD("get_instance_color", "instance"), &MultiMesh::get_instance_color); + ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data); + ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data); ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb); ClassDB::bind_method(D_METHOD("_set_transform_array"), &MultiMesh::_set_transform_array); ClassDB::bind_method(D_METHOD("_get_transform_array"), &MultiMesh::_get_transform_array); ClassDB::bind_method(D_METHOD("_set_color_array"), &MultiMesh::_set_color_array); ClassDB::bind_method(D_METHOD("_get_color_array"), &MultiMesh::_get_color_array); + ClassDB::bind_method(D_METHOD("_set_custom_data_array"), &MultiMesh::_set_custom_data_array); + ClassDB::bind_method(D_METHOD("_get_custom_data_array"), &MultiMesh::_get_custom_data_array); ADD_PROPERTY(PropertyInfo(Variant::INT, "color_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_color_format", "get_color_format"); ADD_PROPERTY(PropertyInfo(Variant::INT, "transform_format", PROPERTY_HINT_ENUM, "2D,3D"), "set_transform_format", "get_transform_format"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1"), "set_instance_count", "get_instance_count"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "custom_data_format", PROPERTY_HINT_ENUM, "None,Byte,Float"), "set_custom_data_format", "get_custom_data_format"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "instance_count", PROPERTY_HINT_RANGE, "0,16384,1,or_greater"), "set_instance_count", "get_instance_count"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "mesh", PROPERTY_HINT_RESOURCE_TYPE, "Mesh"), "set_mesh", "get_mesh"); ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR3_ARRAY, "transform_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_transform_array", "_get_transform_array"); ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "color_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_color_array", "_get_color_array"); + ADD_PROPERTY(PropertyInfo(Variant::POOL_COLOR_ARRAY, "custom_data_array", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "_set_custom_data_array", "_get_custom_data_array"); BIND_ENUM_CONSTANT(TRANSFORM_2D); BIND_ENUM_CONSTANT(TRANSFORM_3D); @@ -220,13 +274,19 @@ void MultiMesh::_bind_methods() { BIND_ENUM_CONSTANT(COLOR_NONE); BIND_ENUM_CONSTANT(COLOR_8BIT); BIND_ENUM_CONSTANT(COLOR_FLOAT); + + BIND_ENUM_CONSTANT(CUSTOM_DATA_NONE); + BIND_ENUM_CONSTANT(CUSTOM_DATA_8BIT); + BIND_ENUM_CONSTANT(CUSTOM_DATA_FLOAT); } MultiMesh::MultiMesh() { multimesh = VisualServer::get_singleton()->multimesh_create(); color_format = COLOR_NONE; + custom_data_format = CUSTOM_DATA_NONE; transform_format = TRANSFORM_2D; + instance_count = 0; } MultiMesh::~MultiMesh() { diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h index 0875d6d06d..ec5a5ca4d5 100644 --- a/scene/resources/multimesh.h +++ b/scene/resources/multimesh.h @@ -51,11 +51,19 @@ public: COLOR_FLOAT = VS::MULTIMESH_COLOR_FLOAT, }; + enum CustomDataFormat { + CUSTOM_DATA_NONE, + CUSTOM_DATA_8BIT, + CUSTOM_DATA_FLOAT, + }; + private: Ref<Mesh> mesh; RID multimesh; TransformFormat transform_format; ColorFormat color_format; + CustomDataFormat custom_data_format; + int instance_count; protected: static void _bind_methods(); @@ -66,6 +74,9 @@ protected: void _set_color_array(const PoolVector<Color> &p_array); PoolVector<Color> _get_color_array() const; + void _set_custom_data_array(const PoolVector<Color> &p_array); + PoolVector<Color> _get_custom_data_array() const; + public: void set_mesh(const Ref<Mesh> &p_mesh); Ref<Mesh> get_mesh() const; @@ -73,6 +84,9 @@ public: void set_color_format(ColorFormat p_color_format); ColorFormat get_color_format() const; + void set_custom_data_format(CustomDataFormat p_custom_data_format); + CustomDataFormat get_custom_data_format() const; + void set_transform_format(TransformFormat p_transform_format); TransformFormat get_transform_format() const; @@ -85,6 +99,9 @@ public: void set_instance_color(int p_instance, const Color &p_color); Color get_instance_color(int p_instance) const; + void set_instance_custom_data(int p_instance, const Color &p_custom_data); + Color get_instance_custom_data(int p_instance) const; + virtual AABB get_aabb() const; virtual RID get_rid() const; @@ -95,5 +112,6 @@ public: VARIANT_ENUM_CAST(MultiMesh::TransformFormat); VARIANT_ENUM_CAST(MultiMesh::ColorFormat); +VARIANT_ENUM_CAST(MultiMesh::CustomDataFormat); #endif // MULTI_MESH_H diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index f034e07ff9..086fb83af9 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -31,9 +31,9 @@ #include "packed_scene.h" #include "core/core_string_names.h" -#include "engine.h" -#include "io/resource_loader.h" -#include "project_settings.h" +#include "core/engine.h" +#include "core/io/resource_loader.h" +#include "core/project_settings.h" #include "scene/2d/node_2d.h" #include "scene/3d/spatial.h" #include "scene/gui/control.h" diff --git a/scene/resources/packed_scene.h b/scene/resources/packed_scene.h index 278986eb62..e5f22f5e3b 100644 --- a/scene/resources/packed_scene.h +++ b/scene/resources/packed_scene.h @@ -31,7 +31,7 @@ #ifndef PACKED_SCENE_H #define PACKED_SCENE_H -#include "resource.h" +#include "core/resource.h" #include "scene/main/node.h" class SceneState : public Reference { diff --git a/scene/resources/particles_material.cpp b/scene/resources/particles_material.cpp new file mode 100644 index 0000000000..6f67ba8af1 --- /dev/null +++ b/scene/resources/particles_material.cpp @@ -0,0 +1,1262 @@ +/*************************************************************************/ +/* particles_material.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "particles_material.h" + +Mutex *ParticlesMaterial::material_mutex = NULL; +SelfList<ParticlesMaterial>::List ParticlesMaterial::dirty_materials; +Map<ParticlesMaterial::MaterialKey, ParticlesMaterial::ShaderData> ParticlesMaterial::shader_map; +ParticlesMaterial::ShaderNames *ParticlesMaterial::shader_names = NULL; + +void ParticlesMaterial::init_shaders() { + +#ifndef NO_THREADS + material_mutex = Mutex::create(); +#endif + + shader_names = memnew(ShaderNames); + + shader_names->spread = "spread"; + shader_names->flatness = "flatness"; + shader_names->initial_linear_velocity = "initial_linear_velocity"; + shader_names->initial_angle = "initial_angle"; + shader_names->angular_velocity = "angular_velocity"; + shader_names->orbit_velocity = "orbit_velocity"; + shader_names->linear_accel = "linear_accel"; + shader_names->radial_accel = "radial_accel"; + shader_names->tangent_accel = "tangent_accel"; + shader_names->damping = "damping"; + shader_names->scale = "scale"; + shader_names->hue_variation = "hue_variation"; + shader_names->anim_speed = "anim_speed"; + shader_names->anim_offset = "anim_offset"; + + shader_names->initial_linear_velocity_random = "initial_linear_velocity_random"; + shader_names->initial_angle_random = "initial_angle_random"; + shader_names->angular_velocity_random = "angular_velocity_random"; + shader_names->orbit_velocity_random = "orbit_velocity_random"; + shader_names->linear_accel_random = "linear_accel_random"; + shader_names->radial_accel_random = "radial_accel_random"; + shader_names->tangent_accel_random = "tangent_accel_random"; + shader_names->damping_random = "damping_random"; + shader_names->scale_random = "scale_random"; + shader_names->hue_variation_random = "hue_variation_random"; + shader_names->anim_speed_random = "anim_speed_random"; + shader_names->anim_offset_random = "anim_offset_random"; + + shader_names->angle_texture = "angle_texture"; + shader_names->angular_velocity_texture = "angular_velocity_texture"; + shader_names->orbit_velocity_texture = "orbit_velocity_texture"; + shader_names->linear_accel_texture = "linear_accel_texture"; + shader_names->radial_accel_texture = "radial_accel_texture"; + shader_names->tangent_accel_texture = "tangent_accel_texture"; + shader_names->damping_texture = "damping_texture"; + shader_names->scale_texture = "scale_texture"; + shader_names->hue_variation_texture = "hue_variation_texture"; + shader_names->anim_speed_texture = "anim_speed_texture"; + shader_names->anim_offset_texture = "anim_offset_texture"; + + shader_names->color = "color_value"; + shader_names->color_ramp = "color_ramp"; + + shader_names->emission_sphere_radius = "emission_sphere_radius"; + shader_names->emission_box_extents = "emission_box_extents"; + shader_names->emission_texture_point_count = "emission_texture_point_count"; + shader_names->emission_texture_points = "emission_texture_points"; + shader_names->emission_texture_normal = "emission_texture_normal"; + shader_names->emission_texture_color = "emission_texture_color"; + + shader_names->trail_divisor = "trail_divisor"; + shader_names->trail_size_modifier = "trail_size_modifier"; + shader_names->trail_color_modifier = "trail_color_modifier"; + + shader_names->gravity = "gravity"; +} + +void ParticlesMaterial::finish_shaders() { + +#ifndef NO_THREADS + memdelete(material_mutex); +#endif + + memdelete(shader_names); +} + +void ParticlesMaterial::_update_shader() { + + dirty_materials.remove(&element); + + MaterialKey mk = _compute_key(); + if (mk.key == current_key.key) + return; //no update required in the end + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users == 0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + } + + current_key = mk; + + if (shader_map.has(mk)) { + + VS::get_singleton()->material_set_shader(_get_material(), shader_map[mk].shader); + shader_map[mk].users++; + return; + } + + //must create a shader! + + String code = "shader_type particles;\n"; + + code += "uniform float spread;\n"; + code += "uniform float flatness;\n"; + code += "uniform float initial_linear_velocity;\n"; + code += "uniform float initial_angle;\n"; + code += "uniform float angular_velocity;\n"; + code += "uniform float orbit_velocity;\n"; + code += "uniform float linear_accel;\n"; + code += "uniform float radial_accel;\n"; + code += "uniform float tangent_accel;\n"; + code += "uniform float damping;\n"; + code += "uniform float scale;\n"; + code += "uniform float hue_variation;\n"; + code += "uniform float anim_speed;\n"; + code += "uniform float anim_offset;\n"; + + code += "uniform float initial_linear_velocity_random;\n"; + code += "uniform float initial_angle_random;\n"; + code += "uniform float angular_velocity_random;\n"; + code += "uniform float orbit_velocity_random;\n"; + code += "uniform float linear_accel_random;\n"; + code += "uniform float radial_accel_random;\n"; + code += "uniform float tangent_accel_random;\n"; + code += "uniform float damping_random;\n"; + code += "uniform float scale_random;\n"; + code += "uniform float hue_variation_random;\n"; + code += "uniform float anim_speed_random;\n"; + code += "uniform float anim_offset_random;\n"; + + switch (emission_shape) { + case EMISSION_SHAPE_POINT: { + //do none + } break; + case EMISSION_SHAPE_SPHERE: { + code += "uniform float emission_sphere_radius;\n"; + } break; + case EMISSION_SHAPE_BOX: { + code += "uniform vec3 emission_box_extents;\n"; + } break; + case EMISSION_SHAPE_DIRECTED_POINTS: { + code += "uniform sampler2D emission_texture_normal : hint_black;\n"; + } //fallthrough + case EMISSION_SHAPE_POINTS: { + code += "uniform sampler2D emission_texture_points : hint_black;\n"; + code += "uniform int emission_texture_point_count;\n"; + if (emission_color_texture.is_valid()) { + code += "uniform sampler2D emission_texture_color : hint_white;\n"; + } + } break; + } + + code += "uniform vec4 color_value : hint_color;\n"; + + code += "uniform int trail_divisor;\n"; + + code += "uniform vec3 gravity;\n"; + + if (color_ramp.is_valid()) + code += "uniform sampler2D color_ramp;\n"; + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) + code += "uniform sampler2D linear_velocity_texture;\n"; + if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) + code += "uniform sampler2D orbit_velocity_texture;\n"; + if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) + code += "uniform sampler2D angular_velocity_texture;\n"; + if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) + code += "uniform sampler2D linear_accel_texture;\n"; + if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) + code += "uniform sampler2D radial_accel_texture;\n"; + if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) + code += "uniform sampler2D tangent_accel_texture;\n"; + if (tex_parameters[PARAM_DAMPING].is_valid()) + code += "uniform sampler2D damping_texture;\n"; + if (tex_parameters[PARAM_ANGLE].is_valid()) + code += "uniform sampler2D angle_texture;\n"; + if (tex_parameters[PARAM_SCALE].is_valid()) + code += "uniform sampler2D scale_texture;\n"; + if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) + code += "uniform sampler2D hue_variation_texture;\n"; + if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) + code += "uniform sampler2D anim_speed_texture;\n"; + if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) + code += "uniform sampler2D anim_offset_texture;\n"; + + if (trail_size_modifier.is_valid()) { + code += "uniform sampler2D trail_size_modifier;\n"; + } + + if (trail_color_modifier.is_valid()) { + code += "uniform sampler2D trail_color_modifier;\n"; + } + + //need a random function + code += "\n\n"; + code += "float rand_from_seed(inout uint seed) {\n"; + code += " int k;\n"; + code += " int s = int(seed);\n"; + code += " if (s == 0)\n"; + code += " s = 305420679;\n"; + code += " k = s / 127773;\n"; + code += " s = 16807 * (s - k * 127773) - 2836 * k;\n"; + code += " if (s < 0)\n"; + code += " s += 2147483647;\n"; + code += " seed = uint(s);\n"; + code += " return float(seed % uint(65536)) / 65535.0;\n"; + code += "}\n"; + code += "\n"; + + code += "float rand_from_seed_m1_p1(inout uint seed) {\n"; + code += " return rand_from_seed(seed) * 2.0 - 1.0;\n"; + code += "}\n"; + code += "\n"; + + //improve seed quality + code += "uint hash(uint x) {\n"; + code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + code += " x = ((x >> uint(16)) ^ x) * uint(73244475);\n"; + code += " x = (x >> uint(16)) ^ x;\n"; + code += " return x;\n"; + code += "}\n"; + code += "\n"; + + code += "void vertex() {\n"; + code += " uint base_number = NUMBER / uint(trail_divisor);\n"; + code += " uint alt_seed = hash(base_number + uint(1) + RANDOM_SEED);\n"; + code += " float angle_rand = rand_from_seed(alt_seed);\n"; + code += " float scale_rand = rand_from_seed(alt_seed);\n"; + code += " float hue_rot_rand = rand_from_seed(alt_seed);\n"; + code += " float anim_offset_rand = rand_from_seed(alt_seed);\n"; + code += " float pi = 3.14159;\n"; + code += " float degree_to_rad = pi / 180.0;\n"; + code += "\n"; + + if (emission_shape >= EMISSION_SHAPE_POINTS) { + code += " int point = min(emission_texture_point_count - 1, int(rand_from_seed(alt_seed) * float(emission_texture_point_count)));\n"; + 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"; + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) + code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(0.0, 0.0), 0.0).r;\n"; + else + code += " float tex_linear_velocity = 0.0;\n"; + + if (tex_parameters[PARAM_ANGLE].is_valid()) + code += " float tex_angle = textureLod(angle_texture, vec2(0.0, 0.0), 0.0).r;\n"; + else + code += " float tex_angle = 0.0;\n"; + + if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) + code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(0.0, 0.0), 0.0).r;\n"; + else + code += " float tex_anim_offset = 0.0;\n"; + + code += " float spread_rad = spread * degree_to_rad;\n"; + + if (flags[FLAG_DISABLE_Z]) { + + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " vec3 rot = vec3(cos(angle1_rad), sin(angle1_rad), 0.0);\n"; + code += " VELOCITY = rot * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + + } else { + //initiate velocity spread in 3D + code += " float angle1_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad;\n"; + code += " float angle2_rad = rand_from_seed_m1_p1(alt_seed) * spread_rad * (1.0 - flatness);\n"; + code += " vec3 direction_xz = vec3(sin(angle1_rad), 0, cos(angle1_rad));\n"; + code += " vec3 direction_yz = vec3(0, sin(angle2_rad), cos(angle2_rad));\n"; + code += " direction_yz.z = direction_yz.z / sqrt(direction_yz.z); // better uniform distribution\n"; + code += " vec3 direction = vec3(direction_xz.x * direction_yz.z, direction_yz.y, direction_xz.z * direction_yz.z);\n"; + code += " direction = normalize(direction);\n"; + code += " VELOCITY = direction * initial_linear_velocity * mix(1.0, rand_from_seed(alt_seed), initial_linear_velocity_random);\n"; + } + + code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n"; + code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle + code += " CUSTOM.y = 0.0;\n"; // phase + 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) { + case EMISSION_SHAPE_POINT: { + //do none + } break; + case EMISSION_SHAPE_SPHERE: { + code += " TRANSFORM[3].xyz = normalize(vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0)) * emission_sphere_radius;\n"; + } break; + case EMISSION_SHAPE_BOX: { + code += " TRANSFORM[3].xyz = vec3(rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, rand_from_seed(alt_seed) * 2.0 - 1.0) * emission_box_extents;\n"; + } break; + case EMISSION_SHAPE_POINTS: + case EMISSION_SHAPE_DIRECTED_POINTS: { + code += " TRANSFORM[3].xyz = texelFetch(emission_texture_points, emission_tex_ofs, 0).xyz;\n"; + + if (emission_shape == EMISSION_SHAPE_DIRECTED_POINTS) { + if (flags[FLAG_DISABLE_Z]) { + + code += " mat2 rotm;"; + code += " rotm[0] = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xy;\n"; + code += " rotm[1] = rotm[0].yx * vec2(1.0, -1.0);\n"; + code += " VELOCITY.xy = rotm * VELOCITY.xy;\n"; + } else { + code += " vec3 normal = texelFetch(emission_texture_normal, emission_tex_ofs, 0).xyz;\n"; + code += " vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0, 1.0, 0.0);\n"; + code += " vec3 tangent = normalize(cross(v0, normal));\n"; + code += " vec3 bitangent = normalize(cross(tangent, normal));\n"; + code += " VELOCITY = mat3(tangent, bitangent, normal) * VELOCITY;\n"; + } + } + } break; + } + code += " VELOCITY = (EMISSION_TRANSFORM * vec4(VELOCITY, 0.0)).xyz;\n"; + code += " TRANSFORM = EMISSION_TRANSFORM * TRANSFORM;\n"; + if (flags[FLAG_DISABLE_Z]) { + code += " VELOCITY.z = 0.0;\n"; + code += " TRANSFORM[3].z = 0.0;\n"; + } + + code += " } else {\n"; + + code += " CUSTOM.y += DELTA / LIFETIME;\n"; + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) + code += " float tex_linear_velocity = textureLod(linear_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_linear_velocity = 0.0;\n"; + + if (flags[FLAG_DISABLE_Z]) { + + if (tex_parameters[PARAM_ORBIT_VELOCITY].is_valid()) + code += " float tex_orbit_velocity = textureLod(orbit_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_orbit_velocity = 0.0;\n"; + } + + if (tex_parameters[PARAM_ANGULAR_VELOCITY].is_valid()) + code += " float tex_angular_velocity = textureLod(angular_velocity_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_angular_velocity = 0.0;\n"; + + if (tex_parameters[PARAM_LINEAR_ACCEL].is_valid()) + code += " float tex_linear_accel = textureLod(linear_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_linear_accel = 0.0;\n"; + + if (tex_parameters[PARAM_RADIAL_ACCEL].is_valid()) + code += " float tex_radial_accel = textureLod(radial_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_radial_accel = 0.0;\n"; + + if (tex_parameters[PARAM_TANGENTIAL_ACCEL].is_valid()) + code += " float tex_tangent_accel = textureLod(tangent_accel_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_tangent_accel = 0.0;\n"; + + if (tex_parameters[PARAM_DAMPING].is_valid()) + code += " float tex_damping = textureLod(damping_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_damping = 0.0;\n"; + + if (tex_parameters[PARAM_ANGLE].is_valid()) + code += " float tex_angle = textureLod(angle_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_angle = 0.0;\n"; + + if (tex_parameters[PARAM_ANIM_SPEED].is_valid()) + code += " float tex_anim_speed = textureLod(anim_speed_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_anim_speed = 0.0;\n"; + + if (tex_parameters[PARAM_ANIM_OFFSET].is_valid()) + code += " float tex_anim_offset = textureLod(anim_offset_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_anim_offset = 0.0;\n"; + + code += " vec3 force = gravity;\n"; + code += " vec3 pos = TRANSFORM[3].xyz;\n"; + if (flags[FLAG_DISABLE_Z]) { + code += " pos.z = 0.0;\n"; + } + code += " // apply linear acceleration\n"; + code += " force += length(VELOCITY) > 0.0 ? normalize(VELOCITY) * (linear_accel + tex_linear_accel) * mix(1.0, rand_from_seed(alt_seed), linear_accel_random) : vec3(0.0);\n"; + code += " // apply radial acceleration\n"; + code += " vec3 org = EMISSION_TRANSFORM[3].xyz;\n"; + code += " vec3 diff = pos - org;\n"; + code += " force += length(diff) > 0.0 ? normalize(diff) * (radial_accel + tex_radial_accel) * mix(1.0, rand_from_seed(alt_seed), radial_accel_random) : vec3(0.0);\n"; + code += " // apply tangential acceleration;\n"; + if (flags[FLAG_DISABLE_Z]) { + code += " force += length(diff.yx) > 0.0 ? vec3(normalize(diff.yx * vec2(-1.0, 1.0)), 0.0) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; + + } else { + code += " vec3 crossDiff = cross(normalize(diff), normalize(gravity));\n"; + code += " force += length(crossDiff) > 0.0 ? normalize(crossDiff) * ((tangent_accel + tex_tangent_accel) * mix(1.0, rand_from_seed(alt_seed), tangent_accel_random)) : vec3(0.0);\n"; + } + code += " // apply attractor forces\n"; + code += " VELOCITY += force * DELTA;\n"; + code += " // orbit velocity\n"; + if (flags[FLAG_DISABLE_Z]) { + + code += " float orbit_amount = (orbit_velocity + tex_orbit_velocity) * mix(1.0, rand_from_seed(alt_seed), orbit_velocity_random);\n"; + code += " if (orbit_amount != 0.0) {\n"; + code += " float ang = orbit_amount * DELTA * pi * 2.0;\n"; + code += " mat2 rot = mat2(vec2(cos(ang), -sin(ang)), vec2(sin(ang), cos(ang)));\n"; + code += " TRANSFORM[3].xy -= diff.xy;\n"; + code += " TRANSFORM[3].xy += rot * diff.xy;\n"; + code += " }\n"; + } + + if (tex_parameters[PARAM_INITIAL_LINEAR_VELOCITY].is_valid()) { + code += " VELOCITY = normalize(VELOCITY) * tex_linear_velocity;\n"; + } + code += " if (damping + tex_damping > 0.0) {\n"; + code += " float v = length(VELOCITY);\n"; + code += " float damp = (damping + tex_damping) * mix(1.0, rand_from_seed(alt_seed), damping_random);\n"; + code += " v -= damp * DELTA;\n"; + code += " if (v < 0.0) {\n"; + code += " VELOCITY = vec3(0.0);\n"; + code += " } else {\n"; + code += " VELOCITY = normalize(VELOCITY) * v;\n"; + code += " }\n"; + code += " }\n"; + code += " float base_angle = (initial_angle + tex_angle) * mix(1.0, angle_rand, initial_angle_random);\n"; + code += " base_angle += CUSTOM.y * LIFETIME * (angular_velocity + tex_angular_velocity) * mix(1.0, rand_from_seed(alt_seed) * 2.0 - 1.0, angular_velocity_random);\n"; + code += " CUSTOM.x = base_angle * degree_to_rad;\n"; // angle + code += " CUSTOM.z = (anim_offset + tex_anim_offset) * mix(1.0, anim_offset_rand, anim_offset_random) + CUSTOM.y * (anim_speed + tex_anim_speed) * mix(1.0, rand_from_seed(alt_seed), anim_speed_random);\n"; // angle + if (flags[FLAG_ANIM_LOOP]) { + code += " CUSTOM.z = mod(CUSTOM.z, 1.0);\n"; // loop + + } else { + code += " CUSTOM.z = clamp(CUSTOM.z, 0.0, 1.0);\n"; // 0 to 1 only + } + code += " }\n"; + // apply color + // apply hue rotation + if (tex_parameters[PARAM_SCALE].is_valid()) + code += " float tex_scale = textureLod(scale_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_scale = 1.0;\n"; + + if (tex_parameters[PARAM_HUE_VARIATION].is_valid()) + code += " float tex_hue_variation = textureLod(hue_variation_texture, vec2(CUSTOM.y, 0.0), 0.0).r;\n"; + else + code += " float tex_hue_variation = 0.0;\n"; + + code += " float hue_rot_angle = (hue_variation + tex_hue_variation) * pi * 2.0 * mix(1.0, hue_rot_rand * 2.0 - 1.0, hue_variation_random);\n"; + code += " float hue_rot_c = cos(hue_rot_angle);\n"; + code += " float hue_rot_s = sin(hue_rot_angle);\n"; + code += " mat4 hue_rot_mat = mat4(vec4(0.299, 0.587, 0.114, 0.0),\n"; + code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; + code += " vec4(0.299, 0.587, 0.114, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 1.0)) +\n"; + code += " mat4(vec4(0.701, -0.587, -0.114, 0.0),\n"; + code += " vec4(-0.299, 0.413, -0.114, 0.0),\n"; + code += " vec4(-0.300, -0.588, 0.886, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_c +\n"; + code += " mat4(vec4(0.168, 0.330, -0.497, 0.0),\n"; + code += " vec4(-0.328, 0.035, 0.292, 0.0),\n"; + code += " vec4(1.250, -1.050, -0.203, 0.0),\n"; + code += " vec4(0.000, 0.000, 0.000, 0.0)) * hue_rot_s;\n"; + if (color_ramp.is_valid()) { + code += " COLOR = hue_rot_mat * textureLod(color_ramp, vec2(CUSTOM.y, 0.0), 0.0);\n"; + } else { + code += " COLOR = hue_rot_mat * color_value;\n"; + } + if (emission_color_texture.is_valid() && emission_shape >= EMISSION_SHAPE_POINTS) { + code += " COLOR *= texelFetch(emission_texture_color, emission_tex_ofs, 0);\n"; + } + if (trail_color_modifier.is_valid()) { + code += " if (trail_divisor > 1) {\n"; + code += " COLOR *= textureLod(trail_color_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0);\n"; + code += " }\n"; + } + code += "\n"; + + if (flags[FLAG_DISABLE_Z]) { + + if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + code += " if (length(VELOCITY) > 0.0) {\n"; + code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; + code += " } else {\n"; + code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n"; + code += " }\n"; + code += " TRANSFORM[0].xyz = normalize(cross(TRANSFORM[1].xyz, TRANSFORM[2].xyz));\n"; + code += " TRANSFORM[2] = vec4(0.0, 0.0, 1.0, 0.0);\n"; + } else { + code += " TRANSFORM[0] = vec4(cos(CUSTOM.x), -sin(CUSTOM.x), 0.0, 0.0);\n"; + code += " TRANSFORM[1] = vec4(sin(CUSTOM.x), cos(CUSTOM.x), 0.0, 0.0);\n"; + code += " TRANSFORM[2] = vec4(0.0, 0.0, 1.0, 0.0);\n"; + } + + } else { + // orient particle Y towards velocity + if (flags[FLAG_ALIGN_Y_TO_VELOCITY]) { + code += " if (length(VELOCITY) > 0.0) {\n"; + code += " TRANSFORM[1].xyz = normalize(VELOCITY);\n"; + code += " } else {\n"; + code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n"; + code += " }\n"; + code += " if (TRANSFORM[1].xyz == normalize(TRANSFORM[0].xyz)) {\n"; + code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n"; + code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n"; + code += " } else {\n"; + code += " TRANSFORM[2].xyz = normalize(cross(normalize(TRANSFORM[0].xyz), normalize(TRANSFORM[1].xyz)));\n"; + code += " TRANSFORM[0].xyz = normalize(cross(normalize(TRANSFORM[1].xyz), normalize(TRANSFORM[2].xyz)));\n"; + code += " }\n"; + } else { + code += " TRANSFORM[0].xyz = normalize(TRANSFORM[0].xyz);\n"; + code += " TRANSFORM[1].xyz = normalize(TRANSFORM[1].xyz);\n"; + code += " TRANSFORM[2].xyz = normalize(TRANSFORM[2].xyz);\n"; + } + // turn particle by rotation in Y + if (flags[FLAG_ROTATE_Y]) { + code += " TRANSFORM = TRANSFORM * mat4(vec4(cos(CUSTOM.x), 0.0, -sin(CUSTOM.x), 0.0), vec4(0.0, 1.0, 0.0, 0.0), vec4(sin(CUSTOM.x), 0.0, cos(CUSTOM.x), 0.0), vec4(0.0, 0.0, 0.0, 1.0));\n"; + } + } + //scale by scale + code += " float base_scale = mix(scale * tex_scale, 1.0, scale_random * scale_rand);\n"; + code += " if (base_scale == 0.0) {\n"; + code += " base_scale = 0.000001;\n"; + code += " }\n"; + if (trail_size_modifier.is_valid()) { + code += " if (trail_divisor > 1) {\n"; + code += " base_scale *= textureLod(trail_size_modifier, vec2(float(int(NUMBER) % trail_divisor) / float(trail_divisor - 1), 0.0), 0.0).r;\n"; + code += " }\n"; + } + + code += " TRANSFORM[0].xyz *= base_scale;\n"; + code += " TRANSFORM[1].xyz *= base_scale;\n"; + code += " TRANSFORM[2].xyz *= base_scale;\n"; + if (flags[FLAG_DISABLE_Z]) { + code += " VELOCITY.z = 0.0;\n"; + code += " TRANSFORM[3].z = 0.0;\n"; + } + code += "}\n"; + code += "\n"; + + ShaderData shader_data; + shader_data.shader = VS::get_singleton()->shader_create(); + shader_data.users = 1; + + VS::get_singleton()->shader_set_code(shader_data.shader, code); + + shader_map[mk] = shader_data; + + VS::get_singleton()->material_set_shader(_get_material(), shader_data.shader); +} + +void ParticlesMaterial::flush_changes() { + + if (material_mutex) + material_mutex->lock(); + + while (dirty_materials.first()) { + + dirty_materials.first()->self()->_update_shader(); + } + + if (material_mutex) + material_mutex->unlock(); +} + +void ParticlesMaterial::_queue_shader_change() { + + if (material_mutex) + material_mutex->lock(); + + if (!element.in_list()) { + dirty_materials.add(&element); + } + + if (material_mutex) + material_mutex->unlock(); +} + +bool ParticlesMaterial::_is_shader_dirty() const { + + bool dirty = false; + + if (material_mutex) + material_mutex->lock(); + + dirty = element.in_list(); + + if (material_mutex) + material_mutex->unlock(); + + return dirty; +} + +void ParticlesMaterial::set_spread(float p_spread) { + + spread = p_spread; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->spread, p_spread); +} + +float ParticlesMaterial::get_spread() const { + + return spread; +} + +void ParticlesMaterial::set_flatness(float p_flatness) { + + flatness = p_flatness; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->flatness, p_flatness); +} +float ParticlesMaterial::get_flatness() const { + + return flatness; +} + +void ParticlesMaterial::set_param(Parameter p_param, float p_value) { + + ERR_FAIL_INDEX(p_param, PARAM_MAX); + + parameters[p_param] = p_value; + + switch (p_param) { + case PARAM_INITIAL_LINEAR_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity, p_value); + } break; + case PARAM_ANGULAR_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity, p_value); + } break; + case PARAM_ORBIT_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity, p_value); + } break; + case PARAM_LINEAR_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel, p_value); + } break; + case PARAM_RADIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel, p_value); + } break; + case PARAM_TANGENTIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel, p_value); + } break; + case PARAM_DAMPING: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping, p_value); + } break; + case PARAM_ANGLE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle, p_value); + } break; + case PARAM_SCALE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale, p_value); + } break; + case PARAM_HUE_VARIATION: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation, p_value); + } break; + case PARAM_ANIM_SPEED: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed, p_value); + } break; + case PARAM_ANIM_OFFSET: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset, p_value); + } break; + case PARAM_MAX: break; // Can't happen, but silences warning + } +} +float ParticlesMaterial::get_param(Parameter p_param) const { + + ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); + + return parameters[p_param]; +} + +void ParticlesMaterial::set_param_randomness(Parameter p_param, float p_value) { + + ERR_FAIL_INDEX(p_param, PARAM_MAX); + + randomness[p_param] = p_value; + + switch (p_param) { + case PARAM_INITIAL_LINEAR_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_linear_velocity_random, p_value); + } break; + case PARAM_ANGULAR_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_random, p_value); + } break; + case PARAM_ORBIT_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_random, p_value); + } break; + case PARAM_LINEAR_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_random, p_value); + } break; + case PARAM_RADIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_random, p_value); + } break; + case PARAM_TANGENTIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_random, p_value); + } break; + case PARAM_DAMPING: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_random, p_value); + } break; + case PARAM_ANGLE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->initial_angle_random, p_value); + } break; + case PARAM_SCALE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_random, p_value); + } break; + case PARAM_HUE_VARIATION: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_random, p_value); + } break; + case PARAM_ANIM_SPEED: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_random, p_value); + } break; + case PARAM_ANIM_OFFSET: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_random, p_value); + } break; + case PARAM_MAX: break; // Can't happen, but silences warning + } +} +float ParticlesMaterial::get_param_randomness(Parameter p_param) const { + + ERR_FAIL_INDEX_V(p_param, PARAM_MAX, 0); + + return randomness[p_param]; +} + +static void _adjust_curve_range(const Ref<Texture> &p_texture, float p_min, float p_max) { + + Ref<CurveTexture> curve_tex = p_texture; + if (!curve_tex.is_valid()) + return; + + curve_tex->ensure_default_setup(p_min, p_max); +} + +void ParticlesMaterial::set_param_texture(Parameter p_param, const Ref<Texture> &p_texture) { + + ERR_FAIL_INDEX(p_param, PARAM_MAX); + + tex_parameters[p_param] = p_texture; + + switch (p_param) { + case PARAM_INITIAL_LINEAR_VELOCITY: { + //do none for this one + } break; + case PARAM_ANGULAR_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angular_velocity_texture, p_texture); + _adjust_curve_range(p_texture, -360, 360); + } break; + case PARAM_ORBIT_VELOCITY: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->orbit_velocity_texture, p_texture); + _adjust_curve_range(p_texture, -500, 500); + } break; + case PARAM_LINEAR_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->linear_accel_texture, p_texture); + _adjust_curve_range(p_texture, -200, 200); + } break; + case PARAM_RADIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->radial_accel_texture, p_texture); + _adjust_curve_range(p_texture, -200, 200); + } break; + case PARAM_TANGENTIAL_ACCEL: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->tangent_accel_texture, p_texture); + _adjust_curve_range(p_texture, -200, 200); + } break; + case PARAM_DAMPING: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->damping_texture, p_texture); + _adjust_curve_range(p_texture, 0, 100); + } break; + case PARAM_ANGLE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->angle_texture, p_texture); + _adjust_curve_range(p_texture, -360, 360); + } break; + case PARAM_SCALE: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->scale_texture, p_texture); + + Ref<CurveTexture> curve_tex = p_texture; + if (curve_tex.is_valid()) { + curve_tex->ensure_default_setup(); + } + + } break; + case PARAM_HUE_VARIATION: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->hue_variation_texture, p_texture); + _adjust_curve_range(p_texture, -1, 1); + } break; + case PARAM_ANIM_SPEED: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_speed_texture, p_texture); + _adjust_curve_range(p_texture, 0, 200); + } break; + case PARAM_ANIM_OFFSET: { + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->anim_offset_texture, p_texture); + } break; + case PARAM_MAX: break; // Can't happen, but silences warning + } + + _queue_shader_change(); +} +Ref<Texture> ParticlesMaterial::get_param_texture(Parameter p_param) const { + + ERR_FAIL_INDEX_V(p_param, PARAM_MAX, Ref<Texture>()); + + return tex_parameters[p_param]; +} + +void ParticlesMaterial::set_color(const Color &p_color) { + + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color, p_color); + color = p_color; +} + +Color ParticlesMaterial::get_color() const { + + return color; +} + +void ParticlesMaterial::set_color_ramp(const Ref<Texture> &p_texture) { + + color_ramp = p_texture; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->color_ramp, p_texture); + _queue_shader_change(); + _change_notify(); +} + +Ref<Texture> ParticlesMaterial::get_color_ramp() const { + + return color_ramp; +} + +void ParticlesMaterial::set_flag(Flags p_flag, bool p_enable) { + ERR_FAIL_INDEX(p_flag, FLAG_MAX); + flags[p_flag] = p_enable; + _queue_shader_change(); + if (p_flag == FLAG_DISABLE_Z) { + _change_notify(); + } +} + +bool ParticlesMaterial::get_flag(Flags p_flag) const { + ERR_FAIL_INDEX_V(p_flag, FLAG_MAX, false); + return flags[p_flag]; +} + +void ParticlesMaterial::set_emission_shape(EmissionShape p_shape) { + + emission_shape = p_shape; + _change_notify(); + _queue_shader_change(); +} + +void ParticlesMaterial::set_emission_sphere_radius(float p_radius) { + + emission_sphere_radius = p_radius; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_sphere_radius, p_radius); +} + +void ParticlesMaterial::set_emission_box_extents(Vector3 p_extents) { + + emission_box_extents = p_extents; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_box_extents, p_extents); +} + +void ParticlesMaterial::set_emission_point_texture(const Ref<Texture> &p_points) { + + emission_point_texture = p_points; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_points, p_points); +} + +void ParticlesMaterial::set_emission_normal_texture(const Ref<Texture> &p_normals) { + + emission_normal_texture = p_normals; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_normal, p_normals); +} + +void ParticlesMaterial::set_emission_color_texture(const Ref<Texture> &p_colors) { + + emission_color_texture = p_colors; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_color, p_colors); + _queue_shader_change(); +} + +void ParticlesMaterial::set_emission_point_count(int p_count) { + + emission_point_count = p_count; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->emission_texture_point_count, p_count); +} + +ParticlesMaterial::EmissionShape ParticlesMaterial::get_emission_shape() const { + + return emission_shape; +} + +float ParticlesMaterial::get_emission_sphere_radius() const { + + return emission_sphere_radius; +} +Vector3 ParticlesMaterial::get_emission_box_extents() const { + + return emission_box_extents; +} +Ref<Texture> ParticlesMaterial::get_emission_point_texture() const { + + return emission_point_texture; +} +Ref<Texture> ParticlesMaterial::get_emission_normal_texture() const { + + return emission_normal_texture; +} + +Ref<Texture> ParticlesMaterial::get_emission_color_texture() const { + + return emission_color_texture; +} + +int ParticlesMaterial::get_emission_point_count() const { + + return emission_point_count; +} + +void ParticlesMaterial::set_trail_divisor(int p_divisor) { + + trail_divisor = p_divisor; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_divisor, p_divisor); +} + +int ParticlesMaterial::get_trail_divisor() const { + + return trail_divisor; +} + +void ParticlesMaterial::set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier) { + + trail_size_modifier = p_trail_size_modifier; + + Ref<CurveTexture> curve = trail_size_modifier; + if (curve.is_valid()) { + curve->ensure_default_setup(); + } + + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_size_modifier, curve); + _queue_shader_change(); +} + +Ref<CurveTexture> ParticlesMaterial::get_trail_size_modifier() const { + + return trail_size_modifier; +} + +void ParticlesMaterial::set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier) { + + trail_color_modifier = p_trail_color_modifier; + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->trail_color_modifier, p_trail_color_modifier); + _queue_shader_change(); +} + +Ref<GradientTexture> ParticlesMaterial::get_trail_color_modifier() const { + + return trail_color_modifier; +} + +void ParticlesMaterial::set_gravity(const Vector3 &p_gravity) { + + gravity = p_gravity; + Vector3 gset = gravity; + if (gset == Vector3()) { + gset = Vector3(0, -0.000001, 0); //as gravity is used as upvector in some calculations + } + VisualServer::get_singleton()->material_set_param(_get_material(), shader_names->gravity, gset); +} + +Vector3 ParticlesMaterial::get_gravity() const { + + return gravity; +} + +RID ParticlesMaterial::get_shader_rid() const { + + ERR_FAIL_COND_V(!shader_map.has(current_key), RID()); + return shader_map[current_key].shader; +} + +void ParticlesMaterial::_validate_property(PropertyInfo &property) const { + + if (property.name == "color" && color_ramp.is_valid()) { + property.usage = 0; + } + + if (property.name == "emission_sphere_radius" && emission_shape != EMISSION_SHAPE_SPHERE) { + property.usage = 0; + } + + if (property.name == "emission_box_extents" && emission_shape != EMISSION_SHAPE_BOX) { + property.usage = 0; + } + + if ((property.name == "emission_point_texture" || property.name == "emission_color_texture") && (emission_shape < EMISSION_SHAPE_POINTS)) { + property.usage = 0; + } + + if (property.name == "emission_normal_texture" && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS) { + property.usage = 0; + } + + if (property.name == "emission_point_count" && (emission_shape != EMISSION_SHAPE_POINTS && emission_shape != EMISSION_SHAPE_DIRECTED_POINTS)) { + property.usage = 0; + } + + if (property.name.begins_with("orbit_") && !flags[FLAG_DISABLE_Z]) { + property.usage = 0; + } +} + +Shader::Mode ParticlesMaterial::get_shader_mode() const { + + return Shader::MODE_PARTICLES; +} + +void ParticlesMaterial::_bind_methods() { + + ClassDB::bind_method(D_METHOD("set_spread", "degrees"), &ParticlesMaterial::set_spread); + ClassDB::bind_method(D_METHOD("get_spread"), &ParticlesMaterial::get_spread); + + ClassDB::bind_method(D_METHOD("set_flatness", "amount"), &ParticlesMaterial::set_flatness); + ClassDB::bind_method(D_METHOD("get_flatness"), &ParticlesMaterial::get_flatness); + + ClassDB::bind_method(D_METHOD("set_param", "param", "value"), &ParticlesMaterial::set_param); + ClassDB::bind_method(D_METHOD("get_param", "param"), &ParticlesMaterial::get_param); + + ClassDB::bind_method(D_METHOD("set_param_randomness", "param", "randomness"), &ParticlesMaterial::set_param_randomness); + ClassDB::bind_method(D_METHOD("get_param_randomness", "param"), &ParticlesMaterial::get_param_randomness); + + ClassDB::bind_method(D_METHOD("set_param_texture", "param", "texture"), &ParticlesMaterial::set_param_texture); + ClassDB::bind_method(D_METHOD("get_param_texture", "param"), &ParticlesMaterial::get_param_texture); + + ClassDB::bind_method(D_METHOD("set_color", "color"), &ParticlesMaterial::set_color); + ClassDB::bind_method(D_METHOD("get_color"), &ParticlesMaterial::get_color); + + ClassDB::bind_method(D_METHOD("set_color_ramp", "ramp"), &ParticlesMaterial::set_color_ramp); + ClassDB::bind_method(D_METHOD("get_color_ramp"), &ParticlesMaterial::get_color_ramp); + + ClassDB::bind_method(D_METHOD("set_flag", "flag", "enable"), &ParticlesMaterial::set_flag); + ClassDB::bind_method(D_METHOD("get_flag", "flag"), &ParticlesMaterial::get_flag); + + ClassDB::bind_method(D_METHOD("set_emission_shape", "shape"), &ParticlesMaterial::set_emission_shape); + ClassDB::bind_method(D_METHOD("get_emission_shape"), &ParticlesMaterial::get_emission_shape); + + ClassDB::bind_method(D_METHOD("set_emission_sphere_radius", "radius"), &ParticlesMaterial::set_emission_sphere_radius); + ClassDB::bind_method(D_METHOD("get_emission_sphere_radius"), &ParticlesMaterial::get_emission_sphere_radius); + + ClassDB::bind_method(D_METHOD("set_emission_box_extents", "extents"), &ParticlesMaterial::set_emission_box_extents); + ClassDB::bind_method(D_METHOD("get_emission_box_extents"), &ParticlesMaterial::get_emission_box_extents); + + ClassDB::bind_method(D_METHOD("set_emission_point_texture", "texture"), &ParticlesMaterial::set_emission_point_texture); + ClassDB::bind_method(D_METHOD("get_emission_point_texture"), &ParticlesMaterial::get_emission_point_texture); + + ClassDB::bind_method(D_METHOD("set_emission_normal_texture", "texture"), &ParticlesMaterial::set_emission_normal_texture); + ClassDB::bind_method(D_METHOD("get_emission_normal_texture"), &ParticlesMaterial::get_emission_normal_texture); + + ClassDB::bind_method(D_METHOD("set_emission_color_texture", "texture"), &ParticlesMaterial::set_emission_color_texture); + ClassDB::bind_method(D_METHOD("get_emission_color_texture"), &ParticlesMaterial::get_emission_color_texture); + + ClassDB::bind_method(D_METHOD("set_emission_point_count", "point_count"), &ParticlesMaterial::set_emission_point_count); + ClassDB::bind_method(D_METHOD("get_emission_point_count"), &ParticlesMaterial::get_emission_point_count); + + ClassDB::bind_method(D_METHOD("set_trail_divisor", "divisor"), &ParticlesMaterial::set_trail_divisor); + ClassDB::bind_method(D_METHOD("get_trail_divisor"), &ParticlesMaterial::get_trail_divisor); + + ClassDB::bind_method(D_METHOD("set_trail_size_modifier", "texture"), &ParticlesMaterial::set_trail_size_modifier); + ClassDB::bind_method(D_METHOD("get_trail_size_modifier"), &ParticlesMaterial::get_trail_size_modifier); + + ClassDB::bind_method(D_METHOD("set_trail_color_modifier", "texture"), &ParticlesMaterial::set_trail_color_modifier); + ClassDB::bind_method(D_METHOD("get_trail_color_modifier"), &ParticlesMaterial::get_trail_color_modifier); + + ClassDB::bind_method(D_METHOD("get_gravity"), &ParticlesMaterial::get_gravity); + ClassDB::bind_method(D_METHOD("set_gravity", "accel_vec"), &ParticlesMaterial::set_gravity); + + ADD_GROUP("Trail", "trail_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "trail_divisor", PROPERTY_HINT_RANGE, "1,1000000,1"), "set_trail_divisor", "get_trail_divisor"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_size_modifier", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_trail_size_modifier", "get_trail_size_modifier"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "trail_color_modifier", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_trail_color_modifier", "get_trail_color_modifier"); + ADD_GROUP("Emission Shape", "emission_"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_shape", PROPERTY_HINT_ENUM, "Point,Sphere,Box,Points,Directed Points"), "set_emission_shape", "get_emission_shape"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "emission_sphere_radius", PROPERTY_HINT_RANGE, "0.01,128,0.01,or_greater"), "set_emission_sphere_radius", "get_emission_sphere_radius"); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "emission_box_extents"), "set_emission_box_extents", "get_emission_box_extents"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_point_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_point_texture", "get_emission_point_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_normal_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_normal_texture", "get_emission_normal_texture"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "emission_color_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_emission_color_texture", "get_emission_color_texture"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "emission_point_count", PROPERTY_HINT_RANGE, "0,1000000,1"), "set_emission_point_count", "get_emission_point_count"); + ADD_GROUP("Flags", "flag_"); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_align_y"), "set_flag", "get_flag", FLAG_ALIGN_Y_TO_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_rotate_y"), "set_flag", "get_flag", FLAG_ROTATE_Y); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flag_disable_z"), "set_flag", "get_flag", FLAG_DISABLE_Z); + ADD_GROUP("Spread", ""); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "spread", PROPERTY_HINT_RANGE, "0,180,0.01"), "set_spread", "get_spread"); + ADD_PROPERTY(PropertyInfo(Variant::REAL, "flatness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_flatness", "get_flatness"); + ADD_GROUP("Gravity", ""); + ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "gravity"), "set_gravity", "get_gravity"); + ADD_GROUP("Initial Velocity", "initial_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity", PROPERTY_HINT_RANGE, "0,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "initial_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_INITIAL_LINEAR_VELOCITY); + ADD_GROUP("Angular Velocity", "angular_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity", PROPERTY_HINT_RANGE, "-360,360,0.01"), "set_param", "get_param", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angular_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGULAR_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angular_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGULAR_VELOCITY); + ADD_GROUP("Orbit Velocity", "orbit_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity", PROPERTY_HINT_RANGE, "-1000,1000,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "orbit_velocity_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ORBIT_VELOCITY); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "orbit_velocity_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ORBIT_VELOCITY); + ADD_GROUP("Linear Accel", "linear_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "linear_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_LINEAR_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "linear_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_LINEAR_ACCEL); + ADD_GROUP("Radial Accel", "radial_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "radial_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_RADIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "radial_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_RADIAL_ACCEL); + ADD_GROUP("Tangential Accel", "tangential_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel", PROPERTY_HINT_RANGE, "-100,100,0.01,or_lesser,or_greater"), "set_param", "get_param", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "tangential_accel_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_TANGENTIAL_ACCEL); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "tangential_accel_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_TANGENTIAL_ACCEL); + ADD_GROUP("Damping", ""); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping", PROPERTY_HINT_RANGE, "0,100,0.01,or_greater"), "set_param", "get_param", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "damping_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_DAMPING); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "damping_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_DAMPING); + ADD_GROUP("Angle", ""); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle", PROPERTY_HINT_RANGE, "-720,720,0.1,or_lesser,or_greater"), "set_param", "get_param", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "angle_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANGLE); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "angle_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANGLE); + ADD_GROUP("Scale", ""); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale", PROPERTY_HINT_RANGE, "0,1000,0.01,or_greater"), "set_param", "get_param", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "scale_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_SCALE); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "scale_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_SCALE); + ADD_GROUP("Color", ""); + ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color"), "set_color", "get_color"); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "GradientTexture"), "set_color_ramp", "get_color_ramp"); + + ADD_GROUP("Hue Variation", "hue_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation", PROPERTY_HINT_RANGE, "-1,1,0.1"), "set_param", "get_param", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "hue_variation_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_HUE_VARIATION); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "hue_variation_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_HUE_VARIATION); + ADD_GROUP("Animation", "anim_"); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed", PROPERTY_HINT_RANGE, "0,128,0.01,or_greater"), "set_param", "get_param", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_speed_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_speed_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_SPEED); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param", "get_param", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "anim_offset_random", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_param_randomness", "get_param_randomness", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "anim_offset_curve", PROPERTY_HINT_RESOURCE_TYPE, "CurveTexture"), "set_param_texture", "get_param_texture", PARAM_ANIM_OFFSET); + ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "anim_loop"), "set_flag", "get_flag", FLAG_ANIM_LOOP); + + BIND_ENUM_CONSTANT(PARAM_INITIAL_LINEAR_VELOCITY); + BIND_ENUM_CONSTANT(PARAM_ANGULAR_VELOCITY); + BIND_ENUM_CONSTANT(PARAM_ORBIT_VELOCITY); + BIND_ENUM_CONSTANT(PARAM_LINEAR_ACCEL); + BIND_ENUM_CONSTANT(PARAM_RADIAL_ACCEL); + BIND_ENUM_CONSTANT(PARAM_TANGENTIAL_ACCEL); + BIND_ENUM_CONSTANT(PARAM_DAMPING); + BIND_ENUM_CONSTANT(PARAM_ANGLE); + BIND_ENUM_CONSTANT(PARAM_SCALE); + BIND_ENUM_CONSTANT(PARAM_HUE_VARIATION); + BIND_ENUM_CONSTANT(PARAM_ANIM_SPEED); + BIND_ENUM_CONSTANT(PARAM_ANIM_OFFSET); + BIND_ENUM_CONSTANT(PARAM_MAX); + + BIND_ENUM_CONSTANT(FLAG_ALIGN_Y_TO_VELOCITY); + BIND_ENUM_CONSTANT(FLAG_ROTATE_Y); + BIND_ENUM_CONSTANT(FLAG_MAX); + + BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINT); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_SPHERE); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_BOX); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_POINTS); + BIND_ENUM_CONSTANT(EMISSION_SHAPE_DIRECTED_POINTS); +} + +ParticlesMaterial::ParticlesMaterial() : + element(this) { + + set_spread(45); + set_flatness(0); + set_param(PARAM_INITIAL_LINEAR_VELOCITY, 0); + set_param(PARAM_ORBIT_VELOCITY, 0); + set_param(PARAM_LINEAR_ACCEL, 0); + set_param(PARAM_RADIAL_ACCEL, 0); + set_param(PARAM_TANGENTIAL_ACCEL, 0); + set_param(PARAM_DAMPING, 0); + set_param(PARAM_ANGLE, 0); + set_param(PARAM_SCALE, 1); + set_param(PARAM_HUE_VARIATION, 0); + set_param(PARAM_ANIM_SPEED, 0); + set_param(PARAM_ANIM_OFFSET, 0); + set_emission_shape(EMISSION_SHAPE_POINT); + set_emission_sphere_radius(1); + set_emission_box_extents(Vector3(1, 1, 1)); + set_trail_divisor(1); + set_gravity(Vector3(0, -9.8, 0)); + emission_point_count = 1; + + for (int i = 0; i < PARAM_MAX; i++) { + set_param_randomness(Parameter(i), 0); + } + + for (int i = 0; i < FLAG_MAX; i++) { + flags[i] = false; + } + + set_color(Color(1, 1, 1, 1)); + + current_key.key = 0; + current_key.invalid_key = 1; + + _queue_shader_change(); +} + +ParticlesMaterial::~ParticlesMaterial() { + + if (material_mutex) + material_mutex->lock(); + + if (shader_map.has(current_key)) { + shader_map[current_key].users--; + if (shader_map[current_key].users == 0) { + //deallocate shader, as it's no longer in use + VS::get_singleton()->free(shader_map[current_key].shader); + shader_map.erase(current_key); + } + + VS::get_singleton()->material_set_shader(_get_material(), RID()); + } + + if (material_mutex) + material_mutex->unlock(); +} diff --git a/scene/resources/particles_material.h b/scene/resources/particles_material.h new file mode 100644 index 0000000000..91fdcc0346 --- /dev/null +++ b/scene/resources/particles_material.h @@ -0,0 +1,302 @@ +/*************************************************************************/ +/* particles_material.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "core/rid.h" +#include "scene/resources/material.h" + +#ifndef PARTICLES_MATERIAL_H +#define PARTICLES_MATERIAL_H + +class ParticlesMaterial : public Material { + + GDCLASS(ParticlesMaterial, Material) + +public: + enum Parameter { + + PARAM_INITIAL_LINEAR_VELOCITY, + PARAM_ANGULAR_VELOCITY, + PARAM_ORBIT_VELOCITY, + PARAM_LINEAR_ACCEL, + PARAM_RADIAL_ACCEL, + PARAM_TANGENTIAL_ACCEL, + PARAM_DAMPING, + PARAM_ANGLE, + PARAM_SCALE, + PARAM_HUE_VARIATION, + PARAM_ANIM_SPEED, + PARAM_ANIM_OFFSET, + PARAM_MAX + }; + + enum Flags { + FLAG_ALIGN_Y_TO_VELOCITY, + FLAG_ROTATE_Y, + FLAG_DISABLE_Z, + FLAG_ANIM_LOOP, + FLAG_MAX + }; + + enum EmissionShape { + EMISSION_SHAPE_POINT, + EMISSION_SHAPE_SPHERE, + EMISSION_SHAPE_BOX, + EMISSION_SHAPE_POINTS, + EMISSION_SHAPE_DIRECTED_POINTS, + }; + +private: + union MaterialKey { + + struct { + uint32_t texture_mask : 16; + uint32_t texture_color : 1; + uint32_t flags : 4; + uint32_t emission_shape : 2; + uint32_t trail_size_texture : 1; + uint32_t trail_color_texture : 1; + uint32_t invalid_key : 1; + uint32_t has_emission_color : 1; + }; + + uint32_t key; + + bool operator<(const MaterialKey &p_key) const { + return key < p_key.key; + } + }; + + struct ShaderData { + RID shader; + int users; + }; + + static Map<MaterialKey, ShaderData> shader_map; + + MaterialKey current_key; + + _FORCE_INLINE_ MaterialKey _compute_key() const { + + MaterialKey mk; + mk.key = 0; + for (int i = 0; i < PARAM_MAX; i++) { + if (tex_parameters[i].is_valid()) { + mk.texture_mask |= (1 << i); + } + } + for (int i = 0; i < FLAG_MAX; i++) { + if (flags[i]) { + mk.flags |= (1 << i); + } + } + + mk.texture_color = color_ramp.is_valid() ? 1 : 0; + mk.emission_shape = emission_shape; + mk.trail_color_texture = trail_color_modifier.is_valid() ? 1 : 0; + mk.trail_size_texture = trail_size_modifier.is_valid() ? 1 : 0; + mk.has_emission_color = emission_shape >= EMISSION_SHAPE_POINTS && emission_color_texture.is_valid(); + + return mk; + } + + static Mutex *material_mutex; + static SelfList<ParticlesMaterial>::List dirty_materials; + + struct ShaderNames { + StringName spread; + StringName flatness; + StringName initial_linear_velocity; + StringName initial_angle; + StringName angular_velocity; + StringName orbit_velocity; + StringName linear_accel; + StringName radial_accel; + StringName tangent_accel; + StringName damping; + StringName scale; + StringName hue_variation; + StringName anim_speed; + StringName anim_offset; + + StringName initial_linear_velocity_random; + StringName initial_angle_random; + StringName angular_velocity_random; + StringName orbit_velocity_random; + StringName linear_accel_random; + StringName radial_accel_random; + StringName tangent_accel_random; + StringName damping_random; + StringName scale_random; + StringName hue_variation_random; + StringName anim_speed_random; + StringName anim_offset_random; + + StringName angle_texture; + StringName angular_velocity_texture; + StringName orbit_velocity_texture; + StringName linear_accel_texture; + StringName radial_accel_texture; + StringName tangent_accel_texture; + StringName damping_texture; + StringName scale_texture; + StringName hue_variation_texture; + StringName anim_speed_texture; + StringName anim_offset_texture; + + StringName color; + StringName color_ramp; + + StringName emission_sphere_radius; + StringName emission_box_extents; + StringName emission_texture_point_count; + StringName emission_texture_points; + StringName emission_texture_normal; + StringName emission_texture_color; + + StringName trail_divisor; + StringName trail_size_modifier; + StringName trail_color_modifier; + + StringName gravity; + }; + + static ShaderNames *shader_names; + + SelfList<ParticlesMaterial> element; + + void _update_shader(); + _FORCE_INLINE_ void _queue_shader_change(); + _FORCE_INLINE_ bool _is_shader_dirty() const; + + float spread; + float flatness; + + float parameters[PARAM_MAX]; + float randomness[PARAM_MAX]; + + Ref<Texture> tex_parameters[PARAM_MAX]; + Color color; + Ref<Texture> color_ramp; + + bool flags[FLAG_MAX]; + + EmissionShape emission_shape; + float emission_sphere_radius; + Vector3 emission_box_extents; + Ref<Texture> emission_point_texture; + Ref<Texture> emission_normal_texture; + Ref<Texture> emission_color_texture; + int emission_point_count; + + bool anim_loop; + + int trail_divisor; + + Ref<CurveTexture> trail_size_modifier; + Ref<GradientTexture> trail_color_modifier; + + Vector3 gravity; + + //do not save emission points here + +protected: + static void _bind_methods(); + virtual void _validate_property(PropertyInfo &property) const; + +public: + void set_spread(float p_spread); + float get_spread() const; + + void set_flatness(float p_flatness); + float get_flatness() const; + + void set_param(Parameter p_param, float p_value); + float get_param(Parameter p_param) const; + + void set_param_randomness(Parameter p_param, float p_value); + float get_param_randomness(Parameter p_param) const; + + void set_param_texture(Parameter p_param, const Ref<Texture> &p_texture); + Ref<Texture> get_param_texture(Parameter p_param) const; + + void set_color(const Color &p_color); + Color get_color() const; + + void set_color_ramp(const Ref<Texture> &p_texture); + Ref<Texture> get_color_ramp() const; + + void set_flag(Flags p_flag, bool p_enable); + bool get_flag(Flags p_flag) const; + + void set_emission_shape(EmissionShape p_shape); + void set_emission_sphere_radius(float p_radius); + void set_emission_box_extents(Vector3 p_extents); + void set_emission_point_texture(const Ref<Texture> &p_points); + void set_emission_normal_texture(const Ref<Texture> &p_normals); + void set_emission_color_texture(const Ref<Texture> &p_colors); + void set_emission_point_count(int p_count); + + EmissionShape get_emission_shape() const; + float get_emission_sphere_radius() const; + Vector3 get_emission_box_extents() const; + Ref<Texture> get_emission_point_texture() const; + Ref<Texture> get_emission_normal_texture() const; + Ref<Texture> get_emission_color_texture() const; + int get_emission_point_count() const; + + void set_trail_divisor(int p_divisor); + int get_trail_divisor() const; + + void set_trail_size_modifier(const Ref<CurveTexture> &p_trail_size_modifier); + Ref<CurveTexture> get_trail_size_modifier() const; + + void set_trail_color_modifier(const Ref<GradientTexture> &p_trail_color_modifier); + Ref<GradientTexture> get_trail_color_modifier() const; + + void set_gravity(const Vector3 &p_gravity); + Vector3 get_gravity() const; + + static void init_shaders(); + static void finish_shaders(); + static void flush_changes(); + + RID get_shader_rid() const; + + virtual Shader::Mode get_shader_mode() const; + + ParticlesMaterial(); + ~ParticlesMaterial(); +}; + +VARIANT_ENUM_CAST(ParticlesMaterial::Parameter) +VARIANT_ENUM_CAST(ParticlesMaterial::Flags) +VARIANT_ENUM_CAST(ParticlesMaterial::EmissionShape) + +#endif // PARTICLES_MATERIAL_H diff --git a/scene/resources/physics_material.cpp b/scene/resources/physics_material.cpp index dc5ca1aef6..03b3589727 100644 --- a/scene/resources/physics_material.cpp +++ b/scene/resources/physics_material.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "physics_material.h" void PhysicsMaterial::_bind_methods() { diff --git a/scene/resources/physics_material.h b/scene/resources/physics_material.h index c69e44a7da..bf11bf0ac1 100644 --- a/scene/resources/physics_material.h +++ b/scene/resources/physics_material.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,10 +27,11 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #ifndef physics_material_override_H #define physics_material_override_H -#include "resource.h" +#include "core/resource.h" #include "servers/physics_server.h" class PhysicsMaterial : public Resource { diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp index 44f9ebaf33..bd03930c9e 100644 --- a/scene/resources/polygon_path_finder.cpp +++ b/scene/resources/polygon_path_finder.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "polygon_path_finder.h" -#include "geometry.h" +#include "core/math/geometry.h" bool PolygonPathFinder::_is_point_inside(const Vector2 &p_point) const { diff --git a/scene/resources/polygon_path_finder.h b/scene/resources/polygon_path_finder.h index 19761c274c..66282458af 100644 --- a/scene/resources/polygon_path_finder.h +++ b/scene/resources/polygon_path_finder.h @@ -31,7 +31,7 @@ #ifndef POLYGON_PATH_FINDER_H #define POLYGON_PATH_FINDER_H -#include "resource.h" +#include "core/resource.h" class PolygonPathFinder : public Resource { diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp index 28aa6f1aa7..63aa44e1d8 100644 --- a/scene/resources/primitive_meshes.cpp +++ b/scene/resources/primitive_meshes.cpp @@ -89,7 +89,7 @@ void PrimitiveMesh::_update() const { pending_request = false; - _clear_triangle_mesh(); + clear_cache(); const_cast<PrimitiveMesh *>(this)->emit_changed(); } diff --git a/scene/resources/room.h b/scene/resources/room.h index 359d918665..d5ad847516 100644 --- a/scene/resources/room.h +++ b/scene/resources/room.h @@ -31,8 +31,8 @@ #ifndef ROOM_BOUNDS_H #define ROOM_BOUNDS_H -#include "bsp_tree.h" -#include "resource.h" +#include "core/math/bsp_tree.h" +#include "core/resource.h" /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/scene/resources/scene_format_text.cpp b/scene/resources/scene_format_text.cpp index fd9989fe72..597ffe49ae 100644 --- a/scene/resources/scene_format_text.cpp +++ b/scene/resources/scene_format_text.cpp @@ -30,15 +30,15 @@ #include "scene_format_text.h" #include "core/io/resource_format_binary.h" -#include "os/dir_access.h" -#include "project_settings.h" -#include "version.h" +#include "core/os/dir_access.h" +#include "core/project_settings.h" +#include "core/version.h" //version 2: changed names for basis, aabb, poolvectors, etc. #define FORMAT_VERSION 2 -#include "os/dir_access.h" -#include "version.h" +#include "core/os/dir_access.h" +#include "core/version.h" #define _printerr() ERR_PRINT(String(res_path + ":" + itos(lines) + " - Parse Error: " + error_text).utf8().get_data()); @@ -294,25 +294,25 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R if (!next_tag.fields.has("from")) { error = ERR_FILE_CORRUPT; - error_text = "missing 'from' field fron connection tag"; + error_text = "missing 'from' field from connection tag"; return Ref<PackedScene>(); } if (!next_tag.fields.has("to")) { error = ERR_FILE_CORRUPT; - error_text = "missing 'to' field fron connection tag"; + error_text = "missing 'to' field from connection tag"; return Ref<PackedScene>(); } if (!next_tag.fields.has("signal")) { error = ERR_FILE_CORRUPT; - error_text = "missing 'signal' field fron connection tag"; + error_text = "missing 'signal' field from connection tag"; return Ref<PackedScene>(); } if (!next_tag.fields.has("method")) { error = ERR_FILE_CORRUPT; - error_text = "missing 'method' field fron connection tag"; + error_text = "missing 'method' field from connection tag"; return Ref<PackedScene>(); } @@ -358,7 +358,7 @@ Ref<PackedScene> ResourceInteractiveLoaderText::_parse_node_tag(VariantParser::R if (!next_tag.fields.has("path")) { error = ERR_FILE_CORRUPT; - error_text = "missing 'path' field fron connection tag"; + error_text = "missing 'path' field from connection tag"; _printerr(); return Ref<PackedScene>(); } diff --git a/scene/resources/scene_format_text.h b/scene/resources/scene_format_text.h index c28ded3d77..8d1af2bbb2 100644 --- a/scene/resources/scene_format_text.h +++ b/scene/resources/scene_format_text.h @@ -31,11 +31,11 @@ #ifndef SCENE_FORMAT_TEXT_H #define SCENE_FORMAT_TEXT_H -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "os/file_access.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/os/file_access.h" +#include "core/variant_parser.h" #include "scene/resources/packed_scene.h" -#include "variant_parser.h" class ResourceInteractiveLoaderText : public ResourceInteractiveLoader { diff --git a/scene/resources/shader.cpp b/scene/resources/shader.cpp index f53f03c1c8..66bf3b4991 100644 --- a/scene/resources/shader.cpp +++ b/scene/resources/shader.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "shader.h" -#include "os/file_access.h" +#include "core/os/file_access.h" #include "scene/scene_string_names.h" #include "servers/visual/shader_language.h" #include "servers/visual_server.h" @@ -126,6 +126,11 @@ void Shader::get_default_texture_param_list(List<StringName> *r_textures) const r_textures->push_back(E->key()); } } + +bool Shader::is_text_shader() const { + return true; +} + bool Shader::has_param(const StringName &p_param) const { return params_cache.has(p_param); @@ -235,8 +240,10 @@ Error ResourceFormatSaverShader::save(const String &p_path, const RES &p_resourc void ResourceFormatSaverShader::get_recognized_extensions(const RES &p_resource, List<String> *p_extensions) const { - if (Object::cast_to<Shader>(*p_resource)) { - p_extensions->push_back("shader"); + if (const Shader *shader = Object::cast_to<Shader>(*p_resource)) { + if (shader->is_text_shader()) { + p_extensions->push_back("shader"); + } } } bool ResourceFormatSaverShader::recognize(const RES &p_resource) const { diff --git a/scene/resources/shader.h b/scene/resources/shader.h index efc5da7753..c2c205237f 100644 --- a/scene/resources/shader.h +++ b/scene/resources/shader.h @@ -31,9 +31,9 @@ #ifndef SHADER_H #define SHADER_H -#include "io/resource_loader.h" -#include "io/resource_saver.h" -#include "resource.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" +#include "core/resource.h" #include "scene/resources/texture.h" class Shader : public Resource { @@ -79,6 +79,8 @@ public: Ref<Texture> get_default_texture_param(const StringName &p_param) const; void get_default_texture_param_list(List<StringName> *r_textures) const; + virtual bool is_text_shader() const; + _FORCE_INLINE_ StringName remap_param(const StringName &p_param) const { if (params_cache_dirty) get_param_list(NULL); diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp index a48ce0564b..8ccca81acd 100644 --- a/scene/resources/shape.cpp +++ b/scene/resources/shape.cpp @@ -30,7 +30,7 @@ #include "shape.h" -#include "os/os.h" +#include "core/os/os.h" #include "scene/main/scene_tree.h" #include "scene/resources/mesh.h" #include "servers/physics_server.h" diff --git a/scene/resources/shape.h b/scene/resources/shape.h index 0c44b86e92..6643f4ee44 100644 --- a/scene/resources/shape.h +++ b/scene/resources/shape.h @@ -31,7 +31,7 @@ #ifndef SHAPE_H #define SHAPE_H -#include "resource.h" +#include "core/resource.h" class ArrayMesh; class Shape : public Resource { diff --git a/scene/resources/shape_2d.h b/scene/resources/shape_2d.h index 7eb0406bd8..fa39daa565 100644 --- a/scene/resources/shape_2d.h +++ b/scene/resources/shape_2d.h @@ -31,7 +31,7 @@ #ifndef SHAPE_2D_H #define SHAPE_2D_H -#include "resource.h" +#include "core/resource.h" class Shape2D : public Resource { GDCLASS(Shape2D, Resource); diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp index 4176aed4d8..a6a52c7bba 100644 --- a/scene/resources/sky_box.cpp +++ b/scene/resources/sky_box.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "sky_box.h" -#include "io/image_loader.h" +#include "core/io/image_loader.h" void Sky::set_radiance_size(RadianceSize p_size) { ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX); diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h index e561653a9e..bbb852822d 100644 --- a/scene/resources/sky_box.h +++ b/scene/resources/sky_box.h @@ -31,7 +31,7 @@ #ifndef SKY_BOX_H #define SKY_BOX_H -#include "os/thread.h" +#include "core/os/thread.h" #include "scene/resources/texture.h" class Sky : public Resource { GDCLASS(Sky, Resource); diff --git a/scene/resources/space_2d.h b/scene/resources/space_2d.h index 148285ac6d..1143ad2bd5 100644 --- a/scene/resources/space_2d.h +++ b/scene/resources/space_2d.h @@ -31,7 +31,7 @@ #ifndef SPACE_2D_H #define SPACE_2D_H -#include "resource.h" +#include "core/resource.h" #include "servers/physics_2d_server.h" class Space2D : public Resource { diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h index ed193a1ab4..df3ebe1c36 100644 --- a/scene/resources/style_box.h +++ b/scene/resources/style_box.h @@ -31,7 +31,7 @@ #ifndef STYLE_BOX_H #define STYLE_BOX_H -#include "resource.h" +#include "core/resource.h" #include "scene/resources/texture.h" #include "servers/visual_server.h" /** diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index 81fabf40fe..5d4c7861e3 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -29,7 +29,8 @@ /*************************************************************************/ #include "surface_tool.h" -#include "method_bind_ext.gen.inc" + +#include "core/method_bind_ext.gen.inc" #define _VERTEX_SNAP 0.0001 #define EQ_VERTEX_DIST 0.00001 diff --git a/scene/resources/text_file.cpp b/scene/resources/text_file.cpp index e2fe0adfc5..2af24ad2d5 100644 --- a/scene/resources/text_file.cpp +++ b/scene/resources/text_file.cpp @@ -30,7 +30,7 @@ #include "text_file.h" -#include "os/file_access.h" +#include "core/os/file_access.h" bool TextFile::has_text() const { return text != ""; diff --git a/scene/resources/text_file.h b/scene/resources/text_file.h index 40b648eebb..3abc769dc6 100644 --- a/scene/resources/text_file.h +++ b/scene/resources/text_file.h @@ -31,8 +31,8 @@ #ifndef TEXTFILE_H #define TEXTFILE_H -#include "io/resource_loader.h" -#include "io/resource_saver.h" +#include "core/io/resource_loader.h" +#include "core/io/resource_saver.h" class TextFile : public Resource { diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 811e5c3d2c..f0e3979f13 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -29,11 +29,12 @@ /*************************************************************************/ #include "texture.h" -#include "bit_mask.h" + +#include "core/core_string_names.h" +#include "core/io/image_loader.h" #include "core/method_bind_ext.gen.inc" #include "core/os/os.h" -#include "core_string_names.h" -#include "io/image_loader.h" +#include "scene/resources/bit_mask.h" Size2 Texture::get_size() const { @@ -206,6 +207,9 @@ void ImageTexture::set_flags(uint32_t p_flags) { flags=p_flags|cube; */ flags = p_flags; + if (w == 0 || h == 0) { + return; //uninitialized, do not set to texture + } VisualServer::get_singleton()->texture_set_flags(texture, p_flags); } @@ -1606,7 +1610,7 @@ void GradientTexture::_bind_methods() { ClassDB::bind_method(D_METHOD("_update"), &GradientTexture::_update); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "width"), "set_width", "get_width"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width"); } void GradientTexture::set_gradient(Ref<Gradient> p_gradient) { @@ -1632,16 +1636,17 @@ void GradientTexture::_queue_update() { if (update_pending) return; + update_pending = true; call_deferred("_update"); } void GradientTexture::_update() { + update_pending = false; + if (gradient.is_null()) return; - update_pending = false; - PoolVector<uint8_t> data; data.resize(width * 4); { @@ -1944,8 +1949,8 @@ void AnimatedTexture::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::REAL, "fps", PROPERTY_HINT_RANGE, "0,1024,0.1"), "set_fps", "get_fps"); for (int i = 0; i < MAX_FRAMES; i++) { - ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_frame_texture", "get_frame_texture", i); - ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01"), "set_frame_delay", "get_frame_delay", i); + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "frame_" + itos(i) + "/texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_frame_texture", "get_frame_texture", i); + ADD_PROPERTYI(PropertyInfo(Variant::REAL, "frame_" + itos(i) + "/delay_sec", PROPERTY_HINT_RANGE, "0.0,16.0,0.01", PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL), "set_frame_delay", "get_frame_delay", i); } } diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 79e6d2cdf9..cb759c63da 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -31,15 +31,16 @@ #ifndef TEXTURE_H #define TEXTURE_H -#include "curve.h" -#include "io/resource_loader.h" -#include "os/mutex.h" -#include "os/rw_lock.h" -#include "os/thread_safe.h" -#include "rect2.h" -#include "resource.h" +#include "core/io/resource_loader.h" +#include "core/math/rect2.h" +#include "core/os/mutex.h" +#include "core/os/rw_lock.h" +#include "core/os/thread_safe.h" +#include "core/resource.h" #include "scene/resources/color_ramp.h" +#include "scene/resources/curve.h" #include "servers/visual_server.h" + /** @author Juan Linietsky <reduzio@gmail.com> */ diff --git a/scene/resources/theme.cpp b/scene/resources/theme.cpp index f903669fc7..b102d477f2 100644 --- a/scene/resources/theme.cpp +++ b/scene/resources/theme.cpp @@ -29,8 +29,8 @@ /*************************************************************************/ #include "theme.h" -#include "os/file_access.h" -#include "print_string.h" +#include "core/os/file_access.h" +#include "core/print_string.h" Ref<Theme> Theme::default_theme; diff --git a/scene/resources/theme.h b/scene/resources/theme.h index e0d4038e7e..0b76e95f18 100644 --- a/scene/resources/theme.h +++ b/scene/resources/theme.h @@ -31,8 +31,8 @@ #ifndef THEME_H #define THEME_H -#include "io/resource_loader.h" -#include "resource.h" +#include "core/io/resource_loader.h" +#include "core/resource.h" #include "scene/resources/font.h" #include "scene/resources/shader.h" #include "scene/resources/style_box.h" diff --git a/scene/resources/tile_set.cpp b/scene/resources/tile_set.cpp index c85f672ebf..f852ecd7eb 100644 --- a/scene/resources/tile_set.cpp +++ b/scene/resources/tile_set.cpp @@ -29,7 +29,7 @@ /*************************************************************************/ #include "tile_set.h" -#include "array.h" +#include "core/array.h" bool TileSet::_set(const StringName &p_name, const Variant &p_value) { @@ -940,6 +940,8 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("create_tile", "id"), &TileSet::create_tile); ClassDB::bind_method(D_METHOD("autotile_set_bitmask_mode", "id", "mode"), &TileSet::autotile_set_bitmask_mode); ClassDB::bind_method(D_METHOD("autotile_get_bitmask_mode", "id"), &TileSet::autotile_get_bitmask_mode); + ClassDB::bind_method(D_METHOD("autotile_set_size", "id", "size"), &TileSet::autotile_set_size); + ClassDB::bind_method(D_METHOD("autotile_get_size", "id"), &TileSet::autotile_get_size); ClassDB::bind_method(D_METHOD("tile_set_name", "id", "name"), &TileSet::tile_set_name); ClassDB::bind_method(D_METHOD("tile_get_name", "id"), &TileSet::tile_get_name); ClassDB::bind_method(D_METHOD("tile_set_texture", "id", "texture"), &TileSet::tile_set_texture); @@ -956,6 +958,8 @@ void TileSet::_bind_methods() { ClassDB::bind_method(D_METHOD("tile_get_region", "id"), &TileSet::tile_get_region); ClassDB::bind_method(D_METHOD("tile_set_shape", "id", "shape_id", "shape"), &TileSet::tile_set_shape); ClassDB::bind_method(D_METHOD("tile_get_shape", "id", "shape_id"), &TileSet::tile_get_shape); + ClassDB::bind_method(D_METHOD("tile_set_shape_offset", "id", "shape_id", "shape_offset"), &TileSet::tile_set_shape_offset); + ClassDB::bind_method(D_METHOD("tile_get_shape_offset", "id", "shape_id"), &TileSet::tile_get_shape_offset); ClassDB::bind_method(D_METHOD("tile_set_shape_transform", "id", "shape_id", "shape_transform"), &TileSet::tile_set_shape_transform); ClassDB::bind_method(D_METHOD("tile_get_shape_transform", "id", "shape_id"), &TileSet::tile_get_shape_transform); ClassDB::bind_method(D_METHOD("tile_set_shape_one_way", "id", "shape_id", "one_way"), &TileSet::tile_set_shape_one_way); diff --git a/scene/resources/tile_set.h b/scene/resources/tile_set.h index 40eee2700d..1802bf12b6 100644 --- a/scene/resources/tile_set.h +++ b/scene/resources/tile_set.h @@ -32,7 +32,7 @@ #define TILE_SET_H #include "core/array.h" -#include "resource.h" +#include "core/resource.h" #include "scene/2d/light_occluder_2d.h" #include "scene/2d/navigation_polygon.h" #include "scene/resources/shape_2d.h" @@ -80,8 +80,8 @@ public: struct AutotileData { BitmaskMode bitmask_mode; - int spacing; Size2 size; + int spacing; Vector2 icon_coord; Map<Vector2, uint16_t> flags; Map<Vector2, Ref<OccluderPolygon2D> > occluder_map; @@ -90,11 +90,10 @@ public: // Default size to prevent invalid value explicit AutotileData() : + bitmask_mode(BITMASK_2X2), size(64, 64), spacing(0), - icon_coord(0, 0) { - bitmask_mode = BITMASK_2X2; - } + icon_coord(0, 0) {} }; private: @@ -111,8 +110,8 @@ private: Vector2 navigation_polygon_offset; Ref<NavigationPolygon> navigation_polygon; Ref<ShaderMaterial> material; - Color modulate; TileMode tile_mode; + Color modulate; AutotileData autotile_data; int z_index; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index dac12205b6..96b9cfa137 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -1,6 +1,36 @@ +/*************************************************************************/ +/* visual_shader.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "visual_shader.h" +#include "core/vmap.h" #include "servers/visual/shader_types.h" -#include "vmap.h" void VisualShaderNode::set_output_port_for_preview(int p_index) { @@ -384,6 +414,10 @@ Shader::Mode VisualShader::get_mode() const { return shader_mode; } +bool VisualShader::is_text_shader() const { + return false; +} + String VisualShader::generate_preview_shader(Type p_type, int p_node, int p_port, Vector<DefaultTextureParam> &default_tex_params) const { Ref<VisualShaderNode> node = get_node(p_type, p_node); @@ -762,10 +796,10 @@ Error VisualShader::_write_node(Type type, StringBuilder &global_code, StringBui val.basis.transpose(); inputs[i] = "n_in" + itos(node) + "p" + itos(i); Array values; - for (int i = 0; i < 3; i++) { - values.push_back(val.basis[i].x); - values.push_back(val.basis[i].y); - values.push_back(val.basis[i].z); + for (int j = 0; j < 3; j++) { + values.push_back(val.basis[j].x); + values.push_back(val.basis[j].y); + values.push_back(val.basis[j].z); } values.push_back(val.origin.x); values.push_back(val.origin.y); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 6ff1c9a9fe..2867daac3a 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -1,8 +1,38 @@ +/*************************************************************************/ +/* visual_shader.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef VISUAL_SHADER_H #define VISUAL_SHADER_H +#include "core/string_builder.h" #include "scene/resources/shader.h" -#include "string_builder.h" class VisualShaderNodeUniform; class VisualShaderNode; @@ -111,6 +141,8 @@ public: void set_mode(Mode p_mode); virtual Mode get_mode() const; + virtual bool is_text_shader() const; + void set_graph_offset(const Vector2 &p_offset); Vector2 get_graph_offset() const; diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp index 98ecdbdf30..d011b102a2 100644 --- a/scene/resources/visual_shader_nodes.cpp +++ b/scene/resources/visual_shader_nodes.cpp @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* visual_shader_nodes.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #include "visual_shader_nodes.h" ////////////// Scalar diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h index 2ede36fbc8..3057f7239a 100644 --- a/scene/resources/visual_shader_nodes.h +++ b/scene/resources/visual_shader_nodes.h @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* visual_shader_nodes.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2018 Godot Engine contributors (cf. AUTHORS.md) */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + #ifndef VISUAL_SHADER_NODES_H #define VISUAL_SHADER_NODES_H diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp index 82183d24e7..b4588cd87c 100644 --- a/scene/resources/world.cpp +++ b/scene/resources/world.cpp @@ -30,8 +30,8 @@ #include "world.h" -#include "camera_matrix.h" -#include "octree.h" +#include "core/math/camera_matrix.h" +#include "core/math/octree.h" #include "scene/3d/camera.h" #include "scene/3d/visibility_notifier.h" #include "scene/scene_string_names.h" diff --git a/scene/resources/world.h b/scene/resources/world.h index 54bdf25784..4ba6b13476 100644 --- a/scene/resources/world.h +++ b/scene/resources/world.h @@ -31,14 +31,14 @@ #ifndef WORLD_H #define WORLD_H -#include "resource.h" +#include "core/resource.h" #include "scene/resources/environment.h" #include "servers/physics_server.h" #include "servers/visual_server.h" -class SpatialIndexer; class Camera; class VisibilityNotifier; +struct SpatialIndexer; class World : public Resource { GDCLASS(World, Resource); diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp index bed6ffd1bd..dd78d04104 100644 --- a/scene/resources/world_2d.cpp +++ b/scene/resources/world_2d.cpp @@ -29,13 +29,13 @@ /*************************************************************************/ #include "world_2d.h" -#include "servers/physics_2d_server.h" -#include "servers/visual_server.h" -//#include "servers/spatial_sound_2d_server.h" -#include "project_settings.h" + +#include "core/project_settings.h" #include "scene/2d/camera_2d.h" #include "scene/2d/visibility_notifier_2d.h" #include "scene/main/viewport.h" +#include "servers/physics_2d_server.h" +#include "servers/visual_server.h" struct SpatialIndexer2D { diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h index 59f34e32f2..88ad392f85 100644 --- a/scene/resources/world_2d.h +++ b/scene/resources/world_2d.h @@ -31,13 +31,13 @@ #ifndef WORLD_2D_H #define WORLD_2D_H -#include "project_settings.h" -#include "resource.h" +#include "core/project_settings.h" +#include "core/resource.h" #include "servers/physics_2d_server.h" -class SpatialIndexer2D; class VisibilityNotifier2D; class Viewport; +struct SpatialIndexer2D; class World2D : public Resource { |