@vgai/engine 0.5.16 → 0.5.18
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/dist/adapter/adapter-module.d.ts +1 -16
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +1 -11
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts +0 -2
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.js +3 -6
- package/dist/adapter/renderer-config.d.ts +83 -0
- package/dist/adapter/renderer-config.d.ts.map +1 -0
- package/dist/adapter/renderer-config.js +121 -0
- package/dist/adapter/root-adapter.d.ts +6 -2
- package/dist/adapter/root-adapter.d.ts.map +1 -1
- package/dist/adapter/root-seam-contract.d.ts +5 -0
- package/dist/adapter/root-seam-contract.d.ts.map +1 -1
- package/dist/adapter/root-seam-contract.js +1 -0
- package/dist/adapter/setup-three-root-adapter.js +9 -9
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-adapter.js +92 -41
- package/dist/data/curve.d.ts +1 -1
- package/dist/data/curve.js +2 -2
- package/dist/dev/instruments.d.ts +4 -4
- package/dist/dev/instruments.js +4 -4
- package/dist/dev/register-render-vitals.d.ts +2 -2
- package/dist/dev/register-render-vitals.js +2 -2
- package/dist/dev/static-batch-advisor.d.ts +1 -1
- package/dist/dev/static-batch-advisor.js +2 -2
- package/dist/input/input-manager.d.ts +15 -0
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +22 -0
- package/dist/manifest/load.d.ts +0 -3
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +0 -4
- package/dist/manifest/schema.d.ts +0 -2
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +3 -24
- package/dist/pixi/authoring.d.ts +33 -0
- package/dist/pixi/authoring.d.ts.map +1 -1
- package/dist/pixi/authoring.js +86 -6
- package/dist/react/world-state.d.ts +12 -0
- package/dist/react/world-state.d.ts.map +1 -1
- package/dist/react/world-state.js +14 -0
- package/dist/render/soft-particle-depth.d.ts +3 -3
- package/dist/render/soft-particle-depth.d.ts.map +1 -1
- package/dist/render/soft-particle-depth.js +8 -13
- package/dist/runtime/create-runtime.d.ts +2 -16
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +36 -38
- package/dist/runtime/dev-build.d.ts +37 -0
- package/dist/runtime/dev-build.d.ts.map +1 -0
- package/dist/runtime/dev-build.js +49 -0
- package/dist/runtime/game.d.ts +9 -1
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +25 -1
- package/dist/runtime/mount-manifest.d.ts +0 -13
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +2 -21
- package/dist/world3d-react/engine-bridge.d.ts.map +1 -1
- package/dist/world3d-react/engine-bridge.js +28 -3
- package/dist/world3d-react/index.d.ts +2 -2
- package/dist/world3d-react/index.d.ts.map +1 -1
- package/dist/world3d-react/index.js +2 -2
- package/dist/world3d-react/r3f-adapter.d.ts +2 -2
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
- package/dist/world3d-react/r3f-adapter.js +90 -15
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +12 -2
- package/dist/world3d-react/rapier-physics-bridge.d.ts +4 -4
- package/dist/world3d-react/rapier-physics-bridge.js +3 -3
- package/dist/world3d-react/renderer-config.d.ts +7 -69
- package/dist/world3d-react/renderer-config.d.ts.map +1 -1
- package/dist/world3d-react/renderer-config.js +7 -108
- package/dist/world3d-react/world-context.d.ts +43 -0
- package/dist/world3d-react/world-context.d.ts.map +1 -1
- package/dist/world3d-react/world-context.js +89 -46
- package/dist-config/config.js.map +1 -1
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +3 -3
- package/schemas/vgai-project.schema.json +2 -7
- package/src/adapter/adapter-module.ts +1 -25
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +3 -8
- package/src/adapter/renderer-config.ts +178 -0
- package/src/adapter/root-adapter.ts +6 -2
- package/src/adapter/root-seam-contract.ts +1 -0
- package/src/adapter/setup-three-root-adapter.ts +9 -9
- package/src/canvas-react/pixi-react-adapter.tsx +98 -53
- package/src/data/curve.ts +2 -2
- package/src/dev/instruments.ts +4 -4
- package/src/dev/register-render-vitals.ts +2 -2
- package/src/dev/static-batch-advisor.ts +2 -2
- package/src/input/input-manager.ts +23 -0
- package/src/manifest/load.ts +0 -7
- package/src/manifest/schema.ts +3 -26
- package/src/pixi/authoring.ts +98 -6
- package/src/react/world-state.tsx +15 -0
- package/src/render/soft-particle-depth.ts +8 -13
- package/src/runtime/create-runtime.ts +38 -52
- package/src/runtime/dev-build.ts +49 -0
- package/src/runtime/game.ts +31 -2
- package/src/runtime/mount-manifest.ts +2 -33
- package/src/world3d-react/engine-bridge.ts +28 -3
- package/src/world3d-react/index.ts +5 -5
- package/src/world3d-react/r3f-adapter.tsx +89 -20
- package/src/world3d-react/r3f-root-factory.tsx +12 -2
- package/src/world3d-react/rapier-physics-bridge.tsx +4 -4
- package/src/world3d-react/renderer-config.ts +7 -164
- package/src/world3d-react/world-context.ts +100 -51
- package/dist/runtime/dev-layers.d.ts +0 -34
- package/dist/runtime/dev-layers.d.ts.map +0 -1
- package/dist/runtime/dev-layers.js +0 -46
- package/src/runtime/dev-layers.ts +0 -46
|
@@ -30,7 +30,6 @@ import { loadGameManifest, } from '../manifest/load';
|
|
|
30
30
|
import { createGameRuntime } from './create-runtime';
|
|
31
31
|
import { maybeInstallDebugBridge } from './debug-bridge';
|
|
32
32
|
import { getDebugRegistry } from './debug-registry';
|
|
33
|
-
import { devLayersEnabled } from './dev-layers';
|
|
34
33
|
import { getGameplayRngTrapControl } from './gameplay-rng-trap';
|
|
35
34
|
import { RENDER_SEED_QUERY_PARAM } from './render-seed';
|
|
36
35
|
/**
|
|
@@ -167,7 +166,6 @@ function buildRootMountSpec(world, entry) {
|
|
|
167
166
|
id: world.id,
|
|
168
167
|
zOrder: world.zOrder,
|
|
169
168
|
pausable: world.pausable,
|
|
170
|
-
dev: world.dev,
|
|
171
169
|
};
|
|
172
170
|
// `entry`'s `kind` is guaranteed to agree with `world.kind` past the guard
|
|
173
171
|
// above (or `entry` is `undefined`) — TS can't narrow a `Record` lookup
|
|
@@ -208,10 +206,6 @@ function buildRootMountSpec(world, entry) {
|
|
|
208
206
|
* ingest }` adapter with no caller-supplied adapter, or an empty manifest all
|
|
209
207
|
* throw a named `Error` identifying the world id, its kind, and what was
|
|
210
208
|
* expected — never a silent skip or a partially-mounted session.
|
|
211
|
-
*
|
|
212
|
-
* The ONE root that IS skipped silently is a `dev: true` dev layer when dev
|
|
213
|
-
* layers are disabled (`devLayersEnabled`) — that skip is the feature: it is
|
|
214
|
-
* what makes a dev GUI safe to leave in the game.
|
|
215
209
|
*/
|
|
216
210
|
export async function mountManifestRoots(opts) {
|
|
217
211
|
const manifest = resolveManifest(opts.manifest);
|
|
@@ -219,20 +213,7 @@ export async function mountManifestRoots(opts) {
|
|
|
219
213
|
throw new Error('mountManifestRoots: manifest declares no roots — nothing to mount.');
|
|
220
214
|
}
|
|
221
215
|
const entries = opts.entries ?? {};
|
|
222
|
-
|
|
223
|
-
// only when dev layers are enabled, so a production build carries no dev
|
|
224
|
-
// GUI. The answer comes from `devLayersEnabled` and nowhere else — see that
|
|
225
|
-
// function's header for why there is exactly one owner. Dropping the root
|
|
226
|
-
// here (rather than mounting it hidden) is deliberate: nothing of the dev
|
|
227
|
-
// layer is constructed, so its entry module's cost and its DOM never exist
|
|
228
|
-
// in a shipped build.
|
|
229
|
-
const devEnabled = devLayersEnabled(opts.devLayers);
|
|
230
|
-
const mountable = devEnabled ? manifest.roots : manifest.roots.filter((world) => !world.dev);
|
|
231
|
-
if (mountable.length === 0) {
|
|
232
|
-
throw new Error('mountManifestRoots: every root in this manifest is a dev layer (`dev: true`) and dev ' +
|
|
233
|
-
'layers are disabled for this build — there is no game to mount.');
|
|
234
|
-
}
|
|
235
|
-
const roots = mountable.map((world) => buildRootMountSpec(world, entries[world.id]));
|
|
216
|
+
const roots = manifest.roots.map((world) => buildRootMountSpec(world, entries[world.id]));
|
|
236
217
|
// D15 (T-D15.1) — resolved BEFORE `createGameRuntime` (which constructs the
|
|
237
218
|
// Game, and therefore `ctx.random`, before any world's `mount()`/`setup()`
|
|
238
219
|
// runs — see `createGame`'s own doc comment): the seed must be baked in at
|
|
@@ -253,7 +234,7 @@ export async function mountManifestRoots(opts) {
|
|
|
253
234
|
headless: opts.headless,
|
|
254
235
|
// `rendering.antialias` reaches the WebGL context at CONSTRUCTION and can be honoured
|
|
255
236
|
// nowhere else — see the manifest schema's own `rendering` block and
|
|
256
|
-
// `
|
|
237
|
+
// `adapter/renderer-config.ts`'s header for why it is not a world-level declaration.
|
|
257
238
|
...(manifest.rendering === undefined ? {} : { antialias: manifest.rendering.antialias }),
|
|
258
239
|
seed: resolvedSeed,
|
|
259
240
|
playtest: opts.playtest,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/engine-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;
|
|
1
|
+
{"version":3,"file":"engine-bridge.d.ts","sourceRoot":"","sources":["../../src/world3d-react/engine-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC;;wCAEoC;IACpC,QAAQ,CAAC,GAAG,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;CAC3C;AAED,eAAO,MAAM,YAAY,mDAAgD,CAAC;AAE1E;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,IAAI,cAAc,CAkC/C"}
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
* component reaches engine services.
|
|
15
15
|
*/
|
|
16
16
|
import { createContext, useContext } from 'react';
|
|
17
|
+
import { useOptionalGame } from '../react/world-state';
|
|
17
18
|
export const EngineBridge = createContext(null);
|
|
18
19
|
/**
|
|
19
20
|
* This R3F root's context, for use inside any component in the tree — an
|
|
@@ -39,10 +40,34 @@ export const EngineBridge = createContext(null);
|
|
|
39
40
|
*/
|
|
40
41
|
export function useGameContext() {
|
|
41
42
|
const bridge = useContext(EngineBridge);
|
|
43
|
+
// Read unconditionally (rules of hooks) — used only to shape the throw below.
|
|
44
|
+
const hostedByGame = useOptionalGame() !== null;
|
|
42
45
|
if (!bridge?.ctx) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
// NAME THE REAL CAUSE. This throw used to say "check that the component is
|
|
47
|
+
// rendered inside your world entry" — advice a scaffolded game has already
|
|
48
|
+
// followed, because the shape `vgai create` produces (`export default
|
|
49
|
+
// function World()`) mounts as a COMPONENT ROOT and receives no vgai
|
|
50
|
+
// runtime context at all: `r3f-root-factory.tsx` passes
|
|
51
|
+
// `engineRuntime: false` deliberately, so this hook can never resolve
|
|
52
|
+
// there however the component is nested. A world whose first render calls
|
|
53
|
+
// it dies with "fiber crashed before its first commit" and a fix
|
|
54
|
+
// instruction that cannot work. The `Game` in scope tells the two cases
|
|
55
|
+
// apart: present means a vgai-mounted world, absent means no root at all.
|
|
56
|
+
throw new Error(hostedByGame
|
|
57
|
+
? 'useGameContext(): this world mounts as a COMPONENT ROOT (the default-exported ' +
|
|
58
|
+
'shape `vgai create` scaffolds) and receives no vgai runtime context — by design, ' +
|
|
59
|
+
'so nesting cannot fix it. Game-scoped services are on the Game handle instead: ' +
|
|
60
|
+
'`useGame().input` (from @vgai/engine/react/world-state) is the game-owned ' +
|
|
61
|
+
"InputManager the host already loaded this project's input map into and the same " +
|
|
62
|
+
'one `game.input.hold/tap` drives; `useDebugProvider`/`useDebugCommand`/' +
|
|
63
|
+
'`useWorldState` are the state/command doors. If this world genuinely needs the ' +
|
|
64
|
+
'imperative runtime (`ctx.systems`, adapter options like `inputMapPath`), export ' +
|
|
65
|
+
'`adapter = createR3FAdapter({ id, content: <World/> })` from the entry instead of ' +
|
|
66
|
+
'default-exporting the component.'
|
|
67
|
+
: 'useGameContext(): no engine root context and no Game in scope — this component is ' +
|
|
68
|
+
'rendering outside any mounted vgai root (a standalone <Canvas>, a story, or a ' +
|
|
69
|
+
"bare test render). Mount it through your project's three root, or read services " +
|
|
70
|
+
'the component root way (native hooks and project-owned state).');
|
|
46
71
|
}
|
|
47
72
|
return bridge.ctx;
|
|
48
73
|
}
|
|
@@ -33,15 +33,15 @@
|
|
|
33
33
|
* Deliberately NOT re-exported here: `<RapierPhysicsBridge>`
|
|
34
34
|
* (`@engine/world3d-react/rapier-physics-bridge`), which registers an R3F
|
|
35
35
|
* world's `@react-three/rapier` physics as the game's
|
|
36
|
-
* `SystemAdapters.physics` — so the
|
|
36
|
+
* `SystemAdapters.physics` — so the colliders instrument and the
|
|
37
37
|
* editor's transform coordination can see it. It imports
|
|
38
38
|
* `@react-three/rapier`, and only a world that already depends on that library
|
|
39
39
|
* should pull it into its graph; a deep import keeps this barrel's peer
|
|
40
40
|
* contract to `react`/`@react-three/fiber`/`three` alone.
|
|
41
41
|
*/
|
|
42
|
+
export { applyWorldRendererConfig, type WorldOutputColorSpace, type WorldRendererConfig, type WorldToneMapping, } from '../adapter/renderer-config';
|
|
42
43
|
export { EngineBridge, type EngineBridgeValue, useGameContext } from './engine-bridge';
|
|
43
44
|
export { type CreateR3FAdapterOptions, createR3FAdapter } from './r3f-adapter';
|
|
44
45
|
export { r3fRootFactory, resolveR3FEntryAdapter } from './r3f-root-factory';
|
|
45
|
-
export { applyWorldRendererConfig, type WorldOutputColorSpace, type WorldRendererConfig, type WorldToneMapping, } from './renderer-config';
|
|
46
46
|
export { createR3FRootContext, DEFAULT_INPUT_MAP_PATH, type R3FGameContext, type R3FRootContextOptions, type R3FRootRuntime, } from './world-context';
|
|
47
47
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world3d-react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,KAAK,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/world3d-react/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EACL,wBAAwB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,GACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,KAAK,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,iBAAiB,CAAC"}
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
* Deliberately NOT re-exported here: `<RapierPhysicsBridge>`
|
|
34
34
|
* (`@engine/world3d-react/rapier-physics-bridge`), which registers an R3F
|
|
35
35
|
* world's `@react-three/rapier` physics as the game's
|
|
36
|
-
* `SystemAdapters.physics` — so the
|
|
36
|
+
* `SystemAdapters.physics` — so the colliders instrument and the
|
|
37
37
|
* editor's transform coordination can see it. It imports
|
|
38
38
|
* `@react-three/rapier`, and only a world that already depends on that library
|
|
39
39
|
* should pull it into its graph; a deep import keeps this barrel's peer
|
|
40
40
|
* contract to `react`/`@react-three/fiber`/`three` alone.
|
|
41
41
|
*/
|
|
42
|
+
export { applyWorldRendererConfig, } from '../adapter/renderer-config';
|
|
42
43
|
export { EngineBridge, useGameContext } from './engine-bridge';
|
|
43
44
|
export { createR3FAdapter } from './r3f-adapter';
|
|
44
45
|
export { r3fRootFactory, resolveR3FEntryAdapter } from './r3f-root-factory';
|
|
45
|
-
export { applyWorldRendererConfig, } from './renderer-config';
|
|
46
46
|
export { createR3FRootContext, DEFAULT_INPUT_MAP_PATH, } from './world-context';
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { type ReactNode } from 'react';
|
|
22
22
|
import type { RootAdapter } from '../adapter';
|
|
23
|
-
import { type WorldRendererConfig } from '
|
|
23
|
+
import { type WorldRendererConfig } from '../adapter/renderer-config';
|
|
24
24
|
/** What {@link createR3FAdapter} needs to build one `RootAdapter`. */
|
|
25
25
|
export interface CreateR3FAdapterOptions {
|
|
26
26
|
/** Stable id (telemetry/registry/conformance) — `RootAdapter.id`. */
|
|
@@ -45,7 +45,7 @@ export interface CreateR3FAdapterOptions {
|
|
|
45
45
|
/** The colour pipeline this world was AUTHORED for, applied to the host's renderer for the life
|
|
46
46
|
* of the mount and restored on dispose. Omit it (every world here does) to keep the host's own
|
|
47
47
|
* defaults; declare it when the world's colours were picked against a different engine's
|
|
48
|
-
* pipeline — see
|
|
48
|
+
* pipeline — see `../adapter/renderer-config.ts`. */
|
|
49
49
|
readonly renderer?: WorldRendererConfig | undefined;
|
|
50
50
|
}
|
|
51
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r3f-adapter.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-adapter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,OAAO,EAA2B,KAAK,SAAS,EAAsB,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAoB,WAAW,EAAoB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"r3f-adapter.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-adapter.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,OAAO,EAA2B,KAAK,SAAS,EAAsB,MAAM,OAAO,CAAC;AACpF,OAAO,KAAK,EAAoB,WAAW,EAAoB,MAAM,YAAY,CAAC;AAClF,OAAO,EAA4B,KAAK,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AA+DhG,sEAAsE;AACtE,MAAM,WAAW,uBAAuB;IACtC,qEAAqE;IACrE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB;;uBAEmB;IACnB,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC;IAC5B;;;;0CAIsC;IACtC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAClD;;;;;OAKG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C;;;0DAGsD;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,SAAS,CAAC;CACrD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,WAAW,CA2kB9E"}
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
*/
|
|
21
21
|
import { advance, createRoot, extend, flushSync, events as pointerEvents, useFrame, } from '@react-three/fiber';
|
|
22
22
|
import { createElement, Fragment, useEffect, useMemo } from 'react';
|
|
23
|
+
import { applyWorldRendererConfig } from '../adapter/renderer-config';
|
|
23
24
|
import { registerRenderVitals } from '../dev/register-render-vitals';
|
|
24
25
|
import { createRenderDebugAdapter, frameCaptureContextFor, } from '../dev/render-debug-adapter';
|
|
25
26
|
import { collectRenderMemory } from '../dev/render-memory';
|
|
@@ -28,10 +29,9 @@ import { createWebGLFrameCapture } from '../dev/webgl-frame-capture';
|
|
|
28
29
|
import { WorldProvider } from '../react/world-state';
|
|
29
30
|
import { createSoftParticleDepthPass } from '../render/soft-particle-depth';
|
|
30
31
|
import { getDebugRegistry } from '../runtime/debug-registry';
|
|
31
|
-
import {
|
|
32
|
+
import { devBuildEnabled } from '../runtime/dev-build';
|
|
32
33
|
import { EngineBridge } from './engine-bridge';
|
|
33
|
-
import {
|
|
34
|
-
import { createR3FRootContext } from './world-context';
|
|
34
|
+
import { createR3FRootContext, DEFAULT_INPUT_MAP_PATH, wireGameInputSeams } from './world-context';
|
|
35
35
|
/**
|
|
36
36
|
* Scene depth for any soft-particle system this world mounted, drawn between
|
|
37
37
|
* gameplay and the draw.
|
|
@@ -52,6 +52,11 @@ import { createR3FRootContext } from './world-context';
|
|
|
52
52
|
* sort is stable) — the tie-break among priority-0 callbacks is insertion
|
|
53
53
|
* order.
|
|
54
54
|
*
|
|
55
|
+
* It is mounted only when THIS host carries a real WebGL context. The editor's
|
|
56
|
+
* design-time host deliberately reconciles the scene without one because the
|
|
57
|
+
* editor viewport owns the real renderer and camera; that viewport runs the
|
|
58
|
+
* same generic depth pass immediately before it presents the adopted scene.
|
|
59
|
+
*
|
|
55
60
|
* Costs nothing while no soft-particle system is armed — see
|
|
56
61
|
* `../render/soft-particle-depth.ts` for what "armed" means and what the pass
|
|
57
62
|
* spends when it is.
|
|
@@ -127,10 +132,32 @@ export function createR3FAdapter(options) {
|
|
|
127
132
|
// `ctx` rides the bridge so ordinary components can reach engine
|
|
128
133
|
// services through `useGameContext()`.
|
|
129
134
|
const bridge = runtime ? { ctx: runtime.ctx } : null;
|
|
135
|
+
const gameDebugRegistry = host.game ? getDebugRegistry(host.game) : null;
|
|
136
|
+
// THE HOST STILL WIRES THIS GAME'S INPUT WHEN THE WORLD TAKES NO CONTEXT.
|
|
137
|
+
//
|
|
138
|
+
// A default-exported world mounts with `engineRuntime: false` — no vgai
|
|
139
|
+
// runtime context enters its React tree, by design. That says nothing
|
|
140
|
+
// about the GAME-scoped input the host owns from the outside: the
|
|
141
|
+
// project's declared map, and this root's `game.input.*` seams on the
|
|
142
|
+
// debug registry. Skipping those made a fresh scaffold's bot/autoplay/
|
|
143
|
+
// `vgai eval` input doors throw `DEBUG_INPUT_UNAVAILABLE` and left the
|
|
144
|
+
// declared actions unloaded — in the ONE world shape `vgai create`
|
|
145
|
+
// produces. Same host-vs-context split as `WorldProvider` below.
|
|
146
|
+
//
|
|
147
|
+
// `inputMapPath` unset (what the default-export factory passes) means
|
|
148
|
+
// "the conventional path, if this project ships one" — quiet when it
|
|
149
|
+
// does not, since a brand-new project declares no actions yet.
|
|
150
|
+
const hostInputReady = runtime || !gameDebugRegistry
|
|
151
|
+
? null
|
|
152
|
+
: wireGameInputSeams(host, gameDebugRegistry, {
|
|
153
|
+
id,
|
|
154
|
+
inputMapPath: inputMapPath ?? DEFAULT_INPUT_MAP_PATH,
|
|
155
|
+
optionalInputMap: inputMapPath === undefined,
|
|
156
|
+
});
|
|
130
157
|
// Actions must exist before any component's init()/first frame reads
|
|
131
158
|
// them — wait for the (never-rejecting) input-map load before the first
|
|
132
159
|
// commit.
|
|
133
|
-
await runtime?.inputMapReady;
|
|
160
|
+
await (runtime?.inputMapReady ?? hostInputReady);
|
|
134
161
|
// The world's own colour pipeline. Applied AFTER `root.configure()` below — see the comment
|
|
135
162
|
// at its call site for why "before" is the version that silently does nothing.
|
|
136
163
|
let restoreRendererConfig = () => { };
|
|
@@ -257,13 +284,37 @@ export function createR3FAdapter(options) {
|
|
|
257
284
|
// until this landed. `host.game` is genuinely absent in bare/headless
|
|
258
285
|
// hosts, so the provider is conditional and those hooks stay the inert
|
|
259
286
|
// no-ops they already document themselves to be.
|
|
260
|
-
|
|
287
|
+
//
|
|
288
|
+
// READ FROM `host.game`, NEVER FROM `runtime` — the two are not the same
|
|
289
|
+
// question, and conflating them silently dark-ended the seam for every
|
|
290
|
+
// scaffolded game. The IDIOMATIC three world (`export default function
|
|
291
|
+
// World()`) mounts through `resolveR3FEntryAdapter` with
|
|
292
|
+
// `engineRuntime: false` (`r3f-root-factory.tsx`), so it has no
|
|
293
|
+
// `runtime` and no `bridge` — by design, because the vgai runtime
|
|
294
|
+
// CONTEXT (`useGameContext`) must not enter an ecosystem-native tree.
|
|
295
|
+
// `WorldProvider` is not that context: it carries the Game handle the
|
|
296
|
+
// host already holds, and it is the only way a game's own
|
|
297
|
+
// `useDebugProvider('stat', …)` can reach the ONE game-scoped registry
|
|
298
|
+
// the editor/`vgai eval` read. Keyed off `runtime`, every
|
|
299
|
+
// default-exported world's registrations no-opped in silence and
|
|
300
|
+
// `vgai eval 'await game.providers()'` listed only the built-ins.
|
|
301
|
+
// The canvas lane never had the gap (`canvas-react/
|
|
302
|
+
// pixi-react-root-factory.tsx` keeps its entry runtime on).
|
|
303
|
+
const game = host.game;
|
|
261
304
|
// `SoftParticleDepth` trails the world's own tree deliberately — see its
|
|
262
|
-
// docblock for why the subscription must land last.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
:
|
|
305
|
+
// docblock for why the subscription must land last. A no-context design
|
|
306
|
+
// mount omits this fiber callback because the adopting editor viewport
|
|
307
|
+
// runs the pass with its own renderer and camera instead.
|
|
308
|
+
const world = createElement(Fragment, null, content, runtime && typeof host.renderer.getContext === 'function'
|
|
309
|
+
? createElement(SoftParticleDepth, { key: 'vgai-soft-particle-depth' })
|
|
310
|
+
: null, createElement(MountEffectsReady, { key: 'vgai-mount-effects-ready' }));
|
|
311
|
+
// The two providers are INDEPENDENT: `EngineBridge` rides `bridge` (the
|
|
312
|
+
// vgai runtime context, absent for a native default-exported world),
|
|
313
|
+
// `WorldProvider` rides `host.game` (the React seam, present whenever a
|
|
314
|
+
// Game hosts this world). Nesting the second inside the first is what
|
|
315
|
+
// made the seam a hostage of the first.
|
|
316
|
+
const provided = game ? createElement(WorldProvider, { game }, world) : world;
|
|
317
|
+
root.render(bridge ? createElement(EngineBridge.Provider, { value: bridge }, provided) : provided);
|
|
267
318
|
// A reconcile-time crash (e.g. a missing `extend` catalogue entry)
|
|
268
319
|
// surfaces as an uncaught window error and `onCreated` never fires —
|
|
269
320
|
// without this guard, `mount()` would await `statePromise` FOREVER and
|
|
@@ -274,6 +325,8 @@ export function createR3FAdapter(options) {
|
|
|
274
325
|
cleanup();
|
|
275
326
|
root.unmount();
|
|
276
327
|
runtime?.dispose();
|
|
328
|
+
if (!runtime)
|
|
329
|
+
gameDebugRegistry?.strip(id);
|
|
277
330
|
restoreRendererConfig();
|
|
278
331
|
reject(new Error(`r3f-adapter: fiber crashed before its first commit — ${event.message} ` +
|
|
279
332
|
'(mount() fails loudly instead of hanging on onCreated)'));
|
|
@@ -282,6 +335,8 @@ export function createR3FAdapter(options) {
|
|
|
282
335
|
cleanup();
|
|
283
336
|
root.unmount();
|
|
284
337
|
runtime?.dispose();
|
|
338
|
+
if (!runtime)
|
|
339
|
+
gameDebugRegistry?.strip(id);
|
|
285
340
|
restoreRendererConfig();
|
|
286
341
|
reject(new Error('r3f-adapter: onCreated did not fire within 10s — the R3F tree never reached ' +
|
|
287
342
|
'its first commit (mount() fails loudly instead of hanging)'));
|
|
@@ -334,7 +389,6 @@ export function createR3FAdapter(options) {
|
|
|
334
389
|
// `RootState` for precisely this reason, so reading it per frame is the
|
|
335
390
|
// supported way to see the live root. It is a plain map read.
|
|
336
391
|
const live = () => state.get();
|
|
337
|
-
const gameDebugRegistry = host.game ? getDebugRegistry(host.game) : null;
|
|
338
392
|
// --- Live render vitals (issue #1504), for an R3F world -----------------
|
|
339
393
|
// The SAME door the classic adapter seeds
|
|
340
394
|
// (`../adapter/setup-three-root-adapter.ts`), seeded here for the same
|
|
@@ -345,11 +399,11 @@ export function createR3FAdapter(options) {
|
|
|
345
399
|
// world is the only shape a scaffolded project's three root has, so a
|
|
346
400
|
// door wired only into the classic path is a door no scaffolded project
|
|
347
401
|
// ever gets (issue #1518: `game.state('render.vitals')` answered "no
|
|
348
|
-
// state provider registered" in the field while every other
|
|
349
|
-
// the same world worked).
|
|
402
|
+
// state provider registered" in the field while every other debug
|
|
403
|
+
// reading of the same world worked).
|
|
350
404
|
//
|
|
351
405
|
// The gate is the same three conditions, minus the one that cannot
|
|
352
|
-
// arise: `
|
|
406
|
+
// arise: `devBuildEnabled()` (`../runtime/dev-build.ts`, the ONE owner
|
|
353
407
|
// of "is this a dev context" — a ship build registers nothing and pays
|
|
354
408
|
// nothing), and a `Game` shell (the readings are folded out of that
|
|
355
409
|
// game's profiler frames). "Not headless" needs no term here: a headless
|
|
@@ -367,7 +421,7 @@ export function createR3FAdapter(options) {
|
|
|
367
421
|
// (the fold) and `runtime.dispose()`'s scoped `strip(id)` (the
|
|
368
422
|
// registrations) — the same split the classic adapter documents.
|
|
369
423
|
let renderVitals = null;
|
|
370
|
-
if (host.game &&
|
|
424
|
+
if (host.game && devBuildEnabled()) {
|
|
371
425
|
// Same auto-enable as the classic adapter: the readings are folded out
|
|
372
426
|
// of profiler frames, and the profiler is a flag the editor already
|
|
373
427
|
// sets on play — under the dev gate this is the same cost arriving a
|
|
@@ -551,6 +605,27 @@ export function createR3FAdapter(options) {
|
|
|
551
605
|
renderVitals?.dispose();
|
|
552
606
|
renderVitals = null;
|
|
553
607
|
runtime?.dispose();
|
|
608
|
+
// The no-context path has no `runtime.dispose()` to carry its scoped
|
|
609
|
+
// strip, so it ends its own registrations here — the same
|
|
610
|
+
// `strip(id)`, at the same moment. That is what ends this world's
|
|
611
|
+
// PROVIDERS AND COMMANDS (the render-vitals door above is the one
|
|
612
|
+
// this path actually registers under `id`); sibling roots are
|
|
613
|
+
// untouched.
|
|
614
|
+
//
|
|
615
|
+
// It does NOT end the input seams `wireGameInputSeams` set, and
|
|
616
|
+
// nothing else does either: `strip` walks providers/commands only
|
|
617
|
+
// (`runtime/debug-registry.ts`), so `virtualInputTargets`/
|
|
618
|
+
// `inputActionsSources`/`inputTraceSources` keep this world's id
|
|
619
|
+
// until a remount of the same id overwrites it. The runtime path has
|
|
620
|
+
// always been identical, and the residue is inert rather than
|
|
621
|
+
// hidden: every one of those closures reads GAME-scoped state
|
|
622
|
+
// (`game.input`, `game.loop.fixedDt`, the game's seed), so a stale
|
|
623
|
+
// entry actuates exactly what a live one would. What it can still do
|
|
624
|
+
// is name a dead world in `DEBUG_INPUT_WORLD_NOT_FOUND`'s registered
|
|
625
|
+
// list. Do not write "the strip clears the input seams" here again
|
|
626
|
+
// without changing `strip` to actually do it.
|
|
627
|
+
if (!runtime)
|
|
628
|
+
gameDebugRegistry?.strip(id);
|
|
554
629
|
restoreRendererConfig();
|
|
555
630
|
},
|
|
556
631
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"r3f-root-factory.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-root-factory.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAUnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"r3f-root-factory.d.ts","sourceRoot":"","sources":["../../src/world3d-react/r3f-root-factory.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAUnE;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAwB/F;AAED;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE,qBAQ5B,CAAC"}
|
|
@@ -60,8 +60,18 @@ export function resolveR3FEntryAdapter(entryModule, rootId) {
|
|
|
60
60
|
id: rootId,
|
|
61
61
|
content: createElement(mod.default),
|
|
62
62
|
// A default-exported R3F component is an ordinary R3F app. The host
|
|
63
|
-
// controls Fiber's native `frameloop: 'never'` scheduler; vgai
|
|
64
|
-
//
|
|
63
|
+
// controls Fiber's native `frameloop: 'never'` scheduler; the vgai
|
|
64
|
+
// runtime CONTEXT (`useGameContext`, `ctx.systems`) never enters its
|
|
65
|
+
// React tree.
|
|
66
|
+
//
|
|
67
|
+
// This flag governs that context and nothing else. It does NOT govern
|
|
68
|
+
// `WorldProvider`: `useDebugProvider`/`useDebugCommand`/`useWorldState`
|
|
69
|
+
// are the documented door a game declares its own state/commands
|
|
70
|
+
// through, and they must work in the idiomatic shape — which is the
|
|
71
|
+
// ONLY shape `vgai create` scaffolds. `r3f-adapter.tsx` therefore keys
|
|
72
|
+
// that provider off `host.game`, not off this flag; see the comment
|
|
73
|
+
// beside `const game = host.game` there for the measured symptom
|
|
74
|
+
// (`vgai eval 'await game.providers()'` listing only built-ins).
|
|
65
75
|
engineRuntime: false,
|
|
66
76
|
});
|
|
67
77
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `@react-three/rapier` physics VISIBLE to the engine's editor/dev seams.
|
|
4
4
|
*
|
|
5
5
|
* WHY IT EXISTS. `SystemAdapters.physics` is what the editor's transform
|
|
6
|
-
* coordination (`freeze → apply → unfreeze`) and the
|
|
6
|
+
* coordination (`freeze → apply → unfreeze`) and the universal
|
|
7
7
|
* "Colliders drawn" instrument (`@engine/dev/instruments`) read. The
|
|
8
8
|
* first-party imperative three root registers one from
|
|
9
9
|
* `../adapter/setup-three-root-adapter.ts`; an R3F world builds no first-party
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* on the R3F root it is mounted in. It allocates nothing else — no timers, no
|
|
45
45
|
* subscriptions, no per-frame work (see the phase note below), and no Rapier
|
|
46
46
|
* objects: the bodies it edits belong to `<Physics>`.
|
|
47
|
-
* SHARERS: every reader of `game.systemAdapters.physics` — the
|
|
47
|
+
* SHARERS: every reader of `game.systemAdapters.physics` — the
|
|
48
48
|
* colliders instrument, the editor's transform coordination. They read; they
|
|
49
49
|
* never dispose.
|
|
50
50
|
* TEARDOWN: the effect's cleanup, and nothing else — it clears the SAME key it
|
|
@@ -55,13 +55,13 @@
|
|
|
55
55
|
*
|
|
56
56
|
* PHASE ORDERING: none to respect — this component registers pull-only
|
|
57
57
|
* callbacks and runs no per-frame work. Every method it exposes is invoked
|
|
58
|
-
* BETWEEN frames, by an editor gesture or
|
|
58
|
+
* BETWEEN frames, by an editor gesture or an instrument command, never from a
|
|
59
59
|
* phase.
|
|
60
60
|
*/
|
|
61
61
|
export interface RapierPhysicsBridgeProps {
|
|
62
62
|
/**
|
|
63
63
|
* Set the `debug` prop of the SAME `<Physics>` this bridge is mounted in.
|
|
64
|
-
* The
|
|
64
|
+
* The "Colliders drawn" instrument calls it; the world's own state is
|
|
65
65
|
* what `<Physics debug={…}>` reads, so the library's debug rendering is the
|
|
66
66
|
* only thing that ever draws a collider.
|
|
67
67
|
*/
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `@react-three/rapier` physics VISIBLE to the engine's editor/dev seams.
|
|
4
4
|
*
|
|
5
5
|
* WHY IT EXISTS. `SystemAdapters.physics` is what the editor's transform
|
|
6
|
-
* coordination (`freeze → apply → unfreeze`) and the
|
|
6
|
+
* coordination (`freeze → apply → unfreeze`) and the universal
|
|
7
7
|
* "Colliders drawn" instrument (`@engine/dev/instruments`) read. The
|
|
8
8
|
* first-party imperative three root registers one from
|
|
9
9
|
* `../adapter/setup-three-root-adapter.ts`; an R3F world builds no first-party
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* on the R3F root it is mounted in. It allocates nothing else — no timers, no
|
|
45
45
|
* subscriptions, no per-frame work (see the phase note below), and no Rapier
|
|
46
46
|
* objects: the bodies it edits belong to `<Physics>`.
|
|
47
|
-
* SHARERS: every reader of `game.systemAdapters.physics` — the
|
|
47
|
+
* SHARERS: every reader of `game.systemAdapters.physics` — the
|
|
48
48
|
* colliders instrument, the editor's transform coordination. They read; they
|
|
49
49
|
* never dispose.
|
|
50
50
|
* TEARDOWN: the effect's cleanup, and nothing else — it clears the SAME key it
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
*
|
|
56
56
|
* PHASE ORDERING: none to respect — this component registers pull-only
|
|
57
57
|
* callbacks and runs no per-frame work. Every method it exposes is invoked
|
|
58
|
-
* BETWEEN frames, by an editor gesture or
|
|
58
|
+
* BETWEEN frames, by an editor gesture or an instrument command, never from a
|
|
59
59
|
* phase.
|
|
60
60
|
*/
|
|
61
61
|
import { useRapier } from '@react-three/rapier';
|
|
@@ -1,73 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* world3d-react/renderer-config
|
|
2
|
+
* `@engine/world3d-react/renderer-config` — a published entry point.
|
|
3
3
|
*
|
|
4
|
-
* The
|
|
5
|
-
* engine
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* So a world may DECLARE the pipeline it was authored for, and `createR3FAdapter` applies it to the
|
|
11
|
-
* host's renderer for the life of the mount, restoring what it found on dispose. Three properties
|
|
12
|
-
* of that shape are load-bearing:
|
|
13
|
-
*
|
|
14
|
-
* - **It is per-renderer, never engine-wide.** Every field here is a `WebGLRenderer` instance
|
|
15
|
-
* property, and a play root gets its own renderer (`create-runtime.ts`). Nothing here reaches a
|
|
16
|
-
* module-level three global, so one world's declaration cannot change how the editor's own
|
|
17
|
-
* viewport, another root, or a thumbnail bake renders.
|
|
18
|
-
* - **Absent means "leave the host's value alone".** Every field is optional and an omitted one
|
|
19
|
-
* is never written, so declaring a tone mapping does not silently reset the clear colour.
|
|
20
|
-
* - **It is restored on dispose.** The renderer outlives the mount, so a world that did not put
|
|
21
|
-
* back what it found would leak its pipeline into whatever mounts next.
|
|
22
|
-
*
|
|
23
|
-
* This is deliberately NOT a general render-settings system. It carries what a world can honestly
|
|
24
|
-
* state about its own colour pipeline and nothing else; a property the host fixes at CONSTRUCTION
|
|
25
|
-
* (the WebGL context's `antialias` attribute, and therefore the MSAA sample count) cannot be
|
|
26
|
-
* declared here, because there would be no honest moment to apply it.
|
|
27
|
-
*/
|
|
28
|
-
import type * as THREE from 'three';
|
|
29
|
-
/** The tone-mapping operators three exposes, named as data rather than as three's numeric enum. */
|
|
30
|
-
export type WorldToneMapping = 'none' | 'linear' | 'reinhard' | 'cineon' | 'aces' | 'agx' | 'neutral';
|
|
31
|
-
/**
|
|
32
|
-
* The output transfer function the frame is written with.
|
|
33
|
-
*
|
|
34
|
-
* - `srgb` — three's own default and this engine's: linear lighting, sRGB encode on output.
|
|
35
|
-
* - `srgb-linear` — NO output transform. This is what a gamma-space renderer needs: the shading
|
|
36
|
-
* result is already in display space and encoding it a second time washes the frame out.
|
|
37
|
-
*/
|
|
38
|
-
export type WorldOutputColorSpace = 'srgb' | 'srgb-linear';
|
|
39
|
-
/**
|
|
40
|
-
* The shadow-map filter, named as data rather than as three's numeric enum.
|
|
41
|
-
*
|
|
42
|
-
* This is a renderer INSTANCE property (`WebGLRenderer.shadowMap.type`), not a context attribute,
|
|
43
|
-
* so unlike MSAA it has an honest moment at which a world can ask for it — which is the whole test
|
|
44
|
-
* this file's header states. A source engine that declares its own shadow filter (Godot 3's
|
|
45
|
-
* `rendering/quality/shadows/filter_mode`) would otherwise inherit whatever the host built with.
|
|
46
|
-
*/
|
|
47
|
-
export type WorldShadowMapType = 'basic' | 'pcf' | 'pcf-soft' | 'vsm';
|
|
48
|
-
/** What a world may declare about the renderer that draws it. Every field is optional; see header. */
|
|
49
|
-
export interface WorldRendererConfig {
|
|
50
|
-
readonly toneMapping?: WorldToneMapping | undefined;
|
|
51
|
-
readonly toneMappingExposure?: number | undefined;
|
|
52
|
-
readonly outputColorSpace?: WorldOutputColorSpace | undefined;
|
|
53
|
-
/**
|
|
54
|
-
* `WebGLRenderer.shadowMap.type`. Writing it after a shadow map has already been built needs
|
|
55
|
-
* `shadowMap.needsUpdate`, which this function sets — three caches the compiled depth material
|
|
56
|
-
* per type and would otherwise keep filtering with the previous one.
|
|
57
|
-
*/
|
|
58
|
-
readonly shadowMapType?: WorldShadowMapType | undefined;
|
|
59
|
-
/**
|
|
60
|
-
* The colour the frame is cleared to, as a CSS hex string. The renderer's existing clear ALPHA
|
|
61
|
-
* is preserved: a stacked canvas is transparent on purpose (`create-runtime.ts` gives every
|
|
62
|
-
* non-bottom root `alpha: true`), and forcing it opaque here would hide every layer below.
|
|
63
|
-
*/
|
|
64
|
-
readonly clearColor?: string | undefined;
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Apply `config` to `renderer`, returning the restore function that puts back what was there.
|
|
68
|
-
*
|
|
69
|
-
* `three` is passed in rather than imported for values so the enum constants come from the HOST's
|
|
70
|
-
* three instance — the same identity rule `r3f-adapter.tsx` follows for the scene and camera.
|
|
4
|
+
* The engine package's export map is the wildcard `"./*"`, so every file under
|
|
5
|
+
* `packages/engine/src/` is an entry point a game outside this repo can import by path. The module
|
|
6
|
+
* itself now lives in the adapter seam (`@engine/adapter/renderer-config`, which its header
|
|
7
|
+
* explains), and this file keeps the path that shipped resolving to it. Import the seam path in
|
|
8
|
+
* new code.
|
|
71
9
|
*/
|
|
72
|
-
export
|
|
10
|
+
export * from '../adapter/renderer-config';
|
|
73
11
|
//# sourceMappingURL=renderer-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer-config.d.ts","sourceRoot":"","sources":["../../src/world3d-react/renderer-config.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"renderer-config.d.ts","sourceRoot":"","sources":["../../src/world3d-react/renderer-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,cAAc,4BAA4B,CAAC"}
|