@voluma/vlam 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.
@@ -32,12 +32,17 @@ export interface LodSource {
32
32
  */
33
33
  runsAtLevelFor?(from: number, to: number, level: number): LodRun[];
34
34
  /**
35
- * Coarsest covering runs for finest cells currently in the camera frustum.
36
- * Used by `.lcc2` startup `initialReveal: 'hold-coverage'` so the first
37
- * painted frame has no empty cells. Optional: sources without a nested
38
- * octree cover leave it undefined (the hold then stays disabled).
35
+ * Covering runs for finest cells currently in the camera frustum (or
36
+ * containing the camera). Used by `.lcc` / `.lcc2` startup
37
+ * `initialReveal: 'hold-coverage'` so the first painted frame has no empty
38
+ * cells. Classic LCC freezes nearby groups at finest+1 and farther in-view
39
+ * groups at coarsest; `.lcc2` still returns coarsest root-children.
40
+ * `cameraForward` (mesh-local) lets classic LCC ignore full-Z cells that
41
+ * sit entirely behind the camera plane — their AABBs otherwise hit the
42
+ * frustum from every indoor pose. Optional: sources without coverage groups
43
+ * or a nested octree cover leave it undefined (the hold then stays disabled).
39
44
  */
40
- coverageRunsFor?(cameraLocal: THREE.Vector3, frustum: THREE.Frustum): LodRun[];
45
+ coverageRunsFor?(cameraLocal: THREE.Vector3, frustum: THREE.Frustum, cameraForward?: THREE.Vector3): LodRun[];
41
46
  /**
42
47
  * Notified when a chunk finishes decoding, so a source that discovers its
43
48
  * structure from chunk payloads (a `.rad` LOD tree lives in the chunks, not
@@ -75,10 +80,11 @@ export interface StreamedChunkOptions {
75
80
  }
76
81
  /**
77
82
  * A single always-resident environment/background tile a format ships outside
78
- * its LOD structure - the `.lcc2` `env.sog` sky, loaded once and toggled with
79
- * {@link StreamedSplatMesh.setEnvironmentEnabled} rather than scheduled by
80
- * camera distance. Its splat count is absent from the manifest and measured
81
- * when the tile decodes (see `docs/formats/lcc2-notes.md`).
83
+ * its LOD structure - classic `.lcc` `environment.bin` and `.lcc2` `env.sog`,
84
+ * loaded once and toggled with {@link StreamedSplatMesh.setEnvironmentEnabled}
85
+ * rather than scheduled by camera distance. `.lcc2` measures the splat count
86
+ * at decode (see `docs/formats/lcc2-notes.md`); classic `.lcc` sizes it from
87
+ * the file length.
82
88
  */
83
89
  export interface EnvironmentTile {
84
90
  /** Chunk-file index (into {@link StreamedScene.chunkUrls}) of the tile. */
@@ -23,7 +23,8 @@ export declare function estimateSceneDecodedBytes(scene: StreamedScene): number;
23
23
  /**
24
24
  * Read-only startup-hold progress for {@link StreamedSplatMeshOptions.initialReveal}.
25
25
  * Exported for hosts that gate visibility on the first useful coverage frame
26
- * (classic `.lcc` nearby L0, or `.lcc2` in-view coarsest cells).
26
+ * (classic `.lcc` nearby L1 / far coarsest, `.lcc2` in-view coarsest, or an
27
+ * explicit nearby-L0 hold).
27
28
  */
28
29
  export type InitialRevealState = {
29
30
  readonly status: 'disabled';
@@ -172,28 +173,35 @@ export interface StreamedSplatMeshOptions extends SplatMeshOptions {
172
173
  * - `'progressive'`: cells become visible as each swap group commits — can
173
174
  * show sparse near-detail (classic `.lcc`) or empty octree squares
174
175
  * (`.lcc2`) while siblings load.
175
- * - `'hold-near-l0'` (the default for classic `.lcc` when unset): hide the
176
- * mesh until the camera's home coverage group is resident (L0 when it fits;
177
- * otherwise coarsen via the leaf ladder L1→L2). Neighbours are not part of
178
- * the hold - they compete via screenImportance and would steal the first
179
- * fetch slots. Home selection uses distance within `lodBaseDistance` and
180
- * does not require frustum intersection (HiRes tiles often fail `inView`
181
- * when the camera stands inside looking out). Coarser rungs come from
182
- * `LodSource.runsAtLevelFor`. Only home files are fetched during the hold.
183
- * A one-minute watchdog also degrades if the cut cannot finish.
184
- * - `'hold-coverage'` (the default for `.lcc2` when unset): hide the mesh
185
- * until every in-view finest cell has a coarsest covering node resident
186
- * (any LOD), and until the always-resident environment tile is in the pool
187
- * when the scene ships one and it starts enabled. Does not wait for finest
188
- * tiles or the rest of the stream. An empty frustum falls back to the
189
- * nearest cell. Requires `LodSource.coverageRunsFor`; other formats treat
190
- * this as disabled.
176
+ * - `'hold-near-l0'` (opt-in): hide the mesh until the camera's home coverage
177
+ * group is resident (L0 when it fits; otherwise coarsen via the leaf ladder
178
+ * L1→L2). Neighbours are not part of the hold - they compete via
179
+ * screenImportance and would steal the first fetch slots. Home selection
180
+ * uses distance within `lodBaseDistance` and does not require frustum
181
+ * intersection (HiRes tiles often fail `inView` when the camera stands
182
+ * inside looking out). Coarser rungs come from `LodSource.runsAtLevelFor`.
183
+ * Only home files are fetched during the hold. A one-minute watchdog also
184
+ * degrades if the cut cannot finish. Classic `.lcc` uses the **resolved**
185
+ * cut from the first schedule (after camera + format transform), not
186
+ * distance ambition alone.
187
+ * - `'hold-coverage'` (the default for classic `.lcc` and `.lcc2` when
188
+ * unset): hide the mesh until every in-view finest cell has covering
189
+ * coverage resident, and until the always-resident environment tile is in
190
+ * the pool when the scene ships one and it starts enabled. Classic `.lcc`
191
+ * freezes nearby cells (within `lodBaseDistance · lodMultiplier`) at
192
+ * finest+1 (L1, never L0) and farther in-view cells at coarsest. A cell
193
+ * counts as in-view when the camera stands inside it, or when the unpadded
194
+ * AABB hits the frustum and pokes in front of the camera plane (support
195
+ * vertex — centres behind the look still count), **or** the cell is within
196
+ * `lodBaseDistance` and pokes forward (30 m neighbours that fill the
197
+ * frame while the look is off-axis). `.lcc2` still waits on
198
+ * coarsest root-children. Does not wait for finest tiles or the rest of
199
+ * the stream. An empty frustum falls back to the nearest cell. Requires
200
+ * `LodSource.coverageRunsFor`; other formats treat this as disabled.
191
201
  *
192
202
  * A one-minute watchdog degrades to progressive if the frozen set cannot
193
- * finish. Does not make detail downloads instantaneous. Classic `.lcc` uses
194
- * the **resolved** cut from the first schedule (after camera + format
195
- * transform), not distance ambition alone. Other streamed formats default
196
- * to `'progressive'`.
203
+ * finish. Does not make detail downloads instantaneous. Other streamed
204
+ * formats default to `'progressive'`.
197
205
  */
198
206
  initialReveal?: 'progressive' | 'hold-near-l0' | 'hold-coverage';
199
207
  /** Receives lightweight LOD mutation events for performance attribution. */
@@ -927,11 +935,19 @@ export declare class StreamedSplatMesh extends SplatMesh {
927
935
  private publishInitialRevealProgress;
928
936
  private releaseInitialReveal;
929
937
  /**
930
- * `.lcc2` coverage hold: freeze coarsest covering runs for in-view cells.
938
+ * Coverage hold: freeze covering runs for in-view cells (classic `.lcc`
939
+ * physical cells at L1 near / coarsest far, `.lcc2` octree root-children).
931
940
  * Missing `coverageRunsFor` (or an empty result after fallback) releases
932
941
  * immediately so the mesh does not stay hidden with nothing to fetch.
942
+ * If the mixed set overflows the pool, coarsen only the near (non-coarsest)
943
+ * groups one more rung before degrading to progressive.
933
944
  */
934
945
  private captureCoverageHold;
946
+ /**
947
+ * Bump each coverage run one coarser rung when the source has one. Already-
948
+ * coarsest (far) runs stay put so a tight pool only drops near L1 → L2.
949
+ */
950
+ private coarsenCoverageNearRuns;
935
951
  private captureOrContinueInitialReveal;
936
952
  /** After staging/commits, release the hold when every frozen run is resident. */
937
953
  private finishInitialRevealIfComplete;