42 lines
1.7 KiB
Python
42 lines
1.7 KiB
Python
|
|
"""Regenerate hand-poses/canonical_rest.json — the canonical Quaternius finger-bone REST
|
||
|
|
rotations, taken from the Kevin pack the hand poses were harvested against.
|
||
|
|
|
||
|
|
The runtime needs this to apply a pose REST-RELATIVE on rigs whose finger rest differs from
|
||
|
|
canonical (Mako's *_01 knuckles sit 11.5 deg off, so applying a canonical pose directly
|
||
|
|
rotates his knuckles away from his own rest and tears the palm/wrist boundary):
|
||
|
|
|
||
|
|
delta = canonical_rest^-1 * pose
|
||
|
|
target = body_rest * delta
|
||
|
|
|
||
|
|
usage: make_canonical_rest.py [kevin.glb] [out.json]
|
||
|
|
"""
|
||
|
|
import json, struct, sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
REPO = Path(__file__).resolve().parents[1]
|
||
|
|
GAME = REPO.parent / "ariki-game"
|
||
|
|
|
||
|
|
src = Path(sys.argv[1]) if len(sys.argv) > 1 else \
|
||
|
|
GAME / "assets/quaternius/kevin/kevin_female_combat.glb"
|
||
|
|
out = Path(sys.argv[2]) if len(sys.argv) > 2 else REPO / "hand-poses/canonical_rest.json"
|
||
|
|
|
||
|
|
d = src.read_bytes()
|
||
|
|
jl = struct.unpack_from("<I", d, 12)[0]
|
||
|
|
g = json.loads(d[20:20 + jl].decode("utf-8"))
|
||
|
|
|
||
|
|
pose_bones = list(json.loads((REPO / "hand-poses/pose_flat.json").read_text())["bones"])
|
||
|
|
rest = {nd.get("name"): nd.get("rotation", [0, 0, 0, 1]) for nd in g["nodes"]}
|
||
|
|
missing = [b for b in pose_bones if b not in rest]
|
||
|
|
if missing:
|
||
|
|
raise SystemExit(f"canonical source lacks pose bones: {missing}")
|
||
|
|
|
||
|
|
payload = {
|
||
|
|
"_comment": ("Canonical Quaternius finger-bone REST rotations. The runtime applies a "
|
||
|
|
"pose rest-relative: delta = canonical_rest^-1 * pose, "
|
||
|
|
"target = body_rest * delta. Regenerate with tools/make_canonical_rest.py."),
|
||
|
|
"source": src.name,
|
||
|
|
"bones": {b: [round(v, 8) for v in rest[b]] for b in pose_bones},
|
||
|
|
}
|
||
|
|
out.write_text(json.dumps(payload, indent=1))
|
||
|
|
print(f"wrote {out} with {len(payload['bones'])} bones from {src.name}")
|