fix(walk): the cycle starts at maximum stride, so the capture shows one

The stride shot regressed twice for two different reasons, and only the second was
the clip. The walk cycle was authored on a sine, which is zero at both the start and
the middle of the cycle - exactly the two frames where the legs pass together - so a
deterministic capture at any phase near those frames read as a still. The probe
proved it: frames 0 and 15 carried identical hip rotations while 7 and 22 were the
stride.

The cycle now starts at maximum stride (cosine). Length, amplitudes, keys and loop
are unchanged; only the phase moved. demo-third-person-walk is back as shot 8 and
shows a genuine stride with the curled hands from 0.2.1.

8/8 shots verify.
This commit is contained in:
zwitschi committed 2026-11-09 12:55:53 +01:00
1 parent 0d57b718cf
commit 4b9ad22108
46 files changed
+95 -50

No files matched your search

+4 -1
View File
@@ -274,7 +274,10 @@ def clip_walk(arm, frames):
for frame in range(1, frames + 1):
t = 2.0 * math.pi * (frame - 1) / frames
swing = math.sin(t)
# cos, not sin: the clip starts at maximum stride. A sine starts and crosses
# zero twice per cycle, and the review capture kept landing on those passing
# frames - legs together, which reads as a still. The cycle is unchanged.
swing = math.cos(t)
# Hip swing, opposite phase per leg; negative X is forward.
key_euler(bones["upperleg01.L"], frame, x=-HIP * swing)
key_euler(bones["upperleg01.R"], frame, x=HIP * swing)