cozyclay 2.1.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +65 -0
- package/README.md +12 -30
- package/bin/agent/agent-routes.mjs +40 -113
- package/bin/agent/agent-runner.mjs +9 -10
- package/bin/agent/cliproxy-provider.mjs +135 -0
- package/bin/agent/credential-store.mjs +30 -7
- package/bin/agent/pi-tools.mjs +4 -1
- package/bin/agent/provider-keys.mjs +32 -0
- package/bin/agent/provider-login.mjs +110 -0
- package/bin/agent/provider-routes.mjs +99 -0
- package/bin/agent/providers.mjs +19 -97
- package/bin/agent/script-tool.mjs +17 -4
- package/bin/agent/studio-motion-reference.mjs +23 -0
- package/bin/agent/studio-prompt.mjs +1 -1
- package/bin/agent/studio-rebase-text.mjs +32 -0
- package/bin/agent/studio-rebase.mjs +26 -39
- package/bin/agent/studio-tools.mjs +9 -28
- package/bin/agent/tool-arguments.mjs +49 -0
- package/bin/agent/turn-frames.mjs +66 -0
- package/bin/codex-auth.mjs +9 -2
- package/bin/cozyclay.mjs +10 -116
- package/bin/live/cli.mjs +22 -6
- package/bin/mcp-runtime.mjs +2 -12
- package/bin/package-signature.mjs +0 -4
- package/dist/app/index.html +7 -6
- package/dist/assets/EXRLoader-CvVIvGVE.js +1 -0
- package/dist/assets/analytics-C9sUnndd.js +1 -0
- package/dist/assets/app-CCh--1Hc.js +5087 -0
- package/dist/assets/app-f-fkV5uP.css +1 -0
- package/dist/assets/compile-worker-CkxiD6lH.js +5 -0
- package/dist/assets/fflate.module-KbGj5-H6.js +5 -0
- package/dist/assets/{first-shot-handoff-BlT33CGf.js → first-shot-handoff-CC4xe4HM.js} +1 -1
- package/dist/assets/{landing-BSesrCpL.js → landing-DjHD8u7k.js} +1 -1
- package/dist/assets/scene-asset-sync-Hx_FzdOH.js +20 -0
- package/dist/assets/scene-asset-sync-_S8NQl5B.css +1 -0
- package/dist/assets/workflow-C4yKH1p4.js +179 -0
- package/dist/cozyclay-package.json +1 -1
- package/dist/index.html +3 -3
- package/dist/llms.txt +14 -0
- package/dist/sw.js +3 -6
- package/dist/workflow/index.html +5 -4
- package/mcp/LIVE-PROTOCOL.md +7 -47
- package/mcp/README.md +16 -26
- package/mcp/live-hub.mjs +6 -10
- package/mcp/package.json +1 -3
- package/mcp/tool-handlers.mjs +4 -168
- package/package.json +3 -22
- package/src/App.jsx +174 -2639
- package/src/agent-progress.js +79 -0
- package/src/agent-turn-mark.js +30 -0
- package/src/analytics.js +1 -19
- package/src/app-context.js +5 -0
- package/src/app-stage.jsx +2 -34
- package/src/asset-pane.jsx +6 -5
- package/src/camera-block.js +21 -0
- package/src/camera-direction.js +120 -0
- package/src/character-kind.js +3 -9
- package/src/command-bus.js +8 -6
- package/src/commands/cast.js +5 -34
- package/src/commands/elements/character.js +1 -1
- package/src/commands/elements/motion.js +1 -6
- package/src/commands/elements/object.js +6 -2
- package/src/commands/elements/shot.js +4 -1
- package/src/commands/elements.js +38 -14
- package/src/commands/index.js +3 -1
- package/src/commands/kits.js +37 -0
- package/src/commands/motion-timing.js +57 -0
- package/src/commands/motion.js +9 -152
- package/src/commands/motion3-compile.js +65 -0
- package/src/commands/motion3.js +207 -0
- package/src/commands/objects.js +6 -4
- package/src/commands/shot.js +49 -11
- package/src/commands/stage.js +14 -1
- package/src/commands/view.js +4 -1
- package/src/document-mirrors.js +42 -0
- package/src/document-store.js +4 -0
- package/src/domains/cast.js +19 -194
- package/src/domains/motion/motion-range-pin-rules.js +1 -1
- package/src/domains/motion/take-source.js +51 -0
- package/src/domains/motion.js +60 -1838
- package/src/domains/scenes.js +12 -55
- package/src/domains/shots.js +2 -2
- package/src/domains/stage.js +4 -2
- package/src/draft-ghost.js +46 -0
- package/src/draft-ghost.jsx +129 -0
- package/src/dualview.jsx +4 -3
- package/src/effects/EffectsLayer.jsx +112 -0
- package/src/effects/effect-meshes.js +232 -0
- package/src/effects/effect-record.js +103 -0
- package/src/effects/emitter.js +59 -0
- package/src/effects/simulate.js +261 -0
- package/src/effects/state.js +59 -0
- package/src/execution-telemetry.js +2 -3
- package/src/first-success-guide.jsx +5 -5
- package/src/ghost-set.js +257 -0
- package/src/held-object-edit.jsx +113 -0
- package/src/held-object-pose.js +175 -0
- package/src/hierarchy-model.js +1 -1
- package/src/hierarchy-panel.jsx +1 -1
- package/src/imported-mesh.jsx +103 -0
- package/src/kits/held.js +84 -0
- package/src/kits/index.js +70 -0
- package/src/kits/smoking.js +57 -0
- package/src/light-blockers.js +93 -0
- package/src/motion/beat-board-model.js +84 -0
- package/src/motion/beat-board.css +124 -0
- package/src/motion/beat-board.jsx +59 -0
- package/src/motion/center-of-mass.js +66 -0
- package/src/motion/fix-collisions.js +850 -0
- package/src/motion/physics-review.js +118 -0
- package/src/{ardy → motion}/physics-support.js +1 -76
- package/src/motion/rig-snapshot.js +22 -0
- package/src/motion/take-segments.jsx +140 -0
- package/src/{ardy → motion}/timeline-coordinates.js +0 -21
- package/src/{ardy → motion}/timeline.css +1 -2
- package/src/{ardy → motion}/timeline.jsx +48 -419
- package/src/motion/waypoints.js +76 -0
- package/src/motion3/beats.js +83 -0
- package/src/motion3/body.js +158 -0
- package/src/motion3/bones.js +47 -0
- package/src/motion3/carried.js +47 -0
- package/src/motion3/compile-job.js +75 -0
- package/src/motion3/compile-worker.js +10 -0
- package/src/motion3/compiler/anchors.js +105 -0
- package/src/motion3/compiler/arm-orient.js +128 -0
- package/src/motion3/compiler/channels.js +125 -0
- package/src/motion3/compiler/compile.js +205 -0
- package/src/motion3/compiler/gait-rhythm.js +97 -0
- package/src/motion3/compiler/grip.js +171 -0
- package/src/motion3/compiler/head-steady.js +48 -0
- package/src/motion3/compiler/hold.js +134 -0
- package/src/motion3/compiler/idle.js +113 -0
- package/src/motion3/compiler/limbs.js +170 -0
- package/src/motion3/compiler/math.js +72 -0
- package/src/motion3/compiler/pose.js +162 -0
- package/src/motion3/compiler/quat.js +49 -0
- package/src/motion3/compiler/skeleton.js +74 -0
- package/src/motion3/compiler/validate-common.js +32 -0
- package/src/motion3/compiler/validate-goals.js +118 -0
- package/src/motion3/compiler/validate-objects.js +143 -0
- package/src/motion3/compiler/validate-parts.js +116 -0
- package/src/motion3/compiler/validate.js +122 -0
- package/src/motion3/compiler/vocab.js +73 -0
- package/src/motion3/compiler/walk-pelvis.js +275 -0
- package/src/motion3/compiler/walk.js +207 -0
- package/src/motion3/compiler/wrist-clamp.js +32 -0
- package/src/motion3/delta.js +47 -0
- package/src/motion3/describe.js +174 -0
- package/src/motion3/docs.js +27 -0
- package/src/motion3/edit-carry.js +21 -0
- package/src/motion3/fix/ease.js +16 -0
- package/src/motion3/fix/ground.js +37 -0
- package/src/motion3/fix/index.js +52 -0
- package/src/motion3/fix/push.js +71 -0
- package/src/motion3/fix/reach.js +46 -0
- package/src/motion3/fix/retime.js +79 -0
- package/src/motion3/fix/self.js +211 -0
- package/src/motion3/fix/slide.js +70 -0
- package/src/motion3/fix/turn.js +51 -0
- package/src/motion3/follow.js +39 -0
- package/src/motion3/free-motion.js +173 -0
- package/src/motion3/grip-choice.js +130 -0
- package/src/motion3/hold-plan.js +157 -0
- package/src/motion3/json-patch.js +77 -0
- package/src/motion3/key-aim.js +105 -0
- package/src/motion3/key-edit.js +82 -0
- package/src/motion3/lenient.js +127 -0
- package/src/motion3/object-keys.js +236 -0
- package/src/motion3/object-pose.js +182 -0
- package/src/motion3/object-tracks.js +12 -0
- package/src/motion3/pipeline.js +102 -0
- package/src/motion3/playback.js +51 -0
- package/src/motion3/probes.js +91 -0
- package/src/motion3/qa/body-checks.js +34 -0
- package/src/motion3/qa/check-names.js +14 -0
- package/src/motion3/qa/checks.js +121 -0
- package/src/motion3/qa/contact-checks.js +51 -0
- package/src/motion3/qa/explain.js +80 -0
- package/src/motion3/qa/fmt.js +5 -0
- package/src/motion3/qa/foot-checks.js +72 -0
- package/src/motion3/qa/geometry.js +77 -0
- package/src/motion3/qa/goals.js +191 -0
- package/src/motion3/qa/ground.js +60 -0
- package/src/motion3/qa/hints-contact.js +179 -0
- package/src/motion3/qa/hints-goal.js +160 -0
- package/src/motion3/qa/hints-knee.js +24 -0
- package/src/motion3/qa/hints-motion.js +209 -0
- package/src/motion3/qa/hints-object.js +91 -0
- package/src/motion3/qa/index.js +42 -0
- package/src/motion3/qa/key-checks.js +82 -0
- package/src/motion3/qa/near.js +96 -0
- package/src/motion3/qa/object-checks.js +135 -0
- package/src/motion3/qa/patch.js +161 -0
- package/src/motion3/qa/severity.js +38 -0
- package/src/motion3/qa/spec-checks.js +65 -0
- package/src/motion3/qa/style.js +218 -0
- package/src/motion3/qa/wrist-checks.js +69 -0
- package/src/motion3/qa/wrist-obs.js +60 -0
- package/src/motion3/refs.js +120 -0
- package/src/motion3/repair-tune.js +121 -0
- package/src/motion3/repair.js +83 -0
- package/src/motion3/report.js +67 -0
- package/src/motion3/rigs/index.js +14 -0
- package/src/motion3/rigs/x-bot-tpose-body.json +1 -0
- package/src/motion3/rigs/x-bot-tpose.json +1 -0
- package/src/motion3/rigs/y-bot-tpose-body.json +1 -0
- package/src/motion3/rigs/y-bot-tpose.json +1 -0
- package/src/motion3/scene.js +60 -0
- package/src/motion3/schema/brief.js +89 -0
- package/src/motion3/schema/fields.js +44 -0
- package/src/motion3/schema/spec-examples.js +46 -0
- package/src/motion3/schema/topics.js +111 -0
- package/src/motion3/schema/types.js +147 -0
- package/src/motion3/search.js +117 -0
- package/src/motion3/second-hand.js +112 -0
- package/src/motion3/skills/basic.js +82 -0
- package/src/motion3/skills/book.js +76 -0
- package/src/motion3/skills/car.js +145 -0
- package/src/motion3/skills/frames-auto.js +29 -0
- package/src/motion3/skills/index.js +83 -0
- package/src/motion3/skills/info.js +65 -0
- package/src/motion3/skills/smoke-kit.js +109 -0
- package/src/motion3/skills/smoke.js +160 -0
- package/src/motion3/spec-store.js +59 -0
- package/src/motion3/take-edit.js +155 -0
- package/src/motion3/take.js +63 -0
- package/src/motion3/timeline.js +127 -0
- package/src/motion3/views.js +121 -0
- package/src/motion3/walk-plan.js +119 -0
- package/src/object-catalog.jsx +7 -1
- package/src/object-colors.js +98 -0
- package/src/object-gizmo-parts.js +115 -0
- package/src/object-gizmo.jsx +37 -122
- package/src/object-glow.js +139 -0
- package/src/object-hidden.js +33 -0
- package/src/object-look.js +196 -0
- package/src/object-size.js +10 -0
- package/src/object-travel.js +71 -6
- package/src/panels/CameraPanel.jsx +7 -7
- package/src/panels/HdrEnvironmentControls.jsx +59 -0
- package/src/panels/LightPanel.jsx +25 -4
- package/src/panels/ObjectLookPanel.jsx +88 -0
- package/src/panels/PoseImagePanel.jsx +1 -1
- package/src/panels/PosePanel.jsx +2 -17
- package/src/panels/RigControlPanel.jsx +5 -53
- package/src/panels/SubjectBox.jsx +4 -1
- package/src/panels/details.css +14 -0
- package/src/posestudio.jsx +4 -27
- package/src/project-browser.jsx +3 -4
- package/src/project-resources.js +18 -31
- package/src/project.js +13 -104
- package/src/props.jsx +25 -280
- package/src/rail-dot-drag.js +23 -0
- package/src/render-passes.js +10 -0
- package/src/resource-status.jsx +1 -0
- package/src/result-modal.jsx +4 -19
- package/src/room.jsx +20 -12
- package/src/scene-assets.js +8 -6
- package/src/scene-light-place.js +72 -0
- package/src/scene-lights.jsx +148 -0
- package/src/scene-objects.js +31 -139
- package/src/scenes.js +15 -105
- package/src/semantic-edit.js +2 -5
- package/src/set-pieces.jsx +183 -0
- package/src/settings-menu.jsx +3 -11
- package/src/shell/BottomDock.jsx +11 -53
- package/src/shell/CompositionGuideButton.jsx +20 -0
- package/src/shell/DetailsSlot.jsx +16 -200
- package/src/shell/GhostsMenuGroup.jsx +74 -0
- package/src/shell/LibrarySlot.jsx +1 -3
- package/src/shell/MenuBar.jsx +3 -3
- package/src/shell/PreferencesDialog.jsx +15 -264
- package/src/shell/PreferencesSlot.jsx +2 -8
- package/src/shell/ShotPreviewHeader.jsx +17 -0
- package/src/shell/TopBar.jsx +5 -83
- package/src/shell/ViewportToolbar.jsx +23 -93
- package/src/shell/agent-glass.css +19 -6
- package/src/shell/details-selection.js +42 -0
- package/src/shell/ghosts-menu.css +22 -0
- package/src/shell/glass-regions.css +29 -3
- package/src/shell/preferences.css +6 -1
- package/src/shell/viewport.css +12 -0
- package/src/shot-authoring.js +4 -7
- package/src/soft-shadows.js +37 -0
- package/src/stage-attach-frames.js +12 -12
- package/src/stage-canvas-rigs.jsx +3 -3
- package/src/stage-capture.jsx +42 -8
- package/src/stage-characters.jsx +22 -216
- package/src/stage-editor-gizmos.jsx +6 -6
- package/src/stage-environment.js +93 -0
- package/src/stage-hdr-builtins.js +107 -0
- package/src/stage-hdr-image.js +116 -0
- package/src/stage-hdr-library.js +70 -0
- package/src/stage-hdr-map.js +94 -0
- package/src/stage-hdr.js +130 -0
- package/src/stage-lighting.js +149 -0
- package/src/stage-occlusion.js +210 -0
- package/src/stage-sky.jsx +159 -0
- package/src/stage-startup-defaults.js +5 -9
- package/src/studio-actions.js +12 -14
- package/src/studio-agent-commands.js +46 -16
- package/src/studio-agent-motion.js +9 -9
- package/src/studio-agent-protocol.js +46 -73
- package/src/studio-app-binding.js +29 -45
- package/src/studio-asset-list.js +17 -0
- package/src/studio-contact-sheet.js +37 -5
- package/src/studio-elements.js +27 -7
- package/src/studio-entity-bounds.js +18 -0
- package/src/studio-error-codes.js +8 -0
- package/src/studio-export-framing.js +152 -0
- package/src/studio-lighting-check.js +103 -0
- package/src/studio-motion-visual.js +150 -0
- package/src/studio-schema-errors.js +80 -0
- package/src/studio-support-gap.js +74 -0
- package/src/styles.css +1 -19
- package/src/timeline-defaults.js +5 -0
- package/src/timeline-extent.js +8 -20
- package/src/tutorial-walk.js +17 -0
- package/src/ui-scrub.js +1 -1
- package/src/use-shot-camera-tracks.js +12 -0
- package/src/view-ghosts.js +97 -0
- package/src/view-ghosts.jsx +49 -0
- package/src/workflow/AgentPanel.jsx +47 -166
- package/src/workflow/AgentProgressCard.jsx +107 -0
- package/src/workflow/AgentReplyText.jsx +37 -0
- package/src/workflow/AgentTurnSteps.jsx +84 -0
- package/src/workflow/LoginPanel.jsx +140 -0
- package/src/workflow/WorkflowBuilder.jsx +7 -23
- package/src/workflow/agent-client.js +54 -51
- package/src/workflow/agent-panel.css +71 -1
- package/src/workflow/agent-progress-card.css +167 -0
- package/src/workflow/agent-progress-view.js +47 -0
- package/src/workflow/agent-turn-steps.css +113 -0
- package/src/workflow/agent-turn.js +191 -0
- package/src/workflow/login-client.js +34 -0
- package/src/workflow/motion-input.js +18 -31
- package/src/workflow/node-schema.js +1 -1
- package/src/workflow/reply-markdown.js +69 -0
- package/src/workflow/scene-asset-sync.js +8 -8
- package/tools/agent-session-stats.mjs +61 -0
- package/tools/dev-full.mjs +5 -56
- package/tools/eslint-baseline.json +12 -13
- package/tools/headless-studio.mjs +85 -0
- package/tools/knip-baseline.json +0 -179
- package/tools/loc-baseline.json +33 -83
- package/tools/motion3/extract-body.mjs +103 -0
- package/tools/motion3/extract-rig.mjs +85 -0
- package/tools/process-supervisor.mjs +0 -88
- package/tools/run-tests.mjs +9 -124
- package/bin/agent/motion-runtime.mjs +0 -76
- package/dist/ardy/cskel27-rest.json +0 -557
- package/dist/assets/analytics-B41FmPYI.js +0 -1
- package/dist/assets/app-Do-Og5Pu.css +0 -1
- package/dist/assets/app-DwP-tl2x.js +0 -4920
- package/dist/assets/config-Bx7pYsD9.js +0 -1
- package/dist/assets/config-DeoFTYzb.css +0 -1
- package/dist/assets/demo-Dt0qZfS7.js +0 -1
- package/dist/assets/scene-asset-sync-BCWDJB1d.js +0 -19
- package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
- package/dist/assets/ticket-jqMhqL88.js +0 -1
- package/dist/assets/workflow-Br-K7Srs.js +0 -179
- package/dist/demo/walk-then-stop.npz +0 -0
- package/mcp/ardy-prompts.mjs +0 -218
- package/src/ardy/auto-fix-panel.css +0 -108
- package/src/ardy/auto-physics.js +0 -1194
- package/src/ardy/client.js +0 -153
- package/src/ardy/convert.js +0 -313
- package/src/ardy/cskel27-neutral.js +0 -39
- package/src/ardy/cskel27.js +0 -77
- package/src/ardy/export.js +0 -165
- package/src/ardy/fix-collisions.js +0 -2257
- package/src/ardy/foot-lock.js +0 -230
- package/src/ardy/motion-calibration.js +0 -118
- package/src/ardy/motion-edit.js +0 -213
- package/src/ardy/motion-url.js +0 -55
- package/src/ardy/mp4-duration.js +0 -102
- package/src/ardy/npz.js +0 -595
- package/src/ardy/physics-panel.css +0 -21
- package/src/ardy/physics-panel.jsx +0 -89
- package/src/ardy/physics-refine.js +0 -111
- package/src/ardy/physics-review.js +0 -567
- package/src/ardy/physics-temporal.js +0 -54
- package/src/ardy/platform-fit-panel.css +0 -64
- package/src/ardy/platform-fit-panel.jsx +0 -41
- package/src/ardy/platform-fit.js +0 -326
- package/src/ardy/playback.js +0 -711
- package/src/ardy/pose-pin.js +0 -97
- package/src/ardy/prompt-clips.js +0 -30
- package/src/ardy/retime.js +0 -211
- package/src/ardy/root-drop.js +0 -369
- package/src/ardy/timeline-resize.js +0 -13
- package/src/ardy/to-cskel27.js +0 -225
- package/src/ardy/trim.js +0 -33
- package/src/ardy/waypoints.js +0 -369
- package/src/ardy-bridge-contract.js +0 -281
- package/src/domains/motion/motion-video-capture.js +0 -664
- package/src/i2v-motion-client.js +0 -77
- package/src/i2v-motion-studio.jsx +0 -180
- package/src/line-edit.js +0 -1348
- package/src/motion/generation.js +0 -105
- package/src/motion-readiness-ui.jsx +0 -67
- package/src/motion-readiness.js +0 -40
- package/src/motion-resources.js +0 -177
- package/src/motion-store.js +0 -65
- package/src/motion-trail.js +0 -601
- package/src/multimodel-ingest.js +0 -394
- package/src/panels/PromptBlocksPanel.jsx +0 -444
- package/src/panels/VideoCapturePanel.jsx +0 -181
- package/src/pose-extract/browser.js +0 -42
- package/src/pose-extract/detector.js +0 -100
- package/src/pose-extract/fit.js +0 -227
- package/src/pose-extract/image-frame.js +0 -51
- package/src/pose-extract/index.js +0 -58
- package/src/pose-extract/keyframes.js +0 -74
- package/src/pose-extract/landmarks.js +0 -162
- package/src/pose-extract/mirror.js +0 -153
- package/src/pose-extract/take.js +0 -131
- package/src/pose-extract/video-frames.js +0 -91
- package/src/take-recipe.js +0 -165
- package/src/trail-key-conflicts.js +0 -39
- package/src/trail-pick.js +0 -59
- package/src/use-i2v-capture-modal.js +0 -15
- package/tools/ardy/BRIDGE.md +0 -37
- package/tools/ardy/GVHMR-NPZ.md +0 -68
- package/tools/ardy/README.md +0 -124
- package/tools/ardy/__pycache__/cclay_gvhmr_worker.cpython-313.pyc +0 -0
- package/tools/ardy/artifacts.mjs +0 -34
- package/tools/ardy/bridge.mjs +0 -1732
- package/tools/ardy/bvh-cskel27.mjs +0 -1265
- package/tools/ardy/cclay_constrained_generate.py +0 -561
- package/tools/ardy/cclay_gvhmr_worker.py +0 -264
- package/tools/ardy/cclay_motion_edit.py +0 -510
- package/tools/ardy/cclay_sequence_generate.py +0 -705
- package/tools/ardy/cclay_worker.py +0 -304
- package/tools/ardy/dump-npz.py +0 -205
- package/tools/ardy/extract-rest.mjs +0 -299
- package/tools/ardy/extract.mjs +0 -507
- package/tools/ardy/footage.mjs +0 -467
- package/tools/ardy/gvhmr-floor.mjs +0 -102
- package/tools/ardy/gvhmr-to-cskel27.mjs +0 -21
- package/tools/ardy/gvhmr_fastpath.py +0 -168
- package/tools/ardy/gvhmr_trajectory.py +0 -240
- package/tools/ardy/merge-text-encoder.py +0 -160
- package/tools/ardy/mocap-metrics.mjs +0 -200
- package/tools/ardy/mocap-quality-gate.mjs +0 -110
- package/tools/ardy/motion-stabilize.mjs +0 -348
- package/tools/ardy/npz.mjs +0 -414
- package/tools/ardy/pose-to-npz.mjs +0 -106
- package/tools/ardy/prompt-limits.mjs +0 -5
- package/tools/ardy/run-edit-on-box.sh +0 -73
- package/tools/ardy/run-local.mjs +0 -233
- package/tools/ardy/run-on-box.sh +0 -593
- package/tools/ardy/run-sequence-on-box.sh +0 -177
- package/tools/ardy/runners/gvhmr-worker.mjs +0 -206
- package/tools/ardy/runners/index.mjs +0 -18
- package/tools/ardy/runners/local.mjs +0 -455
- package/tools/ardy/runners/proc.mjs +0 -125
- package/tools/ardy/runners/remote.mjs +0 -252
- package/tools/ardy/setup-local.mjs +0 -189
- package/tools/ardy/setup-text-encoder-on-box.sh +0 -93
- package/tools/ardy/setup-text-encoder.py +0 -306
- package/tools/ardy/smpl-cskel27.mjs +0 -178
- package/tools/ardy/visual-qa.mjs +0 -196
- package/tools/ardy/vq-car.mjs +0 -52
- package/tools/bench/EXP3.md +0 -61
- package/tools/bench/cclay_bench_extract_incam.py +0 -125
- package/tools/bench/cclay_bench_extract_obs.py +0 -204
- package/tools/bench/cclay_bench_runner.py +0 -42
- package/tools/bench/cube-contact.mjs +0 -162
- package/tools/bench/exp3.mjs +0 -152
- package/tools/bench/extract-bench-lib.mjs +0 -216
- package/tools/bench/extract-bench.mjs +0 -302
- package/tools/bench/fal-generate.mjs +0 -88
- package/tools/bench/fit/README.md +0 -189
- package/tools/bench/fit/camera.mjs +0 -59
- package/tools/bench/fit/contact.mjs +0 -419
- package/tools/bench/fit/footlock.mjs +0 -234
- package/tools/bench/fit/motion.mjs +0 -85
- package/tools/bench/fit/pin.mjs +0 -27
- package/tools/bench/fit/remote.mjs +0 -105
- package/tools/bench/fit-bench.mjs +0 -126
- package/tools/bench/fit-sanity.mjs +0 -45
- package/tools/bench/metrics.mjs +0 -313
- package/tools/bench/obs/depth.mjs +0 -258
- package/tools/bench/obs/extrinsics.mjs +0 -175
- package/tools/bench/obs/fit_mannequin_betas.py +0 -340
- package/tools/bench/obs/ground.mjs +0 -294
- package/tools/bench/obs/heading.mjs +0 -151
- package/tools/bench/obs/ladder.mjs +0 -555
- package/tools/bench/obs/mannequin-betas.json +0 -124
- package/tools/bench/obs/remote.mjs +0 -83
- package/tools/bench/obs/rest_joints.py +0 -52
- package/tools/bench/obs/ybot-targets.mjs +0 -49
- package/tools/bench/obs-bench.mjs +0 -520
- package/tools/bench/score.mjs +0 -343
- package/tools/bench/summarize.mjs +0 -86
- package/tools/demo-worker/README.md +0 -137
- package/tools/demo-worker/api-client.mjs +0 -233
- package/tools/demo-worker/generate.mjs +0 -301
- package/tools/demo-worker/index.mjs +0 -466
- package/tools/demo-worker/sign-core.mjs +0 -112
- package/tools/demo-worker/sign.mjs +0 -161
- package/tools/gt-render/browser.mjs +0 -159
- package/tools/gt-render/camera-math.mjs +0 -276
- package/tools/gt-render/page.mjs +0 -267
- package/tools/gt-render/render.mjs +0 -514
- package/tools/gt-render/scene-box.mjs +0 -31
- package/tools/gt-render/take-transform.mjs +0 -87
- package/tools/kimodo/compare-seam.mjs +0 -108
- package/tools/kimodo/constraints.mjs +0 -244
- package/tools/kimodo/edit.mjs +0 -259
- package/tools/kimodo/effector-constraints.mjs +0 -200
- package/tools/kimodo/generate.mjs +0 -646
- package/tools/kimodo/local-output.mjs +0 -265
- package/tools/kimodo/measure-pose.mjs +0 -65
- package/tools/kimodo/measure-preserve.mjs +0 -899
- package/tools/kimodo/measure-waypoints.mjs +0 -55
- package/tools/kimodo/mlx-generate.py +0 -111
- package/tools/kimodo/pose-constraints.mjs +0 -248
- package/tools/kimodo/preserve-mask.mjs +0 -543
- package/tools/kimodo/read-npz.mjs +0 -189
- package/tools/kimodo/run-edit-on-box.mjs +0 -155
- package/tools/kimodo/run-sequence-on-box.mjs +0 -178
- package/tools/kimodo/runner.mjs +0 -284
- package/tools/kimodo/seam-batch.mjs +0 -77
- package/tools/kimodo/setup-local.mjs +0 -30
- package/tools/kimodo/setup-on-box.sh +0 -339
- package/tools/kimodo/soma77-to-cskel27.mjs +0 -305
- package/tools/morphgs/assets/gen_truth.py +0 -39
- package/tools/morphgs/assets/mesh_ori_rig.txt +0 -27
- package/tools/morphgs/assets/playback-check.mjs +0 -30
- package/tools/morphgs/demo-gate.sh +0 -26
- package/tools/morphgs/fbx2morphgs.mjs +0 -68
- package/tools/morphgs/morphgs-to-cskel27.mjs +0 -105
- package/tools/morphgs/patches/preprocess_src-none-mode.patch +0 -76
- package/tools/morphgs/setup-on-cluster.sh +0 -126
- package/tools/projflow/driver.py +0 -1069
- package/tools/projflow/generate.mjs +0 -805
- package/tools/projflow/hml22-to-cskel27.mjs +0 -735
- package/tools/projflow/line-edit-job.mjs +0 -547
- package/tools/projflow/replay.mjs +0 -452
- package/tools/projflow/runner.mjs +0 -269
- package/tools/projflow/service.mjs +0 -742
- package/tools/track/DESIGN.md +0 -513
- package/tools/track/backfill-provenance.mjs +0 -116
- package/tools/track/budget.mjs +0 -8
- package/tools/track/check-rig.mjs +0 -209
- package/tools/track/diagnostics.schema.json +0 -60
- package/tools/track/export-rig.mjs +0 -256
- package/tools/track/fallback.mjs +0 -7
- package/tools/track/fk-parity-fixture.mjs +0 -161
- package/tools/track/gate.mjs +0 -349
- package/tools/track/masks.mjs +0 -318
- package/tools/track/metrics.mjs +0 -201
- package/tools/track/publish-obs.mjs +0 -108
- package/tools/track/py/check_env.py +0 -61
- package/tools/track/py/eval_lr.py +0 -229
- package/tools/track/py/lr_viterbi.py +0 -294
- package/tools/track/py/masks.py +0 -405
- package/tools/track/py/objective.py +0 -382
- package/tools/track/py/rig.py +0 -508
- package/tools/track/py/scene.py +0 -326
- package/tools/track/py/test_joint_indices.py +0 -123
- package/tools/track/py/test_lr_viterbi.py +0 -195
- package/tools/track/py/test_masks.py +0 -229
- package/tools/track/py/test_rig.py +0 -288
- package/tools/track/py/test_scene.py +0 -354
- package/tools/track/py/test_track.py +0 -328
- package/tools/track/py/track.py +0 -411
- package/tools/track/remote.mjs +0 -140
- package/tools/track/rig-dump.mjs +0 -227
- package/tools/track/run-box-tests.mjs +0 -14
- package/tools/track/run-box.mjs +0 -168
- package/tools/track/setup-box.sh +0 -59
- package/tools/track/study-2d.mjs +0 -728
- /package/src/{ardy → motion}/collision-blockers.js +0 -0
- /package/src/{ardy → motion}/ground.js +0 -0
- /package/src/{ardy → motion}/ik-drag.js +0 -0
- /package/src/{ardy → motion}/ik-key-json.js +0 -0
- /package/src/{ardy → motion}/ik.js +0 -0
- /package/src/{ardy → motion}/physics-surface.js +0 -0
- /package/src/{ardy → motion}/playback-clock.js +0 -0
- /package/src/{ardy → motion}/range-pin.js +0 -0
package/tools/loc-baseline.json
CHANGED
|
@@ -1,126 +1,76 @@
|
|
|
1
1
|
{
|
|
2
|
-
"bin/agent/agent-routes.mjs":
|
|
2
|
+
"bin/agent/agent-routes.mjs": 865,
|
|
3
3
|
"bin/agent/agent-runner.mjs": 496,
|
|
4
4
|
"bin/agent/providers.mjs": 409,
|
|
5
5
|
"bin/agent/session-store.mjs": 324,
|
|
6
|
-
"bin/agent/studio-rebase.mjs": 268,
|
|
7
6
|
"bin/agent/supervisor.mjs": 283,
|
|
8
7
|
"bin/agent/video-adapters.mjs": 334,
|
|
9
|
-
"bin/cozyclay.mjs":
|
|
10
|
-
"bin/live/cli.mjs":
|
|
11
|
-
"mcp/live-hub.mjs":
|
|
12
|
-
"mcp/tool-handlers.mjs":
|
|
13
|
-
"mcp/verify-live-batch.mjs":
|
|
8
|
+
"bin/cozyclay.mjs": 440,
|
|
9
|
+
"bin/live/cli.mjs": 456,
|
|
10
|
+
"mcp/live-hub.mjs": 529,
|
|
11
|
+
"mcp/tool-handlers.mjs": 1730,
|
|
12
|
+
"mcp/verify-live-batch.mjs": 486,
|
|
14
13
|
"mcp/verify-live-capture.mjs": 268,
|
|
15
14
|
"mcp/verify-live-controller.mjs": 340,
|
|
16
|
-
"mcp/verify-live-
|
|
17
|
-
"mcp/verify-live
|
|
18
|
-
"
|
|
19
|
-
"src/
|
|
20
|
-
"src/App.jsx": 6624,
|
|
21
|
-
"src/ardy/auto-physics.js": 1094,
|
|
22
|
-
"src/ardy/collision-blockers.js": 273,
|
|
23
|
-
"src/ardy/convert.js": 285,
|
|
24
|
-
"src/ardy/fix-collisions.js": 1987,
|
|
25
|
-
"src/ardy/ik.js": 1135,
|
|
26
|
-
"src/ardy/npz.js": 534,
|
|
27
|
-
"src/ardy/physics-review.js": 510,
|
|
28
|
-
"src/ardy/platform-fit.js": 277,
|
|
29
|
-
"src/ardy/playback.js": 565,
|
|
30
|
-
"src/ardy/range-pin.js": 277,
|
|
31
|
-
"src/ardy/root-drop.js": 313,
|
|
32
|
-
"src/ardy/timeline.jsx": 2384,
|
|
33
|
-
"src/ardy/waypoints.js": 311,
|
|
15
|
+
"mcp/verify-live-p0.mjs": 264,
|
|
16
|
+
"mcp/verify-live.mjs": 416,
|
|
17
|
+
"src/analytics.js": 1169,
|
|
18
|
+
"src/App.jsx": 4711,
|
|
34
19
|
"src/asset-pane.jsx": 648,
|
|
35
20
|
"src/camera-follow.js": 505,
|
|
36
21
|
"src/camera-move.js": 289,
|
|
37
22
|
"src/camera-tutorial.jsx": 443,
|
|
38
23
|
"src/command-bus.js": 378,
|
|
39
24
|
"src/controls.jsx": 340,
|
|
40
|
-
"src/domains/cast.js":
|
|
41
|
-
"src/domains/motion.js":
|
|
42
|
-
"src/domains/motion/motion-video-capture.js": 592,
|
|
25
|
+
"src/domains/cast.js": 717,
|
|
26
|
+
"src/domains/motion.js": 812,
|
|
43
27
|
"src/domains/objects.js": 907,
|
|
44
|
-
"src/domains/scenes.js":
|
|
28
|
+
"src/domains/scenes.js": 754,
|
|
45
29
|
"src/domains/shots.js": 411,
|
|
46
30
|
"src/dualview.jsx": 371,
|
|
47
31
|
"src/hierarchy-panel.jsx": 779,
|
|
48
|
-
"src/line-edit.js": 1215,
|
|
49
32
|
"src/live-control.js": 338,
|
|
50
33
|
"src/matte-editor.js": 486,
|
|
51
34
|
"src/matte.js": 472,
|
|
52
|
-
"src/motion-
|
|
53
|
-
"src/
|
|
35
|
+
"src/motion/collision-blockers.js": 273,
|
|
36
|
+
"src/motion/fix-collisions.js": 748,
|
|
37
|
+
"src/motion/ik.js": 1135,
|
|
38
|
+
"src/motion/range-pin.js": 277,
|
|
39
|
+
"src/motion/timeline.jsx": 2047,
|
|
54
40
|
"src/object-gizmo.jsx": 824,
|
|
55
41
|
"src/object-path.js": 410,
|
|
56
42
|
"src/panels/ObjectTransformPanel.jsx": 545,
|
|
57
|
-
"src/panels/PromptBlocksPanel.jsx": 433,
|
|
58
43
|
"src/panels/SculptPanel.jsx": 370,
|
|
59
44
|
"src/planview.jsx": 887,
|
|
60
45
|
"src/poses.js": 321,
|
|
61
|
-
"src/posestudio.jsx":
|
|
46
|
+
"src/posestudio.jsx": 1240,
|
|
62
47
|
"src/project-browser.jsx": 401,
|
|
63
|
-
"src/project
|
|
64
|
-
"src/
|
|
65
|
-
"src/props.jsx": 649,
|
|
48
|
+
"src/project.js": 603,
|
|
49
|
+
"src/props.jsx": 417,
|
|
66
50
|
"src/range-pin-panel.jsx": 305,
|
|
67
51
|
"src/scene-assets.js": 400,
|
|
68
52
|
"src/scene-mesh.js": 350,
|
|
69
|
-
"src/scene-objects.js":
|
|
70
|
-
"src/scenes.js":
|
|
53
|
+
"src/scene-objects.js": 1136,
|
|
54
|
+
"src/scenes.js": 387,
|
|
71
55
|
"src/sculpt-compare.js": 357,
|
|
72
56
|
"src/sculpt-recipe.js": 363,
|
|
73
57
|
"src/sculpt-run.js": 309,
|
|
74
58
|
"src/shell/BoardSlot.jsx": 316,
|
|
75
|
-
"src/shell/BottomDock.jsx":
|
|
76
|
-
"src/shell/DetailsSlot.jsx":
|
|
59
|
+
"src/shell/BottomDock.jsx": 416,
|
|
60
|
+
"src/shell/DetailsSlot.jsx": 334,
|
|
77
61
|
"src/shell/MenuBar.jsx": 640,
|
|
78
|
-
"src/shell/PreferencesDialog.jsx":
|
|
79
|
-
"src/shell/ViewportToolbar.jsx":
|
|
62
|
+
"src/shell/PreferencesDialog.jsx": 466,
|
|
63
|
+
"src/shell/ViewportToolbar.jsx": 567,
|
|
80
64
|
"src/shot-authoring.js": 348,
|
|
81
65
|
"src/stage-canvas-rigs.jsx": 352,
|
|
82
66
|
"src/stage-editor-gizmos.jsx": 1116,
|
|
83
|
-
"src/studio-agent-commands.js":
|
|
84
|
-
"src/studio-agent-protocol.js":
|
|
85
|
-
"src/studio-app-binding.js":
|
|
67
|
+
"src/studio-agent-commands.js": 492,
|
|
68
|
+
"src/studio-agent-protocol.js": 486,
|
|
69
|
+
"src/studio-app-binding.js": 346,
|
|
86
70
|
"src/ui.jsx": 393,
|
|
87
71
|
"src/workflow/agent-client.js": 1386,
|
|
88
|
-
"src/workflow/AgentPanel.jsx":
|
|
89
|
-
"src/workflow/WorkflowBuilder.jsx":
|
|
90
|
-
"tools/ardy/bridge.mjs": 1321,
|
|
91
|
-
"tools/ardy/bvh-cskel27.mjs": 912,
|
|
92
|
-
"tools/ardy/extract-rest.mjs": 266,
|
|
93
|
-
"tools/ardy/extract.mjs": 412,
|
|
94
|
-
"tools/ardy/footage.mjs": 409,
|
|
95
|
-
"tools/ardy/motion-stabilize.mjs": 279,
|
|
96
|
-
"tools/ardy/npz.mjs": 369,
|
|
97
|
-
"tools/ardy/runners/local.mjs": 367,
|
|
98
|
-
"tools/bench/extract-bench.mjs": 284,
|
|
99
|
-
"tools/bench/fit/contact.mjs": 380,
|
|
100
|
-
"tools/bench/metrics.mjs": 290,
|
|
101
|
-
"tools/bench/obs-bench.mjs": 486,
|
|
102
|
-
"tools/bench/obs/ground.mjs": 265,
|
|
103
|
-
"tools/bench/obs/ladder.mjs": 480,
|
|
104
|
-
"tools/bench/score.mjs": 316,
|
|
105
|
-
"tools/demo-worker/generate.mjs": 274,
|
|
106
|
-
"tools/demo-worker/index.mjs": 426,
|
|
107
|
-
"tools/gt-render/camera-math.mjs": 255,
|
|
108
|
-
"tools/gt-render/render.mjs": 485,
|
|
109
|
-
"tools/kimodo/generate.mjs": 519,
|
|
110
|
-
"tools/kimodo/local-output.mjs": 255,
|
|
111
|
-
"tools/kimodo/measure-preserve.mjs": 795,
|
|
112
|
-
"tools/kimodo/preserve-mask.mjs": 452,
|
|
113
|
-
"tools/kimodo/soma77-to-cskel27.mjs": 271,
|
|
114
|
-
"tools/projflow/generate.mjs": 682,
|
|
115
|
-
"tools/projflow/hml22-to-cskel27.mjs": 633,
|
|
116
|
-
"tools/projflow/line-edit-job.mjs": 484,
|
|
117
|
-
"tools/projflow/replay.mjs": 397,
|
|
118
|
-
"tools/projflow/service.mjs": 651,
|
|
72
|
+
"src/workflow/AgentPanel.jsx": 880,
|
|
73
|
+
"src/workflow/WorkflowBuilder.jsx": 592,
|
|
119
74
|
"tools/qa/css-rule-usage.mjs": 251,
|
|
120
|
-
"tools/run-tests.mjs":
|
|
121
|
-
"tools/track/gate.mjs": 325,
|
|
122
|
-
"tools/track/masks.mjs": 297,
|
|
123
|
-
"tools/track/study-2d.mjs": 663,
|
|
124
|
-
"workers/api/src/index.js": 426,
|
|
125
|
-
"workers/api/src/queue.js": 441
|
|
75
|
+
"tools/run-tests.mjs": 448
|
|
126
76
|
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
// Fit the collision body of a Mixamo FBX rig from its skin to src/motion3/rigs/<model>-body.json
|
|
2
|
+
// for motion3's self-collision (src/motion3/body.js): one signed distance grid per skinned bone, in
|
|
3
|
+
// that bone's bind frame (the bone moves it rigidly), from the skin vertices the bone carries; and
|
|
4
|
+
// for each limb bone the radius of its skin along the bone (the probe spheres a limb collides with).
|
|
5
|
+
// Run once per rig: node tools/motion3/extract-body.mjs y-bot-tpose
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
import * as THREE from "three";
|
|
9
|
+
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
|
|
10
|
+
import { skeletonFor } from "../../src/motion3/rigs/index.js";
|
|
11
|
+
import { axisEnd } from "../../src/motion3/body.js";
|
|
12
|
+
import { sub, apply, T, dot, len } from "../../src/motion3/compiler/math.js";
|
|
13
|
+
|
|
14
|
+
const model = process.argv[2] ?? "y-bot-tpose";
|
|
15
|
+
const STEP = 0.015, MARGIN = 0.04, MEMBER = 0.25, MM = 1000;
|
|
16
|
+
const buf = fs.readFileSync(path.resolve("public/models", `${model}.fbx`));
|
|
17
|
+
const root = new FBXLoader().parse(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength), "");
|
|
18
|
+
root.updateMatrixWorld(true);
|
|
19
|
+
const sk = skeletonFor(model), name = n => n.replace(/^mixamorig:?/, "");
|
|
20
|
+
|
|
21
|
+
// Skin vertices (metres, bind pose) with normals and the bones that carry them, both meshes (the
|
|
22
|
+
// Y/X Bot joint balls are their own mesh), duplicates merged.
|
|
23
|
+
const verts = new Map();
|
|
24
|
+
root.traverse(o => {
|
|
25
|
+
if (!o.isSkinnedMesh) return;
|
|
26
|
+
const g = o.geometry, pos = g.attributes.position, nrm = g.attributes.normal, si = g.attributes.skinIndex, sw = g.attributes.skinWeight;
|
|
27
|
+
const v = new THREE.Vector3(), n = new THREE.Vector3(), nm = new THREE.Matrix3().getNormalMatrix(o.matrixWorld);
|
|
28
|
+
for (let i = 0; i < pos.count; i++) {
|
|
29
|
+
v.fromBufferAttribute(pos, i).applyMatrix4(o.matrixWorld).multiplyScalar(0.01);
|
|
30
|
+
const key = v.toArray().map(x => Math.round(x * 2000)).join();
|
|
31
|
+
const entry = verts.get(key) ?? { p: v.toArray(), n: [0, 0, 0], w: new Map() };
|
|
32
|
+
n.fromBufferAttribute(nrm, i).applyMatrix3(nm).normalize();
|
|
33
|
+
entry.n = entry.n.map((x, k) => x + n.getComponent(k));
|
|
34
|
+
for (let k = 0; k < 4; k++) {
|
|
35
|
+
const w = sw.getComponent(i, k), b = sk.index[name(o.skeleton.bones[si.getComponent(i, k)].name)];
|
|
36
|
+
if (w > 0 && b !== undefined) entry.w.set(b, Math.max(entry.w.get(b) ?? 0, w));
|
|
37
|
+
}
|
|
38
|
+
verts.set(key, entry);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
const V = [...verts.values()].map(e => ({ ...e, n: e.n.map(x => x / (len(e.n) || 1)) }));
|
|
42
|
+
const dominant = e => [...e.w].sort((a, b) => b[1] - a[1])[0]?.[0];
|
|
43
|
+
// Fingers bend inside the hand: their skin is no grid of the hand; every other skinned bone gets one.
|
|
44
|
+
const FINGER = /Hand(Thumb|Index|Middle|Ring|Pinky)/;
|
|
45
|
+
const owners = [...new Set(V.map(dominant))].filter(b => b !== undefined && !FINGER.test(sk.names[b]));
|
|
46
|
+
|
|
47
|
+
/** Signed distance grid of the skin bone b carries, in b's bind frame (millimetres, Int8, outside +). */
|
|
48
|
+
function grid(b) {
|
|
49
|
+
const toLocal = p => apply(T(sk.restWorldRot[b]), sub(p, sk.restWorldPos[b]));
|
|
50
|
+
const pts = V.filter(e => (e.w.get(b) ?? 0) >= MEMBER || dominant(e) === b).map(e => ({ p: toLocal(e.p), n: apply(T(sk.restWorldRot[b]), e.n) }));
|
|
51
|
+
const own = V.filter(e => dominant(e) === b).map(e => toLocal(e.p));
|
|
52
|
+
const lo = [0, 1, 2].map(k => Math.min(...own.map(p => p[k])) - MARGIN), hi = [0, 1, 2].map(k => Math.max(...own.map(p => p[k])) + MARGIN);
|
|
53
|
+
const dims = lo.map((l, k) => Math.max(2, Math.ceil((hi[k] - l) / STEP) + 1));
|
|
54
|
+
// a hash of the member points: the nearest few decide distance and side
|
|
55
|
+
const cell = 0.03, hash = new Map(), at = p => p.map(x => Math.floor(x / cell)).join();
|
|
56
|
+
for (const q of pts) { const k = at(q.p); if (!hash.has(k)) hash.set(k, []); hash.get(k).push(q); }
|
|
57
|
+
const near = p => {
|
|
58
|
+
const c = p.map(x => Math.floor(x / cell)), found = [];
|
|
59
|
+
for (let r = 1; r <= 6 && found.length < 6; r++) {
|
|
60
|
+
found.length = 0;
|
|
61
|
+
for (let i = -r; i <= r; i++) for (let j = -r; j <= r; j++) for (let k = -r; k <= r; k++) found.push(...(hash.get(`${c[0] + i},${c[1] + j},${c[2] + k}`) ?? []));
|
|
62
|
+
}
|
|
63
|
+
return found.map(q => ({ q, d: len(sub(p, q.p)) })).sort((x, y) => x.d - y.d).slice(0, 6);
|
|
64
|
+
};
|
|
65
|
+
const data = new Int8Array(dims[0] * dims[1] * dims[2]);
|
|
66
|
+
for (let x = 0; x < dims[0]; x++) for (let y = 0; y < dims[1]; y++) for (let z = 0; z < dims[2]; z++) {
|
|
67
|
+
const p = [lo[0] + x * STEP, lo[1] + y * STEP, lo[2] + z * STEP], nn = near(p);
|
|
68
|
+
let d = 0.127;
|
|
69
|
+
if (nn.length) {
|
|
70
|
+
// side: the nearest points' normals vote, nearer ones louder; distance: to the nearest point's
|
|
71
|
+
// tangent plane where the point lies over it, else to the point
|
|
72
|
+
const side = nn.reduce((acc, { q, d: dq }) => acc + Math.sign(dot(sub(p, q.p), q.n)) / (dq + 0.005), 0) >= 0 ? 1 : -1;
|
|
73
|
+
const { q, d: dq } = nn[0], along = Math.abs(dot(sub(p, q.p), q.n)), lateral = Math.sqrt(Math.max(0, dq * dq - along * along));
|
|
74
|
+
d = side * (lateral < STEP ? along : dq);
|
|
75
|
+
}
|
|
76
|
+
data[(x * dims[1] + y) * dims[2] + z] = Math.max(-127, Math.min(127, Math.round(d * MM)));
|
|
77
|
+
}
|
|
78
|
+
return { min: lo.map(v => +v.toFixed(4)), dims, data: Buffer.from(data.buffer).toString("base64") };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/** Skin radius along a limb bone (bone to its first child), [t, r] at 6 stations: the 80th percentile of
|
|
82
|
+
* the skin's distance from the bone, but for a hand the median capped at HAND (the palm is flat, and the
|
|
83
|
+
* thumb's root rides the hand bone: a round 80th percentile would make it a 10 cm ball); HAND is the palm's half thickness (qa/geometry.js hand_*). */
|
|
84
|
+
const HAND = 0.022;
|
|
85
|
+
function profile(b) {
|
|
86
|
+
const hand = /Hand$/.test(sk.names[b]);
|
|
87
|
+
const child = axisEnd(sk, b), A = sk.restWorldPos[b], B = sk.restWorldPos[child], axis = sub(B, A), L2 = dot(axis, axis);
|
|
88
|
+
const bins = Array.from({ length: 6 }, () => []);
|
|
89
|
+
for (const e of V) {
|
|
90
|
+
if (dominant(e) !== b) continue;
|
|
91
|
+
const t = dot(sub(e.p, A), axis) / L2;
|
|
92
|
+
if (t < 0 || t > 1) continue;
|
|
93
|
+
bins[Math.min(5, Math.floor(t * 6))].push(len(sub(sub(e.p, A), axis.map(v => v * t))));
|
|
94
|
+
}
|
|
95
|
+
const pick = r => { const v = r.sort((x, y) => x - y)[Math.floor(r.length * (hand ? 0.5 : 0.8))]; return +(hand ? Math.min(HAND, v) : v).toFixed(4); };
|
|
96
|
+
return bins.map((r, i) => [+((i + 0.5) / 6).toFixed(3), r.length ? pick(r) : null]).filter(([, r]) => r !== null);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const LIMBS = ["Arm", "ForeArm", "Hand", "UpLeg", "Leg"].flatMap(n => [`Left${n}`, `Right${n}`]);
|
|
100
|
+
const out = { model, step: STEP, unit: "mm", grids: Object.fromEntries(owners.map(b => [sk.names[b], grid(b)])), radii: Object.fromEntries(LIMBS.map(n => [n, profile(sk.index[n])])) };
|
|
101
|
+
const file = path.resolve("src/motion3/rigs", `${model}-body.json`);
|
|
102
|
+
fs.writeFileSync(file, `${JSON.stringify(out)}\n`);
|
|
103
|
+
console.log(`${file}: ${owners.length} grids, ${(fs.statSync(file).size / 1024).toFixed(0)} KB`);
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// Dump a Mixamo FBX rig's bind skeleton plus measured face/body landmarks to
|
|
2
|
+
// src/motion3/rigs/<model>.json for the motion3 compiler.
|
|
3
|
+
// Run once per rig: node tools/motion3/extract-rig.mjs x-bot-tpose
|
|
4
|
+
import fs from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as THREE from "three";
|
|
7
|
+
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
|
|
8
|
+
|
|
9
|
+
const model = process.argv[2] ?? "x-bot-tpose";
|
|
10
|
+
const buf = fs.readFileSync(path.resolve("public/models", `${model}.fbx`));
|
|
11
|
+
const root = new FBXLoader().parse(buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength), "");
|
|
12
|
+
root.updateMatrixWorld(true);
|
|
13
|
+
let mesh = null;
|
|
14
|
+
root.traverse(o => { if (o.isSkinnedMesh && (!mesh || o.skeleton.bones.length > mesh.skeleton.bones.length)) mesh = o; });
|
|
15
|
+
// The whole bone hierarchy under the skinned Hips, end bones included (some rigs do not skin them).
|
|
16
|
+
const bones = [];
|
|
17
|
+
// Mixamo FBX nests an identity "skinned" copy of every bone under its control bone; the
|
|
18
|
+
// project rule (src/ardy/playback.js findBone) is first depth-first match wins, so keep
|
|
19
|
+
// the first bone of each name and never the nested copies.
|
|
20
|
+
const seen = new Set();
|
|
21
|
+
let top0 = mesh.skeleton.bones[0];
|
|
22
|
+
while (top0.parent?.isBone) top0 = top0.parent; // skinned bones may be the nested copies
|
|
23
|
+
top0.traverse(o => { if (o.isBone && !seen.has(o.name)) { seen.add(o.name); bones.push(o); } });
|
|
24
|
+
const idx = new Map(bones.map((b, i) => [b, i]));
|
|
25
|
+
const name = b => b.name.replace(/^mixamorig:?/, "");
|
|
26
|
+
const v = new THREE.Vector3(), q = new THREE.Quaternion(), s = new THREE.Vector3();
|
|
27
|
+
const out = { model, units: "cm", mesh: mesh.name, bones: bones.map(b => {
|
|
28
|
+
b.matrixWorld.decompose(v, q, s);
|
|
29
|
+
return { name: name(b), parent: idx.has(b.parent) ? idx.get(b.parent) : -1, localPos: b.position.toArray(), localQuat: b.quaternion.toArray(),
|
|
30
|
+
worldPos: v.toArray(), worldQuat: q.toArray() };
|
|
31
|
+
}) };
|
|
32
|
+
// Bind-pose vertices in world space (skinning at bind pose is the identity).
|
|
33
|
+
const pos = mesh.geometry.attributes.position, P = [];
|
|
34
|
+
for (let i = 0; i < pos.count; i++) P.push(v.fromBufferAttribute(pos, i).applyMatrix4(mesh.matrixWorld).toArray());
|
|
35
|
+
const B = n => out.bones.find(b => b.name === n).worldPos;
|
|
36
|
+
const head = B("Head"), neck = B("Neck");
|
|
37
|
+
// HeadTop_End is not in every rig (Y Bot has none): fall back to the highest skin vertex.
|
|
38
|
+
const top = out.bones.find(b => b.name === "HeadTop_End")?.worldPos
|
|
39
|
+
?? [head[0], Math.max(...P.filter(p => p[1] > head[1]).map(p => p[1])), head[2]];
|
|
40
|
+
// Head profile on the mid-sagittal strip |x| < 1.5 cm: the face is the front (+z) silhouette.
|
|
41
|
+
const strip = P.filter(p => Math.abs(p[0]) < 1.5 && p[1] > neck[1] && p[1] < top[1] + 2);
|
|
42
|
+
const rows = [];
|
|
43
|
+
for (let y = Math.floor(neck[1]); y < top[1]; y += 1) {
|
|
44
|
+
const r = strip.filter(p => p[1] >= y && p[1] < y + 1);
|
|
45
|
+
if (r.length) rows.push({ y: y + 0.5, front: Math.max(...r.map(p => p[2])), back: Math.min(...r.map(p => p[2])) });
|
|
46
|
+
}
|
|
47
|
+
// Head skin only: from 6 cm below the head joint up, inside |x| < 12 cm (keeps the shoulders out).
|
|
48
|
+
const headVerts = P.filter(p => p[1] > head[1] - 6 && Math.abs(p[0]) < 12);
|
|
49
|
+
const ext = k => [Math.min(...headVerts.map(p => p[k])), Math.max(...headVerts.map(p => p[k]))];
|
|
50
|
+
const hb = { x: ext(0), y: ext(1), z: ext(2) };
|
|
51
|
+
// The bot head has no modelled mouth: put it 16% of the head height above the chin, on
|
|
52
|
+
// the front silhouette (interpolated from the profile rows), 0.3 cm proud of the skin.
|
|
53
|
+
const mouthY = hb.y[0] + 0.16 * (hb.y[1] - hb.y[0]);
|
|
54
|
+
const near = rows.filter(r => r.front > 0).sort((a, b) => Math.abs(a.y - mouthY) - Math.abs(b.y - mouthY)).slice(0, 3);
|
|
55
|
+
const mouthZ = Math.max(...near.map(r => r.front)) + 0.3;
|
|
56
|
+
// The left foot's skin (every skinned mesh, vertices at least half weighted to LeftFoot/LeftToe*,
|
|
57
|
+
// the membership the verify_result floor measure uses). QA's ball and tip sole points ride the
|
|
58
|
+
// ToeBase and Toe_End joints this far down (cm, to the mm; < 0: the skin is above the joint):
|
|
59
|
+
// ball = the lowest skin under the toe pad (from ToeBase halfway to Toe_End), tip = the lowest
|
|
60
|
+
// skin in the front 1.5 cm of the foot.
|
|
61
|
+
const footSkin = [];
|
|
62
|
+
root.traverse(m => {
|
|
63
|
+
const g = m.isSkinnedMesh && m.geometry.attributes, wp = new THREE.Vector3();
|
|
64
|
+
if (!g?.skinIndex) return;
|
|
65
|
+
for (let i = 0; i < g.position.count; i++) {
|
|
66
|
+
let w = 0;
|
|
67
|
+
for (let j = 0; j < 4; j++) if (/LeftFoot|LeftToe/.test(m.skeleton.bones[g.skinIndex.getComponent(i, j)]?.name ?? "")) w += g.skinWeight.getComponent(i, j);
|
|
68
|
+
if (w >= 0.5) footSkin.push(wp.fromBufferAttribute(g.position, i).applyMatrix4(m.matrixWorld).toArray());
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
const toe = B("LeftToeBase"), toeEnd = B("LeftToe_End"), front = Math.max(...footSkin.map(p => p[2]));
|
|
72
|
+
const lowest = (z0, z1) => Math.min(...footSkin.filter(p => p[2] >= z0 && p[2] <= z1).map(p => p[1]));
|
|
73
|
+
const mm = x => Math.round(x * 10) / 10 || 0;
|
|
74
|
+
out.landmarks = {
|
|
75
|
+
// all in bind-pose world cm; the compiler re-expresses them in the Head bone frame
|
|
76
|
+
mouth: [0, mouthY, mouthZ],
|
|
77
|
+
headEllipsoid: { centre: [(hb.x[0] + hb.x[1]) / 2, (hb.y[0] + hb.y[1]) / 2, (hb.z[0] + hb.z[1]) / 2],
|
|
78
|
+
radii: [(hb.x[1] - hb.x[0]) / 2, (hb.y[1] - hb.y[0]) / 2, (hb.z[1] - hb.z[0]) / 2] },
|
|
79
|
+
headJoint: head, headTop: top,
|
|
80
|
+
sole: { ball: mm(toe[1] - lowest(toe[2], (toe[2] + toeEnd[2]) / 2)), tip: mm(toeEnd[1] - lowest(front - 1.5, front)) },
|
|
81
|
+
};
|
|
82
|
+
const file = path.resolve("src/motion3/rigs", `${model}.json`);
|
|
83
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
84
|
+
fs.writeFileSync(file, JSON.stringify(out));
|
|
85
|
+
console.log(JSON.stringify({ file, bones: out.bones.length, verts: P.length, landmarks: out.landmarks }));
|
|
@@ -27,94 +27,6 @@ export function waitForExit(child) {
|
|
|
27
27
|
});
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
function bridgeError(name, port, detail, code) {
|
|
31
|
-
const error = new Error(`${name} on 127.0.0.1:${port} ${detail}`);
|
|
32
|
-
error.code = code;
|
|
33
|
-
return error;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function waitForBridgeReady(child, { name, port, readyType, listenErrorType }, timeoutMs = 5000) {
|
|
37
|
-
return new Promise((resolve, reject) => {
|
|
38
|
-
let settled = false;
|
|
39
|
-
const finish = (callback, value) => {
|
|
40
|
-
if (settled) return;
|
|
41
|
-
settled = true;
|
|
42
|
-
clearTimeout(timeout);
|
|
43
|
-
child.off("message", onMessage);
|
|
44
|
-
child.off("exit", onExit);
|
|
45
|
-
child.off("error", onError);
|
|
46
|
-
callback(value);
|
|
47
|
-
};
|
|
48
|
-
const fail = (detail, code) => finish(reject, bridgeError(name, port, detail, code));
|
|
49
|
-
const onMessage = (message) => {
|
|
50
|
-
if (!message || message.port !== port) return;
|
|
51
|
-
if (message.type === readyType) finish(resolve);
|
|
52
|
-
if (message.type === listenErrorType) {
|
|
53
|
-
fail(`could not listen: ${message.code ?? "unknown error"}`, message.code);
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const onExit = (code, signal) => fail(`exited ${signal ? `from ${signal}` : `with code ${code ?? 0}`}`);
|
|
57
|
-
const onError = (error) => fail(`could not start: ${error.message}`);
|
|
58
|
-
const timeout = setTimeout(() => fail(`did not report readiness within ${timeoutMs} ms`), timeoutMs);
|
|
59
|
-
child.on("message", onMessage);
|
|
60
|
-
child.once("exit", onExit);
|
|
61
|
-
child.once("error", onError);
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export async function startBridge({
|
|
66
|
-
command,
|
|
67
|
-
args,
|
|
68
|
-
cwd,
|
|
69
|
-
env,
|
|
70
|
-
mainPort,
|
|
71
|
-
portEnv = "COZYCLAY_BRIDGE_PORT",
|
|
72
|
-
name = "motion bridge",
|
|
73
|
-
readyType = "cozyclay-bridge-ready",
|
|
74
|
-
listenErrorType = "cozyclay-bridge-listen-error",
|
|
75
|
-
onSpawn,
|
|
76
|
-
onFailure,
|
|
77
|
-
onReady,
|
|
78
|
-
}) {
|
|
79
|
-
const explicitPort = env[portEnv];
|
|
80
|
-
if (explicitPort !== undefined) {
|
|
81
|
-
const port = Number(explicitPort);
|
|
82
|
-
if (!Number.isInteger(port) || port < 1 || port > 65535) {
|
|
83
|
-
throw new Error(`${portEnv}=${JSON.stringify(explicitPort)} is not a valid port`);
|
|
84
|
-
}
|
|
85
|
-
return startBridgeAt(port, true);
|
|
86
|
-
}
|
|
87
|
-
for (let port = mainPort + 1; port <= 65535; port += 1) {
|
|
88
|
-
try {
|
|
89
|
-
return await startBridgeAt(port, false);
|
|
90
|
-
} catch (error) {
|
|
91
|
-
if (error?.code !== "EADDRINUSE") throw error;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
throw new Error(`no free bridge port is available at or above ${mainPort + 1}`);
|
|
95
|
-
|
|
96
|
-
async function startBridgeAt(port, isExplicit) {
|
|
97
|
-
const child = spawnOwned(command, args, {
|
|
98
|
-
cwd,
|
|
99
|
-
env: { ...env, [portEnv]: String(port) },
|
|
100
|
-
stdio: ["inherit", "inherit", "inherit", "ipc"],
|
|
101
|
-
});
|
|
102
|
-
onSpawn?.(child);
|
|
103
|
-
try {
|
|
104
|
-
await waitForBridgeReady(child, { name, port, readyType, listenErrorType });
|
|
105
|
-
onReady?.(child);
|
|
106
|
-
return { child, port };
|
|
107
|
-
} catch (error) {
|
|
108
|
-
onFailure?.(child);
|
|
109
|
-
await terminateOwned(child);
|
|
110
|
-
if (isExplicit && error?.code === "EADDRINUSE") {
|
|
111
|
-
throw new Error(`${portEnv}=${port} is already in use; choose another ${portEnv}`);
|
|
112
|
-
}
|
|
113
|
-
throw error;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
30
|
function signalOwned(child, signal) {
|
|
119
31
|
if (!child || child.exitCode !== null || child.signalCode !== null) return;
|
|
120
32
|
try {
|