Skip to content

Commit 044e0de

Browse files
fix: fire setDirty when pager fetch pipeline drains (closes #298)
When a static camera is combined with on-demand rendering, the onDirty chain breaks during paged LOD loading because chunk fetches complete asynchronously — outside any render frame — and nothing signals the renderer that new data is ready to process. Fix: call setDirty() at two points in SplatPager: - when fetchers drains to 0 (all in-flight downloads finished) - when processFetched() fully empties the fetched queue The consumeLodTreeUpdates path is intentionally unchanged; SparkRenderer already calls setDirty() there via the existing lodDirty flow. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5c63bd5 commit 044e0de

7 files changed

Lines changed: 36 additions & 10 deletions

File tree

dist/spark.cjs.js

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/spark.cjs.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/spark.module.js

Lines changed: 12 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/spark.module.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/types/SplatPager.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ export interface SplatPagerOptions {
8484
* @default 3
8585
*/
8686
numFetchers?: number;
87+
onDirty?: () => void;
8788
}
8889
export declare class SplatPager {
8990
renderer: THREE.WebGLRenderer;
@@ -96,6 +97,7 @@ export declare class SplatPager {
9697
autoDrive: boolean;
9798
numFetchers: number;
9899
fetchPause: number;
100+
onDirty?: () => void;
99101
splatsChunkToPage: Map<PagedSplats, ({
100102
page: number;
101103
lru: number;

src/SparkRenderer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,7 @@ export class SparkRenderer extends THREE.Mesh {
12331233
extSplats: this.pagedExtSplats,
12341234
maxSplats: this.maxPagedSplats,
12351235
numFetchers: this.numLodFetchers,
1236+
onDirty: () => this.setDirty(),
12361237
});
12371238

12381239
const { lodId } = (await worker.call("newLodTree", {

src/SplatPager.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,7 @@ export interface SplatPagerOptions {
462462
* @default 3
463463
*/
464464
numFetchers?: number;
465+
onDirty?: () => void;
465466
}
466467

467468
export class SplatPager {
@@ -478,6 +479,7 @@ export class SplatPager {
478479
autoDrive: boolean;
479480
numFetchers: number;
480481
fetchPause = 0;
482+
onDirty?: () => void;
481483

482484
splatsChunkToPage: Map<
483485
PagedSplats,
@@ -573,6 +575,7 @@ export class SplatPager {
573575

574576
this.autoDrive = options.autoDrive ?? true;
575577
this.numFetchers = options.numFetchers ?? 3;
578+
this.onDirty = options.onDirty;
576579

577580
this.splatsChunkToPage = new Map();
578581
this.pageToSplatsChunk = new Array(this.maxPages);
@@ -1277,6 +1280,7 @@ export class SplatPager {
12771280
this.fetchers = this.fetchers.filter(
12781281
({ splats: s, chunk: c }) => splats !== s || chunk !== c,
12791282
);
1283+
if (this.fetchers.length === 0) this.onDirty?.();
12801284
this.processFetched();
12811285
});
12821286
// Add self to active fetchers list
@@ -1336,11 +1340,14 @@ export class SplatPager {
13361340

13371341
private processFetched() {
13381342
const now = performance.now();
1343+
let processed = false;
13391344
while (true) {
13401345
const fetched = this.fetched.shift();
13411346
if (!fetched) {
1347+
if (processed) this.onDirty?.();
13421348
break;
13431349
}
1350+
processed = true;
13441351
const { splats, chunk, data } = fetched;
13451352

13461353
let page = this.allocatePage();

0 commit comments

Comments
 (0)