#!/usr/bin/env python3 """ convert_config_meshes.py - Bulk-convert 3D mesh files referenced in a game object JSON config. Reads , converts every .txt mesh to binary (.txt.bin via BSMF format), and writes the updated config to with meshPath values pointing to the .bin files. Works for both regular game object configs and interactive object configs. Mesh paths in the JSON are relative to the current working directory — run this script from the project root. Usage: python convert_config_meshes.py """ import json import os import sys from convert_model_to_binary import convert def convert_config(src_path: str, dst_path: str) -> None: with open(src_path, 'r', encoding='utf-8') as f: config = json.load(f) objects = config.get("objects", []) # Track already-converted paths so shared meshes are only processed once. cache: dict[str, str | None] = {} for obj in objects: mesh_path = obj.get("meshPath") if not mesh_path or not mesh_path.lower().endswith(".txt"): continue if mesh_path not in cache: if not os.path.isfile(mesh_path): print(f" WARNING: mesh not found, skipping: {mesh_path}") cache[mesh_path] = None else: bin_path = mesh_path + ".bin" convert(mesh_path, bin_path) cache[mesh_path] = bin_path if cache[mesh_path] is not None: obj["meshPath"] = cache[mesh_path] os.makedirs(os.path.dirname(os.path.abspath(dst_path)), exist_ok=True) with open(dst_path, 'w', encoding='utf-8') as f: json.dump(config, f, indent=4, ensure_ascii=False) converted_count = sum(1 for v in cache.values() if v is not None) print(f"Saved: {dst_path} ({converted_count} mesh(es) converted, " f"{len(cache) - converted_count} skipped)") if __name__ == '__main__': if len(sys.argv) != 3: print(f"Usage: {sys.argv[0]} ") sys.exit(1) convert_config(sys.argv[1], sys.argv[2])