cozyclay 2.1.1 → 3.0.1

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 (585) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +43 -116
  4. package/bin/agent/agent-runner.mjs +14 -15
  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/session-store.mjs +2 -2
  14. package/bin/agent/studio-context-budget.mjs +93 -0
  15. package/bin/agent/studio-motion-reference.mjs +23 -0
  16. package/bin/agent/studio-prompt.mjs +1 -1
  17. package/bin/agent/studio-rebase-text.mjs +32 -0
  18. package/bin/agent/studio-rebase.mjs +26 -39
  19. package/bin/agent/studio-tools.mjs +9 -28
  20. package/bin/agent/tool-arguments.mjs +49 -0
  21. package/bin/agent/turn-frames.mjs +66 -0
  22. package/bin/codex-auth.mjs +9 -2
  23. package/bin/cozyclay.mjs +10 -116
  24. package/bin/live/cli.mjs +3 -3
  25. package/bin/mcp-runtime.mjs +2 -12
  26. package/bin/package-signature.mjs +0 -4
  27. package/dist/app/index.html +7 -6
  28. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  29. package/dist/assets/analytics-BWCqdgWA.js +1 -0
  30. package/dist/assets/app-DfTCxaKk.js +5087 -0
  31. package/dist/assets/app-f-fkV5uP.css +1 -0
  32. package/dist/assets/compile-worker-BxKXh07s.js +5 -0
  33. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  34. package/dist/assets/{first-shot-handoff-msLI71g1.js → first-shot-handoff-DNO8kv_N.js} +1 -1
  35. package/dist/assets/{landing-ChUvB_zL.js → landing-yfZaJkWc.js} +1 -1
  36. package/dist/assets/scene-asset-sync-U3kS2rvK.js +20 -0
  37. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  38. package/dist/assets/workflow-D78eiKTa.js +179 -0
  39. package/dist/cozyclay-package.json +1 -1
  40. package/dist/index.html +3 -3
  41. package/dist/sw.js +3 -6
  42. package/dist/workflow/index.html +5 -4
  43. package/mcp/LIVE-PROTOCOL.md +7 -47
  44. package/mcp/README.md +16 -26
  45. package/mcp/live-hub.mjs +6 -10
  46. package/mcp/package.json +1 -3
  47. package/mcp/tool-handlers.mjs +4 -168
  48. package/package.json +3 -22
  49. package/src/App.jsx +151 -2625
  50. package/src/agent-progress.js +80 -0
  51. package/src/agent-turn-mark.js +30 -0
  52. package/src/analytics.js +1 -19
  53. package/src/app-context.js +12 -2
  54. package/src/app-stage.jsx +2 -34
  55. package/src/asset-pane.jsx +6 -5
  56. package/src/camera-block.js +21 -0
  57. package/src/camera-direction.js +120 -0
  58. package/src/character-kind.js +3 -9
  59. package/src/command-bus.js +10 -8
  60. package/src/commands/cast.js +5 -34
  61. package/src/commands/elements/character.js +1 -1
  62. package/src/commands/elements/motion.js +1 -6
  63. package/src/commands/elements/object.js +6 -2
  64. package/src/commands/elements/shot.js +4 -1
  65. package/src/commands/elements.js +38 -14
  66. package/src/commands/index.js +3 -1
  67. package/src/commands/kits.js +37 -0
  68. package/src/commands/motion-timing.js +57 -0
  69. package/src/commands/motion.js +9 -152
  70. package/src/commands/motion3-compile.js +65 -0
  71. package/src/commands/motion3.js +214 -0
  72. package/src/commands/objects.js +6 -4
  73. package/src/commands/shot.js +55 -13
  74. package/src/commands/stage.js +14 -1
  75. package/src/commands/view.js +4 -1
  76. package/src/document-mirrors.js +42 -0
  77. package/src/document-store.js +4 -0
  78. package/src/domains/cast.js +19 -194
  79. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  80. package/src/domains/motion/take-source.js +53 -0
  81. package/src/domains/motion.js +60 -1838
  82. package/src/domains/scenes.js +12 -55
  83. package/src/domains/shots.js +2 -2
  84. package/src/domains/stage.js +4 -2
  85. package/src/draft-ghost.js +47 -0
  86. package/src/draft-ghost.jsx +129 -0
  87. package/src/dualview.jsx +4 -3
  88. package/src/effects/EffectsLayer.jsx +112 -0
  89. package/src/effects/effect-meshes.js +232 -0
  90. package/src/effects/effect-record.js +103 -0
  91. package/src/effects/emitter.js +59 -0
  92. package/src/effects/simulate.js +261 -0
  93. package/src/effects/state.js +59 -0
  94. package/src/execution-telemetry.js +2 -3
  95. package/src/first-success-guide.jsx +5 -5
  96. package/src/ghost-set.js +257 -0
  97. package/src/held-object-edit.jsx +113 -0
  98. package/src/held-object-pose.js +175 -0
  99. package/src/hierarchy-model.js +1 -1
  100. package/src/hierarchy-panel.jsx +1 -1
  101. package/src/imported-mesh.jsx +103 -0
  102. package/src/kits/held.js +84 -0
  103. package/src/kits/index.js +70 -0
  104. package/src/kits/smoking.js +57 -0
  105. package/src/light-blockers.js +93 -0
  106. package/src/motion/beat-board-model.js +84 -0
  107. package/src/motion/beat-board.css +124 -0
  108. package/src/motion/beat-board.jsx +60 -0
  109. package/src/motion/center-of-mass.js +66 -0
  110. package/src/motion/fix-collisions.js +850 -0
  111. package/src/motion/physics-review.js +118 -0
  112. package/src/{ardy → motion}/physics-support.js +1 -76
  113. package/src/motion/rig-snapshot.js +22 -0
  114. package/src/motion/take-segments.jsx +140 -0
  115. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  116. package/src/{ardy → motion}/timeline.css +1 -2
  117. package/src/{ardy → motion}/timeline.jsx +42 -413
  118. package/src/motion/waypoints.js +76 -0
  119. package/src/motion3/beats.js +83 -0
  120. package/src/motion3/body.js +158 -0
  121. package/src/motion3/bones.js +47 -0
  122. package/src/motion3/carried.js +47 -0
  123. package/src/motion3/compile-job.js +79 -0
  124. package/src/motion3/compile-worker.js +10 -0
  125. package/src/motion3/compiler/anchors.js +113 -0
  126. package/src/motion3/compiler/arm-orient.js +128 -0
  127. package/src/motion3/compiler/channels.js +125 -0
  128. package/src/motion3/compiler/compile.js +205 -0
  129. package/src/motion3/compiler/gait-rhythm.js +97 -0
  130. package/src/motion3/compiler/grip.js +171 -0
  131. package/src/motion3/compiler/head-steady.js +48 -0
  132. package/src/motion3/compiler/hold.js +134 -0
  133. package/src/motion3/compiler/idle.js +113 -0
  134. package/src/motion3/compiler/limbs.js +197 -0
  135. package/src/motion3/compiler/math.js +72 -0
  136. package/src/motion3/compiler/pose.js +177 -0
  137. package/src/motion3/compiler/quat.js +49 -0
  138. package/src/motion3/compiler/skeleton.js +74 -0
  139. package/src/motion3/compiler/validate-common.js +32 -0
  140. package/src/motion3/compiler/validate-goals.js +118 -0
  141. package/src/motion3/compiler/validate-objects.js +144 -0
  142. package/src/motion3/compiler/validate-parts.js +118 -0
  143. package/src/motion3/compiler/validate.js +122 -0
  144. package/src/motion3/compiler/vocab.js +74 -0
  145. package/src/motion3/compiler/walk-pelvis.js +275 -0
  146. package/src/motion3/compiler/walk.js +207 -0
  147. package/src/motion3/compiler/wrist-clamp.js +32 -0
  148. package/src/motion3/delta.js +47 -0
  149. package/src/motion3/describe.js +177 -0
  150. package/src/motion3/docs.js +27 -0
  151. package/src/motion3/edit-carry.js +21 -0
  152. package/src/motion3/fix/ease.js +16 -0
  153. package/src/motion3/fix/ground.js +37 -0
  154. package/src/motion3/fix/index.js +52 -0
  155. package/src/motion3/fix/push.js +71 -0
  156. package/src/motion3/fix/reach.js +46 -0
  157. package/src/motion3/fix/retime.js +79 -0
  158. package/src/motion3/fix/self.js +211 -0
  159. package/src/motion3/fix/slide.js +70 -0
  160. package/src/motion3/fix/turn.js +51 -0
  161. package/src/motion3/follow.js +39 -0
  162. package/src/motion3/free-motion.js +204 -0
  163. package/src/motion3/grip-choice.js +130 -0
  164. package/src/motion3/hold-plan.js +157 -0
  165. package/src/motion3/json-patch.js +77 -0
  166. package/src/motion3/key-aim.js +105 -0
  167. package/src/motion3/key-edit.js +82 -0
  168. package/src/motion3/lenient.js +127 -0
  169. package/src/motion3/object-keys.js +236 -0
  170. package/src/motion3/object-pose.js +182 -0
  171. package/src/motion3/object-tracks.js +12 -0
  172. package/src/motion3/people.js +82 -0
  173. package/src/motion3/pipeline.js +102 -0
  174. package/src/motion3/playback.js +51 -0
  175. package/src/motion3/probes.js +91 -0
  176. package/src/motion3/qa/body-checks.js +34 -0
  177. package/src/motion3/qa/check-names.js +14 -0
  178. package/src/motion3/qa/checks.js +125 -0
  179. package/src/motion3/qa/contact-checks.js +51 -0
  180. package/src/motion3/qa/explain.js +80 -0
  181. package/src/motion3/qa/fmt.js +5 -0
  182. package/src/motion3/qa/foot-checks.js +72 -0
  183. package/src/motion3/qa/geometry.js +77 -0
  184. package/src/motion3/qa/goals.js +191 -0
  185. package/src/motion3/qa/ground.js +60 -0
  186. package/src/motion3/qa/hints-contact.js +195 -0
  187. package/src/motion3/qa/hints-goal.js +160 -0
  188. package/src/motion3/qa/hints-knee.js +24 -0
  189. package/src/motion3/qa/hints-motion.js +209 -0
  190. package/src/motion3/qa/hints-object.js +91 -0
  191. package/src/motion3/qa/index.js +44 -0
  192. package/src/motion3/qa/key-checks.js +82 -0
  193. package/src/motion3/qa/near.js +96 -0
  194. package/src/motion3/qa/object-checks.js +135 -0
  195. package/src/motion3/qa/patch.js +161 -0
  196. package/src/motion3/qa/people-checks.js +37 -0
  197. package/src/motion3/qa/severity.js +38 -0
  198. package/src/motion3/qa/spec-checks.js +65 -0
  199. package/src/motion3/qa/style.js +228 -0
  200. package/src/motion3/qa/wrist-checks.js +69 -0
  201. package/src/motion3/qa/wrist-obs.js +60 -0
  202. package/src/motion3/refs.js +129 -0
  203. package/src/motion3/repair-tune.js +121 -0
  204. package/src/motion3/repair.js +83 -0
  205. package/src/motion3/report.js +67 -0
  206. package/src/motion3/rigs/index.js +14 -0
  207. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  208. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  209. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  210. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  211. package/src/motion3/scene.js +60 -0
  212. package/src/motion3/schema/brief.js +89 -0
  213. package/src/motion3/schema/fields.js +44 -0
  214. package/src/motion3/schema/spec-examples.js +46 -0
  215. package/src/motion3/schema/topics.js +113 -0
  216. package/src/motion3/schema/types.js +149 -0
  217. package/src/motion3/search.js +117 -0
  218. package/src/motion3/second-hand.js +112 -0
  219. package/src/motion3/settle.js +136 -0
  220. package/src/motion3/skills/basic.js +83 -0
  221. package/src/motion3/skills/book.js +76 -0
  222. package/src/motion3/skills/car.js +145 -0
  223. package/src/motion3/skills/flip.js +200 -0
  224. package/src/motion3/skills/frames-auto.js +29 -0
  225. package/src/motion3/skills/impact.js +109 -0
  226. package/src/motion3/skills/index.js +85 -0
  227. package/src/motion3/skills/info.js +80 -0
  228. package/src/motion3/skills/smoke-kit.js +109 -0
  229. package/src/motion3/skills/smoke.js +160 -0
  230. package/src/motion3/spec-store.js +59 -0
  231. package/src/motion3/take-edit.js +155 -0
  232. package/src/motion3/take.js +63 -0
  233. package/src/motion3/timeline.js +127 -0
  234. package/src/motion3/views.js +121 -0
  235. package/src/motion3/walk-plan.js +119 -0
  236. package/src/object-catalog.jsx +7 -1
  237. package/src/object-colors.js +98 -0
  238. package/src/object-gizmo-parts.js +115 -0
  239. package/src/object-gizmo.jsx +37 -122
  240. package/src/object-glow.js +139 -0
  241. package/src/object-hidden.js +33 -0
  242. package/src/object-look.js +196 -0
  243. package/src/object-size.js +10 -0
  244. package/src/object-travel.js +71 -6
  245. package/src/panels/CameraPanel.jsx +7 -7
  246. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  247. package/src/panels/LightPanel.jsx +25 -4
  248. package/src/panels/ObjectLookPanel.jsx +88 -0
  249. package/src/panels/PosePanel.jsx +2 -17
  250. package/src/panels/RigControlPanel.jsx +5 -53
  251. package/src/panels/SubjectBox.jsx +4 -1
  252. package/src/panels/details.css +14 -0
  253. package/src/posestudio.jsx +4 -27
  254. package/src/project-browser.jsx +3 -4
  255. package/src/project-resources.js +18 -31
  256. package/src/project.js +13 -104
  257. package/src/props.jsx +25 -280
  258. package/src/qa-label.js +25 -0
  259. package/src/rail-dot-drag.js +23 -0
  260. package/src/render-passes.js +10 -0
  261. package/src/resource-status.jsx +1 -0
  262. package/src/result-modal.jsx +4 -19
  263. package/src/room.jsx +20 -12
  264. package/src/scene-assets.js +8 -6
  265. package/src/scene-light-place.js +72 -0
  266. package/src/scene-lights.jsx +148 -0
  267. package/src/scene-objects.js +31 -139
  268. package/src/scenes.js +15 -105
  269. package/src/semantic-edit.js +2 -5
  270. package/src/set-pieces.jsx +183 -0
  271. package/src/settings-menu.jsx +3 -11
  272. package/src/shell/BottomDock.jsx +9 -51
  273. package/src/shell/DetailsSlot.jsx +16 -200
  274. package/src/shell/GhostsMenuGroup.jsx +74 -0
  275. package/src/shell/LibrarySlot.jsx +1 -3
  276. package/src/shell/MenuBar.jsx +3 -3
  277. package/src/shell/PreferencesDialog.jsx +15 -264
  278. package/src/shell/PreferencesSlot.jsx +2 -8
  279. package/src/shell/TopBar.jsx +5 -84
  280. package/src/shell/ViewportToolbar.jsx +10 -70
  281. package/src/shell/agent-glass.css +19 -6
  282. package/src/shell/details-selection.js +42 -0
  283. package/src/shell/ghosts-menu.css +22 -0
  284. package/src/shell/glass-regions.css +29 -3
  285. package/src/shell/preferences.css +6 -1
  286. package/src/shot-authoring.js +4 -7
  287. package/src/soft-shadows.js +37 -0
  288. package/src/stage-attach-frames.js +12 -12
  289. package/src/stage-canvas-rigs.jsx +3 -3
  290. package/src/stage-capture.jsx +42 -8
  291. package/src/stage-characters.jsx +22 -216
  292. package/src/stage-editor-gizmos.jsx +6 -6
  293. package/src/stage-environment.js +93 -0
  294. package/src/stage-hdr-builtins.js +107 -0
  295. package/src/stage-hdr-image.js +116 -0
  296. package/src/stage-hdr-library.js +70 -0
  297. package/src/stage-hdr-map.js +94 -0
  298. package/src/stage-hdr.js +130 -0
  299. package/src/stage-lighting.js +149 -0
  300. package/src/stage-occlusion.js +210 -0
  301. package/src/stage-sky.jsx +159 -0
  302. package/src/stage-startup-defaults.js +5 -9
  303. package/src/studio-actions.js +16 -14
  304. package/src/studio-agent-commands.js +19 -16
  305. package/src/studio-agent-motion.js +9 -9
  306. package/src/studio-agent-protocol.js +47 -77
  307. package/src/studio-app-binding.js +27 -47
  308. package/src/studio-asset-list.js +17 -0
  309. package/src/studio-contact-sheet.js +37 -5
  310. package/src/studio-elements.js +27 -7
  311. package/src/studio-entity-bounds.js +18 -0
  312. package/src/studio-error-codes.js +15 -0
  313. package/src/studio-export-framing.js +152 -0
  314. package/src/studio-lighting-check.js +103 -0
  315. package/src/studio-motion-visual.js +150 -0
  316. package/src/studio-schema-errors.js +80 -0
  317. package/src/studio-support-gap.js +74 -0
  318. package/src/styles.css +1 -19
  319. package/src/timeline-defaults.js +5 -0
  320. package/src/timeline-extent.js +8 -20
  321. package/src/tutorial-walk.js +17 -0
  322. package/src/ui-scrub.js +1 -1
  323. package/src/use-shot-camera-tracks.js +12 -0
  324. package/src/view-ghosts.js +97 -0
  325. package/src/view-ghosts.jsx +49 -0
  326. package/src/workflow/AgentPanel.jsx +47 -166
  327. package/src/workflow/AgentProgressCard.jsx +109 -0
  328. package/src/workflow/AgentReplyText.jsx +37 -0
  329. package/src/workflow/AgentTurnSteps.jsx +84 -0
  330. package/src/workflow/LoginPanel.jsx +140 -0
  331. package/src/workflow/WorkflowBuilder.jsx +7 -23
  332. package/src/workflow/agent-client.js +54 -51
  333. package/src/workflow/agent-panel.css +71 -1
  334. package/src/workflow/agent-progress-card.css +167 -0
  335. package/src/workflow/agent-progress-view.js +47 -0
  336. package/src/workflow/agent-turn-steps.css +113 -0
  337. package/src/workflow/agent-turn.js +191 -0
  338. package/src/workflow/login-client.js +34 -0
  339. package/src/workflow/motion-input.js +18 -31
  340. package/src/workflow/node-schema.js +1 -1
  341. package/src/workflow/reply-markdown.js +69 -0
  342. package/src/workflow/scene-asset-sync.js +8 -8
  343. package/tools/agent-session-stats.mjs +61 -0
  344. package/tools/dev-full.mjs +5 -56
  345. package/tools/eslint-baseline.json +12 -13
  346. package/tools/knip-baseline.json +0 -179
  347. package/tools/loc-baseline.json +31 -81
  348. package/tools/motion3/extract-body.mjs +103 -0
  349. package/tools/motion3/extract-rig.mjs +85 -0
  350. package/tools/process-supervisor.mjs +0 -88
  351. package/tools/run-tests.mjs +9 -125
  352. package/bin/agent/motion-runtime.mjs +0 -76
  353. package/dist/ardy/cskel27-rest.json +0 -557
  354. package/dist/assets/analytics-C9pMpW7s.js +0 -1
  355. package/dist/assets/app-B_2XB9rw.css +0 -1
  356. package/dist/assets/app-DAuvKPP8.js +0 -4920
  357. package/dist/assets/config-Bx7pYsD9.js +0 -1
  358. package/dist/assets/config-DeoFTYzb.css +0 -1
  359. package/dist/assets/demo-CvKuBgy5.js +0 -1
  360. package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
  361. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  362. package/dist/assets/ticket-BPk2Ni95.js +0 -1
  363. package/dist/assets/workflow-jJRBR94Z.js +0 -179
  364. package/dist/demo/walk-then-stop.npz +0 -0
  365. package/mcp/ardy-prompts.mjs +0 -218
  366. package/src/ardy/auto-fix-panel.css +0 -108
  367. package/src/ardy/auto-physics.js +0 -1194
  368. package/src/ardy/client.js +0 -153
  369. package/src/ardy/convert.js +0 -313
  370. package/src/ardy/cskel27-neutral.js +0 -39
  371. package/src/ardy/cskel27.js +0 -77
  372. package/src/ardy/export.js +0 -165
  373. package/src/ardy/fix-collisions.js +0 -2257
  374. package/src/ardy/foot-lock.js +0 -230
  375. package/src/ardy/motion-calibration.js +0 -118
  376. package/src/ardy/motion-edit.js +0 -213
  377. package/src/ardy/motion-url.js +0 -55
  378. package/src/ardy/mp4-duration.js +0 -102
  379. package/src/ardy/npz.js +0 -595
  380. package/src/ardy/physics-panel.css +0 -21
  381. package/src/ardy/physics-panel.jsx +0 -89
  382. package/src/ardy/physics-refine.js +0 -111
  383. package/src/ardy/physics-review.js +0 -567
  384. package/src/ardy/physics-temporal.js +0 -54
  385. package/src/ardy/platform-fit-panel.css +0 -64
  386. package/src/ardy/platform-fit-panel.jsx +0 -41
  387. package/src/ardy/platform-fit.js +0 -326
  388. package/src/ardy/playback.js +0 -711
  389. package/src/ardy/pose-pin.js +0 -97
  390. package/src/ardy/prompt-clips.js +0 -30
  391. package/src/ardy/retime.js +0 -211
  392. package/src/ardy/root-drop.js +0 -369
  393. package/src/ardy/timeline-resize.js +0 -13
  394. package/src/ardy/to-cskel27.js +0 -225
  395. package/src/ardy/trim.js +0 -33
  396. package/src/ardy/waypoints.js +0 -369
  397. package/src/ardy-bridge-contract.js +0 -281
  398. package/src/domains/motion/motion-video-capture.js +0 -664
  399. package/src/i2v-motion-client.js +0 -77
  400. package/src/i2v-motion-studio.jsx +0 -180
  401. package/src/line-edit.js +0 -1348
  402. package/src/motion/generation.js +0 -105
  403. package/src/motion-readiness-ui.jsx +0 -67
  404. package/src/motion-readiness.js +0 -40
  405. package/src/motion-resources.js +0 -177
  406. package/src/motion-store.js +0 -65
  407. package/src/motion-trail.js +0 -601
  408. package/src/multimodel-ingest.js +0 -394
  409. package/src/panels/PromptBlocksPanel.jsx +0 -444
  410. package/src/panels/VideoCapturePanel.jsx +0 -181
  411. package/src/pose-extract/browser.js +0 -42
  412. package/src/pose-extract/detector.js +0 -100
  413. package/src/pose-extract/fit.js +0 -227
  414. package/src/pose-extract/image-frame.js +0 -51
  415. package/src/pose-extract/index.js +0 -58
  416. package/src/pose-extract/keyframes.js +0 -74
  417. package/src/pose-extract/landmarks.js +0 -162
  418. package/src/pose-extract/mirror.js +0 -153
  419. package/src/pose-extract/take.js +0 -131
  420. package/src/pose-extract/video-frames.js +0 -91
  421. package/src/take-recipe.js +0 -165
  422. package/src/trail-key-conflicts.js +0 -39
  423. package/src/trail-pick.js +0 -59
  424. package/src/use-i2v-capture-modal.js +0 -15
  425. package/tools/ardy/BRIDGE.md +0 -37
  426. package/tools/ardy/GVHMR-NPZ.md +0 -68
  427. package/tools/ardy/README.md +0 -124
  428. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  429. package/tools/ardy/artifacts.mjs +0 -34
  430. package/tools/ardy/bridge.mjs +0 -1732
  431. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  432. package/tools/ardy/cclay_constrained_generate.py +0 -561
  433. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  434. package/tools/ardy/cclay_motion_edit.py +0 -510
  435. package/tools/ardy/cclay_sequence_generate.py +0 -705
  436. package/tools/ardy/cclay_worker.py +0 -304
  437. package/tools/ardy/dump-npz.py +0 -205
  438. package/tools/ardy/extract-rest.mjs +0 -299
  439. package/tools/ardy/extract.mjs +0 -507
  440. package/tools/ardy/footage.mjs +0 -467
  441. package/tools/ardy/gvhmr-floor.mjs +0 -102
  442. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  443. package/tools/ardy/gvhmr_fastpath.py +0 -168
  444. package/tools/ardy/gvhmr_trajectory.py +0 -240
  445. package/tools/ardy/merge-text-encoder.py +0 -160
  446. package/tools/ardy/mocap-metrics.mjs +0 -200
  447. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  448. package/tools/ardy/motion-stabilize.mjs +0 -348
  449. package/tools/ardy/npz.mjs +0 -414
  450. package/tools/ardy/pose-to-npz.mjs +0 -106
  451. package/tools/ardy/prompt-limits.mjs +0 -5
  452. package/tools/ardy/run-edit-on-box.sh +0 -73
  453. package/tools/ardy/run-local.mjs +0 -233
  454. package/tools/ardy/run-on-box.sh +0 -593
  455. package/tools/ardy/run-sequence-on-box.sh +0 -177
  456. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  457. package/tools/ardy/runners/index.mjs +0 -18
  458. package/tools/ardy/runners/local.mjs +0 -455
  459. package/tools/ardy/runners/proc.mjs +0 -125
  460. package/tools/ardy/runners/remote.mjs +0 -252
  461. package/tools/ardy/setup-local.mjs +0 -189
  462. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  463. package/tools/ardy/setup-text-encoder.py +0 -306
  464. package/tools/ardy/smpl-cskel27.mjs +0 -178
  465. package/tools/ardy/visual-qa.mjs +0 -196
  466. package/tools/ardy/vq-car.mjs +0 -52
  467. package/tools/bench/EXP3.md +0 -61
  468. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  469. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  470. package/tools/bench/cclay_bench_runner.py +0 -42
  471. package/tools/bench/cube-contact.mjs +0 -162
  472. package/tools/bench/exp3.mjs +0 -152
  473. package/tools/bench/extract-bench-lib.mjs +0 -216
  474. package/tools/bench/extract-bench.mjs +0 -302
  475. package/tools/bench/fal-generate.mjs +0 -88
  476. package/tools/bench/fit/README.md +0 -189
  477. package/tools/bench/fit/camera.mjs +0 -59
  478. package/tools/bench/fit/contact.mjs +0 -419
  479. package/tools/bench/fit/footlock.mjs +0 -234
  480. package/tools/bench/fit/motion.mjs +0 -85
  481. package/tools/bench/fit/pin.mjs +0 -27
  482. package/tools/bench/fit/remote.mjs +0 -105
  483. package/tools/bench/fit-bench.mjs +0 -126
  484. package/tools/bench/fit-sanity.mjs +0 -45
  485. package/tools/bench/metrics.mjs +0 -313
  486. package/tools/bench/obs/depth.mjs +0 -258
  487. package/tools/bench/obs/extrinsics.mjs +0 -175
  488. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  489. package/tools/bench/obs/ground.mjs +0 -294
  490. package/tools/bench/obs/heading.mjs +0 -151
  491. package/tools/bench/obs/ladder.mjs +0 -555
  492. package/tools/bench/obs/mannequin-betas.json +0 -124
  493. package/tools/bench/obs/remote.mjs +0 -83
  494. package/tools/bench/obs/rest_joints.py +0 -52
  495. package/tools/bench/obs/ybot-targets.mjs +0 -49
  496. package/tools/bench/obs-bench.mjs +0 -520
  497. package/tools/bench/score.mjs +0 -343
  498. package/tools/bench/summarize.mjs +0 -86
  499. package/tools/demo-worker/README.md +0 -137
  500. package/tools/demo-worker/api-client.mjs +0 -233
  501. package/tools/demo-worker/generate.mjs +0 -301
  502. package/tools/demo-worker/index.mjs +0 -466
  503. package/tools/demo-worker/sign-core.mjs +0 -112
  504. package/tools/demo-worker/sign.mjs +0 -161
  505. package/tools/gt-render/browser.mjs +0 -182
  506. package/tools/gt-render/camera-math.mjs +0 -276
  507. package/tools/gt-render/page.mjs +0 -267
  508. package/tools/gt-render/render.mjs +0 -514
  509. package/tools/gt-render/scene-box.mjs +0 -31
  510. package/tools/gt-render/take-transform.mjs +0 -87
  511. package/tools/kimodo/compare-seam.mjs +0 -108
  512. package/tools/kimodo/constraints.mjs +0 -244
  513. package/tools/kimodo/edit.mjs +0 -259
  514. package/tools/kimodo/effector-constraints.mjs +0 -200
  515. package/tools/kimodo/generate.mjs +0 -646
  516. package/tools/kimodo/local-output.mjs +0 -265
  517. package/tools/kimodo/measure-pose.mjs +0 -65
  518. package/tools/kimodo/measure-preserve.mjs +0 -899
  519. package/tools/kimodo/measure-waypoints.mjs +0 -55
  520. package/tools/kimodo/mlx-generate.py +0 -111
  521. package/tools/kimodo/pose-constraints.mjs +0 -248
  522. package/tools/kimodo/preserve-mask.mjs +0 -543
  523. package/tools/kimodo/read-npz.mjs +0 -189
  524. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  525. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  526. package/tools/kimodo/runner.mjs +0 -284
  527. package/tools/kimodo/seam-batch.mjs +0 -77
  528. package/tools/kimodo/setup-local.mjs +0 -30
  529. package/tools/kimodo/setup-on-box.sh +0 -339
  530. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  531. package/tools/morphgs/assets/gen_truth.py +0 -39
  532. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  533. package/tools/morphgs/assets/playback-check.mjs +0 -30
  534. package/tools/morphgs/demo-gate.sh +0 -26
  535. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  536. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  537. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  538. package/tools/morphgs/setup-on-cluster.sh +0 -126
  539. package/tools/projflow/driver.py +0 -1069
  540. package/tools/projflow/generate.mjs +0 -805
  541. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  542. package/tools/projflow/line-edit-job.mjs +0 -547
  543. package/tools/projflow/replay.mjs +0 -452
  544. package/tools/projflow/runner.mjs +0 -269
  545. package/tools/projflow/service.mjs +0 -742
  546. package/tools/track/DESIGN.md +0 -513
  547. package/tools/track/backfill-provenance.mjs +0 -116
  548. package/tools/track/budget.mjs +0 -8
  549. package/tools/track/check-rig.mjs +0 -209
  550. package/tools/track/diagnostics.schema.json +0 -60
  551. package/tools/track/export-rig.mjs +0 -256
  552. package/tools/track/fallback.mjs +0 -7
  553. package/tools/track/fk-parity-fixture.mjs +0 -161
  554. package/tools/track/gate.mjs +0 -349
  555. package/tools/track/masks.mjs +0 -318
  556. package/tools/track/metrics.mjs +0 -201
  557. package/tools/track/publish-obs.mjs +0 -108
  558. package/tools/track/py/check_env.py +0 -61
  559. package/tools/track/py/eval_lr.py +0 -229
  560. package/tools/track/py/lr_viterbi.py +0 -294
  561. package/tools/track/py/masks.py +0 -405
  562. package/tools/track/py/objective.py +0 -382
  563. package/tools/track/py/rig.py +0 -508
  564. package/tools/track/py/scene.py +0 -326
  565. package/tools/track/py/test_joint_indices.py +0 -123
  566. package/tools/track/py/test_lr_viterbi.py +0 -195
  567. package/tools/track/py/test_masks.py +0 -229
  568. package/tools/track/py/test_rig.py +0 -288
  569. package/tools/track/py/test_scene.py +0 -354
  570. package/tools/track/py/test_track.py +0 -328
  571. package/tools/track/py/track.py +0 -411
  572. package/tools/track/remote.mjs +0 -140
  573. package/tools/track/rig-dump.mjs +0 -227
  574. package/tools/track/run-box-tests.mjs +0 -14
  575. package/tools/track/run-box.mjs +0 -168
  576. package/tools/track/setup-box.sh +0 -59
  577. package/tools/track/study-2d.mjs +0 -728
  578. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  579. /package/src/{ardy → motion}/ground.js +0 -0
  580. /package/src/{ardy → motion}/ik-drag.js +0 -0
  581. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  582. /package/src/{ardy → motion}/ik.js +0 -0
  583. /package/src/{ardy → motion}/physics-surface.js +0 -0
  584. /package/src/{ardy → motion}/playback-clock.js +0 -0
  585. /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 };