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