cozyclay 2.1.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +60 -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 +3 -3
- 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-msLI71g1.js → first-shot-handoff-CC4xe4HM.js} +1 -1
- package/dist/assets/{landing-ChUvB_zL.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/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 +150 -2624
- 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 +42 -413
- 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/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 +9 -51
- 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/TopBar.jsx +5 -84
- package/src/shell/ViewportToolbar.jsx +10 -70
- 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/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 +19 -16
- package/src/studio-agent-motion.js +9 -9
- package/src/studio-agent-protocol.js +41 -71
- package/src/studio-app-binding.js +25 -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/knip-baseline.json +0 -179
- package/tools/loc-baseline.json +31 -81
- 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 +8 -124
- package/bin/agent/motion-runtime.mjs +0 -76
- package/dist/ardy/cskel27-rest.json +0 -557
- package/dist/assets/analytics-C9pMpW7s.js +0 -1
- package/dist/assets/app-B_2XB9rw.css +0 -1
- package/dist/assets/app-DAuvKPP8.js +0 -4920
- package/dist/assets/config-Bx7pYsD9.js +0 -1
- package/dist/assets/config-DeoFTYzb.css +0 -1
- package/dist/assets/demo-CvKuBgy5.js +0 -1
- package/dist/assets/scene-asset-sync-DKkpjKBV.js +0 -19
- package/dist/assets/scene-asset-sync-DjJ_cJ2R.css +0 -1
- package/dist/assets/ticket-BPk2Ni95.js +0 -1
- package/dist/assets/workflow-jJRBR94Z.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 -182
- 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
|
@@ -2,7 +2,6 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
2
2
|
import { createPortal } from "react-dom";
|
|
3
3
|
import { getAnalyticsOptOut, setAnalyticsOptOut } from "../analytics.js";
|
|
4
4
|
import { loadAutoColor, saveAutoColor } from "../auto-color.js";
|
|
5
|
-
import { motionReadinessMessage } from "../motion-readiness-ui.jsx";
|
|
6
5
|
import { ko, LOCALE, setLocale } from "../locale.js";
|
|
7
6
|
import { readStoredGridView, writeStoredGridView } from "../grid-view.js";
|
|
8
7
|
import { readTheme, saveTheme } from "../theme.js";
|
|
@@ -13,75 +12,31 @@ const LANGUAGES = [
|
|
|
13
12
|
{ id: "ko", label: "한국어", action: "한국어로 전환" },
|
|
14
13
|
];
|
|
15
14
|
|
|
15
|
+
// Only pages whose settings reach the editor are listed; a control that
|
|
16
|
+
// changes nothing is not offered.
|
|
16
17
|
const NAV_GROUPS = [
|
|
17
18
|
{
|
|
18
19
|
label: ko("General", "일반"),
|
|
19
20
|
items: [
|
|
20
21
|
{ id: "Appearance", label: ko("Appearance", "모양") },
|
|
21
22
|
{ id: "Viewport", label: ko("Viewport", "뷰포트") },
|
|
22
|
-
{ id: "Input & Camera", label: ko("Input & Camera", "입력 및 카메라") },
|
|
23
23
|
{ id: "Hotkeys", label: ko("Hotkeys", "단축키") },
|
|
24
24
|
],
|
|
25
25
|
},
|
|
26
|
-
{
|
|
27
|
-
label: ko("Motion", "모션"),
|
|
28
|
-
items: [
|
|
29
|
-
{ id: "ARDY Connection", label: ko("ARDY Connection", "ARDY 연결") },
|
|
30
|
-
{ id: "IK Correction", label: ko("IK Correction", "IK 보정") },
|
|
31
|
-
],
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
label: ko("Integrations", "통합"),
|
|
35
|
-
items: [{ id: "MCP Server", label: ko("MCP Server", "MCP 서버") }],
|
|
36
|
-
},
|
|
37
|
-
{
|
|
38
|
-
label: ko("Project", "프로젝트"),
|
|
39
|
-
items: [
|
|
40
|
-
{ id: "Units & Frame rate", label: ko("Units & Frame rate", "단위 및 프레임 레이트") },
|
|
41
|
-
{ id: "Autosave", label: ko("Autosave", "자동 저장") },
|
|
42
|
-
],
|
|
43
|
-
},
|
|
44
26
|
];
|
|
27
|
+
const NAV_LABELS = Object.fromEntries(NAV_GROUPS.flatMap((group) => group.items.map((item) => [item.id, item.label])));
|
|
28
|
+
|
|
29
|
+
const MOD = typeof navigator !== "undefined" && /Mac|iPhone|iPad/.test(navigator.platform ?? "") ? "⌘" : "Ctrl ";
|
|
45
30
|
|
|
46
31
|
const HOTKEYS = [
|
|
47
32
|
["Move", "W", "이동"],
|
|
48
33
|
["Rotate", "E", "회전"],
|
|
49
34
|
["Scale", "R", "크기 조절"],
|
|
50
35
|
["Frame selection", "F", "선택 프레임"],
|
|
51
|
-
["Duplicate",
|
|
36
|
+
["Duplicate", `${MOD}D`, "복제"],
|
|
52
37
|
["Drop to floor", "End", "바닥에 놓기"],
|
|
53
38
|
];
|
|
54
39
|
|
|
55
|
-
const PREFERENCE_KEYS = Object.freeze({
|
|
56
|
-
grid: "cozyclay.grid-view.v1",
|
|
57
|
-
invertY: "cozyclay.preferences.invert-y.v1",
|
|
58
|
-
orbit: "cozyclay.preferences.orbit-selection.v1",
|
|
59
|
-
snap: "cozyclay.preferences.snapping.v1",
|
|
60
|
-
ctrlSnap: "cozyclay.preferences.ctrl-snapping.v1",
|
|
61
|
-
footLock: "cozyclay.preferences.foot-lock.v1",
|
|
62
|
-
bodyContact: "cozyclay.preferences.body-contact.v1",
|
|
63
|
-
autosave: "cozyclay.preferences.autosave.v1",
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
function readFlag(key, fallback = false) {
|
|
67
|
-
try {
|
|
68
|
-
return localStorage.getItem(key) === "1";
|
|
69
|
-
} catch {
|
|
70
|
-
return fallback;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function writeFlag(key, value) {
|
|
75
|
-
try {
|
|
76
|
-
localStorage.setItem(key, value ? "1" : "0");
|
|
77
|
-
} catch {
|
|
78
|
-
// Viewer preferences are best effort when storage is unavailable.
|
|
79
|
-
}
|
|
80
|
-
if (typeof window !== "undefined") {
|
|
81
|
-
window.dispatchEvent(new CustomEvent("cozyclay:preferences-changed", { detail: { key, value } }));
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
40
|
function PreferenceRow({ title, description, children, testid }) {
|
|
86
41
|
return (
|
|
87
42
|
<div className="v2-preferences__row" data-testid={testid}>
|
|
@@ -94,10 +49,11 @@ function PreferenceRow({ title, description, children, testid }) {
|
|
|
94
49
|
);
|
|
95
50
|
}
|
|
96
51
|
|
|
52
|
+
// A page with one section leaves out its title: the page header already names it.
|
|
97
53
|
function PreferenceSection({ title, children }) {
|
|
98
54
|
return (
|
|
99
55
|
<section className="v2-preferences__section">
|
|
100
|
-
<h2 className="v2-preferences__section-title">{title}</h2>
|
|
56
|
+
{title && <h2 className="v2-preferences__section-title">{title}</h2>}
|
|
101
57
|
<div className="v2-preferences__section-rows">{children}</div>
|
|
102
58
|
</section>
|
|
103
59
|
);
|
|
@@ -120,43 +76,6 @@ function ToggleControl({ pressed, onChange, label, testid }) {
|
|
|
120
76
|
);
|
|
121
77
|
}
|
|
122
78
|
|
|
123
|
-
function SelectControl({ value, options, onChange, label, testid }) {
|
|
124
|
-
const current = options.indexOf(value);
|
|
125
|
-
return (
|
|
126
|
-
<button
|
|
127
|
-
type="button"
|
|
128
|
-
className="v2-preferences__select"
|
|
129
|
-
aria-label={label}
|
|
130
|
-
data-testid={testid}
|
|
131
|
-
onClick={() => onChange(options[(current + 1) % options.length])}
|
|
132
|
-
>
|
|
133
|
-
<span>{value}</span>
|
|
134
|
-
<span className="v2-preferences__select-caret" aria-hidden="true">▾</span>
|
|
135
|
-
</button>
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function RangeControl({ value, min, max, step, label, unit = "", onChange, testid }) {
|
|
140
|
-
const percentage = ((value - min) / (max - min)) * 100;
|
|
141
|
-
return (
|
|
142
|
-
<div className="v2-preferences__range-wrap">
|
|
143
|
-
<input
|
|
144
|
-
type="range"
|
|
145
|
-
className="v2-preferences__range"
|
|
146
|
-
min={min}
|
|
147
|
-
max={max}
|
|
148
|
-
step={step}
|
|
149
|
-
value={value}
|
|
150
|
-
aria-label={label}
|
|
151
|
-
data-testid={testid}
|
|
152
|
-
style={{ "--prefs-range-progress": `${percentage}%` }}
|
|
153
|
-
onChange={(event) => onChange(Number(event.target.value))}
|
|
154
|
-
/>
|
|
155
|
-
<span className="v2-preferences__range-value">{value}{unit}</span>
|
|
156
|
-
</div>
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
79
|
function ReadonlyHotkeys() {
|
|
161
80
|
return (
|
|
162
81
|
<div className="v2-preferences__hotkeys" data-testid="preferences-hotkeys">
|
|
@@ -170,40 +89,6 @@ function ReadonlyHotkeys() {
|
|
|
170
89
|
);
|
|
171
90
|
}
|
|
172
91
|
|
|
173
|
-
function MotionConnection({ state, checking, onRetry }) {
|
|
174
|
-
const unavailable = state === "unavailable";
|
|
175
|
-
const retryLabel = checking
|
|
176
|
-
? ko("Checking…", "확인 중…")
|
|
177
|
-
: unavailable
|
|
178
|
-
? ko("Retry connection", "연결 다시 확인")
|
|
179
|
-
: ko("Check connection", "연결 확인");
|
|
180
|
-
return (
|
|
181
|
-
<div className="v2-preferences__motion-setup" data-testid="motion-setup" data-state={state}>
|
|
182
|
-
<div className="v2-preferences__motion-status" data-state={state} role="status" aria-busy={checking}>
|
|
183
|
-
<span className="v2-preferences__status-dot" aria-hidden="true" />
|
|
184
|
-
<span>{motionReadinessMessage(state)}</span>
|
|
185
|
-
</div>
|
|
186
|
-
<p>{ko(
|
|
187
|
-
"Motion generation is optional. Sample motion, camera editing and exports work without a connection.",
|
|
188
|
-
"모션 생성은 선택 사항이에요. 연결 없이도 샘플 모션, 카메라 편집, 내보내기를 쓸 수 있어요.",
|
|
189
|
-
)}</p>
|
|
190
|
-
<p>{ko(
|
|
191
|
-
"Retry checks the local motion bridge without changing the current scene.",
|
|
192
|
-
"다시 확인해도 현재 씬은 바뀌지 않고 로컬 모션 브리지 상태만 확인해요.",
|
|
193
|
-
)}</p>
|
|
194
|
-
<button
|
|
195
|
-
type="button"
|
|
196
|
-
className="v2-preferences__primary-button"
|
|
197
|
-
data-testid="motion-health-retry"
|
|
198
|
-
disabled={checking}
|
|
199
|
-
onClick={() => onRetry?.()}
|
|
200
|
-
>
|
|
201
|
-
{retryLabel}
|
|
202
|
-
</button>
|
|
203
|
-
</div>
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
92
|
function ThemeControls() {
|
|
208
93
|
const [theme, setTheme] = useState(readTheme);
|
|
209
94
|
const options = [
|
|
@@ -229,15 +114,7 @@ function ThemeControls() {
|
|
|
229
114
|
}
|
|
230
115
|
|
|
231
116
|
function preferenceSection(section, props) {
|
|
232
|
-
const {
|
|
233
|
-
autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState,
|
|
234
|
-
gridView, setGridView, flySpeed, setFlySpeed, sensitivity, setSensitivity,
|
|
235
|
-
orbitSelection, setOrbitSelection, invertY, setInvertY, snapping, setSnapping,
|
|
236
|
-
ctrlSnap, setCtrlSnap, footLock, setFootLock, bodyContact, setBodyContact,
|
|
237
|
-
shading, setShading, gridSize, setGridSize, rotationStep, setRotationStep,
|
|
238
|
-
units, setUnits, frameRate, setFrameRate, autosave, setAutosave,
|
|
239
|
-
motionState, motionChecking, onRetry, cameraTutorial,
|
|
240
|
-
} = props;
|
|
117
|
+
const { autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState, gridView, setGridView, cameraTutorial } = props;
|
|
241
118
|
const languageControls = (
|
|
242
119
|
<div className="v2-preferences__language-controls">
|
|
243
120
|
{LANGUAGES.map((language) => (
|
|
@@ -260,7 +137,7 @@ function preferenceSection(section, props) {
|
|
|
260
137
|
case "Appearance":
|
|
261
138
|
return (
|
|
262
139
|
<>
|
|
263
|
-
<PreferenceSection title={ko("
|
|
140
|
+
<PreferenceSection title={ko("Display", "표시")}>
|
|
264
141
|
<PreferenceRow title={ko("Language", "언어")} description={ko("Choose the labels used throughout the editor.", "에디터에서 사용할 언어를 선택하세요.")}>
|
|
265
142
|
{languageControls}
|
|
266
143
|
</PreferenceRow>
|
|
@@ -286,119 +163,25 @@ function preferenceSection(section, props) {
|
|
|
286
163
|
);
|
|
287
164
|
case "Viewport":
|
|
288
165
|
return (
|
|
289
|
-
<PreferenceSection
|
|
166
|
+
<PreferenceSection>
|
|
290
167
|
<PreferenceRow title={ko("Reference grid", "기준 그리드")} description={ko("Use a dark reference grid instead of the clay deck.", "클레이 데크 대신 어두운 기준 그리드를 사용해요.")}>
|
|
291
168
|
<ToggleControl pressed={gridView} onChange={(value) => { setGridView(value); writeStoredGridView(globalThis.localStorage, value); }} label={ko("Reference grid", "기준 그리드")} testid="preferences-grid" />
|
|
292
169
|
</PreferenceRow>
|
|
293
|
-
<PreferenceRow title={ko("Shading", "셰이딩")} description={ko("Choose the viewport lighting preview.", "뷰포트 조명 미리보기를 선택하세요.")}>
|
|
294
|
-
<SelectControl value={shading} options={[ko("Clay Lit", "클레이 조명"), ko("Solid", "솔리드")]} onChange={setShading} label={ko("Shading mode", "셰이딩 모드")} testid="preferences-shading" />
|
|
295
|
-
</PreferenceRow>
|
|
296
170
|
</PreferenceSection>
|
|
297
171
|
);
|
|
298
|
-
case "Input & Camera":
|
|
299
|
-
return (
|
|
300
|
-
<>
|
|
301
|
-
<PreferenceSection title={ko("Camera", "카메라")}>
|
|
302
|
-
<PreferenceRow title={ko("Fly speed", "비행 속도")} description={ko("Right mouse button + WASD", "마우스 오른쪽 버튼 + WASD")}>
|
|
303
|
-
<RangeControl value={flySpeed} min={1} max={6} step={1} label={ko("Fly speed", "비행 속도")} onChange={setFlySpeed} testid="preferences-fly-speed" />
|
|
304
|
-
</PreferenceRow>
|
|
305
|
-
<PreferenceRow title={ko("Mouse sensitivity", "마우스 감도")} description={ko("Pointer movement while looking around.", "둘러볼 때 포인터 이동 감도예요.")}>
|
|
306
|
-
<RangeControl value={sensitivity} min={0.1} max={1} step={0.05} label={ko("Mouse sensitivity", "마우스 감도")} onChange={setSensitivity} testid="preferences-sensitivity" />
|
|
307
|
-
</PreferenceRow>
|
|
308
|
-
<PreferenceRow title={ko("Orbit around selection", "선택 항목 중심으로 회전")} description={ko("Alt-drag keeps the selected item at the pivot.", "Alt를 누르고 드래그하면 선택 항목을 중심으로 돌아요.")}>
|
|
309
|
-
<ToggleControl pressed={orbitSelection} onChange={(value) => { setOrbitSelection(value); writeFlag(PREFERENCE_KEYS.orbit, value); }} label={ko("Orbit around selection", "선택 항목 중심으로 회전")} testid="preferences-orbit" />
|
|
310
|
-
</PreferenceRow>
|
|
311
|
-
<PreferenceRow title={ko("Invert Y", "Y축 반전")} description={ko("Reverse vertical camera movement.", "카메라의 수직 움직임을 반대로 해요.")}>
|
|
312
|
-
<ToggleControl pressed={invertY} onChange={(value) => { setInvertY(value); writeFlag(PREFERENCE_KEYS.invertY, value); }} label={ko("Invert Y", "Y축 반전")} testid="preferences-invert-y" />
|
|
313
|
-
</PreferenceRow>
|
|
314
|
-
</PreferenceSection>
|
|
315
|
-
<PreferenceSection title={ko("Snapping", "스냅")}>
|
|
316
|
-
<PreferenceRow title={ko("Snapping", "스냅")} description={ko("Keep transforms on the active grid.", "변환을 활성 그리드에 맞춰요.")}>
|
|
317
|
-
<ToggleControl pressed={snapping} onChange={(value) => { setSnapping(value); writeFlag(PREFERENCE_KEYS.snap, value); }} label={ko("Snapping", "스냅")} testid="preferences-snapping" />
|
|
318
|
-
</PreferenceRow>
|
|
319
|
-
<PreferenceRow title={ko("Grid size", "그리드 크기")} description={ko("Stage movement increment.", "스테이지 이동 단위예요.")}>
|
|
320
|
-
<SelectControl value={gridSize} options={["10 cm", "25 cm", "50 cm"]} onChange={setGridSize} label={ko("Grid size", "그리드 크기")} testid="preferences-grid-size" />
|
|
321
|
-
</PreferenceRow>
|
|
322
|
-
<PreferenceRow title={ko("Rotation step", "회전 단위")} description={ko("Stage rotation increment.", "스테이지 회전 단위예요.")}>
|
|
323
|
-
<SelectControl value={rotationStep} options={["15°", "30°", "45°"]} onChange={setRotationStep} label={ko("Rotation step", "회전 단위")} testid="preferences-rotation-step" />
|
|
324
|
-
</PreferenceRow>
|
|
325
|
-
<PreferenceRow title={ko("Ctrl inverts snapping", "Ctrl로 스냅 반전")} description={ko("Hold Ctrl to temporarily reverse snapping.", "Ctrl을 누르면 스냅을 잠시 반대로 적용해요.")}>
|
|
326
|
-
<ToggleControl pressed={ctrlSnap} onChange={(value) => { setCtrlSnap(value); writeFlag(PREFERENCE_KEYS.ctrlSnap, value); }} label={ko("Ctrl inverts snapping", "Ctrl로 스냅 반전")} testid="preferences-ctrl-snapping" />
|
|
327
|
-
</PreferenceRow>
|
|
328
|
-
</PreferenceSection>
|
|
329
|
-
<PreferenceSection title={ko("Hotkeys", "단축키")}>
|
|
330
|
-
<ReadonlyHotkeys />
|
|
331
|
-
</PreferenceSection>
|
|
332
|
-
</>
|
|
333
|
-
);
|
|
334
172
|
case "Hotkeys":
|
|
335
173
|
return (
|
|
336
|
-
<PreferenceSection
|
|
174
|
+
<PreferenceSection>
|
|
337
175
|
<p className="v2-preferences__section-note">{ko("Shortcuts are read-only here. They stay active whenever focus is outside a text field.", "단축키는 여기서 읽기 전용이에요. 텍스트 입력란 밖에서 항상 사용할 수 있어요.")}</p>
|
|
338
176
|
<ReadonlyHotkeys />
|
|
339
177
|
</PreferenceSection>
|
|
340
178
|
);
|
|
341
|
-
case "ARDY Connection":
|
|
342
|
-
return (
|
|
343
|
-
<PreferenceSection title={ko("ARDY Connection", "ARDY 연결")}>
|
|
344
|
-
<PreferenceRow title={ko("Motion setup", "모션 설정")} description={ko("Check today's motion generation route.", "현재 모션 생성 경로를 확인해요.")}>
|
|
345
|
-
<span className="v2-preferences__value">{motionReadinessMessage(motionState)}</span>
|
|
346
|
-
</PreferenceRow>
|
|
347
|
-
<div className="v2-preferences__row v2-preferences__row--full">
|
|
348
|
-
<MotionConnection state={motionState} checking={motionChecking} onRetry={onRetry} />
|
|
349
|
-
</div>
|
|
350
|
-
</PreferenceSection>
|
|
351
|
-
);
|
|
352
|
-
case "IK Correction":
|
|
353
|
-
return (
|
|
354
|
-
<PreferenceSection title={ko("IK Correction", "IK 보정")}>
|
|
355
|
-
<PreferenceRow title={ko("Foot lock", "발 고정")} description={ko("Keep planted feet stable through the take.", "테이크 전체에서 발을 안정적으로 고정해요.")}>
|
|
356
|
-
<ToggleControl pressed={footLock} onChange={(value) => { setFootLock(value); writeFlag(PREFERENCE_KEYS.footLock, value); }} label={ko("Foot lock", "발 고정")} testid="preferences-foot-lock" />
|
|
357
|
-
</PreferenceRow>
|
|
358
|
-
<PreferenceRow title={ko("Body contact", "신체 접촉")} description={ko("Keep contact points when applying corrections.", "보정을 적용할 때 접촉 지점을 유지해요.")}>
|
|
359
|
-
<ToggleControl pressed={bodyContact} onChange={(value) => { setBodyContact(value); writeFlag(PREFERENCE_KEYS.bodyContact, value); }} label={ko("Body contact", "신체 접촉")} testid="preferences-body-contact" />
|
|
360
|
-
</PreferenceRow>
|
|
361
|
-
</PreferenceSection>
|
|
362
|
-
);
|
|
363
|
-
case "MCP Server":
|
|
364
|
-
return (
|
|
365
|
-
<PreferenceSection title={ko("MCP Server", "MCP 서버")}>
|
|
366
|
-
<PreferenceRow title={ko("Status", "상태")} description={ko("Agent connections are managed by the running studio.", "에이전트 연결은 실행 중인 스튜디오가 관리해요.")}>
|
|
367
|
-
<span className="v2-preferences__status-value"><span className="v2-preferences__status-dot is-muted" aria-hidden="true" />{ko("Not connected", "연결되지 않음")}</span>
|
|
368
|
-
</PreferenceRow>
|
|
369
|
-
<PreferenceRow title={ko("Port", "포트")} description={ko("The local command endpoint.", "로컬 명령 엔드포인트예요.")}>
|
|
370
|
-
<span className="v2-preferences__value v2-preferences__value--mono">8765</span>
|
|
371
|
-
</PreferenceRow>
|
|
372
|
-
</PreferenceSection>
|
|
373
|
-
);
|
|
374
|
-
case "Units & Frame rate":
|
|
375
|
-
return (
|
|
376
|
-
<PreferenceSection title={ko("Units & Frame rate", "단위 및 프레임 레이트")}>
|
|
377
|
-
<PreferenceRow title={ko("Units", "단위")} description={ko("Display distances in the inspector.", "인스펙터에서 거리를 표시하는 단위예요.")}>
|
|
378
|
-
<SelectControl value={units} options={[ko("Centimeters", "센티미터"), ko("Meters", "미터")]} onChange={setUnits} label={ko("Units", "단위")} testid="preferences-units" />
|
|
379
|
-
</PreferenceRow>
|
|
380
|
-
<PreferenceRow title={ko("Frame rate", "프레임 레이트")} description={ko("Playback and timeline frame rate.", "재생 및 타임라인 프레임 레이트예요.")}>
|
|
381
|
-
<SelectControl value={frameRate} options={["24 fps", "30 fps", "60 fps"]} onChange={setFrameRate} label={ko("Frame rate", "프레임 레이트")} testid="preferences-frame-rate" />
|
|
382
|
-
</PreferenceRow>
|
|
383
|
-
</PreferenceSection>
|
|
384
|
-
);
|
|
385
|
-
case "Autosave":
|
|
386
|
-
return (
|
|
387
|
-
<PreferenceSection title={ko("Autosave", "자동 저장")}>
|
|
388
|
-
<PreferenceRow title={ko("Autosave", "자동 저장")} description={ko("Save a project snapshot after an edit settles.", "편집이 끝나면 프로젝트 스냅샷을 저장해요.")}>
|
|
389
|
-
<ToggleControl pressed={autosave} onChange={(value) => { setAutosave(value); writeFlag(PREFERENCE_KEYS.autosave, value); }} label={ko("Autosave", "자동 저장")} testid="preferences-autosave" />
|
|
390
|
-
</PreferenceRow>
|
|
391
|
-
<PreferenceRow title={ko("Interval", "간격")} description={ko("The current editor default.", "현재 에디터 기본값이에요.")}>
|
|
392
|
-
<span className="v2-preferences__value">2 min</span>
|
|
393
|
-
</PreferenceRow>
|
|
394
|
-
</PreferenceSection>
|
|
395
|
-
);
|
|
396
179
|
default:
|
|
397
180
|
return null;
|
|
398
181
|
}
|
|
399
182
|
}
|
|
400
183
|
|
|
401
|
-
export default function PreferencesDialog({ open, onClose,
|
|
184
|
+
export default function PreferencesDialog({ open, onClose, initialSection = "Appearance", cameraTutorial }) {
|
|
402
185
|
const dialogRef = useRef(null);
|
|
403
186
|
const searchRef = useRef(null);
|
|
404
187
|
const closeRef = useRef(onClose);
|
|
@@ -408,24 +191,6 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
|
|
|
408
191
|
const [analyticsOptOut, setAnalyticsOptOutState] = useState(getAnalyticsOptOut);
|
|
409
192
|
const [autoColor, setAutoColor] = useState(() => loadAutoColor());
|
|
410
193
|
const [gridView, setGridView] = useState(() => readStoredGridView(globalThis.localStorage));
|
|
411
|
-
const [flySpeed, setFlySpeed] = useState(3);
|
|
412
|
-
const [sensitivity, setSensitivity] = useState(0.55);
|
|
413
|
-
const [orbitSelection, setOrbitSelection] = useState(() => readFlag(PREFERENCE_KEYS.orbit, true));
|
|
414
|
-
const [invertY, setInvertY] = useState(() => readFlag(PREFERENCE_KEYS.invertY));
|
|
415
|
-
const [snapping, setSnapping] = useState(() => readFlag(PREFERENCE_KEYS.snap, true));
|
|
416
|
-
const [ctrlSnap, setCtrlSnap] = useState(() => readFlag(PREFERENCE_KEYS.ctrlSnap, true));
|
|
417
|
-
const [footLock, setFootLock] = useState(() => readFlag(PREFERENCE_KEYS.footLock, true));
|
|
418
|
-
const [bodyContact, setBodyContact] = useState(() => readFlag(PREFERENCE_KEYS.bodyContact, true));
|
|
419
|
-
const [shading, setShading] = useState(() => ko("Clay Lit", "클레이 조명"));
|
|
420
|
-
const [gridSize, setGridSize] = useState("10 cm");
|
|
421
|
-
const [rotationStep, setRotationStep] = useState("15°");
|
|
422
|
-
const [units, setUnits] = useState(() => ko("Centimeters", "센티미터"));
|
|
423
|
-
const [frameRate, setFrameRate] = useState("24 fps");
|
|
424
|
-
const [autosave, setAutosave] = useState(() => readFlag(PREFERENCE_KEYS.autosave, true));
|
|
425
|
-
const setupProps = motionSetup?.props ?? {};
|
|
426
|
-
const motionState = setupProps.state ?? "unavailable";
|
|
427
|
-
const motionChecking = setupProps.checking === true;
|
|
428
|
-
const onRetry = setupProps.onRetry;
|
|
429
194
|
|
|
430
195
|
const filteredGroups = useMemo(() => {
|
|
431
196
|
const term = query.trim().toLocaleLowerCase();
|
|
@@ -468,16 +233,7 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
|
|
|
468
233
|
}, [open, initialSection]);
|
|
469
234
|
|
|
470
235
|
if (!open || typeof document === "undefined") return null;
|
|
471
|
-
const currentProps = {
|
|
472
|
-
autoColor, setAutoColor, analyticsOptOut,
|
|
473
|
-
setAnalyticsOptOutState,
|
|
474
|
-
gridView, setGridView, flySpeed, setFlySpeed, sensitivity, setSensitivity,
|
|
475
|
-
orbitSelection, setOrbitSelection, invertY, setInvertY, snapping, setSnapping,
|
|
476
|
-
ctrlSnap, setCtrlSnap, footLock, setFootLock, bodyContact, setBodyContact,
|
|
477
|
-
shading, setShading, gridSize, setGridSize, rotationStep, setRotationStep,
|
|
478
|
-
units, setUnits, frameRate, setFrameRate, autosave, setAutosave,
|
|
479
|
-
motionState, motionChecking, onRetry, cameraTutorial,
|
|
480
|
-
};
|
|
236
|
+
const currentProps = { autoColor, setAutoColor, analyticsOptOut, setAnalyticsOptOutState, gridView, setGridView, cameraTutorial };
|
|
481
237
|
|
|
482
238
|
return createPortal(
|
|
483
239
|
<div className="v2-preferences" data-testid="preferences-dialog-backdrop" onPointerDown={(event) => { if (event.target === event.currentTarget) closeRef.current?.(); }}>
|
|
@@ -520,12 +276,7 @@ export default function PreferencesDialog({ open, onClose, motionSetup, initialS
|
|
|
520
276
|
</aside>
|
|
521
277
|
<main className="v2-preferences__content">
|
|
522
278
|
<header className="v2-preferences__content-header">
|
|
523
|
-
<h1 id="v2-preferences-title">{
|
|
524
|
-
<button type="button" className="v2-preferences__reset" data-testid="preferences-reset" onClick={() => {
|
|
525
|
-
setFlySpeed(3); setSensitivity(0.55); setOrbitSelection(true); setInvertY(false); setSnapping(true); setCtrlSnap(true);
|
|
526
|
-
setShading(ko("Clay Lit", "클레이 조명")); setGridSize("10 cm"); setRotationStep("15°"); setUnits(ko("Centimeters", "센티미터")); setFrameRate("24 fps"); setAutosave(true);
|
|
527
|
-
writeFlag(PREFERENCE_KEYS.orbit, true); writeFlag(PREFERENCE_KEYS.invertY, false); writeFlag(PREFERENCE_KEYS.snap, true); writeFlag(PREFERENCE_KEYS.ctrlSnap, true); writeFlag(PREFERENCE_KEYS.autosave, true);
|
|
528
|
-
}}>{ko("Reset to defaults", "기본값으로 재설정")}</button>
|
|
279
|
+
<h1 id="v2-preferences-title">{NAV_LABELS[activeSection] ?? activeSection}</h1>
|
|
529
280
|
</header>
|
|
530
281
|
<div className="v2-preferences__content-scroll">
|
|
531
282
|
{preferenceSection(activeSection, currentProps)}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { useEffect, useRef } from "react";
|
|
2
2
|
import { flushSync } from "react-dom";
|
|
3
3
|
import SettingsMenu from "../settings-menu.jsx";
|
|
4
|
-
import { MotionSetup } from "../motion-readiness-ui.jsx";
|
|
5
4
|
import { useStudioShell } from "./studio-shell-context.js";
|
|
6
5
|
|
|
7
6
|
// Temporary adapter until the Preferences region replaces SettingsMenu.
|
|
@@ -10,9 +9,7 @@ import { useStudioShell } from "./studio-shell-context.js";
|
|
|
10
9
|
// the shell context, without mounting a second copy or changing SettingsMenu.
|
|
11
10
|
export default function PreferencesSlot() {
|
|
12
11
|
const {
|
|
13
|
-
preferencesOpen, setPreferencesOpen,
|
|
14
|
-
trailReadinessState, lineReadinessState, readinessState, bridgeChecking,
|
|
15
|
-
recheckMotionHealth,
|
|
12
|
+
preferencesOpen, setPreferencesOpen,
|
|
16
13
|
} = useStudioShell();
|
|
17
14
|
const hostRef = useRef(null);
|
|
18
15
|
useEffect(() => {
|
|
@@ -31,10 +28,7 @@ export default function PreferencesSlot() {
|
|
|
31
28
|
}, [preferencesOpen]);
|
|
32
29
|
return (
|
|
33
30
|
<div className="preferences-slot" ref={hostRef}>
|
|
34
|
-
<SettingsMenu
|
|
35
|
-
motionSetupReveal={motionSetupReveal}
|
|
36
|
-
motionSetup={<MotionSetup state={motionSetupKind === "trail" ? trailReadinessState : motionSetupKind === "line" ? lineReadinessState : readinessState} checking={bridgeChecking} onRetry={recheckMotionHealth} />}
|
|
37
|
-
/>
|
|
31
|
+
<SettingsMenu />
|
|
38
32
|
</div>
|
|
39
33
|
);
|
|
40
34
|
}
|
package/src/shell/TopBar.jsx
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { useRef, useState } from "react";
|
|
2
1
|
import { useStudioShell } from "./studio-shell-context.js";
|
|
3
2
|
import ProjectPanel from "../panels/ProjectPanel.jsx";
|
|
4
|
-
import MenuBar
|
|
3
|
+
import MenuBar from "./MenuBar.jsx";
|
|
5
4
|
import { SaveState } from "./StatusBar.jsx";
|
|
6
|
-
import { ko
|
|
5
|
+
import { ko } from "../locale.js";
|
|
7
6
|
import "./topbar.css";
|
|
8
7
|
|
|
9
|
-
// 2a top bar: File/Edit/Window/Help, then
|
|
10
|
-
//
|
|
8
|
+
// 2a top bar: File/Edit/Window/Help, then the MCP state. Motion is authored by the
|
|
9
|
+
// agent (motion.compile), so there is no generate button. Save and Export live in File (G7). #570: the project name
|
|
11
10
|
// and its save state head the left column (ProjectHead below).
|
|
12
11
|
export default function TopBar({ preferences }) {
|
|
13
|
-
const { recState, liveHubStatus, liveWorkspaceHandle
|
|
12
|
+
const { recState, liveHubStatus, liveWorkspaceHandle } = useStudioShell();
|
|
14
13
|
const connected = liveHubStatus === "connected";
|
|
15
14
|
return (
|
|
16
15
|
<header className="topbar v2-topbar" data-rec-state={recState}>
|
|
@@ -25,7 +24,6 @@ export default function TopBar({ preferences }) {
|
|
|
25
24
|
<i className="topbar-mcp-dot" aria-hidden="true" />
|
|
26
25
|
<span className="topbar-mcp-text">{connected ? ko("MCP connected", "MCP 연결됨") : ko("MCP offline", "MCP 꺼짐")}</span>
|
|
27
26
|
</span>
|
|
28
|
-
{previsMode !== "storyboard" && <GenerateMotion />}
|
|
29
27
|
</header>
|
|
30
28
|
);
|
|
31
29
|
}
|
|
@@ -65,80 +63,3 @@ function PrevisModeBadge({ mode }) {
|
|
|
65
63
|
</span>
|
|
66
64
|
);
|
|
67
65
|
}
|
|
68
|
-
|
|
69
|
-
// "Generate Motion" is today's Scene generate (G6) and the one home for
|
|
70
|
-
// generation (IS-2): with authored prompt blocks it runs them all, as the
|
|
71
|
-
// removed Details "Generate all blocks" did; otherwise it runs the prompt.
|
|
72
|
-
// The caret holds the take bar's Scene actions; a refused action says why in
|
|
73
|
-
// place and in a toast (R3).
|
|
74
|
-
function GenerateMotion() {
|
|
75
|
-
const {
|
|
76
|
-
runArdy, sceneGenerateDisabledReason, sceneAgainDisabledReason, runSceneAgain,
|
|
77
|
-
addSceneBlock, tlFrame, setToast, ardyRunning, promptClips, runStudioAction,
|
|
78
|
-
} = useStudioShell();
|
|
79
|
-
const hasBlocks = promptClips.some((clip) => clip.text.trim());
|
|
80
|
-
const [open, setOpen] = useState(false);
|
|
81
|
-
const caretRef = useRef(null);
|
|
82
|
-
const reason = sceneGenerateDisabledReason();
|
|
83
|
-
const actions = [
|
|
84
|
-
{ id: "new", label: ko("Start over", "새로 만들기"), reason, run: () => runArdy({ fresh: true }) },
|
|
85
|
-
{ id: "again", label: ko("Take it again", "다시 뽑기"), reason: sceneAgainDisabledReason(), run: runSceneAgain },
|
|
86
|
-
{ id: "block", label: isKo ? `프레임 ${tlFrame}에 블록 추가` : `Add block at frame ${tlFrame}`, reason: "", run: addSceneBlock },
|
|
87
|
-
];
|
|
88
|
-
return (
|
|
89
|
-
<div className="topbar-generate" role="group" aria-label={ko("Generate Motion", "모션 생성")}>
|
|
90
|
-
<button
|
|
91
|
-
type="button"
|
|
92
|
-
className="topbar-generate-main"
|
|
93
|
-
data-testid="topbar-generate"
|
|
94
|
-
aria-disabled={reason ? "true" : undefined}
|
|
95
|
-
data-disabled-reason={reason || undefined}
|
|
96
|
-
title={reason || ko("Generate motion from the prompt and blocks", "프롬프트와 블록으로 모션을 생성합니다")}
|
|
97
|
-
onClick={() => (reason ? setToast(reason) : hasBlocks ? runStudioAction("motion.generateAllBlocks") : runArdy())}
|
|
98
|
-
>
|
|
99
|
-
{ardyRunning ? ko("Generating…", "생성 중…") : (
|
|
100
|
-
<>
|
|
101
|
-
<span className="topbar-generate-full">{ko("Generate Motion", "모션 생성")}</span>
|
|
102
|
-
<span className="topbar-generate-short">{ko("Generate", "생성")}</span>
|
|
103
|
-
</>
|
|
104
|
-
)}
|
|
105
|
-
</button>
|
|
106
|
-
<button
|
|
107
|
-
type="button"
|
|
108
|
-
className="topbar-generate-caret"
|
|
109
|
-
data-testid="topbar-generate-menu"
|
|
110
|
-
ref={caretRef}
|
|
111
|
-
aria-haspopup="menu"
|
|
112
|
-
aria-expanded={open}
|
|
113
|
-
aria-label={ko("More generate actions", "생성 작업 더 보기")}
|
|
114
|
-
onClick={() => setOpen((value) => !value)}
|
|
115
|
-
>
|
|
116
|
-
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M6 9l6 6 6-6" /></svg>
|
|
117
|
-
</button>
|
|
118
|
-
{open && (
|
|
119
|
-
<MenuPopover anchorRef={caretRef} align="end" onClose={() => setOpen(false)} label={ko("Generate actions", "생성 작업")}>
|
|
120
|
-
{actions.map((action) => (
|
|
121
|
-
<button
|
|
122
|
-
type="button"
|
|
123
|
-
role="menuitem"
|
|
124
|
-
key={action.id}
|
|
125
|
-
className="menubar-item"
|
|
126
|
-
data-generate-action={action.id}
|
|
127
|
-
disabled={Boolean(action.reason)}
|
|
128
|
-
aria-disabled={action.reason ? "true" : undefined}
|
|
129
|
-
data-disabled-reason={action.reason || undefined}
|
|
130
|
-
onClick={() => {
|
|
131
|
-
setOpen(false);
|
|
132
|
-
if (action.reason) setToast(action.reason);
|
|
133
|
-
else action.run();
|
|
134
|
-
}}
|
|
135
|
-
>
|
|
136
|
-
<span className="menubar-item-label">{action.label}</span>
|
|
137
|
-
{action.reason && <small className="menubar-item-reason">{action.reason}</small>}
|
|
138
|
-
</button>
|
|
139
|
-
))}
|
|
140
|
-
</MenuPopover>
|
|
141
|
-
)}
|
|
142
|
-
</div>
|
|
143
|
-
);
|
|
144
|
-
}
|