Fix import hints breaking node paths in animations
This commit is contained in:
parent
567b600362
commit
1cdad6c5bb
|
@ -370,16 +370,17 @@ static void _pre_gen_shape_list(Ref<ImporterMesh> &mesh, Vector<Ref<Shape3D>> &r
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map) {
|
Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames) {
|
||||||
// children first
|
// Children first.
|
||||||
for (int i = 0; i < p_node->get_child_count(); i++) {
|
for (int i = 0; i < p_node->get_child_count(); i++) {
|
||||||
Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map);
|
Node *r = _pre_fix_node(p_node->get_child(i), p_root, collision_map, r_node_renames);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
i--; //was erased
|
i--; // Was erased.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String name = p_node->get_name();
|
String name = p_node->get_name();
|
||||||
|
NodePath original_path = p_root->get_path_to(p_node); // Used to detect renames due to import hints.
|
||||||
|
|
||||||
bool isroot = p_node == p_root;
|
bool isroot = p_node == p_root;
|
||||||
|
|
||||||
|
@ -414,14 +415,21 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Object::cast_to<AnimationPlayer>(p_node)) {
|
if (Object::cast_to<AnimationPlayer>(p_node)) {
|
||||||
//remove animations referencing non-importable nodes
|
|
||||||
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
|
AnimationPlayer *ap = Object::cast_to<AnimationPlayer>(p_node);
|
||||||
|
|
||||||
|
// Node paths in animation tracks are relative to the following path (this is used to fix node paths below).
|
||||||
|
Node *ap_root = ap->get_node(ap->get_root());
|
||||||
|
NodePath path_prefix = p_root->get_path_to(ap_root);
|
||||||
|
|
||||||
|
bool nodes_were_renamed = r_node_renames.size() != 0;
|
||||||
|
|
||||||
List<StringName> anims;
|
List<StringName> anims;
|
||||||
ap->get_animation_list(&anims);
|
ap->get_animation_list(&anims);
|
||||||
for (const StringName &E : anims) {
|
for (const StringName &E : anims) {
|
||||||
Ref<Animation> anim = ap->get_animation(E);
|
Ref<Animation> anim = ap->get_animation(E);
|
||||||
ERR_CONTINUE(anim.is_null());
|
ERR_CONTINUE(anim.is_null());
|
||||||
|
|
||||||
|
// Remove animation tracks referencing non-importable nodes.
|
||||||
for (int i = 0; i < anim->get_track_count(); i++) {
|
for (int i = 0; i < anim->get_track_count(); i++) {
|
||||||
NodePath path = anim->track_get_path(i);
|
NodePath path = anim->track_get_path(i);
|
||||||
|
|
||||||
|
@ -435,6 +443,27 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fix node paths in animations, in case nodes were renamed earlier due to import hints.
|
||||||
|
if (nodes_were_renamed) {
|
||||||
|
for (int i = 0; i < anim->get_track_count(); i++) {
|
||||||
|
NodePath path = anim->track_get_path(i);
|
||||||
|
// Convert track path to absolute node path without subnames (some manual work because we are not in the scene tree).
|
||||||
|
Vector<StringName> absolute_path_names = path_prefix.get_names();
|
||||||
|
absolute_path_names.append_array(path.get_names());
|
||||||
|
NodePath absolute_path(absolute_path_names, false);
|
||||||
|
absolute_path.simplify();
|
||||||
|
// Fix paths to renamed nodes.
|
||||||
|
for (const Pair<NodePath, Node *> &F : r_node_renames) {
|
||||||
|
if (F.first == absolute_path) {
|
||||||
|
NodePath new_path(ap_root->get_path_to(F.second).get_names(), path.get_subnames(), false);
|
||||||
|
print_verbose(vformat("Fix: Correcting node path in animation track: %s should be %s", path, new_path));
|
||||||
|
anim->track_set_path(i, new_path);
|
||||||
|
break; // Only one match is possible.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String animname = E;
|
String animname = E;
|
||||||
const int loop_string_count = 3;
|
const int loop_string_count = 3;
|
||||||
static const char *loop_strings[loop_string_count] = { "loop_mode", "loop", "cycle" };
|
static const char *loop_strings[loop_string_count] = { "loop_mode", "loop", "cycle" };
|
||||||
|
@ -452,13 +481,22 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
if (isroot) {
|
if (isroot) {
|
||||||
return p_node;
|
return p_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String fixed_name;
|
||||||
|
if (_teststr(name, "colonly")) {
|
||||||
|
fixed_name = _fixstr(name, "colonly");
|
||||||
|
} else if (_teststr(name, "convcolonly")) {
|
||||||
|
fixed_name = _fixstr(name, "convcolonly");
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(fixed_name.is_empty(), nullptr);
|
||||||
|
|
||||||
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
|
ImporterMeshInstance3D *mi = Object::cast_to<ImporterMeshInstance3D>(p_node);
|
||||||
if (mi) {
|
if (mi) {
|
||||||
Ref<ImporterMesh> mesh = mi->get_mesh();
|
Ref<ImporterMesh> mesh = mi->get_mesh();
|
||||||
|
|
||||||
if (mesh.is_valid()) {
|
if (mesh.is_valid()) {
|
||||||
Vector<Ref<Shape3D>> shapes;
|
Vector<Ref<Shape3D>> shapes;
|
||||||
String fixed_name;
|
|
||||||
if (collision_map.has(mesh)) {
|
if (collision_map.has(mesh)) {
|
||||||
shapes = collision_map[mesh];
|
shapes = collision_map[mesh];
|
||||||
} else if (_teststr(name, "colonly")) {
|
} else if (_teststr(name, "colonly")) {
|
||||||
|
@ -469,14 +507,6 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
collision_map[mesh] = shapes;
|
collision_map[mesh] = shapes;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_teststr(name, "colonly")) {
|
|
||||||
fixed_name = _fixstr(name, "colonly");
|
|
||||||
} else if (_teststr(name, "convcolonly")) {
|
|
||||||
fixed_name = _fixstr(name, "convcolonly");
|
|
||||||
}
|
|
||||||
|
|
||||||
ERR_FAIL_COND_V(fixed_name.is_empty(), nullptr);
|
|
||||||
|
|
||||||
if (shapes.size()) {
|
if (shapes.size()) {
|
||||||
StaticBody3D *col = memnew(StaticBody3D);
|
StaticBody3D *col = memnew(StaticBody3D);
|
||||||
col->set_transform(mi->get_transform());
|
col->set_transform(mi->get_transform());
|
||||||
|
@ -492,11 +522,11 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
} else if (p_node->has_meta("empty_draw_type")) {
|
} else if (p_node->has_meta("empty_draw_type")) {
|
||||||
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
|
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
|
||||||
StaticBody3D *sb = memnew(StaticBody3D);
|
StaticBody3D *sb = memnew(StaticBody3D);
|
||||||
sb->set_name(_fixstr(name, "colonly"));
|
sb->set_name(fixed_name);
|
||||||
Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
|
Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
|
||||||
p_node->replace_by(sb);
|
p_node->replace_by(sb);
|
||||||
memdelete(p_node);
|
memdelete(p_node);
|
||||||
p_node = nullptr;
|
p_node = sb;
|
||||||
CollisionShape3D *colshape = memnew(CollisionShape3D);
|
CollisionShape3D *colshape = memnew(CollisionShape3D);
|
||||||
if (empty_draw_type == "CUBE") {
|
if (empty_draw_type == "CUBE") {
|
||||||
BoxShape3D *boxShape = memnew(BoxShape3D);
|
BoxShape3D *boxShape = memnew(BoxShape3D);
|
||||||
|
@ -635,6 +665,14 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p_node) {
|
||||||
|
NodePath new_path = p_root->get_path_to(p_node);
|
||||||
|
if (new_path != original_path) {
|
||||||
|
print_verbose(vformat("Fix: Renamed %s to %s", original_path, new_path));
|
||||||
|
r_node_renames.push_back({ original_path, p_node });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return p_node;
|
return p_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1828,8 +1866,8 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
|
Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
|
||||||
|
List<Pair<NodePath, Node *>> node_renames;
|
||||||
_pre_fix_node(scene, scene, collision_map);
|
_pre_fix_node(scene, scene, collision_map, node_renames);
|
||||||
|
|
||||||
return scene;
|
return scene;
|
||||||
}
|
}
|
||||||
|
@ -1904,8 +1942,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
|
||||||
|
|
||||||
Set<Ref<ImporterMesh>> scanned_meshes;
|
Set<Ref<ImporterMesh>> scanned_meshes;
|
||||||
Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
|
Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
|
||||||
|
List<Pair<NodePath, Node *>> node_renames;
|
||||||
|
|
||||||
_pre_fix_node(scene, scene, collision_map);
|
_pre_fix_node(scene, scene, collision_map, node_renames);
|
||||||
|
|
||||||
for (int i = 0; i < post_importer_plugins.size(); i++) {
|
for (int i = 0; i < post_importer_plugins.size(); i++) {
|
||||||
post_importer_plugins.write[i]->pre_process(scene, p_options);
|
post_importer_plugins.write[i]->pre_process(scene, p_options);
|
||||||
|
|
|
@ -261,7 +261,7 @@ public:
|
||||||
// Import scenes *after* everything else (such as textures).
|
// Import scenes *after* everything else (such as textures).
|
||||||
virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; }
|
virtual int get_import_order() const override { return ResourceImporter::IMPORT_ORDER_SCENE; }
|
||||||
|
|
||||||
Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map);
|
Node *_pre_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, List<Pair<NodePath, Node *>> &r_node_renames);
|
||||||
Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
|
Node *_post_fix_node(Node *p_node, Node *p_root, Map<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Set<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
|
||||||
|
|
||||||
Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
|
Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
|
||||||
|
|
Loading…
Reference in New Issue