diff options
Diffstat (limited to 'modules')
-rw-r--r-- | modules/gdscript/doc_classes/@GDScript.xml | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 8 | ||||
-rw-r--r-- | modules/gdscript/gdscript_tokenizer.cpp | 2 | ||||
-rw-r--r-- | modules/navigation/nav_map.cpp | 19 | ||||
-rw-r--r-- | modules/navigation/nav_map.h | 7 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 137 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.h | 7 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 132 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.h | 6 | ||||
-rw-r--r-- | modules/visual_script/doc_classes/VisualScript.xml | 2 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_editor.cpp | 40 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_editor.h | 1 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_property_selector.cpp | 65 | ||||
-rw-r--r-- | modules/visual_script/editor/visual_script_property_selector.h | 10 | ||||
-rw-r--r-- | modules/visual_script/visual_script.cpp | 2 |
15 files changed, 375 insertions, 65 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index d9fab01dce..d0926d317b 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -186,7 +186,7 @@ <description> Returns an array with the given range. Range can be 1 argument [code]N[/code] (0 to [code]N[/code] - 1), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). Returns an empty array if the range isn't valid (e.g. [code]range(2, 5, -1)[/code] or [code]range(5, 5, 1)[/code]). Returns an array with the given range. [code]range()[/code] can have 1 argument N ([code]0[/code] to [code]N - 1[/code]), two arguments ([code]initial[/code], [code]final - 1[/code]) or three arguments ([code]initial[/code], [code]final - 1[/code], [code]increment[/code]). [code]increment[/code] can be negative. If [code]increment[/code] is negative, [code]final - 1[/code] will become [code]final + 1[/code]. Also, the initial value must be greater than the final value for the loop to run. - [code]range()(/code] converts all arguments to [int] before processing. + [code]range()[/code] converts all arguments to [int] before processing. [codeblock] print(range(4)) print(range(2, 5)) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 59254fc3ad..55c7ace938 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -1032,7 +1032,13 @@ Error GDScript::load_source_code(const String &p_path) { Error err; Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err); if (err) { - ERR_FAIL_COND_V(err, err); + const char *err_name; + if (err < 0 || err >= ERR_MAX) { + err_name = "(invalid error code)"; + } else { + err_name = error_names[err]; + } + ERR_FAIL_COND_V_MSG(err, err, "Attempt to open script '" + p_path + "' resulted in error '" + err_name + "'."); } uint64_t len = f->get_length(); diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index d3287ab345..63fad0d9bb 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -1493,7 +1493,7 @@ GDScriptTokenizer::Token GDScriptTokenizer::scan() { } default: - return make_error(vformat(R"(Unknown character "%s".")", String(&c, 1))); + return make_error(vformat(R"(Unknown character "%s".)", String(&c, 1))); } } diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index 217e503d82..cbc0adc574 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -30,7 +30,6 @@ #include "nav_map.h" -#include "core/os/threaded_array_processor.h" #include "nav_region.h" #include "rvo_agent.h" @@ -142,10 +141,10 @@ Vector<Vector3> NavMap::get_path(Vector3 p_origin, Vector3 p_destination, bool p bool is_reachable = true; while (true) { - gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id]; - // Takes the current least_cost_poly neighbors (iterating over its edges) and compute the traveled_distance. - for (size_t i = 0; i < least_cost_poly->poly->edges.size(); i++) { + for (size_t i = 0; i < navigation_polys[least_cost_id].poly->edges.size(); i++) { + gd::NavigationPoly *least_cost_poly = &navigation_polys[least_cost_id]; + const gd::Edge &edge = least_cost_poly->poly->edges[i]; // Iterate over connections in this edge, then compute the new optimized travel distance assigned to this polygon. @@ -674,7 +673,10 @@ void NavMap::compute_single_step(uint32_t index, RvoAgent **agent) { void NavMap::step(real_t p_deltatime) { deltatime = p_deltatime; if (controlled_agents.size() > 0) { - thread_process_array( + if (step_work_pool.get_thread_count() == 0) { + step_work_pool.init(); + } + step_work_pool.do_work( controlled_agents.size(), this, &NavMap::compute_single_step, @@ -719,3 +721,10 @@ void NavMap::clip_path(const std::vector<gd::NavigationPoly> &p_navigation_polys } } } + +NavMap::NavMap() { +} + +NavMap::~NavMap() { + step_work_pool.finish(); +} diff --git a/modules/navigation/nav_map.h b/modules/navigation/nav_map.h index f46297a7ce..5232e42bed 100644 --- a/modules/navigation/nav_map.h +++ b/modules/navigation/nav_map.h @@ -35,6 +35,7 @@ #include "core/math/math_defs.h" #include "core/templates/map.h" +#include "core/templates/thread_work_pool.h" #include "nav_utils.h" #include <KdTree.h> @@ -80,8 +81,12 @@ class NavMap : public NavRid { /// Change the id each time the map is updated. uint32_t map_update_id = 0; + /// Pooled threads for computing steps + ThreadWorkPool step_work_pool; + public: - NavMap() {} + NavMap(); + ~NavMap(); void set_up(Vector3 p_up); Vector3 get_up() const { diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 4cd5dada4d..0ae8219e23 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -994,8 +994,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( int w = (bounds.r - bounds.l); int h = (bounds.t - bounds.b); - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -1029,7 +1029,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * 4; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * 4; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); wr[ofs + 0] = (uint8_t)(CLAMP(image(j, i)[0] * 256.f, 0.f, 255.f)); wr[ofs + 1] = (uint8_t)(CLAMP(image(j, i)[1] * 256.f, 0.f, 255.f)); @@ -1049,8 +1049,9 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_msdf( chr.texture_idx = tex_pos.index; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(bounds.l, -bounds.t); + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(bounds.l - p_rect_margin, -bounds.t - p_rect_margin); + chr.rect.size = chr.uv_rect.size; } return chr; @@ -1062,8 +1063,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma int w = bitmap.width; int h = bitmap.rows; - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -1083,7 +1084,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * color_size; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * color_size; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); switch (bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { @@ -1124,8 +1125,8 @@ _FORCE_INLINE_ TextServerAdvanced::FontGlyph TextServerAdvanced::rasterize_bitma chr.texture_idx = tex_pos.index; chr.found = true; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling; + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(xofs - p_rect_margin, -yofs - p_rect_margin) * p_data->scale / p_data->oversampling; chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling; return chr; } @@ -1796,6 +1797,29 @@ bool TextServerAdvanced::font_is_antialiased(const RID &p_font_rid) const { return fd->antialiased; } +void TextServerAdvanced::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->mipmaps != p_generate_mipmaps) { + for (KeyValue<Vector2i, FontDataForSizeAdvanced *> &E : fd->cache) { + for (int i = 0; i < E.value->textures.size(); i++) { + E.value->textures.write[i].dirty = true; + } + } + fd->mipmaps = p_generate_mipmaps; + } +} + +bool TextServerAdvanced::font_get_generate_mipmaps(const RID &p_font_rid) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, false); + + MutexLock lock(fd->mutex); + return fd->mipmaps; +} + void TextServerAdvanced::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -2276,6 +2300,9 @@ void TextServerAdvanced::font_set_texture_image(const RID &p_font_rid, const Vec Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } tex.texture = Ref<ImageTexture>(); tex.texture.instantiate(); @@ -2559,6 +2586,86 @@ void TextServerAdvanced::font_set_glyph_texture_idx(const RID &p_font_rid, const gl[p_glyph].found = true; } +RID TextServerAdvanced::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, RID()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), RID()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return RID(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), RID()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_rid(); + } + } + + return RID(); +} + +Size2 TextServerAdvanced::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Size2()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Size2()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return Size2(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), Size2()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_size(); + } + } + + return Size2(); +} + Dictionary TextServerAdvanced::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const { FontDataAdvanced *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); @@ -2865,6 +2972,9 @@ void TextServerAdvanced::font_draw_glyph(const RID &p_font_rid, const RID &p_can Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); @@ -2941,6 +3051,9 @@ void TextServerAdvanced::font_draw_glyph_outline(const RID &p_font_rid, const RI Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); @@ -3304,7 +3417,9 @@ void TextServerAdvanced::shaped_text_set_bidi_override(const RID &p_shaped, cons } sd->bidi_override.clear(); for (int i = 0; i < p_override.size(); i++) { - sd->bidi_override.push_back(p_override[i]); + if (p_override[i].get_type() == Variant::VECTOR2I) { + sd->bidi_override.push_back(p_override[i]); + } } invalidate(sd, false); } diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 8afba6adca..fa59566a94 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -216,6 +216,7 @@ class TextServerAdvanced : public TextServerExtension { Mutex mutex; bool antialiased = true; + bool mipmaps = false; bool msdf = false; int msdf_range = 14; int msdf_source_size = 48; @@ -483,6 +484,9 @@ public: virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override; virtual bool font_is_antialiased(const RID &p_font_rid) const override; + virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override; + virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override; + virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override; virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override; @@ -567,6 +571,9 @@ public: virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override; + virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; virtual Array font_get_kerning_list(const RID &p_font_rid, int64_t p_size) const override; diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 47c6a73b24..1251aaf2b9 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -438,8 +438,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( int w = (bounds.r - bounds.l); int h = (bounds.t - bounds.b); - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -473,7 +473,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * 4; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * 4; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); wr[ofs + 0] = (uint8_t)(CLAMP(image(j, i)[0] * 256.f, 0.f, 255.f)); wr[ofs + 1] = (uint8_t)(CLAMP(image(j, i)[1] * 256.f, 0.f, 255.f)); @@ -493,8 +493,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_msdf( chr.texture_idx = tex_pos.index; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(bounds.l, -bounds.t); + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(bounds.l - p_rect_margin, -bounds.t - p_rect_margin); chr.rect.size = chr.uv_rect.size; } return chr; @@ -506,8 +506,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma int w = bitmap.width; int h = bitmap.rows; - int mw = w + p_rect_margin * 2; - int mh = h + p_rect_margin * 2; + int mw = w + p_rect_margin * 4; + int mh = h + p_rect_margin * 4; ERR_FAIL_COND_V(mw > 4096, FontGlyph()); ERR_FAIL_COND_V(mh > 4096, FontGlyph()); @@ -527,7 +527,7 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { - int ofs = ((i + tex_pos.y + p_rect_margin) * tex.texture_w + j + tex_pos.x + p_rect_margin) * color_size; + int ofs = ((i + tex_pos.y + p_rect_margin * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * color_size; ERR_FAIL_COND_V(ofs >= tex.imgdata.size(), FontGlyph()); switch (bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { @@ -568,8 +568,8 @@ _FORCE_INLINE_ TextServerFallback::FontGlyph TextServerFallback::rasterize_bitma chr.texture_idx = tex_pos.index; chr.found = true; - chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w, h); - chr.rect.position = Vector2(xofs, -yofs) * p_data->scale / p_data->oversampling; + chr.uv_rect = Rect2(tex_pos.x + p_rect_margin, tex_pos.y + p_rect_margin, w + p_rect_margin * 2, h + p_rect_margin * 2); + chr.rect.position = Vector2(xofs - p_rect_margin, -yofs - p_rect_margin) * p_data->scale / p_data->oversampling; chr.rect.size = chr.uv_rect.size * p_data->scale / p_data->oversampling; return chr; } @@ -959,6 +959,29 @@ bool TextServerFallback::font_is_antialiased(const RID &p_font_rid) const { return fd->antialiased; } +void TextServerFallback::font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND(!fd); + + MutexLock lock(fd->mutex); + if (fd->mipmaps != p_generate_mipmaps) { + for (KeyValue<Vector2i, FontDataForSizeFallback *> &E : fd->cache) { + for (int i = 0; i < E.value->textures.size(); i++) { + E.value->textures.write[i].dirty = true; + } + } + fd->mipmaps = p_generate_mipmaps; + } +} + +bool TextServerFallback::font_get_generate_mipmaps(const RID &p_font_rid) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, false); + + MutexLock lock(fd->mutex); + return fd->mipmaps; +} + void TextServerFallback::font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND(!fd); @@ -1439,6 +1462,9 @@ void TextServerFallback::font_set_texture_image(const RID &p_font_rid, const Vec Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } tex.texture = Ref<ImageTexture>(); tex.texture.instantiate(); @@ -1708,6 +1734,86 @@ void TextServerFallback::font_set_glyph_texture_idx(const RID &p_font_rid, const gl[p_glyph].found = true; } +RID TextServerFallback::font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, RID()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), RID()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return RID(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), RID()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_rid(); + } + } + + return RID(); +} + +Size2 TextServerFallback::font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const { + FontDataFallback *fd = font_owner.get_or_null(p_font_rid); + ERR_FAIL_COND_V(!fd, Size2()); + + MutexLock lock(fd->mutex); + Vector2i size = _get_size_outline(fd, p_size); + + ERR_FAIL_COND_V(!_ensure_cache_for_size(fd, size), Size2()); + if (!_ensure_glyph(fd, size, p_glyph)) { + return Size2(); // Invalid or non graphicl glyph, do not display errors. + } + + const HashMap<int32_t, FontGlyph> &gl = fd->cache[size]->glyph_map; + ERR_FAIL_COND_V(gl[p_glyph].texture_idx < -1 || gl[p_glyph].texture_idx >= fd->cache[size]->textures.size(), Size2()); + + if (RenderingServer::get_singleton() != nullptr) { + if (gl[p_glyph].texture_idx != -1) { + if (fd->cache[size]->textures[gl[p_glyph].texture_idx].dirty) { + FontTexture &tex = fd->cache[size]->textures.write[gl[p_glyph].texture_idx]; + Ref<Image> img; + img.instantiate(); + img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } + if (tex.texture.is_null()) { + tex.texture.instantiate(); + tex.texture->create_from_image(img); + } else { + tex.texture->update(img); + } + tex.dirty = false; + } + return fd->cache[size]->textures[gl[p_glyph].texture_idx].texture->get_size(); + } + } + + return Size2(); +} + Dictionary TextServerFallback::font_get_glyph_contours(const RID &p_font_rid, int64_t p_size, int64_t p_index) const { FontDataFallback *fd = font_owner.get_or_null(p_font_rid); ERR_FAIL_COND_V(!fd, Dictionary()); @@ -1996,6 +2102,9 @@ void TextServerFallback::font_draw_glyph(const RID &p_font_rid, const RID &p_can Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); @@ -2072,6 +2181,9 @@ void TextServerFallback::font_draw_glyph_outline(const RID &p_font_rid, const RI Ref<Image> img; img.instantiate(); img->create_from_data(tex.texture_w, tex.texture_h, false, tex.format, tex.imgdata); + if (fd->mipmaps) { + img->generate_mipmaps(); + } if (tex.texture.is_null()) { tex.texture.instantiate(); tex.texture->create_from_image(img); diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index ea77659b5d..d6f61e02f8 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -179,6 +179,7 @@ class TextServerFallback : public TextServerExtension { Mutex mutex; bool antialiased = true; + bool mipmaps = false; bool msdf = false; int msdf_range = 14; int msdf_source_size = 48; @@ -375,6 +376,9 @@ public: virtual void font_set_antialiased(const RID &p_font_rid, bool p_antialiased) override; virtual bool font_is_antialiased(const RID &p_font_rid) const override; + virtual void font_set_generate_mipmaps(const RID &p_font_rid, bool p_generate_mipmaps) override; + virtual bool font_get_generate_mipmaps(const RID &p_font_rid) const override; + virtual void font_set_multichannel_signed_distance_field(const RID &p_font_rid, bool p_msdf) override; virtual bool font_is_multichannel_signed_distance_field(const RID &p_font_rid) const override; @@ -458,6 +462,8 @@ public: virtual int64_t font_get_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual void font_set_glyph_texture_idx(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph, int64_t p_texture_idx) override; + virtual RID font_get_glyph_texture_rid(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; + virtual Size2 font_get_glyph_texture_size(const RID &p_font_rid, const Vector2i &p_size, int64_t p_glyph) const override; virtual Dictionary font_get_glyph_contours(const RID &p_font, int64_t p_size, int64_t p_index) const override; diff --git a/modules/visual_script/doc_classes/VisualScript.xml b/modules/visual_script/doc_classes/VisualScript.xml index 96310538bf..5807c98d32 100644 --- a/modules/visual_script/doc_classes/VisualScript.xml +++ b/modules/visual_script/doc_classes/VisualScript.xml @@ -316,7 +316,7 @@ </method> <method name="set_scroll"> <return type="void" /> - <argument index="0" name="ofs" type="Vector2" /> + <argument index="0" name="offset" type="Vector2" /> <description> Set the screen center to the given position. </description> diff --git a/modules/visual_script/editor/visual_script_editor.cpp b/modules/visual_script/editor/visual_script_editor.cpp index 495303d6c4..06fa90eb29 100644 --- a/modules/visual_script/editor/visual_script_editor.cpp +++ b/modules/visual_script/editor/visual_script_editor.cpp @@ -3390,6 +3390,8 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_NODE_PATH); n->set_base_path(drop_path); } + } else { + n->set_call_mode(VisualScriptFunctionCall::CALL_MODE_INSTANCE); } if (drop_node) { n->set_base_type(drop_node->get_class()); @@ -3702,8 +3704,13 @@ void VisualScriptEditor::_selected_connect_node(const String &p_text, const Stri Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_type(base_type); Object::cast_to<VisualScriptTypeCast>(vnode.ptr())->set_base_script(base_script); } else if (Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())) { - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_type(base_type); - Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_script(base_script); + if (base_type_map.has(base_type)) { + Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_basic_type(base_type_map[base_type]); + Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_call_mode(VisualScriptFunctionCall::CALL_MODE_BASIC_TYPE); + } else { + Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_type(base_type); + Object::cast_to<VisualScriptFunctionCall>(vnode.ptr())->set_base_script(base_script); + } } else if (Object::cast_to<VisualScriptPropertySet>(vnode.ptr())) { Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_type(base_type); Object::cast_to<VisualScriptPropertySet>(vnode.ptr())->set_base_script(base_script); @@ -4751,6 +4758,35 @@ VisualScriptEditor::VisualScriptEditor() { popup_menu->add_item(TTR("Duplicate"), EDIT_DUPLICATE_NODES); popup_menu->add_item(TTR("Clear Copy Buffer"), EDIT_CLEAR_COPY_BUFFER); popup_menu->connect("id_pressed", callable_mp(this, &VisualScriptEditor::_menu_option)); + + base_type_map.insert("String", Variant::STRING); + base_type_map.insert("Vector2", Variant::VECTOR2); + base_type_map.insert("Vector2i", Variant::VECTOR2I); + base_type_map.insert("Rect2", Variant::RECT2); + base_type_map.insert("Rect2i", Variant::RECT2I); + base_type_map.insert("Vector3", Variant::VECTOR3); + base_type_map.insert("Vector3i", Variant::VECTOR3I); + base_type_map.insert("Transform2D", Variant::TRANSFORM2D); + base_type_map.insert("Plane", Variant::PLANE); + base_type_map.insert("Quaternion", Variant::QUATERNION); + base_type_map.insert("AABB", Variant::AABB); + base_type_map.insert("Basis", Variant::BASIS); + base_type_map.insert("Transform3D", Variant::TRANSFORM3D); + base_type_map.insert("Color", Variant::COLOR); + base_type_map.insert("NodePath", Variant::NODE_PATH); + base_type_map.insert("RID", Variant::RID); + base_type_map.insert("Callable", Variant::CALLABLE); + base_type_map.insert("Dictionary", Variant::DICTIONARY); + base_type_map.insert("Array", Variant::ARRAY); + base_type_map.insert("PackedByteArray", Variant::PACKED_BYTE_ARRAY); + base_type_map.insert("PackedInt32Array", Variant::PACKED_INT32_ARRAY); + base_type_map.insert("PackedFloat32Array", Variant::PACKED_FLOAT32_ARRAY); + base_type_map.insert("PackedInt64Array", Variant::PACKED_INT64_ARRAY); + base_type_map.insert("PackedFloat64Array", Variant::PACKED_FLOAT64_ARRAY); + base_type_map.insert("PackedStringArray", Variant::PACKED_STRING_ARRAY); + base_type_map.insert("PackedVector2Array", Variant::PACKED_VECTOR2_ARRAY); + base_type_map.insert("PackedVector3Array", Variant::PACKED_VECTOR3_ARRAY); + base_type_map.insert("PackedColorArray", Variant::PACKED_COLOR_ARRAY); } VisualScriptEditor::~VisualScriptEditor() { diff --git a/modules/visual_script/editor/visual_script_editor.h b/modules/visual_script/editor/visual_script_editor.h index 5b355a71df..fcfd44cecd 100644 --- a/modules/visual_script/editor/visual_script_editor.h +++ b/modules/visual_script/editor/visual_script_editor.h @@ -144,6 +144,7 @@ class VisualScriptEditor : public ScriptEditorBase { Map<StringName, Color> node_colors; HashMap<StringName, Ref<StyleBox>> node_styles; + Map<StringName, Variant::Type> base_type_map; void _update_graph_connections(); void _update_graph(int p_only_id = -1); diff --git a/modules/visual_script/editor/visual_script_property_selector.cpp b/modules/visual_script/editor/visual_script_property_selector.cpp index 31406a2a6f..07929e5c0e 100644 --- a/modules/visual_script/editor/visual_script_property_selector.cpp +++ b/modules/visual_script/editor/visual_script_property_selector.cpp @@ -86,6 +86,13 @@ void VisualScriptPropertySelector::_update_results_s(String p_string) { _update_results(); } +void VisualScriptPropertySelector::_update_results_search_all() { + if (search_classes->is_pressed()) { + scope_combo->select(COMBO_ALL); + } + _update_results(); +} + void VisualScriptPropertySelector::_update_results() { _update_icons(); search_runner = Ref<SearchRunner>(memnew(SearchRunner(this, results_tree))); @@ -167,7 +174,7 @@ void VisualScriptPropertySelector::select_method_from_base_type(const String &p_ search_properties->set_pressed(false); search_theme_items->set_pressed(false); - scope_combo->select(2); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" + scope_combo->select(COMBO_BASE); results_tree->clear(); show_window(.5f); @@ -201,8 +208,7 @@ void VisualScriptPropertySelector::select_from_base_type(const String &p_base, c search_properties->set_pressed(true); search_theme_items->set_pressed(false); - // When class is Input only show inheritors - scope_combo->select(0); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" + scope_combo->select(COMBO_RELATED); results_tree->clear(); show_window(.5f); @@ -234,7 +240,7 @@ void VisualScriptPropertySelector::select_from_script(const Ref<Script> &p_scrip search_properties->set_pressed(true); search_theme_items->set_pressed(false); - scope_combo->select(2); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" + scope_combo->select(COMBO_BASE); results_tree->clear(); show_window(.5f); @@ -264,7 +270,7 @@ void VisualScriptPropertySelector::select_from_basic_type(Variant::Type p_type, search_properties->set_pressed(true); search_theme_items->set_pressed(false); - scope_combo->select(2); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" //id5 "Search All" + scope_combo->select(COMBO_BASE); results_tree->clear(); show_window(.5f); @@ -294,7 +300,7 @@ void VisualScriptPropertySelector::select_from_action(const String &p_type, cons search_properties->set_pressed(false); search_theme_items->set_pressed(false); - scope_combo->select(0); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" //id5 "Search All" + scope_combo->select(COMBO_RELATED); results_tree->clear(); show_window(.5f); @@ -330,7 +336,7 @@ void VisualScriptPropertySelector::select_from_instance(Object *p_instance, cons search_properties->set_pressed(true); search_theme_items->set_pressed(false); - scope_combo->select(2); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" //id5 "Search All" + scope_combo->select(COMBO_BASE); results_tree->clear(); show_window(.5f); @@ -363,7 +369,7 @@ void VisualScriptPropertySelector::select_from_visual_script(const Ref<Script> & search_properties->set_pressed(true); search_theme_items->set_pressed(false); - scope_combo->select(2); //id0 = "Search Related" //id2 = "Search Base" //id3 = "Search Inheriters" //id4 = "Search Unrelated" //id5 "Search All" + scope_combo->select(COMBO_BASE); results_tree->clear(); show_window(.5f); @@ -418,7 +424,7 @@ VisualScriptPropertySelector::VisualScriptPropertySelector() { search_classes = memnew(Button); search_classes->set_flat(true); search_classes->set_tooltip(TTR("Search Classes")); - search_classes->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results)); + search_classes->connect("pressed", callable_mp(this, &VisualScriptPropertySelector::_update_results_search_all)); search_classes->set_toggle_mode(true); search_classes->set_pressed(true); search_classes->set_focus_mode(Control::FOCUS_NONE); @@ -739,49 +745,46 @@ bool VisualScriptPropertySelector::SearchRunner::_phase_node_classes_build() { if (vs_nodes.is_empty()) { return true; } - String registerd_node_name = vs_nodes[0]; + String registered_node_name = vs_nodes[0]; vs_nodes.pop_front(); - Vector<String> path = registerd_node_name.split("/"); + Vector<String> path = registered_node_name.split("/"); if (path[0] == "constants") { - _add_class_doc(registerd_node_name, "", "constants"); + _add_class_doc(registered_node_name, "", "constants"); } else if (path[0] == "custom") { - _add_class_doc(registerd_node_name, "", "custom"); + _add_class_doc(registered_node_name, "", "custom"); } else if (path[0] == "data") { - _add_class_doc(registerd_node_name, "", "data"); + _add_class_doc(registered_node_name, "", "data"); } else if (path[0] == "flow_control") { - _add_class_doc(registerd_node_name, "", "flow_control"); + _add_class_doc(registered_node_name, "", "flow_control"); } else if (path[0] == "functions") { if (path[1] == "built_in") { - _add_class_doc(registerd_node_name, "functions", "built_in"); + _add_class_doc(registered_node_name, "functions", "built_in"); } else if (path[1] == "by_type") { - if (search_flags & SEARCH_CLASSES) { - _add_class_doc(registerd_node_name, path[2], "by_type_class"); - } + // No action is required. + // Using function references from ClassDB to remove confusion for users. } else if (path[1] == "constructors") { - if (search_flags & SEARCH_CLASSES) { - _add_class_doc(registerd_node_name, path[2].substr(0, path[2].find_char('(')), "constructors_class"); - } + _add_class_doc(registered_node_name, "", "constructors"); } else if (path[1] == "deconstruct") { - _add_class_doc(registerd_node_name, "", "deconstruct"); + _add_class_doc(registered_node_name, "", "deconstruct"); } else if (path[1] == "wait") { - _add_class_doc(registerd_node_name, "functions", "yield"); + _add_class_doc(registered_node_name, "functions", "yield"); } else { - _add_class_doc(registerd_node_name, "functions", ""); + _add_class_doc(registered_node_name, "functions", ""); } } else if (path[0] == "index") { - _add_class_doc(registerd_node_name, "", "index"); + _add_class_doc(registered_node_name, "", "index"); } else if (path[0] == "operators") { if (path[1] == "bitwise") { - _add_class_doc(registerd_node_name, "operators", "bitwise"); + _add_class_doc(registered_node_name, "operators", "bitwise"); } else if (path[1] == "compare") { - _add_class_doc(registerd_node_name, "operators", "compare"); + _add_class_doc(registered_node_name, "operators", "compare"); } else if (path[1] == "logic") { - _add_class_doc(registerd_node_name, "operators", "logic"); + _add_class_doc(registered_node_name, "operators", "logic"); } else if (path[1] == "math") { - _add_class_doc(registerd_node_name, "operators", "math"); + _add_class_doc(registered_node_name, "operators", "math"); } else { - _add_class_doc(registerd_node_name, "operators", ""); + _add_class_doc(registered_node_name, "operators", ""); } } return false; diff --git a/modules/visual_script/editor/visual_script_property_selector.h b/modules/visual_script/editor/visual_script_property_selector.h index faf39a14e4..1b32ee2967 100644 --- a/modules/visual_script/editor/visual_script_property_selector.h +++ b/modules/visual_script/editor/visual_script_property_selector.h @@ -62,6 +62,15 @@ class VisualScriptPropertySelector : public ConfirmationDialog { SCOPE_ALL = SCOPE_BASE | SCOPE_INHERITERS | SCOPE_UNRELATED }; + enum ScopeCombo { + COMBO_RELATED, + COMBO_SEPARATOR, + COMBO_BASE, + COMBO_INHERITERS, + COMBO_UNRELATED, + COMBO_ALL, + }; + LineEdit *search_box = nullptr; Button *case_sensitive_button = nullptr; @@ -88,6 +97,7 @@ class VisualScriptPropertySelector : public ConfirmationDialog { void _sbox_input(const Ref<InputEvent> &p_ie); void _update_results_i(int p_int); void _update_results_s(String p_string); + void _update_results_search_all(); void _update_results(); void _confirmed(); diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp index e8c44e2556..e31550b203 100644 --- a/modules/visual_script/visual_script.cpp +++ b/modules/visual_script/visual_script.cpp @@ -1118,7 +1118,7 @@ void VisualScript::_bind_methods() { ClassDB::bind_method(D_METHOD("has_function", "name"), &VisualScript::has_function); ClassDB::bind_method(D_METHOD("remove_function", "name"), &VisualScript::remove_function); ClassDB::bind_method(D_METHOD("rename_function", "name", "new_name"), &VisualScript::rename_function); - ClassDB::bind_method(D_METHOD("set_scroll", "ofs"), &VisualScript::set_scroll); + ClassDB::bind_method(D_METHOD("set_scroll", "offset"), &VisualScript::set_scroll); ClassDB::bind_method(D_METHOD("get_scroll"), &VisualScript::get_scroll); ClassDB::bind_method(D_METHOD("add_node", "id", "node", "position"), &VisualScript::add_node, DEFVAL(Point2())); |