diff options
-rw-r--r-- | core/extension/gdnative_interface.h | 70 | ||||
-rw-r--r-- | core/extension/native_extension.cpp | 4 | ||||
-rw-r--r-- | editor/history_dock.cpp | 2 | ||||
-rw-r--r-- | editor/import/post_import_plugin_skeleton_renamer.cpp | 208 | ||||
-rw-r--r-- | editor/import/post_import_plugin_skeleton_renamer.h | 2 | ||||
-rw-r--r-- | scene/3d/bone_attachment_3d.cpp | 4 | ||||
-rw-r--r-- | scene/3d/bone_attachment_3d.h | 2 | ||||
-rw-r--r-- | scene/3d/skeleton_3d.cpp | 2 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 1 | ||||
-rw-r--r-- | servers/rendering/shader_language.cpp | 20 |
10 files changed, 211 insertions, 104 deletions
diff --git a/core/extension/gdnative_interface.h b/core/extension/gdnative_interface.h index a361e40096..50410c4857 100644 --- a/core/extension/gdnative_interface.h +++ b/core/extension/gdnative_interface.h @@ -109,6 +109,7 @@ typedef enum { GDNATIVE_VARIANT_OP_LESS_EQUAL, GDNATIVE_VARIANT_OP_GREATER, GDNATIVE_VARIANT_OP_GREATER_EQUAL, + /* mathematic */ GDNATIVE_VARIANT_OP_ADD, GDNATIVE_VARIANT_OP_SUBTRACT, @@ -118,6 +119,7 @@ typedef enum { GDNATIVE_VARIANT_OP_POSITIVE, GDNATIVE_VARIANT_OP_MODULE, GDNATIVE_VARIANT_OP_POWER, + /* bitwise */ GDNATIVE_VARIANT_OP_SHIFT_LEFT, GDNATIVE_VARIANT_OP_SHIFT_RIGHT, @@ -125,11 +127,13 @@ typedef enum { GDNATIVE_VARIANT_OP_BIT_OR, GDNATIVE_VARIANT_OP_BIT_XOR, GDNATIVE_VARIANT_OP_BIT_NEGATE, + /* logic */ GDNATIVE_VARIANT_OP_AND, GDNATIVE_VARIANT_OP_OR, GDNATIVE_VARIANT_OP_XOR, GDNATIVE_VARIANT_OP_NOT, + /* containment */ GDNATIVE_VARIANT_OP_IN, GDNATIVE_VARIANT_OP_MAX @@ -152,11 +156,11 @@ typedef uint64_t GDObjectInstanceID; typedef enum { GDNATIVE_CALL_OK, GDNATIVE_CALL_ERROR_INVALID_METHOD, - GDNATIVE_CALL_ERROR_INVALID_ARGUMENT, /* expected is variant type */ - GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS, /* expected is number of arguments */ - GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS, /* expected is number of arguments */ + GDNATIVE_CALL_ERROR_INVALID_ARGUMENT, // Expected a different variant type. + GDNATIVE_CALL_ERROR_TOO_MANY_ARGUMENTS, // Expected lower number of arguments. + GDNATIVE_CALL_ERROR_TOO_FEW_ARGUMENTS, // Expected higher number of arguments. GDNATIVE_CALL_ERROR_INSTANCE_IS_NULL, - GDNATIVE_CALL_ERROR_METHOD_NOT_CONST, /* used for const call */ + GDNATIVE_CALL_ERROR_METHOD_NOT_CONST, // Used for const call. } GDNativeCallErrorType; typedef struct { @@ -204,20 +208,24 @@ typedef struct { GDNativeVariantType type; GDNativeStringNamePtr name; GDNativeStringNamePtr class_name; - uint32_t hint; // Bitfield of `PropertyHint` (defined in `extension_api.json`) + uint32_t hint; // Bitfield of `PropertyHint` (defined in `extension_api.json`). GDNativeStringPtr hint_string; - uint32_t usage; // Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`) + uint32_t usage; // Bitfield of `PropertyUsageFlags` (defined in `extension_api.json`). } GDNativePropertyInfo; typedef struct { GDNativeStringNamePtr name; GDNativePropertyInfo return_value; - uint32_t flags; // Bitfield of `GDNativeExtensionClassMethodFlags` + uint32_t flags; // Bitfield of `GDNativeExtensionClassMethodFlags`. int32_t id; - GDNativePropertyInfo *arguments; // array of `argument_count` size + + /* Arguments: `default_arguments` is an array of size `argument_count`. */ uint32_t argument_count; - GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size + GDNativePropertyInfo *arguments; + + /* Default arguments: `default_arguments` is an array of size `default_argument_count`. */ uint32_t default_argument_count; + GDNativeVariantPtr *default_arguments; } GDNativeMethodInfo; typedef const GDNativePropertyInfo *(*GDNativeExtensionClassGetPropertyList)(GDExtensionClassInstancePtr p_instance, uint32_t *r_count); @@ -246,11 +254,11 @@ typedef struct { GDNativeExtensionClassToString to_string_func; GDNativeExtensionClassReference reference_func; GDNativeExtensionClassUnreference unreference_func; - GDNativeExtensionClassCreateInstance create_instance_func; /* this one is mandatory */ - GDNativeExtensionClassFreeInstance free_instance_func; /* this one is mandatory */ - GDNativeExtensionClassGetVirtual get_virtual_func; + GDNativeExtensionClassCreateInstance create_instance_func; // (Default) constructor; mandatory. If the class is not instantiable, consider making it virtual or abstract. + GDNativeExtensionClassFreeInstance free_instance_func; // Destructor; mandatory. + GDNativeExtensionClassGetVirtual get_virtual_func; // Queries a virtual function by name and returns a callback to invoke the requested virtual function. GDNativeExtensionClassGetRID get_rid_func; - void *class_userdata; + void *class_userdata; // Per-class user data, later accessible in instance bindings. } GDNativeExtensionClassCreationInfo; typedef void *GDNativeExtensionClassLibraryPtr; @@ -289,21 +297,28 @@ typedef struct { void *method_userdata; GDNativeExtensionClassMethodCall call_func; GDNativeExtensionClassMethodPtrCall ptrcall_func; - uint32_t method_flags; // Bitfield of `GDNativeExtensionClassMethodFlags` - uint32_t argument_count; + uint32_t method_flags; // Bitfield of `GDNativeExtensionClassMethodFlags`. + + /* If `has_return_value` is false, `return_value_info` and `return_value_metadata` are ignored. */ GDNativeBool has_return_value; - GDNativePropertyInfo *return_value_info; // Ignored if `has_return_value` is false - GDNativeExtensionClassMethodArgumentMetadata return_value_metadata; // Ignored if `has_return_value` is false - /* name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. */ - GDNativePropertyInfo *aguments_info; // array of `argument_count` size - GDNativeExtensionClassMethodArgumentMetadata *aguments_metadata; // array of `argument_count` size + GDNativePropertyInfo *return_value_info; + GDNativeExtensionClassMethodArgumentMetadata return_value_metadata; + + /* Arguments: `arguments_info` and `arguments_metadata` are array of size `argument_count`. + * Name and hint information for the argument can be omitted in release builds. Class name should always be present if it applies. + */ + uint32_t argument_count; + GDNativePropertyInfo *arguments_info; + GDNativeExtensionClassMethodArgumentMetadata *arguments_metadata; + + /* Default arguments: `default_arguments` is an array of size `default_argument_count`. */ uint32_t default_argument_count; - GDNativeVariantPtr *default_arguments; // array of `default_argument_count` size + GDNativeVariantPtr *default_arguments; } GDNativeExtensionClassMethodInfo; /* SCRIPT INSTANCE EXTENSION */ -typedef void *GDNativeExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInstance native implementation +typedef void *GDNativeExtensionScriptInstanceDataPtr; // Pointer to custom ScriptInstance native implementation. typedef GDNativeBool (*GDNativeExtensionScriptInstanceSet)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, const GDNativeVariantPtr p_value); typedef GDNativeBool (*GDNativeExtensionScriptInstanceGet)(GDNativeExtensionScriptInstanceDataPtr p_instance, const GDNativeStringNamePtr p_name, GDNativeVariantPtr r_ret); @@ -389,6 +404,7 @@ typedef struct { const char *version_string; /* GODOT CORE */ + void *(*mem_alloc)(size_t p_bytes); void *(*mem_realloc)(void *p_ptr, size_t p_bytes); void (*mem_free)(void *p_ptr); @@ -455,7 +471,6 @@ typedef struct { GDNativePtrUtilityFunction (*variant_get_ptr_utility_function)(const GDNativeStringNamePtr p_function, GDNativeInt p_hash); /* extra utilities */ - void (*string_new_with_latin1_chars)(GDNativeStringPtr r_dest, const char *p_contents); void (*string_new_with_utf8_chars)(GDNativeStringPtr r_dest, const char *p_contents); void (*string_new_with_utf16_chars)(GDNativeStringPtr r_dest, const char16_t *p_contents); @@ -466,6 +481,7 @@ typedef struct { void (*string_new_with_utf16_chars_and_len)(GDNativeStringPtr r_dest, const char16_t *p_contents, const GDNativeInt p_size); void (*string_new_with_utf32_chars_and_len)(GDNativeStringPtr r_dest, const char32_t *p_contents, const GDNativeInt p_size); void (*string_new_with_wide_chars_and_len)(GDNativeStringPtr r_dest, const wchar_t *p_contents, const GDNativeInt p_size); + /* Information about the following functions: * - The return value is the resulting encoded string length. * - The length returned is in characters, not in bytes. It also does not include a trailing zero. @@ -537,13 +553,14 @@ typedef struct { GDNativeScriptInstancePtr (*script_instance_create)(const GDNativeExtensionScriptInstanceInfo *p_info, GDNativeExtensionScriptInstanceDataPtr p_instance_data); /* CLASSDB */ + GDNativeObjectPtr (*classdb_construct_object)(const GDNativeStringNamePtr p_classname); /* The passed class must be a built-in godot class, or an already-registered extension class. In both case, object_set_instance should be called to fully initialize the object. */ GDNativeMethodBindPtr (*classdb_get_method_bind)(const GDNativeStringNamePtr p_classname, const GDNativeStringNamePtr p_methodname, GDNativeInt p_hash); void *(*classdb_get_class_tag)(const GDNativeStringNamePtr p_classname); /* CLASSDB EXTENSION */ - // Provided parameters for `classdb_register_extension_*` can be safely freed once the function returns + /* Provided parameters for `classdb_register_extension_*` can be safely freed once the function returns. */ void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs); void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info); void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const GDNativeStringNamePtr p_class_name, const GDNativeStringNamePtr p_enum_name, const GDNativeStringNamePtr p_constant_name, GDNativeInt p_constant_value, GDNativeBool p_is_bitfield); @@ -579,9 +596,10 @@ typedef struct { } GDNativeInitialization; /* Define a C function prototype that implements the function below and expose it to dlopen() (or similar). - * It will be called on initialization. The name must be an unique one specified in the .gdextension config file. + * This is the entry point of the GDExtension library and will be called on initialization. + * It can be used to set up different init levels, which are called during various stages of initialization/shutdown. + * The function name must be a unique one specified in the .gdextension config file. */ - typedef GDNativeBool (*GDNativeInitializationFunction)(const GDNativeInterface *p_interface, const GDNativeExtensionClassLibraryPtr p_library, GDNativeInitialization *r_initialization); #ifdef __cplusplus diff --git a/core/extension/native_extension.cpp b/core/extension/native_extension.cpp index 8bbb72fd82..83a2e80793 100644 --- a/core/extension/native_extension.cpp +++ b/core/extension/native_extension.cpp @@ -108,8 +108,8 @@ public: } for (uint32_t i = 0; i < p_method_info->argument_count; i++) { - arguments_info.push_back(PropertyInfo(p_method_info->aguments_info[i])); - arguments_metadata.push_back(GodotTypeInfo::Metadata(p_method_info->aguments_metadata[i])); + arguments_info.push_back(PropertyInfo(p_method_info->arguments_info[i])); + arguments_metadata.push_back(GodotTypeInfo::Metadata(p_method_info->arguments_metadata[i])); } set_hint_flags(p_method_info->method_flags); diff --git a/editor/history_dock.cpp b/editor/history_dock.cpp index 57088a76cb..47b7e9f5d7 100644 --- a/editor/history_dock.cpp +++ b/editor/history_dock.cpp @@ -219,6 +219,8 @@ void HistoryDock::_notification(int p_notification) { } HistoryDock::HistoryDock() { + set_name("History"); + ur_manager = EditorNode::get_undo_redo(); ur_manager->connect("history_changed", callable_mp(this, &HistoryDock::on_history_changed)); ur_manager->connect("version_changed", callable_mp(this, &HistoryDock::on_version_changed)); diff --git a/editor/import/post_import_plugin_skeleton_renamer.cpp b/editor/import/post_import_plugin_skeleton_renamer.cpp index 72ccb832c7..c2694329c2 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.cpp +++ b/editor/import/post_import_plugin_skeleton_renamer.cpp @@ -44,100 +44,164 @@ void PostImportPluginSkeletonRenamer::get_internal_import_options(InternalImport } } -void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { - if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { - // Prepare objects. - Object *map = p_options["retarget/bone_map"].get_validated_object(); - if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { - return; - } - BoneMap *bone_map = Object::cast_to<BoneMap>(map); - Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); +void PostImportPluginSkeletonRenamer::_internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options, HashMap<String, String> p_rename_map) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { + return; + } + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); - // Rename bones in Skeleton3D. - { - int len = skeleton->get_bone_count(); - for (int i = 0; i < len; i++) { - StringName bn = bone_map->find_profile_bone_name(skeleton->get_bone_name(i)); - if (bn) { - skeleton->set_bone_name(i, bn); - } + // Rename bones in Skeleton3D. + { + int len = skeleton->get_bone_count(); + for (int i = 0; i < len; i++) { + StringName bn = p_rename_map[skeleton->get_bone_name(i)]; + if (bn) { + skeleton->set_bone_name(i, bn); } } + } - // Rename bones in Skin. - { - TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D"); - while (nodes.size()) { - ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back()); - Ref<Skin> skin = mi->get_skin(); - if (skin.is_valid()) { - Node *node = mi->get_node(mi->get_skeleton_path()); - if (node) { - Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node); - if (mesh_skeleton && node == skeleton) { - int len = skin->get_bind_count(); - for (int i = 0; i < len; i++) { - StringName bn = bone_map->find_profile_bone_name(skin->get_bind_name(i)); - if (bn) { - skin->set_bind_name(i, bn); - } + // Rename bones in Skin. + { + TypedArray<Node> nodes = p_base_scene->find_children("*", "ImporterMeshInstance3D"); + while (nodes.size()) { + ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(nodes.pop_back()); + Ref<Skin> skin = mi->get_skin(); + if (skin.is_valid()) { + Node *node = mi->get_node(mi->get_skeleton_path()); + if (node) { + Skeleton3D *mesh_skeleton = Object::cast_to<Skeleton3D>(node); + if (mesh_skeleton && node == skeleton) { + int len = skin->get_bind_count(); + for (int i = 0; i < len; i++) { + StringName bn = p_rename_map[skin->get_bind_name(i)]; + if (bn) { + skin->set_bind_name(i, bn); } } } } } } + } - // Rename bones in AnimationPlayer. - { - TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); - while (nodes.size()) { - AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); - List<StringName> anims; - ap->get_animation_list(&anims); - for (const StringName &name : anims) { - Ref<Animation> anim = ap->get_animation(name); - int len = anim->get_track_count(); - for (int i = 0; i < len; i++) { - if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { - continue; - } - String track_path = String(anim->track_get_path(i).get_concatenated_names()); - Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); - if (node) { - Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); - if (track_skeleton && track_skeleton == skeleton) { - StringName bn = bone_map->find_profile_bone_name(anim->track_get_path(i).get_subname(0)); - if (bn) { - anim->track_set_path(i, track_path + ":" + bn); - } + // Rename bones in AnimationPlayer. + { + TypedArray<Node> nodes = p_base_scene->find_children("*", "AnimationPlayer"); + while (nodes.size()) { + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(nodes.pop_back()); + List<StringName> anims; + ap->get_animation_list(&anims); + for (const StringName &name : anims) { + Ref<Animation> anim = ap->get_animation(name); + int len = anim->get_track_count(); + for (int i = 0; i < len; i++) { + if (anim->track_get_path(i).get_subname_count() != 1 || !(anim->track_get_type(i) == Animation::TYPE_POSITION_3D || anim->track_get_type(i) == Animation::TYPE_ROTATION_3D || anim->track_get_type(i) == Animation::TYPE_SCALE_3D)) { + continue; + } + String track_path = String(anim->track_get_path(i).get_concatenated_names()); + Node *node = (ap->get_node(ap->get_root()))->get_node(NodePath(track_path)); + if (node) { + Skeleton3D *track_skeleton = Object::cast_to<Skeleton3D>(node); + if (track_skeleton && track_skeleton == skeleton) { + StringName bn = p_rename_map[anim->track_get_path(i).get_subname(0)]; + if (bn) { + anim->track_set_path(i, track_path + ":" + bn); } } } } } } + } + + // Rename bones in all Nodes by calling method. + { + Vector<Variant> vargs; + vargs.push_back(p_base_scene); + vargs.push_back(skeleton); + Dictionary rename_map_dict; + for (HashMap<String, String>::Iterator E = p_rename_map.begin(); E; ++E) { + rename_map_dict[E->key] = E->value; + } + vargs.push_back(rename_map_dict); + const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * vargs.size()); + const Variant *args = vargs.ptr(); + uint32_t argcount = vargs.size(); + for (uint32_t i = 0; i < argcount; i++) { + argptrs[i] = &args[i]; + } + + TypedArray<Node> nodes = p_base_scene->find_children("*"); + while (nodes.size()) { + Node *nd = Object::cast_to<Node>(nodes.pop_back()); + Callable::CallError ce; + nd->callp("_notify_skeleton_bones_renamed", argptrs, argcount, ce); + } + } +} + +void PostImportPluginSkeletonRenamer::internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) { + if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) { + // Prepare objects. + Object *map = p_options["retarget/bone_map"].get_validated_object(); + if (!map || !bool(p_options["retarget/bone_renamer/rename_bones"])) { + return; + } + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node); + BoneMap *bone_map = Object::cast_to<BoneMap>(map); + int len = skeleton->get_bone_count(); + + // First, prepare main rename map. + HashMap<String, String> main_rename_map; + for (int i = 0; i < len; i++) { + String bone_name = skeleton->get_bone_name(i); + String target_name = bone_map->find_profile_bone_name(bone_name); + if (target_name.is_empty()) { + continue; + } + main_rename_map.insert(bone_name, target_name); + } - // Rename bones in all Nodes by calling method. + // Preprocess of renaming bones to avoid to conflict with original bone name. + HashMap<String, String> pre_rename_map; // HashMap<skeleton bone name, target(profile) bone name> { - Vector<Variant> vargs; - vargs.push_back(p_base_scene); - vargs.push_back(skeleton); - vargs.push_back(bone_map); - const Variant **argptrs = (const Variant **)alloca(sizeof(const Variant **) * vargs.size()); - const Variant *args = vargs.ptr(); - uint32_t argcount = vargs.size(); - for (uint32_t i = 0; i < argcount; i++) { - argptrs[i] = &args[i]; + Vector<String> solved_name_stack; + for (int i = 0; i < len; i++) { + String bone_name = skeleton->get_bone_name(i); + String target_name = bone_map->find_profile_bone_name(bone_name); + if (target_name.is_empty() || bone_name == target_name || skeleton->find_bone(target_name) == -1) { + continue; // No conflicting. + } + + // Solve conflicting. + Ref<SkeletonProfile> profile = bone_map->get_profile(); + String solved_name = target_name; + for (int j = 2; skeleton->find_bone(solved_name) >= 0 || profile->find_bone(solved_name) >= 0 || solved_name_stack.has(solved_name); j++) { + solved_name = target_name + itos(j); + } + solved_name_stack.push_back(solved_name); + pre_rename_map.insert(target_name, solved_name); } + _internal_process(p_category, p_base_scene, p_node, p_resource, p_options, pre_rename_map); + } - TypedArray<Node> nodes = p_base_scene->find_children("*"); - while (nodes.size()) { - Node *nd = Object::cast_to<Node>(nodes.pop_back()); - Callable::CallError ce; - nd->callp("_notify_skeleton_bones_renamed", argptrs, argcount, ce); + // Main process of renaming bones. + { + // Apply pre-renaming result to prepared main rename map. + Vector<String> remove_queue; + for (HashMap<String, String>::Iterator E = main_rename_map.begin(); E; ++E) { + if (pre_rename_map.has(E->key)) { + remove_queue.push_back(E->key); + } + } + for (int i = 0; i < remove_queue.size(); i++) { + main_rename_map.insert(pre_rename_map[remove_queue[i]], main_rename_map[remove_queue[i]]); + main_rename_map.erase(remove_queue[i]); } + _internal_process(p_category, p_base_scene, p_node, p_resource, p_options, main_rename_map); } // Make unique skeleton. diff --git a/editor/import/post_import_plugin_skeleton_renamer.h b/editor/import/post_import_plugin_skeleton_renamer.h index 73cbabd1c5..b430f49ff4 100644 --- a/editor/import/post_import_plugin_skeleton_renamer.h +++ b/editor/import/post_import_plugin_skeleton_renamer.h @@ -40,6 +40,8 @@ public: virtual void get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) override; virtual void internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options) override; + void _internal_process(InternalImportCategory p_category, Node *p_base_scene, Node *p_node, Ref<Resource> p_resource, const Dictionary &p_options, HashMap<String, String> p_rename_map); + PostImportPluginSkeletonRenamer(); }; diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index d8524a7392..9cf10dbef1 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -375,7 +375,7 @@ void BoneAttachment3D::on_bone_pose_update(int p_bone_index) { } } #ifdef TOOLS_ENABLED -void BoneAttachment3D::_notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Ref<BoneMap> p_bone_map) { +void BoneAttachment3D::_notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Dictionary p_rename_map) { const Skeleton3D *parent = nullptr; if (use_external_skeleton) { if (external_skeleton_node_cache.is_valid()) { @@ -385,7 +385,7 @@ void BoneAttachment3D::_notify_skeleton_bones_renamed(Node *p_base_scene, Skelet parent = Object::cast_to<Skeleton3D>(get_parent()); } if (parent && parent == p_skeleton) { - StringName bn = p_bone_map->find_profile_bone_name(bone_name); + StringName bn = p_rename_map[bone_name]; if (bn) { set_bone_name(bn); } diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index 2db6ba6268..81338b30e9 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -72,7 +72,7 @@ protected: static void _bind_methods(); #ifdef TOOLS_ENABLED - virtual void _notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Ref<BoneMap> p_bone_map); + virtual void _notify_skeleton_bones_renamed(Node *p_base_scene, Skeleton3D *p_skeleton, Dictionary p_rename_map); #endif // TOOLS_ENABLED public: diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index a1f962c690..b205c2cde0 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -541,7 +541,7 @@ void Skeleton3D::set_bone_name(int p_bone, const String &p_name) { for (int i = 0; i < bone_size; i++) { if (i != p_bone) { - ERR_FAIL_COND(bones[i].name == p_name); + ERR_FAIL_COND_MSG(bones[i].name == p_name, "Skeleton3D: '" + get_name() + "', bone name: '" + p_name + "' is already exist."); } } diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 0f55c7b3b8..ee45a8ea6f 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -960,6 +960,7 @@ void register_scene_types() { ClassDB::add_compatibility_class("Navigation3D", "Node3D"); ClassDB::add_compatibility_class("Navigation2D", "Node2D"); ClassDB::add_compatibility_class("OpenSimplexNoise", "FastNoiseLite"); + ClassDB::add_compatibility_class("ProximityGroup", "Node3D"); ClassDB::add_compatibility_class("ToolButton", "Button"); ClassDB::add_compatibility_class("YSort", "Node2D"); // Portal and room occlusion was replaced by raster occlusion (OccluderInstance3D node). diff --git a/servers/rendering/shader_language.cpp b/servers/rendering/shader_language.cpp index 92e172494e..497e4476d0 100644 --- a/servers/rendering/shader_language.cpp +++ b/servers/rendering/shader_language.cpp @@ -4309,8 +4309,18 @@ ShaderLanguage::DataType ShaderLanguage::get_scalar_type(DataType p_type) { TYPE_INT, TYPE_UINT, TYPE_FLOAT, + TYPE_INT, + TYPE_UINT, + TYPE_FLOAT, + TYPE_INT, + TYPE_UINT, + TYPE_FLOAT, + TYPE_FLOAT, + TYPE_VOID, }; + static_assert(sizeof(scalar_types) / sizeof(*scalar_types) == TYPE_MAX); + return scalar_types[p_type]; } @@ -4340,8 +4350,18 @@ int ShaderLanguage::get_cardinality(DataType p_type) { 1, 1, 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, }; + static_assert(sizeof(cardinality_table) / sizeof(*cardinality_table) == TYPE_MAX); + return cardinality_table[p_type]; } |