@babylonjs/loaders 9.13.0 → 9.14.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.
- package/BVH/bvhFileLoader.d.ts +4 -67
- package/BVH/bvhFileLoader.js +6 -130
- package/BVH/bvhFileLoader.js.map +1 -1
- package/BVH/bvhFileLoader.pure.d.ts +75 -0
- package/BVH/bvhFileLoader.pure.js +154 -0
- package/BVH/bvhFileLoader.pure.js.map +1 -0
- package/BVH/bvhFileLoader.types.d.ts +11 -0
- package/BVH/bvhFileLoader.types.js +2 -0
- package/BVH/bvhFileLoader.types.js.map +1 -0
- package/BVH/pure.d.ts +3 -0
- package/BVH/pure.js +5 -0
- package/BVH/pure.js.map +1 -0
- package/FBX/fbxFileLoader.d.ts +4 -192
- package/FBX/fbxFileLoader.js +6 -2437
- package/FBX/fbxFileLoader.js.map +1 -1
- package/FBX/fbxFileLoader.pure.d.ts +190 -0
- package/FBX/fbxFileLoader.pure.js +2451 -0
- package/FBX/fbxFileLoader.pure.js.map +1 -0
- package/FBX/fbxFileLoader.types.d.ts +11 -0
- package/FBX/fbxFileLoader.types.js +2 -0
- package/FBX/fbxFileLoader.types.js.map +1 -0
- package/FBX/pure.d.ts +3 -0
- package/FBX/pure.js +4 -0
- package/FBX/pure.js.map +1 -0
- package/OBJ/objFileLoader.d.ts +4 -134
- package/OBJ/objFileLoader.js +6 -315
- package/OBJ/objFileLoader.js.map +1 -1
- package/OBJ/objFileLoader.pure.d.ts +132 -0
- package/OBJ/objFileLoader.pure.js +329 -0
- package/OBJ/objFileLoader.pure.js.map +1 -0
- package/OBJ/objFileLoader.types.d.ts +11 -0
- package/OBJ/objFileLoader.types.js +2 -0
- package/OBJ/objFileLoader.types.js.map +1 -0
- package/OBJ/pure.d.ts +5 -0
- package/OBJ/pure.js +6 -0
- package/OBJ/pure.js.map +1 -0
- package/OBJ/solidParser.js +4 -3
- package/OBJ/solidParser.js.map +1 -1
- package/SPLAT/gaussianSplattingBlockAllocator.d.ts +137 -0
- package/SPLAT/gaussianSplattingBlockAllocator.js +555 -0
- package/SPLAT/gaussianSplattingBlockAllocator.js.map +1 -0
- package/SPLAT/gaussianSplattingDownloadManager.d.ts +109 -0
- package/SPLAT/gaussianSplattingDownloadManager.js +241 -0
- package/SPLAT/gaussianSplattingDownloadManager.js.map +1 -0
- package/SPLAT/gaussianSplattingResidencyController.d.ts +133 -0
- package/SPLAT/gaussianSplattingResidencyController.js +222 -0
- package/SPLAT/gaussianSplattingResidencyController.js.map +1 -0
- package/SPLAT/gaussianSplattingStream.d.ts +122 -4
- package/SPLAT/gaussianSplattingStream.js +413 -42
- package/SPLAT/gaussianSplattingStream.js.map +1 -1
- package/SPLAT/gaussianSplattingWorkBuffer.d.ts +36 -0
- package/SPLAT/gaussianSplattingWorkBuffer.js +125 -13
- package/SPLAT/gaussianSplattingWorkBuffer.js.map +1 -1
- package/SPLAT/gaussianSplattingWorkBufferShaders.d.ts +15 -0
- package/SPLAT/gaussianSplattingWorkBufferShaders.js +82 -0
- package/SPLAT/gaussianSplattingWorkBufferShaders.js.map +1 -1
- package/SPLAT/pure.d.ts +5 -0
- package/SPLAT/pure.js +7 -0
- package/SPLAT/pure.js.map +1 -0
- package/SPLAT/sog.d.ts +1 -97
- package/SPLAT/sog.js +1 -501
- package/SPLAT/sog.js.map +1 -1
- package/SPLAT/sog.pure.d.ts +102 -0
- package/SPLAT/sog.pure.js +514 -0
- package/SPLAT/sog.pure.js.map +1 -0
- package/SPLAT/splatFileLoader.d.ts +5 -106
- package/SPLAT/splatFileLoader.js +9 -636
- package/SPLAT/splatFileLoader.js.map +1 -1
- package/SPLAT/splatFileLoader.pure.d.ts +104 -0
- package/SPLAT/splatFileLoader.pure.js +650 -0
- package/SPLAT/splatFileLoader.pure.js.map +1 -0
- package/SPLAT/splatFileLoader.types.d.ts +11 -0
- package/SPLAT/splatFileLoader.types.js +2 -0
- package/SPLAT/splatFileLoader.types.js.map +1 -0
- package/STL/pure.d.ts +2 -0
- package/STL/pure.js +3 -0
- package/STL/pure.js.map +1 -0
- package/STL/stlFileLoader.d.ts +5 -76
- package/STL/stlFileLoader.js +7 -236
- package/STL/stlFileLoader.js.map +1 -1
- package/STL/stlFileLoader.pure.d.ts +73 -0
- package/STL/stlFileLoader.pure.js +249 -0
- package/STL/stlFileLoader.pure.js.map +1 -0
- package/STL/stlFileLoader.types.d.ts +10 -0
- package/STL/stlFileLoader.types.js +2 -0
- package/STL/stlFileLoader.types.js.map +1 -0
- package/glTF/1.0/pure.d.ts +3 -0
- package/glTF/1.0/pure.js +4 -0
- package/glTF/1.0/pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_area.d.ts +4 -39
- package/glTF/2.0/Extensions/EXT_lights_area.js +6 -91
- package/glTF/2.0/Extensions/EXT_lights_area.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_area.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js +106 -0
- package/glTF/2.0/Extensions/EXT_lights_area.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_area.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.d.ts +4 -39
- package/glTF/2.0/Extensions/EXT_lights_ies.js +6 -81
- package/glTF/2.0/Extensions/EXT_lights_ies.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js +96 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_ies.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.d.ts +4 -46
- package/glTF/2.0/Extensions/EXT_lights_image_based.js +6 -113
- package/glTF/2.0/Extensions/EXT_lights_image_based.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.d.ts +37 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js +128 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.d.ts +17 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_lights_image_based.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +5 -37
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +7 -92
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.d.ts +35 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js +106 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +4 -37
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js +6 -48
- package/glTF/2.0/Extensions/EXT_meshopt_compression.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.d.ts +36 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js +63 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_meshopt_compression.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.d.ts +4 -32
- package/glTF/2.0/Extensions/EXT_texture_avif.js +6 -36
- package/glTF/2.0/Extensions/EXT_texture_avif.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.d.ts +31 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.js +51 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_texture_avif.types.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.d.ts +4 -31
- package/glTF/2.0/Extensions/EXT_texture_webp.js +6 -35
- package/glTF/2.0/Extensions/EXT_texture_webp.js.map +1 -1
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.d.ts +30 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.js +50 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.pure.js.map +1 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.d.ts +9 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.js +2 -0
- package/glTF/2.0/Extensions/EXT_texture_webp.types.js.map +1 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.d.ts +4 -51
- package/glTF/2.0/Extensions/ExtrasAsMetadata.js +6 -71
- package/glTF/2.0/Extensions/ExtrasAsMetadata.js.map +1 -1
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.d.ts +50 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js +85 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.pure.js.map +1 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.d.ts +9 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js +2 -0
- package/glTF/2.0/Extensions/ExtrasAsMetadata.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +5 -45
- package/glTF/2.0/Extensions/KHR_animation_pointer.js +7 -75
- package/glTF/2.0/Extensions/KHR_animation_pointer.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.d.ts +43 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js +89 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_animation_pointer.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +4 -45
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +6 -90
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.d.ts +44 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js +105 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_draco_mesh_compression.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.d.ts +4 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js +5 -0
- package/glTF/2.0/Extensions/KHR_interactivity/pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity.d.ts +4 -36
- package/glTF/2.0/Extensions/KHR_interactivity.js +6 -148
- package/glTF/2.0/Extensions/KHR_interactivity.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_interactivity.pure.d.ts +35 -0
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js +163 -0
- package/glTF/2.0/Extensions/KHR_interactivity.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_interactivity.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +4 -39
- package/glTF/2.0/Extensions/KHR_lights_punctual.js +6 -89
- package/glTF/2.0/Extensions/KHR_lights_punctual.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.d.ts +38 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js +104 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_lights_punctual.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js +6 -63
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js +78 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_anisotropy.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js +6 -77
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js +92 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_clearcoat.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.d.ts +4 -47
- package/glTF/2.0/Extensions/KHR_materials_coat.js +6 -117
- package/glTF/2.0/Extensions/KHR_materials_coat.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.d.ts +46 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.js +132 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_coat.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js +6 -56
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js +71 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +6 -71
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js +86 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js +6 -54
- package/glTF/2.0/Extensions/KHR_materials_dispersion.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js +69 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_dispersion.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +6 -45
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js +60 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_emissive_strength.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_fuzz.js +6 -75
- package/glTF/2.0/Extensions/KHR_materials_fuzz.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js +90 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_fuzz.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.d.ts +4 -44
- package/glTF/2.0/Extensions/KHR_materials_ior.js +6 -52
- package/glTF/2.0/Extensions/KHR_materials_ior.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.d.ts +43 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.js +67 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_ior.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js +6 -66
- package/glTF/2.0/Extensions/KHR_materials_iridescence.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js +81 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_iridescence.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +6 -72
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js +87 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_sheen.js +6 -71
- package/glTF/2.0/Extensions/KHR_materials_sheen.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js +86 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_sheen.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_specular.js +6 -74
- package/glTF/2.0/Extensions/KHR_materials_specular.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.js +89 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_specular.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_transmission.js +6 -70
- package/glTF/2.0/Extensions/KHR_materials_transmission.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js +85 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_transmission.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +4 -40
- package/glTF/2.0/Extensions/KHR_materials_unlit.js +6 -64
- package/glTF/2.0/Extensions/KHR_materials_unlit.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.d.ts +39 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js +79 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_unlit.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.d.ts +4 -110
- package/glTF/2.0/Extensions/KHR_materials_variants.js +6 -260
- package/glTF/2.0/Extensions/KHR_materials_variants.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.d.ts +97 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.js +275 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.d.ts +29 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_variants.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.d.ts +4 -41
- package/glTF/2.0/Extensions/KHR_materials_volume.js +6 -77
- package/glTF/2.0/Extensions/KHR_materials_volume.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.d.ts +40 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.js +92 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_volume.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.d.ts +4 -43
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js +6 -113
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.d.ts +42 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js +128 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_materials_volume_scatter.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.d.ts +4 -27
- package/glTF/2.0/Extensions/KHR_mesh_quantization.js +6 -20
- package/glTF/2.0/Extensions/KHR_mesh_quantization.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.d.ts +26 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js +35 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_mesh_quantization.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.d.ts +4 -29
- package/glTF/2.0/Extensions/KHR_node_hoverability.js +6 -187
- package/glTF/2.0/Extensions/KHR_node_hoverability.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.d.ts +28 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js +202 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_hoverability.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.d.ts +4 -28
- package/glTF/2.0/Extensions/KHR_node_selectability.js +6 -121
- package/glTF/2.0/Extensions/KHR_node_selectability.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.d.ts +27 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js +136 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_selectability.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.d.ts +4 -28
- package/glTF/2.0/Extensions/KHR_node_visibility.js +6 -64
- package/glTF/2.0/Extensions/KHR_node_visibility.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.d.ts +27 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.js +79 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_node_visibility.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +4 -31
- package/glTF/2.0/Extensions/KHR_texture_basisu.js +6 -35
- package/glTF/2.0/Extensions/KHR_texture_basisu.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.d.ts +30 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js +50 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_texture_basisu.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.d.ts +4 -35
- package/glTF/2.0/Extensions/KHR_texture_transform.js +6 -56
- package/glTF/2.0/Extensions/KHR_texture_transform.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.d.ts +34 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.js +71 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_texture_transform.types.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +4 -37
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js +6 -45
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.js.map +1 -1
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.d.ts +36 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js +60 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.pure.js.map +1 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.d.ts +9 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js +2 -0
- package/glTF/2.0/Extensions/KHR_xmp_json_ld.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.d.ts +5 -54
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js +7 -226
- package/glTF/2.0/Extensions/MSFT_audio_emitter.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.d.ts +52 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js +240 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_audio_emitter.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_lod.d.ts +4 -102
- package/glTF/2.0/Extensions/MSFT_lod.js +6 -335
- package/glTF/2.0/Extensions/MSFT_lod.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_lod.pure.d.ts +96 -0
- package/glTF/2.0/Extensions/MSFT_lod.pure.js +350 -0
- package/glTF/2.0/Extensions/MSFT_lod.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.d.ts +14 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_lod.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.d.ts +6 -27
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js +8 -40
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.d.ts +24 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js +53 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_minecraftMesh.types.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.d.ts +6 -27
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js +8 -38
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.js.map +1 -1
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.d.ts +24 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js +51 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.pure.js.map +1 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.d.ts +9 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js +2 -0
- package/glTF/2.0/Extensions/MSFT_sRGBFactors.types.js.map +1 -0
- package/glTF/2.0/Extensions/pure.d.ts +45 -0
- package/glTF/2.0/Extensions/pure.js +47 -0
- package/glTF/2.0/Extensions/pure.js.map +1 -0
- package/glTF/2.0/glTFLoader.d.ts +1 -471
- package/glTF/2.0/glTFLoader.js +3 -2539
- package/glTF/2.0/glTFLoader.js.map +1 -1
- package/glTF/2.0/glTFLoader.pure.d.ts +476 -0
- package/glTF/2.0/glTFLoader.pure.js +2563 -0
- package/glTF/2.0/glTFLoader.pure.js.map +1 -0
- package/glTF/2.0/pure.d.ts +8 -0
- package/glTF/2.0/pure.js +10 -0
- package/glTF/2.0/pure.js.map +1 -0
- package/glTF/glTFFileLoader.d.ts +5 -551
- package/glTF/glTFFileLoader.js +6 -996
- package/glTF/glTFFileLoader.js.map +1 -1
- package/glTF/glTFFileLoader.pure.d.ts +562 -0
- package/glTF/glTFFileLoader.pure.js +1024 -0
- package/glTF/glTFFileLoader.pure.js.map +1 -0
- package/glTF/glTFFileLoader.types.d.ts +11 -0
- package/glTF/glTFFileLoader.types.js +2 -0
- package/glTF/glTFFileLoader.types.js.map +1 -0
- package/glTF/pure.d.ts +6 -0
- package/glTF/pure.js +8 -0
- package/glTF/pure.js.map +1 -0
- package/package.json +56 -4
- package/pure.d.ts +8 -0
- package/pure.js +10 -0
- package/pure.js.map +1 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gaussianSplattingStream.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingStream.ts"],"names":[],"mappings":"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","sourcesContent":["import { GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh\";\r\nimport { type IGaussianSplattingSplatRange } from \"core/Meshes/GaussianSplatting/gaussianSplattingMeshBase\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Vector3, Matrix } from \"core/Maths/math.vector\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Frustum } from \"core/Maths/math.frustum\";\r\nimport { Plane } from \"core/Maths/math.plane\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { BoundingInfo } from \"core/Culling/boundingInfo\";\r\nimport { CreateLineSystem } from \"core/Meshes/Builders/linesBuilder\";\r\nimport { type LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { ParseSogMetaAsTextures, type SOGRootData } from \"./sog\";\r\nimport { GaussianSplattingWorkBuffer } from \"./gaussianSplattingWorkBuffer\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\n\r\n/**\r\n * A single LOD variant of a tree node: a contiguous splat range inside one streamed SOG file.\r\n */\r\ninterface ISOGLODEntry {\r\n /** Index into {@link ISOGLODMetadata.filenames}. */\r\n file: number;\r\n /** First splat index inside that file. */\r\n offset: number;\r\n /** Number of splats. */\r\n count: number;\r\n}\r\n\r\n/**\r\n * A node of the PlayCanvas-style SOG LOD octree. Internal nodes have `children`; leaves have `lods`.\r\n */\r\ninterface ISOGLODNode {\r\n bound: { min: number[]; max: number[] };\r\n children?: ISOGLODNode[];\r\n lods?: { [level: string]: ISOGLODEntry };\r\n /** LOD level currently streamed/rendered for this node, or undefined until its base LOD is ready. */\r\n activeLod?: number;\r\n /** Distance-based ideal LOD level for this node, recomputed per frame. */\r\n optimalLod?: number;\r\n /** Available LOD levels for this leaf, sorted ascending (0 = finest). Set during the tree walk. */\r\n availableLevels?: number[];\r\n /** Coarsest available level (= max key), always streamed as the permanent base layer. */\r\n baseLod?: number;\r\n /** Final LOD level the node should stream/render (distance optimal, capped by maxDetailLod). */\r\n targetLevel?: number;\r\n /** Frames remaining before this node may switch LOD again (oscillation damping). */\r\n lodCooldown?: number;\r\n /** True when the node's bounding box currently intersects the camera frustum. Drives the LOD bias that\r\n * pushes off-screen nodes to the coarsest level (they stay rendered, not hidden). */\r\n inFrustum?: boolean;\r\n /** Cached local-space bounding info used for the per-node frustum test (created once per leaf). */\r\n cullBounds?: BoundingInfo;\r\n}\r\n\r\n/**\r\n * Parsed contents of a PlayCanvas-style `lod-meta.json` file.\r\n */\r\nexport interface ISOGLODMetadata {\r\n /** Number of LOD levels (0 = highest detail). */\r\n lodLevels: number;\r\n /** SOG `meta.json` paths, relative to the metadata file, indexed by `ISOGLODEntry.file`. */\r\n filenames: string[];\r\n /** Optional always-on environment `.sog` bundle, relative to the metadata file. */\r\n environment?: string;\r\n /** Root of the LOD octree. */\r\n tree: ISOGLODNode;\r\n}\r\n\r\n/**\r\n * Selects which LOD value drives the {@link GaussianSplattingStream} debug wireframe colors.\r\n */\r\nexport type GaussianSplattingStreamDebugLodSource = \"optimal\" | \"current\";\r\n\r\n/**\r\n * Options for {@link GaussianSplattingStream}.\r\n */\r\nexport interface IGaussianSplattingStreamOptions {\r\n /** URL of the fflate UMD module used to unzip `.sog` environment bundles. */\r\n deflateURL?: string;\r\n /** Pre-loaded fflate module. */\r\n fflate?: any;\r\n /** When true, renders a wireframe box per LOD node, colored by the node's LOD level. */\r\n debugDisplay?: boolean;\r\n /** Which LOD value drives the debug wireframe colors. Defaults to `\"optimal\"`. */\r\n debugLodSource?: GaussianSplattingStreamDebugLodSource;\r\n /** Distance (in local units) of the first LOD transition. PlayCanvas default `5`. */\r\n lodBaseDistance?: number;\r\n /** Geometric ratio between successive LOD transition distances. PlayCanvas default `3`. */\r\n lodMultiplier?: number;\r\n /** Distance multiplier applied to nodes behind the camera (`1` = no penalty). PlayCanvas default `1`. */\r\n lodBehindPenalty?: number;\r\n /** Lowest LOD index the optimal-LOD heuristic may select. Defaults to `0`. */\r\n lodRangeMin?: number;\r\n /** Highest LOD index the optimal-LOD heuristic may select. Defaults to `lodLevels - 1`. */\r\n lodRangeMax?: number;\r\n /** Maximum number of LOD source files to GPU-decode per frame (spreads work to avoid hitches). Defaults to `1`. */\r\n maxDecodesPerFrame?: number;\r\n /** Frames a node must wait after switching LOD before it may switch again (oscillation damping). Defaults to `10`. */\r\n lodCooldownFrames?: number;\r\n /** Minimum number of frames between LOD re-evaluations (throttles per-frame work during motion). Defaults to `4`. */\r\n lodUpdateInterval?: number;\r\n /** Minimum camera movement (world units) required to re-evaluate LODs. Defaults to `0.5`. */\r\n lodUpdateDistance?: number;\r\n /**\r\n * Finest (most detailed) LOD level any node is allowed to render. `0` allows full detail (level 0);\r\n * `1` caps detail at the next-coarser level, and so on. Higher values force a coarser maximum detail.\r\n */\r\n maxDetailLod?: number;\r\n /**\r\n * When true (default), LOD nodes outside the camera frustum are biased to their coarsest LOD rather than\r\n * rendered at full detail. They stay in the sort/render set so they appear instantly (at low detail) when\r\n * the camera turns toward them, then refine. Set to `false` to render every node at its distance LOD.\r\n */\r\n frustumCulling?: boolean;\r\n}\r\n\r\n// tan(22.5deg): reference half-FOV for a 45-degree vertical FOV, used for FOV compensation (matches PlayCanvas).\r\nconst RefTanHalfFov = Math.tan((22.5 * Math.PI) / 180);\r\n\r\n// Scratch objects reused by the per-frame optimal-LOD evaluation (avoids per-call allocations).\r\nconst TmpInvWorld = new Matrix();\r\nconst TmpLocalCamera = new Vector3();\r\nconst TmpLocalForward = new Vector3();\r\nconst TmpWorldForward = new Vector3();\r\n// Camera-local forward axis (+Z) used to derive the world-space view direction.\r\nconst LocalForwardAxis = new Vector3(0, 0, 1);\r\n\r\n// The 12 edges of a box, as index pairs into its 8 corners. 12 edges x 2 endpoints = 24 vertices per box.\r\nconst BoxEdges = [\r\n [0, 1],\r\n [1, 2],\r\n [2, 3],\r\n [3, 0],\r\n [4, 5],\r\n [5, 6],\r\n [6, 7],\r\n [7, 4],\r\n [0, 4],\r\n [1, 5],\r\n [2, 6],\r\n [3, 7],\r\n];\r\n// Vertices generated per leaf box (BoxEdges.length * 2).\r\nconst VerticesPerBox = BoxEdges.length * 2;\r\n\r\n/**\r\n * Wireframe colors per LOD level (cycled by `node.activeLod`).\r\n */\r\nconst GsLodDebugColors = [\r\n new Color4(1.0, 0.2, 0.2, 1.0), // LOD 0 - red\r\n new Color4(1.0, 0.6, 0.1, 1.0), // LOD 1 - orange\r\n new Color4(1.0, 1.0, 0.2, 1.0), // LOD 2 - yellow\r\n new Color4(0.3, 1.0, 0.3, 1.0), // LOD 3 - green\r\n new Color4(0.2, 1.0, 1.0, 1.0), // LOD 4 - cyan\r\n new Color4(0.4, 0.5, 1.0, 1.0), // LOD 5 - blue\r\n new Color4(0.9, 0.4, 1.0, 1.0), // LOD 6 - magenta\r\n new Color4(1.0, 1.0, 1.0, 1.0), // LOD 7 - white\r\n];\r\n\r\n/**\r\n * Streams a PlayCanvas-style SOG LOD scene (`lod-meta.json`) into a single Gaussian Splatting mesh.\r\n *\r\n * Each selected SOG file (plus the environment) is loaded directly as GPU textures and decoded on the\r\n * GPU into one unified, PlayCanvas-style square work buffer (no CPU splat decode or `updateData`). Only\r\n * the splats of each node's currently-selected LOD are rendered/sorted via the mesh's interval filter.\r\n *\r\n * The coarsest (least-detail) LOD of every node is streamed first as a permanent base layer so the whole\r\n * scene is visible quickly with no holes. A distance-based \"optimal\" LOD is then computed per node (see\r\n * {@link evaluateOptimalLods}); finer LOD source files are streamed on demand and a node only switches to\r\n * a finer LOD once that file is decoded, so transitions never flash or leave gaps.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingStream extends GaussianSplattingMesh {\r\n private readonly _metadata: ISOGLODMetadata;\r\n private readonly _rootUrl: string;\r\n private readonly _streamOptions: IGaussianSplattingStreamOptions;\r\n\r\n // Flat list of leaf nodes that carry renderable LOD entries (used by the LOD heuristic and debug).\r\n private readonly _leafNodes: ISOGLODNode[] = [];\r\n\r\n // LOD heuristic parameters (PlayCanvas-aligned defaults).\r\n private _lodBaseDistance = 5;\r\n private _lodMultiplier = 3;\r\n private _lodBehindPenalty = 1;\r\n private _lodRangeMin = 0;\r\n private _lodRangeMax: number;\r\n private _maxDecodesPerFrame = 1;\r\n private _lodCooldownFrames = 10;\r\n // Minimum frames between LOD re-evaluations, and minimum camera movement (world units) to re-evaluate.\r\n private _lodUpdateInterval = 4;\r\n private _lodUpdateDistance = 0.5;\r\n private _maxDetailLod = 0;\r\n\r\n // Frustum LOD bias: when enabled, nodes outside the camera frustum are rendered at their coarsest LOD.\r\n private _frustumCulling = true;\r\n // Reused world-space frustum planes and view-projection scratch matrix (avoids per-frame allocation).\r\n private readonly _frustumPlanes: Plane[] = [\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n ];\r\n private readonly _cullViewProj = new Matrix();\r\n\r\n // GPU work buffer holding all decoded splats; created once the total capacity is known.\r\n private _workBuffer: Nullable<GaussianSplattingWorkBuffer> = null;\r\n // True once GPU position readback has been validated against a CPU decode (see _probeReadbackAsync). While\r\n // false, positions are decoded on the CPU from the means images; once validated, every SOG image uses the\r\n // fast direct upload and positions are read back from the work buffer (non-blocking).\r\n private _useGpuPositionReadback = false;\r\n // Whether the engine reports GPU readback support (candidate to validate on the first decode).\r\n private _readbackCandidate = false;\r\n // Set once the one-time readback validation has run (success or failure).\r\n private _readbackProbed = false;\r\n\r\n // Global splat offset where each source file begins in the work buffer (fixed for all files up front).\r\n private readonly _fileBaseSplat = new Map<number, number>();\r\n // Splat count of each source file (learned from its metadata before allocation).\r\n private readonly _fileCounts = new Map<number, number>();\r\n // Cached SOG metadata per file so on-demand decodes don't refetch the meta.json.\r\n private readonly _fileMeta = new Map<number, { sogData: SOGRootData; subRootUrl: string }>();\r\n // Files whose splats have been GPU-decoded into the work buffer.\r\n private readonly _decodedFiles = new Set<number>();\r\n // Files whose decode is currently in flight (dedupes concurrent requests).\r\n private readonly _loadingFiles = new Set<number>();\r\n // FIFO of file ids waiting to be decoded (drained under a per-frame budget).\r\n private readonly _decodeQueue: number[] = [];\r\n\r\n // Global range covered by the environment file (always rendered), or null until it loads.\r\n private _environmentRange: Nullable<{ offset: number; count: number }> = null;\r\n // Unzipped environment bundle contents, retained between count-gathering and decode.\r\n private _environmentFiles: Nullable<Map<string, Uint8Array>> = null;\r\n\r\n // Per-frame LOD streaming loop; installed once the base layer is ready.\r\n private _lodObserver: Nullable<Observer<Scene>> = null;\r\n private _baseLayerReady = false;\r\n // Throttling state for the per-frame LOD loop.\r\n private _framesSinceLodUpdate = 0;\r\n private readonly _lastLodCamPos = new Vector3(Infinity, Infinity, Infinity);\r\n // Forces the next LOD update to run regardless of the throttle (e.g. after a budget change).\r\n private _forceLodUpdate = false;\r\n\r\n // Running local-space bounds of all decoded splat centers (for frustum culling / picking).\r\n private readonly _boundsMin = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n private readonly _boundsMax = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Debug LOD-node wireframe display.\r\n private _debugDisplay = false;\r\n private _debugLodSource: GaussianSplattingStreamDebugLodSource = \"optimal\";\r\n private _debugMesh: Nullable<LinesMesh> = null;\r\n private _debugObserver: Nullable<Observer<Scene>> = null;\r\n // Per-vertex RGBA color buffer mirror, updated in place when LOD colors change (avoids mesh rebuild flicker).\r\n private _debugColorData: Nullable<Float32Array> = null;\r\n // Signature of the per-leaf displayed LOD levels, used to skip rebuilding unchanged debug geometry.\r\n private _debugSignature = 0;\r\n\r\n private _disposed = false;\r\n\r\n /**\r\n * Returns true when the parsed JSON looks like a PlayCanvas-style `lod-meta.json` payload.\r\n * @param data parsed JSON\r\n * @returns whether the data is SOG LOD metadata\r\n */\r\n public static IsLODMetadata(data: unknown): data is ISOGLODMetadata {\r\n if (typeof data !== \"object\" || data === null) {\r\n return false;\r\n }\r\n const meta = data as Partial<ISOGLODMetadata>;\r\n return typeof meta.lodLevels === \"number\" && Array.isArray(meta.filenames) && typeof meta.tree === \"object\" && meta.tree !== null;\r\n }\r\n\r\n /**\r\n * Creates a new SOG LOD streaming mesh and immediately starts streaming (non-blocking).\r\n * @param name mesh name\r\n * @param metadata parsed `lod-meta.json`\r\n * @param rootUrl base URL the metadata's relative paths resolve against\r\n * @param scene hosting scene\r\n * @param options streaming options\r\n */\r\n constructor(name: string, metadata: ISOGLODMetadata, rootUrl: string, scene: Scene, options: IGaussianSplattingStreamOptions = {}) {\r\n super(name, null, scene, false);\r\n this._metadata = metadata;\r\n this._rootUrl = rootUrl;\r\n this._streamOptions = options;\r\n\r\n // LOD heuristic parameters: take the provided values, otherwise keep the PlayCanvas-aligned defaults.\r\n const maxLod = Math.max(0, metadata.lodLevels - 1);\r\n this._lodRangeMax = maxLod;\r\n if (options.lodBaseDistance !== undefined) {\r\n this._lodBaseDistance = Math.max(0.1, options.lodBaseDistance);\r\n }\r\n if (options.lodMultiplier !== undefined) {\r\n this._lodMultiplier = Math.max(1.2, options.lodMultiplier);\r\n }\r\n if (options.lodBehindPenalty !== undefined) {\r\n this._lodBehindPenalty = Math.max(1, options.lodBehindPenalty);\r\n }\r\n if (options.lodRangeMin !== undefined) {\r\n this._lodRangeMin = Math.max(0, Math.min(options.lodRangeMin, maxLod));\r\n }\r\n if (options.lodRangeMax !== undefined) {\r\n this._lodRangeMax = Math.max(this._lodRangeMin, Math.min(options.lodRangeMax, maxLod));\r\n }\r\n if (options.maxDecodesPerFrame !== undefined) {\r\n this._maxDecodesPerFrame = Math.max(1, options.maxDecodesPerFrame);\r\n }\r\n if (options.lodCooldownFrames !== undefined) {\r\n this._lodCooldownFrames = Math.max(0, options.lodCooldownFrames);\r\n }\r\n if (options.lodUpdateInterval !== undefined) {\r\n this._lodUpdateInterval = Math.max(1, options.lodUpdateInterval);\r\n }\r\n if (options.lodUpdateDistance !== undefined) {\r\n this._lodUpdateDistance = Math.max(0, options.lodUpdateDistance);\r\n }\r\n if (options.maxDetailLod !== undefined) {\r\n this._maxDetailLod = Math.max(0, Math.floor(options.maxDetailLod));\r\n }\r\n if (options.frustumCulling !== undefined) {\r\n this._frustumCulling = options.frustumCulling;\r\n }\r\n if (options.debugLodSource) {\r\n this._debugLodSource = options.debugLodSource;\r\n }\r\n\r\n // PlayCanvas SOG data is authored with a flipped Y; match the standard SOG loader.\r\n this.scaling.y *= -1;\r\n // PlayCanvas SOG LOD scenes are authored Z-up; rotate into Babylon's Y-up convention.\r\n this.rotation.x = -Math.PI / 2;\r\n\r\n this._collectLodEntries(metadata.tree);\r\n\r\n if (options.debugDisplay) {\r\n this.debugDisplay = true;\r\n }\r\n\r\n // Kick off streaming without blocking the caller or the render loop.\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n this._streamAllAsync().catch((e) => {\r\n Logger.Error(\"GaussianSplattingStream: streaming failed: \" + (e?.message ?? e));\r\n });\r\n }\r\n\r\n public override getClassName(): string {\r\n return \"GaussianSplattingStream\";\r\n }\r\n\r\n /**\r\n * Finest (most detailed) LOD level any node is allowed to render. `0` allows full detail (level 0);\r\n * `1` caps detail at the next-coarser level, and so on. Nodes already coarser than this cap (by\r\n * distance) are unaffected. Changes take effect in real time.\r\n */\r\n public get maxDetailLod(): number {\r\n return this._maxDetailLod;\r\n }\r\n\r\n public set maxDetailLod(value: number) {\r\n const level = Math.max(0, Math.floor(value));\r\n if (this._maxDetailLod === level) {\r\n return;\r\n }\r\n this._maxDetailLod = level;\r\n // Re-evaluate LODs on the next frame regardless of the movement throttle so the change is immediate.\r\n this._forceLodUpdate = true;\r\n }\r\n\r\n /**\r\n * Coarsest LOD level index in the scene (number of LOD levels minus one). Useful as the upper bound\r\n * for {@link maxDetailLod}.\r\n */\r\n public get maxLodLevel(): number {\r\n return Math.max(0, this._metadata.lodLevels - 1);\r\n }\r\n\r\n /**\r\n * When true (default), nodes whose bounding box is outside the camera frustum are biased to the coarsest\r\n * LOD instead of being hidden. They stay in the sort/render set (their off-screen splats are clipped), so\r\n * turning the camera toward them shows low detail immediately with no invisible frames, then refines.\r\n * Changes take effect in real time.\r\n */\r\n public get frustumCulling(): boolean {\r\n return this._frustumCulling;\r\n }\r\n\r\n public set frustumCulling(value: boolean) {\r\n if (this._frustumCulling === value) {\r\n return;\r\n }\r\n this._frustumCulling = value;\r\n // Re-evaluate LODs next frame so the off-screen bias is applied/removed immediately.\r\n this._forceLodUpdate = true;\r\n }\r\n\r\n /**\r\n * When true, renders a wireframe box per LOD node, colored by the LOD level selected by {@link debugLodSource}.\r\n */\r\n public get debugDisplay(): boolean {\r\n return this._debugDisplay;\r\n }\r\n\r\n public set debugDisplay(value: boolean) {\r\n if (this._debugDisplay === value) {\r\n return;\r\n }\r\n this._debugDisplay = value;\r\n if (value) {\r\n this._refreshDebugDisplay();\r\n } else {\r\n this._clearDebugDisplay();\r\n }\r\n }\r\n\r\n /**\r\n * Selects which LOD value drives the debug wireframe colors: the distance-based `\"optimal\"` LOD\r\n * (default, recomputed as the camera moves) or the `\"current\"` streamed/rendered LOD.\r\n */\r\n public get debugLodSource(): GaussianSplattingStreamDebugLodSource {\r\n return this._debugLodSource;\r\n }\r\n\r\n public set debugLodSource(value: GaussianSplattingStreamDebugLodSource) {\r\n if (this._debugLodSource === value) {\r\n return;\r\n }\r\n this._debugLodSource = value;\r\n if (this._debugDisplay) {\r\n this._refreshDebugDisplay();\r\n }\r\n }\r\n\r\n public override dispose(doNotRecurse?: boolean): void {\r\n this._disposed = true;\r\n if (this._lodObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._lodObserver);\r\n this._lodObserver = null;\r\n }\r\n this._clearDebugDisplay();\r\n this._workBuffer?.dispose();\r\n this._workBuffer = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n /**\r\n * Re-evaluates the optimal LOD for every node based on the camera position. The result is stored in\r\n * each node's `optimalLod`. Rendering is unaffected; this currently drives only diagnostics and the\r\n * debug wireframe display.\r\n * @param camera camera to evaluate against (defaults to the scene's active camera)\r\n */\r\n public evaluateOptimalLods(camera: Nullable<Camera> = this._scene.activeCamera): void {\r\n if (!camera || this._leafNodes.length === 0) {\r\n return;\r\n }\r\n\r\n const maxLod = Math.max(0, this._metadata.lodLevels - 1);\r\n const base = this._lodBaseDistance;\r\n const mult = this._lodMultiplier;\r\n const behindPenalty = this._lodBehindPenalty;\r\n const rangeMin = this._lodRangeMin;\r\n const rangeMax = this._lodRangeMax;\r\n\r\n // FOV compensation: use min(tanHalfV, tanHalfH) so transitions stay perceptually uniform (matches PlayCanvas).\r\n const aspect = this._scene.getEngine().getAspectRatio(camera) || 1;\r\n let tanHalfV = Math.tan(camera.fov * 0.5);\r\n if (camera.fovMode === Camera.FOVMODE_HORIZONTAL_FIXED) {\r\n tanHalfV /= aspect;\r\n }\r\n const tanHalfH = tanHalfV * aspect;\r\n const fovScale = Math.min(tanHalfV, tanHalfH) / RefTanHalfFov;\r\n\r\n // Transform the camera into the mesh's local space (where the node bounds live).\r\n this.computeWorldMatrix(false).invertToRef(TmpInvWorld);\r\n const localCamera = Vector3.TransformCoordinatesToRef(camera.globalPosition, TmpInvWorld, TmpLocalCamera);\r\n const px = localCamera.x;\r\n const py = localCamera.y;\r\n const pz = localCamera.z;\r\n\r\n let fwx = 0;\r\n let fwy = 0;\r\n let fwz = 0;\r\n if (behindPenalty > 1) {\r\n camera.getDirectionToRef(LocalForwardAxis, TmpWorldForward);\r\n const localForward = Vector3.TransformNormalToRef(TmpWorldForward, TmpInvWorld, TmpLocalForward);\r\n localForward.normalize();\r\n fwx = localForward.x;\r\n fwy = localForward.y;\r\n fwz = localForward.z;\r\n }\r\n\r\n for (const node of this._leafNodes) {\r\n const mn = node.bound.min;\r\n const mx = node.bound.max;\r\n\r\n // Distance from the camera to the closest point on this node's AABB (local space).\r\n const qx = px < mn[0] ? mn[0] : px > mx[0] ? mx[0] : px;\r\n const qy = py < mn[1] ? mn[1] : py > mx[1] ? mx[1] : py;\r\n const qz = pz < mn[2] ? mn[2] : pz > mx[2] ? mx[2] : pz;\r\n const dx = qx - px;\r\n const dy = qy - py;\r\n const dz = qz - pz;\r\n const actualDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\r\n\r\n // Push nodes behind the camera toward coarser LODs when a penalty is configured.\r\n let penalizedDistance = actualDistance;\r\n if (behindPenalty > 1 && actualDistance > 0.01) {\r\n const dotOverDistance = (fwx * dx + fwy * dy + fwz * dz) / actualDistance;\r\n if (dotOverDistance < 0) {\r\n penalizedDistance = actualDistance * (1 + -dotOverDistance * (behindPenalty - 1));\r\n }\r\n }\r\n\r\n // Geometric LOD bands: threshold[k] = base * mult^(k-1).\r\n const fovAdjustedDistance = penalizedDistance * fovScale;\r\n let optimalLod: number;\r\n if (maxLod === 0 || fovAdjustedDistance < base) {\r\n optimalLod = 0;\r\n } else {\r\n optimalLod = maxLod;\r\n while (optimalLod > 1 && fovAdjustedDistance < base * Math.pow(mult, optimalLod - 1)) {\r\n optimalLod--;\r\n }\r\n }\r\n\r\n if (optimalLod < rangeMin) {\r\n optimalLod = rangeMin;\r\n } else if (optimalLod > rangeMax) {\r\n optimalLod = rangeMax;\r\n }\r\n\r\n // Frustum-based LOD bias: nodes outside the camera frustum are pushed to the coarsest allowed\r\n // level instead of being hidden. They stay in the render/sort set (their splats are off-screen\r\n // and clipped anyway), so when the camera turns to include them they are already present at low\r\n // detail with no invisible frames, then refine to the distance-optimal level.\r\n if (this._frustumCulling && node.inFrustum === false) {\r\n optimalLod = rangeMax;\r\n }\r\n\r\n node.optimalLod = optimalLod;\r\n }\r\n }\r\n\r\n /**\r\n * The LOD level used to color a node's debug box, per {@link debugLodSource}.\r\n * @param node leaf node\r\n * @returns the displayed LOD level\r\n */\r\n private _displayedLodLevel(node: ISOGLODNode): number {\r\n if (this._debugLodSource === \"optimal\") {\r\n return node.optimalLod ?? node.activeLod ?? 0;\r\n }\r\n return node.activeLod ?? 0;\r\n }\r\n\r\n /**\r\n * Rebuilds the debug wireframe (evaluating the optimal LOD first when needed) and wires up the per-frame\r\n * recolor observer. The observer runs for both LOD sources: \"optimal\" colors track the camera, and\r\n * \"current\" colors track LOD levels as they stream in/out.\r\n */\r\n private _refreshDebugDisplay(): void {\r\n if (this._debugLodSource === \"optimal\") {\r\n this.evaluateOptimalLods();\r\n }\r\n this._buildDebugMesh();\r\n\r\n const needsObserver = this._debugDisplay;\r\n if (needsObserver && !this._debugObserver) {\r\n this._debugObserver = this._scene.onBeforeRenderObservable.add(() => this._onDebugFrame());\r\n } else if (!needsObserver && this._debugObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._debugObserver);\r\n this._debugObserver = null;\r\n }\r\n }\r\n\r\n /**\r\n * Per-frame debug update: recolors the existing wireframe in place whenever the displayed LOD levels\r\n * change. For the \"optimal\" source the optimal LOD is recomputed first (it tracks the camera); for the\r\n * \"current\" source the levels are driven by the streaming loop, so no recomputation is needed here. The\r\n * geometry is never rebuilt, which avoids the dispose/recreate flicker while the camera moves.\r\n */\r\n private _onDebugFrame(): void {\r\n if (this._debugLodSource === \"optimal\") {\r\n this.evaluateOptimalLods();\r\n }\r\n if (this._computeDebugSignature() !== this._debugSignature) {\r\n this._updateDebugColors();\r\n }\r\n }\r\n\r\n /**\r\n * Builds the LOD-node wireframe boxes once (one box per leaf node), colored by the displayed LOD level.\r\n * The color vertex buffer is created updatable so subsequent recolors can happen in place.\r\n */\r\n private _buildDebugMesh(): void {\r\n if (this._debugMesh) {\r\n this._debugMesh.dispose();\r\n this._debugMesh = null;\r\n }\r\n this._debugColorData = null;\r\n\r\n const lines: Vector3[][] = [];\r\n const colors: Color4[][] = [];\r\n for (const node of this._leafNodes) {\r\n const color = GsLodDebugColors[this._displayedLodLevel(node) % GsLodDebugColors.length];\r\n const mn = node.bound.min;\r\n const mx = node.bound.max;\r\n const corners = [\r\n new Vector3(mn[0], mn[1], mn[2]),\r\n new Vector3(mx[0], mn[1], mn[2]),\r\n new Vector3(mx[0], mx[1], mn[2]),\r\n new Vector3(mn[0], mx[1], mn[2]),\r\n new Vector3(mn[0], mn[1], mx[2]),\r\n new Vector3(mx[0], mn[1], mx[2]),\r\n new Vector3(mx[0], mx[1], mx[2]),\r\n new Vector3(mn[0], mx[1], mx[2]),\r\n ];\r\n for (const edge of BoxEdges) {\r\n lines.push([corners[edge[0]], corners[edge[1]]]);\r\n colors.push([color, color]);\r\n }\r\n }\r\n\r\n this._debugSignature = this._computeDebugSignature();\r\n if (lines.length === 0) {\r\n return;\r\n }\r\n\r\n const mesh = CreateLineSystem(this.name + \"_lodDebug\", { lines, colors, updatable: true, useVertexAlpha: false }, this._scene);\r\n mesh.parent = this;\r\n mesh.isPickable = false;\r\n mesh.doNotSerialize = true;\r\n mesh.reservedDataStore = { hidden: true };\r\n this._debugMesh = mesh;\r\n this._debugColorData = new Float32Array(this._leafNodes.length * VerticesPerBox * 4);\r\n }\r\n\r\n /**\r\n * Recolors the existing wireframe in place from the current displayed LOD levels, without rebuilding geometry.\r\n */\r\n private _updateDebugColors(): void {\r\n if (!this._debugMesh || !this._debugColorData) {\r\n return;\r\n }\r\n const data = this._debugColorData;\r\n let offset = 0;\r\n for (const node of this._leafNodes) {\r\n const color = GsLodDebugColors[this._displayedLodLevel(node) % GsLodDebugColors.length];\r\n for (let v = 0; v < VerticesPerBox; v++) {\r\n data[offset++] = color.r;\r\n data[offset++] = color.g;\r\n data[offset++] = color.b;\r\n data[offset++] = color.a;\r\n }\r\n }\r\n this._debugMesh.updateVerticesData(VertexBuffer.ColorKind, data);\r\n this._debugSignature = this._computeDebugSignature();\r\n }\r\n\r\n /**\r\n * Computes a cheap 32-bit rolling hash of every leaf's displayed LOD level, used to detect when the\r\n * debug wireframe needs recoloring. Avoids per-frame string allocation in the render loop.\r\n * @returns a numeric signature of the current displayed LOD levels\r\n */\r\n private _computeDebugSignature(): number {\r\n let hash = 0;\r\n for (const node of this._leafNodes) {\r\n hash = (hash * 31 + this._displayedLodLevel(node)) | 0;\r\n }\r\n return hash;\r\n }\r\n\r\n /**\r\n * Disposes the LOD-node wireframe boxes and stops live debug updates.\r\n */\r\n private _clearDebugDisplay(): void {\r\n if (this._debugObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._debugObserver);\r\n this._debugObserver = null;\r\n }\r\n if (this._debugMesh) {\r\n this._debugMesh.dispose();\r\n this._debugMesh = null;\r\n }\r\n this._debugColorData = null;\r\n this._debugSignature = 0;\r\n }\r\n\r\n /**\r\n * Walks the LOD tree and records every leaf that carries renderable LOD entries, capturing the set of\r\n * available levels and the coarsest (base) level for each.\r\n * @param node current tree node\r\n */\r\n private _collectLodEntries(node: ISOGLODNode): void {\r\n if (node.children) {\r\n for (const child of node.children) {\r\n this._collectLodEntries(child);\r\n }\r\n return;\r\n }\r\n\r\n if (!node.lods) {\r\n return;\r\n }\r\n\r\n // Collect all levels that hold splats (PlayCanvas convention: level 0 is the finest, higher = coarser).\r\n const levels: number[] = [];\r\n for (const key of Object.keys(node.lods)) {\r\n const level = Number(key);\r\n const entry = node.lods[key];\r\n if (Number.isFinite(level) && entry && entry.count > 0) {\r\n levels.push(level);\r\n }\r\n }\r\n if (levels.length === 0) {\r\n return;\r\n }\r\n levels.sort((a, b) => a - b);\r\n\r\n node.availableLevels = levels;\r\n node.baseLod = levels[levels.length - 1];\r\n node.activeLod = undefined;\r\n node.lodCooldown = 0;\r\n node.inFrustum = true;\r\n // Local-space bounds for the per-node frustum test; the mesh world matrix is applied per evaluation.\r\n node.cullBounds = new BoundingInfo(Vector3.FromArray(node.bound.min), Vector3.FromArray(node.bound.max));\r\n this._leafNodes.push(node);\r\n }\r\n\r\n /**\r\n * Streams the scene: learns every source file's splat count, allocates one unified GPU work buffer\r\n * sized for all LOD files, decodes the environment and the coarsest LOD of every node as a permanent\r\n * base layer, then installs the per-frame loop that streams finer LODs on demand.\r\n */\r\n private async _streamAllAsync(): Promise<void> {\r\n // Phase 1: learn splat counts for the environment and every referenced LOD file (cheap meta only).\r\n const fileIds = this._collectAllFileIds();\r\n const envCount = await this._gatherCountsAsync(fileIds);\r\n if (this._disposed) {\r\n return;\r\n }\r\n\r\n // Phase 2: assign fixed work-buffer offsets (environment first, then every file) and allocate.\r\n // Index 0 is reserved as a never-decoded padding splat: the sort worker and index buffer pad unused\r\n // slots with index 0, and leaving that slot zeroed (center.w = 0 => zero covariance, alpha 0) makes\r\n // the padding invisible instead of ghosting a copy of the first real splat.\r\n let capacity = 1;\r\n if (envCount > 0) {\r\n this._environmentRange = { offset: capacity, count: envCount };\r\n capacity += envCount;\r\n }\r\n for (const fileId of fileIds) {\r\n const count = this._fileCounts.get(fileId);\r\n if (count === undefined || count <= 0) {\r\n continue;\r\n }\r\n this._fileBaseSplat.set(fileId, capacity);\r\n capacity += count;\r\n }\r\n if (capacity <= 1) {\r\n return;\r\n }\r\n\r\n this._workBuffer = new GaussianSplattingWorkBuffer(this._scene, capacity);\r\n // GPU readback is only enabled after it is validated against a CPU decode on the first file (see\r\n // _probeReadbackAsync); until then positions are decoded on the CPU so there is always a correct result.\r\n this._readbackCandidate = this._workBuffer.supportsAsyncCentersReadback;\r\n const splatPositions = new Float32Array(capacity * 4);\r\n const textures = this._workBuffer.textures;\r\n this._setExternalWorkBuffer(textures[0], textures[1], textures[2], textures[3], splatPositions, capacity);\r\n // Nothing is active until at least one resource has been decoded.\r\n this.setSplatIndexRanges([]);\r\n this.setEnabled(true);\r\n\r\n // Phase 3: decode the environment, then every node's coarsest LOD as the permanent base layer.\r\n if (this._environmentRange && this._environmentFiles) {\r\n await this._decodeEnvironmentAsync();\r\n }\r\n this._environmentFiles = null;\r\n\r\n const baseFiles = new Set<number>();\r\n for (const node of this._leafNodes) {\r\n const entry = node.lods![String(node.baseLod)];\r\n if (entry && this._fileBaseSplat.has(entry.file)) {\r\n baseFiles.add(entry.file);\r\n }\r\n }\r\n for (const fileId of Array.from(baseFiles)) {\r\n if (this._disposed) {\r\n return;\r\n }\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._decodeFileAsync(fileId);\r\n }\r\n\r\n if (this._disposed) {\r\n return;\r\n }\r\n // Phase 4: hand off to the per-frame LOD streaming loop.\r\n this._baseLayerReady = true;\r\n if (!this._lodObserver) {\r\n this._lodObserver = this._scene.onBeforeRenderObservable.add(() => this._onLodFrame());\r\n }\r\n }\r\n\r\n /**\r\n * Collects the unique set of source file indices referenced by any LOD of any leaf, sorted ascending.\r\n * @returns sorted unique file indices\r\n */\r\n private _collectAllFileIds(): number[] {\r\n const ids = new Set<number>();\r\n for (const node of this._leafNodes) {\r\n for (const level of node.availableLevels!) {\r\n const entry = node.lods![String(level)];\r\n if (entry) {\r\n ids.add(entry.file);\r\n }\r\n }\r\n }\r\n return Array.from(ids).sort((a, b) => a - b);\r\n }\r\n\r\n /**\r\n * Fetches the environment bundle and every referenced file's metadata to learn splat counts, caching\r\n * each file's parsed metadata for the later on-demand decode. Metadata fetches run in parallel.\r\n * @param fileIds file indices to fetch metadata for\r\n * @returns the environment splat count (0 when there is no environment)\r\n */\r\n private async _gatherCountsAsync(fileIds: number[]): Promise<number> {\r\n let envCount = 0;\r\n if (this._metadata.environment) {\r\n try {\r\n const url = this._rootUrl + this._metadata.environment;\r\n const buffer = (await Tools.LoadFileAsync(url, true)) as ArrayBuffer;\r\n const files = await this._unzipAsync(new Uint8Array(buffer));\r\n const metaBytes = files.get(\"meta.json\");\r\n if (metaBytes) {\r\n const meta = JSON.parse(new TextDecoder().decode(metaBytes)) as SOGRootData;\r\n envCount = GaussianSplattingStream._GetSplatCount(meta);\r\n this._environmentFiles = files;\r\n }\r\n } catch (e: any) {\r\n // The environment is non-essential — keep streaming the LOD tree even if it fails.\r\n Logger.Warn(\"GaussianSplattingStream: failed to load environment: \" + (e?.message ?? e));\r\n }\r\n }\r\n\r\n await Promise.all(\r\n fileIds.map(async (fileId) => {\r\n const relativePath = this._metadata.filenames[fileId];\r\n if (!relativePath) {\r\n Logger.Warn(`GaussianSplattingStream: missing filename for file index ${fileId}.`);\r\n return;\r\n }\r\n try {\r\n const metaUrl = this._rootUrl + relativePath;\r\n const subRootUrl = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\r\n const metaText = (await Tools.LoadFileAsync(metaUrl, false)) as string;\r\n const sogData = JSON.parse(metaText) as SOGRootData;\r\n this._fileCounts.set(fileId, GaussianSplattingStream._GetSplatCount(sogData));\r\n this._fileMeta.set(fileId, { sogData, subRootUrl });\r\n } catch (e: any) {\r\n Logger.Warn(`GaussianSplattingStream: failed to load metadata for ${relativePath}: ${e?.message ?? e}`);\r\n }\r\n })\r\n );\r\n\r\n return envCount;\r\n }\r\n\r\n /**\r\n * Queues a file for on-demand decode if it isn't already decoded, in flight, or already queued.\r\n * @param fileId file index to decode\r\n */\r\n private _enqueueDecode(fileId: number): void {\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId) || !this._fileMeta.has(fileId)) {\r\n return;\r\n }\r\n if (this._decodeQueue.indexOf(fileId) === -1) {\r\n this._decodeQueue.push(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Starts up to {@link _maxDecodesPerFrame} queued decodes for this frame. Decodes run asynchronously\r\n * and promote any waiting nodes once they complete.\r\n */\r\n private _pumpDecodeQueue(): void {\r\n let started = 0;\r\n while (this._decodeQueue.length > 0 && started < this._maxDecodesPerFrame) {\r\n const fileId = this._decodeQueue.shift()!;\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId)) {\r\n continue;\r\n }\r\n started++;\r\n // eslint-disable-next-line github/no-then\r\n this._decodeFileAsync(fileId).catch((e) => {\r\n Logger.Warn(\"GaussianSplattingStream: decode failed: \" + (e?.message ?? e));\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Writes a decoded splat range's positions into the shared buffer, expands the bounds, and incrementally\r\n * patches the sort worker.\r\n * @param positions stride-4 positions for the range\r\n * @param base first splat index of the range in the work buffer\r\n * @param count number of splats in the range\r\n */\r\n private _applyPositions(positions: Float32Array, base: number, count: number): void {\r\n this._splatPositions!.set(positions, base * 4);\r\n this._updateBounds(positions, count);\r\n // Incrementally patch only this range in the sort worker (avoids the full position-buffer re-copy).\r\n this._postWorkerPositionsRange(base, count);\r\n }\r\n\r\n /**\r\n * One-time validation of GPU position readback: reads a sample of the just-decoded range back from the work\r\n * buffer and compares it to the CPU-decoded positions. Enables {@link _useGpuPositionReadback} only on an\r\n * exact (within float tolerance) match, so an unsupported or incorrect readback (e.g. a backend without the\r\n * required texture usage, or an orientation mismatch) safely keeps the CPU decode path.\r\n * @param base first splat index of the validated range\r\n * @param count number of splats in the range\r\n * @param cpuPositions the CPU-decoded stride-4 positions for the range (ground truth)\r\n */\r\n private async _probeReadbackAsync(base: number, count: number, cpuPositions: Float32Array): Promise<void> {\r\n this._readbackProbed = true;\r\n if (!this._workBuffer) {\r\n return;\r\n }\r\n const sampleCount = Math.min(count, 1024);\r\n let ok = false;\r\n try {\r\n const gpu = await this._workBuffer.readCentersRangeAsync(base, sampleCount);\r\n if (this._disposed) {\r\n return;\r\n }\r\n if (gpu && gpu.length >= sampleCount * 4) {\r\n ok = true;\r\n for (let i = 0; i < sampleCount && ok; i++) {\r\n for (let j = 0; j < 3; j++) {\r\n const a = gpu[i * 4 + j];\r\n const b = cpuPositions[i * 4 + j];\r\n if (Math.abs(a - b) > 1e-2 * (1 + Math.abs(b))) {\r\n ok = false;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n } catch {\r\n ok = false;\r\n }\r\n this._useGpuPositionReadback = ok;\r\n Logger.Log(\r\n ok\r\n ? \"GaussianSplattingStream: GPU position readback validated; streamed LOD positions are read back from the GPU.\"\r\n : \"GaussianSplattingStream: GPU position readback unavailable; decoding LOD positions on the CPU.\"\r\n );\r\n }\r\n\r\n /**\r\n * Resolves the decoded positions for a splat range and applies them. Once GPU readback has been validated,\r\n * positions are read back from the work buffer (non-blocking) and `pack.positions` is empty; otherwise the\r\n * CPU-decoded `pack.positions` are used, and — on the first such decode — the GPU readback is validated\r\n * against them so subsequent decodes can use the fast path.\r\n * @param pack the parsed SOG pack (its `positions` is populated only on the CPU path)\r\n * @param base first splat index of the range in the work buffer\r\n * @param count number of splats in the range\r\n * @returns whether positions were applied\r\n */\r\n private async _applyDecodedPositionsAsync(pack: ISogTexturePack, base: number, count: number): Promise<boolean> {\r\n if (this._useGpuPositionReadback && this._workBuffer) {\r\n const positions = await this._workBuffer.readCentersRangeAsync(base, count);\r\n if (this._disposed) {\r\n return false;\r\n }\r\n if (positions && this._splatPositions) {\r\n this._applyPositions(positions, base, count);\r\n return true;\r\n }\r\n // Validated readback unexpectedly returned nothing; fall through to the (likely empty) CPU positions.\r\n }\r\n\r\n const cpu = pack.positions.length >= count * 4 ? (pack.positions.subarray(0, count * 4) as Float32Array) : null;\r\n if (!cpu || !this._splatPositions) {\r\n return false;\r\n }\r\n this._applyPositions(cpu, base, count);\r\n // First CPU decode while readback is a candidate: validate it so later decodes can use the fast path.\r\n if (!this._readbackProbed && this._readbackCandidate) {\r\n await this._probeReadbackAsync(base, count, cpu);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Decodes the always-on environment bundle into its work-buffer block and activates its range.\r\n */\r\n private async _decodeEnvironmentAsync(): Promise<void> {\r\n if (!this._environmentRange || !this._environmentFiles || !this._workBuffer) {\r\n return;\r\n }\r\n const range = this._environmentRange;\r\n try {\r\n const parsed = await ParseSogMetaAsTextures(this._environmentFiles, \"\", this._scene, !this._useGpuPositionReadback);\r\n const pack = parsed.sogTextures;\r\n if (!pack) {\r\n return;\r\n }\r\n try {\r\n if (this._disposed || !this._workBuffer) {\r\n return;\r\n }\r\n await this._workBuffer.decodeAsync(pack, range.offset);\r\n if (this._disposed) {\r\n return;\r\n }\r\n await this._applyDecodedPositionsAsync(pack, range.offset, range.count);\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._refreshActiveRanges();\r\n } finally {\r\n // Always release the GPU source textures (the decode pass is the only consumer).\r\n GaussianSplattingStream._DisposePack(pack);\r\n }\r\n } catch (e: any) {\r\n Logger.Warn(\"GaussianSplattingStream: failed to decode environment: \" + (e?.message ?? e));\r\n }\r\n }\r\n\r\n /**\r\n * Loads one LOD source file as GPU textures, decodes it into its fixed work-buffer block, records its\r\n * CPU centers for sorting, frees the source textures, then promotes any nodes that were waiting for it.\r\n * Concurrent or repeat requests for the same file are ignored.\r\n * @param fileId file index to decode\r\n */\r\n private async _decodeFileAsync(fileId: number): Promise<void> {\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId)) {\r\n return;\r\n }\r\n const meta = this._fileMeta.get(fileId);\r\n const base = this._fileBaseSplat.get(fileId);\r\n const count = this._fileCounts.get(fileId);\r\n if (!meta || base === undefined || count === undefined) {\r\n return;\r\n }\r\n this._loadingFiles.add(fileId);\r\n try {\r\n const parsed = await ParseSogMetaAsTextures(meta.sogData, meta.subRootUrl, this._scene, !this._useGpuPositionReadback);\r\n const pack = parsed.sogTextures;\r\n if (!pack) {\r\n return;\r\n }\r\n try {\r\n if (this._disposed || !this._workBuffer) {\r\n return;\r\n }\r\n await this._workBuffer.decodeAsync(pack, base);\r\n if (this._disposed) {\r\n return;\r\n }\r\n await this._applyDecodedPositionsAsync(pack, base, count);\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._decodedFiles.add(fileId);\r\n // Promote any nodes that can now reach their desired LOD via this newly decoded file.\r\n if (this._applyDesiredLods()) {\r\n this._refreshActiveRanges();\r\n }\r\n } finally {\r\n // Always release the GPU source textures (the decode pass is the only consumer).\r\n GaussianSplattingStream._DisposePack(pack);\r\n }\r\n } finally {\r\n this._loadingFiles.delete(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Snaps a desired LOD level to the nearest level the node provides, while never selecting a level finer\r\n * than {@link maxDetailLod} (i.e. with an index below the cap). Ties prefer the finer allowed level. If\r\n * the node has no level at or coarser than the cap, its coarsest available level is used.\r\n * @param node leaf node\r\n * @param desired desired LOD level\r\n * @returns the chosen available level\r\n */\r\n private _cappedLevelForNode(node: ISOGLODNode, desired: number): number {\r\n const levels = node.availableLevels!;\r\n const floor = this._maxDetailLod;\r\n let best = -1;\r\n let bestDiff = Number.POSITIVE_INFINITY;\r\n for (const level of levels) {\r\n if (level < floor) {\r\n continue;\r\n }\r\n const diff = Math.abs(level - desired);\r\n if (diff < bestDiff) {\r\n best = level;\r\n bestDiff = diff;\r\n }\r\n }\r\n // No level is coarse enough to satisfy the cap: fall back to the coarsest the node has.\r\n return best < 0 ? node.baseLod! : best;\r\n }\r\n\r\n /**\r\n * Computes each node's {@link ISOGLODNode.targetLevel}: the distance-based optimal level snapped to an\r\n * available level, capped so no node renders finer (more detailed) than {@link maxDetailLod}.\r\n */\r\n private _computeTargetLevels(): void {\r\n for (const node of this._leafNodes) {\r\n const desired = node.optimalLod ?? node.baseLod!;\r\n node.targetLevel = this._cappedLevelForNode(node, desired);\r\n }\r\n }\r\n\r\n /**\r\n * Applies each node's {@link ISOGLODNode.targetLevel}: switches a node to its target level when that\r\n * level's file is already decoded, otherwise queues the file and leaves the node on its current LOD (so\r\n * nothing ever disappears). Nodes within their post-switch cooldown are left untouched to damp oscillation.\r\n * @returns true when at least one node changed LOD (callers should refresh the active ranges)\r\n */\r\n private _applyDesiredLods(): boolean {\r\n let dirty = false;\r\n for (const node of this._leafNodes) {\r\n if (node.lodCooldown && node.lodCooldown > 0) {\r\n continue;\r\n }\r\n const desired = node.targetLevel ?? node.baseLod!;\r\n if (desired === node.activeLod) {\r\n continue;\r\n }\r\n const entry = node.lods![String(desired)];\r\n if (!entry) {\r\n continue;\r\n }\r\n if (this._decodedFiles.has(entry.file)) {\r\n node.activeLod = desired;\r\n node.lodCooldown = this._lodCooldownFrames;\r\n dirty = true;\r\n } else {\r\n this._enqueueDecode(entry.file);\r\n }\r\n }\r\n return dirty;\r\n }\r\n\r\n /**\r\n * Per-frame LOD streaming loop. Ticks cooldowns and pumps the decode queue every frame, and runs the\r\n * cheap per-node frustum test every frame so the off-screen LOD bias tracks camera rotation. The LOD\r\n * re-evaluation is throttled to at most every {@link _lodUpdateInterval} frames once the camera has\r\n * translated far enough, but also runs immediately whenever a node enters/leaves the frustum (so its\r\n * detail upgrades/downgrades promptly) or a cap change forces it. Active ranges rebuild on any LOD change.\r\n */\r\n private _onLodFrame(): void {\r\n if (this._disposed || !this._baseLayerReady) {\r\n return;\r\n }\r\n for (const node of this._leafNodes) {\r\n if (node.lodCooldown && node.lodCooldown > 0) {\r\n node.lodCooldown--;\r\n }\r\n }\r\n // In-flight/queued decodes still progress every frame.\r\n this._pumpDecodeQueue();\r\n\r\n // Per-node frustum test runs every frame (cheap) so the off-screen LOD bias tracks camera rotation,\r\n // not just the translation that gates the throttled LOD re-evaluation below.\r\n const frustumChanged = this._updateNodeFrustum();\r\n\r\n let runLodEval = this._forceLodUpdate || frustumChanged;\r\n if (!runLodEval && ++this._framesSinceLodUpdate >= this._lodUpdateInterval) {\r\n const camera = this._scene.activeCamera;\r\n const threshold = this._lodUpdateDistance;\r\n if (!camera || Vector3.DistanceSquared(camera.globalPosition, this._lastLodCamPos) >= threshold * threshold) {\r\n if (camera) {\r\n this._lastLodCamPos.copyFrom(camera.globalPosition);\r\n }\r\n runLodEval = true;\r\n }\r\n }\r\n\r\n if (runLodEval) {\r\n this._forceLodUpdate = false;\r\n this._framesSinceLodUpdate = 0;\r\n this.evaluateOptimalLods(this._scene.activeCamera);\r\n this._computeTargetLevels();\r\n if (this._applyDesiredLods()) {\r\n this._refreshActiveRanges();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates each leaf node's {@link ISOGLODNode.inFrustum} flag from a per-node frustum test against the\r\n * active camera. When {@link frustumCulling} is disabled (or there is no camera) every node is marked\r\n * in-frustum. Bounds are static (from the LOD tree), so flags are valid for all nodes regardless of\r\n * decode state. Returns true when any node's in-frustum state changed (so the LOD bias must be re-applied).\r\n * @returns whether any node's in-frustum state changed\r\n */\r\n private _updateNodeFrustum(): boolean {\r\n const camera = this._scene.activeCamera;\r\n let changed = false;\r\n\r\n if (!this._frustumCulling || !camera) {\r\n for (const node of this._leafNodes) {\r\n if (node.inFrustum === false) {\r\n node.inFrustum = true;\r\n changed = true;\r\n }\r\n }\r\n return changed;\r\n }\r\n\r\n // World-space frustum planes from the current view-projection, tested against each node's world AABB.\r\n // force=false uses the renderId/sync fast-path (still recomputes when the transform actually changed),\r\n // avoiding a full world-matrix recompute every frame for the per-node frustum test.\r\n const world = this.computeWorldMatrix(false);\r\n camera.getViewMatrix().multiplyToRef(camera.getProjectionMatrix(), this._cullViewProj);\r\n Frustum.GetPlanesToRef(this._cullViewProj, this._frustumPlanes);\r\n\r\n for (const node of this._leafNodes) {\r\n node.cullBounds!.update(world);\r\n const inFrustum = node.cullBounds!.isInFrustum(this._frustumPlanes);\r\n if (inFrustum !== node.inFrustum) {\r\n node.inFrustum = inFrustum;\r\n changed = true;\r\n }\r\n }\r\n return changed;\r\n }\r\n\r\n /**\r\n * Reads the splat count from SOG metadata.\r\n * @param data SOG metadata\r\n * @returns the splat count\r\n */\r\n private static _GetSplatCount(data: SOGRootData): number {\r\n return data.count ?? (Array.isArray(data.means.shape) ? data.means.shape[0] : 0);\r\n }\r\n\r\n /**\r\n * Disposes all GPU source textures of a SOG pack (they are only needed for the one decode pass).\r\n * @param pack the SOG texture pack\r\n */\r\n private static _DisposePack(pack: ISogTexturePack): void {\r\n pack.meansTextureL.dispose();\r\n pack.meansTextureU.dispose();\r\n pack.scalesTexture.dispose();\r\n pack.quatsTexture.dispose();\r\n pack.sh0Texture.dispose();\r\n pack.shCentroidsTexture?.dispose();\r\n pack.shLabelsTexture?.dispose();\r\n pack.codebookTexture?.dispose();\r\n }\r\n\r\n /**\r\n * Expands the running splat-center bounds with a newly decoded file's centers and updates the\r\n * mesh bounding info so the GS is correctly frustum-culled and pickable.\r\n * @param positions stride-4 splat centers for the new file\r\n * @param count number of splats\r\n */\r\n private _updateBounds(positions: Float32Array, count: number): void {\r\n const min = this._boundsMin;\r\n const max = this._boundsMax;\r\n for (let i = 0; i < count; i++) {\r\n const x = positions[i * 4 + 0];\r\n const y = positions[i * 4 + 1];\r\n const z = positions[i * 4 + 2];\r\n min.minimizeInPlaceFromFloats(x, y, z);\r\n max.maximizeInPlaceFromFloats(x, y, z);\r\n }\r\n this.setBoundingInfo(new BoundingInfo(min, max));\r\n }\r\n\r\n /**\r\n * Rebuilds the active interval set from the environment plus each node's currently-selected LOD entry,\r\n * coalesces adjacent ranges, and pushes the result to the sort worker.\r\n */\r\n private _refreshActiveRanges(): void {\r\n const ranges: IGaussianSplattingSplatRange[] = [];\r\n\r\n if (this._environmentRange) {\r\n ranges.push({ offset: this._environmentRange.offset, count: this._environmentRange.count });\r\n }\r\n\r\n for (const node of this._leafNodes) {\r\n if (node.activeLod === undefined) {\r\n continue;\r\n }\r\n const entry = node.lods![String(node.activeLod)];\r\n if (!entry) {\r\n continue;\r\n }\r\n const base = this._fileBaseSplat.get(entry.file);\r\n if (base === undefined) {\r\n continue;\r\n }\r\n ranges.push({ offset: base + entry.offset, count: entry.count });\r\n }\r\n\r\n this.setSplatIndexRanges(GaussianSplattingStream._CoalesceRanges(ranges));\r\n }\r\n\r\n /**\r\n * Sorts and merges adjacent/overlapping ranges to keep the interval list compact.\r\n * @param ranges raw ranges\r\n * @returns coalesced ranges\r\n */\r\n private static _CoalesceRanges(ranges: IGaussianSplattingSplatRange[]): IGaussianSplattingSplatRange[] {\r\n if (ranges.length <= 1) {\r\n return ranges;\r\n }\r\n const sorted = ranges.slice().sort((a, b) => a.offset - b.offset);\r\n const merged: IGaussianSplattingSplatRange[] = [{ offset: sorted[0].offset, count: sorted[0].count }];\r\n for (let i = 1; i < sorted.length; i++) {\r\n const last = merged[merged.length - 1];\r\n const range = sorted[i];\r\n const lastEnd = last.offset + last.count;\r\n if (range.offset <= lastEnd) {\r\n const end = Math.max(lastEnd, range.offset + range.count);\r\n last.count = end - last.offset;\r\n } else {\r\n merged.push({ offset: range.offset, count: range.count });\r\n }\r\n }\r\n return merged;\r\n }\r\n\r\n /**\r\n * Unzips a `.sog` bundle into a name -> bytes map, loading fflate on demand.\r\n * @param data zipped bytes\r\n * @returns map of entry name to bytes\r\n */\r\n private async _unzipAsync(data: Uint8Array): Promise<Map<string, Uint8Array>> {\r\n let fflateModule = this._streamOptions.fflate;\r\n if (!fflateModule) {\r\n if (typeof (window as any).fflate === \"undefined\") {\r\n await Tools.LoadScriptAsync(this._streamOptions.deflateURL ?? \"https://unpkg.com/fflate/umd/index.js\");\r\n }\r\n fflateModule = (window as any).fflate;\r\n }\r\n\r\n const unzipped = fflateModule.unzipSync(data) as Record<string, Uint8Array>;\r\n const files = new Map<string, Uint8Array>();\r\n for (const [name, content] of Object.entries(unzipped)) {\r\n files.set(name, content);\r\n }\r\n return files;\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"gaussianSplattingStream.js","sourceRoot":"","sources":["../../../../dev/loaders/src/SPLAT/gaussianSplattingStream.ts"],"names":[],"mappings":"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","sourcesContent":["import { GaussianSplattingMesh } from \"core/Meshes/GaussianSplatting/gaussianSplattingMesh\";\r\nimport { type IGaussianSplattingSplatRange } from \"core/Meshes/GaussianSplatting/gaussianSplattingMeshBase\";\r\nimport { type Scene } from \"core/scene\";\r\nimport { type Nullable } from \"core/types\";\r\nimport { Logger } from \"core/Misc/logger\";\r\nimport { Tools } from \"core/Misc/tools\";\r\nimport { Vector3, Matrix } from \"core/Maths/math.vector\";\r\nimport { Color4 } from \"core/Maths/math.color\";\r\nimport { Frustum } from \"core/Maths/math.frustum\";\r\nimport { Plane } from \"core/Maths/math.plane\";\r\nimport { Camera } from \"core/Cameras/camera\";\r\nimport { type Observer } from \"core/Misc/observable\";\r\nimport { BoundingInfo } from \"core/Culling/boundingInfo\";\r\nimport { CreateLineSystem } from \"core/Meshes/Builders/linesBuilder\";\r\nimport { type LinesMesh } from \"core/Meshes/linesMesh\";\r\nimport { VertexBuffer } from \"core/Buffers/buffer\";\r\nimport { ParseSogMetaAsTextures, type SOGRootData } from \"./sog.pure\";\r\nimport { GaussianSplattingWorkBuffer } from \"./gaussianSplattingWorkBuffer\";\r\nimport { GaussianSplattingDownloadManager } from \"./gaussianSplattingDownloadManager\";\r\nimport { GaussianSplattingResidencyController } from \"./gaussianSplattingResidencyController\";\r\nimport { type ISogTexturePack } from \"./splatDefs\";\r\n\r\n/**\r\n * A single LOD variant of a tree node: a contiguous splat range inside one streamed SOG file.\r\n */\r\ninterface ISOGLODEntry {\r\n /** Index into {@link ISOGLODMetadata.filenames}. */\r\n file: number;\r\n /** First splat index inside that file. */\r\n offset: number;\r\n /** Number of splats. */\r\n count: number;\r\n}\r\n\r\n/**\r\n * A node of the PlayCanvas-style SOG LOD octree. Internal nodes have `children`; leaves have `lods`.\r\n */\r\ninterface ISOGLODNode {\r\n bound: { min: number[]; max: number[] };\r\n children?: ISOGLODNode[];\r\n lods?: { [level: string]: ISOGLODEntry };\r\n /** LOD level currently streamed/rendered for this node, or undefined until its base LOD is ready. */\r\n activeLod?: number;\r\n /** Distance-based ideal LOD level for this node, recomputed per frame. */\r\n optimalLod?: number;\r\n /** Available LOD levels for this leaf, sorted ascending (0 = finest). Set during the tree walk. */\r\n availableLevels?: number[];\r\n /** Coarsest available level (= max key), always streamed as the permanent base layer. */\r\n baseLod?: number;\r\n /** Final LOD level the node should stream/render (distance optimal, capped by maxDetailLod). */\r\n targetLevel?: number;\r\n /** Frames remaining before this node may switch LOD again (oscillation damping). */\r\n lodCooldown?: number;\r\n /** True when the node's bounding box currently intersects the camera frustum. Drives the LOD bias that\r\n * pushes off-screen nodes to the coarsest level (they stay rendered, not hidden). */\r\n inFrustum?: boolean;\r\n /** Cached local-space bounding info used for the per-node frustum test (created once per leaf). */\r\n cullBounds?: BoundingInfo;\r\n /** File index this node currently has an in-flight/queued decode request for (its not-yet-decoded target),\r\n * or undefined when the node's target is already decoded. Drives pending-download reference counting. */\r\n pendingFile?: number;\r\n /** File index this node's current {@link activeLod} renders from, or undefined before any LOD is active.\r\n * Drives the resident reference count that keeps a file in the work buffer. */\r\n activeFile?: number;\r\n}\r\n\r\n/**\r\n * Parsed contents of a PlayCanvas-style `lod-meta.json` file.\r\n */\r\nexport interface ISOGLODMetadata {\r\n /** Number of LOD levels (0 = highest detail). */\r\n lodLevels: number;\r\n /** SOG `meta.json` paths, relative to the metadata file, indexed by `ISOGLODEntry.file`. */\r\n filenames: string[];\r\n /** Optional always-on environment `.sog` bundle, relative to the metadata file. */\r\n environment?: string;\r\n /** Root of the LOD octree. */\r\n tree: ISOGLODNode;\r\n}\r\n\r\n/**\r\n * Selects which LOD value drives the {@link GaussianSplattingStream} debug wireframe colors.\r\n */\r\nexport type GaussianSplattingStreamDebugLodSource = \"optimal\" | \"current\";\r\n\r\n/**\r\n * Options for {@link GaussianSplattingStream}.\r\n */\r\nexport interface IGaussianSplattingStreamOptions {\r\n /** URL of the fflate UMD module used to unzip `.sog` environment bundles. */\r\n deflateURL?: string;\r\n /** Pre-loaded fflate module. */\r\n fflate?: any;\r\n /** When true, renders a wireframe box per LOD node, colored by the node's LOD level. */\r\n debugDisplay?: boolean;\r\n /** Which LOD value drives the debug wireframe colors. Defaults to `\"optimal\"`. */\r\n debugLodSource?: GaussianSplattingStreamDebugLodSource;\r\n /** Distance (in local units) of the first LOD transition. PlayCanvas default `5`. */\r\n lodBaseDistance?: number;\r\n /** Geometric ratio between successive LOD transition distances. PlayCanvas default `3`. */\r\n lodMultiplier?: number;\r\n /** Distance multiplier applied to nodes behind the camera (`1` = no penalty). PlayCanvas default `1`. */\r\n lodBehindPenalty?: number;\r\n /** Lowest LOD index the optimal-LOD heuristic may select. Defaults to `0`. */\r\n lodRangeMin?: number;\r\n /** Highest LOD index the optimal-LOD heuristic may select. Defaults to `lodLevels - 1`. */\r\n lodRangeMax?: number;\r\n /** Maximum number of LOD source files to GPU-decode per frame (spreads work to avoid hitches). Defaults to `1`. */\r\n maxDecodesPerFrame?: number;\r\n /** Frames a node must wait after switching LOD before it may switch again (oscillation damping). Defaults to `10`. */\r\n lodCooldownFrames?: number;\r\n /** Minimum number of frames between LOD re-evaluations (throttles per-frame work during motion). Defaults to `4`. */\r\n lodUpdateInterval?: number;\r\n /** Minimum camera movement (world units) required to re-evaluate LODs. Defaults to `0.5`. */\r\n lodUpdateDistance?: number;\r\n /**\r\n * Finest (most detailed) LOD level any node is allowed to render. `0` allows full detail (level 0);\r\n * `1` caps detail at the next-coarser level, and so on. Higher values force a coarser maximum detail.\r\n */\r\n maxDetailLod?: number;\r\n /**\r\n * When true (default), LOD nodes outside the camera frustum are biased to their coarsest LOD rather than\r\n * rendered at full detail. They stay in the sort/render set so they appear instantly (at low detail) when\r\n * the camera turns toward them, then refine. Set to `false` to render every node at its distance LOD.\r\n */\r\n frustumCulling?: boolean;\r\n /** Maximum number of LOD file downloads allowed to run concurrently. PlayCanvas default `2`. */\r\n maxConcurrentDownloads?: number;\r\n /** Number of times a failed file download is retried before giving up. PlayCanvas default `2`. */\r\n maxDownloadRetries?: number;\r\n /**\r\n * GPU memory budget (in megabytes) for resident splats. When set (and smaller than the full dataset),\r\n * LOD files are streamed through a fixed-size work buffer and unreferenced files are evicted to stay\r\n * within budget, allowing datasets larger than a single full-dataset buffer. Converted to a splat count\r\n * at ~84 bytes/splat. Combined with {@link maxResidentSplats} by taking the smaller of the two.\r\n */\r\n memoryBudgetMb?: number;\r\n /**\r\n * Maximum number of splats kept resident in the work buffer. When set (and smaller than the full\r\n * dataset), enables eviction-based streaming (see {@link memoryBudgetMb}). Default unset = size the work\r\n * buffer for the whole dataset (no eviction).\r\n */\r\n maxResidentSplats?: number;\r\n /**\r\n * Frames an unreferenced (no longer rendered) LOD file stays resident before it is evicted, so a quick\r\n * return to it avoids a re-download. Only used when a budget enables eviction. PlayCanvas default `100`.\r\n */\r\n evictionCooldownFrames?: number;\r\n}\r\n\r\n// tan(22.5deg): reference half-FOV for a 45-degree vertical FOV, used for FOV compensation (matches PlayCanvas).\r\nconst RefTanHalfFov = Math.tan((22.5 * Math.PI) / 180);\r\n\r\n// Sentinel \"file\" ids for the residency controller's pinned (never-evicted) allocations.\r\nconst PaddingFileId = -2;\r\nconst EnvironmentFileId = -1;\r\n// Approximate bytes per resident splat used to convert a memory budget (MB) to a splat budget: the four\r\n// work-buffer textures cost 16+16+16+4 = 52 bytes on the GPU, plus ~32 bytes of CPU position/sort data.\r\nconst BytesPerResidentSplat = 84;\r\n\r\n// Scratch objects reused by the per-frame optimal-LOD evaluation (avoids per-call allocations).\r\nconst TmpInvWorld = new Matrix();\r\nconst TmpLocalCamera = new Vector3();\r\nconst TmpLocalForward = new Vector3();\r\nconst TmpWorldForward = new Vector3();\r\n// Camera-local forward axis (+Z) used to derive the world-space view direction.\r\nconst LocalForwardAxis = new Vector3(0, 0, 1);\r\n\r\n// The 12 edges of a box, as index pairs into its 8 corners. 12 edges x 2 endpoints = 24 vertices per box.\r\nconst BoxEdges = [\r\n [0, 1],\r\n [1, 2],\r\n [2, 3],\r\n [3, 0],\r\n [4, 5],\r\n [5, 6],\r\n [6, 7],\r\n [7, 4],\r\n [0, 4],\r\n [1, 5],\r\n [2, 6],\r\n [3, 7],\r\n];\r\n// Vertices generated per leaf box (BoxEdges.length * 2).\r\nconst VerticesPerBox = BoxEdges.length * 2;\r\n\r\n/**\r\n * Wireframe colors per LOD level (cycled by `node.activeLod`).\r\n */\r\nconst GsLodDebugColors = [\r\n new Color4(1.0, 0.2, 0.2, 1.0), // LOD 0 - red\r\n new Color4(1.0, 0.6, 0.1, 1.0), // LOD 1 - orange\r\n new Color4(1.0, 1.0, 0.2, 1.0), // LOD 2 - yellow\r\n new Color4(0.3, 1.0, 0.3, 1.0), // LOD 3 - green\r\n new Color4(0.2, 1.0, 1.0, 1.0), // LOD 4 - cyan\r\n new Color4(0.4, 0.5, 1.0, 1.0), // LOD 5 - blue\r\n new Color4(0.9, 0.4, 1.0, 1.0), // LOD 6 - magenta\r\n new Color4(1.0, 1.0, 1.0, 1.0), // LOD 7 - white\r\n];\r\n\r\n/**\r\n * Streams a PlayCanvas-style SOG LOD scene (`lod-meta.json`) into a single Gaussian Splatting mesh.\r\n *\r\n * Each selected SOG file (plus the environment) is loaded directly as GPU textures and decoded on the\r\n * GPU into one unified, PlayCanvas-style square work buffer (no CPU splat decode or `updateData`). Only\r\n * the splats of each node's currently-selected LOD are rendered/sorted via the mesh's interval filter.\r\n *\r\n * The coarsest (least-detail) LOD of every node is streamed first as a permanent base layer so the whole\r\n * scene is visible quickly with no holes. A distance-based \"optimal\" LOD is then computed per node (see\r\n * {@link evaluateOptimalLods}); finer LOD source files are streamed on demand and a node only switches to\r\n * a finer LOD once that file is decoded, so transitions never flash or leave gaps.\r\n *\r\n * @experimental\r\n */\r\nexport class GaussianSplattingStream extends GaussianSplattingMesh {\r\n private readonly _metadata: ISOGLODMetadata;\r\n private readonly _rootUrl: string;\r\n private readonly _streamOptions: IGaussianSplattingStreamOptions;\r\n\r\n // Flat list of leaf nodes that carry renderable LOD entries (used by the LOD heuristic and debug).\r\n private readonly _leafNodes: ISOGLODNode[] = [];\r\n\r\n // LOD heuristic parameters (PlayCanvas-aligned defaults).\r\n private _lodBaseDistance = 5;\r\n private _lodMultiplier = 3;\r\n private _lodBehindPenalty = 1;\r\n private _lodRangeMin = 0;\r\n private _lodRangeMax: number;\r\n private _maxDecodesPerFrame = 1;\r\n private _lodCooldownFrames = 10;\r\n // Minimum frames between LOD re-evaluations, and minimum camera movement (world units) to re-evaluate.\r\n private _lodUpdateInterval = 4;\r\n private _lodUpdateDistance = 0.5;\r\n private _maxDetailLod = 0;\r\n\r\n // Frustum LOD bias: when enabled, nodes outside the camera frustum are rendered at their coarsest LOD.\r\n private _frustumCulling = true;\r\n // Reused world-space frustum planes and view-projection scratch matrix (avoids per-frame allocation).\r\n private readonly _frustumPlanes: Plane[] = [\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n new Plane(0, 0, 0, 0),\r\n ];\r\n private readonly _cullViewProj = new Matrix();\r\n\r\n // GPU work buffer holding all decoded splats; created once the total capacity is known.\r\n private _workBuffer: Nullable<GaussianSplattingWorkBuffer> = null;\r\n // True once GPU position readback has been validated against a CPU decode (see _probeReadbackAsync). While\r\n // false, positions are decoded on the CPU from the means images; once validated, every SOG image uses the\r\n // fast direct upload and positions are read back from the work buffer (non-blocking).\r\n private _useGpuPositionReadback = false;\r\n // Whether the engine reports GPU readback support (candidate to validate on the first decode).\r\n private _readbackCandidate = false;\r\n // Set once the one-time readback validation has run (success or failure).\r\n private _readbackProbed = false;\r\n\r\n // Residency controller: owns the work-buffer slot allocator, per-file blocks, and eviction cooldowns.\r\n private _residency: Nullable<GaussianSplattingResidencyController> = null;\r\n // Splat count of each source file (learned from its metadata before allocation).\r\n private readonly _fileCounts = new Map<number, number>();\r\n // Cached SOG metadata per file so on-demand decodes don't refetch the meta.json.\r\n private readonly _fileMeta = new Map<number, { sogData: SOGRootData; subRootUrl: string }>();\r\n // Files whose splats have been fully GPU-decoded into the work buffer (render-safe).\r\n private readonly _decodedFiles = new Set<number>();\r\n // Files whose decode is currently in flight (dedupes concurrent requests).\r\n private readonly _loadingFiles = new Set<number>();\r\n // FIFO of file ids waiting to be decoded (drained under a per-frame budget).\r\n private readonly _decodeQueue: number[] = [];\r\n // Per-file reference count: number of leaf nodes whose active LOD renders, or whose pending target points\r\n // at, each file. At zero, a decoded file is scheduled for eviction and a still-downloading file is cancelled.\r\n private readonly _fileRefs = new Map<number, number>();\r\n // Files whose in-flight decode was cancelled; checked at decode checkpoints to bail out cooperatively.\r\n private readonly _cancelledDecodes = new Set<number>();\r\n // Eviction streaming config: enabled only when a budget smaller than the full dataset is configured.\r\n private _evictionEnabled = false;\r\n private _residentBudget = 0;\r\n private _evictionCooldownFrames = 100;\r\n // Serializes the allocate -> decode -> readback critical section so a defrag relayout (which runs inside it)\r\n // never overlaps another file's decode writing the work buffer, which would corrupt the moved data.\r\n private _decodeGate: Promise<void> = Promise.resolve();\r\n // Reusable scratch for the (rare) defrag relayout, to avoid per-relayout allocations during streaming.\r\n private readonly _relayoutOldOffsets = new Map<number, number>();\r\n private _relayoutSrcIndex: Nullable<Float32Array> = null;\r\n\r\n // Throttles and retries the SOG file/image downloads (PlayCanvas-style download manager).\r\n private readonly _downloadManager: GaussianSplattingDownloadManager;\r\n\r\n // Global range covered by the environment file (always rendered), or null until it loads.\r\n private _environmentRange: Nullable<{ offset: number; count: number }> = null;\r\n // Unzipped environment bundle contents, retained between count-gathering and decode.\r\n private _environmentFiles: Nullable<Map<string, Uint8Array>> = null;\r\n\r\n // Per-frame LOD streaming loop; installed once the base layer is ready.\r\n private _lodObserver: Nullable<Observer<Scene>> = null;\r\n private _baseLayerReady = false;\r\n // Throttling state for the per-frame LOD loop.\r\n private _framesSinceLodUpdate = 0;\r\n private readonly _lastLodCamPos = new Vector3(Infinity, Infinity, Infinity);\r\n // Forces the next LOD update to run regardless of the throttle (e.g. after a budget change).\r\n private _forceLodUpdate = false;\r\n\r\n // Running local-space bounds of all decoded splat centers (for frustum culling / picking).\r\n private readonly _boundsMin = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);\r\n private readonly _boundsMax = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);\r\n\r\n // Debug LOD-node wireframe display.\r\n private _debugDisplay = false;\r\n private _debugLodSource: GaussianSplattingStreamDebugLodSource = \"optimal\";\r\n private _debugMesh: Nullable<LinesMesh> = null;\r\n private _debugObserver: Nullable<Observer<Scene>> = null;\r\n // Per-vertex RGBA color buffer mirror, updated in place when LOD colors change (avoids mesh rebuild flicker).\r\n private _debugColorData: Nullable<Float32Array> = null;\r\n // Signature of the per-leaf displayed LOD levels, used to skip rebuilding unchanged debug geometry.\r\n private _debugSignature = 0;\r\n\r\n private _disposed = false;\r\n\r\n /**\r\n * Returns true when the parsed JSON looks like a PlayCanvas-style `lod-meta.json` payload.\r\n * @param data parsed JSON\r\n * @returns whether the data is SOG LOD metadata\r\n */\r\n public static IsLODMetadata(data: unknown): data is ISOGLODMetadata {\r\n if (typeof data !== \"object\" || data === null) {\r\n return false;\r\n }\r\n const meta = data as Partial<ISOGLODMetadata>;\r\n return typeof meta.lodLevels === \"number\" && Array.isArray(meta.filenames) && typeof meta.tree === \"object\" && meta.tree !== null;\r\n }\r\n\r\n /**\r\n * Creates a new SOG LOD streaming mesh and immediately starts streaming (non-blocking).\r\n * @param name mesh name\r\n * @param metadata parsed `lod-meta.json`\r\n * @param rootUrl base URL the metadata's relative paths resolve against\r\n * @param scene hosting scene\r\n * @param options streaming options\r\n */\r\n constructor(name: string, metadata: ISOGLODMetadata, rootUrl: string, scene: Scene, options: IGaussianSplattingStreamOptions = {}) {\r\n super(name, null, scene, false);\r\n this._metadata = metadata;\r\n this._rootUrl = rootUrl;\r\n this._streamOptions = options;\r\n\r\n // LOD heuristic parameters: take the provided values, otherwise keep the PlayCanvas-aligned defaults.\r\n const maxLod = Math.max(0, metadata.lodLevels - 1);\r\n this._lodRangeMax = maxLod;\r\n if (options.lodBaseDistance !== undefined) {\r\n this._lodBaseDistance = Math.max(0.1, options.lodBaseDistance);\r\n }\r\n if (options.lodMultiplier !== undefined) {\r\n this._lodMultiplier = Math.max(1.2, options.lodMultiplier);\r\n }\r\n if (options.lodBehindPenalty !== undefined) {\r\n this._lodBehindPenalty = Math.max(1, options.lodBehindPenalty);\r\n }\r\n if (options.lodRangeMin !== undefined) {\r\n this._lodRangeMin = Math.max(0, Math.min(options.lodRangeMin, maxLod));\r\n }\r\n if (options.lodRangeMax !== undefined) {\r\n this._lodRangeMax = Math.max(this._lodRangeMin, Math.min(options.lodRangeMax, maxLod));\r\n }\r\n if (options.maxDecodesPerFrame !== undefined) {\r\n this._maxDecodesPerFrame = Math.max(1, options.maxDecodesPerFrame);\r\n }\r\n if (options.lodCooldownFrames !== undefined) {\r\n this._lodCooldownFrames = Math.max(0, options.lodCooldownFrames);\r\n }\r\n if (options.lodUpdateInterval !== undefined) {\r\n this._lodUpdateInterval = Math.max(1, options.lodUpdateInterval);\r\n }\r\n if (options.lodUpdateDistance !== undefined) {\r\n this._lodUpdateDistance = Math.max(0, options.lodUpdateDistance);\r\n }\r\n if (options.maxDetailLod !== undefined) {\r\n this._maxDetailLod = Math.max(0, Math.floor(options.maxDetailLod));\r\n }\r\n if (options.frustumCulling !== undefined) {\r\n this._frustumCulling = options.frustumCulling;\r\n }\r\n if (options.debugLodSource) {\r\n this._debugLodSource = options.debugLodSource;\r\n }\r\n if (options.evictionCooldownFrames !== undefined) {\r\n this._evictionCooldownFrames = Math.max(0, Math.floor(options.evictionCooldownFrames));\r\n }\r\n // Resolve the resident-splat budget from the splat-count and/or memory-size options (smaller wins).\r\n let budget = 0;\r\n if (options.maxResidentSplats !== undefined && options.maxResidentSplats > 0) {\r\n budget = Math.floor(options.maxResidentSplats);\r\n }\r\n if (options.memoryBudgetMb !== undefined && options.memoryBudgetMb > 0) {\r\n const fromMB = Math.floor((options.memoryBudgetMb * 1024 * 1024) / BytesPerResidentSplat);\r\n budget = budget > 0 ? Math.min(budget, fromMB) : fromMB;\r\n }\r\n this._residentBudget = budget;\r\n\r\n this._downloadManager = new GaussianSplattingDownloadManager({\r\n maxConcurrent: options.maxConcurrentDownloads,\r\n maxRetries: options.maxDownloadRetries,\r\n });\r\n\r\n // PlayCanvas SOG data is authored with a flipped Y; match the standard SOG loader.\r\n this.scaling.y *= -1;\r\n // PlayCanvas SOG LOD scenes are authored Z-up; rotate into Babylon's Y-up convention.\r\n this.rotation.x = -Math.PI / 2;\r\n\r\n this._collectLodEntries(metadata.tree);\r\n\r\n if (options.debugDisplay) {\r\n this.debugDisplay = true;\r\n }\r\n\r\n // Kick off streaming without blocking the caller or the render loop.\r\n // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then\r\n this._streamAllAsync().catch((e) => {\r\n Logger.Error(\"GaussianSplattingStream: streaming failed: \" + (e?.message ?? e));\r\n });\r\n }\r\n\r\n public override getClassName(): string {\r\n return \"GaussianSplattingStream\";\r\n }\r\n\r\n /**\r\n * Resolves once the scene is fully streamed and displayed for the current camera: a LOD re-evaluation has\r\n * run for the current point of view, every reachable LOD file has finished downloading and decoding (no\r\n * downloads, decodes, or queued work remain), and the depth sort for the resulting splats has been applied\r\n * and rendered. Intended for deterministic automated testing and screenshot/image comparison.\r\n *\r\n * Streaming and settling require rendered frames. If an external render loop is already running, this waits\r\n * on it passively; otherwise (e.g. when awaited inside an async `createScene` before the host starts its\r\n * render loop) it drives `scene.render()` itself until settled, so it never deadlocks.\r\n *\r\n * Note: the promise only resolves while the camera is still — if the camera keeps moving, the target LODs\r\n * (and the depth sort) keep changing and the stream never settles. Position the camera, then await this.\r\n * @param stableFrames number of consecutive settled frames to require before resolving (defaults to 3), so\r\n * the final sorted frame is actually on screen\r\n * @returns a promise that resolves when loading and rendering are complete for the current view\r\n */\r\n public async whenSettledAsync(stableFrames = 3): Promise<void> {\r\n if (this._disposed) {\r\n return;\r\n }\r\n // Re-evaluate LODs immediately so the target levels reflect the current camera before we wait.\r\n this._forceLodUpdate = true;\r\n const required = Math.max(1, stableFrames);\r\n const scene = this._scene;\r\n let stable = 0;\r\n const isSettled = (): boolean => {\r\n if (this._isLoadingIdle() && this._isDepthSortSettled) {\r\n return ++stable >= required;\r\n }\r\n stable = 0;\r\n return false;\r\n };\r\n\r\n // An external render loop is already driving frames: observe it passively.\r\n if (scene.getEngine().activeRenderLoops.length > 0) {\r\n await new Promise<void>((resolve) => {\r\n let observer: Nullable<Observer<Scene>> = null;\r\n observer = scene.onAfterRenderObservable.add(() => {\r\n if (this._disposed || isSettled()) {\r\n if (observer) {\r\n scene.onAfterRenderObservable.remove(observer);\r\n observer = null;\r\n }\r\n resolve();\r\n }\r\n });\r\n });\r\n return;\r\n }\r\n\r\n // No render loop yet (e.g. awaited inside createScene): drive rendering ourselves so the streaming\r\n // decodes and depth sort can progress, yielding between frames so async downloads/readbacks resolve.\r\n // Wrap each render in beginFrame/endFrame exactly like the engine's own render loop: on WebGPU,\r\n // endFrame submits the frame's command buffers and presents the swapchain, so a bare scene.render()\r\n // would leave the acquired swapchain texture to be destroyed at the frame boundary before its command\r\n // buffer is submitted (\"destroyed texture used in a submit\").\r\n const engine = scene.getEngine();\r\n const requestFrame = (globalThis as { requestAnimationFrame?: (cb: () => void) => void }).requestAnimationFrame;\r\n while (!this._disposed) {\r\n engine.beginFrame();\r\n scene.render();\r\n engine.endFrame();\r\n if (isSettled()) {\r\n return;\r\n }\r\n // eslint-disable-next-line no-await-in-loop\r\n await new Promise<void>((resolve) => {\r\n if (typeof requestFrame === \"function\") {\r\n requestFrame(() => resolve());\r\n } else {\r\n setTimeout(resolve, 16);\r\n }\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Whether the base layer is ready and there is no streaming work in flight (nothing queued for decode, no\r\n * decode running, and no downloads pending).\r\n * @returns true when no loading work remains\r\n */\r\n private _isLoadingIdle(): boolean {\r\n return this._baseLayerReady && this._decodeQueue.length === 0 && this._loadingFiles.size === 0 && this._downloadManager.isIdle;\r\n }\r\n\r\n /**\r\n * Finest (most detailed) LOD level any node is allowed to render. `0` allows full detail (level 0);\r\n * `1` caps detail at the next-coarser level, and so on. Nodes already coarser than this cap (by\r\n * distance) are unaffected. Changes take effect in real time.\r\n */\r\n public get maxDetailLod(): number {\r\n return this._maxDetailLod;\r\n }\r\n\r\n public set maxDetailLod(value: number) {\r\n const level = Math.max(0, Math.floor(value));\r\n if (this._maxDetailLod === level) {\r\n return;\r\n }\r\n this._maxDetailLod = level;\r\n // Re-evaluate LODs on the next frame regardless of the movement throttle so the change is immediate.\r\n this._forceLodUpdate = true;\r\n }\r\n\r\n /**\r\n * Coarsest LOD level index in the scene (number of LOD levels minus one). Useful as the upper bound\r\n * for {@link maxDetailLod}.\r\n */\r\n public get maxLodLevel(): number {\r\n return Math.max(0, this._metadata.lodLevels - 1);\r\n }\r\n\r\n /**\r\n * When true (default), nodes whose bounding box is outside the camera frustum are biased to the coarsest\r\n * LOD instead of being hidden. They stay in the sort/render set (their off-screen splats are clipped), so\r\n * turning the camera toward them shows low detail immediately with no invisible frames, then refines.\r\n * Changes take effect in real time.\r\n */\r\n public get frustumCulling(): boolean {\r\n return this._frustumCulling;\r\n }\r\n\r\n public set frustumCulling(value: boolean) {\r\n if (this._frustumCulling === value) {\r\n return;\r\n }\r\n this._frustumCulling = value;\r\n // Re-evaluate LODs next frame so the off-screen bias is applied/removed immediately.\r\n this._forceLodUpdate = true;\r\n }\r\n\r\n /**\r\n * When true, renders a wireframe box per LOD node, colored by the LOD level selected by {@link debugLodSource}.\r\n */\r\n public get debugDisplay(): boolean {\r\n return this._debugDisplay;\r\n }\r\n\r\n public set debugDisplay(value: boolean) {\r\n if (this._debugDisplay === value) {\r\n return;\r\n }\r\n this._debugDisplay = value;\r\n if (value) {\r\n this._refreshDebugDisplay();\r\n } else {\r\n this._clearDebugDisplay();\r\n }\r\n }\r\n\r\n /**\r\n * Selects which LOD value drives the debug wireframe colors: the distance-based `\"optimal\"` LOD\r\n * (default, recomputed as the camera moves) or the `\"current\"` streamed/rendered LOD.\r\n */\r\n public get debugLodSource(): GaussianSplattingStreamDebugLodSource {\r\n return this._debugLodSource;\r\n }\r\n\r\n public set debugLodSource(value: GaussianSplattingStreamDebugLodSource) {\r\n if (this._debugLodSource === value) {\r\n return;\r\n }\r\n this._debugLodSource = value;\r\n if (this._debugDisplay) {\r\n this._refreshDebugDisplay();\r\n }\r\n }\r\n\r\n public override dispose(doNotRecurse?: boolean): void {\r\n this._disposed = true;\r\n if (this._lodObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._lodObserver);\r\n this._lodObserver = null;\r\n }\r\n this._clearDebugDisplay();\r\n this._downloadManager.dispose();\r\n this._residency?.dispose();\r\n this._residency = null;\r\n this._workBuffer?.dispose();\r\n this._workBuffer = null;\r\n super.dispose(doNotRecurse);\r\n }\r\n\r\n /**\r\n * Re-evaluates the optimal LOD for every node based on the camera position. The result is stored in\r\n * each node's `optimalLod`. Rendering is unaffected; this currently drives only diagnostics and the\r\n * debug wireframe display.\r\n * @param camera camera to evaluate against (defaults to the scene's active camera)\r\n */\r\n public evaluateOptimalLods(camera: Nullable<Camera> = this._scene.activeCamera): void {\r\n if (!camera || this._leafNodes.length === 0) {\r\n return;\r\n }\r\n\r\n const maxLod = Math.max(0, this._metadata.lodLevels - 1);\r\n const base = this._lodBaseDistance;\r\n const mult = this._lodMultiplier;\r\n const behindPenalty = this._lodBehindPenalty;\r\n const rangeMin = this._lodRangeMin;\r\n const rangeMax = this._lodRangeMax;\r\n\r\n // FOV compensation: use min(tanHalfV, tanHalfH) so transitions stay perceptually uniform (matches PlayCanvas).\r\n const aspect = this._scene.getEngine().getAspectRatio(camera) || 1;\r\n let tanHalfV = Math.tan(camera.fov * 0.5);\r\n if (camera.fovMode === Camera.FOVMODE_HORIZONTAL_FIXED) {\r\n tanHalfV /= aspect;\r\n }\r\n const tanHalfH = tanHalfV * aspect;\r\n const fovScale = Math.min(tanHalfV, tanHalfH) / RefTanHalfFov;\r\n\r\n // Transform the camera into the mesh's local space (where the node bounds live).\r\n this.computeWorldMatrix(false).invertToRef(TmpInvWorld);\r\n const localCamera = Vector3.TransformCoordinatesToRef(camera.globalPosition, TmpInvWorld, TmpLocalCamera);\r\n const px = localCamera.x;\r\n const py = localCamera.y;\r\n const pz = localCamera.z;\r\n\r\n let fwx = 0;\r\n let fwy = 0;\r\n let fwz = 0;\r\n if (behindPenalty > 1) {\r\n camera.getDirectionToRef(LocalForwardAxis, TmpWorldForward);\r\n const localForward = Vector3.TransformNormalToRef(TmpWorldForward, TmpInvWorld, TmpLocalForward);\r\n localForward.normalize();\r\n fwx = localForward.x;\r\n fwy = localForward.y;\r\n fwz = localForward.z;\r\n }\r\n\r\n for (const node of this._leafNodes) {\r\n const mn = node.bound.min;\r\n const mx = node.bound.max;\r\n\r\n // Distance from the camera to the closest point on this node's AABB (local space).\r\n const qx = px < mn[0] ? mn[0] : px > mx[0] ? mx[0] : px;\r\n const qy = py < mn[1] ? mn[1] : py > mx[1] ? mx[1] : py;\r\n const qz = pz < mn[2] ? mn[2] : pz > mx[2] ? mx[2] : pz;\r\n const dx = qx - px;\r\n const dy = qy - py;\r\n const dz = qz - pz;\r\n const actualDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\r\n\r\n // Push nodes behind the camera toward coarser LODs when a penalty is configured.\r\n let penalizedDistance = actualDistance;\r\n if (behindPenalty > 1 && actualDistance > 0.01) {\r\n const dotOverDistance = (fwx * dx + fwy * dy + fwz * dz) / actualDistance;\r\n if (dotOverDistance < 0) {\r\n penalizedDistance = actualDistance * (1 + -dotOverDistance * (behindPenalty - 1));\r\n }\r\n }\r\n\r\n // Geometric LOD bands: threshold[k] = base * mult^(k-1).\r\n const fovAdjustedDistance = penalizedDistance * fovScale;\r\n let optimalLod: number;\r\n if (maxLod === 0 || fovAdjustedDistance < base) {\r\n optimalLod = 0;\r\n } else {\r\n optimalLod = maxLod;\r\n while (optimalLod > 1 && fovAdjustedDistance < base * Math.pow(mult, optimalLod - 1)) {\r\n optimalLod--;\r\n }\r\n }\r\n\r\n if (optimalLod < rangeMin) {\r\n optimalLod = rangeMin;\r\n } else if (optimalLod > rangeMax) {\r\n optimalLod = rangeMax;\r\n }\r\n\r\n // Frustum-based LOD bias: nodes outside the camera frustum are pushed to the coarsest allowed\r\n // level instead of being hidden. They stay in the render/sort set (their splats are off-screen\r\n // and clipped anyway), so when the camera turns to include them they are already present at low\r\n // detail with no invisible frames, then refine to the distance-optimal level.\r\n if (this._frustumCulling && node.inFrustum === false) {\r\n optimalLod = rangeMax;\r\n }\r\n\r\n node.optimalLod = optimalLod;\r\n }\r\n }\r\n\r\n /**\r\n * The LOD level used to color a node's debug box, per {@link debugLodSource}.\r\n * @param node leaf node\r\n * @returns the displayed LOD level\r\n */\r\n private _displayedLodLevel(node: ISOGLODNode): number {\r\n if (this._debugLodSource === \"optimal\") {\r\n return node.optimalLod ?? node.activeLod ?? 0;\r\n }\r\n return node.activeLod ?? 0;\r\n }\r\n\r\n /**\r\n * Rebuilds the debug wireframe (evaluating the optimal LOD first when needed) and wires up the per-frame\r\n * recolor observer. The observer runs for both LOD sources: \"optimal\" colors track the camera, and\r\n * \"current\" colors track LOD levels as they stream in/out.\r\n */\r\n private _refreshDebugDisplay(): void {\r\n if (this._debugLodSource === \"optimal\") {\r\n this.evaluateOptimalLods();\r\n }\r\n this._buildDebugMesh();\r\n\r\n const needsObserver = this._debugDisplay;\r\n if (needsObserver && !this._debugObserver) {\r\n this._debugObserver = this._scene.onBeforeRenderObservable.add(() => this._onDebugFrame());\r\n } else if (!needsObserver && this._debugObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._debugObserver);\r\n this._debugObserver = null;\r\n }\r\n }\r\n\r\n /**\r\n * Per-frame debug update: recolors the existing wireframe in place whenever the displayed LOD levels\r\n * change. For the \"optimal\" source the optimal LOD is recomputed first (it tracks the camera); for the\r\n * \"current\" source the levels are driven by the streaming loop, so no recomputation is needed here. The\r\n * geometry is never rebuilt, which avoids the dispose/recreate flicker while the camera moves.\r\n */\r\n private _onDebugFrame(): void {\r\n if (this._debugLodSource === \"optimal\") {\r\n this.evaluateOptimalLods();\r\n }\r\n if (this._computeDebugSignature() !== this._debugSignature) {\r\n this._updateDebugColors();\r\n }\r\n }\r\n\r\n /**\r\n * Builds the LOD-node wireframe boxes once (one box per leaf node), colored by the displayed LOD level.\r\n * The color vertex buffer is created updatable so subsequent recolors can happen in place.\r\n */\r\n private _buildDebugMesh(): void {\r\n if (this._debugMesh) {\r\n this._debugMesh.dispose();\r\n this._debugMesh = null;\r\n }\r\n this._debugColorData = null;\r\n\r\n const lines: Vector3[][] = [];\r\n const colors: Color4[][] = [];\r\n for (const node of this._leafNodes) {\r\n const color = GsLodDebugColors[this._displayedLodLevel(node) % GsLodDebugColors.length];\r\n const mn = node.bound.min;\r\n const mx = node.bound.max;\r\n const corners = [\r\n new Vector3(mn[0], mn[1], mn[2]),\r\n new Vector3(mx[0], mn[1], mn[2]),\r\n new Vector3(mx[0], mx[1], mn[2]),\r\n new Vector3(mn[0], mx[1], mn[2]),\r\n new Vector3(mn[0], mn[1], mx[2]),\r\n new Vector3(mx[0], mn[1], mx[2]),\r\n new Vector3(mx[0], mx[1], mx[2]),\r\n new Vector3(mn[0], mx[1], mx[2]),\r\n ];\r\n for (const edge of BoxEdges) {\r\n lines.push([corners[edge[0]], corners[edge[1]]]);\r\n colors.push([color, color]);\r\n }\r\n }\r\n\r\n this._debugSignature = this._computeDebugSignature();\r\n if (lines.length === 0) {\r\n return;\r\n }\r\n\r\n const mesh = CreateLineSystem(this.name + \"_lodDebug\", { lines, colors, updatable: true, useVertexAlpha: false }, this._scene);\r\n mesh.parent = this;\r\n mesh.isPickable = false;\r\n mesh.doNotSerialize = true;\r\n mesh.reservedDataStore = { hidden: true };\r\n this._debugMesh = mesh;\r\n this._debugColorData = new Float32Array(this._leafNodes.length * VerticesPerBox * 4);\r\n }\r\n\r\n /**\r\n * Recolors the existing wireframe in place from the current displayed LOD levels, without rebuilding geometry.\r\n */\r\n private _updateDebugColors(): void {\r\n if (!this._debugMesh || !this._debugColorData) {\r\n return;\r\n }\r\n const data = this._debugColorData;\r\n let offset = 0;\r\n for (const node of this._leafNodes) {\r\n const color = GsLodDebugColors[this._displayedLodLevel(node) % GsLodDebugColors.length];\r\n for (let v = 0; v < VerticesPerBox; v++) {\r\n data[offset++] = color.r;\r\n data[offset++] = color.g;\r\n data[offset++] = color.b;\r\n data[offset++] = color.a;\r\n }\r\n }\r\n this._debugMesh.updateVerticesData(VertexBuffer.ColorKind, data);\r\n this._debugSignature = this._computeDebugSignature();\r\n }\r\n\r\n /**\r\n * Computes a cheap 32-bit rolling hash of every leaf's displayed LOD level, used to detect when the\r\n * debug wireframe needs recoloring. Avoids per-frame string allocation in the render loop.\r\n * @returns a numeric signature of the current displayed LOD levels\r\n */\r\n private _computeDebugSignature(): number {\r\n let hash = 0;\r\n for (const node of this._leafNodes) {\r\n hash = (hash * 31 + this._displayedLodLevel(node)) | 0;\r\n }\r\n return hash;\r\n }\r\n\r\n /**\r\n * Disposes the LOD-node wireframe boxes and stops live debug updates.\r\n */\r\n private _clearDebugDisplay(): void {\r\n if (this._debugObserver) {\r\n this._scene.onBeforeRenderObservable.remove(this._debugObserver);\r\n this._debugObserver = null;\r\n }\r\n if (this._debugMesh) {\r\n this._debugMesh.dispose();\r\n this._debugMesh = null;\r\n }\r\n this._debugColorData = null;\r\n this._debugSignature = 0;\r\n }\r\n\r\n /**\r\n * Walks the LOD tree and records every leaf that carries renderable LOD entries, capturing the set of\r\n * available levels and the coarsest (base) level for each.\r\n * @param node current tree node\r\n */\r\n private _collectLodEntries(node: ISOGLODNode): void {\r\n if (node.children) {\r\n for (const child of node.children) {\r\n this._collectLodEntries(child);\r\n }\r\n return;\r\n }\r\n\r\n if (!node.lods) {\r\n return;\r\n }\r\n\r\n // Collect all levels that hold splats (PlayCanvas convention: level 0 is the finest, higher = coarser).\r\n const levels: number[] = [];\r\n for (const key of Object.keys(node.lods)) {\r\n const level = Number(key);\r\n const entry = node.lods[key];\r\n if (Number.isFinite(level) && entry && entry.count > 0) {\r\n levels.push(level);\r\n }\r\n }\r\n if (levels.length === 0) {\r\n return;\r\n }\r\n levels.sort((a, b) => a - b);\r\n\r\n node.availableLevels = levels;\r\n node.baseLod = levels[levels.length - 1];\r\n node.activeLod = undefined;\r\n node.lodCooldown = 0;\r\n node.inFrustum = true;\r\n // Local-space bounds for the per-node frustum test; the mesh world matrix is applied per evaluation.\r\n node.cullBounds = new BoundingInfo(Vector3.FromArray(node.bound.min), Vector3.FromArray(node.bound.max));\r\n this._leafNodes.push(node);\r\n }\r\n\r\n /**\r\n * Streams the scene: learns every source file's splat count, allocates one unified GPU work buffer\r\n * sized for all LOD files, decodes the environment and the coarsest LOD of every node as a permanent\r\n * base layer, then installs the per-frame loop that streams finer LODs on demand.\r\n */\r\n private async _streamAllAsync(): Promise<void> {\r\n // Phase 1: learn splat counts for the environment and every referenced LOD file (cheap meta only).\r\n const fileIds = this._collectAllFileIds();\r\n const envCount = await this._gatherCountsAsync(fileIds);\r\n if (this._disposed) {\r\n return;\r\n }\r\n\r\n // Phase 2: learn the full dataset size (padding + environment + every LOD file). The work buffer is\r\n // sized to this unless a smaller budget enables eviction-based streaming.\r\n // Index 0 is reserved as a never-decoded padding splat: the sort worker and index buffer pad unused\r\n // slots with index 0, and leaving that slot zeroed (center.w = 0 => zero covariance, alpha 0) makes\r\n // the padding invisible instead of ghosting a copy of the first real splat.\r\n let fullCapacity = 1;\r\n if (envCount > 0) {\r\n fullCapacity += envCount;\r\n }\r\n for (const fileId of fileIds) {\r\n const count = this._fileCounts.get(fileId);\r\n if (count !== undefined && count > 0) {\r\n fullCapacity += count;\r\n }\r\n }\r\n if (fullCapacity <= 1) {\r\n return;\r\n }\r\n\r\n // Eviction streams the dataset through a fixed budget; only enabled when that budget is below the full set.\r\n this._evictionEnabled = this._residentBudget > 0 && this._residentBudget < fullCapacity;\r\n const capacity = this._evictionEnabled ? Math.max(this._residentBudget, 1) : fullCapacity;\r\n\r\n this._residency = new GaussianSplattingResidencyController(capacity, this._evictionCooldownFrames, (file) => this._onFileEvicted(file));\r\n // Pin splat 0 as the invisible padding splat, then the environment (always rendered) — neither is evicted.\r\n this._residency.pin(PaddingFileId, 1);\r\n if (envCount > 0) {\r\n const envOffset = this._residency.pin(EnvironmentFileId, envCount);\r\n if (envOffset !== null) {\r\n this._environmentRange = { offset: envOffset, count: envCount };\r\n } else {\r\n Logger.Warn(\"GaussianSplattingStream: environment does not fit the memory budget; skipping it.\");\r\n this._environmentFiles = null;\r\n }\r\n }\r\n\r\n this._workBuffer = new GaussianSplattingWorkBuffer(this._scene, capacity);\r\n // GPU readback is only enabled after it is validated against a CPU decode on the first file (see\r\n // _probeReadbackAsync); until then positions are decoded on the CPU so there is always a correct result.\r\n this._readbackCandidate = this._workBuffer.supportsAsyncCentersReadback;\r\n const splatPositions = new Float32Array(capacity * 4);\r\n const textures = this._workBuffer.textures;\r\n this._setExternalWorkBuffer(textures[0], textures[1], textures[2], textures[3], splatPositions, capacity);\r\n // Nothing is active until at least one resource has been decoded.\r\n this.setSplatIndexRanges([]);\r\n this.setEnabled(true);\r\n\r\n // Phase 3: decode the environment, then every node's coarsest LOD as the permanent base layer.\r\n if (this._environmentRange && this._environmentFiles) {\r\n await this._decodeEnvironmentAsync();\r\n }\r\n this._environmentFiles = null;\r\n\r\n const baseFiles = new Set<number>();\r\n for (const node of this._leafNodes) {\r\n const entry = node.lods![String(node.baseLod)];\r\n if (entry && this._fileCounts.has(entry.file)) {\r\n baseFiles.add(entry.file);\r\n }\r\n }\r\n for (const fileId of Array.from(baseFiles)) {\r\n if (this._disposed) {\r\n return;\r\n }\r\n // eslint-disable-next-line no-await-in-loop\r\n await this._decodeFileAsync(fileId);\r\n }\r\n\r\n if (this._disposed) {\r\n return;\r\n }\r\n // Phase 4: hand off to the per-frame LOD streaming loop.\r\n this._baseLayerReady = true;\r\n if (!this._lodObserver) {\r\n this._lodObserver = this._scene.onBeforeRenderObservable.add(() => this._onLodFrame());\r\n }\r\n }\r\n\r\n /**\r\n * Collects the unique set of source file indices referenced by any LOD of any leaf, sorted ascending.\r\n * @returns sorted unique file indices\r\n */\r\n private _collectAllFileIds(): number[] {\r\n const ids = new Set<number>();\r\n for (const node of this._leafNodes) {\r\n for (const level of node.availableLevels!) {\r\n const entry = node.lods![String(level)];\r\n if (entry) {\r\n ids.add(entry.file);\r\n }\r\n }\r\n }\r\n return Array.from(ids).sort((a, b) => a - b);\r\n }\r\n\r\n /**\r\n * Fetches the environment bundle and every referenced file's metadata to learn splat counts, caching\r\n * each file's parsed metadata for the later on-demand decode. Metadata fetches run in parallel.\r\n * @param fileIds file indices to fetch metadata for\r\n * @returns the environment splat count (0 when there is no environment)\r\n */\r\n private async _gatherCountsAsync(fileIds: number[]): Promise<number> {\r\n let envCount = 0;\r\n if (this._metadata.environment) {\r\n try {\r\n const url = this._rootUrl + this._metadata.environment;\r\n const buffer = await this._downloadManager.loadFileAsync(url);\r\n const files = await this._unzipAsync(new Uint8Array(buffer));\r\n const metaBytes = files.get(\"meta.json\");\r\n if (metaBytes) {\r\n const meta = JSON.parse(new TextDecoder().decode(metaBytes)) as SOGRootData;\r\n envCount = GaussianSplattingStream._GetSplatCount(meta);\r\n this._environmentFiles = files;\r\n }\r\n } catch (e: any) {\r\n // The environment is non-essential — keep streaming the LOD tree even if it fails.\r\n Logger.Warn(\"GaussianSplattingStream: failed to load environment: \" + (e?.message ?? e));\r\n }\r\n }\r\n\r\n await Promise.all(\r\n fileIds.map(async (fileId) => {\r\n const relativePath = this._metadata.filenames[fileId];\r\n if (!relativePath) {\r\n Logger.Warn(`GaussianSplattingStream: missing filename for file index ${fileId}.`);\r\n return;\r\n }\r\n try {\r\n const metaUrl = this._rootUrl + relativePath;\r\n const subRootUrl = metaUrl.substring(0, metaUrl.lastIndexOf(\"/\") + 1);\r\n const metaBuffer = await this._downloadManager.loadFileAsync(metaUrl);\r\n const sogData = JSON.parse(new TextDecoder().decode(new Uint8Array(metaBuffer))) as SOGRootData;\r\n this._fileCounts.set(fileId, GaussianSplattingStream._GetSplatCount(sogData));\r\n this._fileMeta.set(fileId, { sogData, subRootUrl });\r\n } catch (e: any) {\r\n Logger.Warn(`GaussianSplattingStream: failed to load metadata for ${relativePath}: ${e?.message ?? e}`);\r\n }\r\n })\r\n );\r\n\r\n return envCount;\r\n }\r\n\r\n /**\r\n * Queues a file for on-demand decode if it isn't already decoded, in flight, or already queued.\r\n * @param fileId file index to decode\r\n */\r\n private _enqueueDecode(fileId: number): void {\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId) || !this._fileMeta.has(fileId)) {\r\n return;\r\n }\r\n if (this._decodeQueue.indexOf(fileId) === -1) {\r\n this._decodeQueue.push(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Starts up to {@link _maxDecodesPerFrame} queued decodes for this frame. Decodes run asynchronously\r\n * and promote any waiting nodes once they complete.\r\n */\r\n private _pumpDecodeQueue(): void {\r\n let started = 0;\r\n while (this._decodeQueue.length > 0 && started < this._maxDecodesPerFrame) {\r\n const fileId = this._decodeQueue.shift()!;\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId)) {\r\n continue;\r\n }\r\n started++;\r\n // eslint-disable-next-line github/no-then\r\n this._decodeFileAsync(fileId).catch((e) => {\r\n Logger.Warn(\"GaussianSplattingStream: decode failed: \" + (e?.message ?? e));\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Writes a decoded splat range's positions into the shared buffer, expands the bounds, and incrementally\r\n * patches the sort worker.\r\n * @param positions stride-4 positions for the range\r\n * @param base first splat index of the range in the work buffer\r\n * @param count number of splats in the range\r\n */\r\n private _applyPositions(positions: Float32Array, base: number, count: number): void {\r\n this._splatPositions!.set(positions, base * 4);\r\n this._updateBounds(positions, count);\r\n // Incrementally patch only this range in the sort worker (avoids the full position-buffer re-copy).\r\n this._postWorkerPositionsRange(base, count);\r\n }\r\n\r\n /**\r\n * One-time validation of GPU position readback: reads a sample of the just-decoded range back from the work\r\n * buffer and compares it to the CPU-decoded positions. Enables {@link _useGpuPositionReadback} only on an\r\n * exact (within float tolerance) match, so an unsupported or incorrect readback (e.g. a backend without the\r\n * required texture usage, or an orientation mismatch) safely keeps the CPU decode path.\r\n * @param base first splat index of the validated range\r\n * @param count number of splats in the range\r\n * @param cpuPositions the CPU-decoded stride-4 positions for the range (ground truth)\r\n */\r\n private async _probeReadbackAsync(base: number, count: number, cpuPositions: Float32Array): Promise<void> {\r\n this._readbackProbed = true;\r\n if (!this._workBuffer) {\r\n return;\r\n }\r\n const sampleCount = Math.min(count, 1024);\r\n let ok = false;\r\n try {\r\n const gpu = await this._workBuffer.readCentersRangeAsync(base, sampleCount);\r\n if (this._disposed) {\r\n return;\r\n }\r\n if (gpu && gpu.length >= sampleCount * 4) {\r\n ok = true;\r\n for (let i = 0; i < sampleCount && ok; i++) {\r\n for (let j = 0; j < 3; j++) {\r\n const a = gpu[i * 4 + j];\r\n const b = cpuPositions[i * 4 + j];\r\n if (Math.abs(a - b) > 1e-2 * (1 + Math.abs(b))) {\r\n ok = false;\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n } catch {\r\n ok = false;\r\n }\r\n this._useGpuPositionReadback = ok;\r\n Logger.Log(\r\n ok\r\n ? \"GaussianSplattingStream: GPU position readback validated; streamed LOD positions are read back from the GPU.\"\r\n : \"GaussianSplattingStream: GPU position readback unavailable; decoding LOD positions on the CPU.\"\r\n );\r\n }\r\n\r\n /**\r\n * Resolves the decoded positions for a splat range and applies them. Once GPU readback has been validated,\r\n * positions are read back from the work buffer (non-blocking) and `pack.positions` is empty; otherwise the\r\n * CPU-decoded `pack.positions` are used, and — on the first such decode — the GPU readback is validated\r\n * against them so subsequent decodes can use the fast path.\r\n * @param pack the parsed SOG pack (its `positions` is populated only on the CPU path)\r\n * @param base first splat index of the range in the work buffer\r\n * @param count number of splats in the range\r\n * @returns whether positions were applied\r\n */\r\n private async _applyDecodedPositionsAsync(pack: ISogTexturePack, base: number, count: number): Promise<boolean> {\r\n if (this._useGpuPositionReadback && this._workBuffer) {\r\n const positions = await this._workBuffer.readCentersRangeAsync(base, count);\r\n if (this._disposed) {\r\n return false;\r\n }\r\n if (positions && this._splatPositions) {\r\n this._applyPositions(positions, base, count);\r\n return true;\r\n }\r\n // Validated readback unexpectedly returned nothing; fall through to the (likely empty) CPU positions.\r\n }\r\n\r\n const cpu = pack.positions.length >= count * 4 ? (pack.positions.subarray(0, count * 4) as Float32Array) : null;\r\n if (!cpu || !this._splatPositions) {\r\n return false;\r\n }\r\n this._applyPositions(cpu, base, count);\r\n // First CPU decode while readback is a candidate: validate it so later decodes can use the fast path.\r\n if (!this._readbackProbed && this._readbackCandidate) {\r\n await this._probeReadbackAsync(base, count, cpu);\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Decodes the always-on environment bundle into its work-buffer block and activates its range.\r\n */\r\n private async _decodeEnvironmentAsync(): Promise<void> {\r\n if (!this._environmentRange || !this._environmentFiles || !this._workBuffer) {\r\n return;\r\n }\r\n const range = this._environmentRange;\r\n try {\r\n const parsed = await ParseSogMetaAsTextures(this._environmentFiles, \"\", this._scene, !this._useGpuPositionReadback, this._downloadManager);\r\n const pack = parsed.sogTextures;\r\n if (!pack) {\r\n return;\r\n }\r\n try {\r\n if (this._disposed || !this._workBuffer) {\r\n return;\r\n }\r\n await this._workBuffer.decodeAsync(pack, range.offset);\r\n if (this._disposed) {\r\n return;\r\n }\r\n await this._applyDecodedPositionsAsync(pack, range.offset, range.count);\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._refreshActiveRanges();\r\n } finally {\r\n // Always release the GPU source textures (the decode pass is the only consumer).\r\n GaussianSplattingStream._DisposePack(pack);\r\n }\r\n } catch (e: any) {\r\n Logger.Warn(\"GaussianSplattingStream: failed to decode environment: \" + (e?.message ?? e));\r\n }\r\n }\r\n\r\n /**\r\n * Loads one LOD source file as GPU textures, decodes it into its fixed work-buffer block, records its\r\n * CPU centers for sorting, frees the source textures, then promotes any nodes that were waiting for it.\r\n * Concurrent or repeat requests for the same file are ignored. If the file is cancelled mid-flight\r\n * (because every node that wanted it retargeted), the decode bails cooperatively at the next checkpoint.\r\n * @param fileId file index to decode\r\n */\r\n private async _decodeFileAsync(fileId: number): Promise<void> {\r\n if (this._decodedFiles.has(fileId) || this._loadingFiles.has(fileId) || !this._residency) {\r\n return;\r\n }\r\n const meta = this._fileMeta.get(fileId);\r\n const count = this._fileCounts.get(fileId);\r\n if (!meta || count === undefined) {\r\n return;\r\n }\r\n this._loadingFiles.add(fileId);\r\n this._cancelledDecodes.delete(fileId);\r\n let allocated = false;\r\n try {\r\n const parsed = await ParseSogMetaAsTextures(meta.sogData, meta.subRootUrl, this._scene, !this._useGpuPositionReadback, this._downloadManager, fileId);\r\n const pack = parsed.sogTextures;\r\n if (!pack) {\r\n return;\r\n }\r\n // Serialize the allocate -> decode -> readback section: a relayout runs only inside it (see\r\n // _relayoutAndAllocateAsync), so it never moves a file whose decode has not finished writing.\r\n const release = await this._acquireDecodeGateAsync();\r\n try {\r\n if (this._disposed || !this._workBuffer || this._cancelledDecodes.has(fileId)) {\r\n return;\r\n }\r\n let base = this._residency.allocate(fileId, count);\r\n if (base === null) {\r\n // Defragment the work buffer to reclaim fragmented free space, then retry.\r\n base = await this._relayoutAndAllocateAsync(fileId, count);\r\n }\r\n if (base === null) {\r\n // No room even after evicting and compacting: refuse and keep nodes on their current LOD.\r\n // A file cancelled mid-flight isn't a budget problem, so don't warn for it.\r\n if (!this._cancelledDecodes.has(fileId)) {\r\n Logger.Warn(`GaussianSplattingStream: resident memory budget full; skipping LOD file ${fileId}.`);\r\n }\r\n return;\r\n }\r\n allocated = true;\r\n if (this._disposed || !this._workBuffer || this._cancelledDecodes.has(fileId)) {\r\n return;\r\n }\r\n await this._workBuffer.decodeAsync(pack, base);\r\n if (this._disposed || this._cancelledDecodes.has(fileId)) {\r\n return;\r\n }\r\n await this._applyDecodedPositionsAsync(pack, base, count);\r\n if (this._disposed) {\r\n return;\r\n }\r\n this._decodedFiles.add(fileId);\r\n // Promote any nodes that can now reach their desired LOD via this newly decoded file.\r\n if (this._applyDesiredLods()) {\r\n this._refreshActiveRanges();\r\n }\r\n } finally {\r\n GaussianSplattingStream._DisposePack(pack);\r\n release();\r\n }\r\n } catch (e) {\r\n // A cancelled file rejects its downloads on purpose — swallow that; re-throw genuine failures.\r\n if (!this._cancelledDecodes.has(fileId)) {\r\n throw e;\r\n }\r\n } finally {\r\n // If a slot was allocated but the decode did not complete (cancelled/disposed), release it.\r\n if (allocated && !this._decodedFiles.has(fileId)) {\r\n this._residency.free(fileId);\r\n }\r\n this._loadingFiles.delete(fileId);\r\n this._cancelledDecodes.delete(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Acquires the decode gate (a simple async mutex). Resolves once any prior holder releases, returning a\r\n * release function the caller must invoke in a `finally`.\r\n * @returns the release function\r\n */\r\n private async _acquireDecodeGateAsync(): Promise<() => void> {\r\n const previous = this._decodeGate;\r\n let release!: () => void;\r\n this._decodeGate = new Promise<void>((resolve) => {\r\n release = resolve;\r\n });\r\n await previous;\r\n return release;\r\n }\r\n\r\n /**\r\n * Defragments the work buffer to make room for a file that did not fit, then allocates its slot. Runs the\r\n * compaction + GPU relayout atomically inside a single `onBeforeRender` so no inconsistent CPU/GPU layout\r\n * is ever rendered. Returns the new slot offset, or null if even compaction cannot free enough contiguous\r\n * space (the caller refuses the upgrade).\r\n * @param fileId file to allocate after compaction\r\n * @param count splats the file needs\r\n * @returns the allocated offset, or null\r\n */\r\n private async _relayoutAndAllocateAsync(fileId: number, count: number): Promise<Nullable<number>> {\r\n if (!this._residency || !this._workBuffer) {\r\n return null;\r\n }\r\n // Even a perfect compaction cannot help if the total free space is below what is needed.\r\n if (this._residency.freeSize < count) {\r\n return null;\r\n }\r\n return await new Promise<Nullable<number>>((resolve) => {\r\n const attempt = () => {\r\n // Bail out (no relayout) if the file was cancelled while we waited for the shader to be ready,\r\n // so rapidly-changing targets don't trigger an expensive compaction for a file no longer needed.\r\n if (this._disposed || !this._residency || !this._workBuffer || this._cancelledDecodes.has(fileId)) {\r\n resolve(null);\r\n return;\r\n }\r\n if (!this._workBuffer.isRelayoutReady()) {\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n return;\r\n }\r\n this._performRelayout();\r\n resolve(this._residency.allocate(fileId, count));\r\n };\r\n this._scene.onBeforeRenderObservable.addOnce(attempt);\r\n });\r\n }\r\n\r\n /**\r\n * Compacts the resident set and relocates the corresponding GPU textures and CPU positions to the new\r\n * layout. Must run at a frame-safe point with the work buffer's relayout shader ready.\r\n */\r\n private _performRelayout(): void {\r\n if (!this._residency || !this._workBuffer || !this._splatPositions) {\r\n return;\r\n }\r\n const oldOffsets = this._relayoutOldOffsets;\r\n oldOffsets.clear();\r\n for (const block of this._residency.getResidentBlocks()) {\r\n oldOffsets.set(block.file, block.offset);\r\n }\r\n const moves = this._residency.compact();\r\n if (moves.length === 0) {\r\n return;\r\n }\r\n\r\n const capacity = this._residency.capacity;\r\n if (!this._relayoutSrcIndex || this._relayoutSrcIndex.length !== capacity) {\r\n this._relayoutSrcIndex = new Float32Array(capacity);\r\n }\r\n const srcIndexByDst = this._relayoutSrcIndex;\r\n srcIndexByDst.fill(-1);\r\n\r\n const resident = this._residency.getResidentBlocks();\r\n // Destination->source splat index map for the GPU relayout pass.\r\n for (const block of resident) {\r\n const oldOffset = oldOffsets.get(block.file)!;\r\n for (let k = 0; k < block.count; k++) {\r\n srcIndexByDst[block.offset + k] = oldOffset + k;\r\n }\r\n }\r\n // GPU: relocate the decoded textures in place (same texture instances).\r\n this._workBuffer.relayoutSync(srcIndexByDst);\r\n\r\n // CPU positions: compaction only ever moves a block to a lower offset, so copying in place in ascending\r\n // new-offset order is safe (a block's source is never overwritten by an earlier move). This avoids a\r\n // full capacity*4 scratch buffer.\r\n const positions = this._splatPositions;\r\n resident.sort((a, b) => a.offset - b.offset);\r\n for (const block of resident) {\r\n const oldOffset = oldOffsets.get(block.file)!;\r\n if (oldOffset !== block.offset) {\r\n positions.copyWithin(block.offset * 4, oldOffset * 4, (oldOffset + block.count) * 4);\r\n }\r\n }\r\n\r\n // Update the environment offset (it may have moved), re-post to the sort worker, and refresh ranges.\r\n if (this._environmentRange) {\r\n const envOffset = this._residency.offset(EnvironmentFileId);\r\n if (envOffset !== undefined) {\r\n this._environmentRange.offset = envOffset;\r\n }\r\n }\r\n this._notifyWorkerNewData();\r\n this._refreshActiveRanges();\r\n }\r\n\r\n /**\r\n * Drops a file evicted by the residency controller from the decoded set so it will be re-decoded on demand.\r\n * The file had no remaining references, so no node was rendering or downloading it.\r\n * @param fileId evicted file index\r\n */\r\n private _onFileEvicted(fileId: number): void {\r\n this._decodedFiles.delete(fileId);\r\n }\r\n\r\n /**\r\n * Snaps a desired LOD level to the nearest level the node provides, while never selecting a level finer\r\n * than {@link maxDetailLod} (i.e. with an index below the cap). Ties prefer the finer allowed level. If\r\n * the node has no level at or coarser than the cap, its coarsest available level is used.\r\n * @param node leaf node\r\n * @param desired desired LOD level\r\n * @returns the chosen available level\r\n */\r\n private _cappedLevelForNode(node: ISOGLODNode, desired: number): number {\r\n const levels = node.availableLevels!;\r\n const floor = this._maxDetailLod;\r\n let best = -1;\r\n let bestDiff = Number.POSITIVE_INFINITY;\r\n for (const level of levels) {\r\n if (level < floor) {\r\n continue;\r\n }\r\n const diff = Math.abs(level - desired);\r\n if (diff < bestDiff) {\r\n best = level;\r\n bestDiff = diff;\r\n }\r\n }\r\n // No level is coarse enough to satisfy the cap: fall back to the coarsest the node has.\r\n return best < 0 ? node.baseLod! : best;\r\n }\r\n\r\n /**\r\n * Computes each node's {@link ISOGLODNode.targetLevel}: the distance-based optimal level snapped to an\r\n * available level, capped so no node renders finer (more detailed) than {@link maxDetailLod}.\r\n */\r\n private _computeTargetLevels(): void {\r\n for (const node of this._leafNodes) {\r\n const desired = node.optimalLod ?? node.baseLod!;\r\n node.targetLevel = this._cappedLevelForNode(node, desired);\r\n }\r\n }\r\n\r\n /**\r\n * Applies each node's {@link ISOGLODNode.targetLevel}: switches a node to its target level when that\r\n * level's file is already decoded, otherwise records a pending download request for the file and leaves\r\n * the node on its current LOD (so nothing ever disappears). Nodes within their post-switch cooldown are\r\n * left untouched to damp oscillation (and keep their existing pending request).\r\n *\r\n * Each node tracks the single file it currently needs but lacks ({@link ISOGLODNode.pendingFile}). When a\r\n * node's target changes before that file finished downloading, the old file's reference is released; if no\r\n * other node still needs it, its queued/in-flight download is cancelled (see {@link _releaseFileRef}).\r\n * @returns true when at least one node changed LOD (callers should refresh the active ranges)\r\n */\r\n private _applyDesiredLods(): boolean {\r\n let dirty = false;\r\n for (const node of this._leafNodes) {\r\n // Nodes in cooldown keep their current LOD and their existing pending request untouched.\r\n if (node.lodCooldown && node.lodCooldown > 0) {\r\n continue;\r\n }\r\n const desired = node.targetLevel ?? node.baseLod!;\r\n let newPending: number | undefined;\r\n if (desired !== node.activeLod) {\r\n const entry = node.lods![String(desired)];\r\n if (entry) {\r\n if (this._decodedFiles.has(entry.file)) {\r\n this._switchActiveFile(node, entry.file);\r\n node.activeLod = desired;\r\n node.lodCooldown = this._lodCooldownFrames;\r\n dirty = true;\r\n } else {\r\n newPending = entry.file;\r\n }\r\n }\r\n }\r\n // Reconcile this node's pending-download reference against its (possibly changed) target.\r\n if (node.pendingFile !== newPending) {\r\n if (node.pendingFile !== undefined) {\r\n this._releaseFileRef(node.pendingFile);\r\n }\r\n if (newPending !== undefined) {\r\n this._acquirePendingFile(newPending);\r\n }\r\n node.pendingFile = newPending;\r\n }\r\n }\r\n return dirty;\r\n }\r\n\r\n /**\r\n * Moves a node's resident reference from its previous active file to the one it now renders, so the file\r\n * count that keeps a block in the work buffer stays accurate (and cancels any pending eviction of the new\r\n * file). The new file is already decoded.\r\n * @param node leaf node switching its rendered file\r\n * @param file the file the node now renders from\r\n */\r\n private _switchActiveFile(node: ISOGLODNode, file: number): void {\r\n if (node.activeFile === file) {\r\n return;\r\n }\r\n if (node.activeFile !== undefined) {\r\n this._releaseFileRef(node.activeFile);\r\n }\r\n this._acquireFileRef(file);\r\n node.activeFile = file;\r\n }\r\n\r\n /**\r\n * Adds a reference to a file (active render or pending download), cancelling any scheduled eviction.\r\n * @param fileId file index\r\n */\r\n private _acquireFileRef(fileId: number): void {\r\n const refs = (this._fileRefs.get(fileId) ?? 0) + 1;\r\n this._fileRefs.set(fileId, refs);\r\n if (refs === 1) {\r\n // Referenced again before its eviction cooldown elapsed: keep it resident.\r\n this._residency?.cancelEviction(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Records that a node needs a not-yet-decoded file, bumping its reference count and queueing the decode.\r\n * @param fileId file index the node now targets\r\n */\r\n private _acquirePendingFile(fileId: number): void {\r\n this._acquireFileRef(fileId);\r\n this._enqueueDecode(fileId);\r\n }\r\n\r\n /**\r\n * Releases a node's reference to a file. When the last reference is dropped: a decoded file is scheduled\r\n * for eviction (when streaming under a budget), and a still-downloading file has its queued decode dropped\r\n * and any in-flight download cancelled.\r\n * @param fileId file index the node no longer references\r\n */\r\n private _releaseFileRef(fileId: number): void {\r\n const refs = (this._fileRefs.get(fileId) ?? 0) - 1;\r\n if (refs > 0) {\r\n this._fileRefs.set(fileId, refs);\r\n return;\r\n }\r\n this._fileRefs.delete(fileId);\r\n if (this._decodedFiles.has(fileId)) {\r\n // No node renders it anymore: schedule eviction (only when streaming under a budget).\r\n if (this._evictionEnabled) {\r\n this._residency?.scheduleEviction(fileId);\r\n }\r\n return;\r\n }\r\n // Still downloading/queued: drop the queued decode and cancel any in-flight download.\r\n const queueIndex = this._decodeQueue.indexOf(fileId);\r\n if (queueIndex !== -1) {\r\n this._decodeQueue.splice(queueIndex, 1);\r\n }\r\n if (this._loadingFiles.has(fileId)) {\r\n // Flag the in-flight decode to bail at its next checkpoint and cancel its image downloads.\r\n this._cancelledDecodes.add(fileId);\r\n this._downloadManager.cancelGroup(fileId);\r\n }\r\n }\r\n\r\n /**\r\n * Per-frame LOD streaming loop. Ticks cooldowns and pumps the decode queue every frame, and runs the\r\n * cheap per-node frustum test every frame so the off-screen LOD bias tracks camera rotation. The LOD\r\n * re-evaluation is throttled to at most every {@link _lodUpdateInterval} frames once the camera has\r\n * translated far enough, but also runs immediately whenever a node enters/leaves the frustum (so its\r\n * detail upgrades/downgrades promptly) or a cap change forces it. Active ranges rebuild on any LOD change.\r\n */\r\n private _onLodFrame(): void {\r\n if (this._disposed || !this._baseLayerReady) {\r\n return;\r\n }\r\n for (const node of this._leafNodes) {\r\n if (node.lodCooldown && node.lodCooldown > 0) {\r\n node.lodCooldown--;\r\n }\r\n }\r\n // Tick eviction cooldowns: unreferenced files are freed once their cooldown elapses (budgeted streaming).\r\n if (this._evictionEnabled) {\r\n this._residency?.tick();\r\n }\r\n // In-flight/queued decodes still progress every frame.\r\n this._pumpDecodeQueue();\r\n\r\n // Per-node frustum test runs every frame (cheap) so the off-screen LOD bias tracks camera rotation,\r\n // not just the translation that gates the throttled LOD re-evaluation below.\r\n const frustumChanged = this._updateNodeFrustum();\r\n\r\n let runLodEval = this._forceLodUpdate || frustumChanged;\r\n if (!runLodEval && ++this._framesSinceLodUpdate >= this._lodUpdateInterval) {\r\n const camera = this._scene.activeCamera;\r\n const threshold = this._lodUpdateDistance;\r\n if (!camera || Vector3.DistanceSquared(camera.globalPosition, this._lastLodCamPos) >= threshold * threshold) {\r\n if (camera) {\r\n this._lastLodCamPos.copyFrom(camera.globalPosition);\r\n }\r\n runLodEval = true;\r\n }\r\n }\r\n\r\n if (runLodEval) {\r\n this._forceLodUpdate = false;\r\n this._framesSinceLodUpdate = 0;\r\n this.evaluateOptimalLods(this._scene.activeCamera);\r\n this._computeTargetLevels();\r\n if (this._applyDesiredLods()) {\r\n this._refreshActiveRanges();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Updates each leaf node's {@link ISOGLODNode.inFrustum} flag from a per-node frustum test against the\r\n * active camera. When {@link frustumCulling} is disabled (or there is no camera) every node is marked\r\n * in-frustum. Bounds are static (from the LOD tree), so flags are valid for all nodes regardless of\r\n * decode state. Returns true when any node's in-frustum state changed (so the LOD bias must be re-applied).\r\n * @returns whether any node's in-frustum state changed\r\n */\r\n private _updateNodeFrustum(): boolean {\r\n const camera = this._scene.activeCamera;\r\n let changed = false;\r\n\r\n if (!this._frustumCulling || !camera) {\r\n for (const node of this._leafNodes) {\r\n if (node.inFrustum === false) {\r\n node.inFrustum = true;\r\n changed = true;\r\n }\r\n }\r\n return changed;\r\n }\r\n\r\n // World-space frustum planes from the current view-projection, tested against each node's world AABB.\r\n // force=false uses the renderId/sync fast-path (still recomputes when the transform actually changed),\r\n // avoiding a full world-matrix recompute every frame for the per-node frustum test.\r\n const world = this.computeWorldMatrix(false);\r\n camera.getViewMatrix().multiplyToRef(camera.getProjectionMatrix(), this._cullViewProj);\r\n Frustum.GetPlanesToRef(this._cullViewProj, this._frustumPlanes);\r\n\r\n for (const node of this._leafNodes) {\r\n node.cullBounds!.update(world);\r\n const inFrustum = node.cullBounds!.isInFrustum(this._frustumPlanes);\r\n if (inFrustum !== node.inFrustum) {\r\n node.inFrustum = inFrustum;\r\n changed = true;\r\n }\r\n }\r\n return changed;\r\n }\r\n\r\n /**\r\n * Reads the splat count from SOG metadata.\r\n * @param data SOG metadata\r\n * @returns the splat count\r\n */\r\n private static _GetSplatCount(data: SOGRootData): number {\r\n return data.count ?? (Array.isArray(data.means.shape) ? data.means.shape[0] : 0);\r\n }\r\n\r\n /**\r\n * Disposes all GPU source textures of a SOG pack (they are only needed for the one decode pass).\r\n * @param pack the SOG texture pack\r\n */\r\n private static _DisposePack(pack: ISogTexturePack): void {\r\n pack.meansTextureL.dispose();\r\n pack.meansTextureU.dispose();\r\n pack.scalesTexture.dispose();\r\n pack.quatsTexture.dispose();\r\n pack.sh0Texture.dispose();\r\n pack.shCentroidsTexture?.dispose();\r\n pack.shLabelsTexture?.dispose();\r\n pack.codebookTexture?.dispose();\r\n }\r\n\r\n /**\r\n * Expands the running splat-center bounds with a newly decoded file's centers and updates the\r\n * mesh bounding info so the GS is correctly frustum-culled and pickable.\r\n * @param positions stride-4 splat centers for the new file\r\n * @param count number of splats\r\n */\r\n private _updateBounds(positions: Float32Array, count: number): void {\r\n const min = this._boundsMin;\r\n const max = this._boundsMax;\r\n for (let i = 0; i < count; i++) {\r\n const x = positions[i * 4 + 0];\r\n const y = positions[i * 4 + 1];\r\n const z = positions[i * 4 + 2];\r\n min.minimizeInPlaceFromFloats(x, y, z);\r\n max.maximizeInPlaceFromFloats(x, y, z);\r\n }\r\n this.setBoundingInfo(new BoundingInfo(min, max));\r\n }\r\n\r\n /**\r\n * Rebuilds the active interval set from the environment plus each node's currently-selected LOD entry,\r\n * coalesces adjacent ranges, and pushes the result to the sort worker.\r\n */\r\n private _refreshActiveRanges(): void {\r\n const ranges: IGaussianSplattingSplatRange[] = [];\r\n\r\n if (this._environmentRange) {\r\n ranges.push({ offset: this._environmentRange.offset, count: this._environmentRange.count });\r\n }\r\n\r\n for (const node of this._leafNodes) {\r\n if (node.activeLod === undefined) {\r\n continue;\r\n }\r\n const entry = node.lods![String(node.activeLod)];\r\n if (!entry) {\r\n continue;\r\n }\r\n const base = this._residency?.offset(entry.file);\r\n if (base === undefined) {\r\n continue;\r\n }\r\n ranges.push({ offset: base + entry.offset, count: entry.count });\r\n }\r\n\r\n this.setSplatIndexRanges(GaussianSplattingStream._CoalesceRanges(ranges));\r\n }\r\n\r\n /**\r\n * Sorts and merges adjacent/overlapping ranges to keep the interval list compact.\r\n * @param ranges raw ranges\r\n * @returns coalesced ranges\r\n */\r\n private static _CoalesceRanges(ranges: IGaussianSplattingSplatRange[]): IGaussianSplattingSplatRange[] {\r\n if (ranges.length <= 1) {\r\n return ranges;\r\n }\r\n const sorted = ranges.slice().sort((a, b) => a.offset - b.offset);\r\n const merged: IGaussianSplattingSplatRange[] = [{ offset: sorted[0].offset, count: sorted[0].count }];\r\n for (let i = 1; i < sorted.length; i++) {\r\n const last = merged[merged.length - 1];\r\n const range = sorted[i];\r\n const lastEnd = last.offset + last.count;\r\n if (range.offset <= lastEnd) {\r\n const end = Math.max(lastEnd, range.offset + range.count);\r\n last.count = end - last.offset;\r\n } else {\r\n merged.push({ offset: range.offset, count: range.count });\r\n }\r\n }\r\n return merged;\r\n }\r\n\r\n /**\r\n * Unzips a `.sog` bundle into a name -> bytes map, loading fflate on demand.\r\n * @param data zipped bytes\r\n * @returns map of entry name to bytes\r\n */\r\n private async _unzipAsync(data: Uint8Array): Promise<Map<string, Uint8Array>> {\r\n let fflateModule = this._streamOptions.fflate;\r\n if (!fflateModule) {\r\n if (typeof (window as any).fflate === \"undefined\") {\r\n await Tools.LoadScriptAsync(this._streamOptions.deflateURL ?? \"https://unpkg.com/fflate/umd/index.js\");\r\n }\r\n fflateModule = (window as any).fflate;\r\n }\r\n\r\n const unzipped = fflateModule.unzipSync(data) as Record<string, Uint8Array>;\r\n const files = new Map<string, Uint8Array>();\r\n for (const [name, content] of Object.entries(unzipped)) {\r\n files.set(name, content);\r\n }\r\n return files;\r\n }\r\n}\r\n"]}
|