@@ -248,6 +248,8 @@ void EditorScenePostImportPlugin::_bind_methods() {
248248
249249// ///////////////////////////////////////////////////////
250250
251+ const String ResourceImporterScene::material_extension[3 ] = { " .tres" , " .res" , " .material" };
252+
251253String ResourceImporterScene::get_importer_name () const {
252254 // For compatibility with 4.2 and earlier we need to keep the "scene" and "animation_library" names.
253255 // However this is arbitrary so for new import types we can use any string.
@@ -1366,15 +1368,28 @@ Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, co
13661368 return p_node;
13671369}
13681370
1369- Node *ResourceImporterScene::_post_fix_node (Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps, float p_applied_root_scale) {
1371+ Node *ResourceImporterScene::_post_fix_node (Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps, float p_applied_root_scale, const String &p_source_file, const HashMap<StringName, Variant> &p_options ) {
13701372 // children first
13711373 for (int i = 0 ; i < p_node->get_child_count (); i++) {
1372- Node *r = _post_fix_node (p_node->get_child (i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps, p_applied_root_scale);
1374+ Node *r = _post_fix_node (p_node->get_child (i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps, p_applied_root_scale, p_source_file, p_options );
13731375 if (!r) {
13741376 i--; // was erased
13751377 }
13761378 }
13771379
1380+ int extract_mat = 0 ;
1381+ if (p_options.has (" materials/extract" )) {
1382+ extract_mat = p_options[" materials/extract" ];
1383+ }
1384+
1385+ String spath = p_source_file.get_base_dir ();
1386+ if (p_options.has (" materials/extract_path" )) {
1387+ String extpath = p_options[" materials/extract_path" ];
1388+ if (!extpath.is_empty ()) {
1389+ spath = extpath;
1390+ }
1391+ }
1392+
13781393 bool isroot = p_node == p_root;
13791394
13801395 String import_id = p_node->get_meta (" import_id" , " PATH:" + p_root->get_path_to (p_node));
@@ -1520,7 +1535,6 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
15201535 Ref<Material> mat = m->get_surface_material (i);
15211536 if (mat.is_valid ()) {
15221537 String mat_id = mat->get_meta (" import_id" , mat->get_name ());
1523-
15241538 if (!mat_id.is_empty () && p_material_data.has (mat_id)) {
15251539 Dictionary matdata = p_material_data[mat_id];
15261540 {
@@ -1537,7 +1551,27 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
15371551 for (int j = 0 ; j < post_importer_plugins.size (); j++) {
15381552 post_importer_plugins.write [j]->internal_process (EditorScenePostImportPlugin::INTERNAL_IMPORT_CATEGORY_MATERIAL, p_root, p_node, mat, matdata);
15391553 }
1554+ }
1555+ if (!mat_id.is_empty () && extract_mat != 0 ) {
1556+ String ext = material_extension[p_options.has (" materials/extract_format" ) ? (int )p_options[" materials/extract_format" ] : 0 ];
1557+ String path = spath.path_join (mat_id.validate_filename () + ext);
1558+ String uid_path = ResourceUID::path_to_uid (path);
15401559
1560+ Dictionary matdata = p_material_data[mat_id];
1561+ matdata[" use_external/enabled" ] = true ;
1562+ matdata[" use_external/path" ] = uid_path;
1563+ matdata[" use_external/fallback_path" ] = path;
1564+ if (!FileAccess::exists (path) || extract_mat == 2 /* overwrite*/ ) {
1565+ ResourceSaver::save (mat, path);
1566+ }
1567+
1568+ Ref<Material> external_mat = ResourceLoader::load (path, " " , ResourceFormatLoader::CACHE_MODE_REPLACE);
1569+ if (external_mat.is_valid ()) {
1570+ m->set_surface_material (i, external_mat);
1571+ }
1572+ }
1573+ if (!mat_id.is_empty () && p_material_data.has (mat_id)) {
1574+ Dictionary matdata = p_material_data[mat_id];
15411575 if (matdata.has (" use_external/enabled" ) && bool (matdata[" use_external/enabled" ]) && matdata.has (" use_external/path" )) {
15421576 String path = matdata[" use_external/path" ];
15431577 Ref<Material> external_mat = ResourceLoader::load (path);
@@ -2434,6 +2468,9 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
24342468 r_options->push_back (ImportOption (PropertyInfo (Variant::BOOL, " animation/remove_immutable_tracks" ), true ));
24352469 r_options->push_back (ImportOption (PropertyInfo (Variant::BOOL, " animation/import_rest_as_RESET" ), false ));
24362470 r_options->push_back (ImportOption (PropertyInfo (Variant::STRING, " import_script/path" , PROPERTY_HINT_FILE, script_ext_hint), " " ));
2471+ r_options->push_back (ImportOption (PropertyInfo (Variant::INT, " materials/extract" , PROPERTY_HINT_ENUM, " Keep Internal,Extract Once,Extract and Overwrite" ), 0 ));
2472+ r_options->push_back (ImportOption (PropertyInfo (Variant::INT, " materials/extract_format" , PROPERTY_HINT_ENUM, " Text (*.tres),Binary (*.res),Material (*.material)" ), 0 ));
2473+ r_options->push_back (ImportOption (PropertyInfo (Variant::STRING, " materials/extract_path" , PROPERTY_HINT_DIR, " " ), " " ));
24372474
24382475 r_options->push_back (ImportOption (PropertyInfo (Variant::DICTIONARY, " _subresources" , PROPERTY_HINT_NONE, " " , PROPERTY_USAGE_NO_EDITOR), Dictionary ()));
24392476
@@ -3106,7 +3143,7 @@ Error ResourceImporterScene::import(ResourceUID::ID p_source_id, const String &p
31063143 }
31073144 bool remove_immutable_tracks = p_options.has (" animation/remove_immutable_tracks" ) ? (bool )p_options[" animation/remove_immutable_tracks" ] : true ;
31083145 _pre_fix_animations (scene, scene, node_data, animation_data, fps);
3109- _post_fix_node (scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps, apply_root ? root_scale : 1.0 );
3146+ _post_fix_node (scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps, apply_root ? root_scale : 1.0 , p_source_file, p_options );
31103147 _post_fix_animations (scene, scene, node_data, animation_data, fps, remove_immutable_tracks);
31113148
31123149 String root_type = p_options[" nodes/root_type" ];
0 commit comments