@threenative/core 0.3.2 → 0.3.4
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/capabilities.json +1891 -101
- package/dist/{assets-kyoF7JlJ.d.ts → assets-CqvE429w.d.ts} +52 -3
- package/dist/{audio-BFiGneTL.d.ts → audio-7i3Xl0l3.d.ts} +32 -1
- package/dist/{canvas-layer-BLVijiUJ.d.ts → canvas-layer-DDmC_VVF.d.ts} +1 -1
- package/dist/{game-XGrTzapq.d.ts → game-CljaDv4D.d.ts} +503 -11
- package/dist/{gpu-readback-D2iRvoe9.d.ts → gpu-readback-CqJEfWNQ.d.ts} +16 -6
- package/dist/hot.d.ts +5 -5
- package/dist/hot.js +20 -3
- package/dist/index.d.ts +1496 -43
- package/dist/index.js +8345 -753
- package/dist/playtest.d.ts +11 -5
- package/dist/playtest.js +96 -11
- package/dist/react.d.ts +2 -2
- package/dist/{renderer-C6hqZpoG.d.ts → renderer-CfsS2hxi.d.ts} +436 -14
- package/dist/ui-layer.d.ts +15 -7
- package/dist/ui-layer.js +2 -1
- package/dist/world.d.ts +900 -14
- package/dist/world.js +10876 -126
- package/gpl/fixtures/make_world_fixture.py +184 -0
- package/gpl/recipes/_common.py +11 -0
- package/gpl/recipes/decimate.py +11 -5
- package/gpl/recipes/export_world.py +682 -0
- package/mcp/blender-server.mjs +55 -1
- package/mcp/engine-server.mjs +84 -22
- package/mcp/servers.mjs +3 -3
- package/package.json +6 -6
- package/patches/three@0.185.1.patch +2228 -105
- package/scripts/apply-three-patch.mjs +61 -37
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { I as IAssetLoader, a as IAssetLoaderOptions } from './assets-
|
|
2
|
-
import {
|
|
1
|
+
import { I as IAssetLoader, a as IAssetLoaderOptions } from './assets-CqvE429w.js';
|
|
2
|
+
import { F as FramePassKind, K as IRenderPassSample, n as IFramePhaseSample, o as IPipelineCensus, I as IRendererLike, as as IRendererOptions, a as IFrameBudgetWindow, j as IFrameBudgetOptions } from './renderer-CfsS2hxi.js';
|
|
3
3
|
import { Vector2, Vector3, Object3D, Camera, Intersection, Scene as Scene$1 } from 'three';
|
|
4
|
-
import { V as Viewport, C as CanvasLayer, I as IViewportOptions } from './canvas-layer-
|
|
4
|
+
import { V as Viewport, C as CanvasLayer, I as IViewportOptions } from './canvas-layer-DDmC_VVF.js';
|
|
5
5
|
import { StoreApi } from 'zustand/vanilla';
|
|
6
6
|
|
|
7
7
|
type ThreeNativeOrientation = "landscape" | "portrait" | "sensor";
|
|
@@ -101,6 +101,23 @@ interface IThreeNativeModelPassesConfig {
|
|
|
101
101
|
}
|
|
102
102
|
/** Model optimization options for the asset compile step; `"none"` ships sources verbatim. */
|
|
103
103
|
interface IThreeNativeModelsConfig {
|
|
104
|
+
/**
|
|
105
|
+
* Lossless scene-graph compaction: flatten empty transform chains, join sibling primitives
|
|
106
|
+
* that share a material, and batch a mesh several nodes reuse as `EXT_mesh_gpu_instancing`.
|
|
107
|
+
*
|
|
108
|
+
* On by default; `false` ships the scene graph as authored. A node matching `protectedPattern`,
|
|
109
|
+
* named in `protectedNames`, targeted by an animation or a skin joint is never merged or
|
|
110
|
+
* instanced, so an exact-name lookup or a bone-driven node survives.
|
|
111
|
+
*/
|
|
112
|
+
readonly compact?: boolean | {
|
|
113
|
+
readonly flatten?: boolean;
|
|
114
|
+
readonly instance?: boolean | {
|
|
115
|
+
readonly min?: number;
|
|
116
|
+
};
|
|
117
|
+
readonly join?: boolean;
|
|
118
|
+
readonly protectedNames?: readonly string[];
|
|
119
|
+
readonly protectedPattern?: string;
|
|
120
|
+
};
|
|
104
121
|
/** Standard glTF TEXCOORD_1 atlas generation for offline static-light assets. */
|
|
105
122
|
readonly lightmap?: {
|
|
106
123
|
readonly atlasSize: number;
|
|
@@ -167,6 +184,113 @@ interface IThreeNativeModelsConfig {
|
|
|
167
184
|
readonly simplifyRatio?: number;
|
|
168
185
|
};
|
|
169
186
|
}
|
|
187
|
+
/** Quality policy for automatic discrete LOD; it picks the projected pixel-error budget. */
|
|
188
|
+
type ThreeNativeLodPreset = "aggressive" | "balanced" | "quality";
|
|
189
|
+
/** What the `minTriangles` pre-filter is measured against. */
|
|
190
|
+
type ThreeNativeLodMinTrianglesScope = "primitive" | "asset";
|
|
191
|
+
/** Generation knobs shared by every preset. All are ceilings or filters, not promises. */
|
|
192
|
+
interface IThreeNativeLodGenerationConfig {
|
|
193
|
+
/**
|
|
194
|
+
* Increasing geometric-error targets in normalized mesh-extent units; 1–16 positive finite
|
|
195
|
+
* numbers that strictly increase. Default `[0.002, 0.006, 0.02, 0.06]`. Each is simplified from
|
|
196
|
+
* LOD0 independently and a target that cannot reduce is dropped.
|
|
197
|
+
*/
|
|
198
|
+
readonly errorTargets?: readonly number[];
|
|
199
|
+
/** Levels in the chain **including LOD0**; integer 1–8, default 4. `1` emits nothing derived. */
|
|
200
|
+
readonly maxLevels?: number;
|
|
201
|
+
/**
|
|
202
|
+
* Fraction of its predecessor's triangles a derived level must save to be kept; finite in
|
|
203
|
+
* `[0, 1)`, default `0.2`. This is the benefit gate — a mesh that cannot reach it is skipped
|
|
204
|
+
* with `insufficient-reduction`, which is a normal outcome, not an error.
|
|
205
|
+
*/
|
|
206
|
+
readonly minSaving?: number;
|
|
207
|
+
/**
|
|
208
|
+
* Cheap pre-filter floor in triangles; positive integer, default `128`. It only avoids
|
|
209
|
+
* clearly-pointless work (the simplifier's fixed per-call cost); `minSaving` is the real gate.
|
|
210
|
+
*/
|
|
211
|
+
readonly minTriangles?: number;
|
|
212
|
+
/**
|
|
213
|
+
* What `minTriangles` is measured against; `"primitive"` or `"asset"`, default `"asset"`. The
|
|
214
|
+
* asset scope measures the whole model, so a model split into many small primitives is still
|
|
215
|
+
* eligible on its total.
|
|
216
|
+
*/
|
|
217
|
+
readonly minTrianglesScope?: ThreeNativeLodMinTrianglesScope;
|
|
218
|
+
/**
|
|
219
|
+
* Opt-in far rung that joins a mesh's same-material primitives into one draw per material group.
|
|
220
|
+
* Default `false`: with no option the cook is byte-identical to today. A join never crosses a
|
|
221
|
+
* material, never touches a skinned, morph-target or animated node, and never leaves the mesh's
|
|
222
|
+
* own node, so authored LOD0, node identity, per-node visibility, picking and transforms are
|
|
223
|
+
* untouched; the joined geometry is an additional far rung beside LOD0.
|
|
224
|
+
*/
|
|
225
|
+
readonly join?: boolean;
|
|
226
|
+
}
|
|
227
|
+
/** Screen-space selection knobs. */
|
|
228
|
+
interface IThreeNativeLodRuntimeConfig {
|
|
229
|
+
/** Projected geometric-error budget in raster pixels; positive finite. Default by preset. */
|
|
230
|
+
readonly maxPixelError?: number;
|
|
231
|
+
/** Fraction in `[0, 0.5)`, default 0.15, that stabilizes coarsening at a boundary. */
|
|
232
|
+
readonly hysteresis?: number;
|
|
233
|
+
}
|
|
234
|
+
/** A partial override for one asset; nested objects overlay, they never replace. */
|
|
235
|
+
interface IThreeNativeLodOverride {
|
|
236
|
+
readonly enabled?: boolean;
|
|
237
|
+
readonly generation?: IThreeNativeLodGenerationConfig;
|
|
238
|
+
readonly preset?: ThreeNativeLodPreset;
|
|
239
|
+
readonly runtime?: IThreeNativeLodRuntimeConfig;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Automatic discrete LOD policy. `{}` resolves to enabled/balanced and any explicit block turns
|
|
243
|
+
* generation on; `false` and `{ enabled: false }` are equivalent absolute kill switches that no
|
|
244
|
+
* per-asset override can re-enable. Overrides are keyed by canonical project-relative source asset
|
|
245
|
+
* (`/` separators).
|
|
246
|
+
*
|
|
247
|
+
* Omission currently bakes nothing: the default-on front door opens only after the qualification
|
|
248
|
+
* phase passes. Until then `assets.lod: {}` is the opt-in that resolves to enabled/balanced.
|
|
249
|
+
*/
|
|
250
|
+
interface IThreeNativeLodConfig {
|
|
251
|
+
readonly enabled?: boolean;
|
|
252
|
+
readonly generation?: IThreeNativeLodGenerationConfig;
|
|
253
|
+
readonly overrides?: Readonly<Record<string, boolean | IThreeNativeLodOverride>>;
|
|
254
|
+
readonly preset?: ThreeNativeLodPreset;
|
|
255
|
+
readonly runtime?: IThreeNativeLodRuntimeConfig;
|
|
256
|
+
}
|
|
257
|
+
/** One measured byte ceiling on a produced artifact, and what crossing it does. */
|
|
258
|
+
interface IThreeNativeArtifactBudgetLimit {
|
|
259
|
+
/** Bytes, exclusive: a build measuring exactly the limit is inside it. */
|
|
260
|
+
readonly limit: number;
|
|
261
|
+
/** `"error"` refuses the build and keeps the previous artifact; `"warn"` prints and publishes. */
|
|
262
|
+
readonly severity: "error" | "warn";
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Runtime ceilings a profile wants every playtest of the artifact it builds to hold.
|
|
266
|
+
*
|
|
267
|
+
* The fields are the playtest harness's own `assert.performance` fields, one name for one meaning:
|
|
268
|
+
* a budget declared here is merged into each scenario's performance assertion, so a budget and a
|
|
269
|
+
* scenario bound the same number instead of two vocabularies for one measurement. Spelled out
|
|
270
|
+
* rather than imported — the harness runs against plain Three.js with no dependency on this
|
|
271
|
+
* package, and core must not invert that. A closed key list validated in both places is the price;
|
|
272
|
+
* `create-threenative/__tests__/build-report.spec.ts` fails if the two lists drift.
|
|
273
|
+
*/
|
|
274
|
+
interface IThreeNativePerformanceBudget {
|
|
275
|
+
/** Per-pass draw-call ceilings, keyed by pass kind: main, shadow, reflection, nested. */
|
|
276
|
+
readonly maxPassDrawCalls?: Readonly<Partial<Record<ThreeNativeRenderPassKind, number>>>;
|
|
277
|
+
/** Per-pass triangle ceilings, keyed by pass kind: main, shadow, reflection, nested. */
|
|
278
|
+
readonly maxPassTriangles?: Readonly<Partial<Record<ThreeNativeRenderPassKind, number>>>;
|
|
279
|
+
/** Per-phase millisecond ceilings at nearest-rank p95: hostGap, update, render, overlay, residual. */
|
|
280
|
+
readonly maxPhaseMsP95?: Readonly<Partial<Record<ThreeNativeFramePhase, number>>>;
|
|
281
|
+
/** Maximum renderer draw-call count across every pass combined. */
|
|
282
|
+
readonly maxDrawCalls?: number;
|
|
283
|
+
/** Maximum nearest-rank 95th-percentile frame time in milliseconds. */
|
|
284
|
+
readonly maxFrameMsP95?: number;
|
|
285
|
+
/** Maximum renderer triangle count across every pass combined. */
|
|
286
|
+
readonly maxTriangles?: number;
|
|
287
|
+
/** Frame-budget floor: the median presented frame must sustain at least this many frames a second. */
|
|
288
|
+
readonly minFps?: number;
|
|
289
|
+
}
|
|
290
|
+
/** The engine's frame-budget phases, as a budget spells them. */
|
|
291
|
+
type ThreeNativeFramePhase = "hostGap" | "overlay" | "render" | "residual" | "update";
|
|
292
|
+
/** The render-pass kinds a per-pass budget bounds. */
|
|
293
|
+
type ThreeNativeRenderPassKind = "main" | "shadow" | "reflection" | "nested";
|
|
170
294
|
interface IThreeNativeConfig {
|
|
171
295
|
readonly app?: {
|
|
172
296
|
readonly id?: string;
|
|
@@ -181,7 +305,10 @@ interface IThreeNativeConfig {
|
|
|
181
305
|
readonly fullscreen?: boolean;
|
|
182
306
|
readonly keepScreenOn?: boolean;
|
|
183
307
|
/**
|
|
184
|
-
* Maximum native presentation rate in frames per second.
|
|
308
|
+
* Maximum native presentation rate in frames per second. Left out, it follows the display's own
|
|
309
|
+
* refresh rate capped at 120 on desktop and web, and stays 60 on mobile where the ceiling is
|
|
310
|
+
* power and heat; the resolved value and its source are reported on every `TN_FRAME_BUDGET`
|
|
311
|
+
* line as `targetFps` and `targetSource`. A number set here wins outright, and `0` removes the
|
|
185
312
|
* software ceiling. Android also submits this value as the surface's preferred frame rate,
|
|
186
313
|
* which the display policy may decline because of hardware, power, or thermal state. Android
|
|
187
314
|
* uses non-blocking presentation above 60 fps so a missed high-refresh interval does not fall
|
|
@@ -207,6 +334,43 @@ interface IThreeNativeConfig {
|
|
|
207
334
|
readonly maximized?: boolean;
|
|
208
335
|
readonly resizable?: boolean;
|
|
209
336
|
};
|
|
337
|
+
/**
|
|
338
|
+
* Named cook profiles: one authored asset tree, one compiler, a different representation per
|
|
339
|
+
* artifact. `--profile` on `threenative build` wins over `defaults[target]`; with neither, the
|
|
340
|
+
* `assets` block is used exactly as declared. An overlay changes resource-processing options
|
|
341
|
+
* only — the source root, the output root, worker concurrency and exclusions stay in `assets`.
|
|
342
|
+
*/
|
|
343
|
+
readonly buildProfiles?: {
|
|
344
|
+
readonly defaults?: {
|
|
345
|
+
readonly android?: string;
|
|
346
|
+
readonly desktop?: string;
|
|
347
|
+
readonly ios?: string;
|
|
348
|
+
readonly web?: string;
|
|
349
|
+
};
|
|
350
|
+
readonly profiles: Readonly<Record<string, {
|
|
351
|
+
/**
|
|
352
|
+
* Byte ceilings on what this profile actually produced, measured after packaging and
|
|
353
|
+
* checked before the artifact is published. `artifactBytes` is the artifact itself (a
|
|
354
|
+
* file, or the recursive sum of a directory, `.app` bundle or outDir);
|
|
355
|
+
* `packagedAssetBytes` is the sum of the asset files that survived the packaging
|
|
356
|
+
* selector. `"error"` refuses the build and leaves the previous artifact in place;
|
|
357
|
+
* `"warn"` prints and publishes.
|
|
358
|
+
*/
|
|
359
|
+
readonly artifactBudget?: {
|
|
360
|
+
readonly artifactBytes?: IThreeNativeArtifactBudgetLimit;
|
|
361
|
+
readonly packagedAssetBytes?: IThreeNativeArtifactBudgetLimit;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* Runtime ceilings this profile's artifact must hold, published into the
|
|
365
|
+
* `<artifact>.build-report.json` a build writes beside it and merged by
|
|
366
|
+
* `threenative-playtest --build-report` into every scenario's `assert.performance`. The
|
|
367
|
+
* build measures none of it — it cannot; the numbers exist only once a runtime drew
|
|
368
|
+
* frames — so a budget never refuses a build and never passes one either.
|
|
369
|
+
*/
|
|
370
|
+
readonly performanceBudget?: IThreeNativePerformanceBudget;
|
|
371
|
+
readonly assets?: Pick<NonNullable<IThreeNativeConfig["assets"]>, "audio" | "budget" | "lod" | "models" | "targets" | "textures">;
|
|
372
|
+
}>>;
|
|
373
|
+
};
|
|
210
374
|
readonly assets?: {
|
|
211
375
|
/**
|
|
212
376
|
* Audio conditioning options, or `"none"` to ship every clip exactly as committed. Absent
|
|
@@ -224,6 +388,18 @@ interface IThreeNativeConfig {
|
|
|
224
388
|
};
|
|
225
389
|
/** Source-relative globs omitted from builds; excluded bytes are still reported. */
|
|
226
390
|
readonly exclude?: readonly string[];
|
|
391
|
+
/**
|
|
392
|
+
* How many cook workers a bake may run at once; absent means the driver's default,
|
|
393
|
+
* min(4, cores - 1). Not part of any cache key, so changing it re-cooks nothing.
|
|
394
|
+
*/
|
|
395
|
+
readonly concurrency?: number;
|
|
396
|
+
/**
|
|
397
|
+
* Automatic discrete LOD. `assets.lod: {}` opts in with the balanced default; `false` or
|
|
398
|
+
* `{ enabled: false }` is the absolute kill switch, and per-asset overrides key off canonical
|
|
399
|
+
* source asset paths. Omission currently bakes nothing — the default-on front door opens only
|
|
400
|
+
* after the qualification phase passes. See {@link IThreeNativeLodConfig}.
|
|
401
|
+
*/
|
|
402
|
+
readonly lod?: boolean | IThreeNativeLodConfig;
|
|
227
403
|
readonly models?: "none" | IThreeNativeModelsConfig;
|
|
228
404
|
readonly output?: string;
|
|
229
405
|
readonly source?: string;
|
|
@@ -258,6 +434,63 @@ interface IThreeNativeConfig {
|
|
|
258
434
|
* surface, and says so in `TN_ALPHA_ANTIALIASING` rather than reporting itself applied.
|
|
259
435
|
*/
|
|
260
436
|
readonly alphaAntialiasing?: boolean;
|
|
437
|
+
/**
|
|
438
|
+
* Whether the engine may render an internal mirror of the scene to collapse repeated draws,
|
|
439
|
+
* and how often that mirror proves a batched material still matches its group's shared draw.
|
|
440
|
+
*
|
|
441
|
+
* On by default, which is the shipping behaviour and is what an unset option means. The mirror
|
|
442
|
+
* is opportunistic and correctness-preserving, but it pays a reconciliation cost per frame, so
|
|
443
|
+
* a game that has measured it as a loss — a scene whose draw count falls without its frame time
|
|
444
|
+
* following — can decline it with `false`. An opted-out game builds no mirror and runs no
|
|
445
|
+
* eligibility scan, so the opt-out costs nothing rather than declining each frame; the authored
|
|
446
|
+
* scene is what renders. The `TN_RENDER_PROJECTION` marker still reports it, with its own
|
|
447
|
+
* reason code rather than one of the measured declines.
|
|
448
|
+
*
|
|
449
|
+
* An object instead of `false` names the material check:
|
|
450
|
+
*
|
|
451
|
+
* - `materialChecks: "spread"` — **the default.** A bounded slice of the batched materials is
|
|
452
|
+
* proved per frame instead of all of them, so a frame of 4,096 colour-only materials costs
|
|
453
|
+
* 512 checks rather than 4,096. A material that gains a roughness, a map or a define still
|
|
454
|
+
* leaves its group and is drawn exactly; it is caught up to `materialCheckStaleFrames` frames
|
|
455
|
+
* later, and `TN_RENDER_PROJECTION` reports that bound. A base-colour edit never waits: the
|
|
456
|
+
* per-instance colour is O(1) per member and always exact.
|
|
457
|
+
* - `materialChecks: "everyFrame"` — the named alternative, and the check exactly as it shipped
|
|
458
|
+
* before the sweep existed: every material proved every frame, at about 1.1 µs a material. Use
|
|
459
|
+
* it when a game would rather pay the per-frame cost than accept the bound.
|
|
460
|
+
*
|
|
461
|
+
* Any other value throws at startup rather than falling back to a default nobody asked for.
|
|
462
|
+
*/
|
|
463
|
+
readonly projection?: boolean | {
|
|
464
|
+
readonly materialChecks?: "spread" | "everyFrame";
|
|
465
|
+
};
|
|
466
|
+
/**
|
|
467
|
+
* Projected diameter, in raster pixels, below which the engine does not submit an object to
|
|
468
|
+
* the render camera. On by default at a conservative **0.5 px**: an object under half a pixel
|
|
469
|
+
* cannot light a whole pixel of the frame, so only unresolvable geometry is removed. Set a
|
|
470
|
+
* larger number for a tuned cut — a shipped game's ladder chose 2 px — or `false` to leave
|
|
471
|
+
* every object drawn. The measurement still runs with `false`; `TN_PROJECTION` reports how many
|
|
472
|
+
* objects were considered and skipped. Exempt a single object with `alwaysRender` from
|
|
473
|
+
* `@threenative/core`; the player's camera-attached objects and shadow casters are already kept.
|
|
474
|
+
*/
|
|
475
|
+
readonly minimumProjectedPixels?: number | false;
|
|
476
|
+
/**
|
|
477
|
+
* How much of the scene graph the engine walks for world matrices each frame.
|
|
478
|
+
*
|
|
479
|
+
* `"visible"` — the default — does not recurse into a hidden subtree. three's own
|
|
480
|
+
* `updateMatrixWorld` walks every child whatever its `visible` flag, multiplying a world matrix
|
|
481
|
+
* for a full-detail body whose merged stand-in is showing, a hidden LOD level, a parked model —
|
|
482
|
+
* none of which can draw. The engine composes every visible node exactly as three does, and
|
|
483
|
+
* remembers a hidden node it skipped so the first frame that subtree shows again its whole
|
|
484
|
+
* chain is refreshed before anything reads it. A game that reads a **hidden** object's
|
|
485
|
+
* `matrixWorld` directly must not rely on the walk having reached it: use `getWorldPosition`
|
|
486
|
+
* (which updates the chain) or call `updateWorldMatrix(true, false)` first.
|
|
487
|
+
*
|
|
488
|
+
* `"all"` visits every node, exactly as three's own walk does — for a game that reads hidden
|
|
489
|
+
* world matrices without going through `getWorld*` and cannot say so per object. Both modes
|
|
490
|
+
* report the number of nodes walked in the `TN_PROJECTION` window, so the cost of the walk the
|
|
491
|
+
* default removed is measurable rather than asserted.
|
|
492
|
+
*/
|
|
493
|
+
readonly matrixWorld?: "visible" | "all";
|
|
261
494
|
/**
|
|
262
495
|
* Android-only rendering overrides selected by the engine.
|
|
263
496
|
*
|
|
@@ -279,7 +512,7 @@ interface IThreeNativeConfig {
|
|
|
279
512
|
};
|
|
280
513
|
readonly ui?: {
|
|
281
514
|
/**
|
|
282
|
-
* Which renderer draws `src/ui/`.
|
|
515
|
+
* Which renderer draws `src/ui/`. Defaults to `"web"`.
|
|
283
516
|
*
|
|
284
517
|
* `"web"` runs the same React DOM, Tailwind, CSS, SVG and fonts on every target, through
|
|
285
518
|
* that platform's own browser-class renderer composited over the game surface. What is
|
|
@@ -298,6 +531,182 @@ interface IThreeNativeConfig {
|
|
|
298
531
|
};
|
|
299
532
|
}
|
|
300
533
|
|
|
534
|
+
/**
|
|
535
|
+
* Per-object geometry cost, measured from what the renderer actually submitted.
|
|
536
|
+
*
|
|
537
|
+
* A total triangle counter cannot name the offender: a main character can cost 500 triangles while
|
|
538
|
+
* a barely visible tree submits two million, and both land in the same number. `FrameBudget` stays
|
|
539
|
+
* authoritative for a frame's per-pass totals; this attributes a slice of those totals to the
|
|
540
|
+
* objects that caused them, and reconciles the two so the difference is visible rather than
|
|
541
|
+
* assumed away.
|
|
542
|
+
*
|
|
543
|
+
* Three properties make it a measurement rather than a guess:
|
|
544
|
+
*
|
|
545
|
+
* 1. **It counts submissions, not scene contents.** The instrument is `onBeforeRender`, which the
|
|
546
|
+
* renderer calls once per object, per material group, per pass, *after* frustum and projected-
|
|
547
|
+
* size culling. A `visible` flag is a game's intent; a submission is what the GPU was handed.
|
|
548
|
+
* 2. **It is armed only on request.** Nothing is installed, walked or counted until a consumer asks
|
|
549
|
+
* for one capture, and every hook is removed when that frame ends, is cancelled, or the scene
|
|
550
|
+
* exits. An idle game pays nothing.
|
|
551
|
+
* 3. **It says "unavailable" with a reason.** A packed batch's per-member draws, an indirect
|
|
552
|
+
* counter with no readback, a geometry with no recoverable source detail: each is named, never
|
|
553
|
+
* reported as zero and never quietly dropped, and the unattributed remainder of every pass is
|
|
554
|
+
* reported beside the measured total.
|
|
555
|
+
*
|
|
556
|
+
* @situation find out which scene object is submitting the frame's triangles
|
|
557
|
+
* @situation tell a cheap foreground character from an expensive distant prop
|
|
558
|
+
*/
|
|
559
|
+
|
|
560
|
+
/** Rows returned when a request does not name a limit. */
|
|
561
|
+
declare const GEOMETRY_CAPTURE_DEFAULT_LIMIT = 50;
|
|
562
|
+
/** The most rows one request may ask for. A transport carries a report, not a scene dump. */
|
|
563
|
+
declare const GEOMETRY_CAPTURE_MAX_LIMIT = 500;
|
|
564
|
+
/** The inspection ceiling, shared with scene-node observation so one scene has one limit. */
|
|
565
|
+
declare const GEOMETRY_CAPTURE_WALK_CAP = 50000;
|
|
566
|
+
/** How long a request waits for a presented world frame before answering "unavailable". */
|
|
567
|
+
declare const GEOMETRY_CAPTURE_TIMEOUT_MS = 2000;
|
|
568
|
+
/** The `userData` key a loader stamps on a model root so a clone keeps its provenance. */
|
|
569
|
+
declare const GEOMETRY_ASSET_KEY = "tnAssetPath";
|
|
570
|
+
/** The orderings a request may ask for. Ranking happens over the inspected scope, then slices. */
|
|
571
|
+
declare const GEOMETRY_CAPTURE_SORTS: readonly ["triangles", "draws", "projected"];
|
|
572
|
+
type GeometryCaptureSort = (typeof GEOMETRY_CAPTURE_SORTS)[number];
|
|
573
|
+
interface IGeometryCaptureRequest {
|
|
574
|
+
/** Rows to return, 1 to `GEOMETRY_CAPTURE_MAX_LIMIT`. */
|
|
575
|
+
readonly limit?: number;
|
|
576
|
+
readonly sort?: GeometryCaptureSort;
|
|
577
|
+
readonly timeoutMs?: number;
|
|
578
|
+
}
|
|
579
|
+
/** What a rendered object is: the game's own object, or the mirror standing in for some of them. */
|
|
580
|
+
type GeometryOwnershipKind = "exact" | "instancedBatch" | "materialBatch";
|
|
581
|
+
/** Where a row's triangle number came from, so a derived number is never read as a measured one. */
|
|
582
|
+
type GeometryTriangleSource = "renderer" | "batchMembers";
|
|
583
|
+
interface IGeometryPassCost {
|
|
584
|
+
readonly draws: number;
|
|
585
|
+
readonly triangles: number;
|
|
586
|
+
}
|
|
587
|
+
interface IGeometryCapturePass extends IGeometryPassCost {
|
|
588
|
+
readonly kind: FramePassKind;
|
|
589
|
+
/** What the rows below account for. */
|
|
590
|
+
readonly attributedDraws: number;
|
|
591
|
+
readonly attributedTriangles: number;
|
|
592
|
+
/**
|
|
593
|
+
* Measured minus attributed. Negative means the rows over-claim — a derived batch sum, say —
|
|
594
|
+
* which is a finding, not something to clamp away.
|
|
595
|
+
*/
|
|
596
|
+
readonly unattributedDraws: number;
|
|
597
|
+
readonly unattributedTriangles: number;
|
|
598
|
+
}
|
|
599
|
+
interface IGeometryCaptureMesh {
|
|
600
|
+
readonly id: string;
|
|
601
|
+
readonly name: string;
|
|
602
|
+
readonly path: string;
|
|
603
|
+
readonly type: string;
|
|
604
|
+
/** LOD0 triangles of this mesh, when the source detail is recoverable. */
|
|
605
|
+
readonly fullDetailTriangles?: number;
|
|
606
|
+
/** Triangles in the buffer the renderer was pointed at this frame. */
|
|
607
|
+
readonly selectedDetailTriangles?: number;
|
|
608
|
+
readonly submittedTriangles?: number;
|
|
609
|
+
readonly trianglesSource?: GeometryTriangleSource;
|
|
610
|
+
readonly draws: number;
|
|
611
|
+
readonly materials: number;
|
|
612
|
+
readonly instances?: number;
|
|
613
|
+
readonly submissions: Readonly<Partial<Record<FramePassKind, IGeometryPassCost>>>;
|
|
614
|
+
readonly batchOwner?: string;
|
|
615
|
+
readonly visible: boolean;
|
|
616
|
+
readonly inFrustum?: boolean;
|
|
617
|
+
readonly unavailable?: readonly string[];
|
|
618
|
+
}
|
|
619
|
+
interface IGeometryCaptureRow {
|
|
620
|
+
readonly id: string;
|
|
621
|
+
readonly generation: number;
|
|
622
|
+
readonly name: string;
|
|
623
|
+
readonly path: string;
|
|
624
|
+
readonly type: string;
|
|
625
|
+
/** The logical asset this row came from, when a loader stamped one. */
|
|
626
|
+
readonly asset?: string;
|
|
627
|
+
readonly fullDetailTriangles?: number;
|
|
628
|
+
readonly selectedDetailTriangles?: number;
|
|
629
|
+
readonly submittedTriangles?: number;
|
|
630
|
+
readonly trianglesSource?: GeometryTriangleSource;
|
|
631
|
+
readonly lod?: {
|
|
632
|
+
readonly level?: number;
|
|
633
|
+
readonly levels?: number;
|
|
634
|
+
};
|
|
635
|
+
/** Estimated projected diameter in drawing-buffer pixels. An estimate, never a pixel count. */
|
|
636
|
+
readonly projectedPixels?: number;
|
|
637
|
+
/**
|
|
638
|
+
* Where those bounds landed, in drawing-buffer pixels from the top-left. An overlay outlines
|
|
639
|
+
* this; it is the estimated bounds' centre, not a silhouette.
|
|
640
|
+
*/
|
|
641
|
+
readonly projectedCenter?: readonly [number, number];
|
|
642
|
+
readonly viewportFraction?: number;
|
|
643
|
+
readonly cameraDistance?: number;
|
|
644
|
+
readonly inFrustum?: boolean;
|
|
645
|
+
readonly visibility: "submitted" | "notSubmitted";
|
|
646
|
+
/** Submitted copies of this row's geometry, instances included. */
|
|
647
|
+
readonly copies: number;
|
|
648
|
+
readonly instances?: number;
|
|
649
|
+
/** Triangles counted once per distinct geometry, for a unique-inventory reading. */
|
|
650
|
+
readonly uniqueTriangles?: number;
|
|
651
|
+
readonly draws: number;
|
|
652
|
+
readonly materials: number;
|
|
653
|
+
readonly submissions: Readonly<Partial<Record<FramePassKind, IGeometryPassCost>>>;
|
|
654
|
+
readonly batch?: {
|
|
655
|
+
readonly kind: GeometryOwnershipKind;
|
|
656
|
+
readonly owner: string;
|
|
657
|
+
readonly members: number;
|
|
658
|
+
readonly perMemberDrawsAvailable: boolean;
|
|
659
|
+
};
|
|
660
|
+
readonly unavailable?: readonly string[];
|
|
661
|
+
readonly meshes: readonly IGeometryCaptureMesh[];
|
|
662
|
+
}
|
|
663
|
+
interface IGeometryCaptureAsset {
|
|
664
|
+
readonly asset: string;
|
|
665
|
+
readonly objects: number;
|
|
666
|
+
readonly submittedTriangles?: number;
|
|
667
|
+
readonly draws: number;
|
|
668
|
+
/** Triangles of the distinct geometries this asset contributed, counted once each. */
|
|
669
|
+
readonly uniqueTriangles?: number;
|
|
670
|
+
readonly unavailable?: readonly string[];
|
|
671
|
+
}
|
|
672
|
+
interface IGeometryCaptureReport {
|
|
673
|
+
readonly status: "captured" | "unavailable";
|
|
674
|
+
/** Set when `status` is `unavailable`. A stale capture is never returned as a fresh one. */
|
|
675
|
+
readonly reason?: string;
|
|
676
|
+
readonly capturedAtMs?: number;
|
|
677
|
+
readonly durationMs?: number;
|
|
678
|
+
readonly generation?: number;
|
|
679
|
+
readonly tick?: number;
|
|
680
|
+
readonly frame?: number;
|
|
681
|
+
readonly backend?: string;
|
|
682
|
+
readonly camera?: {
|
|
683
|
+
readonly type: "perspective" | "orthographic" | "unknown";
|
|
684
|
+
readonly position: readonly [number, number, number];
|
|
685
|
+
readonly fov?: number;
|
|
686
|
+
readonly zoom?: number;
|
|
687
|
+
readonly near?: number;
|
|
688
|
+
readonly far?: number;
|
|
689
|
+
};
|
|
690
|
+
readonly viewport?: {
|
|
691
|
+
readonly width: number;
|
|
692
|
+
readonly height: number;
|
|
693
|
+
};
|
|
694
|
+
readonly sort?: GeometryCaptureSort;
|
|
695
|
+
readonly limit?: number;
|
|
696
|
+
/** Rows the inspected scope produced before the limit sliced them. */
|
|
697
|
+
readonly matched?: number;
|
|
698
|
+
readonly returned?: number;
|
|
699
|
+
/** True when the limit cut rows; distinct from an incomplete inspection. */
|
|
700
|
+
readonly rowsTruncated?: boolean;
|
|
701
|
+
/** False when the walk cap stopped the inspection, so no ranking is a global claim. */
|
|
702
|
+
readonly inspectionComplete?: boolean;
|
|
703
|
+
readonly partialRanking?: boolean;
|
|
704
|
+
readonly inspectedNodes?: number;
|
|
705
|
+
readonly passes?: readonly IGeometryCapturePass[];
|
|
706
|
+
readonly objects?: readonly IGeometryCaptureRow[];
|
|
707
|
+
readonly assets?: readonly IGeometryCaptureAsset[];
|
|
708
|
+
}
|
|
709
|
+
|
|
301
710
|
/**
|
|
302
711
|
* One action, read either as a button through `pressed`/`justPressed`, a 2D axis through
|
|
303
712
|
* `vector`, or a scalar axis through `axis`. Which one you get depends on the fields you fill in,
|
|
@@ -398,6 +807,14 @@ interface IRawInputState {
|
|
|
398
807
|
buttons: readonly boolean[];
|
|
399
808
|
};
|
|
400
809
|
}
|
|
810
|
+
/**
|
|
811
|
+
* Ask the browser to lock the pointer to `target`, the capture every first-person mouse look needs.
|
|
812
|
+
*
|
|
813
|
+
* Returns the platform's own promise when it has one, so the caller can wait for the lock the way
|
|
814
|
+
* the browser reports it, and `undefined` when the platform answered synchronously. A target that
|
|
815
|
+
* cannot capture at all throws rather than leaving a game with a camera that never turns.
|
|
816
|
+
*/
|
|
817
|
+
declare function captureMouse(target: EventTarget): Promise<void> | undefined;
|
|
401
818
|
declare class InputMap {
|
|
402
819
|
#private;
|
|
403
820
|
readonly raw: IRawInputState;
|
|
@@ -438,6 +855,7 @@ interface IAfterPhysicsContext {
|
|
|
438
855
|
declare function afterPhysics(context: IAfterPhysicsContext, callback: AfterPhysicsCallback): () => void;
|
|
439
856
|
interface IRenderPerformanceMetrics {
|
|
440
857
|
readonly drawCalls?: number;
|
|
858
|
+
readonly passes?: readonly IRenderPassSample[];
|
|
441
859
|
readonly triangles?: number;
|
|
442
860
|
}
|
|
443
861
|
interface IRenderPerformanceSample extends IRenderPerformanceMetrics {
|
|
@@ -704,6 +1122,33 @@ interface IWarmUpOptions {
|
|
|
704
1122
|
* This is opt-in because WebGPU does not expose a portable pipeline-serialization API.
|
|
705
1123
|
*/
|
|
706
1124
|
readonly cache?: IWarmUpCacheOptions;
|
|
1125
|
+
/**
|
|
1126
|
+
* Render the warm scene once after compiling, so every pass's pipelines exist before the first
|
|
1127
|
+
* frame. Default `true`.
|
|
1128
|
+
*
|
|
1129
|
+
* `compileAsync` builds only the main-pass pipelines. A shadow-casting light's shadow map and a
|
|
1130
|
+
* reflection pass each need their own variants, created synchronously on first use — on a native
|
|
1131
|
+
* Midway launch that was **44–107 pipelines after "ready"**, with freezes up to 615 ms. One
|
|
1132
|
+
* hidden render of the warm scene, with the shadow map forced to update, builds them while the
|
|
1133
|
+
* startup cover is still up. The render is invisible (it does not clear, and its output is
|
|
1134
|
+
* behind the loading layer) and restores every renderer and scene state it touches.
|
|
1135
|
+
*
|
|
1136
|
+
* Set `false` to skip it. The warm-up still reports `passes: []` and `passPipelines: 0`, because
|
|
1137
|
+
* turning a convention off must not turn its measurement off.
|
|
1138
|
+
*/
|
|
1139
|
+
readonly renderPasses?: boolean;
|
|
1140
|
+
/**
|
|
1141
|
+
* Also render objects the scene has hidden for that one covered render. Default `false`.
|
|
1142
|
+
*
|
|
1143
|
+
* `renderPasses` already disables frustum culling, so every caster is submitted to the shadow
|
|
1144
|
+
* pass and every reflected object to the reflection pass even when the startup camera cannot see
|
|
1145
|
+
* it. A hidden LOD level or a parked model is still skipped, though: three never draws a subtree
|
|
1146
|
+
* whose ancestor's `visible` is false, so its shadow and reflection pipelines stay unbuilt. With
|
|
1147
|
+
* this on, the warm-up forces every hidden object visible for that one render — ancestors
|
|
1148
|
+
* included — and restores every original `visible` exactly afterwards. The count is reported as
|
|
1149
|
+
* `visibilityForced`, so a game can see how much of its scene the render had to un-hide.
|
|
1150
|
+
*/
|
|
1151
|
+
readonly includeHidden?: boolean;
|
|
707
1152
|
}
|
|
708
1153
|
/** What the warm-up did, so a caller can report it rather than assume it. */
|
|
709
1154
|
type WarmUpObservationStatus = "complete" | "incomplete" | "unavailable";
|
|
@@ -770,12 +1215,27 @@ interface IWarmUpReport {
|
|
|
770
1215
|
readonly computeTimedOut?: boolean;
|
|
771
1216
|
/** The optional persistent warm-up hint's outcome. */
|
|
772
1217
|
readonly cache?: WarmUpCacheStatus;
|
|
1218
|
+
/**
|
|
1219
|
+
* The passes the hidden warm render exercised: `main` always, plus `shadow` when a shadow-casting
|
|
1220
|
+
* light is present and `reflection` when a reflector node is reachable from a material. Empty when
|
|
1221
|
+
* `renderPasses` was off, so an overridden convention still reports what it did. Absent when the
|
|
1222
|
+
* renderer exposes no `render` at all.
|
|
1223
|
+
*/
|
|
1224
|
+
readonly passes?: readonly string[];
|
|
1225
|
+
/** Backend pipelines observed created by the hidden warm render alone. Absent with `passes`. */
|
|
1226
|
+
readonly passPipelines?: number;
|
|
1227
|
+
/** Objects whose `frustumCulled` the warm render turned off, so off-screen casters were submitted. */
|
|
1228
|
+
readonly cullingForced?: number;
|
|
1229
|
+
/** Hidden objects the warm render forced visible (`includeHidden`); zero when it was off. */
|
|
1230
|
+
readonly visibilityForced?: number;
|
|
773
1231
|
}
|
|
774
1232
|
/** The narrow slice of the renderer this needs. Structural so a test needs no renderer. */
|
|
775
1233
|
interface IWarmUpRenderer {
|
|
776
1234
|
compileAsync?: (scene: Object3D, camera: Camera, targetScene?: Object3D) => Promise<void>;
|
|
777
1235
|
computeAsync?: (node: unknown) => Promise<void>;
|
|
778
1236
|
pipelineCensus?: () => IPipelineCensus;
|
|
1237
|
+
/** The renderer's own render path, used to build every pass's pipelines once. */
|
|
1238
|
+
render?: (scene: Object3D, camera: Camera) => void;
|
|
779
1239
|
raw?: unknown;
|
|
780
1240
|
}
|
|
781
1241
|
/**
|
|
@@ -861,6 +1321,10 @@ interface IStartupStatus {
|
|
|
861
1321
|
* 0 to 1, monotonic and honest: the loader's settled/requested ratio carries the first 0.7
|
|
862
1322
|
* while the start scene loads, 0.8 once the world is entered, 0.9 once first-use compilation
|
|
863
1323
|
* settled, 1 when `whenReady()` resolves.
|
|
1324
|
+
*
|
|
1325
|
+
* Monotonic is enforced, not assumed: this is a high-water mark over the measured load state,
|
|
1326
|
+
* because that state can fall — requesting an asset after an earlier one settled shrinks the
|
|
1327
|
+
* ratio, and a bar that jumps backwards reads to a player as the load restarting.
|
|
864
1328
|
*/
|
|
865
1329
|
readonly progress: number;
|
|
866
1330
|
/** When each milestone happened; members appear as they are reached. */
|
|
@@ -925,6 +1389,12 @@ interface ICtx<TState extends Record<string, unknown> = Record<string, unknown>,
|
|
|
925
1389
|
readonly after: (delay: number, callback: () => void) => ScheduleHandle;
|
|
926
1390
|
/** Register a callback for the engine-owned phase after physics writes solved transforms. */
|
|
927
1391
|
readonly afterPhysics: (callback: AfterPhysicsCallback) => () => void;
|
|
1392
|
+
/**
|
|
1393
|
+
* Register work that runs once per actual world render, after the frame's last fixed update and
|
|
1394
|
+
* before the projection reconciles and the renderer draws. A held, loader-only frame has no world
|
|
1395
|
+
* draw and therefore dispatches nothing.
|
|
1396
|
+
*/
|
|
1397
|
+
readonly beforeRender: (callback: () => void) => () => void;
|
|
928
1398
|
readonly every: (callback: (dt: number) => void) => ScheduleHandle;
|
|
929
1399
|
readonly state: GameStore<TState>;
|
|
930
1400
|
readonly tween: <T extends object>(target: T, properties: {
|
|
@@ -951,13 +1421,19 @@ interface ICtx<TState extends Record<string, unknown> = Record<string, unknown>,
|
|
|
951
1421
|
type PluginCleanup = () => void;
|
|
952
1422
|
interface IGameObservationSampleRequest {
|
|
953
1423
|
readonly entities?: readonly string[];
|
|
1424
|
+
/** Asks for one armed per-object geometry capture. Absent means no capture is collected. */
|
|
1425
|
+
readonly geometry?: IGeometryCaptureRequest;
|
|
954
1426
|
readonly include?: readonly string[];
|
|
955
1427
|
readonly label?: string;
|
|
956
1428
|
readonly resources?: readonly string[];
|
|
957
1429
|
}
|
|
958
1430
|
interface IGameObservationContribution {
|
|
959
1431
|
readonly capabilities: readonly string[];
|
|
960
|
-
|
|
1432
|
+
/**
|
|
1433
|
+
* May answer a promise: an observation that has to wait for the renderer — a geometry capture
|
|
1434
|
+
* waits for one presented world frame — cannot be produced inside the request that asked for it.
|
|
1435
|
+
*/
|
|
1436
|
+
readonly sample: (request: IGameObservationSampleRequest) => Readonly<Record<string, unknown>> | Promise<Readonly<Record<string, unknown>>>;
|
|
961
1437
|
}
|
|
962
1438
|
interface IGameRuntimeObservations {
|
|
963
1439
|
contribute(contribution: IGameObservationContribution): PluginCleanup;
|
|
@@ -974,12 +1450,22 @@ interface IGamePluginRuntime {
|
|
|
974
1450
|
readonly enableRuntimeDiagnostics?: () => void;
|
|
975
1451
|
/** The frame's cost attribution so far, or undefined when the game turned the budget off. */
|
|
976
1452
|
readonly frameBudgetWindow?: () => IFrameBudgetWindow | undefined;
|
|
1453
|
+
/**
|
|
1454
|
+
* Stop the live clock, so a rendered frame simulates nothing and banks no wall-clock time.
|
|
1455
|
+
*
|
|
1456
|
+
* A run that counts fixed-step ticks must not also accumulate real seconds into the same
|
|
1457
|
+
* simulation, and the frames before its first `advance()` are exactly where a boot's seconds
|
|
1458
|
+
* used to land. Optional: a runtime without a clock just never freezes one.
|
|
1459
|
+
*/
|
|
1460
|
+
readonly freezeClock?: () => void;
|
|
977
1461
|
/**
|
|
978
1462
|
* Hold start-scene entry until `gate` settles.
|
|
979
1463
|
*
|
|
980
|
-
* The returned promise settles after
|
|
981
|
-
*
|
|
982
|
-
*
|
|
1464
|
+
* The returned promise settles after the scene that owns the world has entered: the start scene
|
|
1465
|
+
* unless it navigated out of its own `enter()`, in which case it is the scene it navigated to,
|
|
1466
|
+
* loaded and entered. A runner can therefore release the gate after applying pre-entry setup,
|
|
1467
|
+
* then await the returned promise before describing entity-derived capabilities — the entities
|
|
1468
|
+
* they read are the ones the world actually has. The frame loop remains held throughout.
|
|
983
1469
|
*/
|
|
984
1470
|
readonly holdStart?: (gate: Promise<void>) => Promise<void>;
|
|
985
1471
|
readonly observations: IGameRuntimeObservations;
|
|
@@ -1001,6 +1487,11 @@ interface IGamePluginRuntime {
|
|
|
1001
1487
|
readonly startupTimeline?: () => IStartupTimeline;
|
|
1002
1488
|
/** The renderer-owned bounded pipeline capture, when the renderer has not been opted out. */
|
|
1003
1489
|
readonly pipelineCensus?: () => IPipelineCensus;
|
|
1490
|
+
/**
|
|
1491
|
+
* Arms one per-object geometry capture and answers its report after the next presented world
|
|
1492
|
+
* frame. Absent on a runtime with no render loop to arm.
|
|
1493
|
+
*/
|
|
1494
|
+
readonly geometryCapture?: (request?: IGeometryCaptureRequest) => Promise<IGeometryCaptureReport>;
|
|
1004
1495
|
readonly step: number;
|
|
1005
1496
|
}
|
|
1006
1497
|
interface IGamePlatformSource {
|
|
@@ -1100,6 +1591,7 @@ interface IGameConfig<TState extends Record<string, unknown> = Record<string, un
|
|
|
1100
1591
|
*/
|
|
1101
1592
|
readonly step?: number;
|
|
1102
1593
|
readonly start: string;
|
|
1594
|
+
/** Optional slower UI publication interval. Omitted publishes once per rendered frame. */
|
|
1103
1595
|
readonly stateFlushMs?: number;
|
|
1104
1596
|
}
|
|
1105
1597
|
interface IPerspectiveCameraConfig {
|
|
@@ -1124,7 +1616,7 @@ type CameraConfig = IPerspectiveCameraConfig | IOrthogonalCameraConfig;
|
|
|
1124
1616
|
* two channels through an in-process broker, which is what keeps one `src/ui/` honest: a HUD
|
|
1125
1617
|
* that works here works on a phone.
|
|
1126
1618
|
*
|
|
1127
|
-
* Publication is automatic
|
|
1619
|
+
* Publication is automatic at the rendered frame cadence (or the named stateFlushMs override), and it stops
|
|
1128
1620
|
* entirely when nothing is listening — a game whose `ui.renderer` is `native` pays nothing.
|
|
1129
1621
|
*/
|
|
1130
1622
|
interface IGameUi {
|
|
@@ -1163,4 +1655,4 @@ interface IGame<TState extends Record<string, unknown> = Record<string, unknown>
|
|
|
1163
1655
|
}
|
|
1164
1656
|
declare function defineGame<TState extends Record<string, unknown>, TPhysics = undefined>(config: IGameConfig<TState, TPhysics>): IGame<TState, TPhysics>;
|
|
1165
1657
|
|
|
1166
|
-
export {
|
|
1658
|
+
export { type IWarmUpRenderer as $, type AfterPhysicsCallback as A, type IRandom as B, type ContextMenuPolicy as C, type IRawInputPointer as D, type IRawInputPointerEdge as E, type IRawInputState as F, GEOMETRY_ASSET_KEY as G, type IRaycastOptions as H, type IGame as I, type IScenePickerOptions as J, type IThreeNativeAudioConfig as K, type IThreeNativeAudioLoop as L, type IThreeNativeAudioOverride as M, type IThreeNativeAudioSpectrum as N, type IThreeNativeBootSplash as O, type IThreeNativeConfig as P, type IThreeNativeIconVariants as Q, type IThreeNativeLodConfig as R, type IThreeNativeLodGenerationConfig as S, type IThreeNativeLodOverride as T, type IThreeNativeLodRuntimeConfig as U, type IThreeNativeTexturesConfig as V, type ITweenOptions as W, type IWarmUpCacheOptions as X, type IWarmUpObservation as Y, type IWarmUpOptions as Z, type IWarmUpProgress as _, type IGamePluginRuntime as a, type IWarmUpReport as a0, type InputBindings as a1, InputMap as a2, type InputPlatformSource as a3, type PointerEvent3DListener as a4, type PointerEvent3DType as a5, PointerEvents3D as a6, Scene as a7, type SceneFrame as a8, ScenePicker as a9, type ScheduleHandle as aa, Scheduler as ab, type ThreeNativeBackgroundMode as ac, type ThreeNativeLodMinTrianglesScope as ad, type ThreeNativeLodPreset as ae, type ThreeNativeOrientation as af, type ThreeNativeUiRenderer as ag, type WarmUpCacheStatus as ah, type WarmUpObservationStatus as ai, afterPhysics as aj, captureMouse as ak, createRandom as al, defineGame as am, warmUpScene as an, type IGamePluginHooks as b, GEOMETRY_CAPTURE_DEFAULT_LIMIT as c, GEOMETRY_CAPTURE_MAX_LIMIT as d, GEOMETRY_CAPTURE_SORTS as e, GEOMETRY_CAPTURE_TIMEOUT_MS as f, GEOMETRY_CAPTURE_WALK_CAP as g, type GeometryCaptureSort as h, type ICtx as i, type IGameObservationContribution as j, type IGameObservationSampleRequest as k, type IGamePlatformSource as l, type IGeometryCaptureAsset as m, type IGeometryCaptureMesh as n, type IGeometryCapturePass as o, type IGeometryCaptureReport as p, type IGeometryCaptureRequest as q, type IGeometryCaptureRow as r, type IInputAction as s, type IInputGamepad as t, type IPointerDragHandle as u, type IPointerEvent3D as v, type IPointerEvents3D as w, type IPointerEvents3DOptions as x, type IPointerEvents3DPicker as y, type IPointerState as z };
|