This commit is contained in:
Nicholas Butzke
2026-08-02 02:20:02 -04:00
parent 61669627db
commit 922983429e
226 changed files with 34032 additions and 18521 deletions
+34 -3
View File
@@ -253,7 +253,20 @@ check(len(orphans) <= 1, "every chain is attached to the body",
# ----------------------------------------------------------------------- clips
actions = {a.name: a for a in bpy.data.actions}
print(f"\n {len(actions)} clips: {', '.join(sorted(actions))}\n")
check(len(actions) >= 10, "the canonical clip set shipped", f"{len(actions)} clips")
required_clips = {
"Idle", "Walk", "Run", "Sprint", "Jump", "Fall", "Land",
"CrouchIdle", "CrouchWalk", "Dash", "Slide",
"RunForward", "RunBackward", "RunLeft", "RunRight",
"StrafeWalkForward", "StrafeWalkBackward",
"StrafeWalkLeft", "StrafeWalkRight",
"WallRunLeft", "WallRunRight", "Grapple",
}
missing_clips = sorted(required_clips - actions.keys())
check(not missing_clips, "the canonical clip set shipped",
f"missing: {', '.join(missing_clips)}" if missing_clips
else f"{len(actions)} clips")
check("WallRun" not in actions, "the placeholder run-cycle wall run was removed",
"legacy WallRun is still present" if "WallRun" in actions else "")
def curves(action):
@@ -305,7 +318,8 @@ else:
# are upper-body clips with genuinely static legs, so demanding leg motion from
# every clip fails on a correct build.
LOCOMOTION = {"Idle", "Walk", "Run", "Sprint", "Jump", "Fall", "Land",
"CrouchIdle", "CrouchWalk", "Dash"}
"CrouchIdle", "CrouchWalk", "Dash",
"WallRunLeft", "WallRunRight"}
# The thighs and shins by ROLE, so this works on any rig's spelling.
leg_bones = {b for s in ROLE_LEGS.values() for b in s}
@@ -314,10 +328,13 @@ if not leg_bones:
if any(h in b.name.lower() for h in ("thigh", "shin"))}
frozen = []
held_rest = []
legless = []
keyed_cloth = set()
held_poses = {"Grapple"}
for name, action in sorted(actions.items()):
moved = defaultdict(float)
authored_offset = 0.0
for fc in curves(action):
b = bone_of(fc.data_path)
if not b or len(fc.keyframe_points) < 2:
@@ -326,7 +343,19 @@ for name, action in sorted(actions.items()):
keyed_cloth.add(b)
vals = [kp.co.y for kp in fc.keyframe_points]
moved[b] = max(moved[b], max(vals) - min(vals))
if max(moved.values(), default=0.0) < 0.005:
# A held pose is intentionally almost constant. Quaternion XYZ and
# translation channels are zero in the rest pose, so a meaningful
# absolute value proves the clip contains an authored silhouette.
if (fc.data_path.endswith("rotation_quaternion")
and fc.array_index in (1, 2, 3)) \
or fc.data_path.endswith("location"):
authored_offset = max(
authored_offset, max((abs(value) for value in vals), default=0.0)
)
if name in held_poses:
if authored_offset < 0.03:
held_rest.append(f"{name}({authored_offset:.4f})")
elif max(moved.values(), default=0.0) < 0.005:
frozen.append(name)
legs = max((v for b, v in moved.items() if b in leg_bones), default=0.0)
if name in LOCOMOTION and legs < 0.01:
@@ -334,6 +363,8 @@ for name, action in sorted(actions.items()):
check(not frozen, "no clip retargeted to a frozen rest pose",
f"frozen: {', '.join(frozen)}" if frozen else "")
check(not held_rest, "held clips contain a non-rest authored pose",
f"rest-like: {', '.join(held_rest)}" if held_rest else "")
check(not legless, "locomotion clips animate the legs",
f"static legs: {', '.join(legless)}" if legless else "")
check(not keyed_cloth, "cloth bones carry no animation keys",