diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/gltf/gltf_document.cpp | 46 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.h | 3 | ||||
| -rw-r--r-- | modules/gltf/gltf_state.cpp | 11 | ||||
| -rw-r--r-- | modules/gltf/gltf_state.h | 4 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs | 21 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs | 20 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj | 2 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.cpp | 13 | ||||
| -rw-r--r-- | modules/mono/mono_gd/gd_mono_internals.h | 3 | ||||
| -rw-r--r-- | modules/text_server_adv/bitmap_font_adv.cpp | 31 | ||||
| -rw-r--r-- | modules/text_server_adv/bitmap_font_adv.h | 5 | ||||
| -rw-r--r-- | modules/text_server_fb/bitmap_font_fb.cpp | 7 |
12 files changed, 134 insertions, 32 deletions
diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 4868347a74..0a4d4055b4 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -72,6 +72,7 @@ #include "scene/3d/node_3d.h" #include "scene/3d/skeleton_3d.h" #include "scene/animation/animation_player.h" +#include "scene/main/node.h" #include "scene/resources/surface_tool.h" #include <limits> @@ -449,14 +450,8 @@ Error GLTFDocument::_serialize_nodes(Ref<GLTFState> state) { return OK; } -String GLTFDocument::_sanitize_scene_name(const String &name) { - RegEx regex("([^a-zA-Z0-9_ -]+)"); - String p_name = regex.sub(name, "", true); - return p_name; -} - String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name) { - const String s_name = _sanitize_scene_name(p_name); + const String s_name = p_name.validate_node_name(); String name; int index = 1; @@ -464,7 +459,7 @@ String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name name = s_name; if (index > 1) { - name += " " + itos(index); + name += itos(index); } if (!state->unique_names.has(name)) { break; @@ -477,6 +472,39 @@ String GLTFDocument::_gen_unique_name(Ref<GLTFState> state, const String &p_name return name; } +String GLTFDocument::_sanitize_animation_name(const String &p_name) { + // Animations disallow the normal node invalid characters as well as "," and "[" + // (See animation/animation_player.cpp::add_animation) + + // TODO: Consider adding invalid_characters or a validate_animation_name to animation_player to mirror Node. + String name = p_name.validate_node_name(); + name = name.replace(",", ""); + name = name.replace("[", ""); + return name; +} + +String GLTFDocument::_gen_unique_animation_name(Ref<GLTFState> state, const String &p_name) { + const String s_name = _sanitize_animation_name(p_name); + + String name; + int index = 1; + while (true) { + name = s_name; + + if (index > 1) { + name += itos(index); + } + if (!state->unique_animation_names.has(name)) { + break; + } + index++; + } + + state->unique_animation_names.insert(name); + + return name; +} + String GLTFDocument::_sanitize_bone_name(const String &name) { String p_name = name.camelcase_to_underscore(true); @@ -4729,7 +4757,7 @@ Error GLTFDocument::_parse_animations(Ref<GLTFState> state) { if (name.begins_with("loop") || name.ends_with("loop") || name.begins_with("cycle") || name.ends_with("cycle")) { animation->set_loop(true); } - animation->set_name(_sanitize_scene_name(name)); + animation->set_name(_gen_unique_animation_name(state, name)); } for (int j = 0; j < channels.size(); j++) { diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index ddf307e6a7..bda1ce87d6 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -162,8 +162,9 @@ private: Error _parse_nodes(Ref<GLTFState> state); String _get_type_name(const GLTFType p_component); String _get_accessor_type_name(const GLTFDocument::GLTFType p_type); - String _sanitize_scene_name(const String &name); String _gen_unique_name(Ref<GLTFState> state, const String &p_name); + String _sanitize_animation_name(const String &name); + String _gen_unique_animation_name(Ref<GLTFState> state, const String &p_name); String _sanitize_bone_name(const String &name); String _gen_unique_bone_name(Ref<GLTFState> state, const GLTFSkeletonIndex skel_i, diff --git a/modules/gltf/gltf_state.cpp b/modules/gltf/gltf_state.cpp index 86f8f44612..ff9778e7d8 100644 --- a/modules/gltf/gltf_state.cpp +++ b/modules/gltf/gltf_state.cpp @@ -71,6 +71,8 @@ void GLTFState::_bind_methods() { ClassDB::bind_method(D_METHOD("set_lights", "lights"), &GLTFState::set_lights); ClassDB::bind_method(D_METHOD("get_unique_names"), &GLTFState::get_unique_names); ClassDB::bind_method(D_METHOD("set_unique_names", "unique_names"), &GLTFState::set_unique_names); + ClassDB::bind_method(D_METHOD("get_unique_animation_names"), &GLTFState::get_unique_animation_names); + ClassDB::bind_method(D_METHOD("set_unique_animation_names", "unique_animation_names"), &GLTFState::set_unique_animation_names); ClassDB::bind_method(D_METHOD("get_skeletons"), &GLTFState::get_skeletons); ClassDB::bind_method(D_METHOD("set_skeletons", "skeletons"), &GLTFState::set_skeletons); ClassDB::bind_method(D_METHOD("get_skeleton_to_node"), &GLTFState::get_skeleton_to_node); @@ -98,6 +100,7 @@ void GLTFState::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "cameras", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_cameras", "get_cameras"); // Vector<Ref<GLTFCamera>> ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "lights", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_lights", "get_lights"); // Vector<Ref<GLTFLight>> ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "unique_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_unique_names", "get_unique_names"); // Set<String> + ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "unique_animation_names", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_unique_animation_names", "get_unique_animation_names"); // Set<String> ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "skeletons", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeletons", "get_skeletons"); // Vector<Ref<GLTFSkeleton>> ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "skeleton_to_node", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_skeleton_to_node", "get_skeleton_to_node"); // Map<GLTFSkeletonIndex, ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "animations", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL | PROPERTY_USAGE_EDITOR), "set_animations", "get_animations"); // Vector<Ref<GLTFAnimation>> @@ -255,6 +258,14 @@ void GLTFState::set_unique_names(Array p_unique_names) { GLTFDocument::set_from_array(unique_names, p_unique_names); } +Array GLTFState::get_unique_animation_names() { + return GLTFDocument::to_array(unique_animation_names); +} + +void GLTFState::set_unique_animation_names(Array p_unique_animation_names) { + GLTFDocument::set_from_array(unique_animation_names, p_unique_animation_names); +} + Array GLTFState::get_skeletons() { return GLTFDocument::to_array(skeletons); } diff --git a/modules/gltf/gltf_state.h b/modules/gltf/gltf_state.h index 4ce5aa9491..9030962b03 100644 --- a/modules/gltf/gltf_state.h +++ b/modules/gltf/gltf_state.h @@ -80,6 +80,7 @@ class GLTFState : public Resource { Vector<Ref<GLTFCamera>> cameras; Vector<Ref<GLTFLight>> lights; Set<String> unique_names; + Set<String> unique_animation_names; Vector<Ref<GLTFSkeleton>> skeletons; Map<GLTFSkeletonIndex, GLTFNodeIndex> skeleton_to_node; @@ -147,6 +148,9 @@ public: Array get_unique_names(); void set_unique_names(Array p_unique_names); + Array get_unique_animation_names(); + void set_unique_animation_names(Array p_unique_names); + Array get_skeletons(); void set_skeletons(Array p_skeletons); diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs new file mode 100644 index 0000000000..702a6c76ba --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotUnhandledExceptionEvent.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Godot +{ + public static partial class GD + { + /// <summary> + /// Fires when an unhandled exception occurs, regardless of project settings. + /// </summary> + public static event EventHandler<UnhandledExceptionArgs> UnhandledException; + + private static void OnUnhandledException(Exception e) + { + UnhandledException?.Invoke(null, new UnhandledExceptionArgs(e)); + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs new file mode 100644 index 0000000000..be01674568 --- /dev/null +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/UnhandledExceptionArgs.cs @@ -0,0 +1,20 @@ +using System; + +namespace Godot +{ + /// <summary> + /// Event arguments for when unhandled exceptions occur. + /// </summary> + public class UnhandledExceptionArgs + { + /// <summary> + /// Exception object + /// </summary> + public Exception Exception { get; private set; } + + internal UnhandledExceptionArgs(Exception exception) + { + Exception = exception; + } + } +} diff --git a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj index e98eabaff2..54aaaf1f92 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj +++ b/modules/mono/glue/GodotSharp/GodotSharp/GodotSharp.csproj @@ -40,6 +40,7 @@ <Compile Include="Core\GodotSynchronizationContext.cs" /> <Compile Include="Core\GodotTaskScheduler.cs" /> <Compile Include="Core\GodotTraceListener.cs" /> + <Compile Include="Core\GodotUnhandledExceptionEvent.cs" /> <Compile Include="Core\Interfaces\IAwaitable.cs" /> <Compile Include="Core\Interfaces\IAwaiter.cs" /> <Compile Include="Core\Interfaces\ISerializationListener.cs" /> @@ -59,6 +60,7 @@ <Compile Include="Core\StringName.cs" /> <Compile Include="Core\Transform.cs" /> <Compile Include="Core\Transform2D.cs" /> + <Compile Include="Core\UnhandledExceptionArgs.cs" /> <Compile Include="Core\Vector2.cs" /> <Compile Include="Core\Vector2i.cs" /> <Compile Include="Core\Vector3.cs" /> diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index 65e2680905..fa93c6533a 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -43,7 +43,6 @@ #include <mono/metadata/exception.h> namespace GDMonoInternals { - void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { // This method should not fail @@ -113,9 +112,11 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { void unhandled_exception(MonoException *p_exc) { mono_print_unhandled_exception((MonoObject *)p_exc); + gd_unhandled_exception_event(p_exc); if (GDMono::get_singleton()->get_unhandled_exception_policy() == GDMono::POLICY_TERMINATE_APP) { // Too bad 'mono_invoke_unhandled_exception_hook' is not exposed to embedders + mono_unhandled_exception((MonoObject *)p_exc); GDMono::unhandled_exception_hook((MonoObject *)p_exc, nullptr); GD_UNREACHABLE(); } else { @@ -127,4 +128,14 @@ void unhandled_exception(MonoException *p_exc) { #endif } } + +void gd_unhandled_exception_event(MonoException *p_exc) { + MonoImage *mono_image = GDMono::get_singleton()->get_core_api_assembly()->get_image(); + + MonoClass *gd_klass = mono_class_from_name(mono_image, "Godot", "GD"); + MonoMethod *unhandled_exception_method = mono_class_get_method_from_name(gd_klass, "OnUnhandledException", -1); + void *args[1]; + args[0] = p_exc; + mono_runtime_invoke(unhandled_exception_method, nullptr, (void **)args, nullptr); +} } // namespace GDMonoInternals diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 34d2d35b2d..26eb270eee 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -38,7 +38,6 @@ #include "core/object/class_db.h" namespace GDMonoInternals { - void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); /** @@ -46,6 +45,8 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); * Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead. */ void unhandled_exception(MonoException *p_exc); + +void gd_unhandled_exception_event(MonoException *p_exc); } // namespace GDMonoInternals #endif // GD_MONO_INTERNALS_H diff --git a/modules/text_server_adv/bitmap_font_adv.cpp b/modules/text_server_adv/bitmap_font_adv.cpp index e33556b232..df7b42eac6 100644 --- a/modules/text_server_adv/bitmap_font_adv.cpp +++ b/modules/text_server_adv/bitmap_font_adv.cpp @@ -361,6 +361,10 @@ Error BitmapFontDataAdvanced::load_from_file(const String &p_filename, int p_bas base_size = height; } + if (hb_handle) { + hb_font_destroy(hb_handle); + } + hb_handle = hb_bmp_font_create(this, base_size, nullptr); valid = true; memdelete(f); @@ -379,12 +383,10 @@ Error BitmapFontDataAdvanced::bitmap_new(float p_height, float p_ascent, int p_b char_map.clear(); textures.clear(); kerning_map.clear(); - - for (Map<float, hb_font_t *>::Element *E = cache.front(); E; E = E->next()) { - hb_font_destroy(E->get()); + if (hb_handle) { + hb_font_destroy(hb_handle); } - cache.clear(); - + hb_handle = hb_bmp_font_create(this, base_size, nullptr); valid = true; return OK; @@ -466,10 +468,7 @@ float BitmapFontDataAdvanced::get_base_size() const { hb_font_t *BitmapFontDataAdvanced::get_hb_handle(int p_size) { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!valid, nullptr); - if (!cache.has(p_size)) { - cache[p_size] = hb_bmp_font_create(this, p_size, nullptr); - } - return cache[p_size]; + return hb_handle; } bool BitmapFontDataAdvanced::has_char(char32_t p_char) const { @@ -516,6 +515,10 @@ Vector2 BitmapFontDataAdvanced::get_size(uint32_t p_char, int p_size) const { return c->rect.size * (float(p_size) / float(base_size)); } +float BitmapFontDataAdvanced::get_font_scale(int p_size) const { + return float(p_size) / float(base_size); +} + Vector2 BitmapFontDataAdvanced::get_kerning(uint32_t p_char, uint32_t p_next, int p_size) const { _THREAD_SAFE_METHOD_ ERR_FAIL_COND_V(!valid, Vector2()); @@ -543,13 +546,13 @@ Vector2 BitmapFontDataAdvanced::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { Point2i cpos = p_pos; - cpos += c->align * (float(p_size) / float(base_size)); - cpos.y -= ascent * (float(p_size) / float(base_size)); + cpos += (c->align + Vector2(0, -ascent)) * (float(p_size) / float(base_size)); + Size2i csize = c->rect.size * (float(p_size) / float(base_size)); if (RenderingServer::get_singleton() != nullptr) { //if (distance_field_hint) { // Not implemented. // RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, true); //} - RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, c->rect.size * (float(p_size) / float(base_size))), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false); + RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false); //if (distance_field_hint) { // RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, false); //} @@ -576,7 +579,7 @@ Vector2 BitmapFontDataAdvanced::draw_glyph_outline(RID p_canvas, int p_size, int } BitmapFontDataAdvanced::~BitmapFontDataAdvanced() { - for (Map<float, hb_font_t *>::Element *E = cache.front(); E; E = E->next()) { - hb_font_destroy(E->get()); + if (hb_handle) { + hb_font_destroy(hb_handle); } } diff --git a/modules/text_server_adv/bitmap_font_adv.h b/modules/text_server_adv/bitmap_font_adv.h index da7c2b00ac..7b620021e1 100644 --- a/modules/text_server_adv/bitmap_font_adv.h +++ b/modules/text_server_adv/bitmap_font_adv.h @@ -63,11 +63,11 @@ private: HashMap<uint32_t, Character> char_map; Map<KerningPairKey, int> kerning_map; - Map<float, hb_font_t *> cache; + hb_font_t *hb_handle = nullptr; float height = 0.f; float ascent = 0.f; - float base_size = 0.f; + int base_size = 0; bool distance_field_hint = false; public: @@ -101,6 +101,7 @@ public: virtual bool has_outline() const override { return false; }; virtual float get_base_size() const override; + virtual float get_font_scale(int p_size) const override; virtual hb_font_t *get_hb_handle(int p_size) override; diff --git a/modules/text_server_fb/bitmap_font_fb.cpp b/modules/text_server_fb/bitmap_font_fb.cpp index c58f8cbba1..313f170f04 100644 --- a/modules/text_server_fb/bitmap_font_fb.cpp +++ b/modules/text_server_fb/bitmap_font_fb.cpp @@ -319,14 +319,13 @@ Vector2 BitmapFontDataFallback::draw_glyph(RID p_canvas, int p_size, const Vecto ERR_FAIL_COND_V(c->texture_idx < -1 || c->texture_idx >= textures.size(), Vector2()); if (c->texture_idx != -1) { Point2i cpos = p_pos; - cpos += c->align * (float(p_size) / float(base_size)); - cpos.y -= ascent * (float(p_size) / float(base_size)); - + cpos += (c->align + Vector2(0, -ascent)) * (float(p_size) / float(base_size)); + Size2i csize = c->rect.size * (float(p_size) / float(base_size)); if (RenderingServer::get_singleton() != nullptr) { //if (distance_field_hint) { // Not implemented. // RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, true); //} - RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, c->rect.size * (float(p_size) / float(base_size))), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false); + RenderingServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas, Rect2(cpos, csize), textures[c->texture_idx]->get_rid(), c->rect, p_color, false, false); //if (distance_field_hint) { // RenderingServer::get_singleton()->canvas_item_set_distance_field_mode(p_canvas, false); //} |