68 lines
3.1 KiB
Python
68 lines
3.1 KiB
Python
"""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()
|