"""Executed by Blender: static GLB or skinned FBX with the active animation.""" import argparse from pathlib import Path import sys import bpy def main(): parser = argparse.ArgumentParser() parser.add_argument("--output", required=True) parser.add_argument("--collection", default="Character") parser.add_argument("--skeletal", action="store_true") args = parser.parse_args(sys.argv[sys.argv.index("--") + 1:]) collection = bpy.data.collections.get(args.collection) if collection is None: raise RuntimeError(f"Brak kolekcji {args.collection!r} w zapisanym pliku blend.") meshes = [obj for obj in collection.all_objects if obj.type == "MESH"] if not meshes: raise RuntimeError("Kolekcja Character nie zawiera siatek.") bpy.ops.object.select_all(action="DESELECT") if args.skeletal: armatures = {modifier.object for obj in meshes for modifier in obj.modifiers if modifier.type == "ARMATURE" and modifier.object is not None} if len(armatures) != 1: raise RuntimeError("Eksport szkieletowy wymaga jednego Armature przypisanego do siatek.") armature = next(iter(armatures)) for obj in [*meshes, armature]: obj.hide_set(False) obj.select_set(True) bpy.context.view_layer.objects.active = armature output = Path(args.output).resolve() output.parent.mkdir(parents=True, exist_ok=True) bpy.ops.export_scene.fbx( filepath=str(output), use_selection=True, object_types={"MESH", "ARMATURE"}, add_leaf_bones=False, use_armature_deform_only=False, bake_anim=True, bake_anim_use_all_actions=False, bake_anim_use_nla_strips=False, bake_anim_force_startend_keying=True, bake_anim_simplify_factor=0.0, axis_forward="-Y", axis_up="Z", path_mode="COPY", embed_textures=True) print("WORKSHOP_EXPORTED=" + str(output)) return depsgraph = bpy.context.evaluated_depsgraph_get() copies = [] for obj in meshes: evaluated = obj.evaluated_get(depsgraph) data = bpy.data.meshes.new_from_object(evaluated, depsgraph=depsgraph) duplicate = bpy.data.objects.new(obj.name + "_export", data) bpy.context.scene.collection.objects.link(duplicate) duplicate.matrix_world = obj.matrix_world.copy() duplicate.select_set(True) copies.append(duplicate) bpy.context.view_layer.objects.active = copies[0] bpy.ops.object.join() joined = bpy.context.object joined.name = "Character" # Origin at world zero: stable pivot, independent of which body part is first. bpy.context.scene.cursor.location = (0, 0, 0) bpy.ops.object.origin_set(type="ORIGIN_CURSOR") output = Path(args.output).resolve() output.parent.mkdir(parents=True, exist_ok=True) bpy.ops.export_scene.gltf(filepath=str(output), export_format="GLB", use_selection=True, export_animations=False, export_materials="EXPORT", export_yup=True) print("WORKSHOP_EXPORTED=" + str(output)) if __name__ == "__main__": main()