cozyclay 2.1.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (585) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +12 -30
  3. package/bin/agent/agent-routes.mjs +43 -116
  4. package/bin/agent/agent-runner.mjs +14 -15
  5. package/bin/agent/cliproxy-provider.mjs +135 -0
  6. package/bin/agent/credential-store.mjs +30 -7
  7. package/bin/agent/pi-tools.mjs +4 -1
  8. package/bin/agent/provider-keys.mjs +32 -0
  9. package/bin/agent/provider-login.mjs +110 -0
  10. package/bin/agent/provider-routes.mjs +99 -0
  11. package/bin/agent/providers.mjs +19 -97
  12. package/bin/agent/script-tool.mjs +17 -4
  13. package/bin/agent/session-store.mjs +2 -2
  14. package/bin/agent/studio-context-budget.mjs +93 -0
  15. package/bin/agent/studio-motion-reference.mjs +23 -0
  16. package/bin/agent/studio-prompt.mjs +1 -1
  17. package/bin/agent/studio-rebase-text.mjs +32 -0
  18. package/bin/agent/studio-rebase.mjs +26 -39
  19. package/bin/agent/studio-tools.mjs +9 -28
  20. package/bin/agent/tool-arguments.mjs +49 -0
  21. package/bin/agent/turn-frames.mjs +66 -0
  22. package/bin/codex-auth.mjs +9 -2
  23. package/bin/cozyclay.mjs +10 -116
  24. package/bin/live/cli.mjs +3 -3
  25. package/bin/mcp-runtime.mjs +2 -12
  26. package/bin/package-signature.mjs +0 -4
  27. package/dist/app/index.html +7 -6
  28. package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
  29. package/dist/assets/analytics-BWCqdgWA.js +1 -0
  30. package/dist/assets/app-DfTCxaKk.js +5087 -0
  31. package/dist/assets/app-f-fkV5uP.css +1 -0
  32. package/dist/assets/compile-worker-BxKXh07s.js +5 -0
  33. package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
  34. package/dist/assets/{first-shot-handoff-msLI71g1.js → first-shot-handoff-DNO8kv_N.js} +1 -1
  35. package/dist/assets/{landing-ChUvB_zL.js → landing-yfZaJkWc.js} +1 -1
  36. package/dist/assets/scene-asset-sync-U3kS2rvK.js +20 -0
  37. package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
  38. package/dist/assets/workflow-D78eiKTa.js +179 -0
  39. package/dist/cozyclay-package.json +1 -1
  40. package/dist/index.html +3 -3
  41. package/dist/sw.js +3 -6
  42. package/dist/workflow/index.html +5 -4
  43. package/mcp/LIVE-PROTOCOL.md +7 -47
  44. package/mcp/README.md +16 -26
  45. package/mcp/live-hub.mjs +6 -10
  46. package/mcp/package.json +1 -3
  47. package/mcp/tool-handlers.mjs +4 -168
  48. package/package.json +3 -22
  49. package/src/App.jsx +151 -2625
  50. package/src/agent-progress.js +80 -0
  51. package/src/agent-turn-mark.js +30 -0
  52. package/src/analytics.js +1 -19
  53. package/src/app-context.js +12 -2
  54. package/src/app-stage.jsx +2 -34
  55. package/src/asset-pane.jsx +6 -5
  56. package/src/camera-block.js +21 -0
  57. package/src/camera-direction.js +120 -0
  58. package/src/character-kind.js +3 -9
  59. package/src/command-bus.js +10 -8
  60. package/src/commands/cast.js +5 -34
  61. package/src/commands/elements/character.js +1 -1
  62. package/src/commands/elements/motion.js +1 -6
  63. package/src/commands/elements/object.js +6 -2
  64. package/src/commands/elements/shot.js +4 -1
  65. package/src/commands/elements.js +38 -14
  66. package/src/commands/index.js +3 -1
  67. package/src/commands/kits.js +37 -0
  68. package/src/commands/motion-timing.js +57 -0
  69. package/src/commands/motion.js +9 -152
  70. package/src/commands/motion3-compile.js +65 -0
  71. package/src/commands/motion3.js +214 -0
  72. package/src/commands/objects.js +6 -4
  73. package/src/commands/shot.js +55 -13
  74. package/src/commands/stage.js +14 -1
  75. package/src/commands/view.js +4 -1
  76. package/src/document-mirrors.js +42 -0
  77. package/src/document-store.js +4 -0
  78. package/src/domains/cast.js +19 -194
  79. package/src/domains/motion/motion-range-pin-rules.js +1 -1
  80. package/src/domains/motion/take-source.js +53 -0
  81. package/src/domains/motion.js +60 -1838
  82. package/src/domains/scenes.js +12 -55
  83. package/src/domains/shots.js +2 -2
  84. package/src/domains/stage.js +4 -2
  85. package/src/draft-ghost.js +47 -0
  86. package/src/draft-ghost.jsx +129 -0
  87. package/src/dualview.jsx +4 -3
  88. package/src/effects/EffectsLayer.jsx +112 -0
  89. package/src/effects/effect-meshes.js +232 -0
  90. package/src/effects/effect-record.js +103 -0
  91. package/src/effects/emitter.js +59 -0
  92. package/src/effects/simulate.js +261 -0
  93. package/src/effects/state.js +59 -0
  94. package/src/execution-telemetry.js +2 -3
  95. package/src/first-success-guide.jsx +5 -5
  96. package/src/ghost-set.js +257 -0
  97. package/src/held-object-edit.jsx +113 -0
  98. package/src/held-object-pose.js +175 -0
  99. package/src/hierarchy-model.js +1 -1
  100. package/src/hierarchy-panel.jsx +1 -1
  101. package/src/imported-mesh.jsx +103 -0
  102. package/src/kits/held.js +84 -0
  103. package/src/kits/index.js +70 -0
  104. package/src/kits/smoking.js +57 -0
  105. package/src/light-blockers.js +93 -0
  106. package/src/motion/beat-board-model.js +84 -0
  107. package/src/motion/beat-board.css +124 -0
  108. package/src/motion/beat-board.jsx +60 -0
  109. package/src/motion/center-of-mass.js +66 -0
  110. package/src/motion/fix-collisions.js +850 -0
  111. package/src/motion/physics-review.js +118 -0
  112. package/src/{ardy → motion}/physics-support.js +1 -76
  113. package/src/motion/rig-snapshot.js +22 -0
  114. package/src/motion/take-segments.jsx +140 -0
  115. package/src/{ardy → motion}/timeline-coordinates.js +0 -21
  116. package/src/{ardy → motion}/timeline.css +1 -2
  117. package/src/{ardy → motion}/timeline.jsx +42 -413
  118. package/src/motion/waypoints.js +76 -0
  119. package/src/motion3/beats.js +83 -0
  120. package/src/motion3/body.js +158 -0
  121. package/src/motion3/bones.js +47 -0
  122. package/src/motion3/carried.js +47 -0
  123. package/src/motion3/compile-job.js +79 -0
  124. package/src/motion3/compile-worker.js +10 -0
  125. package/src/motion3/compiler/anchors.js +113 -0
  126. package/src/motion3/compiler/arm-orient.js +128 -0
  127. package/src/motion3/compiler/channels.js +125 -0
  128. package/src/motion3/compiler/compile.js +205 -0
  129. package/src/motion3/compiler/gait-rhythm.js +97 -0
  130. package/src/motion3/compiler/grip.js +171 -0
  131. package/src/motion3/compiler/head-steady.js +48 -0
  132. package/src/motion3/compiler/hold.js +134 -0
  133. package/src/motion3/compiler/idle.js +113 -0
  134. package/src/motion3/compiler/limbs.js +197 -0
  135. package/src/motion3/compiler/math.js +72 -0
  136. package/src/motion3/compiler/pose.js +177 -0
  137. package/src/motion3/compiler/quat.js +49 -0
  138. package/src/motion3/compiler/skeleton.js +74 -0
  139. package/src/motion3/compiler/validate-common.js +32 -0
  140. package/src/motion3/compiler/validate-goals.js +118 -0
  141. package/src/motion3/compiler/validate-objects.js +144 -0
  142. package/src/motion3/compiler/validate-parts.js +118 -0
  143. package/src/motion3/compiler/validate.js +122 -0
  144. package/src/motion3/compiler/vocab.js +74 -0
  145. package/src/motion3/compiler/walk-pelvis.js +275 -0
  146. package/src/motion3/compiler/walk.js +207 -0
  147. package/src/motion3/compiler/wrist-clamp.js +32 -0
  148. package/src/motion3/delta.js +47 -0
  149. package/src/motion3/describe.js +177 -0
  150. package/src/motion3/docs.js +27 -0
  151. package/src/motion3/edit-carry.js +21 -0
  152. package/src/motion3/fix/ease.js +16 -0
  153. package/src/motion3/fix/ground.js +37 -0
  154. package/src/motion3/fix/index.js +52 -0
  155. package/src/motion3/fix/push.js +71 -0
  156. package/src/motion3/fix/reach.js +46 -0
  157. package/src/motion3/fix/retime.js +79 -0
  158. package/src/motion3/fix/self.js +211 -0
  159. package/src/motion3/fix/slide.js +70 -0
  160. package/src/motion3/fix/turn.js +51 -0
  161. package/src/motion3/follow.js +39 -0
  162. package/src/motion3/free-motion.js +204 -0
  163. package/src/motion3/grip-choice.js +130 -0
  164. package/src/motion3/hold-plan.js +157 -0
  165. package/src/motion3/json-patch.js +77 -0
  166. package/src/motion3/key-aim.js +105 -0
  167. package/src/motion3/key-edit.js +82 -0
  168. package/src/motion3/lenient.js +127 -0
  169. package/src/motion3/object-keys.js +236 -0
  170. package/src/motion3/object-pose.js +182 -0
  171. package/src/motion3/object-tracks.js +12 -0
  172. package/src/motion3/people.js +82 -0
  173. package/src/motion3/pipeline.js +102 -0
  174. package/src/motion3/playback.js +51 -0
  175. package/src/motion3/probes.js +91 -0
  176. package/src/motion3/qa/body-checks.js +34 -0
  177. package/src/motion3/qa/check-names.js +14 -0
  178. package/src/motion3/qa/checks.js +125 -0
  179. package/src/motion3/qa/contact-checks.js +51 -0
  180. package/src/motion3/qa/explain.js +80 -0
  181. package/src/motion3/qa/fmt.js +5 -0
  182. package/src/motion3/qa/foot-checks.js +72 -0
  183. package/src/motion3/qa/geometry.js +77 -0
  184. package/src/motion3/qa/goals.js +191 -0
  185. package/src/motion3/qa/ground.js +60 -0
  186. package/src/motion3/qa/hints-contact.js +195 -0
  187. package/src/motion3/qa/hints-goal.js +160 -0
  188. package/src/motion3/qa/hints-knee.js +24 -0
  189. package/src/motion3/qa/hints-motion.js +209 -0
  190. package/src/motion3/qa/hints-object.js +91 -0
  191. package/src/motion3/qa/index.js +44 -0
  192. package/src/motion3/qa/key-checks.js +82 -0
  193. package/src/motion3/qa/near.js +96 -0
  194. package/src/motion3/qa/object-checks.js +135 -0
  195. package/src/motion3/qa/patch.js +161 -0
  196. package/src/motion3/qa/people-checks.js +37 -0
  197. package/src/motion3/qa/severity.js +38 -0
  198. package/src/motion3/qa/spec-checks.js +65 -0
  199. package/src/motion3/qa/style.js +228 -0
  200. package/src/motion3/qa/wrist-checks.js +69 -0
  201. package/src/motion3/qa/wrist-obs.js +60 -0
  202. package/src/motion3/refs.js +129 -0
  203. package/src/motion3/repair-tune.js +121 -0
  204. package/src/motion3/repair.js +83 -0
  205. package/src/motion3/report.js +67 -0
  206. package/src/motion3/rigs/index.js +14 -0
  207. package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
  208. package/src/motion3/rigs/x-bot-tpose.json +1 -0
  209. package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
  210. package/src/motion3/rigs/y-bot-tpose.json +1 -0
  211. package/src/motion3/scene.js +60 -0
  212. package/src/motion3/schema/brief.js +89 -0
  213. package/src/motion3/schema/fields.js +44 -0
  214. package/src/motion3/schema/spec-examples.js +46 -0
  215. package/src/motion3/schema/topics.js +113 -0
  216. package/src/motion3/schema/types.js +149 -0
  217. package/src/motion3/search.js +117 -0
  218. package/src/motion3/second-hand.js +112 -0
  219. package/src/motion3/settle.js +136 -0
  220. package/src/motion3/skills/basic.js +83 -0
  221. package/src/motion3/skills/book.js +76 -0
  222. package/src/motion3/skills/car.js +145 -0
  223. package/src/motion3/skills/flip.js +200 -0
  224. package/src/motion3/skills/frames-auto.js +29 -0
  225. package/src/motion3/skills/impact.js +109 -0
  226. package/src/motion3/skills/index.js +85 -0
  227. package/src/motion3/skills/info.js +80 -0
  228. package/src/motion3/skills/smoke-kit.js +109 -0
  229. package/src/motion3/skills/smoke.js +160 -0
  230. package/src/motion3/spec-store.js +59 -0
  231. package/src/motion3/take-edit.js +155 -0
  232. package/src/motion3/take.js +63 -0
  233. package/src/motion3/timeline.js +127 -0
  234. package/src/motion3/views.js +121 -0
  235. package/src/motion3/walk-plan.js +119 -0
  236. package/src/object-catalog.jsx +7 -1
  237. package/src/object-colors.js +98 -0
  238. package/src/object-gizmo-parts.js +115 -0
  239. package/src/object-gizmo.jsx +37 -122
  240. package/src/object-glow.js +139 -0
  241. package/src/object-hidden.js +33 -0
  242. package/src/object-look.js +196 -0
  243. package/src/object-size.js +10 -0
  244. package/src/object-travel.js +71 -6
  245. package/src/panels/CameraPanel.jsx +7 -7
  246. package/src/panels/HdrEnvironmentControls.jsx +59 -0
  247. package/src/panels/LightPanel.jsx +25 -4
  248. package/src/panels/ObjectLookPanel.jsx +88 -0
  249. package/src/panels/PosePanel.jsx +2 -17
  250. package/src/panels/RigControlPanel.jsx +5 -53
  251. package/src/panels/SubjectBox.jsx +4 -1
  252. package/src/panels/details.css +14 -0
  253. package/src/posestudio.jsx +4 -27
  254. package/src/project-browser.jsx +3 -4
  255. package/src/project-resources.js +18 -31
  256. package/src/project.js +13 -104
  257. package/src/props.jsx +25 -280
  258. package/src/qa-label.js +25 -0
  259. package/src/rail-dot-drag.js +23 -0
  260. package/src/render-passes.js +10 -0
  261. package/src/resource-status.jsx +1 -0
  262. package/src/result-modal.jsx +4 -19
  263. package/src/room.jsx +20 -12
  264. package/src/scene-assets.js +8 -6
  265. package/src/scene-light-place.js +72 -0
  266. package/src/scene-lights.jsx +148 -0
  267. package/src/scene-objects.js +31 -139
  268. package/src/scenes.js +15 -105
  269. package/src/semantic-edit.js +2 -5
  270. package/src/set-pieces.jsx +183 -0
  271. package/src/settings-menu.jsx +3 -11
  272. package/src/shell/BottomDock.jsx +9 -51
  273. package/src/shell/DetailsSlot.jsx +16 -200
  274. package/src/shell/GhostsMenuGroup.jsx +74 -0
  275. package/src/shell/LibrarySlot.jsx +1 -3
  276. package/src/shell/MenuBar.jsx +3 -3
  277. package/src/shell/PreferencesDialog.jsx +15 -264
  278. package/src/shell/PreferencesSlot.jsx +2 -8
  279. package/src/shell/TopBar.jsx +5 -84
  280. package/src/shell/ViewportToolbar.jsx +10 -70
  281. package/src/shell/agent-glass.css +19 -6
  282. package/src/shell/details-selection.js +42 -0
  283. package/src/shell/ghosts-menu.css +22 -0
  284. package/src/shell/glass-regions.css +29 -3
  285. package/src/shell/preferences.css +6 -1
  286. package/src/shot-authoring.js +4 -7
  287. package/src/soft-shadows.js +37 -0
  288. package/src/stage-attach-frames.js +12 -12
  289. package/src/stage-canvas-rigs.jsx +3 -3
  290. package/src/stage-capture.jsx +42 -8
  291. package/src/stage-characters.jsx +22 -216
  292. package/src/stage-editor-gizmos.jsx +6 -6
  293. package/src/stage-environment.js +93 -0
  294. package/src/stage-hdr-builtins.js +107 -0
  295. package/src/stage-hdr-image.js +116 -0
  296. package/src/stage-hdr-library.js +70 -0
  297. package/src/stage-hdr-map.js +94 -0
  298. package/src/stage-hdr.js +130 -0
  299. package/src/stage-lighting.js +149 -0
  300. package/src/stage-occlusion.js +210 -0
  301. package/src/stage-sky.jsx +159 -0
  302. package/src/stage-startup-defaults.js +5 -9
  303. package/src/studio-actions.js +16 -14
  304. package/src/studio-agent-commands.js +19 -16
  305. package/src/studio-agent-motion.js +9 -9
  306. package/src/studio-agent-protocol.js +47 -77
  307. package/src/studio-app-binding.js +27 -47
  308. package/src/studio-asset-list.js +17 -0
  309. package/src/studio-contact-sheet.js +37 -5
  310. package/src/studio-elements.js +27 -7
  311. package/src/studio-entity-bounds.js +18 -0
  312. package/src/studio-error-codes.js +15 -0
  313. package/src/studio-export-framing.js +152 -0
  314. package/src/studio-lighting-check.js +103 -0
  315. package/src/studio-motion-visual.js +150 -0
  316. package/src/studio-schema-errors.js +80 -0
  317. package/src/studio-support-gap.js +74 -0
  318. package/src/styles.css +1 -19
  319. package/src/timeline-defaults.js +5 -0
  320. package/src/timeline-extent.js +8 -20
  321. package/src/tutorial-walk.js +17 -0
  322. package/src/ui-scrub.js +1 -1
  323. package/src/use-shot-camera-tracks.js +12 -0
  324. package/src/view-ghosts.js +97 -0
  325. package/src/view-ghosts.jsx +49 -0
  326. package/src/workflow/AgentPanel.jsx +47 -166
  327. package/src/workflow/AgentProgressCard.jsx +109 -0
  328. package/src/workflow/AgentReplyText.jsx +37 -0
  329. package/src/workflow/AgentTurnSteps.jsx +84 -0
  330. package/src/workflow/LoginPanel.jsx +140 -0
  331. package/src/workflow/WorkflowBuilder.jsx +7 -23
  332. package/src/workflow/agent-client.js +54 -51
  333. package/src/workflow/agent-panel.css +71 -1
  334. package/src/workflow/agent-progress-card.css +167 -0
  335. package/src/workflow/agent-progress-view.js +47 -0
  336. package/src/workflow/agent-turn-steps.css +113 -0
  337. package/src/workflow/agent-turn.js +191 -0
  338. package/src/workflow/login-client.js +34 -0
  339. package/src/workflow/motion-input.js +18 -31
  340. package/src/workflow/node-schema.js +1 -1
  341. package/src/workflow/reply-markdown.js +69 -0
  342. package/src/workflow/scene-asset-sync.js +8 -8
  343. package/tools/agent-session-stats.mjs +61 -0
  344. package/tools/dev-full.mjs +5 -56
  345. package/tools/eslint-baseline.json +12 -13
  346. package/tools/knip-baseline.json +0 -179
  347. package/tools/loc-baseline.json +31 -81
  348. package/tools/motion3/extract-body.mjs +103 -0
  349. package/tools/motion3/extract-rig.mjs +85 -0
  350. package/tools/process-supervisor.mjs +0 -88
  351. package/tools/run-tests.mjs +9 -125
  352. package/bin/agent/motion-runtime.mjs +0 -76
  353. package/dist/ardy/cskel27-rest.json +0 -557
  354. package/dist/assets/analytics-C9pMpW7s.js +0 -1
  355. package/dist/assets/app-B_2XB9rw.css +0 -1
  356. package/dist/assets/app-DAuvKPP8.js +0 -4920
  357. package/dist/assets/config-Bx7pYsD9.js +0 -1
  358. package/dist/assets/config-DeoFTYzb.css +0 -1
  359. package/dist/assets/demo-CvKuBgy5.js +0 -1
  360. package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
  361. package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
  362. package/dist/assets/ticket-BPk2Ni95.js +0 -1
  363. package/dist/assets/workflow-jJRBR94Z.js +0 -179
  364. package/dist/demo/walk-then-stop.npz +0 -0
  365. package/mcp/ardy-prompts.mjs +0 -218
  366. package/src/ardy/auto-fix-panel.css +0 -108
  367. package/src/ardy/auto-physics.js +0 -1194
  368. package/src/ardy/client.js +0 -153
  369. package/src/ardy/convert.js +0 -313
  370. package/src/ardy/cskel27-neutral.js +0 -39
  371. package/src/ardy/cskel27.js +0 -77
  372. package/src/ardy/export.js +0 -165
  373. package/src/ardy/fix-collisions.js +0 -2257
  374. package/src/ardy/foot-lock.js +0 -230
  375. package/src/ardy/motion-calibration.js +0 -118
  376. package/src/ardy/motion-edit.js +0 -213
  377. package/src/ardy/motion-url.js +0 -55
  378. package/src/ardy/mp4-duration.js +0 -102
  379. package/src/ardy/npz.js +0 -595
  380. package/src/ardy/physics-panel.css +0 -21
  381. package/src/ardy/physics-panel.jsx +0 -89
  382. package/src/ardy/physics-refine.js +0 -111
  383. package/src/ardy/physics-review.js +0 -567
  384. package/src/ardy/physics-temporal.js +0 -54
  385. package/src/ardy/platform-fit-panel.css +0 -64
  386. package/src/ardy/platform-fit-panel.jsx +0 -41
  387. package/src/ardy/platform-fit.js +0 -326
  388. package/src/ardy/playback.js +0 -711
  389. package/src/ardy/pose-pin.js +0 -97
  390. package/src/ardy/prompt-clips.js +0 -30
  391. package/src/ardy/retime.js +0 -211
  392. package/src/ardy/root-drop.js +0 -369
  393. package/src/ardy/timeline-resize.js +0 -13
  394. package/src/ardy/to-cskel27.js +0 -225
  395. package/src/ardy/trim.js +0 -33
  396. package/src/ardy/waypoints.js +0 -369
  397. package/src/ardy-bridge-contract.js +0 -281
  398. package/src/domains/motion/motion-video-capture.js +0 -664
  399. package/src/i2v-motion-client.js +0 -77
  400. package/src/i2v-motion-studio.jsx +0 -180
  401. package/src/line-edit.js +0 -1348
  402. package/src/motion/generation.js +0 -105
  403. package/src/motion-readiness-ui.jsx +0 -67
  404. package/src/motion-readiness.js +0 -40
  405. package/src/motion-resources.js +0 -177
  406. package/src/motion-store.js +0 -65
  407. package/src/motion-trail.js +0 -601
  408. package/src/multimodel-ingest.js +0 -394
  409. package/src/panels/PromptBlocksPanel.jsx +0 -444
  410. package/src/panels/VideoCapturePanel.jsx +0 -181
  411. package/src/pose-extract/browser.js +0 -42
  412. package/src/pose-extract/detector.js +0 -100
  413. package/src/pose-extract/fit.js +0 -227
  414. package/src/pose-extract/image-frame.js +0 -51
  415. package/src/pose-extract/index.js +0 -58
  416. package/src/pose-extract/keyframes.js +0 -74
  417. package/src/pose-extract/landmarks.js +0 -162
  418. package/src/pose-extract/mirror.js +0 -153
  419. package/src/pose-extract/take.js +0 -131
  420. package/src/pose-extract/video-frames.js +0 -91
  421. package/src/take-recipe.js +0 -165
  422. package/src/trail-key-conflicts.js +0 -39
  423. package/src/trail-pick.js +0 -59
  424. package/src/use-i2v-capture-modal.js +0 -15
  425. package/tools/ardy/BRIDGE.md +0 -37
  426. package/tools/ardy/GVHMR-NPZ.md +0 -68
  427. package/tools/ardy/README.md +0 -124
  428. package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
  429. package/tools/ardy/artifacts.mjs +0 -34
  430. package/tools/ardy/bridge.mjs +0 -1732
  431. package/tools/ardy/bvh-cskel27.mjs +0 -1265
  432. package/tools/ardy/cclay_constrained_generate.py +0 -561
  433. package/tools/ardy/cclay_gvhmr_worker.py +0 -264
  434. package/tools/ardy/cclay_motion_edit.py +0 -510
  435. package/tools/ardy/cclay_sequence_generate.py +0 -705
  436. package/tools/ardy/cclay_worker.py +0 -304
  437. package/tools/ardy/dump-npz.py +0 -205
  438. package/tools/ardy/extract-rest.mjs +0 -299
  439. package/tools/ardy/extract.mjs +0 -507
  440. package/tools/ardy/footage.mjs +0 -467
  441. package/tools/ardy/gvhmr-floor.mjs +0 -102
  442. package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
  443. package/tools/ardy/gvhmr_fastpath.py +0 -168
  444. package/tools/ardy/gvhmr_trajectory.py +0 -240
  445. package/tools/ardy/merge-text-encoder.py +0 -160
  446. package/tools/ardy/mocap-metrics.mjs +0 -200
  447. package/tools/ardy/mocap-quality-gate.mjs +0 -110
  448. package/tools/ardy/motion-stabilize.mjs +0 -348
  449. package/tools/ardy/npz.mjs +0 -414
  450. package/tools/ardy/pose-to-npz.mjs +0 -106
  451. package/tools/ardy/prompt-limits.mjs +0 -5
  452. package/tools/ardy/run-edit-on-box.sh +0 -73
  453. package/tools/ardy/run-local.mjs +0 -233
  454. package/tools/ardy/run-on-box.sh +0 -593
  455. package/tools/ardy/run-sequence-on-box.sh +0 -177
  456. package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
  457. package/tools/ardy/runners/index.mjs +0 -18
  458. package/tools/ardy/runners/local.mjs +0 -455
  459. package/tools/ardy/runners/proc.mjs +0 -125
  460. package/tools/ardy/runners/remote.mjs +0 -252
  461. package/tools/ardy/setup-local.mjs +0 -189
  462. package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
  463. package/tools/ardy/setup-text-encoder.py +0 -306
  464. package/tools/ardy/smpl-cskel27.mjs +0 -178
  465. package/tools/ardy/visual-qa.mjs +0 -196
  466. package/tools/ardy/vq-car.mjs +0 -52
  467. package/tools/bench/EXP3.md +0 -61
  468. package/tools/bench/cclay_bench_extract_incam.py +0 -125
  469. package/tools/bench/cclay_bench_extract_obs.py +0 -204
  470. package/tools/bench/cclay_bench_runner.py +0 -42
  471. package/tools/bench/cube-contact.mjs +0 -162
  472. package/tools/bench/exp3.mjs +0 -152
  473. package/tools/bench/extract-bench-lib.mjs +0 -216
  474. package/tools/bench/extract-bench.mjs +0 -302
  475. package/tools/bench/fal-generate.mjs +0 -88
  476. package/tools/bench/fit/README.md +0 -189
  477. package/tools/bench/fit/camera.mjs +0 -59
  478. package/tools/bench/fit/contact.mjs +0 -419
  479. package/tools/bench/fit/footlock.mjs +0 -234
  480. package/tools/bench/fit/motion.mjs +0 -85
  481. package/tools/bench/fit/pin.mjs +0 -27
  482. package/tools/bench/fit/remote.mjs +0 -105
  483. package/tools/bench/fit-bench.mjs +0 -126
  484. package/tools/bench/fit-sanity.mjs +0 -45
  485. package/tools/bench/metrics.mjs +0 -313
  486. package/tools/bench/obs/depth.mjs +0 -258
  487. package/tools/bench/obs/extrinsics.mjs +0 -175
  488. package/tools/bench/obs/fit_mannequin_betas.py +0 -340
  489. package/tools/bench/obs/ground.mjs +0 -294
  490. package/tools/bench/obs/heading.mjs +0 -151
  491. package/tools/bench/obs/ladder.mjs +0 -555
  492. package/tools/bench/obs/mannequin-betas.json +0 -124
  493. package/tools/bench/obs/remote.mjs +0 -83
  494. package/tools/bench/obs/rest_joints.py +0 -52
  495. package/tools/bench/obs/ybot-targets.mjs +0 -49
  496. package/tools/bench/obs-bench.mjs +0 -520
  497. package/tools/bench/score.mjs +0 -343
  498. package/tools/bench/summarize.mjs +0 -86
  499. package/tools/demo-worker/README.md +0 -137
  500. package/tools/demo-worker/api-client.mjs +0 -233
  501. package/tools/demo-worker/generate.mjs +0 -301
  502. package/tools/demo-worker/index.mjs +0 -466
  503. package/tools/demo-worker/sign-core.mjs +0 -112
  504. package/tools/demo-worker/sign.mjs +0 -161
  505. package/tools/gt-render/browser.mjs +0 -182
  506. package/tools/gt-render/camera-math.mjs +0 -276
  507. package/tools/gt-render/page.mjs +0 -267
  508. package/tools/gt-render/render.mjs +0 -514
  509. package/tools/gt-render/scene-box.mjs +0 -31
  510. package/tools/gt-render/take-transform.mjs +0 -87
  511. package/tools/kimodo/compare-seam.mjs +0 -108
  512. package/tools/kimodo/constraints.mjs +0 -244
  513. package/tools/kimodo/edit.mjs +0 -259
  514. package/tools/kimodo/effector-constraints.mjs +0 -200
  515. package/tools/kimodo/generate.mjs +0 -646
  516. package/tools/kimodo/local-output.mjs +0 -265
  517. package/tools/kimodo/measure-pose.mjs +0 -65
  518. package/tools/kimodo/measure-preserve.mjs +0 -899
  519. package/tools/kimodo/measure-waypoints.mjs +0 -55
  520. package/tools/kimodo/mlx-generate.py +0 -111
  521. package/tools/kimodo/pose-constraints.mjs +0 -248
  522. package/tools/kimodo/preserve-mask.mjs +0 -543
  523. package/tools/kimodo/read-npz.mjs +0 -189
  524. package/tools/kimodo/run-edit-on-box.mjs +0 -155
  525. package/tools/kimodo/run-sequence-on-box.mjs +0 -178
  526. package/tools/kimodo/runner.mjs +0 -284
  527. package/tools/kimodo/seam-batch.mjs +0 -77
  528. package/tools/kimodo/setup-local.mjs +0 -30
  529. package/tools/kimodo/setup-on-box.sh +0 -339
  530. package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
  531. package/tools/morphgs/assets/gen_truth.py +0 -39
  532. package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
  533. package/tools/morphgs/assets/playback-check.mjs +0 -30
  534. package/tools/morphgs/demo-gate.sh +0 -26
  535. package/tools/morphgs/fbx2morphgs.mjs +0 -68
  536. package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
  537. package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
  538. package/tools/morphgs/setup-on-cluster.sh +0 -126
  539. package/tools/projflow/driver.py +0 -1069
  540. package/tools/projflow/generate.mjs +0 -805
  541. package/tools/projflow/hml22-to-cskel27.mjs +0 -735
  542. package/tools/projflow/line-edit-job.mjs +0 -547
  543. package/tools/projflow/replay.mjs +0 -452
  544. package/tools/projflow/runner.mjs +0 -269
  545. package/tools/projflow/service.mjs +0 -742
  546. package/tools/track/DESIGN.md +0 -513
  547. package/tools/track/backfill-provenance.mjs +0 -116
  548. package/tools/track/budget.mjs +0 -8
  549. package/tools/track/check-rig.mjs +0 -209
  550. package/tools/track/diagnostics.schema.json +0 -60
  551. package/tools/track/export-rig.mjs +0 -256
  552. package/tools/track/fallback.mjs +0 -7
  553. package/tools/track/fk-parity-fixture.mjs +0 -161
  554. package/tools/track/gate.mjs +0 -349
  555. package/tools/track/masks.mjs +0 -318
  556. package/tools/track/metrics.mjs +0 -201
  557. package/tools/track/publish-obs.mjs +0 -108
  558. package/tools/track/py/check_env.py +0 -61
  559. package/tools/track/py/eval_lr.py +0 -229
  560. package/tools/track/py/lr_viterbi.py +0 -294
  561. package/tools/track/py/masks.py +0 -405
  562. package/tools/track/py/objective.py +0 -382
  563. package/tools/track/py/rig.py +0 -508
  564. package/tools/track/py/scene.py +0 -326
  565. package/tools/track/py/test_joint_indices.py +0 -123
  566. package/tools/track/py/test_lr_viterbi.py +0 -195
  567. package/tools/track/py/test_masks.py +0 -229
  568. package/tools/track/py/test_rig.py +0 -288
  569. package/tools/track/py/test_scene.py +0 -354
  570. package/tools/track/py/test_track.py +0 -328
  571. package/tools/track/py/track.py +0 -411
  572. package/tools/track/remote.mjs +0 -140
  573. package/tools/track/rig-dump.mjs +0 -227
  574. package/tools/track/run-box-tests.mjs +0 -14
  575. package/tools/track/run-box.mjs +0 -168
  576. package/tools/track/setup-box.sh +0 -59
  577. package/tools/track/study-2d.mjs +0 -728
  578. /package/src/{ardy → motion}/collision-blockers.js +0 -0
  579. /package/src/{ardy → motion}/ground.js +0 -0
  580. /package/src/{ardy → motion}/ik-drag.js +0 -0
  581. /package/src/{ardy → motion}/ik-key-json.js +0 -0
  582. /package/src/{ardy → motion}/ik.js +0 -0
  583. /package/src/{ardy → motion}/physics-surface.js +0 -0
  584. /package/src/{ardy → motion}/playback-clock.js +0 -0
  585. /package/src/{ardy → motion}/range-pin.js +0 -0
@@ -1,339 +0,0 @@
1
- #!/usr/bin/env bash
2
- # Provision the best-supported Kimodo runtime for the host this script runs on.
3
- # Run directly on the host, or through setup-local.mjs (which pipes it over ssh).
4
- #
5
- # The installer is a router: it detects OS / architecture / RAM / CUDA and
6
- # installs one of four backends, best first:
7
- #
8
- # kimodo-mlx macOS arm64 with > 32 GB RAM — MLX/Metal port with the
9
- # 15 GB LLM2Vec encoder resident in unified memory
10
- # (measured 0.93 s warm E2E vs 37 s kimodo.cpp Metal on an
11
- # M4 Max 64 GB; see NomaDamas/kimodo-mlx README benchmarks).
12
- # kimodo.cpp-metal macOS arm64 with <= 32 GB RAM — GGML build streaming
13
- # transformer layers from disk; residency is the wrong
14
- # trade when the encoder cannot stay in memory.
15
- # nvidia-cuda Linux with a working NVIDIA GPU — the upstream PyTorch
16
- # Kimodo stack (nv-tlabs/kimodo), fully CUDA accelerated.
17
- # kimodo.cpp-cpu any other Unix — GGML CPU build, Vulkan when available.
18
- #
19
- # Detection can be overridden for tests and dry-runs:
20
- # CCLAY_KIMODO_DETECT_OS, CCLAY_KIMODO_DETECT_ARCH,
21
- # CCLAY_KIMODO_DETECT_RAM_GB, CCLAY_KIMODO_DETECT_CUDA (0|1)
22
- # The route itself is overridden with --backend or CCLAY_KIMODO_BACKEND.
23
- set -euo pipefail
24
-
25
- KIMODO_DIR="${CCLAY_KIMODO_REMOTE_DIR:-$HOME/.cozyclay/kimodo}"
26
- VENV_DIR="${CCLAY_KIMODO_VENV_DIR:-$HOME/.cozyclay/kimodo-venv}"
27
- MLX_DIR="${CCLAY_KIMODO_MLX_DIR:-$HOME/.cozyclay/kimodo-mlx}"
28
- MLX_VENV_DIR="${CCLAY_KIMODO_MLX_VENV_DIR:-$HOME/.cozyclay/kimodo-mlx-venv}"
29
- CPP_DIR="${CCLAY_KIMODO_CPP_DIR:-$HOME/.cozyclay/kimodo.cpp}"
30
- CPP_VENV_DIR="${CCLAY_KIMODO_CPP_VENV_DIR:-$HOME/.cozyclay/kimodo-cpp-venv}"
31
- # kimodo.cpp ref the Metal patch in NomaDamas/kimodo-mlx is known to apply to.
32
- CPP_METAL_REF="${CCLAY_KIMODO_CPP_METAL_REF:-568b0253}"
33
- MLX_MIN_RAM_GB="${CCLAY_KIMODO_MLX_MIN_RAM_GB:-32}"
34
- CPP_VULKAN="${CCLAY_KIMODO_CPP_VULKAN:-auto}"
35
- MODEL="${CCLAY_KIMODO_MODEL:-Kimodo-SOMA-RP-v1.1}"
36
- BACKEND="${CCLAY_KIMODO_BACKEND:-auto}"
37
- DRY_RUN=0
38
-
39
- usage() {
40
- cat <<'EOF'
41
- Usage: setup-on-box.sh [--backend NAME] [--kimodo-dir DIR] [--venv DIR]
42
- [--model NAME] [--dry-run]
43
-
44
- Detects the host and installs the best-supported Kimodo backend:
45
- kimodo-mlx, kimodo.cpp-metal, nvidia-cuda, or kimodo.cpp-cpu.
46
- --backend (or CCLAY_KIMODO_BACKEND) forces a route; --dry-run prints the
47
- detected route and every command without changing the host.
48
- HF_TOKEN may be present in the environment for Hugging Face access; it is never
49
- printed by this script.
50
- EOF
51
- }
52
- log() { printf 'setup-kimodo: %s\n' "$*"; }
53
- die() { printf 'setup-kimodo: error: %s\n' "$*" >&2; exit 1; }
54
- run() {
55
- if [ "$DRY_RUN" -eq 1 ]; then printf '+ '; printf '%q ' "$@"; printf '\n'; return 0; fi
56
- "$@"
57
- }
58
-
59
- while [ "$#" -gt 0 ]; do
60
- case "$1" in
61
- --backend) [ "$#" -ge 2 ] || die "--backend needs a value"; BACKEND="$2"; shift 2 ;;
62
- --kimodo-dir) [ "$#" -ge 2 ] || die "--kimodo-dir needs a value"; KIMODO_DIR="$2"; shift 2 ;;
63
- --venv) [ "$#" -ge 2 ] || die "--venv needs a value"; VENV_DIR="$2"; shift 2 ;;
64
- --model) [ "$#" -ge 2 ] || die "--model needs a value"; MODEL="$2"; shift 2 ;;
65
- --dry-run) DRY_RUN=1; shift ;;
66
- --help|-h) usage; exit 0 ;;
67
- *) die "unknown option: $1" ;;
68
- esac
69
- done
70
-
71
- # --- host detection -------------------------------------------------------
72
-
73
- detect_os() {
74
- if [ -n "${CCLAY_KIMODO_DETECT_OS:-}" ]; then printf '%s' "$CCLAY_KIMODO_DETECT_OS"; else uname -s; fi
75
- }
76
- detect_arch() {
77
- if [ -n "${CCLAY_KIMODO_DETECT_ARCH:-}" ]; then printf '%s' "$CCLAY_KIMODO_DETECT_ARCH"; else uname -m; fi
78
- }
79
- detect_ram_gb() {
80
- if [ -n "${CCLAY_KIMODO_DETECT_RAM_GB:-}" ]; then printf '%s' "$CCLAY_KIMODO_DETECT_RAM_GB"; return; fi
81
- local bytes=""
82
- case "$(detect_os)" in
83
- Darwin) bytes=$(sysctl -n hw.memsize 2>/dev/null || true) ;;
84
- Linux) bytes=$(awk '/^MemTotal:/ {print $2 * 1024}' /proc/meminfo 2>/dev/null || true) ;;
85
- esac
86
- [ -n "$bytes" ] || { printf '0'; return; }
87
- printf '%s' $(( bytes / 1073741824 ))
88
- }
89
- detect_cuda() {
90
- if [ -n "${CCLAY_KIMODO_DETECT_CUDA:-}" ]; then printf '%s' "$CCLAY_KIMODO_DETECT_CUDA"; return; fi
91
- if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then printf '1'; else printf '0'; fi
92
- }
93
-
94
- route_backend() {
95
- case "$BACKEND" in
96
- auto) ;;
97
- kimodo-mlx|kimodo.cpp-metal|nvidia-cuda|kimodo.cpp-cpu) printf '%s' "$BACKEND"; return ;;
98
- *) die "unknown backend: $BACKEND (expected kimodo-mlx, kimodo.cpp-metal, nvidia-cuda, kimodo.cpp-cpu, or auto)" ;;
99
- esac
100
- local os arch ram cuda
101
- os=$(detect_os); arch=$(detect_arch); ram=$(detect_ram_gb); cuda=$(detect_cuda)
102
- case "$os" in
103
- Darwin)
104
- case "$arch" in
105
- arm64)
106
- # > 32 GB keeps the 15 GB encoder resident; at or below it, stream.
107
- if [ "$ram" -gt "$MLX_MIN_RAM_GB" ]; then printf 'kimodo-mlx'; else printf 'kimodo.cpp-metal'; fi
108
- ;;
109
- *) printf 'kimodo.cpp-cpu' ;;
110
- esac
111
- ;;
112
- Linux)
113
- if [ "$cuda" = "1" ]; then printf 'nvidia-cuda'; else printf 'kimodo.cpp-cpu'; fi
114
- ;;
115
- *) die "unsupported OS: $os (use --backend to force a route, or run inside WSL on Windows)" ;;
116
- esac
117
- }
118
-
119
- OS=$(detect_os); ARCH=$(detect_arch); RAM_GB=$(detect_ram_gb); CUDA=$(detect_cuda)
120
- BACKEND=$(route_backend)
121
-
122
- if [ "$DRY_RUN" -eq 1 ]; then
123
- log "dry run; no files, packages, or models will be changed"
124
- fi
125
- log "detected: os=$OS arch=$ARCH ram=${RAM_GB}GB cuda=$CUDA"
126
- log "backend=$BACKEND"
127
-
128
- # --- backends ---------------------------------------------------------------
129
-
130
- install_nvidia_cuda() {
131
- if [ "$DRY_RUN" -ne 1 ]; then
132
- command -v git >/dev/null 2>&1 || die "git is required"
133
- command -v python3 >/dev/null 2>&1 || die "python3 is required"
134
- command -v nvidia-smi >/dev/null 2>&1 || die "an NVIDIA CUDA host is required (nvidia-smi not found)"
135
- nvidia-smi >/dev/null 2>&1 || die "nvidia-smi cannot access the GPU"
136
- fi
137
-
138
- if [ ! -e "$KIMODO_DIR/.git" ]; then
139
- mkdir -p "$(dirname "$KIMODO_DIR")"
140
- run git clone --depth 1 https://github.com/nv-tlabs/kimodo.git "$KIMODO_DIR"
141
- else
142
- log "Kimodo checkout already exists at $KIMODO_DIR"
143
- fi
144
-
145
- if [ ! -x "$VENV_DIR/bin/python" ]; then
146
- run python3 -m venv "$VENV_DIR"
147
- else
148
- log "Python environment already exists at $VENV_DIR"
149
- fi
150
-
151
- PY="$VENV_DIR/bin/python"
152
- run "$PY" -m pip install --upgrade pip
153
- run "$PY" -m pip install torch
154
- run "$PY" -m pip install -e "$KIMODO_DIR" llm2vec
155
-
156
- if [ "$DRY_RUN" -eq 1 ]; then
157
- log "would prefetch model $MODEL and LLM2Vec encoder assets"
158
- else
159
- "$PY" - "$MODEL" <<'PY'
160
- import sys
161
- from huggingface_hub import snapshot_download
162
- model = sys.argv[1]
163
- snapshot_download(repo_id=f"nvidia/{model}")
164
- snapshot_download(repo_id="meta-llama/Meta-Llama-3-8B-Instruct")
165
- snapshot_download(repo_id="McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp")
166
- snapshot_download(repo_id="McGill-NLP/LLM2Vec-Meta-Llama-3-8B-Instruct-mntp-supervised")
167
- print("model and encoder assets ready")
168
- PY
169
- fi
170
-
171
- if [ "$VENV_DIR" != "$KIMODO_DIR/.venv" ]; then
172
- if [ "$DRY_RUN" -eq 1 ]; then
173
- log "would link $KIMODO_DIR/.venv -> $VENV_DIR"
174
- else
175
- ln -sfn "$VENV_DIR" "$KIMODO_DIR/.venv"
176
- fi
177
- fi
178
-
179
- log "export CCLAY_MOTION_BACKEND=kimodo"
180
- log "export CCLAY_KIMODO_HOST=<this host>"
181
- log "export CCLAY_KIMODO_REPO=$KIMODO_DIR (venv available at $KIMODO_DIR/.venv)"
182
- log "Kimodo model: $MODEL"
183
- }
184
-
185
- install_kimodo_mlx() {
186
- if [ "$DRY_RUN" -ne 1 ]; then
187
- command -v git >/dev/null 2>&1 || die "git is required"
188
- command -v python3 >/dev/null 2>&1 || die "python3 is required"
189
- fi
190
-
191
- if [ ! -e "$MLX_DIR/.git" ]; then
192
- mkdir -p "$(dirname "$MLX_DIR")"
193
- run git clone --depth 1 https://github.com/NomaDamas/kimodo-mlx.git "$MLX_DIR"
194
- else
195
- log "kimodo-mlx checkout already exists at $MLX_DIR"
196
- fi
197
-
198
- if [ ! -x "$MLX_VENV_DIR/bin/python" ]; then
199
- if command -v uv >/dev/null 2>&1; then
200
- run uv venv --python 3.12 "$MLX_VENV_DIR"
201
- else
202
- run python3 -m venv "$MLX_VENV_DIR"
203
- fi
204
- else
205
- log "Python environment already exists at $MLX_VENV_DIR"
206
- fi
207
-
208
- PY="$MLX_VENV_DIR/bin/python"
209
- HF="$MLX_VENV_DIR/bin/hf"
210
- run "$PY" -m pip install --upgrade pip
211
- run "$PY" -m pip install -e "$MLX_DIR" huggingface_hub
212
-
213
- run "$HF" download "nvidia/$MODEL" --local-dir "$MLX_DIR/models/$(printf '%s' "$MODEL" | sed 's/^Kimodo-/nvidia-/' | tr 'A-Z' 'a-z')"
214
- run "$HF" download LocalAI-io/Llama-3-Kimodo-GGML --local-dir "$MLX_DIR/models/llm2vec-text-bundle"
215
-
216
- if [ "$DRY_RUN" -eq 1 ]; then
217
- log "would run: $PY -m kimodo_mlx diagnose (expect mlx-metal)"
218
- log "would verify: $PY -m kimodo_mlx --help"
219
- else
220
- "$PY" -m kimodo_mlx diagnose || die "kimodo-mlx diagnose failed; see $MLX_DIR/README.md"
221
- "$PY" -m kimodo_mlx --help >/dev/null || die "kimodo-mlx CLI verification failed; see $MLX_DIR/README.md"
222
- fi
223
-
224
- log "kimodo-mlx ready: $PY -m kimodo_mlx generate --prompt \"walk forward\" --frames 30 --steps 10"
225
- }
226
-
227
- install_kimodo_cpp() {
228
- local accel="$1" # metal | cpu
229
- if [ "$DRY_RUN" -ne 1 ]; then
230
- command -v git >/dev/null 2>&1 || die "git is required"
231
- command -v cmake >/dev/null 2>&1 || die "cmake is required (CMake 3.25+)"
232
- command -v python3 >/dev/null 2>&1 || die "python3 is required"
233
- fi
234
-
235
- if [ ! -e "$CPP_DIR/.git" ]; then
236
- mkdir -p "$(dirname "$CPP_DIR")"
237
- run git clone --depth 1 https://github.com/localai-org/kimodo.cpp.git "$CPP_DIR"
238
- else
239
- log "kimodo.cpp checkout already exists at $CPP_DIR"
240
- fi
241
- run git -C "$CPP_DIR" submodule update --init --recursive
242
-
243
- local build_dir="$CPP_DIR/build-$accel"
244
- if [ "$accel" = "metal" ]; then
245
- # The GGML Metal wiring lives in a patch maintained with the kimodo-mlx
246
- # port; apply it onto the ref it was written against.
247
- if [ ! -e "$MLX_DIR/.git" ]; then
248
- mkdir -p "$(dirname "$MLX_DIR")"
249
- run git clone --depth 1 https://github.com/NomaDamas/kimodo-mlx.git "$MLX_DIR"
250
- fi
251
- run git -C "$CPP_DIR" fetch --depth 1 origin "$CPP_METAL_REF"
252
- run git -C "$CPP_DIR" checkout FETCH_HEAD
253
- if [ "$DRY_RUN" -eq 1 ]; then
254
- printf '+ '; printf '%q ' git -C "$CPP_DIR" apply "$MLX_DIR/patches/0001-kimodo-ggml-metal.patch"; printf '\n'
255
- else
256
- if git -C "$CPP_DIR" apply --check "$MLX_DIR/patches/0001-kimodo-ggml-metal.patch" 2>/dev/null; then
257
- git -C "$CPP_DIR" apply "$MLX_DIR/patches/0001-kimodo-ggml-metal.patch"
258
- elif git -C "$CPP_DIR" apply --check -R "$MLX_DIR/patches/0001-kimodo-ggml-metal.patch" 2>/dev/null; then
259
- log "Metal patch already applied; continuing"
260
- else
261
- die "Metal patch cannot be applied cleanly; see $CPP_DIR and $MLX_DIR/patches/0001-kimodo-ggml-metal.patch"
262
- fi
263
- fi
264
- run cmake -S "$CPP_DIR" -B "$build_dir" \
265
- -DKIMODO_ENABLE_VULKAN=OFF -DKIMODO_ENABLE_METAL=ON -DKIMODO_BUILD_TESTS=OFF
266
- else
267
- local vulkan="$CPP_VULKAN"
268
- if [ "$vulkan" = "auto" ]; then
269
- if pkg-config --exists vulkan 2>/dev/null || [ -f /usr/include/vulkan/vulkan.h ]; then
270
- vulkan=ON
271
- else
272
- vulkan=OFF
273
- fi
274
- fi
275
- log "kimodo.cpp CPU build: vulkan=$vulkan"
276
- run cmake -S "$CPP_DIR" -B "$build_dir" \
277
- -DKIMODO_ENABLE_VULKAN="$vulkan" -DKIMODO_BUILD_TESTS=OFF
278
- fi
279
- run cmake --build "$build_dir" --parallel
280
-
281
- local binary="$build_dir/kmd-generate"
282
- if [ "$DRY_RUN" -eq 1 ]; then
283
- log "would verify executable $binary"
284
- else
285
- [ -x "$binary" ] || die "kimodo.cpp build did not produce executable: $binary"
286
- log "verified kimodo.cpp executable: $binary"
287
- fi
288
-
289
- if [ "$accel" = "metal" ] && [ "$DRY_RUN" -ne 1 ]; then
290
- local metal_enabled=0
291
- if [ -f "$build_dir/CMakeCache.txt" ] && grep -Eq '^KIMODO_ENABLE_METAL(:BOOL)?=ON$' "$build_dir/CMakeCache.txt"; then
292
- metal_enabled=1
293
- else
294
- while IFS= read -r -d '' binary; do
295
- if command -v nm >/dev/null 2>&1 && nm "$binary" 2>/dev/null | grep -Eiq 'metal|ggml_metal'; then
296
- metal_enabled=1
297
- break
298
- fi
299
- done < <(find "$build_dir" -type f -perm -111 -print0 2>/dev/null)
300
- fi
301
- [ "$metal_enabled" -eq 1 ] || die "Metal build verification failed; KIMODO_ENABLE_METAL is not enabled"
302
- log "verified Metal build: KIMODO_ENABLE_METAL=ON"
303
- fi
304
-
305
- # GGUF weights come from the LocalAI-io org through the upstream script,
306
- # which needs the hf CLI; keep it in a small dedicated venv.
307
- if [ ! -x "$CPP_VENV_DIR/bin/hf" ]; then
308
- run python3 -m venv "$CPP_VENV_DIR"
309
- run "$CPP_VENV_DIR/bin/python" -m pip install --upgrade pip huggingface_hub
310
- fi
311
- local cpp_model
312
- cpp_model=$(printf '%s' "$MODEL" | sed 's/^Kimodo-//' | tr 'A-Z' 'a-z')
313
- run env "PATH=$CPP_VENV_DIR/bin:$PATH" bash "$CPP_DIR/scripts/download_gguf_weights.sh" \
314
- --output "$CPP_DIR" --model "$cpp_model"
315
-
316
- log "kimodo.cpp ($accel) ready: build at $build_dir, GGUF weights under $CPP_DIR"
317
- }
318
-
319
- case "$BACKEND" in
320
- nvidia-cuda) install_nvidia_cuda ;;
321
- kimodo-mlx) install_kimodo_mlx ;;
322
- kimodo.cpp-metal) install_kimodo_cpp metal ;;
323
- kimodo.cpp-cpu) install_kimodo_cpp cpu ;;
324
- esac
325
-
326
- # Tell the Studio runner exactly which installed route to use.
327
- if [ "$DRY_RUN" -eq 1 ]; then
328
- log "would write $HOME/.cozyclay/kimodo-backend.json"
329
- else
330
- mkdir -p "$HOME/.cozyclay"
331
- if [ "$BACKEND" = "kimodo-mlx" ]; then
332
- printf '{"backend":"%s","model":"%s","motion":"%s/models/nvidia-soma-rp-v1.1","text":"%s/models/llm2vec-text-bundle"}\n' "$BACKEND" "$MODEL" "$MLX_DIR" "$MLX_DIR" > "$HOME/.cozyclay/kimodo-backend.json"
333
- elif [ "$BACKEND" = "kimodo.cpp-metal" ] || [ "$BACKEND" = "kimodo.cpp-cpu" ]; then
334
- printf '{"backend":"%s","model":"%s","motion":"%s/models/kimodo-%s-f32.gguf","text":"%s/generated/llm2vec-text-bundle"}\n' "$BACKEND" "$MODEL" "$CPP_DIR" "$(printf '%s' "$MODEL" | sed 's/^Kimodo-//' | tr 'A-Z' 'a-z')" "$CPP_DIR" > "$HOME/.cozyclay/kimodo-backend.json"
335
- else
336
- printf '{"backend":"%s","model":"%s"}\n' "$BACKEND" "$MODEL" > "$HOME/.cozyclay/kimodo-backend.json"
337
- fi
338
- fi
339
- log "ready"
@@ -1,305 +0,0 @@
1
- /**
2
- * soma77-to-cskel27.mjs — Kimodo's somaskel77 motion npz → the exact motion
3
- * arrays the cclay npz encoder consumes ({ frames, fps, rotMats, rootPos,
4
- * posedJoints }), i.e. the same shape tools/ardy/bvh-cskel27.mjs produces.
5
- *
6
- * WHY GLOBAL ROTATIONS. cskel27 and somaskel77 do not share a spine
7
- * segmentation: cskel27 runs Hips→Spine→Spine1→Spine2→Spine3 (four segments
8
- * before the shoulder carrier) where somaskel77 runs Hips→Spine1→Spine2→Chest
9
- * (three), and somaskel77 splits the neck in two (Neck1→Neck2) where cskel27
10
- * has one. Re-deriving each cskel27 LOCAL from a per-joint global — exactly
11
- * the rule tools/ardy/bvh-cskel27.mjs states for the Mixamo case — makes that
12
- * mismatch a non-issue in both directions:
13
- *
14
- * - a source segment cskel27 lacks (Neck2) is absorbed into the child's
15
- * local, because local = parentGlobalᵀ · global composes whatever sits
16
- * between the two mapped joints. No rotation is lost.
17
- * - a cskel27 joint the source lacks (Spine2, the Hand ends) borrows its
18
- * nearest mapped ancestor's global, so its local comes out identity —
19
- * the same "not authored" rule poseToCskel27 and bvhToCskel27Motion use.
20
- *
21
- * Both skeletons rest in the same convention (Y-up, metres, standard T-pose:
22
- * Kimodo writes its NPZ against the canonical SOMA T-pose, and CSKEL27_NEUTRAL
23
- * is the cskel27 T-pose), so a somaskel77 global IS the cskel27 global for the
24
- * matching joint and no basis change is needed.
25
- *
26
- * POSITIONS ARE RE-GROWN, never copied: the take has to move CozyClay's body,
27
- * not drag Kimodo's per-model bone lengths into the scene. FK runs over the
28
- * canonical cskel27 skeleton and the root trajectory is scaled by the
29
- * leg-length ratio so stride length survives the reproportioning, then
30
- * floor-shifted so the clip's lowest foot sample touches Y=0.
31
- */
32
-
33
- import { CSKEL27_JOINTS, CSKEL27_PARENTS } from "../../src/ardy/cskel27.js";
34
- import { deriveBoneOffsets, forwardKinematics, matMul, matTranspose } from "../../src/ardy/convert.js";
35
- import { canonicalCskel27Reference } from "../../src/ardy/to-cskel27.js";
36
-
37
- /**
38
- * somaskel77 joint order, transcribed from the upstream skeleton definition
39
- * (`SOMASkeleton77.bone_order_names_with_parents` in ardy/skeleton/definitions.py,
40
- * identical in the Kimodo tree). Index here == joint index in the Kimodo npz
41
- * arrays. The standard-T-pose BVH in the Kimodo assets carries an extra `Root`
42
- * node ABOVE Hips that is a BVH-file artifact only — it is not part of the
43
- * joint arrays, so this list starts at Hips and is 77 long.
44
- */
45
- export const SOMA77_JOINTS = [
46
- "Hips", "Spine1", "Spine2", "Chest", "Neck1", "Neck2", "Head", "HeadEnd",
47
- "Jaw", "LeftEye", "RightEye",
48
- "LeftShoulder", "LeftArm", "LeftForeArm", "LeftHand",
49
- "LeftHandThumb1", "LeftHandThumb2", "LeftHandThumb3", "LeftHandThumbEnd",
50
- "LeftHandIndex1", "LeftHandIndex2", "LeftHandIndex3", "LeftHandIndex4", "LeftHandIndexEnd",
51
- "LeftHandMiddle1", "LeftHandMiddle2", "LeftHandMiddle3", "LeftHandMiddle4", "LeftHandMiddleEnd",
52
- "LeftHandRing1", "LeftHandRing2", "LeftHandRing3", "LeftHandRing4", "LeftHandRingEnd",
53
- "LeftHandPinky1", "LeftHandPinky2", "LeftHandPinky3", "LeftHandPinky4", "LeftHandPinkyEnd",
54
- "RightShoulder", "RightArm", "RightForeArm", "RightHand",
55
- "RightHandThumb1", "RightHandThumb2", "RightHandThumb3", "RightHandThumbEnd",
56
- "RightHandIndex1", "RightHandIndex2", "RightHandIndex3", "RightHandIndex4", "RightHandIndexEnd",
57
- "RightHandMiddle1", "RightHandMiddle2", "RightHandMiddle3", "RightHandMiddle4", "RightHandMiddleEnd",
58
- "RightHandRing1", "RightHandRing2", "RightHandRing3", "RightHandRing4", "RightHandRingEnd",
59
- "RightHandPinky1", "RightHandPinky2", "RightHandPinky3", "RightHandPinky4", "RightHandPinkyEnd",
60
- "LeftLeg", "LeftShin", "LeftFoot", "LeftToeBase", "LeftToeEnd",
61
- "RightLeg", "RightShin", "RightFoot", "RightToeBase", "RightToeEnd",
62
- ];
63
-
64
- /**
65
- * cskel27 joint name → the somaskel77 joint whose GLOBAL rotation drives it,
66
- * or null for "this joint is not authored by the source".
67
- *
68
- * The two anchors that fix the torso alignment are structural, not cosmetic:
69
- * Hips is the root in both, and cskel27's Spine3 carries the shoulders and the
70
- * neck exactly as somaskel77's Chest does — so Spine3↔Chest is forced. That
71
- * leaves three cskel27 links (Spine, Spine1, Spine2) spanning the two
72
- * somaskel77 links (Spine1, Spine2) between those anchors, so exactly one
73
- * cskel27 spine joint must go unauthored. Spine2 is the one chosen: mapping
74
- * from the bottom up keeps the lower spine — where the large trunk rotation
75
- * lives — driven by real data, and pushes the identity link to the top of the
76
- * chain where the residual Spine2→Chest rotation is absorbed into Spine3's
77
- * local anyway.
78
- *
79
- * NOTE ON THE LEGS: the names shift by one between the two skeletons.
80
- * somaskel77's LeftLeg is the THIGH (cskel27's LeftUpLeg) and its LeftShin is
81
- * the shank (cskel27's LeftLeg). Mapping these by identical name would silently
82
- * put the knee rotation on the hip.
83
- *
84
- * The hand ends stay unauthored, matching bvhToCskel27Motion: somaskel77's
85
- * nearest equivalents are finger roots, and borrowing one would splay the hand.
86
- */
87
- export const CSKEL27_FROM_SOMA77 = {
88
- Hips: "Hips",
89
- Spine: "Spine1",
90
- Spine1: "Spine2",
91
- Spine2: null,
92
- Spine3: "Chest",
93
- Neck: "Neck1",
94
- Head: "Head",
95
-
96
- RightShoulder: "RightShoulder",
97
- RightArm: "RightArm",
98
- RightForeArm: "RightForeArm",
99
- RightHand: "RightHand",
100
- RightHandEnd: null,
101
- RightHandThumb1: "RightHandThumb1",
102
-
103
- LeftShoulder: "LeftShoulder",
104
- LeftArm: "LeftArm",
105
- LeftForeArm: "LeftForeArm",
106
- LeftHand: "LeftHand",
107
- LeftHandEnd: null,
108
- LeftHandThumb1: "LeftHandThumb1",
109
-
110
- RightUpLeg: "RightLeg",
111
- RightLeg: "RightShin",
112
- RightFoot: "RightFoot",
113
- RightToeBase: "RightToeBase",
114
-
115
- LeftUpLeg: "LeftLeg",
116
- LeftLeg: "LeftShin",
117
- LeftFoot: "LeftFoot",
118
- LeftToeBase: "LeftToeBase",
119
- };
120
-
121
- const IDENTITY = [
122
- [1, 0, 0],
123
- [0, 1, 0],
124
- [0, 0, 1],
125
- ];
126
-
127
- /** cskel27 joints whose Y decides where the floor is. */
128
- const GROUND_JOINTS = ["LeftFoot", "LeftToeBase", "RightFoot", "RightToeBase"];
129
-
130
- /**
131
- * Per cskel27 joint, the somaskel77 index whose global rotation it takes.
132
- * An unmapped joint walks up the cskel27 parent chain to the nearest mapped
133
- * ancestor, which is what makes its local come out identity.
134
- */
135
- export function resolveSourceIndices(jointNames = SOMA77_JOINTS) {
136
- const sourceIndex = new Map(jointNames.map((name, index) => [name, index]));
137
- const missing = Object.values(CSKEL27_FROM_SOMA77).filter(
138
- (name) => name !== null && !sourceIndex.has(name)
139
- );
140
- if (missing.length) {
141
- throw new Error(`soma77ToCskel27Motion: source skeleton is missing ${missing.join(", ")}`);
142
- }
143
- const resolved = new Array(CSKEL27_JOINTS.length);
144
- for (let index = 0; index < CSKEL27_JOINTS.length; index += 1) {
145
- let cursor = index;
146
- let source = CSKEL27_FROM_SOMA77[CSKEL27_JOINTS[cursor]];
147
- while (source == null) {
148
- cursor = CSKEL27_PARENTS[cursor];
149
- if (cursor === null) {
150
- throw new Error(
151
- `soma77ToCskel27Motion: ${CSKEL27_JOINTS[index]} has no mapped ancestor`
152
- );
153
- }
154
- source = CSKEL27_FROM_SOMA77[CSKEL27_JOINTS[cursor]];
155
- }
156
- resolved[index] = sourceIndex.get(source);
157
- }
158
- return resolved;
159
- }
160
-
161
- function readMat(flat, base) {
162
- return [
163
- [flat[base], flat[base + 1], flat[base + 2]],
164
- [flat[base + 3], flat[base + 4], flat[base + 5]],
165
- [flat[base + 6], flat[base + 7], flat[base + 8]],
166
- ];
167
- }
168
-
169
- function chainLength(positions, indexByName, names) {
170
- let total = 0;
171
- for (let step = 1; step < names.length; step += 1) {
172
- const a = positions[indexByName.get(names[step - 1])];
173
- const b = positions[indexByName.get(names[step])];
174
- total += Math.hypot(b[0] - a[0], b[1] - a[1], b[2] - a[2]);
175
- }
176
- return total;
177
- }
178
-
179
- /**
180
- * @param {object} input
181
- * @param {number} input.frames
182
- * @param {number} input.fps
183
- * @param {Float32Array} input.globalRotMats Kimodo `global_rot_mats`, frames*J*9
184
- * @param {Float32Array} input.posedJoints Kimodo `posed_joints`, frames*J*3
185
- * @param {string[]} [input.jointNames] source joint order (default somaskel77)
186
- * @returns {{frames:number, fps:number, rotMats:Float32Array, rootPos:Float32Array, posedJoints:Float32Array}}
187
- */
188
- export function soma77ToCskel27Motion({ frames, fps, globalRotMats, posedJoints, jointNames = SOMA77_JOINTS }) {
189
- if (!Number.isInteger(frames) || frames < 1) {
190
- throw new Error("soma77ToCskel27Motion: frames must be a positive integer");
191
- }
192
- if (!Number.isInteger(fps) || fps < 1) {
193
- throw new Error("soma77ToCskel27Motion: fps must be a positive integer");
194
- }
195
- const jointCount = jointNames.length;
196
- if (globalRotMats.length !== frames * jointCount * 9) {
197
- throw new Error(
198
- `soma77ToCskel27Motion: globalRotMats must be ${frames * jointCount * 9} long, got ${globalRotMats.length}`
199
- );
200
- }
201
- if (posedJoints.length !== frames * jointCount * 3) {
202
- throw new Error(
203
- `soma77ToCskel27Motion: posedJoints must be ${frames * jointCount * 3} long, got ${posedJoints.length}`
204
- );
205
- }
206
-
207
- const sources = resolveSourceIndices(jointNames);
208
- const indexByName = new Map(jointNames.map((name, index) => [name, index]));
209
-
210
- // Canonical cskel27 proportions. The reference rests with identity locals,
211
- // so these offsets are the neutral skeleton's own bone vectors.
212
- const reference = canonicalCskel27Reference();
213
- const boneOffsets = deriveBoneOffsets(reference.posed_joints, reference.local_rot_mats);
214
-
215
- // Leg-length ratio, measured on the source's own first frame against the
216
- // canonical body, so a stride generated for Kimodo's proportions covers the
217
- // same fraction of a step on CozyClay's.
218
- const firstFrame = [];
219
- for (let joint = 0; joint < jointCount; joint += 1) {
220
- const base = joint * 3;
221
- firstFrame.push([posedJoints[base], posedJoints[base + 1], posedJoints[base + 2]]);
222
- }
223
- const sourceLeg = chainLength(firstFrame, indexByName, ["LeftLeg", "LeftShin", "LeftFoot"]);
224
- const canonicalIndex = new Map(CSKEL27_JOINTS.map((name, index) => [name, index]));
225
- const canonicalLeg = chainLength(reference.posed_joints, canonicalIndex, [
226
- "LeftUpLeg",
227
- "LeftLeg",
228
- "LeftFoot",
229
- ]);
230
- if (!(sourceLeg > 0)) {
231
- throw new Error("soma77ToCskel27Motion: source leg length measured as zero");
232
- }
233
- const rootScale = canonicalLeg / sourceLeg;
234
-
235
- const rotMats = new Float32Array(frames * 27 * 9);
236
- const rootPos = new Float32Array(frames * 3);
237
- const outPosed = new Float32Array(frames * 27 * 3);
238
-
239
- const hipsSource = indexByName.get("Hips");
240
- let floorY = Infinity;
241
-
242
- for (let frame = 0; frame < frames; frame += 1) {
243
- const rotBase = frame * jointCount * 9;
244
- const globals = new Array(27);
245
- for (let joint = 0; joint < 27; joint += 1) {
246
- globals[joint] = readMat(globalRotMats, rotBase + sources[joint] * 9);
247
- }
248
-
249
- const locals = new Array(27);
250
- for (let joint = 0; joint < 27; joint += 1) {
251
- const parent = CSKEL27_PARENTS[joint];
252
- locals[joint] =
253
- parent === null ? globals[joint].map((row) => row.slice()) : matMul(matTranspose(globals[parent]), globals[joint]);
254
- }
255
-
256
- const posBase = frame * jointCount * 3 + hipsSource * 3;
257
- const root = [
258
- posedJoints[posBase] * rootScale,
259
- posedJoints[posBase + 1] * rootScale,
260
- posedJoints[posBase + 2] * rootScale,
261
- ];
262
- const positions = forwardKinematics(locals, boneOffsets, root);
263
-
264
- for (const name of GROUND_JOINTS) {
265
- const y = positions[canonicalIndex.get(name)][1];
266
- if (y < floorY) floorY = y;
267
- }
268
-
269
- const outRotBase = frame * 27 * 9;
270
- for (let joint = 0; joint < 27; joint += 1) {
271
- const m = locals[joint];
272
- for (let row = 0; row < 3; row += 1) {
273
- for (let col = 0; col < 3; col += 1) {
274
- rotMats[outRotBase + joint * 3 * 3 + row * 3 + col] = m[row][col];
275
- }
276
- }
277
- }
278
- rootPos[frame * 3] = root[0];
279
- rootPos[frame * 3 + 1] = root[1];
280
- rootPos[frame * 3 + 2] = root[2];
281
- const outPosBase = frame * 27 * 3;
282
- for (let joint = 0; joint < 27; joint += 1) {
283
- outPosed[outPosBase + joint * 3] = positions[joint][0];
284
- outPosed[outPosBase + joint * 3 + 1] = positions[joint][1];
285
- outPosed[outPosBase + joint * 3 + 2] = positions[joint][2];
286
- }
287
- }
288
-
289
- // One rigid floor shift for the whole clip: per-frame grounding would
290
- // flatten the arc of a jump, which is exactly the motion this pipeline
291
- // exists to stage.
292
- if (Number.isFinite(floorY) && floorY !== 0) {
293
- for (let frame = 0; frame < frames; frame += 1) {
294
- rootPos[frame * 3 + 1] -= floorY;
295
- const outPosBase = frame * 27 * 3;
296
- for (let joint = 0; joint < 27; joint += 1) {
297
- outPosed[outPosBase + joint * 3 + 1] -= floorY;
298
- }
299
- }
300
- }
301
-
302
- return { frames, fps, rotMats, rootPos, posedJoints: outPosed };
303
- }
304
-
305
- export { IDENTITY as CSKEL27_IDENTITY };
@@ -1,39 +0,0 @@
1
- # Ground truth from MorphGS's own Animation.step: writes rot_params.npy + pred_joints.npy exactly like src/render.py:606-618.
2
- # usage: python gen_truth.py <MorphGS-root> <mesh.obj> <rig.txt> <outdir>
3
- import sys, os
4
- morphgs_root, mesh_path, rig_path, out = sys.argv[1:5]
5
- sys.path.insert(0, os.path.join(morphgs_root, "src"))
6
- import numpy as np, torch, trimesh
7
- from model.RigModel import Rig
8
- from model.AnimationField import Animation, get_embedder
9
-
10
- os.makedirs(out, exist_ok=True)
11
- mesh = trimesh.load_mesh(mesh_path, process=False, maintain_order=True)
12
- rig = Rig(mesh, rig_path, smooth_w=0, device="cpu", skinning_method="lbs")
13
- N = rig.joints_name; J = len(N); ix = N.index
14
- # Emulate MorphGS morphology (ParametricModel.get_joints_pos): legs +8%, arms -5%, same bone directions.
15
- scale = {n: 1.08 for n in N if "Leg" in n or "Foot" in n or "Toe" in n}
16
- scale.update({n: 0.95 for n in N if "Arm" in n or "Hand" in n})
17
- joints = rig.joints_pos.clone()
18
- for p, c in rig.bones: # bones are BFS-ordered from the root, parents first
19
- joints[c] = joints[p] + (rig.joints_pos[c] - rig.joints_pos[p]) * scale.get(N[c], 1.0)
20
- # Animation.__init__ hard-codes a CUDA deform net (AnimationField.py:83); step() with explicit rot_params never uses it.
21
- anim = Animation.__new__(Animation)
22
- anim.skinning_method, anim.embed_time_fn, anim.joint_num = "lbs", get_embedder(6, 1)[0], J
23
- fixed = rig.fixed_joint_indices
24
- torch.manual_seed(0)
25
- frames = []
26
- f1 = torch.zeros(J, 3) # the lead's spec
27
- f1[ix("LeftForeArm")] = torch.tensor([0, 0, np.pi / 2]); f1[ix("RightLeg")] = torch.tensor([np.pi / 3, 0, 0])
28
- f1[ix("Hips")] = torch.tensor([0, np.pi / 6, 0])
29
- frames += [(torch.zeros(J, 3), torch.zeros(3)), (f1, torch.tensor([0.3, 0.0, 0.2]))]
30
- for _ in range(4): # random full-body poses, every joint (fixed ones included -- step() must zero them)
31
- frames.append((torch.randn(J, 3) * 0.5, torch.randn(3) * 0.3))
32
- rps, pj = [], []
33
- for i, (rp, gt) in enumerate(frames):
34
- d = anim.step(rig.vertices, joints, rig.skinning_weights, rig, torch.tensor([i / len(frames)]),
35
- rot_params=rp.clone(), global_translation=gt, fixed_joints=fixed)
36
- rps.append(d["rot_params"].numpy()); pj.append(d["joints_warped"].numpy())
37
- np.save(f"{out}/rot_params.npy", np.stack(rps).astype(np.float32))
38
- np.save(f"{out}/pred_joints.npy", np.stack(pj).astype(np.float32))
39
- print(f"frames={len(frames)} J={J} fixed={[N[i] for i in fixed]} -> {out}")