The retry loop that decides whether a generated motion "travels far enough" measures the wrong axis, so every real Kimodo clip fails it. The result is 4 GPU calls per prompt instead of 1, and the extra 3 never improve the answer.
The bug
extractPathFromBVH builds each waypoint as [x, y, z]:
// app.js:425
path.push([x, y, z]);
The travel gate then reads indices 0 and 1:
// app.js:1932-1933
const travelDist = Math.sqrt(
(endPt[0] - startPt[0]) ** 2 + (endPt[1] - startPt[1]) ** 2
);
Index 1 is y, which is height. So the gate measures how far the character moved horizontally-and-vertically in the XY plane, when what it wants is ground distance in the XZ plane.
what it should measure what it measures
Z (forward) Y (up)
^ ^
| * end |
| / | * end <- barely moves;
| / <- real travel | / a walk cycle
| / (433 units) |/ bobs a few units
| / * start
* start ------> X ------> X
Measured against the 7 clips shipped in assets/motions/
| clip |
true XZ travel |
what the gate reads |
passes gate (>= 50)? |
| sneak_forward |
433.2 |
38.6 |
no |
| test_motion |
421.4 |
0.6 |
no |
| sneak_jump |
214.7 |
41.5 |
no |
| spinning_kick |
161.5 |
39.2 |
no |
| backflip |
145.2 |
16.2 |
no |
| silly_dance |
2.6 |
2.5 |
no |
| drunk_dance |
1.9 |
2.8 |
no |
7 of 7 fail. 5 of 7 would pass a correct XZ check.
Why it costs 4 GPU calls
app.js:1908 loops attempt <= MAX_RETRIES with MAX_RETRIES = 3, so the loop runs 4 times. Since the gate can never be satisfied, it always exhausts all 4 attempts and then keeps the last sample regardless of the check. Every prompt pays for 4 motion generations and 8 to 20 seconds of dead wait, and the 3 retries are pure waste.
Fix
Read index 2 instead of index 1:
const travelDist = Math.hypot(endPt[0] - startPt[0], endPt[2] - startPt[2]);
Worth pairing with a check that the loop actually honours its own gate, rather than keeping the last sample either way.
The retry loop that decides whether a generated motion "travels far enough" measures the wrong axis, so every real Kimodo clip fails it. The result is 4 GPU calls per prompt instead of 1, and the extra 3 never improve the answer.
The bug
extractPathFromBVHbuilds each waypoint as[x, y, z]:The travel gate then reads indices 0 and 1:
Index 1 is
y, which is height. So the gate measures how far the character moved horizontally-and-vertically in the XY plane, when what it wants is ground distance in the XZ plane.Measured against the 7 clips shipped in
assets/motions/7 of 7 fail. 5 of 7 would pass a correct XZ check.
Why it costs 4 GPU calls
app.js:1908loopsattempt <= MAX_RETRIESwithMAX_RETRIES = 3, so the loop runs 4 times. Since the gate can never be satisfied, it always exhausts all 4 attempts and then keeps the last sample regardless of the check. Every prompt pays for 4 motion generations and 8 to 20 seconds of dead wait, and the 3 retries are pure waste.Fix
Read index 2 instead of index 1:
Worth pairing with a check that the loop actually honours its own gate, rather than keeping the last sample either way.