Skip to content

Commit b848536

Browse files
committed
Merge pull request #107211 from bruvzg/mat_ext_and_over
Restore 3.x style material auto-extraction import option.
2 parents 6e5bcd2 + a0c4a8c commit b848536

File tree

5 files changed

+119
-5
lines changed

5 files changed

+119
-5
lines changed

doc/classes/ResourceImporterScene.xml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,21 @@
3333
<member name="import_script/path" type="String" setter="" getter="" default="&quot;&quot;">
3434
Path to an import script, which can run code after the import process has completed for custom processing. See [url=$DOCS_URL/tutorials/assets_pipeline/importing_3d_scenes/import_configuration.html#using-import-scripts-for-automation]Using import scripts for automation[/url] for more information.
3535
</member>
36+
<member name="materials/extract" type="int" setter="" getter="" default="0">
37+
Material extraction mode.
38+
- [code]0 (Keep Internal)[/code], materials are not extracted.
39+
- [code]1 (Extract Once)[/code], materials are extracted once and reused on subsequent import.
40+
- [code]2 (Extract and Overwrite)[/code], materials are extracted and overwritten on every import.
41+
</member>
42+
<member name="materials/extract_format" type="int" setter="" getter="" default="0">
43+
Extracted material file format.
44+
- [code]0 (Text)[/code], text file format ([code]*.tres[/code]).
45+
- [code]1 (Binary)[/code], binary file format ([code]*.res[/code]).
46+
- [code]2 (Material)[/code], binary file format ([code]*.material[/code]).
47+
</member>
48+
<member name="materials/extract_path" type="String" setter="" getter="" default="&quot;&quot;">
49+
Path extracted materials are saved to. If empty, source scene path is used.
50+
</member>
3651
<member name="meshes/create_shadow_meshes" type="bool" setter="" getter="" default="true">
3752
If [code]true[/code], enables the generation of shadow meshes on import. This optimizes shadow rendering without reducing quality by welding vertices together when possible. This in turn reduces the memory bandwidth required to render shadows. Shadow mesh generation currently doesn't support using a lower detail level than the source mesh (but shadow rendering will make use of LODs when relevant).
3853
</member>

editor/import/3d/resource_importer_scene.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ void EditorScenePostImportPlugin::_bind_methods() {
248248

249249
/////////////////////////////////////////////////////////
250250

251+
const String ResourceImporterScene::material_extension[3] = { ".tres", ".res", ".material" };
252+
251253
String 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"];

editor/import/3d/resource_importer_scene.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ class ResourceImporterScene : public ResourceImporter {
235235
String _scene_import_type = "PackedScene";
236236

237237
public:
238+
static const String material_extension[3];
238239
static ResourceImporterScene *get_scene_singleton() { return scene_singleton; }
239240
static ResourceImporterScene *get_animation_singleton() { return animation_singleton; }
240241

@@ -285,7 +286,7 @@ class ResourceImporterScene : public ResourceImporter {
285286
void _pre_fix_global(Node *p_scene, const HashMap<StringName, Variant> &p_options) const;
286287
Node *_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames, const HashMap<StringName, Variant> &p_options);
287288
Node *_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps);
288-
Node *_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);
289+
Node *_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);
289290
Node *_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps, bool p_remove_immutable_tracks);
290291

291292
Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, const String &p_save_to_path, bool p_keep_custom_tracks);

editor/import/3d/scene_import_settings.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,23 @@ class SceneImportSettingsData : public Object {
201201
}
202202
};
203203

204+
bool SceneImportSettingsDialog::_get_current(const StringName &p_name, Variant &r_ret) const {
205+
if (scene_import_settings_data->_get(p_name, r_ret)) {
206+
return true;
207+
}
208+
if (defaults.has(p_name)) {
209+
r_ret = defaults[p_name];
210+
return true;
211+
}
212+
return false;
213+
}
214+
215+
void SceneImportSettingsDialog::_set_default(const StringName &p_name, const Variant &p_value) {
216+
defaults[p_name] = p_value;
217+
scene_import_settings_data->defaults[p_name] = p_value;
218+
scene_import_settings_data->_set(p_name, p_value);
219+
}
220+
204221
void SceneImportSettingsDialog::_fill_material(Tree *p_tree, const Ref<Material> &p_material, TreeItem *p_parent) {
205222
String import_id;
206223
bool has_import_id = false;
@@ -233,6 +250,24 @@ void SceneImportSettingsDialog::_fill_material(Tree *p_tree, const Ref<Material>
233250
MaterialData &material_data = material_map[import_id];
234251
ERR_FAIL_COND(p_material != material_data.material);
235252

253+
Variant value;
254+
if (_get_current("materials/extract", value) && (int)value != 0) {
255+
String spath = base_path.get_base_dir();
256+
if (_get_current("materials/extract_path", value)) {
257+
String extpath = value;
258+
if (!extpath.is_empty()) {
259+
spath = extpath;
260+
}
261+
}
262+
263+
String ext = ResourceImporterScene::material_extension[_get_current("materials/extract_format", value) ? (int)value : 0];
264+
String path = spath.path_join(import_id.validate_filename() + ext);
265+
String uid_path = ResourceUID::path_to_uid(path);
266+
material_data.settings["use_external/enabled"] = true;
267+
material_data.settings["use_external/path"] = uid_path;
268+
material_data.settings["use_external/fallback_path"] = path;
269+
}
270+
236271
Ref<Texture2D> icon = get_editor_theme_icon(SNAME("StandardMaterial3D"));
237272

238273
TreeItem *item = p_tree->create_item(p_parent);
@@ -1004,6 +1039,30 @@ void SceneImportSettingsDialog::_inspector_property_edited(const String &p_name)
10041039
animation_loop_mode = Animation::LoopMode::LOOP_NONE;
10051040
}
10061041
}
1042+
if ((p_name == "use_external/enabled") || (p_name == "use_external/path") || (p_name == "use_external/fallback_path")) {
1043+
MaterialData &material_data = material_map[selected_id];
1044+
String spath = base_path.get_base_dir();
1045+
Variant value;
1046+
if (_get_current("materials/extract_path", value)) {
1047+
String extpath = value;
1048+
if (!extpath.is_empty()) {
1049+
spath = extpath;
1050+
}
1051+
}
1052+
String opath = material_data.settings.has("use_external/path") ? (String)material_data.settings["use_external/path"] : String();
1053+
if (opath.begins_with("uid://")) {
1054+
opath = ResourceUID::uid_to_path(opath);
1055+
}
1056+
String ext = ResourceImporterScene::material_extension[_get_current("materials/extract_format", value) ? (int)value : 0];
1057+
String npath = spath.path_join(selected_id.validate_filename() + ext);
1058+
1059+
if (!material_data.settings.has("use_external/enabled") || (bool)material_data.settings["use_external/enabled"] == false || opath != npath) {
1060+
if (_get_current("materials/extract", value) && (int)value != 0) {
1061+
print_line("Material settings changed, automatic material extraction disabled.");
1062+
}
1063+
_set_default("materials/extract", 0);
1064+
}
1065+
}
10071066
}
10081067

10091068
void SceneImportSettingsDialog::_reset_bone_transforms() {

editor/import/3d/scene_import_settings.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ class SceneImportSettingsDialog : public ConfirmationDialog {
164164
};
165165
HashMap<String, NodeData> node_map;
166166

167+
bool _get_current(const StringName &p_name, Variant &r_ret) const;
168+
void _set_default(const StringName &p_name, const Variant &p_value);
167169
void _fill_material(Tree *p_tree, const Ref<Material> &p_material, TreeItem *p_parent);
168170
void _fill_mesh(Tree *p_tree, const Ref<Mesh> &p_mesh, TreeItem *p_parent);
169171
void _fill_animation(Tree *p_tree, const Ref<Animation> &p_anim, const String &p_name, TreeItem *p_parent);

0 commit comments

Comments
 (0)