@@ -25,6 +25,7 @@ import {
2525 exposeQuakeRenderBundleAtlasPages ,
2626 mountQuakeRenderBundleMesh ,
2727 preloadQuakeRenderBundleAtlasPages ,
28+ preloadQuakeRenderBundleElementAssets ,
2829 registerQuakeRenderBundleDebugLeafSourceFace ,
2930 registerQuakeRenderBundleDebugOutlineLeaves ,
3031 stripPolyMeshMetadata ,
@@ -155,6 +156,7 @@ export interface QuakeWorldController {
155156 syncVisibility : ( force ?: boolean ) => void ;
156157 visibleLeavesAt : ( origin : [ number , number , number ] ) => Set < number > | null ;
157158 waitForVisibleAtlasPages : ( ) => Promise < void > ;
159+ waitForVisibleTextures : ( ) => Promise < void > ;
158160}
159161
160162export interface QuakeWorldDebugBucket {
@@ -214,6 +216,8 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
214216 let visibleAtlasPageKey = "" ;
215217 let visibleAtlasPageSet = new Set < number > ( ) ;
216218 let visibleAtlasPageReadyPromise : Promise < void > = Promise . resolve ( ) ;
219+ let visibleAtlasPrewarmReadyPromise : Promise < void > = Promise . resolve ( ) ;
220+ let visibleWorldTextureReadyPromise : Promise < void > = Promise . resolve ( ) ;
217221 let debugShellVisible = false ;
218222
219223 const clear = ( ) : void => {
@@ -241,6 +245,8 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
241245 visibleAtlasPageKey = "" ;
242246 visibleAtlasPageSet = new Set ( ) ;
243247 visibleAtlasPageReadyPromise = Promise . resolve ( ) ;
248+ visibleAtlasPrewarmReadyPromise = Promise . resolve ( ) ;
249+ visibleWorldTextureReadyPromise = Promise . resolve ( ) ;
244250 } ;
245251
246252 const clearPresentationResyncTimers = ( ) : void => {
@@ -1129,6 +1135,12 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
11291135 } ;
11301136
11311137 const waitForVisibleAtlasPages = ( ) : Promise < void > => visibleAtlasPageReadyPromise ;
1138+ const waitForVisibleTextures = ( ) : Promise < void > =>
1139+ Promise . all ( [
1140+ visibleAtlasPageReadyPromise ,
1141+ visibleAtlasPrewarmReadyPromise ,
1142+ visibleWorldTextureReadyPromise ,
1143+ ] ) . then ( ( ) => undefined ) ;
11321144
11331145 const syncWorldAtlasResidencyPages = ( leafIndex : number | null ) : void => {
11341146 const atlasResidency = currentRenderBundle ?. atlasResidency ;
@@ -1143,7 +1155,7 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
11431155 const exposedPages = currentPages . length ? currentPages : allPages ;
11441156 const warmPages = prewarmPages . length ? prewarmPages : exposedPages ;
11451157 setVisibleAtlasResidencyPages ( exposedPages ) ;
1146- void preloadQuakeRenderBundleAtlasPages ( currentRenderBundle , warmPages ) ;
1158+ visibleAtlasPrewarmReadyPromise = preloadQuakeRenderBundleAtlasPages ( currentRenderBundle , warmPages ) ;
11471159 } ;
11481160
11491161 const setVisibleAtlasResidencyPages = ( pageIndexes : readonly number [ ] ) : void => {
@@ -1159,14 +1171,38 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
11591171 } ;
11601172
11611173 const syncMountedAtlasResidencyPages = ( ) : void => {
1162- if ( ! currentHandle || ! currentRenderBundle || currentRenderBundle . atlasResidency ?. mode !== "pvs-pages" ) return ;
1163- const nextPages = mountedAtlasResidencyPageIndexes ( visibleAtlasPageSet ) ;
1164- const pageKey = nextPages . join ( "," ) ;
1165- if ( pageKey === visibleAtlasPageKey ) return ;
1166- exposeQuakeRenderBundleAtlasPages ( currentHandle . element , currentRenderBundle , nextPages ) ;
1167- visibleAtlasPageSet = new Set ( nextPages ) ;
1168- visibleAtlasPageKey = pageKey ;
1169- visibleAtlasPageReadyPromise = preloadQuakeRenderBundleAtlasPages ( currentRenderBundle , nextPages ) ;
1174+ if ( ! currentHandle || ! currentRenderBundle ) return ;
1175+ if ( currentRenderBundle . atlasResidency ?. mode === "pvs-pages" ) {
1176+ const nextPages = mountedAtlasResidencyPageIndexes ( visibleAtlasPageSet ) ;
1177+ const pageKey = nextPages . join ( "," ) ;
1178+ if ( pageKey !== visibleAtlasPageKey ) {
1179+ exposeQuakeRenderBundleAtlasPages ( currentHandle . element , currentRenderBundle , nextPages ) ;
1180+ visibleAtlasPageSet = new Set ( nextPages ) ;
1181+ visibleAtlasPageKey = pageKey ;
1182+ visibleAtlasPageReadyPromise = preloadQuakeRenderBundleAtlasPages ( currentRenderBundle , nextPages ) ;
1183+ }
1184+ }
1185+ syncMountedWorldTextureReadiness ( ) ;
1186+ } ;
1187+
1188+ const syncMountedWorldTextureReadiness = ( ) : void => {
1189+ if ( ! currentHandle ) {
1190+ visibleWorldTextureReadyPromise = Promise . resolve ( ) ;
1191+ return ;
1192+ }
1193+ visibleWorldTextureReadyPromise = preloadQuakeRenderBundleElementAssets (
1194+ currentHandle . element ,
1195+ mountedWorldTextureElements ( ) ,
1196+ ) ;
1197+ } ;
1198+
1199+ const mountedWorldTextureElements = ( ) : HTMLElement [ ] => {
1200+ const elements : HTMLElement [ ] = [ ] ;
1201+ for ( const leaf of quakeLeaves ) {
1202+ if ( leaf . meshKind !== "world" || ! leaf . mounted || ! leaf . element . isConnected ) continue ;
1203+ elements . push ( leaf . element ) ;
1204+ }
1205+ return elements ;
11701206 } ;
11711207
11721208 const normalizedAtlasResidencyPageIndexes = ( pageIndexes : Iterable < number > ) : number [ ] =>
@@ -1353,6 +1389,7 @@ export function createQuakeWorldController(options: QuakeWorldControllerOptions)
13531389 syncVisibility,
13541390 visibleLeavesAt : ( origin : [ number , number , number ] ) => currentVisibility ?. visibleLeavesAt ( origin ) ?? null ,
13551391 waitForVisibleAtlasPages,
1392+ waitForVisibleTextures,
13561393 } ;
13571394}
13581395
0 commit comments