@volter/editor-game 0.5.66 → 0.5.68
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/contributions/audio-unlock.service.ts +2 -2
- package/contributions/autoplay.service.ts +1 -1
- package/contributions/bridge.command.ts +3 -3
- package/contributions/build-player.document.tsx +95 -0
- package/contributions/canvas/component-board.service.ts +16 -0
- package/contributions/canvas/design-time-mount.service.ts +45 -0
- package/contributions/canvas-story-capture.service.ts +12 -0
- package/contributions/edit-mode-audio.service.ts +2 -2
- package/contributions/edit-mode-networking.service.ts +1 -1
- package/contributions/gameplay.command.ts +4 -4
- package/contributions/generation.service.ts +1 -1
- package/contributions/godot.style.ts +26 -6
- package/contributions/godot.view.ts +6 -0
- package/contributions/ingest.service.ts +2 -2
- package/contributions/instances.command.ts +1 -1
- package/contributions/navmesh.menu.ts +1 -1
- package/contributions/network-observer.service.ts +14 -0
- package/contributions/play.command.ts +10 -4
- package/contributions/react/component-board.service.ts +1 -1
- package/contributions/react/design-time-mount.service.ts +1 -1
- package/contributions/scene-document.service.ts +3 -3
- package/contributions/state-watch.menu.ts +1 -1
- package/contributions/state-watch.utility.tsx +1 -1
- package/contributions/team-playtest.service.ts +4 -4
- package/contributions/three/component-board.service.ts +1 -1
- package/contributions/three/component-verbs.command.ts +6 -6
- package/contributions/three/three-authoring.service.ts +8 -5
- package/contributions/three-story-capture.service.ts +12 -0
- package/contributions/unity.style.ts +17 -7
- package/contributions/unity.view.ts +6 -0
- package/contributions/unreal.style.ts +10 -2
- package/contributions/unreal.view.ts +5 -0
- package/package.json +21 -10
- package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
- package/src/asset-budget/asset-budget-model.ts +1 -1
- package/src/audio/AudioDebuggerPanel.tsx +1 -1
- package/src/bridge/dispatch.ts +14 -14
- package/src/bridge/live-frames.ts +1 -1
- package/src/bridge/screenshot.ts +3 -3
- package/src/build/BuildProfilesPanel.tsx +14 -3
- package/src/build/build-session.ts +35 -0
- package/src/canvas/canvas-board/CanvasBoardDocument.tsx +749 -0
- package/src/canvas/canvas-board/canvas-board-model.ts +407 -0
- package/src/canvas/canvas-board/canvas-component-board.ts +56 -0
- package/src/canvas/canvas-design-mount.ts +524 -0
- package/src/canvas/design-time-canvas-mount.ts +79 -0
- package/src/coverage/live-authoring-surface.ts +5 -5
- package/src/coverage/live-project-verbs.ts +1 -1
- package/src/coverage/native-system-coverage.ts +5 -5
- package/src/coverage/root-coverage.ts +1 -1
- package/src/coverage/session-coverage.ts +3 -3
- package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +7 -7
- package/src/edit-mode/edit-mode-audio.ts +4 -4
- package/src/edit-mode/edit-mode-networking.ts +2 -2
- package/src/game-document/GameCaptureFrameButton.tsx +1 -1
- package/src/game-document/GameDocument.tsx +2 -2
- package/src/game-document/GamePanel.tsx +4 -4
- package/src/game-document/InstanceInspectorPicker.tsx +2 -2
- package/src/game-document/crowd-debug.ts +1 -1
- package/src/game-document/device-preview.ts +10 -11
- package/src/game-document/physics-debug.ts +1 -1
- package/src/generation/GenerationActivity.tsx +3 -3
- package/src/generation/generation-documents.tsx +5 -5
- package/src/generation/generation-jobs.ts +1 -1
- package/src/host/adapter-runtime-bindings.ts +96 -5
- package/src/host/authoring/babylon-authoring-adapter.ts +6 -6
- package/src/host/authoring/gesture-persist.ts +1 -1
- package/src/host/authoring/ingest-data-writer.ts +1 -1
- package/src/host/authoring/ingest-source-persistence.ts +4 -4
- package/src/host/authoring/mounted-authoring.ts +4 -4
- package/src/host/authoring/phaser-live-authoring-adapter.ts +4 -4
- package/src/host/authoring/pixi-authoring-adapter.ts +178 -31
- package/src/host/authoring/pixi-creatable-kinds.ts +62 -0
- package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
- package/src/host/authoring/pixi-live-write-target.ts +4 -4
- package/src/host/authoring/pixi-source-identity.ts +3 -3
- package/src/host/authoring/pixi-source-write-target.ts +1709 -0
- package/src/host/authoring/pixi-still-presentation.ts +1 -1
- package/src/host/authoring/pixi-structure-history.ts +2 -2
- package/src/host/authoring/pixi-transform-channels.ts +16 -14
- package/src/host/authoring/source-persistence-backend.ts +3 -3
- package/src/host/authoring/struct-write-pipe.ts +1 -1
- package/src/host/binding-resolver.ts +8 -9
- package/src/host/browser-transpile.ts +1 -1
- package/src/host/canvas-entry-runtime.ts +58 -47
- package/src/host/canvas-preview-frames.ts +482 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
- package/src/host/components/HeaderTelemetry.tsx +4 -4
- package/src/host/components/PixiIsolationSceneContent.tsx +11 -11
- package/src/host/components/ThreeIsolationSceneContent.tsx +3 -3
- package/src/host/components/frame-debugger-model.ts +2 -2
- package/src/host/components/header-telemetry-model.ts +2 -2
- package/src/host/components/scene-document.tsx +14 -14
- package/src/host/components/utility-view-state.ts +1 -1
- package/src/host/components/world-root-stage-binding.tsx +12 -12
- package/src/host/components/world-root-stage.ts +70 -49
- package/src/host/coverage/system-adapter-coverage.ts +3 -4
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +9 -11
- package/src/host/document-preview-three.ts +1 -1
- package/src/host/entry-adjudication.ts +6 -6
- package/src/host/game-css-scope-transform.ts +4 -0
- package/src/host/game-realm-page.ts +1 -1
- package/src/host/gameplay-export.ts +25 -14
- package/src/host/gameplay-recording.ts +5 -5
- package/src/host/gated-globals.ts +2 -2
- package/src/host/history/json-history-resource.ts +1 -1
- package/src/host/projection/pixi.ts +24 -2
- package/src/host/r3f-entry-runtime.ts +65 -34
- package/src/host/react-mount-runtime.ts +7 -48
- package/src/host/realm-services.ts +1 -1
- package/src/host/roots/canvas-root.tsx +373 -0
- package/src/host/roots/r3f-root.tsx +473 -0
- package/src/host/roots/react-root.ts +9 -43
- package/src/host/served-bundle-runtime-modules.ts +3 -19
- package/src/host/server-log-bridge.ts +2 -2
- package/src/host/stories/mounted-story-viewport-source.ts +1 -1
- package/src/host/stories/pixi-story-model.ts +30 -0
- package/src/host/stories/story-media-captures.ts +46 -0
- package/src/host/stories/story-media-presence.ts +3 -3
- package/src/host/stories/story-pixi-preview.ts +408 -0
- package/src/host/stories/story-three-preview.ts +806 -0
- package/src/host/stories/three-story-captures.ts +35 -0
- package/src/host/story-three-preview-runtime.ts +56 -0
- package/src/host/use-active-performance-source.ts +2 -2
- package/src/host/viewport-pose-memory.ts +1 -1
- package/src/host/viewport-root-presentation.ts +6 -5
- package/src/ingest/active-ingest.ts +1 -1
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
- package/src/ingest/authoring/ingest-root-adapter.ts +8 -8
- package/src/ingest/deferred-ingest-play.ts +6 -6
- package/src/ingest/discovery-public-ingest.ts +2 -2
- package/src/ingest/ingest-boot-viewport.ts +2 -2
- package/src/ingest/ingest-canvas-scene-document.tsx +9 -9
- package/src/ingest/ingest-canvas-scene.ts +3 -3
- package/src/ingest/ingest-evidence-hook.ts +1 -1
- package/src/ingest/ingest-frame-snapshot.ts +1 -1
- package/src/ingest/ingest-play-control.ts +1 -1
- package/src/ingest/ingest-render-debug.ts +10 -10
- package/src/ingest/ingest-siblings.ts +13 -25
- package/src/ingest/module-mode.ts +14 -14
- package/src/ingest/mount-canvas-ingest-root.ts +21 -21
- package/src/ingest/mount-coverage.ts +2 -2
- package/src/ingest/mount-dom-ingest-root.ts +11 -11
- package/src/ingest/mount-ingest-root.ts +8 -8
- package/src/ingest/mount-three-ingest-root.ts +8 -8
- package/src/ingest/resolve-canvas.ts +1 -1
- package/src/ingest/served-html-boot.ts +1 -1
- package/src/ingest/surface-canvas.ts +1 -1
- package/src/ingest/unmount-ingest-root.ts +5 -5
- package/src/navmesh/navmesh-handler.ts +24 -16
- package/src/network/NetworkInspectorPanel.tsx +939 -37
- package/src/network/network-inspector-model.ts +20 -2
- package/src/play/play-log-events.ts +1 -1
- package/src/play/play-mode.ts +76 -133
- package/src/play/play-recording.ts +1 -1
- package/src/play/react-play-live-authoring.ts +3 -3
- package/src/play/run-selection.ts +93 -0
- package/src/play-bar/PlayBar.tsx +20 -39
- package/src/profiler/FrameDebuggerPanel.tsx +1 -1
- package/src/profiler/PerformancePanel.tsx +3 -3
- package/src/react/design-time-react-mount.ts +23 -65
- package/src/react/dom-authoring-adapter.ts +9 -9
- package/src/react/react-inspector-section.tsx +5 -5
- package/src/react/react-world-authoring-adapter.ts +11 -11
- package/src/react/story-documents/story-documents.tsx +9 -9
- package/src/react/ui-board-document.tsx +7 -7
- package/src/react/ui-component-board.ts +2 -2
- package/src/runtime/adapter/audio-meter.ts +21 -0
- package/src/runtime/adapter/first-party-audio-system.ts +230 -0
- package/src/runtime/adapter/ingest/contract-debug-adapter.ts +114 -0
- package/src/runtime/adapter/ingest/contract-system-adapters.ts +256 -0
- package/src/runtime/adapter/ingest/merge-debug-adapters.ts +197 -0
- package/src/runtime/adapter/ingest/observation-debug-adapter.ts +162 -0
- package/src/runtime/adapter/ingest/upstream-pin.ts +51 -0
- package/src/runtime/adapter/native-debug-module.ts +498 -0
- package/src/runtime/audio/bus-mixer.ts +161 -0
- package/src/runtime/audio/pose-guard.ts +80 -0
- package/src/runtime/core/frame-pacing.ts +126 -0
- package/src/runtime/core/game-loop.ts +225 -0
- package/src/runtime/core/game-scoped-slot.ts +28 -0
- package/src/runtime/core/seeded-random.ts +162 -0
- package/src/runtime/core/sim-clock.ts +391 -0
- package/src/runtime/core/system-runner.ts +269 -0
- package/src/runtime/core/types.ts +104 -0
- package/src/runtime/create-runtime.ts +1128 -0
- package/src/runtime/debug-bridge.ts +570 -0
- package/src/runtime/debug-registry.ts +899 -0
- package/src/runtime/dev/chrome-trace.ts +153 -0
- package/src/runtime/dev/instruments.ts +403 -0
- package/src/runtime/dev/logger.ts +119 -0
- package/src/runtime/dev/performance-profiler.ts +367 -0
- package/src/runtime/dev/register-render-vitals.ts +276 -0
- package/src/runtime/dev/render-census.ts +354 -0
- package/src/runtime/dev/render-debug-adapter.ts +218 -0
- package/src/runtime/dev/render-memory.ts +226 -0
- package/src/runtime/dev/render-vitals.ts +338 -0
- package/src/runtime/dev/static-batch-advisor.ts +188 -0
- package/src/runtime/dev/webgl-frame-capture.ts +366 -0
- package/src/runtime/dev/webgl-gpu-timer.ts +53 -0
- package/src/runtime/dev-build.ts +47 -0
- package/src/runtime/game.ts +1636 -0
- package/src/runtime/gameplay-rng-trap.ts +135 -0
- package/src/runtime/host-context.ts +64 -0
- package/src/runtime/input-router.ts +182 -0
- package/src/runtime/mount-manifest.ts +480 -0
- package/src/runtime/pixi/authoring.ts +706 -0
- package/src/runtime/pixi/ingest.ts +116 -0
- package/src/runtime/pixi/physics-registry.ts +49 -0
- package/src/runtime/pixi/render-pass-bracket.ts +117 -0
- package/src/runtime/pixi/scene-capture.ts +179 -0
- package/src/runtime/pixi/system-adapters.ts +69 -0
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/presentation.ts +141 -0
- package/src/runtime/render-control.ts +642 -0
- package/src/runtime/render-seed.ts +77 -0
- package/src/runtime/run-ticks-settled.ts +73 -0
- package/src/runtime/setup/setup-audio.ts +72 -0
- package/src/services/audio-pose-guard.ts +2 -2
- package/src/services/game-audio.ts +152 -0
- package/src/services/game-network.ts +767 -0
- package/src/services/game-physics.ts +334 -0
- package/src/state-watch/StateWatchPanel.tsx +1 -1
- package/src/three/authoring/camera-runtime-inspector-section.tsx +3 -2
- package/src/three/authoring/constraint-inspector-section.tsx +6 -5
- package/src/three/authoring/model-asset-inspector-section.tsx +7 -6
- package/src/three/authoring/oid-source-persistence.ts +7 -7
- package/src/three/authoring/r3f-design-session.ts +58 -54
- package/src/three/authoring/r3f-source-authoring-adapter.ts +95 -91
- package/src/three/authoring/reflection-probe-inspector-section.tsx +3 -2
- package/src/three/authoring/three-authoring-adapter.ts +29 -29
- package/src/three/component-verbs/extract-menu.ts +7 -6
- package/src/three/component-verbs/fork-menu.ts +7 -6
- package/src/three/component-verbs/internals-menu.ts +2 -2
- package/src/three/story-documents/three-story-documents.tsx +13 -13
- package/src/three/three-board/ThreeBoardDocument.tsx +13 -12
- package/src/three/three-board/board-scene.ts +6 -6
- package/src/three/three-board/three-component-board.ts +2 -2
- package/src/services/game-audio-unlock.ts +0 -48
|
@@ -20,18 +20,18 @@ import {
|
|
|
20
20
|
activeDocumentSourcePath,
|
|
21
21
|
activeSaveDestination,
|
|
22
22
|
activeSaveState,
|
|
23
|
-
} from '@volter/editor-
|
|
24
|
-
import { Object3DDocumentViewport } from '@volter/editor-
|
|
23
|
+
} from '@volter/editor-sdk/kit/authoring/shell-document-ops';
|
|
24
|
+
import { Object3DDocumentViewport } from '@volter/editor-threejs/kit/components/Object3DDocumentViewport';
|
|
25
25
|
import type { DocumentPreviewSource } from '@volter/editor-sdk/kit/document-preview-source';
|
|
26
26
|
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
27
|
-
import type { EditorShellStore, ViewportTab } from '@volter/editor-
|
|
28
|
-
import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/editor-
|
|
29
|
-
import { getCurrentProject } from '@volter/editor-
|
|
30
|
-
import { isolationTabsReplaceGenericScene, sceneTabRow } from '@volter/editor-
|
|
27
|
+
import type { EditorShellStore, ViewportTab } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
28
|
+
import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/editor-sdk/kit/project-adapter';
|
|
29
|
+
import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
|
|
30
|
+
import { isolationTabsReplaceGenericScene, sceneTabRow } from '@volter/editor-sdk/kit/scene-document-plan';
|
|
31
31
|
import {
|
|
32
32
|
registerAvailableWorkspaceDocument,
|
|
33
33
|
unregisterAvailableWorkspaceDocument,
|
|
34
|
-
} from '@volter/editor-
|
|
34
|
+
} from '@volter/editor-sdk/kit/workspace-available-documents';
|
|
35
35
|
import { SCENE_DOCUMENT_ID } from '@volter/editor-sdk/kit/workspace-document-ids';
|
|
36
36
|
import {
|
|
37
37
|
activateWorkspaceDocument,
|
|
@@ -378,23 +378,23 @@ export function bindSceneDocument(store: EditorShellStore): () => void {
|
|
|
378
378
|
// tab still represents the same authored TSX document.
|
|
379
379
|
let lastSourcePath: string | null = null;
|
|
380
380
|
const view: CenterDocumentsStore = {
|
|
381
|
-
subscribe: (listener) => store.subscribe(listener),
|
|
381
|
+
subscribe: (listener) => store.shell.subscribe(listener),
|
|
382
382
|
get playState() {
|
|
383
|
-
return store.playState;
|
|
383
|
+
return store.shell.playState;
|
|
384
384
|
},
|
|
385
385
|
get activeViewportTab() {
|
|
386
|
-
return store.activeViewportTab;
|
|
386
|
+
return store.shell.activeViewportTab;
|
|
387
387
|
},
|
|
388
388
|
get savePath() {
|
|
389
|
-
return activeSaveDestination(store);
|
|
389
|
+
return activeSaveDestination(store.shell);
|
|
390
390
|
},
|
|
391
391
|
get sourcePath() {
|
|
392
|
-
const current = activeDocumentSourcePath(store);
|
|
392
|
+
const current = activeDocumentSourcePath(store.shell);
|
|
393
393
|
if (current) lastSourcePath = current;
|
|
394
394
|
return lastSourcePath;
|
|
395
395
|
},
|
|
396
396
|
get isDirty() {
|
|
397
|
-
return activeSaveState(store) === 'unsaved';
|
|
397
|
+
return activeSaveState(store.shell) === 'unsaved';
|
|
398
398
|
},
|
|
399
399
|
};
|
|
400
400
|
const docs = createCenterDocumentDescriptors(view);
|
|
@@ -403,7 +403,7 @@ export function bindSceneDocument(store: EditorShellStore): () => void {
|
|
|
403
403
|
const run = () =>
|
|
404
404
|
syncCenterDocuments(view, docs, getCurrentProject()?.config.hasThreeRoot !== false);
|
|
405
405
|
run();
|
|
406
|
-
const unsubscribe = store.subscribe(run);
|
|
406
|
+
const unsubscribe = store.shell.subscribe(run);
|
|
407
407
|
const unsubscribeAdapter = subscribeProjectAdapter(run);
|
|
408
408
|
// Unbinding follows the session's store and leaves the document registered:
|
|
409
409
|
// a store arriving again at boot must not close a restored Scene tab. The
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* button both select a view of a bench that now ships in `@volter/editor-game`.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import { showWorkspaceUtility } from '@volter/editor-
|
|
19
|
+
import { showWorkspaceUtility } from '@volter/editor-sdk/kit/workspace-host-commands';
|
|
20
20
|
|
|
21
21
|
export type ProfilerViewId = 'profiler' | 'frame';
|
|
22
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THE GAME'S WORLD-ROOT BINDING for the kit's stage host
|
|
3
|
-
* (`@volter/editor-
|
|
3
|
+
* (`@volter/editor-threejs/kit/components/world-root-binding`): the world's surface,
|
|
4
4
|
* its stage, and the overlays the stage shows only over a world.
|
|
5
5
|
*
|
|
6
6
|
* `Overlays` is the world-root half of vgai's `stage-overlay-set.tsx` — every
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `StageOverlays`, which the host renders beside this.
|
|
11
11
|
*/
|
|
12
12
|
import { EDITOR_LAYER } from '@volter/editor-threejs/viewport/editor-layers';
|
|
13
|
-
import { activeAuthoringVersion, subscribeActiveAuthoring } from '@volter/editor-
|
|
13
|
+
import { activeAuthoringVersion, subscribeActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
|
|
14
14
|
import {
|
|
15
15
|
getMountFailureReports,
|
|
16
16
|
subscribeToMountFailures,
|
|
@@ -18,16 +18,16 @@ import {
|
|
|
18
18
|
import {
|
|
19
19
|
object3DDocumentSessionsVersion,
|
|
20
20
|
subscribeObject3DDocumentSessions,
|
|
21
|
-
} from '@volter/editor-
|
|
22
|
-
import { RootSelectionOverlay } from '@volter/editor-
|
|
23
|
-
import { SurfaceStateOverlay } from '@volter/editor-
|
|
21
|
+
} from '@volter/editor-threejs/kit/authoring/object3d-document-session-registry';
|
|
22
|
+
import { RootSelectionOverlay } from '@volter/editor-sdk/kit/components/RootSelectionOverlay';
|
|
23
|
+
import { SurfaceStateOverlay } from '@volter/editor-sdk/kit/components/SurfaceStateOverlay';
|
|
24
24
|
import type {
|
|
25
25
|
WorldRootOverlayProps,
|
|
26
26
|
WorldRootStageBinding,
|
|
27
|
-
} from '@volter/editor-
|
|
28
|
-
import type { EditorShellStore } from '@volter/editor-
|
|
27
|
+
} from '@volter/editor-threejs/kit/components/world-root-binding';
|
|
28
|
+
import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
29
29
|
import { readinessFacet, subscribeRootReadiness } from '@volter/editor-sdk/kit/readiness';
|
|
30
|
-
import { documentStageContext } from '@volter/editor-
|
|
30
|
+
import { documentStageContext } from '@volter/editor-sdk/kit/stage-context';
|
|
31
31
|
import { explainSurface } from '@volter/editor-sdk/kit/surface-state';
|
|
32
32
|
import {
|
|
33
33
|
subscribeWorkspaceDocuments,
|
|
@@ -54,7 +54,7 @@ function SceneViewportStateOverlay({
|
|
|
54
54
|
rootIds: readonly string[];
|
|
55
55
|
mountStatus: 'mounting' | 'ready';
|
|
56
56
|
}) {
|
|
57
|
-
useSyncExternalStore(store.subscribe, store.getSnapshot);
|
|
57
|
+
useSyncExternalStore(store.shell.subscribe, store.shell.getSnapshot);
|
|
58
58
|
const rootReadiness = useSyncExternalStore(subscribeRootReadiness, readinessFacet);
|
|
59
59
|
const mountFailures = useSyncExternalStore(subscribeToMountFailures, getMountFailureReports);
|
|
60
60
|
const sceneBackground = store.scene?.background as THREE.Color | null | undefined;
|
|
@@ -70,7 +70,7 @@ function SceneViewportStateOverlay({
|
|
|
70
70
|
ignoredLayer: EDITOR_LAYER,
|
|
71
71
|
}),
|
|
72
72
|
),
|
|
73
|
-
[store.scene, store.contentVersion],
|
|
73
|
+
[store.scene, store.shell.contentVersion],
|
|
74
74
|
);
|
|
75
75
|
const sceneHasContent = Boolean(
|
|
76
76
|
store.scene && (sceneBackgroundIsAuthored || sceneHasRenderableObjects),
|
|
@@ -93,13 +93,13 @@ function WorldRootOverlays({
|
|
|
93
93
|
mountStatus,
|
|
94
94
|
rootIds,
|
|
95
95
|
}: WorldRootOverlayProps) {
|
|
96
|
-
useSyncExternalStore(store.subscribe, store.getShellSnapshot ?? store.getSnapshot);
|
|
96
|
+
useSyncExternalStore(store.shell.subscribe, store.shell.getShellSnapshot ?? store.shell.getSnapshot);
|
|
97
97
|
useSyncExternalStore(subscribeActiveAuthoring, activeAuthoringVersion);
|
|
98
98
|
useSyncExternalStore(subscribeObject3DDocumentSessions, object3DDocumentSessionsVersion);
|
|
99
99
|
useSyncExternalStore(subscribeWorkspaceDocuments, workspaceDocumentRegistryVersion);
|
|
100
100
|
// The world root's stage is the Scene document's: the kit's overlay props
|
|
101
101
|
// carry no document id, and the Scene document is the one world-root stage.
|
|
102
|
-
const ctx = documentStageContext(store, documentId, 'document');
|
|
102
|
+
const ctx = documentStageContext(store.shell, documentId, 'document');
|
|
103
103
|
return (
|
|
104
104
|
<>
|
|
105
105
|
{/* Three-scene selection overlay. React/Pixi documents mount their own
|
|
@@ -26,10 +26,9 @@ import {
|
|
|
26
26
|
registerStudioPreset,
|
|
27
27
|
type StudioPreset,
|
|
28
28
|
} from '@volter/editor-sdk/kit/viewport-presentation';
|
|
29
|
-
import type { ViewportPresentation, ViewportRoot } from '@volter/editor-sdk/host';
|
|
30
29
|
import { themeVars } from '@volter/editor-sdk/widgets';
|
|
31
|
-
import { createPerformanceProfiler } from '
|
|
32
|
-
import { createWebGLGpuTimer } from '
|
|
30
|
+
import { createPerformanceProfiler } from '../../runtime/dev/performance-profiler';
|
|
31
|
+
import { createWebGLGpuTimer } from '../../runtime/dev/webgl-gpu-timer';
|
|
33
32
|
import type { AuthoringAdapter, Transform } from '@volter/editor-project/adapter';
|
|
34
33
|
import { markHostRenderer } from '@volter/editor-threejs/viewport/renderer-ownership';
|
|
35
34
|
import { applyWorldRendererConfig } from '@volter/threejs-runtime/adapter/renderer-config';
|
|
@@ -51,62 +50,75 @@ import {
|
|
|
51
50
|
type Pass,
|
|
52
51
|
} from 'postprocessing';
|
|
53
52
|
import * as THREE from 'three';
|
|
54
|
-
import { getActiveAuthoring } from '@volter/editor-
|
|
55
|
-
import type { CompositeAuthoringAdapter } from '@volter/editor-
|
|
53
|
+
import { getActiveAuthoring } from '@volter/editor-sdk/kit/authoring/active-adapter';
|
|
54
|
+
import type { CompositeAuthoringAdapter } from '@volter/editor-sdk/kit/authoring/composite-authoring-adapter';
|
|
56
55
|
import {
|
|
57
56
|
applyAuthoringTransform,
|
|
58
57
|
beginAuthoringTransformEdit,
|
|
59
58
|
endAuthoringTransformEdit,
|
|
60
|
-
} from '@volter/editor-
|
|
61
|
-
import { designTimeMountFor } from '@volter/editor-
|
|
62
|
-
import { attachProjectAuthoringStage } from '@volter/editor-
|
|
59
|
+
} from '@volter/editor-sdk/kit/authoring/consumer-actions';
|
|
60
|
+
import { designTimeMountFor } from '@volter/editor-sdk/kit/authoring/design-time-mount-registry';
|
|
61
|
+
import { attachProjectAuthoringStage } from '@volter/editor-sdk/kit/authoring/project-authoring-session';
|
|
63
62
|
import {
|
|
64
63
|
isThreejsSurfaceVisible,
|
|
65
64
|
resolveThreeViewportRootId,
|
|
66
|
-
} from '@volter/editor-
|
|
65
|
+
} from '@volter/editor-threejs/kit/authoring/world-hidden-viewport';
|
|
67
66
|
import { AutoFrameWindow } from '../auto-frame-window';
|
|
68
67
|
import {
|
|
69
68
|
type CameraAuthoringSubject,
|
|
70
69
|
type CameraViewMode,
|
|
71
70
|
cameraAuthoringPresentation,
|
|
72
71
|
installCameraAuthoringHost,
|
|
73
|
-
} from '@volter/editor-
|
|
74
|
-
import { registerPresentedCanvasFrame } from '
|
|
75
|
-
import { collectState } from '@volter/editor-
|
|
76
|
-
import { getDownloadedAssetPath, getOnlineAssetFiles, reportEditorState } from '@volter/editor-
|
|
72
|
+
} from '@volter/editor-threejs/kit/camera-authoring';
|
|
73
|
+
import { registerPresentedCanvasFrame } from '../canvas-preview-frames';
|
|
74
|
+
import { collectState } from '@volter/editor-sdk/kit/command-listener';
|
|
75
|
+
import { getDownloadedAssetPath, getOnlineAssetFiles, reportEditorState } from '@volter/editor-sdk/kit/editor-api';
|
|
77
76
|
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
78
77
|
import { isEditorPresentationActive } from '@volter/editor-sdk/kit/editor-presentation-activity';
|
|
79
|
-
import type { EditorStats } from '@volter/editor-
|
|
80
|
-
import type { EditorShellStore } from '@volter/editor-
|
|
81
|
-
import { EditorViewport, type OnlineAssetDrop } from '@volter/editor-
|
|
82
|
-
import { entityObject3D } from '@volter/editor-
|
|
78
|
+
import type { EditorStats } from '@volter/editor-sdk/kit/editor-runtime';
|
|
79
|
+
import type { EditorShellStore } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
80
|
+
import { EditorViewport, type OnlineAssetDrop } from '@volter/editor-threejs/kit/editor-viewport';
|
|
81
|
+
import { entityObject3D } from '@volter/editor-threejs/kit/entity-object';
|
|
83
82
|
import {
|
|
84
83
|
nativeSelectionColors,
|
|
85
84
|
nativeViewportLook,
|
|
86
85
|
subscribeNativeSelectionTheme,
|
|
87
86
|
} from '@volter/editor-sdk/kit/native-selection-style';
|
|
88
|
-
import { registerPerformanceSource } from '@volter/editor-
|
|
87
|
+
import { registerPerformanceSource } from '@volter/editor-sdk/kit/performance-sources';
|
|
89
88
|
import { drawSceneUnlessRefused } from '../scene-view-drawability';
|
|
90
|
-
import { withSceneFogNeutralized } from '@volter/editor-
|
|
89
|
+
import { withSceneFogNeutralized } from '@volter/editor-threejs/kit/scene-view-fog';
|
|
91
90
|
import { connectServerLogs } from '../server-log-bridge';
|
|
92
|
-
import { focusedStageStore } from '@volter/editor-
|
|
91
|
+
import { focusedStageStore } from '@volter/editor-sdk/kit/stage-context';
|
|
93
92
|
import {
|
|
94
93
|
acquireThreeSelectionOutline,
|
|
95
94
|
releaseThreeSelectionOutline,
|
|
96
95
|
setThreeSelectionOutlineColors,
|
|
97
96
|
syncThreeSelectionOutline,
|
|
98
|
-
} from '@volter/editor-
|
|
97
|
+
} from '@volter/editor-threejs/kit/three-viewport/selection-outline';
|
|
99
98
|
import {
|
|
100
99
|
setThreeViewportProjection,
|
|
101
100
|
subscribeThreeViewportPresentation,
|
|
102
101
|
threeViewportPresentation,
|
|
103
|
-
} from '@volter/editor-
|
|
102
|
+
} from '@volter/editor-sdk/kit/three-viewport-presentation';
|
|
104
103
|
import { recordViewportFirstFrame } from '@volter/editor-sdk/kit/viewport-activation-timings';
|
|
105
104
|
import { savedViewportPose, saveViewportPose } from '../viewport-pose-memory';
|
|
106
105
|
import { presentThreeRoots } from '../viewport-root-presentation';
|
|
107
|
-
import { isEditorViewportShadingTarget } from '@volter/editor-
|
|
108
|
-
import { downloadOnlineAssetWithHistory } from '@volter/editor-
|
|
109
|
-
import { bindStagePresenceMarkers } from '@volter/editor-
|
|
106
|
+
import { isEditorViewportShadingTarget } from '@volter/editor-threejs/kit/viewport-shading-boundary';
|
|
107
|
+
import { downloadOnlineAssetWithHistory } from '@volter/editor-sdk/kit/components/asset-editor-persistence';
|
|
108
|
+
import { bindStagePresenceMarkers } from '@volter/editor-threejs/kit/components/stage-presence-markers';
|
|
109
|
+
import type { ViewportPresentation, ViewportRoot } from '@volter/editor-threejs/viewport-api';
|
|
110
|
+
|
|
111
|
+
/** Everything the world root's stage hands its medium's design session: the stage's own three
|
|
112
|
+
* handles. The stage and the medium that registered for `three` agree on it; the kit's mount
|
|
113
|
+
* registry types it `unknown`. */
|
|
114
|
+
export interface WorldRootSessionContext {
|
|
115
|
+
/** The shell store the session's adapter is built over. */
|
|
116
|
+
readonly store: EditorShellStore;
|
|
117
|
+
/** The edit-mode composite the session swaps its own child adapter into. */
|
|
118
|
+
readonly composite: CompositeAuthoringAdapter;
|
|
119
|
+
/** The stage's renderer — the session adopts it rather than building one. */
|
|
120
|
+
readonly renderer: THREE.WebGLRenderer;
|
|
121
|
+
}
|
|
110
122
|
|
|
111
123
|
/**
|
|
112
124
|
* THE WORLD STAGE'S STARTING PRESENTATION. Its studio is the light the world has always been
|
|
@@ -468,8 +480,8 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
468
480
|
);
|
|
469
481
|
const syncSelectionOutline = (): void => {
|
|
470
482
|
if (!selectionOutline) return;
|
|
471
|
-
const adapter = getActiveAuthoring(store);
|
|
472
|
-
const roots = [...store.selectedEntityIds]
|
|
483
|
+
const adapter = getActiveAuthoring(store.shell);
|
|
484
|
+
const roots = [...store.shell.selectedEntityIds]
|
|
473
485
|
// Edit↔Play swaps the active child before its native graph is rebuilt.
|
|
474
486
|
// Do not route a stale outgoing id through the composite during that
|
|
475
487
|
// handoff: it is temporarily absent, not an ownership error.
|
|
@@ -495,7 +507,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
495
507
|
// postprocessing). `editor-viewport.ts` bumps `composerVersion` (via
|
|
496
508
|
// `store.reapplyEnvironment()`) on the world hide/show edges, which is
|
|
497
509
|
// what re-runs this rebuild.
|
|
498
|
-
const hiddenRootId = resolveThreeViewportRootId(store);
|
|
510
|
+
const hiddenRootId = resolveThreeViewportRootId(store.shell);
|
|
499
511
|
void hiddenRootId;
|
|
500
512
|
// Unwind the previous adoption's config BEFORE re-deriving, so the
|
|
501
513
|
// re-derive below and the (possibly absent) re-apply at the end both
|
|
@@ -568,24 +580,24 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
568
580
|
applyViewportPresentation();
|
|
569
581
|
|
|
570
582
|
const resolveCameraSubject = (id: string): CameraAuthoringSubject | null =>
|
|
571
|
-
cameraSubjectFor(getActiveAuthoring(store), store.objectMap, id);
|
|
583
|
+
cameraSubjectFor(getActiveAuthoring(store.shell), store.objectMap, id);
|
|
572
584
|
|
|
573
585
|
let pilotGestureId: string | null = null;
|
|
574
586
|
const finishPilotGesture = (): void => {
|
|
575
587
|
if (!pilotGestureId) return;
|
|
576
|
-
endAuthoringTransformEdit(getActiveAuthoring(store), pilotGestureId);
|
|
588
|
+
endAuthoringTransformEdit(getActiveAuthoring(store.shell), pilotGestureId);
|
|
577
589
|
pilotGestureId = null;
|
|
578
590
|
};
|
|
579
591
|
const beginPilotGesture = (): void => {
|
|
580
592
|
const view = cameraAuthoringPresentation().view;
|
|
581
593
|
if (view?.mode !== 'pilot' || !view.subject.canAuthorPose) return;
|
|
582
594
|
pilotGestureId = view.subject.id;
|
|
583
|
-
beginAuthoringTransformEdit(getActiveAuthoring(store), pilotGestureId);
|
|
595
|
+
beginAuthoringTransformEdit(getActiveAuthoring(store.shell), pilotGestureId);
|
|
584
596
|
};
|
|
585
597
|
const applyPilotGesture = (): void => {
|
|
586
598
|
if (!pilotGestureId || viewport.cameraViewMode !== 'pilot') return;
|
|
587
599
|
const subject = resolveCameraSubject(pilotGestureId);
|
|
588
|
-
const adapter = getActiveAuthoring(store);
|
|
600
|
+
const adapter = getActiveAuthoring(store.shell);
|
|
589
601
|
const transforms = adapter.transforms;
|
|
590
602
|
if (!subject || !transforms) return;
|
|
591
603
|
// `transforms.get` REFUSES BY THROWING for a node with no transform truth
|
|
@@ -610,16 +622,16 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
610
622
|
rotation: subject.camera.quaternion.toArray() as [number, number, number, number],
|
|
611
623
|
scale: previous.scale,
|
|
612
624
|
});
|
|
613
|
-
store.notifyIngestEdit();
|
|
625
|
+
store.shell.notifyIngestEdit();
|
|
614
626
|
};
|
|
615
627
|
viewport.orbitControls.addEventListener('start', beginPilotGesture);
|
|
616
628
|
viewport.orbitControls.addEventListener('change', applyPilotGesture);
|
|
617
629
|
viewport.orbitControls.addEventListener('end', finishPilotGesture);
|
|
618
630
|
|
|
619
631
|
const disposeCameraAuthoring = installCameraAuthoringHost({
|
|
620
|
-
active: () => store.playState === 'stopped' && store.activeViewportTab === 'edit',
|
|
632
|
+
active: () => store.shell.playState === 'stopped' && store.shell.activeViewportTab === 'edit',
|
|
621
633
|
selected: () => {
|
|
622
|
-
const id = store.selectedEntityId;
|
|
634
|
+
const id = store.shell.selectedEntityId;
|
|
623
635
|
return id ? resolveCameraSubject(id) : null;
|
|
624
636
|
},
|
|
625
637
|
resolve: resolveCameraSubject,
|
|
@@ -636,7 +648,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
636
648
|
presence.reportCamera();
|
|
637
649
|
},
|
|
638
650
|
alignToViewport: (subject: CameraAuthoringSubject) => {
|
|
639
|
-
const adapter = getActiveAuthoring(store);
|
|
651
|
+
const adapter = getActiveAuthoring(store.shell);
|
|
640
652
|
const transforms = adapter.transforms;
|
|
641
653
|
if (!transforms || !subject.canAuthorPose) return;
|
|
642
654
|
const targetObject = store.objectMap.get(subject.id) ?? null;
|
|
@@ -671,10 +683,10 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
671
683
|
rotation: localQuaternion.toArray() as [number, number, number, number],
|
|
672
684
|
scale: previous.scale,
|
|
673
685
|
});
|
|
674
|
-
store.notifyIngestEdit();
|
|
686
|
+
store.shell.notifyIngestEdit();
|
|
675
687
|
endAuthoringTransformEdit(adapter, subject.id);
|
|
676
688
|
},
|
|
677
|
-
subscribe: store.subscribe,
|
|
689
|
+
subscribe: store.shell.subscribe,
|
|
678
690
|
});
|
|
679
691
|
|
|
680
692
|
// --- Store subscription → sync viewport ---
|
|
@@ -694,7 +706,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
694
706
|
// React never owns it.
|
|
695
707
|
let lastThreejsSurface: boolean | null = null;
|
|
696
708
|
const syncSurfaceVisibility = (): void => {
|
|
697
|
-
const visible = isThreejsSurfaceVisible(store);
|
|
709
|
+
const visible = isThreejsSurfaceVisible(store.shell);
|
|
698
710
|
if (visible === lastThreejsSurface) return;
|
|
699
711
|
lastThreejsSurface = visible;
|
|
700
712
|
canvas.style.opacity = visible ? '1' : '0';
|
|
@@ -715,7 +727,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
715
727
|
syncSurfaceVisibility();
|
|
716
728
|
|
|
717
729
|
let lastComposerVersion = store.composerVersion;
|
|
718
|
-
const unsubStore = store.subscribe(() => {
|
|
730
|
+
const unsubStore = store.shell.subscribe(() => {
|
|
719
731
|
syncSurfaceVisibility();
|
|
720
732
|
// Swap viewport scene if the store's scene changed (play mode enter/exit)
|
|
721
733
|
const storeScene = store.scene;
|
|
@@ -755,14 +767,14 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
755
767
|
viewport.orbitControls.addEventListener('end', rememberPose);
|
|
756
768
|
|
|
757
769
|
// --- Viewport action subscription ---
|
|
758
|
-
const unsubActions = store.onViewportAction((action) => {
|
|
770
|
+
const unsubActions = store.shell.onViewportAction((action) => {
|
|
759
771
|
switch (action.type) {
|
|
760
772
|
// Resolved through the ACTIVE ADAPTER first, same as selection and the
|
|
761
773
|
// gizmo — an adopted play scene's nodes live in the adapter's walk and
|
|
762
774
|
// never reach `objectMap`, so a store-only lookup silently framed
|
|
763
775
|
// nothing for every entity in a running game (`entity-object.ts`).
|
|
764
776
|
case 'focus-entity': {
|
|
765
|
-
const obj = entityObject3D(getActiveAuthoring(store), store.objectMap, action.id);
|
|
777
|
+
const obj = entityObject3D(getActiveAuthoring(store.shell), store.objectMap, action.id);
|
|
766
778
|
if (obj) viewport.focusOn(obj);
|
|
767
779
|
break;
|
|
768
780
|
}
|
|
@@ -786,13 +798,13 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
786
798
|
break;
|
|
787
799
|
}
|
|
788
800
|
}
|
|
789
|
-
gameCameraLookup =
|
|
801
|
+
gameCameraLookup = store.sceneCameraLookup;
|
|
790
802
|
autoFrame.begin(performance.now(), gameCameraLookup !== null);
|
|
791
803
|
break;
|
|
792
804
|
}
|
|
793
805
|
case 'focus-selection': {
|
|
794
|
-
const adapter = getActiveAuthoring(store);
|
|
795
|
-
const objects = [...store.selectedEntityIds]
|
|
806
|
+
const adapter = getActiveAuthoring(store.shell);
|
|
807
|
+
const objects = [...store.shell.selectedEntityIds]
|
|
796
808
|
.map((id) => entityObject3D(adapter, store.objectMap, id))
|
|
797
809
|
.filter((o): o is THREE.Object3D => o !== null);
|
|
798
810
|
viewport.focusOnMultiple(objects);
|
|
@@ -804,6 +816,15 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
804
816
|
case 'set-view-preset':
|
|
805
817
|
viewport.setViewPreset(action.preset);
|
|
806
818
|
break;
|
|
819
|
+
case 'step-view':
|
|
820
|
+
viewport.stepView(action.step);
|
|
821
|
+
break;
|
|
822
|
+
case 'frame-all':
|
|
823
|
+
viewport.focusOnScene();
|
|
824
|
+
break;
|
|
825
|
+
case 'zoom-view':
|
|
826
|
+
viewport.zoomStep(action.direction);
|
|
827
|
+
break;
|
|
807
828
|
case 'set-camera-pose':
|
|
808
829
|
viewport.setPose(action.position, action.target, action.fov);
|
|
809
830
|
break;
|
|
@@ -899,7 +920,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
899
920
|
|
|
900
921
|
/** Whether this stage is the one the shared panels are following, and so the
|
|
901
922
|
* one that fills the shell's frame/camera readout — see its use below. */
|
|
902
|
-
const ownsShellReadout = (): boolean => focusedStageStore(store) === store;
|
|
923
|
+
const ownsShellReadout = (): boolean => focusedStageStore(store.shell) === store.shell;
|
|
903
924
|
|
|
904
925
|
function frame(now: number, resumed: boolean): void {
|
|
905
926
|
if (disposed) return;
|
|
@@ -1024,7 +1045,7 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
1024
1045
|
const stageMount = designTimeMountFor('three');
|
|
1025
1046
|
if (disposed || editModeComposite !== composite) return;
|
|
1026
1047
|
const disposeSession = stageMount
|
|
1027
|
-
? await stageMount.mountWorldRootSession({ store, composite, renderer })
|
|
1048
|
+
? await stageMount.mountWorldRootSession({ store, composite, renderer } satisfies WorldRootSessionContext)
|
|
1028
1049
|
: () => {};
|
|
1029
1050
|
if (disposed || editModeComposite !== composite) {
|
|
1030
1051
|
disposeSession();
|
|
@@ -1034,9 +1055,9 @@ export function installWorldRootStage(options: WorldRootStageOptions): WorldRoot
|
|
|
1034
1055
|
if (!disposed) options.onMountStatus('ready');
|
|
1035
1056
|
}
|
|
1036
1057
|
|
|
1037
|
-
const authoringStage = attachProjectAuthoringStage(store, installStage);
|
|
1058
|
+
const authoringStage = attachProjectAuthoringStage(store.shell, installStage);
|
|
1038
1059
|
authoringStage.ready
|
|
1039
|
-
.then(() => reportEditorState(collectState(store)))
|
|
1060
|
+
.then(() => reportEditorState(collectState(store.shell)))
|
|
1040
1061
|
.catch((err) => {
|
|
1041
1062
|
editorConsole.error(
|
|
1042
1063
|
`Editor boot failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
* no live session.
|
|
47
47
|
*/
|
|
48
48
|
|
|
49
|
-
import type { DeclaredSystemAbsence } from '
|
|
49
|
+
import type { DeclaredSystemAbsence } from '../../runtime/game';
|
|
50
50
|
import type { SystemAdapters } from '@volter/editor-project/adapter/system-adapter';
|
|
51
51
|
import {
|
|
52
52
|
SYSTEM_ADAPTER_SLOTS,
|
|
@@ -139,9 +139,8 @@ function shippedLibraries(slot: SystemAdapterSlot, facts: NativeProjectFacts): r
|
|
|
139
139
|
function contradictionFix(slot: SystemAdapterSlot, libraries: readonly string[]): string {
|
|
140
140
|
return (
|
|
141
141
|
`this project depends on ${libraries.join(' + ')}, so "nothing built a ${slot} world" is not ` +
|
|
142
|
-
`a settled answer. Reach a terminal state either way: BIND it — declare
|
|
143
|
-
`the root entry's \`systems\` table
|
|
144
|
-
`Rapier bridge; other slots take the game's own adapter) — or DECLARE the absence with ` +
|
|
142
|
+
`a settled answer. Reach a terminal state either way: BIND it — declare the game's own ${slot} ` +
|
|
143
|
+
`adapter in the root entry's \`systems\` table — or DECLARE the absence with ` +
|
|
145
144
|
`\`absent(reason)\` in that same table. The reason must NAME the dependency and say why it ` +
|
|
146
145
|
`is there while the subsystem is not (a transitive pull, a leftover, a build-only use); a ` +
|
|
147
146
|
`declared absence blind to the shipped dependency grades malformed, not terminal.`
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { type ReactNode, useEffect, useLayoutEffect, useState } from 'react';
|
|
2
|
-
import { resetProjectThumbnailManifestCache } from '@volter/editor-
|
|
3
|
-
import { type EditorRuntime, EditorRuntimeProvider, type EditorStats } from '@volter/editor-
|
|
4
|
-
import { EditorShellStore } from '@volter/editor-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
2
|
+
import { resetProjectThumbnailManifestCache } from '@volter/editor-sdk/kit/asset-workflow/thumbnail-system';
|
|
3
|
+
import { type EditorRuntime, EditorRuntimeProvider, type EditorStats } from '@volter/editor-sdk/kit/editor-runtime';
|
|
4
|
+
import { type EditorShellStore, threeStateOf } from '@volter/editor-threejs/kit/editor-shell-store';
|
|
5
|
+
import { ShellStore } from '@volter/editor-sdk/kit/shell-store';
|
|
6
|
+
import { EditorSession } from '@volter/editor-sdk/kit/history/editor-session';
|
|
7
|
+
import { getStorageBackend, MemStorage, setStorageBackend } from '@volter/editor-sdk/kit/storage/index';
|
|
7
8
|
import {
|
|
8
9
|
activeWorkspaceUtility,
|
|
9
10
|
installWorkspaceHostCommands,
|
|
10
11
|
setActiveWorkspaceUtility,
|
|
11
12
|
setWorkspaceUtilityTabs,
|
|
12
13
|
workspaceUtilityTabs,
|
|
13
|
-
} from '@volter/editor-
|
|
14
|
+
} from '@volter/editor-sdk/kit/workspace-host-commands';
|
|
14
15
|
import { availableWorkspaceUtilities } from '@volter/editor-sdk/kit/workspace-utility-registry';
|
|
15
16
|
|
|
16
17
|
const ZERO_STATS: EditorStats = {
|
|
@@ -24,15 +25,12 @@ const ZERO_STATS: EditorStats = {
|
|
|
24
25
|
|
|
25
26
|
/** A story runtime's Three half, for a production component that reads the scene. */
|
|
26
27
|
export function storyThreeStore(runtime: EditorRuntime): EditorShellStore {
|
|
27
|
-
|
|
28
|
-
throw new Error('This runtime was not made by createStoryEditorRuntime: it has no Three store.');
|
|
29
|
-
}
|
|
30
|
-
return runtime.store;
|
|
28
|
+
return threeStateOf(runtime.store);
|
|
31
29
|
}
|
|
32
30
|
|
|
33
31
|
/** A real, bounded editor runtime for production component stories. */
|
|
34
32
|
export function createStoryEditorRuntime(): EditorRuntime {
|
|
35
|
-
const store = new
|
|
33
|
+
const store = new ShellStore();
|
|
36
34
|
const session = new EditorSession('storybook-fixture');
|
|
37
35
|
store.attachHistory(session.history);
|
|
38
36
|
return {
|
|
@@ -3,7 +3,7 @@ import { isEditorOwnedObject } from '@volter/editor-threejs/viewport/editor-laye
|
|
|
3
3
|
import { markHostRenderer } from '@volter/editor-threejs/viewport/renderer-ownership';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
5
|
import type { DocumentPreviewCaptureRequest } from '@volter/editor-sdk/kit/document-preview-source';
|
|
6
|
-
import { frameableContentBounds } from '@volter/editor-
|
|
6
|
+
import { frameableContentBounds } from '@volter/editor-threejs/kit/scene-framing';
|
|
7
7
|
|
|
8
8
|
function authoredCameras(root: THREE.Object3D): THREE.Camera[] {
|
|
9
9
|
const cameras: THREE.Camera[] = [];
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* WHAT DOES THIS ENTRY MODULE MEAN? — the ONE editor-side answer.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* `roots/r3f-root.tsx` owns the answer itself (`resolveR3FEntryAdapter`), and
|
|
5
|
+
* `resolveR3FEntryAdapterForEditor` hands it the React and Fiber of the
|
|
6
|
+
* project's own module graph. The rest of the editor's job is to ASK, once.
|
|
7
7
|
* Before this module there were three askers, and they had already drifted:
|
|
8
8
|
*
|
|
9
9
|
* - the dev-server lane called the packaged-aware `…ForEditor`;
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
* told which lane and which file, and that is the caller's knowledge, not
|
|
21
21
|
* this function's.
|
|
22
22
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* The canvas lane has its own single owner (`roots/canvas-root.tsx`'s
|
|
24
|
+
* `resolveCanvasEntryAdapter`, reached through `canvas-entry-runtime.ts`) and
|
|
25
|
+
* is not adjudicated here.
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import type { RootAdapter } from '@volter/editor-project/adapter';
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** The `@scope` transform the session applies to a game's stylesheets, for a
|
|
2
|
+
* page that must scope CSS a game creates at runtime. Its own module so the
|
|
3
|
+
* transform's parser loads only where a game's page asks for it. */
|
|
4
|
+
export { scopeGameCss } from '@volter/editor-sdk/session/scoped-game-css';
|
|
@@ -90,7 +90,7 @@ export const SCOPED_STYLE_MARK = 'vgaiScopedCss';
|
|
|
90
90
|
let gameCssScoper: Promise<(css: string) => string> | null = null;
|
|
91
91
|
export function loadGameCssScoper(): Promise<(css: string) => string> {
|
|
92
92
|
gameCssScoper ??= Promise.all([
|
|
93
|
-
import('
|
|
93
|
+
import('./game-css-scope-transform'),
|
|
94
94
|
import('@volter/editor-sdk/session/game-css-scope'),
|
|
95
95
|
]).then(
|
|
96
96
|
([{ scopeGameCss }, { GAME_CSS_SCOPE_SELECTOR }]) =>
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { pcmStats } from '@volter/game-runtime/audio/wav-encode';
|
|
2
1
|
import type { OfflineAudioRenderer } from '@volter/editor-project/adapter';
|
|
3
2
|
import {
|
|
4
3
|
AudioBufferSource,
|
|
@@ -10,8 +9,25 @@ import {
|
|
|
10
9
|
Quality,
|
|
11
10
|
WebMOutputFormat,
|
|
12
11
|
} from 'mediabunny';
|
|
13
|
-
import type { CaptureOptions } from '@volter/editor-
|
|
14
|
-
import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor-
|
|
12
|
+
import type { CaptureOptions } from '@volter/editor-sdk/kit/composite-screenshot';
|
|
13
|
+
import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor-sdk/kit/composite-screenshot';
|
|
14
|
+
|
|
15
|
+
/** RMS and peak over all channels and samples: evidence the track is sound, not an all-zero
|
|
16
|
+
* buffer. */
|
|
17
|
+
function pcmStats(channelData: readonly Float32Array[]): { rms: number; peak: number } {
|
|
18
|
+
let sumSquares = 0;
|
|
19
|
+
let peak = 0;
|
|
20
|
+
let count = 0;
|
|
21
|
+
for (const data of channelData) {
|
|
22
|
+
for (let i = 0; i < data.length; i++) {
|
|
23
|
+
const v = data[i] ?? 0;
|
|
24
|
+
sumSquares += v * v;
|
|
25
|
+
peak = Math.max(peak, Math.abs(v));
|
|
26
|
+
count++;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return { rms: count > 0 ? Math.sqrt(sumSquares / count) : 0, peak };
|
|
30
|
+
}
|
|
15
31
|
|
|
16
32
|
/**
|
|
17
33
|
* Opus in the SAME WebM `Output` the video track already uses — the whole
|
|
@@ -25,14 +41,10 @@ import { createImageSnapshotCache, drawPlayCompositeFrame } from '@volter/editor
|
|
|
25
41
|
* second container pipeline beside the first is how one export's timing,
|
|
26
42
|
* metadata and codec support drift away from the other's.
|
|
27
43
|
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* muxer are in the same JS heap, so encoding to 16-bit WAV and handing the
|
|
33
|
-
* bytes back to an encoder would quantize the samples for no reason at all.
|
|
34
|
-
* `pcmStats` from that module IS used, for the non-silence evidence in the
|
|
35
|
-
* result.
|
|
44
|
+
* The `AudioBuffer` and the muxer are in the same JS heap, so the samples go
|
|
45
|
+
* to the encoder as they are; encoding to 16-bit WAV on the way would quantize
|
|
46
|
+
* them for no reason at all. {@link pcmStats} gives the non-silence evidence in
|
|
47
|
+
* the result.
|
|
36
48
|
*
|
|
37
49
|
* Opus rather than a PCM track (Matroska can carry `A_PCM/INT/LIT`) because
|
|
38
50
|
* WebM's normal audio codec is what every player and every `ffprobe` build
|
|
@@ -105,9 +117,8 @@ export interface GameplayExportResult {
|
|
|
105
117
|
/** How the export gets sound: the world's own audio for the ABSOLUTE sim
|
|
106
118
|
* window the frame walk covers, rendered offline.
|
|
107
119
|
*
|
|
108
|
-
* THE OFFSET TRAP,
|
|
109
|
-
* argument of this whole path
|
|
110
|
-
* first): an offline render of `[10, 10.72)` schedules its first event at
|
|
120
|
+
* THE OFFSET TRAP, stated at the call site because it is the correctness
|
|
121
|
+
* argument of this whole path: an offline render of `[10, 10.72)` schedules its first event at
|
|
111
122
|
* LOCAL time 0, not absolute 10. `startSeconds` is where the paused run
|
|
112
123
|
* stands on its own canonical clock when frame 0 is captured; `render` is
|
|
113
124
|
* asked for `[startSeconds, startSeconds + frames / fps)` and must subtract
|