diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 7 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 2 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_parser.h | 1 | ||||
| -rw-r--r-- | modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp | 9 | ||||
| -rw-r--r-- | modules/gltf/editor/editor_scene_exporter_gltf_settings.h | 1 | ||||
| -rw-r--r-- | modules/mbedtls/SCsub | 6 | ||||
| -rw-r--r-- | modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs | 4 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs | 10 | ||||
| -rw-r--r-- | modules/navigation/2d/nav_mesh_generator_2d.cpp | 144 | ||||
| -rw-r--r-- | modules/openxr/doc_classes/OpenXRHand.xml | 7 | ||||
| -rw-r--r-- | modules/openxr/scene/openxr_hand.cpp | 37 | ||||
| -rw-r--r-- | modules/openxr/scene/openxr_hand.h | 14 | ||||
| -rw-r--r-- | modules/openxr/util.h | 20 | ||||
| -rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 28 | ||||
| -rw-r--r-- | modules/text_server_adv/text_server_adv.h | 1 | ||||
| -rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 4 | ||||
| -rw-r--r-- | modules/text_server_fb/text_server_fb.h | 1 |
17 files changed, 170 insertions, 126 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 6af6460b31..f67f4913c3 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -3293,6 +3293,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a if (get_function_signature(p_call, is_constructor, base_type, p_call->function_name, return_type, par_types, default_arg_count, method_flags)) { // If the method is implemented in the class hierarchy, the virtual flag will not be set for that MethodInfo and the search stops there. // Virtual check only possible for super() calls because class hierarchy is known. Node/Objects may have scripts attached we don't know of at compile-time. + p_call->is_static = method_flags.has_flag(METHOD_FLAG_STATIC); if (p_call->is_super && method_flags.has_flag(METHOD_FLAG_VIRTUAL)) { push_error(vformat(R"*(Cannot call the parent class' virtual function "%s()" because it hasn't been defined.)*", p_call->function_name), p_call); } @@ -3311,7 +3312,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a base_type.is_meta_type = false; } - if (is_self && static_context && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + if (is_self && static_context && !p_call->is_static) { // Get the parent function above any lambda. GDScriptParser::FunctionNode *parent_function = parser->current_function; while (parent_function && parent_function->source_lambda) { @@ -3323,10 +3324,10 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a } else { push_error(vformat(R"*(Cannot call non-static function "%s()" from a static variable initializer.)*", p_call->function_name), p_call); } - } else if (!is_self && base_type.is_meta_type && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + } else if (!is_self && base_type.is_meta_type && !p_call->is_static) { base_type.is_meta_type = false; // For `to_string()`. push_error(vformat(R"*(Cannot call non-static function "%s()" on the class "%s" directly. Make an instance instead.)*", p_call->function_name, base_type.to_string()), p_call); - } else if (is_self && !method_flags.has_flag(METHOD_FLAG_STATIC)) { + } else if (is_self && !p_call->is_static) { mark_lambda_use_self(); } diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index 13ed66710c..d706c1b101 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -648,7 +648,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code // Not exact arguments, but still can use method bind call. gen->write_call_method_bind(result, self, method, arguments); } - } else if (codegen.is_static || (codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { + } else if (call->is_static || codegen.is_static || (codegen.function_node && codegen.function_node->is_static) || call->function_name == "new") { GDScriptCodeGenerator::Address self; self.mode = GDScriptCodeGenerator::Address::CLASS; if (is_awaited) { diff --git a/modules/gdscript/gdscript_parser.h b/modules/gdscript/gdscript_parser.h index ea67f1eaff..d047fa8e46 100644 --- a/modules/gdscript/gdscript_parser.h +++ b/modules/gdscript/gdscript_parser.h @@ -498,6 +498,7 @@ public: Vector<ExpressionNode *> arguments; StringName function_name; bool is_super = false; + bool is_static = false; CallNode() { type = CALL; diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp index b0283b0c55..d11300343a 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.cpp @@ -84,6 +84,11 @@ void EditorSceneExporterGLTFSettings::_get_property_list(List<PropertyInfo> *p_l } } +void EditorSceneExporterGLTFSettings::_on_extension_property_list_changed() { + generate_property_list(_document); + emit_signal("property_list_changed"); +} + bool EditorSceneExporterGLTFSettings::_set_extension_setting(const String &p_name_str, const Variant &p_value) { PackedStringArray split = String(p_name_str).split("/", true, 1); if (!_config_name_to_extension_map.has(split[0])) { @@ -130,6 +135,10 @@ void EditorSceneExporterGLTFSettings::generate_property_list(Ref<GLTFDocument> p String image_format_hint_string = "None,PNG,JPEG"; // Add properties from all document extensions. for (Ref<GLTFDocumentExtension> &extension : GLTFDocument::get_all_gltf_document_extensions()) { + const Callable on_prop_changed = callable_mp(this, &EditorSceneExporterGLTFSettings::_on_extension_property_list_changed); + if (!extension->is_connected("property_list_changed", on_prop_changed)) { + extension->connect("property_list_changed", on_prop_changed); + } const String config_prefix = get_friendly_config_prefix(extension); _config_name_to_extension_map[config_prefix] = extension; // If the extension allows saving in different image formats, add to the enum. diff --git a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h index 6032932367..e1ce674274 100644 --- a/modules/gltf/editor/editor_scene_exporter_gltf_settings.h +++ b/modules/gltf/editor/editor_scene_exporter_gltf_settings.h @@ -48,6 +48,7 @@ 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; + void _on_extension_property_list_changed(); bool _set_extension_setting(const String &p_name_str, const Variant &p_value); bool _get_extension_setting(const String &p_name_str, Variant &r_ret) const; diff --git a/modules/mbedtls/SCsub b/modules/mbedtls/SCsub index 4b8f65d8ff..04d26f9942 100644 --- a/modules/mbedtls/SCsub +++ b/modules/mbedtls/SCsub @@ -100,9 +100,9 @@ if env["builtin_mbedtls"]: thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources] env_mbed_tls.Prepend(CPPPATH=["#thirdparty/mbedtls/include/"]) - env_mbed_tls.Append( - CPPDEFINES=[("MBEDTLS_CONFIG_FILE", '\\"thirdparty/mbedtls/include/godot_module_mbedtls_config.h\\"')] - ) + config_path = "thirdparty/mbedtls/include/godot_module_mbedtls_config.h" + config_path = f"<{config_path}>" if env_mbed_tls["ninja"] and env_mbed_tls.msvc else f'\\"{config_path}\\"' + env_mbed_tls.Append(CPPDEFINES=[("MBEDTLS_CONFIG_FILE", config_path)]) env_thirdparty = env_mbed_tls.Clone() env_thirdparty.disable_warnings() diff --git a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs index bf6cab11c7..d3899c809a 100644 --- a/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs +++ b/modules/mono/editor/GodotTools/GodotTools/GodotSharpEditor.cs @@ -167,8 +167,8 @@ namespace GodotTools public void ShowConfirmCreateSlnDialog() { - _confirmCreateSlnDialog.Title = "C# solution already exists. This will override the existing C# project file, any manual changes will be lost.".TTR(); - _confirmCreateSlnDialog.DialogText = "Create C# solution".TTR(); + _confirmCreateSlnDialog.Title = "Create C# solution".TTR(); + _confirmCreateSlnDialog.DialogText = "C# solution already exists. This will override the existing C# project file, any manual changes will be lost.".TTR(); EditorInterface.Singleton.PopupDialogCentered(_confirmCreateSlnDialog); } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs index ef3c9c79d4..7a88fea5f1 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/DelegateUtils.cs @@ -207,7 +207,7 @@ namespace Godot foreach (FieldInfo field in fields) { - Type fieldType = field.GetType(); + Type fieldType = field.FieldType; Variant.Type variantType = GD.TypeToVariantType(fieldType); @@ -216,7 +216,7 @@ namespace Godot static byte[] VarToBytes(in godot_variant var) { - NativeFuncs.godotsharp_var_to_bytes(var, false.ToGodotBool(), out var varBytes); + NativeFuncs.godotsharp_var_to_bytes(var, godot_bool.True, out var varBytes); using (varBytes) return Marshaling.ConvertNativePackedByteArrayToSystemArray(varBytes); } @@ -483,7 +483,7 @@ namespace Godot if (fieldInfo != null) { - var variantValue = GD.BytesToVar(valueBuffer); + var variantValue = GD.BytesToVarWithObjects(valueBuffer); object? managedValue = RuntimeTypeConversionHelper.ConvertToObjectOfType( (godot_variant)variantValue.NativeVar, fieldInfo.FieldType); fieldInfo.SetValue(recreatedTarget, managedValue); @@ -799,7 +799,7 @@ namespace Godot return func(variant); if (typeof(GodotObject).IsAssignableFrom(type)) - return Convert.ChangeType(VariantUtils.ConvertTo<GodotObject>(variant), type, CultureInfo.InvariantCulture); + return VariantUtils.ConvertTo<GodotObject>(variant); if (typeof(GodotObject[]).IsAssignableFrom(type)) { @@ -818,7 +818,7 @@ namespace Godot } using var godotArray = NativeFuncs.godotsharp_variant_as_array(variant); - return Convert.ChangeType(ConvertToSystemArrayOfGodotObject(godotArray, type), type, CultureInfo.InvariantCulture); + return ConvertToSystemArrayOfGodotObject(godotArray, type); } if (type.IsEnum) diff --git a/modules/navigation/2d/nav_mesh_generator_2d.cpp b/modules/navigation/2d/nav_mesh_generator_2d.cpp index 069cc0f4a8..0738a102eb 100644 --- a/modules/navigation/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation/2d/nav_mesh_generator_2d.cpp @@ -575,8 +575,6 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo return; } - int tilemap_layer = 0; // only main tile map layer is supported - Ref<TileSet> tile_set = tilemap->get_tileset(); if (!tile_set.is_valid()) { return; @@ -589,77 +587,115 @@ void NavMeshGenerator2D::generator_parse_tilemap_node(const Ref<NavigationPolygo return; } - const Transform2D tilemap_xform = p_source_geometry_data->root_node_transform * tilemap->get_global_transform(); - TypedArray<Vector2i> used_cells = tilemap->get_used_cells(tilemap_layer); + HashSet<Vector2i> cells_with_navigation_polygon; + HashSet<Vector2i> cells_with_collision_polygon; - for (int used_cell_index = 0; used_cell_index < used_cells.size(); used_cell_index++) { - const Vector2i &cell = used_cells[used_cell_index]; + const Transform2D tilemap_xform = p_source_geometry_data->root_node_transform * tilemap->get_global_transform(); - const TileData *tile_data = tilemap->get_cell_tile_data(tilemap_layer, cell, false); - if (tile_data == nullptr) { - continue; - } +#ifdef DEBUG_ENABLED + int error_print_counter = 0; + int error_print_max = 10; +#endif // DEBUG_ENABLED - // Transform flags. - const int alternative_id = tilemap->get_cell_alternative_tile(tilemap_layer, cell, false); - bool flip_h = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H); - bool flip_v = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V); - bool transpose = (alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE); + for (int tilemap_layer = 0; tilemap_layer < tilemap->get_layers_count(); tilemap_layer++) { + TypedArray<Vector2i> used_cells = tilemap->get_used_cells(tilemap_layer); - Transform2D tile_transform; - tile_transform.set_origin(tilemap->map_to_local(cell)); + for (int used_cell_index = 0; used_cell_index < used_cells.size(); used_cell_index++) { + const Vector2i &cell = used_cells[used_cell_index]; - const Transform2D tile_transform_offset = tilemap_xform * tile_transform; + const TileData *tile_data = tilemap->get_cell_tile_data(tilemap_layer, cell, false); + if (tile_data == nullptr) { + continue; + } - if (navigation_layers_count > 0) { - Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer, flip_h, flip_v, transpose); - if (navigation_polygon.is_valid()) { - for (int outline_index = 0; outline_index < navigation_polygon->get_outline_count(); outline_index++) { - const Vector<Vector2> &navigation_polygon_outline = navigation_polygon->get_outline(outline_index); - if (navigation_polygon_outline.size() == 0) { - continue; + // Transform flags. + const int alternative_id = tilemap->get_cell_alternative_tile(tilemap_layer, cell, false); + bool flip_h = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_H); + bool flip_v = (alternative_id & TileSetAtlasSource::TRANSFORM_FLIP_V); + bool transpose = (alternative_id & TileSetAtlasSource::TRANSFORM_TRANSPOSE); + + Transform2D tile_transform; + tile_transform.set_origin(tilemap->map_to_local(cell)); + + const Transform2D tile_transform_offset = tilemap_xform * tile_transform; + + if (navigation_layers_count > 0) { + Ref<NavigationPolygon> navigation_polygon = tile_data->get_navigation_polygon(tilemap_layer, flip_h, flip_v, transpose); + if (navigation_polygon.is_valid()) { + if (cells_with_navigation_polygon.has(cell)) { +#ifdef DEBUG_ENABLED + error_print_counter++; + if (error_print_counter <= error_print_max) { + WARN_PRINT(vformat("TileMap navigation mesh baking error. The TileMap cell key Vector2i(%s, %s) has navigation mesh from 2 or more different TileMap layers assigned. This can cause unexpected navigation mesh baking results. The duplicated cell data was ignored.", cell.x, cell.y)); + } +#endif // DEBUG_ENABLED + } else { + cells_with_navigation_polygon.insert(cell); + + for (int outline_index = 0; outline_index < navigation_polygon->get_outline_count(); outline_index++) { + const Vector<Vector2> &navigation_polygon_outline = navigation_polygon->get_outline(outline_index); + if (navigation_polygon_outline.size() == 0) { + continue; + } + + Vector<Vector2> traversable_outline; + traversable_outline.resize(navigation_polygon_outline.size()); + + const Vector2 *navigation_polygon_outline_ptr = navigation_polygon_outline.ptr(); + Vector2 *traversable_outline_ptrw = traversable_outline.ptrw(); + + for (int traversable_outline_index = 0; traversable_outline_index < traversable_outline.size(); traversable_outline_index++) { + traversable_outline_ptrw[traversable_outline_index] = tile_transform_offset.xform(navigation_polygon_outline_ptr[traversable_outline_index]); + } + + p_source_geometry_data->_add_traversable_outline(traversable_outline); + } } + } + } - Vector<Vector2> traversable_outline; - traversable_outline.resize(navigation_polygon_outline.size()); - - const Vector2 *navigation_polygon_outline_ptr = navigation_polygon_outline.ptr(); - Vector2 *traversable_outline_ptrw = traversable_outline.ptrw(); - - for (int traversable_outline_index = 0; traversable_outline_index < traversable_outline.size(); traversable_outline_index++) { - traversable_outline_ptrw[traversable_outline_index] = tile_transform_offset.xform(navigation_polygon_outline_ptr[traversable_outline_index]); + if (physics_layers_count > 0 && (parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS || parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_BOTH) && (tile_set->get_physics_layer_collision_layer(tilemap_layer) & parsed_collision_mask)) { + if (cells_with_collision_polygon.has(cell)) { +#ifdef DEBUG_ENABLED + error_print_counter++; + if (error_print_counter <= error_print_max) { + WARN_PRINT(vformat("TileMap navigation mesh baking error. The cell key Vector2i(%s, %s) has collision polygons from 2 or more different TileMap layers assigned that all match the parsed collision mask. This can cause unexpected navigation mesh baking results. The duplicated cell data was ignored.", cell.x, cell.y)); } +#endif // DEBUG_ENABLED + } else { + cells_with_collision_polygon.insert(cell); - p_source_geometry_data->_add_traversable_outline(traversable_outline); - } - } - } + for (int collision_polygon_index = 0; collision_polygon_index < tile_data->get_collision_polygons_count(tilemap_layer); collision_polygon_index++) { + PackedVector2Array collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index); + if (collision_polygon_points.size() == 0) { + continue; + } - if (physics_layers_count > 0 && (parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_STATIC_COLLIDERS || parsed_geometry_type == NavigationPolygon::PARSED_GEOMETRY_BOTH) && (tile_set->get_physics_layer_collision_layer(tilemap_layer) & parsed_collision_mask)) { - for (int collision_polygon_index = 0; collision_polygon_index < tile_data->get_collision_polygons_count(tilemap_layer); collision_polygon_index++) { - PackedVector2Array collision_polygon_points = tile_data->get_collision_polygon_points(tilemap_layer, collision_polygon_index); - if (collision_polygon_points.size() == 0) { - continue; - } + if (flip_h || flip_v || transpose) { + collision_polygon_points = TileData::get_transformed_vertices(collision_polygon_points, flip_h, flip_v, transpose); + } - if (flip_h || flip_v || transpose) { - collision_polygon_points = TileData::get_transformed_vertices(collision_polygon_points, flip_h, flip_v, transpose); - } + Vector<Vector2> obstruction_outline; + obstruction_outline.resize(collision_polygon_points.size()); - Vector<Vector2> obstruction_outline; - obstruction_outline.resize(collision_polygon_points.size()); + const Vector2 *collision_polygon_points_ptr = collision_polygon_points.ptr(); + Vector2 *obstruction_outline_ptrw = obstruction_outline.ptrw(); - const Vector2 *collision_polygon_points_ptr = collision_polygon_points.ptr(); - Vector2 *obstruction_outline_ptrw = obstruction_outline.ptrw(); + for (int obstruction_outline_index = 0; obstruction_outline_index < obstruction_outline.size(); obstruction_outline_index++) { + obstruction_outline_ptrw[obstruction_outline_index] = tile_transform_offset.xform(collision_polygon_points_ptr[obstruction_outline_index]); + } - for (int obstruction_outline_index = 0; obstruction_outline_index < obstruction_outline.size(); obstruction_outline_index++) { - obstruction_outline_ptrw[obstruction_outline_index] = tile_transform_offset.xform(collision_polygon_points_ptr[obstruction_outline_index]); + p_source_geometry_data->_add_obstruction_outline(obstruction_outline); + } } - - p_source_geometry_data->_add_obstruction_outline(obstruction_outline); } } } +#ifdef DEBUG_ENABLED + if (error_print_counter > error_print_max) { + ERR_PRINT(vformat("TileMap navigation mesh baking error. A total of %s cells with navigation or collision polygons from 2 or more different TileMap layers overlap. This can cause unexpected navigation mesh baking results. The duplicated cell data was ignored.", error_print_counter)); + } +#endif // DEBUG_ENABLED } void NavMeshGenerator2D::generator_parse_navigationobstacle_node(const Ref<NavigationPolygon> &p_navigation_mesh, Ref<NavigationMeshSourceGeometryData2D> p_source_geometry_data, Node *p_node) { diff --git a/modules/openxr/doc_classes/OpenXRHand.xml b/modules/openxr/doc_classes/OpenXRHand.xml index 23d932ddd7..9cc548dd6f 100644 --- a/modules/openxr/doc_classes/OpenXRHand.xml +++ b/modules/openxr/doc_classes/OpenXRHand.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8" ?> -<class name="OpenXRHand" inherits="Node3D" deprecated="Use [XRHandModifier3D] instead." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> +<class name="OpenXRHand" inherits="SkeletonModifier3D" deprecated="Use [XRHandModifier3D] instead." xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> Node supporting hand and finger tracking in OpenXR. </brief_description> @@ -18,14 +18,11 @@ <member name="hand" type="int" setter="set_hand" getter="get_hand" enum="OpenXRHand.Hands" default="0"> Specifies whether this node tracks the left or right hand of the player. </member> - <member name="hand_skeleton" type="NodePath" setter="set_hand_skeleton" getter="get_hand_skeleton" default="NodePath("")"> - Set a [Skeleton3D] node for which the pose positions will be updated. - </member> <member name="motion_range" type="int" setter="set_motion_range" getter="get_motion_range" enum="OpenXRHand.MotionRange" default="0"> Set the motion range (if supported) limiting the hand motion. </member> <member name="skeleton_rig" type="int" setter="set_skeleton_rig" getter="get_skeleton_rig" enum="OpenXRHand.SkeletonRig" default="0"> - Set the type of skeleton rig the [member hand_skeleton] is compliant with. + Set the type of skeleton rig the parent [Skeleton3D] is compliant with. </member> </members> <constants> diff --git a/modules/openxr/scene/openxr_hand.cpp b/modules/openxr/scene/openxr_hand.cpp index 2a4104f6ee..f20d1f8e19 100644 --- a/modules/openxr/scene/openxr_hand.cpp +++ b/modules/openxr/scene/openxr_hand.cpp @@ -40,9 +40,6 @@ void OpenXRHand::_bind_methods() { ClassDB::bind_method(D_METHOD("set_hand", "hand"), &OpenXRHand::set_hand); ClassDB::bind_method(D_METHOD("get_hand"), &OpenXRHand::get_hand); - ClassDB::bind_method(D_METHOD("set_hand_skeleton", "hand_skeleton"), &OpenXRHand::set_hand_skeleton); - ClassDB::bind_method(D_METHOD("get_hand_skeleton"), &OpenXRHand::get_hand_skeleton); - ClassDB::bind_method(D_METHOD("set_motion_range", "motion_range"), &OpenXRHand::set_motion_range); ClassDB::bind_method(D_METHOD("get_motion_range"), &OpenXRHand::get_motion_range); @@ -54,7 +51,6 @@ void OpenXRHand::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "hand", PROPERTY_HINT_ENUM, "Left,Right"), "set_hand", "get_hand"); ADD_PROPERTY(PropertyInfo(Variant::INT, "motion_range", PROPERTY_HINT_ENUM, "Unobstructed,Conform to controller"), "set_motion_range", "get_motion_range"); - ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "hand_skeleton", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Skeleton3D"), "set_hand_skeleton", "get_hand_skeleton"); ADD_PROPERTY(PropertyInfo(Variant::INT, "skeleton_rig", PROPERTY_HINT_ENUM, "OpenXR,Humanoid"), "set_skeleton_rig", "get_skeleton_rig"); ADD_PROPERTY(PropertyInfo(Variant::INT, "bone_update", PROPERTY_HINT_ENUM, "Full,Rotation Only"), "set_bone_update", "get_bone_update"); @@ -90,12 +86,6 @@ OpenXRHand::Hands OpenXRHand::get_hand() const { return hand; } -void OpenXRHand::set_hand_skeleton(const NodePath &p_hand_skeleton) { - hand_skeleton = p_hand_skeleton; - - // TODO if inside tree call _get_bones() -} - void OpenXRHand::set_motion_range(MotionRange p_motion_range) { ERR_FAIL_INDEX(p_motion_range, MOTION_RANGE_MAX); motion_range = p_motion_range; @@ -107,10 +97,6 @@ OpenXRHand::MotionRange OpenXRHand::get_motion_range() const { return motion_range; } -NodePath OpenXRHand::get_hand_skeleton() const { - return hand_skeleton; -} - void OpenXRHand::_set_motion_range() { if (!hand_tracking_ext) { return; @@ -152,20 +138,6 @@ OpenXRHand::BoneUpdate OpenXRHand::get_bone_update() const { return bone_update; } -Skeleton3D *OpenXRHand::get_skeleton() { - if (!has_node(hand_skeleton)) { - return nullptr; - } - - Node *node = get_node(hand_skeleton); - if (!node) { - return nullptr; - } - - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); - return skeleton; -} - void OpenXRHand::_get_joint_data() { // Table of bone names for different rig types. static const String bone_names[SKELETON_RIG_MAX][XR_HAND_JOINT_COUNT_EXT] = { @@ -290,7 +262,7 @@ void OpenXRHand::_get_joint_data() { } } -void OpenXRHand::_update_skeleton() { +void OpenXRHand::_process_modification() { if (openxr_api == nullptr || !openxr_api->is_initialized()) { return; } else if (hand_tracking_ext == nullptr || !hand_tracking_ext->get_active()) { @@ -395,21 +367,14 @@ void OpenXRHand::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { _get_joint_data(); - - set_process_internal(true); } break; case NOTIFICATION_EXIT_TREE: { - set_process_internal(false); - // reset for (int i = 0; i < XR_HAND_JOINT_COUNT_EXT; i++) { joints[i].bone = -1; joints[i].parent_joint = -1; } } break; - case NOTIFICATION_INTERNAL_PROCESS: { - _update_skeleton(); - } break; default: { } break; } diff --git a/modules/openxr/scene/openxr_hand.h b/modules/openxr/scene/openxr_hand.h index 4c77e7277c..fc0a994f48 100644 --- a/modules/openxr/scene/openxr_hand.h +++ b/modules/openxr/scene/openxr_hand.h @@ -31,16 +31,15 @@ #ifndef OPENXR_HAND_H #define OPENXR_HAND_H -#include "scene/3d/node_3d.h" -#include "scene/3d/skeleton_3d.h" +#include "scene/3d/skeleton_modifier_3d.h" #include <openxr/openxr.h> class OpenXRAPI; class OpenXRHandTrackingExtension; -class OpenXRHand : public Node3D { - GDCLASS(OpenXRHand, Node3D); +class OpenXRHand : public SkeletonModifier3D { + GDCLASS(OpenXRHand, SkeletonModifier3D); public: enum Hands { // Deprecated, need to change this to OpenXRInterface::Hands. @@ -86,13 +85,13 @@ private: void _set_motion_range(); - Skeleton3D *get_skeleton(); void _get_joint_data(); - void _update_skeleton(); protected: static void _bind_methods(); + virtual void _process_modification() override; + public: OpenXRHand(); @@ -102,9 +101,6 @@ public: void set_motion_range(MotionRange p_motion_range); MotionRange get_motion_range() const; - void set_hand_skeleton(const NodePath &p_hand_skeleton); - NodePath get_hand_skeleton() const; - void set_skeleton_rig(SkeletonRig p_skeleton_rig); SkeletonRig get_skeleton_rig() const; diff --git a/modules/openxr/util.h b/modules/openxr/util.h index 7488b5cf8e..4c611d6f4a 100644 --- a/modules/openxr/util.h +++ b/modules/openxr/util.h @@ -34,21 +34,23 @@ #define UNPACK(...) __VA_ARGS__ #define INIT_XR_FUNC_V(openxr_api, name) \ - do { \ + if constexpr (true) { \ XrResult get_instance_proc_addr_result; \ get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \ ERR_FAIL_COND_V(XR_FAILED(get_instance_proc_addr_result), false); \ - } while (0) + } else \ + ((void)0) #define EXT_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(OpenXRAPI::get_singleton(), name) #define OPENXR_API_INIT_XR_FUNC_V(name) INIT_XR_FUNC_V(this, name) #define INIT_XR_FUNC(openxr_api, name) \ - do { \ + if constexpr (true) { \ XrResult get_instance_proc_addr_result; \ get_instance_proc_addr_result = openxr_api->get_instance_proc_addr(#name, (PFN_xrVoidFunction *)&name##_ptr); \ ERR_FAIL_COND(XR_FAILED(get_instance_proc_addr_result)); \ - } while (0) + } else \ + ((void)0) #define EXT_INIT_XR_FUNC(name) INIT_XR_FUNC(OpenXRAPI::get_singleton(), name) #define OPENXR_API_INIT_XR_FUNC(name) INIT_XR_FUNC(this, name) @@ -59,16 +61,18 @@ #define EXT_TRY_INIT_XR_FUNC(name) TRY_INIT_XR_FUNC(OpenXRAPI::get_singleton(), name) #define OPENXR_TRY_API_INIT_XR_FUNC(name) TRY_INIT_XR_FUNC(this, name) #define GDEXTENSION_INIT_XR_FUNC(name) \ - do { \ + if constexpr (true) { \ name##_ptr = reinterpret_cast<PFN_##name>(get_openxr_api()->get_instance_proc_addr(#name)); \ ERR_FAIL_NULL(name##_ptr); \ - } while (0) + } else \ + ((void)0) #define GDEXTENSION_INIT_XR_FUNC_V(name) \ - do { \ + if constexpr (true) { \ name##_ptr = reinterpret_cast<PFN_##name>(get_openxr_api()->get_instance_proc_addr(#name)); \ ERR_FAIL_NULL_V(name##_ptr, false); \ - } while (0) + } else \ + ((void)0) #define EXT_PROTO_XRRESULT_FUNC1(func_name, arg1_type, arg1) \ PFN_##func_name func_name##_ptr = nullptr; \ diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index f5174d7d46..cc1ceec41e 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -6976,6 +6976,34 @@ String TextServerAdvanced::_string_to_lower(const String &p_string, const String return String::utf16(lower.ptr(), len); } +String TextServerAdvanced::_string_to_title(const String &p_string, const String &p_language) const { +#ifndef ICU_STATIC_DATA + if (!icu_data_loaded) { + return p_string.capitalize(); + } +#endif + + if (p_string.is_empty()) { + return p_string; + } + const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; + + // Convert to UTF-16. + Char16String utf16 = p_string.utf16(); + + Vector<char16_t> upper; + UErrorCode err = U_ZERO_ERROR; + int32_t len = u_strToTitle(nullptr, 0, utf16.get_data(), -1, nullptr, lang.ascii().get_data(), &err); + ERR_FAIL_COND_V_MSG(err != U_BUFFER_OVERFLOW_ERROR, p_string, u_errorName(err)); + upper.resize(len); + err = U_ZERO_ERROR; + u_strToTitle(upper.ptrw(), len, utf16.get_data(), -1, nullptr, lang.ascii().get_data(), &err); + ERR_FAIL_COND_V_MSG(U_FAILURE(err), p_string, u_errorName(err)); + + // Convert back to UTF-32. + return String::utf16(upper.ptr(), len); +} + PackedInt32Array TextServerAdvanced::_string_get_word_breaks(const String &p_string, const String &p_language, int64_t p_chars_per_line) const { const String lang = (p_language.is_empty()) ? TranslationServer::get_singleton()->get_tool_locale() : p_language; // Convert to UTF-16. diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 154fe670eb..160eb27528 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -991,6 +991,7 @@ public: MODBIND2RC(String, string_to_upper, const String &, const String &); MODBIND2RC(String, string_to_lower, const String &, const String &); + MODBIND2RC(String, string_to_title, const String &, const String &); MODBIND0(cleanup); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 302bd677fe..1a0a4ec356 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -4439,6 +4439,10 @@ String TextServerFallback::_string_to_lower(const String &p_string, const String return p_string.to_lower(); } +String TextServerFallback::_string_to_title(const String &p_string, const String &p_language) const { + return p_string.capitalize(); +} + PackedInt32Array TextServerFallback::_string_get_word_breaks(const String &p_string, const String &p_language, int64_t p_chars_per_line) const { PackedInt32Array ret; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 0db1f7318f..9fd5af8b51 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -848,6 +848,7 @@ public: MODBIND2RC(String, string_to_upper, const String &, const String &); MODBIND2RC(String, string_to_lower, const String &, const String &); + MODBIND2RC(String, string_to_title, const String &, const String &); MODBIND0(cleanup); |
