@voluma/vlam 0.2.4 → 0.3.2
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/README.md +3 -4
- package/dist/chunk-loader-DlNwggfG.js +1859 -0
- package/dist/chunk-loader-DlNwggfG.js.map +1 -0
- package/dist/{compute-sorter.d.ts → core/compute-sorter.d.ts} +1 -1
- package/dist/core/index.d.ts +45 -0
- package/dist/{splat-scene.d.ts → core/merged-splat-mesh.d.ts} +14 -15
- package/dist/{orientation.d.ts → core/orientation.d.ts} +7 -7
- package/dist/{relighting.d.ts → core/relighting.d.ts} +1 -1
- package/dist/{source-transform.d.ts → core/source-transform.d.ts} +4 -4
- package/dist/{splat-budget.d.ts → core/splat-budget.d.ts} +2 -2
- package/dist/{splat-data.d.ts → core/splat-data.d.ts} +4 -4
- package/dist/{splat-mesh-material.d.ts → core/splat-mesh-material.d.ts} +2 -2
- package/dist/{splat-mesh-types.d.ts → core/splat-mesh-types.d.ts} +19 -10
- package/dist/{splat-mesh.d.ts → core/splat-mesh.d.ts} +4 -4
- package/dist/{splat-modifier.d.ts → core/splat-modifier.d.ts} +5 -5
- package/dist/{webgpu-limits.d.ts → core/webgpu-limits.d.ts} +0 -59
- package/dist/{effects.d.ts → effects/index.d.ts} +14 -13
- package/dist/effects.js.map +1 -1
- package/dist/formats/ksplat/index.d.ts +1 -1
- package/dist/formats/ksplat/parse-ksplat.d.ts +1 -1
- package/dist/formats/ksplat.js.map +1 -1
- package/dist/formats/lcc/collision-mesh.d.ts +3 -3
- package/dist/formats/lcc/collision-partition.d.ts +1 -1
- package/dist/formats/lcc/lcc.d.ts +3 -3
- package/dist/formats/lcc/lcc2.d.ts +2 -2
- package/dist/formats/lcc/parse-lcc.d.ts +1 -1
- package/dist/formats/lcc.js +17 -16
- package/dist/formats/lcc.js.map +1 -1
- package/dist/formats/ply/index.d.ts +1 -1
- package/dist/formats/ply/parse-compressed-ply.d.ts +2 -2
- package/dist/formats/ply/parse-splat-ply.d.ts +4 -4
- package/dist/formats/ply.js +1 -1
- package/dist/formats/ply.js.map +1 -1
- package/dist/formats/rad/frontier-worker-protocol.d.ts +8 -1
- package/dist/formats/rad/index.d.ts +2 -2
- package/dist/formats/rad/parse-rad.d.ts +2 -2
- package/dist/formats/rad/rad-foveated-source.d.ts +3 -3
- package/dist/formats/rad/rad.d.ts +7 -7
- package/dist/formats/rad.js +3 -3
- package/dist/formats/rad.js.map +1 -1
- package/dist/formats/sog/index.d.ts +1 -1
- package/dist/formats/sog/parse-sog.d.ts +6 -6
- package/dist/formats/sog.js.map +1 -1
- package/dist/formats/splat/index.d.ts +1 -1
- package/dist/formats/splat/parse-splat.d.ts +1 -1
- package/dist/formats/splat.js.map +1 -1
- package/dist/formats/spz/index.d.ts +1 -1
- package/dist/formats/spz/parse-spz.d.ts +1 -1
- package/dist/formats/spz.js.map +1 -1
- package/dist/half-float-Cs4FDq8Q.js.map +1 -1
- package/dist/index.js +253 -9047
- package/dist/index.js.map +1 -1
- package/dist/{chunk-loader.d.ts → loaders/chunk-loader.d.ts} +4 -4
- package/dist/loaders/index.d.ts +15 -0
- package/dist/{load-scene.d.ts → loaders/load-splat-data.d.ts} +16 -14
- package/dist/{load-worker-protocol.d.ts → loaders/load-worker-protocol.d.ts} +2 -2
- package/dist/{loading.d.ts → loaders/loading.d.ts} +8 -8
- package/dist/loaders.js +26 -0
- package/dist/loaders.js.map +1 -0
- package/dist/loading-wLo8vRbA.js.map +1 -1
- package/dist/{splat-mesh-types-CTN_duw2.js → lod-scheduler-B0a_uBlv.js} +133 -140
- package/dist/lod-scheduler-B0a_uBlv.js.map +1 -0
- package/dist/logging-BfPdd7NJ.js.map +1 -1
- package/dist/{ply-header-BwgExCn-.js → ply-header-B9WllbPg.js} +3 -3
- package/dist/ply-header-B9WllbPg.js.map +1 -0
- package/dist/radix-sorter-BrbUg_CV.js +178 -0
- package/dist/radix-sorter-BrbUg_CV.js.map +1 -0
- package/dist/relighting-Tiwep8yd.js +977 -0
- package/dist/relighting-Tiwep8yd.js.map +1 -0
- package/dist/selection/index.d.ts +13 -0
- package/dist/{selection-volume.d.ts → selection/selection-volume.d.ts} +1 -1
- package/dist/{splat-partition.d.ts → selection/splat-partition.d.ts} +2 -2
- package/dist/selection.js +137 -0
- package/dist/selection.js.map +1 -0
- package/dist/sh-pack-D5wAe5gg.js.map +1 -1
- package/dist/{splat-budget-DXew_86c.js → splat-budget-DuVZspPQ.js} +7 -7
- package/dist/splat-budget-DuVZspPQ.js.map +1 -0
- package/dist/splat-data-BZM5dhhx.js.map +1 -1
- package/dist/splat-mesh-CsLOQb08.js +1942 -0
- package/dist/splat-mesh-CsLOQb08.js.map +1 -0
- package/dist/splat-mesh-types-BZIko-_9.js +18 -0
- package/dist/splat-mesh-types-BZIko-_9.js.map +1 -0
- package/dist/static-lod/index.d.ts +12 -0
- package/dist/{static-lod-splat-mesh.d.ts → static-lod/static-lod-splat-mesh.d.ts} +3 -3
- package/dist/{static-lod-worker-protocol.d.ts → static-lod/static-lod-worker-protocol.d.ts} +1 -1
- package/dist/{static-lod.d.ts → static-lod/static-lod.d.ts} +1 -1
- package/dist/{static-lod-worker-D2fyqQZO.js → static-lod-worker-DktKnJkR.js} +46 -46
- package/dist/{static-lod-worker-D2fyqQZO.js.map → static-lod-worker-DktKnJkR.js.map} +1 -1
- package/dist/static-lod.js +148 -0
- package/dist/static-lod.js.map +1 -0
- package/dist/{budget-governor.d.ts → streaming/budget-governor.d.ts} +4 -4
- package/dist/{camera-budget-governor.d.ts → streaming/camera-budget-governor.d.ts} +11 -11
- package/dist/{chunk-cache-budget.d.ts → streaming/chunk-cache-budget.d.ts} +5 -5
- package/dist/{chunk-fetch-scheduler.d.ts → streaming/chunk-fetch-scheduler.d.ts} +4 -4
- package/dist/{dataset-source.d.ts → streaming/dataset-source.d.ts} +1 -1
- package/dist/streaming/index.d.ts +23 -0
- package/dist/{lod-scheduler.d.ts → streaming/lod-scheduler.d.ts} +1 -1
- package/dist/{lod-source.d.ts → streaming/lod-source.d.ts} +9 -9
- package/dist/{streamed-splat-mesh-utils.d.ts → streaming/streamed-splat-mesh-utils.d.ts} +2 -2
- package/dist/{streamed-splat-mesh.d.ts → streaming/streamed-splat-mesh.d.ts} +66 -32
- package/dist/streaming.js +2911 -0
- package/dist/streaming.js.map +1 -0
- package/dist/unified/index.d.ts +11 -0
- package/dist/{unified-splat-renderer.d.ts → unified/unified-splat-mesh.d.ts} +23 -16
- package/dist/unified/unified-work-buffer.d.ts +66 -0
- package/dist/{work-buffer-gather.d.ts → unified/work-buffer-gather.d.ts} +6 -6
- package/dist/{work-buffer-material.d.ts → unified/work-buffer-material.d.ts} +1 -1
- package/dist/unified.js +746 -0
- package/dist/unified.js.map +1 -0
- package/dist/webgpu-limits-Y3CI_6_6.js +43 -0
- package/dist/webgpu-limits-Y3CI_6_6.js.map +1 -0
- package/package.json +27 -7
- package/dist/index.d.ts +0 -54
- package/dist/ply-header-BwgExCn-.js.map +0 -1
- package/dist/splat-budget-DXew_86c.js.map +0 -1
- package/dist/splat-mesh-types-CTN_duw2.js.map +0 -1
- /package/dist/{create-splat-renderer.d.ts → core/create-splat-renderer.d.ts} +0 -0
- /package/dist/{depth-of-field.d.ts → core/depth-of-field.d.ts} +0 -0
- /package/dist/{half-float.d.ts → core/half-float.d.ts} +0 -0
- /package/dist/{logging.d.ts → core/logging.d.ts} +0 -0
- /package/dist/{radix-sort.d.ts → core/radix-sort.d.ts} +0 -0
- /package/dist/{radix-sorter.d.ts → core/radix-sorter.d.ts} +0 -0
- /package/dist/{relighting-pass.d.ts → core/relighting-pass.d.ts} +0 -0
- /package/dist/{sh-pack.d.ts → core/sh-pack.d.ts} +0 -0
- /package/dist/{sort-scheduler.d.ts → core/sort-scheduler.d.ts} +0 -0
- /package/dist/{sort-worker-protocol.d.ts → core/sort-worker-protocol.d.ts} +0 -0
- /package/dist/{sorter.d.ts → core/sorter.d.ts} +0 -0
- /package/dist/{splat-depth-pack.d.ts → core/splat-depth-pack.d.ts} +0 -0
- /package/dist/{splat-mesh-picking.d.ts → core/splat-mesh-picking.d.ts} +0 -0
- /package/dist/{splat-mesh-pool.d.ts → core/splat-mesh-pool.d.ts} +0 -0
- /package/dist/{splat-modifier-stack.d.ts → core/splat-modifier-stack.d.ts} +0 -0
- /package/dist/{splat-query.d.ts → core/splat-query.d.ts} +0 -0
- /package/dist/{splat-sort-bounds.d.ts → core/splat-sort-bounds.d.ts} +0 -0
- /package/dist/{storage-attribute-mirror.d.ts → core/storage-attribute-mirror.d.ts} +0 -0
- /package/dist/{worker-sorter.d.ts → core/worker-sorter.d.ts} +0 -0
- /package/dist/{xr-view.d.ts → core/xr-view.d.ts} +0 -0
- /package/dist/{ply-header.d.ts → loaders/ply-header.d.ts} +0 -0
- /package/dist/{lod-manifest.d.ts → streaming/lod-manifest.d.ts} +0 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@voluma/vlam/streaming` - budgeted LOD streaming for scenes larger than
|
|
3
|
+
* GPU memory.
|
|
4
|
+
*
|
|
5
|
+
* {@link StreamedSplatMesh.load} opens Streamed SOG, LCC / `.lcc2`, and Spark
|
|
6
|
+
* `.rad`. Shared loading errors and request types are re-exported so a host
|
|
7
|
+
* that only imports this entry can still name them.
|
|
8
|
+
*
|
|
9
|
+
* Static auto-LOD lives on `@voluma/vlam/static-lod`.
|
|
10
|
+
*
|
|
11
|
+
* @module streaming
|
|
12
|
+
*/
|
|
13
|
+
export { StreamedSplatMesh, type StreamedSplatMeshOptions, type InitialRevealState, type PersistentChannelOptions, type StreamedSplatPerformanceEvent, } from './streamed-splat-mesh';
|
|
14
|
+
export { BudgetGovernor, type BudgetGovernorOptions, type BudgetGovernedMember, } from './budget-governor';
|
|
15
|
+
export { CameraBudgetGovernor, type CameraBudgetGovernorOptions, type CameraBudgetMember, type CameraBudgetMemberOptions, } from './camera-budget-governor';
|
|
16
|
+
export { ChunkFetchScheduler, type ChunkFetchSchedulerOptions, type ChunkFetchClient, type ChunkFetchHandle, type ChunkFetchKind, } from './chunk-fetch-scheduler';
|
|
17
|
+
export { ChunkCacheBudget, type ChunkCacheBudgetOptions, type ChunkCacheClient, type ChunkCacheHandle, } from './chunk-cache-budget';
|
|
18
|
+
export { httpDatasetSource, createLocalDataset } from './dataset-source';
|
|
19
|
+
export type { SplatDatasetSource, LocalDataset } from './dataset-source';
|
|
20
|
+
export type { CollisionMeshTile } from '../formats/lcc/collision-mesh';
|
|
21
|
+
export type { SplatCollisionData, CollisionMeshDescriptor, EnvironmentTile } from './lod-source';
|
|
22
|
+
export { resolveCpuCacheBytes } from '../core/splat-budget';
|
|
23
|
+
export { SplatLoadError, isAbortError, type SplatProgressCallback, type StreamedSplatFormat, type SplatRequestOptions, type SplatLoadPhase, type SplatInputOptions, } from '../loaders/loading';
|
|
@@ -205,7 +205,7 @@ export declare class LodScheduler implements LodSource {
|
|
|
205
205
|
* Uses leftover budget to restore detail after {@link enforceBudget}
|
|
206
206
|
* demoted leaves, nearest first, while the total stays under the fill
|
|
207
207
|
* target. By default this may also refine *past* the distance-chosen level
|
|
208
|
-
* when headroom remains (octree /
|
|
208
|
+
* when headroom remains (octree / page-table streams). With
|
|
209
209
|
* {@link fillPastDistance} false (classic LCC), fill never goes finer than
|
|
210
210
|
* each leaf's distance-selected level - so a cell at the L1 band does not
|
|
211
211
|
* fetch L0 only to demote moments later with the camera still.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as THREE from 'three/webgpu';
|
|
2
2
|
import { type LodRun } from './lod-scheduler';
|
|
3
|
-
import type { ChunkFileFormat } from '
|
|
4
|
-
import type { RadChunkRangeRequest } from '
|
|
5
|
-
import type { LccChunkParams } from '
|
|
6
|
-
import type { SplatData } from '
|
|
3
|
+
import type { ChunkFileFormat } from '../loaders/loading';
|
|
4
|
+
import type { RadChunkRangeRequest } from '../loaders/load-worker-protocol';
|
|
5
|
+
import type { LccChunkParams } from '../formats/lcc/parse-lcc';
|
|
6
|
+
import type { SplatData } from '../core/splat-data';
|
|
7
7
|
import type { SplatDatasetSource } from './dataset-source';
|
|
8
8
|
/**
|
|
9
9
|
* Per-frame LOD decision maker: given the camera, returns the set of runs
|
|
@@ -106,7 +106,7 @@ export interface CollisionMeshDescriptor {
|
|
|
106
106
|
* Coordinates are source-local, the same frame as {@link StreamedScene.bounds}:
|
|
107
107
|
* {@link StreamedScene.formatTransform} maps them to world.
|
|
108
108
|
*/
|
|
109
|
-
export interface
|
|
109
|
+
export interface SplatCollisionData {
|
|
110
110
|
readonly meshes: readonly CollisionMeshDescriptor[];
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
@@ -155,7 +155,7 @@ export interface StreamedScene {
|
|
|
155
155
|
*/
|
|
156
156
|
readonly formatTransform?: THREE.Matrix4;
|
|
157
157
|
/** Optional collision geometry the format ships; undefined when it has none. */
|
|
158
|
-
readonly collision?:
|
|
158
|
+
readonly collision?: SplatCollisionData;
|
|
159
159
|
/**
|
|
160
160
|
* Optional always-resident environment tile the format ships outside its LOD
|
|
161
161
|
* structure (the `.lcc2` sky) - present only when the dataset carries one.
|
|
@@ -175,13 +175,13 @@ export interface StreamedScene {
|
|
|
175
175
|
/**
|
|
176
176
|
* Splats per chunk file, so a `(file, localIndex)` pair maps to a stable global
|
|
177
177
|
* splat index (`file * chunkSize + local`). Set by `.rad`; the page-table
|
|
178
|
-
* renderer (`foveationMode: '
|
|
178
|
+
* renderer (`foveationMode: 'page-table'`) keys frontier splats by that global.
|
|
179
179
|
*/
|
|
180
180
|
readonly chunkSize?: number;
|
|
181
181
|
/**
|
|
182
182
|
* A chunk the scene builder already fetched and decoded (`.rad` decodes chunk
|
|
183
183
|
* 0 for the scene bounds and the SH codebook). Handing it straight to the
|
|
184
|
-
* renderer saves a second round trip - and in `
|
|
184
|
+
* renderer saves a second round trip - and in `page-table` mode it is what
|
|
185
185
|
* seeds the worker's tree roots, without which the first traversals return an
|
|
186
186
|
* empty frontier and the view stays blank until chunk 0 arrives a second time.
|
|
187
187
|
*/
|
|
@@ -191,7 +191,7 @@ export interface StreamedScene {
|
|
|
191
191
|
};
|
|
192
192
|
/**
|
|
193
193
|
* Source-local xyz subsample of the coarsest overview (`.rad` chunk 0).
|
|
194
|
-
* Survives after
|
|
194
|
+
* Survives after page-table mode transfers chunk-0 buffers to the worker, so
|
|
195
195
|
* a host can estimate terrain height before any later chunk decodes.
|
|
196
196
|
*/
|
|
197
197
|
readonly overviewPositions?: Float32Array;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Scheduling and data helpers shared by the streamed mesh implementation. */
|
|
2
|
-
import type { SplatRange } from '
|
|
3
|
-
import type { SplatData } from '
|
|
2
|
+
import type { SplatRange } from '../core/splat-mesh';
|
|
3
|
+
import type { SplatData } from '../core/splat-data';
|
|
4
4
|
import type { LodRun } from './lod-scheduler';
|
|
5
5
|
/** One resident entry: the run description plus its pool handle. */
|
|
6
6
|
type ResidentEntry = [string, {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
export * from './streamed-splat-mesh-utils';
|
|
2
2
|
import * as THREE from 'three/webgpu';
|
|
3
|
-
import { SplatMesh, type SplatChannelOptions, type SplatMeshOptions, type SplatUpdateOptions } from '
|
|
4
|
-
import type { StaticLodSplatMesh, StaticLodSplatMeshLoadOptions } from './static-lod-splat-mesh';
|
|
3
|
+
import { SplatMesh, type SplatChannelOptions, type SplatMeshOptions, type SplatUpdateOptions } from '../core/splat-mesh';
|
|
5
4
|
import { type StreamedScene } from './lod-source';
|
|
6
|
-
import type { CollisionMeshTile } from '
|
|
7
|
-
import { type SplatRequestOptions, type StreamedSplatFormat } from '
|
|
8
|
-
import { type SplatDeviceProfile } from '
|
|
9
|
-
import { type FrontierFoveation } from '
|
|
5
|
+
import type { CollisionMeshTile } from '../formats/lcc/collision-mesh';
|
|
6
|
+
import { type SplatRequestOptions, type StreamedSplatFormat } from '../loaders/loading';
|
|
7
|
+
import { type SplatDeviceProfile } from '../core/splat-budget';
|
|
8
|
+
import { type FrontierFoveation } from '../formats/rad/frontier-worker-protocol';
|
|
10
9
|
import type { ChunkFetchScheduler } from './chunk-fetch-scheduler';
|
|
11
10
|
import type { ChunkCacheBudget } from './chunk-cache-budget';
|
|
12
11
|
/**
|
|
@@ -87,13 +86,13 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
87
86
|
* should be able to *grow* this mesh's share: the pool is allocated once at
|
|
88
87
|
* construction and never grows, so without headroom reserved here a governed
|
|
89
88
|
* mesh can only ever be shrunk below the budget it was built with. That is
|
|
90
|
-
* the whole reason a hand-split `pool / N`
|
|
91
|
-
* camera - every
|
|
89
|
+
* the whole reason a hand-split `pool / N` mesh stays coarse near the
|
|
90
|
+
* camera - every mesh's ceiling was fixed at a quarter of the pool.
|
|
92
91
|
*
|
|
93
92
|
* It is not free: the pool costs its *ceiling* in memory whether or not the
|
|
94
93
|
* budget ever reaches it (~64 B of GPU pool plus ~56 B of CPU backing per
|
|
95
94
|
* splat, 1.5× for capacity slack). Price it with `estimateSplatPoolBytes`
|
|
96
|
-
* before choosing - for several
|
|
95
|
+
* before choosing - for several additional meshes the
|
|
97
96
|
* sum of the ceilings is what has to fit, not the shared budget. A ceiling
|
|
98
97
|
* around 1.5–2× a member's fair share is usually the right trade.
|
|
99
98
|
*
|
|
@@ -101,12 +100,23 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
101
100
|
* number.
|
|
102
101
|
*/
|
|
103
102
|
maxBudget?: number;
|
|
103
|
+
/**
|
|
104
|
+
* Lets a host that pins {@link budget} and/or {@link maxBudget} still take the
|
|
105
|
+
* finest-level lift for `.rad` strategy selection and pool sizing. Without it,
|
|
106
|
+
* pinning either option disables the lift and a capture whose leaf count sits
|
|
107
|
+
* between the host ceiling and {@link FOVEATION_LEAF_THRESHOLD} incorrectly
|
|
108
|
+
* lands on the foveated page-table path instead of the prefix reader.
|
|
109
|
+
*
|
|
110
|
+
* {@link budgetCap} still vetoes the lift when set. Mobile and fill-constrained
|
|
111
|
+
* desktops remain exempt inside {@link liftBudgetToFinestLevel}.
|
|
112
|
+
*/
|
|
113
|
+
allowFinestLevelLift?: boolean;
|
|
104
114
|
/**
|
|
105
115
|
* Multiplier on this mesh's LOD detail, matching Spark's per-mesh `lodScale`:
|
|
106
116
|
* `> 1` refines further (finer cut, more splats drawn), `< 1` coarsens.
|
|
107
117
|
* Default `1`.
|
|
108
118
|
*
|
|
109
|
-
* **`.rad` `foveationMode: '
|
|
119
|
+
* **`.rad` `foveationMode: 'page-table'` only** - it scales the frontier cut
|
|
110
120
|
* the page-table traversal is given (`pixel_scale × lodScale ≤ limit`, exactly
|
|
111
121
|
* Spark's formula). It does nothing on a mesh with no per-splat cut to scale:
|
|
112
122
|
* a moderate `.rad` read as a chunk prefix, or a Streamed SOG / LCC scene. For
|
|
@@ -128,7 +138,7 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
128
138
|
* later streaming is stopped by {@link SplatMesh.dispose}.
|
|
129
139
|
*/
|
|
130
140
|
signal?: AbortSignal;
|
|
131
|
-
/** Base URL a relative manifest URL resolves against (like {@link
|
|
141
|
+
/** Base URL a relative manifest URL resolves against (like {@link loadSplatData}). */
|
|
132
142
|
baseUrl?: string | URL;
|
|
133
143
|
/** World-unit distance inside which the finest LOD is used. Default 10. */
|
|
134
144
|
lodBaseDistance?: number;
|
|
@@ -186,7 +196,7 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
186
196
|
* to `'progressive'`.
|
|
187
197
|
*/
|
|
188
198
|
initialReveal?: 'progressive' | 'hold-near-l0' | 'hold-coverage';
|
|
189
|
-
/** Receives lightweight LOD
|
|
199
|
+
/** Receives lightweight LOD mutation events for performance attribution. */
|
|
190
200
|
onPerformanceEvent?: (event: StreamedSplatPerformanceEvent) => void;
|
|
191
201
|
/**
|
|
192
202
|
* View-dependent color (higher-order SH). This is the streaming counterpart
|
|
@@ -234,7 +244,7 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
234
244
|
* or suspended, and has one effect on its own: the background sweep that
|
|
235
245
|
* pre-warms the whole capture into the page-table cache stops. That sweep is
|
|
236
246
|
* pure speculation about a camera move that has not happened, and on a
|
|
237
|
-
* multi-
|
|
247
|
+
* multi-mesh scene it is most of the traffic competing with the mesh the
|
|
238
248
|
* viewer is actually looking at.
|
|
239
249
|
*
|
|
240
250
|
* Unset (the default) leaves fetching exactly as it was: every mesh sweeps.
|
|
@@ -244,8 +254,8 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
244
254
|
/**
|
|
245
255
|
* Scene-wide fetch arbitration, shared by every streamed mesh the way a
|
|
246
256
|
* {@link SplatMeshOptions.pool} is - see {@link ChunkFetchScheduler}. Without
|
|
247
|
-
* one, each mesh fetches toward its own in-flight cap and a near
|
|
248
|
-
* detail queues behind a dozen far
|
|
257
|
+
* one, each mesh fetches toward its own in-flight cap and a near mesh's
|
|
258
|
+
* detail queues behind a dozen far meshes' background traffic.
|
|
249
259
|
*
|
|
250
260
|
* The scheduler is *not* owned by the mesh: dispose unregisters this mesh and
|
|
251
261
|
* leaves the scheduler running for its siblings. Weights come from
|
|
@@ -261,7 +271,7 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
|
|
|
261
271
|
* Without one, each `.rad` page-table mesh caps its own cache at
|
|
262
272
|
* `max(cpuCacheBytes, min(2 GiB, this capture's decoded size))`: the right
|
|
263
273
|
* number for a lone streamed scene, and no bound at all across a scene of
|
|
264
|
-
*
|
|
274
|
+
* additional meshes, because every mesh gets its own and each is sized to its own
|
|
265
275
|
* capture. With one, that figure becomes this mesh's *ceiling* and the budget
|
|
266
276
|
* splits a scene total across every registered mesh by camera weight.
|
|
267
277
|
*
|
|
@@ -328,11 +338,6 @@ export interface PersistentChannelOptions extends SplatChannelOptions {
|
|
|
328
338
|
* `docs/formats/streamed-shn-notes.md`).
|
|
329
339
|
*/
|
|
330
340
|
export declare class StreamedSplatMesh extends SplatMesh {
|
|
331
|
-
/**
|
|
332
|
-
* Loads a non-streamed splat file into a worker-built merged hierarchy.
|
|
333
|
-
* The returned static mesh shares this class's runtime budget contract.
|
|
334
|
-
*/
|
|
335
|
-
static loadAutoLod(input: string | URL, options: StaticLodSplatMeshLoadOptions): Promise<StaticLodSplatMesh>;
|
|
336
341
|
private readonly scene;
|
|
337
342
|
private readonly loader;
|
|
338
343
|
/**
|
|
@@ -399,7 +404,7 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
399
404
|
private lodLevelScratch;
|
|
400
405
|
/** Desired-but-not-resident files this tick; protected from cache eviction. */
|
|
401
406
|
private readonly neededFiles;
|
|
402
|
-
/** Non-null in `foveationMode: '
|
|
407
|
+
/** Non-null in `foveationMode: 'page-table'`: the worker that owns the chunk
|
|
403
408
|
* cache + traversal + pager off the main thread, and the always-active slab it
|
|
404
409
|
* pages the returned frontier into. */
|
|
405
410
|
private readonly frontierWorker;
|
|
@@ -454,8 +459,17 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
454
459
|
* governed budget outgrows it, rather than the library's own default. */
|
|
455
460
|
private pageTableDrawTargetExplicit;
|
|
456
461
|
/** Last frontier's drawn (non-degenerate) splat count - the true on-screen size
|
|
457
|
-
* in `
|
|
462
|
+
* in `page-table` mode, where the slab is fully "active" but mostly degenerate. */
|
|
458
463
|
private pageTableDrawn;
|
|
464
|
+
private frontierConverged;
|
|
465
|
+
private pendingFrontierSplats;
|
|
466
|
+
private staleResidentSplats;
|
|
467
|
+
private lastPlanAppends;
|
|
468
|
+
private lastPlanMoves;
|
|
469
|
+
private lastPlanGeneration;
|
|
470
|
+
private lastPlanBudget;
|
|
471
|
+
private lastPlanCamera;
|
|
472
|
+
private firstFrontierCamera;
|
|
459
473
|
/** Monotonic reschedule id; a stale plan (superseded by a newer request) is
|
|
460
474
|
* dropped. `pageTableInFlight` coalesces to one outstanding traversal. */
|
|
461
475
|
private pageTableSeq;
|
|
@@ -563,8 +577,8 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
563
577
|
* tells the worker's pager the new slot count.
|
|
564
578
|
*
|
|
565
579
|
* This is the mechanism that makes a shared pool worth having: storage follows
|
|
566
|
-
* the governed budget, so approaching a
|
|
567
|
-
* behind you hand theirs back, instead of every
|
|
580
|
+
* the governed budget, so approaching a mesh grows its pages while the ones
|
|
581
|
+
* behind you hand theirs back, instead of every mesh holding its ceiling for
|
|
568
582
|
* the whole session. Growth stops at the construction ceiling and at whatever
|
|
569
583
|
* the pool can actually spare - a mesh that cannot grow simply stays coarse
|
|
570
584
|
* rather than throwing.
|
|
@@ -680,17 +694,37 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
680
694
|
* `undefined` when the format does not declare a content size.
|
|
681
695
|
*/
|
|
682
696
|
get contentSplatCount(): number | undefined;
|
|
697
|
+
/**
|
|
698
|
+
* Which `.rad` streaming strategy this mesh selected at load, or `null` when
|
|
699
|
+
* the scene is not a Spark `.rad` capture.
|
|
700
|
+
*/
|
|
701
|
+
get radStrategy(): 'prefix' | 'page-table' | null;
|
|
683
702
|
/**
|
|
684
703
|
* The drawn-splat target currently driving the `.rad` page-table frontier -
|
|
685
704
|
* the governed budget, capped by
|
|
686
705
|
* {@link SplatMeshOptions.foveationDrawBudget}. `0` on a mesh that is not in
|
|
687
|
-
* `foveationMode: '
|
|
706
|
+
* `foveationMode: 'page-table'`, which has no frontier to target.
|
|
688
707
|
*
|
|
689
708
|
* This is the number that decides how deep the traversal descends, so it is
|
|
690
709
|
* what to watch when checking that a near mesh really did receive more
|
|
691
710
|
* detail: {@link budget} is the pool's allowance, this is what is spent.
|
|
692
711
|
*/
|
|
693
712
|
get drawBudget(): number;
|
|
713
|
+
/**
|
|
714
|
+
* Page-table frontier coherence for hosts that gate preload/transitions.
|
|
715
|
+
* `undefined` fields stay 0 when this mesh is not in page-table mode.
|
|
716
|
+
*/
|
|
717
|
+
get frontierState(): Readonly<{
|
|
718
|
+
frontierConverged: boolean;
|
|
719
|
+
pendingFrontierSplats: number;
|
|
720
|
+
staleResidentSplats: number;
|
|
721
|
+
lastPlanAppends: number;
|
|
722
|
+
lastPlanMoves: number;
|
|
723
|
+
planGeneration: number;
|
|
724
|
+
planBudget: number;
|
|
725
|
+
lastPlanCamera: readonly [number, number, number] | null;
|
|
726
|
+
firstFrontierCamera: readonly [number, number, number] | null;
|
|
727
|
+
}>;
|
|
694
728
|
/**
|
|
695
729
|
* Spark's per-mesh `lodScale` (see {@link StreamedSplatMeshOptions.lodScale}).
|
|
696
730
|
* Mutable: raise it to sharpen a focused mesh, lower it to coarsen a
|
|
@@ -700,7 +734,7 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
700
734
|
*/
|
|
701
735
|
get lodScale(): number;
|
|
702
736
|
set lodScale(value: number);
|
|
703
|
-
/** In `
|
|
737
|
+
/** In `page-table` mode the slab is fully active but mostly degenerate, so the
|
|
704
738
|
* base `activeSplatCount` (slab size) is not the on-screen count - report the
|
|
705
739
|
* frontier's drawn size instead. */
|
|
706
740
|
get activeSplatCount(): number;
|
|
@@ -736,7 +770,7 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
736
770
|
/** Chunk fetches currently in flight. */
|
|
737
771
|
get pendingChunkCount(): number;
|
|
738
772
|
/**
|
|
739
|
-
* Main-thread cost of applying paging plans in `foveationMode: '
|
|
773
|
+
* Main-thread cost of applying paging plans in `foveationMode: 'page-table'`.
|
|
740
774
|
*
|
|
741
775
|
* A plan is applied whole, off the render loop's own timing, so its cost does
|
|
742
776
|
* not appear in {@link getUpdateTimings} - but it lands on the same thread and
|
|
@@ -906,7 +940,7 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
906
940
|
* and it starts enabled. Failed / unfit / disabled tiles do not block reveal.
|
|
907
941
|
*/
|
|
908
942
|
private environmentPendingForReveal;
|
|
909
|
-
/** Creates a
|
|
943
|
+
/** Creates a performance event for a changed streamed-LOD tick, if any. */
|
|
910
944
|
private createPerformanceEvent;
|
|
911
945
|
/** Returns whether all new rows can coexist with the currently visible region. */
|
|
912
946
|
private canStageGroup;
|
|
@@ -963,7 +997,7 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
963
997
|
/** Ranks the env tile ahead of every LOD want in {@link flushClassicFetches}. */
|
|
964
998
|
private enqueueEnvironmentFetch;
|
|
965
999
|
/**
|
|
966
|
-
* Page-table reschedule (`foveationMode: '
|
|
1000
|
+
* Page-table reschedule (`foveationMode: 'page-table'`): posts the camera to the
|
|
967
1001
|
* worker, which owns the cache + traversal + pager and replies asynchronously
|
|
968
1002
|
* with a paging plan. Coalesced to one outstanding request so the main thread
|
|
969
1003
|
* never blocks. Also drives chunk fetching, in priority order.
|
|
@@ -979,8 +1013,8 @@ export declare class StreamedSplatMesh extends SplatMesh {
|
|
|
979
1013
|
* worker's cache/traversal/gather can use it. */
|
|
980
1014
|
private forwardChunkToWorker;
|
|
981
1015
|
/** Parallel chunk fetches. HTTP/2 multiplexes them; on HTTP/1.1 the browser's
|
|
982
|
-
* per-host cap simply queues. Same cap for classic and
|
|
983
|
-
* detail is not structurally starved on the non-
|
|
1016
|
+
* per-host cap simply queues. Same cap for classic and page-table so near
|
|
1017
|
+
* detail is not structurally starved on the non-page-table path. */
|
|
984
1018
|
private get maxInflight();
|
|
985
1019
|
/**
|
|
986
1020
|
* Whether this mesh may run its speculative background sweep. A mesh with no
|