cozyclay 2.1.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (583) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +40 -113
  4. package/bin/agent/agent-runner.mjs +9 -10
  5. package/bin/agent/cliproxy-provider.mjs +135 -0
  6. package/bin/agent/credential-store.mjs +30 -7
  7. package/bin/agent/pi-tools.mjs +4 -1
  8. package/bin/agent/provider-keys.mjs +32 -0
  9. package/bin/agent/provider-login.mjs +110 -0
  10. package/bin/agent/provider-routes.mjs +99 -0
  11. package/bin/agent/providers.mjs +19 -97
  12. package/bin/agent/script-tool.mjs +17 -4
  13. package/bin/agent/studio-motion-reference.mjs +23 -0
  14. package/bin/agent/studio-prompt.mjs +1 -1
  15. package/bin/agent/studio-rebase-text.mjs +32 -0
  16. package/bin/agent/studio-rebase.mjs +26 -39
  17. package/bin/agent/studio-tools.mjs +9 -28
  18. package/bin/agent/tool-arguments.mjs +49 -0
  19. package/bin/agent/turn-frames.mjs +66 -0
  20. package/bin/codex-auth.mjs +9 -2
  21. package/bin/cozyclay.mjs +10 -116
  22. package/bin/live/cli.mjs +22 -6
  23. package/bin/mcp-runtime.mjs +2 -12
  24. package/bin/package-signature.mjs +0 -4
  25. package/dist/app/index.html +7 -6
  26. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  27. package/dist/assets/analytics-C9sUnndd.js +1 -0
  28. package/dist/assets/app-CCh--1Hc.js +5087 -0
  29. package/dist/assets/app-f-fkV5uP.css +1 -0
  30. package/dist/assets/compile-worker-CkxiD6lH.js +5 -0
  31. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  32. package/dist/assets/{first-shot-handoff-BlT33CGf.js → first-shot-handoff-CC4xe4HM.js} +1 -1
  33. package/dist/assets/{landing-BSesrCpL.js → landing-DjHD8u7k.js} +1 -1
  34. package/dist/assets/scene-asset-sync-Hx_FzdOH.js +20 -0
  35. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  36. package/dist/assets/workflow-C4yKH1p4.js +179 -0
  37. package/dist/cozyclay-package.json +1 -1
  38. package/dist/index.html +3 -3
  39. package/dist/llms.txt +14 -0
  40. package/dist/sw.js +3 -6
  41. package/dist/workflow/index.html +5 -4
  42. package/mcp/LIVE-PROTOCOL.md +7 -47
  43. package/mcp/README.md +16 -26
  44. package/mcp/live-hub.mjs +6 -10
  45. package/mcp/package.json +1 -3
  46. package/mcp/tool-handlers.mjs +4 -168
  47. package/package.json +3 -22
  48. package/src/App.jsx +174 -2639
  49. package/src/agent-progress.js +79 -0
  50. package/src/agent-turn-mark.js +30 -0
  51. package/src/analytics.js +1 -19
  52. package/src/app-context.js +5 -0
  53. package/src/app-stage.jsx +2 -34
  54. package/src/asset-pane.jsx +6 -5
  55. package/src/camera-block.js +21 -0
  56. package/src/camera-direction.js +120 -0
  57. package/src/character-kind.js +3 -9
  58. package/src/command-bus.js +8 -6
  59. package/src/commands/cast.js +5 -34
  60. package/src/commands/elements/character.js +1 -1
  61. package/src/commands/elements/motion.js +1 -6
  62. package/src/commands/elements/object.js +6 -2
  63. package/src/commands/elements/shot.js +4 -1
  64. package/src/commands/elements.js +38 -14
  65. package/src/commands/index.js +3 -1
  66. package/src/commands/kits.js +37 -0
  67. package/src/commands/motion-timing.js +57 -0
  68. package/src/commands/motion.js +9 -152
  69. package/src/commands/motion3-compile.js +65 -0
  70. package/src/commands/motion3.js +207 -0
  71. package/src/commands/objects.js +6 -4
  72. package/src/commands/shot.js +49 -11
  73. package/src/commands/stage.js +14 -1
  74. package/src/commands/view.js +4 -1
  75. package/src/document-mirrors.js +42 -0
  76. package/src/document-store.js +4 -0
  77. package/src/domains/cast.js +19 -194
  78. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  79. package/src/domains/motion/take-source.js +51 -0
  80. package/src/domains/motion.js +60 -1838
  81. package/src/domains/scenes.js +12 -55
  82. package/src/domains/shots.js +2 -2
  83. package/src/domains/stage.js +4 -2
  84. package/src/draft-ghost.js +46 -0
  85. package/src/draft-ghost.jsx +129 -0
  86. package/src/dualview.jsx +4 -3
  87. package/src/effects/EffectsLayer.jsx +112 -0
  88. package/src/effects/effect-meshes.js +232 -0
  89. package/src/effects/effect-record.js +103 -0
  90. package/src/effects/emitter.js +59 -0
  91. package/src/effects/simulate.js +261 -0
  92. package/src/effects/state.js +59 -0
  93. package/src/execution-telemetry.js +2 -3
  94. package/src/first-success-guide.jsx +5 -5
  95. package/src/ghost-set.js +257 -0
  96. package/src/held-object-edit.jsx +113 -0
  97. package/src/held-object-pose.js +175 -0
  98. package/src/hierarchy-model.js +1 -1
  99. package/src/hierarchy-panel.jsx +1 -1
  100. package/src/imported-mesh.jsx +103 -0
  101. package/src/kits/held.js +84 -0
  102. package/src/kits/index.js +70 -0
  103. package/src/kits/smoking.js +57 -0
  104. package/src/light-blockers.js +93 -0
  105. package/src/motion/beat-board-model.js +84 -0
  106. package/src/motion/beat-board.css +124 -0
  107. package/src/motion/beat-board.jsx +59 -0
  108. package/src/motion/center-of-mass.js +66 -0
  109. package/src/motion/fix-collisions.js +850 -0
  110. package/src/motion/physics-review.js +118 -0
  111. package/src/{ardy → motion}/physics-support.js +1 -76
  112. package/src/motion/rig-snapshot.js +22 -0
  113. package/src/motion/take-segments.jsx +140 -0
  114. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  115. package/src/{ardy → motion}/timeline.css +1 -2
  116. package/src/{ardy → motion}/timeline.jsx +48 -419
  117. package/src/motion/waypoints.js +76 -0
  118. package/src/motion3/beats.js +83 -0
  119. package/src/motion3/body.js +158 -0
  120. package/src/motion3/bones.js +47 -0
  121. package/src/motion3/carried.js +47 -0
  122. package/src/motion3/compile-job.js +75 -0
  123. package/src/motion3/compile-worker.js +10 -0
  124. package/src/motion3/compiler/anchors.js +105 -0
  125. package/src/motion3/compiler/arm-orient.js +128 -0
  126. package/src/motion3/compiler/channels.js +125 -0
  127. package/src/motion3/compiler/compile.js +205 -0
  128. package/src/motion3/compiler/gait-rhythm.js +97 -0
  129. package/src/motion3/compiler/grip.js +171 -0
  130. package/src/motion3/compiler/head-steady.js +48 -0
  131. package/src/motion3/compiler/hold.js +134 -0
  132. package/src/motion3/compiler/idle.js +113 -0
  133. package/src/motion3/compiler/limbs.js +170 -0
  134. package/src/motion3/compiler/math.js +72 -0
  135. package/src/motion3/compiler/pose.js +162 -0
  136. package/src/motion3/compiler/quat.js +49 -0
  137. package/src/motion3/compiler/skeleton.js +74 -0
  138. package/src/motion3/compiler/validate-common.js +32 -0
  139. package/src/motion3/compiler/validate-goals.js +118 -0
  140. package/src/motion3/compiler/validate-objects.js +143 -0
  141. package/src/motion3/compiler/validate-parts.js +116 -0
  142. package/src/motion3/compiler/validate.js +122 -0
  143. package/src/motion3/compiler/vocab.js +73 -0
  144. package/src/motion3/compiler/walk-pelvis.js +275 -0
  145. package/src/motion3/compiler/walk.js +207 -0
  146. package/src/motion3/compiler/wrist-clamp.js +32 -0
  147. package/src/motion3/delta.js +47 -0
  148. package/src/motion3/describe.js +174 -0
  149. package/src/motion3/docs.js +27 -0
  150. package/src/motion3/edit-carry.js +21 -0
  151. package/src/motion3/fix/ease.js +16 -0
  152. package/src/motion3/fix/ground.js +37 -0
  153. package/src/motion3/fix/index.js +52 -0
  154. package/src/motion3/fix/push.js +71 -0
  155. package/src/motion3/fix/reach.js +46 -0
  156. package/src/motion3/fix/retime.js +79 -0
  157. package/src/motion3/fix/self.js +211 -0
  158. package/src/motion3/fix/slide.js +70 -0
  159. package/src/motion3/fix/turn.js +51 -0
  160. package/src/motion3/follow.js +39 -0
  161. package/src/motion3/free-motion.js +173 -0
  162. package/src/motion3/grip-choice.js +130 -0
  163. package/src/motion3/hold-plan.js +157 -0
  164. package/src/motion3/json-patch.js +77 -0
  165. package/src/motion3/key-aim.js +105 -0
  166. package/src/motion3/key-edit.js +82 -0
  167. package/src/motion3/lenient.js +127 -0
  168. package/src/motion3/object-keys.js +236 -0
  169. package/src/motion3/object-pose.js +182 -0
  170. package/src/motion3/object-tracks.js +12 -0
  171. package/src/motion3/pipeline.js +102 -0
  172. package/src/motion3/playback.js +51 -0
  173. package/src/motion3/probes.js +91 -0
  174. package/src/motion3/qa/body-checks.js +34 -0
  175. package/src/motion3/qa/check-names.js +14 -0
  176. package/src/motion3/qa/checks.js +121 -0
  177. package/src/motion3/qa/contact-checks.js +51 -0
  178. package/src/motion3/qa/explain.js +80 -0
  179. package/src/motion3/qa/fmt.js +5 -0
  180. package/src/motion3/qa/foot-checks.js +72 -0
  181. package/src/motion3/qa/geometry.js +77 -0
  182. package/src/motion3/qa/goals.js +191 -0
  183. package/src/motion3/qa/ground.js +60 -0
  184. package/src/motion3/qa/hints-contact.js +179 -0
  185. package/src/motion3/qa/hints-goal.js +160 -0
  186. package/src/motion3/qa/hints-knee.js +24 -0
  187. package/src/motion3/qa/hints-motion.js +209 -0
  188. package/src/motion3/qa/hints-object.js +91 -0
  189. package/src/motion3/qa/index.js +42 -0
  190. package/src/motion3/qa/key-checks.js +82 -0
  191. package/src/motion3/qa/near.js +96 -0
  192. package/src/motion3/qa/object-checks.js +135 -0
  193. package/src/motion3/qa/patch.js +161 -0
  194. package/src/motion3/qa/severity.js +38 -0
  195. package/src/motion3/qa/spec-checks.js +65 -0
  196. package/src/motion3/qa/style.js +218 -0
  197. package/src/motion3/qa/wrist-checks.js +69 -0
  198. package/src/motion3/qa/wrist-obs.js +60 -0
  199. package/src/motion3/refs.js +120 -0
  200. package/src/motion3/repair-tune.js +121 -0
  201. package/src/motion3/repair.js +83 -0
  202. package/src/motion3/report.js +67 -0
  203. package/src/motion3/rigs/index.js +14 -0
  204. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  205. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  206. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  207. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  208. package/src/motion3/scene.js +60 -0
  209. package/src/motion3/schema/brief.js +89 -0
  210. package/src/motion3/schema/fields.js +44 -0
  211. package/src/motion3/schema/spec-examples.js +46 -0
  212. package/src/motion3/schema/topics.js +111 -0
  213. package/src/motion3/schema/types.js +147 -0
  214. package/src/motion3/search.js +117 -0
  215. package/src/motion3/second-hand.js +112 -0
  216. package/src/motion3/skills/basic.js +82 -0
  217. package/src/motion3/skills/book.js +76 -0
  218. package/src/motion3/skills/car.js +145 -0
  219. package/src/motion3/skills/frames-auto.js +29 -0
  220. package/src/motion3/skills/index.js +83 -0
  221. package/src/motion3/skills/info.js +65 -0
  222. package/src/motion3/skills/smoke-kit.js +109 -0
  223. package/src/motion3/skills/smoke.js +160 -0
  224. package/src/motion3/spec-store.js +59 -0
  225. package/src/motion3/take-edit.js +155 -0
  226. package/src/motion3/take.js +63 -0
  227. package/src/motion3/timeline.js +127 -0
  228. package/src/motion3/views.js +121 -0
  229. package/src/motion3/walk-plan.js +119 -0
  230. package/src/object-catalog.jsx +7 -1
  231. package/src/object-colors.js +98 -0
  232. package/src/object-gizmo-parts.js +115 -0
  233. package/src/object-gizmo.jsx +37 -122
  234. package/src/object-glow.js +139 -0
  235. package/src/object-hidden.js +33 -0
  236. package/src/object-look.js +196 -0
  237. package/src/object-size.js +10 -0
  238. package/src/object-travel.js +71 -6
  239. package/src/panels/CameraPanel.jsx +7 -7
  240. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  241. package/src/panels/LightPanel.jsx +25 -4
  242. package/src/panels/ObjectLookPanel.jsx +88 -0
  243. package/src/panels/PoseImagePanel.jsx +1 -1
  244. package/src/panels/PosePanel.jsx +2 -17
  245. package/src/panels/RigControlPanel.jsx +5 -53
  246. package/src/panels/SubjectBox.jsx +4 -1
  247. package/src/panels/details.css +14 -0
  248. package/src/posestudio.jsx +4 -27
  249. package/src/project-browser.jsx +3 -4
  250. package/src/project-resources.js +18 -31
  251. package/src/project.js +13 -104
  252. package/src/props.jsx +25 -280
  253. package/src/rail-dot-drag.js +23 -0
  254. package/src/render-passes.js +10 -0
  255. package/src/resource-status.jsx +1 -0
  256. package/src/result-modal.jsx +4 -19
  257. package/src/room.jsx +20 -12
  258. package/src/scene-assets.js +8 -6
  259. package/src/scene-light-place.js +72 -0
  260. package/src/scene-lights.jsx +148 -0
  261. package/src/scene-objects.js +31 -139
  262. package/src/scenes.js +15 -105
  263. package/src/semantic-edit.js +2 -5
  264. package/src/set-pieces.jsx +183 -0
  265. package/src/settings-menu.jsx +3 -11
  266. package/src/shell/BottomDock.jsx +11 -53
  267. package/src/shell/CompositionGuideButton.jsx +20 -0
  268. package/src/shell/DetailsSlot.jsx +16 -200
  269. package/src/shell/GhostsMenuGroup.jsx +74 -0
  270. package/src/shell/LibrarySlot.jsx +1 -3
  271. package/src/shell/MenuBar.jsx +3 -3
  272. package/src/shell/PreferencesDialog.jsx +15 -264
  273. package/src/shell/PreferencesSlot.jsx +2 -8
  274. package/src/shell/ShotPreviewHeader.jsx +17 -0
  275. package/src/shell/TopBar.jsx +5 -83
  276. package/src/shell/ViewportToolbar.jsx +23 -93
  277. package/src/shell/agent-glass.css +19 -6
  278. package/src/shell/details-selection.js +42 -0
  279. package/src/shell/ghosts-menu.css +22 -0
  280. package/src/shell/glass-regions.css +29 -3
  281. package/src/shell/preferences.css +6 -1
  282. package/src/shell/viewport.css +12 -0
  283. package/src/shot-authoring.js +4 -7
  284. package/src/soft-shadows.js +37 -0
  285. package/src/stage-attach-frames.js +12 -12
  286. package/src/stage-canvas-rigs.jsx +3 -3
  287. package/src/stage-capture.jsx +42 -8
  288. package/src/stage-characters.jsx +22 -216
  289. package/src/stage-editor-gizmos.jsx +6 -6
  290. package/src/stage-environment.js +93 -0
  291. package/src/stage-hdr-builtins.js +107 -0
  292. package/src/stage-hdr-image.js +116 -0
  293. package/src/stage-hdr-library.js +70 -0
  294. package/src/stage-hdr-map.js +94 -0
  295. package/src/stage-hdr.js +130 -0
  296. package/src/stage-lighting.js +149 -0
  297. package/src/stage-occlusion.js +210 -0
  298. package/src/stage-sky.jsx +159 -0
  299. package/src/stage-startup-defaults.js +5 -9
  300. package/src/studio-actions.js +12 -14
  301. package/src/studio-agent-commands.js +46 -16
  302. package/src/studio-agent-motion.js +9 -9
  303. package/src/studio-agent-protocol.js +46 -73
  304. package/src/studio-app-binding.js +29 -45
  305. package/src/studio-asset-list.js +17 -0
  306. package/src/studio-contact-sheet.js +37 -5
  307. package/src/studio-elements.js +27 -7
  308. package/src/studio-entity-bounds.js +18 -0
  309. package/src/studio-error-codes.js +8 -0
  310. package/src/studio-export-framing.js +152 -0
  311. package/src/studio-lighting-check.js +103 -0
  312. package/src/studio-motion-visual.js +150 -0
  313. package/src/studio-schema-errors.js +80 -0
  314. package/src/studio-support-gap.js +74 -0
  315. package/src/styles.css +1 -19
  316. package/src/timeline-defaults.js +5 -0
  317. package/src/timeline-extent.js +8 -20
  318. package/src/tutorial-walk.js +17 -0
  319. package/src/ui-scrub.js +1 -1
  320. package/src/use-shot-camera-tracks.js +12 -0
  321. package/src/view-ghosts.js +97 -0
  322. package/src/view-ghosts.jsx +49 -0
  323. package/src/workflow/AgentPanel.jsx +47 -166
  324. package/src/workflow/AgentProgressCard.jsx +107 -0
  325. package/src/workflow/AgentReplyText.jsx +37 -0
  326. package/src/workflow/AgentTurnSteps.jsx +84 -0
  327. package/src/workflow/LoginPanel.jsx +140 -0
  328. package/src/workflow/WorkflowBuilder.jsx +7 -23
  329. package/src/workflow/agent-client.js +54 -51
  330. package/src/workflow/agent-panel.css +71 -1
  331. package/src/workflow/agent-progress-card.css +167 -0
  332. package/src/workflow/agent-progress-view.js +47 -0
  333. package/src/workflow/agent-turn-steps.css +113 -0
  334. package/src/workflow/agent-turn.js +191 -0
  335. package/src/workflow/login-client.js +34 -0
  336. package/src/workflow/motion-input.js +18 -31
  337. package/src/workflow/node-schema.js +1 -1
  338. package/src/workflow/reply-markdown.js +69 -0
  339. package/src/workflow/scene-asset-sync.js +8 -8
  340. package/tools/agent-session-stats.mjs +61 -0
  341. package/tools/dev-full.mjs +5 -56
  342. package/tools/eslint-baseline.json +12 -13
  343. package/tools/headless-studio.mjs +85 -0
  344. package/tools/knip-baseline.json +0 -179
  345. package/tools/loc-baseline.json +33 -83
  346. package/tools/motion3/extract-body.mjs +103 -0
  347. package/tools/motion3/extract-rig.mjs +85 -0
  348. package/tools/process-supervisor.mjs +0 -88
  349. package/tools/run-tests.mjs +9 -124
  350. package/bin/agent/motion-runtime.mjs +0 -76
  351. package/dist/ardy/cskel27-rest.json +0 -557
  352. package/dist/assets/analytics-B41FmPYI.js +0 -1
  353. package/dist/assets/app-Do-Og5Pu.css +0 -1
  354. package/dist/assets/app-DwP-tl2x.js +0 -4920
  355. package/dist/assets/config-Bx7pYsD9.js +0 -1
  356. package/dist/assets/config-DeoFTYzb.css +0 -1
  357. package/dist/assets/demo-Dt0qZfS7.js +0 -1
  358. package/dist/assets/scene-asset-sync-BCWDJB1d.js +0 -19
  359. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  360. package/dist/assets/ticket-jqMhqL88.js +0 -1
  361. package/dist/assets/workflow-Br-K7Srs.js +0 -179
  362. package/dist/demo/walk-then-stop.npz +0 -0
  363. package/mcp/ardy-prompts.mjs +0 -218
  364. package/src/ardy/auto-fix-panel.css +0 -108
  365. package/src/ardy/auto-physics.js +0 -1194
  366. package/src/ardy/client.js +0 -153
  367. package/src/ardy/convert.js +0 -313
  368. package/src/ardy/cskel27-neutral.js +0 -39
  369. package/src/ardy/cskel27.js +0 -77
  370. package/src/ardy/export.js +0 -165
  371. package/src/ardy/fix-collisions.js +0 -2257
  372. package/src/ardy/foot-lock.js +0 -230
  373. package/src/ardy/motion-calibration.js +0 -118
  374. package/src/ardy/motion-edit.js +0 -213
  375. package/src/ardy/motion-url.js +0 -55
  376. package/src/ardy/mp4-duration.js +0 -102
  377. package/src/ardy/npz.js +0 -595
  378. package/src/ardy/physics-panel.css +0 -21
  379. package/src/ardy/physics-panel.jsx +0 -89
  380. package/src/ardy/physics-refine.js +0 -111
  381. package/src/ardy/physics-review.js +0 -567
  382. package/src/ardy/physics-temporal.js +0 -54
  383. package/src/ardy/platform-fit-panel.css +0 -64
  384. package/src/ardy/platform-fit-panel.jsx +0 -41
  385. package/src/ardy/platform-fit.js +0 -326
  386. package/src/ardy/playback.js +0 -711
  387. package/src/ardy/pose-pin.js +0 -97
  388. package/src/ardy/prompt-clips.js +0 -30
  389. package/src/ardy/retime.js +0 -211
  390. package/src/ardy/root-drop.js +0 -369
  391. package/src/ardy/timeline-resize.js +0 -13
  392. package/src/ardy/to-cskel27.js +0 -225
  393. package/src/ardy/trim.js +0 -33
  394. package/src/ardy/waypoints.js +0 -369
  395. package/src/ardy-bridge-contract.js +0 -281
  396. package/src/domains/motion/motion-video-capture.js +0 -664
  397. package/src/i2v-motion-client.js +0 -77
  398. package/src/i2v-motion-studio.jsx +0 -180
  399. package/src/line-edit.js +0 -1348
  400. package/src/motion/generation.js +0 -105
  401. package/src/motion-readiness-ui.jsx +0 -67
  402. package/src/motion-readiness.js +0 -40
  403. package/src/motion-resources.js +0 -177
  404. package/src/motion-store.js +0 -65
  405. package/src/motion-trail.js +0 -601
  406. package/src/multimodel-ingest.js +0 -394
  407. package/src/panels/PromptBlocksPanel.jsx +0 -444
  408. package/src/panels/VideoCapturePanel.jsx +0 -181
  409. package/src/pose-extract/browser.js +0 -42
  410. package/src/pose-extract/detector.js +0 -100
  411. package/src/pose-extract/fit.js +0 -227
  412. package/src/pose-extract/image-frame.js +0 -51
  413. package/src/pose-extract/index.js +0 -58
  414. package/src/pose-extract/keyframes.js +0 -74
  415. package/src/pose-extract/landmarks.js +0 -162
  416. package/src/pose-extract/mirror.js +0 -153
  417. package/src/pose-extract/take.js +0 -131
  418. package/src/pose-extract/video-frames.js +0 -91
  419. package/src/take-recipe.js +0 -165
  420. package/src/trail-key-conflicts.js +0 -39
  421. package/src/trail-pick.js +0 -59
  422. package/src/use-i2v-capture-modal.js +0 -15
  423. package/tools/ardy/BRIDGE.md +0 -37
  424. package/tools/ardy/GVHMR-NPZ.md +0 -68
  425. package/tools/ardy/README.md +0 -124
  426. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  427. package/tools/ardy/artifacts.mjs +0 -34
  428. package/tools/ardy/bridge.mjs +0 -1732
  429. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  430. package/tools/ardy/cclay_constrained_generate.py +0 -561
  431. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  432. package/tools/ardy/cclay_motion_edit.py +0 -510
  433. package/tools/ardy/cclay_sequence_generate.py +0 -705
  434. package/tools/ardy/cclay_worker.py +0 -304
  435. package/tools/ardy/dump-npz.py +0 -205
  436. package/tools/ardy/extract-rest.mjs +0 -299
  437. package/tools/ardy/extract.mjs +0 -507
  438. package/tools/ardy/footage.mjs +0 -467
  439. package/tools/ardy/gvhmr-floor.mjs +0 -102
  440. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  441. package/tools/ardy/gvhmr_fastpath.py +0 -168
  442. package/tools/ardy/gvhmr_trajectory.py +0 -240
  443. package/tools/ardy/merge-text-encoder.py +0 -160
  444. package/tools/ardy/mocap-metrics.mjs +0 -200
  445. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  446. package/tools/ardy/motion-stabilize.mjs +0 -348
  447. package/tools/ardy/npz.mjs +0 -414
  448. package/tools/ardy/pose-to-npz.mjs +0 -106
  449. package/tools/ardy/prompt-limits.mjs +0 -5
  450. package/tools/ardy/run-edit-on-box.sh +0 -73
  451. package/tools/ardy/run-local.mjs +0 -233
  452. package/tools/ardy/run-on-box.sh +0 -593
  453. package/tools/ardy/run-sequence-on-box.sh +0 -177
  454. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  455. package/tools/ardy/runners/index.mjs +0 -18
  456. package/tools/ardy/runners/local.mjs +0 -455
  457. package/tools/ardy/runners/proc.mjs +0 -125
  458. package/tools/ardy/runners/remote.mjs +0 -252
  459. package/tools/ardy/setup-local.mjs +0 -189
  460. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  461. package/tools/ardy/setup-text-encoder.py +0 -306
  462. package/tools/ardy/smpl-cskel27.mjs +0 -178
  463. package/tools/ardy/visual-qa.mjs +0 -196
  464. package/tools/ardy/vq-car.mjs +0 -52
  465. package/tools/bench/EXP3.md +0 -61
  466. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  467. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  468. package/tools/bench/cclay_bench_runner.py +0 -42
  469. package/tools/bench/cube-contact.mjs +0 -162
  470. package/tools/bench/exp3.mjs +0 -152
  471. package/tools/bench/extract-bench-lib.mjs +0 -216
  472. package/tools/bench/extract-bench.mjs +0 -302
  473. package/tools/bench/fal-generate.mjs +0 -88
  474. package/tools/bench/fit/README.md +0 -189
  475. package/tools/bench/fit/camera.mjs +0 -59
  476. package/tools/bench/fit/contact.mjs +0 -419
  477. package/tools/bench/fit/footlock.mjs +0 -234
  478. package/tools/bench/fit/motion.mjs +0 -85
  479. package/tools/bench/fit/pin.mjs +0 -27
  480. package/tools/bench/fit/remote.mjs +0 -105
  481. package/tools/bench/fit-bench.mjs +0 -126
  482. package/tools/bench/fit-sanity.mjs +0 -45
  483. package/tools/bench/metrics.mjs +0 -313
  484. package/tools/bench/obs/depth.mjs +0 -258
  485. package/tools/bench/obs/extrinsics.mjs +0 -175
  486. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  487. package/tools/bench/obs/ground.mjs +0 -294
  488. package/tools/bench/obs/heading.mjs +0 -151
  489. package/tools/bench/obs/ladder.mjs +0 -555
  490. package/tools/bench/obs/mannequin-betas.json +0 -124
  491. package/tools/bench/obs/remote.mjs +0 -83
  492. package/tools/bench/obs/rest_joints.py +0 -52
  493. package/tools/bench/obs/ybot-targets.mjs +0 -49
  494. package/tools/bench/obs-bench.mjs +0 -520
  495. package/tools/bench/score.mjs +0 -343
  496. package/tools/bench/summarize.mjs +0 -86
  497. package/tools/demo-worker/README.md +0 -137
  498. package/tools/demo-worker/api-client.mjs +0 -233
  499. package/tools/demo-worker/generate.mjs +0 -301
  500. package/tools/demo-worker/index.mjs +0 -466
  501. package/tools/demo-worker/sign-core.mjs +0 -112
  502. package/tools/demo-worker/sign.mjs +0 -161
  503. package/tools/gt-render/browser.mjs +0 -159
  504. package/tools/gt-render/camera-math.mjs +0 -276
  505. package/tools/gt-render/page.mjs +0 -267
  506. package/tools/gt-render/render.mjs +0 -514
  507. package/tools/gt-render/scene-box.mjs +0 -31
  508. package/tools/gt-render/take-transform.mjs +0 -87
  509. package/tools/kimodo/compare-seam.mjs +0 -108
  510. package/tools/kimodo/constraints.mjs +0 -244
  511. package/tools/kimodo/edit.mjs +0 -259
  512. package/tools/kimodo/effector-constraints.mjs +0 -200
  513. package/tools/kimodo/generate.mjs +0 -646
  514. package/tools/kimodo/local-output.mjs +0 -265
  515. package/tools/kimodo/measure-pose.mjs +0 -65
  516. package/tools/kimodo/measure-preserve.mjs +0 -899
  517. package/tools/kimodo/measure-waypoints.mjs +0 -55
  518. package/tools/kimodo/mlx-generate.py +0 -111
  519. package/tools/kimodo/pose-constraints.mjs +0 -248
  520. package/tools/kimodo/preserve-mask.mjs +0 -543
  521. package/tools/kimodo/read-npz.mjs +0 -189
  522. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  523. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  524. package/tools/kimodo/runner.mjs +0 -284
  525. package/tools/kimodo/seam-batch.mjs +0 -77
  526. package/tools/kimodo/setup-local.mjs +0 -30
  527. package/tools/kimodo/setup-on-box.sh +0 -339
  528. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  529. package/tools/morphgs/assets/gen_truth.py +0 -39
  530. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  531. package/tools/morphgs/assets/playback-check.mjs +0 -30
  532. package/tools/morphgs/demo-gate.sh +0 -26
  533. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  534. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  535. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  536. package/tools/morphgs/setup-on-cluster.sh +0 -126
  537. package/tools/projflow/driver.py +0 -1069
  538. package/tools/projflow/generate.mjs +0 -805
  539. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  540. package/tools/projflow/line-edit-job.mjs +0 -547
  541. package/tools/projflow/replay.mjs +0 -452
  542. package/tools/projflow/runner.mjs +0 -269
  543. package/tools/projflow/service.mjs +0 -742
  544. package/tools/track/DESIGN.md +0 -513
  545. package/tools/track/backfill-provenance.mjs +0 -116
  546. package/tools/track/budget.mjs +0 -8
  547. package/tools/track/check-rig.mjs +0 -209
  548. package/tools/track/diagnostics.schema.json +0 -60
  549. package/tools/track/export-rig.mjs +0 -256
  550. package/tools/track/fallback.mjs +0 -7
  551. package/tools/track/fk-parity-fixture.mjs +0 -161
  552. package/tools/track/gate.mjs +0 -349
  553. package/tools/track/masks.mjs +0 -318
  554. package/tools/track/metrics.mjs +0 -201
  555. package/tools/track/publish-obs.mjs +0 -108
  556. package/tools/track/py/check_env.py +0 -61
  557. package/tools/track/py/eval_lr.py +0 -229
  558. package/tools/track/py/lr_viterbi.py +0 -294
  559. package/tools/track/py/masks.py +0 -405
  560. package/tools/track/py/objective.py +0 -382
  561. package/tools/track/py/rig.py +0 -508
  562. package/tools/track/py/scene.py +0 -326
  563. package/tools/track/py/test_joint_indices.py +0 -123
  564. package/tools/track/py/test_lr_viterbi.py +0 -195
  565. package/tools/track/py/test_masks.py +0 -229
  566. package/tools/track/py/test_rig.py +0 -288
  567. package/tools/track/py/test_scene.py +0 -354
  568. package/tools/track/py/test_track.py +0 -328
  569. package/tools/track/py/track.py +0 -411
  570. package/tools/track/remote.mjs +0 -140
  571. package/tools/track/rig-dump.mjs +0 -227
  572. package/tools/track/run-box-tests.mjs +0 -14
  573. package/tools/track/run-box.mjs +0 -168
  574. package/tools/track/setup-box.sh +0 -59
  575. package/tools/track/study-2d.mjs +0 -728
  576. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  577. /package/src/{ardy → motion}/ground.js +0 -0
  578. /package/src/{ardy → motion}/ik-drag.js +0 -0
  579. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  580. /package/src/{ardy → motion}/ik.js +0 -0
  581. /package/src/{ardy → motion}/physics-surface.js +0 -0
  582. /package/src/{ardy → motion}/playback-clock.js +0 -0
  583. /package/src/{ardy → motion}/range-pin.js +0 -0
@@ -1,313 +0,0 @@
1
- /**
2
- * Pure scoring math for the mocap bench (#431): rigid/similarity alignment,
3
- * pose and trajectory errors, mask IoU, box contact and timeline resampling.
4
- * No DOM, no Three, no I/O; unit-tested by test/verify-bench-metrics.mjs.
5
- *
6
- * Conventions: points are [x, y, z] in the Studio scene (metres, +Y up).
7
- * A yaw is a rotation about +Y with the same sign as src/ardy/motion-
8
- * calibration.js: x' = cos*x + sin*z, z' = -sin*x + cos*z.
9
- */
10
-
11
- export const DEG = Math.PI / 180;
12
-
13
- export function rotateYaw([x, y, z], yawRad) {
14
- const c = Math.cos(yawRad);
15
- const s = Math.sin(yawRad);
16
- return [c * x + s * z, y, -s * x + c * z];
17
- }
18
-
19
- const sub = (a, b) => [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
20
- const dist = (a, b) => Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]);
21
-
22
- function centroid(points) {
23
- const c = [0, 0, 0];
24
- for (const p of points) {
25
- c[0] += p[0];
26
- c[1] += p[1];
27
- c[2] += p[2];
28
- }
29
- return c.map((value) => value / points.length);
30
- }
31
-
32
- /**
33
- * Least-squares yaw (about +Y) and ground-plane translation mapping `src`
34
- * onto `dst` (paired points): dst ~ rotateYaw(src, yaw) + [tx, 0, tz].
35
- * Height is neither rotated nor translated: both takes stand on the same
36
- * floor, so a height error stays an error.
37
- */
38
- export function fitYawTranslation(src, dst) {
39
- if (src.length !== dst.length || !src.length) throw new Error("fitYawTranslation needs paired, non-empty point sets");
40
- const cs = centroid(src);
41
- const cd = centroid(dst);
42
- // Maximise sum b . R(a) over theta: C = sum(ax bx + az bz), S = sum(az bx - ax bz).
43
- let C = 0;
44
- let S = 0;
45
- for (let i = 0; i < src.length; i += 1) {
46
- const ax = src[i][0] - cs[0];
47
- const az = src[i][2] - cs[2];
48
- const bx = dst[i][0] - cd[0];
49
- const bz = dst[i][2] - cd[2];
50
- C += ax * bx + az * bz;
51
- S += az * bx - ax * bz;
52
- }
53
- const yawRad = C === 0 && S === 0 ? 0 : Math.atan2(S, C);
54
- const rc = rotateYaw(cs, yawRad);
55
- return { yawRad, yawDeg: yawRad / DEG, tx: cd[0] - rc[0], tz: cd[2] - rc[2] };
56
- }
57
-
58
- export function applyYawTranslation(point, { yawRad, tx, tz }) {
59
- const r = rotateYaw(point, yawRad);
60
- return [r[0] + tx, r[1], r[2] + tz];
61
- }
62
-
63
- /** Eigenvector of the largest eigenvalue of a symmetric 4x4 (cyclic Jacobi). */
64
- function dominantEigenvector4(input) {
65
- const a = input.map((row) => row.slice());
66
- const v = [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]];
67
- for (let sweep = 0; sweep < 64; sweep += 1) {
68
- let off = 0;
69
- for (let p = 0; p < 4; p += 1) for (let q = p + 1; q < 4; q += 1) off += a[p][q] * a[p][q];
70
- if (off < 1e-30) break;
71
- for (let p = 0; p < 4; p += 1) {
72
- for (let q = p + 1; q < 4; q += 1) {
73
- if (Math.abs(a[p][q]) < 1e-300) continue;
74
- const theta = (a[q][q] - a[p][p]) / (2 * a[p][q]);
75
- const t = Math.sign(theta || 1) / (Math.abs(theta) + Math.sqrt(theta * theta + 1));
76
- const c = 1 / Math.sqrt(t * t + 1);
77
- const s = t * c;
78
- for (let k = 0; k < 4; k += 1) {
79
- const akp = a[k][p];
80
- const akq = a[k][q];
81
- a[k][p] = c * akp - s * akq;
82
- a[k][q] = s * akp + c * akq;
83
- }
84
- for (let k = 0; k < 4; k += 1) {
85
- const apk = a[p][k];
86
- const aqk = a[q][k];
87
- a[p][k] = c * apk - s * aqk;
88
- a[q][k] = s * apk + c * aqk;
89
- }
90
- for (let k = 0; k < 4; k += 1) {
91
- const vkp = v[k][p];
92
- const vkq = v[k][q];
93
- v[k][p] = c * vkp - s * vkq;
94
- v[k][q] = s * vkp + c * vkq;
95
- }
96
- }
97
- }
98
- }
99
- let best = 0;
100
- for (let i = 1; i < 4; i += 1) if (a[i][i] > a[best][best]) best = i;
101
- return [v[0][best], v[1][best], v[2][best], v[3][best]];
102
- }
103
-
104
- /**
105
- * Similarity Procrustes (Horn's quaternion method, proper rotation only):
106
- * scale, R, t minimising sum |s R src_i + t - dst_i|^2.
107
- * Returns { scale, R (row-major 3x3), t, aligned }.
108
- */
109
- export function similarityAlign(src, dst, { allowScale = true } = {}) {
110
- if (src.length !== dst.length || !src.length) throw new Error("similarityAlign needs paired, non-empty point sets");
111
- const cs = centroid(src);
112
- const cd = centroid(dst);
113
- const S = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
114
- let srcNorm = 0;
115
- for (let i = 0; i < src.length; i += 1) {
116
- const a = sub(src[i], cs);
117
- const b = sub(dst[i], cd);
118
- srcNorm += a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
119
- for (let r = 0; r < 3; r += 1) for (let c = 0; c < 3; c += 1) S[r][c] += a[r] * b[c];
120
- }
121
- const [[xx, xy, xz], [yx, yy, yz], [zx, zy, zz]] = S;
122
- const N = [
123
- [xx + yy + zz, yz - zy, zx - xz, xy - yx],
124
- [yz - zy, xx - yy - zz, xy + yx, zx + xz],
125
- [zx - xz, xy + yx, -xx + yy - zz, yz + zy],
126
- [xy - yx, zx + xz, yz + zy, -xx - yy + zz],
127
- ];
128
- const [w, x, y, z] = dominantEigenvector4(N);
129
- const n = Math.hypot(w, x, y, z) || 1;
130
- const q = [w / n, x / n, y / n, z / n];
131
- const R = [
132
- 1 - 2 * (q[2] * q[2] + q[3] * q[3]), 2 * (q[1] * q[2] - q[0] * q[3]), 2 * (q[1] * q[3] + q[0] * q[2]),
133
- 2 * (q[1] * q[2] + q[0] * q[3]), 1 - 2 * (q[1] * q[1] + q[3] * q[3]), 2 * (q[2] * q[3] - q[0] * q[1]),
134
- 2 * (q[1] * q[3] - q[0] * q[2]), 2 * (q[2] * q[3] + q[0] * q[1]), 1 - 2 * (q[1] * q[1] + q[2] * q[2]),
135
- ];
136
- const rot = (p) => [R[0] * p[0] + R[1] * p[1] + R[2] * p[2], R[3] * p[0] + R[4] * p[1] + R[5] * p[2], R[6] * p[0] + R[7] * p[1] + R[8] * p[2]];
137
- let dot = 0;
138
- for (let i = 0; i < src.length; i += 1) {
139
- const ra = rot(sub(src[i], cs));
140
- const b = sub(dst[i], cd);
141
- dot += ra[0] * b[0] + ra[1] * b[1] + ra[2] * b[2];
142
- }
143
- const scale = allowScale && srcNorm > 0 ? dot / srcNorm : 1;
144
- const rcs = rot(cs);
145
- const t = [cd[0] - scale * rcs[0], cd[1] - scale * rcs[1], cd[2] - scale * rcs[2]];
146
- const aligned = src.map((p) => {
147
- const r = rot(p);
148
- return [scale * r[0] + t[0], scale * r[1] + t[1], scale * r[2] + t[2]];
149
- });
150
- return { scale, R, t, aligned };
151
- }
152
-
153
- /** Mean per-joint Euclidean error of two paired joint sets. */
154
- export function meanJointError(pred, gt) {
155
- if (pred.length !== gt.length || !pred.length) throw new Error("meanJointError needs paired, non-empty joint sets");
156
- let total = 0;
157
- for (let i = 0; i < pred.length; i += 1) total += dist(pred[i], gt[i]);
158
- return total / pred.length;
159
- }
160
-
161
- /** MPJPE after subtracting each set's own root joint. */
162
- export function rootRelativeError(pred, gt, rootIndex = 0) {
163
- const pr = pred[rootIndex];
164
- const gr = gt[rootIndex];
165
- return meanJointError(pred.map((p) => sub(p, pr)), gt.map((g) => sub(g, gr)));
166
- }
167
-
168
- /** MPJPE after per-frame similarity Procrustes of pred onto gt. */
169
- export function procrustesError(pred, gt) {
170
- return meanJointError(similarityAlign(pred, gt).aligned, gt);
171
- }
172
-
173
- /** Per-frame position errors of two paired trajectories, summarised. */
174
- export function trajectoryError(pred, gt) {
175
- if (pred.length !== gt.length || !pred.length) throw new Error("trajectoryError needs paired, non-empty trajectories");
176
- const errors = pred.map((p, i) => dist(p, gt[i]));
177
- const mean = errors.reduce((a, b) => a + b, 0) / errors.length;
178
- const rmse = Math.sqrt(errors.reduce((a, b) => a + b * b, 0) / errors.length);
179
- return { errors, mean, rmse, max: Math.max(...errors), final: errors[errors.length - 1] };
180
- }
181
-
182
- /** Summed ground-plane (XZ) step length of a trajectory. */
183
- export function pathLengthXZ(points) {
184
- let total = 0;
185
- for (let i = 1; i < points.length; i += 1) total += Math.hypot(points[i][0] - points[i - 1][0], points[i][2] - points[i - 1][2]);
186
- return total;
187
- }
188
-
189
- /** Ground-plane (XZ) distance from the first to the last point. */
190
- export function displacementXZ(points) {
191
- const a = points[0];
192
- const b = points[points.length - 1];
193
- return Math.hypot(b[0] - a[0], b[2] - a[2]);
194
- }
195
-
196
- /** pred / gt, or null when gt is 0 (a ratio of nothing is not a number). */
197
- export function ratio(pred, gt) {
198
- return gt > 0 ? pred / gt : null;
199
- }
200
-
201
- /**
202
- * Intersection over union of two 8-bit masks (pixel set where value >=
203
- * threshold). Two empty masks agree perfectly: IoU 1.
204
- */
205
- export function maskIoU(a, b, threshold = 128) {
206
- if (a.length !== b.length) throw new Error(`maskIoU: mask sizes differ (${a.length} vs ${b.length})`);
207
- let intersection = 0;
208
- let union = 0;
209
- for (let i = 0; i < a.length; i += 1) {
210
- const x = a[i] >= threshold;
211
- const y = b[i] >= threshold;
212
- if (x && y) intersection += 1;
213
- if (x || y) union += 1;
214
- }
215
- return { iou: union ? intersection / union : 1, intersection, union };
216
- }
217
-
218
- /**
219
- * Signed distance of every point of a flat [x0, y0, z0, ...] array to an
220
- * axis-aligned box { min: [x, y, z], max: [x, y, z] }: positive outside
221
- * (Euclidean distance to the box), negative inside (minus the distance to
222
- * the nearest face). Reduced to the minimum and the count inside.
223
- *
224
- * Self-contained on purpose (no outer references): render.mjs injects its
225
- * source into the Studio page with Function.prototype.toString.
226
- */
227
- export function boxContactValues(points, box) {
228
- const [x0, y0, z0] = box.min;
229
- const [x1, y1, z1] = box.max;
230
- let minSigned = Infinity;
231
- let closest = -1;
232
- let inside = 0;
233
- const count = Math.floor(points.length / 3);
234
- for (let i = 0; i < count; i += 1) {
235
- const x = points[i * 3];
236
- const y = points[i * 3 + 1];
237
- const z = points[i * 3 + 2];
238
- const dx = Math.max(x0 - x, x - x1);
239
- const dy = Math.max(y0 - y, y - y1);
240
- const dz = Math.max(z0 - z, z - z1);
241
- let signed;
242
- if (dx <= 0 && dy <= 0 && dz <= 0) {
243
- signed = Math.max(dx, dy, dz);
244
- inside += 1;
245
- } else {
246
- signed = Math.hypot(Math.max(dx, 0), Math.max(dy, 0), Math.max(dz, 0));
247
- }
248
- if (signed < minSigned) {
249
- minSigned = signed;
250
- closest = i;
251
- }
252
- }
253
- return { minSignedDistance: minSigned, closestIndex: closest, insideCount: inside, count };
254
- }
255
-
256
- /** Contact summary of one frame: closest approach (0 when touching or
257
- * inside) and deepest penetration (0 when nothing is inside). */
258
- export function contactFromSigned(minSignedDistance) {
259
- return { minDistanceM: Math.max(0, minSignedDistance), maxPenetrationM: Math.max(0, -minSignedDistance) };
260
- }
261
-
262
- /** Validate a box given as { min: [x,y,z], max: [x,y,z] }. */
263
- export function parseBox(value) {
264
- const box = typeof value === "string" ? JSON.parse(value) : value;
265
- const ok = (v) => Array.isArray(v) && v.length === 3 && v.every(Number.isFinite);
266
- if (!box || !ok(box.min) || !ok(box.max)) throw new Error("box must be {\"min\":[x,y,z],\"max\":[x,y,z]} in scene metres");
267
- if (box.min.some((v, i) => v > box.max[i])) throw new Error("box min must not exceed max on any axis");
268
- return { min: box.min.slice(), max: box.max.slice() };
269
- }
270
-
271
- /**
272
- * Map every GT timeline frame to the nearest-in-time pred frame. A GT frame
273
- * whose time lies past the pred's last frame (by more than half a pred frame)
274
- * is not scored. Returns { predIndex: (number|null)[], scored, dropped }.
275
- */
276
- export function resampleToTimeline({ gtFrames, gtFps, predFrames, predFps }) {
277
- if (!(gtFps > 0) || !(predFps > 0)) throw new Error("resampleToTimeline needs positive frame rates");
278
- const predIndex = [];
279
- let scored = 0;
280
- for (let i = 0; i < gtFrames; i += 1) {
281
- const k = Math.round((i / gtFps) * predFps);
282
- if (k <= predFrames - 1) {
283
- predIndex.push(k);
284
- scored += 1;
285
- } else {
286
- predIndex.push(null);
287
- }
288
- }
289
- return { predIndex, scored, dropped: gtFrames - scored, exact: gtFps === predFps && gtFrames === predFrames };
290
- }
291
-
292
- /**
293
- * The scene calibration (Studio sceneCalibration semantics: yaw about the
294
- * take's anchor A, then offset) that equals applying G(p) = rotateYaw(p, g.yaw)
295
- * + [g.tx, 0, g.tz] after an existing calibration { yawDeg, offsetX, offsetZ }:
296
- * G(A + o + Ry(psi)(U - A)) = A + o' + Ry(psi + theta)(U - A),
297
- * o' = Ry(theta)(A + o) + t - A.
298
- */
299
- export function composeCalibration(calibration, anchor, g) {
300
- const base = [anchor.x + (calibration.offsetX ?? 0), 0, anchor.z + (calibration.offsetZ ?? 0)];
301
- const moved = applyYawTranslation(base, g);
302
- return {
303
- ...calibration,
304
- yawDeg: (calibration.yawDeg ?? 0) + g.yawDeg,
305
- offsetX: moved[0] - anchor.x,
306
- offsetZ: moved[2] - anchor.z,
307
- };
308
- }
309
-
310
- export function mean(values) {
311
- const finite = values.filter((v) => v !== null && Number.isFinite(v));
312
- return finite.length ? finite.reduce((a, b) => a + b, 0) / finite.length : null;
313
- }
@@ -1,258 +0,0 @@
1
- const COCO_TO_SMPL = [
2
- [5, 16], [6, 17], [7, 18], [8, 19], [9, 20], [10, 21],
3
- [11, 1], [12, 2], [13, 4], [14, 5], [15, 7], [16, 8],
4
- ];
5
-
6
- const DEFAULT_MIN_CONF = 0.3;
7
- const DEFAULT_SIGMA = 2;
8
- const EPSILON = 1e-10;
9
-
10
- function valuesOf(value) {
11
- return value?.data ?? value;
12
- }
13
-
14
- function shapeOf(value) {
15
- return value?.shape ? Array.from(value.shape) : null;
16
- }
17
-
18
- function flatValues(value, name) {
19
- const data = valuesOf(value);
20
- if (ArrayBuffer.isView(data) || Array.isArray(data)) return data;
21
- throw new TypeError(`${name}: expected an array or a shaped array`);
22
- }
23
-
24
- function frameRows(value, frames, width, components, name) {
25
- const shape = shapeOf(value);
26
- const data = flatValues(value, name);
27
- if (shape) {
28
- const expected = [frames, width, components];
29
- if (shape.length !== 3 || shape.some((n, i) => n !== expected[i])) {
30
- throw new Error(`${name}: expected shape [${expected.join(", ")}]`);
31
- }
32
- }
33
- if (Array.isArray(data) && data.length === frames && data.every(row => Array.isArray(row))) {
34
- return data.map((row, frame) => {
35
- if (row.length !== width || row.some(point => !Array.isArray(point) && !ArrayBuffer.isView(point))) {
36
- throw new Error(`${name}[${frame}]: expected [${width}, ${components}]`);
37
- }
38
- return row.map((point, index) => {
39
- if (point.length !== components) throw new Error(`${name}[${frame}][${index}]: expected ${components} values`);
40
- return Array.from(point, Number);
41
- });
42
- });
43
- }
44
- if (data.length !== frames * width * components) {
45
- throw new Error(`${name}: expected ${frames * width * components} values`);
46
- }
47
- return Array.from({ length: frames }, (_, frame) => Array.from({ length: width }, (_, index) => {
48
- const offset = (frame * width + index) * components;
49
- return Array.from(data.slice(offset, offset + components), Number);
50
- }));
51
- }
52
-
53
- function vectorFrames(value, frames, width, name) {
54
- const shape = shapeOf(value);
55
- const data = flatValues(value, name);
56
- if (shape) {
57
- const expected = [frames, width];
58
- if (shape.length !== 2 || shape.some((n, i) => n !== expected[i])) {
59
- throw new Error(`${name}: expected shape [${expected.join(", ")}]`);
60
- }
61
- }
62
- if (Array.isArray(data) && data.length === frames && data.every(row => Array.isArray(row) || ArrayBuffer.isView(row))) {
63
- return data.map((row, frame) => {
64
- if (row.length !== width) throw new Error(`${name}[${frame}]: expected ${width} values`);
65
- return Array.from(row, Number);
66
- });
67
- }
68
- if (data.length !== frames * width) throw new Error(`${name}: expected ${frames * width} values`);
69
- return Array.from({ length: frames }, (_, frame) => Array.from(data.slice(frame * width, (frame + 1) * width), Number));
70
- }
71
-
72
- function matrix3(K) {
73
- const data = valuesOf(K);
74
- const shape = shapeOf(K);
75
- if (shape && (shape.length !== 2 || shape[0] !== 3 || shape[1] !== 3)) throw new Error("K: expected shape [3, 3]");
76
- const matrix = Array.isArray(data) && data.length === 3 && data.every(row => Array.isArray(row) || ArrayBuffer.isView(row))
77
- ? data.map(row => Array.from(row, Number))
78
- : data?.length === 9 ? Array.from({ length: 3 }, (_, row) => Array.from(data.slice(row * 3, row * 3 + 3), Number)) : null;
79
- if (!matrix || matrix.some(row => row.length !== 3 || row.some(value => !Number.isFinite(value)))) throw new Error("K: expected a finite 3x3 matrix");
80
- if (!(Math.abs(matrix[0][0]) > EPSILON) || !(Math.abs(matrix[1][1]) > EPSILON)) throw new Error("K: fx and fy must be nonzero");
81
- return matrix;
82
- }
83
-
84
- function finiteVector(value, fallback = [0, 0, 0]) {
85
- return (Array.isArray(value) || ArrayBuffer.isView(value)) && value.length === 3 && Array.from(value).every(Number.isFinite)
86
- ? Array.from(value, Number) : fallback.slice();
87
- }
88
-
89
- function addNormal(normal, rhs, row, target, weight) {
90
- for (let i = 0; i < 3; i++) {
91
- for (let j = 0; j < 3; j++) normal[i][j] += weight * row[i] * row[j];
92
- rhs[i] += weight * row[i] * target;
93
- }
94
- }
95
-
96
- function solve3(normal, rhs) {
97
- const a = normal.map((row, i) => [...row, rhs[i]]);
98
- for (let column = 0; column < 3; column++) {
99
- let pivot = column;
100
- for (let row = column + 1; row < 3; row++) {
101
- if (Math.abs(a[row][column]) > Math.abs(a[pivot][column])) pivot = row;
102
- }
103
- if (Math.abs(a[pivot][column]) <= EPSILON) return null;
104
- [a[column], a[pivot]] = [a[pivot], a[column]];
105
- for (let row = column + 1; row < 3; row++) {
106
- const scale = a[row][column] / a[column][column];
107
- for (let col = column; col < 4; col++) a[row][col] -= scale * a[column][col];
108
- }
109
- }
110
- const answer = [0, 0, 0];
111
- for (let row = 2; row >= 0; row--) {
112
- let value = a[row][3];
113
- for (let col = row + 1; col < 3; col++) value -= a[row][col] * answer[col];
114
- answer[row] = value / a[row][row];
115
- }
116
- return answer.every(Number.isFinite) ? answer : null;
117
- }
118
-
119
- function observations(joints, keypoints, K, minConf) {
120
- const fx = K[0][0], fy = K[1][1], cx = K[0][2], cy = K[1][2];
121
- return COCO_TO_SMPL.flatMap(([coco, smpl]) => {
122
- const point = keypoints[coco], joint = joints[smpl];
123
- if (!point || !joint || point.length < 3 || joint.length < 3) return [];
124
- const confidence = Number(point[2]);
125
- if (!(confidence >= minConf) || !joint.every(Number.isFinite) || !point.slice(0, 2).every(Number.isFinite)) return [];
126
- return [{ X: joint[0], Y: joint[1], Z: joint[2], u: point[0], v: point[1], confidence }];
127
- });
128
- }
129
-
130
- function linearTranslation(items, K) {
131
- const fx = K[0][0], fy = K[1][1], cx = K[0][2], cy = K[1][2];
132
- const normal = Array.from({ length: 3 }, () => [0, 0, 0]);
133
- const rhs = [0, 0, 0];
134
- for (const item of items) {
135
- const weight = item.confidence;
136
- // fx*(X+tx) + (cx-u)*(Z+tz) = 0, and the equivalent y equation.
137
- addNormal(normal, rhs, [fx, 0, cx - item.u], item.u * item.Z - fx * item.X, weight);
138
- addNormal(normal, rhs, [0, fy, cy - item.v], item.v * item.Z - fy * item.Y, weight);
139
- }
140
- return solve3(normal, rhs);
141
- }
142
-
143
- function refineTranslation(start, items, K, iterations = 5) {
144
- const fx = K[0][0], fy = K[1][1];
145
- const translation = start.slice();
146
- for (let iteration = 0; iteration < iterations; iteration++) {
147
- const normal = Array.from({ length: 3 }, () => [0, 0, 0]);
148
- const rhs = [0, 0, 0];
149
- let rows = 0;
150
- for (const item of items) {
151
- const x = item.X + translation[0], y = item.Y + translation[1], z = item.Z + translation[2];
152
- if (!(z > EPSILON)) continue;
153
- const u = fx * x / z + K[0][2], v = fy * y / z + K[1][2];
154
- const du = u - item.u, dv = v - item.v;
155
- const ju = [fx / z, 0, -fx * x / (z * z)];
156
- const jv = [0, fy / z, -fy * y / (z * z)];
157
- addNormal(normal, rhs, ju, -du, item.confidence);
158
- addNormal(normal, rhs, jv, -dv, item.confidence);
159
- rows += 2;
160
- }
161
- if (rows < 3) break;
162
- const delta = solve3(normal, rhs);
163
- if (!delta) break;
164
- translation[0] += delta[0];
165
- translation[1] += delta[1];
166
- translation[2] += delta[2];
167
- if (Math.hypot(...delta) < 1e-8) break;
168
- }
169
- return translation;
170
- }
171
-
172
- function residual(translation, items, K) {
173
- let error = 0;
174
- let weight = 0;
175
- for (const item of items) {
176
- const z = item.Z + translation[2];
177
- if (!(z > EPSILON)) continue;
178
- const u = K[0][0] * (item.X + translation[0]) / z + K[0][2];
179
- const v = K[1][1] * (item.Y + translation[1]) / z + K[1][2];
180
- error += item.confidence * ((u - item.u) ** 2 + (v - item.v) ** 2);
181
- weight += item.confidence;
182
- }
183
- return weight > 0 ? Math.sqrt(error / weight) : Infinity;
184
- }
185
-
186
- function gaussianSmooth(translations, sigma) {
187
- if (!(sigma > 0) || translations.length < 2) return translations.map(translation => translation.slice());
188
- const radius = Math.ceil(3 * sigma);
189
- return translations.map((_, frame) => {
190
- const out = [0, 0, 0];
191
- let total = 0;
192
- for (let other = Math.max(0, frame - radius); other <= Math.min(translations.length - 1, frame + radius); other++) {
193
- const distance = other - frame;
194
- const weight = Math.exp(-(distance * distance) / (2 * sigma * sigma));
195
- total += weight;
196
- for (let axis = 0; axis < 3; axis++) out[axis] += weight * translations[other][axis];
197
- }
198
- return out.map(value => value / total);
199
- });
200
- }
201
-
202
- function guardJumps(translations, maxJump) {
203
- if (!(maxJump > 0) || !Number.isFinite(maxJump)) return translations;
204
- const guarded = [];
205
- for (const translation of translations) {
206
- if (!guarded.length) {
207
- guarded.push(translation.slice());
208
- continue;
209
- }
210
- const previous = guarded.at(-1);
211
- const delta = translation.map((value, axis) => value - previous[axis]);
212
- const distance = Math.hypot(...delta);
213
- if (distance <= maxJump) guarded.push(translation.slice());
214
- else {
215
- const scale = maxJump / distance;
216
- guarded.push(previous.map((value, axis) => value + delta[axis] * scale));
217
- }
218
- }
219
- return guarded;
220
- }
221
-
222
- /**
223
- * Recover per-frame camera translation from known-size, root-relative SMPL-X
224
- * joints and COCO-17 observations. `incamTransl` is accepted as the fallback
225
- * translation because the root-relative joints alone do not contain one.
226
- */
227
- export function solveTranslations({ jointsRel, kp2d, K, minConf = DEFAULT_MIN_CONF, sigma = DEFAULT_SIGMA, incamTransl, maxJump = Infinity } = {}) {
228
- const keypointData = flatValues(kp2d, "kp2d");
229
- const keypointShape = shapeOf(kp2d);
230
- const frames = keypointShape?.[0] ?? (Array.isArray(keypointData) && keypointData.every(row => Array.isArray(row) || ArrayBuffer.isView(row)) ? keypointData.length : Math.floor(keypointData.length / (17 * 3)));
231
- if (!Number.isInteger(frames) || frames < 1) throw new Error("kp2d: expected at least one frame");
232
- const joints = frameRows(jointsRel, frames, 22, 3, "jointsRel");
233
- const keypoints = frameRows(kp2d, frames, 17, 3, "kp2d");
234
- const intrinsics = matrix3(K);
235
- if (!(Number.isFinite(minConf) && minConf >= 0)) throw new Error("minConf: expected a nonnegative number");
236
- if (!(Number.isFinite(sigma) && sigma >= 0)) throw new Error("sigma: expected a nonnegative number");
237
- const fallback = incamTransl === undefined
238
- ? Array.from({ length: frames }, () => [0, 0, 0])
239
- : vectorFrames(incamTransl, frames, 3, "incamTransl");
240
- const rawTranslations = [];
241
- const flags = [];
242
- const frameItems = [];
243
- for (let frame = 0; frame < frames; frame++) {
244
- const items = observations(joints[frame], keypoints[frame], intrinsics, minConf);
245
- let translation = items.length >= 4 ? linearTranslation(items, intrinsics) : null;
246
- const usedFallback = items.length < 4 || !translation;
247
- if (usedFallback) translation = finiteVector(fallback[frame]);
248
- else translation = refineTranslation(translation, items, intrinsics);
249
- rawTranslations.push(translation);
250
- flags.push(usedFallback);
251
- frameItems.push(items);
252
- }
253
- const translations = guardJumps(gaussianSmooth(rawTranslations, sigma), maxJump);
254
- const residualPx = translations.map((translation, frame) => residual(translation, frameItems[frame], intrinsics));
255
- return { transl: translations, flags, residualPx };
256
- }
257
-
258
- export { COCO_TO_SMPL };