diff --git a/src/SparkRenderer.ts b/src/SparkRenderer.ts index 83a96028..ffa662dc 100644 --- a/src/SparkRenderer.ts +++ b/src/SparkRenderer.ts @@ -1233,6 +1233,7 @@ export class SparkRenderer extends THREE.Mesh { extSplats: this.pagedExtSplats, maxSplats: this.maxPagedSplats, numFetchers: this.numLodFetchers, + onLodTreeUpdate: () => this.setDirty(), }); const { lodId } = (await worker.call("newLodTree", { diff --git a/src/SplatPager.ts b/src/SplatPager.ts index 58af2f6d..fede8c90 100644 --- a/src/SplatPager.ts +++ b/src/SplatPager.ts @@ -462,6 +462,11 @@ export interface SplatPagerOptions { * @default 3 */ numFetchers?: number; + /** + * Called when the LOD tree gains newly-decoded pages (the fetch queue + * drains), so on-demand renderers can request a redraw. + */ + onLodTreeUpdate?: () => void; } export class SplatPager { @@ -478,6 +483,7 @@ export class SplatPager { autoDrive: boolean; numFetchers: number; fetchPause = 0; + onLodTreeUpdate?: () => void; splatsChunkToPage: Map< PagedSplats, @@ -573,6 +579,7 @@ export class SplatPager { this.autoDrive = options.autoDrive ?? true; this.numFetchers = options.numFetchers ?? 3; + this.onLodTreeUpdate = options.onLodTreeUpdate; this.splatsChunkToPage = new Map(); this.pageToSplatsChunk = new Array(this.maxPages); @@ -1336,11 +1343,14 @@ export class SplatPager { private processFetched() { const now = performance.now(); + let processed = false; while (true) { const fetched = this.fetched.shift(); if (!fetched) { + if (processed) this.onLodTreeUpdate?.(); break; } + processed = true; const { splats, chunk, data } = fetched; let page = this.allocatePage();