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,153 +0,0 @@
1
- /**
2
- * Browser-side client for the ARDY dev sidecar (tools/ardy/bridge.mjs).
3
- *
4
- * The sidecar is an OPTIONAL dev companion: it listens on 127.0.0.1:5181 and
5
- * Vite proxies /ardy to it during development only. The production build is
6
- * a static SPA with no server at all, so every function here treats a missing
7
- * sidecar as an expected state and reports it as data — never as a thrown
8
- * error — so the UI can degrade to a hint instead of crashing.
9
- */
10
- import { ko, isKo } from "../locale.js";
11
-
12
- const JSON_HEADERS = { "Content-Type": "application/json" };
13
-
14
- // Bounded wait so a hung proxy or a slow-but-alive bridge cannot wedge the
15
- // panel behind a spinner forever. Long enough to not mislabel a healthy
16
- // bridge that answers in a couple of seconds, short enough to keep the
17
- // no-sidecar state snappy.
18
- const PROBE_TIMEOUT_MS = 5000;
19
-
20
- /**
21
- * Prefer the sidecar's {"reason": "..."} error body; fall back to `fallback`
22
- * when the body is not JSON (e.g. the dev proxy's own error page).
23
- */
24
- async function reasonOf(res, fallback) {
25
- try {
26
- const payload = await res.json();
27
- if (payload && typeof payload.reason === "string" && payload.reason) return payload.reason;
28
- } catch {
29
- // non-JSON error body — keep the caller's fallback
30
- }
31
- return fallback;
32
- }
33
-
34
- async function healthPayload(res) {
35
- try {
36
- const payload = await res.json();
37
- return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
38
- } catch {
39
- return {};
40
- }
41
- }
42
-
43
- /**
44
- * Probe the sidecar once. Resolves to { ok:true, host, encoder, device,
45
- * extractionBackend } on a
46
- * healthy 200, otherwise { ok:false, reason }. Never rejects: the most common
47
- * failure (no sidecar running) is a UI state, not a crash.
48
- */
49
- export async function checkBridge() {
50
- try {
51
- const res = await fetch("/ardy/health", { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
52
- const payload = await healthPayload(res);
53
- if (!res.ok) {
54
- return {
55
- ...payload,
56
- ok: false,
57
- reason: payload.reason || (isKo ? `브리지 상태가 좋지 않아요(HTTP ${res.status})` : `bridge unhealthy (HTTP ${res.status})`),
58
- };
59
- }
60
- // Health responses are authoritative. A successful HTTP status without an
61
- // explicit boolean health result is malformed, never a ready bridge.
62
- if (typeof payload.ok !== "boolean") return { ...payload, ok: false, reason: "invalid health response" };
63
- return payload;
64
- } catch (err) {
65
- return { ok: false, reason: err?.message || ko("bridge unreachable", "브리지에 연결할 수 없어요") };
66
- }
67
- }
68
-
69
- /**
70
- * List base motions the box reported. Returns [] when the sidecar is down —
71
- * the caller renders an empty state, it does not crash.
72
- */
73
- export async function listBases() {
74
- try {
75
- const res = await fetch("/ardy/bases", { signal: AbortSignal.timeout(PROBE_TIMEOUT_MS) });
76
- if (!res.ok) return [];
77
- const payload = await res.json();
78
- return payload && Array.isArray(payload.bases) ? payload.bases : [];
79
- } catch {
80
- return [];
81
- }
82
- }
83
-
84
- /**
85
- * POST a generation and stream the ndjson answer.
86
- *
87
- * The response is read incrementally with a streaming reader and every parsed
88
- * line is handed to `onEvent(event)`. Lines may be split at any byte — text is
89
- * buffered until the trailing newline arrives, so a JSON object broken across
90
- * two chunks is still delivered as one event.
91
- *
92
- * Resolves with the terminal `done` event ({event, output, bytes}); rejects on
93
- * a terminal `error` event, a malformed line, a non-200 response, or an
94
- * aborted signal (the AbortError propagates so callers can tell cancellation
95
- * apart from failure). `signal` is optional.
96
- */
97
- export async function generate(body, onEvent, { signal } = {}) {
98
- const res = await fetch("/ardy/generate", {
99
- method: "POST",
100
- headers: JSON_HEADERS,
101
- body: JSON.stringify(body),
102
- signal,
103
- });
104
- if (!res.ok) {
105
- throw new Error(await reasonOf(res, `generate failed (HTTP ${res.status})`));
106
- }
107
- if (!res.body) throw new Error(ko("generate: response has no body stream", "생성 응답에 본문 스트림이 없어요"));
108
-
109
- const reader = res.body.getReader();
110
- const decoder = new TextDecoder();
111
- let buffer = "";
112
- for (;;) {
113
- const { done, value } = await reader.read();
114
- if (done) break;
115
- buffer += decoder.decode(value, { stream: true });
116
- // Drain complete lines only; a chunk may end mid-line, in which case
117
- // the remainder stays in the buffer until its newline arrives.
118
- let nl = buffer.indexOf("\n");
119
- while (nl !== -1) {
120
- const terminal = applyLine(buffer.slice(0, nl).trim());
121
- buffer = buffer.slice(nl + 1);
122
- if (terminal) return terminal;
123
- nl = buffer.indexOf("\n");
124
- }
125
- }
126
- // Flush the decoder so a multi-byte char split by the final chunk boundary
127
- // is complete, then treat a non-empty tail as one last line: the contract
128
- // does not promise a trailing newline on the terminal event.
129
- buffer += decoder.decode();
130
- if (buffer.trim()) {
131
- const terminal = applyLine(buffer.trim());
132
- if (terminal) return terminal;
133
- }
134
- throw new Error(ko("generate: stream ended without a done or error event", "완료 또는 오류 이벤트 없이 생성 스트림이 끝났어요"));
135
-
136
- /** Parse one ndjson line; returns the done event, throws on error/bad line. */
137
- function applyLine(line) {
138
- let event;
139
- try {
140
- event = JSON.parse(line);
141
- } catch (err) {
142
- throw new Error(`generate: bad ndjson line: ${err.message}`);
143
- }
144
- onEvent(event);
145
- if (event.event === "error") {
146
- throw new Error(
147
- typeof event.message === "string" && event.message ? event.message : "generate: generator reported an error",
148
- );
149
- }
150
- if (event.event === "done") return event;
151
- return null;
152
- }
153
- }
@@ -1,313 +0,0 @@
1
- /**
2
- * Pure, framework-free math for the CozyClay -> ARDY pose bridge.
3
- * JS twin of /Users/yun/CozyClay/blender-addon/cclay/motion_constraints.py,
4
- * with the small matrix/quaternion helpers mirrored from
5
- * /Users/yun/CozyClay/blender-addon/cclay/motion_retarget.py so the math is
6
- * not re-derived (keep the two files in lockstep when the Python changes).
7
- *
8
- * Matrices are row-major 3x3 nested arrays, quaternions are w-first
9
- * [w, x, y, z] (Blender/motion_constraints order, NOT three.js [x, y, z, w]).
10
- * The math contract, from PoseTrackBuilder.step in motion_retarget.py:
11
- *
12
- * basis = Rb^T @ L @ Rb (ARDY local rotation L -> Blender basis)
13
- * L = Rb @ basis @ Rb^T (inverse, this module)
14
- *
15
- * where Rb is the target bone's armature-space rest rotation (3x3). Every
16
- * function is total: shape mismatches raise a clear Error instead of leaking
17
- * NaN. No file IO, no three.js, no UI — pure functions over plain arrays.
18
- */
19
-
20
- import { CSKEL27_PARENTS } from "./cskel27.js";
21
-
22
- // Quaternion norm below which a rotation matrix cannot be built. Mirrors
23
- // motion_retarget._QUATERNION_NORM_EPSILON so the inverse path rejects the
24
- // same degenerate inputs the forward path would have produced.
25
- const QUATERNION_NORM_EPSILON = 1e-12;
26
-
27
- function isFiniteNumber(value) {
28
- return typeof value === "number" && Number.isFinite(value);
29
- }
30
-
31
- function requireQuat(q, label) {
32
- if (!Array.isArray(q) || q.length !== 4 || !q.every(isFiniteNumber)) {
33
- throw new Error(`${label} must be a [w, x, y, z] quaternion of four finite numbers`);
34
- }
35
- return q;
36
- }
37
-
38
- function requireMat3(m, label) {
39
- if (
40
- !Array.isArray(m) ||
41
- m.length !== 3 ||
42
- !m.every(
43
- (row) => Array.isArray(row) && row.length === 3 && row.every(isFiniteNumber)
44
- )
45
- ) {
46
- throw new Error(`${label} must be a row-major 3x3 matrix of finite numbers`);
47
- }
48
- return m;
49
- }
50
-
51
- function requireVec3(v, label) {
52
- if (!Array.isArray(v) || v.length !== 3 || !v.every(isFiniteNumber)) {
53
- throw new Error(`${label} must be an [x, y, z] vector of three finite numbers`);
54
- }
55
- return v;
56
- }
57
-
58
- function requireJointMatrices(values, label) {
59
- if (!Array.isArray(values) || values.length !== CSKEL27_PARENTS.length) {
60
- throw new Error(
61
- `${label} must hold ${CSKEL27_PARENTS.length} entries (one per cskel27 joint)`
62
- );
63
- }
64
- values.forEach((m, index) => requireMat3(m, `${label}[${index}]`));
65
- return values;
66
- }
67
-
68
- function requireJointVectors(values, label) {
69
- if (!Array.isArray(values) || values.length !== CSKEL27_PARENTS.length) {
70
- throw new Error(
71
- `${label} must hold ${CSKEL27_PARENTS.length} entries (one per cskel27 joint)`
72
- );
73
- }
74
- values.forEach((v, index) => requireVec3(v, `${label}[${index}]`));
75
- return values;
76
- }
77
-
78
- // Joint indices ordered so every parent precedes its children. Mirrors
79
- // motion_constraints._topological_order.
80
- function topologicalOrder() {
81
- const placed = new Set();
82
- const order = [];
83
- CSKEL27_PARENTS.forEach((parent, index) => {
84
- if (parent === null) {
85
- placed.add(index);
86
- order.push(index);
87
- }
88
- });
89
- order.sort((a, b) => a - b);
90
- while (order.length < CSKEL27_PARENTS.length) {
91
- let progressed = false;
92
- for (let index = 0; index < CSKEL27_PARENTS.length; index += 1) {
93
- if (!placed.has(index) && placed.has(CSKEL27_PARENTS[index])) {
94
- order.push(index);
95
- placed.add(index);
96
- progressed = true;
97
- }
98
- }
99
- if (!progressed) {
100
- throw new Error("cskel27 parent table is not a tree");
101
- }
102
- }
103
- return order;
104
- }
105
-
106
- const CSKEL27_TOPOLOGICAL_ORDER = topologicalOrder();
107
-
108
- /** Row-major 3x3 matrix product a @ b (motion_retarget._mat_mul). */
109
- export function matMul(a, b) {
110
- requireMat3(a, "matMul(a, b): a");
111
- requireMat3(b, "matMul(a, b): b");
112
- return [
113
- [
114
- a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0],
115
- a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1],
116
- a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2],
117
- ],
118
- [
119
- a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0],
120
- a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1],
121
- a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2],
122
- ],
123
- [
124
- a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0],
125
- a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1],
126
- a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2],
127
- ],
128
- ];
129
- }
130
-
131
- /** Row-major 3x3 transpose (motion_retarget._mat_transpose). */
132
- export function matTranspose(m) {
133
- requireMat3(m, "matTranspose(m): m");
134
- return [
135
- [m[0][0], m[1][0], m[2][0]],
136
- [m[0][1], m[1][1], m[2][1]],
137
- [m[0][2], m[1][2], m[2][2]],
138
- ];
139
- }
140
-
141
- // Row-major 3x3 matrix times column vector (motion_retarget._mat_vec).
142
- function matVec(m, v) {
143
- return [
144
- m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
145
- m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
146
- m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2],
147
- ];
148
- }
149
-
150
- /**
151
- * Normalized [w, x, y, z] -> row-major 3x3 rotation matrix.
152
- * Twin of motion_constraints._quat_to_mat (which is the inverse of
153
- * motion_retarget._mat_to_quat). A zero-length or non-finite quaternion is
154
- * rejected explicitly rather than producing a garbage matrix.
155
- */
156
- export function quatToMat(q) {
157
- const [wRaw, xRaw, yRaw, zRaw] = requireQuat(q, "quatToMat(q): q");
158
- const normSq = wRaw * wRaw + xRaw * xRaw + yRaw * yRaw + zRaw * zRaw;
159
- if (!Number.isFinite(normSq) || normSq <= QUATERNION_NORM_EPSILON) {
160
- throw new Error("quatToMat(q): quaternion is zero-length and cannot represent a rotation");
161
- }
162
- const inverseNorm = 1 / Math.sqrt(normSq);
163
- const w = wRaw * inverseNorm;
164
- const x = xRaw * inverseNorm;
165
- const y = yRaw * inverseNorm;
166
- const z = zRaw * inverseNorm;
167
- // Standard quaternion -> rotation matrix (right-handed, row-major).
168
- return [
169
- [1 - 2 * (y * y + z * z), 2 * (x * y - w * z), 2 * (x * z + w * y)],
170
- [2 * (x * y + w * z), 1 - 2 * (x * x + z * z), 2 * (y * z - w * x)],
171
- [2 * (x * z - w * y), 2 * (y * z + w * x), 1 - 2 * (x * x + y * y)],
172
- ];
173
- }
174
-
175
- /**
176
- * Row-major 3x3 rotation matrix -> normalized [w, x, y, z].
177
- * Twin of motion_retarget._mat_to_quat (Shepperd's method). A non-finite or
178
- * degenerate matrix raises instead of returning a garbage quaternion.
179
- */
180
- export function matToQuat(m) {
181
- requireMat3(m, "matToQuat(m): m");
182
- let quat;
183
- const trace = m[0][0] + m[1][1] + m[2][2];
184
- if (trace > 0) {
185
- const s = Math.sqrt(trace + 1) * 2;
186
- quat = [0.25 * s, (m[2][1] - m[1][2]) / s, (m[0][2] - m[2][0]) / s, (m[1][0] - m[0][1]) / s];
187
- } else if (m[0][0] > m[1][1] && m[0][0] > m[2][2]) {
188
- const s = Math.sqrt(1 + m[0][0] - m[1][1] - m[2][2]) * 2;
189
- quat = [(m[2][1] - m[1][2]) / s, 0.25 * s, (m[0][1] + m[1][0]) / s, (m[0][2] + m[2][0]) / s];
190
- } else if (m[1][1] > m[2][2]) {
191
- const s = Math.sqrt(1 + m[1][1] - m[0][0] - m[2][2]) * 2;
192
- quat = [(m[0][2] - m[2][0]) / s, (m[0][1] + m[1][0]) / s, 0.25 * s, (m[1][2] + m[2][1]) / s];
193
- } else {
194
- const s = Math.sqrt(1 + m[2][2] - m[0][0] - m[1][1]) * 2;
195
- quat = [(m[1][0] - m[0][1]) / s, (m[0][2] + m[2][0]) / s, (m[1][2] + m[2][1]) / s, 0.25 * s];
196
- }
197
- const squaredNorm = quat.reduce((sum, component) => sum + component * component, 0);
198
- if (!Number.isFinite(squaredNorm) || squaredNorm <= QUATERNION_NORM_EPSILON) {
199
- throw new Error("matToQuat(m): matrix is degenerate and cannot represent a rotation");
200
- }
201
- const inverseNorm = 1 / Math.sqrt(squaredNorm);
202
- const normalized = quat.map((component) => component * inverseNorm);
203
- if (!normalized.every(isFiniteNumber)) {
204
- throw new Error("matToQuat(m): matrix is degenerate and cannot represent a rotation");
205
- }
206
- return normalized;
207
- }
208
-
209
- /**
210
- * ARDY local rotation L -> Blender pose basis: basis = Rb^T @ L @ Rb.
211
- * (the forward direction of the PoseTrackBuilder.step contract).
212
- */
213
- export function localToBasis(L, Rb) {
214
- const local = requireMat3(L, "localToBasis(L, Rb): L");
215
- const rest = requireMat3(Rb, "localToBasis(L, Rb): Rb");
216
- const restT = matTranspose(rest);
217
- return matMul(restT, matMul(local, rest));
218
- }
219
-
220
- /**
221
- * Blender pose basis -> ARDY local rotation L: L = Rb @ basis @ Rb^T.
222
- * (the inverse of the PoseTrackBuilder.step contract).
223
- */
224
- export function basisToLocal(basis, Rb) {
225
- const b = requireMat3(basis, "basisToLocal(basis, Rb): basis");
226
- const rest = requireMat3(Rb, "basisToLocal(basis, Rb): Rb");
227
- const restT = matTranspose(rest);
228
- return matMul(rest, matMul(b, restT));
229
- }
230
-
231
- /**
232
- * Blender pose-bone quaternion (normalized [w, x, y, z]) -> ARDY local
233
- * rotation L, given the bone's armature-space rest rotation Rb.
234
- * Twin of motion_constraints.basis_quaternion_to_local_rotation:
235
- * basis = quatToMat(quat); L = Rb @ basis @ Rb^T.
236
- */
237
- export function basisQuaternionToLocalRotation(quatWFirst, restRotation) {
238
- const basis = quatToMat(quatWFirst);
239
- return basisToLocal(basis, restRotation);
240
- }
241
-
242
- /**
243
- * Accumulate per-joint local rotations into global ones down the tree.
244
- * Twin of motion_constraints.global_rotations. Returns 27 fresh matrices in
245
- * cskel27 index order.
246
- */
247
- export function globalRotations(localRotations) {
248
- const locals = requireJointMatrices(localRotations, "globalRotations(localRotations)");
249
- const out = new Array(CSKEL27_PARENTS.length);
250
- for (const index of CSKEL27_TOPOLOGICAL_ORDER) {
251
- const parent = CSKEL27_PARENTS[index];
252
- out[index] =
253
- parent === null
254
- ? locals[index].map((row) => row.slice())
255
- : matMul(out[parent], locals[index]);
256
- }
257
- return out;
258
- }
259
-
260
- /**
261
- * Constant bone vectors, each expressed in its parent's global frame, derived
262
- * from one posed frame: offset = R_parent^T @ (child - parent).
263
- * Twin of motion_constraints.derive_bone_offsets (argument order swapped: JS
264
- * call sites pass the source positions first). Deriving them from the clip
265
- * rather than hardcoding a rest skeleton keeps this correct if ARDY ever
266
- * reproportions cskel27.
267
- */
268
- export function deriveBoneOffsets(jointPositions, localRotations) {
269
- const positions = requireJointVectors(jointPositions, "deriveBoneOffsets(jointPositions, ...)");
270
- const rotations = globalRotations(localRotations);
271
- const offsets = new Array(CSKEL27_PARENTS.length);
272
- for (let index = 0; index < offsets.length; index += 1) {
273
- offsets[index] = [0, 0, 0];
274
- }
275
- for (const index of CSKEL27_TOPOLOGICAL_ORDER) {
276
- const parent = CSKEL27_PARENTS[index];
277
- if (parent === null) continue;
278
- const delta = [
279
- positions[index][0] - positions[parent][0],
280
- positions[index][1] - positions[parent][1],
281
- positions[index][2] - positions[parent][2],
282
- ];
283
- offsets[index] = matVec(matTranspose(rotations[parent]), delta);
284
- }
285
- return offsets;
286
- }
287
-
288
- /**
289
- * Joint positions in npz space for one posed frame: the mapping that answers
290
- * "where does the ARDY skeleton put this joint when posed like these
291
- * rotations". Twin of motion_constraints.forward_kinematics. `rootPosition`
292
- * defaults to the npz origin when the caller only needs relative pose.
293
- */
294
- export function forwardKinematics(localRotations, boneOffsets, rootPosition = [0, 0, 0]) {
295
- const rotations = globalRotations(localRotations);
296
- requireJointVectors(boneOffsets, "forwardKinematics(...): boneOffsets");
297
- const root = requireVec3(rootPosition, "forwardKinematics(...): rootPosition");
298
- const positions = new Array(CSKEL27_PARENTS.length);
299
- for (const index of CSKEL27_TOPOLOGICAL_ORDER) {
300
- const parent = CSKEL27_PARENTS[index];
301
- if (parent === null) {
302
- positions[index] = root.slice();
303
- continue;
304
- }
305
- const moved = matVec(rotations[parent], boneOffsets[index]);
306
- positions[index] = [
307
- positions[parent][0] + moved[0],
308
- positions[parent][1] + moved[1],
309
- positions[parent][2] + moved[2],
310
- ];
311
- }
312
- return positions;
313
- }
@@ -1,39 +0,0 @@
1
- /**
2
- * CoreSkeleton27 neutral-pose joint positions (metres, Y-up), exported
3
- * verbatim from the box (`CoreSkeleton27().neutral_joints`, ~/ardy) — the
4
- * same reference the viser demo's Mixamo avatar uses as ardy_bind_positions
5
- * in compute_bone_transforms. Index order == CSKEL27_JOINTS. The hips sit
6
- * at the origin and the lowest joint (toes) at y = -0.9544128.
7
- *
8
- * Positional skinning needs this: a bone's bind offset is measured
9
- * against the ARDY neutral joint, not against the rig's own rest pose.
10
- */
11
- export const CSKEL27_NEUTRAL = [
12
- [0.0, 0.0, 0.0], // Hips
13
- [0.0, 0.0709891, -0.0473261], // Spine
14
- [0.0, 0.1642033, -0.0637623], // Spine1
15
- [0.0, 0.2584953, -0.0720118], // Spine2
16
- [0.0, 0.3531475, -0.0720119], // Spine3
17
- [0.0, 0.6016096, -0.0365176], // Neck
18
- [0.0, 0.7297793, -0.0139179], // Head
19
- [-0.0319949, 0.5259196, -0.0186873], // RightShoulder
20
- [-0.1909029, 0.5259195, -0.0186873], // RightArm
21
- [-0.4863389, 0.5259194, -0.0186873], // RightForeArm
22
- [-0.7189909, 0.5259193, -0.0186873], // RightHand
23
- [-0.7886024, 0.5259193, -0.0186873], // RightHandEnd
24
- [-0.7468355, 0.5073563, 0.0277204], // RightHandThumb1
25
- [0.0319949, 0.5259196, -0.0186873], // LeftShoulder
26
- [0.1909029, 0.5259196, -0.0186873], // LeftArm
27
- [0.4863389, 0.5259196, -0.0186873], // LeftForeArm
28
- [0.7189909, 0.5259196, -0.0186873], // LeftHand
29
- [0.7886024, 0.5259196, -0.0186873], // LeftHandEnd
30
- [0.7468355, 0.5073565, 0.0277204], // LeftHandThumb1
31
- [-0.0949182, -0.0277289, 0.0], // RightUpLeg
32
- [-0.0949182, -0.4398469, 0.0], // RightLeg
33
- [-0.0949182, -0.8959379, 0.0], // RightFoot
34
- [-0.0949182, -0.9544128, 0.1606583], // RightToeBase
35
- [0.0949182, -0.0277289, 0.0], // LeftUpLeg
36
- [0.0949182, -0.4398469, 0.0], // LeftLeg
37
- [0.0949182, -0.8959379, 0.0], // LeftFoot
38
- [0.0949182, -0.9544128, 0.1606583], // LeftToeBase
39
- ];
@@ -1,77 +0,0 @@
1
- /**
2
- * cskel27 joint order and parent hierarchy, transcribed verbatim from the
3
- * ARDY reference implementation:
4
- * - CSKEL27_JOINTS mirrors `motion_retarget.CSKEL27_JOINTS`
5
- * (/Users/yun/CozyClay/blender-addon/cclay/motion_retarget.py)
6
- * - CSKEL27_PARENTS mirrors `motion_constraints._PARENT_BY_NAME` /
7
- * `CSKEL27_PARENTS` (/Users/yun/CozyClay/blender-addon/cclay/motion_constraints.py)
8
- *
9
- * Index in CSKEL27_JOINTS == joint index in the npz arrays
10
- * (local_rot_mats[:, i], posed_joints[:, i]). motion_retarget deliberately
11
- * carries no hierarchy (it is rotation-only); the parent table was verified
12
- * numerically in the Python repo (deriving offsets from one frame and running
13
- * FK across every other frame reproduces the npz's own posed_joints to
14
- * ~2.8e-07, float32 serialization noise) — a wrong parent moves that error to
15
- * whole npz units immediately, so this table must stay exact.
16
- */
17
-
18
- /** The 27 ARDY core-skeleton joints in index order. */
19
- export const CSKEL27_JOINTS = [
20
- "Hips", "Spine", "Spine1", "Spine2", "Spine3", "Neck", "Head",
21
- "RightShoulder", "RightArm", "RightForeArm", "RightHand",
22
- "RightHandEnd", "RightHandThumb1",
23
- "LeftShoulder", "LeftArm", "LeftForeArm", "LeftHand",
24
- "LeftHandEnd", "LeftHandThumb1",
25
- "RightUpLeg", "RightLeg", "RightFoot", "RightToeBase",
26
- "LeftUpLeg", "LeftLeg", "LeftFoot", "LeftToeBase",
27
- ];
28
-
29
- const JOINT_INDEX = Object.fromEntries(
30
- CSKEL27_JOINTS.map((name, index) => [name, index])
31
- );
32
-
33
- // Parent per joint by name, transcribed verbatim from
34
- // motion_constraints._PARENT_BY_NAME. The root (Hips) has no parent.
35
- const PARENT_BY_NAME = {
36
- "Hips": null,
37
- "Spine": "Hips", "Spine1": "Spine", "Spine2": "Spine1", "Spine3": "Spine2",
38
- "Neck": "Spine3", "Head": "Neck",
39
- "RightShoulder": "Spine3", "RightArm": "RightShoulder",
40
- "RightForeArm": "RightArm", "RightHand": "RightForeArm",
41
- "RightHandEnd": "RightHand", "RightHandThumb1": "RightHand",
42
- "LeftShoulder": "Spine3", "LeftArm": "LeftShoulder",
43
- "LeftForeArm": "LeftArm", "LeftHand": "LeftForeArm",
44
- "LeftHandEnd": "LeftHand", "LeftHandThumb1": "LeftHand",
45
- "RightUpLeg": "Hips", "RightLeg": "RightUpLeg",
46
- "RightFoot": "RightLeg", "RightToeBase": "RightFoot",
47
- "LeftUpLeg": "Hips", "LeftLeg": "LeftUpLeg",
48
- "LeftFoot": "LeftLeg", "LeftToeBase": "LeftFoot",
49
- };
50
-
51
- /** Parent joint index per cskel27 index; the root (Hips) is null. */
52
- export const CSKEL27_PARENTS = CSKEL27_JOINTS.map(
53
- (name) => (PARENT_BY_NAME[name] === null ? null : JOINT_INDEX[PARENT_BY_NAME[name]])
54
- );
55
-
56
- /** The joints CozyClay edits (src/poses.js POSE_BONES), as cskel27 names.
57
- * POSE_BONES' Mixamo Spine2 has no entry here: cskel27's "Spine2" is already
58
- * fed by Mixamo Spine1 (COZYCLAY_TO_CSKEL27), so wiring it would need a
59
- * Spine3 mapping — until then its rotation stays editor-side and does not
60
- * reach the ARDY wire pose. */
61
- export const COZYCLAY_BONES = [
62
- "Hips", "Spine", "Spine1", "Neck", "Head",
63
- "LeftShoulder", "RightShoulder", "LeftArm", "RightArm",
64
- "LeftForeArm", "RightForeArm", "LeftHand", "RightHand",
65
- "LeftUpLeg", "RightUpLeg", "LeftLeg", "RightLeg",
66
- "LeftFoot", "RightFoot",
67
- ];
68
-
69
- /** CozyClay/Mixamo bone name -> playback-equivalent cskel27 joint index.
70
- * Core has one more torso segment, so its first animated spine joint is
71
- * Spine1 and the Mixamo chest lands on Spine2. */
72
- export const COZYCLAY_TO_CSKEL27 = Object.fromEntries(
73
- COZYCLAY_BONES.map((name) => [
74
- name,
75
- JOINT_INDEX[name === "Spine" ? "Spine1" : name === "Spine1" ? "Spine2" : name],
76
- ])
77
- );