Fix Scene Importer crashing when mesh or animation save paths are invalid

(cherry picked from commit cd87916d98)
This commit is contained in:
BlueCube3310 2023-10-23 21:26:38 +02:00 committed by Rémi Verschelde
parent 18d497d744
commit 3553d33708
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 52 additions and 20 deletions

View File

@ -31,6 +31,7 @@
#include "resource_importer_scene.h" #include "resource_importer_scene.h"
#include "core/error/error_macros.h" #include "core/error/error_macros.h"
#include "core/io/dir_access.h"
#include "core/io/resource_saver.h" #include "core/io/resource_saver.h"
#include "core/object/script_language.h" #include "core/object/script_language.h"
#include "editor/editor_node.h" #include "editor/editor_node.h"
@ -2393,6 +2394,21 @@ Node *ResourceImporterScene::pre_import(const String &p_source_file, const HashM
return scene; return scene;
} }
Error ResourceImporterScene::_check_resource_save_paths(const Dictionary &p_data) {
Array keys = p_data.keys();
for (int i = 0; i < keys.size(); i++) {
const Dictionary &settings = p_data[keys[i]];
if (bool(settings.get("save_to_file/enabled", false)) && settings.has("save_to_file/path")) {
const String &save_path = settings["save_to_file/path"];
ERR_FAIL_COND_V(!save_path.is_empty() && !DirAccess::exists(save_path.get_base_dir()), ERR_FILE_BAD_PATH);
}
}
return OK;
}
Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) { Error ResourceImporterScene::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
const String &src_path = p_source_file; const String &src_path = p_source_file;
@ -2445,7 +2461,42 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
import_flags |= EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION; import_flags |= EditorSceneFormatImporter::IMPORT_FORCE_DISABLE_MESH_COMPRESSION;
} }
Dictionary subresources = p_options["_subresources"];
Dictionary node_data;
if (subresources.has("nodes")) {
node_data = subresources["nodes"];
}
Dictionary material_data;
if (subresources.has("materials")) {
material_data = subresources["materials"];
}
Dictionary animation_data;
if (subresources.has("animations")) {
animation_data = subresources["animations"];
}
Dictionary mesh_data;
if (subresources.has("meshes")) {
mesh_data = subresources["meshes"];
}
Error err = OK; Error err = OK;
// Check whether any of the meshes or animations have nonexistent save paths
// and if they do, fail the import immediately.
err = _check_resource_save_paths(mesh_data);
if (err != OK) {
return err;
}
err = _check_resource_save_paths(animation_data);
if (err != OK) {
return err;
}
List<String> missing_deps; // for now, not much will be done with this List<String> missing_deps; // for now, not much will be done with this
Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err); Node *scene = importer->import_scene(src_path, import_flags, p_options, &missing_deps, &err);
if (!scene || err != OK) { if (!scene || err != OK) {
@ -2469,22 +2520,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
scene_3d->scale(scale); scene_3d->scale(scale);
} }
} }
Dictionary subresources = p_options["_subresources"];
Dictionary node_data;
if (subresources.has("nodes")) {
node_data = subresources["nodes"];
}
Dictionary material_data;
if (subresources.has("materials")) {
material_data = subresources["materials"];
}
Dictionary animation_data;
if (subresources.has("animations")) {
animation_data = subresources["animations"];
}
HashSet<Ref<ImporterMesh>> scanned_meshes; HashSet<Ref<ImporterMesh>> scanned_meshes;
HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map; HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> collision_map;
@ -2564,10 +2599,6 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
} }
} }
Dictionary mesh_data;
if (subresources.has("meshes")) {
mesh_data = subresources["meshes"];
}
scene = _generate_meshes(scene, mesh_data, gen_lods, create_shadow_meshes, LightBakeMode(light_bake_mode), lightmap_texel_size, src_lightmap_cache, mesh_lightmap_caches); scene = _generate_meshes(scene, mesh_data, gen_lods, create_shadow_meshes, LightBakeMode(light_bake_mode), lightmap_texel_size, src_lightmap_cache, mesh_lightmap_caches);
if (mesh_lightmap_caches.size()) { if (mesh_lightmap_caches.size()) {

View File

@ -214,6 +214,7 @@ class ResourceImporterScene : public ResourceImporter {
SHAPE_TYPE_CAPSULE, SHAPE_TYPE_CAPSULE,
}; };
static Error _check_resource_save_paths(const Dictionary &p_data);
Array _get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node); Array _get_skinned_pose_transforms(ImporterMeshInstance3D *p_src_mesh_node);
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner); void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
Node *_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches); Node *_generate_meshes(Node *p_node, const Dictionary &p_mesh_data, bool p_generate_lods, bool p_create_shadow_meshes, LightBakeMode p_light_bake_mode, float p_lightmap_texel_size, const Vector<uint8_t> &p_src_lightmap_cache, Vector<Vector<uint8_t>> &r_lightmap_caches);