@volter/editor-core 0.5.57
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/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Native Three selection presentation for editor-owned authoring viewports.
|
|
3
|
+
*
|
|
4
|
+
* A transform box answers where an object's editable bounds are; it does not
|
|
5
|
+
* answer which pixels belong to the selected object. Unity and Unreal draw
|
|
6
|
+
* both for that reason. This module supplies the geometry-following half with
|
|
7
|
+
* postprocessing's real OutlineEffect, while EditorViewport keeps native
|
|
8
|
+
* helpers for cameras, lights, bones and other nodes that draw no geometry.
|
|
9
|
+
*
|
|
10
|
+
* The effect is presentation only. It never enters a project render pipeline,
|
|
11
|
+
* changes source, or adds an authoring-data format.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import {
|
|
15
|
+
EDITOR_SELECTION_LAYER,
|
|
16
|
+
isInEditorOwnedSubtree,
|
|
17
|
+
} from '@volter/editor-threejs/viewport/editor-layers';
|
|
18
|
+
import type { OutlineEffect } from 'postprocessing';
|
|
19
|
+
import type * as THREE from 'three';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The three postprocessing bindings {@link createThreeSelectionOutline} needs,
|
|
23
|
+
* passed in rather than statically imported.
|
|
24
|
+
*
|
|
25
|
+
* `postprocessing` is ~200 kB of shaders and passes, and the surfaces this
|
|
26
|
+
* module serves do not all want it: `editor-viewport.ts` imports only
|
|
27
|
+
* {@link collectThreeSelectionOutlineTargets} (a pure traversal), and the
|
|
28
|
+
* Asset Lab 3D document builds its composer on its FIRST frame, not at module
|
|
29
|
+
* load. A static import here put the whole library in both closures
|
|
30
|
+
* eagerly. A caller that already loaded postprocessing for its own composer
|
|
31
|
+
* hands over its own bindings (`the world root's stage`); one that has not opens the
|
|
32
|
+
* lazy door {@link loadThreeSelectionOutline}.
|
|
33
|
+
*/
|
|
34
|
+
export interface ThreeSelectionOutlineEffects {
|
|
35
|
+
readonly OutlineEffect: typeof import('postprocessing').OutlineEffect;
|
|
36
|
+
readonly BlendFunction: typeof import('postprocessing').BlendFunction;
|
|
37
|
+
readonly KernelSize: typeof import('postprocessing').KernelSize;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build the editor's real postprocessing effect. A half-resolution medium
|
|
42
|
+
* blur resolves to a stable 3–4 CSS-pixel silhouette on both 1x and HiDPI
|
|
43
|
+
* displays instead of a driver-dependent hairline; pulse is deliberately
|
|
44
|
+
* disabled because selection is state, not an alert.
|
|
45
|
+
*/
|
|
46
|
+
export function createThreeSelectionOutline(
|
|
47
|
+
{ BlendFunction, KernelSize, OutlineEffect }: ThreeSelectionOutlineEffects,
|
|
48
|
+
scene: THREE.Scene,
|
|
49
|
+
camera: THREE.Camera,
|
|
50
|
+
colors: { readonly visible: number; readonly hidden: number },
|
|
51
|
+
): OutlineEffect {
|
|
52
|
+
const effect = withoutSelectionLayerWarning(
|
|
53
|
+
() =>
|
|
54
|
+
new OutlineEffect(scene, camera, {
|
|
55
|
+
// Alpha keeps the selection color legible over both black and white
|
|
56
|
+
// materials. The effect's default screen blend washes out on pale assets.
|
|
57
|
+
blendFunction: BlendFunction.ALPHA,
|
|
58
|
+
visibleEdgeColor: colors.visible,
|
|
59
|
+
hiddenEdgeColor: colors.hidden,
|
|
60
|
+
edgeStrength: 5,
|
|
61
|
+
pulseSpeed: 0,
|
|
62
|
+
blur: true,
|
|
63
|
+
kernelSize: KernelSize.MEDIUM,
|
|
64
|
+
resolutionScale: 0.5,
|
|
65
|
+
xRay: true,
|
|
66
|
+
}),
|
|
67
|
+
);
|
|
68
|
+
// OutlineEffect temporarily removes layer 0 from selected meshes, renders
|
|
69
|
+
// scene depth, then renders only its selection layer for the mask. The
|
|
70
|
+
// editor camera normally enables ALL layers so it can draw layer-31 gizmos;
|
|
71
|
+
// without this exclusion the selected mesh remains in the depth pass via
|
|
72
|
+
// the effect's own layer and both masks cancel to no visible edge.
|
|
73
|
+
effect.selectionLayer = EDITOR_SELECTION_LAYER;
|
|
74
|
+
camera.layers.disable(EDITOR_SELECTION_LAYER);
|
|
75
|
+
return effect;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* `OutlineEffect` constructs its `Selection` with a render layer taken from
|
|
80
|
+
* a module-wide counter, which the editor then overrides
|
|
81
|
+
* (`EDITOR_SELECTION_LAYER`, below). The counter still moves, and after 30
|
|
82
|
+
* constructions in one page — every Object3D document session builds its
|
|
83
|
+
* own effect — the library warns "Layer out of range, resetting to 2" and
|
|
84
|
+
* carries on. For this editor that line is noise: the layer it worries
|
|
85
|
+
* about is replaced before the effect ever renders. The console gate treats
|
|
86
|
+
* every warning as unresolved work, so the one message is held back for
|
|
87
|
+
* exactly the synchronous construction that provokes it; anything else the
|
|
88
|
+
* constructor says still reaches the console.
|
|
89
|
+
*/
|
|
90
|
+
function withoutSelectionLayerWarning<T>(construct: () => T): T {
|
|
91
|
+
const warn = console.warn;
|
|
92
|
+
console.warn = (...args: unknown[]) => {
|
|
93
|
+
if (args[0] === 'Layer out of range, resetting to 2') return;
|
|
94
|
+
warn.apply(console, args);
|
|
95
|
+
};
|
|
96
|
+
try {
|
|
97
|
+
return construct();
|
|
98
|
+
} finally {
|
|
99
|
+
console.warn = warn;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** THE LAZY DOOR: load `postprocessing` on demand and build the effect. For a
|
|
104
|
+
* caller with no composer of its own, so the library arrives with the
|
|
105
|
+
* silhouette rather than with the surface. Repeat calls are free — the module
|
|
106
|
+
* is cached after the first. */
|
|
107
|
+
export async function loadThreeSelectionOutline(
|
|
108
|
+
scene: THREE.Scene,
|
|
109
|
+
camera: THREE.Camera,
|
|
110
|
+
colors: { readonly visible: number; readonly hidden: number },
|
|
111
|
+
): Promise<OutlineEffect> {
|
|
112
|
+
const { BlendFunction, KernelSize, OutlineEffect } = await import('postprocessing');
|
|
113
|
+
return createThreeSelectionOutline(
|
|
114
|
+
{ BlendFunction, KernelSize, OutlineEffect },
|
|
115
|
+
scene,
|
|
116
|
+
camera,
|
|
117
|
+
colors,
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Apply supplied renderer-ready colors without rebuilding GPU pass resources. */
|
|
122
|
+
export function setThreeSelectionOutlineColors(
|
|
123
|
+
effect: OutlineEffect,
|
|
124
|
+
colors: { readonly visible: number; readonly hidden: number },
|
|
125
|
+
): void {
|
|
126
|
+
effect.visibleEdgeColor.setHex(colors.visible);
|
|
127
|
+
effect.hiddenEdgeColor.setHex(colors.hidden);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function isOutlineRenderable(object: THREE.Object3D): boolean {
|
|
131
|
+
if ((object as THREE.Bone).isBone) return false;
|
|
132
|
+
return (
|
|
133
|
+
(object as THREE.Mesh).isMesh ||
|
|
134
|
+
(object as THREE.Line).isLine ||
|
|
135
|
+
(object as THREE.Points).isPoints ||
|
|
136
|
+
(object as THREE.Sprite).isSprite
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Expand selected semantic roots to the actual renderables postprocessing can
|
|
142
|
+
* mask. Selection rows commonly name a Group/component root, while an outline
|
|
143
|
+
* effect can only paint its Mesh/Line/Points/Sprite descendants.
|
|
144
|
+
*/
|
|
145
|
+
export function collectThreeSelectionOutlineTargets(
|
|
146
|
+
selectedRoots: Iterable<THREE.Object3D>,
|
|
147
|
+
): THREE.Object3D[] {
|
|
148
|
+
const targets: THREE.Object3D[] = [];
|
|
149
|
+
const seen = new Set<THREE.Object3D>();
|
|
150
|
+
for (const root of selectedRoots) {
|
|
151
|
+
// A bone has its own native joint highlight. Walking through it to a
|
|
152
|
+
// skinned/accessory descendant would make selecting the joint look like
|
|
153
|
+
// selecting the model instead.
|
|
154
|
+
if ((root as THREE.Bone).isBone) continue;
|
|
155
|
+
// Select what the component actually DRAWS, including implementation
|
|
156
|
+
// children folded out of the hierarchy. Unlike an AABB measurement, the
|
|
157
|
+
// mask pass cannot be poisoned by pooled/template geometry that is not
|
|
158
|
+
// currently rendered; it only paints pixels the subtree draws now.
|
|
159
|
+
root.traverse((object) => {
|
|
160
|
+
if (seen.has(object) || isInEditorOwnedSubtree(object) || !isOutlineRenderable(object)) {
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
seen.add(object);
|
|
164
|
+
targets.push(object);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return targets;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/** Update only when the concrete renderable set changed, avoiding layer churn. */
|
|
171
|
+
export function syncThreeSelectionOutline(
|
|
172
|
+
effect: OutlineEffect,
|
|
173
|
+
selectedRoots: Iterable<THREE.Object3D>,
|
|
174
|
+
): void {
|
|
175
|
+
const targets = collectThreeSelectionOutlineTargets(selectedRoots);
|
|
176
|
+
if (
|
|
177
|
+
effect.selection.size === targets.length &&
|
|
178
|
+
targets.every((target) => effect.selection.has(target))
|
|
179
|
+
) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
effect.selection.set(targets);
|
|
183
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { EDITOR_LAYER } from '@volter/editor-threejs/viewport/editor-layers';
|
|
2
|
+
import { getObjectMark, setObjectMark } from '@volter/editor-threejs/ecs/object-marks';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
|
|
5
|
+
const SKELETON_HELPER_TYPE = 'skeletons';
|
|
6
|
+
const SKELETON_PARENT_COLOR = new THREE.Color(0x00e5ff);
|
|
7
|
+
const SKELETON_CHILD_COLOR = new THREE.Color(0xffb000);
|
|
8
|
+
|
|
9
|
+
export function styleEditorSkeletonHelper(helper: THREE.SkeletonHelper): void {
|
|
10
|
+
const colors = helper.geometry.getAttribute('color');
|
|
11
|
+
// SkeletonHelper emits two vertices per bone link. Three's stock pure
|
|
12
|
+
// blue/green endpoints disappear against vgai's dark viewport, especially
|
|
13
|
+
// in captures. Keep the native helper geometry, but use editor-contrast
|
|
14
|
+
// colors so the inspection affordance is actually visible.
|
|
15
|
+
for (let i = 0; i < colors.count; i += 2) {
|
|
16
|
+
colors.setXYZ(i, SKELETON_PARENT_COLOR.r, SKELETON_PARENT_COLOR.g, SKELETON_PARENT_COLOR.b);
|
|
17
|
+
if (i + 1 < colors.count) {
|
|
18
|
+
colors.setXYZ(i + 1, SKELETON_CHILD_COLOR.r, SKELETON_CHILD_COLOR.g, SKELETON_CHILD_COLOR.b);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
colors.needsUpdate = true;
|
|
22
|
+
helper.renderOrder = 999;
|
|
23
|
+
const material = helper.material as THREE.LineBasicMaterial;
|
|
24
|
+
material.depthTest = false;
|
|
25
|
+
material.depthWrite = false;
|
|
26
|
+
material.toneMapped = false;
|
|
27
|
+
setObjectMark(helper, 'editorHelper', true);
|
|
28
|
+
setObjectMark(helper, 'editorHelperType', SKELETON_HELPER_TYPE);
|
|
29
|
+
helper.traverse((child) => child.layers.set(EDITOR_LAYER));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function ensureSkeletonHelper(root: THREE.Object3D): THREE.SkeletonHelper | null {
|
|
33
|
+
let existing: THREE.SkeletonHelper | null = null;
|
|
34
|
+
let hasSkinnedMesh = false;
|
|
35
|
+
root.traverse((object) => {
|
|
36
|
+
if (getObjectMark(object, 'editorHelperType') === SKELETON_HELPER_TYPE) {
|
|
37
|
+
existing = object as THREE.SkeletonHelper;
|
|
38
|
+
}
|
|
39
|
+
if ((object as THREE.SkinnedMesh).isSkinnedMesh) hasSkinnedMesh = true;
|
|
40
|
+
});
|
|
41
|
+
if (existing || !hasSkinnedMesh) return existing;
|
|
42
|
+
|
|
43
|
+
const helper = new THREE.SkeletonHelper(root);
|
|
44
|
+
if (helper.bones.length === 0) {
|
|
45
|
+
helper.dispose();
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
styleEditorSkeletonHelper(helper);
|
|
49
|
+
|
|
50
|
+
// SkeletonHelper normally expects to be a scene-root sibling. Keeping it
|
|
51
|
+
// under the entity makes lifecycle cleanup automatic, so use entity-local
|
|
52
|
+
// coordinates instead of applying the entity world transform twice.
|
|
53
|
+
helper.matrix = new THREE.Matrix4();
|
|
54
|
+
helper.matrixAutoUpdate = false;
|
|
55
|
+
helper.name = 'EditorSkeletonHelper';
|
|
56
|
+
helper.visible = Boolean(getObjectMark(root, 'skeletonVisible'));
|
|
57
|
+
setObjectMark(helper, 'skeletonEnabled', helper.visible);
|
|
58
|
+
root.add(helper);
|
|
59
|
+
root.updateMatrixWorld(true);
|
|
60
|
+
return helper;
|
|
61
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The colour to give a TONE-MAPPED material so the screen shows the palette's
|
|
5
|
+
* exact sRGB hex — the inverse of three's ACES fit (the input and output
|
|
6
|
+
* matrices and the RRT/ODT rational, `tonemapping_pars_fragment`) through the
|
|
7
|
+
* exposure; Linear divides by it; no tone mapping passes through; any other
|
|
8
|
+
* operator is left as-is.
|
|
9
|
+
*
|
|
10
|
+
* WHICH SURFACES ACTUALLY WANT IT, measured on the live Model stage
|
|
11
|
+
* (`document-script` over the session's scene, beside a `capture-editor-chrome`
|
|
12
|
+
* frame of the same instant — the chrome door serves the PRESENTED frame, so
|
|
13
|
+
* the two are the same pixels):
|
|
14
|
+
*
|
|
15
|
+
* - `scene.background` as a `THREE.Color`: **no**. three does not shade a
|
|
16
|
+
* colour background, it CLEARS to it (`WebGLBackground.setClear` →
|
|
17
|
+
* `glClearColor`), so no fragment shader and no tone map ever touches it.
|
|
18
|
+
* Measured: the scene held `#494949` — this function's inversion of the
|
|
19
|
+
* palette's `#3f3f3f` — and the screen read `#494949` exactly, luminance
|
|
20
|
+
* 73 against Blender's 63. The inversion was compensating for a transform
|
|
21
|
+
* that does not run, and that alone is what made the stage light.
|
|
22
|
+
* - the floor grid (`editor-floor-grid`, a `ShaderMaterial` with
|
|
23
|
+
* `toneMapped: true`): **yes**. Measured: `uColor` held `#575757` — this
|
|
24
|
+
* function's inversion of the palette's `#545454` — and the 1 m line read
|
|
25
|
+
* 83–84 on screen, i.e. the operator ran and landed it on the palette.
|
|
26
|
+
* - the floor axes (`LineSegments2`/`LineMaterial`, `toneMapped: false`):
|
|
27
|
+
* **no**. `toneMapped: false` is honoured per material (three compiles the
|
|
28
|
+
* tone-map chunk per program, not as a composer output pass), so the
|
|
29
|
+
* inverted colour reached the screen raw and over-saturated: `#ee234d`
|
|
30
|
+
* where Blender's X axis is `#cb293f`.
|
|
31
|
+
*
|
|
32
|
+
* So the operator runs PER MATERIAL here, not in a final composer pass: the
|
|
33
|
+
* grid's `toneMapped: true` was mapped and the axes' `toneMapped: false` was
|
|
34
|
+
* not, in the same frame, through the same composer.
|
|
35
|
+
*/
|
|
36
|
+
export function toneMappedSourceColor(
|
|
37
|
+
hex: number,
|
|
38
|
+
renderer: THREE.WebGLRenderer | undefined,
|
|
39
|
+
): THREE.Color {
|
|
40
|
+
const target = new THREE.Color(hex); // sRGB hex → linear, three's management
|
|
41
|
+
if (!renderer || renderer.toneMapping === THREE.NoToneMapping) return target;
|
|
42
|
+
const exposure = renderer.toneMappingExposure || 1;
|
|
43
|
+
if (renderer.toneMapping === THREE.LinearToneMapping) return target.multiplyScalar(1 / exposure);
|
|
44
|
+
if (renderer.toneMapping === THREE.AgXToneMapping) return agxSourceColor(target, exposure);
|
|
45
|
+
if (renderer.toneMapping !== THREE.ACESFilmicToneMapping) return target;
|
|
46
|
+
const IN: Mat3 = [
|
|
47
|
+
[0.59719, 0.35458, 0.04823],
|
|
48
|
+
[0.076, 0.90834, 0.01566],
|
|
49
|
+
[0.0284, 0.13383, 0.83777],
|
|
50
|
+
];
|
|
51
|
+
const OUT: Mat3 = [
|
|
52
|
+
[1.60475, -0.53108, -0.07367],
|
|
53
|
+
[-0.10208, 1.10813, -0.00605],
|
|
54
|
+
[-0.00327, -0.07276, 1.07602],
|
|
55
|
+
];
|
|
56
|
+
const fit = (v: number) =>
|
|
57
|
+
(v * (v + 0.0245786) - 0.000090537) / (v * (0.983729 * v + 0.432951) + 0.238081);
|
|
58
|
+
const invertFit = (f: number) => {
|
|
59
|
+
let lo = 0;
|
|
60
|
+
let hi = 64;
|
|
61
|
+
for (let i = 0; i < 60; i++) {
|
|
62
|
+
const mid = (lo + hi) / 2;
|
|
63
|
+
if (fit(mid) < f) lo = mid;
|
|
64
|
+
else hi = mid;
|
|
65
|
+
}
|
|
66
|
+
return (lo + hi) / 2;
|
|
67
|
+
};
|
|
68
|
+
const f = mulMat3(invertMat3(OUT), [target.r, target.g, target.b]);
|
|
69
|
+
const u = f.map((c) => (c <= 0 ? 0 : invertFit(Math.min(c, 0.999)))) as Vec3;
|
|
70
|
+
const x = mulMat3(invertMat3(IN), u).map((c) => Math.max(0, c) * (0.6 / exposure)) as Vec3;
|
|
71
|
+
return new THREE.Color().setRGB(x[0], x[1], x[2], THREE.LinearSRGBColorSpace);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* The same inversion for AgX — the operator the Blender look's stage runs
|
|
75
|
+
* (`ToolViewportDressing.toneMapping`), because Blender's own scene does.
|
|
76
|
+
*
|
|
77
|
+
* Every step of `AgXToneMapping` (`tonemapping_pars_fragment.glsl`) run
|
|
78
|
+
* backwards: the Rec.2020 round trip, the outset matrix, the 2.2 linearize,
|
|
79
|
+
* the sigmoid (bisected — the contrast approximation is a sixth-order
|
|
80
|
+
* polynomial with no closed inverse), the log2 encode, and the inset matrix.
|
|
81
|
+
* three spells its matrices COLUMN-major, as GLSL's `mat3(vec3, vec3, vec3)`
|
|
82
|
+
* constructor does; these are the transposes, because {@link mulMat3} is
|
|
83
|
+
* row-major.
|
|
84
|
+
*/
|
|
85
|
+
function agxSourceColor(target: THREE.Color, exposure: number): THREE.Color {
|
|
86
|
+
// three spells its matrices COLUMN-major, as GLSL's `mat3(vec3, vec3, vec3)`
|
|
87
|
+
// constructor does; these are the transposes, because {@link mulMat3} is
|
|
88
|
+
// row-major. Every row sums to 1 — each of the four is grey-preserving, and
|
|
89
|
+
// that is the cheap check that the transposition is the right way round.
|
|
90
|
+
const SRGB_TO_REC2020: Mat3 = [
|
|
91
|
+
[0.6274, 0.3293, 0.0433],
|
|
92
|
+
[0.0691, 0.9195, 0.0113],
|
|
93
|
+
[0.0164, 0.088, 0.8956],
|
|
94
|
+
];
|
|
95
|
+
const REC2020_TO_SRGB: Mat3 = [
|
|
96
|
+
[1.6605, -0.5876, -0.0728],
|
|
97
|
+
[-0.1246, 1.1329, -0.0083],
|
|
98
|
+
[-0.0182, -0.1006, 1.1187],
|
|
99
|
+
];
|
|
100
|
+
const INSET: Mat3 = [
|
|
101
|
+
[0.856627153315983, 0.0951212405381588, 0.0482516061458583],
|
|
102
|
+
[0.137318972929847, 0.761241990602591, 0.101439036467562],
|
|
103
|
+
[0.11189821299995, 0.0767994186031903, 0.811302368396859],
|
|
104
|
+
];
|
|
105
|
+
const OUTSET: Mat3 = [
|
|
106
|
+
[1.1271005818144368, -0.11060664309660323, -0.016493938717834573],
|
|
107
|
+
[-0.1413297634984383, 1.157823702216272, -0.016493938717834257],
|
|
108
|
+
[-0.14132976349843826, -0.11060664309660294, 1.2519364065950405],
|
|
109
|
+
];
|
|
110
|
+
const MIN_EV = -12.47393;
|
|
111
|
+
const MAX_EV = 4.026069;
|
|
112
|
+
const contrast = (x: number) => {
|
|
113
|
+
const x2 = x * x;
|
|
114
|
+
const x4 = x2 * x2;
|
|
115
|
+
return (
|
|
116
|
+
15.5 * x4 * x2 -
|
|
117
|
+
40.14 * x4 * x +
|
|
118
|
+
31.96 * x4 -
|
|
119
|
+
6.868 * x2 * x +
|
|
120
|
+
0.4298 * x2 +
|
|
121
|
+
0.1191 * x -
|
|
122
|
+
0.00232
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
const invertContrast = (f: number) => {
|
|
126
|
+
let lo = 0;
|
|
127
|
+
let hi = 1;
|
|
128
|
+
for (let i = 0; i < 60; i++) {
|
|
129
|
+
const mid = (lo + hi) / 2;
|
|
130
|
+
if (contrast(mid) < f) lo = mid;
|
|
131
|
+
else hi = mid;
|
|
132
|
+
}
|
|
133
|
+
return (lo + hi) / 2;
|
|
134
|
+
};
|
|
135
|
+
// Every step of the forward operator, backwards and in reverse order.
|
|
136
|
+
const rec2020 = mulMat3(SRGB_TO_REC2020, [target.r, target.g, target.b]);
|
|
137
|
+
const sigmoid = mulMat3(
|
|
138
|
+
invertMat3(OUTSET),
|
|
139
|
+
rec2020.map((c) => Math.max(0, c) ** (1 / 2.2)) as Vec3,
|
|
140
|
+
);
|
|
141
|
+
const open = sigmoid.map((c) => 2 ** (invertContrast(c) * (MAX_EV - MIN_EV) + MIN_EV)) as Vec3;
|
|
142
|
+
const linear = mulMat3(REC2020_TO_SRGB, mulMat3(invertMat3(INSET), open)).map(
|
|
143
|
+
(c) => Math.max(0, c) / exposure,
|
|
144
|
+
) as Vec3;
|
|
145
|
+
return new THREE.Color().setRGB(linear[0], linear[1], linear[2], THREE.LinearSRGBColorSpace);
|
|
146
|
+
}
|
|
147
|
+
type Vec3 = [number, number, number];
|
|
148
|
+
type Mat3 = [Vec3, Vec3, Vec3];
|
|
149
|
+
function mulMat3(m: Mat3, v: Vec3): Vec3 {
|
|
150
|
+
return [
|
|
151
|
+
m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2],
|
|
152
|
+
m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2],
|
|
153
|
+
m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2],
|
|
154
|
+
];
|
|
155
|
+
}
|
|
156
|
+
function invertMat3(m: Mat3): Mat3 {
|
|
157
|
+
const [[a, b, c], [d, e, f], [g, h, i]] = m;
|
|
158
|
+
const A = e * i - f * h;
|
|
159
|
+
const B = -(d * i - f * g);
|
|
160
|
+
const C = d * h - e * g;
|
|
161
|
+
const det = a * A + b * B + c * C;
|
|
162
|
+
return [
|
|
163
|
+
[A / det, -(b * i - c * h) / det, (b * f - c * e) / det],
|
|
164
|
+
[B / det, (a * i - c * g) / det, -(a * f - c * d) / det],
|
|
165
|
+
[C / det, -(a * h - b * g) / det, (a * e - b * d) / det],
|
|
166
|
+
];
|
|
167
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The LOOK LANES' neutral studio IBL — `scene.environment` for every surface
|
|
3
|
+
* that photographs an asset instead of displaying it: the Asset Lab capture
|
|
4
|
+
* path (`asset-preview.ts`: the model-file lane, `vgai screenshot <module>`
|
|
5
|
+
* through `project.bake.preview`, labeled shot sets, source-review sheets,
|
|
6
|
+
* splats) and the asset-browser thumbnails (`model-thumbnail.ts`).
|
|
7
|
+
*
|
|
8
|
+
* Why it exists: a `MeshStandardMaterial` with `metalness: 1` has NO diffuse
|
|
9
|
+
* term — everything it shows is reflected environment. Lit by directional
|
|
10
|
+
* lights alone it renders BLACK with a pinprick specular, so iron reads as
|
|
11
|
+
* painted plastic, and the measured cost of that (cold barrel, 2026-08-29) is
|
|
12
|
+
* that agents detune `metalness` to survive the screenshot — the look lane
|
|
13
|
+
* silently teaching a wrong material value into shipped assets.
|
|
14
|
+
*
|
|
15
|
+
* The bake is three's own `RoomEnvironment` through `PMREMGenerator`, reused
|
|
16
|
+
* verbatim from the document viewport's dressing
|
|
17
|
+
* ({@link createStandardEnvironment}) so a capture and the open document light
|
|
18
|
+
* the same subject the same way. Procedural: no HDRI binary, deterministic
|
|
19
|
+
* frame to frame.
|
|
20
|
+
*
|
|
21
|
+
* Two rules this module exists to hold:
|
|
22
|
+
*
|
|
23
|
+
* - **`environment` only, never `background`.** Each lane keeps its own
|
|
24
|
+
* backdrop (the Asset Lab's neutral clear colour, or transparent). An IBL
|
|
25
|
+
* that also painted the background would change every existing frame's
|
|
26
|
+
* composition, not just its materials.
|
|
27
|
+
* - **One bake per renderer.** A PMREM target is GL-context-bound, so it
|
|
28
|
+
* cannot be shared across renderers, and baking it per SCENE would pay for
|
|
29
|
+
* it once per shot in a 24-frame orbit. The cache is keyed by renderer and
|
|
30
|
+
* freed through {@link disposeStudioEnvironment}, which every caller that
|
|
31
|
+
* disposes its renderer must call — a PMREM render target leaks otherwise.
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import {
|
|
35
|
+
createStandardEnvironment,
|
|
36
|
+
type StandardEnvironment,
|
|
37
|
+
} from '@volter/editor-threejs/viewport/environment';
|
|
38
|
+
import type * as THREE from 'three';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* How hard the IBL pushes against the lane's existing key/fill rig.
|
|
42
|
+
*
|
|
43
|
+
* The key and fill are UNCHANGED — they still own the form, the direction of
|
|
44
|
+
* the shading and the highlight. This is a reflection budget, not a second key.
|
|
45
|
+
*
|
|
46
|
+
* The blend was picked by reading before/after pairs of the barrel GLB and a
|
|
47
|
+
* metalness sweep in the module lane, holding the wood constant and asking how
|
|
48
|
+
* little environment buys back the metal:
|
|
49
|
+
* - 1.0 with the ambient untouched: the iron reads, the wood lifts and flattens
|
|
50
|
+
* — the shadow side of the staves fills in and the stave-to-stave tone
|
|
51
|
+
* variation collapses;
|
|
52
|
+
* - 0.55 with {@link STUDIO_AMBIENT_WITH_ENVIRONMENT} at 0.35: metal good,
|
|
53
|
+
* wood still visibly brighter and lower-contrast than the historical frame;
|
|
54
|
+
* - 0.45 with the ambient at 0.25 (shipped): the wood frame is indistinguishable
|
|
55
|
+
* from the historical one at full scale — same warmth, same grain, same
|
|
56
|
+
* terminator — while every hoop gains a gradient across the band and the
|
|
57
|
+
* bottom hoop stops reading as a shadow.
|
|
58
|
+
*/
|
|
59
|
+
export const STUDIO_ENVIRONMENT_INTENSITY = 0.45;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The lanes' ambient fill is REDUCED when the IBL is present: a
|
|
63
|
+
* hemisphere/ambient light is a crude stand-in for exactly what the environment
|
|
64
|
+
* now does properly, and leaving both at full strength double-pays the ambient
|
|
65
|
+
* term and washes the subject. Each lane multiplies its own historical ambient
|
|
66
|
+
* intensity by this, so the total ambient energy lands near where it was and
|
|
67
|
+
* only its DIRECTIONALITY improves.
|
|
68
|
+
*/
|
|
69
|
+
export const STUDIO_AMBIENT_WITH_ENVIRONMENT = 0.25;
|
|
70
|
+
|
|
71
|
+
const perRenderer = new WeakMap<THREE.WebGLRenderer, StandardEnvironment>();
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Light `scene` with the studio IBL baked for `renderer`, baking it on first
|
|
75
|
+
* use for that renderer. `scene.background` is deliberately untouched.
|
|
76
|
+
*/
|
|
77
|
+
export function applyStudioEnvironment(scene: THREE.Scene, renderer: THREE.WebGLRenderer): void {
|
|
78
|
+
let environment = perRenderer.get(renderer);
|
|
79
|
+
if (!environment) {
|
|
80
|
+
environment = createStandardEnvironment(renderer);
|
|
81
|
+
perRenderer.set(renderer, environment);
|
|
82
|
+
}
|
|
83
|
+
scene.environment = environment.texture;
|
|
84
|
+
scene.environmentIntensity = STUDIO_ENVIRONMENT_INTENSITY;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Free the bake this renderer owns. Idempotent, and safe for a renderer that
|
|
89
|
+
* never had one — call it beside `renderer.dispose()`.
|
|
90
|
+
*/
|
|
91
|
+
export function disposeStudioEnvironment(renderer: THREE.WebGLRenderer): void {
|
|
92
|
+
const environment = perRenderer.get(renderer);
|
|
93
|
+
if (!environment) return;
|
|
94
|
+
perRenderer.delete(renderer);
|
|
95
|
+
environment.dispose();
|
|
96
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type ThreeViewportProjection = 'perspective' | 'orthographic';
|
|
2
|
+
|
|
3
|
+
export interface ThreeViewportPresentationState {
|
|
4
|
+
readonly projection: ThreeViewportProjection;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
let state: ThreeViewportPresentationState = { projection: 'perspective' };
|
|
8
|
+
const listeners = new Set<() => void>();
|
|
9
|
+
|
|
10
|
+
export function threeViewportPresentation(): ThreeViewportPresentationState {
|
|
11
|
+
return state;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function subscribeThreeViewportPresentation(listener: () => void): () => void {
|
|
15
|
+
listeners.add(listener);
|
|
16
|
+
return () => listeners.delete(listener);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function setThreeViewportProjection(projection: ThreeViewportProjection): void {
|
|
20
|
+
if (state.projection === projection) return;
|
|
21
|
+
state = { ...state, projection };
|
|
22
|
+
for (const listener of listeners) listener();
|
|
23
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `play` channel every project contribution's props carry — ONE resolution
|
|
3
|
+
* of "which live game is this contribution looking at", read by all four
|
|
4
|
+
* contribution hosts (`components/ToolHost.tsx`,
|
|
5
|
+
* `components/InspectorToolSection.tsx`,
|
|
6
|
+
* `components/AssetInspectorToolSection.tsx`, and `@vgai/game`'s generation
|
|
7
|
+
* documents).
|
|
8
|
+
*
|
|
9
|
+
* A dev-GUI contribution's whole subject is the running game (owner ruling,
|
|
10
|
+
* `docs/ARCHITECTURE-CORE.md`, 2026-08-19), and this is its door to one.
|
|
11
|
+
*
|
|
12
|
+
* THE DEPENDENCY POINTS THE OTHER WAY, deliberately — play-mode PUBLISHES a
|
|
13
|
+
* reader here, and this module imports nothing of play-mode's. That is the
|
|
14
|
+
* same shape `performance-sources.ts` uses, and it is load-bearing rather than
|
|
15
|
+
* stylistic: an inspector section importing play-mode drags the entire runtime
|
|
16
|
+
* boot chain (renderer setup, vendored postprocessing, WebGL) into every
|
|
17
|
+
* module graph that mounts one — which is a real cost in the editor and an
|
|
18
|
+
* outright import-time crash in a headless host.
|
|
19
|
+
*
|
|
20
|
+
* RESOURCE OWNERSHIP: the reader is play-mode's, for the exact lifetime of one
|
|
21
|
+
* play session. It is the only writer, `publishToolContributionPlay(null)` on
|
|
22
|
+
* exit is the only teardown, and nothing here caches its result.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import type { ToolContributionPlay } from '@volter/editor-sdk/contributions';
|
|
26
|
+
import { subscribeInspectedInstance } from './authoring/active-systems';
|
|
27
|
+
|
|
28
|
+
type PlayReader = () => ToolContributionPlay | null;
|
|
29
|
+
|
|
30
|
+
let _read: PlayReader | null = null;
|
|
31
|
+
const _listeners = new Set<() => void>();
|
|
32
|
+
|
|
33
|
+
/** Publish the live reader for a play session, or `null` when one ends. */
|
|
34
|
+
export function publishToolContributionPlay(read: PlayReader | null): void {
|
|
35
|
+
_read = read;
|
|
36
|
+
for (const listener of _listeners) listener();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** The inspected play instance, or `null` while nothing is playing. */
|
|
40
|
+
export function toolContributionPlay(): ToolContributionPlay | null {
|
|
41
|
+
return _read?.() ?? null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Observe the two things that change WHICH game a contribution is bound to: a
|
|
46
|
+
* session starting or stopping (the publication above), and the Inspect
|
|
47
|
+
* selector moving between live seats. Both, because either alone leaves a host
|
|
48
|
+
* describing another mount's game — and the split is exactly the case where
|
|
49
|
+
* that is invisible.
|
|
50
|
+
*/
|
|
51
|
+
export function subscribeToolContributionPlay(listener: () => void): () => void {
|
|
52
|
+
_listeners.add(listener);
|
|
53
|
+
const unsubscribeInstance = subscribeInspectedInstance(listener);
|
|
54
|
+
return () => {
|
|
55
|
+
_listeners.delete(listener);
|
|
56
|
+
unsubscribeInstance();
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* A stable identity for the bound instance — the `getSnapshot` for
|
|
62
|
+
* {@link subscribeToolContributionPlay}.
|
|
63
|
+
*
|
|
64
|
+
* A STRING rather than the `play` object itself, because
|
|
65
|
+
* `useSyncExternalStore` compares snapshots with `Object.is` and
|
|
66
|
+
* {@link toolContributionPlay} builds a fresh object on every call: returning
|
|
67
|
+
* that would report a change on every render and loop. The mount id is enough
|
|
68
|
+
* to key on because it is never reused (`play-mode.ts`'s instance-identity
|
|
69
|
+
* block), so a remount is always a new value.
|
|
70
|
+
*/
|
|
71
|
+
export function toolContributionPlayKey(): string {
|
|
72
|
+
const play = toolContributionPlay();
|
|
73
|
+
return play ? `play:${play.instanceId}` : 'stopped';
|
|
74
|
+
}
|