@forgeax-extension/character-3d 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/SOURCE_PROVENANCE.md +8 -0
  2. package/dist/assets/index-CIx3aXo1.js +4336 -0
  3. package/dist/assets/index-CIx3aXo1.js.map +1 -0
  4. package/dist/assets/index-CmhOHLEB.css +1 -0
  5. package/dist/hdr/README.md +28 -0
  6. package/dist/hdr/presets.json +8 -0
  7. package/dist/index.html +13 -0
  8. package/forgeax-extension.json +428 -0
  9. package/marketplace-card.json +56 -0
  10. package/package.json +59 -0
  11. package/packages/external-asset-meta/package.json +24 -0
  12. package/packages/external-asset-meta/src/cook.test.ts +211 -0
  13. package/packages/external-asset-meta/src/cook.ts +188 -0
  14. package/packages/external-asset-meta/src/draco3dgltf.d.ts +11 -0
  15. package/packages/external-asset-meta/src/index.ts +18 -0
  16. package/packages/external-asset-meta/src/normalize.test.ts +36 -0
  17. package/packages/external-asset-meta/src/normalize.ts +101 -0
  18. package/packages/external-asset-meta/src/types.ts +82 -0
  19. package/schemas/adopt-playable-character.args.json +26 -0
  20. package/schemas/adopt-playable-character.returns.json +31 -0
  21. package/schemas/apply-motion.args.json +47 -0
  22. package/schemas/apply-motion.returns.json +23 -0
  23. package/schemas/auto-rig.args.json +35 -0
  24. package/schemas/auto-rig.returns.json +23 -0
  25. package/schemas/delete-asset.args.json +18 -0
  26. package/schemas/delete-asset.returns.json +18 -0
  27. package/schemas/engine-import-status.args.json +18 -0
  28. package/schemas/engine-import-status.returns.json +50 -0
  29. package/schemas/export-playable-character.args.json +21 -0
  30. package/schemas/export-playable-character.returns.json +47 -0
  31. package/schemas/gen3d-asset-manifest.json +281 -0
  32. package/schemas/generate-meshy-text-mock.args.json +42 -0
  33. package/schemas/generate-meshy-text-mock.returns.json +301 -0
  34. package/schemas/get-credentials.args.json +7 -0
  35. package/schemas/get-credentials.returns.json +45 -0
  36. package/schemas/get-playable-profile.args.json +11 -0
  37. package/schemas/get-playable-profile.returns.json +188 -0
  38. package/schemas/image-to-3d.args.json +47 -0
  39. package/schemas/image-to-3d.returns.json +306 -0
  40. package/schemas/import-to-engine.args.json +18 -0
  41. package/schemas/import-to-engine.returns.json +35 -0
  42. package/schemas/list-assets.args.json +22 -0
  43. package/schemas/list-assets.returns.json +296 -0
  44. package/schemas/list-motions.args.json +29 -0
  45. package/schemas/list-motions.returns.json +41 -0
  46. package/schemas/pose-standardization.args.json +28 -0
  47. package/schemas/pose-standardization.returns.json +29 -0
  48. package/schemas/provider-status.args.json +7 -0
  49. package/schemas/provider-status.returns.json +70 -0
  50. package/schemas/refine-mesh.args.json +33 -0
  51. package/schemas/refine-mesh.returns.json +306 -0
  52. package/schemas/rename-asset.args.json +22 -0
  53. package/schemas/rename-asset.returns.json +14 -0
  54. package/schemas/retopo-lowpoly.args.json +34 -0
  55. package/schemas/retopo-lowpoly.returns.json +24 -0
  56. package/schemas/score-quality.args.json +36 -0
  57. package/schemas/score-quality.returns.json +12 -0
  58. package/schemas/set-credentials.args.json +32 -0
  59. package/schemas/set-credentials.returns.json +45 -0
  60. package/schemas/set-playable-motion-mapping.args.json +25 -0
  61. package/schemas/set-playable-motion-mapping.returns.json +33 -0
  62. package/schemas/set-playable-profile.args.json +32 -0
  63. package/schemas/set-playable-profile.returns.json +67 -0
  64. package/schemas/text-to-3d.args.json +51 -0
  65. package/schemas/text-to-3d.returns.json +306 -0
  66. package/schemas/upload-image.args.json +19 -0
  67. package/schemas/upload-image.returns.json +21 -0
  68. package/schemas/upload-video.args.json +14 -0
  69. package/schemas/upload-video.returns.json +14 -0
  70. package/schemas/views-to-3d.args.json +58 -0
  71. package/schemas/views-to-3d.returns.json +306 -0
  72. package/server/adopt-playable-character.ts +291 -0
  73. package/server/asset-storage.ts +136 -0
  74. package/server/asset-upload.ts +123 -0
  75. package/server/audit.ts +58 -0
  76. package/server/cache.ts +75 -0
  77. package/server/cos-uploader.ts +141 -0
  78. package/server/credentials-store.ts +186 -0
  79. package/server/engine-import.ts +238 -0
  80. package/server/env.ts +287 -0
  81. package/server/export-playable-character.ts +364 -0
  82. package/server/generate.ts +89 -0
  83. package/server/merge-playable-character.ts +259 -0
  84. package/server/motion-catalog.ts +137 -0
  85. package/server/per-game-store.ts +1016 -0
  86. package/server/providers/gateway-client.ts +171 -0
  87. package/server/providers/gateway-data.ts +182 -0
  88. package/server/providers/gateway-models.ts +49 -0
  89. package/server/providers/hunyuan-rest.ts +317 -0
  90. package/server/providers/hunyuan-workflow.ts +225 -0
  91. package/server/providers/meshy-direct-client.ts +223 -0
  92. package/server/providers/meshy.ts +548 -0
  93. package/server/providers/rodin-gateway.ts +193 -0
  94. package/server/providers/rodin.ts +253 -0
  95. package/server/providers/visvise.ts +329 -0
  96. package/server/rate-guard.ts +29 -0
  97. package/server/tool-handlers.ts +2193 -0
  98. package/shared/catalog.ts +307 -0
  99. package/shared/manifest.ts +378 -0
  100. package/shared/meshy-actions.ts +690 -0
  101. package/shared/playable-preview-url.test.ts +14 -0
  102. package/shared/playable-preview-url.ts +13 -0
  103. package/shared/playable-profile.test.ts +127 -0
  104. package/shared/playable-profile.ts +171 -0
  105. package/shared/provider-params.test.ts +172 -0
  106. package/shared/provider-params.ts +389 -0
  107. package/shared/quality/heuristics.test.ts +84 -0
  108. package/shared/quality/heuristics.ts +100 -0
  109. package/shared/rodin-image.test.ts +51 -0
  110. package/shared/rodin-image.ts +125 -0
@@ -0,0 +1 @@
1
+ :root{color-scheme:dark;--prim-space-2: 2px;--prim-space-4: 4px;--prim-space-6: 6px;--prim-space-8: 8px;--prim-space-10: 10px;--prim-space-12: 12px;--prim-space-16: 16px;--prim-space-20: 20px;--prim-color-neutral-0: #FFFFFF;--prim-color-neutral-550: #737373;--prim-color-neutral-750: #404040;--prim-color-neutral-800: #333333;--prim-color-neutral-850: #242424;--prim-color-neutral-900: #191919;--prim-color-neutral-950: #0D0D0D;--prim-color-neutral-1000: #000000;--prim-color-lime-300: #DFFF78;--prim-color-lime-400: #D4FF48;--prim-color-lime-700: #6A7F24;--prim-color-blue-400: #639CF8;--prim-color-green-400: #4FD17F;--prim-color-green-600: #1B9D4B;--prim-color-yellow-600: #BA8E06;--prim-color-red-400: #F26A6A;--prim-color-red-600: #BE3636;--prim-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", system-ui, sans-serif;--prim-font-mono: "Fira Mono", "JetBrains Mono", "SF Mono", "Menlo", ui-monospace, monospace;--prim-radius-4: 4px;--prim-radius-6: 6px;--prim-radius-8: 8px;--prim-radius-12: 12px;--prim-radius-16: 16px;--prim-radius-24: 24px;--prim-radius-full: 9999px;--color-text-primary: var(--prim-color-neutral-0);--color-text-secondary: rgba(255, 255, 255, .6);--color-text-tertiary: rgba(255, 255, 255, .3);--color-text-disabled: rgba(255, 255, 255, .2);--color-text-on-bright-primary: var(--prim-color-neutral-1000);--color-text-on-bright: var(--color-text-on-bright-primary);--color-icon-primary: var(--color-text-primary);--color-icon-secondary: var(--color-text-secondary);--color-icon-tertiary: var(--color-text-tertiary);--color-icon-on-bright-primary: var(--color-text-on-bright-primary);--color-background-canvas: var(--prim-color-neutral-950);--color-background-base: var(--prim-color-neutral-900);--color-background-elevated: var(--prim-color-neutral-850);--color-background-floating: var(--prim-color-neutral-800);--color-border-subtle: var(--prim-color-neutral-800);--color-border-default: var(--prim-color-neutral-750);--color-border-strong: var(--prim-color-neutral-550);--color-border-focus: var(--prim-color-lime-400);--color-divider-strong: rgba(255, 255, 255, .15);--color-divider-default: rgba(255, 255, 255, .1);--color-divider-subtle: rgba(255, 255, 255, .05);--color-brand-primary: var(--prim-color-lime-400);--color-brand-primary-light: var(--prim-color-lime-300);--color-brand-primary-soft: var(--prim-color-lime-700);--color-brand-primary-hover: #C5F038;--color-brand-soft: rgba(212, 255, 72, .1);--color-brand-line: color-mix(in srgb, var(--color-brand-primary) 38%, transparent);--primary: var(--color-brand-primary);--primary-bg: var(--color-brand-soft);--color-accent-blue-default: var(--prim-color-blue-400);--color-accent-green-default: var(--prim-color-green-400);--color-accent-green: var(--prim-color-green-400);--color-accent-error: var(--prim-color-red-400);--color-status-success: var(--prim-color-green-600);--color-status-warning: var(--prim-color-yellow-600);--color-status-error: var(--prim-color-red-600);--color-status-amber: #F5B243;--color-status-warning-text: #FFC966;--color-overlay-modal: rgba(0, 0, 0, .5);--color-overlay-focus: rgba(212, 255, 72, .3);--color-interaction-hover: rgba(255, 255, 255, .05);--color-interaction-selected-brand: rgba(212, 255, 72, .1);--color-interaction-selected-neutral: rgba(255, 255, 255, .1);--color-interaction-disabled: rgba(0, 0, 0, .5);--color-interaction-error: rgba(255, 107, 107, .08);--z-content: 0;--z-raised: 1;--z-sticky: 10;--z-dropdown: 100;--z-popover: 1000;--z-app-modal: 10000;--z-app-modal-top: 10010;--z-menu: 10100;--z-toast: 10150;--z-tooltip: 10200;--color-border-brand: var(--color-brand-primary);--color-border-error: var(--color-status-error);--color-text-error: var(--color-status-error);--font-sans: var(--prim-font-sans);--font-mono: var(--prim-font-mono);--radius-sm: var(--prim-radius-4);--radius-md: var(--prim-radius-8);--radius-lg: var(--prim-radius-12);--radius-xl: var(--prim-radius-16);--radius-2xl: var(--prim-radius-24);--radius-pill: var(--prim-radius-full);--g3-side-w: 320px;--g3-control-h: 32px;--g3-workbar-h: 42px;--motion-duration-instant: 80ms;--motion-duration-fast: .11s;--motion-duration-base: .15s;--motion-duration-smooth: .19s;--motion-duration-panel: .22s;--motion-duration-pulse: 1.4s;--motion-fast: var(--motion-duration-fast);--motion-ease-out: cubic-bezier(.16, 1, .3, 1);--motion-ease-standard: cubic-bezier(.2, .8, .2, 1);--motion-press-scale: .996;--motion-hover-y: -1px;--motion-row-x: 1.5px;--motion-shadow-hover: 0 4px 12px rgba(0, 0, 0, .14);--motion-shadow-active: 0 1px 6px rgba(0, 0, 0, .12)}*{box-sizing:border-box}html,body,#root{width:100%;height:100%;margin:0}body{background:var(--color-background-canvas);color:var(--color-text-primary);font-family:var(--font-sans);font-size:13px;overflow:hidden}button,input,select,textarea{font:inherit}button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible,summary:focus-visible{outline:2px solid var(--color-brand-primary);outline-offset:2px}.gx-root{display:flex;width:100%;height:100%;min-width:0;min-height:0;color:var(--color-text-primary);background:var(--color-background-canvas)}.gx-root--left,.gx-root--left .gx-left,.gx-root--center,.gx-root--center .gx-center,.gx-root--standalone{width:100%;height:100%;min-height:0}.gx-root--standalone .gx-left{flex:0 0 var(--g3-side-w);width:var(--g3-side-w);border-right:1px solid var(--color-divider-default)}.gx-left{display:flex;flex-direction:column;min-height:0;width:100%;height:100%;background:var(--color-background-base)}.gx-center{display:flex;flex-direction:column;position:relative;min-width:0;min-height:0;flex:1 1 0;width:100%;height:100%;background:var(--color-background-canvas);overflow:hidden}body[data-pane=left] .gx-left,body[data-pane=center] .gx-center{height:100%;min-height:0}.workbench-pane-header{display:flex;align-items:center;gap:8px;padding:14px 16px;border-bottom:1px solid rgba(255,255,255,.07);flex:0 0 auto}.workbench-pane-title{min-width:0;color:var(--color-brand-primary);font-size:15px;font-weight:700;line-height:normal;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.workbench-pane-pill{margin-left:auto;padding:3px 8px;border:1px solid color-mix(in srgb,var(--color-brand-primary) 28%,transparent);border-radius:999px;background:color-mix(in srgb,var(--color-brand-primary) 8%,transparent);color:var(--color-brand-primary);font-size:10px;font-weight:700;line-height:normal;white-space:nowrap}button.workbench-pane-pill{display:inline-flex;align-items:center;gap:5px;cursor:pointer;transition:background var(--motion-duration-base) var(--motion-ease-out),border-color var(--motion-duration-base) var(--motion-ease-out)}button.workbench-pane-pill:hover{background:color-mix(in srgb,var(--color-brand-primary) 16%,transparent);border-color:color-mix(in srgb,var(--color-brand-primary) 50%,transparent)}button.workbench-pane-pill:focus-visible{outline:2px solid var(--color-brand-primary);outline-offset:1px}.workbench-pane-scroll{flex:1 1 0;min-height:0;overflow:auto;scrollbar-width:thin;scrollbar-color:rgba(212,255,72,.24) transparent}.workbench-pane-scroll::-webkit-scrollbar{width:6px;height:6px}.workbench-pane-scroll::-webkit-scrollbar-track{background:transparent}.workbench-pane-scroll::-webkit-scrollbar-thumb{background:#d4ff482e;border-radius:999px}.workbench-pane-scroll::-webkit-scrollbar-thumb:hover{background:#d4ff4857}.g3-setup,.gx-setup{min-height:0;display:flex;flex-direction:column;flex:1 1 0;background:var(--color-background-base)}.g3-setup-scroll,.gx-setup{min-height:0;flex:1 1 0;overflow:auto;padding:var(--prim-space-12);display:flex;flex-direction:column;gap:var(--prim-space-8)}.g3-setup-scroll>*{flex-shrink:0}.gx-setup{overflow:visible}.g3-setup-footer,.gx-action-row{padding:var(--prim-space-12);border-top:1px solid var(--color-divider-default);display:flex;flex-direction:column;gap:var(--prim-space-8);background:var(--color-background-base);flex:0 0 auto}.gx-action-row{flex-direction:row;flex-wrap:wrap;justify-content:flex-end;align-items:center;padding:var(--prim-space-10) var(--prim-space-12)}.g3-setup-footer .g3-btn,.g3-setup-footer .fx-btn,.gx-action-row .g3-btn,.gx-action-row .fx-btn{width:100%;min-height:36px}.gx-action-row .g3-btn,.gx-action-row .fx-btn{min-width:132px}.g3-setup-error{display:flex;align-items:flex-start;gap:var(--prim-space-8);padding:var(--prim-space-8);border:1px solid var(--color-border-error);border-radius:var(--radius-md);background:var(--color-interaction-error);color:var(--color-accent-error)}.g3-setup-error>svg{flex:0 0 auto;margin-top:1px}.g3-setup-error-body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}.g3-setup-error-title{font-size:11px;font-weight:700}.g3-setup-error-copy{margin:0;font-size:10px;line-height:1.45;color:var(--color-text-secondary);max-height:7em;overflow-y:auto;overflow-wrap:anywhere;-webkit-user-select:text;user-select:text}.g3-setup-error .g3-icon-btn{width:22px;height:22px;flex:0 0 auto}.g3-step{border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);background:var(--color-background-base);overflow:hidden;transition:border-color var(--motion-duration-fast) var(--motion-ease-out),background var(--motion-duration-fast) var(--motion-ease-out)}.g3-step.is-open{border-color:var(--color-border-default);background:var(--color-background-elevated)}.g3-step-trigger{width:100%;min-height:46px;padding:var(--prim-space-8) var(--prim-space-10);border:0;background:transparent;color:var(--color-text-primary);display:grid;grid-template-columns:24px minmax(0,1fr) auto;align-items:center;gap:var(--prim-space-8);text-align:left;cursor:pointer}.g3-step-trigger:hover{background:var(--color-interaction-hover)}.g3-step-index{width:24px;height:24px;display:grid;place-items:center;border:1px solid var(--color-border-default);border-radius:var(--radius-pill);color:var(--color-text-secondary);font:600 10px var(--font-mono)}.g3-step.is-open .g3-step-index{border-color:var(--color-brand-primary);background:var(--color-brand-soft);color:var(--color-brand-primary)}.g3-step-copy{display:flex;flex-direction:column;gap:1px;min-width:0}.g3-step-name{display:block;font-size:12px;font-weight:650}.g3-step-summary{display:block;margin-top:1px;color:var(--color-text-tertiary);font-size:10px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.g3-step-chevron{color:var(--color-text-tertiary);transition:transform var(--motion-duration-base) var(--motion-ease-out)}.g3-step.is-open .g3-step-chevron{transform:rotate(180deg)}.g3-step-body{padding:0 var(--prim-space-10) var(--prim-space-10);display:flex;flex-direction:column;gap:var(--prim-space-10)}.g3-label,.field-label{display:flex;align-items:center;justify-content:space-between;gap:var(--prim-space-6);margin:var(--prim-space-10) 0 var(--prim-space-6);color:var(--color-text-secondary);font-size:10px;font-weight:650}.field>.field-label,.field>.g3-label{margin-top:0}.g3-optional{color:var(--color-text-tertiary);font-weight:400}.g3-field-help,.step-note{margin:0;margin-top:var(--prim-space-4);color:var(--color-text-tertiary);font-size:9px;line-height:1.45}.step-note{font-size:10px;color:var(--color-text-secondary);line-height:1.5}.step-note--warn{color:var(--color-status-amber)}.field{display:flex;flex-direction:column;gap:var(--prim-space-6)}.field-count{color:var(--color-text-tertiary);font-size:10px}.g3-segmented,.fx-segmented{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);grid-template-columns:none;gap:var(--prim-space-4);padding:var(--prim-space-4);border-radius:var(--radius-md);background:var(--color-background-canvas)}.fx-segmented{grid-auto-flow:column;grid-auto-columns:1fr;grid-template-columns:none;gap:var(--prim-space-6);padding:0;background:transparent}.g3-segmented button,.fx-segmented-btn{min-height:28px;padding:0 var(--prim-space-6);border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-secondary);font-size:11px;cursor:pointer;transition:background var(--motion-duration-fast) var(--motion-ease-out),border-color var(--motion-duration-fast) var(--motion-ease-out),color var(--motion-duration-fast) var(--motion-ease-out)}.fx-segmented-btn{display:inline-flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-4);min-height:46px;padding:var(--prim-space-6) var(--prim-space-4);border-color:var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating)}.g3-segmented button:hover,.fx-segmented-btn:hover:not(.is-selected):not(.is-active){background:var(--color-interaction-hover);color:var(--color-text-primary)}.g3-segmented button.is-active,.fx-segmented-btn.is-selected,.fx-segmented-btn.is-active{border-color:var(--color-brand-line);background:var(--color-brand-soft);color:var(--color-brand-primary)}.fx-segmented-btn:active{transform:scale(var(--motion-press-scale))}.g3-input,.g3-select,.g3-textarea,.fx-input,.fx-textarea,.adv-select{width:100%;border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-canvas);color:var(--color-text-primary);outline:2px solid transparent;outline-offset:1px;transition:border-color var(--motion-duration-fast) var(--motion-ease-out)}.g3-input,.g3-select,.fx-input,.adv-select{min-height:var(--g3-control-h);padding:0 var(--prim-space-10)}.adv-select{padding:var(--prim-space-6) var(--prim-space-8);font-size:12px}.g3-textarea,.fx-textarea{min-height:84px;padding:var(--prim-space-8) var(--prim-space-10);resize:vertical;line-height:1.45}.fx-textarea--lg{min-height:132px}.g3-input::placeholder,.g3-textarea::placeholder,.fx-input::placeholder,.fx-textarea::placeholder{color:var(--color-text-tertiary)}.g3-input:focus-visible,.g3-select:focus-visible,.g3-textarea:focus-visible,.fx-input:focus-visible,.fx-textarea:focus-visible,.adv-select:focus-visible{border-color:var(--color-brand-primary);outline-color:var(--color-brand-primary)}.g3-check,.fx-check{display:flex;align-items:center;gap:var(--prim-space-6);color:var(--color-text-secondary);font-size:10px;cursor:pointer}.fx-check{gap:var(--prim-space-8);font-size:12px}.g3-check input,.fx-check input{margin:0;width:15px;height:15px;accent-color:var(--color-brand-primary)}.image-input-row{display:flex;align-items:stretch;gap:var(--prim-space-6)}.image-input-row .g3-input,.image-input-row .fx-input{flex:1 1 auto;min-width:0}.image-input-row .g3-btn,.image-input-row .fx-btn{flex:0 0 auto;white-space:nowrap}.g3-view-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--prim-space-6)}.g3-drop{position:relative;min-height:82px;border:1px dashed var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-canvas);color:var(--color-text-tertiary);overflow:hidden;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-4);transition:border-color var(--motion-duration-fast) var(--motion-ease-out),background var(--motion-duration-fast) var(--motion-ease-out)}.g3-drop:hover,.g3-drop.is-dragover{border-color:var(--color-brand-primary);background:var(--color-brand-soft);color:var(--color-text-secondary)}.g3-drop:focus-within{outline:2px solid var(--color-brand-primary);outline-offset:2px}.g3-drop.is-filled{border-style:solid;border-color:var(--color-border-default)}.g3-drop input{position:absolute;inline-size:1px;block-size:1px;opacity:0;pointer-events:none}.g3-drop-preview{position:absolute;top:0;right:0;bottom:0;left:0;display:none;background:linear-gradient(150deg,var(--color-background-floating),var(--color-background-canvas))}.g3-drop.is-filled .g3-drop-preview{display:block}.g3-drop-preview img{width:100%;height:100%;object-fit:cover;opacity:.72}.g3-drop-preview:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(180deg,transparent 48%,color-mix(in srgb,var(--color-background-canvas) 88%,transparent))}.g3-drop-label{position:relative;z-index:var(--z-raised);font-size:10px;font-weight:650}.g3-drop-meta{position:relative;z-index:var(--z-raised);font-size:9px}.g3-btn,.fx-btn{min-height:30px;padding:0 var(--prim-space-10);border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:transparent;color:var(--color-text-secondary);display:inline-flex;align-items:center;justify-content:center;gap:var(--prim-space-6);font-size:11px;font-weight:600;cursor:pointer;white-space:nowrap;transition:background var(--motion-duration-fast) var(--motion-ease-out),border-color var(--motion-duration-fast) var(--motion-ease-out),color var(--motion-duration-fast) var(--motion-ease-out),transform var(--motion-duration-instant) linear,box-shadow var(--motion-duration-smooth) var(--motion-ease-out)}.g3-btn:hover:not(:disabled),.fx-btn:hover:not(:disabled){border-color:var(--color-border-strong);background:var(--color-interaction-hover);color:var(--color-text-primary)}.g3-btn:active:not(:disabled),.fx-btn:active:not(:disabled){transform:scale(var(--motion-press-scale))}.g3-btn:disabled,.fx-btn:disabled{cursor:not-allowed;color:var(--color-text-disabled);border-color:var(--color-border-subtle);opacity:.55}.g3-btn.is-active{border-color:var(--color-brand-primary);color:var(--color-brand-primary);background:color-mix(in srgb,var(--color-brand-primary) 12%,transparent)}.g3-btn.is-primary,.fx-btn--primary{border-color:var(--color-brand-primary);background:var(--color-brand-primary);color:var(--color-text-on-bright);font-weight:650}.g3-btn.is-primary:hover:not(:disabled),.fx-btn--primary:hover:not(:disabled),.fx-btn--primary:active:not(:disabled),.fx-btn--primary:focus-visible{border-color:var(--color-brand-primary-hover);background:var(--color-brand-primary-hover);color:var(--color-text-on-bright)}.g3-btn.is-primary svg,.fx-btn--primary svg{color:var(--color-icon-on-bright-primary)}.g3-btn.is-danger,.fx-btn--danger{border-color:color-mix(in srgb,var(--color-status-error) 55%,var(--color-border-default));color:var(--color-accent-error)}.fx-btn--sm{min-height:28px;padding:0 var(--prim-space-10);font-size:12px}.fx-btn--ghost{border-color:transparent;background:transparent;color:var(--color-text-secondary)}.fx-btn--ghost:hover:not(:disabled){background:var(--color-interaction-hover);color:var(--color-text-primary)}.g3-icon-btn,.fx-icon-btn{width:28px;height:28px;border:0;border-radius:var(--radius-md);background:transparent;color:var(--color-text-secondary);display:grid;place-items:center;cursor:pointer;flex:0 0 auto;transition:background var(--motion-duration-fast) var(--motion-ease-out),color var(--motion-duration-fast) var(--motion-ease-out),border-color var(--motion-duration-fast) var(--motion-ease-out)}.fx-icon-btn{width:26px;height:26px;border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-icon-secondary)}.g3-icon-btn:hover,.fx-icon-btn:hover{background:var(--color-interaction-hover);color:var(--color-text-primary)}.fx-icon-btn:hover{color:var(--color-brand-primary);border-color:var(--color-border-strong)}.g3-icon-btn.is-active{background:var(--color-brand-soft);color:var(--color-brand-primary)}.g3-advanced,.adv-params{margin-top:var(--prim-space-10);border-top:1px solid var(--color-divider-subtle);padding-top:var(--prim-space-8)}.g3-advanced summary,.adv-params-summary{color:var(--color-text-secondary);cursor:pointer;font-size:10px;-webkit-user-select:none;user-select:none;display:flex;align-items:center;gap:var(--prim-space-6)}.adv-params-summary{font-size:12px}.g3-advanced-grid,.adv-params-body{margin-top:var(--prim-space-8);display:grid;gap:var(--prim-space-8)}.g3-advanced-grid{grid-template-columns:1fr}.slot-primary-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--prim-space-8)}.slot-primary-btn{min-height:32px;padding:0 var(--prim-space-12)}.slot-secondary-link{color:var(--color-text-secondary);border-style:dashed}.status-chip{display:inline-flex;align-items:center;gap:var(--prim-space-6);min-height:28px;padding:0 var(--prim-space-10);border-radius:var(--radius-md);border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-text-secondary);font-size:11px;line-height:1.3}.status-chip--ok{border-color:color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default)}.status-chip--warn{border-color:color-mix(in srgb,var(--color-status-amber) 40%,transparent);background:color-mix(in srgb,var(--color-status-amber) 12%,transparent);color:var(--color-status-amber)}button.status-chip{width:100%;cursor:pointer;text-align:left;transition:filter var(--motion-duration-base) var(--motion-ease-out)}button.status-chip:hover{filter:brightness(1.12)}.status-chip-key{margin-left:auto;opacity:.7}.gx-center-scroll{flex:1 1 0;min-height:0;overflow:auto;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-brand-primary) 24%,transparent) transparent}.gx-center-scroll::-webkit-scrollbar{width:6px;height:6px}.gx-center-scroll::-webkit-scrollbar-track{background:transparent}.gx-center-scroll::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-brand-primary) 18%,transparent);border-radius:var(--radius-pill)}.gx-center-scroll::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-brand-primary) 34%,transparent)}.gx-center-stage{display:grid;grid-template-columns:minmax(0,1fr) minmax(220px,280px);gap:var(--prim-space-12);align-items:stretch;padding:var(--prim-space-12);min-height:0;flex:1 1 0;min-width:0;height:100%}.gx-center-stage.is-rail-collapsed{grid-template-columns:minmax(0,1fr)}.gx-maincol,.g3-workspace{display:grid;grid-template-rows:auto minmax(144px,1fr) auto auto auto;min-width:0;min-height:0;height:100%;position:relative;background:var(--color-background-canvas)}.gx-workspace{display:flex;flex-direction:column;gap:var(--prim-space-12);min-width:0;min-height:0}.gx-center-toolbar{display:flex;flex-wrap:wrap;gap:var(--prim-space-8);align-items:center;grid-column:1 / -1}.gx-maincol>.gx-center-toolbar{grid-column:auto;margin-bottom:var(--prim-space-8)}.gx-asset-rail{display:flex;flex-direction:column;gap:var(--prim-space-12);min-width:0;min-height:0;overflow:auto;position:sticky;top:0;align-self:start;max-height:100%}.gx-rightcol{display:flex;flex-direction:column;gap:var(--prim-space-12);min-width:0}.g3-workbar{min-height:var(--g3-workbar-h);height:var(--g3-workbar-h);padding:var(--prim-space-6) var(--prim-space-12);border-bottom:1px solid var(--color-divider-default);display:flex;align-items:center;gap:var(--prim-space-6);background:var(--color-background-base);flex:0 0 auto;min-width:0;width:100%;overflow-x:auto;overflow-y:hidden}.g3-workbar:has(.mv-popover){overflow:visible}.g3-workbar,.g3-actionbar{scrollbar-width:none}.g3-workbar::-webkit-scrollbar,.g3-actionbar::-webkit-scrollbar{display:none}.g3-workbar-spacer,.g3-spacer,.g3-action-spacer{flex:1}.g3-view-tabs{display:flex;align-items:center;gap:var(--prim-space-2);flex-shrink:0}.g3-view-tab{min-height:28px;padding:0 var(--prim-space-8);border:0;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-secondary);font-size:10px;white-space:nowrap;flex-shrink:0;cursor:pointer}.g3-view-tab:hover:not(:disabled){background:var(--color-interaction-hover);color:var(--color-text-primary)}.g3-view-tab.is-active{background:var(--color-interaction-selected-neutral);color:var(--color-text-primary)}.g3-view-tab:disabled{color:var(--color-text-disabled);cursor:not-allowed}.g3-toolbar-select{min-height:28px;max-width:94px;padding:0 var(--prim-space-8);border:1px solid var(--color-border-subtle);border-radius:var(--prim-radius-6);background:var(--color-background-canvas);color:var(--color-text-secondary);font-size:9px}.g3-viewport{position:relative;min-height:0;overflow:hidden;background:radial-gradient(circle at 50% 34%,var(--color-background-elevated),var(--color-background-canvas) 72%)}.g3-viewport .model-viewer{min-height:0}.g3-viewport:focus-visible{outline:2px solid var(--color-border-focus);outline-offset:-2px}.g3-viewport canvas{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;display:block}.g3-viewport .model-viewer,.g3-viewport>.model-viewer{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;border:0;border-radius:0}.g3-viewport-hint{position:absolute;z-index:var(--z-raised);left:var(--prim-space-12);bottom:var(--prim-space-12);padding:var(--prim-space-4) var(--prim-space-8);border:1px solid var(--color-divider-default);border-radius:var(--radius-pill);background:color-mix(in srgb,var(--color-background-base) 76%,transparent);color:var(--color-text-tertiary);font-size:9px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);pointer-events:none}.g3-state-overlay{position:absolute;z-index:var(--z-sticky);top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;padding:var(--prim-space-20);background:color-mix(in srgb,var(--color-background-canvas) 78%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.g3-state-overlay[hidden]{display:none}.g3-state-card{width:min(360px,100%);padding:var(--prim-space-16);border:1px solid var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-base);box-shadow:var(--motion-shadow-hover);text-align:center}.g3-state-icon{width:34px;height:34px;margin:0 auto var(--prim-space-10);border-radius:var(--radius-pill);display:grid;place-items:center;background:var(--color-interaction-selected-neutral);color:var(--color-text-secondary)}.g3-state-icon.is-running:before{content:"";width:16px;height:16px;border:2px solid var(--color-divider-strong);border-top-color:var(--color-brand-primary);border-radius:50%;animation:g3Spin var(--motion-duration-pulse) linear infinite}.g3-state-icon.is-error{background:color-mix(in srgb,var(--color-status-error) 18%,transparent);color:var(--color-accent-error)}.g3-state-title{font-size:13px;font-weight:700}.g3-state-copy{margin-top:var(--prim-space-4);color:var(--color-text-secondary);font-size:11px;line-height:1.5}.g3-state-stage{margin-top:var(--prim-space-10);color:var(--color-brand-primary);font:10px var(--font-mono)}.g3-state-actions{margin-top:var(--prim-space-12);display:flex;justify-content:center;gap:var(--prim-space-6);flex-wrap:wrap}.g3-result{border-top:1px solid var(--color-divider-default);background:var(--color-background-base);flex:0 0 auto}.g3-result-head{min-height:48px;padding:var(--prim-space-8) var(--prim-space-12);display:flex;align-items:center;gap:var(--prim-space-8);flex-wrap:wrap}.g3-result-main{min-width:0;flex:1}.g3-result-name{color:var(--color-text-primary);font-size:12px;font-weight:700}.g3-result-path{margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-tertiary);font:9px var(--font-mono)}.g3-chip{min-height:20px;padding:0 var(--prim-space-8);border-radius:var(--radius-pill);background:var(--color-interaction-selected-neutral);color:var(--color-text-secondary);display:inline-flex;align-items:center;gap:var(--prim-space-4);font-size:9px;font-weight:650;white-space:nowrap}.g3-chip.is-success{background:color-mix(in srgb,var(--color-status-success) 20%,transparent);color:var(--color-accent-green)}.g3-chip.is-warning{background:color-mix(in srgb,var(--color-status-warning) 22%,transparent);color:var(--color-status-warning-text)}.g3-metrics{display:grid;grid-template-columns:repeat(6,minmax(0,1fr));border-top:1px solid var(--color-divider-subtle)}.g3-metric{min-width:0;padding:var(--prim-space-8) var(--prim-space-12);border-right:1px solid var(--color-divider-subtle)}.g3-metric:last-child{border-right:0}.g3-metric b{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-primary);font:600 10px var(--font-mono)}.g3-metric span{display:block;margin-top:1px;color:var(--color-text-tertiary);font-size:9px}.g3-advanced-panel{display:flex;flex-direction:column;min-height:0;max-height:min(42vh,320px);border-top:1px solid var(--color-divider-default);background:var(--color-background-elevated);overflow:hidden}.g3-advanced-panel-head{flex:0 0 auto;display:flex;align-items:center;justify-content:space-between;gap:var(--prim-space-8);padding:var(--prim-space-8) var(--prim-space-12);border-bottom:1px solid var(--color-divider-default);color:var(--color-text-primary);font-size:12px;font-weight:700}.g3-advanced-panel-body{flex:1 1 auto;min-height:0;overflow:auto;padding:var(--prim-space-12)}.g3-actionbar{min-height:48px;padding:var(--prim-space-8) var(--prim-space-12);border-top:1px solid var(--color-divider-default);background:var(--color-background-base);display:flex;align-items:center;gap:var(--prim-space-6);flex-wrap:nowrap;flex:0 0 auto;min-width:0;width:100%;overflow-x:auto;overflow-y:hidden}.g3-actionbar:has(.g3-more[open]){overflow:visible}.g3-actionbar .g3-btn,.g3-actionbar .fx-btn{min-height:30px}.g3-action-requirement{color:var(--color-text-tertiary);font-size:9px}.g3-more{position:relative}.g3-more>summary{list-style:none;cursor:pointer}.g3-more>summary::-webkit-details-marker{display:none}.g3-more-menu{position:absolute;z-index:var(--z-popover);right:0;bottom:calc(100% + var(--prim-space-6));min-width:148px;padding:var(--prim-space-6);border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);box-shadow:var(--motion-shadow-hover);display:flex;flex-direction:column;gap:var(--prim-space-4)}.g3-more-menu .g3-btn{width:100%;justify-content:flex-start;border-color:transparent}.g3-drawer{position:absolute;z-index:var(--z-popover);top:var(--g3-workbar-h);right:0;bottom:0;width:min(340px,48%);border-left:1px solid var(--color-border-default);background:var(--color-background-base);box-shadow:var(--motion-shadow-hover);transform:translate(100%);transition:transform var(--motion-duration-panel) var(--motion-ease-out);display:flex;flex-direction:column}.g3-drawer[hidden]{display:none}.g3-drawer-scrim{position:absolute;top:0;right:0;bottom:0;left:0;z-index:calc(var(--z-popover) - 1);background:color-mix(in srgb,var(--color-overlay-modal) 60%,transparent)}.g3-drawer.is-open{transform:translate(0)}.g3-drawer-head{min-height:46px;padding:var(--prim-space-8) var(--prim-space-12);border-bottom:1px solid var(--color-divider-default);display:flex;align-items:center;gap:var(--prim-space-8);flex:0 0 auto}.g3-drawer-title{flex:1;font-size:12px;font-weight:700}.g3-drawer-body{min-height:0;flex:1;overflow:auto;padding:var(--prim-space-12)}.g3-drawer-foot{padding:var(--prim-space-12);border-top:1px solid var(--color-divider-default);display:flex;justify-content:flex-end;gap:var(--prim-space-6);flex:0 0 auto}.gx-quality-drawer{position:absolute;top:0;right:0;bottom:0;left:0;z-index:var(--z-popover);display:flex;justify-content:flex-end;background:color-mix(in srgb,var(--color-background-canvas) 35%,transparent);pointer-events:auto}.gx-quality-drawer-panel{width:min(340px,48%);height:100%;display:flex;flex-direction:column;background:var(--color-background-base);border-left:1px solid var(--color-border-default);box-shadow:var(--motion-shadow-hover);min-height:0;animation:g3DrawerIn var(--motion-duration-panel) var(--motion-ease-out) both}.gx-quality-drawer-head{display:flex;align-items:center;gap:var(--prim-space-8);padding:var(--prim-space-12) var(--prim-space-14, 14px);border-bottom:1px solid var(--color-border-subtle);flex:0 0 auto}.gx-quality-drawer-title{font-size:13px;font-weight:700;color:var(--color-text-primary)}.gx-quality-drawer-head .fx-icon-btn,.gx-quality-drawer-head .g3-icon-btn{margin-left:auto}.gx-quality-drawer-body{flex:1 1 0;min-height:0;overflow:auto;padding:var(--prim-space-12)}@keyframes g3DrawerIn{0%{transform:translate(100%)}to{transform:translate(0)}}.g3-modal{position:fixed;z-index:var(--z-app-modal);top:0;right:0;bottom:0;left:0;display:grid;place-items:center;padding:var(--prim-space-20);background:var(--color-overlay-modal);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px)}.g3-modal[hidden]{display:none}.g3-modal-panel,.g3-modal-card{width:min(420px,100%);border:1px solid var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-elevated);box-shadow:var(--motion-shadow-hover);display:flex;flex-direction:column;max-height:100%;overflow:hidden}.g3-modal-head{padding:var(--prim-space-16);border-bottom:1px solid var(--color-divider-default);display:flex;align-items:center;gap:var(--prim-space-8);flex:0 0 auto}.g3-modal-title{flex:1;display:inline-flex;align-items:center;gap:var(--prim-space-8);font-size:14px;font-weight:750;color:var(--color-text-primary)}.g3-modal-title svg{color:var(--color-brand-primary)}.g3-modal-body{padding:var(--prim-space-16);color:var(--color-text-secondary);font-size:11px;line-height:1.55;min-height:0;overflow:auto}.g3-modal-foot,.g3-modal-actions{padding:var(--prim-space-12) var(--prim-space-16);border-top:1px solid var(--color-divider-default);display:flex;justify-content:flex-end;gap:var(--prim-space-8);flex:0 0 auto}.g3-modal-kicker{color:var(--color-status-warning-text);font-size:9px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.g3-confirm-cost{margin-top:var(--prim-space-12);padding:var(--prim-space-10);border-radius:var(--radius-md);background:var(--color-background-canvas);display:flex;align-items:center;justify-content:space-between;gap:var(--prim-space-10)}.g3-confirm-cost b{color:var(--color-status-warning-text);font:700 12px var(--font-mono)}.g3-notice{padding:var(--prim-space-10);border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);background:var(--color-background-elevated);color:var(--color-text-secondary);font-size:10px;line-height:1.5}.g3-notice.is-warning{border-color:color-mix(in srgb,var(--color-status-warning) 45%,var(--color-border-subtle));background:color-mix(in srgb,var(--color-status-warning) 10%,var(--color-background-elevated));color:var(--color-status-warning-text)}.g3-visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:-1px!important;overflow:hidden!important;clip:rect(0,0,0,0)!important;white-space:nowrap!important;border:0!important}@keyframes g3Spin{to{transform:rotate(360deg)}}.ws-header{display:flex;flex-direction:column;gap:2px}.ws-eyebrow{color:var(--color-text-tertiary);font-size:11px;font-weight:650;letter-spacing:.02em;text-transform:uppercase}.ws-title{margin:0;font-size:18px;font-weight:700;line-height:1.2}.gx-card{border:1px solid var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-elevated);padding:var(--prim-space-12)}.gx-card-title{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:650}.gx-card-title svg{color:var(--color-icon-secondary)}.gx-card-title .fx-icon-btn,.gx-card-title .g3-icon-btn{margin-left:auto}.result-ops{display:flex;flex-direction:column;gap:var(--prim-space-10);padding-top:var(--prim-space-4);border-top:1px solid var(--color-border-subtle)}.result-ops-head{font-size:12px;font-weight:700;color:var(--color-text-secondary)}.playable-fold{border:1px solid var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-elevated);padding:var(--prim-space-8) var(--prim-space-10)}.playable-fold-summary{cursor:pointer;font-size:12px;font-weight:650;color:var(--color-text-primary);list-style:none}.playable-fold-summary::-webkit-details-marker{display:none}.playable-fold[open] .playable-fold-summary{margin-bottom:var(--prim-space-8);padding-bottom:var(--prim-space-8);border-bottom:1px solid var(--color-border-subtle)}.result-card{display:flex;flex-direction:column;gap:var(--prim-space-12)}.result-card-head{display:flex;align-items:center;justify-content:space-between;gap:var(--prim-space-10)}.result-card-id{display:flex;flex-direction:column;gap:2px;min-width:0}.result-card-id strong{font-size:13px;font-weight:650}.result-card-id span{color:var(--color-text-secondary);font-size:11px}.badge-row{display:flex;gap:var(--prim-space-6);flex-wrap:wrap}.badge{display:inline-flex;align-items:center;min-height:22px;padding:0 9px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-text-secondary);font-size:10px;white-space:nowrap}.badge--mock{border-color:color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default)}.badge--real{border-color:color-mix(in srgb,var(--color-status-amber) 40%,transparent);background:color-mix(in srgb,var(--color-status-amber) 12%,transparent);color:var(--color-status-amber)}.badge--cache{border-color:color-mix(in srgb,var(--color-accent-blue-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-blue-default) 10%,transparent);color:var(--color-accent-blue-default)}.manifest-facts{display:grid;grid-template-columns:110px minmax(0,1fr);gap:var(--prim-space-12);margin:0;align-items:start}.manifest-facts dl{display:grid;gap:var(--prim-space-8);margin:0;min-width:0}.manifest-facts dl>div{border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);padding:7px 9px;min-width:0}.manifest-facts dt{margin:0;color:var(--color-text-tertiary);font-size:10px;text-transform:uppercase;letter-spacing:.02em}.manifest-facts dd{margin:3px 0 0;font-size:12px;font-weight:600}.mono{font-family:var(--font-mono);word-break:break-all}.preview-thumb{width:110px;height:110px;border-radius:var(--radius-lg);border:1px solid var(--color-border-default);object-fit:cover;background:var(--color-background-floating)}.preview-thumb--empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-6);color:var(--color-text-tertiary);font-size:10px;text-align:center}.pose-result{display:flex;gap:var(--prim-space-10);align-items:flex-start}.pose-result .preview-thumb{width:84px;height:84px}.pose-result-meta{display:flex;flex-direction:column;align-items:flex-start;gap:var(--prim-space-8);min-width:0}.gx-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-10);padding:28px 18px;border:1px dashed var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-base);text-align:center}.gx-state svg{color:var(--color-icon-tertiary)}.gx-state-title{font-size:13px;font-weight:600}.gx-state-copy{margin:0;color:var(--color-text-secondary);font-size:12px;line-height:1.5;max-width:36ch}.gx-error{border:1px solid color-mix(in srgb,var(--color-status-error) 50%,transparent);border-radius:var(--radius-lg);background:var(--color-interaction-error);padding:var(--prim-space-12);display:flex;flex-direction:column;gap:var(--prim-space-8)}.gx-error-head{display:flex;align-items:center;gap:7px;color:var(--color-status-error);font-weight:650;font-size:13px}.gx-error-msg{margin:0;color:var(--color-text-secondary);font-size:12px;line-height:1.5;word-break:break-word}.gx-error-actions{display:flex;gap:var(--prim-space-8)}.gx-spin{animation:gx-spin .9s linear infinite;color:var(--color-brand-primary)}@keyframes gx-spin{to{transform:rotate(360deg)}}.model-viewer{position:relative;width:100%;height:100%;min-height:144px;border:1px solid var(--color-border-default);border-radius:var(--radius-lg);overflow:hidden;background:var(--color-background-canvas)}.gx-maincol>.model-viewer,.g3-workspace>.model-viewer,.result-card>.model-viewer{flex:1 1 auto;min-height:144px;height:auto;align-self:stretch}.model-viewer-canvas{width:100%;height:100%}.model-viewer-canvas canvas{display:block;width:100%;height:100%}.model-viewer-overlay{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;font-size:12px;color:var(--color-text-secondary);pointer-events:none}.model-viewer-overlay--error{color:var(--color-status-error)}.model-viewer-toolbar{position:absolute;top:var(--prim-space-8);right:var(--prim-space-8);display:flex;gap:var(--prim-space-6);z-index:var(--z-raised)}.mv-toggle,.mv-bg-seg>button{font-size:11px;line-height:1;padding:5px 9px;border-radius:var(--radius-sm);border:1px solid var(--color-border-default);background:color-mix(in srgb,var(--color-background-canvas) 70%,transparent);color:var(--color-text-secondary);cursor:pointer;-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);transition:background var(--motion-duration-fast) var(--motion-ease-out),color var(--motion-duration-fast) var(--motion-ease-out),border-color var(--motion-duration-fast) var(--motion-ease-out)}.mv-toggle:hover:not(:disabled),.mv-bg-seg>button:hover:not(:disabled){color:var(--color-text-primary)}.mv-toggle.is-on,.mv-bg-seg>button.is-active{border-color:var(--color-border-brand);background:var(--color-interaction-selected-brand);color:var(--color-text-primary)}.mv-toggle:disabled,.mv-bg-seg>button:disabled{opacity:.4;cursor:not-allowed}.model-viewer-clips{position:absolute;top:var(--prim-space-8);left:var(--prim-space-8);display:flex;flex-wrap:wrap;gap:var(--prim-space-6);max-width:calc(100% - 180px);z-index:var(--z-raised)}.model-viewer-info{position:absolute;left:var(--prim-space-8);bottom:var(--prim-space-8);display:flex;gap:var(--prim-space-10);font-size:11px;color:var(--color-text-secondary);padding:5px 9px;border-radius:var(--radius-sm);background:color-mix(in srgb,var(--color-background-canvas) 70%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);pointer-events:none;z-index:var(--z-raised)}.model-viewer--empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-10);width:100%;height:100%;min-height:144px;border:1px dashed var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-base);color:var(--color-text-tertiary);font-size:12px}.model-viewer--empty svg{color:var(--color-icon-tertiary)}.mv-view-row{position:absolute;bottom:var(--prim-space-8);right:var(--prim-space-8);display:flex;gap:var(--prim-space-4);flex-wrap:wrap;z-index:var(--z-raised)}.mv-settings-wrap{position:relative}.mv-popover{position:absolute;right:0;top:calc(100% + var(--prim-space-6));z-index:var(--z-dropdown);display:grid;gap:var(--prim-space-10);width:240px;padding:var(--prim-space-12);border:1px solid var(--color-border-strong);border-radius:var(--radius-md);background:var(--color-background-floating);box-shadow:var(--motion-shadow-hover)}.mv-popover label,.mv-popover .mv-setting-group{display:grid;gap:var(--prim-space-4);font-size:11px;color:var(--color-text-secondary)}.mv-popover input[type=range]{width:100%;accent-color:var(--color-brand-primary)}.mv-popover select{border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);color:var(--color-text-primary);padding:5px 8px}.mv-wire-seg,.mv-bg-seg{display:flex;gap:var(--prim-space-4)}.lib-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(116px,1fr));gap:var(--prim-space-8);margin-top:var(--prim-space-10)}.lib-card{position:relative;border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);overflow:hidden}.lib-card-main{display:block;width:100%;text-align:left;background:none;border:none;padding:0;color:inherit;cursor:pointer}.lib-card-thumb{position:relative;aspect-ratio:1 / 1;background:var(--color-background-canvas)}.lib-card-thumb img{width:100%;height:100%;object-fit:cover;display:block}.lib-card-thumb--empty{width:100%;height:100%;display:flex;align-items:center;justify-content:center;color:var(--color-icon-tertiary)}.lib-card-thumb .lib-tag{position:absolute;top:5px;left:5px}.lib-card-caption{margin:6px 8px 2px;font-size:12px;line-height:1.35;color:var(--color-text-primary);overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;position:relative}.lib-card-rename-btn{opacity:0;display:inline-flex;vertical-align:middle;margin-left:3px;padding:1px;transition:opacity var(--motion-duration-fast);color:var(--color-text-tertiary)}.lib-card:hover .lib-card-rename-btn,.lib-card:focus-within .lib-card-rename-btn{opacity:1}.lib-card-rename{display:flex;align-items:center;gap:3px;margin:4px 6px 2px}.lib-card-rename-input{flex:1;font-size:11px;padding:2px 5px;border-radius:var(--radius-sm);border:1px solid var(--color-border-default);background:var(--color-background-canvas);color:var(--color-text-primary);min-width:0}.lib-card-meta{display:block;margin:0 8px 8px;font-size:10px;color:var(--color-text-tertiary)}.lib-card-del{position:absolute;top:5px;right:5px;opacity:0;background:color-mix(in srgb,var(--color-background-canvas) 75%,transparent);-webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px)}.lib-card:hover .lib-card-del,.lib-card:focus-within .lib-card-del{opacity:1}.lib-card-confirm{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;gap:var(--prim-space-6);align-items:center;justify-content:center;font-size:12px;color:var(--color-text-primary);background:color-mix(in srgb,var(--color-background-floating) 88%,transparent);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.lib-card.is-selected{border-color:var(--color-brand-primary);background:var(--color-interaction-selected-brand)}.lib-tag{display:inline-flex;align-items:center;min-height:18px;padding:0 7px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);font-size:10px}.lib-tag--mock{border-color:color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default)}.lib-tag--real{border-color:color-mix(in srgb,var(--color-status-amber) 40%,transparent);background:color-mix(in srgb,var(--color-status-amber) 12%,transparent);color:var(--color-status-amber)}.lib-card-readiness{display:flex;gap:var(--prim-space-4);flex-wrap:wrap;margin:0 8px 8px}.lib-readiness-tag{display:inline-flex;align-items:center;min-height:16px;padding:0 6px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-text-secondary);font-size:9px}.lib-readiness-tag--anim{border-color:color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default)}.reserved-card{border:1px dashed var(--color-border-default);border-radius:var(--radius-lg);background:var(--color-background-base);padding:var(--prim-space-12);opacity:.85}.reserved-head{display:flex;align-items:center;gap:7px}.reserved-head svg{color:var(--color-icon-tertiary)}.reserved-title{font-size:12px;font-weight:650;color:var(--color-text-secondary);flex:1 1 auto}.reserved-badge{display:inline-flex;align-items:center;min-height:18px;padding:0 7px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-text-tertiary);font-size:10px;white-space:nowrap}.reserved-note{margin:var(--prim-space-8) 0 0;color:var(--color-text-tertiary);font-size:10px;line-height:1.5}.quality-dims{display:flex;flex-wrap:wrap;gap:var(--prim-space-6);margin-top:var(--prim-space-10)}.quality-dim{display:inline-flex;align-items:center;gap:5px;min-height:24px;padding:0 var(--prim-space-8);border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);background:var(--color-background-floating);color:var(--color-text-tertiary);font-size:11px}.q-row{display:grid;grid-template-columns:56px 1fr 30px 34px auto;gap:var(--prim-space-8);align-items:center;margin-bottom:var(--prim-space-6)}.q-label{font-size:11px;color:var(--color-text-secondary)}.q-bar{height:6px;border-radius:3px;background:var(--color-background-floating);overflow:hidden}.q-bar-fill{height:100%;background:var(--color-brand-primary);transition:width var(--motion-duration-base) var(--motion-ease-out)}.q-val{font-size:11px;color:var(--color-text-primary);text-align:right}.q-src{font-size:10px;padding:1px 5px;border-radius:var(--radius-pill)}.q-src--auto{color:var(--color-brand-primary);background:var(--color-brand-soft)}.q-src--manual{color:var(--color-status-amber)}.q-src--none{color:var(--color-text-tertiary)}.q-edit{width:52px;padding:2px 4px;border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);color:var(--color-text-primary)}.q-actions{display:flex;gap:var(--prim-space-6);margin-top:var(--prim-space-8)}.downstream{display:flex;flex-direction:column;gap:var(--prim-space-10);margin-top:var(--prim-space-4);padding:var(--prim-space-12);border:1px solid var(--color-border-subtle);border-radius:var(--radius-lg);background:var(--color-background-base)}.downstream-head{display:flex;align-items:center;gap:7px;font-size:12px;font-weight:650;color:var(--color-text-secondary)}.downstream-head svg{color:var(--color-icon-tertiary)}.downstream-step{display:flex;align-items:flex-start;gap:var(--prim-space-10)}.downstream-step.is-disabled{opacity:.55}.downstream-step-no{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;margin-top:1px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);font-size:10px;color:var(--color-text-secondary)}.downstream-step-body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:5px}.downstream-step-title{display:flex;align-items:center;gap:5px;font-size:12px;font-weight:600;color:var(--color-text-primary)}.downstream-hint{font-size:10px;line-height:1.5;color:var(--color-text-tertiary)}.downstream-ok{font-size:10px;color:var(--color-accent-green-default)}.downstream-aside{display:flex;padding-top:var(--prim-space-8);border-top:1px dashed var(--color-border-subtle)}.motion-browser{display:flex;flex-direction:column;gap:var(--prim-space-8);width:100%}.motion-browser-filters{display:flex;gap:var(--prim-space-6);flex-wrap:wrap;align-items:center}.motion-search{display:flex;align-items:center;gap:var(--prim-space-6);flex:1 1 140px;min-width:120px;padding:0 var(--prim-space-8);border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);color:var(--color-icon-tertiary);transition:border-color var(--motion-duration-fast) var(--motion-ease-out)}.motion-search:focus-within{border-color:var(--color-brand-primary)}.motion-search-input{flex:1 1 auto;min-width:0;min-height:28px;border:0;background:transparent;color:var(--color-text-primary);outline:2px solid transparent;outline-offset:1px;font-size:12px}.motion-search-input:focus-visible{outline-color:var(--color-brand-primary)}.motion-filter-select{flex:0 0 auto;font-size:11px;padding:5px 6px}.motion-browser-note{font-size:10px;line-height:1.4;color:var(--color-status-amber)}.motion-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:var(--prim-space-6);max-height:280px;overflow-y:auto;padding:2px;scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-brand-primary) 24%,transparent) transparent}.motion-list::-webkit-scrollbar{width:6px}.motion-list::-webkit-scrollbar-track{background:transparent}.motion-list::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-brand-primary) 18%,transparent);border-radius:var(--radius-pill)}.motion-list::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-brand-primary) 34%,transparent)}.motion-item{display:flex;flex-direction:column;gap:5px;padding:var(--prim-space-6);border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-floating);color:var(--color-text-primary);text-align:left;cursor:pointer;transition:transform var(--motion-duration-base) var(--motion-ease-out),border-color var(--motion-duration-base) var(--motion-ease-out),background var(--motion-duration-base) var(--motion-ease-out)}.motion-item:hover:not(:disabled){border-color:var(--color-border-strong);background:var(--color-interaction-hover);transform:translate3d(0,var(--motion-hover-y),0)}.motion-item:active:not(:disabled){transform:scale(var(--motion-press-scale));transition-duration:var(--motion-duration-instant)}.motion-item:disabled{cursor:not-allowed;opacity:.55}.motion-item.is-applied{border-color:var(--color-accent-green-default)}.motion-item-thumb{width:100%;aspect-ratio:1 / 1;border-radius:var(--radius-sm);object-fit:cover;background:var(--color-background-canvas)}.motion-item-thumb--empty{display:flex;align-items:center;justify-content:center;color:var(--color-icon-tertiary)}.motion-item-label{font-size:11px;font-weight:600;line-height:1.3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.motion-item-meta{display:flex;align-items:center;gap:var(--prim-space-4);flex-wrap:wrap}.motion-item-cat{font-size:9px;color:var(--color-text-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.motion-item-applied{margin-left:auto;color:var(--color-accent-green-default);font-size:11px}.motion-free-badge{display:inline-flex;align-items:center;min-height:15px;padding:0 5px;border-radius:var(--radius-pill);border:1px solid color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default);font-size:9px;white-space:nowrap}.g3-motion-list{margin-top:var(--prim-space-10);display:flex;flex-direction:column;gap:var(--prim-space-6)}.g3-motion-item{width:100%;padding:var(--prim-space-8) var(--prim-space-10);border:1px solid var(--color-border-subtle);border-radius:var(--radius-md);background:transparent;color:var(--color-text-secondary);display:flex;align-items:center;gap:var(--prim-space-8);text-align:left;cursor:pointer}.g3-motion-item:hover,.g3-motion-item.is-selected{border-color:var(--color-brand-line);background:var(--color-brand-soft);color:var(--color-text-primary)}.g3-score-list{display:flex;flex-direction:column;gap:var(--prim-space-10)}.g3-score-list.is-spaced,.g3-file-list,.g3-pose-preview{margin-top:var(--prim-space-12)}.g3-score-row{display:grid;grid-template-columns:90px minmax(0,1fr) 28px;align-items:center;gap:var(--prim-space-8);color:var(--color-text-secondary);font-size:10px}.g3-score-row input{accent-color:var(--color-brand-primary);width:100%}.g3-score-value{color:var(--color-text-primary);font:10px var(--font-mono);text-align:right}.g3-file-list{display:flex;flex-direction:column;gap:var(--prim-space-6)}.g3-file-name{flex:1;font:400 9px var(--font-mono)}.g3-pose-loading{width:100%;box-shadow:none}.g3-pose-preview{aspect-ratio:4 / 3;border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:radial-gradient(circle at 50% 24%,var(--color-brand-primary) 0 7%,transparent 8%),linear-gradient(150deg,var(--color-background-floating),var(--color-background-canvas));display:grid;place-items:end center;padding:var(--prim-space-12);color:var(--color-text-secondary);font-size:10px}.gx-modal-overlay{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-app-modal);display:flex;align-items:center;justify-content:center;padding:var(--prim-space-20);background:var(--color-overlay-modal);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px);animation:motion-fade-in var(--motion-duration-fast) var(--motion-ease-out) both}.gx-modal{display:flex;flex-direction:column;width:100%;max-width:420px;max-height:100%;border:1px solid var(--color-border-strong);border-radius:var(--radius-lg);background:var(--color-background-elevated);box-shadow:var(--motion-shadow-hover);overflow:hidden}.gx-modal-head{display:flex;align-items:center;gap:var(--prim-space-8);padding:var(--prim-space-12) 14px;border-bottom:1px solid var(--color-divider-default);flex:0 0 auto}.gx-modal-title{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:650;color:var(--color-text-primary)}.gx-modal-title svg{color:var(--color-brand-primary)}.gx-modal-close{margin-left:auto}.gx-modal-body{flex:1 1 auto;min-height:0;overflow:auto;padding:14px;display:flex;flex-direction:column;gap:var(--prim-space-12);scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-brand-primary) 24%,transparent) transparent}.gx-modal-body::-webkit-scrollbar{width:6px}.gx-modal-body::-webkit-scrollbar-track{background:transparent}.gx-modal-body::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-brand-primary) 18%,transparent);border-radius:var(--radius-pill)}.gx-modal-body::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-brand-primary) 34%,transparent)}.gx-modal-state{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--prim-space-10);padding:32px 18px;text-align:center;color:var(--color-text-secondary);font-size:12px}.gx-modal-state svg{color:var(--color-icon-tertiary)}.gx-modal-state .gx-state-copy{word-break:break-word}.gx-modal-foot{display:flex;align-items:center;gap:var(--prim-space-8);padding:var(--prim-space-10) 14px;border-top:1px solid var(--color-divider-default);flex:0 0 auto}.gx-modal-msg{flex:1 1 auto;min-width:0;font-size:11px;line-height:1.4;word-break:break-word}.gx-modal-msg--ok{color:var(--color-accent-green-default)}.gx-modal-msg--err{color:var(--color-status-error)}.cred-section{display:flex;flex-direction:column;gap:var(--prim-space-8);padding:var(--prim-space-12);border:1px solid var(--color-border-default);border-radius:var(--radius-md);background:var(--color-background-base)}.cred-section-head{display:flex;align-items:center;gap:var(--prim-space-8)}.cred-section-title{font-size:12px;font-weight:650;color:var(--color-text-primary)}.cred-tag{display:inline-flex;align-items:center;min-height:16px;padding:0 6px;border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);color:var(--color-text-tertiary);font-size:9px}.cred-badge{margin-left:auto;display:inline-flex;align-items:center;min-height:18px;padding:0 var(--prim-space-8);border-radius:var(--radius-pill);border:1px solid var(--color-border-default);background:var(--color-background-floating);font-size:10px;white-space:nowrap}.cred-badge--on{border-color:color-mix(in srgb,var(--color-accent-green-default) 35%,transparent);background:color-mix(in srgb,var(--color-accent-green-default) 10%,transparent);color:var(--color-accent-green-default)}.cred-badge--off{color:var(--color-text-tertiary)}.cred-secret-row{display:flex;align-items:stretch;gap:var(--prim-space-6)}.cred-secret-row .fx-input,.cred-secret-row .g3-input{flex:1 1 auto;min-width:0}.cred-secret-row .fx-btn,.cred-secret-row .g3-btn{flex:0 0 auto;white-space:nowrap}.motion-row{will-change:transform,background,border-color,color,box-shadow;transition:transform var(--motion-duration-base) var(--motion-ease-out),background var(--motion-duration-base) var(--motion-ease-out),border-color var(--motion-duration-base) var(--motion-ease-out),color var(--motion-duration-fast) var(--motion-ease-out),box-shadow var(--motion-duration-base) var(--motion-ease-out)}.motion-row:hover{transform:translate3d(var(--motion-row-x),0,0);box-shadow:inset 2px 0 color-mix(in srgb,var(--color-brand-primary) 40%,transparent),0 4px 12px color-mix(in srgb,var(--prim-color-neutral-1000) 14%,transparent)}.motion-row:active{transform:translate3d(1px,0,0) scale(var(--motion-press-scale));box-shadow:var(--motion-shadow-active);transition-duration:var(--motion-duration-instant)}.motion-row.is-selected:hover{transform:none}.motion-fade-in{animation:motion-fade-in var(--motion-duration-base) var(--motion-ease-out) both}@keyframes motion-fade-in{0%{opacity:0}to{opacity:1}}@media(max-width:900px){.gx-center-stage{grid-template-columns:1fr;grid-template-rows:minmax(0,1fr) auto;gap:var(--prim-space-10);padding:var(--prim-space-10);height:100%}.gx-maincol,.g3-workspace{min-height:0;height:100%}.gx-asset-rail{position:static;max-height:min(200px,32vh);overflow:auto}.g3-drawer,.gx-quality-drawer-panel{width:min(100%,100%)}.g3-setup-scroll,.gx-setup{padding:var(--prim-space-10);gap:var(--prim-space-8)}}@media(max-width:900px)and (max-height:760px){.gx-center-stage{grid-template-rows:minmax(0,1fr) minmax(96px,120px)}.gx-maincol,.g3-workspace{grid-template-rows:auto minmax(96px,1fr) auto minmax(0,180px) auto}.gx-asset-rail{max-height:120px}}@media(max-width:520px){.g3-metrics{grid-template-columns:repeat(3,minmax(0,1fr))}.g3-metric:nth-child(3n){border-right:0}.g3-metric:nth-child(n+4){border-top:1px solid var(--color-divider-subtle)}}@media(min-width:901px)and (max-width:1200px){.gx-center-stage.is-rail-open{grid-template-columns:minmax(0,1fr) minmax(200px,240px)}}@media(max-width:1400px){.gx-root--standalone .gx-left{flex-basis:260px;width:260px}.g3-view-tab{padding-inline:var(--prim-space-4);font-size:9px}.g3-toolbar-select{max-width:72px}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{scroll-behavior:auto!important;animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}.motion-row:hover,.motion-row:active,.g3-btn:hover:not(:disabled),.g3-btn:active:not(:disabled),.fx-btn:hover:not(:disabled),.fx-btn:active:not(:disabled),.fx-segmented-btn:active,.motion-item:hover:not(:disabled),.motion-item:active:not(:disabled){transform:none!important}.gx-quality-drawer-panel{animation:none!important}}
@@ -0,0 +1,28 @@
1
+ # HDR 环境贴图预设目录
2
+
3
+ 这是视图器(`ModelViewer` / `viewer/environment.ts`,见
4
+ `docs/PLAN-2026-06-13-viewer-quality-provider-params.md` §A.2)加载 HDR 环境光照
5
+ (IBL)的**占位目录**。把 `.hdr` 文件放进来即可被预设选择器引用。
6
+
7
+ ## 路径与服务方式
8
+
9
+ - 源路径(你放文件的地方):`packages/marketplace/extensions/gen3d/public/hdr/`
10
+ - vite 会把 `public/` 原样拷进构建产物 `dist/` 根,插件 `base: './'`,因此运行时
11
+ 视图器以相对路径 `./hdr/<file>.hdr` 加载(Studio 内嵌走 same-origin,standalone
12
+ dev :15175 走 vite)。
13
+ - **本目录纳入 git**(插件 `.gitignore` 只忽略 `dist/`,不忽略 `public/` 与 `.hdr`),
14
+ 所以放进来的文件会随仓库走、**换机不丢**。⚠️ `.hdr` 是二进制,体积偏大时考虑 git-lfs。
15
+
16
+ ## 文件要求(建议)
17
+
18
+ - 格式:**equirectangular(等距柱状)`.hdr`(RGBE)**。
19
+ - 分辨率:**1k(2048×1024 左右)**,单个约 1–3MB;不建议 2k/4k(懒加载也会显著增重)。
20
+ - 命名:小写中划线,语义化,例如 `studio-soft.hdr` / `studio-outdoor.hdr` / `sunset.hdr`。
21
+
22
+ ## 登记方式:`presets.json`
23
+
24
+ 视图器从本目录的 `presets.json` 读取可选预设清单(懒加载:选中某项时才下载对应
25
+ `.hdr`)。`builtin-neutral`(three.js `RoomEnvironment`,零文件中性影棚)恒为默认项、
26
+ 无需文件。新增 HDR = 放文件 + 在 `presets.json` 的 `custom[]` 里加一条。
27
+
28
+ 当前为占位:`custom[]` 为空,仅 `builtin-neutral` 可用,直到你固化真实 `.hdr`。
@@ -0,0 +1,8 @@
1
+ {
2
+ "_note": "把 .hdr 放进本目录后,在 custom[] 加一条 { id, label, file, blurriness?, intensity? }。builtin[] 无需文件(three RoomEnvironment)。详见 README.md。",
3
+ "_example": { "id": "studio-soft", "label": "柔光影棚", "file": "studio-soft.hdr", "blurriness": 0.25, "intensity": 1 },
4
+ "builtin": [
5
+ { "id": "builtin-neutral", "label": "中性影棚(内置)", "kind": "room-environment" }
6
+ ],
7
+ "custom": []
8
+ }
@@ -0,0 +1,13 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>3D Character Generation</title>
7
+ <script type="module" crossorigin src="./assets/index-CIx3aXo1.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/index-CmhOHLEB.css">
9
+ </head>
10
+ <body>
11
+ <div id="root"></div>
12
+ </body>
13
+ </html>
@@ -0,0 +1,428 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "id": "@forgeax-extension/character-3d",
4
+ "version": "0.1.2",
5
+ "displayName": {
6
+ "zh": "3D角色",
7
+ "en": "3D Character Generation"
8
+ },
9
+ "description": {
10
+ "zh": "3D 角色生成工作台 · 接 Hunyuan3D / VISVISE / Rodin(经 LiteLLM 网关;Meshy 代码保留、UI 隐藏):文本 / 图片 / 多视图生成 3D,自动绑骨 + 文本/视频动作,质量评分,产出可持久化的游戏可用 3D 资产 manifest。",
11
+ "en": "3D character generation editor — drives Hunyuan3D / VISVISE / Rodin via the LiteLLM gateway (Meshy code retained, UI hidden): text/image/multi-view to 3D, auto-rig + text/video motion, and quality scoring, producing durable game-ready 3D asset manifests."
12
+ },
13
+ "author": {
14
+ "name": "forgeax",
15
+ "email": "dev@forgeax.local"
16
+ },
17
+ "icon": "PersonStanding",
18
+ "keywords": [
19
+ "3d",
20
+ "generation",
21
+ "meshy",
22
+ "hunyuan3d",
23
+ "asset",
24
+ "glb"
25
+ ],
26
+ "entry": {
27
+ "backend": "./server/tool-handlers.ts",
28
+ "frontend": "./dist/index.html",
29
+ "standalone": {
30
+ "start": "npm run dev",
31
+ "port": 15176,
32
+ "readyProbe": "/",
33
+ "dev": {
34
+ "watch": true,
35
+ "hmr": true
36
+ },
37
+ "embeddedAlso": true,
38
+ "devOnly": false
39
+ }
40
+ },
41
+ "permissions": [],
42
+ "hot": false,
43
+ "experimental": true,
44
+ "compatibleWith": {
45
+ "forgeax-bus": "^1.0.0"
46
+ },
47
+ "contributes": {
48
+ "panelTypes": [
49
+ {
50
+ "id": "gen3d.content",
51
+ "runtime": "iframe",
52
+ "entry": "./dist/index.html"
53
+ }
54
+ ],
55
+ "pages": [
56
+ {
57
+ "id": "gen3d",
58
+ "title": {
59
+ "zh": "3D角色",
60
+ "en": "3D Character Generation"
61
+ },
62
+ "icon": "PersonStanding",
63
+ "cardinality": "singleton",
64
+ "restorePolicy": "project",
65
+ "layout": {
66
+ "version": 2,
67
+ "root": {
68
+ "kind": "split",
69
+ "direction": "horizontal",
70
+ "sizes": [
71
+ 320,
72
+ 840
73
+ ],
74
+ "children": [
75
+ {
76
+ "kind": "tabs",
77
+ "placements": [
78
+ "sidebar"
79
+ ],
80
+ "active": "sidebar"
81
+ },
82
+ {
83
+ "kind": "tabs",
84
+ "placements": [
85
+ "workspace"
86
+ ],
87
+ "active": "workspace"
88
+ }
89
+ ]
90
+ }
91
+ },
92
+ "layoutVersion": 2,
93
+ "panels": [
94
+ {
95
+ "id": "sidebar",
96
+ "panelType": {
97
+ "extension": "self",
98
+ "id": "gen3d.content"
99
+ },
100
+ "initialProps": {
101
+ "pane": "left",
102
+ "width": 320,
103
+ "scrollable": true
104
+ }
105
+ },
106
+ {
107
+ "id": "workspace",
108
+ "panelType": {
109
+ "extension": "self",
110
+ "id": "gen3d.content"
111
+ },
112
+ "initialProps": {
113
+ "pane": "center",
114
+ "minHeight": 600,
115
+ "scrollable": true
116
+ }
117
+ }
118
+ ],
119
+ "matchProduces": [
120
+ "**/.forgeax/games/*/assets/3d/characters/**",
121
+ "**/.forgeax/games/*/assets/3d/meshes/**"
122
+ ],
123
+ "preferredAgent": "@forgeax-extension/agent-gen3d"
124
+ }
125
+ ],
126
+ "activities": [
127
+ {
128
+ "id": "gen3d.launcher",
129
+ "title": {
130
+ "zh": "3D角色",
131
+ "en": "3D Character Generation"
132
+ },
133
+ "icon": "PersonStanding",
134
+ "order": 155,
135
+ "category": "3D",
136
+ "pageType": {
137
+ "extension": "self",
138
+ "id": "gen3d"
139
+ }
140
+ }
141
+ ],
142
+ "tools": [
143
+ {
144
+ "id": "gen3d:provider-status",
145
+ "args": "./schemas/provider-status.args.json",
146
+ "returns": "./schemas/provider-status.returns.json",
147
+ "exposedToAI": true,
148
+ "description": {
149
+ "zh": "读取 3D 生成供应商能力矩阵;返回静态、无配额数据。",
150
+ "en": "Read the 3D generation provider capability matrix. Returns static no-quota data."
151
+ }
152
+ },
153
+ {
154
+ "id": "gen3d:list-assets",
155
+ "args": "./schemas/list-assets.args.json",
156
+ "returns": "./schemas/list-assets.returns.json",
157
+ "exposedToAI": true,
158
+ "description": {
159
+ "zh": "列出当前游戏已生成的持久化 3D 资产 manifest,可按 slot / provider 过滤。",
160
+ "en": "List the active game's durable 3D asset manifests, optionally filtered by slot / provider."
161
+ }
162
+ },
163
+ {
164
+ "id": "gen3d:delete-asset",
165
+ "args": "./schemas/delete-asset.args.json",
166
+ "returns": "./schemas/delete-asset.returns.json",
167
+ "exposedToAI": false,
168
+ "requireConfirm": "destructive",
169
+ "description": {
170
+ "zh": "删除当前游戏的一个 3D 资产(主 GLB + sidecar + 同名附属文件),并对其 cacheKey 打 tombstone 防止缓存复活。破坏性操作,仅经 UI 确认触发。",
171
+ "en": "Delete a 3D asset from the active game (main GLB + sidecar + same-basename sidefiles) and tombstone its cacheKey so it never resurrects from a cache hit. Destructive; UI-confirm only."
172
+ }
173
+ },
174
+ {
175
+ "id": "gen3d:generate-meshy-text-mock",
176
+ "args": "./schemas/generate-meshy-text-mock.args.json",
177
+ "returns": "./schemas/generate-meshy-text-mock.returns.json",
178
+ "exposedToAI": true,
179
+ "description": {
180
+ "zh": "生成确定性的 Meshy 文生 3D mock 资产并落盘为持久 manifest;不调用远端。",
181
+ "en": "Generate a deterministic Meshy text-to-3D mock asset persisted as a durable manifest, with no remote calls."
182
+ }
183
+ },
184
+ {
185
+ "id": "gen3d:text-to-3d",
186
+ "args": "./schemas/text-to-3d.args.json",
187
+ "returns": "./schemas/text-to-3d.returns.json",
188
+ "exposedToAI": true,
189
+ "description": {
190
+ "zh": "文生 3D:选 provider(混元 workflow / VISVISE / Rodin 网关 rodin-3d;Meshy 仍可用但 UI 隐藏)生成并落盘持久 manifest(cache-first)。未配置真实 provider 时回退确定性 mock,保持无配额安全。",
191
+ "en": "Text-to-3D via the chosen provider (Hunyuan workflow / VISVISE / Rodin gateway rodin-3d; Meshy remains callable but UI-hidden), persisted as a durable manifest (cache-first). Falls back to a deterministic mock when no real provider is configured (quota-safe)."
192
+ }
193
+ },
194
+ {
195
+ "id": "gen3d:image-to-3d",
196
+ "args": "./schemas/image-to-3d.args.json",
197
+ "returns": "./schemas/image-to-3d.returns.json",
198
+ "exposedToAI": true,
199
+ "description": {
200
+ "zh": "图生 3D:选 provider(混元 workflow / VISVISE / Rodin 网关 rodin-3d;Meshy 仍可用但 UI 隐藏)生成并落盘持久 manifest(cache-first)。未配置真实 provider 时回退确定性 mock。",
201
+ "en": "Image-to-3D via the chosen provider (Hunyuan workflow / VISVISE / Rodin gateway rodin-3d; Meshy remains callable but UI-hidden), persisted as a durable manifest (cache-first). Falls back to a deterministic mock when no real provider is configured."
202
+ }
203
+ },
204
+ {
205
+ "id": "gen3d:views-to-3d",
206
+ "args": "./schemas/views-to-3d.args.json",
207
+ "returns": "./schemas/views-to-3d.returns.json",
208
+ "exposedToAI": true,
209
+ "description": {
210
+ "zh": "多视图生 3D:混元 workflow(命名视图槽)、Rodin 网关 rodin-3d(有序 image_urls,正视在前)、Meshy(有序图数组)。VISVISE 无 views,调用会 views_not_supported。未配置真实 provider 时回退确定性 mock。",
211
+ "en": "Multi-view-to-3D: Hunyuan workflow named view slots, Rodin gateway rodin-3d ordered image_urls (front first), and Meshy ordered image arrays. VISVISE has no views model (views_not_supported). Falls back to a deterministic mock when no real provider is configured."
212
+ }
213
+ },
214
+ {
215
+ "id": "gen3d:refine-mesh",
216
+ "args": "./schemas/refine-mesh.args.json",
217
+ "returns": "./schemas/refine-mesh.returns.json",
218
+ "exposedToAI": false,
219
+ "description": {
220
+ "zh": "精修网格(Meshy 专属第二阶段):对一个 Meshy 文生 preview 任务加贴图,落盘新的持久 manifest(mode=refine,cache-first)。未配置 Meshy 时回退确定性 mock。",
221
+ "en": "Refine mesh (Meshy-only second stage): add texture to a Meshy text preview task, persisted as a new durable manifest (mode=refine, cache-first). Falls back to a deterministic mock when Meshy is not configured."
222
+ }
223
+ },
224
+ {
225
+ "id": "gen3d:pose-standardization",
226
+ "args": "./schemas/pose-standardization.args.json",
227
+ "returns": "./schemas/pose-standardization.returns.json",
228
+ "exposedToAI": true,
229
+ "description": {
230
+ "zh": "姿态标准化(上游预处理):默认 Hunyuan REST;VISVISE 图生传 provider=visvise(visvise-image-pose)。输出图落盘为 scratch blob 供后续图生 3D;不产出 3D 资产 manifest。Rodin 图生跳过此步。未配置真实 provider 时回退确定性 mock。",
231
+ "en": "Pose standardization (upstream preprocessing): default Hunyuan REST; pass provider=visvise for VISVISE image-to-3d (visvise-image-pose). The output image is a scratch blob for later image-to-3D; it does NOT produce a 3D asset manifest. Rodin image-to-3d skips this step. Falls back to a deterministic mock when no real provider is configured."
232
+ }
233
+ },
234
+ {
235
+ "id": "gen3d:upload-image",
236
+ "args": "./schemas/upload-image.args.json",
237
+ "returns": "./schemas/upload-image.returns.json",
238
+ "exposedToAI": false,
239
+ "description": {
240
+ "zh": "本地图片上传(中转产物,非资产):解码 base64(≤8MB)上传到 COS,返回 24h 预签名 URL 供图生/多视图/姿态标准化等 URL-fetch provider 使用。未配置 COS 时报错,提示改为手填 URL。",
241
+ "en": "Local image upload (transfer artifact, NOT an asset): decode base64 (≤8MB), upload to COS, return a 24h presigned URL for URL-fetching providers (image/views/pose tools). Errors with cos_not_configured when COS is absent so the UI can ask the user to paste a URL."
242
+ }
243
+ },
244
+ {
245
+ "id": "gen3d:upload-video",
246
+ "args": "./schemas/upload-video.args.json",
247
+ "returns": "./schemas/upload-video.returns.json",
248
+ "exposedToAI": false,
249
+ "description": {
250
+ "zh": "本地视频预签名上传(中转产物,非资产):返回 COS PUT URL + publicUrl(约 100MB,mp4/webm)。浏览器直传,服务端不收 base64。PUT 完成后把 publicUrl 填进 apply-motion.videoUrl。也可直接贴已有 URL 跳过本工具。",
251
+ "en": "Local video presign upload (transfer artifact, NOT an asset): returns a COS PUT URL + publicUrl (~100MB, mp4/webm). The browser uploads bytes; the server never accepts video base64. After PUT, pass publicUrl as apply-motion.videoUrl. Callers may skip this and paste an existing URL."
252
+ }
253
+ },
254
+ {
255
+ "id": "gen3d:auto-rig",
256
+ "args": "./schemas/auto-rig.args.json",
257
+ "returns": "./schemas/auto-rig.returns.json",
258
+ "exposedToAI": true,
259
+ "requireConfirm": "always",
260
+ "confirmMessage": {
261
+ "zh": "自动绑骨将消耗额度,请确认。",
262
+ "en": "Auto-rig will consume quota. Continue?"
263
+ },
264
+ "description": {
265
+ "zh": "自动绑骨(ADR-0009,经 LiteLLM 网关):把带贴图高模角色 GLB 绑定人形骨架,向同一资产追加 rigged_model GLB+FBX,记录 rig-chain,置位 readiness.rigged。Dispatch:rigProvider=auto 时混元 REST → VISVISE → mock(不再 Meshy 优先);可显式指定 hunyuan_rest/visvise/meshy。默认幂等;force=true 时清除旧骨架与动作后重绑。仅人形。将消耗额度。网关无余额端点(getBalance 恒 null)。",
266
+ "en": "Auto-rig (ADR-0009 via LiteLLM): rig a textured high-poly character GLB, appending rigged_model GLB+FBX, recording the rig-chain and flipping readiness.rigged. Dispatch: rigProvider=auto prefers Hunyuan REST, then VISVISE, then mock (Meshy is no longer first); pass hunyuan_rest/visvise/meshy to force a route. Idempotent by default; force=true clears prior rig+motions and re-runs. Humanoid only. Consumes quota. Gateway has no balance endpoint (getBalance always null)."
267
+ }
268
+ },
269
+ {
270
+ "id": "gen3d:apply-motion",
271
+ "args": "./schemas/apply-motion.args.json",
272
+ "returns": "./schemas/apply-motion.returns.json",
273
+ "exposedToAI": true,
274
+ "requireConfirm": "always",
275
+ "confirmMessage": {
276
+ "zh": "应用动作将消耗额度,请确认。",
277
+ "en": "Apply motion will consume quota. Continue?"
278
+ },
279
+ "description": {
280
+ "zh": "应用动作(ADR-0009,经 LiteLLM 网关):对已绑骨资产追加 animated_model GLB+FBX,置位 readiness.animated。按 manifest.rig.rigProvider 分发:混元用 motionType 9–16;VISVISE 用 prompt 或 videoUrl 之一;Meshy 用 actionId + rig_task_id。需先 auto-rig;按动作幂等。将消耗额度。",
281
+ "en": "Apply motion (ADR-0009 via LiteLLM): append animated_model GLB+FBX to a rigged asset and flip readiness.animated. Dispatched by manifest.rig.rigProvider: Hunyuan uses motionType 9–16; VISVISE uses prompt XOR videoUrl; Meshy uses actionId + rig_task_id. Requires prior auto-rig; idempotent per motion. Consumes quota."
282
+ }
283
+ },
284
+ {
285
+ "id": "gen3d:list-motions",
286
+ "args": "./schemas/list-motions.args.json",
287
+ "returns": "./schemas/list-motions.returns.json",
288
+ "exposedToAI": true,
289
+ "description": {
290
+ "zh": "列出可用动作:返回某资产绑骨系统对应的动作目录切片——Hunyuan 绑骨→v1 固定 8 个;VISVISE 绑骨→text/video 两项;Meshy 绑骨→其公共目录。零配额(GET)。schema 不枚举全量。",
291
+ "en": "List motions for an asset's rig system — Hunyuan-rigged → v1 fixed 8; VISVISE-rigged → text/video; Meshy-rigged → public catalog. Zero quota (GET). The schema never enumerates the full set."
292
+ }
293
+ },
294
+ {
295
+ "id": "gen3d:retopo-lowpoly",
296
+ "args": "./schemas/retopo-lowpoly.args.json",
297
+ "returns": "./schemas/retopo-lowpoly.returns.json",
298
+ "exposedToAI": false,
299
+ "description": {
300
+ "zh": "低模重拓扑(Hunyuan REST low_poly,M13,可选侧支):把高模 GLB 重拓扑为低模,产出一个全新的衍生低模 GLB 资产(cache-first),高模源保留。注意:贴图不保留,因此不是绑骨前的预处理步骤。Gate 0 真机验证(Hunyuan 内网可达公网 COS)通过前默认 mock,exposedToAI=false。",
301
+ "en": "Retopo low-poly (Hunyuan REST low_poly, M13, optional side-branch): retopologize a high-poly GLB to low-poly, producing a NEW derived low-poly GLB asset (cache-first); the high-poly source is retained. Note: textures are NOT preserved, so this is NOT a pre-rig step. Mock-only until Gate 0 real-machine verification (Hunyuan internal egress can fetch public COS) passes, so exposedToAI=false."
302
+ }
303
+ },
304
+ {
305
+ "id": "gen3d:score-quality",
306
+ "args": "./schemas/score-quality.args.json",
307
+ "returns": "./schemas/score-quality.returns.json",
308
+ "exposedToAI": true,
309
+ "description": {
310
+ "zh": "质量评分(按需混合,ADR-0004):合并客户端客观启发式 + 人工覆盖(AI 视觉评本期为 mock 桩)写入资产 sidecar 的 quality 报告,返回更新后的 manifest。lazy 持久化:浏览不写盘,仅评分/覆盖时落库。",
311
+ "en": "Score quality (on-demand hybrid, ADR-0004): merge client objective heuristics + manual overrides (AI vision is a mock stub this round) into the asset sidecar quality report and return the updated manifest. Lazy persistence: browsing never writes; only scoring/override persists."
312
+ }
313
+ },
314
+ {
315
+ "id": "gen3d:rename-asset",
316
+ "args": "./schemas/rename-asset.args.json",
317
+ "returns": "./schemas/rename-asset.returns.json",
318
+ "exposedToAI": true,
319
+ "description": {
320
+ "zh": "设置资产的用户自定义显示名(userLabel)。传 null 或空字符串可清除,恢复自动名称(prompt 首行或文件名 stem)。",
321
+ "en": "Set a user-defined display label (userLabel) on an asset. Pass null or empty string to clear and revert to the auto-name (prompt first line or filename stem)."
322
+ }
323
+ },
324
+ {
325
+ "id": "gen3d:engine-import-status",
326
+ "args": "./schemas/engine-import-status.args.json",
327
+ "returns": "./schemas/engine-import-status.returns.json",
328
+ "exposedToAI": false,
329
+ "description": {
330
+ "zh": "只读:查询该资产(限道具/mesh)的引擎身份证是否存在且对应当前 GLB 内容;角色资产返回明确拒绝说明。",
331
+ "en": "Read-only: check whether the engine identity meta exists and matches the current GLB content (props/mesh only). Character assets return a clear rejection message."
332
+ }
333
+ },
334
+ {
335
+ "id": "gen3d:import-to-engine",
336
+ "args": "./schemas/import-to-engine.args.json",
337
+ "returns": "./schemas/import-to-engine.returns.json",
338
+ "exposedToAI": false,
339
+ "description": {
340
+ "zh": "导入到游戏(限道具/mesh):必要时规范化 Draco → 办/重办引擎身份证,使 Edit 资产面板认得出。角色资产拒绝(ROLE1,走可玩角色导出)。",
341
+ "en": "Import to Game (props/mesh only): normalize Draco if needed → cook/re-cook engine identity meta so the Edit asset panel recognizes it. Character assets are rejected (ROLE1 — use Export Playable Character instead)."
342
+ }
343
+ },
344
+ {
345
+ "id": "gen3d:get-playable-profile",
346
+ "args": "./schemas/get-playable-profile.args.json",
347
+ "returns": "./schemas/get-playable-profile.returns.json",
348
+ "exposedToAI": false,
349
+ "description": {
350
+ "zh": "只读:内置预设 + 游戏默认动作档案 +(可选)角色覆盖/映射草稿/上次交付快照 + 一键更新是否可用 + 是否需迁移审阅 + 是否可接管已有 merged 产物。",
351
+ "en": "Read-only: built-in presets + game default motion profile + (optional) character override/mapping draft/last delivery snapshot + one-click readiness + migration-review needed + adoptable orphan merged delivery."
352
+ }
353
+ },
354
+ {
355
+ "id": "gen3d:set-playable-profile",
356
+ "args": "./schemas/set-playable-profile.args.json",
357
+ "returns": "./schemas/set-playable-profile.returns.json",
358
+ "exposedToAI": false,
359
+ "description": {
360
+ "zh": "写入某个角色的动作槽配置(角色覆盖,PROF6 默认只影响这一个角色);传 `saveAsGameDefault:true` 才会同时更新这个游戏的默认动作档案。",
361
+ "en": "Write a character's motion-slot configuration (a character override — PROF6: this affects only this one character by default). Pass `saveAsGameDefault:true` to also update this game's default motion profile."
362
+ }
363
+ },
364
+ {
365
+ "id": "gen3d:set-playable-motion-mapping",
366
+ "args": "./schemas/set-playable-motion-mapping.args.json",
367
+ "returns": "./schemas/set-playable-motion-mapping.returns.json",
368
+ "exposedToAI": false,
369
+ "description": {
370
+ "zh": "保存某个角色每个动作槽对应的源生成动作草稿(用户确认/改选自动推荐结果后调用)。",
371
+ "en": "Save the draft mapping from each of a character's motion slots to a source generated motion clip (called after the user confirms/adjusts the auto-suggested mapping)."
372
+ }
373
+ },
374
+ {
375
+ "id": "gen3d:export-playable-character",
376
+ "args": "./schemas/export-playable-character.args.json",
377
+ "returns": "./schemas/export-playable-character.returns.json",
378
+ "exposedToAI": false,
379
+ "description": {
380
+ "zh": "导出/更新可玩角色:按有效动作档案合并绑骨+已映射动作 → 写 assets/characters/<stem>-merged.glb 三件套(GLB + 引擎 meta + playable.json)。不改游戏玩法代码。",
381
+ "en": "Export/update playable character: merge rig + mapped motions per effective profile → write assets/characters/<stem>-merged.glb delivery trio (GLB + engine meta + playable.json). Does not modify gameplay code."
382
+ }
383
+ },
384
+ {
385
+ "id": "gen3d:adopt-playable-character",
386
+ "args": "./schemas/adopt-playable-character.args.json",
387
+ "returns": "./schemas/adopt-playable-character.returns.json",
388
+ "exposedToAI": false,
389
+ "description": {
390
+ "zh": "接管已有手工 merged 可玩产物(ADOPT1):目标路径已有 merged.glb + 引擎 meta、但当前源无导出快照时,确认槽→clip 映射后写出 playable.json 并绑定到本源资产。尽量复用旧 GUID。不改玩法代码。",
391
+ "en": "Adopt an existing hand-made merged playable delivery (ADOPT1): when merged.glb + engine meta already exist but this source has no delivery snapshot, confirm slot→clip mappings, write playable.json, and bind to this source. Prefer reusing old GUIDs. Does not modify gameplay code."
392
+ }
393
+ },
394
+ {
395
+ "id": "gen3d:get-credentials",
396
+ "args": "./schemas/get-credentials.args.json",
397
+ "returns": "./schemas/get-credentials.returns.json",
398
+ "exposedToAI": false,
399
+ "description": {
400
+ "zh": "读取网关 + COS 凭证的掩码配置状态(网关 key 由 Studio 设置统一管理,不返回明文)。",
401
+ "en": "Read the masked state of the gateway + COS credentials (the gateway key is managed centrally in Studio Settings; never returns plaintext)."
402
+ }
403
+ },
404
+ {
405
+ "id": "gen3d:set-credentials",
406
+ "args": "./schemas/set-credentials.args.json",
407
+ "returns": "./schemas/set-credentials.returns.json",
408
+ "exposedToAI": false,
409
+ "requireConfirm": "destructive",
410
+ "description": {
411
+ "zh": "写入/更新 COS 凭证与总开关到插件本地 .env 并即时生效(无需重启);网关 key 由 Studio 设置统一管理,此处不可写。",
412
+ "en": "Write/update COS credentials and the master switch to the plugin-local .env and apply them live (no server restart needed). The gateway key is managed centrally in Studio Settings and is not writable here."
413
+ }
414
+ }
415
+ ],
416
+ "events": [
417
+ {
418
+ "name": "gen3d.provider.status-read"
419
+ },
420
+ {
421
+ "name": "gen3d.assets.listed"
422
+ },
423
+ {
424
+ "name": "gen3d.asset.generated"
425
+ }
426
+ ]
427
+ }
428
+ }