netfishing/scripts/normalize_texture_imports.gd

205 lines
5.1 KiB
GDScript3
Raw Normal View History

extends SceneTree
const DEFAULT_PROFILE: Dictionary = {
"params": {
"compress/mode": 2,
"compress/high_quality": false,
"compress/lossy_quality": 0.7,
"compress/uastc_level": 0,
"compress/rdo_quality_loss": 0.0,
"compress/hdr_compression": 1,
"compress/normal_map": 0,
"compress/channel_pack": 0,
"mipmaps/generate": true,
"mipmaps/limit": -1,
"roughness/mode": 0,
"roughness/src_normal": "",
"process/channel_remap/red": 0,
"process/channel_remap/green": 1,
"process/channel_remap/blue": 2,
"process/channel_remap/alpha": 3,
"process/fix_alpha_border": true,
"process/premult_alpha": false,
"process/normal_map_invert_y": false,
"process/hdr_as_srgb": false,
"process/hdr_clamp_exposure": false,
"process/size_limit": 0,
"detect_3d/compress_to": 0,
},
}
2026-08-08 00:34:06 -04:00
var apply_changes: bool = false
var verbose: bool = false
var roots: PackedStringArray = PackedStringArray()
2026-08-08 00:34:06 -04:00
var should_exit: bool = false
2026-08-08 00:34:06 -04:00
var errors: int = 0
var skipped_non_texture: int = 0
var updated: int = 0
var unchanged: int = 0
func _initialize() -> void:
_parse_args()
if should_exit:
return
2026-08-08 00:34:06 -04:00
if roots.is_empty():
printerr("At least one --root path is required.")
quit(2)
return
for root: String in roots:
var normalized_root := root
if not normalized_root.ends_with("/"):
normalized_root += "/"
if not normalized_root.begins_with("res://") and not normalized_root.is_absolute_path():
if normalized_root.begins_with("./"):
normalized_root = "res://%s" % normalized_root.trim_prefix("./")
else:
normalized_root = "res://%s" % normalized_root
_print("Scanning %s" % normalized_root)
_scan_directory(normalized_root)
print_summary()
2026-08-08 00:34:06 -04:00
quit(1 if errors > 0 else 0)
func _parse_args() -> void:
var args := OS.get_cmdline_user_args()
var i := 0
while i < args.size():
var arg := args[i]
if arg == "--help" or arg == "-h":
_print_usage()
should_exit = true
quit(0)
return
elif arg == "--apply":
apply_changes = true
i += 1
elif arg == "--verbose" or arg == "-v":
verbose = true
i += 1
elif arg == "--root":
if i + 1 >= args.size():
printerr("--root requires a path value")
should_exit = true
quit(1)
return
i += 1
2026-08-08 00:34:06 -04:00
roots.append(args[i])
i += 1
elif arg.begins_with("--root="):
roots.append(arg.trim_prefix("--root="))
i += 1
else:
2026-08-08 00:34:06 -04:00
printerr("Unknown argument: ", arg)
should_exit = true
quit(2)
return
func _scan_directory(path: String) -> void:
var dir := DirAccess.open(path)
if dir == null:
printerr("Failed to open root: ", path)
2026-08-08 00:34:06 -04:00
errors += 1
return
dir.list_dir_begin()
while true:
var name := dir.get_next()
if name.is_empty():
break
if name == "." or name == "..":
continue
if name == ".godot":
continue
var candidate := path.path_join(name)
if dir.current_is_dir():
_scan_directory(candidate)
continue
if name.get_extension().to_lower() != "import":
continue
_handle_import_file(candidate)
func _handle_import_file(import_path: String) -> void:
var cfg := ConfigFile.new()
var err := cfg.load(import_path)
if err != OK:
printerr("Could not load import settings: ", import_path, " (", err, ")")
2026-08-08 00:34:06 -04:00
errors += 1
return
if not cfg.has_section("remap") or not cfg.has_section_key("remap", "importer"):
skipped_non_texture += 1
return
if str(cfg.get_value("remap", "importer")) != "texture":
skipped_non_texture += 1
return
var changed := false
for section_name: String in DEFAULT_PROFILE.keys():
var section_data: Dictionary = DEFAULT_PROFILE[section_name]
for section_key: String in section_data.keys():
var desired: Variant = section_data[section_key]
var existing: Variant = null
if cfg.has_section(section_name) and cfg.has_section_key(section_name, section_key):
existing = cfg.get_value(section_name, section_key)
if existing != desired:
cfg.set_value(section_name, section_key, desired)
changed = true
if not changed:
unchanged += 1
if verbose:
_print("Unchanged: %s" % import_path)
return
if apply_changes:
err = cfg.save(import_path)
if err != OK:
printerr("Could not save import settings: ", import_path, " (", err, ")")
2026-08-08 00:34:06 -04:00
errors += 1
return
if verbose:
_print("Updated: %s" % import_path)
else:
_print("Would update: %s" % import_path)
updated += 1
func print_summary() -> void:
if apply_changes:
2026-08-08 00:34:06 -04:00
_print(
"Texture import normalization complete: "
+ "updated=%d unchanged=%d skipped_non_texture=%d errors=%d"
% [updated, unchanged, skipped_non_texture, errors]
)
else:
2026-08-08 00:34:06 -04:00
_print(
"Dry-run complete: "
+ "would-update=%d unchanged=%d skipped_non_texture=%d errors=%d"
% [updated, unchanged, skipped_non_texture, errors]
)
_print("Pass --apply to write normalized settings into .import files.")
func _print(msg: String) -> void:
print(msg)
func _print_usage() -> void:
print("Usage:")
print(" godot --headless --path . --script scripts/normalize_texture_imports.gd [--apply] [--verbose] [--root <path>] [--root=<path>] [--help]")
print()
print("Defaults:")
print("- Dry-run only unless --apply is provided")
2026-08-08 00:34:06 -04:00
print("- Requires at least one explicit --root path")
print("- Skips .godot")