big
This commit is contained in:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user