diff options
Diffstat (limited to 'editor/import')
-rw-r--r-- | editor/import/editor_import_collada.cpp | 4 | ||||
-rw-r--r-- | editor/import/editor_importer_bake_reset.cpp | 223 | ||||
-rw-r--r-- | editor/import/editor_importer_bake_reset.h | 54 | ||||
-rw-r--r-- | editor/import/resource_importer_obj.cpp | 5 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.cpp | 66 | ||||
-rw-r--r-- | editor/import/resource_importer_scene.h | 3 | ||||
-rw-r--r-- | editor/import/scene_import_settings.cpp | 32 | ||||
-rw-r--r-- | editor/import/scene_importer_mesh.cpp | 8 |
8 files changed, 339 insertions, 56 deletions
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index ddf89f077b..b615c73422 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -894,8 +894,8 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<EditorSceneImpor surftool->add_vertex(vertex_array[k].vertex); } - for (List<int>::Element *E = indices_list.front(); E; E = E->next()) { - surftool->add_index(E->get()); + for (int &E : indices_list) { + surftool->add_index(E); } if (!normal_src) { diff --git a/editor/import/editor_importer_bake_reset.cpp b/editor/import/editor_importer_bake_reset.cpp new file mode 100644 index 0000000000..939c47faa4 --- /dev/null +++ b/editor/import/editor_importer_bake_reset.cpp @@ -0,0 +1,223 @@ +/*************************************************************************/ +/* editor_importer_bake_reset.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "editor/import/editor_importer_bake_reset.h" + +#include "core/error/error_macros.h" +#include "core/math/transform_3d.h" +#include "editor/import/scene_importer_mesh_node_3d.h" +#include "resource_importer_scene.h" +#include "scene/3d/mesh_instance_3d.h" +#include "scene/3d/node_3d.h" +#include "scene/3d/skeleton_3d.h" +#include "scene/animation/animation_player.h" + +// Given that an engineering team has made a reference character, one wants ten animators to create animations. +// Currently, a tech artist needs to combine the ten files into one exported gltf2 to import into Godot Engine. +// We bake the RESET animation and then set it to identity, +// so that rigs with corresponding RESET animation can have their animations transferred with ease. +// +// The original algorithm for the code was used to change skeleton bone rolls to be parent to child. +// +// Reference https://github.com/godotengine/godot-proposals/issues/2961 +void BakeReset::_bake_animation_pose(Node *scene, const String &p_bake_anim) { + Map<StringName, BakeResetRestBone> r_rest_bones; + Vector<Node3D *> r_meshes; + List<Node *> queue; + queue.push_back(scene); + while (!queue.is_empty()) { + List<Node *>::Element *E = queue.front(); + Node *node = E->get(); + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(node); + // Step 1: import scene with animations into the rest bones data structure. + _fetch_reset_animation(ap, r_rest_bones, p_bake_anim); + + int child_count = node->get_child_count(); + for (int i = 0; i < child_count; i++) { + queue.push_back(node->get_child(i)); + } + queue.pop_front(); + } + + queue.push_back(scene); + while (!queue.is_empty()) { + List<Node *>::Element *E = queue.front(); + Node *node = E->get(); + EditorSceneImporterMeshNode3D *editor_mesh_3d = scene->cast_to<EditorSceneImporterMeshNode3D>(node); + MeshInstance3D *mesh_3d = scene->cast_to<MeshInstance3D>(node); + if (scene->cast_to<Skeleton3D>(node)) { + Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(node); + + // Step 2: Bake the RESET animation from the RestBone to the skeleton. + _fix_skeleton(skeleton, r_rest_bones); + } + if (editor_mesh_3d) { + NodePath path = editor_mesh_3d->get_skeleton_path(); + if (!path.is_empty() && editor_mesh_3d->get_node_or_null(path) && Object::cast_to<Skeleton3D>(editor_mesh_3d->get_node_or_null(path))) { + r_meshes.push_back(editor_mesh_3d); + } + } else if (mesh_3d) { + NodePath path = mesh_3d->get_skeleton_path(); + if (!path.is_empty() && mesh_3d->get_node_or_null(path) && Object::cast_to<Skeleton3D>(mesh_3d->get_node_or_null(path))) { + r_meshes.push_back(mesh_3d); + } + } + int child_count = node->get_child_count(); + for (int i = 0; i < child_count; i++) { + queue.push_back(node->get_child(i)); + } + queue.pop_front(); + } + + queue.push_back(scene); + while (!queue.is_empty()) { + List<Node *>::Element *E = queue.front(); + Node *node = E->get(); + AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(node); + if (ap) { + // Step 3: Key all RESET animation frames to identity. + _align_animations(ap, r_rest_bones); + } + + int child_count = node->get_child_count(); + for (int i = 0; i < child_count; i++) { + queue.push_back(node->get_child(i)); + } + queue.pop_front(); + } +} + +void BakeReset::_align_animations(AnimationPlayer *p_ap, const Map<StringName, BakeResetRestBone> &r_rest_bones) { + ERR_FAIL_NULL(p_ap); + List<StringName> anim_names; + p_ap->get_animation_list(&anim_names); + for (List<StringName>::Element *anim_i = anim_names.front(); anim_i; anim_i = anim_i->next()) { + Ref<Animation> a = p_ap->get_animation(anim_i->get()); + ERR_CONTINUE(a.is_null()); + for (Map<StringName, BakeResetRestBone>::Element *rest_bone_i = r_rest_bones.front(); rest_bone_i; rest_bone_i = rest_bone_i->next()) { + int track = a->find_track(NodePath(rest_bone_i->key())); + if (track == -1) { + continue; + } + int new_track = a->add_track(Animation::TYPE_TRANSFORM3D); + NodePath new_path = NodePath(rest_bone_i->key()); + BakeResetRestBone rest_bone = rest_bone_i->get(); + a->track_set_path(new_track, new_path); + for (int key_i = 0; key_i < a->track_get_key_count(track); key_i++) { + Vector3 loc; + Quaternion rot; + Vector3 scale; + Error err = a->transform_track_get_key(track, key_i, &loc, &rot, &scale); + ERR_CONTINUE(err); + real_t time = a->track_get_key_time(track, key_i); + rot.normalize(); + loc = loc - rest_bone.loc; + rot = rest_bone.rest_delta.get_rotation_quaternion().inverse() * rot; + rot.normalize(); + scale = Vector3(1, 1, 1) - (rest_bone.rest_delta.get_scale() - scale); + // Apply the reverse of the rest changes to make the key be close to identity transform. + a->transform_track_insert_key(new_track, time, loc, rot, scale); + } + a->remove_track(track); + } + } +} + +void BakeReset::_fetch_reset_animation(AnimationPlayer *p_ap, Map<StringName, BakeResetRestBone> &r_rest_bones, const String &p_bake_anim) { + ERR_FAIL_NULL(p_ap); + List<StringName> anim_names; + p_ap->get_animation_list(&anim_names); + Node *root = p_ap->get_owner(); + ERR_FAIL_NULL(root); + Ref<Animation> a = p_ap->get_animation(p_bake_anim); + ERR_FAIL_NULL(a); + for (int32_t track = 0; track < a->get_track_count(); track++) { + NodePath path = a->track_get_path(track); + String string_path = path; + Skeleton3D *skeleton = root->cast_to<Skeleton3D>(root->get_node(string_path.get_slice(":", 0))); + if (!skeleton) { + continue; + } + String bone_name = string_path.get_slice(":", 1); + for (int key_i = 0; key_i < a->track_get_key_count(track); key_i++) { + Vector3 loc; + Quaternion rot; + Vector3 scale; + Error err = a->transform_track_get_key(track, key_i, &loc, &rot, &scale); + ERR_CONTINUE(err); + rot.normalize(); + Basis rot_basis = Basis(rot, scale); + BakeResetRestBone rest_bone; + rest_bone.rest_delta = rot_basis; + rest_bone.loc = loc; + // Store the animation into the RestBone. + r_rest_bones[StringName(String(skeleton->get_owner()->get_path_to(skeleton)) + ":" + bone_name)] = rest_bone; + break; + } + } +} + +void BakeReset::_fix_skeleton(Skeleton3D *p_skeleton, Map<StringName, BakeReset::BakeResetRestBone> &r_rest_bones) { + int bone_count = p_skeleton->get_bone_count(); + + // First iterate through all the bones and update the RestBone. + for (int j = 0; j < bone_count; j++) { + StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(j); + BakeResetRestBone &rest_bone = r_rest_bones[final_path]; + rest_bone.rest_local = p_skeleton->get_bone_rest(j); + } + for (int i = 0; i < bone_count; i++) { + int parent_bone = p_skeleton->get_bone_parent(i); + String path = p_skeleton->get_owner()->get_path_to(p_skeleton); + StringName final_path = String(path) + String(":") + p_skeleton->get_bone_name(parent_bone); + if (parent_bone >= 0) { + r_rest_bones[path].children.push_back(i); + } + } + + // When we apply transform to a bone, we also have to move all of its children in the opposite direction. + for (int i = 0; i < bone_count; i++) { + StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(i); + r_rest_bones[final_path].rest_local = r_rest_bones[final_path].rest_local * Transform3D(r_rest_bones[final_path].rest_delta, r_rest_bones[final_path].loc); + // Iterate through the children and move in the opposite direction. + for (int j = 0; j < r_rest_bones[final_path].children.size(); j++) { + int child_index = r_rest_bones[final_path].children[j]; + StringName children_path = String(p_skeleton->get_name()) + String(":") + p_skeleton->get_bone_name(child_index); + r_rest_bones[children_path].rest_local = Transform3D(r_rest_bones[final_path].rest_delta, r_rest_bones[final_path].loc).affine_inverse() * r_rest_bones[children_path].rest_local; + } + } + + for (int i = 0; i < bone_count; i++) { + StringName final_path = String(p_skeleton->get_owner()->get_path_to(p_skeleton)) + String(":") + p_skeleton->get_bone_name(i); + ERR_CONTINUE(!r_rest_bones.has(final_path)); + Transform3D rest_transform = r_rest_bones[final_path].rest_local; + p_skeleton->set_bone_rest(i, rest_transform); + } +} diff --git a/editor/import/editor_importer_bake_reset.h b/editor/import/editor_importer_bake_reset.h new file mode 100644 index 0000000000..e36ae86181 --- /dev/null +++ b/editor/import/editor_importer_bake_reset.h @@ -0,0 +1,54 @@ +/*************************************************************************/ +/* editor_importer_bake_reset.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef RESOURCE_IMPORTER_BAKE_RESET_H +#define RESOURCE_IMPORTER_BAKE_RESET_H + +#include "scene/main/node.h" + +class Skeleton3D; +class AnimationPlayer; +class BakeReset { + struct BakeResetRestBone { + Transform3D rest_local; + Basis rest_delta; + Vector3 loc; + Vector<int> children; + }; + +public: + void _bake_animation_pose(Node *scene, const String &p_bake_anim); + +private: + void _fix_skeleton(Skeleton3D *p_skeleton, Map<StringName, BakeReset::BakeResetRestBone> &r_rest_bones); + void _align_animations(AnimationPlayer *p_ap, const Map<StringName, BakeResetRestBone> &r_rest_bones); + void _fetch_reset_animation(AnimationPlayer *p_ap, Map<StringName, BakeResetRestBone> &r_rest_bones, const String &p_bake_anim); +}; +#endif diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp index 01603c0a6a..34bc0a7d8d 100644 --- a/editor/import/resource_importer_obj.cpp +++ b/editor/import/resource_importer_obj.cpp @@ -438,17 +438,16 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in Node3D *scene = memnew(Node3D); - for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) { + for (const Ref<Mesh> &m : meshes) { Ref<EditorSceneImporterMesh> mesh; mesh.instantiate(); - Ref<Mesh> m = E->get(); for (int i = 0; i < m->get_surface_count(); i++) { mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i)); } EditorSceneImporterMeshNode3D *mi = memnew(EditorSceneImporterMeshNode3D); mi->set_mesh(mesh); - mi->set_name(E->get()->get_name()); + mi->set_name(m->get_name()); scene->add_child(mi); mi->set_owner(scene); } diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index c14b948dae..1e642462dc 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -32,6 +32,7 @@ #include "core/io/resource_saver.h" #include "editor/editor_node.h" +#include "editor/import/editor_importer_bake_reset.h" #include "editor/import/scene_import_settings.h" #include "editor/import/scene_importer_mesh_node_3d.h" #include "scene/3d/area_3d.h" @@ -312,8 +313,8 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - Ref<Animation> anim = ap->get_animation(E->get()); + for (const StringName &E : anims) { + Ref<Animation> anim = ap->get_animation(E); ERR_CONTINUE(anim.is_null()); for (int i = 0; i < anim->get_track_count(); i++) { NodePath path = anim->track_get_path(i); @@ -328,14 +329,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<E } } - String animname = E->get(); + String animname = E; const int loop_string_count = 3; static const char *loop_strings[loop_string_count] = { "loops", "loop", "cycle" }; for (int i = 0; i < loop_string_count; i++) { if (_teststr(animname, loop_strings[i])) { anim->set_loop(true); animname = _fixstr(animname, loop_strings[i]); - ap->rename_animation(E->get(), animname); + ap->rename_animation(E, animname); } } } @@ -659,9 +660,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } int idx = 0; - for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) { + for (const Ref<Shape3D> &E : shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); - cshape->set_shape(E->get()); + cshape->set_shape(E); base->add_child(cshape); cshape->set_owner(base->get_owner()); @@ -712,9 +713,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< //fill node settings for this node with default values List<ImportOption> iopts; get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION_NODE, &iopts); - for (List<ImportOption>::Element *E = iopts.front(); E; E = E->next()) { - if (!node_settings.has(E->get().option.name)) { - node_settings[E->get().option.name] = E->get().default_value; + for (const ImportOption &E : iopts) { + if (!node_settings.has(E.option.name)) { + node_settings[E.option.name] = E.default_value; } } } @@ -756,8 +757,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< } else { List<StringName> anims; ap->get_animation_list(&anims); - for (List<StringName>::Element *E = anims.front(); E; E = E->next()) { - String name = E->get(); + for (const StringName &name : anims) { Ref<Animation> anim = ap->get_animation(name); if (p_animation_data.has(name)) { Dictionary anim_settings = p_animation_data[name]; @@ -765,9 +765,9 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, Map<Ref< //fill with default values List<ImportOption> iopts; get_internal_import_options(INTERNAL_IMPORT_CATEGORY_ANIMATION, &iopts); - for (List<ImportOption>::Element *F = iopts.front(); F; F = F->next()) { - if (!anim_settings.has(F->get().option.name)) { - anim_settings[F->get().option.name] = F->get().default_value; + for (const ImportOption &F : iopts) { + if (!anim_settings.has(F.option.name)) { + anim_settings[F.option.name] = F.default_value; } } } @@ -936,8 +936,8 @@ void ResourceImporterScene::_create_clips(AnimationPlayer *anim, const Array &p_ void ResourceImporterScene::_optimize_animations(AnimationPlayer *anim, float p_max_lin_error, float p_max_ang_error, float p_max_angle) { List<StringName> anim_names; anim->get_animation_list(&anim_names); - for (List<StringName>::Element *E = anim_names.front(); E; E = E->next()) { - Ref<Animation> a = anim->get_animation(E->get()); + for (const StringName &E : anim_names) { + Ref<Animation> a = anim->get_animation(E); a->optimize(p_max_lin_error, p_max_ang_error, Math::deg2rad(p_max_angle)); } } @@ -1046,11 +1046,11 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in String script_ext_hint; - for (List<String>::Element *E = script_extentions.front(); E; E = E->next()) { + for (const String &E : script_extentions) { if (script_ext_hint != "") { script_ext_hint += ","; } - script_ext_hint += "*." + E->get(); + script_ext_hint += "*." + E; } r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "nodes/root_scale", PROPERTY_HINT_RANGE, "0.001,1000,0.001"), 1.0)); @@ -1061,6 +1061,7 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "meshes/lightmap_texel_size", PROPERTY_HINT_RANGE, "0.001,100,0.001"), 0.1)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "skins/use_named_skins"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true)); + r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/bake_reset_animation"), true)); r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15)); r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), "")); @@ -1089,9 +1090,9 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { - importer = E->get(); + for (const String &F : extensions) { + if (F.to_lower() == ext) { + importer = E; break; } } @@ -1119,9 +1120,9 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { - importer = E->get(); + for (const String &F : extensions) { + if (F.to_lower() == ext) { + importer = E; break; } } @@ -1291,9 +1292,9 @@ void ResourceImporterScene::_generate_meshes(Node *p_node, const Dictionary &p_m } void ResourceImporterScene::_add_shapes(Node *p_node, const List<Ref<Shape3D>> &p_shapes) { - for (const List<Ref<Shape3D>>::Element *E = p_shapes.front(); E; E = E->next()) { + for (const Ref<Shape3D> &E : p_shapes) { CollisionShape3D *cshape = memnew(CollisionShape3D); - cshape->set_shape(E->get()); + cshape->set_shape(E); p_node->add_child(cshape); cshape->set_owner(p_node->get_owner()); @@ -1311,8 +1312,8 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) { List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { + for (const String &F : extensions) { + if (F.to_lower() == ext) { importer = E->get(); break; } @@ -1351,8 +1352,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p List<String> extensions; E->get()->get_extensions(&extensions); - for (List<String>::Element *F = extensions.front(); F; F = F->next()) { - if (F->get().to_lower() == ext) { + for (const String &F : extensions) { + if (F.to_lower() == ext) { importer = E->get(); break; } @@ -1411,6 +1412,11 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p _pre_fix_node(scene, scene, collision_map); _post_fix_node(scene, scene, collision_map, scanned_meshes, node_data, material_data, animation_data, fps); + bool use_bake_reset_animation = p_options["animation/bake_reset_animation"]; + if (use_bake_reset_animation) { + BakeReset bake_reset; + bake_reset._bake_animation_pose(scene, "RESET"); + } String root_type = p_options["nodes/root_type"]; root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class. diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h index c6e5836a23..781beff689 100644 --- a/editor/import/resource_importer_scene.h +++ b/editor/import/resource_importer_scene.h @@ -155,7 +155,8 @@ public: virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const override; virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const override; - virtual int get_import_order() const override { return 100; } //after everything + // Import scenes *after* everything else (such as textures). + virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; } Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map); Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<EditorSceneImporterMesh>, List<Ref<Shape3D>>> &collision_map, Set<Ref<EditorSceneImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps); diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp index 5dc494d6df..19a8f209bb 100644 --- a/editor/import/scene_import_settings.cpp +++ b/editor/import/scene_import_settings.cpp @@ -71,9 +71,9 @@ class SceneImportSettingsData : public Object { return false; } void _get_property_list(List<PropertyInfo> *p_list) const { - for (const List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - if (ResourceImporterScene::get_singleton()->get_internal_option_visibility(category, E->get().option.name, current)) { - p_list->push_back(E->get().option); + for (const ResourceImporter::ImportOption &E : options) { + if (ResourceImporterScene::get_singleton()->get_internal_option_visibility(category, E.option.name, current)) { + p_list->push_back(E.option); } } } @@ -305,8 +305,8 @@ void SceneImportSettings::_fill_scene(Node *p_node, TreeItem *p_parent_item) { if (anim_node) { List<StringName> animations; anim_node->get_animation_list(&animations); - for (List<StringName>::Element *E = animations.front(); E; E = E->next()) { - _fill_animation(scene_tree, anim_node->get_animation(E->get()), E->get(), item); + for (const StringName &E : animations) { + _fill_animation(scene_tree, anim_node->get_animation(E), E, item); } } @@ -394,8 +394,8 @@ void SceneImportSettings::_load_default_subresource_settings(Map<StringName, Var d = d[p_import_id]; List<ResourceImporterScene::ImportOption> options; ResourceImporterScene::get_singleton()->get_internal_import_options(p_category, &options); - for (List<ResourceImporterScene::ImportOption>::Element *E = options.front(); E; E = E->next()) { - String key = E->get().option.name; + for (const ResourceImporterScene::ImportOption &E : options) { + String key = E.option.name; if (d.has(key)) { settings[key] = d[key]; } @@ -440,12 +440,12 @@ void SceneImportSettings::open_settings(const String &p_path) { if (err == OK) { List<String> keys; config->get_section_keys("params", &keys); - for (List<String>::Element *E = keys.front(); E; E = E->next()) { - Variant value = config->get_value("params", E->get()); - if (E->get() == "_subresources") { + for (const String &E : keys) { + Variant value = config->get_value("params", E); + if (E == "_subresources") { base_subresource_settings = value; } else { - defaults[E->get()] = value; + defaults[E] = value; } } } @@ -605,13 +605,13 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) { scene_import_settings_data->defaults.clear(); scene_import_settings_data->current.clear(); - for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) { - scene_import_settings_data->defaults[E->get().option.name] = E->get().default_value; + for (const ResourceImporter::ImportOption &E : options) { + scene_import_settings_data->defaults[E.option.name] = E.default_value; //needed for visibility toggling (fails if something is missing) - if (scene_import_settings_data->settings->has(E->get().option.name)) { - scene_import_settings_data->current[E->get().option.name] = (*scene_import_settings_data->settings)[E->get().option.name]; + if (scene_import_settings_data->settings->has(E.option.name)) { + scene_import_settings_data->current[E.option.name] = (*scene_import_settings_data->settings)[E.option.name]; } else { - scene_import_settings_data->current[E->get().option.name] = E->get().default_value; + scene_import_settings_data->current[E.option.name] = E.default_value; } } scene_import_settings_data->options = options; diff --git a/editor/import/scene_importer_mesh.cpp b/editor/import/scene_importer_mesh.cpp index f8e93df382..0d14347225 100644 --- a/editor/import/scene_importer_mesh.cpp +++ b/editor/import/scene_importer_mesh.cpp @@ -79,11 +79,11 @@ void EditorSceneImporterMesh::add_surface(Mesh::PrimitiveType p_primitive, const List<Variant> lods; p_lods.get_key_list(&lods); - for (List<Variant>::Element *E = lods.front(); E; E = E->next()) { - ERR_CONTINUE(!E->get().is_num()); + for (const Variant &E : lods) { + ERR_CONTINUE(!E.is_num()); Surface::LOD lod; - lod.distance = E->get(); - lod.indices = p_lods[E->get()]; + lod.distance = E; + lod.indices = p_lods[E]; ERR_CONTINUE(lod.indices.size() == 0); s.lods.push_back(lod); } |