@babylonjs/viewer 7.42.0 → 7.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (607) hide show
  1. package/assets/photoStudio.env +0 -0
  2. package/dist/babylon-viewer.esm.js +2 -0
  3. package/dist/babylon-viewer.esm.js.map +1 -0
  4. package/dist/babylon-viewer.esm.min.js +2 -0
  5. package/dist/babylon-viewer.esm.min.js.map +1 -0
  6. package/dist/chunks/EXT_lights_ies-D-oSSifC.esm.min.js +2 -0
  7. package/dist/chunks/EXT_lights_ies-D-oSSifC.esm.min.js.map +1 -0
  8. package/dist/chunks/EXT_lights_ies-DJJLktlG.esm.js +84 -0
  9. package/dist/chunks/EXT_lights_ies-DJJLktlG.esm.js.map +1 -0
  10. package/dist/chunks/EXT_lights_image_based-Bm1EdHWU.esm.js +171 -0
  11. package/dist/chunks/EXT_lights_image_based-Bm1EdHWU.esm.js.map +1 -0
  12. package/dist/chunks/EXT_lights_image_based-CPP95suP.esm.min.js +2 -0
  13. package/dist/chunks/EXT_lights_image_based-CPP95suP.esm.min.js.map +1 -0
  14. package/dist/chunks/EXT_mesh_gpu_instancing-DuFNjp-b.esm.js +86 -0
  15. package/dist/chunks/EXT_mesh_gpu_instancing-DuFNjp-b.esm.js.map +1 -0
  16. package/dist/chunks/EXT_mesh_gpu_instancing-RXBAS2yg.esm.min.js +2 -0
  17. package/dist/chunks/EXT_mesh_gpu_instancing-RXBAS2yg.esm.min.js.map +1 -0
  18. package/dist/chunks/EXT_meshopt_compression-B_tol2Sa.esm.min.js +2 -0
  19. package/dist/chunks/EXT_meshopt_compression-B_tol2Sa.esm.min.js.map +1 -0
  20. package/dist/chunks/EXT_meshopt_compression-Rai3-_W3.esm.js +134 -0
  21. package/dist/chunks/EXT_meshopt_compression-Rai3-_W3.esm.js.map +1 -0
  22. package/dist/chunks/EXT_texture_avif-D3PbSGsk.esm.js +44 -0
  23. package/dist/chunks/EXT_texture_avif-D3PbSGsk.esm.js.map +1 -0
  24. package/dist/chunks/EXT_texture_avif-DB96e8gK.esm.min.js +2 -0
  25. package/dist/chunks/EXT_texture_avif-DB96e8gK.esm.min.js.map +1 -0
  26. package/dist/chunks/EXT_texture_webp-BrAdNUVI.esm.min.js +2 -0
  27. package/dist/chunks/EXT_texture_webp-BrAdNUVI.esm.min.js.map +1 -0
  28. package/dist/chunks/EXT_texture_webp-BsSdw4hb.esm.js +43 -0
  29. package/dist/chunks/EXT_texture_webp-BsSdw4hb.esm.js.map +1 -0
  30. package/dist/chunks/ExtrasAsMetadata-CvpNkVJm.esm.js +64 -0
  31. package/dist/chunks/ExtrasAsMetadata-CvpNkVJm.esm.js.map +1 -0
  32. package/dist/chunks/ExtrasAsMetadata-CwSGAnId.esm.min.js +2 -0
  33. package/dist/chunks/ExtrasAsMetadata-CwSGAnId.esm.min.js.map +1 -0
  34. package/dist/chunks/KHR_animation_pointer-B29-7REN.esm.js +352 -0
  35. package/dist/chunks/KHR_animation_pointer-B29-7REN.esm.js.map +1 -0
  36. package/dist/chunks/KHR_animation_pointer-DXhkj5r0.esm.min.js +2 -0
  37. package/dist/chunks/KHR_animation_pointer-DXhkj5r0.esm.min.js.map +1 -0
  38. package/dist/chunks/KHR_draco_mesh_compression-4y3oU3vs.esm.js +611 -0
  39. package/dist/chunks/KHR_draco_mesh_compression-4y3oU3vs.esm.js.map +1 -0
  40. package/dist/chunks/KHR_draco_mesh_compression-OUEmCF9O.esm.min.js +2 -0
  41. package/dist/chunks/KHR_draco_mesh_compression-OUEmCF9O.esm.min.js.map +1 -0
  42. package/dist/chunks/KHR_interactivity-DmxwZO-B.esm.min.js +2 -0
  43. package/dist/chunks/KHR_interactivity-DmxwZO-B.esm.min.js.map +1 -0
  44. package/dist/chunks/KHR_interactivity-Nql0vbRS.esm.js +4033 -0
  45. package/dist/chunks/KHR_interactivity-Nql0vbRS.esm.js.map +1 -0
  46. package/dist/chunks/KHR_lights_punctual-BuxTRJTD.esm.min.js +2 -0
  47. package/dist/chunks/KHR_lights_punctual-BuxTRJTD.esm.min.js.map +1 -0
  48. package/dist/chunks/KHR_lights_punctual-DT1Tmy49.esm.js +581 -0
  49. package/dist/chunks/KHR_lights_punctual-DT1Tmy49.esm.js.map +1 -0
  50. package/dist/chunks/KHR_materials_anisotropy-CkyM8JSq.esm.min.js +2 -0
  51. package/dist/chunks/KHR_materials_anisotropy-CkyM8JSq.esm.min.js.map +1 -0
  52. package/dist/chunks/KHR_materials_anisotropy-rMp1ahNa.esm.js +65 -0
  53. package/dist/chunks/KHR_materials_anisotropy-rMp1ahNa.esm.js.map +1 -0
  54. package/dist/chunks/KHR_materials_clearcoat-Dw7bP6zs.esm.js +96 -0
  55. package/dist/chunks/KHR_materials_clearcoat-Dw7bP6zs.esm.js.map +1 -0
  56. package/dist/chunks/KHR_materials_clearcoat-c_8cDReS.esm.min.js +2 -0
  57. package/dist/chunks/KHR_materials_clearcoat-c_8cDReS.esm.min.js.map +1 -0
  58. package/dist/chunks/KHR_materials_diffuse_transmission-CXn0MUer.esm.min.js +2 -0
  59. package/dist/chunks/KHR_materials_diffuse_transmission-CXn0MUer.esm.min.js.map +1 -0
  60. package/dist/chunks/KHR_materials_diffuse_transmission-CsMJW09v.esm.js +97 -0
  61. package/dist/chunks/KHR_materials_diffuse_transmission-CsMJW09v.esm.js.map +1 -0
  62. package/dist/chunks/KHR_materials_dispersion-BDCbGsPA.esm.js +62 -0
  63. package/dist/chunks/KHR_materials_dispersion-BDCbGsPA.esm.js.map +1 -0
  64. package/dist/chunks/KHR_materials_dispersion-D2yTJOjM.esm.min.js +2 -0
  65. package/dist/chunks/KHR_materials_dispersion-D2yTJOjM.esm.min.js.map +1 -0
  66. package/dist/chunks/KHR_materials_emissive_strength-Tz0C88U3.esm.min.js +2 -0
  67. package/dist/chunks/KHR_materials_emissive_strength-Tz0C88U3.esm.min.js.map +1 -0
  68. package/dist/chunks/KHR_materials_emissive_strength-jQMxZKq5.esm.js +55 -0
  69. package/dist/chunks/KHR_materials_emissive_strength-jQMxZKq5.esm.js.map +1 -0
  70. package/dist/chunks/KHR_materials_ior-2zUX8jy7.esm.js +64 -0
  71. package/dist/chunks/KHR_materials_ior-2zUX8jy7.esm.js.map +1 -0
  72. package/dist/chunks/KHR_materials_ior-sCAKuvLs.esm.min.js +2 -0
  73. package/dist/chunks/KHR_materials_ior-sCAKuvLs.esm.min.js.map +1 -0
  74. package/dist/chunks/KHR_materials_iridescence-CTk6lY7i.esm.min.js +2 -0
  75. package/dist/chunks/KHR_materials_iridescence-CTk6lY7i.esm.min.js.map +1 -0
  76. package/dist/chunks/KHR_materials_iridescence-DxBAsUzR.esm.js +72 -0
  77. package/dist/chunks/KHR_materials_iridescence-DxBAsUzR.esm.js.map +1 -0
  78. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-BgkZXf0x.esm.js +81 -0
  79. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-BgkZXf0x.esm.js.map +1 -0
  80. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-Dq7WTMdT.esm.min.js +2 -0
  81. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-Dq7WTMdT.esm.min.js.map +1 -0
  82. package/dist/chunks/KHR_materials_sheen-35UGLw0C.esm.js +85 -0
  83. package/dist/chunks/KHR_materials_sheen-35UGLw0C.esm.js.map +1 -0
  84. package/dist/chunks/KHR_materials_sheen-DQ6C57Dt.esm.min.js +2 -0
  85. package/dist/chunks/KHR_materials_sheen-DQ6C57Dt.esm.min.js.map +1 -0
  86. package/dist/chunks/KHR_materials_specular-BPk7EQUD.esm.min.js +2 -0
  87. package/dist/chunks/KHR_materials_specular-BPk7EQUD.esm.min.js.map +1 -0
  88. package/dist/chunks/KHR_materials_specular-DrL3M38a.esm.js +75 -0
  89. package/dist/chunks/KHR_materials_specular-DrL3M38a.esm.js.map +1 -0
  90. package/dist/chunks/KHR_materials_transmission-3olkVCcW.esm.min.js +2 -0
  91. package/dist/chunks/KHR_materials_transmission-3olkVCcW.esm.min.js.map +1 -0
  92. package/dist/chunks/KHR_materials_transmission-BpjfU0Rf.esm.js +307 -0
  93. package/dist/chunks/KHR_materials_transmission-BpjfU0Rf.esm.js.map +1 -0
  94. package/dist/chunks/KHR_materials_unlit-BK4Bp8qS.esm.min.js +2 -0
  95. package/dist/chunks/KHR_materials_unlit-BK4Bp8qS.esm.min.js.map +1 -0
  96. package/dist/chunks/KHR_materials_unlit-DqWkeMIs.esm.js +74 -0
  97. package/dist/chunks/KHR_materials_unlit-DqWkeMIs.esm.js.map +1 -0
  98. package/dist/chunks/KHR_materials_variants-C8EH6z5q.esm.js +262 -0
  99. package/dist/chunks/KHR_materials_variants-C8EH6z5q.esm.js.map +1 -0
  100. package/dist/chunks/KHR_materials_variants-U_7nHGWs.esm.min.js +2 -0
  101. package/dist/chunks/KHR_materials_variants-U_7nHGWs.esm.min.js.map +1 -0
  102. package/dist/chunks/KHR_materials_volume-QCITeTgE.esm.min.js +2 -0
  103. package/dist/chunks/KHR_materials_volume-QCITeTgE.esm.min.js.map +1 -0
  104. package/dist/chunks/KHR_materials_volume-eXcEVVpW.esm.js +87 -0
  105. package/dist/chunks/KHR_materials_volume-eXcEVVpW.esm.js.map +1 -0
  106. package/dist/chunks/KHR_mesh_quantization-BjqgHT7P.esm.js +26 -0
  107. package/dist/chunks/KHR_mesh_quantization-BjqgHT7P.esm.js.map +1 -0
  108. package/dist/chunks/KHR_mesh_quantization-CEo8-_n9.esm.min.js +2 -0
  109. package/dist/chunks/KHR_mesh_quantization-CEo8-_n9.esm.min.js.map +1 -0
  110. package/dist/chunks/KHR_node_hoverability-CLakAM7o.esm.min.js +2 -0
  111. package/dist/chunks/KHR_node_hoverability-CLakAM7o.esm.min.js.map +1 -0
  112. package/dist/chunks/KHR_node_hoverability-XR4H2sEJ.esm.js +39 -0
  113. package/dist/chunks/KHR_node_hoverability-XR4H2sEJ.esm.js.map +1 -0
  114. package/dist/chunks/KHR_node_visibility-D5-Uq040.esm.js +46 -0
  115. package/dist/chunks/KHR_node_visibility-D5-Uq040.esm.js.map +1 -0
  116. package/dist/chunks/KHR_node_visibility-JpHMpDZy.esm.min.js +2 -0
  117. package/dist/chunks/KHR_node_visibility-JpHMpDZy.esm.min.js.map +1 -0
  118. package/dist/chunks/KHR_texture_basisu-CK096eX9.esm.min.js +2 -0
  119. package/dist/chunks/KHR_texture_basisu-CK096eX9.esm.min.js.map +1 -0
  120. package/dist/chunks/KHR_texture_basisu-JvEhdHQJ.esm.js +43 -0
  121. package/dist/chunks/KHR_texture_basisu-JvEhdHQJ.esm.js.map +1 -0
  122. package/dist/chunks/KHR_texture_transform-ASnRyeyf.esm.js +63 -0
  123. package/dist/chunks/KHR_texture_transform-ASnRyeyf.esm.js.map +1 -0
  124. package/dist/chunks/KHR_texture_transform-Ci769L7F.esm.min.js +2 -0
  125. package/dist/chunks/KHR_texture_transform-Ci769L7F.esm.min.js.map +1 -0
  126. package/dist/chunks/KHR_xmp_json_ld-Cf0IphHD.esm.min.js +2 -0
  127. package/dist/chunks/KHR_xmp_json_ld-Cf0IphHD.esm.min.js.map +1 -0
  128. package/dist/chunks/KHR_xmp_json_ld-ZytUWg-l.esm.js +51 -0
  129. package/dist/chunks/KHR_xmp_json_ld-ZytUWg-l.esm.js.map +1 -0
  130. package/dist/chunks/MSFT_audio_emitter-BjoYL7lC.esm.min.js +2 -0
  131. package/dist/chunks/MSFT_audio_emitter-BjoYL7lC.esm.min.js.map +1 -0
  132. package/dist/chunks/MSFT_audio_emitter-Di8nqSDi.esm.js +2200 -0
  133. package/dist/chunks/MSFT_audio_emitter-Di8nqSDi.esm.js.map +1 -0
  134. package/dist/chunks/MSFT_lod-BMUlo5OU.esm.js +337 -0
  135. package/dist/chunks/MSFT_lod-BMUlo5OU.esm.js.map +1 -0
  136. package/dist/chunks/MSFT_lod-OG5_k4mO.esm.min.js +2 -0
  137. package/dist/chunks/MSFT_lod-OG5_k4mO.esm.min.js.map +1 -0
  138. package/dist/chunks/MSFT_minecraftMesh-CA9_SnEQ.esm.js +46 -0
  139. package/dist/chunks/MSFT_minecraftMesh-CA9_SnEQ.esm.js.map +1 -0
  140. package/dist/chunks/MSFT_minecraftMesh-DA-GfwSb.esm.min.js +2 -0
  141. package/dist/chunks/MSFT_minecraftMesh-DA-GfwSb.esm.min.js.map +1 -0
  142. package/dist/chunks/MSFT_sRGBFactors-BpXptZ3D.esm.js +47 -0
  143. package/dist/chunks/MSFT_sRGBFactors-BpXptZ3D.esm.js.map +1 -0
  144. package/dist/chunks/MSFT_sRGBFactors-COm0y2eh.esm.min.js +2 -0
  145. package/dist/chunks/MSFT_sRGBFactors-COm0y2eh.esm.min.js.map +1 -0
  146. package/dist/chunks/animationGroup-DeyI1KVN.esm.min.js +2 -0
  147. package/dist/chunks/animationGroup-DeyI1KVN.esm.min.js.map +1 -0
  148. package/dist/chunks/animationGroup-DrsZkXQW.esm.js +2482 -0
  149. package/dist/chunks/animationGroup-DrsZkXQW.esm.js.map +1 -0
  150. package/dist/chunks/assetContainer-Cx2Wvxkg.esm.js +1786 -0
  151. package/dist/chunks/assetContainer-Cx2Wvxkg.esm.js.map +1 -0
  152. package/dist/chunks/assetContainer-l3mez3br.esm.min.js +2 -0
  153. package/dist/chunks/assetContainer-l3mez3br.esm.min.js.map +1 -0
  154. package/dist/chunks/bakedVertexAnimation-CwJYQylG.esm.js +114 -0
  155. package/dist/chunks/bakedVertexAnimation-CwJYQylG.esm.js.map +1 -0
  156. package/dist/chunks/bakedVertexAnimation-D5PLG8Vz.esm.min.js +2 -0
  157. package/dist/chunks/bakedVertexAnimation-D5PLG8Vz.esm.min.js.map +1 -0
  158. package/dist/chunks/basisTextureLoader-BNH-2Zvb.esm.min.js +2 -0
  159. package/dist/chunks/basisTextureLoader-BNH-2Zvb.esm.min.js.map +1 -0
  160. package/dist/chunks/basisTextureLoader-JW5tEMV8.esm.js +600 -0
  161. package/dist/chunks/basisTextureLoader-JW5tEMV8.esm.js.map +1 -0
  162. package/dist/chunks/dds-B1kYpKg4.esm.js +540 -0
  163. package/dist/chunks/dds-B1kYpKg4.esm.js.map +1 -0
  164. package/dist/chunks/dds-BIaKvdM8.esm.min.js +2 -0
  165. package/dist/chunks/dds-BIaKvdM8.esm.min.js.map +1 -0
  166. package/dist/chunks/ddsTextureLoader-DHdy4-WN.esm.js +88 -0
  167. package/dist/chunks/ddsTextureLoader-DHdy4-WN.esm.js.map +1 -0
  168. package/dist/chunks/ddsTextureLoader-DQvH8BPG.esm.min.js +2 -0
  169. package/dist/chunks/ddsTextureLoader-DQvH8BPG.esm.min.js.map +1 -0
  170. package/dist/chunks/decalFragment-B07XA08h.esm.min.js +2 -0
  171. package/dist/chunks/decalFragment-B07XA08h.esm.min.js.map +1 -0
  172. package/dist/chunks/decalFragment-ClGzoop1.esm.js +18 -0
  173. package/dist/chunks/decalFragment-ClGzoop1.esm.js.map +1 -0
  174. package/dist/chunks/default.fragment-CAC3-eH5.esm.min.js +2 -0
  175. package/dist/chunks/default.fragment-CAC3-eH5.esm.min.js.map +1 -0
  176. package/dist/chunks/default.fragment-Cr0qnYU0.esm.js +446 -0
  177. package/dist/chunks/default.fragment-Cr0qnYU0.esm.js.map +1 -0
  178. package/dist/chunks/default.fragment-DJgifW8z.esm.min.js +2 -0
  179. package/dist/chunks/default.fragment-DJgifW8z.esm.min.js.map +1 -0
  180. package/dist/chunks/default.fragment-uFTw5k6Z.esm.js +515 -0
  181. package/dist/chunks/default.fragment-uFTw5k6Z.esm.js.map +1 -0
  182. package/dist/chunks/default.vertex-B_u-vpoR.esm.js +211 -0
  183. package/dist/chunks/default.vertex-B_u-vpoR.esm.js.map +1 -0
  184. package/dist/chunks/default.vertex-Bo-YeuPk.esm.min.js +2 -0
  185. package/dist/chunks/default.vertex-Bo-YeuPk.esm.min.js.map +1 -0
  186. package/dist/chunks/default.vertex-C6LMYeLT.esm.min.js +2 -0
  187. package/dist/chunks/default.vertex-C6LMYeLT.esm.min.js.map +1 -0
  188. package/dist/chunks/default.vertex-CzuD5tIE.esm.js +190 -0
  189. package/dist/chunks/default.vertex-CzuD5tIE.esm.js.map +1 -0
  190. package/dist/chunks/defaultUboDeclaration-BSYuerQe.esm.min.js +2 -0
  191. package/dist/chunks/defaultUboDeclaration-BSYuerQe.esm.min.js.map +1 -0
  192. package/dist/chunks/defaultUboDeclaration-CQJaKPLM.esm.min.js +2 -0
  193. package/dist/chunks/defaultUboDeclaration-CQJaKPLM.esm.min.js.map +1 -0
  194. package/dist/chunks/defaultUboDeclaration-DzRt1iTO.esm.js +13 -0
  195. package/dist/chunks/defaultUboDeclaration-DzRt1iTO.esm.js.map +1 -0
  196. package/dist/chunks/defaultUboDeclaration-DzpAmCf1.esm.js +15 -0
  197. package/dist/chunks/defaultUboDeclaration-DzpAmCf1.esm.js.map +1 -0
  198. package/dist/chunks/dumpTools-JfWNUHd1.esm.js +200 -0
  199. package/dist/chunks/dumpTools-JfWNUHd1.esm.js.map +1 -0
  200. package/dist/chunks/dumpTools-MGQM1tV4.esm.min.js +2 -0
  201. package/dist/chunks/dumpTools-MGQM1tV4.esm.min.js.map +1 -0
  202. package/dist/chunks/envTextureLoader-CoD9RkFy.esm.js +64 -0
  203. package/dist/chunks/envTextureLoader-CoD9RkFy.esm.js.map +1 -0
  204. package/dist/chunks/envTextureLoader-_huqF4Iu.esm.min.js +2 -0
  205. package/dist/chunks/envTextureLoader-_huqF4Iu.esm.min.js.map +1 -0
  206. package/dist/chunks/environmentTextureTools-BFBrSyc_.esm.min.js +2 -0
  207. package/dist/chunks/environmentTextureTools-BFBrSyc_.esm.min.js.map +1 -0
  208. package/dist/chunks/environmentTextureTools-DMKf2lIW.esm.js +382 -0
  209. package/dist/chunks/environmentTextureTools-DMKf2lIW.esm.js.map +1 -0
  210. package/dist/chunks/exrTextureLoader-BkuwS0XF.esm.min.js +2 -0
  211. package/dist/chunks/exrTextureLoader-BkuwS0XF.esm.min.js.map +1 -0
  212. package/dist/chunks/exrTextureLoader-DxOSgB3m.esm.js +1683 -0
  213. package/dist/chunks/exrTextureLoader-DxOSgB3m.esm.js.map +1 -0
  214. package/dist/chunks/fogFragment-CdyzhyDy.esm.min.js +2 -0
  215. package/dist/chunks/fogFragment-CdyzhyDy.esm.min.js.map +1 -0
  216. package/dist/chunks/fogFragment-Ct0roave.esm.js +101 -0
  217. package/dist/chunks/fogFragment-Ct0roave.esm.js.map +1 -0
  218. package/dist/chunks/fogFragment-DjORBY8D.esm.min.js +2 -0
  219. package/dist/chunks/fogFragment-DjORBY8D.esm.min.js.map +1 -0
  220. package/dist/chunks/fogFragment-DwdRh83Z.esm.js +102 -0
  221. package/dist/chunks/fogFragment-DwdRh83Z.esm.js.map +1 -0
  222. package/dist/chunks/fresnelFunction-CuDZqiSs.esm.js +12 -0
  223. package/dist/chunks/fresnelFunction-CuDZqiSs.esm.js.map +1 -0
  224. package/dist/chunks/fresnelFunction-zYzL693r.esm.min.js +2 -0
  225. package/dist/chunks/fresnelFunction-zYzL693r.esm.min.js.map +1 -0
  226. package/dist/chunks/glTFLoader-CKBe9bFc.esm.js +7735 -0
  227. package/dist/chunks/glTFLoader-CKBe9bFc.esm.js.map +1 -0
  228. package/dist/chunks/glTFLoader-HrDvovFY.esm.min.js +2 -0
  229. package/dist/chunks/glTFLoader-HrDvovFY.esm.min.js.map +1 -0
  230. package/dist/chunks/glTFLoaderAnimation-D-y1xZvo.esm.min.js +2 -0
  231. package/dist/chunks/glTFLoaderAnimation-D-y1xZvo.esm.min.js.map +1 -0
  232. package/dist/chunks/glTFLoaderAnimation-D57wBZJj.esm.js +77 -0
  233. package/dist/chunks/glTFLoaderAnimation-D57wBZJj.esm.js.map +1 -0
  234. package/dist/chunks/gltfPathToObjectConverter-Dyt_Y9jE.esm.min.js +2 -0
  235. package/dist/chunks/gltfPathToObjectConverter-Dyt_Y9jE.esm.min.js.map +1 -0
  236. package/dist/chunks/gltfPathToObjectConverter-GcUmfOyo.esm.js +67 -0
  237. package/dist/chunks/gltfPathToObjectConverter-GcUmfOyo.esm.js.map +1 -0
  238. package/dist/chunks/harmonicsFunctions-8p1AKl3B.esm.js +35 -0
  239. package/dist/chunks/harmonicsFunctions-8p1AKl3B.esm.js.map +1 -0
  240. package/dist/chunks/harmonicsFunctions-C3M4g6jE.esm.min.js +2 -0
  241. package/dist/chunks/harmonicsFunctions-C3M4g6jE.esm.min.js.map +1 -0
  242. package/dist/chunks/harmonicsFunctions-CoiTSsVa.esm.min.js +2 -0
  243. package/dist/chunks/harmonicsFunctions-CoiTSsVa.esm.min.js.map +1 -0
  244. package/dist/chunks/harmonicsFunctions-HT06ZoZl.esm.js +34 -0
  245. package/dist/chunks/harmonicsFunctions-HT06ZoZl.esm.js.map +1 -0
  246. package/dist/chunks/hdrTextureLoader-B0kksMif.esm.js +253 -0
  247. package/dist/chunks/hdrTextureLoader-B0kksMif.esm.js.map +1 -0
  248. package/dist/chunks/hdrTextureLoader-CnTSpduj.esm.min.js +2 -0
  249. package/dist/chunks/hdrTextureLoader-CnTSpduj.esm.min.js.map +1 -0
  250. package/dist/chunks/helperFunctions-Bq5KkNmT.esm.js +83 -0
  251. package/dist/chunks/helperFunctions-Bq5KkNmT.esm.js.map +1 -0
  252. package/dist/chunks/helperFunctions-DauLsm9X.esm.min.js +2 -0
  253. package/dist/chunks/helperFunctions-DauLsm9X.esm.min.js.map +1 -0
  254. package/dist/chunks/helperFunctions-Du6Zsfhy.esm.min.js +2 -0
  255. package/dist/chunks/helperFunctions-Du6Zsfhy.esm.min.js.map +1 -0
  256. package/dist/chunks/helperFunctions-oDSGYqJN.esm.js +110 -0
  257. package/dist/chunks/helperFunctions-oDSGYqJN.esm.js.map +1 -0
  258. package/dist/chunks/iesTextureLoader-DdRr77cj.esm.js +189 -0
  259. package/dist/chunks/iesTextureLoader-DdRr77cj.esm.js.map +1 -0
  260. package/dist/chunks/iesTextureLoader-DkEckxVj.esm.min.js +2 -0
  261. package/dist/chunks/iesTextureLoader-DkEckxVj.esm.min.js.map +1 -0
  262. package/dist/chunks/index-D46Rc8Qa.esm.js +82819 -0
  263. package/dist/chunks/index-D46Rc8Qa.esm.js.map +1 -0
  264. package/dist/chunks/index-r5IGv8fd.esm.min.js +57 -0
  265. package/dist/chunks/index-r5IGv8fd.esm.min.js.map +1 -0
  266. package/dist/chunks/ktxTextureLoader-CImJ68er.esm.min.js +2 -0
  267. package/dist/chunks/ktxTextureLoader-CImJ68er.esm.min.js.map +1 -0
  268. package/dist/chunks/ktxTextureLoader-CvQzBtnz.esm.js +814 -0
  269. package/dist/chunks/ktxTextureLoader-CvQzBtnz.esm.js.map +1 -0
  270. package/dist/chunks/logDepthDeclaration-BNJ_qeEv.esm.min.js +2 -0
  271. package/dist/chunks/logDepthDeclaration-BNJ_qeEv.esm.min.js.map +1 -0
  272. package/dist/chunks/logDepthDeclaration-Co9yKHfe.esm.js +35 -0
  273. package/dist/chunks/logDepthDeclaration-Co9yKHfe.esm.js.map +1 -0
  274. package/dist/chunks/logDepthDeclaration-DP9tYyv7.esm.min.js +2 -0
  275. package/dist/chunks/logDepthDeclaration-DP9tYyv7.esm.min.js.map +1 -0
  276. package/dist/chunks/logDepthDeclaration-KzS73dPG.esm.js +11 -0
  277. package/dist/chunks/logDepthDeclaration-KzS73dPG.esm.js.map +1 -0
  278. package/dist/chunks/logDepthVertex-BBDSLJJg.esm.js +77 -0
  279. package/dist/chunks/logDepthVertex-BBDSLJJg.esm.js.map +1 -0
  280. package/dist/chunks/logDepthVertex-CHXEv8Hm.esm.min.js +2 -0
  281. package/dist/chunks/logDepthVertex-CHXEv8Hm.esm.min.js.map +1 -0
  282. package/dist/chunks/logDepthVertex-CkCG5UAD.esm.min.js +2 -0
  283. package/dist/chunks/logDepthVertex-CkCG5UAD.esm.min.js.map +1 -0
  284. package/dist/chunks/logDepthVertex-DKTOhgu8.esm.js +81 -0
  285. package/dist/chunks/logDepthVertex-DKTOhgu8.esm.js.map +1 -0
  286. package/dist/chunks/mainUVVaryingDeclaration-BxP2qnf1.esm.js +11 -0
  287. package/dist/chunks/mainUVVaryingDeclaration-BxP2qnf1.esm.js.map +1 -0
  288. package/dist/chunks/mainUVVaryingDeclaration-D-YFWEWb.esm.min.js +2 -0
  289. package/dist/chunks/mainUVVaryingDeclaration-D-YFWEWb.esm.min.js.map +1 -0
  290. package/dist/chunks/mainUVVaryingDeclaration-D5LXIN_s.esm.min.js +2 -0
  291. package/dist/chunks/mainUVVaryingDeclaration-D5LXIN_s.esm.min.js.map +1 -0
  292. package/dist/chunks/mainUVVaryingDeclaration-DBd0Ca2K.esm.js +11 -0
  293. package/dist/chunks/mainUVVaryingDeclaration-DBd0Ca2K.esm.js.map +1 -0
  294. package/dist/chunks/mesh.vertexData.functions-B_pMCAzZ.esm.js +119 -0
  295. package/dist/chunks/mesh.vertexData.functions-B_pMCAzZ.esm.js.map +1 -0
  296. package/dist/chunks/mesh.vertexData.functions-Bo7e6Of9.esm.min.js +2 -0
  297. package/dist/chunks/mesh.vertexData.functions-Bo7e6Of9.esm.min.js.map +1 -0
  298. package/dist/chunks/meshUboDeclaration-D7vtpetW.esm.js +26 -0
  299. package/dist/chunks/meshUboDeclaration-D7vtpetW.esm.js.map +1 -0
  300. package/dist/chunks/meshUboDeclaration-tb8T5asG.esm.min.js +2 -0
  301. package/dist/chunks/meshUboDeclaration-tb8T5asG.esm.min.js.map +1 -0
  302. package/dist/chunks/objFileLoader-B0XaXxyr.esm.min.js +2 -0
  303. package/dist/chunks/objFileLoader-B0XaXxyr.esm.min.js.map +1 -0
  304. package/dist/chunks/objFileLoader-B1MaGxQt.esm.js +1338 -0
  305. package/dist/chunks/objFileLoader-B1MaGxQt.esm.js.map +1 -0
  306. package/dist/chunks/oitFragment-BEKFrqPY.esm.js +1078 -0
  307. package/dist/chunks/oitFragment-BEKFrqPY.esm.js.map +1 -0
  308. package/dist/chunks/oitFragment-CJrbQh0i.esm.min.js +2 -0
  309. package/dist/chunks/oitFragment-CJrbQh0i.esm.min.js.map +1 -0
  310. package/dist/chunks/oitFragment-DCxGblwL.esm.js +1240 -0
  311. package/dist/chunks/oitFragment-DCxGblwL.esm.js.map +1 -0
  312. package/dist/chunks/oitFragment-sZA5tkE3.esm.min.js +2 -0
  313. package/dist/chunks/oitFragment-sZA5tkE3.esm.min.js.map +1 -0
  314. package/dist/chunks/pass.fragment-BYDvFFL5.esm.js +15 -0
  315. package/dist/chunks/pass.fragment-BYDvFFL5.esm.js.map +1 -0
  316. package/dist/chunks/pass.fragment-BgXOqRns.esm.js +15 -0
  317. package/dist/chunks/pass.fragment-BgXOqRns.esm.js.map +1 -0
  318. package/dist/chunks/pass.fragment-DgadxzwS.esm.min.js +2 -0
  319. package/dist/chunks/pass.fragment-DgadxzwS.esm.min.js.map +1 -0
  320. package/dist/chunks/pass.fragment-Dqmp3CRB.esm.min.js +2 -0
  321. package/dist/chunks/pass.fragment-Dqmp3CRB.esm.min.js.map +1 -0
  322. package/dist/chunks/passCube.fragment-07CNLnnq.esm.js +34 -0
  323. package/dist/chunks/passCube.fragment-07CNLnnq.esm.js.map +1 -0
  324. package/dist/chunks/passCube.fragment-4R2Z-LXR.esm.min.js +2 -0
  325. package/dist/chunks/passCube.fragment-4R2Z-LXR.esm.min.js.map +1 -0
  326. package/dist/chunks/passCube.fragment-Aq1scRJ9.esm.js +34 -0
  327. package/dist/chunks/passCube.fragment-Aq1scRJ9.esm.js.map +1 -0
  328. package/dist/chunks/passCube.fragment-DiybDNvK.esm.min.js +2 -0
  329. package/dist/chunks/passCube.fragment-DiybDNvK.esm.min.js.map +1 -0
  330. package/dist/chunks/pbr.fragment-CBb8vd51.esm.min.js +2 -0
  331. package/dist/chunks/pbr.fragment-CBb8vd51.esm.min.js.map +1 -0
  332. package/dist/chunks/pbr.fragment-DSUT21Rk.esm.min.js +2 -0
  333. package/dist/chunks/pbr.fragment-DSUT21Rk.esm.min.js.map +1 -0
  334. package/dist/chunks/pbr.fragment-DmP7eqg7.esm.js +3272 -0
  335. package/dist/chunks/pbr.fragment-DmP7eqg7.esm.js.map +1 -0
  336. package/dist/chunks/pbr.fragment-DzIZJg6m.esm.js +3225 -0
  337. package/dist/chunks/pbr.fragment-DzIZJg6m.esm.js.map +1 -0
  338. package/dist/chunks/pbr.vertex--Lj5Uipt.esm.js +223 -0
  339. package/dist/chunks/pbr.vertex--Lj5Uipt.esm.js.map +1 -0
  340. package/dist/chunks/pbr.vertex-BScRF6wh.esm.min.js +2 -0
  341. package/dist/chunks/pbr.vertex-BScRF6wh.esm.min.js.map +1 -0
  342. package/dist/chunks/pbr.vertex-CZSsnbPf.esm.js +348 -0
  343. package/dist/chunks/pbr.vertex-CZSsnbPf.esm.js.map +1 -0
  344. package/dist/chunks/pbr.vertex-Nho2p99M.esm.min.js +2 -0
  345. package/dist/chunks/pbr.vertex-Nho2p99M.esm.min.js.map +1 -0
  346. package/dist/chunks/postprocess.vertex-B_q6GHTK.esm.js +20 -0
  347. package/dist/chunks/postprocess.vertex-B_q6GHTK.esm.js.map +1 -0
  348. package/dist/chunks/postprocess.vertex-C-ocJcje.esm.min.js +2 -0
  349. package/dist/chunks/postprocess.vertex-C-ocJcje.esm.min.js.map +1 -0
  350. package/dist/chunks/rawTexture-DeYN01jd.esm.min.js +2 -0
  351. package/dist/chunks/rawTexture-DeYN01jd.esm.min.js.map +1 -0
  352. package/dist/chunks/rawTexture-Dh4jdTlv.esm.js +191 -0
  353. package/dist/chunks/rawTexture-Dh4jdTlv.esm.js.map +1 -0
  354. package/dist/chunks/ray-DMN9ip7z.esm.min.js +2 -0
  355. package/dist/chunks/ray-DMN9ip7z.esm.min.js.map +1 -0
  356. package/dist/chunks/ray-QR2k6aJd.esm.js +946 -0
  357. package/dist/chunks/ray-QR2k6aJd.esm.js.map +1 -0
  358. package/dist/chunks/rgbdDecode.fragment-C3AkoFAQ.esm.min.js +2 -0
  359. package/dist/chunks/rgbdDecode.fragment-C3AkoFAQ.esm.min.js.map +1 -0
  360. package/dist/chunks/rgbdDecode.fragment-Cok6PVQr.esm.js +13 -0
  361. package/dist/chunks/rgbdDecode.fragment-Cok6PVQr.esm.js.map +1 -0
  362. package/dist/chunks/rgbdDecode.fragment-CqcagT1x.esm.min.js +2 -0
  363. package/dist/chunks/rgbdDecode.fragment-CqcagT1x.esm.min.js.map +1 -0
  364. package/dist/chunks/rgbdDecode.fragment-DRpqF3bE.esm.js +13 -0
  365. package/dist/chunks/rgbdDecode.fragment-DRpqF3bE.esm.js.map +1 -0
  366. package/dist/chunks/rgbdEncode.fragment-BLe7imXf.esm.min.js +2 -0
  367. package/dist/chunks/rgbdEncode.fragment-BLe7imXf.esm.min.js.map +1 -0
  368. package/dist/chunks/rgbdEncode.fragment-Bi6E_oVW.esm.js +13 -0
  369. package/dist/chunks/rgbdEncode.fragment-Bi6E_oVW.esm.js.map +1 -0
  370. package/dist/chunks/rgbdEncode.fragment-C7hBKPem.esm.min.js +2 -0
  371. package/dist/chunks/rgbdEncode.fragment-C7hBKPem.esm.min.js.map +1 -0
  372. package/dist/chunks/rgbdEncode.fragment-C9DicUjD.esm.js +13 -0
  373. package/dist/chunks/rgbdEncode.fragment-C9DicUjD.esm.js.map +1 -0
  374. package/dist/chunks/splatFileLoader-BzfYte-_.esm.min.js +2 -0
  375. package/dist/chunks/splatFileLoader-BzfYte-_.esm.min.js.map +1 -0
  376. package/dist/chunks/splatFileLoader-K9RpjB6c.esm.js +3660 -0
  377. package/dist/chunks/splatFileLoader-K9RpjB6c.esm.js.map +1 -0
  378. package/dist/chunks/spotLight-CJlK-_c5.esm.min.js +2 -0
  379. package/dist/chunks/spotLight-CJlK-_c5.esm.min.js.map +1 -0
  380. package/dist/chunks/spotLight-DxPJdRVZ.esm.js +701 -0
  381. package/dist/chunks/spotLight-DxPJdRVZ.esm.js.map +1 -0
  382. package/dist/chunks/standardMaterial-BRKRGk7c.esm.js +1811 -0
  383. package/dist/chunks/standardMaterial-BRKRGk7c.esm.js.map +1 -0
  384. package/dist/chunks/standardMaterial-Bs9Jda3X.esm.min.js +2 -0
  385. package/dist/chunks/standardMaterial-Bs9Jda3X.esm.min.js.map +1 -0
  386. package/dist/chunks/stlFileLoader-BSGzPo-z.esm.min.js +2 -0
  387. package/dist/chunks/stlFileLoader-BSGzPo-z.esm.min.js.map +1 -0
  388. package/dist/chunks/stlFileLoader-DtPzeNXZ.esm.js +238 -0
  389. package/dist/chunks/stlFileLoader-DtPzeNXZ.esm.js.map +1 -0
  390. package/dist/chunks/tgaTextureLoader-CFjxRPEE.esm.js +349 -0
  391. package/dist/chunks/tgaTextureLoader-CFjxRPEE.esm.js.map +1 -0
  392. package/dist/chunks/tgaTextureLoader-Ch1a2Rcd.esm.min.js +2 -0
  393. package/dist/chunks/tgaTextureLoader-Ch1a2Rcd.esm.min.js.map +1 -0
  394. package/dist/chunks/thinInstanceMesh-CgfQdxDM.esm.min.js +2 -0
  395. package/dist/chunks/thinInstanceMesh-CgfQdxDM.esm.min.js.map +1 -0
  396. package/dist/chunks/thinInstanceMesh-tQGPk8rE.esm.js +314 -0
  397. package/dist/chunks/thinInstanceMesh-tQGPk8rE.esm.js.map +1 -0
  398. package/dist/chunks/vertexColorMixing-BcDvzwMA.esm.js +440 -0
  399. package/dist/chunks/vertexColorMixing-BcDvzwMA.esm.js.map +1 -0
  400. package/dist/chunks/vertexColorMixing-CJeeWCpY.esm.min.js +2 -0
  401. package/dist/chunks/vertexColorMixing-CJeeWCpY.esm.min.js.map +1 -0
  402. package/dist/chunks/vertexColorMixing-DQESmS2T.esm.js +550 -0
  403. package/dist/chunks/vertexColorMixing-DQESmS2T.esm.js.map +1 -0
  404. package/dist/chunks/vertexColorMixing-DlrEyRWJ.esm.min.js +2 -0
  405. package/dist/chunks/vertexColorMixing-DlrEyRWJ.esm.min.js.map +1 -0
  406. package/dist/chunks/webgpuEngine-B8AMUx8i.esm.js +11539 -0
  407. package/dist/chunks/webgpuEngine-B8AMUx8i.esm.js.map +1 -0
  408. package/dist/chunks/webgpuEngine-CxY3O3Qz.esm.min.js +2 -0
  409. package/dist/chunks/webgpuEngine-CxY3O3Qz.esm.min.js.map +1 -0
  410. package/dist/chunks/workerPool-BUOov2K1.esm.js +122 -0
  411. package/dist/chunks/workerPool-BUOov2K1.esm.js.map +1 -0
  412. package/dist/chunks/workerPool-BWHiDmEZ.esm.min.js +2 -0
  413. package/dist/chunks/workerPool-BWHiDmEZ.esm.min.js.map +1 -0
  414. package/lib/index.d.ts +637 -0
  415. package/lib/index.js +2257 -0
  416. package/lib/index.js.map +1 -0
  417. package/package.json +38 -24
  418. package/readme.md +28 -28
  419. package/configuration/configuration.d.ts +0 -107
  420. package/configuration/configuration.js +0 -16
  421. package/configuration/configuration.js.map +0 -1
  422. package/configuration/configurationCompatibility.d.ts +0 -8
  423. package/configuration/configurationCompatibility.js +0 -66
  424. package/configuration/configurationCompatibility.js.map +0 -1
  425. package/configuration/configurationContainer.d.ts +0 -10
  426. package/configuration/configurationContainer.js +0 -10
  427. package/configuration/configurationContainer.js.map +0 -1
  428. package/configuration/globals.d.ts +0 -6
  429. package/configuration/globals.js +0 -18
  430. package/configuration/globals.js.map +0 -1
  431. package/configuration/index.d.ts +0 -2
  432. package/configuration/index.js +0 -4
  433. package/configuration/index.js.map +0 -1
  434. package/configuration/interfaces/cameraConfiguration.d.ts +0 -31
  435. package/configuration/interfaces/cameraConfiguration.js +0 -2
  436. package/configuration/interfaces/cameraConfiguration.js.map +0 -1
  437. package/configuration/interfaces/colorGradingConfiguration.d.ts +0 -81
  438. package/configuration/interfaces/colorGradingConfiguration.js +0 -2
  439. package/configuration/interfaces/colorGradingConfiguration.js.map +0 -1
  440. package/configuration/interfaces/defaultRenderingPipelineConfiguration.d.ts +0 -20
  441. package/configuration/interfaces/defaultRenderingPipelineConfiguration.js +0 -2
  442. package/configuration/interfaces/defaultRenderingPipelineConfiguration.js.map +0 -1
  443. package/configuration/interfaces/environmentMapConfiguration.d.ts +0 -22
  444. package/configuration/interfaces/environmentMapConfiguration.js +0 -2
  445. package/configuration/interfaces/environmentMapConfiguration.js.map +0 -1
  446. package/configuration/interfaces/groundConfiguration.d.ts +0 -24
  447. package/configuration/interfaces/groundConfiguration.js +0 -2
  448. package/configuration/interfaces/groundConfiguration.js.map +0 -1
  449. package/configuration/interfaces/imageProcessingConfiguration.d.ts +0 -45
  450. package/configuration/interfaces/imageProcessingConfiguration.js +0 -2
  451. package/configuration/interfaces/imageProcessingConfiguration.js.map +0 -1
  452. package/configuration/interfaces/index.d.ts +0 -15
  453. package/configuration/interfaces/index.js +0 -16
  454. package/configuration/interfaces/index.js.map +0 -1
  455. package/configuration/interfaces/lightConfiguration.d.ts +0 -60
  456. package/configuration/interfaces/lightConfiguration.js +0 -2
  457. package/configuration/interfaces/lightConfiguration.js.map +0 -1
  458. package/configuration/interfaces/modelAnimationConfiguration.d.ts +0 -26
  459. package/configuration/interfaces/modelAnimationConfiguration.js +0 -2
  460. package/configuration/interfaces/modelAnimationConfiguration.js.map +0 -1
  461. package/configuration/interfaces/modelConfiguration.d.ts +0 -65
  462. package/configuration/interfaces/modelConfiguration.js +0 -2
  463. package/configuration/interfaces/modelConfiguration.js.map +0 -1
  464. package/configuration/interfaces/observersConfiguration.d.ts +0 -5
  465. package/configuration/interfaces/observersConfiguration.js +0 -2
  466. package/configuration/interfaces/observersConfiguration.js.map +0 -1
  467. package/configuration/interfaces/sceneConfiguration.d.ts +0 -48
  468. package/configuration/interfaces/sceneConfiguration.js +0 -2
  469. package/configuration/interfaces/sceneConfiguration.js.map +0 -1
  470. package/configuration/interfaces/sceneOptimizerConfiguration.d.ts +0 -23
  471. package/configuration/interfaces/sceneOptimizerConfiguration.js +0 -2
  472. package/configuration/interfaces/sceneOptimizerConfiguration.js.map +0 -1
  473. package/configuration/interfaces/skyboxConfiguration.d.ts +0 -21
  474. package/configuration/interfaces/skyboxConfiguration.js +0 -2
  475. package/configuration/interfaces/skyboxConfiguration.js.map +0 -1
  476. package/configuration/interfaces/templateConfiguration.d.ts +0 -67
  477. package/configuration/interfaces/templateConfiguration.js +0 -2
  478. package/configuration/interfaces/templateConfiguration.js.map +0 -1
  479. package/configuration/interfaces/vrConfiguration.d.ts +0 -16
  480. package/configuration/interfaces/vrConfiguration.js +0 -2
  481. package/configuration/interfaces/vrConfiguration.js.map +0 -1
  482. package/configuration/loader.d.ts +0 -4
  483. package/configuration/loader.js +0 -17
  484. package/configuration/loader.js.map +0 -1
  485. package/configuration/mappers.d.ts +0 -43
  486. package/configuration/mappers.js +0 -193
  487. package/configuration/mappers.js.map +0 -1
  488. package/configuration/renderOnlyLoader.d.ts +0 -33
  489. package/configuration/renderOnlyLoader.js +0 -162
  490. package/configuration/renderOnlyLoader.js.map +0 -1
  491. package/configuration/types/default.d.ts +0 -6
  492. package/configuration/types/default.js +0 -121
  493. package/configuration/types/default.js.map +0 -1
  494. package/configuration/types/environmentMap.d.ts +0 -5
  495. package/configuration/types/environmentMap.js +0 -14
  496. package/configuration/types/environmentMap.js.map +0 -1
  497. package/configuration/types/extended.d.ts +0 -6
  498. package/configuration/types/extended.js +0 -317
  499. package/configuration/types/extended.js.map +0 -1
  500. package/configuration/types/index.d.ts +0 -14
  501. package/configuration/types/index.js +0 -51
  502. package/configuration/types/index.js.map +0 -1
  503. package/configuration/types/minimal.d.ts +0 -6
  504. package/configuration/types/minimal.js +0 -43
  505. package/configuration/types/minimal.js.map +0 -1
  506. package/configuration/types/renderOnlyDefault.d.ts +0 -30
  507. package/configuration/types/renderOnlyDefault.js +0 -31
  508. package/configuration/types/renderOnlyDefault.js.map +0 -1
  509. package/configuration/types/shadowLight.d.ts +0 -9
  510. package/configuration/types/shadowLight.js +0 -64
  511. package/configuration/types/shadowLight.js.map +0 -1
  512. package/helper/index.d.ts +0 -29
  513. package/helper/index.js +0 -66
  514. package/helper/index.js.map +0 -1
  515. package/index.d.ts +0 -30
  516. package/index.js +0 -46
  517. package/index.js.map +0 -1
  518. package/initializer.d.ts +0 -11
  519. package/initializer.js +0 -35
  520. package/initializer.js.map +0 -1
  521. package/interfaces.d.ts +0 -5
  522. package/interfaces.js +0 -7
  523. package/interfaces.js.map +0 -1
  524. package/labs/environmentSerializer.d.ts +0 -126
  525. package/labs/environmentSerializer.js +0 -191
  526. package/labs/environmentSerializer.js.map +0 -1
  527. package/labs/texture.d.ts +0 -183
  528. package/labs/texture.js +0 -351
  529. package/labs/texture.js.map +0 -1
  530. package/labs/viewerLabs.d.ts +0 -51
  531. package/labs/viewerLabs.js +0 -134
  532. package/labs/viewerLabs.js.map +0 -1
  533. package/loader/modelLoader.d.ts +0 -56
  534. package/loader/modelLoader.js +0 -202
  535. package/loader/modelLoader.js.map +0 -1
  536. package/loader/plugins/applyMaterialConfig.d.ts +0 -12
  537. package/loader/plugins/applyMaterialConfig.js +0 -16
  538. package/loader/plugins/applyMaterialConfig.js.map +0 -1
  539. package/loader/plugins/extendedMaterialLoaderPlugin.d.ts +0 -9
  540. package/loader/plugins/extendedMaterialLoaderPlugin.js +0 -16
  541. package/loader/plugins/extendedMaterialLoaderPlugin.js.map +0 -1
  542. package/loader/plugins/index.d.ts +0 -19
  543. package/loader/plugins/index.js +0 -44
  544. package/loader/plugins/index.js.map +0 -1
  545. package/loader/plugins/loaderPlugin.d.ts +0 -24
  546. package/loader/plugins/loaderPlugin.js +0 -2
  547. package/loader/plugins/loaderPlugin.js.map +0 -1
  548. package/loader/plugins/msftLodLoaderPlugin.d.ts +0 -12
  549. package/loader/plugins/msftLodLoaderPlugin.js +0 -21
  550. package/loader/plugins/msftLodLoaderPlugin.js.map +0 -1
  551. package/loader/plugins/telemetryLoaderPlugin.d.ts +0 -12
  552. package/loader/plugins/telemetryLoaderPlugin.js +0 -36
  553. package/loader/plugins/telemetryLoaderPlugin.js.map +0 -1
  554. package/managers/observablesManager.d.ts +0 -66
  555. package/managers/observablesManager.js +0 -35
  556. package/managers/observablesManager.js.map +0 -1
  557. package/managers/sceneManager.d.ts +0 -245
  558. package/managers/sceneManager.js +0 -1375
  559. package/managers/sceneManager.js.map +0 -1
  560. package/managers/telemetryManager.d.ts +0 -78
  561. package/managers/telemetryManager.js +0 -117
  562. package/managers/telemetryManager.js.map +0 -1
  563. package/model/modelAnimation.d.ts +0 -215
  564. package/model/modelAnimation.js +0 -237
  565. package/model/modelAnimation.js.map +0 -1
  566. package/model/viewerModel.d.ts +0 -233
  567. package/model/viewerModel.js +0 -673
  568. package/model/viewerModel.js.map +0 -1
  569. package/optimizer/custom/extended.d.ts +0 -13
  570. package/optimizer/custom/extended.js +0 -101
  571. package/optimizer/custom/extended.js.map +0 -1
  572. package/optimizer/custom/index.d.ts +0 -9
  573. package/optimizer/custom/index.js +0 -26
  574. package/optimizer/custom/index.js.map +0 -1
  575. package/renderOnlyIndex.d.ts +0 -11
  576. package/renderOnlyIndex.js +0 -18
  577. package/renderOnlyIndex.js.map +0 -1
  578. package/templating/eventManager.d.ts +0 -35
  579. package/templating/eventManager.js +0 -66
  580. package/templating/eventManager.js.map +0 -1
  581. package/templating/plugins/hdButtonPlugin.d.ts +0 -9
  582. package/templating/plugins/hdButtonPlugin.js +0 -22
  583. package/templating/plugins/hdButtonPlugin.js.map +0 -1
  584. package/templating/plugins/printButton.d.ts +0 -9
  585. package/templating/plugins/printButton.js +0 -41
  586. package/templating/plugins/printButton.js.map +0 -1
  587. package/templating/templateManager.d.ts +0 -197
  588. package/templating/templateManager.js +0 -561
  589. package/templating/templateManager.js.map +0 -1
  590. package/templating/viewerTemplatePlugin.d.ts +0 -21
  591. package/templating/viewerTemplatePlugin.js +0 -69
  592. package/templating/viewerTemplatePlugin.js.map +0 -1
  593. package/viewer/defaultViewer.d.ts +0 -130
  594. package/viewer/defaultViewer.js +0 -672
  595. package/viewer/defaultViewer.js.map +0 -1
  596. package/viewer/renderOnlyViewer.d.ts +0 -9
  597. package/viewer/renderOnlyViewer.js +0 -46
  598. package/viewer/renderOnlyViewer.js.map +0 -1
  599. package/viewer/viewer.d.ts +0 -258
  600. package/viewer/viewer.js +0 -783
  601. package/viewer/viewer.js.map +0 -1
  602. package/viewer/viewerManager.d.ts +0 -58
  603. package/viewer/viewerManager.js +0 -91
  604. package/viewer/viewerManager.js.map +0 -1
  605. package/viewer/viewerWithTemplate.d.ts +0 -9
  606. package/viewer/viewerWithTemplate.js +0 -20
  607. package/viewer/viewerWithTemplate.js.map +0 -1
@@ -0,0 +1,3660 @@
1
+ import { g as ShaderStore, K as RegisterClass, N as PushMaterial, Q as PrepareDefinesForMisc, W as PrepareDefinesForFrameBoundValues, X as PrepareDefinesForAttributes, Y as PrepareAttributesForInstances, Z as PrepareUniformsAndSamplersList, $ as addClipPlaneUniforms, a0 as Camera, a1 as bindClipPlane, a2 as BindFogParameters, a3 as BindLogDepth, a4 as SerializationHelper, a5 as MaterialDefines, V as VertexBuffer, a6 as functions, a7 as HighestCommonFactor, M as Mesh, a8 as Matrix, y as Vector3, H as VertexData, a9 as SubMesh, aa as TmpVectors, L as Logger, ab as EngineStore, ac as runCoroutineAsync, T as Tools, ad as ToHalfFloat, C as Constants, ae as runCoroutineSync, x as Vector2, af as createYieldingScheduler, k as Color4, ag as Quaternion, v as Color3, ah as Vector4, ai as RandomRange, aj as BaseTexture, ak as SPLATFileLoaderMetadata, J as registerSceneLoaderPlugin } from './index-D46Rc8Qa.esm.js';
2
+ import './fogFragment-DwdRh83Z.esm.js';
3
+ import './logDepthDeclaration-Co9yKHfe.esm.js';
4
+ import './logDepthVertex-BBDSLJJg.esm.js';
5
+ import './fogFragment-Ct0roave.esm.js';
6
+ import './logDepthDeclaration-KzS73dPG.esm.js';
7
+ import './meshUboDeclaration-D7vtpetW.esm.js';
8
+ import './logDepthVertex-DKTOhgu8.esm.js';
9
+ import { R as RawTexture } from './rawTexture-Dh4jdTlv.esm.js';
10
+ import './thinInstanceMesh-tQGPk8rE.esm.js';
11
+ import { A as AssetContainer } from './assetContainer-Cx2Wvxkg.esm.js';
12
+ import { Ray } from './ray-QR2k6aJd.esm.js';
13
+ import { S as StandardMaterial } from './standardMaterial-BRKRGk7c.esm.js';
14
+
15
+ // Do not edit.
16
+ const name$9 = "gaussianSplattingFragmentDeclaration";
17
+ const shader$9 = `vec4 gaussianColor(vec4 inColor)
18
+ {float A=-dot(vPosition,vPosition);if (A<-4.0) discard;float B=exp(A)*inColor.a;
19
+ #include<logDepthFragment>
20
+ vec3 color=inColor.rgb;
21
+ #ifdef FOG
22
+ #include<fogFragment>
23
+ #endif
24
+ return vec4(color,B);}
25
+ `;
26
+ // Sideeffect
27
+ ShaderStore.IncludesShadersStore[name$9] = shader$9;
28
+
29
+ // Do not edit.
30
+ const name$8 = "gaussianSplattingPixelShader";
31
+ const shader$8 = `#include<clipPlaneFragmentDeclaration>
32
+ #include<logDepthDeclaration>
33
+ #include<fogFragmentDeclaration>
34
+ varying vec4 vColor;varying vec2 vPosition;
35
+ #include<gaussianSplattingFragmentDeclaration>
36
+ void main () {
37
+ #include<clipPlaneFragment>
38
+ gl_FragColor=gaussianColor(vColor);}
39
+ `;
40
+ // Sideeffect
41
+ ShaderStore.ShadersStore[name$8] = shader$8;
42
+ /** @internal */
43
+ const gaussianSplattingPixelShader = { name: name$8, shader: shader$8 };
44
+
45
+ var gaussianSplatting_fragment$1 = /*#__PURE__*/Object.freeze({
46
+ __proto__: null,
47
+ gaussianSplattingPixelShader: gaussianSplattingPixelShader
48
+ });
49
+
50
+ // Do not edit.
51
+ const name$7 = "gaussianSplattingVertexDeclaration";
52
+ const shader$7 = `attribute vec2 position;uniform mat4 view;uniform mat4 projection;uniform mat4 world;uniform vec4 vEyePosition;`;
53
+ // Sideeffect
54
+ ShaderStore.IncludesShadersStore[name$7] = shader$7;
55
+
56
+ // Do not edit.
57
+ const name$6 = "gaussianSplattingUboDeclaration";
58
+ const shader$6 = `#include<sceneUboDeclaration>
59
+ #include<meshUboDeclaration>
60
+ attribute vec2 position;`;
61
+ // Sideeffect
62
+ ShaderStore.IncludesShadersStore[name$6] = shader$6;
63
+
64
+ // Do not edit.
65
+ const name$5 = "gaussianSplatting";
66
+ const shader$5 = `#if !defined(WEBGL2) && !defined(WEBGPU) && !defined(NATIVE)
67
+ mat3 transpose(mat3 matrix) {return mat3(matrix[0][0],matrix[1][0],matrix[2][0],
68
+ matrix[0][1],matrix[1][1],matrix[2][1],
69
+ matrix[0][2],matrix[1][2],matrix[2][2]);}
70
+ #endif
71
+ vec2 getDataUV(float index,vec2 textureSize) {float y=floor(index/textureSize.x);float x=index-y*textureSize.x;return vec2((x+0.5)/textureSize.x,(y+0.5)/textureSize.y);}
72
+ #if SH_DEGREE>0
73
+ ivec2 getDataUVint(float index,vec2 textureSize) {float y=floor(index/textureSize.x);float x=index-y*textureSize.x;return ivec2(uint(x+0.5),uint(y+0.5));}
74
+ #endif
75
+ struct Splat {vec4 center;vec4 color;vec4 covA;vec4 covB;
76
+ #if SH_DEGREE>0
77
+ uvec4 sh0;
78
+ #endif
79
+ #if SH_DEGREE>1
80
+ uvec4 sh1;
81
+ #endif
82
+ #if SH_DEGREE>2
83
+ uvec4 sh2;
84
+ #endif
85
+ };Splat readSplat(float splatIndex)
86
+ {Splat splat;vec2 splatUV=getDataUV(splatIndex,dataTextureSize);splat.center=texture2D(centersTexture,splatUV);splat.color=texture2D(colorsTexture,splatUV);splat.covA=texture2D(covariancesATexture,splatUV)*splat.center.w;splat.covB=texture2D(covariancesBTexture,splatUV)*splat.center.w;
87
+ #if SH_DEGREE>0
88
+ ivec2 splatUVint=getDataUVint(splatIndex,dataTextureSize);splat.sh0=texelFetch(shTexture0,splatUVint,0);
89
+ #endif
90
+ #if SH_DEGREE>1
91
+ splat.sh1=texelFetch(shTexture1,splatUVint,0);
92
+ #endif
93
+ #if SH_DEGREE>2
94
+ splat.sh2=texelFetch(shTexture2,splatUVint,0);
95
+ #endif
96
+ return splat;}
97
+ #if defined(WEBGL2) || defined(WEBGPU) || defined(NATIVE)
98
+ vec3 computeColorFromSHDegree(vec3 dir,const vec3 sh[16])
99
+ {const float SH_C0=0.28209479;const float SH_C1=0.48860251;float SH_C2[5];SH_C2[0]=1.092548430;SH_C2[1]=-1.09254843;SH_C2[2]=0.315391565;SH_C2[3]=-1.09254843;SH_C2[4]=0.546274215;float SH_C3[7];SH_C3[0]=-0.59004358;SH_C3[1]=2.890611442;SH_C3[2]=-0.45704579;SH_C3[3]=0.373176332;SH_C3[4]=-0.45704579;SH_C3[5]=1.445305721;SH_C3[6]=-0.59004358;vec3 result=/*SH_C0**/sh[0];
100
+ #if SH_DEGREE>0
101
+ float x=dir.x;float y=dir.y;float z=dir.z;result+=- SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3];
102
+ #if SH_DEGREE>1
103
+ float xx=x*x,yy=y*y,zz=z*z;float xy=x*y,yz=y*z,xz=x*z;result+=
104
+ SH_C2[0]*xy*sh[4] +
105
+ SH_C2[1]*yz*sh[5] +
106
+ SH_C2[2]*(2.0*zz-xx-yy)*sh[6] +
107
+ SH_C2[3]*xz*sh[7] +
108
+ SH_C2[4]*(xx-yy)*sh[8];
109
+ #if SH_DEGREE>2
110
+ result+=
111
+ SH_C3[0]*y*(3.0*xx-yy)*sh[9] +
112
+ SH_C3[1]*xy*z*sh[10] +
113
+ SH_C3[2]*y*(4.0*zz-xx-yy)*sh[11] +
114
+ SH_C3[3]*z*(2.0*zz-3.0*xx-3.0*yy)*sh[12] +
115
+ SH_C3[4]*x*(4.0*zz-xx-yy)*sh[13] +
116
+ SH_C3[5]*z*(xx-yy)*sh[14] +
117
+ SH_C3[6]*x*(xx-3.0*yy)*sh[15];
118
+ #endif
119
+ #endif
120
+ #endif
121
+ return result;}
122
+ vec4 decompose(uint value)
123
+ {vec4 components=vec4(
124
+ float((value ) & 255u),
125
+ float((value>>uint( 8)) & 255u),
126
+ float((value>>uint(16)) & 255u),
127
+ float((value>>uint(24)) & 255u));return components*vec4(2./255.)-vec4(1.);}
128
+ vec3 computeSH(Splat splat,vec3 color,vec3 dir)
129
+ {vec3 sh[16];sh[0]=color;
130
+ #if SH_DEGREE>0
131
+ vec4 sh00=decompose(splat.sh0.x);vec4 sh01=decompose(splat.sh0.y);vec4 sh02=decompose(splat.sh0.z);sh[1]=vec3(sh00.x,sh00.y,sh00.z);sh[2]=vec3(sh00.w,sh01.x,sh01.y);sh[3]=vec3(sh01.z,sh01.w,sh02.x);
132
+ #endif
133
+ #if SH_DEGREE>1
134
+ vec4 sh03=decompose(splat.sh0.w);vec4 sh04=decompose(splat.sh1.x);vec4 sh05=decompose(splat.sh1.y);sh[4]=vec3(sh02.y,sh02.z,sh02.w);sh[5]=vec3(sh03.x,sh03.y,sh03.z);sh[6]=vec3(sh03.w,sh04.x,sh04.y);sh[7]=vec3(sh04.z,sh04.w,sh05.x);sh[8]=vec3(sh05.y,sh05.z,sh05.w);
135
+ #endif
136
+ #if SH_DEGREE>2
137
+ vec4 sh06=decompose(splat.sh1.z);vec4 sh07=decompose(splat.sh1.w);vec4 sh08=decompose(splat.sh2.x);vec4 sh09=decompose(splat.sh2.y);vec4 sh10=decompose(splat.sh2.z);vec4 sh11=decompose(splat.sh2.w);sh[9]=vec3(sh06.x,sh06.y,sh06.z);sh[10]=vec3(sh06.w,sh07.x,sh07.y);sh[11]=vec3(sh07.z,sh07.w,sh08.x);sh[12]=vec3(sh08.y,sh08.z,sh08.w);sh[13]=vec3(sh09.x,sh09.y,sh09.z);sh[14]=vec3(sh09.w,sh10.x,sh10.y);sh[15]=vec3(sh10.z,sh10.w,sh11.x);
138
+ #endif
139
+ return computeColorFromSHDegree(dir,sh);}
140
+ #else
141
+ vec3 computeSH(Splat splat,vec3 color,vec3 dir)
142
+ {return color;}
143
+ #endif
144
+ vec4 gaussianSplatting(vec2 meshPos,vec3 worldPos,vec2 scale,vec3 covA,vec3 covB,mat4 worldMatrix,mat4 viewMatrix,mat4 projectionMatrix)
145
+ {mat4 modelView=viewMatrix*worldMatrix;vec4 camspace=viewMatrix*vec4(worldPos,1.);vec4 pos2d=projectionMatrix*camspace;float bounds=1.2*pos2d.w;if (pos2d.z<-pos2d.w || pos2d.x<-bounds || pos2d.x>bounds
146
+ || pos2d.y<-bounds || pos2d.y>bounds) {return vec4(0.0,0.0,2.0,1.0);}
147
+ mat3 Vrk=mat3(
148
+ covA.x,covA.y,covA.z,
149
+ covA.y,covB.x,covB.y,
150
+ covA.z,covB.y,covB.z
151
+ );mat3 J=mat3(
152
+ focal.x/camspace.z,0.,-(focal.x*camspace.x)/(camspace.z*camspace.z),
153
+ 0.,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),
154
+ 0.,0.,0.
155
+ );mat3 invy=mat3(1,0,0,0,-1,0,0,0,1);mat3 T=invy*transpose(mat3(modelView))*J;mat3 cov2d=transpose(T)*Vrk*T;float mid=(cov2d[0][0]+cov2d[1][1])/2.0;float radius=length(vec2((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));float lambda1=mid+radius,lambda2=mid-radius;if (lambda2<0.0)
156
+ {return vec4(0.0,0.0,2.0,1.0);}
157
+ vec2 diagonalVector=normalize(vec2(cov2d[0][1],lambda1-cov2d[0][0]));vec2 majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;vec2 minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2(diagonalVector.y,-diagonalVector.x);vec2 vCenter=vec2(pos2d);return vec4(
158
+ vCenter
159
+ + ((meshPos.x*majorAxis
160
+ + meshPos.y*minorAxis)*invViewport*pos2d.w)*scale,pos2d.zw);}`;
161
+ // Sideeffect
162
+ ShaderStore.IncludesShadersStore[name$5] = shader$5;
163
+
164
+ // Do not edit.
165
+ const name$4 = "gaussianSplattingVertexShader";
166
+ const shader$4 = `#include<__decl__gaussianSplattingVertex>
167
+ #ifdef LOGARITHMICDEPTH
168
+ #extension GL_EXT_frag_depth : enable
169
+ #endif
170
+ #include<clipPlaneVertexDeclaration>
171
+ #include<fogVertexDeclaration>
172
+ #include<logDepthDeclaration>
173
+ attribute float splatIndex;uniform vec2 invViewport;uniform vec2 dataTextureSize;uniform vec2 focal;uniform sampler2D covariancesATexture;uniform sampler2D covariancesBTexture;uniform sampler2D centersTexture;uniform sampler2D colorsTexture;
174
+ #if SH_DEGREE>0
175
+ uniform highp usampler2D shTexture0;
176
+ #endif
177
+ #if SH_DEGREE>1
178
+ uniform highp usampler2D shTexture1;
179
+ #endif
180
+ #if SH_DEGREE>2
181
+ uniform highp usampler2D shTexture2;
182
+ #endif
183
+ varying vec4 vColor;varying vec2 vPosition;
184
+ #include<gaussianSplatting>
185
+ void main () {Splat splat=readSplat(splatIndex);vec3 covA=splat.covA.xyz;vec3 covB=vec3(splat.covA.w,splat.covB.xy);vec4 worldPos=world*vec4(splat.center.xyz,1.0);vColor=splat.color;vPosition=position;
186
+ #if SH_DEGREE>0
187
+ vec3 dir=normalize(worldPos.xyz-vEyePosition.xyz);dir.y*=-1.;
188
+ vColor.xyz=computeSH(splat,splat.color.xyz,dir);
189
+ #endif
190
+ gl_Position=gaussianSplatting(position,worldPos.xyz,vec2(1.,1.),covA,covB,world,view,projection);
191
+ #include<clipPlaneVertex>
192
+ #include<fogVertex>
193
+ #include<logDepthVertex>
194
+ }
195
+ `;
196
+ // Sideeffect
197
+ ShaderStore.ShadersStore[name$4] = shader$4;
198
+ /** @internal */
199
+ const gaussianSplattingVertexShader = { name: name$4, shader: shader$4 };
200
+
201
+ var gaussianSplatting_vertex$1 = /*#__PURE__*/Object.freeze({
202
+ __proto__: null,
203
+ gaussianSplattingVertexShader: gaussianSplattingVertexShader
204
+ });
205
+
206
+ // Do not edit.
207
+ const name$3 = "gaussianSplattingFragmentDeclaration";
208
+ const shader$3 = `fn gaussianColor(inColor: vec4f,inPosition: vec2f)->vec4f
209
+ {var A : f32=-dot(inPosition,inPosition);if (A>-4.0)
210
+ {var B: f32=exp(A)*inColor.a;
211
+ #include<logDepthFragment>
212
+ var color: vec3f=inColor.rgb;
213
+ #ifdef FOG
214
+ #include<fogFragment>
215
+ #endif
216
+ return vec4f(color,B);} else {return vec4f(0.0);}}
217
+ `;
218
+ // Sideeffect
219
+ ShaderStore.IncludesShadersStoreWGSL[name$3] = shader$3;
220
+
221
+ // Do not edit.
222
+ const name$2 = "gaussianSplattingPixelShader";
223
+ const shader$2 = `#include<clipPlaneFragmentDeclaration>
224
+ #include<logDepthDeclaration>
225
+ #include<fogFragmentDeclaration>
226
+ varying vColor: vec4f;varying vPosition: vec2f;
227
+ #include<gaussianSplattingFragmentDeclaration>
228
+ @fragment
229
+ fn main(input: FragmentInputs)->FragmentOutputs {
230
+ #include<clipPlaneFragment>
231
+ fragmentOutputs.color=gaussianColor(input.vColor,input.vPosition);}
232
+ `;
233
+ // Sideeffect
234
+ ShaderStore.ShadersStoreWGSL[name$2] = shader$2;
235
+ /** @internal */
236
+ const gaussianSplattingPixelShaderWGSL = { name: name$2, shader: shader$2 };
237
+
238
+ var gaussianSplatting_fragment = /*#__PURE__*/Object.freeze({
239
+ __proto__: null,
240
+ gaussianSplattingPixelShaderWGSL: gaussianSplattingPixelShaderWGSL
241
+ });
242
+
243
+ // Do not edit.
244
+ const name$1 = "gaussianSplatting";
245
+ const shader$1 = `fn getDataUV(index: f32,dataTextureSize: vec2f)->vec2<f32> {let y: f32=floor(index/dataTextureSize.x);let x: f32=index-y*dataTextureSize.x;return vec2f((x+0.5),(y+0.5));}
246
+ struct Splat {center: vec4f,
247
+ color: vec4f,
248
+ covA: vec4f,
249
+ covB: vec4f,
250
+ #if SH_DEGREE>0
251
+ sh0: vec4<u32>,
252
+ #endif
253
+ #if SH_DEGREE>1
254
+ sh1: vec4<u32>,
255
+ #endif
256
+ #if SH_DEGREE>2
257
+ sh2: vec4<u32>,
258
+ #endif
259
+ };fn readSplat(splatIndex: f32,dataTextureSize: vec2f)->Splat {var splat: Splat;let splatUV=getDataUV(splatIndex,dataTextureSize);let splatUVi32=vec2<i32>(i32(splatUV.x),i32(splatUV.y));splat.center=textureLoad(centersTexture,splatUVi32,0);splat.color=textureLoad(colorsTexture,splatUVi32,0);splat.covA=textureLoad(covariancesATexture,splatUVi32,0)*splat.center.w;splat.covB=textureLoad(covariancesBTexture,splatUVi32,0)*splat.center.w;
260
+ #if SH_DEGREE>0
261
+ splat.sh0=textureLoad(shTexture0,splatUVi32,0);
262
+ #endif
263
+ #if SH_DEGREE>1
264
+ splat.sh1=textureLoad(shTexture1,splatUVi32,0);
265
+ #endif
266
+ #if SH_DEGREE>2
267
+ splat.sh2=textureLoad(shTexture2,splatUVi32,0);
268
+ #endif
269
+ return splat;}
270
+ fn computeColorFromSHDegree(dir: vec3f,sh: array<vec3<f32>,16>)->vec3f
271
+ {let SH_C0: f32=0.28209479;let SH_C1: f32=0.48860251;var SH_C2: array<f32,5>=array<f32,5>(
272
+ 1.092548430,
273
+ -1.09254843,
274
+ 0.315391565,
275
+ -1.09254843,
276
+ 0.546274215
277
+ );var SH_C3: array<f32,7>=array<f32,7>(
278
+ -0.59004358,
279
+ 2.890611442,
280
+ -0.45704579,
281
+ 0.373176332,
282
+ -0.45704579,
283
+ 1.445305721,
284
+ -0.59004358
285
+ );var result: vec3f=/*SH_C0**/sh[0];
286
+ #if SH_DEGREE>0
287
+ let x: f32=dir.x;let y: f32=dir.y;let z: f32=dir.z;result+=-SH_C1*y*sh[1]+SH_C1*z*sh[2]-SH_C1*x*sh[3];
288
+ #if SH_DEGREE>1
289
+ let xx: f32=x*x;let yy: f32=y*y;let zz: f32=z*z;let xy: f32=x*y;let yz: f32=y*z;let xz: f32=x*z;result+=
290
+ SH_C2[0]*xy*sh[4] +
291
+ SH_C2[1]*yz*sh[5] +
292
+ SH_C2[2]*(2.0f*zz-xx-yy)*sh[6] +
293
+ SH_C2[3]*xz*sh[7] +
294
+ SH_C2[4]*(xx-yy)*sh[8];
295
+ #if SH_DEGREE>2
296
+ result+=
297
+ SH_C3[0]*y*(3.0f*xx-yy)*sh[9] +
298
+ SH_C3[1]*xy*z*sh[10] +
299
+ SH_C3[2]*y*(4.0f*zz-xx-yy)*sh[11] +
300
+ SH_C3[3]*z*(2.0f*zz-3.0f*xx-3.0f*yy)*sh[12] +
301
+ SH_C3[4]*x*(4.0f*zz-xx-yy)*sh[13] +
302
+ SH_C3[5]*z*(xx-yy)*sh[14] +
303
+ SH_C3[6]*x*(xx-3.0f*yy)*sh[15];
304
+ #endif
305
+ #endif
306
+ #endif
307
+ return result;}
308
+ fn decompose(value: u32)->vec4f
309
+ {let components : vec4f=vec4f(
310
+ f32((value ) & 255u),
311
+ f32((value>>u32( 8)) & 255u),
312
+ f32((value>>u32(16)) & 255u),
313
+ f32((value>>u32(24)) & 255u));return components*vec4f(2./255.)-vec4f(1.);}
314
+ fn computeSH(splat: Splat,color: vec3f,dir: vec3f)->vec3f
315
+ {var sh: array<vec3<f32>,16>;sh[0]=color;
316
+ #if SH_DEGREE>0
317
+ let sh00: vec4f=decompose(splat.sh0.x);let sh01: vec4f=decompose(splat.sh0.y);let sh02: vec4f=decompose(splat.sh0.z);sh[1]=vec3f(sh00.x,sh00.y,sh00.z);sh[2]=vec3f(sh00.w,sh01.x,sh01.y);sh[3]=vec3f(sh01.z,sh01.w,sh02.x);
318
+ #endif
319
+ #if SH_DEGREE>1
320
+ let sh03: vec4f=decompose(splat.sh0.w);let sh04: vec4f=decompose(splat.sh1.x);let sh05: vec4f=decompose(splat.sh1.y);sh[4]=vec3f(sh02.y,sh02.z,sh02.w);sh[5]=vec3f(sh03.x,sh03.y,sh03.z);sh[6]=vec3f(sh03.w,sh04.x,sh04.y);sh[7]=vec3f(sh04.z,sh04.w,sh05.x);sh[8]=vec3f(sh05.y,sh05.z,sh05.w);
321
+ #endif
322
+ #if SH_DEGREE>2
323
+ let sh06: vec4f=decompose(splat.sh1.z);let sh07: vec4f=decompose(splat.sh1.w);let sh08: vec4f=decompose(splat.sh2.x);let sh09: vec4f=decompose(splat.sh2.y);let sh10: vec4f=decompose(splat.sh2.z);let sh11: vec4f=decompose(splat.sh2.w);sh[9]=vec3f(sh06.x,sh06.y,sh06.z);sh[10]=vec3f(sh06.w,sh07.x,sh07.y);sh[11]=vec3f(sh07.z,sh07.w,sh08.x);sh[12]=vec3f(sh08.y,sh08.z,sh08.w);sh[13]=vec3f(sh09.x,sh09.y,sh09.z);sh[14]=vec3f(sh09.w,sh10.x,sh10.y);sh[15]=vec3f(sh10.z,sh10.w,sh11.x);
324
+ #endif
325
+ return computeColorFromSHDegree(dir,sh);}
326
+ fn gaussianSplatting(
327
+ meshPos: vec2<f32>,
328
+ worldPos: vec3<f32>,
329
+ scale: vec2<f32>,
330
+ covA: vec3<f32>,
331
+ covB: vec3<f32>,
332
+ worldMatrix: mat4x4<f32>,
333
+ viewMatrix: mat4x4<f32>,
334
+ projectionMatrix: mat4x4<f32>,
335
+ focal: vec2f,
336
+ invViewport: vec2f
337
+ )->vec4f {let modelView=viewMatrix*worldMatrix;let camspace=viewMatrix*vec4f(worldPos,1.0);let pos2d=projectionMatrix*camspace;let bounds=1.2*pos2d.w;if (pos2d.z<0. || pos2d.x<-bounds || pos2d.x>bounds || pos2d.y<-bounds || pos2d.y>bounds) {return vec4f(0.0,0.0,2.0,1.0);}
338
+ let Vrk=mat3x3<f32>(
339
+ covA.x,covA.y,covA.z,
340
+ covA.y,covB.x,covB.y,
341
+ covA.z,covB.y,covB.z
342
+ );let J=mat3x3<f32>(
343
+ focal.x/camspace.z,0.0,-(focal.x*camspace.x)/(camspace.z*camspace.z),
344
+ 0.0,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),
345
+ 0.0,0.0,0.0
346
+ );let invy=mat3x3<f32>(
347
+ 1.0,0.0,0.0,
348
+ 0.0,-1.0,0.0,
349
+ 0.0,0.0,1.0
350
+ );let T=invy*transpose(mat3x3<f32>(
351
+ modelView[0].xyz,
352
+ modelView[1].xyz,
353
+ modelView[2].xyz))*J;let cov2d=transpose(T)*Vrk*T;let mid=(cov2d[0][0]+cov2d[1][1])/2.0;let radius=length(vec2<f32>((cov2d[0][0]-cov2d[1][1])/2.0,cov2d[0][1]));let lambda1=mid+radius;let lambda2=mid-radius;if (lambda2<0.0) {return vec4f(0.0,0.0,2.0,1.0);}
354
+ let diagonalVector=normalize(vec2<f32>(cov2d[0][1],lambda1-cov2d[0][0]));let majorAxis=min(sqrt(2.0*lambda1),1024.0)*diagonalVector;let minorAxis=min(sqrt(2.0*lambda2),1024.0)*vec2<f32>(diagonalVector.y,-diagonalVector.x);let vCenter=vec2<f32>(pos2d.x,pos2d.y);return vec4f(
355
+ vCenter+((meshPos.x*majorAxis+meshPos.y*minorAxis)*invViewport*pos2d.w)*scale,
356
+ pos2d.z,
357
+ pos2d.w
358
+ );}
359
+ `;
360
+ // Sideeffect
361
+ ShaderStore.IncludesShadersStoreWGSL[name$1] = shader$1;
362
+
363
+ // Do not edit.
364
+ const name = "gaussianSplattingVertexShader";
365
+ const shader = `#include<sceneUboDeclaration>
366
+ #include<meshUboDeclaration>
367
+ #include<clipPlaneVertexDeclaration>
368
+ #include<fogVertexDeclaration>
369
+ #include<logDepthDeclaration>
370
+ attribute splatIndex: f32;attribute position: vec2f;uniform invViewport: vec2f;uniform dataTextureSize: vec2f;uniform focal: vec2f;var covariancesATexture: texture_2d<f32>;var covariancesBTexture: texture_2d<f32>;var centersTexture: texture_2d<f32>;var colorsTexture: texture_2d<f32>;
371
+ #if SH_DEGREE>0
372
+ var shTexture0: texture_2d<u32>;
373
+ #endif
374
+ #if SH_DEGREE>1
375
+ var shTexture1: texture_2d<u32>;
376
+ #endif
377
+ #if SH_DEGREE>2
378
+ var shTexture2: texture_2d<u32>;
379
+ #endif
380
+ varying vColor: vec4f;varying vPosition: vec2f;
381
+ #include<gaussianSplatting>
382
+ @vertex
383
+ fn main(input : VertexInputs)->FragmentInputs {var splat: Splat=readSplat(input.splatIndex,uniforms.dataTextureSize);var covA: vec3f=splat.covA.xyz;var covB: vec3f=vec3f(splat.covA.w,splat.covB.xy);let worldPos: vec4f=mesh.world*vec4f(splat.center.xyz,1.0);vertexOutputs.vPosition=input.position;
384
+ #if SH_DEGREE>0
385
+ let dir: vec3f=normalize(worldPos.xyz-scene.vEyePosition.xyz);vertexOutputs.vColor=vec4f(computeSH(splat,splat.color.xyz,dir),1.0);
386
+ #else
387
+ vertexOutputs.vColor=splat.color;
388
+ #endif
389
+ vertexOutputs.position=gaussianSplatting(input.position,worldPos.xyz,vec2f(1.0,1.0),covA,covB,mesh.world,scene.view,scene.projection,uniforms.focal,uniforms.invViewport);
390
+ #include<clipPlaneVertex>
391
+ #include<fogVertex>
392
+ #include<logDepthVertex>
393
+ }
394
+ `;
395
+ // Sideeffect
396
+ ShaderStore.ShadersStoreWGSL[name] = shader;
397
+ /** @internal */
398
+ const gaussianSplattingVertexShaderWGSL = { name, shader };
399
+
400
+ var gaussianSplatting_vertex = /*#__PURE__*/Object.freeze({
401
+ __proto__: null,
402
+ gaussianSplattingVertexShaderWGSL: gaussianSplattingVertexShaderWGSL
403
+ });
404
+
405
+ /**
406
+ * @internal
407
+ */
408
+ class GaussianSplattingMaterialDefines extends MaterialDefines {
409
+ /**
410
+ * Constructor of the defines.
411
+ */
412
+ constructor() {
413
+ super();
414
+ this.FOG = false;
415
+ this.THIN_INSTANCES = true;
416
+ this.LOGARITHMICDEPTH = false;
417
+ this.CLIPPLANE = false;
418
+ this.CLIPPLANE2 = false;
419
+ this.CLIPPLANE3 = false;
420
+ this.CLIPPLANE4 = false;
421
+ this.CLIPPLANE5 = false;
422
+ this.CLIPPLANE6 = false;
423
+ this.SH_DEGREE = 0;
424
+ this.rebuild();
425
+ }
426
+ }
427
+ /**
428
+ * GaussianSplattingMaterial material used to render Gaussian Splatting
429
+ * @experimental
430
+ */
431
+ class GaussianSplattingMaterial extends PushMaterial {
432
+ /**
433
+ * Instantiates a Gaussian Splatting Material in the given scene
434
+ * @param name The friendly name of the material
435
+ * @param scene The scene to add the material to
436
+ */
437
+ constructor(name, scene) {
438
+ super(name, scene);
439
+ this.backFaceCulling = false;
440
+ }
441
+ /**
442
+ * Gets a boolean indicating that current material needs to register RTT
443
+ */
444
+ get hasRenderTargetTextures() {
445
+ return false;
446
+ }
447
+ /**
448
+ * Specifies whether or not this material should be rendered in alpha test mode.
449
+ * @returns false
450
+ */
451
+ needAlphaTesting() {
452
+ return false;
453
+ }
454
+ /**
455
+ * Specifies whether or not this material should be rendered in alpha blend mode.
456
+ * @returns true
457
+ */
458
+ needAlphaBlending() {
459
+ return true;
460
+ }
461
+ /**
462
+ * Checks whether the material is ready to be rendered for a given mesh.
463
+ * @param mesh The mesh to render
464
+ * @param subMesh The submesh to check against
465
+ * @returns true if all the dependencies are ready (Textures, Effects...)
466
+ */
467
+ isReadyForSubMesh(mesh, subMesh) {
468
+ const useInstances = true;
469
+ const drawWrapper = subMesh._drawWrapper;
470
+ if (drawWrapper.effect && this.isFrozen) {
471
+ if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {
472
+ return true;
473
+ }
474
+ }
475
+ if (!subMesh.materialDefines) {
476
+ subMesh.materialDefines = new GaussianSplattingMaterialDefines();
477
+ }
478
+ const scene = this.getScene();
479
+ const defines = subMesh.materialDefines;
480
+ if (this._isReadyForSubMesh(subMesh)) {
481
+ return true;
482
+ }
483
+ const engine = scene.getEngine();
484
+ // Misc.
485
+ PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, false, defines);
486
+ // Values that need to be evaluated on every frame
487
+ PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, true);
488
+ // Attribs
489
+ PrepareDefinesForAttributes(mesh, defines, false, false);
490
+ // SH is disabled for webGL1
491
+ if (engine.version > 1 || engine.isWebGPU) {
492
+ defines["SH_DEGREE"] = mesh.shDegree;
493
+ }
494
+ // Get correct effect
495
+ if (defines.isDirty) {
496
+ defines.markAsProcessed();
497
+ scene.resetCachedMaterial();
498
+ //Attributes
499
+ const attribs = [VertexBuffer.PositionKind, "splatIndex"];
500
+ PrepareAttributesForInstances(attribs, defines);
501
+ const uniforms = ["world", "view", "projection", "vFogInfos", "vFogColor", "logarithmicDepthConstant", "invViewport", "dataTextureSize", "focal", "vEyePosition"];
502
+ const samplers = ["covariancesATexture", "covariancesBTexture", "centersTexture", "colorsTexture", "shTexture0", "shTexture1", "shTexture2"];
503
+ const uniformBuffers = ["Scene", "Mesh"];
504
+ PrepareUniformsAndSamplersList({
505
+ uniformsNames: uniforms,
506
+ uniformBuffersNames: uniformBuffers,
507
+ samplers: samplers,
508
+ defines: defines,
509
+ });
510
+ addClipPlaneUniforms(uniforms);
511
+ const join = defines.toString();
512
+ const effect = scene.getEngine().createEffect("gaussianSplatting", {
513
+ attributes: attribs,
514
+ uniformsNames: uniforms,
515
+ uniformBuffersNames: uniformBuffers,
516
+ samplers: samplers,
517
+ defines: join,
518
+ onCompiled: this.onCompiled,
519
+ onError: this.onError,
520
+ indexParameters: {},
521
+ shaderLanguage: this._shaderLanguage,
522
+ extraInitializationsAsync: async () => {
523
+ if (this._shaderLanguage === 1 /* ShaderLanguage.WGSL */) {
524
+ await Promise.all([Promise.resolve().then(function () { return gaussianSplatting_fragment; }), Promise.resolve().then(function () { return gaussianSplatting_vertex; })]);
525
+ }
526
+ else {
527
+ await Promise.all([Promise.resolve().then(function () { return gaussianSplatting_fragment$1; }), Promise.resolve().then(function () { return gaussianSplatting_vertex$1; })]);
528
+ }
529
+ },
530
+ }, engine);
531
+ subMesh.setEffect(effect, defines, this._materialContext);
532
+ }
533
+ if (!subMesh.effect || !subMesh.effect.isReady()) {
534
+ return false;
535
+ }
536
+ defines._renderId = scene.getRenderId();
537
+ drawWrapper._wasPreviouslyReady = true;
538
+ drawWrapper._wasPreviouslyUsingInstances = useInstances;
539
+ return true;
540
+ }
541
+ /**
542
+ * Bind material effect for a specific Gaussian Splatting mesh
543
+ * @param mesh Gaussian splatting mesh
544
+ * @param effect Splatting material or node material
545
+ * @param scene scene that contains mesh and camera used for rendering
546
+ */
547
+ static BindEffect(mesh, effect, scene) {
548
+ const engine = scene.getEngine();
549
+ const camera = scene.activeCamera;
550
+ const renderWidth = engine.getRenderWidth();
551
+ const renderHeight = engine.getRenderHeight();
552
+ // check if rigcamera, get number of rigs
553
+ const numberOfRigs = camera?.rigParent?.rigCameras.length || 1;
554
+ effect.setFloat2("invViewport", 1 / (renderWidth / numberOfRigs), 1 / renderHeight);
555
+ let focal = 1000;
556
+ if (camera) {
557
+ /*
558
+ more explicit version:
559
+ const t = camera.getProjectionMatrix().m[5];
560
+ const FovY = Math.atan(1.0 / t) * 2.0;
561
+ focal = renderHeight / 2.0 / Math.tan(FovY / 2.0);
562
+ Using a shorter version here to not have tan(atan) and 2.0 factor
563
+ */
564
+ const t = camera.getProjectionMatrix().m[5];
565
+ if (camera.fovMode == Camera.FOVMODE_VERTICAL_FIXED) {
566
+ focal = (renderHeight * t) / 2.0;
567
+ }
568
+ else {
569
+ focal = (renderWidth * t) / 2.0;
570
+ }
571
+ }
572
+ effect.setFloat2("focal", focal, focal);
573
+ const gsMesh = mesh;
574
+ if (gsMesh.covariancesATexture) {
575
+ const textureSize = gsMesh.covariancesATexture.getSize();
576
+ effect.setFloat2("dataTextureSize", textureSize.width, textureSize.height);
577
+ effect.setTexture("covariancesATexture", gsMesh.covariancesATexture);
578
+ effect.setTexture("covariancesBTexture", gsMesh.covariancesBTexture);
579
+ effect.setTexture("centersTexture", gsMesh.centersTexture);
580
+ effect.setTexture("colorsTexture", gsMesh.colorsTexture);
581
+ if (gsMesh.shTextures) {
582
+ for (let i = 0; i < gsMesh.shTextures?.length; i++) {
583
+ effect.setTexture(`shTexture${i}`, gsMesh.shTextures[i]);
584
+ }
585
+ }
586
+ }
587
+ }
588
+ /**
589
+ * Binds the submesh to this material by preparing the effect and shader to draw
590
+ * @param world defines the world transformation matrix
591
+ * @param mesh defines the mesh containing the submesh
592
+ * @param subMesh defines the submesh to bind the material to
593
+ */
594
+ bindForSubMesh(world, mesh, subMesh) {
595
+ const scene = this.getScene();
596
+ const defines = subMesh.materialDefines;
597
+ if (!defines) {
598
+ return;
599
+ }
600
+ const effect = subMesh.effect;
601
+ if (!effect) {
602
+ return;
603
+ }
604
+ this._activeEffect = effect;
605
+ // Matrices Mesh.
606
+ mesh.getMeshUniformBuffer().bindToEffect(effect, "Mesh");
607
+ mesh.transferToEffect(world);
608
+ // Bind data
609
+ const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);
610
+ if (mustRebind) {
611
+ this.bindView(effect);
612
+ this.bindViewProjection(effect);
613
+ GaussianSplattingMaterial.BindEffect(mesh, this._activeEffect, scene);
614
+ // Clip plane
615
+ bindClipPlane(effect, this, scene);
616
+ }
617
+ else if (scene.getEngine()._features.needToAlwaysBindUniformBuffers) {
618
+ this._needToBindSceneUbo = true;
619
+ }
620
+ // Fog
621
+ BindFogParameters(scene, mesh, effect);
622
+ // Log. depth
623
+ if (this.useLogarithmicDepth) {
624
+ BindLogDepth(defines, effect, scene);
625
+ }
626
+ this._afterBind(mesh, this._activeEffect, subMesh);
627
+ }
628
+ /**
629
+ * Clones the material.
630
+ * @param name The cloned name.
631
+ * @returns The cloned material.
632
+ */
633
+ clone(name) {
634
+ return SerializationHelper.Clone(() => new GaussianSplattingMaterial(name, this.getScene()), this);
635
+ }
636
+ /**
637
+ * Serializes the current material to its JSON representation.
638
+ * @returns The JSON representation.
639
+ */
640
+ serialize() {
641
+ const serializationObject = super.serialize();
642
+ serializationObject.customType = "BABYLON.GaussianSplattingMaterial";
643
+ return serializationObject;
644
+ }
645
+ /**
646
+ * Gets the class name of the material
647
+ * @returns "GaussianSplattingMaterial"
648
+ */
649
+ getClassName() {
650
+ return "GaussianSplattingMaterial";
651
+ }
652
+ /**
653
+ * Parse a JSON input to create back a Gaussian Splatting material.
654
+ * @param source The JSON data to parse
655
+ * @param scene The scene to create the parsed material in
656
+ * @param rootUrl The root url of the assets the material depends upon
657
+ * @returns the instantiated GaussianSplattingMaterial.
658
+ */
659
+ static Parse(source, scene, rootUrl) {
660
+ return SerializationHelper.Parse(() => new GaussianSplattingMaterial(source.name, scene), source, scene, rootUrl);
661
+ }
662
+ }
663
+ RegisterClass("BABYLON.GaussianSplattingMaterial", GaussianSplattingMaterial);
664
+
665
+ /* eslint-disable @typescript-eslint/naming-convention */
666
+ const HCF = HighestCommonFactor;
667
+ /**
668
+ * Scalar computation library
669
+ */
670
+ const Scalar = {
671
+ ...functions,
672
+ /**
673
+ * Two pi constants convenient for computation.
674
+ */
675
+ TwoPi: Math.PI * 2,
676
+ /**
677
+ * Returns -1 if value is negative and +1 is value is positive.
678
+ * @param value the value
679
+ * @returns the value itself if it's equal to zero.
680
+ */
681
+ Sign: Math.sign,
682
+ /**
683
+ * the log2 of value.
684
+ * @param value the value to compute log2 of
685
+ * @returns the log2 of value.
686
+ */
687
+ Log2: Math.log2,
688
+ /**
689
+ * Returns the highest common factor of two integers.
690
+ * @param a first parameter
691
+ * @param b second parameter
692
+ * @returns HCF of a and b
693
+ */
694
+ HCF,
695
+ };
696
+ /* eslint-enable @typescript-eslint/naming-convention */
697
+
698
+ // @internal
699
+ const unpackUnorm = (value, bits) => {
700
+ const t = (1 << bits) - 1;
701
+ return (value & t) / t;
702
+ };
703
+ // @internal
704
+ const unpack111011 = (value, result) => {
705
+ result.x = unpackUnorm(value >>> 21, 11);
706
+ result.y = unpackUnorm(value >>> 11, 10);
707
+ result.z = unpackUnorm(value, 11);
708
+ };
709
+ // @internal
710
+ const unpack8888 = (value, result) => {
711
+ result[0] = unpackUnorm(value >>> 24, 8) * 255;
712
+ result[1] = unpackUnorm(value >>> 16, 8) * 255;
713
+ result[2] = unpackUnorm(value >>> 8, 8) * 255;
714
+ result[3] = unpackUnorm(value, 8) * 255;
715
+ };
716
+ // @internal
717
+ // unpack quaternion with 2,10,10,10 format (largest element, 3x10bit element)
718
+ const unpackRot = (value, result) => {
719
+ const norm = 1.0 / (Math.sqrt(2) * 0.5);
720
+ const a = (unpackUnorm(value >>> 20, 10) - 0.5) * norm;
721
+ const b = (unpackUnorm(value >>> 10, 10) - 0.5) * norm;
722
+ const c = (unpackUnorm(value, 10) - 0.5) * norm;
723
+ const m = Math.sqrt(1.0 - (a * a + b * b + c * c));
724
+ switch (value >>> 30) {
725
+ case 0:
726
+ result.set(m, a, b, c);
727
+ break;
728
+ case 1:
729
+ result.set(a, m, b, c);
730
+ break;
731
+ case 2:
732
+ result.set(a, b, m, c);
733
+ break;
734
+ case 3:
735
+ result.set(a, b, c, m);
736
+ break;
737
+ }
738
+ };
739
+ /**
740
+ * Representation of the types
741
+ */
742
+ var PLYType;
743
+ (function (PLYType) {
744
+ PLYType[PLYType["FLOAT"] = 0] = "FLOAT";
745
+ PLYType[PLYType["INT"] = 1] = "INT";
746
+ PLYType[PLYType["UINT"] = 2] = "UINT";
747
+ PLYType[PLYType["DOUBLE"] = 3] = "DOUBLE";
748
+ PLYType[PLYType["UCHAR"] = 4] = "UCHAR";
749
+ PLYType[PLYType["UNDEFINED"] = 5] = "UNDEFINED";
750
+ })(PLYType || (PLYType = {}));
751
+ /**
752
+ * Usage types of the PLY values
753
+ */
754
+ var PLYValue;
755
+ (function (PLYValue) {
756
+ PLYValue[PLYValue["MIN_X"] = 0] = "MIN_X";
757
+ PLYValue[PLYValue["MIN_Y"] = 1] = "MIN_Y";
758
+ PLYValue[PLYValue["MIN_Z"] = 2] = "MIN_Z";
759
+ PLYValue[PLYValue["MAX_X"] = 3] = "MAX_X";
760
+ PLYValue[PLYValue["MAX_Y"] = 4] = "MAX_Y";
761
+ PLYValue[PLYValue["MAX_Z"] = 5] = "MAX_Z";
762
+ PLYValue[PLYValue["MIN_SCALE_X"] = 6] = "MIN_SCALE_X";
763
+ PLYValue[PLYValue["MIN_SCALE_Y"] = 7] = "MIN_SCALE_Y";
764
+ PLYValue[PLYValue["MIN_SCALE_Z"] = 8] = "MIN_SCALE_Z";
765
+ PLYValue[PLYValue["MAX_SCALE_X"] = 9] = "MAX_SCALE_X";
766
+ PLYValue[PLYValue["MAX_SCALE_Y"] = 10] = "MAX_SCALE_Y";
767
+ PLYValue[PLYValue["MAX_SCALE_Z"] = 11] = "MAX_SCALE_Z";
768
+ PLYValue[PLYValue["PACKED_POSITION"] = 12] = "PACKED_POSITION";
769
+ PLYValue[PLYValue["PACKED_ROTATION"] = 13] = "PACKED_ROTATION";
770
+ PLYValue[PLYValue["PACKED_SCALE"] = 14] = "PACKED_SCALE";
771
+ PLYValue[PLYValue["PACKED_COLOR"] = 15] = "PACKED_COLOR";
772
+ PLYValue[PLYValue["X"] = 16] = "X";
773
+ PLYValue[PLYValue["Y"] = 17] = "Y";
774
+ PLYValue[PLYValue["Z"] = 18] = "Z";
775
+ PLYValue[PLYValue["SCALE_0"] = 19] = "SCALE_0";
776
+ PLYValue[PLYValue["SCALE_1"] = 20] = "SCALE_1";
777
+ PLYValue[PLYValue["SCALE_2"] = 21] = "SCALE_2";
778
+ PLYValue[PLYValue["DIFFUSE_RED"] = 22] = "DIFFUSE_RED";
779
+ PLYValue[PLYValue["DIFFUSE_GREEN"] = 23] = "DIFFUSE_GREEN";
780
+ PLYValue[PLYValue["DIFFUSE_BLUE"] = 24] = "DIFFUSE_BLUE";
781
+ PLYValue[PLYValue["OPACITY"] = 25] = "OPACITY";
782
+ PLYValue[PLYValue["F_DC_0"] = 26] = "F_DC_0";
783
+ PLYValue[PLYValue["F_DC_1"] = 27] = "F_DC_1";
784
+ PLYValue[PLYValue["F_DC_2"] = 28] = "F_DC_2";
785
+ PLYValue[PLYValue["F_DC_3"] = 29] = "F_DC_3";
786
+ PLYValue[PLYValue["ROT_0"] = 30] = "ROT_0";
787
+ PLYValue[PLYValue["ROT_1"] = 31] = "ROT_1";
788
+ PLYValue[PLYValue["ROT_2"] = 32] = "ROT_2";
789
+ PLYValue[PLYValue["ROT_3"] = 33] = "ROT_3";
790
+ PLYValue[PLYValue["MIN_COLOR_R"] = 34] = "MIN_COLOR_R";
791
+ PLYValue[PLYValue["MIN_COLOR_G"] = 35] = "MIN_COLOR_G";
792
+ PLYValue[PLYValue["MIN_COLOR_B"] = 36] = "MIN_COLOR_B";
793
+ PLYValue[PLYValue["MAX_COLOR_R"] = 37] = "MAX_COLOR_R";
794
+ PLYValue[PLYValue["MAX_COLOR_G"] = 38] = "MAX_COLOR_G";
795
+ PLYValue[PLYValue["MAX_COLOR_B"] = 39] = "MAX_COLOR_B";
796
+ PLYValue[PLYValue["SH_0"] = 40] = "SH_0";
797
+ PLYValue[PLYValue["SH_1"] = 41] = "SH_1";
798
+ PLYValue[PLYValue["SH_2"] = 42] = "SH_2";
799
+ PLYValue[PLYValue["SH_3"] = 43] = "SH_3";
800
+ PLYValue[PLYValue["SH_4"] = 44] = "SH_4";
801
+ PLYValue[PLYValue["SH_5"] = 45] = "SH_5";
802
+ PLYValue[PLYValue["SH_6"] = 46] = "SH_6";
803
+ PLYValue[PLYValue["SH_7"] = 47] = "SH_7";
804
+ PLYValue[PLYValue["SH_8"] = 48] = "SH_8";
805
+ PLYValue[PLYValue["SH_9"] = 49] = "SH_9";
806
+ PLYValue[PLYValue["SH_10"] = 50] = "SH_10";
807
+ PLYValue[PLYValue["SH_11"] = 51] = "SH_11";
808
+ PLYValue[PLYValue["SH_12"] = 52] = "SH_12";
809
+ PLYValue[PLYValue["SH_13"] = 53] = "SH_13";
810
+ PLYValue[PLYValue["SH_14"] = 54] = "SH_14";
811
+ PLYValue[PLYValue["SH_15"] = 55] = "SH_15";
812
+ PLYValue[PLYValue["SH_16"] = 56] = "SH_16";
813
+ PLYValue[PLYValue["SH_17"] = 57] = "SH_17";
814
+ PLYValue[PLYValue["SH_18"] = 58] = "SH_18";
815
+ PLYValue[PLYValue["SH_19"] = 59] = "SH_19";
816
+ PLYValue[PLYValue["SH_20"] = 60] = "SH_20";
817
+ PLYValue[PLYValue["SH_21"] = 61] = "SH_21";
818
+ PLYValue[PLYValue["SH_22"] = 62] = "SH_22";
819
+ PLYValue[PLYValue["SH_23"] = 63] = "SH_23";
820
+ PLYValue[PLYValue["SH_24"] = 64] = "SH_24";
821
+ PLYValue[PLYValue["SH_25"] = 65] = "SH_25";
822
+ PLYValue[PLYValue["SH_26"] = 66] = "SH_26";
823
+ PLYValue[PLYValue["SH_27"] = 67] = "SH_27";
824
+ PLYValue[PLYValue["SH_28"] = 68] = "SH_28";
825
+ PLYValue[PLYValue["SH_29"] = 69] = "SH_29";
826
+ PLYValue[PLYValue["SH_30"] = 70] = "SH_30";
827
+ PLYValue[PLYValue["SH_31"] = 71] = "SH_31";
828
+ PLYValue[PLYValue["SH_32"] = 72] = "SH_32";
829
+ PLYValue[PLYValue["SH_33"] = 73] = "SH_33";
830
+ PLYValue[PLYValue["SH_34"] = 74] = "SH_34";
831
+ PLYValue[PLYValue["SH_35"] = 75] = "SH_35";
832
+ PLYValue[PLYValue["SH_36"] = 76] = "SH_36";
833
+ PLYValue[PLYValue["SH_37"] = 77] = "SH_37";
834
+ PLYValue[PLYValue["SH_38"] = 78] = "SH_38";
835
+ PLYValue[PLYValue["SH_39"] = 79] = "SH_39";
836
+ PLYValue[PLYValue["SH_40"] = 80] = "SH_40";
837
+ PLYValue[PLYValue["SH_41"] = 81] = "SH_41";
838
+ PLYValue[PLYValue["SH_42"] = 82] = "SH_42";
839
+ PLYValue[PLYValue["SH_43"] = 83] = "SH_43";
840
+ PLYValue[PLYValue["SH_44"] = 84] = "SH_44";
841
+ PLYValue[PLYValue["UNDEFINED"] = 85] = "UNDEFINED";
842
+ })(PLYValue || (PLYValue = {}));
843
+ /**
844
+ * Class used to render a gaussian splatting mesh
845
+ */
846
+ class GaussianSplattingMesh extends Mesh {
847
+ /**
848
+ * SH degree. 0 = no sh (default). 1 = 3 parameters. 2 = 8 parameters. 3 = 15 parameters.
849
+ */
850
+ get shDegree() {
851
+ return this._shDegree;
852
+ }
853
+ /**
854
+ * returns the splats data array buffer that contains in order : postions (3 floats), size (3 floats), color (4 bytes), orientation quaternion (4 bytes)
855
+ */
856
+ get splatsData() {
857
+ return this._splatsData;
858
+ }
859
+ /**
860
+ * Gets the covariancesA texture
861
+ */
862
+ get covariancesATexture() {
863
+ return this._covariancesATexture;
864
+ }
865
+ /**
866
+ * Gets the covariancesB texture
867
+ */
868
+ get covariancesBTexture() {
869
+ return this._covariancesBTexture;
870
+ }
871
+ /**
872
+ * Gets the centers texture
873
+ */
874
+ get centersTexture() {
875
+ return this._centersTexture;
876
+ }
877
+ /**
878
+ * Gets the colors texture
879
+ */
880
+ get colorsTexture() {
881
+ return this._colorsTexture;
882
+ }
883
+ /**
884
+ * Gets the SH textures
885
+ */
886
+ get shTextures() {
887
+ return this._shTextures;
888
+ }
889
+ /**
890
+ * set rendering material
891
+ */
892
+ set material(value) {
893
+ this._material = value;
894
+ this._material.backFaceCulling = true;
895
+ this._material.cullBackFaces = false;
896
+ value.resetDrawCache();
897
+ }
898
+ /**
899
+ * get rendering material
900
+ */
901
+ get material() {
902
+ return this._material;
903
+ }
904
+ /**
905
+ * Creates a new gaussian splatting mesh
906
+ * @param name defines the name of the mesh
907
+ * @param url defines the url to load from (optional)
908
+ * @param scene defines the hosting scene (optional)
909
+ * @param keepInRam keep datas in ram for editing purpose
910
+ */
911
+ constructor(name, url = null, scene = null, keepInRam = false) {
912
+ super(name, scene);
913
+ this._vertexCount = 0;
914
+ this._worker = null;
915
+ this._frameIdLastUpdate = -1;
916
+ this._modelViewMatrix = Matrix.Identity();
917
+ this._canPostToWorker = true;
918
+ this._readyToDisplay = false;
919
+ this._covariancesATexture = null;
920
+ this._covariancesBTexture = null;
921
+ this._centersTexture = null;
922
+ this._colorsTexture = null;
923
+ this._splatPositions = null;
924
+ this._splatIndex = null;
925
+ this._shTextures = null;
926
+ this._splatsData = null;
927
+ this._sh = null;
928
+ this._keepInRam = false;
929
+ this._delayedTextureUpdate = null;
930
+ this._oldDirection = new Vector3();
931
+ this._useRGBACovariants = false;
932
+ this._material = null;
933
+ this._tmpCovariances = [0, 0, 0, 0, 0, 0];
934
+ this._sortIsDirty = false;
935
+ this._shDegree = 0;
936
+ const vertexData = new VertexData();
937
+ // Use an intanced quad or triangle. Triangle might be a bit faster because of less shader invocation but I didn't see any difference.
938
+ // Keeping both and use triangle for now.
939
+ // for quad, use following lines
940
+ //vertexData.positions = [-2, -2, 0, 2, -2, 0, 2, 2, 0, -2, 2, 0];
941
+ //vertexData.indices = [0, 1, 2, 0, 2, 3];
942
+ vertexData.positions = [-3, -2, 0, 3, -2, 0, 0, 4, 0];
943
+ vertexData.indices = [0, 1, 2];
944
+ vertexData.applyToMesh(this);
945
+ this.subMeshes = [];
946
+ // for quad, use following line
947
+ //new SubMesh(0, 0, 4, 0, 6, this);
948
+ new SubMesh(0, 0, 3, 0, 3, this);
949
+ this.setEnabled(false);
950
+ // webGL2 and webGPU support for RG texture with float16 is fine. not webGL1
951
+ this._useRGBACovariants = !this.getEngine().isWebGPU && this.getEngine().version === 1.0;
952
+ this._keepInRam = keepInRam;
953
+ if (url) {
954
+ this.loadFileAsync(url);
955
+ }
956
+ this._material = new GaussianSplattingMaterial(this.name + "_material", this._scene);
957
+ }
958
+ /**
959
+ * Returns the class name
960
+ * @returns "GaussianSplattingMesh"
961
+ */
962
+ getClassName() {
963
+ return "GaussianSplattingMesh";
964
+ }
965
+ /**
966
+ * Returns the total number of vertices (splats) within the mesh
967
+ * @returns the total number of vertices
968
+ */
969
+ getTotalVertices() {
970
+ return this._vertexCount;
971
+ }
972
+ /**
973
+ * Is this node ready to be used/rendered
974
+ * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
975
+ * @returns true when ready
976
+ */
977
+ isReady(completeCheck = false) {
978
+ if (!super.isReady(completeCheck, true)) {
979
+ return false;
980
+ }
981
+ if (!this._readyToDisplay) {
982
+ // mesh is ready when worker has done at least 1 sorting
983
+ this._postToWorker(true);
984
+ return false;
985
+ }
986
+ return true;
987
+ }
988
+ /** @internal */
989
+ _postToWorker(forced = false) {
990
+ const frameId = this.getScene().getFrameId();
991
+ if ((forced || frameId !== this._frameIdLastUpdate) && this._worker && this._scene.activeCamera && this._canPostToWorker) {
992
+ const cameraMatrix = this._scene.activeCamera.getViewMatrix();
993
+ this.getWorldMatrix().multiplyToRef(cameraMatrix, this._modelViewMatrix);
994
+ cameraMatrix.invertToRef(TmpVectors.Matrix[0]);
995
+ this.getWorldMatrix().multiplyToRef(TmpVectors.Matrix[0], TmpVectors.Matrix[1]);
996
+ Vector3.TransformNormalToRef(Vector3.Forward(this._scene.useRightHandedSystem), TmpVectors.Matrix[1], TmpVectors.Vector3[2]);
997
+ TmpVectors.Vector3[2].normalize();
998
+ const dot = Vector3.Dot(TmpVectors.Vector3[2], this._oldDirection);
999
+ if (forced || Math.abs(dot - 1) >= 0.01) {
1000
+ this._oldDirection.copyFrom(TmpVectors.Vector3[2]);
1001
+ this._frameIdLastUpdate = frameId;
1002
+ this._canPostToWorker = false;
1003
+ this._worker.postMessage({ view: this._modelViewMatrix.m, depthMix: this._depthMix, useRightHandedSystem: this._scene.useRightHandedSystem }, [
1004
+ this._depthMix.buffer,
1005
+ ]);
1006
+ }
1007
+ }
1008
+ }
1009
+ /**
1010
+ * Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
1011
+ * @param subMesh defines the subMesh to render
1012
+ * @param enableAlphaMode defines if alpha mode can be changed
1013
+ * @param effectiveMeshReplacement defines an optional mesh used to provide info for the rendering
1014
+ * @returns the current mesh
1015
+ */
1016
+ render(subMesh, enableAlphaMode, effectiveMeshReplacement) {
1017
+ this._postToWorker();
1018
+ return super.render(subMesh, enableAlphaMode, effectiveMeshReplacement);
1019
+ }
1020
+ static _TypeNameToEnum(name) {
1021
+ switch (name) {
1022
+ case "float":
1023
+ return 0 /* PLYType.FLOAT */;
1024
+ case "int":
1025
+ return 1 /* PLYType.INT */;
1026
+ case "uint":
1027
+ return 2 /* PLYType.UINT */;
1028
+ case "double":
1029
+ return 3 /* PLYType.DOUBLE */;
1030
+ case "uchar":
1031
+ return 4 /* PLYType.UCHAR */;
1032
+ }
1033
+ return 5 /* PLYType.UNDEFINED */;
1034
+ }
1035
+ static _ValueNameToEnum(name) {
1036
+ switch (name) {
1037
+ case "min_x":
1038
+ return 0 /* PLYValue.MIN_X */;
1039
+ case "min_y":
1040
+ return 1 /* PLYValue.MIN_Y */;
1041
+ case "min_z":
1042
+ return 2 /* PLYValue.MIN_Z */;
1043
+ case "max_x":
1044
+ return 3 /* PLYValue.MAX_X */;
1045
+ case "max_y":
1046
+ return 4 /* PLYValue.MAX_Y */;
1047
+ case "max_z":
1048
+ return 5 /* PLYValue.MAX_Z */;
1049
+ case "min_scale_x":
1050
+ return 6 /* PLYValue.MIN_SCALE_X */;
1051
+ case "min_scale_y":
1052
+ return 7 /* PLYValue.MIN_SCALE_Y */;
1053
+ case "min_scale_z":
1054
+ return 8 /* PLYValue.MIN_SCALE_Z */;
1055
+ case "max_scale_x":
1056
+ return 9 /* PLYValue.MAX_SCALE_X */;
1057
+ case "max_scale_y":
1058
+ return 10 /* PLYValue.MAX_SCALE_Y */;
1059
+ case "max_scale_z":
1060
+ return 11 /* PLYValue.MAX_SCALE_Z */;
1061
+ case "packed_position":
1062
+ return 12 /* PLYValue.PACKED_POSITION */;
1063
+ case "packed_rotation":
1064
+ return 13 /* PLYValue.PACKED_ROTATION */;
1065
+ case "packed_scale":
1066
+ return 14 /* PLYValue.PACKED_SCALE */;
1067
+ case "packed_color":
1068
+ return 15 /* PLYValue.PACKED_COLOR */;
1069
+ case "x":
1070
+ return 16 /* PLYValue.X */;
1071
+ case "y":
1072
+ return 17 /* PLYValue.Y */;
1073
+ case "z":
1074
+ return 18 /* PLYValue.Z */;
1075
+ case "scale_0":
1076
+ return 19 /* PLYValue.SCALE_0 */;
1077
+ case "scale_1":
1078
+ return 20 /* PLYValue.SCALE_1 */;
1079
+ case "scale_2":
1080
+ return 21 /* PLYValue.SCALE_2 */;
1081
+ case "diffuse_red":
1082
+ case "red":
1083
+ return 22 /* PLYValue.DIFFUSE_RED */;
1084
+ case "diffuse_green":
1085
+ case "green":
1086
+ return 23 /* PLYValue.DIFFUSE_GREEN */;
1087
+ case "diffuse_blue":
1088
+ case "blue":
1089
+ return 24 /* PLYValue.DIFFUSE_BLUE */;
1090
+ case "f_dc_0":
1091
+ return 26 /* PLYValue.F_DC_0 */;
1092
+ case "f_dc_1":
1093
+ return 27 /* PLYValue.F_DC_1 */;
1094
+ case "f_dc_2":
1095
+ return 28 /* PLYValue.F_DC_2 */;
1096
+ case "f_dc_3":
1097
+ return 29 /* PLYValue.F_DC_3 */;
1098
+ case "opacity":
1099
+ return 25 /* PLYValue.OPACITY */;
1100
+ case "rot_0":
1101
+ return 30 /* PLYValue.ROT_0 */;
1102
+ case "rot_1":
1103
+ return 31 /* PLYValue.ROT_1 */;
1104
+ case "rot_2":
1105
+ return 32 /* PLYValue.ROT_2 */;
1106
+ case "rot_3":
1107
+ return 33 /* PLYValue.ROT_3 */;
1108
+ case "min_r":
1109
+ return 34 /* PLYValue.MIN_COLOR_R */;
1110
+ case "min_g":
1111
+ return 35 /* PLYValue.MIN_COLOR_G */;
1112
+ case "min_b":
1113
+ return 36 /* PLYValue.MIN_COLOR_B */;
1114
+ case "max_r":
1115
+ return 37 /* PLYValue.MAX_COLOR_R */;
1116
+ case "max_g":
1117
+ return 38 /* PLYValue.MAX_COLOR_G */;
1118
+ case "max_b":
1119
+ return 39 /* PLYValue.MAX_COLOR_B */;
1120
+ case "f_rest_0":
1121
+ return 40 /* PLYValue.SH_0 */;
1122
+ case "f_rest_1":
1123
+ return 41 /* PLYValue.SH_1 */;
1124
+ case "f_rest_2":
1125
+ return 42 /* PLYValue.SH_2 */;
1126
+ case "f_rest_3":
1127
+ return 43 /* PLYValue.SH_3 */;
1128
+ case "f_rest_4":
1129
+ return 44 /* PLYValue.SH_4 */;
1130
+ case "f_rest_5":
1131
+ return 45 /* PLYValue.SH_5 */;
1132
+ case "f_rest_6":
1133
+ return 46 /* PLYValue.SH_6 */;
1134
+ case "f_rest_7":
1135
+ return 47 /* PLYValue.SH_7 */;
1136
+ case "f_rest_8":
1137
+ return 48 /* PLYValue.SH_8 */;
1138
+ case "f_rest_9":
1139
+ return 49 /* PLYValue.SH_9 */;
1140
+ case "f_rest_10":
1141
+ return 50 /* PLYValue.SH_10 */;
1142
+ case "f_rest_11":
1143
+ return 51 /* PLYValue.SH_11 */;
1144
+ case "f_rest_12":
1145
+ return 52 /* PLYValue.SH_12 */;
1146
+ case "f_rest_13":
1147
+ return 53 /* PLYValue.SH_13 */;
1148
+ case "f_rest_14":
1149
+ return 54 /* PLYValue.SH_14 */;
1150
+ case "f_rest_15":
1151
+ return 55 /* PLYValue.SH_15 */;
1152
+ case "f_rest_16":
1153
+ return 56 /* PLYValue.SH_16 */;
1154
+ case "f_rest_17":
1155
+ return 57 /* PLYValue.SH_17 */;
1156
+ case "f_rest_18":
1157
+ return 58 /* PLYValue.SH_18 */;
1158
+ case "f_rest_19":
1159
+ return 59 /* PLYValue.SH_19 */;
1160
+ case "f_rest_20":
1161
+ return 60 /* PLYValue.SH_20 */;
1162
+ case "f_rest_21":
1163
+ return 61 /* PLYValue.SH_21 */;
1164
+ case "f_rest_22":
1165
+ return 62 /* PLYValue.SH_22 */;
1166
+ case "f_rest_23":
1167
+ return 63 /* PLYValue.SH_23 */;
1168
+ case "f_rest_24":
1169
+ return 64 /* PLYValue.SH_24 */;
1170
+ case "f_rest_25":
1171
+ return 65 /* PLYValue.SH_25 */;
1172
+ case "f_rest_26":
1173
+ return 66 /* PLYValue.SH_26 */;
1174
+ case "f_rest_27":
1175
+ return 67 /* PLYValue.SH_27 */;
1176
+ case "f_rest_28":
1177
+ return 68 /* PLYValue.SH_28 */;
1178
+ case "f_rest_29":
1179
+ return 69 /* PLYValue.SH_29 */;
1180
+ case "f_rest_30":
1181
+ return 70 /* PLYValue.SH_30 */;
1182
+ case "f_rest_31":
1183
+ return 71 /* PLYValue.SH_31 */;
1184
+ case "f_rest_32":
1185
+ return 72 /* PLYValue.SH_32 */;
1186
+ case "f_rest_33":
1187
+ return 73 /* PLYValue.SH_33 */;
1188
+ case "f_rest_34":
1189
+ return 74 /* PLYValue.SH_34 */;
1190
+ case "f_rest_35":
1191
+ return 75 /* PLYValue.SH_35 */;
1192
+ case "f_rest_36":
1193
+ return 76 /* PLYValue.SH_36 */;
1194
+ case "f_rest_37":
1195
+ return 77 /* PLYValue.SH_37 */;
1196
+ case "f_rest_38":
1197
+ return 78 /* PLYValue.SH_38 */;
1198
+ case "f_rest_39":
1199
+ return 79 /* PLYValue.SH_39 */;
1200
+ case "f_rest_40":
1201
+ return 80 /* PLYValue.SH_40 */;
1202
+ case "f_rest_41":
1203
+ return 81 /* PLYValue.SH_41 */;
1204
+ case "f_rest_42":
1205
+ return 82 /* PLYValue.SH_42 */;
1206
+ case "f_rest_43":
1207
+ return 83 /* PLYValue.SH_43 */;
1208
+ case "f_rest_44":
1209
+ return 84 /* PLYValue.SH_44 */;
1210
+ }
1211
+ return 85 /* PLYValue.UNDEFINED */;
1212
+ }
1213
+ /**
1214
+ * Parse a PLY file header and returns metas infos on splats and chunks
1215
+ * @param data the loaded buffer
1216
+ * @returns a PLYHeader
1217
+ */
1218
+ static ParseHeader(data) {
1219
+ const ubuf = new Uint8Array(data);
1220
+ const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));
1221
+ const headerEnd = "end_header\n";
1222
+ const headerEndIndex = header.indexOf(headerEnd);
1223
+ if (headerEndIndex < 0 || !header) {
1224
+ // standard splat
1225
+ return null;
1226
+ }
1227
+ const vertexCount = parseInt(/element vertex (\d+)\n/.exec(header)[1]);
1228
+ const chunkElement = /element chunk (\d+)\n/.exec(header);
1229
+ let chunkCount = 0;
1230
+ if (chunkElement) {
1231
+ chunkCount = parseInt(chunkElement[1]);
1232
+ }
1233
+ let rowVertexOffset = 0;
1234
+ let rowChunkOffset = 0;
1235
+ const offsets = {
1236
+ double: 8,
1237
+ int: 4,
1238
+ uint: 4,
1239
+ float: 4,
1240
+ short: 2,
1241
+ ushort: 2,
1242
+ uchar: 1,
1243
+ list: 0,
1244
+ };
1245
+ let ElementMode;
1246
+ (function (ElementMode) {
1247
+ ElementMode[ElementMode["Vertex"] = 0] = "Vertex";
1248
+ ElementMode[ElementMode["Chunk"] = 1] = "Chunk";
1249
+ })(ElementMode || (ElementMode = {}));
1250
+ let chunkMode = 1 /* ElementMode.Chunk */;
1251
+ const vertexProperties = [];
1252
+ const chunkProperties = [];
1253
+ const filtered = header.slice(0, headerEndIndex).split("\n");
1254
+ let shDegree = 0;
1255
+ for (const prop of filtered) {
1256
+ if (prop.startsWith("property ")) {
1257
+ const [, typeName, name] = prop.split(" ");
1258
+ const value = GaussianSplattingMesh._ValueNameToEnum(name);
1259
+ // SH degree 1,2 or 3 for 9, 24 or 45 values
1260
+ if (value >= 84 /* PLYValue.SH_44 */) {
1261
+ shDegree = 3;
1262
+ }
1263
+ else if (value >= 64 /* PLYValue.SH_24 */) {
1264
+ shDegree = 2;
1265
+ }
1266
+ else if (value >= 48 /* PLYValue.SH_8 */) {
1267
+ shDegree = 1;
1268
+ }
1269
+ const type = GaussianSplattingMesh._TypeNameToEnum(typeName);
1270
+ if (chunkMode == 1 /* ElementMode.Chunk */) {
1271
+ chunkProperties.push({ value, type, offset: rowChunkOffset });
1272
+ rowChunkOffset += offsets[typeName];
1273
+ }
1274
+ else if (chunkMode == 0 /* ElementMode.Vertex */) {
1275
+ vertexProperties.push({ value, type, offset: rowVertexOffset });
1276
+ rowVertexOffset += offsets[typeName];
1277
+ }
1278
+ if (!offsets[typeName]) {
1279
+ Logger.Warn(`Unsupported property type: ${typeName}.`);
1280
+ }
1281
+ }
1282
+ else if (prop.startsWith("element ")) {
1283
+ const [, type] = prop.split(" ");
1284
+ if (type == "chunk") {
1285
+ chunkMode = 1 /* ElementMode.Chunk */;
1286
+ }
1287
+ else if (type == "vertex") {
1288
+ chunkMode = 0 /* ElementMode.Vertex */;
1289
+ }
1290
+ }
1291
+ }
1292
+ const dataView = new DataView(data, headerEndIndex + headerEnd.length);
1293
+ const buffer = new ArrayBuffer(GaussianSplattingMesh._RowOutputLength * vertexCount);
1294
+ let shBuffer = null;
1295
+ let shCoefficientCount = 0;
1296
+ if (shDegree) {
1297
+ const shVectorCount = (shDegree + 1) * (shDegree + 1) - 1;
1298
+ shCoefficientCount = shVectorCount * 3;
1299
+ shBuffer = new ArrayBuffer(shCoefficientCount * vertexCount);
1300
+ }
1301
+ return {
1302
+ vertexCount: vertexCount,
1303
+ chunkCount: chunkCount,
1304
+ rowVertexLength: rowVertexOffset,
1305
+ rowChunkLength: rowChunkOffset,
1306
+ vertexProperties: vertexProperties,
1307
+ chunkProperties: chunkProperties,
1308
+ dataView: dataView,
1309
+ buffer: buffer,
1310
+ shDegree: shDegree,
1311
+ shCoefficientCount: shCoefficientCount,
1312
+ shBuffer: shBuffer,
1313
+ };
1314
+ }
1315
+ static _GetCompressedChunks(header, offset) {
1316
+ if (!header.chunkCount) {
1317
+ return null;
1318
+ }
1319
+ const dataView = header.dataView;
1320
+ const compressedChunks = new Array(header.chunkCount);
1321
+ for (let i = 0; i < header.chunkCount; i++) {
1322
+ const currentChunk = {
1323
+ min: new Vector3(),
1324
+ max: new Vector3(),
1325
+ minScale: new Vector3(),
1326
+ maxScale: new Vector3(),
1327
+ minColor: new Vector3(0, 0, 0),
1328
+ maxColor: new Vector3(1, 1, 1),
1329
+ };
1330
+ compressedChunks[i] = currentChunk;
1331
+ for (let propertyIndex = 0; propertyIndex < header.chunkProperties.length; propertyIndex++) {
1332
+ const property = header.chunkProperties[propertyIndex];
1333
+ let value;
1334
+ switch (property.type) {
1335
+ case 0 /* PLYType.FLOAT */:
1336
+ value = dataView.getFloat32(property.offset + offset.value, true);
1337
+ break;
1338
+ default:
1339
+ continue;
1340
+ }
1341
+ switch (property.value) {
1342
+ case 0 /* PLYValue.MIN_X */:
1343
+ currentChunk.min.x = value;
1344
+ break;
1345
+ case 1 /* PLYValue.MIN_Y */:
1346
+ currentChunk.min.y = value;
1347
+ break;
1348
+ case 2 /* PLYValue.MIN_Z */:
1349
+ currentChunk.min.z = value;
1350
+ break;
1351
+ case 3 /* PLYValue.MAX_X */:
1352
+ currentChunk.max.x = value;
1353
+ break;
1354
+ case 4 /* PLYValue.MAX_Y */:
1355
+ currentChunk.max.y = value;
1356
+ break;
1357
+ case 5 /* PLYValue.MAX_Z */:
1358
+ currentChunk.max.z = value;
1359
+ break;
1360
+ case 6 /* PLYValue.MIN_SCALE_X */:
1361
+ currentChunk.minScale.x = value;
1362
+ break;
1363
+ case 7 /* PLYValue.MIN_SCALE_Y */:
1364
+ currentChunk.minScale.y = value;
1365
+ break;
1366
+ case 8 /* PLYValue.MIN_SCALE_Z */:
1367
+ currentChunk.minScale.z = value;
1368
+ break;
1369
+ case 9 /* PLYValue.MAX_SCALE_X */:
1370
+ currentChunk.maxScale.x = value;
1371
+ break;
1372
+ case 10 /* PLYValue.MAX_SCALE_Y */:
1373
+ currentChunk.maxScale.y = value;
1374
+ break;
1375
+ case 11 /* PLYValue.MAX_SCALE_Z */:
1376
+ currentChunk.maxScale.z = value;
1377
+ break;
1378
+ case 34 /* PLYValue.MIN_COLOR_R */:
1379
+ currentChunk.minColor.x = value;
1380
+ break;
1381
+ case 35 /* PLYValue.MIN_COLOR_G */:
1382
+ currentChunk.minColor.y = value;
1383
+ break;
1384
+ case 36 /* PLYValue.MIN_COLOR_B */:
1385
+ currentChunk.minColor.z = value;
1386
+ break;
1387
+ case 37 /* PLYValue.MAX_COLOR_R */:
1388
+ currentChunk.maxColor.x = value;
1389
+ break;
1390
+ case 38 /* PLYValue.MAX_COLOR_G */:
1391
+ currentChunk.maxColor.y = value;
1392
+ break;
1393
+ case 39 /* PLYValue.MAX_COLOR_B */:
1394
+ currentChunk.maxColor.z = value;
1395
+ break;
1396
+ }
1397
+ }
1398
+ offset.value += header.rowChunkLength;
1399
+ }
1400
+ return compressedChunks;
1401
+ }
1402
+ static _GetSplat(header, index, compressedChunks, offset) {
1403
+ const q = TmpVectors.Quaternion[0];
1404
+ const temp3 = TmpVectors.Vector3[0];
1405
+ const rowOutputLength = GaussianSplattingMesh._RowOutputLength;
1406
+ const buffer = header.buffer;
1407
+ const dataView = header.dataView;
1408
+ const position = new Float32Array(buffer, index * rowOutputLength, 3);
1409
+ const scale = new Float32Array(buffer, index * rowOutputLength + 12, 3);
1410
+ const rgba = new Uint8ClampedArray(buffer, index * rowOutputLength + 24, 4);
1411
+ const rot = new Uint8ClampedArray(buffer, index * rowOutputLength + 28, 4);
1412
+ let sh = null;
1413
+ if (header.shBuffer) {
1414
+ sh = new Uint8ClampedArray(header.shBuffer, index * header.shCoefficientCount, header.shCoefficientCount);
1415
+ }
1416
+ const chunkIndex = index >> 8;
1417
+ let r0 = 255;
1418
+ let r1 = 0;
1419
+ let r2 = 0;
1420
+ let r3 = 0;
1421
+ for (let propertyIndex = 0; propertyIndex < header.vertexProperties.length; propertyIndex++) {
1422
+ const property = header.vertexProperties[propertyIndex];
1423
+ let value;
1424
+ switch (property.type) {
1425
+ case 0 /* PLYType.FLOAT */:
1426
+ value = dataView.getFloat32(offset.value + property.offset, true);
1427
+ break;
1428
+ case 1 /* PLYType.INT */:
1429
+ value = dataView.getInt32(offset.value + property.offset, true);
1430
+ break;
1431
+ case 2 /* PLYType.UINT */:
1432
+ value = dataView.getUint32(offset.value + property.offset, true);
1433
+ break;
1434
+ case 3 /* PLYType.DOUBLE */:
1435
+ value = dataView.getFloat64(offset.value + property.offset, true);
1436
+ break;
1437
+ case 4 /* PLYType.UCHAR */:
1438
+ value = dataView.getUint8(offset.value + property.offset);
1439
+ break;
1440
+ default:
1441
+ continue;
1442
+ }
1443
+ switch (property.value) {
1444
+ case 12 /* PLYValue.PACKED_POSITION */:
1445
+ {
1446
+ const compressedChunk = compressedChunks[chunkIndex];
1447
+ unpack111011(value, temp3);
1448
+ position[0] = Scalar.Lerp(compressedChunk.min.x, compressedChunk.max.x, temp3.x);
1449
+ position[1] = Scalar.Lerp(compressedChunk.min.y, compressedChunk.max.y, temp3.y);
1450
+ position[2] = Scalar.Lerp(compressedChunk.min.z, compressedChunk.max.z, temp3.z);
1451
+ }
1452
+ break;
1453
+ case 13 /* PLYValue.PACKED_ROTATION */:
1454
+ {
1455
+ unpackRot(value, q);
1456
+ r0 = q.w;
1457
+ r1 = -q.z;
1458
+ r2 = q.y;
1459
+ r3 = -q.x;
1460
+ }
1461
+ break;
1462
+ case 14 /* PLYValue.PACKED_SCALE */:
1463
+ {
1464
+ const compressedChunk = compressedChunks[chunkIndex];
1465
+ unpack111011(value, temp3);
1466
+ scale[0] = Math.exp(Scalar.Lerp(compressedChunk.minScale.x, compressedChunk.maxScale.x, temp3.x));
1467
+ scale[1] = Math.exp(Scalar.Lerp(compressedChunk.minScale.y, compressedChunk.maxScale.y, temp3.y));
1468
+ scale[2] = Math.exp(Scalar.Lerp(compressedChunk.minScale.z, compressedChunk.maxScale.z, temp3.z));
1469
+ }
1470
+ break;
1471
+ case 15 /* PLYValue.PACKED_COLOR */:
1472
+ {
1473
+ const compressedChunk = compressedChunks[chunkIndex];
1474
+ unpack8888(value, rgba);
1475
+ rgba[0] = Scalar.Lerp(compressedChunk.minColor.x, compressedChunk.maxColor.x, rgba[0] / 255) * 255;
1476
+ rgba[1] = Scalar.Lerp(compressedChunk.minColor.y, compressedChunk.maxColor.y, rgba[1] / 255) * 255;
1477
+ rgba[2] = Scalar.Lerp(compressedChunk.minColor.z, compressedChunk.maxColor.z, rgba[2] / 255) * 255;
1478
+ }
1479
+ break;
1480
+ case 16 /* PLYValue.X */:
1481
+ position[0] = value;
1482
+ break;
1483
+ case 17 /* PLYValue.Y */:
1484
+ position[1] = value;
1485
+ break;
1486
+ case 18 /* PLYValue.Z */:
1487
+ position[2] = value;
1488
+ break;
1489
+ case 19 /* PLYValue.SCALE_0 */:
1490
+ scale[0] = Math.exp(value);
1491
+ break;
1492
+ case 20 /* PLYValue.SCALE_1 */:
1493
+ scale[1] = Math.exp(value);
1494
+ break;
1495
+ case 21 /* PLYValue.SCALE_2 */:
1496
+ scale[2] = Math.exp(value);
1497
+ break;
1498
+ case 22 /* PLYValue.DIFFUSE_RED */:
1499
+ rgba[0] = value;
1500
+ break;
1501
+ case 23 /* PLYValue.DIFFUSE_GREEN */:
1502
+ rgba[1] = value;
1503
+ break;
1504
+ case 24 /* PLYValue.DIFFUSE_BLUE */:
1505
+ rgba[2] = value;
1506
+ break;
1507
+ case 26 /* PLYValue.F_DC_0 */:
1508
+ rgba[0] = (0.5 + GaussianSplattingMesh._SH_C0 * value) * 255;
1509
+ break;
1510
+ case 27 /* PLYValue.F_DC_1 */:
1511
+ rgba[1] = (0.5 + GaussianSplattingMesh._SH_C0 * value) * 255;
1512
+ break;
1513
+ case 28 /* PLYValue.F_DC_2 */:
1514
+ rgba[2] = (0.5 + GaussianSplattingMesh._SH_C0 * value) * 255;
1515
+ break;
1516
+ case 29 /* PLYValue.F_DC_3 */:
1517
+ rgba[3] = (0.5 + GaussianSplattingMesh._SH_C0 * value) * 255;
1518
+ break;
1519
+ case 25 /* PLYValue.OPACITY */:
1520
+ rgba[3] = (1 / (1 + Math.exp(-value))) * 255;
1521
+ break;
1522
+ case 30 /* PLYValue.ROT_0 */:
1523
+ r0 = value;
1524
+ break;
1525
+ case 31 /* PLYValue.ROT_1 */:
1526
+ r1 = value;
1527
+ break;
1528
+ case 32 /* PLYValue.ROT_2 */:
1529
+ r2 = value;
1530
+ break;
1531
+ case 33 /* PLYValue.ROT_3 */:
1532
+ r3 = value;
1533
+ break;
1534
+ }
1535
+ if (sh && property.value >= 40 /* PLYValue.SH_0 */ && property.value <= 84 /* PLYValue.SH_44 */) {
1536
+ const clampedValue = Scalar.Clamp(value * 127.5 + 127.5, 0, 255);
1537
+ const shIndex = property.value - 40 /* PLYValue.SH_0 */;
1538
+ sh[shIndex] = clampedValue;
1539
+ }
1540
+ }
1541
+ q.set(r1, r2, r3, r0);
1542
+ q.normalize();
1543
+ rot[0] = q.w * 128 + 128;
1544
+ rot[1] = q.x * 128 + 128;
1545
+ rot[2] = q.y * 128 + 128;
1546
+ rot[3] = q.z * 128 + 128;
1547
+ offset.value += header.rowVertexLength;
1548
+ }
1549
+ /**
1550
+ * Converts a .ply data with SH coefficients splat
1551
+ * if data array buffer is not ply, returns the original buffer
1552
+ * @param data the .ply data to load
1553
+ * @param useCoroutine use coroutine and yield
1554
+ * @returns the loaded splat buffer and optional array of sh coefficients
1555
+ */
1556
+ static *ConvertPLYWithSHToSplat(data, useCoroutine = false) {
1557
+ const header = GaussianSplattingMesh.ParseHeader(data);
1558
+ if (!header) {
1559
+ return { buffer: data };
1560
+ }
1561
+ const offset = { value: 0 };
1562
+ const compressedChunks = GaussianSplattingMesh._GetCompressedChunks(header, offset);
1563
+ for (let i = 0; i < header.vertexCount; i++) {
1564
+ GaussianSplattingMesh._GetSplat(header, i, compressedChunks, offset);
1565
+ if (i % GaussianSplattingMesh._PlyConversionBatchSize === 0 && useCoroutine) {
1566
+ yield;
1567
+ }
1568
+ }
1569
+ let sh = null;
1570
+ // make SH texture buffers
1571
+ if (header.shDegree && header.shBuffer) {
1572
+ const textureCount = Math.ceil(header.shCoefficientCount / 16); // 4 components can be stored per texture, 4 sh per component
1573
+ let shIndexRead = 0;
1574
+ const ubuf = new Uint8Array(header.shBuffer);
1575
+ // sh is an array of uint8array that will be used to create sh textures
1576
+ sh = [];
1577
+ const splatCount = header.vertexCount;
1578
+ const engine = EngineStore.LastCreatedEngine;
1579
+ if (engine) {
1580
+ const width = engine.getCaps().maxTextureSize;
1581
+ const height = Math.ceil(splatCount / width);
1582
+ // create array for the number of textures needed.
1583
+ for (let textureIndex = 0; textureIndex < textureCount; textureIndex++) {
1584
+ const texture = new Uint8Array(height * width * 4 * 4); // 4 components per texture, 4 sh per component
1585
+ sh.push(texture);
1586
+ }
1587
+ for (let i = 0; i < splatCount; i++) {
1588
+ for (let shIndexWrite = 0; shIndexWrite < header.shCoefficientCount; shIndexWrite++) {
1589
+ const shValue = ubuf[shIndexRead++];
1590
+ const textureIndex = Math.floor(shIndexWrite / 16);
1591
+ const shArray = sh[textureIndex];
1592
+ const byteIndexInTexture = shIndexWrite % 16; // [0..15]
1593
+ const offsetPerSplat = i * 16; // 16 sh values per texture per splat.
1594
+ shArray[byteIndexInTexture + offsetPerSplat] = shValue;
1595
+ }
1596
+ }
1597
+ }
1598
+ }
1599
+ return { buffer: header.buffer, sh: sh };
1600
+ }
1601
+ /**
1602
+ * Converts a .ply data array buffer to splat
1603
+ * if data array buffer is not ply, returns the original buffer
1604
+ * @param data the .ply data to load
1605
+ * @param useCoroutine use coroutine and yield
1606
+ * @returns the loaded splat buffer without SH coefficient, whether ply contains or not SH.
1607
+ */
1608
+ static *ConvertPLYToSplat(data, useCoroutine = false) {
1609
+ const header = GaussianSplattingMesh.ParseHeader(data);
1610
+ if (!header) {
1611
+ return data;
1612
+ }
1613
+ const offset = { value: 0 };
1614
+ const compressedChunks = GaussianSplattingMesh._GetCompressedChunks(header, offset);
1615
+ for (let i = 0; i < header.vertexCount; i++) {
1616
+ GaussianSplattingMesh._GetSplat(header, i, compressedChunks, offset);
1617
+ if (i % GaussianSplattingMesh._PlyConversionBatchSize === 0 && useCoroutine) {
1618
+ yield;
1619
+ }
1620
+ }
1621
+ return header.buffer;
1622
+ }
1623
+ /**
1624
+ * Converts a .ply data array buffer to splat
1625
+ * if data array buffer is not ply, returns the original buffer
1626
+ * @param data the .ply data to load
1627
+ * @returns the loaded splat buffer
1628
+ */
1629
+ static async ConvertPLYToSplatAsync(data) {
1630
+ return runCoroutineAsync(GaussianSplattingMesh.ConvertPLYToSplat(data, true), createYieldingScheduler());
1631
+ }
1632
+ /**
1633
+ * Converts a .ply with SH data array buffer to splat
1634
+ * if data array buffer is not ply, returns the original buffer
1635
+ * @param data the .ply data to load
1636
+ * @returns the loaded splat buffer with SH
1637
+ */
1638
+ static async ConvertPLYWithSHToSplatAsync(data) {
1639
+ return runCoroutineAsync(GaussianSplattingMesh.ConvertPLYWithSHToSplat(data, true), createYieldingScheduler());
1640
+ }
1641
+ /**
1642
+ * Loads a .splat Gaussian Splatting array buffer asynchronously
1643
+ * @param data arraybuffer containing splat file
1644
+ * @returns a promise that resolves when the operation is complete
1645
+ */
1646
+ loadDataAsync(data) {
1647
+ return this.updateDataAsync(data);
1648
+ }
1649
+ /**
1650
+ * Loads a .splat Gaussian or .ply Splatting file asynchronously
1651
+ * @param url path to the splat file to load
1652
+ * @returns a promise that resolves when the operation is complete
1653
+ * @deprecated Please use SceneLoader.ImportMeshAsync instead
1654
+ */
1655
+ loadFileAsync(url) {
1656
+ return Tools.LoadFileAsync(url, true).then(async (plyBuffer) => {
1657
+ GaussianSplattingMesh.ConvertPLYWithSHToSplatAsync(plyBuffer).then((splatsData) => {
1658
+ this.updateDataAsync(splatsData.buffer, splatsData.sh);
1659
+ });
1660
+ });
1661
+ }
1662
+ /**
1663
+ * Releases resources associated with this mesh.
1664
+ * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
1665
+ */
1666
+ dispose(doNotRecurse) {
1667
+ this._covariancesATexture?.dispose();
1668
+ this._covariancesBTexture?.dispose();
1669
+ this._centersTexture?.dispose();
1670
+ this._colorsTexture?.dispose();
1671
+ if (this._shTextures) {
1672
+ this._shTextures.forEach((shTexture) => {
1673
+ shTexture.dispose();
1674
+ });
1675
+ }
1676
+ this._covariancesATexture = null;
1677
+ this._covariancesBTexture = null;
1678
+ this._centersTexture = null;
1679
+ this._colorsTexture = null;
1680
+ this._shTextures = null;
1681
+ this._worker?.terminate();
1682
+ this._worker = null;
1683
+ super.dispose(doNotRecurse, true);
1684
+ }
1685
+ _copyTextures(source) {
1686
+ this._covariancesATexture = source.covariancesATexture?.clone();
1687
+ this._covariancesBTexture = source.covariancesBTexture?.clone();
1688
+ this._centersTexture = source.centersTexture?.clone();
1689
+ this._colorsTexture = source.colorsTexture?.clone();
1690
+ if (source._shTextures) {
1691
+ this._shTextures = [];
1692
+ this._shTextures.forEach((shTexture) => {
1693
+ this._shTextures?.push(shTexture.clone());
1694
+ });
1695
+ }
1696
+ }
1697
+ /**
1698
+ * Returns a new Mesh object generated from the current mesh properties.
1699
+ * @param name is a string, the name given to the new mesh
1700
+ * @returns a new Gaussian Splatting Mesh
1701
+ */
1702
+ clone(name = "") {
1703
+ const newGS = new GaussianSplattingMesh(name, undefined, this.getScene());
1704
+ newGS._copySource(this);
1705
+ newGS.makeGeometryUnique();
1706
+ newGS._vertexCount = this._vertexCount;
1707
+ newGS._copyTextures(this);
1708
+ newGS._modelViewMatrix = Matrix.Identity();
1709
+ newGS._splatPositions = this._splatPositions;
1710
+ newGS._readyToDisplay = false;
1711
+ newGS._instanciateWorker();
1712
+ const binfo = this.getBoundingInfo();
1713
+ newGS.getBoundingInfo().reConstruct(binfo.minimum, binfo.maximum, this.getWorldMatrix());
1714
+ newGS.forcedInstanceCount = newGS._vertexCount;
1715
+ newGS.setEnabled(true);
1716
+ return newGS;
1717
+ }
1718
+ _makeSplat(index, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum) {
1719
+ const matrixRotation = TmpVectors.Matrix[0];
1720
+ const matrixScale = TmpVectors.Matrix[1];
1721
+ const quaternion = TmpVectors.Quaternion[0];
1722
+ const covBSItemSize = this._useRGBACovariants ? 4 : 2;
1723
+ const x = fBuffer[8 * index + 0];
1724
+ const y = -fBuffer[8 * index + 1];
1725
+ const z = fBuffer[8 * index + 2];
1726
+ this._splatPositions[4 * index + 0] = x;
1727
+ this._splatPositions[4 * index + 1] = y;
1728
+ this._splatPositions[4 * index + 2] = z;
1729
+ minimum.minimizeInPlaceFromFloats(x, y, z);
1730
+ maximum.maximizeInPlaceFromFloats(x, y, z);
1731
+ quaternion.set((uBuffer[32 * index + 28 + 1] - 127.5) / 127.5, (uBuffer[32 * index + 28 + 2] - 127.5) / 127.5, (uBuffer[32 * index + 28 + 3] - 127.5) / 127.5, -(uBuffer[32 * index + 28 + 0] - 127.5) / 127.5);
1732
+ quaternion.toRotationMatrix(matrixRotation);
1733
+ Matrix.ScalingToRef(fBuffer[8 * index + 3 + 0] * 2, fBuffer[8 * index + 3 + 1] * 2, fBuffer[8 * index + 3 + 2] * 2, matrixScale);
1734
+ const M = matrixRotation.multiplyToRef(matrixScale, TmpVectors.Matrix[0]).m;
1735
+ const covariances = this._tmpCovariances;
1736
+ covariances[0] = M[0] * M[0] + M[1] * M[1] + M[2] * M[2];
1737
+ covariances[1] = M[0] * M[4] + M[1] * M[5] + M[2] * M[6];
1738
+ covariances[2] = M[0] * M[8] + M[1] * M[9] + M[2] * M[10];
1739
+ covariances[3] = M[4] * M[4] + M[5] * M[5] + M[6] * M[6];
1740
+ covariances[4] = M[4] * M[8] + M[5] * M[9] + M[6] * M[10];
1741
+ covariances[5] = M[8] * M[8] + M[9] * M[9] + M[10] * M[10];
1742
+ // normalize covA, covB
1743
+ let factor = -10000;
1744
+ for (let covIndex = 0; covIndex < 6; covIndex++) {
1745
+ factor = Math.max(factor, Math.abs(covariances[covIndex]));
1746
+ }
1747
+ this._splatPositions[4 * index + 3] = factor;
1748
+ const transform = factor;
1749
+ covA[index * 4 + 0] = ToHalfFloat(covariances[0] / transform);
1750
+ covA[index * 4 + 1] = ToHalfFloat(covariances[1] / transform);
1751
+ covA[index * 4 + 2] = ToHalfFloat(covariances[2] / transform);
1752
+ covA[index * 4 + 3] = ToHalfFloat(covariances[3] / transform);
1753
+ covB[index * covBSItemSize + 0] = ToHalfFloat(covariances[4] / transform);
1754
+ covB[index * covBSItemSize + 1] = ToHalfFloat(covariances[5] / transform);
1755
+ // colors
1756
+ colorArray[index * 4 + 0] = uBuffer[32 * index + 24 + 0];
1757
+ colorArray[index * 4 + 1] = uBuffer[32 * index + 24 + 1];
1758
+ colorArray[index * 4 + 2] = uBuffer[32 * index + 24 + 2];
1759
+ colorArray[index * 4 + 3] = uBuffer[32 * index + 24 + 3];
1760
+ }
1761
+ _updateTextures(covA, covB, colorArray, sh) {
1762
+ const textureSize = this._getTextureSize(this._vertexCount);
1763
+ // Update the textures
1764
+ const createTextureFromData = (data, width, height, format) => {
1765
+ return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);
1766
+ };
1767
+ const createTextureFromDataU8 = (data, width, height, format) => {
1768
+ return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_BYTE);
1769
+ };
1770
+ const createTextureFromDataU32 = (data, width, height, format) => {
1771
+ return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_NEAREST_SAMPLINGMODE, Constants.TEXTURETYPE_UNSIGNED_INTEGER);
1772
+ };
1773
+ const createTextureFromDataF16 = (data, width, height, format) => {
1774
+ return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_HALF_FLOAT);
1775
+ };
1776
+ if (this._covariancesATexture) {
1777
+ this._delayedTextureUpdate = { covA: covA, covB: covB, colors: colorArray, centers: this._splatPositions, sh: sh };
1778
+ const positions = Float32Array.from(this._splatPositions);
1779
+ const vertexCount = this._vertexCount;
1780
+ this._worker.postMessage({ positions, vertexCount }, [positions.buffer]);
1781
+ this._postToWorker(true);
1782
+ }
1783
+ else {
1784
+ this._covariancesATexture = createTextureFromDataF16(covA, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
1785
+ this._covariancesBTexture = createTextureFromDataF16(covB, textureSize.x, textureSize.y, this._useRGBACovariants ? Constants.TEXTUREFORMAT_RGBA : Constants.TEXTUREFORMAT_RG);
1786
+ this._centersTexture = createTextureFromData(this._splatPositions, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
1787
+ this._colorsTexture = createTextureFromDataU8(colorArray, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
1788
+ if (sh) {
1789
+ this._shTextures = [];
1790
+ sh.forEach((shData) => {
1791
+ const buffer = new Uint32Array(shData.buffer);
1792
+ const shTexture = createTextureFromDataU32(buffer, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA_INTEGER);
1793
+ shTexture.wrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE;
1794
+ shTexture.wrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE;
1795
+ this._shTextures.push(shTexture);
1796
+ });
1797
+ }
1798
+ this._instanciateWorker();
1799
+ }
1800
+ }
1801
+ *_updateData(data, isAsync, sh) {
1802
+ // if a covariance texture is present, then it's not a creation but an update
1803
+ if (!this._covariancesATexture) {
1804
+ this._readyToDisplay = false;
1805
+ }
1806
+ // Parse the data
1807
+ const uBuffer = new Uint8Array(data);
1808
+ const fBuffer = new Float32Array(uBuffer.buffer);
1809
+ if (this._keepInRam) {
1810
+ this._splatsData = data;
1811
+ if (sh) {
1812
+ this._sh = sh;
1813
+ }
1814
+ }
1815
+ const vertexCount = uBuffer.length / GaussianSplattingMesh._RowOutputLength;
1816
+ if (vertexCount != this._vertexCount) {
1817
+ this._updateSplatIndexBuffer(vertexCount);
1818
+ }
1819
+ this._vertexCount = vertexCount;
1820
+ // degree == 1 for 1 texture (3 terms), 2 for 2 textures(8 terms) and 3 for 3 textures (15 terms)
1821
+ this._shDegree = sh ? sh.length : 0;
1822
+ const textureSize = this._getTextureSize(vertexCount);
1823
+ const textureLength = textureSize.x * textureSize.y;
1824
+ const lineCountUpdate = GaussianSplattingMesh.ProgressiveUpdateAmount ?? textureSize.y;
1825
+ const textureLengthPerUpdate = textureSize.x * lineCountUpdate;
1826
+ this._splatPositions = new Float32Array(4 * textureLength);
1827
+ const covA = new Uint16Array(textureLength * 4);
1828
+ const covB = new Uint16Array((this._useRGBACovariants ? 4 : 2) * textureLength);
1829
+ const colorArray = new Uint8Array(textureLength * 4);
1830
+ const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
1831
+ const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
1832
+ if (GaussianSplattingMesh.ProgressiveUpdateAmount) {
1833
+ // create textures with not filled-yet array, then update directly portions of it
1834
+ this._updateTextures(covA, covB, colorArray, sh);
1835
+ this.setEnabled(true);
1836
+ const partCount = Math.ceil(textureSize.y / lineCountUpdate);
1837
+ for (let partIndex = 0; partIndex < partCount; partIndex++) {
1838
+ const updateLine = partIndex * lineCountUpdate;
1839
+ const splatIndexBase = updateLine * textureSize.x;
1840
+ for (let i = 0; i < textureLengthPerUpdate; i++) {
1841
+ this._makeSplat(splatIndexBase + i, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum);
1842
+ }
1843
+ this._updateSubTextures(this._splatPositions, covA, covB, colorArray, updateLine, Math.min(lineCountUpdate, textureSize.y - updateLine));
1844
+ // Update the binfo
1845
+ this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());
1846
+ if (isAsync) {
1847
+ yield;
1848
+ }
1849
+ }
1850
+ // sort will be dirty here as just finished filled positions will not be sorted
1851
+ const positions = Float32Array.from(this._splatPositions);
1852
+ const vertexCount = this._vertexCount;
1853
+ this._worker.postMessage({ positions, vertexCount }, [positions.buffer]);
1854
+ this._sortIsDirty = true;
1855
+ }
1856
+ else {
1857
+ for (let i = 0; i < vertexCount; i++) {
1858
+ this._makeSplat(i, fBuffer, uBuffer, covA, covB, colorArray, minimum, maximum);
1859
+ if (isAsync && i % GaussianSplattingMesh._SplatBatchSize === 0) {
1860
+ yield;
1861
+ }
1862
+ }
1863
+ // textures
1864
+ this._updateTextures(covA, covB, colorArray, sh);
1865
+ // Update the binfo
1866
+ this.getBoundingInfo().reConstruct(minimum, maximum, this.getWorldMatrix());
1867
+ this.setEnabled(true);
1868
+ }
1869
+ this._postToWorker(true);
1870
+ }
1871
+ /**
1872
+ * Update asynchronously the buffer
1873
+ * @param data array buffer containing center, color, orientation and scale of splats
1874
+ * @param sh optional array of uint8 array for SH data
1875
+ * @returns a promise
1876
+ */
1877
+ async updateDataAsync(data, sh) {
1878
+ return runCoroutineAsync(this._updateData(data, true, sh), createYieldingScheduler());
1879
+ }
1880
+ /**
1881
+ * @experimental
1882
+ * Update data from GS (position, orientation, color, scaling)
1883
+ * @param data array that contain all the datas
1884
+ * @param sh optional array of uint8 array for SH data
1885
+ */
1886
+ updateData(data, sh) {
1887
+ runCoroutineSync(this._updateData(data, false, sh));
1888
+ }
1889
+ /**
1890
+ * Refreshes the bounding info, taking into account all the thin instances defined
1891
+ * @returns the current Gaussian Splatting
1892
+ */
1893
+ refreshBoundingInfo() {
1894
+ this.thinInstanceRefreshBoundingInfo(false);
1895
+ return this;
1896
+ }
1897
+ // in case size is different
1898
+ _updateSplatIndexBuffer(vertexCount) {
1899
+ if (!this._splatIndex || vertexCount > this._splatIndex.length) {
1900
+ this._splatIndex = new Float32Array(vertexCount);
1901
+ this.thinInstanceSetBuffer("splatIndex", this._splatIndex, 1, false);
1902
+ }
1903
+ this.forcedInstanceCount = vertexCount;
1904
+ }
1905
+ _updateSubTextures(centers, covA, covB, colors, lineStart, lineCount, sh) {
1906
+ const updateTextureFromData = (texture, data, width, lineStart, lineCount) => {
1907
+ this.getEngine().updateTextureData(texture.getInternalTexture(), data, 0, lineStart, width, lineCount, 0, 0, false);
1908
+ };
1909
+ const textureSize = this._getTextureSize(this._vertexCount);
1910
+ const covBSItemSize = this._useRGBACovariants ? 4 : 2;
1911
+ const texelStart = lineStart * textureSize.x;
1912
+ const texelCount = lineCount * textureSize.x;
1913
+ const covAView = new Uint16Array(covA.buffer, texelStart * 4 * Uint16Array.BYTES_PER_ELEMENT, texelCount * 4);
1914
+ const covBView = new Uint16Array(covB.buffer, texelStart * covBSItemSize * Uint16Array.BYTES_PER_ELEMENT, texelCount * covBSItemSize);
1915
+ const colorsView = new Uint8Array(colors.buffer, texelStart * 4, texelCount * 4);
1916
+ const centersView = new Float32Array(centers.buffer, texelStart * 4 * Float32Array.BYTES_PER_ELEMENT, texelCount * 4);
1917
+ updateTextureFromData(this._covariancesATexture, covAView, textureSize.x, lineStart, lineCount);
1918
+ updateTextureFromData(this._covariancesBTexture, covBView, textureSize.x, lineStart, lineCount);
1919
+ updateTextureFromData(this._centersTexture, centersView, textureSize.x, lineStart, lineCount);
1920
+ updateTextureFromData(this._colorsTexture, colorsView, textureSize.x, lineStart, lineCount);
1921
+ if (sh) {
1922
+ for (let i = 0; i < sh.length; i++) {
1923
+ const componentCount = 4;
1924
+ const shView = new Uint8Array(this._sh[i].buffer, texelStart * componentCount, texelCount * componentCount);
1925
+ updateTextureFromData(this._shTextures[i], shView, textureSize.x, lineStart, lineCount);
1926
+ }
1927
+ }
1928
+ }
1929
+ _instanciateWorker() {
1930
+ if (!this._vertexCount) {
1931
+ return;
1932
+ }
1933
+ this._updateSplatIndexBuffer(this._vertexCount);
1934
+ // Start the worker thread
1935
+ this._worker?.terminate();
1936
+ this._worker = new Worker(URL.createObjectURL(new Blob(["(", GaussianSplattingMesh._CreateWorker.toString(), ")(self)"], {
1937
+ type: "application/javascript",
1938
+ })));
1939
+ this._depthMix = new BigInt64Array(this._vertexCount);
1940
+ const positions = Float32Array.from(this._splatPositions);
1941
+ const vertexCount = this._vertexCount;
1942
+ this._worker.postMessage({ positions, vertexCount }, [positions.buffer]);
1943
+ this._worker.onmessage = (e) => {
1944
+ this._depthMix = e.data.depthMix;
1945
+ const indexMix = new Uint32Array(e.data.depthMix.buffer);
1946
+ if (this._splatIndex) {
1947
+ for (let j = 0; j < this._vertexCount; j++) {
1948
+ this._splatIndex[j] = indexMix[2 * j];
1949
+ }
1950
+ }
1951
+ if (this._delayedTextureUpdate) {
1952
+ const textureSize = this._getTextureSize(vertexCount);
1953
+ this._updateSubTextures(this._delayedTextureUpdate.centers, this._delayedTextureUpdate.covA, this._delayedTextureUpdate.covB, this._delayedTextureUpdate.colors, 0, textureSize.y, this._delayedTextureUpdate.sh);
1954
+ this._delayedTextureUpdate = null;
1955
+ }
1956
+ this.thinInstanceBufferUpdated("splatIndex");
1957
+ this._canPostToWorker = true;
1958
+ this._readyToDisplay = true;
1959
+ // sort is dirty when GS is visible for progressive update with a this message arriving but positions were partially filled
1960
+ // another update needs to be kicked. The kick can't happen just when the position buffer is ready because _canPostToWorker might be false.
1961
+ if (this._sortIsDirty) {
1962
+ this._postToWorker(true);
1963
+ this._sortIsDirty = false;
1964
+ }
1965
+ };
1966
+ }
1967
+ _getTextureSize(length) {
1968
+ const engine = this._scene.getEngine();
1969
+ const width = engine.getCaps().maxTextureSize;
1970
+ let height = 1;
1971
+ if (engine.version === 1 && !engine.isWebGPU) {
1972
+ while (width * height < length) {
1973
+ height *= 2;
1974
+ }
1975
+ }
1976
+ else {
1977
+ height = Math.ceil(length / width);
1978
+ }
1979
+ if (height > width) {
1980
+ Logger.Error("GaussianSplatting texture size: (" + width + ", " + height + "), maxTextureSize: " + width);
1981
+ height = width;
1982
+ }
1983
+ return new Vector2(width, height);
1984
+ }
1985
+ }
1986
+ GaussianSplattingMesh._RowOutputLength = 3 * 4 + 3 * 4 + 4 + 4; // Vector3 position, Vector3 scale, 1 u8 quaternion, 1 color with alpha
1987
+ GaussianSplattingMesh._SH_C0 = 0.28209479177387814;
1988
+ // batch size between 2 yield calls. This value is a tradeoff between updates overhead and framerate hiccups
1989
+ // This step is faster the PLY conversion. So batch size can be bigger
1990
+ GaussianSplattingMesh._SplatBatchSize = 327680;
1991
+ // batch size between 2 yield calls during the PLY to splat conversion.
1992
+ GaussianSplattingMesh._PlyConversionBatchSize = 32768;
1993
+ /**
1994
+ * Set the number of batch (a batch is 16384 splats) after which a display update is performed
1995
+ * A value of 0 (default) means display update will not happens before splat is ready.
1996
+ */
1997
+ GaussianSplattingMesh.ProgressiveUpdateAmount = 0;
1998
+ GaussianSplattingMesh._CreateWorker = function (self) {
1999
+ let vertexCount = 0;
2000
+ let positions;
2001
+ let depthMix;
2002
+ let indices;
2003
+ let floatMix;
2004
+ self.onmessage = (e) => {
2005
+ // updated on init
2006
+ if (e.data.positions) {
2007
+ positions = e.data.positions;
2008
+ vertexCount = e.data.vertexCount;
2009
+ }
2010
+ // udpate on view changed
2011
+ else {
2012
+ const viewProj = e.data.view;
2013
+ if (!positions || !viewProj) {
2014
+ // Sanity check, it shouldn't happen!
2015
+ throw new Error("positions or view is not defined!");
2016
+ }
2017
+ depthMix = e.data.depthMix;
2018
+ indices = new Uint32Array(depthMix.buffer);
2019
+ floatMix = new Float32Array(depthMix.buffer);
2020
+ // Sort
2021
+ for (let j = 0; j < vertexCount; j++) {
2022
+ indices[2 * j] = j;
2023
+ }
2024
+ let depthFactor = -1;
2025
+ if (e.data.useRightHandedSystem) {
2026
+ depthFactor = 1;
2027
+ }
2028
+ for (let j = 0; j < vertexCount; j++) {
2029
+ floatMix[2 * j + 1] = 10000 + (viewProj[2] * positions[4 * j + 0] + viewProj[6] * positions[4 * j + 1] + viewProj[10] * positions[4 * j + 2]) * depthFactor;
2030
+ }
2031
+ depthMix.sort();
2032
+ self.postMessage({ depthMix }, [depthMix.buffer]);
2033
+ }
2034
+ };
2035
+ };
2036
+
2037
+ /**
2038
+ * Represents one particle of a points cloud system.
2039
+ */
2040
+ class CloudPoint {
2041
+ /**
2042
+ * Creates a Point Cloud object.
2043
+ * Don't create particles manually, use instead the PCS internal tools like _addParticle()
2044
+ * @param particleIndex (integer) is the particle index in the PCS pool. It's also the particle identifier.
2045
+ * @param group (PointsGroup) is the group the particle belongs to
2046
+ * @param groupId (integer) is the group identifier in the PCS.
2047
+ * @param idxInGroup (integer) is the index of the particle in the current point group (ex: the 10th point of addPoints(30))
2048
+ * @param pcs defines the PCS it is associated to
2049
+ */
2050
+ constructor(particleIndex, group, groupId, idxInGroup, pcs) {
2051
+ /**
2052
+ * particle global index
2053
+ */
2054
+ this.idx = 0;
2055
+ /**
2056
+ * The color of the particle
2057
+ */
2058
+ this.color = new Color4(1.0, 1.0, 1.0, 1.0);
2059
+ /**
2060
+ * The world space position of the particle.
2061
+ */
2062
+ this.position = Vector3.Zero();
2063
+ /**
2064
+ * The world space rotation of the particle. (Not use if rotationQuaternion is set)
2065
+ */
2066
+ this.rotation = Vector3.Zero();
2067
+ /**
2068
+ * The uv of the particle.
2069
+ */
2070
+ this.uv = new Vector2(0.0, 0.0);
2071
+ /**
2072
+ * The current speed of the particle.
2073
+ */
2074
+ this.velocity = Vector3.Zero();
2075
+ /**
2076
+ * The pivot point in the particle local space.
2077
+ */
2078
+ this.pivot = Vector3.Zero();
2079
+ /**
2080
+ * Must the particle be translated from its pivot point in its local space ?
2081
+ * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.
2082
+ * Default : false
2083
+ */
2084
+ this.translateFromPivot = false;
2085
+ /**
2086
+ * Index of this particle in the global "positions" array (Internal use)
2087
+ * @internal
2088
+ */
2089
+ this._pos = 0;
2090
+ /**
2091
+ * @internal Index of this particle in the global "indices" array (Internal use)
2092
+ */
2093
+ this._ind = 0;
2094
+ /**
2095
+ * Group id of this particle
2096
+ */
2097
+ this.groupId = 0;
2098
+ /**
2099
+ * Index of the particle in its group id (Internal use)
2100
+ */
2101
+ this.idxInGroup = 0;
2102
+ /**
2103
+ * @internal Still set as invisible in order to skip useless computations (Internal use)
2104
+ */
2105
+ this._stillInvisible = false;
2106
+ /**
2107
+ * @internal Last computed particle rotation matrix
2108
+ */
2109
+ this._rotationMatrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
2110
+ /**
2111
+ * Parent particle Id, if any.
2112
+ * Default null.
2113
+ */
2114
+ this.parentId = null;
2115
+ /**
2116
+ * @internal Internal global position in the PCS.
2117
+ */
2118
+ this._globalPosition = Vector3.Zero();
2119
+ this.idx = particleIndex;
2120
+ this._group = group;
2121
+ this.groupId = groupId;
2122
+ this.idxInGroup = idxInGroup;
2123
+ this._pcs = pcs;
2124
+ }
2125
+ /**
2126
+ * get point size
2127
+ */
2128
+ get size() {
2129
+ return this.size;
2130
+ }
2131
+ /**
2132
+ * Set point size
2133
+ */
2134
+ set size(scale) {
2135
+ this.size = scale;
2136
+ }
2137
+ /**
2138
+ * Legacy support, changed quaternion to rotationQuaternion
2139
+ */
2140
+ get quaternion() {
2141
+ return this.rotationQuaternion;
2142
+ }
2143
+ /**
2144
+ * Legacy support, changed quaternion to rotationQuaternion
2145
+ */
2146
+ set quaternion(q) {
2147
+ this.rotationQuaternion = q;
2148
+ }
2149
+ /**
2150
+ * Returns a boolean. True if the particle intersects a mesh, else false
2151
+ * The intersection is computed on the particle position and Axis Aligned Bounding Box (AABB) or Sphere
2152
+ * @param target is the object (point or mesh) what the intersection is computed against
2153
+ * @param isSphere is boolean flag when false (default) bounding box of mesh is used, when true the bounding sphere is used
2154
+ * @returns true if it intersects
2155
+ */
2156
+ intersectsMesh(target, isSphere) {
2157
+ if (!target.hasBoundingInfo) {
2158
+ return false;
2159
+ }
2160
+ if (!this._pcs.mesh) {
2161
+ throw new Error("Point Cloud System doesnt contain the Mesh");
2162
+ }
2163
+ if (isSphere) {
2164
+ return target.getBoundingInfo().boundingSphere.intersectsPoint(this.position.add(this._pcs.mesh.position));
2165
+ }
2166
+ const bbox = target.getBoundingInfo().boundingBox;
2167
+ const maxX = bbox.maximumWorld.x;
2168
+ const minX = bbox.minimumWorld.x;
2169
+ const maxY = bbox.maximumWorld.y;
2170
+ const minY = bbox.minimumWorld.y;
2171
+ const maxZ = bbox.maximumWorld.z;
2172
+ const minZ = bbox.minimumWorld.z;
2173
+ const x = this.position.x + this._pcs.mesh.position.x;
2174
+ const y = this.position.y + this._pcs.mesh.position.y;
2175
+ const z = this.position.z + this._pcs.mesh.position.z;
2176
+ return minX <= x && x <= maxX && minY <= y && y <= maxY && minZ <= z && z <= maxZ;
2177
+ }
2178
+ /**
2179
+ * get the rotation matrix of the particle
2180
+ * @internal
2181
+ */
2182
+ getRotationMatrix(m) {
2183
+ let quaternion;
2184
+ if (this.rotationQuaternion) {
2185
+ quaternion = this.rotationQuaternion;
2186
+ }
2187
+ else {
2188
+ quaternion = TmpVectors.Quaternion[0];
2189
+ const rotation = this.rotation;
2190
+ Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
2191
+ }
2192
+ quaternion.toRotationMatrix(m);
2193
+ }
2194
+ }
2195
+ /**
2196
+ * Represents a group of points in a points cloud system
2197
+ * * PCS internal tool, don't use it manually.
2198
+ */
2199
+ class PointsGroup {
2200
+ /**
2201
+ * Get or set the groupId
2202
+ * @deprecated Please use groupId instead
2203
+ */
2204
+ get groupID() {
2205
+ return this.groupId;
2206
+ }
2207
+ set groupID(groupID) {
2208
+ this.groupId = groupID;
2209
+ }
2210
+ /**
2211
+ * Creates a points group object. This is an internal reference to produce particles for the PCS.
2212
+ * PCS internal tool, don't use it manually.
2213
+ * @internal
2214
+ */
2215
+ constructor(id, posFunction) {
2216
+ this.groupId = id;
2217
+ this._positionFunction = posFunction;
2218
+ }
2219
+ }
2220
+
2221
+ /** Defines the 4 color options */
2222
+ var PointColor;
2223
+ (function (PointColor) {
2224
+ /** color value */
2225
+ PointColor[PointColor["Color"] = 2] = "Color";
2226
+ /** uv value */
2227
+ PointColor[PointColor["UV"] = 1] = "UV";
2228
+ /** random value */
2229
+ PointColor[PointColor["Random"] = 0] = "Random";
2230
+ /** stated value */
2231
+ PointColor[PointColor["Stated"] = 3] = "Stated";
2232
+ })(PointColor || (PointColor = {}));
2233
+ /**
2234
+ * The PointCloudSystem (PCS) is a single updatable mesh. The points corresponding to the vertices of this big mesh.
2235
+ * As it is just a mesh, the PointCloudSystem has all the same properties as any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc.
2236
+
2237
+ * The PointCloudSystem is also a particle system, with each point being a particle. It provides some methods to manage the particles.
2238
+ * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.
2239
+ *
2240
+ * Full documentation here : TO BE ENTERED
2241
+ */
2242
+ class PointsCloudSystem {
2243
+ /**
2244
+ * Gets the particle positions computed by the Point Cloud System
2245
+ */
2246
+ get positions() {
2247
+ return this._positions32;
2248
+ }
2249
+ /**
2250
+ * Gets the particle colors computed by the Point Cloud System
2251
+ */
2252
+ get colors() {
2253
+ return this._colors32;
2254
+ }
2255
+ /**
2256
+ * Gets the particle uvs computed by the Point Cloud System
2257
+ */
2258
+ get uvs() {
2259
+ return this._uvs32;
2260
+ }
2261
+ /**
2262
+ * Creates a PCS (Points Cloud System) object
2263
+ * @param name (String) is the PCS name, this will be the underlying mesh name
2264
+ * @param pointSize (number) is the size for each point. Has no effect on a WebGPU engine.
2265
+ * @param scene (Scene) is the scene in which the PCS is added
2266
+ * @param options defines the options of the PCS e.g.
2267
+ * * updatable (optional boolean, default true) : if the PCS must be updatable or immutable
2268
+ */
2269
+ constructor(name, pointSize, scene, options) {
2270
+ /**
2271
+ * The PCS array of cloud point objects. Just access each particle as with any classic array.
2272
+ * Example : var p = SPS.particles[i];
2273
+ */
2274
+ this.particles = new Array();
2275
+ /**
2276
+ * The PCS total number of particles. Read only. Use PCS.counter instead if you need to set your own value.
2277
+ */
2278
+ this.nbParticles = 0;
2279
+ /**
2280
+ * This a counter for your own usage. It's not set by any SPS functions.
2281
+ */
2282
+ this.counter = 0;
2283
+ /**
2284
+ * This empty object is intended to store some PCS specific or temporary values in order to lower the Garbage Collector activity.
2285
+ * Please read :
2286
+ */
2287
+ this.vars = {};
2288
+ this._promises = [];
2289
+ this._positions = new Array();
2290
+ this._indices = new Array();
2291
+ this._normals = new Array();
2292
+ this._colors = new Array();
2293
+ this._uvs = new Array();
2294
+ this._updatable = true;
2295
+ this._isVisibilityBoxLocked = false;
2296
+ this._alwaysVisible = false;
2297
+ this._groups = new Array(); //start indices for each group of particles
2298
+ this._groupCounter = 0;
2299
+ this._computeParticleColor = true;
2300
+ this._computeParticleTexture = true;
2301
+ this._computeParticleRotation = true;
2302
+ this._computeBoundingBox = false;
2303
+ this._isReady = false;
2304
+ this.name = name;
2305
+ this._size = pointSize;
2306
+ this._scene = scene || EngineStore.LastCreatedScene;
2307
+ if (options && options.updatable !== undefined) {
2308
+ this._updatable = options.updatable;
2309
+ }
2310
+ else {
2311
+ this._updatable = true;
2312
+ }
2313
+ }
2314
+ /**
2315
+ * Builds the PCS underlying mesh. Returns a standard Mesh.
2316
+ * If no points were added to the PCS, the returned mesh is just a single point.
2317
+ * @param material The material to use to render the mesh. If not provided, will create a default one
2318
+ * @returns a promise for the created mesh
2319
+ */
2320
+ buildMeshAsync(material) {
2321
+ return Promise.all(this._promises).then(() => {
2322
+ this._isReady = true;
2323
+ return this._buildMesh(material);
2324
+ });
2325
+ }
2326
+ /**
2327
+ * @internal
2328
+ */
2329
+ _buildMesh(material) {
2330
+ if (this.nbParticles === 0) {
2331
+ this.addPoints(1);
2332
+ }
2333
+ this._positions32 = new Float32Array(this._positions);
2334
+ this._uvs32 = new Float32Array(this._uvs);
2335
+ this._colors32 = new Float32Array(this._colors);
2336
+ const vertexData = new VertexData();
2337
+ vertexData.set(this._positions32, VertexBuffer.PositionKind);
2338
+ if (this._uvs32.length > 0) {
2339
+ vertexData.set(this._uvs32, VertexBuffer.UVKind);
2340
+ }
2341
+ let ec = 0; //emissive color value 0 for UVs, 1 for color
2342
+ if (this._colors32.length > 0) {
2343
+ ec = 1;
2344
+ vertexData.set(this._colors32, VertexBuffer.ColorKind);
2345
+ }
2346
+ const mesh = new Mesh(this.name, this._scene);
2347
+ vertexData.applyToMesh(mesh, this._updatable);
2348
+ this.mesh = mesh;
2349
+ // free memory
2350
+ this._positions = null;
2351
+ this._uvs = null;
2352
+ this._colors = null;
2353
+ if (!this._updatable) {
2354
+ this.particles.length = 0;
2355
+ }
2356
+ let mat = material;
2357
+ if (!mat) {
2358
+ mat = new StandardMaterial("point cloud material", this._scene);
2359
+ mat.emissiveColor = new Color3(ec, ec, ec);
2360
+ mat.disableLighting = true;
2361
+ mat.pointsCloud = true;
2362
+ mat.pointSize = this._size;
2363
+ }
2364
+ mesh.material = mat;
2365
+ return new Promise((resolve) => resolve(mesh));
2366
+ }
2367
+ // adds a new particle object in the particles array
2368
+ _addParticle(idx, group, groupId, idxInGroup) {
2369
+ const cp = new CloudPoint(idx, group, groupId, idxInGroup, this);
2370
+ this.particles.push(cp);
2371
+ return cp;
2372
+ }
2373
+ _randomUnitVector(particle) {
2374
+ particle.position = new Vector3(Math.random(), Math.random(), Math.random());
2375
+ particle.color = new Color4(1, 1, 1, 1);
2376
+ }
2377
+ _getColorIndicesForCoord(pointsGroup, x, y, width) {
2378
+ const imageData = pointsGroup._groupImageData;
2379
+ const color = y * (width * 4) + x * 4;
2380
+ const colorIndices = [color, color + 1, color + 2, color + 3];
2381
+ const redIndex = colorIndices[0];
2382
+ const greenIndex = colorIndices[1];
2383
+ const blueIndex = colorIndices[2];
2384
+ const alphaIndex = colorIndices[3];
2385
+ const redForCoord = imageData[redIndex];
2386
+ const greenForCoord = imageData[greenIndex];
2387
+ const blueForCoord = imageData[blueIndex];
2388
+ const alphaForCoord = imageData[alphaIndex];
2389
+ return new Color4(redForCoord / 255, greenForCoord / 255, blueForCoord / 255, alphaForCoord);
2390
+ }
2391
+ _setPointsColorOrUV(mesh, pointsGroup, isVolume, colorFromTexture, hasTexture, color, range, uvSetIndex) {
2392
+ uvSetIndex = uvSetIndex ?? 0;
2393
+ if (isVolume) {
2394
+ mesh.updateFacetData();
2395
+ }
2396
+ const boundInfo = mesh.getBoundingInfo();
2397
+ const diameter = 2 * boundInfo.boundingSphere.radius;
2398
+ let meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
2399
+ const meshInd = mesh.getIndices();
2400
+ const meshUV = mesh.getVerticesData(VertexBuffer.UVKind + (uvSetIndex ? uvSetIndex + 1 : ""));
2401
+ const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);
2402
+ const place = Vector3.Zero();
2403
+ mesh.computeWorldMatrix();
2404
+ const meshMatrix = mesh.getWorldMatrix();
2405
+ if (!meshMatrix.isIdentity()) {
2406
+ meshPos = meshPos.slice(0);
2407
+ for (let p = 0; p < meshPos.length / 3; p++) {
2408
+ Vector3.TransformCoordinatesFromFloatsToRef(meshPos[3 * p], meshPos[3 * p + 1], meshPos[3 * p + 2], meshMatrix, place);
2409
+ meshPos[3 * p] = place.x;
2410
+ meshPos[3 * p + 1] = place.y;
2411
+ meshPos[3 * p + 2] = place.z;
2412
+ }
2413
+ }
2414
+ let idxPoints = 0;
2415
+ let id0 = 0;
2416
+ let id1 = 0;
2417
+ let id2 = 0;
2418
+ let v0X = 0;
2419
+ let v0Y = 0;
2420
+ let v0Z = 0;
2421
+ let v1X = 0;
2422
+ let v1Y = 0;
2423
+ let v1Z = 0;
2424
+ let v2X = 0;
2425
+ let v2Y = 0;
2426
+ let v2Z = 0;
2427
+ const vertex0 = Vector3.Zero();
2428
+ const vertex1 = Vector3.Zero();
2429
+ const vertex2 = Vector3.Zero();
2430
+ const vec0 = Vector3.Zero();
2431
+ const vec1 = Vector3.Zero();
2432
+ let uv0X = 0;
2433
+ let uv0Y = 0;
2434
+ let uv1X = 0;
2435
+ let uv1Y = 0;
2436
+ let uv2X = 0;
2437
+ let uv2Y = 0;
2438
+ const uv0 = Vector2.Zero();
2439
+ const uv1 = Vector2.Zero();
2440
+ const uv2 = Vector2.Zero();
2441
+ const uvec0 = Vector2.Zero();
2442
+ const uvec1 = Vector2.Zero();
2443
+ let col0X = 0;
2444
+ let col0Y = 0;
2445
+ let col0Z = 0;
2446
+ let col0A = 0;
2447
+ let col1X = 0;
2448
+ let col1Y = 0;
2449
+ let col1Z = 0;
2450
+ let col1A = 0;
2451
+ let col2X = 0;
2452
+ let col2Y = 0;
2453
+ let col2Z = 0;
2454
+ let col2A = 0;
2455
+ const col0 = Vector4.Zero();
2456
+ const col1 = Vector4.Zero();
2457
+ const col2 = Vector4.Zero();
2458
+ const colvec0 = Vector4.Zero();
2459
+ const colvec1 = Vector4.Zero();
2460
+ let lamda = 0;
2461
+ let mu = 0;
2462
+ range = range ? range : 0;
2463
+ let facetPoint;
2464
+ let uvPoint;
2465
+ let colPoint = new Vector4(0, 0, 0, 0);
2466
+ let norm = Vector3.Zero();
2467
+ let tang = Vector3.Zero();
2468
+ let biNorm = Vector3.Zero();
2469
+ let angle = 0;
2470
+ let facetPlaneVec = Vector3.Zero();
2471
+ let gap = 0;
2472
+ let distance = 0;
2473
+ const ray = new Ray(Vector3.Zero(), new Vector3(1, 0, 0));
2474
+ let pickInfo;
2475
+ let direction = Vector3.Zero();
2476
+ for (let index = 0; index < meshInd.length / 3; index++) {
2477
+ id0 = meshInd[3 * index];
2478
+ id1 = meshInd[3 * index + 1];
2479
+ id2 = meshInd[3 * index + 2];
2480
+ v0X = meshPos[3 * id0];
2481
+ v0Y = meshPos[3 * id0 + 1];
2482
+ v0Z = meshPos[3 * id0 + 2];
2483
+ v1X = meshPos[3 * id1];
2484
+ v1Y = meshPos[3 * id1 + 1];
2485
+ v1Z = meshPos[3 * id1 + 2];
2486
+ v2X = meshPos[3 * id2];
2487
+ v2Y = meshPos[3 * id2 + 1];
2488
+ v2Z = meshPos[3 * id2 + 2];
2489
+ vertex0.set(v0X, v0Y, v0Z);
2490
+ vertex1.set(v1X, v1Y, v1Z);
2491
+ vertex2.set(v2X, v2Y, v2Z);
2492
+ vertex1.subtractToRef(vertex0, vec0);
2493
+ vertex2.subtractToRef(vertex1, vec1);
2494
+ if (meshUV) {
2495
+ uv0X = meshUV[2 * id0];
2496
+ uv0Y = meshUV[2 * id0 + 1];
2497
+ uv1X = meshUV[2 * id1];
2498
+ uv1Y = meshUV[2 * id1 + 1];
2499
+ uv2X = meshUV[2 * id2];
2500
+ uv2Y = meshUV[2 * id2 + 1];
2501
+ uv0.set(uv0X, uv0Y);
2502
+ uv1.set(uv1X, uv1Y);
2503
+ uv2.set(uv2X, uv2Y);
2504
+ uv1.subtractToRef(uv0, uvec0);
2505
+ uv2.subtractToRef(uv1, uvec1);
2506
+ }
2507
+ if (meshCol && colorFromTexture) {
2508
+ col0X = meshCol[4 * id0];
2509
+ col0Y = meshCol[4 * id0 + 1];
2510
+ col0Z = meshCol[4 * id0 + 2];
2511
+ col0A = meshCol[4 * id0 + 3];
2512
+ col1X = meshCol[4 * id1];
2513
+ col1Y = meshCol[4 * id1 + 1];
2514
+ col1Z = meshCol[4 * id1 + 2];
2515
+ col1A = meshCol[4 * id1 + 3];
2516
+ col2X = meshCol[4 * id2];
2517
+ col2Y = meshCol[4 * id2 + 1];
2518
+ col2Z = meshCol[4 * id2 + 2];
2519
+ col2A = meshCol[4 * id2 + 3];
2520
+ col0.set(col0X, col0Y, col0Z, col0A);
2521
+ col1.set(col1X, col1Y, col1Z, col1A);
2522
+ col2.set(col2X, col2Y, col2Z, col2A);
2523
+ col1.subtractToRef(col0, colvec0);
2524
+ col2.subtractToRef(col1, colvec1);
2525
+ }
2526
+ let width;
2527
+ let height;
2528
+ let deltaS;
2529
+ let deltaV;
2530
+ let h;
2531
+ let s;
2532
+ let v;
2533
+ let hsvCol;
2534
+ const statedColor = new Color3(0, 0, 0);
2535
+ const colPoint3 = new Color3(0, 0, 0);
2536
+ let pointColors;
2537
+ let particle;
2538
+ for (let i = 0; i < pointsGroup._groupDensity[index]; i++) {
2539
+ idxPoints = this.particles.length;
2540
+ this._addParticle(idxPoints, pointsGroup, this._groupCounter, index + i);
2541
+ particle = this.particles[idxPoints];
2542
+ //form a point inside the facet v0, v1, v2;
2543
+ lamda = Math.sqrt(RandomRange(0, 1));
2544
+ mu = RandomRange(0, 1);
2545
+ facetPoint = vertex0.add(vec0.scale(lamda)).add(vec1.scale(lamda * mu));
2546
+ if (isVolume) {
2547
+ norm = mesh.getFacetNormal(index).normalize().scale(-1);
2548
+ tang = vec0.clone().normalize();
2549
+ biNorm = Vector3.Cross(norm, tang);
2550
+ angle = RandomRange(0, 2 * Math.PI);
2551
+ facetPlaneVec = tang.scale(Math.cos(angle)).add(biNorm.scale(Math.sin(angle)));
2552
+ angle = RandomRange(0.1, Math.PI / 2);
2553
+ direction = facetPlaneVec.scale(Math.cos(angle)).add(norm.scale(Math.sin(angle)));
2554
+ ray.origin = facetPoint.add(direction.scale(0.00001));
2555
+ ray.direction = direction;
2556
+ ray.length = diameter;
2557
+ pickInfo = ray.intersectsMesh(mesh);
2558
+ if (pickInfo.hit) {
2559
+ distance = pickInfo.pickedPoint.subtract(facetPoint).length();
2560
+ gap = RandomRange(0, 1) * distance;
2561
+ facetPoint.addInPlace(direction.scale(gap));
2562
+ }
2563
+ }
2564
+ particle.position = facetPoint.clone();
2565
+ this._positions.push(particle.position.x, particle.position.y, particle.position.z);
2566
+ if (colorFromTexture !== undefined) {
2567
+ if (meshUV) {
2568
+ uvPoint = uv0.add(uvec0.scale(lamda)).add(uvec1.scale(lamda * mu));
2569
+ if (colorFromTexture) {
2570
+ //Set particle color to texture color
2571
+ if (hasTexture && pointsGroup._groupImageData !== null) {
2572
+ width = pointsGroup._groupImgWidth;
2573
+ height = pointsGroup._groupImgHeight;
2574
+ pointColors = this._getColorIndicesForCoord(pointsGroup, Math.round(uvPoint.x * width), Math.round(uvPoint.y * height), width);
2575
+ particle.color = pointColors;
2576
+ this._colors.push(pointColors.r, pointColors.g, pointColors.b, pointColors.a);
2577
+ }
2578
+ else {
2579
+ if (meshCol) {
2580
+ //failure in texture and colors available
2581
+ colPoint = col0.add(colvec0.scale(lamda)).add(colvec1.scale(lamda * mu));
2582
+ particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2583
+ this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2584
+ }
2585
+ else {
2586
+ colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);
2587
+ particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2588
+ this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2589
+ }
2590
+ }
2591
+ }
2592
+ else {
2593
+ //Set particle uv based on a mesh uv
2594
+ particle.uv = uvPoint.clone();
2595
+ this._uvs.push(particle.uv.x, particle.uv.y);
2596
+ }
2597
+ }
2598
+ }
2599
+ else {
2600
+ if (color) {
2601
+ statedColor.set(color.r, color.g, color.b);
2602
+ deltaS = RandomRange(-range, range);
2603
+ deltaV = RandomRange(-range, range);
2604
+ hsvCol = statedColor.toHSV();
2605
+ h = hsvCol.r;
2606
+ s = hsvCol.g + deltaS;
2607
+ v = hsvCol.b + deltaV;
2608
+ if (s < 0) {
2609
+ s = 0;
2610
+ }
2611
+ if (s > 1) {
2612
+ s = 1;
2613
+ }
2614
+ if (v < 0) {
2615
+ v = 0;
2616
+ }
2617
+ if (v > 1) {
2618
+ v = 1;
2619
+ }
2620
+ Color3.HSVtoRGBToRef(h, s, v, colPoint3);
2621
+ colPoint.set(colPoint3.r, colPoint3.g, colPoint3.b, 1);
2622
+ }
2623
+ else {
2624
+ colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);
2625
+ }
2626
+ particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2627
+ this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2628
+ }
2629
+ }
2630
+ }
2631
+ }
2632
+ // stores mesh texture in dynamic texture for color pixel retrieval
2633
+ // when pointColor type is color for surface points
2634
+ _colorFromTexture(mesh, pointsGroup, isVolume) {
2635
+ if (mesh.material === null) {
2636
+ Logger.Warn(mesh.name + "has no material.");
2637
+ pointsGroup._groupImageData = null;
2638
+ this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);
2639
+ return;
2640
+ }
2641
+ const mat = mesh.material;
2642
+ const textureList = mat.getActiveTextures();
2643
+ if (textureList.length === 0) {
2644
+ Logger.Warn(mesh.name + "has no usable texture.");
2645
+ pointsGroup._groupImageData = null;
2646
+ this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);
2647
+ return;
2648
+ }
2649
+ const clone = mesh.clone();
2650
+ clone.setEnabled(false);
2651
+ this._promises.push(new Promise((resolve) => {
2652
+ BaseTexture.WhenAllReady(textureList, () => {
2653
+ let n = pointsGroup._textureNb;
2654
+ if (n < 0) {
2655
+ n = 0;
2656
+ }
2657
+ if (n > textureList.length - 1) {
2658
+ n = textureList.length - 1;
2659
+ }
2660
+ const finalize = () => {
2661
+ pointsGroup._groupImgWidth = textureList[n].getSize().width;
2662
+ pointsGroup._groupImgHeight = textureList[n].getSize().height;
2663
+ this._setPointsColorOrUV(clone, pointsGroup, isVolume, true, true, undefined, undefined, textureList[n].coordinatesIndex);
2664
+ clone.dispose();
2665
+ resolve();
2666
+ };
2667
+ pointsGroup._groupImageData = null;
2668
+ const dataPromise = textureList[n].readPixels();
2669
+ if (!dataPromise) {
2670
+ finalize();
2671
+ }
2672
+ else {
2673
+ dataPromise.then((data) => {
2674
+ pointsGroup._groupImageData = data;
2675
+ finalize();
2676
+ });
2677
+ }
2678
+ });
2679
+ }));
2680
+ }
2681
+ // calculates the point density per facet of a mesh for surface points
2682
+ _calculateDensity(nbPoints, positions, indices) {
2683
+ let id0;
2684
+ let id1;
2685
+ let id2;
2686
+ let v0X;
2687
+ let v0Y;
2688
+ let v0Z;
2689
+ let v1X;
2690
+ let v1Y;
2691
+ let v1Z;
2692
+ let v2X;
2693
+ let v2Y;
2694
+ let v2Z;
2695
+ const vertex0 = Vector3.Zero();
2696
+ const vertex1 = Vector3.Zero();
2697
+ const vertex2 = Vector3.Zero();
2698
+ const vec0 = Vector3.Zero();
2699
+ const vec1 = Vector3.Zero();
2700
+ const normal = Vector3.Zero();
2701
+ let area;
2702
+ const cumulativeAreas = [];
2703
+ let surfaceArea = 0;
2704
+ const nbFacets = indices.length / 3;
2705
+ //surface area
2706
+ for (let index = 0; index < nbFacets; index++) {
2707
+ id0 = indices[3 * index];
2708
+ id1 = indices[3 * index + 1];
2709
+ id2 = indices[3 * index + 2];
2710
+ v0X = positions[3 * id0];
2711
+ v0Y = positions[3 * id0 + 1];
2712
+ v0Z = positions[3 * id0 + 2];
2713
+ v1X = positions[3 * id1];
2714
+ v1Y = positions[3 * id1 + 1];
2715
+ v1Z = positions[3 * id1 + 2];
2716
+ v2X = positions[3 * id2];
2717
+ v2Y = positions[3 * id2 + 1];
2718
+ v2Z = positions[3 * id2 + 2];
2719
+ vertex0.set(v0X, v0Y, v0Z);
2720
+ vertex1.set(v1X, v1Y, v1Z);
2721
+ vertex2.set(v2X, v2Y, v2Z);
2722
+ vertex1.subtractToRef(vertex0, vec0);
2723
+ vertex2.subtractToRef(vertex1, vec1);
2724
+ Vector3.CrossToRef(vec0, vec1, normal);
2725
+ area = 0.5 * normal.length();
2726
+ surfaceArea += area;
2727
+ cumulativeAreas[index] = surfaceArea;
2728
+ }
2729
+ const density = new Array(nbFacets);
2730
+ let remainingPoints = nbPoints;
2731
+ for (let index = nbFacets - 1; index > 0; index--) {
2732
+ const cumulativeArea = cumulativeAreas[index];
2733
+ if (cumulativeArea === 0) {
2734
+ // avoiding division by 0 upon degenerate triangles
2735
+ density[index] = 0;
2736
+ }
2737
+ else {
2738
+ const area = cumulativeArea - cumulativeAreas[index - 1];
2739
+ const facetPointsWithFraction = (area / cumulativeArea) * remainingPoints;
2740
+ const floored = Math.floor(facetPointsWithFraction);
2741
+ const fraction = facetPointsWithFraction - floored;
2742
+ const extraPoint = Number(Math.random() < fraction);
2743
+ const facetPoints = floored + extraPoint;
2744
+ density[index] = facetPoints;
2745
+ remainingPoints -= facetPoints;
2746
+ }
2747
+ }
2748
+ density[0] = remainingPoints;
2749
+ return density;
2750
+ }
2751
+ /**
2752
+ * Adds points to the PCS in random positions within a unit sphere
2753
+ * @param nb (positive integer) the number of particles to be created from this model
2754
+ * @param pointFunction is an optional javascript function to be called for each particle on PCS creation
2755
+ * @returns the number of groups in the system
2756
+ */
2757
+ addPoints(nb, pointFunction = this._randomUnitVector) {
2758
+ const pointsGroup = new PointsGroup(this._groupCounter, pointFunction);
2759
+ let cp;
2760
+ // particles
2761
+ let idx = this.nbParticles;
2762
+ for (let i = 0; i < nb; i++) {
2763
+ cp = this._addParticle(idx, pointsGroup, this._groupCounter, i);
2764
+ if (pointsGroup && pointsGroup._positionFunction) {
2765
+ pointsGroup._positionFunction(cp, idx, i);
2766
+ }
2767
+ this._positions.push(cp.position.x, cp.position.y, cp.position.z);
2768
+ if (cp.color) {
2769
+ this._colors.push(cp.color.r, cp.color.g, cp.color.b, cp.color.a);
2770
+ }
2771
+ if (cp.uv) {
2772
+ this._uvs.push(cp.uv.x, cp.uv.y);
2773
+ }
2774
+ idx++;
2775
+ }
2776
+ this.nbParticles += nb;
2777
+ this._groupCounter++;
2778
+ return this._groupCounter;
2779
+ }
2780
+ /**
2781
+ * Adds points to the PCS from the surface of the model shape
2782
+ * @param mesh is any Mesh object that will be used as a surface model for the points
2783
+ * @param nb (positive integer) the number of particles to be created from this model
2784
+ * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)
2785
+ * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position
2786
+ * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color
2787
+ * @returns the number of groups in the system
2788
+ */
2789
+ addSurfacePoints(mesh, nb, colorWith, color, range) {
2790
+ let colored = colorWith ? colorWith : 0 /* PointColor.Random */;
2791
+ if (isNaN(colored) || colored < 0 || colored > 3) {
2792
+ colored = 0 /* PointColor.Random */;
2793
+ }
2794
+ const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
2795
+ const meshInd = mesh.getIndices();
2796
+ this._groups.push(this._groupCounter);
2797
+ const pointsGroup = new PointsGroup(this._groupCounter, null);
2798
+ pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);
2799
+ if (colored === 2 /* PointColor.Color */) {
2800
+ pointsGroup._textureNb = color ? color : 0;
2801
+ }
2802
+ else {
2803
+ color = color ? color : new Color4(1, 1, 1, 1);
2804
+ }
2805
+ switch (colored) {
2806
+ case 2 /* PointColor.Color */:
2807
+ this._colorFromTexture(mesh, pointsGroup, false);
2808
+ break;
2809
+ case 1 /* PointColor.UV */:
2810
+ this._setPointsColorOrUV(mesh, pointsGroup, false, false, false);
2811
+ break;
2812
+ case 0 /* PointColor.Random */:
2813
+ this._setPointsColorOrUV(mesh, pointsGroup, false);
2814
+ break;
2815
+ case 3 /* PointColor.Stated */:
2816
+ this._setPointsColorOrUV(mesh, pointsGroup, false, undefined, undefined, color, range);
2817
+ break;
2818
+ }
2819
+ this.nbParticles += nb;
2820
+ this._groupCounter++;
2821
+ return this._groupCounter - 1;
2822
+ }
2823
+ /**
2824
+ * Adds points to the PCS inside the model shape
2825
+ * @param mesh is any Mesh object that will be used as a surface model for the points
2826
+ * @param nb (positive integer) the number of particles to be created from this model
2827
+ * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)
2828
+ * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position
2829
+ * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color
2830
+ * @returns the number of groups in the system
2831
+ */
2832
+ addVolumePoints(mesh, nb, colorWith, color, range) {
2833
+ let colored = colorWith ? colorWith : 0 /* PointColor.Random */;
2834
+ if (isNaN(colored) || colored < 0 || colored > 3) {
2835
+ colored = 0 /* PointColor.Random */;
2836
+ }
2837
+ const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
2838
+ const meshInd = mesh.getIndices();
2839
+ this._groups.push(this._groupCounter);
2840
+ const pointsGroup = new PointsGroup(this._groupCounter, null);
2841
+ pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);
2842
+ if (colored === 2 /* PointColor.Color */) {
2843
+ pointsGroup._textureNb = color ? color : 0;
2844
+ }
2845
+ else {
2846
+ color = color ? color : new Color4(1, 1, 1, 1);
2847
+ }
2848
+ switch (colored) {
2849
+ case 2 /* PointColor.Color */:
2850
+ this._colorFromTexture(mesh, pointsGroup, true);
2851
+ break;
2852
+ case 1 /* PointColor.UV */:
2853
+ this._setPointsColorOrUV(mesh, pointsGroup, true, false, false);
2854
+ break;
2855
+ case 0 /* PointColor.Random */:
2856
+ this._setPointsColorOrUV(mesh, pointsGroup, true);
2857
+ break;
2858
+ case 3 /* PointColor.Stated */:
2859
+ this._setPointsColorOrUV(mesh, pointsGroup, true, undefined, undefined, color, range);
2860
+ break;
2861
+ }
2862
+ this.nbParticles += nb;
2863
+ this._groupCounter++;
2864
+ return this._groupCounter - 1;
2865
+ }
2866
+ /**
2867
+ * Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.
2868
+ * This method calls `updateParticle()` for each particle of the SPS.
2869
+ * For an animated SPS, it is usually called within the render loop.
2870
+ * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_
2871
+ * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_
2872
+ * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_
2873
+ * @returns the PCS.
2874
+ */
2875
+ setParticles(start = 0, end = this.nbParticles - 1, update = true) {
2876
+ if (!this._updatable || !this._isReady) {
2877
+ return this;
2878
+ }
2879
+ // custom beforeUpdate
2880
+ this.beforeUpdateParticles(start, end, update);
2881
+ const rotMatrix = TmpVectors.Matrix[0];
2882
+ const mesh = this.mesh;
2883
+ const colors32 = this._colors32;
2884
+ const positions32 = this._positions32;
2885
+ const uvs32 = this._uvs32;
2886
+ const tempVectors = TmpVectors.Vector3;
2887
+ const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);
2888
+ const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);
2889
+ const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);
2890
+ const minimum = tempVectors[8].setAll(Number.MAX_VALUE);
2891
+ const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);
2892
+ Matrix.IdentityToRef(rotMatrix);
2893
+ let idx = 0; // current index of the particle
2894
+ if (this.mesh?.isFacetDataEnabled) {
2895
+ this._computeBoundingBox = true;
2896
+ }
2897
+ end = end >= this.nbParticles ? this.nbParticles - 1 : end;
2898
+ if (this._computeBoundingBox) {
2899
+ if (start != 0 || end != this.nbParticles - 1) {
2900
+ // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
2901
+ const boundingInfo = this.mesh?.getBoundingInfo();
2902
+ if (boundingInfo) {
2903
+ minimum.copyFrom(boundingInfo.minimum);
2904
+ maximum.copyFrom(boundingInfo.maximum);
2905
+ }
2906
+ }
2907
+ }
2908
+ idx = 0; // particle index
2909
+ let pindex = 0; //index in positions array
2910
+ let cindex = 0; //index in color array
2911
+ let uindex = 0; //index in uv array
2912
+ // particle loop
2913
+ for (let p = start; p <= end; p++) {
2914
+ const particle = this.particles[p];
2915
+ idx = particle.idx;
2916
+ pindex = 3 * idx;
2917
+ cindex = 4 * idx;
2918
+ uindex = 2 * idx;
2919
+ // call to custom user function to update the particle properties
2920
+ this.updateParticle(particle);
2921
+ const particleRotationMatrix = particle._rotationMatrix;
2922
+ const particlePosition = particle.position;
2923
+ const particleGlobalPosition = particle._globalPosition;
2924
+ if (this._computeParticleRotation) {
2925
+ particle.getRotationMatrix(rotMatrix);
2926
+ }
2927
+ const particleHasParent = particle.parentId !== null;
2928
+ if (particleHasParent) {
2929
+ const parent = this.particles[particle.parentId];
2930
+ const parentRotationMatrix = parent._rotationMatrix;
2931
+ const parentGlobalPosition = parent._globalPosition;
2932
+ const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];
2933
+ const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];
2934
+ const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];
2935
+ particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;
2936
+ particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;
2937
+ particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;
2938
+ if (this._computeParticleRotation) {
2939
+ const rotMatrixValues = rotMatrix.m;
2940
+ particleRotationMatrix[0] =
2941
+ rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];
2942
+ particleRotationMatrix[1] =
2943
+ rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];
2944
+ particleRotationMatrix[2] =
2945
+ rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];
2946
+ particleRotationMatrix[3] =
2947
+ rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];
2948
+ particleRotationMatrix[4] =
2949
+ rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];
2950
+ particleRotationMatrix[5] =
2951
+ rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];
2952
+ particleRotationMatrix[6] =
2953
+ rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];
2954
+ particleRotationMatrix[7] =
2955
+ rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];
2956
+ particleRotationMatrix[8] =
2957
+ rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];
2958
+ }
2959
+ }
2960
+ else {
2961
+ particleGlobalPosition.x = 0;
2962
+ particleGlobalPosition.y = 0;
2963
+ particleGlobalPosition.z = 0;
2964
+ if (this._computeParticleRotation) {
2965
+ const rotMatrixValues = rotMatrix.m;
2966
+ particleRotationMatrix[0] = rotMatrixValues[0];
2967
+ particleRotationMatrix[1] = rotMatrixValues[1];
2968
+ particleRotationMatrix[2] = rotMatrixValues[2];
2969
+ particleRotationMatrix[3] = rotMatrixValues[4];
2970
+ particleRotationMatrix[4] = rotMatrixValues[5];
2971
+ particleRotationMatrix[5] = rotMatrixValues[6];
2972
+ particleRotationMatrix[6] = rotMatrixValues[8];
2973
+ particleRotationMatrix[7] = rotMatrixValues[9];
2974
+ particleRotationMatrix[8] = rotMatrixValues[10];
2975
+ }
2976
+ }
2977
+ const pivotBackTranslation = tempVectors[11];
2978
+ if (particle.translateFromPivot) {
2979
+ pivotBackTranslation.setAll(0.0);
2980
+ }
2981
+ else {
2982
+ pivotBackTranslation.copyFrom(particle.pivot);
2983
+ }
2984
+ // positions
2985
+ const tmpVertex = tempVectors[0];
2986
+ tmpVertex.copyFrom(particle.position);
2987
+ const vertexX = tmpVertex.x - particle.pivot.x;
2988
+ const vertexY = tmpVertex.y - particle.pivot.y;
2989
+ const vertexZ = tmpVertex.z - particle.pivot.z;
2990
+ let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];
2991
+ let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];
2992
+ let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];
2993
+ rotatedX += pivotBackTranslation.x;
2994
+ rotatedY += pivotBackTranslation.y;
2995
+ rotatedZ += pivotBackTranslation.z;
2996
+ const px = (positions32[pindex] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ);
2997
+ const py = (positions32[pindex + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ);
2998
+ const pz = (positions32[pindex + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ);
2999
+ if (this._computeBoundingBox) {
3000
+ minimum.minimizeInPlaceFromFloats(px, py, pz);
3001
+ maximum.maximizeInPlaceFromFloats(px, py, pz);
3002
+ }
3003
+ if (this._computeParticleColor && particle.color) {
3004
+ const color = particle.color;
3005
+ const colors32 = this._colors32;
3006
+ colors32[cindex] = color.r;
3007
+ colors32[cindex + 1] = color.g;
3008
+ colors32[cindex + 2] = color.b;
3009
+ colors32[cindex + 3] = color.a;
3010
+ }
3011
+ if (this._computeParticleTexture && particle.uv) {
3012
+ const uv = particle.uv;
3013
+ const uvs32 = this._uvs32;
3014
+ uvs32[uindex] = uv.x;
3015
+ uvs32[uindex + 1] = uv.y;
3016
+ }
3017
+ }
3018
+ // if the VBO must be updated
3019
+ if (mesh) {
3020
+ if (update) {
3021
+ if (this._computeParticleColor) {
3022
+ mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);
3023
+ }
3024
+ if (this._computeParticleTexture) {
3025
+ mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);
3026
+ }
3027
+ mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);
3028
+ }
3029
+ if (this._computeBoundingBox) {
3030
+ if (mesh.hasBoundingInfo) {
3031
+ mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);
3032
+ }
3033
+ else {
3034
+ mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);
3035
+ }
3036
+ }
3037
+ }
3038
+ this.afterUpdateParticles(start, end, update);
3039
+ return this;
3040
+ }
3041
+ /**
3042
+ * Disposes the PCS.
3043
+ */
3044
+ dispose() {
3045
+ this.mesh?.dispose();
3046
+ this.vars = null;
3047
+ // drop references to internal big arrays for the GC
3048
+ this._positions = null;
3049
+ this._indices = null;
3050
+ this._normals = null;
3051
+ this._uvs = null;
3052
+ this._colors = null;
3053
+ this._indices32 = null;
3054
+ this._positions32 = null;
3055
+ this._uvs32 = null;
3056
+ this._colors32 = null;
3057
+ }
3058
+ /**
3059
+ * Visibility helper : Recomputes the visible size according to the mesh bounding box
3060
+ * doc :
3061
+ * @returns the PCS.
3062
+ */
3063
+ refreshVisibleSize() {
3064
+ if (!this._isVisibilityBoxLocked) {
3065
+ this.mesh?.refreshBoundingInfo();
3066
+ }
3067
+ return this;
3068
+ }
3069
+ /**
3070
+ * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.
3071
+ * @param size the size (float) of the visibility box
3072
+ * note : this doesn't lock the PCS mesh bounding box.
3073
+ * doc :
3074
+ */
3075
+ setVisibilityBox(size) {
3076
+ if (!this.mesh) {
3077
+ return;
3078
+ }
3079
+ const vis = size / 2;
3080
+ this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));
3081
+ }
3082
+ /**
3083
+ * Gets whether the PCS is always visible or not
3084
+ * doc :
3085
+ */
3086
+ get isAlwaysVisible() {
3087
+ return this._alwaysVisible;
3088
+ }
3089
+ /**
3090
+ * Sets the PCS as always visible or not
3091
+ * doc :
3092
+ */
3093
+ set isAlwaysVisible(val) {
3094
+ if (!this.mesh) {
3095
+ return;
3096
+ }
3097
+ this._alwaysVisible = val;
3098
+ this.mesh.alwaysSelectAsActiveMesh = val;
3099
+ }
3100
+ /**
3101
+ * Tells to `setParticles()` to compute the particle rotations or not
3102
+ * Default value : false. The PCS is faster when it's set to false
3103
+ * Note : particle rotations are only applied to parent particles
3104
+ * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate
3105
+ */
3106
+ set computeParticleRotation(val) {
3107
+ this._computeParticleRotation = val;
3108
+ }
3109
+ /**
3110
+ * Tells to `setParticles()` to compute the particle colors or not.
3111
+ * Default value : true. The PCS is faster when it's set to false.
3112
+ * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
3113
+ */
3114
+ set computeParticleColor(val) {
3115
+ this._computeParticleColor = val;
3116
+ }
3117
+ set computeParticleTexture(val) {
3118
+ this._computeParticleTexture = val;
3119
+ }
3120
+ /**
3121
+ * Gets if `setParticles()` computes the particle colors or not.
3122
+ * Default value : false. The PCS is faster when it's set to false.
3123
+ * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
3124
+ */
3125
+ get computeParticleColor() {
3126
+ return this._computeParticleColor;
3127
+ }
3128
+ /**
3129
+ * Gets if `setParticles()` computes the particle textures or not.
3130
+ * Default value : false. The PCS is faster when it's set to false.
3131
+ * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.
3132
+ */
3133
+ get computeParticleTexture() {
3134
+ return this._computeParticleTexture;
3135
+ }
3136
+ /**
3137
+ * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.
3138
+ */
3139
+ set computeBoundingBox(val) {
3140
+ this._computeBoundingBox = val;
3141
+ }
3142
+ /**
3143
+ * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.
3144
+ */
3145
+ get computeBoundingBox() {
3146
+ return this._computeBoundingBox;
3147
+ }
3148
+ // =======================================================================
3149
+ // Particle behavior logic
3150
+ // these following methods may be overwritten by users to fit their needs
3151
+ /**
3152
+ * This function does nothing. It may be overwritten to set all the particle first values.
3153
+ * The PCS doesn't call this function, you may have to call it by your own.
3154
+ * doc :
3155
+ */
3156
+ initParticles() { }
3157
+ /**
3158
+ * This function does nothing. It may be overwritten to recycle a particle
3159
+ * The PCS doesn't call this function, you can to call it
3160
+ * doc :
3161
+ * @param particle The particle to recycle
3162
+ * @returns the recycled particle
3163
+ */
3164
+ recycleParticle(particle) {
3165
+ return particle;
3166
+ }
3167
+ /**
3168
+ * Updates a particle : this function should be overwritten by the user.
3169
+ * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.
3170
+ * doc :
3171
+ * @example : just set a particle position or velocity and recycle conditions
3172
+ * @param particle The particle to update
3173
+ * @returns the updated particle
3174
+ */
3175
+ updateParticle(particle) {
3176
+ return particle;
3177
+ }
3178
+ /**
3179
+ * This will be called before any other treatment by `setParticles()` and will be passed three parameters.
3180
+ * This does nothing and may be overwritten by the user.
3181
+ * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()
3182
+ * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
3183
+ * @param update the boolean update value actually passed to setParticles()
3184
+ */
3185
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3186
+ beforeUpdateParticles(start, stop, update) { }
3187
+ /**
3188
+ * This will be called by `setParticles()` after all the other treatments and just before the actual mesh update.
3189
+ * This will be passed three parameters.
3190
+ * This does nothing and may be overwritten by the user.
3191
+ * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()
3192
+ * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
3193
+ * @param update the boolean update value actually passed to setParticles()
3194
+ */
3195
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3196
+ afterUpdateParticles(start, stop, update) { }
3197
+ }
3198
+
3199
+ /**
3200
+ * Indicator of the parsed ply buffer. A standard ready to use splat or an array of positions for a point cloud
3201
+ */
3202
+ var Mode;
3203
+ (function (Mode) {
3204
+ Mode[Mode["Splat"] = 0] = "Splat";
3205
+ Mode[Mode["PointCloud"] = 1] = "PointCloud";
3206
+ Mode[Mode["Mesh"] = 2] = "Mesh";
3207
+ Mode[Mode["Reject"] = 3] = "Reject";
3208
+ })(Mode || (Mode = {}));
3209
+ /**
3210
+ * @experimental
3211
+ * SPLAT file type loader.
3212
+ * This is a babylon scene loader plugin.
3213
+ */
3214
+ class SPLATFileLoader {
3215
+ /**
3216
+ * Creates loader for gaussian splatting files
3217
+ * @param loadingOptions options for loading and parsing splat and PLY files.
3218
+ */
3219
+ constructor(loadingOptions = SPLATFileLoader._DefaultLoadingOptions) {
3220
+ /**
3221
+ * Defines the name of the plugin.
3222
+ */
3223
+ this.name = SPLATFileLoaderMetadata.name;
3224
+ this._assetContainer = null;
3225
+ /**
3226
+ * Defines the extensions the splat loader is able to load.
3227
+ * force data to come in as an ArrayBuffer
3228
+ */
3229
+ this.extensions = SPLATFileLoaderMetadata.extensions;
3230
+ this._loadingOptions = loadingOptions;
3231
+ }
3232
+ /** @internal */
3233
+ createPlugin(options) {
3234
+ return new SPLATFileLoader(options[SPLATFileLoaderMetadata.name]);
3235
+ }
3236
+ /**
3237
+ * Imports from the loaded gaussian splatting data and adds them to the scene
3238
+ * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
3239
+ * @param scene the scene the meshes should be added to
3240
+ * @param data the gaussian splatting data to load
3241
+ * @param rootUrl root url to load from
3242
+ * @param onProgress callback called while file is loading
3243
+ * @param fileName Defines the name of the file to load
3244
+ * @returns a promise containing the loaded meshes, particles, skeletons and animations
3245
+ */
3246
+ async importMeshAsync(meshesNames, scene, data, rootUrl, onProgress, fileName) {
3247
+ return this._parse(meshesNames, scene, data, rootUrl).then((meshes) => {
3248
+ return {
3249
+ meshes: meshes,
3250
+ particleSystems: [],
3251
+ skeletons: [],
3252
+ animationGroups: [],
3253
+ transformNodes: [],
3254
+ geometries: [],
3255
+ lights: [],
3256
+ spriteManagers: [],
3257
+ };
3258
+ });
3259
+ }
3260
+ static _BuildPointCloud(pointcloud, data) {
3261
+ if (!data.byteLength) {
3262
+ return false;
3263
+ }
3264
+ const uBuffer = new Uint8Array(data);
3265
+ const fBuffer = new Float32Array(data);
3266
+ // parsed array contains room for position(3floats), normal(3floats), color (4b), quantized quaternion (4b)
3267
+ const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
3268
+ const vertexCount = uBuffer.length / rowLength;
3269
+ const pointcloudfunc = function (particle, i) {
3270
+ const x = fBuffer[8 * i + 0];
3271
+ const y = fBuffer[8 * i + 1];
3272
+ const z = fBuffer[8 * i + 2];
3273
+ particle.position = new Vector3(x, y, z);
3274
+ const r = uBuffer[rowLength * i + 24 + 0] / 255;
3275
+ const g = uBuffer[rowLength * i + 24 + 1] / 255;
3276
+ const b = uBuffer[rowLength * i + 24 + 2] / 255;
3277
+ particle.color = new Color4(r, g, b, 1);
3278
+ };
3279
+ pointcloud.addPoints(vertexCount, pointcloudfunc);
3280
+ return true;
3281
+ }
3282
+ static _BuildMesh(scene, parsedPLY) {
3283
+ const mesh = new Mesh("PLYMesh", scene);
3284
+ const uBuffer = new Uint8Array(parsedPLY.data);
3285
+ const fBuffer = new Float32Array(parsedPLY.data);
3286
+ const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
3287
+ const vertexCount = uBuffer.length / rowLength;
3288
+ const positions = [];
3289
+ const vertexData = new VertexData();
3290
+ for (let i = 0; i < vertexCount; i++) {
3291
+ const x = fBuffer[8 * i + 0];
3292
+ const y = fBuffer[8 * i + 1];
3293
+ const z = fBuffer[8 * i + 2];
3294
+ positions.push(x, y, z);
3295
+ }
3296
+ if (parsedPLY.hasVertexColors) {
3297
+ const colors = new Float32Array(vertexCount * 4);
3298
+ for (let i = 0; i < vertexCount; i++) {
3299
+ const r = uBuffer[rowLength * i + 24 + 0] / 255;
3300
+ const g = uBuffer[rowLength * i + 24 + 1] / 255;
3301
+ const b = uBuffer[rowLength * i + 24 + 2] / 255;
3302
+ colors[i * 4 + 0] = r;
3303
+ colors[i * 4 + 1] = g;
3304
+ colors[i * 4 + 2] = b;
3305
+ colors[i * 4 + 3] = 1;
3306
+ }
3307
+ vertexData.colors = colors;
3308
+ }
3309
+ vertexData.positions = positions;
3310
+ vertexData.indices = parsedPLY.faces;
3311
+ vertexData.applyToMesh(mesh);
3312
+ return mesh;
3313
+ }
3314
+ _parseSPZ(data, scene) {
3315
+ const ubuf = new Uint8Array(data);
3316
+ const ubufu32 = new Uint32Array(data);
3317
+ // debug infos
3318
+ const splatCount = ubufu32[2];
3319
+ const shDegree = ubuf[12];
3320
+ const fractionalBits = ubuf[13];
3321
+ //const flags = ubuf[14];
3322
+ const reserved = ubuf[15];
3323
+ // check magic and version
3324
+ if (reserved || ubufu32[0] != 0x5053474e || ubufu32[1] != 2) {
3325
+ // reserved must be 0
3326
+ return new Promise((resolve) => {
3327
+ resolve({ mode: 3 /* Mode.Reject */, data: buffer, hasVertexColors: false });
3328
+ });
3329
+ }
3330
+ const rowOutputLength = 3 * 4 + 3 * 4 + 4 + 4; // 32
3331
+ const buffer = new ArrayBuffer(rowOutputLength * splatCount);
3332
+ const positionScale = 1.0 / (1 << fractionalBits);
3333
+ const int32View = new Int32Array(1);
3334
+ const uint8View = new Uint8Array(int32View.buffer);
3335
+ const read24bComponent = function (u8, offset) {
3336
+ uint8View[0] = u8[offset + 0];
3337
+ uint8View[1] = u8[offset + 1];
3338
+ uint8View[2] = u8[offset + 2];
3339
+ uint8View[3] = u8[offset + 2] & 0x80 ? 0xff : 0x00;
3340
+ return int32View[0] * positionScale;
3341
+ };
3342
+ let byteOffset = 16;
3343
+ const position = new Float32Array(buffer);
3344
+ const scale = new Float32Array(buffer);
3345
+ const rgba = new Uint8ClampedArray(buffer);
3346
+ const rot = new Uint8ClampedArray(buffer);
3347
+ // positions
3348
+ for (let i = 0; i < splatCount; i++) {
3349
+ position[i * 8 + 0] = read24bComponent(ubuf, byteOffset + 0);
3350
+ position[i * 8 + 1] = read24bComponent(ubuf, byteOffset + 3);
3351
+ position[i * 8 + 2] = read24bComponent(ubuf, byteOffset + 6);
3352
+ byteOffset += 9;
3353
+ }
3354
+ // colors
3355
+ const SH_C0 = 0.282;
3356
+ for (let i = 0; i < splatCount; i++) {
3357
+ for (let component = 0; component < 3; component++) {
3358
+ const byteValue = ubuf[byteOffset + splatCount + i * 3 + component];
3359
+ // 0.15 is hard coded value from spz
3360
+ // Scale factor for DC color components. To convert to RGB, we should multiply by 0.282, but it can
3361
+ // be useful to represent base colors that are out of range if the higher spherical harmonics bands
3362
+ // bring them back into range so we multiply by a smaller value.
3363
+ const value = (byteValue - 127.5) / (0.15 * 255);
3364
+ rgba[i * 32 + 24 + component] = Scalar.Clamp((0.5 + SH_C0 * value) * 255, 0, 255);
3365
+ }
3366
+ rgba[i * 32 + 24 + 3] = ubuf[byteOffset + i];
3367
+ }
3368
+ byteOffset += splatCount * 4;
3369
+ // scales
3370
+ for (let i = 0; i < splatCount; i++) {
3371
+ scale[i * 8 + 3 + 0] = Math.exp(ubuf[byteOffset + 0] / 16.0 - 10.0);
3372
+ scale[i * 8 + 3 + 1] = Math.exp(ubuf[byteOffset + 1] / 16.0 - 10.0);
3373
+ scale[i * 8 + 3 + 2] = Math.exp(ubuf[byteOffset + 2] / 16.0 - 10.0);
3374
+ byteOffset += 3;
3375
+ }
3376
+ // convert quaternion
3377
+ for (let i = 0; i < splatCount; i++) {
3378
+ const x = ubuf[byteOffset + 0];
3379
+ const y = ubuf[byteOffset + 1];
3380
+ const z = ubuf[byteOffset + 2];
3381
+ const nx = x / 127.5 - 1;
3382
+ const ny = y / 127.5 - 1;
3383
+ const nz = z / 127.5 - 1;
3384
+ rot[i * 32 + 28 + 1] = x;
3385
+ rot[i * 32 + 28 + 2] = y;
3386
+ rot[i * 32 + 28 + 3] = z;
3387
+ const v = 1 - (nx * nx + ny * ny + nz * nz);
3388
+ rot[i * 32 + 28 + 0] = 127.5 + Math.sqrt(v < 0 ? 0 : v) * 127.5;
3389
+ byteOffset += 3;
3390
+ }
3391
+ //SH
3392
+ if (shDegree) {
3393
+ // shVectorCount is : 3 for dim = 1, 8 for dim = 2 and 15 for dim = 3
3394
+ // number of vec3 vector needed per splat
3395
+ const shVectorCount = (shDegree + 1) * (shDegree + 1) - 1; // minus 1 because sh0 is color
3396
+ // number of component values : 3 per vector3 (45)
3397
+ const shComponentCount = shVectorCount * 3;
3398
+ const textureCount = Math.ceil(shComponentCount / 16); // 4 components can be stored per texture, 4 sh per component
3399
+ let shIndexRead = byteOffset;
3400
+ // sh is an array of uint8array that will be used to create sh textures
3401
+ const sh = [];
3402
+ const engine = scene.getEngine();
3403
+ const width = engine.getCaps().maxTextureSize;
3404
+ const height = Math.ceil(splatCount / width);
3405
+ // create array for the number of textures needed.
3406
+ for (let textureIndex = 0; textureIndex < textureCount; textureIndex++) {
3407
+ const texture = new Uint8Array(height * width * 4 * 4); // 4 components per texture, 4 sh per component
3408
+ sh.push(texture);
3409
+ }
3410
+ for (let i = 0; i < splatCount; i++) {
3411
+ for (let shIndexWrite = 0; shIndexWrite < shComponentCount; shIndexWrite++) {
3412
+ const shValue = ubuf[shIndexRead++];
3413
+ const textureIndex = Math.floor(shIndexWrite / 16);
3414
+ const shArray = sh[textureIndex];
3415
+ const byteIndexInTexture = shIndexWrite % 16; // [0..15]
3416
+ const offsetPerSplat = i * 16; // 16 sh values per texture per splat.
3417
+ shArray[byteIndexInTexture + offsetPerSplat] = shValue;
3418
+ }
3419
+ }
3420
+ return new Promise((resolve) => {
3421
+ resolve({ mode: 0 /* Mode.Splat */, data: buffer, hasVertexColors: false, sh: sh });
3422
+ });
3423
+ }
3424
+ return new Promise((resolve) => {
3425
+ resolve({ mode: 0 /* Mode.Splat */, data: buffer, hasVertexColors: false });
3426
+ });
3427
+ }
3428
+ _parse(meshesNames, scene, data, rootUrl) {
3429
+ const babylonMeshesArray = []; //The mesh for babylon
3430
+ const readableStream = new ReadableStream({
3431
+ start(controller) {
3432
+ controller.enqueue(new Uint8Array(data)); // Enqueue the ArrayBuffer as a Uint8Array
3433
+ controller.close();
3434
+ },
3435
+ });
3436
+ // Use GZip DecompressionStream
3437
+ const decompressionStream = new DecompressionStream("gzip");
3438
+ const decompressedStream = readableStream.pipeThrough(decompressionStream);
3439
+ return new Promise((resolve) => {
3440
+ new Response(decompressedStream)
3441
+ .arrayBuffer()
3442
+ .then((buffer) => {
3443
+ this._parseSPZ(buffer, scene).then((parsedSPZ) => {
3444
+ const gaussianSplatting = new GaussianSplattingMesh("GaussianSplatting", null, scene, this._loadingOptions.keepInRam);
3445
+ gaussianSplatting._parentContainer = this._assetContainer;
3446
+ babylonMeshesArray.push(gaussianSplatting);
3447
+ gaussianSplatting.updateData(parsedSPZ.data, parsedSPZ.sh);
3448
+ });
3449
+ resolve(babylonMeshesArray);
3450
+ })
3451
+ .catch(() => {
3452
+ // Catch any decompression errors
3453
+ SPLATFileLoader._ConvertPLYToSplat(data).then(async (parsedPLY) => {
3454
+ switch (parsedPLY.mode) {
3455
+ case 0 /* Mode.Splat */:
3456
+ {
3457
+ const gaussianSplatting = new GaussianSplattingMesh("GaussianSplatting", null, scene, this._loadingOptions.keepInRam);
3458
+ gaussianSplatting._parentContainer = this._assetContainer;
3459
+ babylonMeshesArray.push(gaussianSplatting);
3460
+ gaussianSplatting.updateData(parsedPLY.data);
3461
+ }
3462
+ break;
3463
+ case 1 /* Mode.PointCloud */:
3464
+ {
3465
+ const pointcloud = new PointsCloudSystem("PointCloud", 1, scene);
3466
+ if (SPLATFileLoader._BuildPointCloud(pointcloud, parsedPLY.data)) {
3467
+ await pointcloud.buildMeshAsync().then((mesh) => {
3468
+ babylonMeshesArray.push(mesh);
3469
+ });
3470
+ }
3471
+ else {
3472
+ pointcloud.dispose();
3473
+ }
3474
+ }
3475
+ break;
3476
+ case 2 /* Mode.Mesh */:
3477
+ {
3478
+ if (parsedPLY.faces) {
3479
+ babylonMeshesArray.push(SPLATFileLoader._BuildMesh(scene, parsedPLY));
3480
+ }
3481
+ else {
3482
+ throw new Error("PLY mesh doesn't contain face informations.");
3483
+ }
3484
+ }
3485
+ break;
3486
+ default:
3487
+ throw new Error("Unsupported Splat mode");
3488
+ }
3489
+ resolve(babylonMeshesArray);
3490
+ });
3491
+ });
3492
+ });
3493
+ }
3494
+ /**
3495
+ * Load into an asset container.
3496
+ * @param scene The scene to load into
3497
+ * @param data The data to import
3498
+ * @param rootUrl The root url for scene and resources
3499
+ * @returns The loaded asset container
3500
+ */
3501
+ loadAssetContainerAsync(scene, data, rootUrl) {
3502
+ const container = new AssetContainer(scene);
3503
+ this._assetContainer = container;
3504
+ return this.importMeshAsync(null, scene, data, rootUrl)
3505
+ .then((result) => {
3506
+ result.meshes.forEach((mesh) => container.meshes.push(mesh));
3507
+ // mesh material will be null before 1st rendered frame.
3508
+ this._assetContainer = null;
3509
+ return container;
3510
+ })
3511
+ .catch((ex) => {
3512
+ this._assetContainer = null;
3513
+ throw ex;
3514
+ });
3515
+ }
3516
+ /**
3517
+ * Imports all objects from the loaded OBJ data and adds them to the scene
3518
+ * @param scene the scene the objects should be added to
3519
+ * @param data the OBJ data to load
3520
+ * @param rootUrl root url to load from
3521
+ * @returns a promise which completes when objects have been loaded to the scene
3522
+ */
3523
+ loadAsync(scene, data, rootUrl) {
3524
+ //Get the 3D model
3525
+ return this.importMeshAsync(null, scene, data, rootUrl).then(() => {
3526
+ // return void
3527
+ });
3528
+ }
3529
+ /**
3530
+ * Code from https://github.com/dylanebert/gsplat.js/blob/main/src/loaders/PLYLoader.ts Under MIT license
3531
+ * Converts a .ply data array buffer to splat
3532
+ * if data array buffer is not ply, returns the original buffer
3533
+ * @param data the .ply data to load
3534
+ * @returns the loaded splat buffer
3535
+ */
3536
+ static _ConvertPLYToSplat(data) {
3537
+ const ubuf = new Uint8Array(data);
3538
+ const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));
3539
+ const headerEnd = "end_header\n";
3540
+ const headerEndIndex = header.indexOf(headerEnd);
3541
+ if (headerEndIndex < 0 || !header) {
3542
+ // standard splat
3543
+ return new Promise((resolve) => {
3544
+ resolve({ mode: 0 /* Mode.Splat */, data: data });
3545
+ });
3546
+ }
3547
+ const vertexCount = parseInt(/element vertex (\d+)\n/.exec(header)[1]);
3548
+ const faceElement = /element face (\d+)\n/.exec(header);
3549
+ let faceCount = 0;
3550
+ if (faceElement) {
3551
+ faceCount = parseInt(faceElement[1]);
3552
+ }
3553
+ const chunkElement = /element chunk (\d+)\n/.exec(header);
3554
+ let chunkCount = 0;
3555
+ if (chunkElement) {
3556
+ chunkCount = parseInt(chunkElement[1]);
3557
+ }
3558
+ let rowVertexOffset = 0;
3559
+ let rowChunkOffset = 0;
3560
+ const offsets = {
3561
+ double: 8,
3562
+ int: 4,
3563
+ uint: 4,
3564
+ float: 4,
3565
+ short: 2,
3566
+ ushort: 2,
3567
+ uchar: 1,
3568
+ list: 0,
3569
+ };
3570
+ let ElementMode;
3571
+ (function (ElementMode) {
3572
+ ElementMode[ElementMode["Vertex"] = 0] = "Vertex";
3573
+ ElementMode[ElementMode["Chunk"] = 1] = "Chunk";
3574
+ })(ElementMode || (ElementMode = {}));
3575
+ let chunkMode = 1 /* ElementMode.Chunk */;
3576
+ const vertexProperties = [];
3577
+ const filtered = header.slice(0, headerEndIndex).split("\n");
3578
+ for (const prop of filtered) {
3579
+ if (prop.startsWith("property ")) {
3580
+ const [, type, name] = prop.split(" ");
3581
+ if (chunkMode == 1 /* ElementMode.Chunk */) {
3582
+ rowChunkOffset += offsets[type];
3583
+ }
3584
+ else if (chunkMode == 0 /* ElementMode.Vertex */) {
3585
+ vertexProperties.push({ name, type, offset: rowVertexOffset });
3586
+ rowVertexOffset += offsets[type];
3587
+ }
3588
+ if (!offsets[type]) {
3589
+ Logger.Warn(`Unsupported property type: ${type}.`);
3590
+ }
3591
+ }
3592
+ else if (prop.startsWith("element ")) {
3593
+ const [, type] = prop.split(" ");
3594
+ if (type == "chunk") {
3595
+ chunkMode = 1 /* ElementMode.Chunk */;
3596
+ }
3597
+ else if (type == "vertex") {
3598
+ chunkMode = 0 /* ElementMode.Vertex */;
3599
+ }
3600
+ }
3601
+ }
3602
+ const rowVertexLength = rowVertexOffset;
3603
+ const rowChunkLength = rowChunkOffset;
3604
+ return GaussianSplattingMesh.ConvertPLYWithSHToSplatAsync(data).then((splatsData) => {
3605
+ const dataView = new DataView(data, headerEndIndex + headerEnd.length);
3606
+ let offset = rowChunkLength * chunkCount + rowVertexLength * vertexCount;
3607
+ // faces
3608
+ const faces = [];
3609
+ if (faceCount) {
3610
+ for (let i = 0; i < faceCount; i++) {
3611
+ const faceVertexCount = dataView.getUint8(offset);
3612
+ if (faceVertexCount != 3) {
3613
+ continue; // only support triangles
3614
+ }
3615
+ offset += 1;
3616
+ for (let j = 0; j < faceVertexCount; j++) {
3617
+ const vertexIndex = dataView.getUint32(offset + (2 - j) * 4, true); // change face winding
3618
+ faces.push(vertexIndex);
3619
+ }
3620
+ offset += 12;
3621
+ }
3622
+ }
3623
+ // early exit for chunked/quantized ply
3624
+ if (chunkCount) {
3625
+ return new Promise((resolve) => {
3626
+ resolve({ mode: 0 /* Mode.Splat */, data: splatsData.buffer, sh: splatsData.sh, faces: faces, hasVertexColors: false });
3627
+ });
3628
+ }
3629
+ // count available properties. if all necessary are present then it's a splat. Otherwise, it's a point cloud
3630
+ // if faces are found, then it's a standard mesh
3631
+ let propertyCount = 0;
3632
+ let propertyColorCount = 0;
3633
+ const splatProperties = ["x", "y", "z", "scale_0", "scale_1", "scale_2", "opacity", "rot_0", "rot_1", "rot_2", "rot_3"];
3634
+ const splatColorProperties = ["red", "green", "blue", "f_dc_0", "f_dc_1", "f_dc_2"];
3635
+ for (let propertyIndex = 0; propertyIndex < vertexProperties.length; propertyIndex++) {
3636
+ const property = vertexProperties[propertyIndex];
3637
+ if (splatProperties.includes(property.name)) {
3638
+ propertyCount++;
3639
+ }
3640
+ if (splatColorProperties.includes(property.name)) {
3641
+ propertyColorCount++;
3642
+ }
3643
+ }
3644
+ const hasMandatoryProperties = propertyCount == splatProperties.length && propertyColorCount == 3;
3645
+ const currentMode = faceCount ? 2 /* Mode.Mesh */ : hasMandatoryProperties ? 0 /* Mode.Splat */ : 1 /* Mode.PointCloud */;
3646
+ // parsed ready ready to be used as a splat
3647
+ return new Promise((resolve) => {
3648
+ resolve({ mode: currentMode, data: splatsData.buffer, sh: splatsData.sh, faces: faces, hasVertexColors: !!propertyColorCount });
3649
+ });
3650
+ });
3651
+ }
3652
+ }
3653
+ SPLATFileLoader._DefaultLoadingOptions = {
3654
+ keepInRam: false,
3655
+ };
3656
+ // Add this loader into the register plugin
3657
+ registerSceneLoaderPlugin(new SPLATFileLoader());
3658
+
3659
+ export { SPLATFileLoader };
3660
+ //# sourceMappingURL=splatFileLoader-K9RpjB6c.esm.js.map