@volter/editor-game 0.5.65
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/LICENSE +661 -0
- package/NOTICE +23 -0
- package/contributions/asset-budget-asset.menu.ts +26 -0
- package/contributions/asset-budget.action.ts +18 -0
- package/contributions/asset-budget.document.tsx +21 -0
- package/contributions/asset-budget.menu.ts +22 -0
- package/contributions/audio-unlock.service.ts +17 -0
- package/contributions/audio.utility.tsx +15 -0
- package/contributions/autoplay.service.ts +48 -0
- package/contributions/bridge.command.ts +172 -0
- package/contributions/build-profiles.document.tsx +21 -0
- package/contributions/build-progress.status.tsx +45 -0
- package/contributions/build.action.ts +26 -0
- package/contributions/build.command.ts +27 -0
- package/contributions/build.header.tsx +37 -0
- package/contributions/build.menu.ts +31 -0
- package/contributions/build.service.ts +31 -0
- package/contributions/connection.status.tsx +43 -0
- package/contributions/coverage.service.ts +118 -0
- package/contributions/edit-mode-audio.service.ts +23 -0
- package/contributions/edit-mode-networking.service.ts +30 -0
- package/contributions/game-document.service.ts +25 -0
- package/contributions/game-eval.command.ts +210 -0
- package/contributions/game.layout.ts +19 -0
- package/contributions/gameplay.command.ts +255 -0
- package/contributions/generation.service.ts +96 -0
- package/contributions/generations.status.tsx +53 -0
- package/contributions/ingest.service.ts +80 -0
- package/contributions/instances.command.ts +75 -0
- package/contributions/navmesh.menu.ts +39 -0
- package/contributions/navmesh.service.ts +19 -0
- package/contributions/network.utility.tsx +17 -0
- package/contributions/play.command.ts +355 -0
- package/contributions/profiler.action.ts +16 -0
- package/contributions/profiler.menu.ts +22 -0
- package/contributions/profiler.utility.tsx +17 -0
- package/contributions/react/component-board.service.ts +21 -0
- package/contributions/react/design-time-mount.service.ts +60 -0
- package/contributions/react/pasteboard.action.ts +41 -0
- package/contributions/react/react-inspector.service.ts +85 -0
- package/contributions/react/story-documents.service.ts +44 -0
- package/contributions/scene-document.service.ts +32 -0
- package/contributions/state-watch.action.ts +17 -0
- package/contributions/state-watch.menu.ts +23 -0
- package/contributions/state-watch.utility.tsx +20 -0
- package/contributions/team-playtest.service.ts +124 -0
- package/contributions/three/camera-runtime.inspector.tsx +34 -0
- package/contributions/three/component-board.service.ts +24 -0
- package/contributions/three/component-verbs.command.ts +110 -0
- package/contributions/three/component-verbs.service.ts +92 -0
- package/contributions/three/constraints.inspector.tsx +34 -0
- package/contributions/three/model-asset-sections.service.ts +26 -0
- package/contributions/three/reflection-probe-capture.inspector.tsx +32 -0
- package/contributions/three/story-documents.service.ts +31 -0
- package/contributions/three/three-authoring.service.ts +66 -0
- package/contributions/transport.header.tsx +19 -0
- package/contributions/xstate-behavior.action.ts +42 -0
- package/contributions/xstate-behavior.document.tsx +73 -0
- package/contributions/xstate-behavior.inspector.tsx +28 -0
- package/contributions/xstate-behavior.menu.ts +23 -0
- package/package.json +144 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1172 -0
- package/src/asset-budget/asset-budget-model.ts +799 -0
- package/src/asset-budget/basis-encoder.ts +165 -0
- package/src/asset-budget/gltf-io.ts +154 -0
- package/src/asset-budget/gltf-optimize.ts +384 -0
- package/src/asset-budget/image-dims.ts +78 -0
- package/src/asset-budget/optimize-apply.ts +221 -0
- package/src/audio/AudioDebuggerPanel.tsx +457 -0
- package/src/audio/audio-debugger-model.ts +87 -0
- package/src/bridge/call.ts +60 -0
- package/src/bridge/dispatch.ts +459 -0
- package/src/bridge/live-frames.ts +25 -0
- package/src/bridge/screenshot.ts +316 -0
- package/src/build/BuildProfilesPanel.tsx +476 -0
- package/src/build/build-session.ts +247 -0
- package/src/build/format-bytes.ts +14 -0
- package/src/command-results.ts +36 -0
- package/src/coverage/live-authoring-surface.ts +30 -0
- package/src/coverage/live-project-verbs.ts +162 -0
- package/src/coverage/native-system-coverage.ts +143 -0
- package/src/coverage/root-coverage.ts +79 -0
- package/src/coverage/session-coverage.ts +193 -0
- package/src/design-system-stories/ApplicationChrome.stories.tsx +100 -0
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +406 -0
- package/src/edit-mode/edit-mode-audio.ts +56 -0
- package/src/edit-mode/edit-mode-networking.ts +112 -0
- package/src/game-document/DevicePresetPicker.tsx +84 -0
- package/src/game-document/GameCaptureFrameButton.tsx +45 -0
- package/src/game-document/GameDocument.tsx +215 -0
- package/src/game-document/GamePanel.tsx +662 -0
- package/src/game-document/InstanceInspectorPicker.tsx +183 -0
- package/src/game-document/crowd-debug.ts +183 -0
- package/src/game-document/device-preview.ts +336 -0
- package/src/game-document/game-view-store.ts +107 -0
- package/src/game-document/physics-debug.ts +187 -0
- package/src/generation/GenerationActivity.tsx +421 -0
- package/src/generation/GenerationGallery.css +231 -0
- package/src/generation/generation-documents.tsx +338 -0
- package/src/generation/generation-jobs.ts +128 -0
- package/src/generation/generation-presentation.ts +257 -0
- package/src/host/adapter-reach.ts +445 -0
- package/src/host/adapter-runtime-bindings.ts +303 -0
- package/src/host/after-paint.ts +112 -0
- package/src/host/api/configurations.ts +66 -0
- package/src/host/authoring/babylon-authoring-adapter.ts +703 -0
- package/src/host/authoring/canvas-runtime-recognition.ts +50 -0
- package/src/host/authoring/contract-hierarchy-authoring.ts +144 -0
- package/src/host/authoring/contract-scenes-stories.ts +204 -0
- package/src/host/authoring/creation-site-related.ts +55 -0
- package/src/host/authoring/ephemeral-persistence.ts +29 -0
- package/src/host/authoring/gesture-persist.ts +84 -0
- package/src/host/authoring/ingest-data-writer.ts +232 -0
- package/src/host/authoring/ingest-source-persistence.ts +826 -0
- package/src/host/authoring/mount-isolated-pixi-screen.ts +250 -0
- package/src/host/authoring/mounted-authoring.ts +41 -0
- package/src/host/authoring/owned-pixi-ticker-listeners.ts +96 -0
- package/src/host/authoring/phaser-live-authoring-adapter.ts +265 -0
- package/src/host/authoring/pixi-authoring-adapter.ts +1554 -0
- package/src/host/authoring/pixi-creation-site-write-target.ts +60 -0
- package/src/host/authoring/pixi-isolation-assets.ts +25 -0
- package/src/host/authoring/pixi-live-write-target.ts +979 -0
- package/src/host/authoring/pixi-source-identity.ts +141 -0
- package/src/host/authoring/pixi-still-presentation.ts +71 -0
- package/src/host/authoring/pixi-structure-history.ts +237 -0
- package/src/host/authoring/pixi-transform-channels.ts +205 -0
- package/src/host/authoring/selection-remount-handoff.ts +23 -0
- package/src/host/authoring/source-persistence-backend.ts +373 -0
- package/src/host/authoring/source-refresh-revisions.ts +81 -0
- package/src/host/authoring/struct-write-pipe.ts +143 -0
- package/src/host/auto-frame-window.ts +89 -0
- package/src/host/binding-resolver.ts +393 -0
- package/src/host/browser-transpile.ts +631 -0
- package/src/host/canvas-entry-runtime.ts +95 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +216 -0
- package/src/host/components/HeaderTelemetry.tsx +341 -0
- package/src/host/components/PixiIsolationSceneContent.tsx +280 -0
- package/src/host/components/ResolutionPicker.tsx +89 -0
- package/src/host/components/ThreeIsolationSceneContent.tsx +180 -0
- package/src/host/components/frame-debugger-model.ts +579 -0
- package/src/host/components/header-telemetry-model.ts +74 -0
- package/src/host/components/scene-document.tsx +447 -0
- package/src/host/components/utility-view-state.ts +87 -0
- package/src/host/components/world-root-stage-binding.tsx +133 -0
- package/src/host/components/world-root-stage.ts +1046 -0
- package/src/host/coverage/authoring-read-probe.ts +583 -0
- package/src/host/coverage/capability-coverage.ts +1587 -0
- package/src/host/coverage/coverage-accounting.ts +261 -0
- package/src/host/coverage/game-contract-seam-evidence.ts +82 -0
- package/src/host/coverage/project-verb-coverage.ts +148 -0
- package/src/host/coverage/system-adapter-coverage.ts +373 -0
- package/src/host/design-system-stories/StoryLayout.tsx +104 -0
- package/src/host/design-system-stories/fixtures/authoring.ts +247 -0
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +115 -0
- package/src/host/document-preview-three.ts +110 -0
- package/src/host/entry-adjudication.ts +89 -0
- package/src/host/game-location-guard.ts +150 -0
- package/src/host/game-module-access.ts +196 -0
- package/src/host/game-realm-page.ts +358 -0
- package/src/host/game-realm-reclaim.ts +55 -0
- package/src/host/game-realm-storage.ts +104 -0
- package/src/host/gameplay-export.ts +288 -0
- package/src/host/gameplay-recording.ts +717 -0
- package/src/host/gated-globals.ts +1511 -0
- package/src/host/history/json-history-resource.ts +254 -0
- package/src/host/ingest/registry.ts +261 -0
- package/src/host/instance-extract-actions.ts +120 -0
- package/src/host/instance-fork-actions.ts +120 -0
- package/src/host/play-control-hook.ts +26 -0
- package/src/host/playwright-shim.ts +479 -0
- package/src/host/projection/dom.ts +295 -0
- package/src/host/projection/pixi.ts +288 -0
- package/src/host/r3f-entry-runtime.ts +77 -0
- package/src/host/react-mount-runtime.ts +162 -0
- package/src/host/realm-services.ts +148 -0
- package/src/host/recording-preview.ts +106 -0
- package/src/host/roots/module-root.ts +203 -0
- package/src/host/roots/react-root.ts +181 -0
- package/src/host/same-realm-loop-gate.ts +544 -0
- package/src/host/scene-view-drawability.ts +69 -0
- package/src/host/sdk/tools.ts +31 -0
- package/src/host/served-bundle-runtime-modules.ts +331 -0
- package/src/host/server-log-bridge.ts +60 -0
- package/src/host/staged-projects.ts +24 -0
- package/src/host/stories/mounted-story-viewport-source.ts +64 -0
- package/src/host/stories/story-arg-descriptors.ts +50 -0
- package/src/host/stories/story-media-presence.ts +152 -0
- package/src/host/surface-content.ts +87 -0
- package/src/host/take-named-export.ts +23 -0
- package/src/host/three-ingest-runtime.ts +76 -0
- package/src/host/types-fastnoise-lite.d.ts +7 -0
- package/src/host/types-mikktspace.d.ts +20 -0
- package/src/host/types-troika-three-text.d.ts +7 -0
- package/src/host/use-active-performance-source.ts +53 -0
- package/src/host/viewport-pose-memory.ts +48 -0
- package/src/host/viewport-root-presentation.ts +40 -0
- package/src/ingest/active-ingest.ts +251 -0
- package/src/ingest/active-scene-navigation.ts +43 -0
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +191 -0
- package/src/ingest/authoring/ingest-root-adapter.ts +897 -0
- package/src/ingest/capture-wait-report.ts +122 -0
- package/src/ingest/deferred-ingest-play.ts +216 -0
- package/src/ingest/deferred-ingest-session.ts +23 -0
- package/src/ingest/discovery-public-ingest.ts +242 -0
- package/src/ingest/dom-stub-mark.ts +7 -0
- package/src/ingest/entry-load.ts +56 -0
- package/src/ingest/game-contract-realm.ts +34 -0
- package/src/ingest/game-pointer-lock.ts +89 -0
- package/src/ingest/held-scene-repaint.ts +73 -0
- package/src/ingest/host-surface-box.ts +174 -0
- package/src/ingest/ingest-boot-viewport.ts +54 -0
- package/src/ingest/ingest-canvas-scene-document.tsx +177 -0
- package/src/ingest/ingest-canvas-scene.ts +50 -0
- package/src/ingest/ingest-evidence-hook.ts +131 -0
- package/src/ingest/ingest-frame-snapshot.ts +183 -0
- package/src/ingest/ingest-play-commands.ts +134 -0
- package/src/ingest/ingest-play-control.ts +299 -0
- package/src/ingest/ingest-render-debug.ts +320 -0
- package/src/ingest/ingest-siblings.ts +487 -0
- package/src/ingest/ingest-status.ts +62 -0
- package/src/ingest/live-ingest-facet.ts +46 -0
- package/src/ingest/module-mode.ts +229 -0
- package/src/ingest/mount-canvas-ingest-root.ts +899 -0
- package/src/ingest/mount-coverage.ts +296 -0
- package/src/ingest/mount-dom-ingest-root.ts +282 -0
- package/src/ingest/mount-ingest-root.ts +744 -0
- package/src/ingest/mount-three-ingest-root.ts +366 -0
- package/src/ingest/resolve-canvas.ts +47 -0
- package/src/ingest/resolve-three.ts +123 -0
- package/src/ingest/served-bundle.ts +109 -0
- package/src/ingest/served-html-boot.ts +292 -0
- package/src/ingest/surface-canvas.ts +84 -0
- package/src/ingest/surface-dom.ts +84 -0
- package/src/ingest/surface-three.ts +128 -0
- package/src/ingest/types.ts +76 -0
- package/src/ingest/unmount-ingest-root.ts +224 -0
- package/src/navmesh/navmesh-actions.ts +27 -0
- package/src/navmesh/navmesh-handler.ts +237 -0
- package/src/navmesh/navmesh-workflow-store.ts +78 -0
- package/src/network/NetworkInspectorPanel.tsx +644 -0
- package/src/network/network-inspector-model.ts +225 -0
- package/src/play/play-boot-stall.ts +118 -0
- package/src/play/play-log-events.ts +26 -0
- package/src/play/play-mode.ts +2553 -0
- package/src/play/play-recording.ts +335 -0
- package/src/play/react-play-live-authoring.ts +165 -0
- package/src/play-bar/PlayBar.tsx +488 -0
- package/src/play-bar/PlayerCountPicker.tsx +100 -0
- package/src/profiler/FrameDebuggerPanel.tsx +458 -0
- package/src/profiler/PerformancePanel.tsx +1068 -0
- package/src/profiler/ProfilerPanel.tsx +53 -0
- package/src/profiler/frame-debugger-store.ts +97 -0
- package/src/profiler/main-thread-busy.ts +90 -0
- package/src/react/design-time-react-mount.ts +782 -0
- package/src/react/dom-authoring-adapter.ts +764 -0
- package/src/react/pasteboard-materialize.ts +154 -0
- package/src/react/react-inspector-section.tsx +2496 -0
- package/src/react/react-world-authoring-adapter.ts +3795 -0
- package/src/react/story-documents/story-args-section.ts +19 -0
- package/src/react/story-documents/story-documents.tsx +1380 -0
- package/src/react/story-paint-bounds.ts +94 -0
- package/src/react/ui-board-document.tsx +101 -0
- package/src/react/ui-board-title.ts +9 -0
- package/src/react/ui-component-board.ts +72 -0
- package/src/services/audio-pose-guard.ts +81 -0
- package/src/services/game-audio-unlock.ts +48 -0
- package/src/state-watch/StateWatchPanel.tsx +535 -0
- package/src/three/authoring/camera-runtime-inspector-section.tsx +135 -0
- package/src/three/authoring/constraint-inspector-section.tsx +189 -0
- package/src/three/authoring/design-time-renderer.ts +189 -0
- package/src/three/authoring/model-asset-inspector-section.css +41 -0
- package/src/three/authoring/model-asset-inspector-section.tsx +869 -0
- package/src/three/authoring/oid-source-persistence.ts +557 -0
- package/src/three/authoring/r3f-design-session.ts +1174 -0
- package/src/three/authoring/r3f-source-authoring-adapter.ts +5949 -0
- package/src/three/authoring/reflection-probe-inspector-section.tsx +76 -0
- package/src/three/authoring/spatial-audio-handles.ts +215 -0
- package/src/three/authoring/spatial-collider-handles.ts +229 -0
- package/src/three/authoring/spatial-joint-handles.ts +114 -0
- package/src/three/authoring/spatial-light-handles.ts +178 -0
- package/src/three/authoring/spatial-lod-handles.ts +93 -0
- package/src/three/authoring/spatial-particle-handles.ts +368 -0
- package/src/three/authoring/three-authoring-adapter.ts +1953 -0
- package/src/three/authoring/three-scene-identity.ts +19 -0
- package/src/three/authoring/three-spatial-handles.ts +161 -0
- package/src/three/authoring/typed-three-inspector.ts +528 -0
- package/src/three/component-verbs/extract-menu.ts +71 -0
- package/src/three/component-verbs/fork-menu.ts +78 -0
- package/src/three/component-verbs/internals-menu.ts +91 -0
- package/src/three/story-documents/three-story-documents.tsx +607 -0
- package/src/three/three-board/ThreeBoardDocument.tsx +888 -0
- package/src/three/three-board/board-framing.ts +412 -0
- package/src/three/three-board/board-layout.ts +401 -0
- package/src/three/three-board/board-scene.ts +901 -0
- package/src/three/three-board/three-component-board.ts +62 -0
- package/src/xstate/XStateBehaviorSection.tsx +130 -0
- package/src/xstate/XStateMachineInspector.tsx +566 -0
- package/src/xstate/character-animation-machine.fixture.ts +74 -0
- package/src/xstate/live-behaviors.ts +106 -0
- package/src/xstate/use-live-actor-state.ts +44 -0
- package/src/xstate/xstate-graph.ts +235 -0
- package/src/xstate/xstate-layout.ts +76 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE GAME DOCUMENT'S SHARED VIEW STATE — resolution and scale, read by the
|
|
3
|
+
* document's CONTENT (which owns the canvas resize/scale math) and written by
|
|
4
|
+
* its document-local TOOLBAR (the resolution/device pickers). A tiny
|
|
5
|
+
* module-scope store in the house `useSyncExternalStore` shape, session-scoped.
|
|
6
|
+
*
|
|
7
|
+
* It moved out of the host with the Game document itself (WORK.md §The
|
|
8
|
+
* workbench, P3b); `ResolutionPicker` stayed behind because the host's story
|
|
9
|
+
* documents read it, so it is reached through the `@editor/*` alias.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { RESOLUTIONS, type Resolution } from '../host/components/ResolutionPicker';
|
|
13
|
+
import { type DevicePreset, setDevicePreset } from './device-preview';
|
|
14
|
+
|
|
15
|
+
// --- Game document view state (W2, inventory row V4) -----------------------
|
|
16
|
+
// Resolution/scale are shared between the Game document's CONTENT (which
|
|
17
|
+
// owns the canvas resize/scale math) and its document-local TOOLBAR (which
|
|
18
|
+
// hosts the picker + mute, §6.3 "Game mute/resolution controls appear only
|
|
19
|
+
// in the Game document") — a tiny module-scope store in the house
|
|
20
|
+
// `useSyncExternalStore` shape, session-scoped like the old GamePanel state.
|
|
21
|
+
|
|
22
|
+
let _gameResolution: Resolution = { label: 'Fill', width: null, height: null };
|
|
23
|
+
let _gameScale = 1;
|
|
24
|
+
let _gameViewVersion = 0;
|
|
25
|
+
const _gameViewListeners = new Set<() => void>();
|
|
26
|
+
|
|
27
|
+
export function notifyGameView(): void {
|
|
28
|
+
_gameViewVersion++;
|
|
29
|
+
for (const fn of _gameViewListeners) fn();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function subscribeGameView(fn: () => void): () => void {
|
|
33
|
+
_gameViewListeners.add(fn);
|
|
34
|
+
return () => {
|
|
35
|
+
_gameViewListeners.delete(fn);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const gameViewVersion = () => _gameViewVersion;
|
|
40
|
+
|
|
41
|
+
/** The Game document's current resolution selection (exported for tests). */
|
|
42
|
+
export function gameDocumentResolution(): Resolution {
|
|
43
|
+
return _gameResolution;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Set the Game document's resolution (exported for tests). */
|
|
47
|
+
export function setGameDocumentResolution(resolution: Resolution): void {
|
|
48
|
+
_gameResolution = resolution;
|
|
49
|
+
notifyGameView();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** What the toolbar's resolution button SHOWS. The presentation precedence
|
|
53
|
+
* lives in `resolvePresentedSize`; this is its display twin: an explicit
|
|
54
|
+
* pick (device preset / resolution) already carries its numbers, but when
|
|
55
|
+
* the store still says Fill and the project declares a `resolution`, the
|
|
56
|
+
* declared size is what is actually on screen — so it is what the bar must
|
|
57
|
+
* say. (Exported for tests.) */
|
|
58
|
+
export function displayedGameResolution(
|
|
59
|
+
picked: Resolution,
|
|
60
|
+
declared: { width: number; height: number } | undefined,
|
|
61
|
+
): Resolution {
|
|
62
|
+
if (picked.width !== null || !declared) return picked;
|
|
63
|
+
return {
|
|
64
|
+
label: `Project — ${declared.width}×${declared.height}`,
|
|
65
|
+
width: declared.width,
|
|
66
|
+
height: declared.height,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Menu entries for the Game toolbar's picker. With a declared resolution,
|
|
71
|
+
* "Fill" is unreachable by design (`resolvePresentedSize` puts the declared
|
|
72
|
+
* size back the moment nothing else is picked), so offering it would be a
|
|
73
|
+
* lie — the declared entry stands in its place. */
|
|
74
|
+
export function gameResolutionOptions(
|
|
75
|
+
declared: { width: number; height: number } | undefined,
|
|
76
|
+
): Resolution[] {
|
|
77
|
+
if (!declared) return RESOLUTIONS;
|
|
78
|
+
return [
|
|
79
|
+
displayedGameResolution({ label: 'Fill', width: null, height: null }, declared),
|
|
80
|
+
...RESOLUTIONS.filter((r) => r.width !== null),
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** One entry point for "a device preset was chosen" (dropdown pick AND
|
|
85
|
+
* per-project restore): the device-preview store takes the preset (DPR,
|
|
86
|
+
* safe-area, touch policy) and the shared game-resolution store takes its
|
|
87
|
+
* CSS resolution, so the existing GamePanel letterbox/scale path applies. */
|
|
88
|
+
export function applyGameDevicePreset(preset: DevicePreset): void {
|
|
89
|
+
setDevicePreset(preset.id);
|
|
90
|
+
setGameDocumentResolution(
|
|
91
|
+
preset.width === null || preset.height === null
|
|
92
|
+
? { label: 'Fill', width: null, height: null }
|
|
93
|
+
: { label: preset.label, width: preset.width, height: preset.height },
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function setGameScale(scale: number): void {
|
|
98
|
+
if (scale === _gameScale) return;
|
|
99
|
+
_gameScale = scale;
|
|
100
|
+
notifyGameView();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The scale the content last fitted the game at — what the toolbar's
|
|
104
|
+
* percentage readout shows. */
|
|
105
|
+
export function gameDocumentScale(): number {
|
|
106
|
+
return _gameScale;
|
|
107
|
+
}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Play-mode physics debug draw (W2a §2.3c) — Rapier's `debugRender()` collider
|
|
3
|
+
* /joint wireframes plus live contact-point markers, over the running game in
|
|
4
|
+
* the Game tab.
|
|
5
|
+
*
|
|
6
|
+
* Split of labor:
|
|
7
|
+
* - The WIREFRAMES are the engine's own: `PhysicsAdapter.setDebugDrawEnabled`
|
|
8
|
+
* flips the flag the first-party adapter's render system reads, feeding
|
|
9
|
+
* `world.debugRender()` into the debug `LineSegments` that already lives in
|
|
10
|
+
* the game scene (`setup-physics.ts`, buffer-reusing). The editor does zero
|
|
11
|
+
* per-frame work for them.
|
|
12
|
+
* - The CONTACT POINTS come from `PhysicsAdapter.contactPoints()` (world-space
|
|
13
|
+
* solver contacts over a reused buffer) and are drawn here as a pooled
|
|
14
|
+
* `THREE.Points` in the game scene, updated per RAF tick.
|
|
15
|
+
*
|
|
16
|
+
* Reads only `SystemAdapters.physics` capabilities off the active game
|
|
17
|
+
* (installed by play-mode's `setActiveSystems`) — the editor never touches
|
|
18
|
+
* Rapier directly. An adapter lacking the capabilities draws nothing
|
|
19
|
+
* (capability-absence degradation). Toggled from the Game tab's Debug menu
|
|
20
|
+
* (`CenterDocuments.tsx`), mirroring `crowd-debug.ts` exactly: RAF-driven,
|
|
21
|
+
* scene-swap safe across play restarts, torn down on disable; on stop the
|
|
22
|
+
* adapters are cleared (`setActiveSystems(null)`) and the game scene is
|
|
23
|
+
* destroyed, so nothing leaks into the next session.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { getActiveSystems } from '@volter/editor-core/authoring/active-systems';
|
|
27
|
+
import { nodeKeyedPhysics, type PhysicsAdapter } from '@volter/editor-project/adapter';
|
|
28
|
+
import { setUserData } from '@volter/threejs-runtime/ecs/user-data';
|
|
29
|
+
import * as THREE from 'three';
|
|
30
|
+
import { getGameScene } from '../play/play-mode';
|
|
31
|
+
|
|
32
|
+
let _enabled = false;
|
|
33
|
+
let _raf = 0;
|
|
34
|
+
let _group: THREE.Group | null = null;
|
|
35
|
+
let _attachedScene: THREE.Scene | null = null;
|
|
36
|
+
/** The adapter instance the debug-draw flag was last applied to (play restarts install a fresh one). */
|
|
37
|
+
let _appliedAdapter: PhysicsAdapter | null = null;
|
|
38
|
+
|
|
39
|
+
let _points: THREE.Points | null = null;
|
|
40
|
+
let _pointsCapacity = 0;
|
|
41
|
+
|
|
42
|
+
export function physicsDebugEnabled(): boolean {
|
|
43
|
+
return _enabled;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function setPhysicsDebugEnabled(enabled: boolean): void {
|
|
47
|
+
if (enabled === _enabled) return;
|
|
48
|
+
_enabled = enabled;
|
|
49
|
+
if (enabled) {
|
|
50
|
+
_raf = requestAnimationFrame(_tick);
|
|
51
|
+
} else {
|
|
52
|
+
cancelAnimationFrame(_raf);
|
|
53
|
+
_appliedAdapter?.setDebugDrawEnabled?.(false);
|
|
54
|
+
_teardown();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function _tick(): void {
|
|
59
|
+
if (!_enabled) return;
|
|
60
|
+
_raf = requestAnimationFrame(_tick);
|
|
61
|
+
const scene = getGameScene();
|
|
62
|
+
// Node-id keyed only: the wireframes and contact points are THREE objects
|
|
63
|
+
// drawn into the game scene, so a canvas mount's display-keyed carrier is
|
|
64
|
+
// not a degraded source here — it is a different subsystem entirely.
|
|
65
|
+
const physics = scene ? nodeKeyedPhysics(getActiveSystems().physics) : null;
|
|
66
|
+
|
|
67
|
+
// (Re)apply the engine-side debug-draw flag whenever the live adapter
|
|
68
|
+
// changes — enabling before play starts, and re-enabling across play
|
|
69
|
+
// restarts, both converge here.
|
|
70
|
+
if (physics !== _appliedAdapter) {
|
|
71
|
+
_appliedAdapter?.setDebugDrawEnabled?.(false);
|
|
72
|
+
_appliedAdapter = physics;
|
|
73
|
+
physics?.setDebugDrawEnabled?.(true);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_syncAttachment(scene);
|
|
77
|
+
if (!_group || !scene) return;
|
|
78
|
+
|
|
79
|
+
const contacts = physics?.contactPoints?.() ?? null;
|
|
80
|
+
_updateContactPoints(_group, contacts);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** (Re)attach the marker group to whatever game scene is currently live. */
|
|
84
|
+
function _syncAttachment(scene: THREE.Scene | null): void {
|
|
85
|
+
if (scene === _attachedScene) return;
|
|
86
|
+
if (_attachedScene && _group) _attachedScene.remove(_group);
|
|
87
|
+
_attachedScene = scene;
|
|
88
|
+
if (scene) {
|
|
89
|
+
if (!_group) {
|
|
90
|
+
_group = new THREE.Group();
|
|
91
|
+
_group.name = 'physics-debug-draw';
|
|
92
|
+
setUserData(_group, 'editorHelper', true);
|
|
93
|
+
}
|
|
94
|
+
scene.add(_group);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Copy this frame's contact xyz triples into the pooled Points geometry. */
|
|
99
|
+
function _updateContactPoints(group: THREE.Group, contacts: Float32Array | null): void {
|
|
100
|
+
const count = contacts ? contacts.length / 3 : 0;
|
|
101
|
+
if (!_points) {
|
|
102
|
+
_pointsCapacity = 64;
|
|
103
|
+
const geo = new THREE.BufferGeometry();
|
|
104
|
+
geo.setAttribute(
|
|
105
|
+
'position',
|
|
106
|
+
new THREE.BufferAttribute(new Float32Array(_pointsCapacity * 3), 3),
|
|
107
|
+
);
|
|
108
|
+
const mat = new THREE.PointsMaterial({
|
|
109
|
+
color: 0xff3355,
|
|
110
|
+
size: 10,
|
|
111
|
+
sizeAttenuation: false,
|
|
112
|
+
depthTest: false,
|
|
113
|
+
transparent: true,
|
|
114
|
+
opacity: 0.95,
|
|
115
|
+
});
|
|
116
|
+
_points = new THREE.Points(geo, mat);
|
|
117
|
+
_points.renderOrder = 999;
|
|
118
|
+
_points.frustumCulled = false;
|
|
119
|
+
group.add(_points);
|
|
120
|
+
}
|
|
121
|
+
const geo = _points.geometry;
|
|
122
|
+
if (count > _pointsCapacity) {
|
|
123
|
+
// Rare growth path (matches `updatePhysicsDebug`'s size-change handling):
|
|
124
|
+
// replace the attribute only when capacity is actually exceeded.
|
|
125
|
+
while (_pointsCapacity < count) _pointsCapacity *= 2;
|
|
126
|
+
geo.setAttribute(
|
|
127
|
+
'position',
|
|
128
|
+
new THREE.BufferAttribute(new Float32Array(_pointsCapacity * 3), 3),
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
const attr = geo.getAttribute('position') as THREE.BufferAttribute;
|
|
132
|
+
if (contacts && count > 0) (attr.array as Float32Array).set(contacts);
|
|
133
|
+
attr.needsUpdate = true;
|
|
134
|
+
geo.setDrawRange(0, count);
|
|
135
|
+
_points.visible = count > 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* e2e hook (mirrors the world root's stage's `__vgaiViewport`): mechanical state for
|
|
140
|
+
* The question this answers — is the Rapier debug wireframe live in the
|
|
141
|
+
* game scene with real geometry, and how many contact markers are drawn.
|
|
142
|
+
*/
|
|
143
|
+
function _stateForE2E(): {
|
|
144
|
+
enabled: boolean;
|
|
145
|
+
wireframeInScene: boolean;
|
|
146
|
+
wireframeVisible: boolean;
|
|
147
|
+
wireframeVertexCount: number;
|
|
148
|
+
contactMarkerCount: number;
|
|
149
|
+
} {
|
|
150
|
+
const scene = getGameScene();
|
|
151
|
+
const adapter = scene ? nodeKeyedPhysics(getActiveSystems().physics) : null;
|
|
152
|
+
const mesh = (adapter?.debugDraw?.() ?? null) as THREE.LineSegments | null;
|
|
153
|
+
let wireframeInScene = false;
|
|
154
|
+
if (mesh && scene) {
|
|
155
|
+
scene.traverse((o) => {
|
|
156
|
+
if (o === mesh) wireframeInScene = true;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
const posAttr = mesh?.geometry.getAttribute('position') as THREE.BufferAttribute | undefined;
|
|
160
|
+
const drawRange = _points?.geometry.drawRange.count ?? 0;
|
|
161
|
+
return {
|
|
162
|
+
enabled: _enabled,
|
|
163
|
+
wireframeInScene,
|
|
164
|
+
wireframeVisible: mesh?.visible ?? false,
|
|
165
|
+
wireframeVertexCount: posAttr?.count ?? 0,
|
|
166
|
+
contactMarkerCount: _points?.visible && Number.isFinite(drawRange) ? drawRange : 0,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
if (typeof window !== 'undefined') {
|
|
170
|
+
(window as unknown as Record<string, unknown>)['__vgaiPhysicsDebug'] = _stateForE2E;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function _teardown(): void {
|
|
174
|
+
if (_group) {
|
|
175
|
+
_attachedScene?.remove(_group);
|
|
176
|
+
if (_points) {
|
|
177
|
+
_points.geometry.dispose();
|
|
178
|
+
(_points.material as THREE.Material).dispose();
|
|
179
|
+
}
|
|
180
|
+
_group.clear();
|
|
181
|
+
}
|
|
182
|
+
_points = null;
|
|
183
|
+
_pointsCapacity = 0;
|
|
184
|
+
_group = null;
|
|
185
|
+
_attachedScene = null;
|
|
186
|
+
_appliedAdapter = null;
|
|
187
|
+
}
|