|
@@ -289,16 +289,17 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape>> &r_shape_lis
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode) {
|
|
|
- // children first
|
|
|
+Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode, List<Pair<NodePath, Node *>> &r_node_renames) {
|
|
|
+ // Children first.
|
|
|
for (int i = 0; i < p_node->get_child_count(); i++) {
|
|
|
- Node *r = _fix_node(p_node->get_child(i), p_root, collision_map, p_light_bake_mode);
|
|
|
+ Node *r = _fix_node(p_node->get_child(i), p_root, collision_map, p_light_bake_mode, r_node_renames);
|
|
|
if (!r) {
|
|
|
- i--; //was erased
|
|
|
+ i--; // Was erased.
|
|
|
}
|
|
|
}
|
|
|
|
|
|
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;
|
|
|
|
|
@@ -337,14 +338,21 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
}
|
|
|
|
|
|
if (Object::cast_to<AnimationPlayer>(p_node)) {
|
|
|
- //remove animations referencing non-importable nodes
|
|
|
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;
|
|
|
ap->get_animation_list(&anims);
|
|
|
for (List<StringName>::Element *E = anims.front(); E; E = E->next()) {
|
|
|
Ref<Animation> anim = ap->get_animation(E->get());
|
|
|
ERR_CONTINUE(anim.is_null());
|
|
|
+
|
|
|
+ // Remove animation tracks referencing non-importable nodes
|
|
|
for (int i = 0; i < anim->get_track_count(); i++) {
|
|
|
NodePath path = anim->track_get_path(i);
|
|
|
|
|
@@ -357,6 +365,27 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 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 List<Pair<NodePath, Node *>>::Element *F = r_node_renames.front(); F; F = F->next()) {
|
|
|
+ if (F->get().first == absolute_path) {
|
|
|
+ NodePath new_path(ap_root->get_path_to(F->get().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.
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -364,13 +393,22 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
if (isroot) {
|
|
|
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 == String(), nullptr);
|
|
|
+
|
|
|
MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
|
|
|
if (mi) {
|
|
|
Ref<Mesh> mesh = mi->get_mesh();
|
|
|
|
|
|
if (mesh.is_valid()) {
|
|
|
List<Ref<Shape>> shapes;
|
|
|
- String fixed_name;
|
|
|
if (collision_map.has(mesh)) {
|
|
|
shapes = collision_map[mesh];
|
|
|
} else if (_teststr(name, "colonly")) {
|
|
@@ -381,14 +419,6 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
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 == String(), nullptr);
|
|
|
-
|
|
|
if (shapes.size()) {
|
|
|
StaticBody *col = memnew(StaticBody);
|
|
|
col->set_transform(mi->get_transform());
|
|
@@ -404,11 +434,11 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
} else if (p_node->has_meta("empty_draw_type")) {
|
|
|
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
|
|
|
StaticBody *sb = memnew(StaticBody);
|
|
|
- sb->set_name(_fixstr(name, "colonly"));
|
|
|
+ sb->set_name(fixed_name);
|
|
|
Object::cast_to<Spatial>(sb)->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
|
|
|
p_node->replace_by(sb);
|
|
|
memdelete(p_node);
|
|
|
- p_node = nullptr;
|
|
|
+ p_node = sb;
|
|
|
CollisionShape *colshape = memnew(CollisionShape);
|
|
|
if (empty_draw_type == "CUBE") {
|
|
|
BoxShape *boxShape = memnew(BoxShape);
|
|
@@ -594,6 +624,14 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ 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;
|
|
|
}
|
|
|
|
|
@@ -1297,8 +1335,8 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
|
|
|
int light_bake_mode = p_options["meshes/light_baking"];
|
|
|
|
|
|
Map<Ref<Mesh>, List<Ref<Shape>>> collision_map;
|
|
|
-
|
|
|
- scene = _fix_node(scene, scene, collision_map, LightBakeMode(light_bake_mode));
|
|
|
+ List<Pair<NodePath, Node *>> node_renames;
|
|
|
+ scene = _fix_node(scene, scene, collision_map, LightBakeMode(light_bake_mode), node_renames);
|
|
|
|
|
|
if (use_optimizer) {
|
|
|
_optimize_animations(scene, anim_optimizer_linerr, anim_optimizer_angerr, anim_optimizer_maxang);
|