@babylonjs/loaders 9.13.0 → 9.15.0

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 (500) hide show
  1. package/BVH/bvhFileLoader.d.ts +4 -67
  2. package/BVH/bvhFileLoader.js +6 -130
  3. package/BVH/bvhFileLoader.js.map +1 -1
  4. package/BVH/bvhFileLoader.pure.d.ts +75 -0
  5. package/BVH/bvhFileLoader.pure.js +154 -0
  6. package/BVH/bvhFileLoader.pure.js.map +1 -0
  7. package/BVH/bvhFileLoader.types.d.ts +11 -0
  8. package/BVH/bvhFileLoader.types.js +2 -0
  9. package/BVH/bvhFileLoader.types.js.map +1 -0
  10. package/BVH/pure.d.ts +3 -0
  11. package/BVH/pure.js +5 -0
  12. package/BVH/pure.js.map +1 -0
  13. package/FBX/fbxFileLoader.d.ts +4 -192
  14. package/FBX/fbxFileLoader.js +6 -2437
  15. package/FBX/fbxFileLoader.js.map +1 -1
  16. package/FBX/fbxFileLoader.pure.d.ts +190 -0
  17. package/FBX/fbxFileLoader.pure.js +2451 -0
  18. package/FBX/fbxFileLoader.pure.js.map +1 -0
  19. package/FBX/fbxFileLoader.types.d.ts +11 -0
  20. package/FBX/fbxFileLoader.types.js +2 -0
  21. package/FBX/fbxFileLoader.types.js.map +1 -0
  22. package/FBX/pure.d.ts +3 -0
  23. package/FBX/pure.js +4 -0
  24. package/FBX/pure.js.map +1 -0
  25. package/OBJ/objFileLoader.d.ts +4 -134
  26. package/OBJ/objFileLoader.js +6 -315
  27. package/OBJ/objFileLoader.js.map +1 -1
  28. package/OBJ/objFileLoader.pure.d.ts +132 -0
  29. package/OBJ/objFileLoader.pure.js +329 -0
  30. package/OBJ/objFileLoader.pure.js.map +1 -0
  31. package/OBJ/objFileLoader.types.d.ts +11 -0
  32. package/OBJ/objFileLoader.types.js +2 -0
  33. package/OBJ/objFileLoader.types.js.map +1 -0
  34. package/OBJ/pure.d.ts +5 -0
  35. package/OBJ/pure.js +6 -0
  36. package/OBJ/pure.js.map +1 -0
  37. package/OBJ/solidParser.js +4 -3
  38. package/OBJ/solidParser.js.map +1 -1
  39. package/SPLAT/gaussianSplattingBlockAllocator.d.ts +137 -0
  40. package/SPLAT/gaussianSplattingBlockAllocator.js +555 -0
  41. package/SPLAT/gaussianSplattingBlockAllocator.js.map +1 -0
  42. package/SPLAT/gaussianSplattingDownloadManager.d.ts +109 -0
  43. package/SPLAT/gaussianSplattingDownloadManager.js +241 -0
  44. package/SPLAT/gaussianSplattingDownloadManager.js.map +1 -0
  45. package/SPLAT/gaussianSplattingResidencyController.d.ts +133 -0
  46. package/SPLAT/gaussianSplattingResidencyController.js +222 -0
  47. package/SPLAT/gaussianSplattingResidencyController.js.map +1 -0
  48. package/SPLAT/gaussianSplattingStream.d.ts +122 -4
  49. package/SPLAT/gaussianSplattingStream.js +413 -42
  50. package/SPLAT/gaussianSplattingStream.js.map +1 -1
  51. package/SPLAT/gaussianSplattingWorkBuffer.d.ts +36 -0
  52. package/SPLAT/gaussianSplattingWorkBuffer.js +125 -13
  53. package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
  54. package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +15 -0
  55. package/SPLAT/gaussianSplattingWorkBufferShaders.js +82 -0
  56. package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -1
  57. package/SPLAT/pure.d.ts +5 -0
  58. package/SPLAT/pure.js +7 -0
  59. package/SPLAT/pure.js.map +1 -0
  60. package/SPLAT/sog.d.ts +1 -97
  61. package/SPLAT/sog.js +1 -501
  62. package/SPLAT/sog.js.map +1 -1
  63. package/SPLAT/sog.pure.d.ts +102 -0
  64. package/SPLAT/sog.pure.js +514 -0
  65. package/SPLAT/sog.pure.js.map +1 -0
  66. package/SPLAT/splatFileLoader.d.ts +5 -106
  67. package/SPLAT/splatFileLoader.js +9 -636
  68. package/SPLAT/splatFileLoader.js.map +1 -1
  69. package/SPLAT/splatFileLoader.pure.d.ts +104 -0
  70. package/SPLAT/splatFileLoader.pure.js +650 -0
  71. package/SPLAT/splatFileLoader.pure.js.map +1 -0
  72. package/SPLAT/splatFileLoader.types.d.ts +11 -0
  73. package/SPLAT/splatFileLoader.types.js +2 -0
  74. package/SPLAT/splatFileLoader.types.js.map +1 -0
  75. package/STL/pure.d.ts +2 -0
  76. package/STL/pure.js +3 -0
  77. package/STL/pure.js.map +1 -0
  78. package/STL/stlFileLoader.d.ts +5 -76
  79. package/STL/stlFileLoader.js +7 -236
  80. package/STL/stlFileLoader.js.map +1 -1
  81. package/STL/stlFileLoader.pure.d.ts +73 -0
  82. package/STL/stlFileLoader.pure.js +249 -0
  83. package/STL/stlFileLoader.pure.js.map +1 -0
  84. package/STL/stlFileLoader.types.d.ts +10 -0
  85. package/STL/stlFileLoader.types.js +2 -0
  86. package/STL/stlFileLoader.types.js.map +1 -0
  87. package/glTF/1.0/pure.d.ts +3 -0
  88. package/glTF/1.0/pure.js +4 -0
  89. package/glTF/1.0/pure.js.map +1 -0
  90. package/glTF/2.0/Extensions/EXT_lights_area.d.ts +4 -39
  91. package/glTF/2.0/Extensions/EXT_lights_area.js +6 -91
  92. package/glTF/2.0/Extensions/EXT_lights_area.js.map +1 -1
  93. package/glTF/2.0/Extensions/EXT_lights_area.pure.d.ts +38 -0
  94. package/glTF/2.0/Extensions/EXT_lights_area.pure.js +106 -0
  95. package/glTF/2.0/Extensions/EXT_lights_area.pure.js.map +1 -0
  96. package/glTF/2.0/Extensions/EXT_lights_area.types.d.ts +9 -0
  97. package/glTF/2.0/Extensions/EXT_lights_area.types.js +2 -0
  98. package/glTF/2.0/Extensions/EXT_lights_area.types.js.map +1 -0
  99. package/glTF/2.0/Extensions/EXT_lights_ies.d.ts +4 -39
  100. package/glTF/2.0/Extensions/EXT_lights_ies.js +6 -81
  101. package/glTF/2.0/Extensions/EXT_lights_ies.js.map +1 -1
  102. package/glTF/2.0/Extensions/EXT_lights_ies.pure.d.ts +38 -0
  103. package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +96 -0
  104. package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -0
  105. package/glTF/2.0/Extensions/EXT_lights_ies.types.d.ts +9 -0
  106. package/glTF/2.0/Extensions/EXT_lights_ies.types.js +2 -0
  107. package/glTF/2.0/Extensions/EXT_lights_ies.types.js.map +1 -0
  108. package/glTF/2.0/Extensions/EXT_lights_image_based.d.ts +4 -46
  109. package/glTF/2.0/Extensions/EXT_lights_image_based.js +6 -113
  110. package/glTF/2.0/Extensions/EXT_lights_image_based.js.map +1 -1
  111. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.d.ts +37 -0
  112. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js +128 -0
  113. package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js.map +1 -0
  114. package/glTF/2.0/Extensions/EXT_lights_image_based.types.d.ts +17 -0
  115. package/glTF/2.0/Extensions/EXT_lights_image_based.types.js +2 -0
  116. package/glTF/2.0/Extensions/EXT_lights_image_based.types.js.map +1 -0
  117. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +5 -37
  118. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +7 -92
  119. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
  120. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.d.ts +35 -0
  121. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js +106 -0
  122. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js.map +1 -0
  123. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.d.ts +9 -0
  124. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js +2 -0
  125. package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js.map +1 -0
  126. package/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +4 -37
  127. package/glTF/2.0/Extensions/EXT_meshopt_compression.js +6 -48
  128. package/glTF/2.0/Extensions/EXT_meshopt_compression.js.map +1 -1
  129. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.d.ts +36 -0
  130. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js +63 -0
  131. package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js.map +1 -0
  132. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.d.ts +9 -0
  133. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js +2 -0
  134. package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js.map +1 -0
  135. package/glTF/2.0/Extensions/EXT_texture_avif.d.ts +4 -32
  136. package/glTF/2.0/Extensions/EXT_texture_avif.js +6 -36
  137. package/glTF/2.0/Extensions/EXT_texture_avif.js.map +1 -1
  138. package/glTF/2.0/Extensions/EXT_texture_avif.pure.d.ts +31 -0
  139. package/glTF/2.0/Extensions/EXT_texture_avif.pure.js +51 -0
  140. package/glTF/2.0/Extensions/EXT_texture_avif.pure.js.map +1 -0
  141. package/glTF/2.0/Extensions/EXT_texture_avif.types.d.ts +9 -0
  142. package/glTF/2.0/Extensions/EXT_texture_avif.types.js +2 -0
  143. package/glTF/2.0/Extensions/EXT_texture_avif.types.js.map +1 -0
  144. package/glTF/2.0/Extensions/EXT_texture_webp.d.ts +4 -31
  145. package/glTF/2.0/Extensions/EXT_texture_webp.js +6 -35
  146. package/glTF/2.0/Extensions/EXT_texture_webp.js.map +1 -1
  147. package/glTF/2.0/Extensions/EXT_texture_webp.pure.d.ts +30 -0
  148. package/glTF/2.0/Extensions/EXT_texture_webp.pure.js +50 -0
  149. package/glTF/2.0/Extensions/EXT_texture_webp.pure.js.map +1 -0
  150. package/glTF/2.0/Extensions/EXT_texture_webp.types.d.ts +9 -0
  151. package/glTF/2.0/Extensions/EXT_texture_webp.types.js +2 -0
  152. package/glTF/2.0/Extensions/EXT_texture_webp.types.js.map +1 -0
  153. package/glTF/2.0/Extensions/ExtrasAsMetadata.d.ts +4 -51
  154. package/glTF/2.0/Extensions/ExtrasAsMetadata.js +6 -71
  155. package/glTF/2.0/Extensions/ExtrasAsMetadata.js.map +1 -1
  156. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.d.ts +50 -0
  157. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js +85 -0
  158. package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js.map +1 -0
  159. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.d.ts +9 -0
  160. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js +2 -0
  161. package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js.map +1 -0
  162. package/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +5 -45
  163. package/glTF/2.0/Extensions/KHR_animation_pointer.js +7 -75
  164. package/glTF/2.0/Extensions/KHR_animation_pointer.js.map +1 -1
  165. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.d.ts +43 -0
  166. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js +89 -0
  167. package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js.map +1 -0
  168. package/glTF/2.0/Extensions/KHR_animation_pointer.types.d.ts +9 -0
  169. package/glTF/2.0/Extensions/KHR_animation_pointer.types.js +2 -0
  170. package/glTF/2.0/Extensions/KHR_animation_pointer.types.js.map +1 -0
  171. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +4 -45
  172. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +6 -90
  173. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -1
  174. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.d.ts +44 -0
  175. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js +105 -0
  176. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js.map +1 -0
  177. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.d.ts +9 -0
  178. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js +2 -0
  179. package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js.map +1 -0
  180. package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +4 -0
  181. package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
  182. package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -0
  183. package/glTF/2.0/Extensions/KHR_interactivity.d.ts +4 -36
  184. package/glTF/2.0/Extensions/KHR_interactivity.js +6 -148
  185. package/glTF/2.0/Extensions/KHR_interactivity.js.map +1 -1
  186. package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +35 -0
  187. package/glTF/2.0/Extensions/KHR_interactivity.pure.js +163 -0
  188. package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -0
  189. package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +9 -0
  190. package/glTF/2.0/Extensions/KHR_interactivity.types.js +2 -0
  191. package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -0
  192. package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +4 -39
  193. package/glTF/2.0/Extensions/KHR_lights_punctual.js +6 -89
  194. package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
  195. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.d.ts +38 -0
  196. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js +104 -0
  197. package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js.map +1 -0
  198. package/glTF/2.0/Extensions/KHR_lights_punctual.types.d.ts +9 -0
  199. package/glTF/2.0/Extensions/KHR_lights_punctual.types.js +2 -0
  200. package/glTF/2.0/Extensions/KHR_lights_punctual.types.js.map +1 -0
  201. package/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +4 -40
  202. package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +6 -63
  203. package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
  204. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.d.ts +39 -0
  205. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js +78 -0
  206. package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js.map +1 -0
  207. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.d.ts +9 -0
  208. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js +2 -0
  209. package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js.map +1 -0
  210. package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +4 -41
  211. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +6 -77
  212. package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
  213. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.d.ts +40 -0
  214. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js +92 -0
  215. package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js.map +1 -0
  216. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.d.ts +9 -0
  217. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js +2 -0
  218. package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js.map +1 -0
  219. package/glTF/2.0/Extensions/KHR_materials_coat.d.ts +4 -47
  220. package/glTF/2.0/Extensions/KHR_materials_coat.js +6 -117
  221. package/glTF/2.0/Extensions/KHR_materials_coat.js.map +1 -1
  222. package/glTF/2.0/Extensions/KHR_materials_coat.pure.d.ts +46 -0
  223. package/glTF/2.0/Extensions/KHR_materials_coat.pure.js +132 -0
  224. package/glTF/2.0/Extensions/KHR_materials_coat.pure.js.map +1 -0
  225. package/glTF/2.0/Extensions/KHR_materials_coat.types.d.ts +9 -0
  226. package/glTF/2.0/Extensions/KHR_materials_coat.types.js +2 -0
  227. package/glTF/2.0/Extensions/KHR_materials_coat.types.js.map +1 -0
  228. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.d.ts +4 -41
  229. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js +6 -56
  230. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js.map +1 -1
  231. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.d.ts +40 -0
  232. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js +71 -0
  233. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js.map +1 -0
  234. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.d.ts +9 -0
  235. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js +2 -0
  236. package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js.map +1 -0
  237. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +4 -41
  238. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +6 -71
  239. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
  240. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.d.ts +40 -0
  241. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js +86 -0
  242. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js.map +1 -0
  243. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.d.ts +9 -0
  244. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js +2 -0
  245. package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js.map +1 -0
  246. package/glTF/2.0/Extensions/KHR_materials_dispersion.d.ts +4 -41
  247. package/glTF/2.0/Extensions/KHR_materials_dispersion.js +6 -54
  248. package/glTF/2.0/Extensions/KHR_materials_dispersion.js.map +1 -1
  249. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.d.ts +40 -0
  250. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js +69 -0
  251. package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js.map +1 -0
  252. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.d.ts +9 -0
  253. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js +2 -0
  254. package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js.map +1 -0
  255. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +4 -40
  256. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +6 -45
  257. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -1
  258. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.d.ts +39 -0
  259. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js +60 -0
  260. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js.map +1 -0
  261. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.d.ts +9 -0
  262. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js +2 -0
  263. package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js.map +1 -0
  264. package/glTF/2.0/Extensions/KHR_materials_fuzz.d.ts +4 -41
  265. package/glTF/2.0/Extensions/KHR_materials_fuzz.js +6 -75
  266. package/glTF/2.0/Extensions/KHR_materials_fuzz.js.map +1 -1
  267. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.d.ts +40 -0
  268. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js +90 -0
  269. package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js.map +1 -0
  270. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.d.ts +9 -0
  271. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js +2 -0
  272. package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js.map +1 -0
  273. package/glTF/2.0/Extensions/KHR_materials_ior.d.ts +4 -44
  274. package/glTF/2.0/Extensions/KHR_materials_ior.js +6 -52
  275. package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
  276. package/glTF/2.0/Extensions/KHR_materials_ior.pure.d.ts +43 -0
  277. package/glTF/2.0/Extensions/KHR_materials_ior.pure.js +67 -0
  278. package/glTF/2.0/Extensions/KHR_materials_ior.pure.js.map +1 -0
  279. package/glTF/2.0/Extensions/KHR_materials_ior.types.d.ts +9 -0
  280. package/glTF/2.0/Extensions/KHR_materials_ior.types.js +2 -0
  281. package/glTF/2.0/Extensions/KHR_materials_ior.types.js.map +1 -0
  282. package/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +4 -40
  283. package/glTF/2.0/Extensions/KHR_materials_iridescence.js +6 -66
  284. package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
  285. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.d.ts +39 -0
  286. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js +81 -0
  287. package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js.map +1 -0
  288. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.d.ts +9 -0
  289. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js +2 -0
  290. package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js.map +1 -0
  291. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.d.ts +4 -40
  292. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +6 -72
  293. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js.map +1 -1
  294. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.d.ts +39 -0
  295. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js +87 -0
  296. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js.map +1 -0
  297. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.d.ts +9 -0
  298. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js +2 -0
  299. package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js.map +1 -0
  300. package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +4 -41
  301. package/glTF/2.0/Extensions/KHR_materials_sheen.js +6 -71
  302. package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
  303. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.d.ts +40 -0
  304. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js +86 -0
  305. package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js.map +1 -0
  306. package/glTF/2.0/Extensions/KHR_materials_sheen.types.d.ts +9 -0
  307. package/glTF/2.0/Extensions/KHR_materials_sheen.types.js +2 -0
  308. package/glTF/2.0/Extensions/KHR_materials_sheen.types.js.map +1 -0
  309. package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +4 -40
  310. package/glTF/2.0/Extensions/KHR_materials_specular.js +6 -74
  311. package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
  312. package/glTF/2.0/Extensions/KHR_materials_specular.pure.d.ts +39 -0
  313. package/glTF/2.0/Extensions/KHR_materials_specular.pure.js +89 -0
  314. package/glTF/2.0/Extensions/KHR_materials_specular.pure.js.map +1 -0
  315. package/glTF/2.0/Extensions/KHR_materials_specular.types.d.ts +9 -0
  316. package/glTF/2.0/Extensions/KHR_materials_specular.types.js +2 -0
  317. package/glTF/2.0/Extensions/KHR_materials_specular.types.js.map +1 -0
  318. package/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +4 -40
  319. package/glTF/2.0/Extensions/KHR_materials_transmission.js +6 -70
  320. package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
  321. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.d.ts +39 -0
  322. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js +85 -0
  323. package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js.map +1 -0
  324. package/glTF/2.0/Extensions/KHR_materials_transmission.types.d.ts +9 -0
  325. package/glTF/2.0/Extensions/KHR_materials_transmission.types.js +2 -0
  326. package/glTF/2.0/Extensions/KHR_materials_transmission.types.js.map +1 -0
  327. package/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +4 -40
  328. package/glTF/2.0/Extensions/KHR_materials_unlit.js +6 -64
  329. package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
  330. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.d.ts +39 -0
  331. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js +79 -0
  332. package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js.map +1 -0
  333. package/glTF/2.0/Extensions/KHR_materials_unlit.types.d.ts +9 -0
  334. package/glTF/2.0/Extensions/KHR_materials_unlit.types.js +2 -0
  335. package/glTF/2.0/Extensions/KHR_materials_unlit.types.js.map +1 -0
  336. package/glTF/2.0/Extensions/KHR_materials_variants.d.ts +4 -110
  337. package/glTF/2.0/Extensions/KHR_materials_variants.js +6 -260
  338. package/glTF/2.0/Extensions/KHR_materials_variants.js.map +1 -1
  339. package/glTF/2.0/Extensions/KHR_materials_variants.pure.d.ts +97 -0
  340. package/glTF/2.0/Extensions/KHR_materials_variants.pure.js +275 -0
  341. package/glTF/2.0/Extensions/KHR_materials_variants.pure.js.map +1 -0
  342. package/glTF/2.0/Extensions/KHR_materials_variants.types.d.ts +29 -0
  343. package/glTF/2.0/Extensions/KHR_materials_variants.types.js +2 -0
  344. package/glTF/2.0/Extensions/KHR_materials_variants.types.js.map +1 -0
  345. package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +4 -41
  346. package/glTF/2.0/Extensions/KHR_materials_volume.js +6 -77
  347. package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
  348. package/glTF/2.0/Extensions/KHR_materials_volume.pure.d.ts +40 -0
  349. package/glTF/2.0/Extensions/KHR_materials_volume.pure.js +92 -0
  350. package/glTF/2.0/Extensions/KHR_materials_volume.pure.js.map +1 -0
  351. package/glTF/2.0/Extensions/KHR_materials_volume.types.d.ts +9 -0
  352. package/glTF/2.0/Extensions/KHR_materials_volume.types.js +2 -0
  353. package/glTF/2.0/Extensions/KHR_materials_volume.types.js.map +1 -0
  354. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.d.ts +4 -43
  355. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js +6 -113
  356. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js.map +1 -1
  357. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.d.ts +42 -0
  358. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js +128 -0
  359. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js.map +1 -0
  360. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.d.ts +9 -0
  361. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js +2 -0
  362. package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js.map +1 -0
  363. package/glTF/2.0/Extensions/KHR_mesh_quantization.d.ts +4 -27
  364. package/glTF/2.0/Extensions/KHR_mesh_quantization.js +6 -20
  365. package/glTF/2.0/Extensions/KHR_mesh_quantization.js.map +1 -1
  366. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.d.ts +26 -0
  367. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js +35 -0
  368. package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js.map +1 -0
  369. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.d.ts +9 -0
  370. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js +2 -0
  371. package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js.map +1 -0
  372. package/glTF/2.0/Extensions/KHR_node_hoverability.d.ts +4 -29
  373. package/glTF/2.0/Extensions/KHR_node_hoverability.js +6 -187
  374. package/glTF/2.0/Extensions/KHR_node_hoverability.js.map +1 -1
  375. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +28 -0
  376. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +202 -0
  377. package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -0
  378. package/glTF/2.0/Extensions/KHR_node_hoverability.types.d.ts +9 -0
  379. package/glTF/2.0/Extensions/KHR_node_hoverability.types.js +2 -0
  380. package/glTF/2.0/Extensions/KHR_node_hoverability.types.js.map +1 -0
  381. package/glTF/2.0/Extensions/KHR_node_selectability.d.ts +4 -28
  382. package/glTF/2.0/Extensions/KHR_node_selectability.js +6 -121
  383. package/glTF/2.0/Extensions/KHR_node_selectability.js.map +1 -1
  384. package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +27 -0
  385. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +136 -0
  386. package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -0
  387. package/glTF/2.0/Extensions/KHR_node_selectability.types.d.ts +9 -0
  388. package/glTF/2.0/Extensions/KHR_node_selectability.types.js +2 -0
  389. package/glTF/2.0/Extensions/KHR_node_selectability.types.js.map +1 -0
  390. package/glTF/2.0/Extensions/KHR_node_visibility.d.ts +4 -28
  391. package/glTF/2.0/Extensions/KHR_node_visibility.js +6 -64
  392. package/glTF/2.0/Extensions/KHR_node_visibility.js.map +1 -1
  393. package/glTF/2.0/Extensions/KHR_node_visibility.pure.d.ts +27 -0
  394. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js +79 -0
  395. package/glTF/2.0/Extensions/KHR_node_visibility.pure.js.map +1 -0
  396. package/glTF/2.0/Extensions/KHR_node_visibility.types.d.ts +9 -0
  397. package/glTF/2.0/Extensions/KHR_node_visibility.types.js +2 -0
  398. package/glTF/2.0/Extensions/KHR_node_visibility.types.js.map +1 -0
  399. package/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +4 -31
  400. package/glTF/2.0/Extensions/KHR_texture_basisu.js +6 -35
  401. package/glTF/2.0/Extensions/KHR_texture_basisu.js.map +1 -1
  402. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.d.ts +30 -0
  403. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js +50 -0
  404. package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js.map +1 -0
  405. package/glTF/2.0/Extensions/KHR_texture_basisu.types.d.ts +9 -0
  406. package/glTF/2.0/Extensions/KHR_texture_basisu.types.js +2 -0
  407. package/glTF/2.0/Extensions/KHR_texture_basisu.types.js.map +1 -0
  408. package/glTF/2.0/Extensions/KHR_texture_transform.d.ts +4 -35
  409. package/glTF/2.0/Extensions/KHR_texture_transform.js +6 -56
  410. package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
  411. package/glTF/2.0/Extensions/KHR_texture_transform.pure.d.ts +34 -0
  412. package/glTF/2.0/Extensions/KHR_texture_transform.pure.js +71 -0
  413. package/glTF/2.0/Extensions/KHR_texture_transform.pure.js.map +1 -0
  414. package/glTF/2.0/Extensions/KHR_texture_transform.types.d.ts +9 -0
  415. package/glTF/2.0/Extensions/KHR_texture_transform.types.js +2 -0
  416. package/glTF/2.0/Extensions/KHR_texture_transform.types.js.map +1 -0
  417. package/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +4 -37
  418. package/glTF/2.0/Extensions/KHR_xmp_json_ld.js +6 -45
  419. package/glTF/2.0/Extensions/KHR_xmp_json_ld.js.map +1 -1
  420. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.d.ts +36 -0
  421. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js +60 -0
  422. package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js.map +1 -0
  423. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.d.ts +9 -0
  424. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js +2 -0
  425. package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js.map +1 -0
  426. package/glTF/2.0/Extensions/MSFT_audio_emitter.d.ts +5 -54
  427. package/glTF/2.0/Extensions/MSFT_audio_emitter.js +7 -226
  428. package/glTF/2.0/Extensions/MSFT_audio_emitter.js.map +1 -1
  429. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.d.ts +52 -0
  430. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js +240 -0
  431. package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js.map +1 -0
  432. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.d.ts +9 -0
  433. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js +2 -0
  434. package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js.map +1 -0
  435. package/glTF/2.0/Extensions/MSFT_lod.d.ts +4 -102
  436. package/glTF/2.0/Extensions/MSFT_lod.js +6 -335
  437. package/glTF/2.0/Extensions/MSFT_lod.js.map +1 -1
  438. package/glTF/2.0/Extensions/MSFT_lod.pure.d.ts +96 -0
  439. package/glTF/2.0/Extensions/MSFT_lod.pure.js +350 -0
  440. package/glTF/2.0/Extensions/MSFT_lod.pure.js.map +1 -0
  441. package/glTF/2.0/Extensions/MSFT_lod.types.d.ts +14 -0
  442. package/glTF/2.0/Extensions/MSFT_lod.types.js +2 -0
  443. package/glTF/2.0/Extensions/MSFT_lod.types.js.map +1 -0
  444. package/glTF/2.0/Extensions/MSFT_minecraftMesh.d.ts +6 -27
  445. package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +8 -40
  446. package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
  447. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.d.ts +24 -0
  448. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js +53 -0
  449. package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js.map +1 -0
  450. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.d.ts +9 -0
  451. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js +2 -0
  452. package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js.map +1 -0
  453. package/glTF/2.0/Extensions/MSFT_sRGBFactors.d.ts +6 -27
  454. package/glTF/2.0/Extensions/MSFT_sRGBFactors.js +8 -38
  455. package/glTF/2.0/Extensions/MSFT_sRGBFactors.js.map +1 -1
  456. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.d.ts +24 -0
  457. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js +51 -0
  458. package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js.map +1 -0
  459. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.d.ts +9 -0
  460. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js +2 -0
  461. package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js.map +1 -0
  462. package/glTF/2.0/Extensions/objectModelMapping.d.ts +31 -2
  463. package/glTF/2.0/Extensions/objectModelMapping.js +3 -3
  464. package/glTF/2.0/Extensions/objectModelMapping.js.map +1 -1
  465. package/glTF/2.0/Extensions/pure.d.ts +45 -0
  466. package/glTF/2.0/Extensions/pure.js +47 -0
  467. package/glTF/2.0/Extensions/pure.js.map +1 -0
  468. package/glTF/2.0/glTFLoader.d.ts +1 -471
  469. package/glTF/2.0/glTFLoader.js +3 -2539
  470. package/glTF/2.0/glTFLoader.js.map +1 -1
  471. package/glTF/2.0/glTFLoader.pure.d.ts +476 -0
  472. package/glTF/2.0/glTFLoader.pure.js +2575 -0
  473. package/glTF/2.0/glTFLoader.pure.js.map +1 -0
  474. package/glTF/2.0/glTFLoaderAnimation.d.ts +2 -2
  475. package/glTF/2.0/glTFLoaderAnimation.js +2 -2
  476. package/glTF/2.0/glTFLoaderAnimation.js.map +1 -1
  477. package/glTF/2.0/pbrMaterialLoadingAdapter.d.ts +1 -1
  478. package/glTF/2.0/pbrMaterialLoadingAdapter.js +2 -2
  479. package/glTF/2.0/pbrMaterialLoadingAdapter.js.map +1 -1
  480. package/glTF/2.0/pure.d.ts +8 -0
  481. package/glTF/2.0/pure.js +10 -0
  482. package/glTF/2.0/pure.js.map +1 -0
  483. package/glTF/glTFFileLoader.d.ts +5 -551
  484. package/glTF/glTFFileLoader.js +6 -996
  485. package/glTF/glTFFileLoader.js.map +1 -1
  486. package/glTF/glTFFileLoader.pure.d.ts +562 -0
  487. package/glTF/glTFFileLoader.pure.js +1024 -0
  488. package/glTF/glTFFileLoader.pure.js.map +1 -0
  489. package/glTF/glTFFileLoader.types.d.ts +11 -0
  490. package/glTF/glTFFileLoader.types.js +2 -0
  491. package/glTF/glTFFileLoader.types.js.map +1 -0
  492. package/glTF/glTFValidation.js +1 -1
  493. package/glTF/glTFValidation.js.map +1 -1
  494. package/glTF/pure.d.ts +6 -0
  495. package/glTF/pure.js +8 -0
  496. package/glTF/pure.js.map +1 -0
  497. package/package.json +56 -4
  498. package/pure.d.ts +8 -0
  499. package/pure.js +10 -0
  500. package/pure.js.map +1 -0
@@ -0,0 +1,222 @@
1
+ import { GaussianSplattingBlockAllocator } from "./gaussianSplattingBlockAllocator.js";
2
+ /**
3
+ * Tracks which streamed Gaussian Splatting files are resident in the GPU work buffer and where, evicting
4
+ * unreferenced files after a cooldown to keep the resident set within a fixed budget.
5
+ *
6
+ * Built on {@link GaussianSplattingBlockAllocator}: each resident file owns a contiguous block of the work
7
+ * buffer's splat-index address space. A file with no remaining references is scheduled for eviction; after
8
+ * `cooldownFrames` ticks (or sooner, if the space is needed by a new allocation — "evict-to-fit") its block
9
+ * is freed and reused. Pinned files (e.g. the always-rendered environment and the padding splat) are never
10
+ * evicted. The {@link onEvict} callback fires for every file the controller evicts so the owner can drop its
11
+ * own bookkeeping (e.g. mark it no longer decoded).
12
+ *
13
+ * This controller owns only memory/residency bookkeeping — it has no knowledge of the scene, GPU, downloads,
14
+ * or reference counting (the caller decides when a file's reference count reaches zero and calls
15
+ * {@link scheduleEviction}).
16
+ * @experimental
17
+ */
18
+ export class GaussianSplattingResidencyController {
19
+ /**
20
+ * Creates a residency controller.
21
+ * @param capacity total splat-index capacity of the work buffer
22
+ * @param cooldownFrames number of ticks an unreferenced file stays resident before being evicted
23
+ * @param onEvict called with the file index whenever the controller evicts a file (via tick or evict-to-fit)
24
+ */
25
+ constructor(capacity, cooldownFrames, onEvict) {
26
+ this._blocks = new Map();
27
+ // file -> frames remaining before eviction (only present for unreferenced, evictable files).
28
+ this._cooldown = new Map();
29
+ this._pinned = new Set();
30
+ this._allocator = new GaussianSplattingBlockAllocator(capacity);
31
+ this._cooldownFrames = Math.max(0, cooldownFrames);
32
+ this._onEvict = onEvict;
33
+ }
34
+ /**
35
+ * Total splat-index capacity.
36
+ */
37
+ get capacity() {
38
+ return this._allocator.capacity;
39
+ }
40
+ /**
41
+ * Number of files currently resident.
42
+ */
43
+ get residentCount() {
44
+ return this._blocks.size;
45
+ }
46
+ /**
47
+ * Total free splat capacity (sum of all gaps, which may be fragmented). After {@link compact} an
48
+ * allocation of up to this size is guaranteed to fit.
49
+ */
50
+ get freeSize() {
51
+ return this._allocator.freeSize;
52
+ }
53
+ /**
54
+ * Whether the given file currently has a block in the work buffer.
55
+ * @param file file index
56
+ * @returns true if resident
57
+ */
58
+ has(file) {
59
+ return this._blocks.has(file);
60
+ }
61
+ /**
62
+ * The work-buffer splat offset of a resident file, or undefined if not resident.
63
+ * @param file file index
64
+ * @returns the splat offset, or undefined
65
+ */
66
+ offset(file) {
67
+ return this._blocks.get(file)?.offset;
68
+ }
69
+ /**
70
+ * Allocates a contiguous block for a file about to be decoded. If there is no room, evicts files whose
71
+ * eviction cooldown is pending (they are unreferenced) and retries once. Returns the splat offset, or null
72
+ * if it still does not fit (the caller should refuse the decode and keep the node's current LOD).
73
+ * @param file file index
74
+ * @param count number of splats the file needs
75
+ * @returns the allocated splat offset, or null if it cannot fit
76
+ */
77
+ allocate(file, count) {
78
+ const existing = this._blocks.get(file);
79
+ if (existing) {
80
+ return existing.offset;
81
+ }
82
+ let block = this._allocator.allocate(count);
83
+ if (!block) {
84
+ // Evict-to-fit: reclaim every unreferenced (cooldown-scheduled) file, then retry once.
85
+ this._evictAllCooled();
86
+ block = this._allocator.allocate(count);
87
+ if (!block) {
88
+ return null;
89
+ }
90
+ }
91
+ this._blocks.set(file, block);
92
+ return block.offset;
93
+ }
94
+ /**
95
+ * Allocates a block for a file that must never be evicted (e.g. the environment or padding splat).
96
+ * @param file file index (use a sentinel that cannot collide with real file indices)
97
+ * @param count number of splats
98
+ * @returns the allocated splat offset, or null if it cannot fit
99
+ */
100
+ pin(file, count) {
101
+ const offset = this.allocate(file, count);
102
+ if (offset !== null) {
103
+ this._pinned.add(file);
104
+ }
105
+ return offset;
106
+ }
107
+ /**
108
+ * Frees a file's block immediately (e.g. when a decode was cancelled before completing). Does not fire
109
+ * {@link onEvict}. No-op for pinned or non-resident files.
110
+ * @param file file index
111
+ */
112
+ free(file) {
113
+ if (this._pinned.has(file)) {
114
+ return;
115
+ }
116
+ const block = this._blocks.get(file);
117
+ if (!block) {
118
+ return;
119
+ }
120
+ this._allocator.free(block);
121
+ this._blocks.delete(file);
122
+ this._cooldown.delete(file);
123
+ }
124
+ /**
125
+ * Compacts the resident blocks to defragment free space (capacity is unchanged), returning every block
126
+ * that moved so the caller can relocate the corresponding GPU/CPU splat data. Call when an allocation
127
+ * fails despite sufficient total free space ({@link freeSize}); afterwards that allocation will fit.
128
+ * @returns the relocations to apply (empty when nothing moved)
129
+ */
130
+ compact() {
131
+ const before = new Map();
132
+ for (const [file, block] of Array.from(this._blocks)) {
133
+ before.set(file, block.offset);
134
+ }
135
+ this._allocator.defrag(0);
136
+ const moves = [];
137
+ for (const [file, block] of Array.from(this._blocks)) {
138
+ const oldOffset = before.get(file);
139
+ if (oldOffset !== block.offset) {
140
+ moves.push({ file, oldOffset, newOffset: block.offset, count: block.size });
141
+ }
142
+ }
143
+ return moves;
144
+ }
145
+ /**
146
+ * Returns the current resident blocks (file index, splat offset, splat count). Used to relocate GPU/CPU
147
+ * data after {@link compact}.
148
+ * @returns one entry per resident file
149
+ */
150
+ getResidentBlocks() {
151
+ const result = [];
152
+ for (const [file, block] of Array.from(this._blocks)) {
153
+ result.push({ file, offset: block.offset, count: block.size });
154
+ }
155
+ return result;
156
+ }
157
+ /**
158
+ * Schedules an unreferenced resident file for eviction after the cooldown. No-op for pinned or
159
+ * non-resident files.
160
+ * @param file file index
161
+ */
162
+ scheduleEviction(file) {
163
+ if (this._pinned.has(file) || !this._blocks.has(file)) {
164
+ return;
165
+ }
166
+ this._cooldown.set(file, this._cooldownFrames);
167
+ }
168
+ /**
169
+ * Cancels a pending eviction because the file was referenced again.
170
+ * @param file file index
171
+ */
172
+ cancelEviction(file) {
173
+ this._cooldown.delete(file);
174
+ }
175
+ /**
176
+ * Advances all eviction cooldowns by one frame, evicting any that expire. Each evicted file fires
177
+ * {@link onEvict}.
178
+ * @returns the file indices evicted this tick
179
+ */
180
+ tick() {
181
+ if (this._cooldown.size === 0) {
182
+ return [];
183
+ }
184
+ const evicted = [];
185
+ for (const [file, frames] of Array.from(this._cooldown)) {
186
+ if (frames <= 1) {
187
+ evicted.push(file);
188
+ }
189
+ else {
190
+ this._cooldown.set(file, frames - 1);
191
+ }
192
+ }
193
+ for (const file of evicted) {
194
+ this._evict(file);
195
+ }
196
+ return evicted;
197
+ }
198
+ /**
199
+ * Releases all bookkeeping. The allocator and maps are cleared.
200
+ */
201
+ dispose() {
202
+ this._blocks.clear();
203
+ this._cooldown.clear();
204
+ this._pinned.clear();
205
+ }
206
+ _evictAllCooled() {
207
+ const files = Array.from(this._cooldown.keys());
208
+ for (const file of files) {
209
+ this._evict(file);
210
+ }
211
+ }
212
+ _evict(file) {
213
+ const block = this._blocks.get(file);
214
+ if (block) {
215
+ this._allocator.free(block);
216
+ this._blocks.delete(file);
217
+ }
218
+ this._cooldown.delete(file);
219
+ this._onEvict(file);
220
+ }
221
+ }
222
+ //# sourceMappingURL=gaussianSplattingResidencyController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaussianSplattingResidencyController.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingResidencyController.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,+BAA+B,EAAkC,MAAM,mCAAmC,CAAC;AAiBpH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,oCAAoC;IAS7C;;;;;OAKG;IACH,YAAmB,QAAgB,EAAE,cAAsB,EAAE,OAA+B;QAb3E,YAAO,GAAG,IAAI,GAAG,EAAqC,CAAC;QACxE,6FAA6F;QAC5E,cAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,YAAO,GAAG,IAAI,GAAG,EAAU,CAAC;QAWzC,IAAI,CAAC,UAAU,GAAG,IAAI,+BAA+B,CAAC,QAAQ,CAAC,CAAC;QAChE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACnD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,IAAW,aAAa;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7B,CAAC;IAED;;;OAGG;IACH,IAAW,QAAQ;QACf,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;IACpC,CAAC;IAED;;;;OAIG;IACI,GAAG,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACI,MAAM,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAC1C,CAAC;IAED;;;;;;;OAOG;IACI,QAAQ,CAAC,IAAY,EAAE,KAAa;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACX,OAAO,QAAQ,CAAC,MAAM,CAAC;QAC3B,CAAC;QACD,IAAI,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,uFAAuF;YACvF,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,IAAI,CAAC;YAChB,CAAC;QACL,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC9B,OAAO,KAAK,CAAC,MAAM,CAAC;IACxB,CAAC;IAED;;;;;OAKG;IACI,GAAG,CAAC,IAAY,EAAE,KAAa;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACI,IAAI,CAAC,IAAY;QACpB,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACT,OAAO;QACX,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;;OAKG;IACI,OAAO;QACV,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;QACzC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC1B,MAAM,KAAK,GAAqB,EAAE,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;YACpC,IAAI,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YAChF,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED;;;;OAIG;IACI,iBAAiB;QACpB,MAAM,MAAM,GAA2D,EAAE,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,IAAY;QAChC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACpD,OAAO;QACX,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,eAAe,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACI,cAAc,CAAC,IAAY;QAC9B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAED;;;;OAIG;IACI,IAAI;QACP,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACtD,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;gBACd,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,CAAC;YACzC,CAAC;QACL,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;OAEG;IACI,OAAO;QACV,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAEO,eAAe;QACnB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAChD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;IACL,CAAC;IAEO,MAAM,CAAC,IAAY;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;CACJ","sourcesContent":["import { type Nullable } from \"core/types\";\r\nimport { GaussianSplattingBlockAllocator, type GaussianSplattingMemBlock } from \"./gaussianSplattingBlockAllocator\";\r\n\r\n/**\r\n * One resident block relocation produced by {@link GaussianSplattingResidencyController.compact}: the file's\r\n * splat data must be moved from `oldOffset` to `newOffset` (`count` splats) in the work buffer.\r\n */\r\nexport interface IResidencyMove {\r\n /** File index whose splat data must move. */\r\n file: number;\r\n /** The file's previous splat offset in the work buffer. */\r\n oldOffset: number;\r\n /** The file's new splat offset after compaction. */\r\n newOffset: number;\r\n /** Number of splats in the file. */\r\n count: number;\r\n}\r\n\r\n/**\r\n * Tracks which streamed Gaussian Splatting files are resident in the GPU work buffer and where, evicting\r\n * unreferenced files after a cooldown to keep the resident set within a fixed budget.\r\n *\r\n * Built on {@link GaussianSplattingBlockAllocator}: each resident file owns a contiguous block of the work\r\n * buffer's splat-index address space. A file with no remaining references is scheduled for eviction; after\r\n * `cooldownFrames` ticks (or sooner, if the space is needed by a new allocation — \"evict-to-fit\") its block\r\n * is freed and reused. Pinned files (e.g. the always-rendered environment and the padding splat) are never\r\n * evicted. The {@link onEvict} callback fires for every file the controller evicts so the owner can drop its\r\n * own bookkeeping (e.g. mark it no longer decoded).\r\n *\r\n * This controller owns only memory/residency bookkeeping — it has no knowledge of the scene, GPU, downloads,\r\n * or reference counting (the caller decides when a file's reference count reaches zero and calls\r\n * {@link scheduleEviction}).\r\n * @experimental\r\n */\r\nexport class GaussianSplattingResidencyController {\r\n private readonly _allocator: GaussianSplattingBlockAllocator;\r\n private readonly _blocks = new Map<number, GaussianSplattingMemBlock>();\r\n // file -> frames remaining before eviction (only present for unreferenced, evictable files).\r\n private readonly _cooldown = new Map<number, number>();\r\n private readonly _pinned = new Set<number>();\r\n private readonly _cooldownFrames: number;\r\n private readonly _onEvict: (file: number) => void;\r\n\r\n /**\r\n * Creates a residency controller.\r\n * @param capacity total splat-index capacity of the work buffer\r\n * @param cooldownFrames number of ticks an unreferenced file stays resident before being evicted\r\n * @param onEvict called with the file index whenever the controller evicts a file (via tick or evict-to-fit)\r\n */\r\n public constructor(capacity: number, cooldownFrames: number, onEvict: (file: number) => void) {\r\n this._allocator = new GaussianSplattingBlockAllocator(capacity);\r\n this._cooldownFrames = Math.max(0, cooldownFrames);\r\n this._onEvict = onEvict;\r\n }\r\n\r\n /**\r\n * Total splat-index capacity.\r\n */\r\n public get capacity(): number {\r\n return this._allocator.capacity;\r\n }\r\n\r\n /**\r\n * Number of files currently resident.\r\n */\r\n public get residentCount(): number {\r\n return this._blocks.size;\r\n }\r\n\r\n /**\r\n * Total free splat capacity (sum of all gaps, which may be fragmented). After {@link compact} an\r\n * allocation of up to this size is guaranteed to fit.\r\n */\r\n public get freeSize(): number {\r\n return this._allocator.freeSize;\r\n }\r\n\r\n /**\r\n * Whether the given file currently has a block in the work buffer.\r\n * @param file file index\r\n * @returns true if resident\r\n */\r\n public has(file: number): boolean {\r\n return this._blocks.has(file);\r\n }\r\n\r\n /**\r\n * The work-buffer splat offset of a resident file, or undefined if not resident.\r\n * @param file file index\r\n * @returns the splat offset, or undefined\r\n */\r\n public offset(file: number): number | undefined {\r\n return this._blocks.get(file)?.offset;\r\n }\r\n\r\n /**\r\n * Allocates a contiguous block for a file about to be decoded. If there is no room, evicts files whose\r\n * eviction cooldown is pending (they are unreferenced) and retries once. Returns the splat offset, or null\r\n * if it still does not fit (the caller should refuse the decode and keep the node's current LOD).\r\n * @param file file index\r\n * @param count number of splats the file needs\r\n * @returns the allocated splat offset, or null if it cannot fit\r\n */\r\n public allocate(file: number, count: number): Nullable<number> {\r\n const existing = this._blocks.get(file);\r\n if (existing) {\r\n return existing.offset;\r\n }\r\n let block = this._allocator.allocate(count);\r\n if (!block) {\r\n // Evict-to-fit: reclaim every unreferenced (cooldown-scheduled) file, then retry once.\r\n this._evictAllCooled();\r\n block = this._allocator.allocate(count);\r\n if (!block) {\r\n return null;\r\n }\r\n }\r\n this._blocks.set(file, block);\r\n return block.offset;\r\n }\r\n\r\n /**\r\n * Allocates a block for a file that must never be evicted (e.g. the environment or padding splat).\r\n * @param file file index (use a sentinel that cannot collide with real file indices)\r\n * @param count number of splats\r\n * @returns the allocated splat offset, or null if it cannot fit\r\n */\r\n public pin(file: number, count: number): Nullable<number> {\r\n const offset = this.allocate(file, count);\r\n if (offset !== null) {\r\n this._pinned.add(file);\r\n }\r\n return offset;\r\n }\r\n\r\n /**\r\n * Frees a file's block immediately (e.g. when a decode was cancelled before completing). Does not fire\r\n * {@link onEvict}. No-op for pinned or non-resident files.\r\n * @param file file index\r\n */\r\n public free(file: number): void {\r\n if (this._pinned.has(file)) {\r\n return;\r\n }\r\n const block = this._blocks.get(file);\r\n if (!block) {\r\n return;\r\n }\r\n this._allocator.free(block);\r\n this._blocks.delete(file);\r\n this._cooldown.delete(file);\r\n }\r\n\r\n /**\r\n * Compacts the resident blocks to defragment free space (capacity is unchanged), returning every block\r\n * that moved so the caller can relocate the corresponding GPU/CPU splat data. Call when an allocation\r\n * fails despite sufficient total free space ({@link freeSize}); afterwards that allocation will fit.\r\n * @returns the relocations to apply (empty when nothing moved)\r\n */\r\n public compact(): IResidencyMove[] {\r\n const before = new Map<number, number>();\r\n for (const [file, block] of Array.from(this._blocks)) {\r\n before.set(file, block.offset);\r\n }\r\n this._allocator.defrag(0);\r\n const moves: IResidencyMove[] = [];\r\n for (const [file, block] of Array.from(this._blocks)) {\r\n const oldOffset = before.get(file)!;\r\n if (oldOffset !== block.offset) {\r\n moves.push({ file, oldOffset, newOffset: block.offset, count: block.size });\r\n }\r\n }\r\n return moves;\r\n }\r\n\r\n /**\r\n * Returns the current resident blocks (file index, splat offset, splat count). Used to relocate GPU/CPU\r\n * data after {@link compact}.\r\n * @returns one entry per resident file\r\n */\r\n public getResidentBlocks(): Array<{ file: number; offset: number; count: number }> {\r\n const result: Array<{ file: number; offset: number; count: number }> = [];\r\n for (const [file, block] of Array.from(this._blocks)) {\r\n result.push({ file, offset: block.offset, count: block.size });\r\n }\r\n return result;\r\n }\r\n\r\n /**\r\n * Schedules an unreferenced resident file for eviction after the cooldown. No-op for pinned or\r\n * non-resident files.\r\n * @param file file index\r\n */\r\n public scheduleEviction(file: number): void {\r\n if (this._pinned.has(file) || !this._blocks.has(file)) {\r\n return;\r\n }\r\n this._cooldown.set(file, this._cooldownFrames);\r\n }\r\n\r\n /**\r\n * Cancels a pending eviction because the file was referenced again.\r\n * @param file file index\r\n */\r\n public cancelEviction(file: number): void {\r\n this._cooldown.delete(file);\r\n }\r\n\r\n /**\r\n * Advances all eviction cooldowns by one frame, evicting any that expire. Each evicted file fires\r\n * {@link onEvict}.\r\n * @returns the file indices evicted this tick\r\n */\r\n public tick(): number[] {\r\n if (this._cooldown.size === 0) {\r\n return [];\r\n }\r\n const evicted: number[] = [];\r\n for (const [file, frames] of Array.from(this._cooldown)) {\r\n if (frames <= 1) {\r\n evicted.push(file);\r\n } else {\r\n this._cooldown.set(file, frames - 1);\r\n }\r\n }\r\n for (const file of evicted) {\r\n this._evict(file);\r\n }\r\n return evicted;\r\n }\r\n\r\n /**\r\n * Releases all bookkeeping. The allocator and maps are cleared.\r\n */\r\n public dispose(): void {\r\n this._blocks.clear();\r\n this._cooldown.clear();\r\n this._pinned.clear();\r\n }\r\n\r\n private _evictAllCooled(): void {\r\n const files = Array.from(this._cooldown.keys());\r\n for (const file of files) {\r\n this._evict(file);\r\n }\r\n }\r\n\r\n private _evict(file: number): void {\r\n const block = this._blocks.get(file);\r\n if (block) {\r\n this._allocator.free(block);\r\n this._blocks.delete(file);\r\n }\r\n this._cooldown.delete(file);\r\n this._onEvict(file);\r\n }\r\n}\r\n"]}
@@ -43,6 +43,12 @@ interface ISOGLODNode {
43
43
  inFrustum?: boolean;
44
44
  /** Cached local-space bounding info used for the per-node frustum test (created once per leaf). */
45
45
  cullBounds?: BoundingInfo;
46
+ /** File index this node currently has an in-flight/queued decode request for (its not-yet-decoded target),
47
+ * or undefined when the node's target is already decoded. Drives pending-download reference counting. */
48
+ pendingFile?: number;
49
+ /** File index this node's current {@link activeLod} renders from, or undefined before any LOD is active.
50
+ * Drives the resident reference count that keeps a file in the work buffer. */
51
+ activeFile?: number;
46
52
  }
47
53
  /**
48
54
  * Parsed contents of a PlayCanvas-style `lod-meta.json` file.
@@ -102,6 +108,28 @@ export interface IGaussianSplattingStreamOptions {
102
108
  * the camera turns toward them, then refine. Set to `false` to render every node at its distance LOD.
103
109
  */
104
110
  frustumCulling?: boolean;
111
+ /** Maximum number of LOD file downloads allowed to run concurrently. PlayCanvas default `2`. */
112
+ maxConcurrentDownloads?: number;
113
+ /** Number of times a failed file download is retried before giving up. PlayCanvas default `2`. */
114
+ maxDownloadRetries?: number;
115
+ /**
116
+ * GPU memory budget (in megabytes) for resident splats. When set (and smaller than the full dataset),
117
+ * LOD files are streamed through a fixed-size work buffer and unreferenced files are evicted to stay
118
+ * within budget, allowing datasets larger than a single full-dataset buffer. Converted to a splat count
119
+ * at ~84 bytes/splat. Combined with {@link maxResidentSplats} by taking the smaller of the two.
120
+ */
121
+ memoryBudgetMb?: number;
122
+ /**
123
+ * Maximum number of splats kept resident in the work buffer. When set (and smaller than the full
124
+ * dataset), enables eviction-based streaming (see {@link memoryBudgetMb}). Default unset = size the work
125
+ * buffer for the whole dataset (no eviction).
126
+ */
127
+ maxResidentSplats?: number;
128
+ /**
129
+ * Frames an unreferenced (no longer rendered) LOD file stays resident before it is evicted, so a quick
130
+ * return to it avoids a re-download. Only used when a budget enables eviction. PlayCanvas default `100`.
131
+ */
132
+ evictionCooldownFrames?: number;
105
133
  }
106
134
  /**
107
135
  * Streams a PlayCanvas-style SOG LOD scene (`lod-meta.json`) into a single Gaussian Splatting mesh.
@@ -139,12 +167,21 @@ export declare class GaussianSplattingStream extends GaussianSplattingMesh {
139
167
  private _useGpuPositionReadback;
140
168
  private _readbackCandidate;
141
169
  private _readbackProbed;
142
- private readonly _fileBaseSplat;
170
+ private _residency;
143
171
  private readonly _fileCounts;
144
172
  private readonly _fileMeta;
145
173
  private readonly _decodedFiles;
146
174
  private readonly _loadingFiles;
147
175
  private readonly _decodeQueue;
176
+ private readonly _fileRefs;
177
+ private readonly _cancelledDecodes;
178
+ private _evictionEnabled;
179
+ private _residentBudget;
180
+ private _evictionCooldownFrames;
181
+ private _decodeGate;
182
+ private readonly _relayoutOldOffsets;
183
+ private _relayoutSrcIndex;
184
+ private readonly _downloadManager;
148
185
  private _environmentRange;
149
186
  private _environmentFiles;
150
187
  private _lodObserver;
@@ -177,6 +214,29 @@ export declare class GaussianSplattingStream extends GaussianSplattingMesh {
177
214
  */
178
215
  constructor(name: string, metadata: ISOGLODMetadata, rootUrl: string, scene: Scene, options?: IGaussianSplattingStreamOptions);
179
216
  getClassName(): string;
217
+ /**
218
+ * Resolves once the scene is fully streamed and displayed for the current camera: a LOD re-evaluation has
219
+ * run for the current point of view, every reachable LOD file has finished downloading and decoding (no
220
+ * downloads, decodes, or queued work remain), and the depth sort for the resulting splats has been applied
221
+ * and rendered. Intended for deterministic automated testing and screenshot/image comparison.
222
+ *
223
+ * Streaming and settling require rendered frames. If an external render loop is already running, this waits
224
+ * on it passively; otherwise (e.g. when awaited inside an async `createScene` before the host starts its
225
+ * render loop) it drives `scene.render()` itself until settled, so it never deadlocks.
226
+ *
227
+ * Note: the promise only resolves while the camera is still — if the camera keeps moving, the target LODs
228
+ * (and the depth sort) keep changing and the stream never settles. Position the camera, then await this.
229
+ * @param stableFrames number of consecutive settled frames to require before resolving (defaults to 3), so
230
+ * the final sorted frame is actually on screen
231
+ * @returns a promise that resolves when loading and rendering are complete for the current view
232
+ */
233
+ whenSettledAsync(stableFrames?: number): Promise<void>;
234
+ /**
235
+ * Whether the base layer is ready and there is no streaming work in flight (nothing queued for decode, no
236
+ * decode running, and no downloads pending).
237
+ * @returns true when no loading work remains
238
+ */
239
+ private _isLoadingIdle;
180
240
  /**
181
241
  * Finest (most detailed) LOD level any node is allowed to render. `0` allows full detail (level 0);
182
242
  * `1` caps detail at the next-coarser level, and so on. Nodes already coarser than this cap (by
@@ -324,10 +384,38 @@ export declare class GaussianSplattingStream extends GaussianSplattingMesh {
324
384
  /**
325
385
  * Loads one LOD source file as GPU textures, decodes it into its fixed work-buffer block, records its
326
386
  * CPU centers for sorting, frees the source textures, then promotes any nodes that were waiting for it.
327
- * Concurrent or repeat requests for the same file are ignored.
387
+ * Concurrent or repeat requests for the same file are ignored. If the file is cancelled mid-flight
388
+ * (because every node that wanted it retargeted), the decode bails cooperatively at the next checkpoint.
328
389
  * @param fileId file index to decode
329
390
  */
330
391
  private _decodeFileAsync;
392
+ /**
393
+ * Acquires the decode gate (a simple async mutex). Resolves once any prior holder releases, returning a
394
+ * release function the caller must invoke in a `finally`.
395
+ * @returns the release function
396
+ */
397
+ private _acquireDecodeGateAsync;
398
+ /**
399
+ * Defragments the work buffer to make room for a file that did not fit, then allocates its slot. Runs the
400
+ * compaction + GPU relayout atomically inside a single `onBeforeRender` so no inconsistent CPU/GPU layout
401
+ * is ever rendered. Returns the new slot offset, or null if even compaction cannot free enough contiguous
402
+ * space (the caller refuses the upgrade).
403
+ * @param fileId file to allocate after compaction
404
+ * @param count splats the file needs
405
+ * @returns the allocated offset, or null
406
+ */
407
+ private _relayoutAndAllocateAsync;
408
+ /**
409
+ * Compacts the resident set and relocates the corresponding GPU textures and CPU positions to the new
410
+ * layout. Must run at a frame-safe point with the work buffer's relayout shader ready.
411
+ */
412
+ private _performRelayout;
413
+ /**
414
+ * Drops a file evicted by the residency controller from the decoded set so it will be re-decoded on demand.
415
+ * The file had no remaining references, so no node was rendering or downloading it.
416
+ * @param fileId evicted file index
417
+ */
418
+ private _onFileEvicted;
331
419
  /**
332
420
  * Snaps a desired LOD level to the nearest level the node provides, while never selecting a level finer
333
421
  * than {@link maxDetailLod} (i.e. with an index below the cap). Ties prefer the finer allowed level. If
@@ -344,11 +432,41 @@ export declare class GaussianSplattingStream extends GaussianSplattingMesh {
344
432
  private _computeTargetLevels;
345
433
  /**
346
434
  * Applies each node's {@link ISOGLODNode.targetLevel}: switches a node to its target level when that
347
- * level's file is already decoded, otherwise queues the file and leaves the node on its current LOD (so
348
- * nothing ever disappears). Nodes within their post-switch cooldown are left untouched to damp oscillation.
435
+ * level's file is already decoded, otherwise records a pending download request for the file and leaves
436
+ * the node on its current LOD (so nothing ever disappears). Nodes within their post-switch cooldown are
437
+ * left untouched to damp oscillation (and keep their existing pending request).
438
+ *
439
+ * Each node tracks the single file it currently needs but lacks ({@link ISOGLODNode.pendingFile}). When a
440
+ * node's target changes before that file finished downloading, the old file's reference is released; if no
441
+ * other node still needs it, its queued/in-flight download is cancelled (see {@link _releaseFileRef}).
349
442
  * @returns true when at least one node changed LOD (callers should refresh the active ranges)
350
443
  */
351
444
  private _applyDesiredLods;
445
+ /**
446
+ * Moves a node's resident reference from its previous active file to the one it now renders, so the file
447
+ * count that keeps a block in the work buffer stays accurate (and cancels any pending eviction of the new
448
+ * file). The new file is already decoded.
449
+ * @param node leaf node switching its rendered file
450
+ * @param file the file the node now renders from
451
+ */
452
+ private _switchActiveFile;
453
+ /**
454
+ * Adds a reference to a file (active render or pending download), cancelling any scheduled eviction.
455
+ * @param fileId file index
456
+ */
457
+ private _acquireFileRef;
458
+ /**
459
+ * Records that a node needs a not-yet-decoded file, bumping its reference count and queueing the decode.
460
+ * @param fileId file index the node now targets
461
+ */
462
+ private _acquirePendingFile;
463
+ /**
464
+ * Releases a node's reference to a file. When the last reference is dropped: a decoded file is scheduled
465
+ * for eviction (when streaming under a budget), and a still-downloading file has its queued decode dropped
466
+ * and any in-flight download cancelled.
467
+ * @param fileId file index the node no longer references
468
+ */
469
+ private _releaseFileRef;
352
470
  /**
353
471
  * Per-frame LOD streaming loop. Ticks cooldowns and pumps the decode queue every frame, and runs the
354
472
  * cheap per-node frustum test every frame so the off-screen LOD bias tracks camera rotation. The LOD