Lane 0: bootstrap MOCAPGOD

git init + .gitignore (weights/capture/queue/out/media excluded), docs/LICENSES.md
skeleton with the SMPL gate, PROGRESS.md ledger, and spec/mixamorig_bones.json —
65 mixamorig bones (colon-prefixed) dumped from character_kit/female/female_game.glb
via headless Blender. This bone file is the retarget ground truth for Lane C.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
type-two 2026-07-17 00:40:26 +10:00
commit 619d35cc79
7 changed files with 1315 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# weights + runtime data stay out of git
weights/
capture/
queue/
out/
clips_out/
*.mp4
*.bvh
__pycache__/
.DS_Store

16
CLAUDE.md Normal file
View File

@ -0,0 +1,16 @@
# MOCAPGOD
Private video→mocap→clip pipeline. **Read PLAN.md before doing anything** — it is the
work order; lanes execute one per session, acceptance checks are the definition of done.
Facts:
- Fleet: m3ultra (`m3ultra@100.89.131.57`) = pose engine (inference/training);
ultra (this Mac) = Blender glue + orchestration + canonical repo; JING5 = capture.
- Skeleton canon: mixamorig 65-joint from `~/Documents/character_kit` (see
`spec/mixamorig_bones.json` once Lane 0 runs).
- Interchange: BVH 30fps + JSON sidecar → anim-only FBX → `merge_anims.py` → GLB banks.
- Legal rails are in PLAN.md §Ground rules — SMPL licensing gate in Lane B is a hard
stop for a John-decision; no Cascadeur reverse engineering; no Mixamo-as-training-data.
- Long jobs: heartbeat convention (`~/.jobs/`); scheduled jobs use /opt/homebrew/bin/python3
(TCC); bulk output through `| lm -l 2`.
- Progress ledger: PROGRESS.md (create on Lane 0).

227
PLAN.md Normal file
View File

@ -0,0 +1,227 @@
# MOCAPGOD — private video-to-mocap pipeline
**Mission:** film John with a phone → extract 3D skeleton motion → retarget onto the
character_kit mixamorig rigs → clean → export FBX/GLB clips → feed the existing clip-bank
pipeline (merge_anims.py → GLB → three.js games + Unreal + 3GOD depot).
100% local, 100% owned, zero cloud, zero subscriptions.
**Written:** 2026-07-17 by Fable, for execution by Opus 4.8 sessions, one lane at a time.
Each lane is a self-contained work order with acceptance checks. Lanes A→D are the v1
critical path. Lanes EF are follow-ons. Do NOT start E/F before D ships.
---
## Ground rules (read before any lane)
1. **Fleet roles**
- **m3ultra** (`m3ultra@100.89.131.57`, 256GB) — POSE ENGINE. Model inference, any
training. Python via conda/uv there. MODELBEAST lives here; mocap becomes a sibling
service, same patterns (job dirs, batch keys — see `MESHGOD/scripts/mb_*` for the
client convention).
- **ultra** (this Mac, M1 Ultra 128GB) — GLUE + DCC. Blender headless retarget/cleanup/
export, orchestration, Unreal verification. Owns the canonical repo.
- **JING5** (M5 MBP) — capture companion + portable inference later. Not in v1 critical path.
2. **Repo:** `~/Documents/MOCAPGOD` on ultra is canonical. Mirror what's needed to m3ultra
under `~/Documents/MOCAPGOD` there too; keep model weights OUT of git (`weights/`,
`.gitignore` from day one). Init git in Lane 0.
3. **Long jobs** follow the heartbeat convention (`~/.claude/skills/jobs/SKILL.md`, status
in `~/.jobs/`). Any script expected >10 min gets a heartbeat. Scheduled jobs touching
~/Documents use `/opt/homebrew/bin/python3` (TCC — see memory: cron python trap).
4. **Verbose output** (installs, model downloads, test runs) pipes through `| lm -l 2`.
5. **Legal rails (hard):**
- NO reverse-engineering Cascadeur or extracting its weights. Ever.
- **SMPL/SMPL-X body model is research-licensed.** Most SOTA video-mocap models emit
SMPL params. Using SMPL-family model files in a commercial pipeline needs a
Meshcapade commercial license. Two allowed paths — pick per Lane B findings:
(a) obtain the license (cheap tiers exist; John decides), or
(b) SMPL-free path: use the model's **joint positions/rotations only**, never the
SMPL mesh/shape model files, and verify the chosen inference repo's own license
permits commercial use of outputs (many are MIT/Apache code with the SMPL file
as a separate user-supplied download — the *outputs* are generally ours, but
VERIFY per repo and record findings in `docs/LICENSES.md`).
- AMASS dataset (if Lane E trains anything): academic license by default — check
commercial terms before training anything shipped. Record in `docs/LICENSES.md`.
- Mixamo clips: fine to ship in games per Adobe ToS; do NOT use as ML training data.
- Everything decided goes in `docs/LICENSES.md` with links + dates.
6. **The treaty (interchange contract)** — every lane speaks this or doesn't ship:
- Skeleton: **mixamorig 65-joint** as defined by `~/Documents/character_kit`
(`female_game.glb` / male base). Canonical bone list generated in Lane 0.
- Intermediate motion format: **BVH at 30fps** + sidecar JSON
(`{fps, joint_order, root_trajectory, source_video, model, version}`).
BVH because Blender imports it natively and it's human-diffable.
- Units metres, Y-up, character faces Z (three.js convention; Unreal yaw-fix happens
at UE import, as established in the A_3D_STORE experiments).
- Final artifact: FBX (anim-only, Mixamo-style "Without Skin") dropped into
`clips_out/`, then merged to multi-clip GLB via character_kit `merge_anims.py`.
---
## Architecture
```
[iPhone/JING5 video] LANE A
│ (AirDrop/Tailscale to ultra: capture/inbox/)
[ingest.py — probe, trim, rename, ship to m3ultra] LANE A
▼ ssh/rsync
[m3ultra POSE ENGINE: video → 3D joints] LANE B
monocular HMR model (GVHMR/WHAM/TRAM-class, chosen in B1)
+ hand pass later (E)
│ emits motion.bvh + motion.json
▼ rsync back
[ultra: Blender headless RETARGET] LANE C
bvh → mixamorig, foot-contact fix, jitter filter, QC render (turntable mp4)
│ emits clip.fbx + qc.mp4
[CLIP FACTORY] LANE D
merge_anims.py → multi-clip GLB → games / 3GOD depot / Unreal import
```
One CLI to rule it: `mocap <video.mp4> --name dj_scratch_01` runs A→D end-to-end.
---
## LANE 0 — bootstrap (30 min, ultra)
Deliverables:
- git init MOCAPGOD, `.gitignore` (weights/, capture/, *.mp4, out dirs), `CLAUDE.md`
(fleet roles, treaty summary, pointers to this PLAN).
- `docs/LICENSES.md` skeleton.
- `spec/mixamorig_bones.json`: generate by opening
`character_kit/female/female_game.glb` in headless Blender and dumping the armature
bone names + rest pose. This file is the retarget ground truth.
- Acceptance: `python3 -c "import json; json.load(open('spec/mixamorig_bones.json'))"`
lists 65 bones; git log shows initial commit.
## LANE A — capture + ingest (half day, ultra)
Goal: friction-free path from "John films a move" to "video queued for the pose engine."
Tasks:
1. `docs/CAPTURE.md` — the recording protocol (keep to one page):
- Phone landscape on tripod/lean, 1080p60 (4K unnecessary for pose), full body in
frame INCLUDING FEET at all times, 23m distance, even light, plain-ish background,
fitted clothing (baggy = joint error), start/end in T-pose for 1s (calibration +
clip trimming anchor), one move per take, 530s takes.
- Transfer: AirDrop to ultra → `~/Documents/MOCAPGOD/capture/inbox/`.
2. `ingest.py` (ultra): watches/scans inbox; per video: ffprobe sanity (fps, duration,
resolution), normalize to 30fps h264 via ffmpeg (`-r 30`), rename
`YYYYMMDD_<name>.mp4`, rsync to `m3ultra:~/Documents/MOCAPGOD/queue/`, log to
`capture/LEDGER.tsv`.
3. Acceptance: drop any phone video in inbox → one command → appears in m3ultra queue,
ledger row written, malformed/portrait/no-audio files handled with clear errors.
## LANE B — pose engine (12 days, m3ultra) ← the heart
Goal: `queue/video.mp4``out/<name>/motion.bvh` + `motion.json`, world-grounded
(root trajectory included, not just pose-in-place).
Tasks:
1. **B1 — model bake-off (do first, half day).** WebSearch for current-best open
monocular human motion recovery ("world-grounded HMR", successors to
GVHMR / WHAM / TRAM / 4D-Humans — the field moves fast; July 2026 SOTA may be newer).
Selection criteria, in order: (1) permissive code license, (2) world-grounded global
trajectory, (3) runs on Apple Silicon (MPS or CPU acceptably; CUDA-only repos often
port with `map_location` + MPS fallbacks — budget for this), (4) SMPL-dependency
status per the legal rails. Install top 2 candidates in separate uv envs, run both on
3 test videos (walk, dance move, pick-up-object), eyeball in Blender. Record the
decision + benchmarks in `docs/B1_BAKEOFF.md`.
2. **B2 — service-ize.** `pose_engine.py`: consumes queue dir, runs chosen model,
converts output (SMPL rotations or joints) → mixamorig-ordered BVH @30fps + sidecar
JSON per the treaty. Heartbeat convention. The SMPL→mixamorig joint mapping table
lives in `spec/smpl_to_mixamorig.json` (write once, verify visually).
3. **B3 — jitter pass.** One-Euro or SavitzkyGolay filter on rotations, configurable;
root trajectory smoothed separately (preserve intentional locomotion).
4. Acceptance: 10s test video → BVH that imports into Blender with a recognizable,
right-way-up, non-sliding-through-floor human motion; runtime < 2× realtime on
m3ultra; survives a queue of 5 videos unattended (heartbeat proves it).
Gotchas from experience: check MPS support early — it decides everything; if the model
needs SMPL files, STOP and do the licensing decision before proceeding (present both
paths to John); keep every model in its own uv env (their dependency trees fight).
## LANE C — retarget + cleanup (1 day, ultra)
Goal: `motion.bvh` → clean `clip.fbx` on the character_kit rig + a QC video proof.
Tasks:
1. `retarget.py` (headless Blender, extends the house style of
`character_kit/scripts/merge_anims.py`):
- Import BVH → constraint-map bones to mixamorig armature from
`spec/mixamorig_bones.json` (name-map table in `spec/`, handles `mixamorig:` vs
`mixamorig_` variants — this bit us before), bake to keyframes.
- Foot-contact fix: detect frames where foot velocity ≈ 0 & height < threshold IK
pin. `# ponytail: threshold heuristic, upgrade to learned contact detection in Lane E if it annoys`.
- Trim the T-pose bookends (Lane A protocol guarantees them), root-motion option
(in-place vs traveling) as a flag.
- Export anim-only FBX (Mixamo "Without Skin" style — merge_anims.py already eats these).
2. QC render: 3-second turntable mp4 of the clip on the female_game body, written next
to the FBX. **Verify with own eyes** (the rule) — every clip gets its mp4 looked at
before entering the bank.
3. Acceptance: full chain A→C on one video of John walking produces an FBX that
`merge_anims.py` merges into `female_game.glb` without errors, and the QC mp4 shows
walking, not soup.
## LANE D — clip factory + integration (half day, ultra)
Goal: one command end-to-end; clips land everywhere they should.
Tasks:
1. `mocap` CLI (single script): `mocap capture/inbox/vid.mp4 --name dj_scratch_01
[--character female|male|both] [--in-place]` → runs A ingest → waits on B (ssh) → C →
drops `clips_out/dj_scratch_01.fbx` + QC mp4, optionally re-merges the character's
clip-bank GLB.
2. Publish hooks (flags, off by default): `--publish-3god` (depot pattern from procity
`publish.py`), `--to-unreal` (import via the established A_3D_STORE deferred-import
pattern; see memory: unreal-asset-convergence — slate post-tick, NOT direct
AssetImportTask through the bridge).
3. `docs/RUNBOOK.md`: the whole flow on one page, written for future-John.
4. Acceptance: film a 10s move → ONE command → new clip playable in 90sDJsim dev build
AND visible on a character in Unreal. That's the v1 finish line. Take the win, stop.
## LANE E — ML upgrades (post-v1, m3ultra, MLX territory; each item independent)
- E1: hand/finger pass (MediaPipe Hands or successor) blended onto body clips —
DJ work needs fingers eventually.
- E2: custom autoposer — MLP (6 control points → full pose) trained in MLX on
licensed/open mocap; our own baby Cascadeur-autopose for procedural NPC posing in
games at runtime. Check AMASS commercial terms FIRST (docs/LICENSES.md).
- E3: inbetweening/motion generation (current open motion-diffusion lineage) for
clip variation + transitions.
- E4: quadruped/centaur retarget experiments (front-half human map + back-half horse
chain) — feeds the centaur RPG. Cascadeur Pro handles the authored side; this is the
generated side.
- E5: style filter — train small nets on OUR OWN authored/captured clip library
(which we fully own) to stylize mocap output.
## LANE F — UX (optional, whenever it annoys)
- Drop-folder daemon (launchd on ultra; remember TCC python path) so AirDropped videos
auto-process; notification with QC mp4 when done.
- Tiny web dashboard on tailnet listing clips + QC videos (stdlib http.server, house style).
---
## Effort + risk summary
| Lane | Effort | Risk | Mitigation |
|---|---|---|---|
| 0+A | ~1 day | trivial | — |
| B | 12 days | MPS compat; SMPL licensing | bake-off first; legal rails decision gate |
| C | 1 day | retarget quality (feet, drift) | contact-fix pass + human QC gate |
| D | half day | none new | reuses proven pieces |
| E | open-ended | dataset licenses | per-item gates |
v1 total: **~34 focused days of agent work.** Quality expectation: solid for stylized
NPC/DJ clips; not Vicon; fingers come in E1. Cascadeur (bought separately) remains the
authoring/polish tool — its "animation unbaking" even cleans OUR mocap output, fully
within its license.
## Session protocol for Opus
One lane per session. Read this file + `CLAUDE.md` + the lane's acceptance checks first.
On completion: tick the lane in `PROGRESS.md`, commit, update `docs/` with anything
learned, leave gotchas for the next lane. Do not gold-plate; every lane's acceptance
check is the definition of done. When blocked on a John-decision (licenses, purchases),
write the decision memo in `docs/DECISIONS.md` and stop the lane there.

20
PROGRESS.md Normal file
View File

@ -0,0 +1,20 @@
# MOCAPGOD progress ledger
One lane per session. Tick on completion. See PLAN.md for acceptance checks.
- [x] **Lane 0** — bootstrap. git + .gitignore, docs/LICENSES.md skeleton,
spec/mixamorig_bones.json (65 bones, `mixamorig:` colon-prefixed). — 2026-07-17
- [x] **Lane A** — capture + ingest. docs/CAPTURE.md protocol, ingest.py
(probe → 30fps normalize → rename → rsync to m3ultra queue → LEDGER.tsv). — 2026-07-17
- [ ] **Lane B** — pose engine (m3ultra). Model bake-off, service-ize, jitter pass.
- [ ] **Lane C** — retarget + cleanup (Blender). bvh → mixamorig FBX + QC turntable.
- [ ] **Lane D** — clip factory. `mocap` CLI end-to-end; games + Unreal integration.
- [ ] Lane E — ML upgrades (post-v1, gated).
- [ ] Lane F — UX (optional).
## Notes for the next lane
- Ground-truth skeleton naming is **`mixamorig:`** (colon), armature object named `Armature`.
Lane C's name-map must handle colon vs underscore variants (PLAN warned about this).
- Blender headless entrypoint: `/Applications/Blender.app/Contents/MacOS/Blender --background --python <script>`.
- House style for Blender scripts: `~/Documents/character_kit/scripts/merge_anims.py`
(note its units warning: mixamorig head sits at ~0.0505 native units — don't rescale via parent).

24
docs/LICENSES.md Normal file
View File

@ -0,0 +1,24 @@
# Licenses & legal findings
Every third-party model/dataset/tool that touches the pipeline gets a row here with
its license, commercial status, link, and the date checked. Skeleton now; Lane B fills
the pose-model rows, Lane E fills any training-dataset rows. See PLAN.md §Ground rules.
## Components
| Component | Version | License | Commercial OK? | Notes | Checked |
|---|---|---|---|---|---|
| _pose model (Lane B1 winner)_ | — | — | — | fill after bake-off | — |
| SMPL / SMPL-X body model | — | research (Meshcapade) | **NO** by default | commercial needs Meshcapade license; or use joints-only path (PLAN §5) | — |
| AMASS dataset | — | academic | **verify** before any shipped training | Lane E only | — |
| Mixamo clips | — | Adobe ToS | ship-in-game OK; **not** ML training data | — | — |
## The SMPL gate (hard stop — John decision)
Most SOTA monocular mocap models emit SMPL parameters. Before any commercial use:
- **Path A:** buy a Meshcapade commercial license (cheap tiers exist).
- **Path B (SMPL-free):** use only the model's joint positions/rotations, never the SMPL
mesh/shape files, AND confirm the inference repo's own code license permits commercial
use of outputs.
Lane B writes the decision to `docs/DECISIONS.md` and stops there if unresolved.

33
spec/dump_bones.py Normal file
View File

@ -0,0 +1,33 @@
# Lane 0: dump the mixamorig armature (names + rest pose) from character_kit → ground truth.
# Run: Blender --background --python spec/dump_bones.py
import bpy, json, os, sys
GLB = os.path.expanduser("~/Documents/character_kit/female/female_game.glb")
OUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mixamorig_bones.json")
bpy.ops.wm.read_factory_settings(use_empty=True)
bpy.ops.import_scene.gltf(filepath=GLB)
arm = next((o for o in bpy.data.objects if o.type == "ARMATURE"), None)
if arm is None:
sys.exit("no armature in " + GLB)
def v(x): # round rest coords, they're the reference not gospel
return [round(c, 6) for c in x]
bones = [{
"name": b.name,
"parent": b.parent.name if b.parent else None,
"head": v(b.head_local), # armature-space rest pose
"tail": v(b.tail_local),
} for b in arm.data.bones]
json.dump({
"source": os.path.relpath(GLB, os.path.expanduser("~/Documents")),
"armature": arm.name,
"count": len(bones),
"units": "metres, Y-up (Blender Z-up native; glTF import applies +90X)",
"joint_order": [b["name"] for b in bones],
"bones": bones,
}, open(OUT, "w"), indent=1)
print("===DUMP=== %d bones -> %s" % (len(bones), OUT))

985
spec/mixamorig_bones.json Normal file
View File

@ -0,0 +1,985 @@
{
"source": "character_kit/female/female_game.glb",
"armature": "Armature",
"count": 65,
"units": "metres, Y-up (Blender Z-up native; glTF import applies +90X)",
"joint_order": [
"mixamorig:Hips",
"mixamorig:Spine",
"mixamorig:Spine1",
"mixamorig:Spine2",
"mixamorig:Neck",
"mixamorig:Head",
"mixamorig:HeadTop_End",
"mixamorig:LeftShoulder",
"mixamorig:LeftArm",
"mixamorig:LeftForeArm",
"mixamorig:LeftHand",
"mixamorig:LeftHandThumb1",
"mixamorig:LeftHandThumb2",
"mixamorig:LeftHandThumb3",
"mixamorig:LeftHandThumb4",
"mixamorig:LeftHandIndex1",
"mixamorig:LeftHandIndex2",
"mixamorig:LeftHandIndex3",
"mixamorig:LeftHandIndex4",
"mixamorig:LeftHandMiddle1",
"mixamorig:LeftHandMiddle2",
"mixamorig:LeftHandMiddle3",
"mixamorig:LeftHandMiddle4",
"mixamorig:LeftHandRing1",
"mixamorig:LeftHandRing2",
"mixamorig:LeftHandRing3",
"mixamorig:LeftHandRing4",
"mixamorig:LeftHandPinky1",
"mixamorig:LeftHandPinky2",
"mixamorig:LeftHandPinky3",
"mixamorig:LeftHandPinky4",
"mixamorig:RightShoulder",
"mixamorig:RightArm",
"mixamorig:RightForeArm",
"mixamorig:RightHand",
"mixamorig:RightHandThumb1",
"mixamorig:RightHandThumb2",
"mixamorig:RightHandThumb3",
"mixamorig:RightHandThumb4",
"mixamorig:RightHandIndex1",
"mixamorig:RightHandIndex2",
"mixamorig:RightHandIndex3",
"mixamorig:RightHandIndex4",
"mixamorig:RightHandMiddle1",
"mixamorig:RightHandMiddle2",
"mixamorig:RightHandMiddle3",
"mixamorig:RightHandMiddle4",
"mixamorig:RightHandRing1",
"mixamorig:RightHandRing2",
"mixamorig:RightHandRing3",
"mixamorig:RightHandRing4",
"mixamorig:RightHandPinky1",
"mixamorig:RightHandPinky2",
"mixamorig:RightHandPinky3",
"mixamorig:RightHandPinky4",
"mixamorig:LeftUpLeg",
"mixamorig:LeftLeg",
"mixamorig:LeftFoot",
"mixamorig:LeftToeBase",
"mixamorig:LeftToe_End",
"mixamorig:RightUpLeg",
"mixamorig:RightLeg",
"mixamorig:RightFoot",
"mixamorig:RightToeBase",
"mixamorig:RightToe_End"
],
"bones": [
{
"name": "mixamorig:Hips",
"parent": null,
"head": [
-0.789225,
9466.236328,
-151.250061
],
"tail": [
-0.789225,
96222.648438,
-151.250061
]
},
{
"name": "mixamorig:Spine",
"parent": "mixamorig:Hips",
"head": [
-0.789225,
10329.720703,
-235.288574
],
"tail": [
-0.789225,
111068.320312,
-10042.535156
]
},
{
"name": "mixamorig:Spine1",
"parent": "mixamorig:Spine",
"head": [
-0.789225,
11337.109375,
-333.333954
],
"tail": [
-0.789225,
126466.703125,
-11543.357422
]
},
{
"name": "mixamorig:Spine2",
"parent": "mixamorig:Spine1",
"head": [
-0.789225,
12488.410156,
-445.384796
],
"tail": [
-0.789225,
142009.34375,
-13056.675781
]
},
{
"name": "mixamorig:Neck",
"parent": "mixamorig:Spine2",
"head": [
-0.789225,
13783.625,
-571.441833
],
"tail": [
-0.789225,
85067.46875,
-571.441833
]
},
{
"name": "mixamorig:Head",
"parent": "mixamorig:Neck",
"head": [
-0.789225,
14487.500977,
-458.759033
],
"tail": [
-0.789225,
252447.953125,
-458.759033
]
},
{
"name": "mixamorig:HeadTop_End",
"parent": "mixamorig:Head",
"head": [
-0.789225,
16837.1875,
-82.598572
],
"tail": [
-0.789225,
254797.640625,
-82.598572
]
},
{
"name": "mixamorig:LeftShoulder",
"parent": "mixamorig:Spine2",
"head": [
442.507721,
13706.248047,
-574.602051
],
"tail": [
88047.03125,
-1489.208984,
-1204.128174
]
},
{
"name": "mixamorig:LeftArm",
"parent": "mixamorig:LeftShoulder",
"head": [
1318.595825,
13554.541992,
-580.922485
],
"tail": [
208370.921875,
-104744.4375,
190.466003
]
},
{
"name": "mixamorig:LeftForeArm",
"parent": "mixamorig:LeftArm",
"head": [
3389.101318,
12371.521484,
-573.214294
],
"tail": [
231106.125,
-111745.664062,
-1380.609131
]
},
{
"name": "mixamorig:LeftHand",
"parent": "mixamorig:LeftForeArm",
"head": [
5666.025391,
11129.896484,
-581.278625
],
"tail": [
40293.351562,
-8529.238281,
-2522.861572
]
},
{
"name": "mixamorig:LeftHandThumb1",
"parent": "mixamorig:LeftHand",
"head": [
5936.674316,
10944.513672,
-354.756042
],
"tail": [
27611.511719,
-3879.083008,
17744.591797
]
},
{
"name": "mixamorig:LeftHandThumb2",
"parent": "mixamorig:LeftHandThumb1",
"head": [
6153.185547,
10796.202148,
-173.540527
],
"tail": [
26929.759766,
-1141.089844,
16353.035156
]
},
{
"name": "mixamorig:LeftHandThumb3",
"parent": "mixamorig:LeftHandThumb2",
"head": [
6361.293945,
10676.62793,
-8.852399
],
"tail": [
26528.636719,
3037.48291,
14642.342773
]
},
{
"name": "mixamorig:LeftHandThumb4",
"parent": "mixamorig:LeftHandThumb3",
"head": [
6562.767578,
10600.321289,
137.978195
],
"tail": [
26730.089844,
2961.184082,
14789.208008
]
},
{
"name": "mixamorig:LeftHandIndex1",
"parent": "mixamorig:LeftHand",
"head": [
6597.790527,
10588.286133,
-409.299316
],
"tail": [
25725.089844,
458.958984,
116.727844
]
},
{
"name": "mixamorig:LeftHandIndex2",
"parent": "mixamorig:LeftHandIndex1",
"head": [
6789.022461,
10486.916016,
-404.033234
],
"tail": [
24523.035156,
347.490234,
104.93399
]
},
{
"name": "mixamorig:LeftHandIndex3",
"parent": "mixamorig:LeftHandIndex2",
"head": [
6966.322266,
10385.450195,
-398.955414
],
"tail": [
23263.535156,
1918.432617,
44.464233
]
},
{
"name": "mixamorig:LeftHandIndex4",
"parent": "mixamorig:LeftHandIndex3",
"head": [
7129.262695,
10300.71875,
-394.512909
],
"tail": [
23426.476562,
1833.701172,
48.906738
]
},
{
"name": "mixamorig:LeftHandMiddle1",
"parent": "mixamorig:LeftHand",
"head": [
6628.808594,
10601.523438,
-560.583801
],
"tail": [
25259.472656,
175.857422,
-597.073608
]
},
{
"name": "mixamorig:LeftHandMiddle2",
"parent": "mixamorig:LeftHandMiddle1",
"head": [
6815.149902,
10497.329102,
-560.967102
],
"tail": [
26283.472656,
-224.355469,
-601.661743
]
},
{
"name": "mixamorig:LeftHandMiddle3",
"parent": "mixamorig:LeftHandMiddle2",
"head": [
7009.799805,
10390.051758,
-561.37616
],
"tail": [
25539.234375,
3322.921875,
-647.295044
]
},
{
"name": "mixamorig:LeftHandMiddle4",
"parent": "mixamorig:LeftHandMiddle3",
"head": [
7195.093262,
10319.376953,
-562.207458
],
"tail": [
25724.527344,
3252.24707,
-648.126343
]
},
{
"name": "mixamorig:LeftHandRing1",
"parent": "mixamorig:LeftHand",
"head": [
6611.787109,
10594.608398,
-709.329651
],
"tail": [
22724.742188,
864.296875,
-1340.466309
]
},
{
"name": "mixamorig:LeftHandRing2",
"parent": "mixamorig:LeftHandRing1",
"head": [
6772.956543,
10497.37793,
-715.746765
],
"tail": [
23769.109375,
932.27832,
-1381.445312
]
},
{
"name": "mixamorig:LeftHandRing3",
"parent": "mixamorig:LeftHandRing2",
"head": [
6942.910156,
10401.706055,
-722.302124
],
"tail": [
19245.6875,
-795.93457,
-1207.831177
]
},
{
"name": "mixamorig:LeftHandRing4",
"parent": "mixamorig:LeftHandRing3",
"head": [
7065.902832,
10289.691406,
-727.157776
],
"tail": [
19368.681641,
-907.949219,
-1212.68689
]
},
{
"name": "mixamorig:LeftHandPinky1",
"parent": "mixamorig:LeftHand",
"head": [
6523.467773,
10637.009766,
-853.324585
],
"tail": [
20784.412109,
955.730469,
-1099.565796
]
},
{
"name": "mixamorig:LeftHandPinky2",
"parent": "mixamorig:LeftHandPinky1",
"head": [
6666.083984,
10540.208008,
-855.844788
],
"tail": [
19741.429688,
3601.384766,
-1097.077393
]
},
{
"name": "mixamorig:LeftHandPinky3",
"parent": "mixamorig:LeftHandPinky2",
"head": [
6796.808594,
10470.764648,
-858.250488
],
"tail": [
19782.582031,
6344.070801,
-1120.328857
]
},
{
"name": "mixamorig:LeftHandPinky4",
"parent": "mixamorig:LeftHandPinky3",
"head": [
6926.664551,
10429.489258,
-860.820496
],
"tail": [
19912.4375,
6302.79541,
-1122.898804
]
},
{
"name": "mixamorig:RightShoulder",
"parent": "mixamorig:Spine2",
"head": [
-444.086426,
13706.254883,
-568.281982
],
"tail": [
-88050.125,
-1489.464844,
61.255005
]
},
{
"name": "mixamorig:RightArm",
"parent": "mixamorig:RightShoulder",
"head": [
-1320.188232,
13554.538086,
-561.957397
],
"tail": [
-208372.546875,
-104744.46875,
-2221.170898
]
},
{
"name": "mixamorig:RightForeArm",
"parent": "mixamorig:RightArm",
"head": [
-3390.705566,
12371.538086,
-578.588135
],
"tail": [
-231104.859375,
-111744.070312,
-673.574585
]
},
{
"name": "mixamorig:RightHand",
"parent": "mixamorig:RightForeArm",
"head": [
-5667.604492,
11129.9375,
-579.476501
],
"tail": [
-39838.847656,
-8479.037109,
-2616.459961
]
},
{
"name": "mixamorig:RightHandThumb1",
"parent": "mixamorig:RightHand",
"head": [
-5934.709961,
10946.12207,
-354.75415
],
"tail": [
-27219.601562,
-3695.910156,
17772.466797
]
},
{
"name": "mixamorig:RightHandThumb2",
"parent": "mixamorig:RightHandThumb1",
"head": [
-6148.393066,
10799.077148,
-174.975739
],
"tail": [
-26944.269531,
-1260.239258,
16634.84375
]
},
{
"name": "mixamorig:RightHandThumb3",
"parent": "mixamorig:RightHandThumb2",
"head": [
-6358.204102,
10677.383789,
-10.001045
],
"tail": [
-25006.152344,
505.775391,
14820.926758
]
},
{
"name": "mixamorig:RightHandThumb4",
"parent": "mixamorig:RightHandThumb3",
"head": [
-6542.012207,
10577.450195,
142.787064
],
"tail": [
-25190.001953,
405.819336,
14973.646484
]
},
{
"name": "mixamorig:RightHandIndex1",
"parent": "mixamorig:RightHand",
"head": [
-6565.821777,
10625.561523,
-408.567749
],
"tail": [
-26418.222656,
-1912.795898,
886.029175
]
},
{
"name": "mixamorig:RightHandIndex2",
"parent": "mixamorig:RightHandIndex1",
"head": [
-6764.312012,
10500.107422,
-395.788574
],
"tail": [
-25917.001953,
-92.72168,
741.736694
]
},
{
"name": "mixamorig:RightHandIndex3",
"parent": "mixamorig:RightHandIndex2",
"head": [
-6955.79248,
10394.117188,
-384.206177
],
"tail": [
-23732.816406,
145.230469,
684.78833
]
},
{
"name": "mixamorig:RightHandIndex4",
"parent": "mixamorig:RightHandIndex3",
"head": [
-7123.512207,
10291.541992,
-373.55481
],
"tail": [
-23900.535156,
42.655273,
695.439697
]
},
{
"name": "mixamorig:RightHandMiddle1",
"parent": "mixamorig:RightHand",
"head": [
-6635.340332,
10581.800781,
-574.067993
],
"tail": [
-24758.15625,
2170.779297,
803.72583
]
},
{
"name": "mixamorig:RightHandMiddle2",
"parent": "mixamorig:RightHandMiddle1",
"head": [
-6816.533203,
10497.678711,
-559.903076
],
"tail": [
-25262.244141,
246.617188,
986.281494
]
},
{
"name": "mixamorig:RightHandMiddle3",
"parent": "mixamorig:RightHandMiddle2",
"head": [
-7000.961426,
10395.112305,
-544.467529
],
"tail": [
-21629.75,
796.844727,
806.360229
]
},
{
"name": "mixamorig:RightHandMiddle4",
"parent": "mixamorig:RightHandMiddle3",
"head": [
-7147.250488,
10299.079102,
-531.332397
],
"tail": [
-21776.039062,
700.811523,
819.495361
]
},
{
"name": "mixamorig:RightHandRing1",
"parent": "mixamorig:RightHand",
"head": [
-6623.062012,
10576.748047,
-705.524963
],
"tail": [
-23174.042969,
1778.883789,
-1581.874756
]
},
{
"name": "mixamorig:RightHandRing2",
"parent": "mixamorig:RightHandRing1",
"head": [
-6788.567871,
10488.748047,
-714.146545
],
"tail": [
-23349.103516,
714.084961,
-1565.905029
]
},
{
"name": "mixamorig:RightHandRing3",
"parent": "mixamorig:RightHandRing2",
"head": [
-6954.165527,
10390.993164,
-722.717468
],
"tail": [
-20906.033203,
2007.145508,
-1436.617188
]
},
{
"name": "mixamorig:RightHandRing4",
"parent": "mixamorig:RightHandRing3",
"head": [
-7093.674316,
10307.145508,
-729.937439
],
"tail": [
-21045.542969,
1923.297852,
-1443.837158
]
},
{
"name": "mixamorig:RightHandPinky1",
"parent": "mixamorig:RightHand",
"head": [
-6513.206543,
10618.483398,
-847.997803
],
"tail": [
-22390.753906,
2783.484863,
-1383.08667
]
},
{
"name": "mixamorig:RightHandPinky2",
"parent": "mixamorig:RightHandPinky1",
"head": [
-6671.937988,
10540.050781,
-853.450745
],
"tail": [
-19410.054688,
3466.481445,
-1255.519775
]
},
{
"name": "mixamorig:RightHandPinky3",
"parent": "mixamorig:RightHandPinky2",
"head": [
-6799.26709,
10469.234375,
-857.699768
],
"tail": [
-19322.640625,
5672.211914,
-1328.71875
]
},
{
"name": "mixamorig:RightHandPinky4",
"parent": "mixamorig:RightHandPinky3",
"head": [
-6924.52002,
10421.283203,
-862.085754
],
"tail": [
-19447.894531,
5624.260742,
-1333.104736
]
},
{
"name": "mixamorig:LeftUpLeg",
"parent": "mixamorig:Hips",
"head": [
886.457642,
8985.595703,
-193.996872
],
"tail": [
-9554.929688,
-408262.4375,
-1658.337769
]
},
{
"name": "mixamorig:LeftLeg",
"parent": "mixamorig:LeftUpLeg",
"head": [
781.932251,
4813.119629,
-208.640701
],
"tail": [
-8360.658203,
-399833.0,
4053.783203
]
},
{
"name": "mixamorig:LeftFoot",
"parent": "mixamorig:LeftLeg",
"head": [
690.580444,
766.657715,
-166.041107
],
"tail": [
-5178.653809,
-67254.273438,
107355.617188
]
},
{
"name": "mixamorig:LeftToeBase",
"parent": "mixamorig:LeftFoot",
"head": [
631.921875,
86.424805,
909.162231
],
"tail": [
-4442.078613,
-1651.948608,
52295.636719
]
},
{
"name": "mixamorig:LeftToe_End",
"parent": "mixamorig:LeftToeBase",
"head": [
581.169006,
69.043587,
1423.025879
],
"tail": [
-4492.523438,
-1669.224365,
52809.539062
]
},
{
"name": "mixamorig:RightUpLeg",
"parent": "mixamorig:Hips",
"head": [
-888.036194,
8985.594727,
-137.668762
],
"tail": [
9563.602539,
-408264.1875,
-8409.758789
]
},
{
"name": "mixamorig:RightLeg",
"parent": "mixamorig:RightUpLeg",
"head": [
-783.510376,
4813.095215,
-220.262909
],
"tail": [
8359.009766,
-399829.96875,
4591.915527
]
},
{
"name": "mixamorig:RightFoot",
"parent": "mixamorig:RightLeg",
"head": [
-692.159668,
766.664001,
-172.128296
],
"tail": [
5172.104004,
-67254.085938,
109036.03125
]
},
{
"name": "mixamorig:RightToeBase",
"parent": "mixamorig:RightFoot",
"head": [
-633.502808,
86.396927,
919.915161
],
"tail": [
4442.318848,
-1651.50293,
52424.015625
]
},
{
"name": "mixamorig:RightToe_End",
"parent": "mixamorig:RightToeBase",
"head": [
-582.748291,
69.009033,
1434.956177
],
"tail": [
4493.073242,
-1668.890869,
52939.058594
]
}
]
}