@volter/editor-game 0.5.65 → 0.5.67
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/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 +3 -3
- package/contributions/generations.status.tsx +1 -1
- package/contributions/godot.palette.json +99 -0
- package/contributions/godot.style.ts +82 -0
- package/contributions/godot.view.ts +75 -0
- package/contributions/ingest.service.ts +4 -4
- 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 +11 -5
- package/contributions/react/component-board.service.ts +1 -1
- package/contributions/react/design-time-mount.service.ts +1 -1
- package/contributions/react/react-inspector.service.ts +2 -2
- package/contributions/scene-document.service.ts +5 -5
- 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 +8 -8
- package/contributions/three/three-authoring.service.ts +8 -5
- package/contributions/three-story-capture.service.ts +12 -0
- package/contributions/unity.palette.json +102 -0
- package/contributions/unity.style.ts +72 -0
- package/contributions/unity.view.ts +82 -0
- package/contributions/unreal.palette.json +105 -0
- package/contributions/unreal.style.ts +66 -0
- package/contributions/unreal.view.ts +93 -0
- package/dist-node/serving.mjs +16 -0
- package/package.json +33 -16
- package/serving/index.ts +27 -0
- package/src/asset-budget/AssetBudgetPanel.tsx +1 -1
- package/src/asset-budget/asset-budget-model.ts +4 -4
- package/src/asset-budget/optimize-apply.ts +7 -7
- package/src/audio/AudioDebuggerPanel.tsx +1 -1
- package/src/bridge/dispatch.ts +16 -16
- package/src/bridge/live-frames.ts +1 -1
- package/src/bridge/screenshot.ts +6 -6
- package/src/build/BuildProfilesPanel.tsx +3 -3
- package/src/canvas/canvas-board/CanvasBoardDocument.tsx +676 -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 +6 -6
- package/src/coverage/live-project-verbs.ts +2 -2
- package/src/coverage/native-system-coverage.ts +6 -6
- package/src/coverage/root-coverage.ts +1 -1
- package/src/coverage/session-coverage.ts +5 -5
- package/src/design-system-stories/ApplicationChrome.stories.tsx +5 -5
- package/src/design-system-stories/InspectorNarrowBodies.stories.tsx +13 -53
- 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 +2 -2
- package/src/game-document/GameDocument.tsx +2 -2
- package/src/game-document/GamePanel.tsx +8 -8
- 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 +6 -8
- package/src/generation/generation-documents.tsx +8 -8
- package/src/generation/generation-jobs.ts +2 -2
- package/src/generation/generation-presentation.ts +1 -1
- package/src/host/adapter-reach.ts +1 -1
- package/src/host/adapter-runtime-bindings.ts +97 -6
- package/src/host/api/configurations.ts +2 -2
- package/src/host/authoring/babylon-authoring-adapter.ts +8 -8
- package/src/host/authoring/contract-hierarchy-authoring.ts +1 -1
- package/src/host/authoring/contract-scenes-stories.ts +1 -1
- package/src/host/authoring/creation-site-related.ts +2 -2
- package/src/host/authoring/ephemeral-persistence.ts +1 -1
- package/src/host/authoring/gesture-persist.ts +2 -2
- package/src/host/authoring/ingest-data-writer.ts +1 -1
- package/src/host/authoring/ingest-source-persistence.ts +8 -8
- package/src/host/authoring/mount-isolated-pixi-screen.ts +1 -1
- 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 +42 -17
- package/src/host/authoring/pixi-creation-site-write-target.ts +2 -2
- package/src/host/authoring/pixi-live-write-target.ts +7 -7
- package/src/host/authoring/pixi-source-identity.ts +3 -3
- package/src/host/authoring/pixi-source-write-target.ts +1614 -0
- package/src/host/authoring/pixi-still-presentation.ts +2 -2
- package/src/host/authoring/pixi-structure-history.ts +3 -3
- package/src/host/authoring/pixi-transform-channels.ts +16 -14
- package/src/host/authoring/source-persistence-backend.ts +6 -6
- package/src/host/authoring/struct-write-pipe.ts +3 -3
- package/src/host/binding-resolver.ts +8 -9
- package/src/host/browser-transpile.ts +2 -2
- package/src/host/canvas-entry-runtime.ts +59 -48
- package/src/host/canvas-preview-frames.ts +482 -0
- package/src/host/components/CameraAuthoringOverlay.tsx +1 -1
- package/src/host/components/HeaderTelemetry.tsx +9 -16
- package/src/host/components/PixiIsolationSceneContent.tsx +17 -16
- package/src/host/components/ThreeIsolationSceneContent.tsx +5 -5
- 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 +29 -61
- package/src/host/components/utility-view-state.ts +1 -1
- package/src/host/components/world-root-stage-binding.tsx +17 -26
- package/src/host/components/world-root-stage.ts +130 -63
- package/src/host/coverage/capability-coverage.ts +13 -1
- package/src/host/coverage/game-contract-seam-evidence.ts +1 -1
- package/src/host/coverage/project-verb-coverage.ts +2 -17
- package/src/host/coverage/system-adapter-coverage.ts +4 -5
- package/src/host/design-system-stories/fixtures/editor-runtime.tsx +14 -8
- package/src/host/document-preview-three.ts +2 -2
- package/src/host/entry-adjudication.ts +6 -6
- package/src/host/game-css-scope-transform.ts +4 -0
- package/src/host/game-module-access.ts +1 -1
- package/src/host/game-realm-page.ts +16 -8
- package/src/host/game-realm-reclaim.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 +6 -6
- package/src/host/history/json-history-resource.ts +3 -3
- package/src/host/instance-extract-actions.ts +1 -1
- package/src/host/instance-fork-actions.ts +1 -1
- package/src/host/projection/dom.ts +2 -2
- package/src/host/projection/pixi.ts +25 -3
- package/src/host/r3f-entry-runtime.ts +65 -34
- package/src/host/react-mount-runtime.ts +8 -49
- package/src/host/realm-services.ts +2 -2
- package/src/host/roots/canvas-root.tsx +361 -0
- package/src/host/roots/module-root.ts +1 -1
- package/src/host/roots/r3f-root.tsx +473 -0
- package/src/host/roots/react-root.ts +9 -43
- package/src/host/scene-view-drawability.ts +2 -2
- package/src/host/served-bundle-runtime-modules.ts +1 -19
- package/src/host/server-log-bridge.ts +3 -3
- 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/three-ingest-runtime.ts +1 -1
- package/src/host/use-active-performance-source.ts +3 -3
- package/src/host/viewport-pose-memory.ts +1 -1
- package/src/host/viewport-root-presentation.ts +6 -5
- package/src/ingest/active-ingest.ts +2 -2
- package/src/ingest/authoring/ingest-dom-surface-authoring.ts +4 -4
- package/src/ingest/authoring/ingest-root-adapter.ts +13 -13
- package/src/ingest/capture-wait-report.ts +1 -1
- package/src/ingest/deferred-ingest-play.ts +11 -10
- package/src/ingest/discovery-public-ingest.ts +2 -2
- package/src/ingest/ingest-boot-viewport.ts +6 -8
- package/src/ingest/ingest-canvas-scene-document.tsx +17 -16
- package/src/ingest/ingest-canvas-scene.ts +5 -8
- 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 +4 -4
- package/src/ingest/ingest-render-debug.ts +11 -11
- package/src/ingest/ingest-siblings.ts +16 -28
- package/src/ingest/module-mode.ts +18 -19
- package/src/ingest/mount-canvas-ingest-root.ts +27 -27
- package/src/ingest/mount-coverage.ts +4 -4
- package/src/ingest/mount-dom-ingest-root.ts +16 -16
- package/src/ingest/mount-ingest-root.ts +14 -14
- package/src/ingest/mount-three-ingest-root.ts +12 -12
- 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 +7 -7
- package/src/navmesh/navmesh-handler.ts +24 -16
- package/src/network/NetworkInspectorPanel.tsx +449 -14
- package/src/network/network-inspector-model.ts +14 -2
- package/src/play/play-log-events.ts +1 -1
- package/src/play/play-mode.ts +99 -142
- package/src/play/play-recording.ts +2 -2
- 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 +4 -4
- package/src/react/design-time-react-mount.ts +37 -85
- package/src/react/dom-authoring-adapter.ts +11 -11
- package/src/react/react-inspector-section.tsx +13 -13
- package/src/react/react-world-authoring-adapter.ts +31 -143
- package/src/react/story-documents/story-documents.tsx +18 -22
- package/src/react/ui-board-document.tsx +10 -11
- package/src/react/ui-component-board.ts +5 -5
- 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 +169 -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 +657 -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 +4 -3
- package/src/three/authoring/constraint-inspector-section.tsx +8 -7
- package/src/three/authoring/model-asset-inspector-section.tsx +14 -17
- package/src/three/authoring/oid-source-persistence.ts +13 -13
- package/src/three/authoring/r3f-design-session.ts +79 -61
- package/src/three/authoring/r3f-source-authoring-adapter.ts +112 -108
- package/src/three/authoring/reflection-probe-inspector-section.tsx +5 -4
- package/src/three/authoring/spatial-joint-handles.ts +1 -1
- package/src/three/authoring/spatial-lod-handles.ts +1 -1
- package/src/three/authoring/spatial-particle-handles.ts +1 -1
- package/src/three/authoring/three-authoring-adapter.ts +33 -33
- package/src/three/component-verbs/extract-menu.ts +8 -7
- package/src/three/component-verbs/fork-menu.ts +8 -7
- package/src/three/component-verbs/internals-menu.ts +3 -3
- package/src/three/drei-asset-caches.ts +13 -0
- package/src/three/story-documents/three-story-documents.tsx +24 -34
- package/src/three/three-board/ThreeBoardDocument.tsx +25 -25
- package/src/three/three-board/board-scene.ts +7 -7
- package/src/three/three-board/three-component-board.ts +5 -5
- package/contributions/react/pasteboard.action.ts +0 -41
- package/contributions/xstate-behavior.action.ts +0 -42
- package/contributions/xstate-behavior.document.tsx +0 -73
- package/contributions/xstate-behavior.inspector.tsx +0 -28
- package/contributions/xstate-behavior.menu.ts +0 -23
- package/src/react/pasteboard-materialize.ts +0 -154
- package/src/services/game-audio-unlock.ts +0 -48
- package/src/xstate/XStateBehaviorSection.tsx +0 -130
- package/src/xstate/XStateMachineInspector.tsx +0 -566
- package/src/xstate/character-animation-machine.fixture.ts +0 -74
- package/src/xstate/live-behaviors.ts +0 -106
- package/src/xstate/use-live-actor-state.ts +0 -44
- package/src/xstate/xstate-graph.ts +0 -235
- package/src/xstate/xstate-layout.ts +0 -76
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE EDITOR'S VIEW OF A GAME'S OWN `@react-three/rapier` WORLD — the physics half of what
|
|
3
|
+
* `game-audio.ts` does for Web Audio: a game writes `<Physics>` and `<RigidBody>` with the
|
|
4
|
+
* library's own API and declares nothing, and the editor still reaches the bodies a drag must
|
|
5
|
+
* freeze and commit.
|
|
6
|
+
*
|
|
7
|
+
* WHERE THE WORLD IS. The library keeps its world, its body↔object map and its Rapier module in
|
|
8
|
+
* the value of the `<Physics>` context provider, and exports no value for that context. The editor
|
|
9
|
+
* mounted the game's R3F root, so it walks that root's fiber tree (Fiber's `_roots`, keyed by
|
|
10
|
+
* canvas, matched by the root's scene) to the provider whose value has that shape. The registry
|
|
11
|
+
* is the one in the Fiber instance the game's root was created with: under the packaged runtime
|
|
12
|
+
* that is the project graph's, reached through the R3F doorway (`r3fRoots`); the shell's own
|
|
13
|
+
* bundled Fiber holds no game root. The walk runs per call, at gesture rate, so a `<Physics>`
|
|
14
|
+
* that mounts, remounts or swaps its world is read as it is now.
|
|
15
|
+
*
|
|
16
|
+
* WHAT IT ANSWERS. Body ownership and the freeze → commit → unfreeze a transform edit needs,
|
|
17
|
+
* through `createRapierBodyEditing` — the same verbs the first-party runtime answers — and a
|
|
18
|
+
* body's colliders and joints, read from the same context value (its collider map, its world's
|
|
19
|
+
* impulse joints), with previews that write a dragged size or anchor to the real collider or joint.
|
|
20
|
+
* The debug draw is OMITTED: drawing is only the `debug` prop of the game's own `<Physics>`, and
|
|
21
|
+
* absence is how a system adapter says "not supported".
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { _roots as shellRoots } from '@react-three/fiber';
|
|
25
|
+
import { R3F_RUNTIME_PATH } from '@volter/editor-sdk/host';
|
|
26
|
+
import { isPackagedRuntime } from '@volter/editor-sdk/kit/packaged-runtime';
|
|
27
|
+
import type { RapierContext, RapierRigidBody } from '@react-three/rapier';
|
|
28
|
+
import type {
|
|
29
|
+
PhysicsAdapter,
|
|
30
|
+
PhysicsColliderShape,
|
|
31
|
+
PhysicsColliderSnapshot,
|
|
32
|
+
PhysicsJointSnapshot,
|
|
33
|
+
PhysicsJointType,
|
|
34
|
+
} from '@volter/editor-project/adapter/system-adapter';
|
|
35
|
+
import {
|
|
36
|
+
createRapierBodyEditing,
|
|
37
|
+
type RapierBodyLookup,
|
|
38
|
+
} from '@volter/threejs-runtime/adapter/rapier-physics-adapter';
|
|
39
|
+
import * as THREE from 'three';
|
|
40
|
+
|
|
41
|
+
type RapierContextValue = RapierContext;
|
|
42
|
+
type RapierBodyState = { readonly object: THREE.Object3D; readonly rigidBody: RapierRigidBody };
|
|
43
|
+
type RapierCollider = ReturnType<RapierContext['world']['getCollider']>;
|
|
44
|
+
type RapierJoint = ReturnType<RapierContext['world']['impulseJoints']['getAll']>[number];
|
|
45
|
+
|
|
46
|
+
interface FiberNode {
|
|
47
|
+
readonly child: FiberNode | null;
|
|
48
|
+
readonly sibling: FiberNode | null;
|
|
49
|
+
readonly memoizedProps: { readonly value?: unknown } | null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function isRapierContext(value: unknown): value is RapierContextValue {
|
|
53
|
+
if (!value || typeof value !== 'object') return false;
|
|
54
|
+
const candidate = value as Partial<RapierContextValue>;
|
|
55
|
+
return (
|
|
56
|
+
candidate.rigidBodyStates instanceof Map &&
|
|
57
|
+
candidate.colliderStates instanceof Map &&
|
|
58
|
+
candidate.world !== undefined &&
|
|
59
|
+
candidate.rapier !== undefined
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
type FiberRoots = typeof shellRoots;
|
|
64
|
+
|
|
65
|
+
let projectRoots: FiberRoots | null = null;
|
|
66
|
+
let projectRootsRequest: Promise<void> | null = null;
|
|
67
|
+
|
|
68
|
+
/** The root registry of the Fiber instance game roots are created with. `null` until the
|
|
69
|
+
* packaged runtime's doorway has answered; the first call starts that import. */
|
|
70
|
+
function gameFiberRoots(): FiberRoots | null {
|
|
71
|
+
if (projectRoots) return projectRoots;
|
|
72
|
+
projectRootsRequest ??= (async () => {
|
|
73
|
+
if (!(await isPackagedRuntime())) {
|
|
74
|
+
projectRoots = shellRoots;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const mod = (await import(/* @vite-ignore */ R3F_RUNTIME_PATH)) as { r3fRoots?: unknown };
|
|
78
|
+
if (!(mod.r3fRoots instanceof Map)) {
|
|
79
|
+
throw new Error(
|
|
80
|
+
"The packaged runtime's synthetic R3F module did not export `r3fRoots` — see R3F_DOORWAY " +
|
|
81
|
+
'in vite-plugin-module-doorways.ts.',
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
projectRoots = mod.r3fRoots as FiberRoots;
|
|
85
|
+
})();
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** The `<Physics>` context value inside the R3F root that renders `scene`, if one is mounted. */
|
|
90
|
+
export function rapierContextFor(scene: THREE.Object3D): RapierContextValue | null {
|
|
91
|
+
const roots = gameFiberRoots();
|
|
92
|
+
if (!roots) return null;
|
|
93
|
+
for (const root of roots.values()) {
|
|
94
|
+
if (root.store.getState().scene !== scene) continue;
|
|
95
|
+
const start = (root.fiber as unknown as { current: FiberNode | null }).current;
|
|
96
|
+
const pending: FiberNode[] = start ? [start] : [];
|
|
97
|
+
while (pending.length > 0) {
|
|
98
|
+
const fiber = pending.pop()!;
|
|
99
|
+
const value = fiber.memoizedProps?.value;
|
|
100
|
+
if (isRapierContext(value)) return value;
|
|
101
|
+
if (fiber.sibling) pending.push(fiber.sibling);
|
|
102
|
+
if (fiber.child) pending.push(fiber.child);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolves once a `<Physics>` world is mounted in the root rendering `scene`,
|
|
110
|
+
* or after `timeoutMs` without one. `<Physics>` suspends until Rapier's WASM
|
|
111
|
+
* loads, so a panel that read the body before then has to be told to read again.
|
|
112
|
+
*/
|
|
113
|
+
export function whenRapierWorldMounts(scene: THREE.Object3D, timeoutMs = 60_000): Promise<boolean> {
|
|
114
|
+
const started = performance.now();
|
|
115
|
+
return new Promise((resolve) => {
|
|
116
|
+
const check = (): void => {
|
|
117
|
+
if (rapierContextFor(scene)) return resolve(true);
|
|
118
|
+
if (performance.now() - started > timeoutMs) return resolve(false);
|
|
119
|
+
setTimeout(check, 250);
|
|
120
|
+
};
|
|
121
|
+
check();
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** The object carrying `nodeId` (the editor's `userData.entityId`) inside a body's subtree. */
|
|
126
|
+
function entityObject(states: Iterable<RapierBodyState>, nodeId: string): THREE.Object3D | undefined {
|
|
127
|
+
let found: THREE.Object3D | undefined;
|
|
128
|
+
for (const state of states) {
|
|
129
|
+
state.object.traverse((candidate) => {
|
|
130
|
+
if (!found && candidate.userData['entityId'] === nodeId) found = candidate;
|
|
131
|
+
});
|
|
132
|
+
if (found) return found;
|
|
133
|
+
}
|
|
134
|
+
return undefined;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** The body whose `<RigidBody>` owns `object`: the object itself or its nearest owning ancestor. */
|
|
138
|
+
function owningBody(object: THREE.Object3D, states: Iterable<RapierBodyState>): RapierRigidBody | undefined {
|
|
139
|
+
const byObject = new Map<THREE.Object3D, RapierRigidBody>();
|
|
140
|
+
for (const state of states) byObject.set(state.object, state.rigidBody);
|
|
141
|
+
for (let node: THREE.Object3D | null = object; node; node = node.parent) {
|
|
142
|
+
const body = byObject.get(node);
|
|
143
|
+
if (body) return body;
|
|
144
|
+
}
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const tuple3 = (value: { x: number; y: number; z: number }): [number, number, number] => [
|
|
149
|
+
value.x,
|
|
150
|
+
value.y,
|
|
151
|
+
value.z,
|
|
152
|
+
];
|
|
153
|
+
const tuple4 = (value: {
|
|
154
|
+
x: number;
|
|
155
|
+
y: number;
|
|
156
|
+
z: number;
|
|
157
|
+
w: number;
|
|
158
|
+
}): [number, number, number, number] => [value.x, value.y, value.z, value.w];
|
|
159
|
+
|
|
160
|
+
/** A collider's shape as plain data. Rapier has more shapes than the seam projects (TriMesh,
|
|
161
|
+
* HeightField, ConvexPolyhedron, …); those report themselves by Rapier's own name rather than
|
|
162
|
+
* dropping out, so a body whose only collider is a trimesh does not read as having none. */
|
|
163
|
+
function colliderShape(context: RapierContext, collider: RapierCollider): PhysicsColliderShape {
|
|
164
|
+
const { ShapeType } = context.rapier;
|
|
165
|
+
switch (collider.shapeType()) {
|
|
166
|
+
case ShapeType.Cuboid:
|
|
167
|
+
return { type: 'cuboid', halfExtents: tuple3(collider.halfExtents()) };
|
|
168
|
+
case ShapeType.Ball:
|
|
169
|
+
return { type: 'ball', radius: collider.radius() };
|
|
170
|
+
case ShapeType.Capsule:
|
|
171
|
+
return { type: 'capsule', halfHeight: collider.halfHeight(), radius: collider.radius() };
|
|
172
|
+
default:
|
|
173
|
+
return {
|
|
174
|
+
type: 'unsupported',
|
|
175
|
+
kind:
|
|
176
|
+
(ShapeType as unknown as Record<number, string | undefined>)[collider.shapeType()] ??
|
|
177
|
+
`shapeType ${collider.shapeType()}`,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function jointType(context: RapierContext, type: number): PhysicsJointType {
|
|
183
|
+
const { JointType } = context.rapier;
|
|
184
|
+
switch (type) {
|
|
185
|
+
case JointType.Revolute:
|
|
186
|
+
return 'revolute';
|
|
187
|
+
case JointType.Fixed:
|
|
188
|
+
return 'fixed';
|
|
189
|
+
case JointType.Prismatic:
|
|
190
|
+
return 'prismatic';
|
|
191
|
+
case JointType.Rope:
|
|
192
|
+
return 'rope';
|
|
193
|
+
case JointType.Spring:
|
|
194
|
+
return 'spring';
|
|
195
|
+
case JointType.Spherical:
|
|
196
|
+
return 'spherical';
|
|
197
|
+
default:
|
|
198
|
+
return 'generic';
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function worldAnchor(body: RapierRigidBody, anchor: { x: number; y: number; z: number }) {
|
|
203
|
+
return tuple3(
|
|
204
|
+
new THREE.Vector3(anchor.x, anchor.y, anchor.z)
|
|
205
|
+
.applyQuaternion(new THREE.Quaternion(...tuple4(body.rotation())))
|
|
206
|
+
.add(new THREE.Vector3(...tuple3(body.translation()))),
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function jointSnapshot(context: RapierContext, joint: RapierJoint): PhysicsJointSnapshot {
|
|
211
|
+
const body1 = joint.body1();
|
|
212
|
+
const body2 = joint.body2();
|
|
213
|
+
const anchor1 = joint.anchor1();
|
|
214
|
+
const anchor2 = joint.anchor2();
|
|
215
|
+
const type = jointType(context, joint.type());
|
|
216
|
+
const axial = type === 'revolute' || type === 'prismatic';
|
|
217
|
+
const frame = axial ? joint.frameX1() : null;
|
|
218
|
+
const axis = frame
|
|
219
|
+
? new THREE.Vector3(1, 0, 0).applyQuaternion(new THREE.Quaternion(frame.x, frame.y, frame.z, frame.w))
|
|
220
|
+
: null;
|
|
221
|
+
const unit = joint as unknown as { limitsEnabled(): boolean; limitsMin(): number; limitsMax(): number };
|
|
222
|
+
return {
|
|
223
|
+
id: String(joint.handle),
|
|
224
|
+
type,
|
|
225
|
+
body1: String(body1.handle),
|
|
226
|
+
body2: String(body2.handle),
|
|
227
|
+
anchor1: tuple3(anchor1),
|
|
228
|
+
anchor2: tuple3(anchor2),
|
|
229
|
+
worldAnchor1: worldAnchor(body1, anchor1),
|
|
230
|
+
worldAnchor2: worldAnchor(body2, anchor2),
|
|
231
|
+
body1Position: tuple3(body1.translation()),
|
|
232
|
+
body2Position: tuple3(body2.translation()),
|
|
233
|
+
body1Rotation: tuple4(body1.rotation()),
|
|
234
|
+
body2Rotation: tuple4(body2.rotation()),
|
|
235
|
+
...(axis
|
|
236
|
+
? {
|
|
237
|
+
axis: tuple3(axis),
|
|
238
|
+
worldAxis: tuple3(axis.clone().applyQuaternion(new THREE.Quaternion(...tuple4(body1.rotation())))),
|
|
239
|
+
}
|
|
240
|
+
: {}),
|
|
241
|
+
...(axial && unit.limitsEnabled() ? { limits: { min: unit.limitsMin(), max: unit.limitsMax() } } : {}),
|
|
242
|
+
contactsEnabled: joint.contactsEnabled(),
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* The editor's physics adapter for the game world rendering `scene`. `<Physics>` suspends until
|
|
248
|
+
* Rapier's WASM has loaded, so at mount its provider is usually not there yet: the adapter
|
|
249
|
+
* resolves the world on every call, and until one is mounted every node reads as unresolved.
|
|
250
|
+
* Whether a world gets one at all is the caller's question (`adapter-runtime-bindings.ts`).
|
|
251
|
+
*/
|
|
252
|
+
export function observedRapierPhysics(scene: THREE.Object3D): PhysicsAdapter {
|
|
253
|
+
const lookup = (nodeId: string): RapierBodyLookup => {
|
|
254
|
+
const context = rapierContextFor(scene);
|
|
255
|
+
if (!context) return { kind: 'unresolved' };
|
|
256
|
+
const states = [...context.rigidBodyStates.values()];
|
|
257
|
+
const object = entityObject(states, nodeId);
|
|
258
|
+
if (!object) return { kind: 'unresolved' };
|
|
259
|
+
const body = owningBody(object, states);
|
|
260
|
+
return body ? { kind: 'body', body } : { kind: 'no-body' };
|
|
261
|
+
};
|
|
262
|
+
/** The live world and the body driving `nodeId`, when both exist now. */
|
|
263
|
+
const bodyOf = (nodeId: string): { context: RapierContext; body: RapierRigidBody } | null => {
|
|
264
|
+
const context = rapierContextFor(scene);
|
|
265
|
+
if (!context) return null;
|
|
266
|
+
const states = [...context.rigidBodyStates.values()];
|
|
267
|
+
const object = entityObject(states, nodeId);
|
|
268
|
+
const body = object ? owningBody(object, states) : undefined;
|
|
269
|
+
return body ? { context, body } : null;
|
|
270
|
+
};
|
|
271
|
+
return {
|
|
272
|
+
...createRapierBodyEditing(lookup),
|
|
273
|
+
colliders(nodeId: string): PhysicsColliderSnapshot[] {
|
|
274
|
+
const found = bodyOf(nodeId);
|
|
275
|
+
if (!found) return [];
|
|
276
|
+
const result: PhysicsColliderSnapshot[] = [];
|
|
277
|
+
for (const state of found.context.colliderStates.values()) {
|
|
278
|
+
if (state.collider.parent()?.handle !== found.body.handle) continue;
|
|
279
|
+
state.object.updateWorldMatrix(true, false);
|
|
280
|
+
const scale = state.object.getWorldScale(new THREE.Vector3());
|
|
281
|
+
result.push({
|
|
282
|
+
id: String(state.collider.handle),
|
|
283
|
+
shape: colliderShape(found.context, state.collider),
|
|
284
|
+
position: tuple3(state.collider.translation()),
|
|
285
|
+
rotation: tuple4(state.collider.rotation()),
|
|
286
|
+
scale: [Math.abs(scale.x), Math.abs(scale.y), Math.abs(scale.z)],
|
|
287
|
+
sensor: state.collider.isSensor(),
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return result.sort((a, b) => Number(a.id) - Number(b.id));
|
|
291
|
+
},
|
|
292
|
+
previewCollider(colliderId: string, shape: PhysicsColliderShape): void {
|
|
293
|
+
const context = rapierContextFor(scene);
|
|
294
|
+
const collider = context
|
|
295
|
+
? [...context.colliderStates.values()].find((state) => String(state.collider.handle) === colliderId)
|
|
296
|
+
?.collider
|
|
297
|
+
: undefined;
|
|
298
|
+
if (!context || !collider || colliderShape(context, collider).type !== shape.type) return;
|
|
299
|
+
switch (shape.type) {
|
|
300
|
+
case 'cuboid':
|
|
301
|
+
collider.setHalfExtents({ x: shape.halfExtents[0], y: shape.halfExtents[1], z: shape.halfExtents[2] });
|
|
302
|
+
break;
|
|
303
|
+
case 'ball':
|
|
304
|
+
collider.setRadius(shape.radius);
|
|
305
|
+
break;
|
|
306
|
+
case 'capsule':
|
|
307
|
+
collider.setHalfHeight(shape.halfHeight);
|
|
308
|
+
collider.setRadius(shape.radius);
|
|
309
|
+
break;
|
|
310
|
+
// A shape the seam does not project has no dimensions to write back.
|
|
311
|
+
case 'unsupported':
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
},
|
|
315
|
+
joints(nodeId: string): PhysicsJointSnapshot[] {
|
|
316
|
+
const found = bodyOf(nodeId);
|
|
317
|
+
if (!found) return [];
|
|
318
|
+
const result: PhysicsJointSnapshot[] = [];
|
|
319
|
+
const joints = found.context.world.impulseJoints;
|
|
320
|
+
joints.forEachJointHandleAttachedToRigidBody(found.body.handle, (handle) => {
|
|
321
|
+
const joint = joints.get(handle);
|
|
322
|
+
if (joint) result.push(jointSnapshot(found.context, joint));
|
|
323
|
+
});
|
|
324
|
+
return result.sort((a, b) => Number(a.id) - Number(b.id));
|
|
325
|
+
},
|
|
326
|
+
previewJointAnchor(jointId: string, endpoint: 0 | 1, anchor: readonly [number, number, number]): void {
|
|
327
|
+
const joint = rapierContextFor(scene)?.world.impulseJoints.get(Number(jointId));
|
|
328
|
+
if (!joint) return;
|
|
329
|
+
const value = { x: anchor[0], y: anchor[1], z: anchor[2] };
|
|
330
|
+
if (endpoint === 0) joint.setAnchor1(value);
|
|
331
|
+
else joint.setAnchor2(value);
|
|
332
|
+
},
|
|
333
|
+
};
|
|
334
|
+
}
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* (`editorHost().projectLocalState`), not a project sidecar or a new format.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { getActiveDebug } from '@volter/editor-
|
|
11
|
+
import { getActiveDebug } from '@volter/editor-sdk/kit/authoring/active-systems';
|
|
12
12
|
import { editorHost } from '@volter/editor-sdk/host';
|
|
13
13
|
import { Button, DisclosureIcon, TextInput, themeVars } from '@volter/editor-sdk/widgets';
|
|
14
14
|
import type { DebugAdapter } from '@volter/editor-project/adapter/system-adapter';
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* the editor creates no camera graph or sidecar.
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
12
|
+
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
13
|
+
import { getActiveCamera } from '@volter/editor-sdk/kit/authoring/active-systems';
|
|
14
|
+
import type { InspectorSectionProps } from '@volter/editor-sdk/kit/inspector-section-registry';
|
|
14
15
|
import type {
|
|
15
16
|
AuthoringAdapter,
|
|
16
17
|
CameraAdapter,
|
|
@@ -26,7 +27,7 @@ function selectedNativeCamera(
|
|
|
26
27
|
adapter: AuthoringAdapter,
|
|
27
28
|
nodeId: string | null,
|
|
28
29
|
): THREE.Camera | null {
|
|
29
|
-
const object = nodeId ? adapter.hierarchy
|
|
30
|
+
const object = nodeId ? threeObject(adapter.hierarchy, nodeId) : null;
|
|
30
31
|
if (!object) return null;
|
|
31
32
|
if ((object as THREE.Camera).isCamera) return object as THREE.Camera;
|
|
32
33
|
const owned = object.userData['_camera'] as THREE.Camera | undefined;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import type { InspectorSectionProps } from '@volter/editor-
|
|
1
|
+
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
2
|
+
import { instanceStampOf } from '@volter/editor-threejs/kit/authoring/component-instance-root';
|
|
3
|
+
import { setAuthoringSelection } from '@volter/editor-sdk/kit/authoring/consumer-actions';
|
|
4
|
+
import type { InspectorSectionProps } from '@volter/editor-sdk/kit/inspector-section-registry';
|
|
5
5
|
import type { AuthoringAdapter, EditorNode } from '@volter/editor-project/adapter';
|
|
6
6
|
import {
|
|
7
7
|
type ConstraintMark,
|
|
@@ -17,9 +17,10 @@ import {
|
|
|
17
17
|
themeVars,
|
|
18
18
|
} from '@volter/editor-sdk/widgets';
|
|
19
19
|
import type * as THREE from 'three';
|
|
20
|
+
import { useThreeEditorStore } from '@volter/editor-threejs/kit/three-state';
|
|
20
21
|
|
|
21
22
|
function objectFor(adapter: AuthoringAdapter, nodeId: string | null) {
|
|
22
|
-
return nodeId ? (adapter.hierarchy
|
|
23
|
+
return nodeId ? threeObject(adapter.hierarchy, nodeId) : null;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
/** Marks owned by this semantic component, including same-instance host nodes
|
|
@@ -65,7 +66,7 @@ function typeLabel(type: ConstraintMark['config']['type']): string {
|
|
|
65
66
|
}
|
|
66
67
|
|
|
67
68
|
export function ConstraintStackSection({ adapter, nodeId }: InspectorSectionProps) {
|
|
68
|
-
const store =
|
|
69
|
+
const store = useThreeEditorStore();
|
|
69
70
|
const object = nodeId
|
|
70
71
|
? (store.objectMap.get(nodeId) ?? objectFor(adapter, nodeId) ?? null)
|
|
71
72
|
: null;
|
|
@@ -77,7 +78,7 @@ export function ConstraintStackSection({ adapter, nodeId }: InspectorSectionProp
|
|
|
77
78
|
if (!object) return;
|
|
78
79
|
const id = adapter.hierarchy.idForObject3D?.(object);
|
|
79
80
|
if (!id) return;
|
|
80
|
-
if (!setAuthoringSelection(adapter, [id], { intent: 'exact' })) store.select(id);
|
|
81
|
+
if (!setAuthoringSelection(adapter, [id], { intent: 'exact' })) store.shell.select(id);
|
|
81
82
|
};
|
|
82
83
|
|
|
83
84
|
return (
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// The section's own styles travel with it: the kit's `editor-styles.css` may
|
|
2
2
|
// not @import a package's stylesheet (it would name a package), so the module
|
|
3
3
|
// that draws them imports them.
|
|
4
|
+
import { threeObject } from '@volter/editor-threejs/adapter/three-contract';
|
|
4
5
|
import './model-asset-inspector-section.css';
|
|
5
6
|
import {
|
|
6
7
|
inspectModel,
|
|
@@ -10,27 +11,26 @@ import {
|
|
|
10
11
|
type ModelRigInspection,
|
|
11
12
|
modelSelectionObjects,
|
|
12
13
|
type Object3DNodeInspection,
|
|
13
|
-
} from '@volter/editor-
|
|
14
|
-
import { setAuthoringSelection } from '@volter/editor-
|
|
15
|
-
import { SourceObject3DAuthoringAdapter } from '@volter/editor-
|
|
16
|
-
import { openToolDocument } from '@volter/editor-
|
|
17
|
-
import {
|
|
18
|
-
import { createHmrRegistrationGroup } from '@volter/editor-core/hmr-registration-group';
|
|
14
|
+
} from '@volter/editor-threejs/kit/asset-workflow/model-inspection';
|
|
15
|
+
import { setAuthoringSelection } from '@volter/editor-sdk/kit/authoring/consumer-actions';
|
|
16
|
+
import { SourceObject3DAuthoringAdapter } from '@volter/editor-threejs/kit/authoring/source-object3d-authoring-adapter';
|
|
17
|
+
import { openToolDocument } from '@volter/editor-sdk/kit/components/tool-documents';
|
|
18
|
+
import { createHmrRegistrationGroup } from '@volter/editor-sdk/kit/hmr-registration-group';
|
|
19
19
|
import {
|
|
20
20
|
CONTRIBUTED_SECTION_ORDER,
|
|
21
21
|
type InspectionSection,
|
|
22
22
|
PROPERTIES_SECTION_ID,
|
|
23
|
-
} from '@volter/editor-
|
|
24
|
-
import { registerInspectorSections } from '@volter/editor-
|
|
23
|
+
} from '@volter/editor-sdk/kit/inspection-model';
|
|
24
|
+
import { registerInspectorSections } from '@volter/editor-sdk/kit/inspector-section-registry';
|
|
25
25
|
import {
|
|
26
26
|
type ProjectOutputProvenance,
|
|
27
27
|
provenanceForProjectAsset,
|
|
28
|
-
} from '@volter/editor-
|
|
28
|
+
} from '@volter/editor-sdk/kit/project-provenance';
|
|
29
29
|
import {
|
|
30
30
|
getDocumentToolContributions,
|
|
31
31
|
getGlobalToolContributions,
|
|
32
32
|
subscribeToolContributions,
|
|
33
|
-
} from '@volter/editor-
|
|
33
|
+
} from '@volter/editor-sdk/kit/tool-loader';
|
|
34
34
|
import type { AuthoringAdapter, EditorNode } from '@volter/editor-project/adapter';
|
|
35
35
|
import { object3DAuthoringSubjectOf } from '@volter/threejs-runtime/adapter/object3d-authoring-subject';
|
|
36
36
|
import { getUserData } from '@volter/threejs-runtime/ecs/user-data';
|
|
@@ -372,7 +372,6 @@ function SourceBody({
|
|
|
372
372
|
readonly provenance: ProjectOutputProvenance | null;
|
|
373
373
|
readonly provenanceLoaded: boolean;
|
|
374
374
|
}) {
|
|
375
|
-
const store = useEditorStore();
|
|
376
375
|
useSyncExternalStore(subscribeToolContributions, getGlobalToolContributions);
|
|
377
376
|
const sourceContribution = provenance
|
|
378
377
|
? getDocumentToolContributions().find(
|
|
@@ -387,7 +386,7 @@ function SourceBody({
|
|
|
387
386
|
type="button"
|
|
388
387
|
variant="ghost"
|
|
389
388
|
size="compact"
|
|
390
|
-
onClick={() => openToolDocument(
|
|
389
|
+
onClick={() => openToolDocument(sourceContribution.id)}
|
|
391
390
|
>
|
|
392
391
|
Open Source
|
|
393
392
|
</Button>
|
|
@@ -647,10 +646,8 @@ const MODEL_SECTION_ORDER = {
|
|
|
647
646
|
splat: CONTRIBUTED_SECTION_ORDER,
|
|
648
647
|
geometry: CONTRIBUTED_SECTION_ORDER + 10,
|
|
649
648
|
rig: CONTRIBUTED_SECTION_ORDER + 20,
|
|
650
|
-
//
|
|
651
|
-
//
|
|
652
|
-
// contributed section's order is this same base plus what it declares, so
|
|
653
|
-
// the slot after Rig is held from there.
|
|
649
|
+
// A contributed section's order is this same base plus what it declares, so
|
|
650
|
+
// a package's section after Rig takes a slot in this gap.
|
|
654
651
|
materials: CONTRIBUTED_SECTION_ORDER + 40,
|
|
655
652
|
source: CONTRIBUTED_SECTION_ORDER + 50,
|
|
656
653
|
} as const;
|
|
@@ -770,7 +767,7 @@ function modelDocumentSections(adapter: AuthoringAdapter): InspectionSection[] {
|
|
|
770
767
|
* clicked decides the data, and each block of that data is its own named,
|
|
771
768
|
* glyphed thing. */
|
|
772
769
|
function object3dNodeSections(node: EditorNode | null, adapter: AuthoringAdapter) {
|
|
773
|
-
const object = node ? adapter.hierarchy
|
|
770
|
+
const object = node ? threeObject(adapter.hierarchy, node.id) : null;
|
|
774
771
|
if (!object) return [];
|
|
775
772
|
// A native subject proxy already describes itself through the adapter's
|
|
776
773
|
// ordinary field currency. Treating its visualization mesh as model
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* `constructed outside project source` for EVERY object in the world and the
|
|
11
11
|
* creation-site writer can never fire once. The game's own source still says
|
|
12
12
|
* exactly where each object came from — it says it in JSX
|
|
13
|
-
* (`<mesh position={[0, 1, 0]}>`), and `
|
|
13
|
+
* (`<mesh position={[0, 1, 0]}>`), and `@volter/editor-react`'s `serving/ui-oid-plugin.ts` already stamps
|
|
14
14
|
* that callsite onto the constructed object as `userData.oid`. This backend is
|
|
15
15
|
* the other end of that stamp.
|
|
16
16
|
*
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
|
|
38
38
|
import { reportIngestSourceRefusal } from '../../host/authoring/ingest-source-persistence';
|
|
39
39
|
import type { SourcePersistenceBackend } from '../../host/authoring/source-persistence-backend';
|
|
40
|
-
import { LIVE_ONLY_DESTINATION } from '@volter/editor-
|
|
41
|
-
import type { ChannelValue } from '@volter/editor-
|
|
42
|
-
import { channelFor } from '@volter/editor-
|
|
43
|
-
import { editorConsole } from '@volter/editor-
|
|
44
|
-
import { editorIsAuthoring } from '@volter/editor-
|
|
45
|
-
import type { HistoryService } from '@volter/editor-
|
|
46
|
-
import { withProjectSourceHistory } from '@volter/editor-
|
|
47
|
-
import { getCurrentProject } from '@volter/editor-
|
|
48
|
-
import type { OidEntry } from '@volter/editor-
|
|
49
|
-
import { bodyPlacedChannel, physicsRefusal } from '@volter/editor-
|
|
50
|
-
import type { SourceWriteBackend } from '@volter/editor-
|
|
51
|
-
import { sourceWriteBackendIfPrimed } from '@volter/editor-
|
|
40
|
+
import { LIVE_ONLY_DESTINATION } from '@volter/editor-sdk/kit/write-pipe';
|
|
41
|
+
import type { ChannelValue } from '@volter/editor-sdk/kit/creation-site-edit';
|
|
42
|
+
import { channelFor } from '@volter/editor-sdk/kit/creation-site-edit';
|
|
43
|
+
import { editorConsole } from '@volter/editor-sdk/kit/editor-console';
|
|
44
|
+
import { editorIsAuthoring } from '@volter/editor-sdk/kit/editor-session-mode';
|
|
45
|
+
import type { HistoryService } from '@volter/editor-sdk/kit/history/history-service';
|
|
46
|
+
import { withProjectSourceHistory } from '@volter/editor-sdk/kit/history/source-history-backend';
|
|
47
|
+
import { getCurrentProject } from '@volter/editor-sdk/kit/active-project';
|
|
48
|
+
import type { OidEntry } from '@volter/editor-react/source/oid-transform';
|
|
49
|
+
import { bodyPlacedChannel, physicsRefusal } from '@volter/editor-react/source/r3f-physics-binding';
|
|
50
|
+
import type { SourceWriteBackend } from '@volter/editor-sdk/kit/ui-source/source-write-backend';
|
|
51
|
+
import { sourceWriteBackendIfPrimed } from '@volter/editor-sdk/kit/ui-source/tier-source-write-backend';
|
|
52
52
|
import type { NodeCreationSite, WriteAck } from '@volter/editor-project/adapter';
|
|
53
53
|
|
|
54
54
|
/** What `AuthoringAdapter.persistence.destination` reports once this backend is
|