# Wind clips — the Mixamo candidates, and why they're rejected

Lane E, Sprint 13 gate 2.4 ("wind clips for the player — lean / stagger / brace,
staged by wind band, through the Mixamo pipeline").

**Outcome: no clip shipped. The Mixamo pipeline cannot supply a wind lean, and the
lean was never going to be a clip in the first place.** Both halves of that are
measured, and the evidence is in this folder. Full argument in THREADS [E] 2026-07-17/18.

## 1. Mixamo has no wind animations

Searched the real API (`fetch.cjs search`, on ultra), not assumed:

| term | what comes back |
|---|---|
| `brace` | eleven **Braced Hang** ledge-climbing clips |
| `wind` | Standing Idle 04, Catwalk Walk Turn 180 |
| `shiver` | nothing, 0 results |
| `stagger` | three walks (Swagger Walk, Walking, Walking) |
| `lean` | Leaning On A Wall, Leaning, One Shoulder Lean |
| `push` | Pushing, Push Up, Button Pushing |

The factory's own header already recorded half of this in Sprint 3 — *"Hammering /
Sweeping Floor / **Bracing** don't exist on Mixamo — skipped."* This is the case
the asset-pipeline skill names directly: *truly bespoke clips don't exist on
Mixamo — hand-author, don't keep searching.*

## 2. The two real candidates, rendered and rejected

`skinshot.py` films a skinned Mixamo FBX twice: **as authored**, and **as the game
shows it** (Hips rotation cleared, which is what `player.js:_rotOnly` does at load).
The second row is the honest one.

- **`rejected_Pushing.png`** — not a wind lean. A deep squat shoving something heavy
  along the ground, standing up at the end. It reads as *moving a couch*. The
  forward angle I hoped to borrow is a squat, not a lean.
- **`rejected_Leaning.png`** — a casual weight-on-the-back-foot lean, the "propped
  against a bar" pose. Hands slack, no tension, near-identical across all five
  frames. A person waiting for a bus, not one in a gale.

Neither is close enough to fix by retiming. Shipping either would have passed every
check we have — they load, they're metre-scale, their nodes survive — and been wrong
on screen. That's the bike rule: **the verify can't answer "is this the right shape."**

## 3. The useful technical result

In both strips the raw and stripped rows are **near-identical**, which is worth
knowing: these clips carry their lean in the **spine**, and spine rotation survives
`_rotOnly` intact. So a hand-authored posture (spine curl, shoulder hunch, arm up)
*would* survive the loader. What cannot survive is a lean authored into the **hips** —
`_rotOnly` drops `Hips.quaternion` from every clip (`player.js:53`, applied `:239`).
Measured on the shipped pack: 17 clips, 195 channels each, **64 survive**.

Which is why the lean belongs in `player.sim.js` as a root pitch aimed at
`wind.dirAt(t)` — the wind's bearing swings (the change; site_02's venturi) and a
canned clip has one fixed lean axis. Same trick as the knockdown and `climbY`.

## Reproducing

```sh
# on ultra (the FBX libraries and the Mixamo login live there; JING5 has neither)
mkdir -p /tmp/shadeswind && cd /tmp/shadeswind
cp ~/Documents/mixamo-fetch/fetch.cjs .
printf 'Pushing\nLeaning\n' > wishlist.txt
SKIN=1 node fetch.cjs "X Bot"          # SKIN=1: needs a mesh to judge a silhouette
/Applications/Blender.app/Contents/MacOS/Blender -b --factory-startup \
    -P skinshot.py -- /tmp/shadeswind/out/Pushing.fbx Pushing
```

Notes for whoever next reaches for this pipeline:
- `fetch.cjs` reads its token from a **logged-in Brave on ultra via CDP** (port 9222).
  Nobody types a password; the session is already there. It 429s after a handful of
  exports — space them out.
- `resolveChar` defaults to `Grandma_mixamo`, which is not currently uploaded to the
  account. **`X Bot`** is a Mixamo stock rig and works; for anim-only export the source
  rig is irrelevant anyway, since `_rotOnly` keeps rotations only.
- Anim-only FBX (`SKIN` unset) has **no mesh** and renders nothing. Judging a
  silhouette needs `SKIN=1`.
- Don't retarget onto `Hum_M_1_mixamo.fbx` to preview: its armature carries FBX's
  0.01 unit scale and the clip's action doesn't, so the body collapses to ~3 cm.
  That's the same "peds cannot round-trip through Blender" trap `build_player_anims.py`
  documents.
