Roll out seven modular outfit bases: eleven distinct outfits across twelve roles
This commit is contained in:
1 parent
3b9e3b61d8
commit
b18236f9b4
27 files changed
+267
-88
No files matched your search
@@ -27,6 +27,7 @@ fixed-colour detail. `blender_assets.py` refuses a part that breaks it.
|
||||
|
||||
import argparse
|
||||
import hashlib
|
||||
import math
|
||||
import json
|
||||
import struct
|
||||
import sys
|
||||
@@ -242,7 +243,7 @@ def _base_name(name: str) -> str:
|
||||
return head if sep and tail.isdigit() else name
|
||||
|
||||
|
||||
def make_base(family_dir: Path, out: Path):
|
||||
def make_base(family_dir: Path, out: Path, yaw: float = 0.0):
|
||||
"""Compose one outfit family from its FBX parts into a single skinned GLB base.
|
||||
|
||||
The pack ships each outfit as four FBX files (Body/Legs/Feet/Head) that share one
|
||||
@@ -344,6 +345,8 @@ def make_base(family_dir: Path, out: Path):
|
||||
bpy.context.view_layer.update()
|
||||
print(f" scaled {family_dir.name} by {scale:.3f} (was {height:.3f} m)")
|
||||
|
||||
# Some families are authored facing the other way; the project's front is Godot
|
||||
# +Z (Blender -Y), so a 180 degree yaw is applied before the transforms are baked.
|
||||
# Bake the armature and mesh object transforms into their data. An FBX import
|
||||
# keeps a scale/rotation on the objects, and the glTF exporter then writes node
|
||||
# transforms that change the rest pose on import (Godot rendered the head at
|
||||
@@ -355,6 +358,19 @@ def make_base(family_dir: Path, out: Path):
|
||||
bpy.context.view_layer.objects.active = keep
|
||||
bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
|
||||
|
||||
# Some families are authored facing the other way; the project's front is Godot
|
||||
# +Z. Rotate the *armature object* and export that node transform — rotating the
|
||||
# mesh as well double-applies the skin, and baking the rotation into an already
|
||||
# bound mesh collapses the character.
|
||||
if abs(yaw) > 0.01:
|
||||
# World-space rotation: the FBX armature carries its own -90 X, so
|
||||
# `rotate_axis("Z")` would turn about that local axis and lay the character
|
||||
# flat instead of facing the other way.
|
||||
from mathutils import Matrix # type: ignore
|
||||
keep.matrix_world = (Matrix.Rotation(math.radians(yaw), 4, "Z")
|
||||
@ keep.matrix_world)
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
out.parent.mkdir(parents=True, exist_ok=True)
|
||||
for obj in bpy.context.scene.objects:
|
||||
obj.select_set(obj is body or obj is keep)
|
||||
@@ -383,6 +399,8 @@ def main(argv=None):
|
||||
base = sub.add_parser("make-base", help="compose one outfit family as a base GLB")
|
||||
base.add_argument("--family", required=True, help="folder under the pack's Separate Skeletal Meshes")
|
||||
base.add_argument("--out", required=True)
|
||||
base.add_argument("--yaw", type=float, default=0.0,
|
||||
help="rotate the finished base about Z (degrees)")
|
||||
argv = list(argv if argv is not None else sys.argv[1:])
|
||||
if "--" in argv: # Blender hands the script path over before its own `--`
|
||||
argv = argv[argv.index("--") + 1:]
|
||||
@@ -392,7 +410,7 @@ def main(argv=None):
|
||||
if args.cmd == "verify":
|
||||
return verify(Path(args.dir))
|
||||
if args.cmd == "make-base":
|
||||
return make_base(Path(args.family), Path(args.out))
|
||||
return make_base(Path(args.family), Path(args.out), args.yaw)
|
||||
return extract(Path(args.file), args.mesh, args.part, Path(args.out))
|
||||
|
||||
|
||||
|
||||
Reference in new issue
Block a user