gaussian-splat-lite 1.3.0 → 1.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.
Files changed (64) hide show
  1. package/CHANGELOG.md +44 -1
  2. package/dist/gaussian-splat-lite.cjs +498 -268
  3. package/dist/gaussian-splat-lite.cjs.map +1 -1
  4. package/dist/gaussian-splat-lite.min.cjs +169 -131
  5. package/dist/gaussian-splat-lite.min.cjs.map +1 -1
  6. package/dist/gaussian-splat-lite.module.js +498 -268
  7. package/dist/gaussian-splat-lite.module.js.map +1 -1
  8. package/dist/gaussian-splat-lite.module.min.js +2428 -2241
  9. package/dist/gaussian-splat-lite.module.min.js.map +1 -1
  10. package/dist/types/data/IndexedSplats.d.cts +12 -5
  11. package/dist/types/data/IndexedSplats.d.ts +12 -5
  12. package/dist/types/data/RadPagedSplats.d.cts +1 -0
  13. package/dist/types/data/RadPagedSplats.d.ts +1 -0
  14. package/dist/types/data/SplatOpacityTable.d.cts +9 -2
  15. package/dist/types/data/SplatOpacityTable.d.ts +9 -2
  16. package/dist/types/data/Splats.d.cts +1 -1
  17. package/dist/types/data/Splats.d.ts +1 -1
  18. package/dist/types/data/defines.d.cts +6 -4
  19. package/dist/types/data/defines.d.ts +6 -4
  20. package/dist/types/data/splatData.d.cts +10 -3
  21. package/dist/types/data/splatData.d.ts +10 -3
  22. package/dist/types/loaders/postDecode/builder.d.cts +1 -1
  23. package/dist/types/loaders/postDecode/builder.d.ts +1 -1
  24. package/dist/types/loaders/postDecode/protocol.d.cts +7 -5
  25. package/dist/types/loaders/postDecode/protocol.d.ts +7 -5
  26. package/dist/types/loaders/stream/StreamWorkerPool.d.cts +1 -4
  27. package/dist/types/loaders/stream/StreamWorkerPool.d.ts +1 -4
  28. package/dist/types/loaders/stream/rad-stream/RadSelectionState.d.cts +7 -4
  29. package/dist/types/loaders/stream/rad-stream/RadSelectionState.d.ts +7 -4
  30. package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.cts +20 -17
  31. package/dist/types/loaders/stream/rad-stream/RadStreamLoader.d.ts +20 -17
  32. package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.cts +18 -2
  33. package/dist/types/loaders/stream/rad-stream/RadStreamScheduler.d.ts +18 -2
  34. package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.cts +1 -1
  35. package/dist/types/loaders/stream/rad-stream/RadStreamWorker.d.ts +1 -1
  36. package/dist/types/loaders/stream/rad-stream/prepareRadSelection.d.cts +7 -16
  37. package/dist/types/loaders/stream/rad-stream/prepareRadSelection.d.ts +7 -16
  38. package/dist/types/loaders/stream/rad-stream/radLod.d.cts +4 -2
  39. package/dist/types/loaders/stream/rad-stream/radLod.d.ts +4 -2
  40. package/dist/types/loaders/stream/rad-stream/workerHandlers.d.cts +29 -58
  41. package/dist/types/loaders/stream/rad-stream/workerHandlers.d.ts +29 -58
  42. package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.cts +0 -1
  43. package/dist/types/loaders/stream/sog-stream/SogStreamBatch.d.ts +0 -1
  44. package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.cts +2 -2
  45. package/dist/types/loaders/stream/sog-stream/SogStreamLoader.d.ts +2 -2
  46. package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.cts +22 -2
  47. package/dist/types/loaders/stream/sog-stream/SogStreamScheduler.d.ts +22 -2
  48. package/dist/types/loaders/stream/sog-stream/sogLod.d.cts +16 -10
  49. package/dist/types/loaders/stream/sog-stream/sogLod.d.ts +16 -10
  50. package/dist/types/loaders/stream/sog-stream/sogVisibility.d.cts +4 -6
  51. package/dist/types/loaders/stream/sog-stream/sogVisibility.d.ts +4 -6
  52. package/dist/types/loaders/stream/sog-stream/workerHandlers.d.cts +2 -8
  53. package/dist/types/loaders/stream/sog-stream/workerHandlers.d.ts +2 -8
  54. package/dist/types/loaders/stream/streamOptions.d.cts +9 -8
  55. package/dist/types/loaders/stream/streamOptions.d.ts +9 -8
  56. package/docs/PostDecode.md +2 -2
  57. package/docs/RadStreamScheduler.md +14 -5
  58. package/docs/SogStreamScheduler.md +8 -6
  59. package/docs/SplatFileType.md +2 -0
  60. package/docs/SplatMesh.md +1 -1
  61. package/docs/Splats.md +1 -1
  62. package/package.json +1 -1
  63. package/dist/types/loaders/stream/StreamByteBudget.d.cts +0 -7
  64. package/dist/types/loaders/stream/StreamByteBudget.d.ts +0 -7
@@ -3,8 +3,16 @@ import type { StreamResolutionSource } from "../StreamCameras.js";
3
3
  import type { StreamSchedulerOptions, StreamStats } from "../streamOptions.js";
4
4
  import type { RadStreamLoaderOptions } from "./RadStreamLoader.js";
5
5
  export type RadStreamSchedulerOptions = RadStreamLoaderOptions &
6
- StreamSchedulerOptions;
6
+ StreamSchedulerOptions & {
7
+ /** Allowed fractional splat budget overshoot. Default: 0.1; 0 forbids overshoot. */
8
+ splatBudgetTolerance?: number;
9
+ /** Retained CPU byte budget, excluding pending copies and WASM. Default: 2 GiB. */
10
+ maxResidentCpuBytes?: number;
11
+ /** Estimated GPU byte budget for resident streaming data. Default: 1 GiB. */
12
+ maxResidentGpuBytes?: number;
13
+ };
7
14
  export type RadStreamStats = StreamStats & {
15
+ /** Resident page limit derived from the smaller CPU/GPU allowance. */
8
16
  pageBudget: number;
9
17
  lodTimeMs: number;
10
18
  };
@@ -17,7 +25,10 @@ export declare class RadStreamScheduler {
17
25
  readonly cooldownMs: number;
18
26
  readonly fadeDurationMs: number;
19
27
  readonly maxConcurrentLoads: number;
28
+ readonly maxResidentCpuBytes: number;
29
+ readonly maxResidentGpuBytes: number;
20
30
  private _splatBudget;
31
+ private _splatBudgetTolerance;
21
32
  private readonly loader;
22
33
  private readonly abort;
23
34
  private readonly streamCameras;
@@ -46,9 +57,12 @@ export declare class RadStreamScheduler {
46
57
  private resolveFirst;
47
58
  private rejectFirst;
48
59
  constructor(options: RadStreamSchedulerOptions);
49
- /** Selected-node budget. Assigning a new value requests LOD selection. */
60
+ /** Target selected-node budget. Assigning a new value requests LOD selection. */
50
61
  get splatBudget(): number;
51
62
  set splatBudget(value: number);
63
+ /** Allowed fractional budget overshoot; zero forbids overshoot. */
64
+ get splatBudgetTolerance(): number;
65
+ set splatBudgetTolerance(value: number);
52
66
  /** Cameras that select detail, in registration order. */
53
67
  get cameras(): readonly THREE.Camera[];
54
68
  hasCamera(camera: THREE.Camera): boolean;
@@ -84,6 +98,7 @@ export declare class RadStreamScheduler {
84
98
  * detail any of them needs.
85
99
  */
86
100
  update(): boolean;
101
+ private get selectionBaselineId();
87
102
  private requestSelection;
88
103
  private selectionPagesReady;
89
104
  private prepareSelection;
@@ -102,6 +117,7 @@ export declare class RadStreamScheduler {
102
117
  private reservePages;
103
118
  private uploadPages;
104
119
  private releasePage;
120
+ private isPageRequired;
105
121
  private releaseUnused;
106
122
  /** Map a raycast hit's rendered index back to its stable file index. */
107
123
  getGlobalIndex(mesh: THREE.Object3D, renderedIndex: number): number;
@@ -1,6 +1,6 @@
1
1
  import { WorkerRpc } from "../../../runtime/WorkerRpc.cjs";
2
2
  import type { RadStreamRpcHandlers } from "./worker.cjs";
3
- /** Worker assigned either LOD ownership or a persistent page decoder. */
3
+ /** Worker assigned traversal, display preparation, or page decoding. */
4
4
  export declare class RadStreamWorker extends WorkerRpc<RadStreamRpcHandlers> {
5
5
  constructor(onDispose?: () => void);
6
6
  }
@@ -1,6 +1,6 @@
1
1
  import { WorkerRpc } from "../../../runtime/WorkerRpc.js";
2
2
  import type { RadStreamRpcHandlers } from "./worker.js";
3
- /** Worker assigned either LOD ownership or a persistent page decoder. */
3
+ /** Worker assigned traversal, display preparation, or page decoding. */
4
4
  export declare class RadStreamWorker extends WorkerRpc<RadStreamRpcHandlers> {
5
5
  constructor(onDispose?: () => void);
6
6
  }
@@ -8,25 +8,16 @@ export type RadSelectionChunk = Pick<
8
8
  RadLodChunk,
9
9
  "sourceToStorage" | "boundsBlocks"
10
10
  >;
11
+ export type RadSelectionPreparation = {
12
+ selection: Omit<RadStreamSelection, "fade">;
13
+ fade: boolean;
14
+ pools: RadPreparedSelection[];
15
+ };
11
16
  /** The scheduler snapshots and pins resident pages before dispatching this work. */
12
17
  export declare function prepareRadSelection(
13
- {
14
- selection,
15
- pools,
16
- }: {
18
+ request: {
17
19
  selection: RadStreamSelection;
18
20
  pools: RadSelectionSnapshot[];
19
21
  },
20
22
  chunks: ReadonlyMap<number, RadSelectionChunk>,
21
- ): {
22
- selection: {
23
- indices: Uint32Array;
24
- wantedChunks: Uint32Array;
25
- touchedChunks: Uint32Array;
26
- selectionId: number;
27
- changedChunks: Uint32Array;
28
- };
29
- fade: boolean;
30
- pools: RadPreparedSelection[];
31
- };
32
- export type RadSelectionPreparation = ReturnType<typeof prepareRadSelection>;
23
+ ): RadSelectionPreparation;
@@ -8,25 +8,16 @@ export type RadSelectionChunk = Pick<
8
8
  RadLodChunk,
9
9
  "sourceToStorage" | "boundsBlocks"
10
10
  >;
11
+ export type RadSelectionPreparation = {
12
+ selection: Omit<RadStreamSelection, "fade">;
13
+ fade: boolean;
14
+ pools: RadPreparedSelection[];
15
+ };
11
16
  /** The scheduler snapshots and pins resident pages before dispatching this work. */
12
17
  export declare function prepareRadSelection(
13
- {
14
- selection,
15
- pools,
16
- }: {
18
+ request: {
17
19
  selection: RadStreamSelection;
18
20
  pools: RadSelectionSnapshot[];
19
21
  },
20
22
  chunks: ReadonlyMap<number, RadSelectionChunk>,
21
- ): {
22
- selection: {
23
- indices: Uint32Array;
24
- wantedChunks: Uint32Array;
25
- touchedChunks: Uint32Array;
26
- selectionId: number;
27
- changedChunks: Uint32Array;
28
- };
29
- fade: boolean;
30
- pools: RadPreparedSelection[];
31
- };
32
- export type RadSelectionPreparation = ReturnType<typeof prepareRadSelection>;
23
+ ): RadSelectionPreparation;
@@ -1,5 +1,5 @@
1
1
  import type { RadMeta } from "../../rad/radFormat.cjs";
2
- /** CPU-only data retained in the dataset worker, never GPU source storage. */
2
+ /** CPU-only page data split between traversal and display preparation workers. */
3
3
  export type RadLodChunk = {
4
4
  centers: Float32Array;
5
5
  radii: Float32Array;
@@ -22,9 +22,11 @@ export type RadLodView = {
22
22
  export type RadLodRequest = {
23
23
  views: RadLodView[];
24
24
  splatBudget: number;
25
+ splatBudgetTolerance: number;
26
+ /** Combined limit for resident tree paths and requested pages. */
27
+ pageBudget: number;
25
28
  pixelThreshold: number;
26
29
  residentChunks: number[];
27
- hysteresis?: number;
28
30
  };
29
31
  export type RadLodSelection = {
30
32
  /** Stable file indices. The scheduler maps these to occupied GPU slots. */
@@ -1,5 +1,5 @@
1
1
  import type { RadMeta } from "../../rad/radFormat.js";
2
- /** CPU-only data retained in the dataset worker, never GPU source storage. */
2
+ /** CPU-only page data split between traversal and display preparation workers. */
3
3
  export type RadLodChunk = {
4
4
  centers: Float32Array;
5
5
  radii: Float32Array;
@@ -22,9 +22,11 @@ export type RadLodView = {
22
22
  export type RadLodRequest = {
23
23
  views: RadLodView[];
24
24
  splatBudget: number;
25
+ splatBudgetTolerance: number;
26
+ /** Combined limit for resident tree paths and requested pages. */
27
+ pageBudget: number;
25
28
  pixelThreshold: number;
26
29
  residentChunks: number[];
27
- hysteresis?: number;
28
30
  };
29
31
  export type RadLodSelection = {
30
32
  /** Stable file indices. The scheduler maps these to occupied GPU slots. */
@@ -1,89 +1,60 @@
1
- import type { RadReadRequest } from "../../rad/RadSource.cjs";
2
- import type { RadHeader } from "../../rad/radFormat.cjs";
1
+ import type { RadReadRequest, RadResourceState } from "../../rad/RadSource.cjs";
2
+ import type { RadHeader, RadStreamChunk } from "../../rad/radFormat.cjs";
3
3
  import type {
4
4
  RadSelectionReply,
5
5
  RadSelectionRequest,
6
6
  } from "./RadSelectionState.cjs";
7
- import type { prepareRadSelection } from "./prepareRadSelection.cjs";
7
+ import type {
8
+ RadSelectionChunk,
9
+ RadSelectionPreparation,
10
+ prepareRadSelection,
11
+ } from "./prepareRadSelection.cjs";
8
12
  import type { RadLodChunk } from "./radLod.cjs";
9
- /** Each worker initializes once as either the dataset LOD tree or a page decoder. */
13
+ /** Workers own LOD traversal, display preparation, or a persistent page decoder. */
10
14
  export declare function createRadStreamHandlers(): {
11
- prepareRadSelection(request: Parameters<typeof prepareRadSelection>[0]): {
12
- selection: {
13
- indices: Uint32Array;
14
- wantedChunks: Uint32Array;
15
- touchedChunks: Uint32Array;
16
- selectionId: number;
17
- changedChunks: Uint32Array;
18
- };
19
- fade: boolean;
20
- pools: import("../../../data/RadPagedSplats.cjs").RadPreparedSelection[];
21
- };
22
- initializeRad({
23
- bytes,
24
- }: {
25
- bytes: Uint8Array;
26
- }): RadHeader;
27
- initializeRadDecoder({
28
- header: value,
29
- rootBytes,
30
- }: {
15
+ prepareRadSelection(
16
+ request: Parameters<typeof prepareRadSelection>[0],
17
+ ): RadSelectionPreparation;
18
+ initializeRad(request: { bytes: Uint8Array }): RadHeader;
19
+ initializeRadDecoder(request: {
31
20
  header: RadHeader;
32
21
  rootBytes?: Uint8Array;
33
22
  }): void;
34
23
  loadRadChunk(
35
- {
36
- index,
37
- generation,
38
- request,
39
- }: {
24
+ args: {
40
25
  index: number;
41
26
  generation: number;
42
27
  request: RadReadRequest;
43
28
  },
44
- {
45
- sendStatus,
46
- }: {
29
+ options: {
47
30
  sendStatus: (data: {
48
31
  loaded: number;
49
32
  }) => void;
50
33
  },
51
34
  ): Promise<{
52
- data: {
53
- numSplats: number;
54
- splatArrays: [Uint32Array<ArrayBufferLike>, Uint32Array<ArrayBufferLike>];
55
- extra: import("../../../data/defines.cjs").SplatExtra;
56
- rootRadius: number | undefined;
57
- } & import("../../../data/defines.cjs").SplatResult & {
58
- sourceIds: Uint32Array;
59
- centerOnlyBoundingBox: Float32Array;
60
- boundingBox: Float32Array;
61
- spatialBounds: Float32Array;
62
- };
35
+ data: RadStreamChunk;
63
36
  tree: RadLodChunk;
64
- state: import("../../rad/RadSource.cjs").RadResourceState | undefined;
37
+ state: RadResourceState | undefined;
65
38
  rootBytes: Uint8Array<ArrayBufferLike> | undefined;
66
39
  }>;
67
- cancelRadLoad({
68
- generation,
69
- }: {
40
+ cancelRadLoad(request: { generation: number }): void;
41
+ retainRadChunk(request: {
42
+ index: number;
70
43
  generation: number;
44
+ tree: Omit<RadLodChunk, keyof RadSelectionChunk>;
71
45
  }): void;
72
- retainRadChunk({
73
- index,
74
- generation,
75
- tree,
76
- }: {
46
+ retainRadSelectionChunk(request: {
77
47
  index: number;
78
48
  generation: number;
79
- tree: RadLodChunk;
80
- }): void;
49
+ chunk: RadSelectionChunk;
50
+ }): number;
81
51
  selectRadLod(request: RadSelectionRequest): RadSelectionReply;
82
- releaseRadChunk({
83
- index,
84
- generation,
85
- }: {
52
+ releaseRadChunk(request: {
86
53
  index: number;
87
54
  generation?: number;
88
55
  }): void;
56
+ releaseRadSelectionChunk(request: {
57
+ index: number;
58
+ generation?: number;
59
+ }): number;
89
60
  };
@@ -1,89 +1,60 @@
1
- import type { RadReadRequest } from "../../rad/RadSource.js";
2
- import type { RadHeader } from "../../rad/radFormat.js";
1
+ import type { RadReadRequest, RadResourceState } from "../../rad/RadSource.js";
2
+ import type { RadHeader, RadStreamChunk } from "../../rad/radFormat.js";
3
3
  import type {
4
4
  RadSelectionReply,
5
5
  RadSelectionRequest,
6
6
  } from "./RadSelectionState.js";
7
- import type { prepareRadSelection } from "./prepareRadSelection.js";
7
+ import type {
8
+ RadSelectionChunk,
9
+ RadSelectionPreparation,
10
+ prepareRadSelection,
11
+ } from "./prepareRadSelection.js";
8
12
  import type { RadLodChunk } from "./radLod.js";
9
- /** Each worker initializes once as either the dataset LOD tree or a page decoder. */
13
+ /** Workers own LOD traversal, display preparation, or a persistent page decoder. */
10
14
  export declare function createRadStreamHandlers(): {
11
- prepareRadSelection(request: Parameters<typeof prepareRadSelection>[0]): {
12
- selection: {
13
- indices: Uint32Array;
14
- wantedChunks: Uint32Array;
15
- touchedChunks: Uint32Array;
16
- selectionId: number;
17
- changedChunks: Uint32Array;
18
- };
19
- fade: boolean;
20
- pools: import("../../../data/RadPagedSplats.js").RadPreparedSelection[];
21
- };
22
- initializeRad({
23
- bytes,
24
- }: {
25
- bytes: Uint8Array;
26
- }): RadHeader;
27
- initializeRadDecoder({
28
- header: value,
29
- rootBytes,
30
- }: {
15
+ prepareRadSelection(
16
+ request: Parameters<typeof prepareRadSelection>[0],
17
+ ): RadSelectionPreparation;
18
+ initializeRad(request: { bytes: Uint8Array }): RadHeader;
19
+ initializeRadDecoder(request: {
31
20
  header: RadHeader;
32
21
  rootBytes?: Uint8Array;
33
22
  }): void;
34
23
  loadRadChunk(
35
- {
36
- index,
37
- generation,
38
- request,
39
- }: {
24
+ args: {
40
25
  index: number;
41
26
  generation: number;
42
27
  request: RadReadRequest;
43
28
  },
44
- {
45
- sendStatus,
46
- }: {
29
+ options: {
47
30
  sendStatus: (data: {
48
31
  loaded: number;
49
32
  }) => void;
50
33
  },
51
34
  ): Promise<{
52
- data: {
53
- numSplats: number;
54
- splatArrays: [Uint32Array<ArrayBufferLike>, Uint32Array<ArrayBufferLike>];
55
- extra: import("../../../data/defines.js").SplatExtra;
56
- rootRadius: number | undefined;
57
- } & import("../../../data/defines.js").SplatResult & {
58
- sourceIds: Uint32Array;
59
- centerOnlyBoundingBox: Float32Array;
60
- boundingBox: Float32Array;
61
- spatialBounds: Float32Array;
62
- };
35
+ data: RadStreamChunk;
63
36
  tree: RadLodChunk;
64
- state: import("../../rad/RadSource.js").RadResourceState | undefined;
37
+ state: RadResourceState | undefined;
65
38
  rootBytes: Uint8Array<ArrayBufferLike> | undefined;
66
39
  }>;
67
- cancelRadLoad({
68
- generation,
69
- }: {
40
+ cancelRadLoad(request: { generation: number }): void;
41
+ retainRadChunk(request: {
42
+ index: number;
70
43
  generation: number;
44
+ tree: Omit<RadLodChunk, keyof RadSelectionChunk>;
71
45
  }): void;
72
- retainRadChunk({
73
- index,
74
- generation,
75
- tree,
76
- }: {
46
+ retainRadSelectionChunk(request: {
77
47
  index: number;
78
48
  generation: number;
79
- tree: RadLodChunk;
80
- }): void;
49
+ chunk: RadSelectionChunk;
50
+ }): number;
81
51
  selectRadLod(request: RadSelectionRequest): RadSelectionReply;
82
- releaseRadChunk({
83
- index,
84
- generation,
85
- }: {
52
+ releaseRadChunk(request: {
86
53
  index: number;
87
54
  generation?: number;
88
55
  }): void;
56
+ releaseRadSelectionChunk(request: {
57
+ index: number;
58
+ generation?: number;
59
+ }): number;
89
60
  };
@@ -14,7 +14,6 @@ export declare class SogStreamBatch extends SplatMesh {
14
14
  group: THREE.Group,
15
15
  onEmpty: () => void,
16
16
  );
17
- get residentBytes(): number;
18
17
  writeRegion(start: number, data: ReorderedSplatResult): void;
19
18
  setRegionOpacity(start: number, opacity: number): void;
20
19
  releaseRegion(start: number): void;
@@ -14,7 +14,6 @@ export declare class SogStreamBatch extends SplatMesh {
14
14
  group: THREE.Group,
15
15
  onEmpty: () => void,
16
16
  );
17
- get residentBytes(): number;
18
17
  writeRegion(start: number, data: ReorderedSplatResult): void;
19
18
  setRegionOpacity(start: number, opacity: number): void;
20
19
  releaseRegion(start: number): void;
@@ -2,7 +2,7 @@ import type { Splats } from "../../../data/Splats.cjs";
2
2
  import type { StreamRequestOptions } from "../streamOptions.cjs";
3
3
  import type { SogStreamWorker } from "./SogStreamWorker.cjs";
4
4
  import type { SogLodMetadata } from "./sogLod.cjs";
5
- import type { SogView } from "./sogVisibility.cjs";
5
+ import type { SogLodRequest } from "./sogVisibility.cjs";
6
6
  import type { SogChunkInfo } from "./workerHandlers.cjs";
7
7
  export type SogStreamLoaderOptions = StreamRequestOptions & {
8
8
  url: string;
@@ -54,7 +54,7 @@ export declare class SogStreamLoader {
54
54
  private assertActive;
55
55
  initialize(signal?: AbortSignal): Promise<SogLodMetadata>;
56
56
  private readIndex;
57
- selectLod(view: SogView, budget: number): Promise<Uint32Array>;
57
+ selectLod(request: SogLodRequest): Promise<Uint32Array>;
58
58
  load(
59
59
  url: string,
60
60
  count: number,
@@ -2,7 +2,7 @@ import type { Splats } from "../../../data/Splats.js";
2
2
  import type { StreamRequestOptions } from "../streamOptions.js";
3
3
  import type { SogStreamWorker } from "./SogStreamWorker.js";
4
4
  import type { SogLodMetadata } from "./sogLod.js";
5
- import type { SogView } from "./sogVisibility.js";
5
+ import type { SogLodRequest } from "./sogVisibility.js";
6
6
  import type { SogChunkInfo } from "./workerHandlers.js";
7
7
  export type SogStreamLoaderOptions = StreamRequestOptions & {
8
8
  url: string;
@@ -54,7 +54,7 @@ export declare class SogStreamLoader {
54
54
  private assertActive;
55
55
  initialize(signal?: AbortSignal): Promise<SogLodMetadata>;
56
56
  private readIndex;
57
- selectLod(view: SogView, budget: number): Promise<Uint32Array>;
57
+ selectLod(request: SogLodRequest): Promise<Uint32Array>;
58
58
  load(
59
59
  url: string,
60
60
  count: number,
@@ -1,8 +1,16 @@
1
1
  import type * as THREE from "three";
2
2
  import type { StreamSchedulerOptions, StreamStats } from "../streamOptions.cjs";
3
3
  import type { SogStreamLoaderOptions } from "./SogStreamLoader.cjs";
4
+ import type { SogBudgetMode } from "./sogLod.cjs";
4
5
  export type SogStreamSchedulerOptions = SogStreamLoaderOptions &
5
- StreamSchedulerOptions;
6
+ StreamSchedulerOptions & {
7
+ /** Defaults to "target". "limit" caps detail at the configured distance bands. */
8
+ splatBudgetMode?: SogBudgetMode;
9
+ /** Base LOD distance in world units for "limit" mode; defaults to 100. Must be finite and positive. */
10
+ lodBaseDistance?: number;
11
+ /** Distance multiplier between LOD levels in both modes; defaults to 2. Must be finite and at least 1. */
12
+ lodMultiplier?: number;
13
+ };
6
14
  export type SogStreamStats = StreamStats & {
7
15
  visibleRegions: number;
8
16
  };
@@ -15,6 +23,9 @@ export declare class SogStreamScheduler {
15
23
  readonly fadeDurationMs: number;
16
24
  readonly maxConcurrentLoads: number;
17
25
  private _splatBudget;
26
+ private _splatBudgetMode;
27
+ private _lodBaseDistance;
28
+ private _lodMultiplier;
18
29
  private readonly options;
19
30
  private readonly loader;
20
31
  private readonly abort;
@@ -37,9 +48,18 @@ export declare class SogStreamScheduler {
37
48
  private resolveFirst;
38
49
  private rejectFirst;
39
50
  constructor(options: SogStreamSchedulerOptions);
40
- /** Visible-point target, including the environment. Reassign to reselect LODs. */
51
+ /** Visible-point budget, including the environment. Reassign to reselect LODs. */
41
52
  get splatBudget(): number;
42
53
  set splatBudget(value: number);
54
+ /** Fill the budget, or limit detail to the configured distance bands. */
55
+ get splatBudgetMode(): SogBudgetMode;
56
+ set splatBudgetMode(value: SogBudgetMode);
57
+ /** Base LOD distance in world units for limit mode. Higher retains more detail. */
58
+ get lodBaseDistance(): number;
59
+ set lodBaseDistance(value: number);
60
+ /** Distance multiplier between LOD levels; affects both budget modes. */
61
+ get lodMultiplier(): number;
62
+ set lodMultiplier(value: number);
43
63
  get stats(): SogStreamStats;
44
64
  /** Group-local bounds from the index; available after initialized resolves. */
45
65
  getBoundingBox(): THREE.Box3;
@@ -1,8 +1,16 @@
1
1
  import type * as THREE from "three";
2
2
  import type { StreamSchedulerOptions, StreamStats } from "../streamOptions.js";
3
3
  import type { SogStreamLoaderOptions } from "./SogStreamLoader.js";
4
+ import type { SogBudgetMode } from "./sogLod.js";
4
5
  export type SogStreamSchedulerOptions = SogStreamLoaderOptions &
5
- StreamSchedulerOptions;
6
+ StreamSchedulerOptions & {
7
+ /** Defaults to "target". "limit" caps detail at the configured distance bands. */
8
+ splatBudgetMode?: SogBudgetMode;
9
+ /** Base LOD distance in world units for "limit" mode; defaults to 100. Must be finite and positive. */
10
+ lodBaseDistance?: number;
11
+ /** Distance multiplier between LOD levels in both modes; defaults to 2. Must be finite and at least 1. */
12
+ lodMultiplier?: number;
13
+ };
6
14
  export type SogStreamStats = StreamStats & {
7
15
  visibleRegions: number;
8
16
  };
@@ -15,6 +23,9 @@ export declare class SogStreamScheduler {
15
23
  readonly fadeDurationMs: number;
16
24
  readonly maxConcurrentLoads: number;
17
25
  private _splatBudget;
26
+ private _splatBudgetMode;
27
+ private _lodBaseDistance;
28
+ private _lodMultiplier;
18
29
  private readonly options;
19
30
  private readonly loader;
20
31
  private readonly abort;
@@ -37,9 +48,18 @@ export declare class SogStreamScheduler {
37
48
  private resolveFirst;
38
49
  private rejectFirst;
39
50
  constructor(options: SogStreamSchedulerOptions);
40
- /** Visible-point target, including the environment. Reassign to reselect LODs. */
51
+ /** Visible-point budget, including the environment. Reassign to reselect LODs. */
41
52
  get splatBudget(): number;
42
53
  set splatBudget(value: number);
54
+ /** Fill the budget, or limit detail to the configured distance bands. */
55
+ get splatBudgetMode(): SogBudgetMode;
56
+ set splatBudgetMode(value: SogBudgetMode);
57
+ /** Base LOD distance in world units for limit mode. Higher retains more detail. */
58
+ get lodBaseDistance(): number;
59
+ set lodBaseDistance(value: number);
60
+ /** Distance multiplier between LOD levels; affects both budget modes. */
61
+ get lodMultiplier(): number;
62
+ set lodMultiplier(value: number);
43
63
  get stats(): SogStreamStats;
44
64
  /** Group-local bounds from the index; available after initialized resolves. */
45
65
  getBoundingBox(): THREE.Box3;
@@ -9,7 +9,7 @@ export type SogLodRange = {
9
9
  };
10
10
  export type SogLodLeaf = {
11
11
  id: number;
12
- /** Coarse to fine, with strictly increasing counts and decreasing levels. */
12
+ /** Coarse to fine, with strictly decreasing levels. */
13
13
  lods: SogLodRange[];
14
14
  };
15
15
  export type SogLodNode = {
@@ -25,8 +25,7 @@ export type SogLodFile = {
25
25
  export type SogLodManifest = {
26
26
  tree: SogLodNode;
27
27
  leaves: SogLodLeaf[];
28
- /** Flattened in leaf/LOD order; each leaf's first entry is unused. */
29
- upgradeRatios: number[];
28
+ lodLevels: number;
30
29
  files: SogLodFile[];
31
30
  environment?: string;
32
31
  };
@@ -38,14 +37,13 @@ export type SogLodIndex = {
38
37
  leafOffsets: Uint32Array;
39
38
  /** Per level: level, file, offset, count. */
40
39
  lods: Float64Array;
41
- /** Best reachable distance-error reduction per added splat, in LOD order. */
42
- upgradeRatios: Float32Array;
40
+ lodLevels: number;
43
41
  urls: string[];
44
42
  counts: Float64Array;
45
43
  environment?: string;
46
44
  };
47
45
  /** Scheduler metadata; the complete spatial tree stays in the LOD worker. */
48
- export type SogLodMetadata = Omit<SogLodIndex, "nodes" | "upgradeRatios"> & {
46
+ export type SogLodMetadata = Omit<SogLodIndex, "nodes" | "lodLevels"> & {
49
47
  /** Root min XYZ and max XYZ. */
50
48
  bounds: Float64Array;
51
49
  };
@@ -63,7 +61,15 @@ export declare function parseSogLodManifest(
63
61
  ): SogLodManifest;
64
62
  export type SogVisibleLeaf = {
65
63
  leaf: SogLodLeaf;
66
- weight: number;
64
+ /** World-space distance to the region, compensated for the camera's field of view. */
65
+ distance: number;
66
+ };
67
+ export type SogBudgetMode = "target" | "limit";
68
+ export type SogLodOptions = {
69
+ budget: number;
70
+ splatBudgetMode: SogBudgetMode;
71
+ lodBaseDistance: number;
72
+ lodMultiplier: number;
67
73
  };
68
74
  /** Reuse cached refinements up to the target, then split gaps of four or more. */
69
75
  export declare function resolveSogLod(
@@ -77,9 +83,9 @@ export declare function resolveSogLod(
77
83
  /** Wait until range is attached before requesting the next LOD. */
78
84
  refinement?: boolean;
79
85
  };
80
- /** Distance bands within a splat budget, using a small heap. */
86
+ /** Select distance bands, fitting their common base distance to the splat budget. */
81
87
  export declare function selectSogLods(
82
88
  visible: SogVisibleLeaf[],
83
- budget: number,
84
- manifest: Pick<SogLodIndex, "leafOffsets" | "upgradeRatios">,
89
+ lodLevels: number,
90
+ options: SogLodOptions,
85
91
  ): Map<number, SogLodRange>;