diff options
Diffstat (limited to 'modules')
60 files changed, 515 insertions, 255 deletions
diff --git a/modules/SCsub b/modules/SCsub index db0e563dc4..e16cc17b67 100644 --- a/modules/SCsub +++ b/modules/SCsub @@ -14,6 +14,18 @@ env_modules.Append(CPPDEFINES=["GODOT_MODULE"]) Export("env_modules") +# Header with MODULE_*_ENABLED defines. +def modules_enabled_builder(target, source, env): + with methods.generated_wrapper(target) as file: + for module in source[0].read(): + file.write(f"#define MODULE_{module.upper()}_ENABLED\n") + + +modules_enabled = env.CommandNoCache( + "modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder) +) + + def register_module_types_builder(target, source, env): modules = source[0].read() mod_inc = "\n".join([f'#include "{p}/register_types.h"' for p in modules.values()]) @@ -44,20 +56,12 @@ void uninitialize_modules(ModuleInitializationLevel p_level) {{ register_module_types = env.CommandNoCache( - "register_module_types.gen.cpp", env.Value(env.modules_detected), env.Run(register_module_types_builder) + "register_module_types.gen.cpp", + [env.Value(env.modules_detected), modules_enabled], + env.Run(register_module_types_builder), ) -# Header with MODULE_*_ENABLED defines. -def modules_enabled_builder(target, source, env): - with methods.generated_wrapper(target) as file: - for module in source[0].read(): - file.write(f"#define MODULE_{module.upper()}_ENABLED\n") - - -env.CommandNoCache("modules_enabled.gen.h", env.Value(env.module_list), env.Run(modules_enabled_builder)) - - vs_sources = [] test_headers = [] # libmodule_<name>.a for each active module. diff --git a/modules/fbx/doc_classes/EditorSceneFormatImporterFBX2GLTF.xml b/modules/fbx/doc_classes/EditorSceneFormatImporterFBX2GLTF.xml index e30782780f..3bf4e7ddc0 100644 --- a/modules/fbx/doc_classes/EditorSceneFormatImporterFBX2GLTF.xml +++ b/modules/fbx/doc_classes/EditorSceneFormatImporterFBX2GLTF.xml @@ -5,7 +5,7 @@ </brief_description> <description> Imports Autodesk FBX 3D scenes by way of converting them to glTF 2.0 using the FBX2glTF command line tool. - The location of the FBX2glTF binary is set via the [member EditorSettings.filesystem/import/fbx2gltf/fbx2gltf_path] editor setting. + The location of the FBX2glTF binary is set via the [member EditorSettings.filesystem/import/fbx/fbx2gltf_path] editor setting. This importer is only used if [member ProjectSettings.filesystem/import/fbx2gltf/enabled] is set to [code]true[/code]. </description> <tutorials> diff --git a/modules/fbx/editor/editor_scene_importer_fbx2gltf.cpp b/modules/fbx/editor/editor_scene_importer_fbx2gltf.cpp index 6629e05197..afb63246e4 100644 --- a/modules/fbx/editor/editor_scene_importer_fbx2gltf.cpp +++ b/modules/fbx/editor/editor_scene_importer_fbx2gltf.cpp @@ -73,7 +73,7 @@ Node *EditorSceneFormatImporterFBX2GLTF::import_scene(const String &p_path, uint // Run fbx2gltf. - String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx2gltf/fbx2gltf_path"); + String fbx2gltf_path = EDITOR_GET("filesystem/import/fbx/fbx2gltf_path"); List<String> args; args.push_back("--pbr-metallic-roughness"); diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index a2680c932f..aa26bb222d 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -1971,7 +1971,12 @@ void GDScriptAnalyzer::resolve_assignable(GDScriptParser::AssignableNode *p_assi const bool is_parameter = p_assignable->type == GDScriptParser::Node::PARAMETER; const String declaration_type = is_constant ? "Constant" : (is_parameter ? "Parameter" : "Variable"); if (p_assignable->infer_datatype || is_constant) { - parser->push_warning(p_assignable, GDScriptWarning::INFERRED_DECLARATION, declaration_type, p_assignable->identifier->name); + // Do not produce the `INFERRED_DECLARATION` warning on type import because there is no way to specify the true type. + // And removing the metatype makes it impossible to use the constant as a type hint (especially for enums). + const bool is_type_import = is_constant && p_assignable->initializer != nullptr && p_assignable->initializer->datatype.is_meta_type; + if (!is_type_import) { + parser->push_warning(p_assignable, GDScriptWarning::INFERRED_DECLARATION, declaration_type, p_assignable->identifier->name); + } } else { parser->push_warning(p_assignable, GDScriptWarning::UNTYPED_DECLARATION, declaration_type, p_assignable->identifier->name); } @@ -4061,10 +4066,23 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident mark_lambda_use_self(); return; // No need to capture. } - // If the identifier is local, check if it's any kind of capture by comparing their source function. - // Only capture locals and enum values. Constants are still accessible from the lambda using the script reference. If not, this method is done. - if (p_identifier->source == GDScriptParser::IdentifierNode::UNDEFINED_SOURCE || p_identifier->source == GDScriptParser::IdentifierNode::MEMBER_CONSTANT) { - return; + + switch (p_identifier->source) { + case GDScriptParser::IdentifierNode::FUNCTION_PARAMETER: + case GDScriptParser::IdentifierNode::LOCAL_VARIABLE: + case GDScriptParser::IdentifierNode::LOCAL_ITERATOR: + case GDScriptParser::IdentifierNode::LOCAL_BIND: + break; // Need to capture. + case GDScriptParser::IdentifierNode::UNDEFINED_SOURCE: // A global. + case GDScriptParser::IdentifierNode::LOCAL_CONSTANT: + case GDScriptParser::IdentifierNode::MEMBER_VARIABLE: + case GDScriptParser::IdentifierNode::MEMBER_CONSTANT: + case GDScriptParser::IdentifierNode::MEMBER_FUNCTION: + case GDScriptParser::IdentifierNode::MEMBER_SIGNAL: + case GDScriptParser::IdentifierNode::MEMBER_CLASS: + case GDScriptParser::IdentifierNode::INHERITED_VARIABLE: + case GDScriptParser::IdentifierNode::STATIC_VARIABLE: + return; // No need to capture. } GDScriptParser::FunctionNode *function_test = current_lambda->function; @@ -4329,15 +4347,45 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri GDScriptParser::DataType base_type = p_subscript->base->get_datatype(); bool valid = false; + // If the base is a metatype, use the analyzer instead. - if (p_subscript->base->is_constant && !base_type.is_meta_type && base_type.kind != GDScriptParser::DataType::CLASS) { - // Just try to get it. - Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); - if (valid) { - p_subscript->is_constant = true; - p_subscript->reduced_value = value; - result_type = type_from_variant(value, p_subscript); + if (p_subscript->base->is_constant && !base_type.is_meta_type) { + // GH-92534. If the base is a GDScript, use the analyzer instead. + bool base_is_gdscript = false; + if (p_subscript->base->reduced_value.get_type() == Variant::OBJECT) { + Ref<GDScript> gdscript = Object::cast_to<GDScript>(p_subscript->base->reduced_value.get_validated_object()); + if (gdscript.is_valid()) { + base_is_gdscript = true; + // Makes a metatype from a constant GDScript, since `base_type` is not a metatype. + GDScriptParser::DataType base_type_meta = type_from_variant(gdscript, p_subscript); + // First try to reduce the attribute from the metatype. + reduce_identifier_from_base(p_subscript->attribute, &base_type_meta); + GDScriptParser::DataType attr_type = p_subscript->attribute->get_datatype(); + if (attr_type.is_set()) { + valid = !attr_type.is_pseudo_type || p_can_be_pseudo_type; + result_type = attr_type; + p_subscript->is_constant = p_subscript->attribute->is_constant; + p_subscript->reduced_value = p_subscript->attribute->reduced_value; + } + if (!valid) { + // If unsuccessful, reset and return to the normal route. + p_subscript->attribute->set_datatype(GDScriptParser::DataType()); + } + } + } + if (!base_is_gdscript) { + // Just try to get it. + Variant value = p_subscript->base->reduced_value.get_named(p_subscript->attribute->name, valid); + if (valid) { + p_subscript->is_constant = true; + p_subscript->reduced_value = value; + result_type = type_from_variant(value, p_subscript); + } } + } + + if (valid) { + // Do nothing. } else if (base_type.is_variant() || !base_type.is_hard_type()) { valid = !base_type.is_pseudo_type || p_can_be_pseudo_type; result_type.kind = GDScriptParser::DataType::VARIANT; @@ -4375,6 +4423,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri mark_node_unsafe(p_subscript); } } + if (!valid) { GDScriptParser::DataType attr_type = p_subscript->attribute->get_datatype(); if (!p_can_be_pseudo_type && (attr_type.is_pseudo_type || result_type.is_pseudo_type)) { @@ -4393,6 +4442,7 @@ void GDScriptAnalyzer::reduce_subscript(GDScriptParser::SubscriptNode *p_subscri if (p_subscript->base->is_constant && p_subscript->index->is_constant) { // Just try to get it. bool valid = false; + // TODO: Check if `p_subscript->base->reduced_value` is GDScript. Variant value = p_subscript->base->reduced_value.get(p_subscript->index->reduced_value, &valid); if (!valid) { push_error(vformat(R"(Cannot get index "%s" from "%s".)", p_subscript->index->reduced_value, p_subscript->base->reduced_value), p_subscript->index); diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index 4ae39d80cd..fcabb7c4a8 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -754,13 +754,17 @@ static String _make_arguments_hint(const MethodInfo &p_info, int p_arg_idx, bool return arghint; } -static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_function, int p_arg_idx) { +static String _make_arguments_hint(const GDScriptParser::FunctionNode *p_function, int p_arg_idx, bool p_just_args = false) { String arghint; - if (p_function->get_datatype().builtin_type == Variant::NIL) { - arghint = "void " + p_function->identifier->name.operator String() + "("; + if (p_just_args) { + arghint = "("; } else { - arghint = p_function->get_datatype().to_string() + " " + p_function->identifier->name.operator String() + "("; + if (p_function->get_datatype().builtin_type == Variant::NIL) { + arghint = "void " + p_function->identifier->name.operator String() + "("; + } else { + arghint = p_function->get_datatype().to_string() + " " + p_function->identifier->name.operator String() + "("; + } } for (int i = 0; i < p_function->parameters.size(); i++) { @@ -2731,6 +2735,25 @@ static void _find_call_arguments(GDScriptParser::CompletionContext &p_context, c while (base_type.is_set() && !base_type.is_variant()) { switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { + if (base_type.is_meta_type && p_method == SNAME("new")) { + const GDScriptParser::ClassNode *current = base_type.class_type; + + do { + if (current->has_member("_init")) { + const GDScriptParser::ClassNode::Member &member = current->get_member("_init"); + + if (member.type == GDScriptParser::ClassNode::Member::FUNCTION) { + r_arghint = base_type.class_type->get_datatype().to_string() + " new" + _make_arguments_hint(member.function, p_argidx, true); + return; + } + } + current = current->base_type.class_type; + } while (current != nullptr); + + r_arghint = base_type.class_type->get_datatype().to_string() + " new()"; + return; + } + if (base_type.class_type->has_member(p_method)) { const GDScriptParser::ClassNode::Member &member = base_type.class_type->get_member(p_method); @@ -3548,9 +3571,13 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co switch (base_type.kind) { case GDScriptParser::DataType::CLASS: { if (base_type.class_type) { - if (base_type.class_type->has_member(p_symbol)) { + String name = p_symbol; + if (name == "new") { + name = "_init"; + } + if (base_type.class_type->has_member(name)) { r_result.type = ScriptLanguage::LOOKUP_RESULT_SCRIPT_LOCATION; - r_result.location = base_type.class_type->get_member(p_symbol).get_line(); + r_result.location = base_type.class_type->get_member(name).get_line(); r_result.class_path = base_type.script_path; Error err = OK; r_result.script = GDScriptCache::get_shallow_script(r_result.class_path, err); diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index 9a4c92f601..f1a35c84b7 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -166,7 +166,7 @@ void GDScriptParser::push_error(const String &p_message, const Node *p_origin) { panic_mode = true; // TODO: Improve positional information. if (p_origin == nullptr) { - errors.push_back({ p_message, current.start_line, current.start_column }); + errors.push_back({ p_message, previous.start_line, previous.start_column }); } else { errors.push_back({ p_message, p_origin->start_line, p_origin->leftmost_column }); } @@ -4315,39 +4315,55 @@ bool GDScriptParser::export_annotations(const AnnotationNode *p_annotation, Node return false; } break; - case GDScriptParser::DataType::CLASS: + case GDScriptParser::DataType::CLASS: { + StringName class_name; + if (export_type.class_type) { + class_name = export_type.class_type->get_global_name(); + } + if (class_name == StringName()) { + push_error(R"(Script export type must be a global class.)", p_annotation); + return false; + } if (ClassDB::is_parent_class(export_type.native_type, SNAME("Resource"))) { variable->export_info.type = Variant::OBJECT; variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE; - variable->export_info.hint_string = export_type.to_string(); + variable->export_info.hint_string = class_name; } else if (ClassDB::is_parent_class(export_type.native_type, SNAME("Node"))) { variable->export_info.type = Variant::OBJECT; variable->export_info.hint = PROPERTY_HINT_NODE_TYPE; - variable->export_info.hint_string = export_type.to_string(); + variable->export_info.hint_string = class_name; } else { push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", p_annotation); return false; } + } break; - break; case GDScriptParser::DataType::SCRIPT: { StringName class_name; - StringName native_base; if (export_type.script_type.is_valid()) { - class_name = export_type.script_type->get_language()->get_global_class_name(export_type.script_type->get_path()); - native_base = export_type.script_type->get_instance_base_type(); + class_name = export_type.script_type->get_global_name(); } if (class_name == StringName()) { Ref<Script> script = ResourceLoader::load(export_type.script_path, SNAME("Script")); if (script.is_valid()) { - class_name = script->get_language()->get_global_class_name(export_type.script_path); - native_base = script->get_instance_base_type(); + class_name = script->get_global_name(); } } - if (class_name != StringName() && native_base != StringName() && ClassDB::is_parent_class(native_base, SNAME("Resource"))) { + if (class_name == StringName()) { + push_error(R"(Script export type must be a global class.)", p_annotation); + return false; + } + if (ClassDB::is_parent_class(export_type.native_type, SNAME("Resource"))) { variable->export_info.type = Variant::OBJECT; variable->export_info.hint = PROPERTY_HINT_RESOURCE_TYPE; variable->export_info.hint_string = class_name; + } else if (ClassDB::is_parent_class(export_type.native_type, SNAME("Node"))) { + variable->export_info.type = Variant::OBJECT; + variable->export_info.hint = PROPERTY_HINT_NODE_TYPE; + variable->export_info.hint_string = class_name; + } else { + push_error(R"(Export type can only be built-in, a resource, a node, or an enum.)", p_annotation); + return false; } } break; case GDScriptParser::DataType::ENUM: { diff --git a/modules/gdscript/language_server/gdscript_text_document.cpp b/modules/gdscript/language_server/gdscript_text_document.cpp index 9bf458e031..2224bb0040 100644 --- a/modules/gdscript/language_server/gdscript_text_document.cpp +++ b/modules/gdscript/language_server/gdscript_text_document.cpp @@ -490,7 +490,7 @@ void GDScriptTextDocument::sync_script_content(const String &p_path, const Strin } void GDScriptTextDocument::show_native_symbol_in_editor(const String &p_symbol_id) { - ScriptEditor::get_singleton()->call_deferred(SNAME("_help_class_goto"), p_symbol_id); + callable_mp(ScriptEditor::get_singleton(), &ScriptEditor::goto_help).call_deferred(p_symbol_id); DisplayServer::get_singleton()->window_move_to_foreground(); } diff --git a/modules/gdscript/language_server/godot_lsp.h b/modules/gdscript/language_server/godot_lsp.h index 284762018f..13c2693390 100644 --- a/modules/gdscript/language_server/godot_lsp.h +++ b/modules/gdscript/language_server/godot_lsp.h @@ -236,7 +236,7 @@ struct ReferenceContext { /** * Include the declaration of the current symbol. */ - bool includeDeclaration; + bool includeDeclaration = false; }; struct ReferenceParams : TextDocumentPositionParams { diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.gd index 8b343de5ef..483e6cab0d 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.gd +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.gd @@ -1,6 +1,8 @@ +class_name ExportVariableTest extends Node const Utils = preload("../../utils.notest.gd") +const PreloadedScript = preload("./export_variable.notest.gd") # Built-in types. @export var test_weak_int = 1 @@ -20,6 +22,10 @@ const Utils = preload("../../utils.notest.gd") @export var test_image: Image @export var test_timer: Timer +# Global custom classes. +@export var test_global_class: ExportVariableTest +@export var test_preloaded_script: PreloadedScript + # Arrays. @export var test_array: Array @export var test_array_bool: Array[bool] diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.notest.gd b/modules/gdscript/tests/scripts/parser/features/export_variable.notest.gd new file mode 100644 index 0000000000..6d064351c1 --- /dev/null +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.notest.gd @@ -0,0 +1,2 @@ +class_name ExportPreloadedClassTest +extends Node diff --git a/modules/gdscript/tests/scripts/parser/features/export_variable.out b/modules/gdscript/tests/scripts/parser/features/export_variable.out index 99d7b27130..bb094e14b4 100644 --- a/modules/gdscript/tests/scripts/parser/features/export_variable.out +++ b/modules/gdscript/tests/scripts/parser/features/export_variable.out @@ -23,6 +23,10 @@ var test_image: Image = null hint=RESOURCE_TYPE hint_string="Image" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Image" var test_timer: Timer = null hint=NODE_TYPE hint_string="Timer" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"Timer" +var test_global_class: ExportVariableTest = null + hint=NODE_TYPE hint_string="ExportVariableTest" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"ExportVariableTest" +var test_preloaded_script: ExportPreloadedClassTest = null + hint=NODE_TYPE hint_string="ExportPreloadedClassTest" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"ExportPreloadedClassTest" var test_array: Array = [] hint=NONE hint_string="" usage=DEFAULT|SCRIPT_VARIABLE class_name=&"" var test_array_bool: Array = Array[bool]([]) diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd new file mode 100644 index 0000000000..bbdf745540 --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.gd @@ -0,0 +1,26 @@ +# GH-92217 +# TODO: Add more tests. + +static var static_var: int: + set(value): + prints("set static_var", value) + get: + print("get static_var") + return 0 + +var member_var: int: + set(value): + prints("set member_var", value) + get: + print("get member_var") + return 0 + +func test(): + var lambda := func (): + var _tmp := static_var + _tmp = member_var + + static_var = 1 + member_var = 1 + + lambda.call() diff --git a/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out new file mode 100644 index 0000000000..0bdf74a43f --- /dev/null +++ b/modules/gdscript/tests/scripts/runtime/features/lambda_captures.out @@ -0,0 +1,5 @@ +GDTEST_OK +get static_var +get member_var +set static_var 1 +set member_var 1 diff --git a/modules/gdscript/tests/scripts/runtime/features/metatypes.gd b/modules/gdscript/tests/scripts/runtime/features/metatypes.gd index 6c5df32ffe..fd23ea0db5 100644 --- a/modules/gdscript/tests/scripts/runtime/features/metatypes.gd +++ b/modules/gdscript/tests/scripts/runtime/features/metatypes.gd @@ -25,12 +25,24 @@ func test(): if str(property.name).begins_with("test_"): print(Utils.get_property_signature(property)) + print("---") check_gdscript_native_class(test_native) check_gdscript(test_script) check_gdscript(test_class) check_enum(test_enum) + print("---") print(test_native.stringify([])) print(test_script.TEST) print(test_class.TEST) print(test_enum.keys()) + + print("---") + # Some users add unnecessary type hints to `const`-`preload`, which removes metatypes. + # For **constant** `GDScript` we still check the class members, despite the wider type. + const ScriptNoMeta: GDScript = Other + const ClassNoMeta: GDScript = MyClass + var a := ScriptNoMeta.TEST + var b := ClassNoMeta.TEST + print(a) + print(b) diff --git a/modules/gdscript/tests/scripts/runtime/features/metatypes.out b/modules/gdscript/tests/scripts/runtime/features/metatypes.out index 352d1caa59..c42287438c 100644 --- a/modules/gdscript/tests/scripts/runtime/features/metatypes.out +++ b/modules/gdscript/tests/scripts/runtime/features/metatypes.out @@ -3,11 +3,16 @@ var test_native: GDScriptNativeClass var test_script: GDScript var test_class: GDScript var test_enum: Dictionary +--- GDScriptNativeClass GDScript GDScript { "A": 0, "B": 1, "C": 2 } +--- [] 100 10 ["A", "B", "C"] +--- +100 +10 diff --git a/modules/gltf/doc_classes/GLTFAccessor.xml b/modules/gltf/doc_classes/GLTFAccessor.xml index ba7323b7cd..54762faed7 100644 --- a/modules/gltf/doc_classes/GLTFAccessor.xml +++ b/modules/gltf/doc_classes/GLTFAccessor.xml @@ -12,34 +12,50 @@ <link title="Runtime file loading and saving">$DOCS_URL/tutorials/io/runtime_file_loading_and_saving.html</link> </tutorials> <members> + <member name="accessor_type" type="int" setter="set_accessor_type" getter="get_accessor_type" default="0"> + The GLTF accessor type as an enum. Possible values are 0 for "SCALAR", 1 for "VEC2", 2 for "VEC3", 3 for "VEC4", 4 for "MAT2", 5 for "MAT3", and 6 for "MAT4". + </member> <member name="buffer_view" type="int" setter="set_buffer_view" getter="get_buffer_view" default="-1"> The index of the buffer view this accessor is referencing. If [code]-1[/code], this accessor is not referencing any buffer view. </member> <member name="byte_offset" type="int" setter="set_byte_offset" getter="get_byte_offset" default="0"> + The offset relative to the start of the buffer view in bytes. </member> <member name="component_type" type="int" setter="set_component_type" getter="get_component_type" default="0"> + The GLTF component type as an enum. Possible values are 5120 for "BYTE", 5121 for "UNSIGNED_BYTE", 5122 for "SHORT", 5123 for "UNSIGNED_SHORT", 5125 for "UNSIGNED_INT", and 5126 for "FLOAT". A value of 5125 or "UNSIGNED_INT" must not be used for any accessor that is not referenced by mesh.primitive.indices. </member> <member name="count" type="int" setter="set_count" getter="get_count" default="0"> + The number of elements referenced by this accessor. </member> <member name="max" type="PackedFloat64Array" setter="set_max" getter="get_max" default="PackedFloat64Array()"> + Maximum value of each component in this accessor. </member> <member name="min" type="PackedFloat64Array" setter="set_min" getter="get_min" default="PackedFloat64Array()"> + Minimum value of each component in this accessor. </member> <member name="normalized" type="bool" setter="set_normalized" getter="get_normalized" default="false"> + Specifies whether integer data values are normalized before usage. </member> <member name="sparse_count" type="int" setter="set_sparse_count" getter="get_sparse_count" default="0"> + Number of deviating accessor values stored in the sparse array. </member> <member name="sparse_indices_buffer_view" type="int" setter="set_sparse_indices_buffer_view" getter="get_sparse_indices_buffer_view" default="0"> + The index of the buffer view with sparse indices. The referenced buffer view MUST NOT have its target or byteStride properties defined. The buffer view and the optional byteOffset MUST be aligned to the componentType byte length. </member> <member name="sparse_indices_byte_offset" type="int" setter="set_sparse_indices_byte_offset" getter="get_sparse_indices_byte_offset" default="0"> + The offset relative to the start of the buffer view in bytes. </member> <member name="sparse_indices_component_type" type="int" setter="set_sparse_indices_component_type" getter="get_sparse_indices_component_type" default="0"> + The indices component data type as an enum. Possible values are 5121 for "UNSIGNED_BYTE", 5123 for "UNSIGNED_SHORT", and 5125 for "UNSIGNED_INT". </member> <member name="sparse_values_buffer_view" type="int" setter="set_sparse_values_buffer_view" getter="get_sparse_values_buffer_view" default="0"> + The index of the bufferView with sparse values. The referenced buffer view MUST NOT have its target or byteStride properties defined. </member> <member name="sparse_values_byte_offset" type="int" setter="set_sparse_values_byte_offset" getter="get_sparse_values_byte_offset" default="0"> + The offset relative to the start of the bufferView in bytes. </member> - <member name="type" type="int" setter="set_type" getter="get_type" default="0"> + <member name="type" type="int" setter="set_type" getter="get_type" default="0" deprecated="Use [member accessor_type] instead."> + The GLTF accessor type as an enum. Use [member accessor_type] instead. </member> </members> </class> diff --git a/modules/gltf/editor/editor_scene_importer_blend.cpp b/modules/gltf/editor/editor_scene_importer_blend.cpp index ccf347e03e..822e11ea4b 100644 --- a/modules/gltf/editor/editor_scene_importer_blend.cpp +++ b/modules/gltf/editor/editor_scene_importer_blend.cpp @@ -207,6 +207,9 @@ Node *EditorSceneFormatImporterBlend::import_scene(const String &p_path, uint32_ parameters_map["use_renderable"] = false; parameters_map["use_visible"] = false; } + if (p_options.has(SNAME("blender/nodes/active_collection_only")) && p_options[SNAME("blender/nodes/active_collection_only")]) { + parameters_map["use_active_collection"] = true; + } if (p_options.has(SNAME("blender/meshes/uvs")) && p_options[SNAME("blender/meshes/uvs")]) { parameters_map["export_texcoords"] = true; @@ -332,6 +335,7 @@ void EditorSceneFormatImporterBlend::get_import_options(const String &p_path, Li r_options->push_back(ResourceImporter::ImportOption(PropertyInfo(Variant::INT, SNAME(PATH), PROPERTY_HINT_ENUM, ENUM_HINT), VALUE)); ADD_OPTION_ENUM("blender/nodes/visible", "All,Visible Only,Renderable", BLEND_VISIBLE_ALL); + ADD_OPTION_BOOL("blender/nodes/active_collection_only", false); ADD_OPTION_BOOL("blender/nodes/punctual_lights", true); ADD_OPTION_BOOL("blender/nodes/cameras", true); ADD_OPTION_BOOL("blender/nodes/custom_properties", true); diff --git a/modules/gltf/gltf_defines.h b/modules/gltf/gltf_defines.h index d044105b42..c1918e5908 100644 --- a/modules/gltf/gltf_defines.h +++ b/modules/gltf/gltf_defines.h @@ -66,14 +66,4 @@ using GLTFSkinIndex = int; using GLTFTextureIndex = int; using GLTFTextureSamplerIndex = int; -enum GLTFType { - TYPE_SCALAR, - TYPE_VEC2, - TYPE_VEC3, - TYPE_VEC4, - TYPE_MAT2, - TYPE_MAT3, - TYPE_MAT4, -}; - #endif // GLTF_DEFINES_H diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 5dcf67b768..32fe37d9af 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -886,7 +886,7 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> p_state) { Ref<GLTFAccessor> accessor = p_state->accessors[i]; d["componentType"] = accessor->component_type; d["count"] = accessor->count; - d["type"] = _get_accessor_type_name(accessor->type); + d["type"] = _get_accessor_type_name(accessor->accessor_type); d["normalized"] = accessor->normalized; d["max"] = accessor->max; d["min"] = accessor->min; @@ -934,58 +934,58 @@ Error GLTFDocument::_encode_accessors(Ref<GLTFState> p_state) { return OK; } -String GLTFDocument::_get_accessor_type_name(const GLTFType p_type) { - if (p_type == GLTFType::TYPE_SCALAR) { +String GLTFDocument::_get_accessor_type_name(const GLTFAccessorType p_accessor_type) { + if (p_accessor_type == GLTFAccessorType::TYPE_SCALAR) { return "SCALAR"; } - if (p_type == GLTFType::TYPE_VEC2) { + if (p_accessor_type == GLTFAccessorType::TYPE_VEC2) { return "VEC2"; } - if (p_type == GLTFType::TYPE_VEC3) { + if (p_accessor_type == GLTFAccessorType::TYPE_VEC3) { return "VEC3"; } - if (p_type == GLTFType::TYPE_VEC4) { + if (p_accessor_type == GLTFAccessorType::TYPE_VEC4) { return "VEC4"; } - if (p_type == GLTFType::TYPE_MAT2) { + if (p_accessor_type == GLTFAccessorType::TYPE_MAT2) { return "MAT2"; } - if (p_type == GLTFType::TYPE_MAT3) { + if (p_accessor_type == GLTFAccessorType::TYPE_MAT3) { return "MAT3"; } - if (p_type == GLTFType::TYPE_MAT4) { + if (p_accessor_type == GLTFAccessorType::TYPE_MAT4) { return "MAT4"; } ERR_FAIL_V("SCALAR"); } -GLTFType GLTFDocument::_get_type_from_str(const String &p_string) { +GLTFAccessorType GLTFDocument::_get_accessor_type_from_str(const String &p_string) { if (p_string == "SCALAR") { - return GLTFType::TYPE_SCALAR; + return GLTFAccessorType::TYPE_SCALAR; } if (p_string == "VEC2") { - return GLTFType::TYPE_VEC2; + return GLTFAccessorType::TYPE_VEC2; } if (p_string == "VEC3") { - return GLTFType::TYPE_VEC3; + return GLTFAccessorType::TYPE_VEC3; } if (p_string == "VEC4") { - return GLTFType::TYPE_VEC4; + return GLTFAccessorType::TYPE_VEC4; } if (p_string == "MAT2") { - return GLTFType::TYPE_MAT2; + return GLTFAccessorType::TYPE_MAT2; } if (p_string == "MAT3") { - return GLTFType::TYPE_MAT3; + return GLTFAccessorType::TYPE_MAT3; } if (p_string == "MAT4") { - return GLTFType::TYPE_MAT4; + return GLTFAccessorType::TYPE_MAT4; } - ERR_FAIL_V(GLTFType::TYPE_SCALAR); + ERR_FAIL_V(GLTFAccessorType::TYPE_SCALAR); } Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) { @@ -1004,7 +1004,7 @@ Error GLTFDocument::_parse_accessors(Ref<GLTFState> p_state) { ERR_FAIL_COND_V(!d.has("count"), ERR_PARSE_ERROR); accessor->count = d["count"]; ERR_FAIL_COND_V(!d.has("type"), ERR_PARSE_ERROR); - accessor->type = _get_type_from_str(d["type"]); + accessor->accessor_type = _get_accessor_type_from_str(d["type"]); if (d.has("bufferView")) { accessor->buffer_view = d["bufferView"]; //optional because it may be sparse... @@ -1088,26 +1088,12 @@ String GLTFDocument::_get_component_type_name(const uint32_t p_component) { return "<Error>"; } -String GLTFDocument::_get_type_name(const GLTFType p_component) { - static const char *names[] = { - "float", - "vec2", - "vec3", - "vec4", - "mat2", - "mat3", - "mat4" - }; - - return names[p_component]; -} - -Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFType p_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { +Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, const int p_count, const GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_vertex_indices) { const int component_count_for_type[7] = { 1, 2, 3, 4, 4, 9, 16 }; - const int component_count = component_count_for_type[p_type]; + const int component_count = component_count_for_type[p_accessor_type]; const int component_size = _get_component_type_size(p_component_type); ERR_FAIL_COND_V(component_size == 0, FAILED); @@ -1117,18 +1103,18 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ switch (p_component_type) { case COMPONENT_TYPE_BYTE: case COMPONENT_TYPE_UNSIGNED_BYTE: { - if (p_type == TYPE_MAT2) { + if (p_accessor_type == TYPE_MAT2) { skip_every = 2; skip_bytes = 2; } - if (p_type == TYPE_MAT3) { + if (p_accessor_type == TYPE_MAT3) { skip_every = 3; skip_bytes = 1; } } break; case COMPONENT_TYPE_SHORT: case COMPONENT_TYPE_UNSIGNED_SHORT: { - if (p_type == TYPE_MAT3) { + if (p_accessor_type == TYPE_MAT3) { skip_every = 6; skip_bytes = 4; } @@ -1147,7 +1133,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ stride += 4 - (stride % 4); //according to spec must be multiple of 4 } //use to debug - print_verbose("glTF: encoding type " + _get_type_name(p_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count)); + print_verbose("glTF: encoding accessor type " + _get_accessor_type_name(p_accessor_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count)); print_verbose("glTF: encoding accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(gltf_buffer.size()) + " view len " + itos(bv->byte_length)); @@ -1310,7 +1296,7 @@ Error GLTFDocument::_encode_buffer_view(Ref<GLTFState> p_state, const double *p_ return OK; } -Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFType p_type, const int p_component_count, const int p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) { +Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, const GLTFAccessorType p_accessor_type, const int p_component_count, const int p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex) { const Ref<GLTFBufferView> bv = p_state->buffer_views[p_buffer_view]; int stride = p_element_size; @@ -1328,7 +1314,7 @@ Error GLTFDocument::_decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, c const uint8_t *bufptr = buffer.ptr(); //use to debug - print_verbose("glTF: type " + _get_type_name(p_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count)); + print_verbose("glTF: accessor type " + _get_accessor_type_name(p_accessor_type) + " component type: " + _get_component_type_name(p_component_type) + " stride: " + itos(stride) + " amount " + itos(p_count)); print_verbose("glTF: accessor offset " + itos(p_byte_offset) + " view offset: " + itos(bv->byte_offset) + " total buffer len: " + itos(buffer.size()) + " view len " + itos(bv->byte_length)); const int buffer_end = (stride * (p_count - 1)) + p_element_size; @@ -1430,7 +1416,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF 1, 2, 3, 4, 4, 9, 16 }; - const int component_count = component_count_for_type[a->type]; + const int component_count = component_count_for_type[a->accessor_type]; const int component_size = _get_component_type_size(a->component_type); ERR_FAIL_COND_V(component_size == 0, Vector<double>()); int element_size = component_count * component_size; @@ -1441,12 +1427,12 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF switch (a->component_type) { case COMPONENT_TYPE_BYTE: case COMPONENT_TYPE_UNSIGNED_BYTE: { - if (a->type == TYPE_MAT2) { + if (a->accessor_type == TYPE_MAT2) { skip_every = 2; skip_bytes = 2; element_size = 8; //override for this case } - if (a->type == TYPE_MAT3) { + if (a->accessor_type == TYPE_MAT3) { skip_every = 3; skip_bytes = 1; element_size = 12; //override for this case @@ -1454,7 +1440,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF } break; case COMPONENT_TYPE_SHORT: case COMPONENT_TYPE_UNSIGNED_SHORT: { - if (a->type == TYPE_MAT3) { + if (a->accessor_type == TYPE_MAT3) { skip_every = 6; skip_bytes = 4; element_size = 16; //override for this case @@ -1471,7 +1457,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF if (a->buffer_view >= 0) { ERR_FAIL_INDEX_V(a->buffer_view, p_state->buffer_views.size(), Vector<double>()); - const Error err = _decode_buffer_view(p_state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex); + const Error err = _decode_buffer_view(p_state, dst, a->buffer_view, skip_every, skip_bytes, element_size, a->count, a->accessor_type, component_count, a->component_type, component_size, a->normalized, a->byte_offset, p_for_vertex); if (err != OK) { return Vector<double>(); } @@ -1495,7 +1481,7 @@ Vector<double> GLTFDocument::_decode_accessor(Ref<GLTFState> p_state, const GLTF Vector<double> data; data.resize(component_count * a->sparse_count); - err = _decode_buffer_view(p_state, data.ptrw(), a->sparse_values_buffer_view, skip_every, skip_bytes, element_size, a->sparse_count, a->type, component_count, a->component_type, component_size, a->normalized, a->sparse_values_byte_offset, p_for_vertex); + err = _decode_buffer_view(p_state, data.ptrw(), a->sparse_values_buffer_view, skip_every, skip_bytes, element_size, a->sparse_count, a->accessor_type, component_count, a->component_type, component_size, a->normalized, a->sparse_values_byte_offset, p_for_vertex); if (err != OK) { return Vector<double>(); } @@ -1550,7 +1536,7 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_SCALAR; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR; int component_type; if (max_index > 65535 || p_for_vertex) { component_type = GLTFDocument::COMPONENT_TYPE_INT; @@ -1562,10 +1548,10 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_ints(Ref<GLTFState> p_state, accessor->min = type_min; accessor->normalized = false; accessor->count = ret_size; - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i, p_for_vertex_indices); + Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i, p_for_vertex_indices); if (err != OK) { return -1; } @@ -1664,17 +1650,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec2(Ref<GLTFState> p_state, p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC2; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC2; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1717,17 +1703,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_color(Ref<GLTFState> p_state p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC4; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1784,17 +1770,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_weights(Ref<GLTFState> p_sta p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC4; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1835,17 +1821,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_joints(Ref<GLTFState> p_stat p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC4; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1888,17 +1874,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_quaternions(Ref<GLTFState> p p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC4; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -1963,17 +1949,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_floats(Ref<GLTFState> p_stat p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_SCALAR; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = ret_size; - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2013,17 +1999,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_vec3(Ref<GLTFState> p_state, p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC3; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2089,12 +2075,12 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_VEC3; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_VEC3; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; sparse_accessor->normalized = false; sparse_accessor->count = p_attribs.size(); - sparse_accessor->type = type; + sparse_accessor->accessor_type = accessor_type; sparse_accessor->component_type = component_type; if (p_reference_accessor < p_state->accessors.size() && p_reference_accessor >= 0 && p_state->accessors[p_reference_accessor].is_valid()) { sparse_accessor->byte_offset = p_state->accessors[p_reference_accessor]->byte_offset; @@ -2117,11 +2103,11 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p } else { sparse_accessor->sparse_indices_component_type = GLTFDocument::COMPONENT_TYPE_UNSIGNED_SHORT; } - if (_encode_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFType::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) { + if (_encode_buffer_view(p_state, changed_indices.ptr(), changed_indices.size(), GLTFAccessorType::TYPE_SCALAR, sparse_accessor->sparse_indices_component_type, sparse_accessor->normalized, sparse_accessor->sparse_indices_byte_offset, false, buffer_view_i_indices) != OK) { return -1; } // We use changed_indices.size() here, because we must pass the number of vec3 values rather than the number of components. - if (_encode_buffer_view(p_state, changed_values.ptr(), changed_indices.size(), sparse_accessor->type, sparse_accessor->component_type, sparse_accessor->normalized, sparse_accessor->sparse_values_byte_offset, false, buffer_view_i_values) != OK) { + if (_encode_buffer_view(p_state, changed_values.ptr(), changed_indices.size(), sparse_accessor->accessor_type, sparse_accessor->component_type, sparse_accessor->normalized, sparse_accessor->sparse_values_byte_offset, false, buffer_view_i_values) != OK) { return -1; } sparse_accessor->sparse_indices_buffer_view = buffer_view_i_indices; @@ -2130,7 +2116,7 @@ GLTFAccessorIndex GLTFDocument::_encode_sparse_accessor_as_vec3(Ref<GLTFState> p } else if (changed_indices.size() > 0) { GLTFBufferIndex buffer_view_i; sparse_accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, sparse_accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, sparse_accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2194,17 +2180,17 @@ GLTFAccessorIndex GLTFDocument::_encode_accessor_as_xform(Ref<GLTFState> p_state p_state->buffers.push_back(Vector<uint8_t>()); } int64_t size = p_state->buffers[0].size(); - const GLTFType type = GLTFType::TYPE_MAT4; + const GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_MAT4; const int component_type = GLTFDocument::COMPONENT_TYPE_FLOAT; accessor->max = type_max; accessor->min = type_min; accessor->normalized = false; accessor->count = p_attribs.size(); - accessor->type = type; + accessor->accessor_type = accessor_type; accessor->component_type = component_type; accessor->byte_offset = 0; - Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); + Error err = _encode_buffer_view(p_state, attribs.ptr(), p_attribs.size(), accessor_type, component_type, accessor->normalized, size, p_for_vertex, buffer_view_i); if (err != OK) { return -1; } @@ -2247,10 +2233,10 @@ Vector<Color> GLTFDocument::_decode_accessor_as_color(Ref<GLTFState> p_state, co return ret; } - const int type = p_state->accessors[p_accessor]->type; - ERR_FAIL_COND_V(!(type == TYPE_VEC3 || type == TYPE_VEC4), ret); + const int accessor_type = p_state->accessors[p_accessor]->accessor_type; + ERR_FAIL_COND_V(!(accessor_type == TYPE_VEC3 || accessor_type == TYPE_VEC4), ret); int vec_len = 3; - if (type == TYPE_VEC4) { + if (accessor_type == TYPE_VEC4) { vec_len = 4; } @@ -5133,7 +5119,11 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshIn ERR_FAIL_COND_V_MSG(p_mesh_instance->get_mesh().is_null(), -1, "glTF: Tried to export a MeshInstance3D node named " + p_mesh_instance->get_name() + ", but it has no mesh. This node will be exported without a mesh."); Ref<Mesh> mesh_resource = p_mesh_instance->get_mesh(); ERR_FAIL_COND_V_MSG(mesh_resource->get_surface_count() == 0, -1, "glTF: Tried to export a MeshInstance3D node named " + p_mesh_instance->get_name() + ", but its mesh has no surfaces. This node will be exported without a mesh."); - + TypedArray<Material> instance_materials; + for (int32_t surface_i = 0; surface_i < mesh_resource->get_surface_count(); surface_i++) { + Ref<Material> mat = p_mesh_instance->get_active_material(surface_i); + instance_materials.append(mat); + } Ref<ImporterMesh> current_mesh = _mesh_to_importer_mesh(mesh_resource); Vector<float> blend_weights; int32_t blend_count = mesh_resource->get_blend_shape_count(); @@ -5144,17 +5134,6 @@ GLTFMeshIndex GLTFDocument::_convert_mesh_to_gltf(Ref<GLTFState> p_state, MeshIn Ref<GLTFMesh> gltf_mesh; gltf_mesh.instantiate(); - TypedArray<Material> instance_materials; - for (int32_t surface_i = 0; surface_i < current_mesh->get_surface_count(); surface_i++) { - Ref<Material> mat = current_mesh->get_surface_material(surface_i); - if (p_mesh_instance->get_surface_override_material(surface_i).is_valid()) { - mat = p_mesh_instance->get_surface_override_material(surface_i); - } - if (p_mesh_instance->get_material_override().is_valid()) { - mat = p_mesh_instance->get_material_override(); - } - instance_materials.append(mat); - } gltf_mesh->set_instance_materials(instance_materials); gltf_mesh->set_mesh(current_mesh); gltf_mesh->set_blend_weights(blend_weights); @@ -5323,11 +5302,22 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd Ref<ImporterMesh> mesh; mesh.instantiate(); { - Ref<Mesh> csg_mesh = csg->get_meshes()[1]; - + Ref<ArrayMesh> csg_mesh = csg->get_meshes()[1]; for (int32_t surface_i = 0; surface_i < csg_mesh->get_surface_count(); surface_i++) { Array array = csg_mesh->surface_get_arrays(surface_i); - Ref<Material> mat = csg_mesh->surface_get_material(surface_i); + + Ref<Material> mat; + + Ref<Material> mat_override = csg->get_material_override(); + if (mat_override.is_valid()) { + mat = mat_override; + } + + Ref<Material> mat_surface_override = csg_mesh->surface_get_material(surface_i); + if (mat_surface_override.is_valid() && mat.is_null()) { + mat = mat_surface_override; + } + String mat_name; if (mat.is_valid()) { mat_name = mat->get_name(); @@ -5335,6 +5325,7 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd // Assign default material when no material is assigned. mat = Ref<StandardMaterial3D>(memnew(StandardMaterial3D)); } + mesh->add_surface(csg_mesh->surface_get_primitive_type(surface_i), array, csg_mesh->surface_get_blend_shape_arrays(surface_i), csg_mesh->surface_get_lods(surface_i), mat, mat_name, csg_mesh->surface_get_format(surface_i)); @@ -5348,7 +5339,7 @@ void GLTFDocument::_convert_csg_shape_to_gltf(CSGShape3D *p_current, GLTFNodeInd GLTFMeshIndex mesh_i = p_state->meshes.size(); p_state->meshes.push_back(gltf_mesh); p_gltf_node->mesh = mesh_i; - p_gltf_node->transform = csg->get_meshes()[0]; + p_gltf_node->transform = csg->get_transform(); p_gltf_node->set_original_name(csg->get_name()); p_gltf_node->set_name(_gen_unique_name(p_state, csg->get_name())); } @@ -6337,6 +6328,7 @@ void GLTFDocument::_process_mesh_instances(Ref<GLTFState> p_state, Node *p_scene ERR_CONTINUE_MSG(skeleton == nullptr, vformat("Unable to find Skeleton for node %d skin %d", node_i, skin_i)); mi->get_parent()->remove_child(mi); + mi->set_owner(nullptr); skeleton->add_child(mi, true); mi->set_owner(p_scene_root); diff --git a/modules/gltf/gltf_document.h b/modules/gltf/gltf_document.h index 5eb9d90811..4f92ceccca 100644 --- a/modules/gltf/gltf_document.h +++ b/modules/gltf/gltf_document.h @@ -111,8 +111,7 @@ private: int _get_component_type_size(const int p_component_type); Error _parse_scenes(Ref<GLTFState> p_state); Error _parse_nodes(Ref<GLTFState> p_state); - String _get_type_name(const GLTFType p_component); - String _get_accessor_type_name(const GLTFType p_type); + String _get_accessor_type_name(const GLTFAccessorType p_accessor_type); String _sanitize_animation_name(const String &p_name); String _gen_unique_animation_name(Ref<GLTFState> p_state, const String &p_name); String _sanitize_bone_name(const String &p_name); @@ -132,13 +131,13 @@ private: void _compute_node_heights(Ref<GLTFState> p_state); Error _parse_buffers(Ref<GLTFState> p_state, const String &p_base_path); Error _parse_buffer_views(Ref<GLTFState> p_state); - GLTFType _get_type_from_str(const String &p_string); + GLTFAccessorType _get_accessor_type_from_str(const String &p_string); Error _parse_accessors(Ref<GLTFState> p_state); Error _decode_buffer_view(Ref<GLTFState> p_state, double *p_dst, const GLTFBufferViewIndex p_buffer_view, const int p_skip_every, const int p_skip_bytes, const int p_element_size, const int p_count, - const GLTFType p_type, const int p_component_count, + const GLTFAccessorType p_accessor_type, const int p_component_count, const int p_component_type, const int p_component_size, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex); @@ -267,7 +266,7 @@ private: const Vector<Transform3D> p_attribs, const bool p_for_vertex); Error _encode_buffer_view(Ref<GLTFState> p_state, const double *p_src, - const int p_count, const GLTFType p_type, + const int p_count, const GLTFAccessorType p_accessor_type, const int p_component_type, const bool p_normalized, const int p_byte_offset, const bool p_for_vertex, GLTFBufferViewIndex &r_accessor, const bool p_for_indices = false); diff --git a/modules/gltf/structures/gltf_accessor.cpp b/modules/gltf/structures/gltf_accessor.cpp index 2119a0ee82..602f0d9dc4 100644 --- a/modules/gltf/structures/gltf_accessor.cpp +++ b/modules/gltf/structures/gltf_accessor.cpp @@ -41,8 +41,10 @@ void GLTFAccessor::_bind_methods() { ClassDB::bind_method(D_METHOD("set_normalized", "normalized"), &GLTFAccessor::set_normalized); ClassDB::bind_method(D_METHOD("get_count"), &GLTFAccessor::get_count); ClassDB::bind_method(D_METHOD("set_count", "count"), &GLTFAccessor::set_count); - ClassDB::bind_method(D_METHOD("get_type"), &GLTFAccessor::get_type); - ClassDB::bind_method(D_METHOD("set_type", "type"), &GLTFAccessor::set_type); + ClassDB::bind_method(D_METHOD("get_accessor_type"), &GLTFAccessor::get_accessor_type); + ClassDB::bind_method(D_METHOD("set_accessor_type", "accessor_type"), &GLTFAccessor::set_accessor_type); + ClassDB::bind_method(D_METHOD("get_type"), &GLTFAccessor::get_accessor_type); + ClassDB::bind_method(D_METHOD("set_type", "type"), &GLTFAccessor::set_accessor_type); ClassDB::bind_method(D_METHOD("get_min"), &GLTFAccessor::get_min); ClassDB::bind_method(D_METHOD("set_min", "min"), &GLTFAccessor::set_min); ClassDB::bind_method(D_METHOD("get_max"), &GLTFAccessor::get_max); @@ -65,7 +67,8 @@ void GLTFAccessor::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "component_type"), "set_component_type", "get_component_type"); // int ADD_PROPERTY(PropertyInfo(Variant::BOOL, "normalized"), "set_normalized", "get_normalized"); // bool ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count"); // int - ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // GLTFType + ADD_PROPERTY(PropertyInfo(Variant::INT, "accessor_type"), "set_accessor_type", "get_accessor_type"); // GLTFAccessorType + ADD_PROPERTY(PropertyInfo(Variant::INT, "type"), "set_type", "get_type"); // Deprecated, GLTFAccessorType ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "min"), "set_min", "get_min"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::PACKED_FLOAT64_ARRAY, "max"), "set_max", "get_max"); // Vector<real_t> ADD_PROPERTY(PropertyInfo(Variant::INT, "sparse_count"), "set_sparse_count", "get_sparse_count"); // int @@ -116,12 +119,12 @@ void GLTFAccessor::set_count(int p_count) { count = p_count; } -int GLTFAccessor::get_type() { - return (int)type; +int GLTFAccessor::get_accessor_type() { + return (int)accessor_type; } -void GLTFAccessor::set_type(int p_type) { - type = (GLTFType)p_type; // TODO: Register enum +void GLTFAccessor::set_accessor_type(int p_accessor_type) { + accessor_type = (GLTFAccessorType)p_accessor_type; // TODO: Register enum } Vector<double> GLTFAccessor::get_min() { diff --git a/modules/gltf/structures/gltf_accessor.h b/modules/gltf/structures/gltf_accessor.h index 6b1734601a..51ca282630 100644 --- a/modules/gltf/structures/gltf_accessor.h +++ b/modules/gltf/structures/gltf_accessor.h @@ -35,6 +35,16 @@ #include "core/io/resource.h" +enum GLTFAccessorType { + TYPE_SCALAR, + TYPE_VEC2, + TYPE_VEC3, + TYPE_VEC4, + TYPE_MAT2, + TYPE_MAT3, + TYPE_MAT4, +}; + struct GLTFAccessor : public Resource { GDCLASS(GLTFAccessor, Resource); friend class GLTFDocument; @@ -45,7 +55,7 @@ private: int component_type = 0; bool normalized = false; int count = 0; - GLTFType type = GLTFType::TYPE_SCALAR; + GLTFAccessorType accessor_type = GLTFAccessorType::TYPE_SCALAR; Vector<double> min; Vector<double> max; int sparse_count = 0; @@ -74,8 +84,8 @@ public: int get_count(); void set_count(int p_count); - int get_type(); - void set_type(int p_type); + int get_accessor_type(); + void set_accessor_type(int p_accessor_type); Vector<double> get_min(); void set_min(Vector<double> p_min); diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 27c74421db..226cb48eb8 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -1275,7 +1275,7 @@ GridMapEditor::GridMapEditor() { settings_pick_distance->set_value(EDITOR_GET("editors/grid_map/pick_distance")); settings_vbc->add_margin_child(TTR("Pick Distance:"), settings_pick_distance); - options->get_popup()->connect("id_pressed", callable_mp(this, &GridMapEditor::_menu_option)); + options->get_popup()->connect(SceneStringName(id_pressed), callable_mp(this, &GridMapEditor::_menu_option)); HBoxContainer *hb = memnew(HBoxContainer); add_child(hb); diff --git a/modules/interactive_music/doc_classes/AudioStreamPlaylist.xml b/modules/interactive_music/doc_classes/AudioStreamPlaylist.xml index 1d429a932f..eb7e1806db 100644 --- a/modules/interactive_music/doc_classes/AudioStreamPlaylist.xml +++ b/modules/interactive_music/doc_classes/AudioStreamPlaylist.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8" ?> <class name="AudioStreamPlaylist" inherits="AudioStream" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../doc/class.xsd"> <brief_description> - [AudioStream] that includes sub-streams and plays them back like a playslit. + [AudioStream] that includes sub-streams and plays them back like a playlist. </brief_description> <description> </description> @@ -11,14 +11,14 @@ <method name="get_bpm" qualifiers="const"> <return type="float" /> <description> - Return the bpm of the playlist, which can vary depending on the clip being played. + Returns the BPM of the playlist, which can vary depending on the clip being played. </description> </method> <method name="get_list_stream" qualifiers="const"> <return type="AudioStream" /> <param index="0" name="stream_index" type="int" /> <description> - Get the stream at playback position index. + Returns the stream at playback position index. </description> </method> <method name="set_list_stream"> @@ -26,7 +26,7 @@ <param index="0" name="stream_index" type="int" /> <param index="1" name="audio_stream" type="AudioStream" /> <description> - Set the stream at playback position index. + Sets the stream at playback position index. </description> </method> </methods> @@ -35,10 +35,10 @@ Fade time used when a stream ends, when going to the next one. Streams are expected to have an extra bit of audio after the end to help with fading. </member> <member name="loop" type="bool" setter="set_loop" getter="has_loop" default="true"> - If true, the playlist will loop, otherwise the playlist when end when the last stream is played. + If [code]true[/code], the playlist will loop, otherwise the playlist will end when the last stream is finished. </member> <member name="shuffle" type="bool" setter="set_shuffle" getter="get_shuffle" default="false"> - Shuffle the playlist. Streams are played in random order. + If [code]true[/code], the playlist will shuffle each time playback starts and each time it loops. </member> <member name="stream_count" type="int" setter="set_stream_count" getter="get_stream_count" default="0"> Amount of streams in the playlist. diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs index eef26cdd4e..5cc2a8026e 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.cs @@ -427,10 +427,11 @@ namespace Godot.Bridge // This method may be called before initialization. if (NativeFuncs.godotsharp_dotnet_module_is_initialized().ToBool() && Engine.IsEditorHint()) { - foreach (var scriptPath in _pathTypeBiMap.Paths) + if (_pathTypeBiMap.Paths.Count > 0) { - using godot_string nativeScriptPath = Marshaling.ConvertStringToNative(scriptPath); - NativeFuncs.godotsharp_internal_editor_file_system_update_file(nativeScriptPath); + string[] scriptPaths = _pathTypeBiMap.Paths.ToArray(); + using godot_packed_string_array scriptPathsNative = Marshaling.ConvertSystemArrayToNativePackedStringArray(scriptPaths); + NativeFuncs.godotsharp_internal_editor_file_system_update_files(scriptPathsNative); } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.types.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.types.cs index 1ec1a75516..29fa13d625 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.types.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Bridge/ScriptManagerBridge.types.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -64,7 +65,7 @@ public static partial class ScriptManagerBridge private System.Collections.Generic.Dictionary<string, Type> _pathTypeMap = new(); private System.Collections.Generic.Dictionary<Type, string> _typePathMap = new(); - public System.Collections.Generic.IEnumerable<string> Paths => _pathTypeMap.Keys; + public IReadOnlyCollection<string> Paths => _pathTypeMap.Keys; public void Add(string scriptPath, Type scriptType) { diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs index 04b6c2e743..6b5d7fed78 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/ExceptionUtils.cs @@ -143,7 +143,7 @@ namespace Godot.NativeInterop if (error.Error != godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_OK) { using godot_variant instanceVariant = VariantUtils.CreateFromGodotObjectPtr(instance); - string where = GetCallErrorWhere(method, &instanceVariant, args, argCount); + string where = GetCallErrorWhere(ref error, method, &instanceVariant, args, argCount); string errorText = GetCallErrorMessage(error, where, args); GD.PushError(errorText); } @@ -161,7 +161,7 @@ namespace Godot.NativeInterop } } - private unsafe static string GetCallErrorWhere(godot_string_name method, godot_variant* instance, godot_variant** args, int argCount) + private unsafe static string GetCallErrorWhere(ref godot_variant_call_error error, godot_string_name method, godot_variant* instance, godot_variant** args, int argCount) { string? methodstr = null; string basestr = GetVariantTypeName(instance); @@ -171,6 +171,10 @@ namespace Godot.NativeInterop if (argCount >= 1) { methodstr = VariantUtils.ConvertToString(*args[0]); + if (error.Error == godot_variant_call_error_error.GODOT_CALL_ERROR_CALL_ERROR_INVALID_ARGUMENT) + { + error.Argument += 1; + } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs index c4fd639cce..cfd9ed7acc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/NativeInterop/NativeFuncs.cs @@ -59,7 +59,7 @@ namespace Godot.NativeInterop internal static partial void godotsharp_stack_info_vector_destroy( ref DebuggingUtils.godot_stack_info_vector p_stack_info_vector); - internal static partial void godotsharp_internal_editor_file_system_update_file(in godot_string p_script_path); + internal static partial void godotsharp_internal_editor_file_system_update_files(in godot_packed_string_array p_script_paths); internal static partial void godotsharp_internal_script_debugger_send_error(in godot_string p_func, in godot_string p_file, int p_line, in godot_string p_err, in godot_string p_descr, diff --git a/modules/mono/glue/runtime_interop.cpp b/modules/mono/glue/runtime_interop.cpp index 1af462dafd..80e9fdf77f 100644 --- a/modules/mono/glue/runtime_interop.cpp +++ b/modules/mono/glue/runtime_interop.cpp @@ -315,13 +315,13 @@ void godotsharp_internal_new_csharp_script(Ref<CSharpScript> *r_dest) { memnew_placement(r_dest, Ref<CSharpScript>(memnew(CSharpScript))); } -void godotsharp_internal_editor_file_system_update_file(const String *p_script_path) { +void godotsharp_internal_editor_file_system_update_files(const PackedStringArray &p_script_paths) { #ifdef TOOLS_ENABLED // If the EditorFileSystem singleton is available, update the file; // otherwise, the file will be updated when the singleton becomes available. EditorFileSystem *efs = EditorFileSystem::get_singleton(); if (efs) { - efs->update_file(*p_script_path); + efs->update_files(p_script_paths); } #else // EditorFileSystem is only available when running in the Godot editor. @@ -1450,7 +1450,7 @@ static const void *unmanaged_callbacks[]{ (void *)godotsharp_engine_get_singleton, (void *)godotsharp_stack_info_vector_resize, (void *)godotsharp_stack_info_vector_destroy, - (void *)godotsharp_internal_editor_file_system_update_file, + (void *)godotsharp_internal_editor_file_system_update_files, (void *)godotsharp_internal_script_debugger_send_error, (void *)godotsharp_internal_script_debugger_is_active, (void *)godotsharp_internal_object_get_associated_gchandle, diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp index 3cc0a5ae53..b28572cf72 100644 --- a/modules/multiplayer/editor/replication_editor.cpp +++ b/modules/multiplayer/editor/replication_editor.cpp @@ -372,7 +372,7 @@ void ReplicationEditor::_notification(int p_what) { [[fallthrough]]; } case NOTIFICATION_ENTER_TREE: { - add_theme_style_override("panel", EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("panel"), SNAME("Panel"))); + add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SceneStringName(panel), SNAME("Panel"))); add_pick_button->set_icon(get_theme_icon(SNAME("Add"), EditorStringName(EditorIcons))); pin->set_icon(get_theme_icon(SNAME("Pin"), EditorStringName(EditorIcons))); } break; diff --git a/modules/multiplayer/scene_cache_interface.cpp b/modules/multiplayer/scene_cache_interface.cpp index 2ea9ce8819..af43123b29 100644 --- a/modules/multiplayer/scene_cache_interface.cpp +++ b/modules/multiplayer/scene_cache_interface.cpp @@ -76,7 +76,7 @@ void SceneCacheInterface::on_peer_change(int p_id, bool p_connected) { for (KeyValue<int, ObjectID> E : pinfo->recv_nodes) { NodeCache *nc = nodes_cache.getptr(E.value); ERR_CONTINUE(!nc); - nc->recv_ids.erase(E.key); + nc->recv_ids.erase(p_id); } for (const ObjectID &oid : pinfo->sent_nodes) { NodeCache *nc = nodes_cache.getptr(oid); diff --git a/modules/navigation/2d/nav_mesh_generator_2d.cpp b/modules/navigation/2d/nav_mesh_generator_2d.cpp index 2198158f9c..ace361a08a 100644 --- a/modules/navigation/2d/nav_mesh_generator_2d.cpp +++ b/modules/navigation/2d/nav_mesh_generator_2d.cpp @@ -263,7 +263,7 @@ void NavMeshGenerator2D::generator_parse_geometry_node(Ref<NavigationPolygon> p_ // Special case for TileMap, so that internal layer get parsed even if p_recurse_children is false. for (int i = 0; i < p_node->get_child_count(); i++) { TileMapLayer *tile_map_layer = Object::cast_to<TileMapLayer>(p_node->get_child(i)); - if (tile_map_layer->get_index_in_tile_map() >= 0) { + if (tile_map_layer && tile_map_layer->get_index_in_tile_map() >= 0) { generator_parse_tile_map_layer_node(p_navigation_mesh, p_source_geometry_data, tile_map_layer); } } diff --git a/modules/navigation/nav_map.cpp b/modules/navigation/nav_map.cpp index dfbc92a919..1779be2cc2 100644 --- a/modules/navigation/nav_map.cpp +++ b/modules/navigation/nav_map.cpp @@ -617,7 +617,7 @@ Vector3 NavMap::get_closest_point_to_segment(const Vector3 &p_from, const Vector const Face3 f(p.points[0].pos, p.points[point_id - 1].pos, p.points[point_id].pos); Vector3 inters; if (f.intersects_segment(p_from, p_to, &inters)) { - const real_t d = closest_point_d = p_from.distance_to(inters); + const real_t d = p_from.distance_to(inters); if (use_collision == false) { closest_point = inters; use_collision = true; diff --git a/modules/openxr/action_map/openxr_interaction_profile_metadata.cpp b/modules/openxr/action_map/openxr_interaction_profile_metadata.cpp index 75cfb095bb..6315c95a03 100644 --- a/modules/openxr/action_map/openxr_interaction_profile_metadata.cpp +++ b/modules/openxr/action_map/openxr_interaction_profile_metadata.cpp @@ -225,21 +225,6 @@ void OpenXRInteractionProfileMetadata::_register_core_metadata() { register_top_level_path("Gamepad", "/user/gamepad", ""); register_top_level_path("Treadmill", "/user/treadmill", ""); - // TODO move this into OpenXRHTCViveTrackerExtension once this is supported. - // register_top_level_path("Handheld object tracker", "/user/vive_tracker_htcx/role/handheld_object", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Left foot tracker", "/user/vive_tracker_htcx/role/left_foot", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Right foot tracker", "/user/vive_tracker_htcx/role/right_foot", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Left shoulder tracker", "/user/vive_tracker_htcx/role/left_shoulder", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Right shoulder tracker", "/user/vive_tracker_htcx/role/right_shoulder", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Left elbow tracker", "/user/vive_tracker_htcx/role/left_elbow", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Right elbow tracker", "/user/vive_tracker_htcx/role/right_elbow", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Left knee tracker", "/user/vive_tracker_htcx/role/left_knee", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Right knee tracker", "/user/vive_tracker_htcx/role/right_knee", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Waist tracker", "/user/vive_tracker_htcx/role/waist", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Chest tracker", "/user/vive_tracker_htcx/role/chest", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Camera tracker", "/user/vive_tracker_htcx/role/camera", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - register_top_level_path("Keyboard tracker", "/user/vive_tracker_htcx/role/keyboard", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); - // Fallback Khronos simple controller register_interaction_profile("Simple controller", "/interaction_profiles/khr/simple_controller", ""); register_io_path("/interaction_profiles/khr/simple_controller", "Grip pose", "/user/hand/left", "/user/hand/left/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); diff --git a/modules/openxr/editor/openxr_action_map_editor.cpp b/modules/openxr/editor/openxr_action_map_editor.cpp index 62b4a427b9..937973f388 100644 --- a/modules/openxr/editor/openxr_action_map_editor.cpp +++ b/modules/openxr/editor/openxr_action_map_editor.cpp @@ -59,7 +59,7 @@ void OpenXRActionMapEditor::_notification(int p_what) { for (int i = 0; i < tabs->get_child_count(); i++) { Control *tab = Object::cast_to<Control>(tabs->get_child(i)); if (tab) { - tab->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + tab->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); } } } break; @@ -110,7 +110,7 @@ OpenXRInteractionProfileEditorBase *OpenXRActionMapEditor::_add_interaction_prof // now add it in.. ERR_FAIL_NULL_V(new_profile_editor, nullptr); tabs->add_child(new_profile_editor); - new_profile_editor->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + new_profile_editor->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); tabs->set_tab_button_icon(tabs->get_tab_count() - 1, get_theme_icon(SNAME("close"), SNAME("TabBar"))); return new_profile_editor; diff --git a/modules/openxr/editor/openxr_action_set_editor.cpp b/modules/openxr/editor/openxr_action_set_editor.cpp index 5d9a3155fb..e2a843a051 100644 --- a/modules/openxr/editor/openxr_action_set_editor.cpp +++ b/modules/openxr/editor/openxr_action_set_editor.cpp @@ -63,7 +63,7 @@ void OpenXRActionSetEditor::_notification(int p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { _theme_changed(); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer"))); } break; } } diff --git a/modules/openxr/editor/openxr_interaction_profile_editor.cpp b/modules/openxr/editor/openxr_interaction_profile_editor.cpp index ab36c0744e..651171358c 100644 --- a/modules/openxr/editor/openxr_interaction_profile_editor.cpp +++ b/modules/openxr/editor/openxr_interaction_profile_editor.cpp @@ -285,7 +285,7 @@ void OpenXRInteractionProfileEditor::_update_interaction_profile() { PanelContainer *panel = memnew(PanelContainer); panel->set_v_size_flags(Control::SIZE_EXPAND_FILL); main_hb->add_child(panel); - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer"))); VBoxContainer *container = memnew(VBoxContainer); panel->add_child(container); @@ -310,7 +310,7 @@ void OpenXRInteractionProfileEditor::_theme_changed() { for (int i = 0; i < main_hb->get_child_count(); i++) { Control *panel = Object::cast_to<Control>(main_hb->get_child(i)); if (panel) { - panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("TabContainer"))); + panel->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("TabContainer"))); } } } diff --git a/modules/openxr/editor/openxr_select_action_dialog.cpp b/modules/openxr/editor/openxr_select_action_dialog.cpp index de0ab40f9e..a4ccc98408 100644 --- a/modules/openxr/editor/openxr_select_action_dialog.cpp +++ b/modules/openxr/editor/openxr_select_action_dialog.cpp @@ -38,7 +38,7 @@ void OpenXRSelectActionDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); } break; } } diff --git a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp index e6705d5c82..53b8cbd401 100644 --- a/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp +++ b/modules/openxr/editor/openxr_select_interaction_profile_dialog.cpp @@ -38,7 +38,7 @@ void OpenXRSelectInteractionProfileDialog::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: case NOTIFICATION_THEME_CHANGED: { - scroll->add_theme_style_override("panel", get_theme_stylebox(SNAME("panel"), SNAME("Tree"))); + scroll->add_theme_style_override(SceneStringName(panel), get_theme_stylebox(SceneStringName(panel), SNAME("Tree"))); } break; } } diff --git a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp index b8a2f58935..d9a66aa827 100644 --- a/modules/openxr/extensions/openxr_hand_tracking_extension.cpp +++ b/modules/openxr/extensions/openxr_hand_tracking_extension.cpp @@ -293,7 +293,12 @@ void OpenXRHandTrackingExtension::on_process() { } godot_tracker->set_hand_tracking_source(source); - godot_tracker->set_pose("default", transform, linear_velocity, angular_velocity); + if (location.locationFlags & XR_SPACE_LOCATION_POSITION_TRACKED_BIT) { + godot_tracker->set_pose("default", transform, linear_velocity, angular_velocity); + } else { + godot_tracker->set_has_tracking_data(false); + godot_tracker->invalidate_pose("default"); + } } } } else { diff --git a/modules/openxr/extensions/openxr_htc_controller_extension.cpp b/modules/openxr/extensions/openxr_htc_controller_extension.cpp index c4ecb4e57c..416934fa47 100644 --- a/modules/openxr/extensions/openxr_htc_controller_extension.cpp +++ b/modules/openxr/extensions/openxr_htc_controller_extension.cpp @@ -37,10 +37,19 @@ HashMap<String, bool *> OpenXRHTCControllerExtension::get_requested_extensions() request_extensions[XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_COSMOS]; request_extensions[XR_HTC_VIVE_FOCUS3_CONTROLLER_INTERACTION_EXTENSION_NAME] = &available[HTC_VIVE_FOCUS3]; + request_extensions[XR_HTC_HAND_INTERACTION_EXTENSION_NAME] = &available[HTC_HAND_INTERACTION]; return request_extensions; } +PackedStringArray OpenXRHTCControllerExtension::get_suggested_tracker_names() { + PackedStringArray arr = { + "/user/hand_htc/left", + "/user/hand_htc/right", + }; + return arr; +} + bool OpenXRHTCControllerExtension::is_available(HTCControllers p_type) { return available[p_type]; } @@ -49,6 +58,9 @@ void OpenXRHTCControllerExtension::on_register_metadata() { OpenXRInteractionProfileMetadata *metadata = OpenXRInteractionProfileMetadata::get_singleton(); ERR_FAIL_NULL(metadata); + metadata->register_top_level_path("HTC left hand tracker", "/user/hand_htc/left", XR_HTC_HAND_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("HTC right hand tracker", "/user/hand_htc/right", XR_HTC_HAND_INTERACTION_EXTENSION_NAME); + // HTC Vive Cosmos controller metadata->register_interaction_profile("Vive Cosmos controller", "/interaction_profiles/htc/vive_cosmos_controller", XR_HTC_VIVE_COSMOS_CONTROLLER_INTERACTION_EXTENSION_NAME); metadata->register_io_path("/interaction_profiles/htc/vive_cosmos_controller", "Grip pose", "/user/hand/left", "/user/hand/left/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); @@ -128,4 +140,17 @@ void OpenXRHTCControllerExtension::on_register_metadata() { metadata->register_io_path("/interaction_profiles/htc/vive_focus3_controller", "Haptic output", "/user/hand/left", "/user/hand/left/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); metadata->register_io_path("/interaction_profiles/htc/vive_focus3_controller", "Haptic output", "/user/hand/right", "/user/hand/right/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); + + // HTC Hand interaction profile + metadata->register_interaction_profile("HTC Hand interaction", "/interaction_profiles/htc/hand_interaction", XR_HTC_HAND_INTERACTION_EXTENSION_NAME); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Grip pose", "/user/hand_htc/left", "/user/hand_htc/left/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Grip pose", "/user/hand_htc/right", "/user/hand_htc/right/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Aim pose", "/user/hand_htc/left", "/user/hand_htc/left/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Aim pose", "/user/hand_htc/right", "/user/hand_htc/right/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Select (pinch)", "/user/hand_htc/left", "/user/hand_htc/left/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Select (pinch)", "/user/hand_htc/right", "/user/hand_htc/right/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Squeeze (grab)", "/user/hand_htc/left", "/user/hand_htc/left/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path("/interaction_profiles/htc/hand_interaction", "Squeeze (grab)", "/user/hand_htc/right", "/user/hand_htc/right/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); } diff --git a/modules/openxr/extensions/openxr_htc_controller_extension.h b/modules/openxr/extensions/openxr_htc_controller_extension.h index 2aaeac2577..6f2b2ceec3 100644 --- a/modules/openxr/extensions/openxr_htc_controller_extension.h +++ b/modules/openxr/extensions/openxr_htc_controller_extension.h @@ -39,11 +39,14 @@ public: // Note, HTC Vive Wand controllers are part of the core spec and not part of our extension. HTC_VIVE_COSMOS, HTC_VIVE_FOCUS3, + HTC_HAND_INTERACTION, HTC_MAX_CONTROLLERS }; virtual HashMap<String, bool *> get_requested_extensions() override; + PackedStringArray get_suggested_tracker_names() override; + bool is_available(HTCControllers p_type); virtual void on_register_metadata() override; diff --git a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp index bb60f7adef..b2ddf71f5e 100644 --- a/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp +++ b/modules/openxr/extensions/openxr_htc_vive_tracker_extension.cpp @@ -69,6 +69,20 @@ void OpenXRHTCViveTrackerExtension::on_register_metadata() { OpenXRInteractionProfileMetadata *metadata = OpenXRInteractionProfileMetadata::get_singleton(); ERR_FAIL_NULL(metadata); + // register_top_level_path("Handheld object tracker", "/user/vive_tracker_htcx/role/handheld_object", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Left foot tracker", "/user/vive_tracker_htcx/role/left_foot", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Right foot tracker", "/user/vive_tracker_htcx/role/right_foot", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Left shoulder tracker", "/user/vive_tracker_htcx/role/left_shoulder", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Right shoulder tracker", "/user/vive_tracker_htcx/role/right_shoulder", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Left elbow tracker", "/user/vive_tracker_htcx/role/left_elbow", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Right elbow tracker", "/user/vive_tracker_htcx/role/right_elbow", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Left knee tracker", "/user/vive_tracker_htcx/role/left_knee", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Right knee tracker", "/user/vive_tracker_htcx/role/right_knee", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Waist tracker", "/user/vive_tracker_htcx/role/waist", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Chest tracker", "/user/vive_tracker_htcx/role/chest", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Camera tracker", "/user/vive_tracker_htcx/role/camera", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + metadata->register_top_level_path("Keyboard tracker", "/user/vive_tracker_htcx/role/keyboard", XR_HTCX_VIVE_TRACKER_INTERACTION_EXTENSION_NAME); + // HTC Vive tracker // Interestingly enough trackers don't have buttons or inputs, yet these are defined in the spec. // I think this can be supported through attachments on the trackers. diff --git a/modules/openxr/extensions/openxr_wmr_controller_extension.cpp b/modules/openxr/extensions/openxr_wmr_controller_extension.cpp index 7d43d2e304..3437320452 100644 --- a/modules/openxr/extensions/openxr_wmr_controller_extension.cpp +++ b/modules/openxr/extensions/openxr_wmr_controller_extension.cpp @@ -38,6 +38,7 @@ HashMap<String, bool *> OpenXRWMRControllerExtension::get_requested_extensions() // Note HP G2 is available on WMR and SteamVR, but Odessey is only available on WMR request_extensions[XR_EXT_HP_MIXED_REALITY_CONTROLLER_EXTENSION_NAME] = &available[WMR_HPMR]; request_extensions[XR_EXT_SAMSUNG_ODYSSEY_CONTROLLER_EXTENSION_NAME] = &available[WMR_SAMSUNG_ODESSY]; + request_extensions[XR_MSFT_HAND_INTERACTION_EXTENSION_NAME] = &available[WMR_HAND_INTERACTION]; return request_extensions; } @@ -117,4 +118,23 @@ void OpenXRWMRControllerExtension::on_register_metadata() { metadata->register_io_path("/interaction_profiles/samsung/odyssey_controller", "Haptic output", "/user/hand/left", "/user/hand/left/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); metadata->register_io_path("/interaction_profiles/samsung/odyssey_controller", "Haptic output", "/user/hand/right", "/user/hand/right/output/haptic", "", OpenXRAction::OPENXR_ACTION_HAPTIC); + + // MSFT Hand interaction profile, also supported by other headsets + metadata->register_interaction_profile("MSFT Hand interaction", "/interaction_profiles/microsoft/hand_interaction", XR_MSFT_HAND_INTERACTION_EXTENSION_NAME); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Grip pose", "/user/hand/left", "/user/hand/left/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Grip pose", "/user/hand/right", "/user/hand/right/input/grip/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Aim pose", "/user/hand/left", "/user/hand/left/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Aim pose", "/user/hand/right", "/user/hand/right/input/aim/pose", "", OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Pinch pose", "/user/hand/left", "/user/hand/left/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Pinch pose", "/user/hand/right", "/user/hand/right/input/pinch_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Poke pose", "/user/hand/left", "/user/hand/left/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Poke pose", "/user/hand/right", "/user/hand/right/input/poke_ext/pose", XR_EXT_HAND_INTERACTION_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Palm pose", "/user/hand/left", "/user/hand/left/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Palm pose", "/user/hand/right", "/user/hand/right/input/palm_ext/pose", XR_EXT_PALM_POSE_EXTENSION_NAME, OpenXRAction::OPENXR_ACTION_POSE); + + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Select (pinch)", "/user/hand/left", "/user/hand/left/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Select (pinch)", "/user/hand/right", "/user/hand/right/input/select/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Squeeze (grab)", "/user/hand/left", "/user/hand/left/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); + metadata->register_io_path("/interaction_profiles/microsoft/hand_interaction", "Squeeze (grab)", "/user/hand/right", "/user/hand/right/input/squeeze/value", "", OpenXRAction::OPENXR_ACTION_FLOAT); } diff --git a/modules/openxr/extensions/openxr_wmr_controller_extension.h b/modules/openxr/extensions/openxr_wmr_controller_extension.h index 3bbdff586e..c8b50f1bbf 100644 --- a/modules/openxr/extensions/openxr_wmr_controller_extension.h +++ b/modules/openxr/extensions/openxr_wmr_controller_extension.h @@ -38,6 +38,7 @@ public: enum WMRControllers { WMR_HPMR, WMR_SAMSUNG_ODESSY, + WMR_HAND_INTERACTION, WMR_MAX_CONTROLLERS }; diff --git a/modules/openxr/scene/openxr_composition_layer.cpp b/modules/openxr/scene/openxr_composition_layer.cpp index b02f3082ab..f69a907be9 100644 --- a/modules/openxr/scene/openxr_composition_layer.cpp +++ b/modules/openxr/scene/openxr_composition_layer.cpp @@ -151,6 +151,16 @@ void OpenXRCompositionLayer::update_fallback_mesh() { should_update_fallback_mesh = true; } +XrPosef OpenXRCompositionLayer::get_openxr_pose() { + Transform3D reference_frame = XRServer::get_singleton()->get_reference_frame(); + Transform3D transform = reference_frame.inverse() * get_transform(); + Quaternion quat(transform.basis.orthonormalized()); + return { + { (float)quat.x, (float)quat.y, (float)quat.z, (float)quat.w }, + { (float)transform.origin.x, (float)transform.origin.y, (float)transform.origin.z } + }; +} + bool OpenXRCompositionLayer::is_viewport_in_use(SubViewport *p_viewport) { for (const OpenXRCompositionLayer *other_composition_layer : composition_layer_nodes) { if (other_composition_layer != this && other_composition_layer->is_inside_tree() && other_composition_layer->get_layer_viewport() == p_viewport) { diff --git a/modules/openxr/scene/openxr_composition_layer.h b/modules/openxr/scene/openxr_composition_layer.h index 6792364295..55cae27d23 100644 --- a/modules/openxr/scene/openxr_composition_layer.h +++ b/modules/openxr/scene/openxr_composition_layer.h @@ -77,6 +77,8 @@ protected: void update_fallback_mesh(); + XrPosef get_openxr_pose(); + static Vector<OpenXRCompositionLayer *> composition_layer_nodes; bool is_viewport_in_use(SubViewport *p_viewport); diff --git a/modules/openxr/scene/openxr_composition_layer_cylinder.cpp b/modules/openxr/scene/openxr_composition_layer_cylinder.cpp index 728ba71006..6c8d2fc885 100644 --- a/modules/openxr/scene/openxr_composition_layer_cylinder.cpp +++ b/modules/openxr/scene/openxr_composition_layer_cylinder.cpp @@ -52,6 +52,7 @@ OpenXRCompositionLayerCylinder::OpenXRCompositionLayerCylinder() { aspect_ratio, // aspectRatio }; openxr_layer_provider = memnew(OpenXRViewportCompositionLayerProvider((XrCompositionLayerBaseHeader *)&composition_layer)); + XRServer::get_singleton()->connect("reference_frame_changed", callable_mp(this, &OpenXRCompositionLayerCylinder::update_transform)); } OpenXRCompositionLayerCylinder::~OpenXRCompositionLayerCylinder() { @@ -131,14 +132,15 @@ Ref<Mesh> OpenXRCompositionLayerCylinder::_create_fallback_mesh() { void OpenXRCompositionLayerCylinder::_notification(int p_what) { switch (p_what) { case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - Transform3D transform = get_transform(); - Quaternion quat(transform.basis.orthonormalized()); - composition_layer.pose.orientation = { (float)quat.x, (float)quat.y, (float)quat.z, (float)quat.w }; - composition_layer.pose.position = { (float)transform.origin.x, (float)transform.origin.y, (float)transform.origin.z }; + update_transform(); } break; } } +void OpenXRCompositionLayerCylinder::update_transform() { + composition_layer.pose = get_openxr_pose(); +} + void OpenXRCompositionLayerCylinder::set_radius(float p_radius) { ERR_FAIL_COND(p_radius <= 0); radius = p_radius; diff --git a/modules/openxr/scene/openxr_composition_layer_cylinder.h b/modules/openxr/scene/openxr_composition_layer_cylinder.h index bb1d242267..9bd5a42d36 100644 --- a/modules/openxr/scene/openxr_composition_layer_cylinder.h +++ b/modules/openxr/scene/openxr_composition_layer_cylinder.h @@ -50,6 +50,8 @@ protected: void _notification(int p_what); + void update_transform(); + virtual Ref<Mesh> _create_fallback_mesh() override; public: diff --git a/modules/openxr/scene/openxr_composition_layer_equirect.cpp b/modules/openxr/scene/openxr_composition_layer_equirect.cpp index 14cfea8da6..b6f5d27ffe 100644 --- a/modules/openxr/scene/openxr_composition_layer_equirect.cpp +++ b/modules/openxr/scene/openxr_composition_layer_equirect.cpp @@ -53,6 +53,7 @@ OpenXRCompositionLayerEquirect::OpenXRCompositionLayerEquirect() { -lower_vertical_angle, // lowerVerticalAngle }; openxr_layer_provider = memnew(OpenXRViewportCompositionLayerProvider((XrCompositionLayerBaseHeader *)&composition_layer)); + XRServer::get_singleton()->connect("reference_frame_changed", callable_mp(this, &OpenXRCompositionLayerEquirect::update_transform)); } OpenXRCompositionLayerEquirect::~OpenXRCompositionLayerEquirect() { @@ -139,14 +140,15 @@ Ref<Mesh> OpenXRCompositionLayerEquirect::_create_fallback_mesh() { void OpenXRCompositionLayerEquirect::_notification(int p_what) { switch (p_what) { case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - Transform3D transform = get_transform(); - Quaternion quat(transform.basis.orthonormalized()); - composition_layer.pose.orientation = { (float)quat.x, (float)quat.y, (float)quat.z, (float)quat.w }; - composition_layer.pose.position = { (float)transform.origin.x, (float)transform.origin.y, (float)transform.origin.z }; + update_transform(); } break; } } +void OpenXRCompositionLayerEquirect::update_transform() { + composition_layer.pose = get_openxr_pose(); +} + void OpenXRCompositionLayerEquirect::set_radius(float p_radius) { ERR_FAIL_COND(p_radius <= 0); radius = p_radius; diff --git a/modules/openxr/scene/openxr_composition_layer_equirect.h b/modules/openxr/scene/openxr_composition_layer_equirect.h index 66f8b0a91c..af6cd92cbe 100644 --- a/modules/openxr/scene/openxr_composition_layer_equirect.h +++ b/modules/openxr/scene/openxr_composition_layer_equirect.h @@ -51,6 +51,8 @@ protected: void _notification(int p_what); + void update_transform(); + virtual Ref<Mesh> _create_fallback_mesh() override; public: diff --git a/modules/openxr/scene/openxr_composition_layer_quad.cpp b/modules/openxr/scene/openxr_composition_layer_quad.cpp index 8c5b8ec26b..21919496d6 100644 --- a/modules/openxr/scene/openxr_composition_layer_quad.cpp +++ b/modules/openxr/scene/openxr_composition_layer_quad.cpp @@ -50,6 +50,7 @@ OpenXRCompositionLayerQuad::OpenXRCompositionLayerQuad() { { (float)quad_size.x, (float)quad_size.y }, // size }; openxr_layer_provider = memnew(OpenXRViewportCompositionLayerProvider((XrCompositionLayerBaseHeader *)&composition_layer)); + XRServer::get_singleton()->connect("reference_frame_changed", callable_mp(this, &OpenXRCompositionLayerQuad::update_transform)); } OpenXRCompositionLayerQuad::~OpenXRCompositionLayerQuad() { @@ -72,14 +73,15 @@ Ref<Mesh> OpenXRCompositionLayerQuad::_create_fallback_mesh() { void OpenXRCompositionLayerQuad::_notification(int p_what) { switch (p_what) { case NOTIFICATION_LOCAL_TRANSFORM_CHANGED: { - Transform3D transform = get_transform(); - Quaternion quat(transform.basis.orthonormalized()); - composition_layer.pose.orientation = { (float)quat.x, (float)quat.y, (float)quat.z, (float)quat.w }; - composition_layer.pose.position = { (float)transform.origin.x, (float)transform.origin.y, (float)transform.origin.z }; + update_transform(); } break; } } +void OpenXRCompositionLayerQuad::update_transform() { + composition_layer.pose = get_openxr_pose(); +} + void OpenXRCompositionLayerQuad::set_quad_size(const Size2 &p_size) { quad_size = p_size; composition_layer.size = { (float)quad_size.x, (float)quad_size.y }; diff --git a/modules/openxr/scene/openxr_composition_layer_quad.h b/modules/openxr/scene/openxr_composition_layer_quad.h index 21bb9b2d85..0c3172dbb2 100644 --- a/modules/openxr/scene/openxr_composition_layer_quad.h +++ b/modules/openxr/scene/openxr_composition_layer_quad.h @@ -47,6 +47,8 @@ protected: void _notification(int p_what); + void update_transform(); + virtual Ref<Mesh> _create_fallback_mesh() override; public: diff --git a/modules/text_server_adv/gdextension_build/SConstruct b/modules/text_server_adv/gdextension_build/SConstruct index 2f7a175d91..d0d13fec3f 100644 --- a/modules/text_server_adv/gdextension_build/SConstruct +++ b/modules/text_server_adv/gdextension_build/SConstruct @@ -61,8 +61,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: thirdparty_tvg_dir = "../../../thirdparty/thorvg/" thirdparty_tvg_sources = [ # common - "src/common/tvgBezier.cpp", "src/common/tvgCompressor.cpp", + "src/common/tvgLines.cpp", "src/common/tvgMath.cpp", "src/common/tvgStr.cpp", # SVG parser @@ -73,6 +73,7 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "src/loaders/svg/tvgSvgUtil.cpp", "src/loaders/svg/tvgXmlParser.cpp", "src/loaders/raw/tvgRawLoader.cpp", + # image loaders "src/loaders/external_png/tvgPngLoader.cpp", "src/loaders/jpg/tvgJpgd.cpp", "src/loaders/jpg/tvgJpgLoader.cpp", @@ -117,6 +118,7 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "../../../thirdparty/thorvg/src/loaders/raw", "../../../thirdparty/thorvg/src/loaders/external_png", "../../../thirdparty/thorvg/src/loaders/jpg", + "../../../thirdparty/libpng", ] ) diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 09a037fd28..361d88af90 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -851,7 +851,7 @@ _FORCE_INLINE_ TextServerAdvanced::FontTexturePosition TextServerAdvanced::find_ { // Zero texture. uint8_t *w = tex.image->ptrw(); - ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.image->data_size(), ret); + ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.image->get_data_size(), ret); // Initialize the texture to all-white pixels to prevent artifacts when the // font is displayed at a non-default scale with filtering enabled. if (p_color_size == 2) { @@ -1040,7 +1040,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 * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * 4; - ERR_FAIL_COND_V(ofs >= tex.image->data_size(), FontGlyph()); + ERR_FAIL_COND_V(ofs >= tex.image->get_data_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)); wr[ofs + 2] = (uint8_t)(CLAMP(image(j, i)[2] * 256.f, 0.f, 255.f)); @@ -1118,7 +1118,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 * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * color_size; - ERR_FAIL_COND_V(ofs >= tex.image->data_size(), FontGlyph()); + ERR_FAIL_COND_V(ofs >= tex.image->get_data_size(), FontGlyph()); switch (p_bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { int byte = i * p_bitmap.pitch + (j >> 3); @@ -2468,7 +2468,7 @@ int64_t TextServerAdvanced::_font_get_spacing(const RID &p_font_rid, SpacingType } } -void TextServerAdvanced::_font_set_baseline_offset(const RID &p_font_rid, float p_baseline_offset) { +void TextServerAdvanced::_font_set_baseline_offset(const RID &p_font_rid, double p_baseline_offset) { FontAdvancedLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); if (fdv) { if (fdv->baseline_offset != p_baseline_offset) { @@ -2486,7 +2486,7 @@ void TextServerAdvanced::_font_set_baseline_offset(const RID &p_font_rid, float } } -float TextServerAdvanced::_font_get_baseline_offset(const RID &p_font_rid) const { +double TextServerAdvanced::_font_get_baseline_offset(const RID &p_font_rid) const { FontAdvancedLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); if (fdv) { return fdv->baseline_offset; @@ -7142,9 +7142,7 @@ PackedInt32Array TextServerAdvanced::_string_get_character_breaks(const String & } ubrk_close(bi); } else { - for (int i = 0; i <= p_string.size(); i++) { - ret.push_back(i); - } + return TextServer::string_get_character_breaks(p_string, p_language); } return ret; @@ -7342,7 +7340,7 @@ bool TextServerAdvanced::_is_valid_identifier(const String &p_string) const { return true; } -bool TextServerAdvanced::_is_valid_letter(char32_t p_unicode) const { +bool TextServerAdvanced::_is_valid_letter(uint64_t p_unicode) const { #ifndef ICU_STATIC_DATA if (!icu_data_loaded) { return TextServer::is_valid_letter(p_unicode); diff --git a/modules/text_server_adv/text_server_adv.h b/modules/text_server_adv/text_server_adv.h index 8895a83089..92bdb93bcf 100644 --- a/modules/text_server_adv/text_server_adv.h +++ b/modules/text_server_adv/text_server_adv.h @@ -296,7 +296,7 @@ class TextServerAdvanced : public TextServerExtension { struct FontAdvancedLinkedVariation { RID base_font; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; }; struct FontAdvanced { @@ -325,7 +325,7 @@ class TextServerAdvanced : public TextServerExtension { int weight = 400; int stretch = 100; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; HashMap<Vector2i, FontForSizeAdvanced *, VariantHasher, VariantComparator> cache; @@ -578,7 +578,7 @@ class TextServerAdvanced : public TextServerExtension { double embolden = 0.0; Transform2D transform; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; bool operator==(const SystemFontKey &p_b) const { return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset); @@ -791,8 +791,8 @@ public: MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t); MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType); - MODBIND2(font_set_baseline_offset, const RID &, float); - MODBIND1RC(float, font_get_baseline_offset, const RID &); + MODBIND2(font_set_baseline_offset, const RID &, double); + MODBIND1RC(double, font_get_baseline_offset, const RID &); MODBIND2(font_set_transform, const RID &, const Transform2D &); MODBIND1RC(Transform2D, font_get_transform, const RID &); @@ -988,7 +988,7 @@ public: MODBIND1RC(String, strip_diacritics, const String &); MODBIND1RC(bool, is_valid_identifier, const String &); - MODBIND1RC(bool, is_valid_letter, char32_t); + MODBIND1RC(bool, is_valid_letter, uint64_t); MODBIND2RC(String, string_to_upper, const String &, const String &); MODBIND2RC(String, string_to_lower, const String &, const String &); diff --git a/modules/text_server_fb/gdextension_build/SConstruct b/modules/text_server_fb/gdextension_build/SConstruct index f6ae7149be..a3c2052040 100644 --- a/modules/text_server_fb/gdextension_build/SConstruct +++ b/modules/text_server_fb/gdextension_build/SConstruct @@ -56,8 +56,8 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: thirdparty_tvg_dir = "../../../thirdparty/thorvg/" thirdparty_tvg_sources = [ # common - "src/common/tvgBezier.cpp", "src/common/tvgCompressor.cpp", + "src/common/tvgLines.cpp", "src/common/tvgMath.cpp", "src/common/tvgStr.cpp", # SVG parser @@ -68,6 +68,7 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "src/loaders/svg/tvgSvgUtil.cpp", "src/loaders/svg/tvgXmlParser.cpp", "src/loaders/raw/tvgRawLoader.cpp", + # image loaders "src/loaders/external_png/tvgPngLoader.cpp", "src/loaders/jpg/tvgJpgd.cpp", "src/loaders/jpg/tvgJpgLoader.cpp", @@ -112,6 +113,7 @@ if env["thorvg_enabled"] and env["freetype_enabled"]: "../../../thirdparty/thorvg/src/loaders/raw", "../../../thirdparty/thorvg/src/loaders/external_png", "../../../thirdparty/thorvg/src/loaders/jpg", + "../../../thirdparty/libpng", ] ) @@ -146,8 +148,6 @@ if env["msdfgen_enabled"] and env["freetype_enabled"]: "core/Projection.cpp", "core/Scanline.cpp", "core/Shape.cpp", - "core/SignedDistance.cpp", - "core/Vector2.cpp", "core/contour-combiners.cpp", "core/edge-coloring.cpp", "core/edge-segments.cpp", diff --git a/modules/text_server_fb/register_types.cpp b/modules/text_server_fb/register_types.cpp index 37c623c5eb..3dd359f0ce 100644 --- a/modules/text_server_fb/register_types.cpp +++ b/modules/text_server_fb/register_types.cpp @@ -62,8 +62,8 @@ using namespace godot; extern "C" { -GDExtensionBool GDE_EXPORT textserver_fallback_init(const GDExtensionInterface *p_interface, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { - GDExtensionBinding::InitObject init_obj(p_interface, p_library, r_initialization); +GDExtensionBool GDE_EXPORT textserver_fallback_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization) { + GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization); init_obj.register_initializer(&initialize_text_server_fb_module); init_obj.register_terminator(&uninitialize_text_server_fb_module); diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index c62f308818..697c3366c5 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -40,6 +40,8 @@ #include <godot_cpp/classes/translation_server.hpp> #include <godot_cpp/core/error_macros.hpp> +#define OT_TAG(m_c1, m_c2, m_c3, m_c4) ((int32_t)((((uint32_t)(m_c1) & 0xff) << 24) | (((uint32_t)(m_c2) & 0xff) << 16) | (((uint32_t)(m_c3) & 0xff) << 8) | ((uint32_t)(m_c4) & 0xff))) + using namespace godot; #define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var) @@ -287,7 +289,7 @@ _FORCE_INLINE_ TextServerFallback::FontTexturePosition TextServerFallback::find_ { // Zero texture. uint8_t *w = tex.image->ptrw(); - ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.image->data_size(), ret); + ERR_FAIL_COND_V(texsize * texsize * p_color_size > tex.image->get_data_size(), ret); // Initialize the texture to all-white pixels to prevent artifacts when the // font is displayed at a non-default scale with filtering enabled. if (p_color_size == 2) { @@ -475,7 +477,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 * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * 4; - ERR_FAIL_COND_V(ofs >= tex.image->data_size(), FontGlyph()); + ERR_FAIL_COND_V(ofs >= tex.image->get_data_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)); wr[ofs + 2] = (uint8_t)(CLAMP(image(j, i)[2] * 256.f, 0.f, 255.f)); @@ -552,7 +554,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 * 2) * tex.texture_w + j + tex_pos.x + p_rect_margin * 2) * color_size; - ERR_FAIL_COND_V(ofs >= tex.image->data_size(), FontGlyph()); + ERR_FAIL_COND_V(ofs >= tex.image->get_data_size(), FontGlyph()); switch (p_bitmap.pixel_mode) { case FT_PIXEL_MODE_MONO: { int byte = i * p_bitmap.pitch + (j >> 3); @@ -1474,7 +1476,7 @@ int64_t TextServerFallback::_font_get_spacing(const RID &p_font_rid, SpacingType } } -void TextServerFallback::_font_set_baseline_offset(const RID &p_font_rid, float p_baseline_offset) { +void TextServerFallback::_font_set_baseline_offset(const RID &p_font_rid, double p_baseline_offset) { FontFallbackLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); if (fdv) { if (fdv->baseline_offset != p_baseline_offset) { @@ -1492,7 +1494,7 @@ void TextServerFallback::_font_set_baseline_offset(const RID &p_font_rid, float } } -float TextServerFallback::_font_get_baseline_offset(const RID &p_font_rid) const { +double TextServerFallback::_font_get_baseline_offset(const RID &p_font_rid) const { FontFallbackLinkedVariation *fdv = font_var_owner.get_or_null(p_font_rid); if (fdv) { return fdv->baseline_offset; @@ -4465,7 +4467,11 @@ PackedInt32Array TextServerFallback::_shaped_text_get_character_breaks(const RID if (size > 0) { ret.resize(size); for (int i = 0; i < size; i++) { +#ifdef GDEXTENSION + ret[i] = i + 1 + sd->start; +#else ret.write[i] = i + 1 + sd->start; +#endif } } return ret; diff --git a/modules/text_server_fb/text_server_fb.h b/modules/text_server_fb/text_server_fb.h index 9ad20c7b26..2235247b31 100644 --- a/modules/text_server_fb/text_server_fb.h +++ b/modules/text_server_fb/text_server_fb.h @@ -247,7 +247,7 @@ class TextServerFallback : public TextServerExtension { struct FontFallbackLinkedVariation { RID base_font; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; }; struct FontFallback { @@ -276,7 +276,7 @@ class TextServerFallback : public TextServerExtension { int weight = 400; int stretch = 100; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; HashMap<Vector2i, FontForSizeFallback *, VariantHasher, VariantComparator> cache; @@ -494,7 +494,7 @@ class TextServerFallback : public TextServerExtension { double embolden = 0.0; Transform2D transform; int extra_spacing[4] = { 0, 0, 0, 0 }; - float baseline_offset = 0.0; + double baseline_offset = 0.0; bool operator==(const SystemFontKey &p_b) const { return (font_name == p_b.font_name) && (antialiasing == p_b.antialiasing) && (italic == p_b.italic) && (disable_embedded_bitmaps == p_b.disable_embedded_bitmaps) && (mipmaps == p_b.mipmaps) && (msdf == p_b.msdf) && (force_autohinter == p_b.force_autohinter) && (weight == p_b.weight) && (stretch == p_b.stretch) && (msdf_range == p_b.msdf_range) && (msdf_source_size == p_b.msdf_source_size) && (fixed_size == p_b.fixed_size) && (hinting == p_b.hinting) && (subpixel_positioning == p_b.subpixel_positioning) && (variation_coordinates == p_b.variation_coordinates) && (oversampling == p_b.oversampling) && (embolden == p_b.embolden) && (transform == p_b.transform) && (extra_spacing[SPACING_TOP] == p_b.extra_spacing[SPACING_TOP]) && (extra_spacing[SPACING_BOTTOM] == p_b.extra_spacing[SPACING_BOTTOM]) && (extra_spacing[SPACING_SPACE] == p_b.extra_spacing[SPACING_SPACE]) && (extra_spacing[SPACING_GLYPH] == p_b.extra_spacing[SPACING_GLYPH]) && (baseline_offset == p_b.baseline_offset); @@ -659,8 +659,8 @@ public: MODBIND3(font_set_spacing, const RID &, SpacingType, int64_t); MODBIND2RC(int64_t, font_get_spacing, const RID &, SpacingType); - MODBIND2(font_set_baseline_offset, const RID &, float); - MODBIND1RC(float, font_get_baseline_offset, const RID &); + MODBIND2(font_set_baseline_offset, const RID &, double); + MODBIND1RC(double, font_get_baseline_offset, const RID &); MODBIND2(font_set_transform, const RID &, const Transform2D &); MODBIND1RC(Transform2D, font_get_transform, const RID &); |