@babylonjs/viewer 7.25.1-alpha → 7.25.1

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 (530) hide show
  1. package/configuration/configuration.d.ts +107 -0
  2. package/configuration/configuration.js +16 -0
  3. package/configuration/configuration.js.map +1 -0
  4. package/configuration/configurationCompatibility.d.ts +8 -0
  5. package/configuration/configurationCompatibility.js +66 -0
  6. package/configuration/configurationCompatibility.js.map +1 -0
  7. package/configuration/configurationContainer.d.ts +10 -0
  8. package/configuration/configurationContainer.js +10 -0
  9. package/configuration/configurationContainer.js.map +1 -0
  10. package/configuration/globals.d.ts +6 -0
  11. package/configuration/globals.js +18 -0
  12. package/configuration/globals.js.map +1 -0
  13. package/configuration/index.d.ts +2 -0
  14. package/configuration/index.js +4 -0
  15. package/configuration/index.js.map +1 -0
  16. package/configuration/interfaces/cameraConfiguration.d.ts +31 -0
  17. package/configuration/interfaces/cameraConfiguration.js +2 -0
  18. package/configuration/interfaces/cameraConfiguration.js.map +1 -0
  19. package/configuration/interfaces/colorGradingConfiguration.d.ts +81 -0
  20. package/configuration/interfaces/colorGradingConfiguration.js +2 -0
  21. package/configuration/interfaces/colorGradingConfiguration.js.map +1 -0
  22. package/configuration/interfaces/defaultRenderingPipelineConfiguration.d.ts +20 -0
  23. package/configuration/interfaces/defaultRenderingPipelineConfiguration.js +2 -0
  24. package/configuration/interfaces/defaultRenderingPipelineConfiguration.js.map +1 -0
  25. package/configuration/interfaces/environmentMapConfiguration.d.ts +22 -0
  26. package/configuration/interfaces/environmentMapConfiguration.js +2 -0
  27. package/configuration/interfaces/environmentMapConfiguration.js.map +1 -0
  28. package/configuration/interfaces/groundConfiguration.d.ts +24 -0
  29. package/configuration/interfaces/groundConfiguration.js +2 -0
  30. package/configuration/interfaces/groundConfiguration.js.map +1 -0
  31. package/configuration/interfaces/imageProcessingConfiguration.d.ts +45 -0
  32. package/configuration/interfaces/imageProcessingConfiguration.js +2 -0
  33. package/configuration/interfaces/imageProcessingConfiguration.js.map +1 -0
  34. package/configuration/interfaces/index.d.ts +15 -0
  35. package/configuration/interfaces/index.js +16 -0
  36. package/configuration/interfaces/index.js.map +1 -0
  37. package/configuration/interfaces/lightConfiguration.d.ts +60 -0
  38. package/configuration/interfaces/lightConfiguration.js +2 -0
  39. package/configuration/interfaces/lightConfiguration.js.map +1 -0
  40. package/configuration/interfaces/modelAnimationConfiguration.d.ts +26 -0
  41. package/configuration/interfaces/modelAnimationConfiguration.js +2 -0
  42. package/configuration/interfaces/modelAnimationConfiguration.js.map +1 -0
  43. package/configuration/interfaces/modelConfiguration.d.ts +65 -0
  44. package/configuration/interfaces/modelConfiguration.js +2 -0
  45. package/configuration/interfaces/modelConfiguration.js.map +1 -0
  46. package/configuration/interfaces/observersConfiguration.d.ts +5 -0
  47. package/configuration/interfaces/observersConfiguration.js +2 -0
  48. package/configuration/interfaces/observersConfiguration.js.map +1 -0
  49. package/configuration/interfaces/sceneConfiguration.d.ts +48 -0
  50. package/configuration/interfaces/sceneConfiguration.js +2 -0
  51. package/configuration/interfaces/sceneConfiguration.js.map +1 -0
  52. package/configuration/interfaces/sceneOptimizerConfiguration.d.ts +23 -0
  53. package/configuration/interfaces/sceneOptimizerConfiguration.js +2 -0
  54. package/configuration/interfaces/sceneOptimizerConfiguration.js.map +1 -0
  55. package/configuration/interfaces/skyboxConfiguration.d.ts +21 -0
  56. package/configuration/interfaces/skyboxConfiguration.js +2 -0
  57. package/configuration/interfaces/skyboxConfiguration.js.map +1 -0
  58. package/configuration/interfaces/templateConfiguration.d.ts +67 -0
  59. package/configuration/interfaces/templateConfiguration.js +2 -0
  60. package/configuration/interfaces/templateConfiguration.js.map +1 -0
  61. package/configuration/interfaces/vrConfiguration.d.ts +16 -0
  62. package/configuration/interfaces/vrConfiguration.js +2 -0
  63. package/configuration/interfaces/vrConfiguration.js.map +1 -0
  64. package/configuration/loader.d.ts +4 -0
  65. package/configuration/loader.js +17 -0
  66. package/configuration/loader.js.map +1 -0
  67. package/configuration/mappers.d.ts +43 -0
  68. package/configuration/mappers.js +192 -0
  69. package/configuration/mappers.js.map +1 -0
  70. package/configuration/renderOnlyLoader.d.ts +33 -0
  71. package/configuration/renderOnlyLoader.js +162 -0
  72. package/configuration/renderOnlyLoader.js.map +1 -0
  73. package/configuration/types/default.d.ts +6 -0
  74. package/configuration/types/default.js +121 -0
  75. package/configuration/types/default.js.map +1 -0
  76. package/configuration/types/environmentMap.d.ts +5 -0
  77. package/configuration/types/environmentMap.js +14 -0
  78. package/configuration/types/environmentMap.js.map +1 -0
  79. package/configuration/types/extended.d.ts +6 -0
  80. package/configuration/types/extended.js +317 -0
  81. package/configuration/types/extended.js.map +1 -0
  82. package/configuration/types/index.d.ts +14 -0
  83. package/configuration/types/index.js +51 -0
  84. package/configuration/types/index.js.map +1 -0
  85. package/configuration/types/minimal.d.ts +6 -0
  86. package/configuration/types/minimal.js +43 -0
  87. package/configuration/types/minimal.js.map +1 -0
  88. package/configuration/types/renderOnlyDefault.d.ts +30 -0
  89. package/configuration/types/renderOnlyDefault.js +31 -0
  90. package/configuration/types/renderOnlyDefault.js.map +1 -0
  91. package/configuration/types/shadowLight.d.ts +9 -0
  92. package/configuration/types/shadowLight.js +64 -0
  93. package/configuration/types/shadowLight.js.map +1 -0
  94. package/helper/index.d.ts +29 -0
  95. package/helper/index.js +66 -0
  96. package/helper/index.js.map +1 -0
  97. package/index.d.ts +30 -0
  98. package/index.js +46 -0
  99. package/index.js.map +1 -0
  100. package/initializer.d.ts +11 -0
  101. package/initializer.js +35 -0
  102. package/initializer.js.map +1 -0
  103. package/interfaces.d.ts +5 -0
  104. package/interfaces.js +7 -0
  105. package/interfaces.js.map +1 -0
  106. package/labs/environmentSerializer.d.ts +126 -0
  107. package/labs/environmentSerializer.js +191 -0
  108. package/labs/environmentSerializer.js.map +1 -0
  109. package/labs/texture.d.ts +183 -0
  110. package/labs/texture.js +350 -0
  111. package/labs/texture.js.map +1 -0
  112. package/labs/viewerLabs.d.ts +51 -0
  113. package/labs/viewerLabs.js +134 -0
  114. package/labs/viewerLabs.js.map +1 -0
  115. package/loader/modelLoader.d.ts +56 -0
  116. package/loader/modelLoader.js +199 -0
  117. package/loader/modelLoader.js.map +1 -0
  118. package/loader/plugins/applyMaterialConfig.d.ts +12 -0
  119. package/loader/plugins/applyMaterialConfig.js +16 -0
  120. package/loader/plugins/applyMaterialConfig.js.map +1 -0
  121. package/loader/plugins/extendedMaterialLoaderPlugin.d.ts +9 -0
  122. package/loader/plugins/extendedMaterialLoaderPlugin.js +16 -0
  123. package/loader/plugins/extendedMaterialLoaderPlugin.js.map +1 -0
  124. package/loader/plugins/index.d.ts +19 -0
  125. package/loader/plugins/index.js +44 -0
  126. package/loader/plugins/index.js.map +1 -0
  127. package/loader/plugins/loaderPlugin.d.ts +24 -0
  128. package/loader/plugins/loaderPlugin.js +2 -0
  129. package/loader/plugins/loaderPlugin.js.map +1 -0
  130. package/loader/plugins/msftLodLoaderPlugin.d.ts +12 -0
  131. package/loader/plugins/msftLodLoaderPlugin.js +21 -0
  132. package/loader/plugins/msftLodLoaderPlugin.js.map +1 -0
  133. package/loader/plugins/telemetryLoaderPlugin.d.ts +12 -0
  134. package/loader/plugins/telemetryLoaderPlugin.js +36 -0
  135. package/loader/plugins/telemetryLoaderPlugin.js.map +1 -0
  136. package/managers/observablesManager.d.ts +66 -0
  137. package/managers/observablesManager.js +35 -0
  138. package/managers/observablesManager.js.map +1 -0
  139. package/managers/sceneManager.d.ts +245 -0
  140. package/managers/sceneManager.js +1375 -0
  141. package/managers/sceneManager.js.map +1 -0
  142. package/managers/telemetryManager.d.ts +78 -0
  143. package/managers/telemetryManager.js +117 -0
  144. package/managers/telemetryManager.js.map +1 -0
  145. package/model/modelAnimation.d.ts +215 -0
  146. package/model/modelAnimation.js +237 -0
  147. package/model/modelAnimation.js.map +1 -0
  148. package/model/viewerModel.d.ts +233 -0
  149. package/model/viewerModel.js +673 -0
  150. package/model/viewerModel.js.map +1 -0
  151. package/optimizer/custom/extended.d.ts +13 -0
  152. package/optimizer/custom/extended.js +101 -0
  153. package/optimizer/custom/extended.js.map +1 -0
  154. package/optimizer/custom/index.d.ts +9 -0
  155. package/optimizer/custom/index.js +26 -0
  156. package/optimizer/custom/index.js.map +1 -0
  157. package/package.json +27 -17
  158. package/readme.md +21 -35
  159. package/renderOnlyIndex.d.ts +11 -0
  160. package/renderOnlyIndex.js +18 -0
  161. package/renderOnlyIndex.js.map +1 -0
  162. package/templating/eventManager.d.ts +35 -0
  163. package/templating/eventManager.js +66 -0
  164. package/templating/eventManager.js.map +1 -0
  165. package/templating/plugins/hdButtonPlugin.d.ts +9 -0
  166. package/templating/plugins/hdButtonPlugin.js +21 -0
  167. package/templating/plugins/hdButtonPlugin.js.map +1 -0
  168. package/templating/plugins/printButton.d.ts +9 -0
  169. package/templating/plugins/printButton.js +40 -0
  170. package/templating/plugins/printButton.js.map +1 -0
  171. package/templating/templateManager.d.ts +197 -0
  172. package/templating/templateManager.js +561 -0
  173. package/templating/templateManager.js.map +1 -0
  174. package/templating/viewerTemplatePlugin.d.ts +21 -0
  175. package/templating/viewerTemplatePlugin.js +69 -0
  176. package/templating/viewerTemplatePlugin.js.map +1 -0
  177. package/viewer/defaultViewer.d.ts +130 -0
  178. package/viewer/defaultViewer.js +675 -0
  179. package/viewer/defaultViewer.js.map +1 -0
  180. package/viewer/renderOnlyViewer.d.ts +9 -0
  181. package/viewer/renderOnlyViewer.js +46 -0
  182. package/viewer/renderOnlyViewer.js.map +1 -0
  183. package/viewer/viewer.d.ts +258 -0
  184. package/viewer/viewer.js +783 -0
  185. package/viewer/viewer.js.map +1 -0
  186. package/viewer/viewerManager.d.ts +58 -0
  187. package/viewer/viewerManager.js +91 -0
  188. package/viewer/viewerManager.js.map +1 -0
  189. package/viewer/viewerWithTemplate.d.ts +9 -0
  190. package/viewer/viewerWithTemplate.js +20 -0
  191. package/viewer/viewerWithTemplate.js.map +1 -0
  192. package/dist/babylon-viewer.esm.js +0 -2
  193. package/dist/babylon-viewer.esm.js.map +0 -1
  194. package/dist/babylon-viewer.esm.min.js +0 -2
  195. package/dist/babylon-viewer.esm.min.js.map +0 -1
  196. package/dist/chunks/EXT_lights_image_based-DVT9d5PE.esm.min.js +0 -2
  197. package/dist/chunks/EXT_lights_image_based-DVT9d5PE.esm.min.js.map +0 -1
  198. package/dist/chunks/EXT_lights_image_based-XqDzs68T.esm.js +0 -170
  199. package/dist/chunks/EXT_lights_image_based-XqDzs68T.esm.js.map +0 -1
  200. package/dist/chunks/EXT_mesh_gpu_instancing-BDdwYyny.esm.min.js +0 -2
  201. package/dist/chunks/EXT_mesh_gpu_instancing-BDdwYyny.esm.min.js.map +0 -1
  202. package/dist/chunks/EXT_mesh_gpu_instancing-DhR2UOBn.esm.js +0 -86
  203. package/dist/chunks/EXT_mesh_gpu_instancing-DhR2UOBn.esm.js.map +0 -1
  204. package/dist/chunks/EXT_meshopt_compression-BqFzh0gY.esm.js +0 -134
  205. package/dist/chunks/EXT_meshopt_compression-BqFzh0gY.esm.js.map +0 -1
  206. package/dist/chunks/EXT_meshopt_compression-SfXDvdUM.esm.min.js +0 -2
  207. package/dist/chunks/EXT_meshopt_compression-SfXDvdUM.esm.min.js.map +0 -1
  208. package/dist/chunks/EXT_texture_avif-JBIGyeRc.esm.js +0 -44
  209. package/dist/chunks/EXT_texture_avif-JBIGyeRc.esm.js.map +0 -1
  210. package/dist/chunks/EXT_texture_avif-q1TkH_G9.esm.min.js +0 -2
  211. package/dist/chunks/EXT_texture_avif-q1TkH_G9.esm.min.js.map +0 -1
  212. package/dist/chunks/EXT_texture_webp-B1s3FiRS.esm.js +0 -43
  213. package/dist/chunks/EXT_texture_webp-B1s3FiRS.esm.js.map +0 -1
  214. package/dist/chunks/EXT_texture_webp-BCI9KAUl.esm.min.js +0 -2
  215. package/dist/chunks/EXT_texture_webp-BCI9KAUl.esm.min.js.map +0 -1
  216. package/dist/chunks/ExtrasAsMetadata-BOD2FG8I.esm.min.js +0 -2
  217. package/dist/chunks/ExtrasAsMetadata-BOD2FG8I.esm.min.js.map +0 -1
  218. package/dist/chunks/ExtrasAsMetadata-ByiJUaSt.esm.js +0 -64
  219. package/dist/chunks/ExtrasAsMetadata-ByiJUaSt.esm.js.map +0 -1
  220. package/dist/chunks/KHR_animation_pointer-CNYMXY_w.esm.js +0 -343
  221. package/dist/chunks/KHR_animation_pointer-CNYMXY_w.esm.js.map +0 -1
  222. package/dist/chunks/KHR_animation_pointer-CnLRV_yl.esm.min.js +0 -2
  223. package/dist/chunks/KHR_animation_pointer-CnLRV_yl.esm.min.js.map +0 -1
  224. package/dist/chunks/KHR_draco_mesh_compression-AZ2o_aLj.esm.min.js +0 -2
  225. package/dist/chunks/KHR_draco_mesh_compression-AZ2o_aLj.esm.min.js.map +0 -1
  226. package/dist/chunks/KHR_draco_mesh_compression-DFY2Ctvm.esm.js +0 -610
  227. package/dist/chunks/KHR_draco_mesh_compression-DFY2Ctvm.esm.js.map +0 -1
  228. package/dist/chunks/KHR_interactivity-3PDcMKr_.esm.js +0 -4033
  229. package/dist/chunks/KHR_interactivity-3PDcMKr_.esm.js.map +0 -1
  230. package/dist/chunks/KHR_interactivity-C-cfOaao.esm.min.js +0 -2
  231. package/dist/chunks/KHR_interactivity-C-cfOaao.esm.min.js.map +0 -1
  232. package/dist/chunks/KHR_lights_punctual-DdpvJMDV.esm.js +0 -1253
  233. package/dist/chunks/KHR_lights_punctual-DdpvJMDV.esm.js.map +0 -1
  234. package/dist/chunks/KHR_lights_punctual-fnDFOclN.esm.min.js +0 -2
  235. package/dist/chunks/KHR_lights_punctual-fnDFOclN.esm.min.js.map +0 -1
  236. package/dist/chunks/KHR_materials_anisotropy-Cb6X0k3m.esm.min.js +0 -2
  237. package/dist/chunks/KHR_materials_anisotropy-Cb6X0k3m.esm.min.js.map +0 -1
  238. package/dist/chunks/KHR_materials_anisotropy-gNrsYmJY.esm.js +0 -64
  239. package/dist/chunks/KHR_materials_anisotropy-gNrsYmJY.esm.js.map +0 -1
  240. package/dist/chunks/KHR_materials_clearcoat-U2HUz3WB.esm.js +0 -96
  241. package/dist/chunks/KHR_materials_clearcoat-U2HUz3WB.esm.js.map +0 -1
  242. package/dist/chunks/KHR_materials_clearcoat-joUz7tSd.esm.min.js +0 -2
  243. package/dist/chunks/KHR_materials_clearcoat-joUz7tSd.esm.min.js.map +0 -1
  244. package/dist/chunks/KHR_materials_diffuse_transmission-Cm1IFxmL.esm.min.js +0 -2
  245. package/dist/chunks/KHR_materials_diffuse_transmission-Cm1IFxmL.esm.min.js.map +0 -1
  246. package/dist/chunks/KHR_materials_diffuse_transmission-Cn5gk-q_.esm.js +0 -97
  247. package/dist/chunks/KHR_materials_diffuse_transmission-Cn5gk-q_.esm.js.map +0 -1
  248. package/dist/chunks/KHR_materials_dispersion-Cpc2ME1B.esm.js +0 -62
  249. package/dist/chunks/KHR_materials_dispersion-Cpc2ME1B.esm.js.map +0 -1
  250. package/dist/chunks/KHR_materials_dispersion-Cv7zIL7j.esm.min.js +0 -2
  251. package/dist/chunks/KHR_materials_dispersion-Cv7zIL7j.esm.min.js.map +0 -1
  252. package/dist/chunks/KHR_materials_emissive_strength-BYxJ1Qaz.esm.js +0 -55
  253. package/dist/chunks/KHR_materials_emissive_strength-BYxJ1Qaz.esm.js.map +0 -1
  254. package/dist/chunks/KHR_materials_emissive_strength-DBEC-Pfr.esm.min.js +0 -2
  255. package/dist/chunks/KHR_materials_emissive_strength-DBEC-Pfr.esm.min.js.map +0 -1
  256. package/dist/chunks/KHR_materials_ior-B4HgptNe.esm.min.js +0 -2
  257. package/dist/chunks/KHR_materials_ior-B4HgptNe.esm.min.js.map +0 -1
  258. package/dist/chunks/KHR_materials_ior-CDtowU9f.esm.js +0 -64
  259. package/dist/chunks/KHR_materials_ior-CDtowU9f.esm.js.map +0 -1
  260. package/dist/chunks/KHR_materials_iridescence-CgkruUTk.esm.min.js +0 -2
  261. package/dist/chunks/KHR_materials_iridescence-CgkruUTk.esm.min.js.map +0 -1
  262. package/dist/chunks/KHR_materials_iridescence-CqmvyPW8.esm.js +0 -72
  263. package/dist/chunks/KHR_materials_iridescence-CqmvyPW8.esm.js.map +0 -1
  264. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-BQV0asO5.esm.js +0 -81
  265. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-BQV0asO5.esm.js.map +0 -1
  266. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-Bv4SCrwb.esm.min.js +0 -2
  267. package/dist/chunks/KHR_materials_pbrSpecularGlossiness-Bv4SCrwb.esm.min.js.map +0 -1
  268. package/dist/chunks/KHR_materials_sheen-BQM2Rjmq.esm.js +0 -85
  269. package/dist/chunks/KHR_materials_sheen-BQM2Rjmq.esm.js.map +0 -1
  270. package/dist/chunks/KHR_materials_sheen-DV5CnbK2.esm.min.js +0 -2
  271. package/dist/chunks/KHR_materials_sheen-DV5CnbK2.esm.min.js.map +0 -1
  272. package/dist/chunks/KHR_materials_specular-4xCkE2rV.esm.js +0 -75
  273. package/dist/chunks/KHR_materials_specular-4xCkE2rV.esm.js.map +0 -1
  274. package/dist/chunks/KHR_materials_specular-CoAFRAcm.esm.min.js +0 -2
  275. package/dist/chunks/KHR_materials_specular-CoAFRAcm.esm.min.js.map +0 -1
  276. package/dist/chunks/KHR_materials_transmission-DUGtSvRL.esm.js +0 -307
  277. package/dist/chunks/KHR_materials_transmission-DUGtSvRL.esm.js.map +0 -1
  278. package/dist/chunks/KHR_materials_transmission-dc1ndoxL.esm.min.js +0 -2
  279. package/dist/chunks/KHR_materials_transmission-dc1ndoxL.esm.min.js.map +0 -1
  280. package/dist/chunks/KHR_materials_unlit-BNXbHdvw.esm.js +0 -74
  281. package/dist/chunks/KHR_materials_unlit-BNXbHdvw.esm.js.map +0 -1
  282. package/dist/chunks/KHR_materials_unlit-D9MVjMTN.esm.min.js +0 -2
  283. package/dist/chunks/KHR_materials_unlit-D9MVjMTN.esm.min.js.map +0 -1
  284. package/dist/chunks/KHR_materials_variants-CBW9J72v.esm.min.js +0 -2
  285. package/dist/chunks/KHR_materials_variants-CBW9J72v.esm.min.js.map +0 -1
  286. package/dist/chunks/KHR_materials_variants-Dkur-XMA.esm.js +0 -238
  287. package/dist/chunks/KHR_materials_variants-Dkur-XMA.esm.js.map +0 -1
  288. package/dist/chunks/KHR_materials_volume-BSWwp0PI.esm.js +0 -87
  289. package/dist/chunks/KHR_materials_volume-BSWwp0PI.esm.js.map +0 -1
  290. package/dist/chunks/KHR_materials_volume-uEEN0xx9.esm.min.js +0 -2
  291. package/dist/chunks/KHR_materials_volume-uEEN0xx9.esm.min.js.map +0 -1
  292. package/dist/chunks/KHR_mesh_quantization--7YAD1i9.esm.js +0 -26
  293. package/dist/chunks/KHR_mesh_quantization--7YAD1i9.esm.js.map +0 -1
  294. package/dist/chunks/KHR_mesh_quantization-D48i0ooq.esm.min.js +0 -2
  295. package/dist/chunks/KHR_mesh_quantization-D48i0ooq.esm.min.js.map +0 -1
  296. package/dist/chunks/KHR_texture_basisu-CJHQOtEz.esm.min.js +0 -2
  297. package/dist/chunks/KHR_texture_basisu-CJHQOtEz.esm.min.js.map +0 -1
  298. package/dist/chunks/KHR_texture_basisu-CZJ-szw2.esm.js +0 -43
  299. package/dist/chunks/KHR_texture_basisu-CZJ-szw2.esm.js.map +0 -1
  300. package/dist/chunks/KHR_texture_transform-CCGZOtJG.esm.js +0 -63
  301. package/dist/chunks/KHR_texture_transform-CCGZOtJG.esm.js.map +0 -1
  302. package/dist/chunks/KHR_texture_transform-Cz_tYWj9.esm.min.js +0 -2
  303. package/dist/chunks/KHR_texture_transform-Cz_tYWj9.esm.min.js.map +0 -1
  304. package/dist/chunks/KHR_xmp_json_ld-BWhXh4yX.esm.min.js +0 -2
  305. package/dist/chunks/KHR_xmp_json_ld-BWhXh4yX.esm.min.js.map +0 -1
  306. package/dist/chunks/KHR_xmp_json_ld-D8vGUblu.esm.js +0 -51
  307. package/dist/chunks/KHR_xmp_json_ld-D8vGUblu.esm.js.map +0 -1
  308. package/dist/chunks/MSFT_audio_emitter-CABqee9Z.esm.min.js +0 -2
  309. package/dist/chunks/MSFT_audio_emitter-CABqee9Z.esm.min.js.map +0 -1
  310. package/dist/chunks/MSFT_audio_emitter-CupxtNMJ.esm.js +0 -2236
  311. package/dist/chunks/MSFT_audio_emitter-CupxtNMJ.esm.js.map +0 -1
  312. package/dist/chunks/MSFT_lod-BZ6xhN71.esm.min.js +0 -2
  313. package/dist/chunks/MSFT_lod-BZ6xhN71.esm.min.js.map +0 -1
  314. package/dist/chunks/MSFT_lod-D6-TVSnT.esm.js +0 -337
  315. package/dist/chunks/MSFT_lod-D6-TVSnT.esm.js.map +0 -1
  316. package/dist/chunks/MSFT_minecraftMesh-DXKcYd7c.esm.js +0 -46
  317. package/dist/chunks/MSFT_minecraftMesh-DXKcYd7c.esm.js.map +0 -1
  318. package/dist/chunks/MSFT_minecraftMesh-jQGuk0z2.esm.min.js +0 -2
  319. package/dist/chunks/MSFT_minecraftMesh-jQGuk0z2.esm.min.js.map +0 -1
  320. package/dist/chunks/MSFT_sRGBFactors-CMIEJuDa.esm.min.js +0 -2
  321. package/dist/chunks/MSFT_sRGBFactors-CMIEJuDa.esm.min.js.map +0 -1
  322. package/dist/chunks/MSFT_sRGBFactors-D1di9DYd.esm.js +0 -47
  323. package/dist/chunks/MSFT_sRGBFactors-D1di9DYd.esm.js.map +0 -1
  324. package/dist/chunks/assetContainer-B4RZAzKO.esm.min.js +0 -2
  325. package/dist/chunks/assetContainer-B4RZAzKO.esm.min.js.map +0 -1
  326. package/dist/chunks/assetContainer-B_DdybqS.esm.js +0 -1598
  327. package/dist/chunks/assetContainer-B_DdybqS.esm.js.map +0 -1
  328. package/dist/chunks/audioEngine-BNEDnVbO.esm.min.js +0 -2
  329. package/dist/chunks/audioEngine-BNEDnVbO.esm.min.js.map +0 -1
  330. package/dist/chunks/audioEngine-CICNJdfP.esm.js +0 -305
  331. package/dist/chunks/audioEngine-CICNJdfP.esm.js.map +0 -1
  332. package/dist/chunks/basisTextureLoader-B_8qIBcv.esm.js +0 -600
  333. package/dist/chunks/basisTextureLoader-B_8qIBcv.esm.js.map +0 -1
  334. package/dist/chunks/basisTextureLoader-qwPrmlI1.esm.min.js +0 -2
  335. package/dist/chunks/basisTextureLoader-qwPrmlI1.esm.min.js.map +0 -1
  336. package/dist/chunks/ddsTextureLoader-Caj9Cn2g.esm.min.js +0 -2
  337. package/dist/chunks/ddsTextureLoader-Caj9Cn2g.esm.min.js.map +0 -1
  338. package/dist/chunks/ddsTextureLoader-Dtde5Y_E.esm.js +0 -87
  339. package/dist/chunks/ddsTextureLoader-Dtde5Y_E.esm.js.map +0 -1
  340. package/dist/chunks/default.fragment-3-A6Ds5q.esm.js +0 -456
  341. package/dist/chunks/default.fragment-3-A6Ds5q.esm.js.map +0 -1
  342. package/dist/chunks/default.fragment-CK_5aPIO.esm.js +0 -515
  343. package/dist/chunks/default.fragment-CK_5aPIO.esm.js.map +0 -1
  344. package/dist/chunks/default.fragment-CW6M2CvG.esm.min.js +0 -2
  345. package/dist/chunks/default.fragment-CW6M2CvG.esm.min.js.map +0 -1
  346. package/dist/chunks/default.fragment-D8IeeUuR.esm.min.js +0 -2
  347. package/dist/chunks/default.fragment-D8IeeUuR.esm.min.js.map +0 -1
  348. package/dist/chunks/default.vertex-BnmEG9Z3.esm.js +0 -178
  349. package/dist/chunks/default.vertex-BnmEG9Z3.esm.js.map +0 -1
  350. package/dist/chunks/default.vertex-CByxmCU_.esm.min.js +0 -2
  351. package/dist/chunks/default.vertex-CByxmCU_.esm.min.js.map +0 -1
  352. package/dist/chunks/default.vertex-CKXtUMTv.esm.min.js +0 -2
  353. package/dist/chunks/default.vertex-CKXtUMTv.esm.min.js.map +0 -1
  354. package/dist/chunks/default.vertex-D5kQBg6V.esm.js +0 -199
  355. package/dist/chunks/default.vertex-D5kQBg6V.esm.js.map +0 -1
  356. package/dist/chunks/defaultUboDeclaration-AgU83OaK.esm.min.js +0 -2
  357. package/dist/chunks/defaultUboDeclaration-AgU83OaK.esm.min.js.map +0 -1
  358. package/dist/chunks/defaultUboDeclaration-BTsCVlsd.esm.min.js +0 -2
  359. package/dist/chunks/defaultUboDeclaration-BTsCVlsd.esm.min.js.map +0 -1
  360. package/dist/chunks/defaultUboDeclaration-bGo0gkae.esm.js +0 -15
  361. package/dist/chunks/defaultUboDeclaration-bGo0gkae.esm.js.map +0 -1
  362. package/dist/chunks/defaultUboDeclaration-pi1Tffi-.esm.js +0 -13
  363. package/dist/chunks/defaultUboDeclaration-pi1Tffi-.esm.js.map +0 -1
  364. package/dist/chunks/engine-DDK673Fr.esm.js +0 -1613
  365. package/dist/chunks/engine-DDK673Fr.esm.js.map +0 -1
  366. package/dist/chunks/engine-DdeN2F9N.esm.min.js +0 -2
  367. package/dist/chunks/engine-DdeN2F9N.esm.min.js.map +0 -1
  368. package/dist/chunks/envTextureLoader-B_We3UAe.esm.min.js +0 -2
  369. package/dist/chunks/envTextureLoader-B_We3UAe.esm.min.js.map +0 -1
  370. package/dist/chunks/envTextureLoader-DeYk_D-u.esm.js +0 -63
  371. package/dist/chunks/envTextureLoader-DeYk_D-u.esm.js.map +0 -1
  372. package/dist/chunks/environmentTextureTools-DT_BQR6L.esm.min.js +0 -2
  373. package/dist/chunks/environmentTextureTools-DT_BQR6L.esm.min.js.map +0 -1
  374. package/dist/chunks/environmentTextureTools-DZ4GOzAY.esm.js +0 -381
  375. package/dist/chunks/environmentTextureTools-DZ4GOzAY.esm.js.map +0 -1
  376. package/dist/chunks/exrTextureLoader-BPFaquLu.esm.min.js +0 -2
  377. package/dist/chunks/exrTextureLoader-BPFaquLu.esm.min.js.map +0 -1
  378. package/dist/chunks/exrTextureLoader-DFfYDSvx.esm.js +0 -1682
  379. package/dist/chunks/exrTextureLoader-DFfYDSvx.esm.js.map +0 -1
  380. package/dist/chunks/fogFragment-ChBeVMbL.esm.min.js +0 -2
  381. package/dist/chunks/fogFragment-ChBeVMbL.esm.min.js.map +0 -1
  382. package/dist/chunks/fogFragment-CnlQ05Rn.esm.js +0 -102
  383. package/dist/chunks/fogFragment-CnlQ05Rn.esm.js.map +0 -1
  384. package/dist/chunks/glTFLoader-CfuuZdCb.esm.js +0 -7552
  385. package/dist/chunks/glTFLoader-CfuuZdCb.esm.js.map +0 -1
  386. package/dist/chunks/glTFLoader-DOyVt9PU.esm.min.js +0 -2
  387. package/dist/chunks/glTFLoader-DOyVt9PU.esm.min.js.map +0 -1
  388. package/dist/chunks/glTFLoaderAnimation-28_L-pzh.esm.js +0 -77
  389. package/dist/chunks/glTFLoaderAnimation-28_L-pzh.esm.js.map +0 -1
  390. package/dist/chunks/glTFLoaderAnimation-Cueukaay.esm.min.js +0 -2
  391. package/dist/chunks/glTFLoaderAnimation-Cueukaay.esm.min.js.map +0 -1
  392. package/dist/chunks/gltfPathToObjectConverter-Dyt_Y9jE.esm.min.js +0 -2
  393. package/dist/chunks/gltfPathToObjectConverter-Dyt_Y9jE.esm.min.js.map +0 -1
  394. package/dist/chunks/gltfPathToObjectConverter-GcUmfOyo.esm.js +0 -67
  395. package/dist/chunks/gltfPathToObjectConverter-GcUmfOyo.esm.js.map +0 -1
  396. package/dist/chunks/harmonicsFunctions-5m2TqpP7.esm.js +0 -34
  397. package/dist/chunks/harmonicsFunctions-5m2TqpP7.esm.js.map +0 -1
  398. package/dist/chunks/harmonicsFunctions-CZvW5nS2.esm.min.js +0 -2
  399. package/dist/chunks/harmonicsFunctions-CZvW5nS2.esm.min.js.map +0 -1
  400. package/dist/chunks/harmonicsFunctions-FoyoVJjx.esm.js +0 -35
  401. package/dist/chunks/harmonicsFunctions-FoyoVJjx.esm.js.map +0 -1
  402. package/dist/chunks/harmonicsFunctions-LPFcAay5.esm.min.js +0 -2
  403. package/dist/chunks/harmonicsFunctions-LPFcAay5.esm.min.js.map +0 -1
  404. package/dist/chunks/hdrTextureLoader-BF58jeD4.esm.min.js +0 -2
  405. package/dist/chunks/hdrTextureLoader-BF58jeD4.esm.min.js.map +0 -1
  406. package/dist/chunks/hdrTextureLoader-CnAlxQ46.esm.js +0 -252
  407. package/dist/chunks/hdrTextureLoader-CnAlxQ46.esm.js.map +0 -1
  408. package/dist/chunks/helperFunctions-BHi3ZDnH.esm.js +0 -80
  409. package/dist/chunks/helperFunctions-BHi3ZDnH.esm.js.map +0 -1
  410. package/dist/chunks/helperFunctions-D9QX7d8q.esm.min.js +0 -2
  411. package/dist/chunks/helperFunctions-D9QX7d8q.esm.min.js.map +0 -1
  412. package/dist/chunks/helperFunctions-bapbKVVS.esm.js +0 -108
  413. package/dist/chunks/helperFunctions-bapbKVVS.esm.js.map +0 -1
  414. package/dist/chunks/helperFunctions-hh2B4qDl.esm.min.js +0 -2
  415. package/dist/chunks/helperFunctions-hh2B4qDl.esm.min.js.map +0 -1
  416. package/dist/chunks/index-4QQveomY.esm.js +0 -79813
  417. package/dist/chunks/index-4QQveomY.esm.js.map +0 -1
  418. package/dist/chunks/index-D5606AHu.esm.min.js +0 -57
  419. package/dist/chunks/index-D5606AHu.esm.min.js.map +0 -1
  420. package/dist/chunks/ktxTextureLoader-CxAMFjnh.esm.js +0 -814
  421. package/dist/chunks/ktxTextureLoader-CxAMFjnh.esm.js.map +0 -1
  422. package/dist/chunks/ktxTextureLoader-s0dUXnt8.esm.min.js +0 -2
  423. package/dist/chunks/ktxTextureLoader-s0dUXnt8.esm.min.js.map +0 -1
  424. package/dist/chunks/logDepthDeclaration-BcnqcXJe.esm.js +0 -35
  425. package/dist/chunks/logDepthDeclaration-BcnqcXJe.esm.js.map +0 -1
  426. package/dist/chunks/logDepthDeclaration-CvXtMvcM.esm.js +0 -42
  427. package/dist/chunks/logDepthDeclaration-CvXtMvcM.esm.js.map +0 -1
  428. package/dist/chunks/logDepthDeclaration-cPWsL3PG.esm.min.js +0 -2
  429. package/dist/chunks/logDepthDeclaration-cPWsL3PG.esm.min.js.map +0 -1
  430. package/dist/chunks/logDepthDeclaration-unowpoZK.esm.min.js +0 -2
  431. package/dist/chunks/logDepthDeclaration-unowpoZK.esm.min.js.map +0 -1
  432. package/dist/chunks/logDepthVertex-BrvDYbCP.esm.min.js +0 -2
  433. package/dist/chunks/logDepthVertex-BrvDYbCP.esm.min.js.map +0 -1
  434. package/dist/chunks/logDepthVertex-CUUB4BTI.esm.js +0 -605
  435. package/dist/chunks/logDepthVertex-CUUB4BTI.esm.js.map +0 -1
  436. package/dist/chunks/logDepthVertex-DaNvEIGn.esm.min.js +0 -2
  437. package/dist/chunks/logDepthVertex-DaNvEIGn.esm.min.js.map +0 -1
  438. package/dist/chunks/logDepthVertex-foN2jGvJ.esm.js +0 -77
  439. package/dist/chunks/logDepthVertex-foN2jGvJ.esm.js.map +0 -1
  440. package/dist/chunks/mainUVVaryingDeclaration-DHTqc_aH.esm.js +0 -11
  441. package/dist/chunks/mainUVVaryingDeclaration-DHTqc_aH.esm.js.map +0 -1
  442. package/dist/chunks/mainUVVaryingDeclaration-PFUWfv7o.esm.min.js +0 -2
  443. package/dist/chunks/mainUVVaryingDeclaration-PFUWfv7o.esm.min.js.map +0 -1
  444. package/dist/chunks/objFileLoader-B-uLP26U.esm.min.js +0 -2
  445. package/dist/chunks/objFileLoader-B-uLP26U.esm.min.js.map +0 -1
  446. package/dist/chunks/objFileLoader-Bl2Pzv0o.esm.js +0 -1280
  447. package/dist/chunks/objFileLoader-Bl2Pzv0o.esm.js.map +0 -1
  448. package/dist/chunks/oitFragment-CZShr04f.esm.min.js +0 -2
  449. package/dist/chunks/oitFragment-CZShr04f.esm.min.js.map +0 -1
  450. package/dist/chunks/oitFragment-D3c3Lp9a.esm.js +0 -1210
  451. package/dist/chunks/oitFragment-D3c3Lp9a.esm.js.map +0 -1
  452. package/dist/chunks/oitFragment-D6uOdl_0.esm.min.js +0 -2
  453. package/dist/chunks/oitFragment-D6uOdl_0.esm.min.js.map +0 -1
  454. package/dist/chunks/oitFragment-E27tpA6b.esm.js +0 -1166
  455. package/dist/chunks/oitFragment-E27tpA6b.esm.js.map +0 -1
  456. package/dist/chunks/pass.fragment-CGX8gTNY.esm.js +0 -15
  457. package/dist/chunks/pass.fragment-CGX8gTNY.esm.js.map +0 -1
  458. package/dist/chunks/pass.fragment-DKqeYsmS.esm.min.js +0 -2
  459. package/dist/chunks/pass.fragment-DKqeYsmS.esm.min.js.map +0 -1
  460. package/dist/chunks/pbr.fragment-5XRl6pKm.esm.min.js +0 -2
  461. package/dist/chunks/pbr.fragment-5XRl6pKm.esm.min.js.map +0 -1
  462. package/dist/chunks/pbr.fragment-Cfsv9tFG.esm.js +0 -3172
  463. package/dist/chunks/pbr.fragment-Cfsv9tFG.esm.js.map +0 -1
  464. package/dist/chunks/pbr.fragment-DGBodARG.esm.min.js +0 -2
  465. package/dist/chunks/pbr.fragment-DGBodARG.esm.min.js.map +0 -1
  466. package/dist/chunks/pbr.fragment-IMDXwBnG.esm.js +0 -3228
  467. package/dist/chunks/pbr.fragment-IMDXwBnG.esm.js.map +0 -1
  468. package/dist/chunks/pbr.vertex-B3JKAxfl.esm.min.js +0 -2
  469. package/dist/chunks/pbr.vertex-B3JKAxfl.esm.min.js.map +0 -1
  470. package/dist/chunks/pbr.vertex-CZIasM0q.esm.js +0 -335
  471. package/dist/chunks/pbr.vertex-CZIasM0q.esm.js.map +0 -1
  472. package/dist/chunks/pbr.vertex-CjU0MUM9.esm.min.js +0 -2
  473. package/dist/chunks/pbr.vertex-CjU0MUM9.esm.min.js.map +0 -1
  474. package/dist/chunks/pbr.vertex-h6JyEpaS.esm.js +0 -208
  475. package/dist/chunks/pbr.vertex-h6JyEpaS.esm.js.map +0 -1
  476. package/dist/chunks/postprocess.vertex-B0ei94Dw.esm.min.js +0 -2
  477. package/dist/chunks/postprocess.vertex-B0ei94Dw.esm.min.js.map +0 -1
  478. package/dist/chunks/postprocess.vertex-r5NscKzh.esm.js +0 -20
  479. package/dist/chunks/postprocess.vertex-r5NscKzh.esm.js.map +0 -1
  480. package/dist/chunks/rawTexture-Bmw0auoS.esm.min.js +0 -2
  481. package/dist/chunks/rawTexture-Bmw0auoS.esm.min.js.map +0 -1
  482. package/dist/chunks/rawTexture-CpYqstLv.esm.js +0 -562
  483. package/dist/chunks/rawTexture-CpYqstLv.esm.js.map +0 -1
  484. package/dist/chunks/rgbdDecode.fragment-BBOPxYJO.esm.min.js +0 -2
  485. package/dist/chunks/rgbdDecode.fragment-BBOPxYJO.esm.min.js.map +0 -1
  486. package/dist/chunks/rgbdDecode.fragment-C1mQs3ed.esm.js +0 -17
  487. package/dist/chunks/rgbdDecode.fragment-C1mQs3ed.esm.js.map +0 -1
  488. package/dist/chunks/rgbdDecode.fragment-CaqsSeIW.esm.min.js +0 -2
  489. package/dist/chunks/rgbdDecode.fragment-CaqsSeIW.esm.min.js.map +0 -1
  490. package/dist/chunks/rgbdDecode.fragment-MPQ7knvL.esm.js +0 -17
  491. package/dist/chunks/rgbdDecode.fragment-MPQ7knvL.esm.js.map +0 -1
  492. package/dist/chunks/rgbdEncode.fragment-6EdQiINi.esm.min.js +0 -2
  493. package/dist/chunks/rgbdEncode.fragment-6EdQiINi.esm.min.js.map +0 -1
  494. package/dist/chunks/rgbdEncode.fragment-C-msuzIz.esm.min.js +0 -2
  495. package/dist/chunks/rgbdEncode.fragment-C-msuzIz.esm.min.js.map +0 -1
  496. package/dist/chunks/rgbdEncode.fragment-Wd9cTDxy.esm.js +0 -17
  497. package/dist/chunks/rgbdEncode.fragment-Wd9cTDxy.esm.js.map +0 -1
  498. package/dist/chunks/rgbdEncode.fragment-X-RqQAkc.esm.js +0 -17
  499. package/dist/chunks/rgbdEncode.fragment-X-RqQAkc.esm.js.map +0 -1
  500. package/dist/chunks/splatFileLoader-DQ9jOQE9.esm.min.js +0 -2
  501. package/dist/chunks/splatFileLoader-DQ9jOQE9.esm.min.js.map +0 -1
  502. package/dist/chunks/splatFileLoader-hdSfXVdE.esm.js +0 -3154
  503. package/dist/chunks/splatFileLoader-hdSfXVdE.esm.js.map +0 -1
  504. package/dist/chunks/standardMaterial-Cq-J9fif.esm.min.js +0 -2
  505. package/dist/chunks/standardMaterial-Cq-J9fif.esm.min.js.map +0 -1
  506. package/dist/chunks/standardMaterial-GIGkmsd2.esm.js +0 -1809
  507. package/dist/chunks/standardMaterial-GIGkmsd2.esm.js.map +0 -1
  508. package/dist/chunks/stlFileLoader--AN8pgtb.esm.min.js +0 -2
  509. package/dist/chunks/stlFileLoader--AN8pgtb.esm.min.js.map +0 -1
  510. package/dist/chunks/stlFileLoader-BjJ0Yz5v.esm.js +0 -237
  511. package/dist/chunks/stlFileLoader-BjJ0Yz5v.esm.js.map +0 -1
  512. package/dist/chunks/tgaTextureLoader-B3gQ-Dwh.esm.min.js +0 -2
  513. package/dist/chunks/tgaTextureLoader-B3gQ-Dwh.esm.min.js.map +0 -1
  514. package/dist/chunks/tgaTextureLoader-BmEYbSF8.esm.js +0 -349
  515. package/dist/chunks/tgaTextureLoader-BmEYbSF8.esm.js.map +0 -1
  516. package/dist/chunks/thinInstanceMesh-DLE1cPa9.esm.js +0 -314
  517. package/dist/chunks/thinInstanceMesh-DLE1cPa9.esm.js.map +0 -1
  518. package/dist/chunks/thinInstanceMesh-DgJgeFTD.esm.min.js +0 -2
  519. package/dist/chunks/thinInstanceMesh-DgJgeFTD.esm.min.js.map +0 -1
  520. package/dist/chunks/vertexColorMixing-Dn7oXj03.esm.js +0 -528
  521. package/dist/chunks/vertexColorMixing-Dn7oXj03.esm.js.map +0 -1
  522. package/dist/chunks/vertexColorMixing-cD_XcjBD.esm.min.js +0 -2
  523. package/dist/chunks/vertexColorMixing-cD_XcjBD.esm.min.js.map +0 -1
  524. package/dist/chunks/workerPool-BUOov2K1.esm.js +0 -122
  525. package/dist/chunks/workerPool-BUOov2K1.esm.js.map +0 -1
  526. package/dist/chunks/workerPool-BWHiDmEZ.esm.min.js +0 -2
  527. package/dist/chunks/workerPool-BWHiDmEZ.esm.min.js.map +0 -1
  528. package/lib/index.d.ts +0 -275
  529. package/lib/index.js +0 -942
  530. package/lib/index.js.map +0 -1
@@ -1,3154 +0,0 @@
1
- import { S as ShaderStore, R as RegisterClass, l as PushMaterial, m as PrepareDefinesForMisc, n as PrepareDefinesForFrameBoundValues, o as PrepareDefinesForAttributes, p as PrepareAttributesForInstances, q as PrepareUniformsAndSamplersList, s as addClipPlaneUniforms, t as Camera, u as bindClipPlane, B as BindFogParameters, v as BindLogDepth, w as SerializationHelper, x as MaterialDefines, i as VertexBuffer, M as Mesh, y as Matrix, j as VertexData, z as SubMesh, D as TmpVectors, h as Vector3, L as Logger, k as Tools, V as Vector2, Q as Quaternion, C as Constants, g as Color4, F as BuildArray, H as Scene, J as PickingInfo, K as Epsilon, N as IntersectionInfo, E as EngineStore, e as Color3, U as Vector4, X as RandomRange, Y as BaseTexture, Z as SPLATFileLoaderMetadata, r as registerSceneLoaderPlugin } from './index-4QQveomY.esm.js';
2
- import './fogFragment-CnlQ05Rn.esm.js';
3
- import './logDepthDeclaration-BcnqcXJe.esm.js';
4
- import './logDepthVertex-foN2jGvJ.esm.js';
5
- import { R as RawTexture } from './rawTexture-CpYqstLv.esm.js';
6
- import './thinInstanceMesh-DLE1cPa9.esm.js';
7
- import { A as AssetContainer } from './assetContainer-B_DdybqS.esm.js';
8
- import { S as StandardMaterial } from './standardMaterial-GIGkmsd2.esm.js';
9
-
10
- // Do not edit.
11
- const name$3 = "gaussianSplattingPixelShader";
12
- const shader$3 = `#include<clipPlaneFragmentDeclaration>
13
- #include<logDepthDeclaration>
14
- #include<fogFragmentDeclaration>
15
- varying vec4 vColor;varying vec2 vPosition;void main () {
16
- #include<clipPlaneFragment>
17
- float A=-dot(vPosition,vPosition);if (A<-4.0) discard;float B=exp(A)*vColor.a;
18
- #include<logDepthFragment>
19
- vec3 color=vColor.rgb;
20
- #ifdef FOG
21
- #include<fogFragment>
22
- #endif
23
- gl_FragColor=vec4(color,B);}
24
- `;
25
- // Sideeffect
26
- ShaderStore.ShadersStore[name$3] = shader$3;
27
-
28
- // Do not edit.
29
- const name$2 = "gaussianSplattingVertexDeclaration";
30
- const shader$2 = `uniform mat4 world;uniform mat4 view;uniform mat4 projection;
31
- `;
32
- // Sideeffect
33
- ShaderStore.IncludesShadersStore[name$2] = shader$2;
34
-
35
- // Do not edit.
36
- const name$1 = "gaussianSplattingUboDeclaration";
37
- const shader$1 = `#include<sceneUboDeclaration>
38
- #include<meshUboDeclaration>
39
- `;
40
- // Sideeffect
41
- ShaderStore.IncludesShadersStore[name$1] = shader$1;
42
-
43
- // Do not edit.
44
- const name = "gaussianSplattingVertexShader";
45
- const shader = `#include<__decl__gaussianSplattingVertex>
46
- #ifdef LOGARITHMICDEPTH
47
- #extension GL_EXT_frag_depth : enable
48
- #endif
49
- #include<clipPlaneVertexDeclaration>
50
- #include<fogVertexDeclaration>
51
- #include<logDepthDeclaration>
52
- attribute vec2 position;attribute float splatIndex;uniform vec2 invViewport;uniform vec2 dataTextureSize;uniform vec2 focal;uniform sampler2D covariancesATexture;uniform sampler2D covariancesBTexture;uniform sampler2D centersTexture;uniform sampler2D colorsTexture;varying vec4 vColor;varying vec2 vPosition;
53
- #if !defined(WEBGL2) && !defined(WEBGPU) && !defined(NATIVE)
54
- mat3 transpose(mat3 matrix) {return mat3(matrix[0][0],matrix[1][0],matrix[2][0],
55
- matrix[0][1],matrix[1][1],matrix[2][1],
56
- matrix[0][2],matrix[1][2],matrix[2][2]);}
57
- #endif
58
- 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);}
59
- void main () {vec2 splatUV=getDataUV(splatIndex,dataTextureSize);vec3 center=texture2D(centersTexture,splatUV).xyz;vec4 color=texture2D(colorsTexture,splatUV);vec3 covA=texture2D(covariancesATexture,splatUV).xyz;vec3 covB=texture2D(covariancesBTexture,splatUV).xyz;vec4 worldPos=world*vec4(center,1.0);mat4 modelView=view*world;vec4 camspace=view*worldPos;vec4 pos2d=projection*camspace;float bounds=1.2*pos2d.w;if (pos2d.z<-pos2d.w || pos2d.x<-bounds || pos2d.x>bounds
60
- || pos2d.y<-bounds || pos2d.y>bounds) {gl_Position=vec4(0.0,0.0,2.0,1.0);return;}
61
- mat3 Vrk=mat3(
62
- covA.x,covA.y,covA.z,
63
- covA.y,covB.x,covB.y,
64
- covA.z,covB.y,covB.z
65
- );mat3 J=mat3(
66
- focal.x/camspace.z,0.,-(focal.x*camspace.x)/(camspace.z*camspace.z),
67
- 0.,focal.y/camspace.z,-(focal.y*camspace.y)/(camspace.z*camspace.z),
68
- 0.,0.,0.
69
- );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) return;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);vColor=color;vPosition=position;vec2 vCenter=vec2(pos2d);gl_Position=vec4(
70
- vCenter
71
- + (position.x*majorAxis
72
- + position.y*minorAxis)*invViewport*pos2d.w,pos2d.zw);
73
- #include<clipPlaneVertex>
74
- #include<fogVertex>
75
- #include<logDepthVertex>
76
- }
77
- `;
78
- // Sideeffect
79
- ShaderStore.ShadersStore[name] = shader;
80
-
81
- /**
82
- * @internal
83
- */
84
- class GaussianSplattingMaterialDefines extends MaterialDefines {
85
- /**
86
- * Constructor of the defines.
87
- */
88
- constructor() {
89
- super();
90
- this.FOG = false;
91
- this.THIN_INSTANCES = true;
92
- this.LOGARITHMICDEPTH = false;
93
- this.CLIPPLANE = false;
94
- this.CLIPPLANE2 = false;
95
- this.CLIPPLANE3 = false;
96
- this.CLIPPLANE4 = false;
97
- this.CLIPPLANE5 = false;
98
- this.CLIPPLANE6 = false;
99
- this.rebuild();
100
- }
101
- }
102
- /**
103
- * GaussianSplattingMaterial material used to render Gaussian Splatting
104
- * @experimental
105
- */
106
- class GaussianSplattingMaterial extends PushMaterial {
107
- /**
108
- * Instantiates a Gaussian Splatting Material in the given scene
109
- * @param name The friendly name of the material
110
- * @param scene The scene to add the material to
111
- */
112
- constructor(name, scene) {
113
- super(name, scene);
114
- this.backFaceCulling = false;
115
- }
116
- /**
117
- * Gets a boolean indicating that current material needs to register RTT
118
- */
119
- get hasRenderTargetTextures() {
120
- return false;
121
- }
122
- /**
123
- * Specifies whether or not this material should be rendered in alpha test mode.
124
- * @returns false
125
- */
126
- needAlphaTesting() {
127
- return false;
128
- }
129
- /**
130
- * Specifies whether or not this material should be rendered in alpha blend mode.
131
- * @returns true
132
- */
133
- needAlphaBlending() {
134
- return true;
135
- }
136
- /**
137
- * Checks whether the material is ready to be rendered for a given mesh.
138
- * @param mesh The mesh to render
139
- * @param subMesh The submesh to check against
140
- * @returns true if all the dependencies are ready (Textures, Effects...)
141
- */
142
- isReadyForSubMesh(mesh, subMesh) {
143
- const useInstances = true;
144
- const drawWrapper = subMesh._drawWrapper;
145
- if (drawWrapper.effect && this.isFrozen) {
146
- if (drawWrapper._wasPreviouslyReady && drawWrapper._wasPreviouslyUsingInstances === useInstances) {
147
- return true;
148
- }
149
- }
150
- if (!subMesh.materialDefines) {
151
- subMesh.materialDefines = new GaussianSplattingMaterialDefines();
152
- }
153
- const scene = this.getScene();
154
- const defines = subMesh.materialDefines;
155
- if (this._isReadyForSubMesh(subMesh)) {
156
- return true;
157
- }
158
- const engine = scene.getEngine();
159
- // Misc.
160
- PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, false, defines);
161
- // Values that need to be evaluated on every frame
162
- PrepareDefinesForFrameBoundValues(scene, engine, this, defines, useInstances, null, true);
163
- // Attribs
164
- PrepareDefinesForAttributes(mesh, defines, false, false);
165
- // Get correct effect
166
- if (defines.isDirty) {
167
- defines.markAsProcessed();
168
- scene.resetCachedMaterial();
169
- //Attributes
170
- const attribs = [VertexBuffer.PositionKind, "splatIndex"];
171
- PrepareAttributesForInstances(attribs, defines);
172
- const uniforms = ["world", "view", "projection", "vFogInfos", "vFogColor", "logarithmicDepthConstant", "invViewport", "dataTextureSize", "focal"];
173
- const samplers = ["covariancesATexture", "covariancesBTexture", "centersTexture", "colorsTexture"];
174
- const uniformBuffers = ["Scene", "Mesh"];
175
- PrepareUniformsAndSamplersList({
176
- uniformsNames: uniforms,
177
- uniformBuffersNames: uniformBuffers,
178
- samplers: samplers,
179
- defines: defines,
180
- });
181
- addClipPlaneUniforms(uniforms);
182
- const join = defines.toString();
183
- const effect = scene.getEngine().createEffect("gaussianSplatting", {
184
- attributes: attribs,
185
- uniformsNames: uniforms,
186
- uniformBuffersNames: uniformBuffers,
187
- samplers: samplers,
188
- defines: join,
189
- onCompiled: this.onCompiled,
190
- onError: this.onError,
191
- }, engine);
192
- subMesh.setEffect(effect, defines, this._materialContext);
193
- }
194
- if (!subMesh.effect || !subMesh.effect.isReady()) {
195
- return false;
196
- }
197
- defines._renderId = scene.getRenderId();
198
- drawWrapper._wasPreviouslyReady = true;
199
- drawWrapper._wasPreviouslyUsingInstances = useInstances;
200
- return true;
201
- }
202
- /**
203
- * Binds the submesh to this material by preparing the effect and shader to draw
204
- * @param world defines the world transformation matrix
205
- * @param mesh defines the mesh containing the submesh
206
- * @param subMesh defines the submesh to bind the material to
207
- */
208
- bindForSubMesh(world, mesh, subMesh) {
209
- const scene = this.getScene();
210
- const defines = subMesh.materialDefines;
211
- if (!defines) {
212
- return;
213
- }
214
- const effect = subMesh.effect;
215
- if (!effect) {
216
- return;
217
- }
218
- this._activeEffect = effect;
219
- // Matrices Mesh.
220
- mesh.getMeshUniformBuffer().bindToEffect(effect, "Mesh");
221
- mesh.transferToEffect(world);
222
- // Bind data
223
- const mustRebind = this._mustRebind(scene, effect, subMesh, mesh.visibility);
224
- if (mustRebind) {
225
- this.bindView(effect);
226
- this.bindViewProjection(effect);
227
- const engine = scene.getEngine();
228
- const camera = this.getScene().activeCamera;
229
- const renderWidth = engine.getRenderWidth();
230
- const renderHeight = engine.getRenderHeight();
231
- // check if rigcamera, get number of rigs
232
- const numberOfRigs = camera?.rigParent?.rigCameras.length || 1;
233
- this._activeEffect.setFloat2("invViewport", 1 / (renderWidth / numberOfRigs), 1 / renderHeight);
234
- let focal = 1000;
235
- if (camera) {
236
- /*
237
- more explicit version:
238
- const t = camera.getProjectionMatrix().m[5];
239
- const FovY = Math.atan(1.0 / t) * 2.0;
240
- focal = renderHeight / 2.0 / Math.tan(FovY / 2.0);
241
- Using a shorter version here to not have tan(atan) and 2.0 factor
242
- */
243
- const t = camera.getProjectionMatrix().m[5];
244
- if (camera.fovMode == Camera.FOVMODE_VERTICAL_FIXED) {
245
- focal = (renderHeight * t) / 2.0;
246
- }
247
- else {
248
- focal = (renderWidth * t) / 2.0;
249
- }
250
- }
251
- this._activeEffect.setFloat2("focal", focal, focal);
252
- const gsMesh = mesh;
253
- if (gsMesh.covariancesATexture) {
254
- const textureSize = gsMesh.covariancesATexture.getSize();
255
- effect.setFloat2("dataTextureSize", textureSize.width, textureSize.height);
256
- effect.setTexture("covariancesATexture", gsMesh.covariancesATexture);
257
- effect.setTexture("covariancesBTexture", gsMesh.covariancesBTexture);
258
- effect.setTexture("centersTexture", gsMesh.centersTexture);
259
- effect.setTexture("colorsTexture", gsMesh.colorsTexture);
260
- }
261
- // Clip plane
262
- bindClipPlane(effect, this, scene);
263
- }
264
- else if (scene.getEngine()._features.needToAlwaysBindUniformBuffers) {
265
- this._needToBindSceneUbo = true;
266
- }
267
- // Fog
268
- BindFogParameters(scene, mesh, effect);
269
- // Log. depth
270
- if (this.useLogarithmicDepth) {
271
- BindLogDepth(defines, effect, scene);
272
- }
273
- this._afterBind(mesh, this._activeEffect, subMesh);
274
- }
275
- /**
276
- * Clones the material.
277
- * @param name The cloned name.
278
- * @returns The cloned material.
279
- */
280
- clone(name) {
281
- return SerializationHelper.Clone(() => new GaussianSplattingMaterial(name, this.getScene()), this);
282
- }
283
- /**
284
- * Serializes the current material to its JSON representation.
285
- * @returns The JSON representation.
286
- */
287
- serialize() {
288
- const serializationObject = super.serialize();
289
- serializationObject.customType = "BABYLON.GaussianSplattingMaterial";
290
- return serializationObject;
291
- }
292
- /**
293
- * Gets the class name of the material
294
- * @returns "GaussianSplattingMaterial"
295
- */
296
- getClassName() {
297
- return "GaussianSplattingMaterial";
298
- }
299
- /**
300
- * Parse a JSON input to create back a Gaussian Splatting material.
301
- * @param source The JSON data to parse
302
- * @param scene The scene to create the parsed material in
303
- * @param rootUrl The root url of the assets the material depends upon
304
- * @returns the instantiated GaussianSplattingMaterial.
305
- */
306
- static Parse(source, scene, rootUrl) {
307
- return SerializationHelper.Parse(() => new GaussianSplattingMaterial(source.name, scene), source, scene, rootUrl);
308
- }
309
- }
310
- RegisterClass("BABYLON.GaussianSplattingMaterial", GaussianSplattingMaterial);
311
-
312
- /**
313
- * Class used to render a gaussian splatting mesh
314
- */
315
- class GaussianSplattingMesh extends Mesh {
316
- /**
317
- * Gets the covariancesA texture
318
- */
319
- get covariancesATexture() {
320
- return this._covariancesATexture;
321
- }
322
- /**
323
- * Gets the covariancesB texture
324
- */
325
- get covariancesBTexture() {
326
- return this._covariancesBTexture;
327
- }
328
- /**
329
- * Gets the centers texture
330
- */
331
- get centersTexture() {
332
- return this._centersTexture;
333
- }
334
- /**
335
- * Gets the colors texture
336
- */
337
- get colorsTexture() {
338
- return this._colorsTexture;
339
- }
340
- /**
341
- * Creates a new gaussian splatting mesh
342
- * @param name defines the name of the mesh
343
- * @param url defines the url to load from (optional)
344
- * @param scene defines the hosting scene (optional)
345
- * @param keepInRam keep datas in ram for editing purpose
346
- */
347
- constructor(name, url = null, scene = null, keepInRam = false) {
348
- super(name, scene);
349
- this._vertexCount = 0;
350
- this._worker = null;
351
- this._frameIdLastUpdate = -1;
352
- this._modelViewMatrix = Matrix.Identity();
353
- this._canPostToWorker = true;
354
- this._readyToDisplay = false;
355
- this._covariancesATexture = null;
356
- this._covariancesBTexture = null;
357
- this._centersTexture = null;
358
- this._colorsTexture = null;
359
- this._splatPositions = null;
360
- //@ts-expect-error
361
- this._covariancesA = null;
362
- //@ts-expect-error
363
- this._covariancesB = null;
364
- //@ts-expect-error
365
- this._colors = null;
366
- this._keepInRam = false;
367
- const vertexData = new VertexData();
368
- vertexData.positions = [-2, -2, 0, 2, -2, 0, 2, 2, 0, -2, 2, 0];
369
- vertexData.indices = [0, 1, 2, 0, 2, 3];
370
- vertexData.applyToMesh(this);
371
- this.subMeshes = [];
372
- new SubMesh(0, 0, 4, 0, 6, this);
373
- this.setEnabled(false);
374
- this._lastModelViewMatrix = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
375
- this._keepInRam = keepInRam;
376
- if (url) {
377
- this.loadFileAsync(url);
378
- }
379
- this.material = new GaussianSplattingMaterial(this.name + "_material", this._scene);
380
- }
381
- /**
382
- * Returns the class name
383
- * @returns "GaussianSplattingMesh"
384
- */
385
- getClassName() {
386
- return "GaussianSplattingMesh";
387
- }
388
- /**
389
- * Returns the total number of vertices (splats) within the mesh
390
- * @returns the total number of vertices
391
- */
392
- getTotalVertices() {
393
- return this._vertexCount;
394
- }
395
- /**
396
- * Is this node ready to be used/rendered
397
- * @param completeCheck defines if a complete check (including materials and lights) has to be done (false by default)
398
- * @returns true when ready
399
- */
400
- isReady(completeCheck = false) {
401
- if (!super.isReady(completeCheck, true)) {
402
- return false;
403
- }
404
- if (!this._readyToDisplay) {
405
- // mesh is ready when worker has done at least 1 sorting
406
- this._postToWorker();
407
- return false;
408
- }
409
- return true;
410
- }
411
- _postToWorker() {
412
- const frameId = this.getScene().getFrameId();
413
- if (frameId !== this._frameIdLastUpdate && this._worker && this._scene.activeCamera && this._canPostToWorker) {
414
- this.getWorldMatrix().multiplyToRef(this._scene.activeCamera.getViewMatrix(), this._modelViewMatrix);
415
- TmpVectors.Vector3[0].set(this._lastModelViewMatrix[8], this._lastModelViewMatrix[9], this._lastModelViewMatrix[10]);
416
- TmpVectors.Vector3[1].set(this._modelViewMatrix.m[8], this._modelViewMatrix.m[9], this._modelViewMatrix.m[10]);
417
- TmpVectors.Vector3[0].normalize();
418
- TmpVectors.Vector3[1].normalize();
419
- const dot = Vector3.Dot(TmpVectors.Vector3[0], TmpVectors.Vector3[1]);
420
- if (Math.abs(dot - 1) >= 0.01) {
421
- this._frameIdLastUpdate = frameId;
422
- this._canPostToWorker = false;
423
- this._lastModelViewMatrix = this._modelViewMatrix.m.slice(0);
424
- this._worker.postMessage({ view: this._modelViewMatrix.m, depthMix: this._depthMix, useRightHandedSystem: this._scene.useRightHandedSystem }, [
425
- this._depthMix.buffer,
426
- ]);
427
- }
428
- }
429
- }
430
- /**
431
- * 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
432
- * @param subMesh defines the subMesh to render
433
- * @param enableAlphaMode defines if alpha mode can be changed
434
- * @param effectiveMeshReplacement defines an optional mesh used to provide info for the rendering
435
- * @returns the current mesh
436
- */
437
- render(subMesh, enableAlphaMode, effectiveMeshReplacement) {
438
- this._postToWorker();
439
- return super.render(subMesh, enableAlphaMode, effectiveMeshReplacement);
440
- }
441
- /**
442
- * Code from https://github.com/dylanebert/gsplat.js/blob/main/src/loaders/PLYLoader.ts Under MIT license
443
- * Converts a .ply data array buffer to splat
444
- * if data array buffer is not ply, returns the original buffer
445
- * @param data the .ply data to load
446
- * @returns the loaded splat buffer
447
- * @deprecated Please use SceneLoader.ImportMeshAsync instead
448
- */
449
- static ConvertPLYToSplat(data) {
450
- const ubuf = new Uint8Array(data);
451
- const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));
452
- const headerEnd = "end_header\n";
453
- const headerEndIndex = header.indexOf(headerEnd);
454
- if (headerEndIndex < 0 || !header) {
455
- return data;
456
- }
457
- const vertexCount = parseInt(/element vertex (\d+)\n/.exec(header)[1]);
458
- let rowOffset = 0;
459
- const offsets = {
460
- double: 8,
461
- int: 4,
462
- uint: 4,
463
- float: 4,
464
- short: 2,
465
- ushort: 2,
466
- uchar: 1,
467
- };
468
- const properties = [];
469
- const filtered = header
470
- .slice(0, headerEndIndex)
471
- .split("\n")
472
- .filter((k) => k.startsWith("property "));
473
- for (const prop of filtered) {
474
- const [, type, name] = prop.split(" ");
475
- properties.push({ name, type, offset: rowOffset });
476
- if (offsets[type]) {
477
- rowOffset += offsets[type];
478
- }
479
- else {
480
- Logger.Error(`Unsupported property type: ${type}. Are you sure it's a valid Gaussian Splatting file?`);
481
- return new ArrayBuffer(0);
482
- }
483
- }
484
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
485
- const SH_C0 = 0.28209479177387814;
486
- const dataView = new DataView(data, headerEndIndex + headerEnd.length);
487
- const buffer = new ArrayBuffer(rowLength * vertexCount);
488
- const q = new Quaternion();
489
- for (let i = 0; i < vertexCount; i++) {
490
- const position = new Float32Array(buffer, i * rowLength, 3);
491
- const scale = new Float32Array(buffer, i * rowLength + 12, 3);
492
- const rgba = new Uint8ClampedArray(buffer, i * rowLength + 24, 4);
493
- const rot = new Uint8ClampedArray(buffer, i * rowLength + 28, 4);
494
- let r0 = 255;
495
- let r1 = 0;
496
- let r2 = 0;
497
- let r3 = 0;
498
- for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {
499
- const property = properties[propertyIndex];
500
- let value;
501
- switch (property.type) {
502
- case "float":
503
- value = dataView.getFloat32(property.offset + i * rowOffset, true);
504
- break;
505
- case "int":
506
- value = dataView.getInt32(property.offset + i * rowOffset, true);
507
- break;
508
- default:
509
- throw new Error(`Unsupported property type: ${property.type}`);
510
- }
511
- switch (property.name) {
512
- case "x":
513
- position[0] = value;
514
- break;
515
- case "y":
516
- position[1] = value;
517
- break;
518
- case "z":
519
- position[2] = value;
520
- break;
521
- case "scale_0":
522
- scale[0] = Math.exp(value);
523
- break;
524
- case "scale_1":
525
- scale[1] = Math.exp(value);
526
- break;
527
- case "scale_2":
528
- scale[2] = Math.exp(value);
529
- break;
530
- case "red":
531
- rgba[0] = value;
532
- break;
533
- case "green":
534
- rgba[1] = value;
535
- break;
536
- case "blue":
537
- rgba[2] = value;
538
- break;
539
- case "f_dc_0":
540
- rgba[0] = (0.5 + SH_C0 * value) * 255;
541
- break;
542
- case "f_dc_1":
543
- rgba[1] = (0.5 + SH_C0 * value) * 255;
544
- break;
545
- case "f_dc_2":
546
- rgba[2] = (0.5 + SH_C0 * value) * 255;
547
- break;
548
- case "f_dc_3":
549
- rgba[3] = (0.5 + SH_C0 * value) * 255;
550
- break;
551
- case "opacity":
552
- rgba[3] = (1 / (1 + Math.exp(-value))) * 255;
553
- break;
554
- case "rot_0":
555
- r0 = value;
556
- break;
557
- case "rot_1":
558
- r1 = value;
559
- break;
560
- case "rot_2":
561
- r2 = value;
562
- break;
563
- case "rot_3":
564
- r3 = value;
565
- break;
566
- }
567
- }
568
- q.set(r1, r2, r3, r0);
569
- q.normalize();
570
- rot[0] = q.w * 128 + 128;
571
- rot[1] = q.x * 128 + 128;
572
- rot[2] = q.y * 128 + 128;
573
- rot[3] = q.z * 128 + 128;
574
- }
575
- return buffer;
576
- }
577
- /**
578
- * Loads a .splat Gaussian Splatting array buffer asynchronously
579
- * @param data arraybuffer containing splat file
580
- * @returns a promise that resolves when the operation is complete
581
- */
582
- loadDataAsync(data) {
583
- return Promise.resolve(this._loadData(data));
584
- }
585
- /**
586
- * Loads a .splat Gaussian or .ply Splatting file asynchronously
587
- * @param url path to the splat file to load
588
- * @returns a promise that resolves when the operation is complete
589
- * @deprecated Please use SceneLoader.ImportMeshAsync instead
590
- */
591
- loadFileAsync(url) {
592
- return Tools.LoadFileAsync(url, true).then((data) => {
593
- this._loadData(GaussianSplattingMesh.ConvertPLYToSplat(data));
594
- });
595
- }
596
- /**
597
- * Releases resources associated with this mesh.
598
- * @param doNotRecurse Set to true to not recurse into each children (recurse into each children by default)
599
- */
600
- dispose(doNotRecurse) {
601
- this._covariancesATexture?.dispose();
602
- this._covariancesBTexture?.dispose();
603
- this._centersTexture?.dispose();
604
- this._colorsTexture?.dispose();
605
- this._covariancesATexture = null;
606
- this._covariancesBTexture = null;
607
- this._centersTexture = null;
608
- this._colorsTexture = null;
609
- this._worker?.terminate();
610
- this._worker = null;
611
- super.dispose(doNotRecurse, true);
612
- }
613
- _copyTextures(source) {
614
- this._covariancesATexture = source.covariancesATexture?.clone();
615
- this._covariancesBTexture = source.covariancesBTexture?.clone();
616
- this._centersTexture = source.centersTexture?.clone();
617
- this._colorsTexture = source.colorsTexture?.clone();
618
- }
619
- /**
620
- * Returns a new Mesh object generated from the current mesh properties.
621
- * @param name is a string, the name given to the new mesh
622
- * @returns a new Gaussian Splatting Mesh
623
- */
624
- clone(name = "") {
625
- const newGS = new GaussianSplattingMesh(name, undefined, this.getScene());
626
- newGS._copySource(this);
627
- newGS.makeGeometryUnique();
628
- newGS._vertexCount = this._vertexCount;
629
- newGS._copyTextures(this);
630
- newGS._modelViewMatrix = Matrix.Identity();
631
- newGS._splatPositions = this._splatPositions;
632
- newGS._readyToDisplay = false;
633
- newGS._instanciateWorker();
634
- const binfo = this.getBoundingInfo();
635
- newGS.getBoundingInfo().reConstruct(binfo.minimum, binfo.maximum, this.getWorldMatrix());
636
- newGS.forcedInstanceCount = newGS._vertexCount;
637
- newGS.setEnabled(true);
638
- return newGS;
639
- }
640
- _loadData(data) {
641
- if (!data.byteLength) {
642
- return;
643
- }
644
- this._readyToDisplay = false;
645
- // Parse the data
646
- const uBuffer = new Uint8Array(data);
647
- const fBuffer = new Float32Array(uBuffer.buffer);
648
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
649
- const vertexCount = uBuffer.length / rowLength;
650
- this._vertexCount = vertexCount;
651
- const textureSize = this._getTextureSize(vertexCount);
652
- const textureLength = textureSize.x * textureSize.y;
653
- this._splatPositions = new Float32Array(3 * textureLength);
654
- const covA = new Float32Array(3 * textureLength);
655
- const covB = new Float32Array(3 * textureLength);
656
- const matrixRotation = TmpVectors.Matrix[0];
657
- const matrixScale = TmpVectors.Matrix[1];
658
- const quaternion = TmpVectors.Quaternion[0];
659
- const minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
660
- const maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
661
- for (let i = 0; i < vertexCount; i++) {
662
- const x = fBuffer[8 * i + 0];
663
- const y = -fBuffer[8 * i + 1];
664
- const z = fBuffer[8 * i + 2];
665
- this._splatPositions[3 * i + 0] = x;
666
- this._splatPositions[3 * i + 1] = y;
667
- this._splatPositions[3 * i + 2] = z;
668
- minimum.minimizeInPlaceFromFloats(x, y, z);
669
- maximum.maximizeInPlaceFromFloats(x, y, z);
670
- quaternion.set((uBuffer[32 * i + 28 + 1] - 128) / 128, (uBuffer[32 * i + 28 + 2] - 128) / 128, (uBuffer[32 * i + 28 + 3] - 128) / 128, -(uBuffer[32 * i + 28 + 0] - 128) / 128);
671
- quaternion.toRotationMatrix(matrixRotation);
672
- Matrix.ScalingToRef(fBuffer[8 * i + 3 + 0] * 2, fBuffer[8 * i + 3 + 1] * 2, fBuffer[8 * i + 3 + 2] * 2, matrixScale);
673
- const M = matrixRotation.multiplyToRef(matrixScale, TmpVectors.Matrix[0]).m;
674
- covA[i * 3 + 0] = M[0] * M[0] + M[1] * M[1] + M[2] * M[2];
675
- covA[i * 3 + 1] = M[0] * M[4] + M[1] * M[5] + M[2] * M[6];
676
- covA[i * 3 + 2] = M[0] * M[8] + M[1] * M[9] + M[2] * M[10];
677
- covB[i * 3 + 0] = M[4] * M[4] + M[5] * M[5] + M[6] * M[6];
678
- covB[i * 3 + 1] = M[4] * M[8] + M[5] * M[9] + M[6] * M[10];
679
- covB[i * 3 + 2] = M[8] * M[8] + M[9] * M[9] + M[10] * M[10];
680
- }
681
- // Update the mesh
682
- const binfo = this.getBoundingInfo();
683
- binfo.reConstruct(minimum, maximum, this.getWorldMatrix());
684
- this.forcedInstanceCount = this._vertexCount;
685
- this.setEnabled(true);
686
- // Update the material
687
- const createTextureFromData = (data, width, height, format) => {
688
- return new RawTexture(data, width, height, format, this._scene, false, false, Constants.TEXTURE_BILINEAR_SAMPLINGMODE, Constants.TEXTURETYPE_FLOAT);
689
- };
690
- const convertRgbToRgba = (rgb) => {
691
- const count = rgb.length / 3;
692
- const rgba = new Float32Array(count * 4);
693
- for (let i = 0; i < count; ++i) {
694
- rgba[i * 4 + 0] = rgb[i * 3 + 0];
695
- rgba[i * 4 + 1] = rgb[i * 3 + 1];
696
- rgba[i * 4 + 2] = rgb[i * 3 + 2];
697
- rgba[i * 4 + 3] = 1.0;
698
- }
699
- return rgba;
700
- };
701
- const colorArray = new Float32Array(textureSize.x * textureSize.y * 4);
702
- for (let i = 0; i < this._vertexCount; ++i) {
703
- colorArray[i * 4 + 0] = uBuffer[32 * i + 24 + 0] / 255;
704
- colorArray[i * 4 + 1] = uBuffer[32 * i + 24 + 1] / 255;
705
- colorArray[i * 4 + 2] = uBuffer[32 * i + 24 + 2] / 255;
706
- colorArray[i * 4 + 3] = uBuffer[32 * i + 24 + 3] / 255;
707
- }
708
- if (this._keepInRam) {
709
- this._covariancesA = covA;
710
- this._covariancesB = covB;
711
- this._colors = colorArray;
712
- }
713
- this._covariancesATexture = createTextureFromData(convertRgbToRgba(covA), textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
714
- this._covariancesBTexture = createTextureFromData(convertRgbToRgba(covB), textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
715
- this._centersTexture = createTextureFromData(convertRgbToRgba(this._splatPositions), textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
716
- this._colorsTexture = createTextureFromData(colorArray, textureSize.x, textureSize.y, Constants.TEXTUREFORMAT_RGBA);
717
- this._instanciateWorker();
718
- }
719
- _instanciateWorker() {
720
- if (!this._vertexCount) {
721
- return;
722
- }
723
- const splatIndex = new Float32Array(this._vertexCount);
724
- this.thinInstanceSetBuffer("splatIndex", splatIndex, 1, false);
725
- // Start the worker thread
726
- this._worker?.terminate();
727
- this._worker = new Worker(URL.createObjectURL(new Blob(["(", GaussianSplattingMesh._CreateWorker.toString(), ")(self)"], {
728
- type: "application/javascript",
729
- })));
730
- this._depthMix = new BigInt64Array(this._vertexCount);
731
- const positions = Float32Array.from(this._splatPositions);
732
- const vertexCount = this._vertexCount;
733
- this._worker.postMessage({ positions, vertexCount }, [positions.buffer]);
734
- this._worker.onmessage = (e) => {
735
- this._depthMix = e.data.depthMix;
736
- const indexMix = new Uint32Array(e.data.depthMix.buffer);
737
- for (let j = 0; j < this._vertexCount; j++) {
738
- splatIndex[j] = indexMix[2 * j];
739
- }
740
- this.thinInstanceBufferUpdated("splatIndex");
741
- this._canPostToWorker = true;
742
- this._readyToDisplay = true;
743
- };
744
- }
745
- _getTextureSize(length) {
746
- const engine = this._scene.getEngine();
747
- const width = engine.getCaps().maxTextureSize;
748
- let height = 1;
749
- if (engine.version === 1 && !engine.isWebGPU) {
750
- while (width * height < length) {
751
- height *= 2;
752
- }
753
- }
754
- else {
755
- height = Math.ceil(length / width);
756
- }
757
- if (height > width) {
758
- Logger.Error("GaussianSplatting texture size: (" + width + ", " + height + "), maxTextureSize: " + width);
759
- height = width;
760
- }
761
- return new Vector2(width, height);
762
- }
763
- }
764
- GaussianSplattingMesh._CreateWorker = function (self) {
765
- let vertexCount = 0;
766
- let positions;
767
- let depthMix;
768
- let indices;
769
- let floatMix;
770
- self.onmessage = (e) => {
771
- // updated on init
772
- if (e.data.positions) {
773
- positions = e.data.positions;
774
- vertexCount = e.data.vertexCount;
775
- }
776
- // udpate on view changed
777
- else {
778
- const viewProj = e.data.view;
779
- if (!positions || !viewProj) {
780
- // Sanity check, it shouldn't happen!
781
- throw new Error("positions or view is not defined!");
782
- }
783
- depthMix = e.data.depthMix;
784
- indices = new Uint32Array(depthMix.buffer);
785
- floatMix = new Float32Array(depthMix.buffer);
786
- // Sort
787
- for (let j = 0; j < vertexCount; j++) {
788
- indices[2 * j] = j;
789
- }
790
- let depthFactor = -1;
791
- if (e.data.useRightHandedSystem) {
792
- depthFactor = 1;
793
- }
794
- for (let j = 0; j < vertexCount; j++) {
795
- floatMix[2 * j + 1] = 10000 + (viewProj[2] * positions[3 * j + 0] + viewProj[6] * positions[3 * j + 1] + viewProj[10] * positions[3 * j + 2]) * depthFactor;
796
- }
797
- depthMix.sort();
798
- self.postMessage({ depthMix }, [depthMix.buffer]);
799
- }
800
- };
801
- };
802
-
803
- /**
804
- * Represents one particle of a points cloud system.
805
- */
806
- class CloudPoint {
807
- /**
808
- * Creates a Point Cloud object.
809
- * Don't create particles manually, use instead the PCS internal tools like _addParticle()
810
- * @param particleIndex (integer) is the particle index in the PCS pool. It's also the particle identifier.
811
- * @param group (PointsGroup) is the group the particle belongs to
812
- * @param groupId (integer) is the group identifier in the PCS.
813
- * @param idxInGroup (integer) is the index of the particle in the current point group (ex: the 10th point of addPoints(30))
814
- * @param pcs defines the PCS it is associated to
815
- */
816
- constructor(particleIndex, group, groupId, idxInGroup, pcs) {
817
- /**
818
- * particle global index
819
- */
820
- this.idx = 0;
821
- /**
822
- * The color of the particle
823
- */
824
- this.color = new Color4(1.0, 1.0, 1.0, 1.0);
825
- /**
826
- * The world space position of the particle.
827
- */
828
- this.position = Vector3.Zero();
829
- /**
830
- * The world space rotation of the particle. (Not use if rotationQuaternion is set)
831
- */
832
- this.rotation = Vector3.Zero();
833
- /**
834
- * The uv of the particle.
835
- */
836
- this.uv = new Vector2(0.0, 0.0);
837
- /**
838
- * The current speed of the particle.
839
- */
840
- this.velocity = Vector3.Zero();
841
- /**
842
- * The pivot point in the particle local space.
843
- */
844
- this.pivot = Vector3.Zero();
845
- /**
846
- * Must the particle be translated from its pivot point in its local space ?
847
- * In this case, the pivot point is set at the origin of the particle local space and the particle is translated.
848
- * Default : false
849
- */
850
- this.translateFromPivot = false;
851
- /**
852
- * Index of this particle in the global "positions" array (Internal use)
853
- * @internal
854
- */
855
- this._pos = 0;
856
- /**
857
- * @internal Index of this particle in the global "indices" array (Internal use)
858
- */
859
- this._ind = 0;
860
- /**
861
- * Group id of this particle
862
- */
863
- this.groupId = 0;
864
- /**
865
- * Index of the particle in its group id (Internal use)
866
- */
867
- this.idxInGroup = 0;
868
- /**
869
- * @internal Still set as invisible in order to skip useless computations (Internal use)
870
- */
871
- this._stillInvisible = false;
872
- /**
873
- * @internal Last computed particle rotation matrix
874
- */
875
- this._rotationMatrix = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0];
876
- /**
877
- * Parent particle Id, if any.
878
- * Default null.
879
- */
880
- this.parentId = null;
881
- /**
882
- * @internal Internal global position in the PCS.
883
- */
884
- this._globalPosition = Vector3.Zero();
885
- this.idx = particleIndex;
886
- this._group = group;
887
- this.groupId = groupId;
888
- this.idxInGroup = idxInGroup;
889
- this._pcs = pcs;
890
- }
891
- /**
892
- * get point size
893
- */
894
- get size() {
895
- return this.size;
896
- }
897
- /**
898
- * Set point size
899
- */
900
- set size(scale) {
901
- this.size = scale;
902
- }
903
- /**
904
- * Legacy support, changed quaternion to rotationQuaternion
905
- */
906
- get quaternion() {
907
- return this.rotationQuaternion;
908
- }
909
- /**
910
- * Legacy support, changed quaternion to rotationQuaternion
911
- */
912
- set quaternion(q) {
913
- this.rotationQuaternion = q;
914
- }
915
- /**
916
- * Returns a boolean. True if the particle intersects a mesh, else false
917
- * The intersection is computed on the particle position and Axis Aligned Bounding Box (AABB) or Sphere
918
- * @param target is the object (point or mesh) what the intersection is computed against
919
- * @param isSphere is boolean flag when false (default) bounding box of mesh is used, when true the bounding sphere is used
920
- * @returns true if it intersects
921
- */
922
- intersectsMesh(target, isSphere) {
923
- if (!target.hasBoundingInfo) {
924
- return false;
925
- }
926
- if (!this._pcs.mesh) {
927
- throw new Error("Point Cloud System doesnt contain the Mesh");
928
- }
929
- if (isSphere) {
930
- return target.getBoundingInfo().boundingSphere.intersectsPoint(this.position.add(this._pcs.mesh.position));
931
- }
932
- const bbox = target.getBoundingInfo().boundingBox;
933
- const maxX = bbox.maximumWorld.x;
934
- const minX = bbox.minimumWorld.x;
935
- const maxY = bbox.maximumWorld.y;
936
- const minY = bbox.minimumWorld.y;
937
- const maxZ = bbox.maximumWorld.z;
938
- const minZ = bbox.minimumWorld.z;
939
- const x = this.position.x + this._pcs.mesh.position.x;
940
- const y = this.position.y + this._pcs.mesh.position.y;
941
- const z = this.position.z + this._pcs.mesh.position.z;
942
- return minX <= x && x <= maxX && minY <= y && y <= maxY && minZ <= z && z <= maxZ;
943
- }
944
- /**
945
- * get the rotation matrix of the particle
946
- * @internal
947
- */
948
- getRotationMatrix(m) {
949
- let quaternion;
950
- if (this.rotationQuaternion) {
951
- quaternion = this.rotationQuaternion;
952
- }
953
- else {
954
- quaternion = TmpVectors.Quaternion[0];
955
- const rotation = this.rotation;
956
- Quaternion.RotationYawPitchRollToRef(rotation.y, rotation.x, rotation.z, quaternion);
957
- }
958
- quaternion.toRotationMatrix(m);
959
- }
960
- }
961
- /**
962
- * Represents a group of points in a points cloud system
963
- * * PCS internal tool, don't use it manually.
964
- */
965
- class PointsGroup {
966
- /**
967
- * Get or set the groupId
968
- * @deprecated Please use groupId instead
969
- */
970
- get groupID() {
971
- return this.groupId;
972
- }
973
- set groupID(groupID) {
974
- this.groupId = groupID;
975
- }
976
- /**
977
- * Creates a points group object. This is an internal reference to produce particles for the PCS.
978
- * PCS internal tool, don't use it manually.
979
- * @internal
980
- */
981
- constructor(id, posFunction) {
982
- this.groupId = id;
983
- this._positionFunction = posFunction;
984
- }
985
- }
986
-
987
- /**
988
- * Class representing a ray with position and direction
989
- */
990
- class Ray {
991
- /**
992
- * Creates a new ray
993
- * @param origin origin point
994
- * @param direction direction
995
- * @param length length of the ray
996
- * @param epsilon The epsilon value to use when calculating the ray/triangle intersection (default: 0)
997
- */
998
- constructor(
999
- /** origin point */
1000
- origin,
1001
- /** direction */
1002
- direction,
1003
- /** [Number.MAX_VALUE] length of the ray */
1004
- length = Number.MAX_VALUE,
1005
- /** [Epsilon] The epsilon value to use when calculating the ray/triangle intersection (default: Epsilon from math constants) */
1006
- epsilon = Epsilon) {
1007
- this.origin = origin;
1008
- this.direction = direction;
1009
- this.length = length;
1010
- this.epsilon = epsilon;
1011
- }
1012
- // Methods
1013
- /**
1014
- * Clone the current ray
1015
- * @returns a new ray
1016
- */
1017
- clone() {
1018
- return new Ray(this.origin.clone(), this.direction.clone(), this.length);
1019
- }
1020
- /**
1021
- * Checks if the ray intersects a box
1022
- * This does not account for the ray length by design to improve perfs.
1023
- * @param minimum bound of the box
1024
- * @param maximum bound of the box
1025
- * @param intersectionTreshold extra extend to be added to the box in all direction
1026
- * @returns if the box was hit
1027
- */
1028
- intersectsBoxMinMax(minimum, maximum, intersectionTreshold = 0) {
1029
- const newMinimum = Ray._TmpVector3[0].copyFromFloats(minimum.x - intersectionTreshold, minimum.y - intersectionTreshold, minimum.z - intersectionTreshold);
1030
- const newMaximum = Ray._TmpVector3[1].copyFromFloats(maximum.x + intersectionTreshold, maximum.y + intersectionTreshold, maximum.z + intersectionTreshold);
1031
- let d = 0.0;
1032
- let maxValue = Number.MAX_VALUE;
1033
- let inv;
1034
- let min;
1035
- let max;
1036
- let temp;
1037
- if (Math.abs(this.direction.x) < 0.0000001) {
1038
- if (this.origin.x < newMinimum.x || this.origin.x > newMaximum.x) {
1039
- return false;
1040
- }
1041
- }
1042
- else {
1043
- inv = 1.0 / this.direction.x;
1044
- min = (newMinimum.x - this.origin.x) * inv;
1045
- max = (newMaximum.x - this.origin.x) * inv;
1046
- if (max === -Infinity) {
1047
- max = Infinity;
1048
- }
1049
- if (min > max) {
1050
- temp = min;
1051
- min = max;
1052
- max = temp;
1053
- }
1054
- d = Math.max(min, d);
1055
- maxValue = Math.min(max, maxValue);
1056
- if (d > maxValue) {
1057
- return false;
1058
- }
1059
- }
1060
- if (Math.abs(this.direction.y) < 0.0000001) {
1061
- if (this.origin.y < newMinimum.y || this.origin.y > newMaximum.y) {
1062
- return false;
1063
- }
1064
- }
1065
- else {
1066
- inv = 1.0 / this.direction.y;
1067
- min = (newMinimum.y - this.origin.y) * inv;
1068
- max = (newMaximum.y - this.origin.y) * inv;
1069
- if (max === -Infinity) {
1070
- max = Infinity;
1071
- }
1072
- if (min > max) {
1073
- temp = min;
1074
- min = max;
1075
- max = temp;
1076
- }
1077
- d = Math.max(min, d);
1078
- maxValue = Math.min(max, maxValue);
1079
- if (d > maxValue) {
1080
- return false;
1081
- }
1082
- }
1083
- if (Math.abs(this.direction.z) < 0.0000001) {
1084
- if (this.origin.z < newMinimum.z || this.origin.z > newMaximum.z) {
1085
- return false;
1086
- }
1087
- }
1088
- else {
1089
- inv = 1.0 / this.direction.z;
1090
- min = (newMinimum.z - this.origin.z) * inv;
1091
- max = (newMaximum.z - this.origin.z) * inv;
1092
- if (max === -Infinity) {
1093
- max = Infinity;
1094
- }
1095
- if (min > max) {
1096
- temp = min;
1097
- min = max;
1098
- max = temp;
1099
- }
1100
- d = Math.max(min, d);
1101
- maxValue = Math.min(max, maxValue);
1102
- if (d > maxValue) {
1103
- return false;
1104
- }
1105
- }
1106
- return true;
1107
- }
1108
- /**
1109
- * Checks if the ray intersects a box
1110
- * This does not account for the ray lenght by design to improve perfs.
1111
- * @param box the bounding box to check
1112
- * @param intersectionTreshold extra extend to be added to the BoundingBox in all direction
1113
- * @returns if the box was hit
1114
- */
1115
- intersectsBox(box, intersectionTreshold = 0) {
1116
- return this.intersectsBoxMinMax(box.minimum, box.maximum, intersectionTreshold);
1117
- }
1118
- /**
1119
- * If the ray hits a sphere
1120
- * @param sphere the bounding sphere to check
1121
- * @param intersectionTreshold extra extend to be added to the BoundingSphere in all direction
1122
- * @returns true if it hits the sphere
1123
- */
1124
- intersectsSphere(sphere, intersectionTreshold = 0) {
1125
- const x = sphere.center.x - this.origin.x;
1126
- const y = sphere.center.y - this.origin.y;
1127
- const z = sphere.center.z - this.origin.z;
1128
- const pyth = x * x + y * y + z * z;
1129
- const radius = sphere.radius + intersectionTreshold;
1130
- const rr = radius * radius;
1131
- if (pyth <= rr) {
1132
- return true;
1133
- }
1134
- const dot = x * this.direction.x + y * this.direction.y + z * this.direction.z;
1135
- if (dot < 0.0) {
1136
- return false;
1137
- }
1138
- const temp = pyth - dot * dot;
1139
- return temp <= rr;
1140
- }
1141
- /**
1142
- * If the ray hits a triange
1143
- * @param vertex0 triangle vertex
1144
- * @param vertex1 triangle vertex
1145
- * @param vertex2 triangle vertex
1146
- * @returns intersection information if hit
1147
- */
1148
- intersectsTriangle(vertex0, vertex1, vertex2) {
1149
- const edge1 = Ray._TmpVector3[0];
1150
- const edge2 = Ray._TmpVector3[1];
1151
- const pvec = Ray._TmpVector3[2];
1152
- const tvec = Ray._TmpVector3[3];
1153
- const qvec = Ray._TmpVector3[4];
1154
- vertex1.subtractToRef(vertex0, edge1);
1155
- vertex2.subtractToRef(vertex0, edge2);
1156
- Vector3.CrossToRef(this.direction, edge2, pvec);
1157
- const det = Vector3.Dot(edge1, pvec);
1158
- if (det === 0) {
1159
- return null;
1160
- }
1161
- const invdet = 1 / det;
1162
- this.origin.subtractToRef(vertex0, tvec);
1163
- const bv = Vector3.Dot(tvec, pvec) * invdet;
1164
- if (bv < -this.epsilon || bv > 1.0 + this.epsilon) {
1165
- return null;
1166
- }
1167
- Vector3.CrossToRef(tvec, edge1, qvec);
1168
- const bw = Vector3.Dot(this.direction, qvec) * invdet;
1169
- if (bw < -this.epsilon || bv + bw > 1.0 + this.epsilon) {
1170
- return null;
1171
- }
1172
- //check if the distance is longer than the predefined length.
1173
- const distance = Vector3.Dot(edge2, qvec) * invdet;
1174
- if (distance > this.length) {
1175
- return null;
1176
- }
1177
- return new IntersectionInfo(1 - bv - bw, bv, distance);
1178
- }
1179
- /**
1180
- * Checks if ray intersects a plane
1181
- * @param plane the plane to check
1182
- * @returns the distance away it was hit
1183
- */
1184
- intersectsPlane(plane) {
1185
- let distance;
1186
- const result1 = Vector3.Dot(plane.normal, this.direction);
1187
- if (Math.abs(result1) < 9.99999997475243e-7) {
1188
- return null;
1189
- }
1190
- else {
1191
- const result2 = Vector3.Dot(plane.normal, this.origin);
1192
- distance = (-plane.d - result2) / result1;
1193
- if (distance < 0.0) {
1194
- if (distance < -9.99999997475243e-7) {
1195
- return null;
1196
- }
1197
- else {
1198
- return 0;
1199
- }
1200
- }
1201
- return distance;
1202
- }
1203
- }
1204
- /**
1205
- * Calculate the intercept of a ray on a given axis
1206
- * @param axis to check 'x' | 'y' | 'z'
1207
- * @param offset from axis interception (i.e. an offset of 1y is intercepted above ground)
1208
- * @returns a vector containing the coordinates where 'axis' is equal to zero (else offset), or null if there is no intercept.
1209
- */
1210
- intersectsAxis(axis, offset = 0) {
1211
- switch (axis) {
1212
- case "y": {
1213
- const t = (this.origin.y - offset) / this.direction.y;
1214
- if (t > 0) {
1215
- return null;
1216
- }
1217
- return new Vector3(this.origin.x + this.direction.x * -t, offset, this.origin.z + this.direction.z * -t);
1218
- }
1219
- case "x": {
1220
- const t = (this.origin.x - offset) / this.direction.x;
1221
- if (t > 0) {
1222
- return null;
1223
- }
1224
- return new Vector3(offset, this.origin.y + this.direction.y * -t, this.origin.z + this.direction.z * -t);
1225
- }
1226
- case "z": {
1227
- const t = (this.origin.z - offset) / this.direction.z;
1228
- if (t > 0) {
1229
- return null;
1230
- }
1231
- return new Vector3(this.origin.x + this.direction.x * -t, this.origin.y + this.direction.y * -t, offset);
1232
- }
1233
- default:
1234
- return null;
1235
- }
1236
- }
1237
- /**
1238
- * Checks if ray intersects a mesh. The ray is defined in WORLD space. A mesh triangle can be picked both from its front and back sides,
1239
- * irrespective of orientation.
1240
- * @param mesh the mesh to check
1241
- * @param fastCheck defines if the first intersection will be used (and not the closest)
1242
- * @param trianglePredicate defines an optional predicate used to select faces when a mesh intersection is detected
1243
- * @param onlyBoundingInfo defines a boolean indicating if picking should only happen using bounding info (false by default)
1244
- * @param worldToUse defines the world matrix to use to get the world coordinate of the intersection point
1245
- * @param skipBoundingInfo a boolean indicating if we should skip the bounding info check
1246
- * @returns picking info of the intersection
1247
- */
1248
- intersectsMesh(mesh, fastCheck, trianglePredicate, onlyBoundingInfo = false, worldToUse, skipBoundingInfo = false) {
1249
- const tm = TmpVectors.Matrix[0];
1250
- mesh.getWorldMatrix().invertToRef(tm);
1251
- if (this._tmpRay) {
1252
- Ray.TransformToRef(this, tm, this._tmpRay);
1253
- }
1254
- else {
1255
- this._tmpRay = Ray.Transform(this, tm);
1256
- }
1257
- return mesh.intersects(this._tmpRay, fastCheck, trianglePredicate, onlyBoundingInfo, worldToUse, skipBoundingInfo);
1258
- }
1259
- /**
1260
- * Checks if ray intersects a mesh
1261
- * @param meshes the meshes to check
1262
- * @param fastCheck defines if the first intersection will be used (and not the closest)
1263
- * @param results array to store result in
1264
- * @returns Array of picking infos
1265
- */
1266
- intersectsMeshes(meshes, fastCheck, results) {
1267
- if (results) {
1268
- results.length = 0;
1269
- }
1270
- else {
1271
- results = [];
1272
- }
1273
- for (let i = 0; i < meshes.length; i++) {
1274
- const pickInfo = this.intersectsMesh(meshes[i], fastCheck);
1275
- if (pickInfo.hit) {
1276
- results.push(pickInfo);
1277
- }
1278
- }
1279
- results.sort(this._comparePickingInfo);
1280
- return results;
1281
- }
1282
- _comparePickingInfo(pickingInfoA, pickingInfoB) {
1283
- if (pickingInfoA.distance < pickingInfoB.distance) {
1284
- return -1;
1285
- }
1286
- else if (pickingInfoA.distance > pickingInfoB.distance) {
1287
- return 1;
1288
- }
1289
- else {
1290
- return 0;
1291
- }
1292
- }
1293
- /**
1294
- * Intersection test between the ray and a given segment within a given tolerance (threshold)
1295
- * @param sega the first point of the segment to test the intersection against
1296
- * @param segb the second point of the segment to test the intersection against
1297
- * @param threshold the tolerance margin, if the ray doesn't intersect the segment but is close to the given threshold, the intersection is successful
1298
- * @returns the distance from the ray origin to the intersection point if there's intersection, or -1 if there's no intersection
1299
- */
1300
- intersectionSegment(sega, segb, threshold) {
1301
- const o = this.origin;
1302
- const u = TmpVectors.Vector3[0];
1303
- const rsegb = TmpVectors.Vector3[1];
1304
- const v = TmpVectors.Vector3[2];
1305
- const w = TmpVectors.Vector3[3];
1306
- segb.subtractToRef(sega, u);
1307
- this.direction.scaleToRef(Ray._Rayl, v);
1308
- o.addToRef(v, rsegb);
1309
- sega.subtractToRef(o, w);
1310
- const a = Vector3.Dot(u, u); // always >= 0
1311
- const b = Vector3.Dot(u, v);
1312
- const c = Vector3.Dot(v, v); // always >= 0
1313
- const d = Vector3.Dot(u, w);
1314
- const e = Vector3.Dot(v, w);
1315
- const D = a * c - b * b; // always >= 0
1316
- let sN, sD = D; // sc = sN / sD, default sD = D >= 0
1317
- let tN, tD = D; // tc = tN / tD, default tD = D >= 0
1318
- // compute the line parameters of the two closest points
1319
- if (D < Ray._Smallnum) {
1320
- // the lines are almost parallel
1321
- sN = 0.0; // force using point P0 on segment S1
1322
- sD = 1.0; // to prevent possible division by 0.0 later
1323
- tN = e;
1324
- tD = c;
1325
- }
1326
- else {
1327
- // get the closest points on the infinite lines
1328
- sN = b * e - c * d;
1329
- tN = a * e - b * d;
1330
- if (sN < 0.0) {
1331
- // sc < 0 => the s=0 edge is visible
1332
- sN = 0.0;
1333
- tN = e;
1334
- tD = c;
1335
- }
1336
- else if (sN > sD) {
1337
- // sc > 1 => the s=1 edge is visible
1338
- sN = sD;
1339
- tN = e + b;
1340
- tD = c;
1341
- }
1342
- }
1343
- if (tN < 0.0) {
1344
- // tc < 0 => the t=0 edge is visible
1345
- tN = 0.0;
1346
- // recompute sc for this edge
1347
- if (-d < 0.0) {
1348
- sN = 0.0;
1349
- }
1350
- else if (-d > a) {
1351
- sN = sD;
1352
- }
1353
- else {
1354
- sN = -d;
1355
- sD = a;
1356
- }
1357
- }
1358
- else if (tN > tD) {
1359
- // tc > 1 => the t=1 edge is visible
1360
- tN = tD;
1361
- // recompute sc for this edge
1362
- if (-d + b < 0.0) {
1363
- sN = 0;
1364
- }
1365
- else if (-d + b > a) {
1366
- sN = sD;
1367
- }
1368
- else {
1369
- sN = -d + b;
1370
- sD = a;
1371
- }
1372
- }
1373
- // finally do the division to get sc and tc
1374
- const sc = Math.abs(sN) < Ray._Smallnum ? 0.0 : sN / sD;
1375
- const tc = Math.abs(tN) < Ray._Smallnum ? 0.0 : tN / tD;
1376
- // get the difference of the two closest points
1377
- const qtc = TmpVectors.Vector3[4];
1378
- v.scaleToRef(tc, qtc);
1379
- const qsc = TmpVectors.Vector3[5];
1380
- u.scaleToRef(sc, qsc);
1381
- qsc.addInPlace(w);
1382
- const dP = TmpVectors.Vector3[6];
1383
- qsc.subtractToRef(qtc, dP); // = S1(sc) - S2(tc)
1384
- const isIntersected = tc > 0 && tc <= this.length && dP.lengthSquared() < threshold * threshold; // return intersection result
1385
- if (isIntersected) {
1386
- return qsc.length();
1387
- }
1388
- return -1;
1389
- }
1390
- /**
1391
- * Update the ray from viewport position
1392
- * @param x position
1393
- * @param y y position
1394
- * @param viewportWidth viewport width
1395
- * @param viewportHeight viewport height
1396
- * @param world world matrix
1397
- * @param view view matrix
1398
- * @param projection projection matrix
1399
- * @param enableDistantPicking defines if picking should handle large values for mesh position/scaling (false by default)
1400
- * @returns this ray updated
1401
- */
1402
- update(x, y, viewportWidth, viewportHeight, world, view, projection, enableDistantPicking = false) {
1403
- if (enableDistantPicking) {
1404
- // With world matrices having great values (like 8000000000 on 1 or more scaling or position axis),
1405
- // multiplying view/projection/world and doing invert will result in loss of float precision in the matrix.
1406
- // One way to fix it is to compute the ray with world at identity then transform the ray in object space.
1407
- // This is slower (2 matrix inverts instead of 1) but precision is preserved.
1408
- // This is hidden behind `EnableDistantPicking` flag (default is false)
1409
- if (!Ray._RayDistant) {
1410
- Ray._RayDistant = Ray.Zero();
1411
- }
1412
- Ray._RayDistant.unprojectRayToRef(x, y, viewportWidth, viewportHeight, Matrix.IdentityReadOnly, view, projection);
1413
- const tm = TmpVectors.Matrix[0];
1414
- world.invertToRef(tm);
1415
- Ray.TransformToRef(Ray._RayDistant, tm, this);
1416
- }
1417
- else {
1418
- this.unprojectRayToRef(x, y, viewportWidth, viewportHeight, world, view, projection);
1419
- }
1420
- return this;
1421
- }
1422
- // Statics
1423
- /**
1424
- * Creates a ray with origin and direction of 0,0,0
1425
- * @returns the new ray
1426
- */
1427
- static Zero() {
1428
- return new Ray(Vector3.Zero(), Vector3.Zero());
1429
- }
1430
- /**
1431
- * Creates a new ray from screen space and viewport
1432
- * @param x position
1433
- * @param y y position
1434
- * @param viewportWidth viewport width
1435
- * @param viewportHeight viewport height
1436
- * @param world world matrix
1437
- * @param view view matrix
1438
- * @param projection projection matrix
1439
- * @returns new ray
1440
- */
1441
- static CreateNew(x, y, viewportWidth, viewportHeight, world, view, projection) {
1442
- const result = Ray.Zero();
1443
- return result.update(x, y, viewportWidth, viewportHeight, world, view, projection);
1444
- }
1445
- /**
1446
- * Function will create a new transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
1447
- * transformed to the given world matrix.
1448
- * @param origin The origin point
1449
- * @param end The end point
1450
- * @param world a matrix to transform the ray to. Default is the identity matrix.
1451
- * @returns the new ray
1452
- */
1453
- static CreateNewFromTo(origin, end, world = Matrix.IdentityReadOnly) {
1454
- const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
1455
- return Ray.CreateFromToToRef(origin, end, result, world);
1456
- }
1457
- /**
1458
- * Function will update a transformed ray starting from origin and ending at the end point. Ray's length will be set, and ray will be
1459
- * transformed to the given world matrix.
1460
- * @param origin The origin point
1461
- * @param end The end point
1462
- * @param result the object to store the result
1463
- * @param world a matrix to transform the ray to. Default is the identity matrix.
1464
- * @returns the ref ray
1465
- */
1466
- static CreateFromToToRef(origin, end, result, world = Matrix.IdentityReadOnly) {
1467
- result.origin.copyFrom(origin);
1468
- const direction = end.subtractToRef(origin, result.direction);
1469
- const length = Math.sqrt(direction.x * direction.x + direction.y * direction.y + direction.z * direction.z);
1470
- result.length = length;
1471
- result.direction.normalize();
1472
- return Ray.TransformToRef(result, world, result);
1473
- }
1474
- /**
1475
- * Transforms a ray by a matrix
1476
- * @param ray ray to transform
1477
- * @param matrix matrix to apply
1478
- * @returns the resulting new ray
1479
- */
1480
- static Transform(ray, matrix) {
1481
- const result = new Ray(new Vector3(0, 0, 0), new Vector3(0, 0, 0));
1482
- Ray.TransformToRef(ray, matrix, result);
1483
- return result;
1484
- }
1485
- /**
1486
- * Transforms a ray by a matrix
1487
- * @param ray ray to transform
1488
- * @param matrix matrix to apply
1489
- * @param result ray to store result in
1490
- * @returns the updated result ray
1491
- */
1492
- static TransformToRef(ray, matrix, result) {
1493
- Vector3.TransformCoordinatesToRef(ray.origin, matrix, result.origin);
1494
- Vector3.TransformNormalToRef(ray.direction, matrix, result.direction);
1495
- result.length = ray.length;
1496
- result.epsilon = ray.epsilon;
1497
- const dir = result.direction;
1498
- const len = dir.length();
1499
- if (!(len === 0 || len === 1)) {
1500
- const num = 1.0 / len;
1501
- dir.x *= num;
1502
- dir.y *= num;
1503
- dir.z *= num;
1504
- result.length *= len;
1505
- }
1506
- return result;
1507
- }
1508
- /**
1509
- * Unproject a ray from screen space to object space
1510
- * @param sourceX defines the screen space x coordinate to use
1511
- * @param sourceY defines the screen space y coordinate to use
1512
- * @param viewportWidth defines the current width of the viewport
1513
- * @param viewportHeight defines the current height of the viewport
1514
- * @param world defines the world matrix to use (can be set to Identity to go to world space)
1515
- * @param view defines the view matrix to use
1516
- * @param projection defines the projection matrix to use
1517
- */
1518
- unprojectRayToRef(sourceX, sourceY, viewportWidth, viewportHeight, world, view, projection) {
1519
- const matrix = TmpVectors.Matrix[0];
1520
- world.multiplyToRef(view, matrix);
1521
- matrix.multiplyToRef(projection, matrix);
1522
- matrix.invert();
1523
- const engine = EngineStore.LastCreatedEngine;
1524
- const nearScreenSource = TmpVectors.Vector3[0];
1525
- nearScreenSource.x = (sourceX / viewportWidth) * 2 - 1;
1526
- nearScreenSource.y = -((sourceY / viewportHeight) * 2 - 1);
1527
- nearScreenSource.z = engine?.useReverseDepthBuffer ? 1 : engine?.isNDCHalfZRange ? 0 : -1;
1528
- // far Z need to be close but < to 1 or camera projection matrix with maxZ = 0 will NaN
1529
- const farScreenSource = TmpVectors.Vector3[1].copyFromFloats(nearScreenSource.x, nearScreenSource.y, 1.0 - 1e-8);
1530
- const nearVec3 = TmpVectors.Vector3[2];
1531
- const farVec3 = TmpVectors.Vector3[3];
1532
- Vector3._UnprojectFromInvertedMatrixToRef(nearScreenSource, matrix, nearVec3);
1533
- Vector3._UnprojectFromInvertedMatrixToRef(farScreenSource, matrix, farVec3);
1534
- this.origin.copyFrom(nearVec3);
1535
- farVec3.subtractToRef(nearVec3, this.direction);
1536
- this.direction.normalize();
1537
- }
1538
- }
1539
- Ray._TmpVector3 = BuildArray(6, Vector3.Zero);
1540
- Ray._RayDistant = Ray.Zero();
1541
- Ray._Smallnum = 0.00000001;
1542
- Ray._Rayl = 10e8;
1543
- Scene.prototype.createPickingRay = function (x, y, world, camera, cameraViewSpace = false) {
1544
- const result = Ray.Zero();
1545
- this.createPickingRayToRef(x, y, world, result, camera, cameraViewSpace);
1546
- return result;
1547
- };
1548
- Scene.prototype.createPickingRayToRef = function (x, y, world, result, camera, cameraViewSpace = false, enableDistantPicking = false) {
1549
- const engine = this.getEngine();
1550
- if (!camera && !(camera = this.activeCamera)) {
1551
- return this;
1552
- }
1553
- const cameraViewport = camera.viewport;
1554
- const renderHeight = engine.getRenderHeight();
1555
- const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);
1556
- // Moving coordinates to local viewport world
1557
- const levelInv = 1 / engine.getHardwareScalingLevel();
1558
- x = x * levelInv - vx;
1559
- y = y * levelInv - (renderHeight - vy - height);
1560
- result.update(x, y, width, height, world ? world : Matrix.IdentityReadOnly, cameraViewSpace ? Matrix.IdentityReadOnly : camera.getViewMatrix(), camera.getProjectionMatrix(), enableDistantPicking);
1561
- return this;
1562
- };
1563
- Scene.prototype.createPickingRayInCameraSpace = function (x, y, camera) {
1564
- const result = Ray.Zero();
1565
- this.createPickingRayInCameraSpaceToRef(x, y, result, camera);
1566
- return result;
1567
- };
1568
- Scene.prototype.createPickingRayInCameraSpaceToRef = function (x, y, result, camera) {
1569
- if (!PickingInfo) {
1570
- return this;
1571
- }
1572
- const engine = this.getEngine();
1573
- if (!camera && !(camera = this.activeCamera)) {
1574
- throw new Error("Active camera not set");
1575
- }
1576
- const cameraViewport = camera.viewport;
1577
- const renderHeight = engine.getRenderHeight();
1578
- const { x: vx, y: vy, width, height } = cameraViewport.toGlobal(engine.getRenderWidth(), renderHeight);
1579
- const identity = Matrix.Identity();
1580
- // Moving coordinates to local viewport world
1581
- const levelInv = 1 / engine.getHardwareScalingLevel();
1582
- x = x * levelInv - vx;
1583
- y = y * levelInv - (renderHeight - vy - height);
1584
- result.update(x, y, width, height, identity, identity, camera.getProjectionMatrix());
1585
- return this;
1586
- };
1587
- Scene.prototype._internalPickForMesh = function (pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate, skipBoundingInfo) {
1588
- const ray = rayFunction(world, mesh.enableDistantPicking);
1589
- const result = mesh.intersects(ray, fastCheck, trianglePredicate, onlyBoundingInfo, world, skipBoundingInfo);
1590
- if (!result || !result.hit) {
1591
- return null;
1592
- }
1593
- if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
1594
- return null;
1595
- }
1596
- return result;
1597
- };
1598
- Scene.prototype._internalPick = function (rayFunction, predicate, fastCheck, onlyBoundingInfo, trianglePredicate) {
1599
- let pickingInfo = null;
1600
- const computeWorldMatrixForCamera = !!(this.activeCameras && this.activeCameras.length > 1 && this.cameraToUseForPointers !== this.activeCamera);
1601
- const currentCamera = this.cameraToUseForPointers || this.activeCamera;
1602
- for (let meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
1603
- const mesh = this.meshes[meshIndex];
1604
- if (predicate) {
1605
- if (!predicate(mesh, -1)) {
1606
- continue;
1607
- }
1608
- }
1609
- else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
1610
- continue;
1611
- }
1612
- const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();
1613
- const world = mesh.computeWorldMatrix(forceCompute, currentCamera);
1614
- if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {
1615
- // first check if the ray intersects the whole bounding box/sphere of the mesh
1616
- const result = this._internalPickForMesh(pickingInfo, rayFunction, mesh, world, true, true, trianglePredicate);
1617
- if (result) {
1618
- if (onlyBoundingInfo) {
1619
- // the user only asked for a bounding info check so we can return
1620
- return result;
1621
- }
1622
- const tmpMatrix = TmpVectors.Matrix[1];
1623
- const thinMatrices = mesh.thinInstanceGetWorldMatrices();
1624
- for (let index = 0; index < thinMatrices.length; index++) {
1625
- if (predicate && !predicate(mesh, index)) {
1626
- continue;
1627
- }
1628
- const thinMatrix = thinMatrices[index];
1629
- thinMatrix.multiplyToRef(world, tmpMatrix);
1630
- const result = this._internalPickForMesh(pickingInfo, rayFunction, mesh, tmpMatrix, fastCheck, onlyBoundingInfo, trianglePredicate, true);
1631
- if (result) {
1632
- pickingInfo = result;
1633
- pickingInfo.thinInstanceIndex = index;
1634
- if (fastCheck) {
1635
- return pickingInfo;
1636
- }
1637
- }
1638
- }
1639
- }
1640
- }
1641
- else {
1642
- const result = this._internalPickForMesh(pickingInfo, rayFunction, mesh, world, fastCheck, onlyBoundingInfo, trianglePredicate);
1643
- if (result) {
1644
- pickingInfo = result;
1645
- if (fastCheck) {
1646
- return pickingInfo;
1647
- }
1648
- }
1649
- }
1650
- }
1651
- return pickingInfo || new PickingInfo();
1652
- };
1653
- Scene.prototype._internalMultiPick = function (rayFunction, predicate, trianglePredicate) {
1654
- if (!PickingInfo) {
1655
- return null;
1656
- }
1657
- const pickingInfos = [];
1658
- const computeWorldMatrixForCamera = !!(this.activeCameras && this.activeCameras.length > 1 && this.cameraToUseForPointers !== this.activeCamera);
1659
- const currentCamera = this.cameraToUseForPointers || this.activeCamera;
1660
- for (let meshIndex = 0; meshIndex < this.meshes.length; meshIndex++) {
1661
- const mesh = this.meshes[meshIndex];
1662
- if (predicate) {
1663
- if (!predicate(mesh, -1)) {
1664
- continue;
1665
- }
1666
- }
1667
- else if (!mesh.isEnabled() || !mesh.isVisible || !mesh.isPickable) {
1668
- continue;
1669
- }
1670
- const forceCompute = computeWorldMatrixForCamera && mesh.isWorldMatrixCameraDependent();
1671
- const world = mesh.computeWorldMatrix(forceCompute, currentCamera);
1672
- if (mesh.hasThinInstances && mesh.thinInstanceEnablePicking) {
1673
- const result = this._internalPickForMesh(null, rayFunction, mesh, world, true, true, trianglePredicate);
1674
- if (result) {
1675
- const tmpMatrix = TmpVectors.Matrix[1];
1676
- const thinMatrices = mesh.thinInstanceGetWorldMatrices();
1677
- for (let index = 0; index < thinMatrices.length; index++) {
1678
- if (predicate && !predicate(mesh, index)) {
1679
- continue;
1680
- }
1681
- const thinMatrix = thinMatrices[index];
1682
- thinMatrix.multiplyToRef(world, tmpMatrix);
1683
- const result = this._internalPickForMesh(null, rayFunction, mesh, tmpMatrix, false, false, trianglePredicate, true);
1684
- if (result) {
1685
- result.thinInstanceIndex = index;
1686
- pickingInfos.push(result);
1687
- }
1688
- }
1689
- }
1690
- }
1691
- else {
1692
- const result = this._internalPickForMesh(null, rayFunction, mesh, world, false, false, trianglePredicate);
1693
- if (result) {
1694
- pickingInfos.push(result);
1695
- }
1696
- }
1697
- }
1698
- return pickingInfos;
1699
- };
1700
- Scene.prototype.pickWithBoundingInfo = function (x, y, predicate, fastCheck, camera) {
1701
- if (!PickingInfo) {
1702
- return null;
1703
- }
1704
- const result = this._internalPick((world) => {
1705
- if (!this._tempPickingRay) {
1706
- this._tempPickingRay = Ray.Zero();
1707
- }
1708
- this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null);
1709
- return this._tempPickingRay;
1710
- }, predicate, fastCheck, true);
1711
- if (result) {
1712
- result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
1713
- }
1714
- return result;
1715
- };
1716
- Object.defineProperty(Scene.prototype, "_pickingAvailable", {
1717
- get: () => true,
1718
- enumerable: false,
1719
- configurable: false,
1720
- });
1721
- Scene.prototype.pick = function (x, y, predicate, fastCheck, camera, trianglePredicate, _enableDistantPicking = false) {
1722
- const result = this._internalPick((world, enableDistantPicking) => {
1723
- if (!this._tempPickingRay) {
1724
- this._tempPickingRay = Ray.Zero();
1725
- }
1726
- this.createPickingRayToRef(x, y, world, this._tempPickingRay, camera || null, false, enableDistantPicking);
1727
- return this._tempPickingRay;
1728
- }, predicate, fastCheck, false, trianglePredicate);
1729
- if (result) {
1730
- result.ray = this.createPickingRay(x, y, Matrix.Identity(), camera || null);
1731
- }
1732
- return result;
1733
- };
1734
- Scene.prototype.pickWithRay = function (ray, predicate, fastCheck, trianglePredicate) {
1735
- const result = this._internalPick((world) => {
1736
- if (!this._pickWithRayInverseMatrix) {
1737
- this._pickWithRayInverseMatrix = Matrix.Identity();
1738
- }
1739
- world.invertToRef(this._pickWithRayInverseMatrix);
1740
- if (!this._cachedRayForTransform) {
1741
- this._cachedRayForTransform = Ray.Zero();
1742
- }
1743
- Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
1744
- return this._cachedRayForTransform;
1745
- }, predicate, fastCheck, false, trianglePredicate);
1746
- if (result) {
1747
- result.ray = ray;
1748
- }
1749
- return result;
1750
- };
1751
- Scene.prototype.multiPick = function (x, y, predicate, camera, trianglePredicate) {
1752
- return this._internalMultiPick((world) => this.createPickingRay(x, y, world, camera || null), predicate, trianglePredicate);
1753
- };
1754
- Scene.prototype.multiPickWithRay = function (ray, predicate, trianglePredicate) {
1755
- return this._internalMultiPick((world) => {
1756
- if (!this._pickWithRayInverseMatrix) {
1757
- this._pickWithRayInverseMatrix = Matrix.Identity();
1758
- }
1759
- world.invertToRef(this._pickWithRayInverseMatrix);
1760
- if (!this._cachedRayForTransform) {
1761
- this._cachedRayForTransform = Ray.Zero();
1762
- }
1763
- Ray.TransformToRef(ray, this._pickWithRayInverseMatrix, this._cachedRayForTransform);
1764
- return this._cachedRayForTransform;
1765
- }, predicate, trianglePredicate);
1766
- };
1767
- Camera.prototype.getForwardRay = function (length = 100, transform, origin) {
1768
- return this.getForwardRayToRef(new Ray(Vector3.Zero(), Vector3.Zero(), length), length, transform, origin);
1769
- };
1770
- Camera.prototype.getForwardRayToRef = function (refRay, length = 100, transform, origin) {
1771
- if (!transform) {
1772
- transform = this.getWorldMatrix();
1773
- }
1774
- refRay.length = length;
1775
- if (origin) {
1776
- refRay.origin.copyFrom(origin);
1777
- }
1778
- else {
1779
- refRay.origin.copyFrom(this.position);
1780
- }
1781
- const forward = TmpVectors.Vector3[2];
1782
- forward.set(0, 0, this._scene.useRightHandedSystem ? -1 : 1);
1783
- const worldForward = TmpVectors.Vector3[3];
1784
- Vector3.TransformNormalToRef(forward, transform, worldForward);
1785
- Vector3.NormalizeToRef(worldForward, refRay.direction);
1786
- return refRay;
1787
- };
1788
-
1789
- /** Defines the 4 color options */
1790
- var PointColor;
1791
- (function (PointColor) {
1792
- /** color value */
1793
- PointColor[PointColor["Color"] = 2] = "Color";
1794
- /** uv value */
1795
- PointColor[PointColor["UV"] = 1] = "UV";
1796
- /** random value */
1797
- PointColor[PointColor["Random"] = 0] = "Random";
1798
- /** stated value */
1799
- PointColor[PointColor["Stated"] = 3] = "Stated";
1800
- })(PointColor || (PointColor = {}));
1801
- /**
1802
- * The PointCloudSystem (PCS) is a single updatable mesh. The points corresponding to the vertices of this big mesh.
1803
- * 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.
1804
-
1805
- * The PointCloudSystem is also a particle system, with each point being a particle. It provides some methods to manage the particles.
1806
- * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior.
1807
- *
1808
- * Full documentation here : TO BE ENTERED
1809
- */
1810
- class PointsCloudSystem {
1811
- /**
1812
- * Gets the particle positions computed by the Point Cloud System
1813
- */
1814
- get positions() {
1815
- return this._positions32;
1816
- }
1817
- /**
1818
- * Gets the particle colors computed by the Point Cloud System
1819
- */
1820
- get colors() {
1821
- return this._colors32;
1822
- }
1823
- /**
1824
- * Gets the particle uvs computed by the Point Cloud System
1825
- */
1826
- get uvs() {
1827
- return this._uvs32;
1828
- }
1829
- /**
1830
- * Creates a PCS (Points Cloud System) object
1831
- * @param name (String) is the PCS name, this will be the underlying mesh name
1832
- * @param pointSize (number) is the size for each point. Has no effect on a WebGPU engine.
1833
- * @param scene (Scene) is the scene in which the PCS is added
1834
- * @param options defines the options of the PCS e.g.
1835
- * * updatable (optional boolean, default true) : if the PCS must be updatable or immutable
1836
- */
1837
- constructor(name, pointSize, scene, options) {
1838
- /**
1839
- * The PCS array of cloud point objects. Just access each particle as with any classic array.
1840
- * Example : var p = SPS.particles[i];
1841
- */
1842
- this.particles = new Array();
1843
- /**
1844
- * The PCS total number of particles. Read only. Use PCS.counter instead if you need to set your own value.
1845
- */
1846
- this.nbParticles = 0;
1847
- /**
1848
- * This a counter for your own usage. It's not set by any SPS functions.
1849
- */
1850
- this.counter = 0;
1851
- /**
1852
- * This empty object is intended to store some PCS specific or temporary values in order to lower the Garbage Collector activity.
1853
- * Please read :
1854
- */
1855
- this.vars = {};
1856
- this._promises = [];
1857
- this._positions = new Array();
1858
- this._indices = new Array();
1859
- this._normals = new Array();
1860
- this._colors = new Array();
1861
- this._uvs = new Array();
1862
- this._updatable = true;
1863
- this._isVisibilityBoxLocked = false;
1864
- this._alwaysVisible = false;
1865
- this._groups = new Array(); //start indices for each group of particles
1866
- this._groupCounter = 0;
1867
- this._computeParticleColor = true;
1868
- this._computeParticleTexture = true;
1869
- this._computeParticleRotation = true;
1870
- this._computeBoundingBox = false;
1871
- this._isReady = false;
1872
- this.name = name;
1873
- this._size = pointSize;
1874
- this._scene = scene || EngineStore.LastCreatedScene;
1875
- if (options && options.updatable !== undefined) {
1876
- this._updatable = options.updatable;
1877
- }
1878
- else {
1879
- this._updatable = true;
1880
- }
1881
- }
1882
- /**
1883
- * Builds the PCS underlying mesh. Returns a standard Mesh.
1884
- * If no points were added to the PCS, the returned mesh is just a single point.
1885
- * @param material The material to use to render the mesh. If not provided, will create a default one
1886
- * @returns a promise for the created mesh
1887
- */
1888
- buildMeshAsync(material) {
1889
- return Promise.all(this._promises).then(() => {
1890
- this._isReady = true;
1891
- return this._buildMesh(material);
1892
- });
1893
- }
1894
- /**
1895
- * @internal
1896
- */
1897
- _buildMesh(material) {
1898
- if (this.nbParticles === 0) {
1899
- this.addPoints(1);
1900
- }
1901
- this._positions32 = new Float32Array(this._positions);
1902
- this._uvs32 = new Float32Array(this._uvs);
1903
- this._colors32 = new Float32Array(this._colors);
1904
- const vertexData = new VertexData();
1905
- vertexData.set(this._positions32, VertexBuffer.PositionKind);
1906
- if (this._uvs32.length > 0) {
1907
- vertexData.set(this._uvs32, VertexBuffer.UVKind);
1908
- }
1909
- let ec = 0; //emissive color value 0 for UVs, 1 for color
1910
- if (this._colors32.length > 0) {
1911
- ec = 1;
1912
- vertexData.set(this._colors32, VertexBuffer.ColorKind);
1913
- }
1914
- const mesh = new Mesh(this.name, this._scene);
1915
- vertexData.applyToMesh(mesh, this._updatable);
1916
- this.mesh = mesh;
1917
- // free memory
1918
- this._positions = null;
1919
- this._uvs = null;
1920
- this._colors = null;
1921
- if (!this._updatable) {
1922
- this.particles.length = 0;
1923
- }
1924
- let mat = material;
1925
- if (!mat) {
1926
- mat = new StandardMaterial("point cloud material", this._scene);
1927
- mat.emissiveColor = new Color3(ec, ec, ec);
1928
- mat.disableLighting = true;
1929
- mat.pointsCloud = true;
1930
- mat.pointSize = this._size;
1931
- }
1932
- mesh.material = mat;
1933
- return new Promise((resolve) => resolve(mesh));
1934
- }
1935
- // adds a new particle object in the particles array
1936
- _addParticle(idx, group, groupId, idxInGroup) {
1937
- const cp = new CloudPoint(idx, group, groupId, idxInGroup, this);
1938
- this.particles.push(cp);
1939
- return cp;
1940
- }
1941
- _randomUnitVector(particle) {
1942
- particle.position = new Vector3(Math.random(), Math.random(), Math.random());
1943
- particle.color = new Color4(1, 1, 1, 1);
1944
- }
1945
- _getColorIndicesForCoord(pointsGroup, x, y, width) {
1946
- const imageData = pointsGroup._groupImageData;
1947
- const color = y * (width * 4) + x * 4;
1948
- const colorIndices = [color, color + 1, color + 2, color + 3];
1949
- const redIndex = colorIndices[0];
1950
- const greenIndex = colorIndices[1];
1951
- const blueIndex = colorIndices[2];
1952
- const alphaIndex = colorIndices[3];
1953
- const redForCoord = imageData[redIndex];
1954
- const greenForCoord = imageData[greenIndex];
1955
- const blueForCoord = imageData[blueIndex];
1956
- const alphaForCoord = imageData[alphaIndex];
1957
- return new Color4(redForCoord / 255, greenForCoord / 255, blueForCoord / 255, alphaForCoord);
1958
- }
1959
- _setPointsColorOrUV(mesh, pointsGroup, isVolume, colorFromTexture, hasTexture, color, range, uvSetIndex) {
1960
- uvSetIndex = uvSetIndex ?? 0;
1961
- if (isVolume) {
1962
- mesh.updateFacetData();
1963
- }
1964
- const boundInfo = mesh.getBoundingInfo();
1965
- const diameter = 2 * boundInfo.boundingSphere.radius;
1966
- let meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
1967
- const meshInd = mesh.getIndices();
1968
- const meshUV = mesh.getVerticesData(VertexBuffer.UVKind + (uvSetIndex ? uvSetIndex + 1 : ""));
1969
- const meshCol = mesh.getVerticesData(VertexBuffer.ColorKind);
1970
- const place = Vector3.Zero();
1971
- mesh.computeWorldMatrix();
1972
- const meshMatrix = mesh.getWorldMatrix();
1973
- if (!meshMatrix.isIdentity()) {
1974
- meshPos = meshPos.slice(0);
1975
- for (let p = 0; p < meshPos.length / 3; p++) {
1976
- Vector3.TransformCoordinatesFromFloatsToRef(meshPos[3 * p], meshPos[3 * p + 1], meshPos[3 * p + 2], meshMatrix, place);
1977
- meshPos[3 * p] = place.x;
1978
- meshPos[3 * p + 1] = place.y;
1979
- meshPos[3 * p + 2] = place.z;
1980
- }
1981
- }
1982
- let idxPoints = 0;
1983
- let id0 = 0;
1984
- let id1 = 0;
1985
- let id2 = 0;
1986
- let v0X = 0;
1987
- let v0Y = 0;
1988
- let v0Z = 0;
1989
- let v1X = 0;
1990
- let v1Y = 0;
1991
- let v1Z = 0;
1992
- let v2X = 0;
1993
- let v2Y = 0;
1994
- let v2Z = 0;
1995
- const vertex0 = Vector3.Zero();
1996
- const vertex1 = Vector3.Zero();
1997
- const vertex2 = Vector3.Zero();
1998
- const vec0 = Vector3.Zero();
1999
- const vec1 = Vector3.Zero();
2000
- let uv0X = 0;
2001
- let uv0Y = 0;
2002
- let uv1X = 0;
2003
- let uv1Y = 0;
2004
- let uv2X = 0;
2005
- let uv2Y = 0;
2006
- const uv0 = Vector2.Zero();
2007
- const uv1 = Vector2.Zero();
2008
- const uv2 = Vector2.Zero();
2009
- const uvec0 = Vector2.Zero();
2010
- const uvec1 = Vector2.Zero();
2011
- let col0X = 0;
2012
- let col0Y = 0;
2013
- let col0Z = 0;
2014
- let col0A = 0;
2015
- let col1X = 0;
2016
- let col1Y = 0;
2017
- let col1Z = 0;
2018
- let col1A = 0;
2019
- let col2X = 0;
2020
- let col2Y = 0;
2021
- let col2Z = 0;
2022
- let col2A = 0;
2023
- const col0 = Vector4.Zero();
2024
- const col1 = Vector4.Zero();
2025
- const col2 = Vector4.Zero();
2026
- const colvec0 = Vector4.Zero();
2027
- const colvec1 = Vector4.Zero();
2028
- let lamda = 0;
2029
- let mu = 0;
2030
- range = range ? range : 0;
2031
- let facetPoint;
2032
- let uvPoint;
2033
- let colPoint = new Vector4(0, 0, 0, 0);
2034
- let norm = Vector3.Zero();
2035
- let tang = Vector3.Zero();
2036
- let biNorm = Vector3.Zero();
2037
- let angle = 0;
2038
- let facetPlaneVec = Vector3.Zero();
2039
- let gap = 0;
2040
- let distance = 0;
2041
- const ray = new Ray(Vector3.Zero(), new Vector3(1, 0, 0));
2042
- let pickInfo;
2043
- let direction = Vector3.Zero();
2044
- for (let index = 0; index < meshInd.length / 3; index++) {
2045
- id0 = meshInd[3 * index];
2046
- id1 = meshInd[3 * index + 1];
2047
- id2 = meshInd[3 * index + 2];
2048
- v0X = meshPos[3 * id0];
2049
- v0Y = meshPos[3 * id0 + 1];
2050
- v0Z = meshPos[3 * id0 + 2];
2051
- v1X = meshPos[3 * id1];
2052
- v1Y = meshPos[3 * id1 + 1];
2053
- v1Z = meshPos[3 * id1 + 2];
2054
- v2X = meshPos[3 * id2];
2055
- v2Y = meshPos[3 * id2 + 1];
2056
- v2Z = meshPos[3 * id2 + 2];
2057
- vertex0.set(v0X, v0Y, v0Z);
2058
- vertex1.set(v1X, v1Y, v1Z);
2059
- vertex2.set(v2X, v2Y, v2Z);
2060
- vertex1.subtractToRef(vertex0, vec0);
2061
- vertex2.subtractToRef(vertex1, vec1);
2062
- if (meshUV) {
2063
- uv0X = meshUV[2 * id0];
2064
- uv0Y = meshUV[2 * id0 + 1];
2065
- uv1X = meshUV[2 * id1];
2066
- uv1Y = meshUV[2 * id1 + 1];
2067
- uv2X = meshUV[2 * id2];
2068
- uv2Y = meshUV[2 * id2 + 1];
2069
- uv0.set(uv0X, uv0Y);
2070
- uv1.set(uv1X, uv1Y);
2071
- uv2.set(uv2X, uv2Y);
2072
- uv1.subtractToRef(uv0, uvec0);
2073
- uv2.subtractToRef(uv1, uvec1);
2074
- }
2075
- if (meshCol && colorFromTexture) {
2076
- col0X = meshCol[4 * id0];
2077
- col0Y = meshCol[4 * id0 + 1];
2078
- col0Z = meshCol[4 * id0 + 2];
2079
- col0A = meshCol[4 * id0 + 3];
2080
- col1X = meshCol[4 * id1];
2081
- col1Y = meshCol[4 * id1 + 1];
2082
- col1Z = meshCol[4 * id1 + 2];
2083
- col1A = meshCol[4 * id1 + 3];
2084
- col2X = meshCol[4 * id2];
2085
- col2Y = meshCol[4 * id2 + 1];
2086
- col2Z = meshCol[4 * id2 + 2];
2087
- col2A = meshCol[4 * id2 + 3];
2088
- col0.set(col0X, col0Y, col0Z, col0A);
2089
- col1.set(col1X, col1Y, col1Z, col1A);
2090
- col2.set(col2X, col2Y, col2Z, col2A);
2091
- col1.subtractToRef(col0, colvec0);
2092
- col2.subtractToRef(col1, colvec1);
2093
- }
2094
- let width;
2095
- let height;
2096
- let deltaS;
2097
- let deltaV;
2098
- let h;
2099
- let s;
2100
- let v;
2101
- let hsvCol;
2102
- const statedColor = new Color3(0, 0, 0);
2103
- const colPoint3 = new Color3(0, 0, 0);
2104
- let pointColors;
2105
- let particle;
2106
- for (let i = 0; i < pointsGroup._groupDensity[index]; i++) {
2107
- idxPoints = this.particles.length;
2108
- this._addParticle(idxPoints, pointsGroup, this._groupCounter, index + i);
2109
- particle = this.particles[idxPoints];
2110
- //form a point inside the facet v0, v1, v2;
2111
- lamda = Math.sqrt(RandomRange(0, 1));
2112
- mu = RandomRange(0, 1);
2113
- facetPoint = vertex0.add(vec0.scale(lamda)).add(vec1.scale(lamda * mu));
2114
- if (isVolume) {
2115
- norm = mesh.getFacetNormal(index).normalize().scale(-1);
2116
- tang = vec0.clone().normalize();
2117
- biNorm = Vector3.Cross(norm, tang);
2118
- angle = RandomRange(0, 2 * Math.PI);
2119
- facetPlaneVec = tang.scale(Math.cos(angle)).add(biNorm.scale(Math.sin(angle)));
2120
- angle = RandomRange(0.1, Math.PI / 2);
2121
- direction = facetPlaneVec.scale(Math.cos(angle)).add(norm.scale(Math.sin(angle)));
2122
- ray.origin = facetPoint.add(direction.scale(0.00001));
2123
- ray.direction = direction;
2124
- ray.length = diameter;
2125
- pickInfo = ray.intersectsMesh(mesh);
2126
- if (pickInfo.hit) {
2127
- distance = pickInfo.pickedPoint.subtract(facetPoint).length();
2128
- gap = RandomRange(0, 1) * distance;
2129
- facetPoint.addInPlace(direction.scale(gap));
2130
- }
2131
- }
2132
- particle.position = facetPoint.clone();
2133
- this._positions.push(particle.position.x, particle.position.y, particle.position.z);
2134
- if (colorFromTexture !== undefined) {
2135
- if (meshUV) {
2136
- uvPoint = uv0.add(uvec0.scale(lamda)).add(uvec1.scale(lamda * mu));
2137
- if (colorFromTexture) {
2138
- //Set particle color to texture color
2139
- if (hasTexture && pointsGroup._groupImageData !== null) {
2140
- width = pointsGroup._groupImgWidth;
2141
- height = pointsGroup._groupImgHeight;
2142
- pointColors = this._getColorIndicesForCoord(pointsGroup, Math.round(uvPoint.x * width), Math.round(uvPoint.y * height), width);
2143
- particle.color = pointColors;
2144
- this._colors.push(pointColors.r, pointColors.g, pointColors.b, pointColors.a);
2145
- }
2146
- else {
2147
- if (meshCol) {
2148
- //failure in texture and colors available
2149
- colPoint = col0.add(colvec0.scale(lamda)).add(colvec1.scale(lamda * mu));
2150
- particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2151
- this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2152
- }
2153
- else {
2154
- colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);
2155
- particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2156
- this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2157
- }
2158
- }
2159
- }
2160
- else {
2161
- //Set particle uv based on a mesh uv
2162
- particle.uv = uvPoint.clone();
2163
- this._uvs.push(particle.uv.x, particle.uv.y);
2164
- }
2165
- }
2166
- }
2167
- else {
2168
- if (color) {
2169
- statedColor.set(color.r, color.g, color.b);
2170
- deltaS = RandomRange(-range, range);
2171
- deltaV = RandomRange(-range, range);
2172
- hsvCol = statedColor.toHSV();
2173
- h = hsvCol.r;
2174
- s = hsvCol.g + deltaS;
2175
- v = hsvCol.b + deltaV;
2176
- if (s < 0) {
2177
- s = 0;
2178
- }
2179
- if (s > 1) {
2180
- s = 1;
2181
- }
2182
- if (v < 0) {
2183
- v = 0;
2184
- }
2185
- if (v > 1) {
2186
- v = 1;
2187
- }
2188
- Color3.HSVtoRGBToRef(h, s, v, colPoint3);
2189
- colPoint.set(colPoint3.r, colPoint3.g, colPoint3.b, 1);
2190
- }
2191
- else {
2192
- colPoint = col0.set(Math.random(), Math.random(), Math.random(), 1);
2193
- }
2194
- particle.color = new Color4(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2195
- this._colors.push(colPoint.x, colPoint.y, colPoint.z, colPoint.w);
2196
- }
2197
- }
2198
- }
2199
- }
2200
- // stores mesh texture in dynamic texture for color pixel retrieval
2201
- // when pointColor type is color for surface points
2202
- _colorFromTexture(mesh, pointsGroup, isVolume) {
2203
- if (mesh.material === null) {
2204
- Logger.Warn(mesh.name + "has no material.");
2205
- pointsGroup._groupImageData = null;
2206
- this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);
2207
- return;
2208
- }
2209
- const mat = mesh.material;
2210
- const textureList = mat.getActiveTextures();
2211
- if (textureList.length === 0) {
2212
- Logger.Warn(mesh.name + "has no usable texture.");
2213
- pointsGroup._groupImageData = null;
2214
- this._setPointsColorOrUV(mesh, pointsGroup, isVolume, true, false);
2215
- return;
2216
- }
2217
- const clone = mesh.clone();
2218
- clone.setEnabled(false);
2219
- this._promises.push(new Promise((resolve) => {
2220
- BaseTexture.WhenAllReady(textureList, () => {
2221
- let n = pointsGroup._textureNb;
2222
- if (n < 0) {
2223
- n = 0;
2224
- }
2225
- if (n > textureList.length - 1) {
2226
- n = textureList.length - 1;
2227
- }
2228
- const finalize = () => {
2229
- pointsGroup._groupImgWidth = textureList[n].getSize().width;
2230
- pointsGroup._groupImgHeight = textureList[n].getSize().height;
2231
- this._setPointsColorOrUV(clone, pointsGroup, isVolume, true, true, undefined, undefined, textureList[n].coordinatesIndex);
2232
- clone.dispose();
2233
- resolve();
2234
- };
2235
- pointsGroup._groupImageData = null;
2236
- const dataPromise = textureList[n].readPixels();
2237
- if (!dataPromise) {
2238
- finalize();
2239
- }
2240
- else {
2241
- dataPromise.then((data) => {
2242
- pointsGroup._groupImageData = data;
2243
- finalize();
2244
- });
2245
- }
2246
- });
2247
- }));
2248
- }
2249
- // calculates the point density per facet of a mesh for surface points
2250
- _calculateDensity(nbPoints, positions, indices) {
2251
- let id0;
2252
- let id1;
2253
- let id2;
2254
- let v0X;
2255
- let v0Y;
2256
- let v0Z;
2257
- let v1X;
2258
- let v1Y;
2259
- let v1Z;
2260
- let v2X;
2261
- let v2Y;
2262
- let v2Z;
2263
- const vertex0 = Vector3.Zero();
2264
- const vertex1 = Vector3.Zero();
2265
- const vertex2 = Vector3.Zero();
2266
- const vec0 = Vector3.Zero();
2267
- const vec1 = Vector3.Zero();
2268
- const normal = Vector3.Zero();
2269
- let area;
2270
- const cumulativeAreas = [];
2271
- let surfaceArea = 0;
2272
- const nbFacets = indices.length / 3;
2273
- //surface area
2274
- for (let index = 0; index < nbFacets; index++) {
2275
- id0 = indices[3 * index];
2276
- id1 = indices[3 * index + 1];
2277
- id2 = indices[3 * index + 2];
2278
- v0X = positions[3 * id0];
2279
- v0Y = positions[3 * id0 + 1];
2280
- v0Z = positions[3 * id0 + 2];
2281
- v1X = positions[3 * id1];
2282
- v1Y = positions[3 * id1 + 1];
2283
- v1Z = positions[3 * id1 + 2];
2284
- v2X = positions[3 * id2];
2285
- v2Y = positions[3 * id2 + 1];
2286
- v2Z = positions[3 * id2 + 2];
2287
- vertex0.set(v0X, v0Y, v0Z);
2288
- vertex1.set(v1X, v1Y, v1Z);
2289
- vertex2.set(v2X, v2Y, v2Z);
2290
- vertex1.subtractToRef(vertex0, vec0);
2291
- vertex2.subtractToRef(vertex1, vec1);
2292
- Vector3.CrossToRef(vec0, vec1, normal);
2293
- area = 0.5 * normal.length();
2294
- surfaceArea += area;
2295
- cumulativeAreas[index] = surfaceArea;
2296
- }
2297
- const density = new Array(nbFacets);
2298
- let remainingPoints = nbPoints;
2299
- for (let index = nbFacets - 1; index > 0; index--) {
2300
- const cumulativeArea = cumulativeAreas[index];
2301
- if (cumulativeArea === 0) {
2302
- // avoiding division by 0 upon degenerate triangles
2303
- density[index] = 0;
2304
- }
2305
- else {
2306
- const area = cumulativeArea - cumulativeAreas[index - 1];
2307
- const facetPointsWithFraction = (area / cumulativeArea) * remainingPoints;
2308
- const floored = Math.floor(facetPointsWithFraction);
2309
- const fraction = facetPointsWithFraction - floored;
2310
- const extraPoint = Number(Math.random() < fraction);
2311
- const facetPoints = floored + extraPoint;
2312
- density[index] = facetPoints;
2313
- remainingPoints -= facetPoints;
2314
- }
2315
- }
2316
- density[0] = remainingPoints;
2317
- return density;
2318
- }
2319
- /**
2320
- * Adds points to the PCS in random positions within a unit sphere
2321
- * @param nb (positive integer) the number of particles to be created from this model
2322
- * @param pointFunction is an optional javascript function to be called for each particle on PCS creation
2323
- * @returns the number of groups in the system
2324
- */
2325
- addPoints(nb, pointFunction = this._randomUnitVector) {
2326
- const pointsGroup = new PointsGroup(this._groupCounter, pointFunction);
2327
- let cp;
2328
- // particles
2329
- let idx = this.nbParticles;
2330
- for (let i = 0; i < nb; i++) {
2331
- cp = this._addParticle(idx, pointsGroup, this._groupCounter, i);
2332
- if (pointsGroup && pointsGroup._positionFunction) {
2333
- pointsGroup._positionFunction(cp, idx, i);
2334
- }
2335
- this._positions.push(cp.position.x, cp.position.y, cp.position.z);
2336
- if (cp.color) {
2337
- this._colors.push(cp.color.r, cp.color.g, cp.color.b, cp.color.a);
2338
- }
2339
- if (cp.uv) {
2340
- this._uvs.push(cp.uv.x, cp.uv.y);
2341
- }
2342
- idx++;
2343
- }
2344
- this.nbParticles += nb;
2345
- this._groupCounter++;
2346
- return this._groupCounter;
2347
- }
2348
- /**
2349
- * Adds points to the PCS from the surface of the model shape
2350
- * @param mesh is any Mesh object that will be used as a surface model for the points
2351
- * @param nb (positive integer) the number of particles to be created from this model
2352
- * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)
2353
- * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position
2354
- * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color
2355
- * @returns the number of groups in the system
2356
- */
2357
- addSurfacePoints(mesh, nb, colorWith, color, range) {
2358
- let colored = colorWith ? colorWith : 0 /* PointColor.Random */;
2359
- if (isNaN(colored) || colored < 0 || colored > 3) {
2360
- colored = 0 /* PointColor.Random */;
2361
- }
2362
- const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
2363
- const meshInd = mesh.getIndices();
2364
- this._groups.push(this._groupCounter);
2365
- const pointsGroup = new PointsGroup(this._groupCounter, null);
2366
- pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);
2367
- if (colored === 2 /* PointColor.Color */) {
2368
- pointsGroup._textureNb = color ? color : 0;
2369
- }
2370
- else {
2371
- color = color ? color : new Color4(1, 1, 1, 1);
2372
- }
2373
- switch (colored) {
2374
- case 2 /* PointColor.Color */:
2375
- this._colorFromTexture(mesh, pointsGroup, false);
2376
- break;
2377
- case 1 /* PointColor.UV */:
2378
- this._setPointsColorOrUV(mesh, pointsGroup, false, false, false);
2379
- break;
2380
- case 0 /* PointColor.Random */:
2381
- this._setPointsColorOrUV(mesh, pointsGroup, false);
2382
- break;
2383
- case 3 /* PointColor.Stated */:
2384
- this._setPointsColorOrUV(mesh, pointsGroup, false, undefined, undefined, color, range);
2385
- break;
2386
- }
2387
- this.nbParticles += nb;
2388
- this._groupCounter++;
2389
- return this._groupCounter - 1;
2390
- }
2391
- /**
2392
- * Adds points to the PCS inside the model shape
2393
- * @param mesh is any Mesh object that will be used as a surface model for the points
2394
- * @param nb (positive integer) the number of particles to be created from this model
2395
- * @param colorWith determines whether a point is colored using color (default), uv, random, stated or none (invisible)
2396
- * @param color (color4) to be used when colorWith is stated or color (number) when used to specify texture position
2397
- * @param range (number from 0 to 1) to determine the variation in shape and tone for a stated color
2398
- * @returns the number of groups in the system
2399
- */
2400
- addVolumePoints(mesh, nb, colorWith, color, range) {
2401
- let colored = colorWith ? colorWith : 0 /* PointColor.Random */;
2402
- if (isNaN(colored) || colored < 0 || colored > 3) {
2403
- colored = 0 /* PointColor.Random */;
2404
- }
2405
- const meshPos = mesh.getVerticesData(VertexBuffer.PositionKind);
2406
- const meshInd = mesh.getIndices();
2407
- this._groups.push(this._groupCounter);
2408
- const pointsGroup = new PointsGroup(this._groupCounter, null);
2409
- pointsGroup._groupDensity = this._calculateDensity(nb, meshPos, meshInd);
2410
- if (colored === 2 /* PointColor.Color */) {
2411
- pointsGroup._textureNb = color ? color : 0;
2412
- }
2413
- else {
2414
- color = color ? color : new Color4(1, 1, 1, 1);
2415
- }
2416
- switch (colored) {
2417
- case 2 /* PointColor.Color */:
2418
- this._colorFromTexture(mesh, pointsGroup, true);
2419
- break;
2420
- case 1 /* PointColor.UV */:
2421
- this._setPointsColorOrUV(mesh, pointsGroup, true, false, false);
2422
- break;
2423
- case 0 /* PointColor.Random */:
2424
- this._setPointsColorOrUV(mesh, pointsGroup, true);
2425
- break;
2426
- case 3 /* PointColor.Stated */:
2427
- this._setPointsColorOrUV(mesh, pointsGroup, true, undefined, undefined, color, range);
2428
- break;
2429
- }
2430
- this.nbParticles += nb;
2431
- this._groupCounter++;
2432
- return this._groupCounter - 1;
2433
- }
2434
- /**
2435
- * Sets all the particles : this method actually really updates the mesh according to the particle positions, rotations, colors, textures, etc.
2436
- * This method calls `updateParticle()` for each particle of the SPS.
2437
- * For an animated SPS, it is usually called within the render loop.
2438
- * @param start The particle index in the particle array where to start to compute the particle property values _(default 0)_
2439
- * @param end The particle index in the particle array where to stop to compute the particle property values _(default nbParticle - 1)_
2440
- * @param update If the mesh must be finally updated on this call after all the particle computations _(default true)_
2441
- * @returns the PCS.
2442
- */
2443
- setParticles(start = 0, end = this.nbParticles - 1, update = true) {
2444
- if (!this._updatable || !this._isReady) {
2445
- return this;
2446
- }
2447
- // custom beforeUpdate
2448
- this.beforeUpdateParticles(start, end, update);
2449
- const rotMatrix = TmpVectors.Matrix[0];
2450
- const mesh = this.mesh;
2451
- const colors32 = this._colors32;
2452
- const positions32 = this._positions32;
2453
- const uvs32 = this._uvs32;
2454
- const tempVectors = TmpVectors.Vector3;
2455
- const camAxisX = tempVectors[5].copyFromFloats(1.0, 0.0, 0.0);
2456
- const camAxisY = tempVectors[6].copyFromFloats(0.0, 1.0, 0.0);
2457
- const camAxisZ = tempVectors[7].copyFromFloats(0.0, 0.0, 1.0);
2458
- const minimum = tempVectors[8].setAll(Number.MAX_VALUE);
2459
- const maximum = tempVectors[9].setAll(-Number.MAX_VALUE);
2460
- Matrix.IdentityToRef(rotMatrix);
2461
- let idx = 0; // current index of the particle
2462
- if (this.mesh?.isFacetDataEnabled) {
2463
- this._computeBoundingBox = true;
2464
- }
2465
- end = end >= this.nbParticles ? this.nbParticles - 1 : end;
2466
- if (this._computeBoundingBox) {
2467
- if (start != 0 || end != this.nbParticles - 1) {
2468
- // only some particles are updated, then use the current existing BBox basis. Note : it can only increase.
2469
- const boundingInfo = this.mesh?.getBoundingInfo();
2470
- if (boundingInfo) {
2471
- minimum.copyFrom(boundingInfo.minimum);
2472
- maximum.copyFrom(boundingInfo.maximum);
2473
- }
2474
- }
2475
- }
2476
- idx = 0; // particle index
2477
- let pindex = 0; //index in positions array
2478
- let cindex = 0; //index in color array
2479
- let uindex = 0; //index in uv array
2480
- // particle loop
2481
- for (let p = start; p <= end; p++) {
2482
- const particle = this.particles[p];
2483
- idx = particle.idx;
2484
- pindex = 3 * idx;
2485
- cindex = 4 * idx;
2486
- uindex = 2 * idx;
2487
- // call to custom user function to update the particle properties
2488
- this.updateParticle(particle);
2489
- const particleRotationMatrix = particle._rotationMatrix;
2490
- const particlePosition = particle.position;
2491
- const particleGlobalPosition = particle._globalPosition;
2492
- if (this._computeParticleRotation) {
2493
- particle.getRotationMatrix(rotMatrix);
2494
- }
2495
- const particleHasParent = particle.parentId !== null;
2496
- if (particleHasParent) {
2497
- const parent = this.particles[particle.parentId];
2498
- const parentRotationMatrix = parent._rotationMatrix;
2499
- const parentGlobalPosition = parent._globalPosition;
2500
- const rotatedY = particlePosition.x * parentRotationMatrix[1] + particlePosition.y * parentRotationMatrix[4] + particlePosition.z * parentRotationMatrix[7];
2501
- const rotatedX = particlePosition.x * parentRotationMatrix[0] + particlePosition.y * parentRotationMatrix[3] + particlePosition.z * parentRotationMatrix[6];
2502
- const rotatedZ = particlePosition.x * parentRotationMatrix[2] + particlePosition.y * parentRotationMatrix[5] + particlePosition.z * parentRotationMatrix[8];
2503
- particleGlobalPosition.x = parentGlobalPosition.x + rotatedX;
2504
- particleGlobalPosition.y = parentGlobalPosition.y + rotatedY;
2505
- particleGlobalPosition.z = parentGlobalPosition.z + rotatedZ;
2506
- if (this._computeParticleRotation) {
2507
- const rotMatrixValues = rotMatrix.m;
2508
- particleRotationMatrix[0] =
2509
- rotMatrixValues[0] * parentRotationMatrix[0] + rotMatrixValues[1] * parentRotationMatrix[3] + rotMatrixValues[2] * parentRotationMatrix[6];
2510
- particleRotationMatrix[1] =
2511
- rotMatrixValues[0] * parentRotationMatrix[1] + rotMatrixValues[1] * parentRotationMatrix[4] + rotMatrixValues[2] * parentRotationMatrix[7];
2512
- particleRotationMatrix[2] =
2513
- rotMatrixValues[0] * parentRotationMatrix[2] + rotMatrixValues[1] * parentRotationMatrix[5] + rotMatrixValues[2] * parentRotationMatrix[8];
2514
- particleRotationMatrix[3] =
2515
- rotMatrixValues[4] * parentRotationMatrix[0] + rotMatrixValues[5] * parentRotationMatrix[3] + rotMatrixValues[6] * parentRotationMatrix[6];
2516
- particleRotationMatrix[4] =
2517
- rotMatrixValues[4] * parentRotationMatrix[1] + rotMatrixValues[5] * parentRotationMatrix[4] + rotMatrixValues[6] * parentRotationMatrix[7];
2518
- particleRotationMatrix[5] =
2519
- rotMatrixValues[4] * parentRotationMatrix[2] + rotMatrixValues[5] * parentRotationMatrix[5] + rotMatrixValues[6] * parentRotationMatrix[8];
2520
- particleRotationMatrix[6] =
2521
- rotMatrixValues[8] * parentRotationMatrix[0] + rotMatrixValues[9] * parentRotationMatrix[3] + rotMatrixValues[10] * parentRotationMatrix[6];
2522
- particleRotationMatrix[7] =
2523
- rotMatrixValues[8] * parentRotationMatrix[1] + rotMatrixValues[9] * parentRotationMatrix[4] + rotMatrixValues[10] * parentRotationMatrix[7];
2524
- particleRotationMatrix[8] =
2525
- rotMatrixValues[8] * parentRotationMatrix[2] + rotMatrixValues[9] * parentRotationMatrix[5] + rotMatrixValues[10] * parentRotationMatrix[8];
2526
- }
2527
- }
2528
- else {
2529
- particleGlobalPosition.x = 0;
2530
- particleGlobalPosition.y = 0;
2531
- particleGlobalPosition.z = 0;
2532
- if (this._computeParticleRotation) {
2533
- const rotMatrixValues = rotMatrix.m;
2534
- particleRotationMatrix[0] = rotMatrixValues[0];
2535
- particleRotationMatrix[1] = rotMatrixValues[1];
2536
- particleRotationMatrix[2] = rotMatrixValues[2];
2537
- particleRotationMatrix[3] = rotMatrixValues[4];
2538
- particleRotationMatrix[4] = rotMatrixValues[5];
2539
- particleRotationMatrix[5] = rotMatrixValues[6];
2540
- particleRotationMatrix[6] = rotMatrixValues[8];
2541
- particleRotationMatrix[7] = rotMatrixValues[9];
2542
- particleRotationMatrix[8] = rotMatrixValues[10];
2543
- }
2544
- }
2545
- const pivotBackTranslation = tempVectors[11];
2546
- if (particle.translateFromPivot) {
2547
- pivotBackTranslation.setAll(0.0);
2548
- }
2549
- else {
2550
- pivotBackTranslation.copyFrom(particle.pivot);
2551
- }
2552
- // positions
2553
- const tmpVertex = tempVectors[0];
2554
- tmpVertex.copyFrom(particle.position);
2555
- const vertexX = tmpVertex.x - particle.pivot.x;
2556
- const vertexY = tmpVertex.y - particle.pivot.y;
2557
- const vertexZ = tmpVertex.z - particle.pivot.z;
2558
- let rotatedX = vertexX * particleRotationMatrix[0] + vertexY * particleRotationMatrix[3] + vertexZ * particleRotationMatrix[6];
2559
- let rotatedY = vertexX * particleRotationMatrix[1] + vertexY * particleRotationMatrix[4] + vertexZ * particleRotationMatrix[7];
2560
- let rotatedZ = vertexX * particleRotationMatrix[2] + vertexY * particleRotationMatrix[5] + vertexZ * particleRotationMatrix[8];
2561
- rotatedX += pivotBackTranslation.x;
2562
- rotatedY += pivotBackTranslation.y;
2563
- rotatedZ += pivotBackTranslation.z;
2564
- const px = (positions32[pindex] = particleGlobalPosition.x + camAxisX.x * rotatedX + camAxisY.x * rotatedY + camAxisZ.x * rotatedZ);
2565
- const py = (positions32[pindex + 1] = particleGlobalPosition.y + camAxisX.y * rotatedX + camAxisY.y * rotatedY + camAxisZ.y * rotatedZ);
2566
- const pz = (positions32[pindex + 2] = particleGlobalPosition.z + camAxisX.z * rotatedX + camAxisY.z * rotatedY + camAxisZ.z * rotatedZ);
2567
- if (this._computeBoundingBox) {
2568
- minimum.minimizeInPlaceFromFloats(px, py, pz);
2569
- maximum.maximizeInPlaceFromFloats(px, py, pz);
2570
- }
2571
- if (this._computeParticleColor && particle.color) {
2572
- const color = particle.color;
2573
- const colors32 = this._colors32;
2574
- colors32[cindex] = color.r;
2575
- colors32[cindex + 1] = color.g;
2576
- colors32[cindex + 2] = color.b;
2577
- colors32[cindex + 3] = color.a;
2578
- }
2579
- if (this._computeParticleTexture && particle.uv) {
2580
- const uv = particle.uv;
2581
- const uvs32 = this._uvs32;
2582
- uvs32[uindex] = uv.x;
2583
- uvs32[uindex + 1] = uv.y;
2584
- }
2585
- }
2586
- // if the VBO must be updated
2587
- if (mesh) {
2588
- if (update) {
2589
- if (this._computeParticleColor) {
2590
- mesh.updateVerticesData(VertexBuffer.ColorKind, colors32, false, false);
2591
- }
2592
- if (this._computeParticleTexture) {
2593
- mesh.updateVerticesData(VertexBuffer.UVKind, uvs32, false, false);
2594
- }
2595
- mesh.updateVerticesData(VertexBuffer.PositionKind, positions32, false, false);
2596
- }
2597
- if (this._computeBoundingBox) {
2598
- if (mesh.hasBoundingInfo) {
2599
- mesh.getBoundingInfo().reConstruct(minimum, maximum, mesh._worldMatrix);
2600
- }
2601
- else {
2602
- mesh.buildBoundingInfo(minimum, maximum, mesh._worldMatrix);
2603
- }
2604
- }
2605
- }
2606
- this.afterUpdateParticles(start, end, update);
2607
- return this;
2608
- }
2609
- /**
2610
- * Disposes the PCS.
2611
- */
2612
- dispose() {
2613
- this.mesh?.dispose();
2614
- this.vars = null;
2615
- // drop references to internal big arrays for the GC
2616
- this._positions = null;
2617
- this._indices = null;
2618
- this._normals = null;
2619
- this._uvs = null;
2620
- this._colors = null;
2621
- this._indices32 = null;
2622
- this._positions32 = null;
2623
- this._uvs32 = null;
2624
- this._colors32 = null;
2625
- }
2626
- /**
2627
- * Visibility helper : Recomputes the visible size according to the mesh bounding box
2628
- * doc :
2629
- * @returns the PCS.
2630
- */
2631
- refreshVisibleSize() {
2632
- if (!this._isVisibilityBoxLocked) {
2633
- this.mesh?.refreshBoundingInfo();
2634
- }
2635
- return this;
2636
- }
2637
- /**
2638
- * Visibility helper : Sets the size of a visibility box, this sets the underlying mesh bounding box.
2639
- * @param size the size (float) of the visibility box
2640
- * note : this doesn't lock the PCS mesh bounding box.
2641
- * doc :
2642
- */
2643
- setVisibilityBox(size) {
2644
- if (!this.mesh) {
2645
- return;
2646
- }
2647
- const vis = size / 2;
2648
- this.mesh.buildBoundingInfo(new Vector3(-vis, -vis, -vis), new Vector3(vis, vis, vis));
2649
- }
2650
- /**
2651
- * Gets whether the PCS is always visible or not
2652
- * doc :
2653
- */
2654
- get isAlwaysVisible() {
2655
- return this._alwaysVisible;
2656
- }
2657
- /**
2658
- * Sets the PCS as always visible or not
2659
- * doc :
2660
- */
2661
- set isAlwaysVisible(val) {
2662
- if (!this.mesh) {
2663
- return;
2664
- }
2665
- this._alwaysVisible = val;
2666
- this.mesh.alwaysSelectAsActiveMesh = val;
2667
- }
2668
- /**
2669
- * Tells to `setParticles()` to compute the particle rotations or not
2670
- * Default value : false. The PCS is faster when it's set to false
2671
- * Note : particle rotations are only applied to parent particles
2672
- * Note : the particle rotations aren't stored values, so setting `computeParticleRotation` to false will prevents the particle to rotate
2673
- */
2674
- set computeParticleRotation(val) {
2675
- this._computeParticleRotation = val;
2676
- }
2677
- /**
2678
- * Tells to `setParticles()` to compute the particle colors or not.
2679
- * Default value : true. The PCS is faster when it's set to false.
2680
- * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
2681
- */
2682
- set computeParticleColor(val) {
2683
- this._computeParticleColor = val;
2684
- }
2685
- set computeParticleTexture(val) {
2686
- this._computeParticleTexture = val;
2687
- }
2688
- /**
2689
- * Gets if `setParticles()` computes the particle colors or not.
2690
- * Default value : false. The PCS is faster when it's set to false.
2691
- * Note : the particle colors are stored values, so setting `computeParticleColor` to false will keep yet the last colors set.
2692
- */
2693
- get computeParticleColor() {
2694
- return this._computeParticleColor;
2695
- }
2696
- /**
2697
- * Gets if `setParticles()` computes the particle textures or not.
2698
- * Default value : false. The PCS is faster when it's set to false.
2699
- * Note : the particle textures are stored values, so setting `computeParticleTexture` to false will keep yet the last colors set.
2700
- */
2701
- get computeParticleTexture() {
2702
- return this._computeParticleTexture;
2703
- }
2704
- /**
2705
- * Tells to `setParticles()` to compute or not the mesh bounding box when computing the particle positions.
2706
- */
2707
- set computeBoundingBox(val) {
2708
- this._computeBoundingBox = val;
2709
- }
2710
- /**
2711
- * Gets if `setParticles()` computes or not the mesh bounding box when computing the particle positions.
2712
- */
2713
- get computeBoundingBox() {
2714
- return this._computeBoundingBox;
2715
- }
2716
- // =======================================================================
2717
- // Particle behavior logic
2718
- // these following methods may be overwritten by users to fit their needs
2719
- /**
2720
- * This function does nothing. It may be overwritten to set all the particle first values.
2721
- * The PCS doesn't call this function, you may have to call it by your own.
2722
- * doc :
2723
- */
2724
- initParticles() { }
2725
- /**
2726
- * This function does nothing. It may be overwritten to recycle a particle
2727
- * The PCS doesn't call this function, you can to call it
2728
- * doc :
2729
- * @param particle The particle to recycle
2730
- * @returns the recycled particle
2731
- */
2732
- recycleParticle(particle) {
2733
- return particle;
2734
- }
2735
- /**
2736
- * Updates a particle : this function should be overwritten by the user.
2737
- * It is called on each particle by `setParticles()`. This is the place to code each particle behavior.
2738
- * doc :
2739
- * @example : just set a particle position or velocity and recycle conditions
2740
- * @param particle The particle to update
2741
- * @returns the updated particle
2742
- */
2743
- updateParticle(particle) {
2744
- return particle;
2745
- }
2746
- /**
2747
- * This will be called before any other treatment by `setParticles()` and will be passed three parameters.
2748
- * This does nothing and may be overwritten by the user.
2749
- * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()
2750
- * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
2751
- * @param update the boolean update value actually passed to setParticles()
2752
- */
2753
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2754
- beforeUpdateParticles(start, stop, update) { }
2755
- /**
2756
- * This will be called by `setParticles()` after all the other treatments and just before the actual mesh update.
2757
- * This will be passed three parameters.
2758
- * This does nothing and may be overwritten by the user.
2759
- * @param start the particle index in the particle array where to start to iterate, same than the value passed to setParticle()
2760
- * @param stop the particle index in the particle array where to stop to iterate, same than the value passed to setParticle()
2761
- * @param update the boolean update value actually passed to setParticles()
2762
- */
2763
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2764
- afterUpdateParticles(start, stop, update) { }
2765
- }
2766
-
2767
- /**
2768
- * Indicator of the parsed ply buffer. A standard ready to use splat or an array of positions for a point cloud
2769
- */
2770
- var Mode;
2771
- (function (Mode) {
2772
- Mode[Mode["Splat"] = 0] = "Splat";
2773
- Mode[Mode["PointCloud"] = 1] = "PointCloud";
2774
- Mode[Mode["Mesh"] = 2] = "Mesh";
2775
- })(Mode || (Mode = {}));
2776
- /**
2777
- * @experimental
2778
- * SPLAT file type loader.
2779
- * This is a babylon scene loader plugin.
2780
- */
2781
- class SPLATFileLoader {
2782
- /**
2783
- * Creates loader for gaussian splatting files
2784
- * @param loadingOptions options for loading and parsing splat and PLY files.
2785
- */
2786
- constructor(loadingOptions = SPLATFileLoader._DefaultLoadingOptions) {
2787
- /**
2788
- * Defines the name of the plugin.
2789
- */
2790
- this.name = SPLATFileLoaderMetadata.name;
2791
- this._assetContainer = null;
2792
- /**
2793
- * Defines the extensions the splat loader is able to load.
2794
- * force data to come in as an ArrayBuffer
2795
- */
2796
- this.extensions = SPLATFileLoaderMetadata.extensions;
2797
- this._loadingOptions = loadingOptions;
2798
- }
2799
- /** @internal */
2800
- createPlugin(options) {
2801
- return new SPLATFileLoader(options[SPLATFileLoaderMetadata.name]);
2802
- }
2803
- /**
2804
- * Imports from the loaded gaussian splatting data and adds them to the scene
2805
- * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
2806
- * @param scene the scene the meshes should be added to
2807
- * @param data the gaussian splatting data to load
2808
- * @param rootUrl root url to load from
2809
- * @param onProgress callback called while file is loading
2810
- * @param fileName Defines the name of the file to load
2811
- * @returns a promise containing the loaded meshes, particles, skeletons and animations
2812
- */
2813
- async importMeshAsync(meshesNames, scene, data, rootUrl, onProgress, fileName) {
2814
- return this._parse(meshesNames, scene, data, rootUrl).then((meshes) => {
2815
- return {
2816
- meshes: meshes,
2817
- particleSystems: [],
2818
- skeletons: [],
2819
- animationGroups: [],
2820
- transformNodes: [],
2821
- geometries: [],
2822
- lights: [],
2823
- spriteManagers: [],
2824
- };
2825
- });
2826
- }
2827
- static _BuildPointCloud(pointcloud, data) {
2828
- if (!data.byteLength) {
2829
- return false;
2830
- }
2831
- const uBuffer = new Uint8Array(data);
2832
- const fBuffer = new Float32Array(data);
2833
- // parsed array contains room for position(3floats), normal(3floats), color (4b), quantized quaternion (4b)
2834
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
2835
- const vertexCount = uBuffer.length / rowLength;
2836
- const pointcloudfunc = function (particle, i) {
2837
- const x = fBuffer[8 * i + 0];
2838
- const y = fBuffer[8 * i + 1];
2839
- const z = fBuffer[8 * i + 2];
2840
- particle.position = new Vector3(x, y, z);
2841
- const r = uBuffer[rowLength * i + 24 + 0] / 255;
2842
- const g = uBuffer[rowLength * i + 24 + 1] / 255;
2843
- const b = uBuffer[rowLength * i + 24 + 2] / 255;
2844
- particle.color = new Color4(r, g, b, 1);
2845
- };
2846
- pointcloud.addPoints(vertexCount, pointcloudfunc);
2847
- return true;
2848
- }
2849
- static _BuildMesh(scene, parsedPLY) {
2850
- const mesh = new Mesh("PLYMesh", scene);
2851
- const uBuffer = new Uint8Array(parsedPLY.data);
2852
- const fBuffer = new Float32Array(parsedPLY.data);
2853
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
2854
- const vertexCount = uBuffer.length / rowLength;
2855
- const positions = [];
2856
- const vertexData = new VertexData();
2857
- for (let i = 0; i < vertexCount; i++) {
2858
- const x = fBuffer[8 * i + 0];
2859
- const y = fBuffer[8 * i + 1];
2860
- const z = fBuffer[8 * i + 2];
2861
- positions.push(x, y, z);
2862
- }
2863
- if (parsedPLY.hasVertexColors) {
2864
- const colors = new Float32Array(vertexCount * 4);
2865
- for (let i = 0; i < vertexCount; i++) {
2866
- const r = uBuffer[rowLength * i + 24 + 0] / 255;
2867
- const g = uBuffer[rowLength * i + 24 + 1] / 255;
2868
- const b = uBuffer[rowLength * i + 24 + 2] / 255;
2869
- colors[i * 4 + 0] = r;
2870
- colors[i * 4 + 1] = g;
2871
- colors[i * 4 + 2] = b;
2872
- colors[i * 4 + 3] = 1;
2873
- }
2874
- vertexData.colors = colors;
2875
- }
2876
- vertexData.positions = positions;
2877
- vertexData.indices = parsedPLY.faces;
2878
- vertexData.applyToMesh(mesh);
2879
- return mesh;
2880
- }
2881
- _parse(meshesNames, scene, data, rootUrl) {
2882
- const babylonMeshesArray = []; //The mesh for babylon
2883
- const parsedPLY = SPLATFileLoader._ConvertPLYToSplat(data);
2884
- switch (parsedPLY.mode) {
2885
- case 0 /* Mode.Splat */:
2886
- {
2887
- const gaussianSplatting = new GaussianSplattingMesh("GaussianSplatting", null, scene, this._loadingOptions.keepInRam);
2888
- gaussianSplatting._parentContainer = this._assetContainer;
2889
- babylonMeshesArray.push(gaussianSplatting);
2890
- gaussianSplatting.loadDataAsync(parsedPLY.data);
2891
- }
2892
- break;
2893
- case 1 /* Mode.PointCloud */:
2894
- {
2895
- const pointcloud = new PointsCloudSystem("PointCloud", 1, scene);
2896
- if (SPLATFileLoader._BuildPointCloud(pointcloud, parsedPLY.data)) {
2897
- return Promise.all([pointcloud.buildMeshAsync()]).then((mesh) => {
2898
- babylonMeshesArray.push(mesh[0]);
2899
- return babylonMeshesArray;
2900
- });
2901
- }
2902
- else {
2903
- pointcloud.dispose();
2904
- }
2905
- }
2906
- break;
2907
- case 2 /* Mode.Mesh */:
2908
- {
2909
- if (parsedPLY.faces) {
2910
- babylonMeshesArray.push(SPLATFileLoader._BuildMesh(scene, parsedPLY));
2911
- }
2912
- else {
2913
- throw new Error("PLY mesh doesn't contain face informations.");
2914
- }
2915
- }
2916
- break;
2917
- default:
2918
- throw new Error("Unsupported Splat mode");
2919
- }
2920
- return Promise.resolve(babylonMeshesArray);
2921
- }
2922
- /**
2923
- * Load into an asset container.
2924
- * @param scene The scene to load into
2925
- * @param data The data to import
2926
- * @param rootUrl The root url for scene and resources
2927
- * @returns The loaded asset container
2928
- */
2929
- loadAssetContainerAsync(scene, data, rootUrl) {
2930
- const container = new AssetContainer(scene);
2931
- this._assetContainer = container;
2932
- return this.importMeshAsync(null, scene, data, rootUrl)
2933
- .then((result) => {
2934
- result.meshes.forEach((mesh) => container.meshes.push(mesh));
2935
- // mesh material will be null before 1st rendered frame.
2936
- this._assetContainer = null;
2937
- return container;
2938
- })
2939
- .catch((ex) => {
2940
- this._assetContainer = null;
2941
- throw ex;
2942
- });
2943
- }
2944
- /**
2945
- * Imports all objects from the loaded OBJ data and adds them to the scene
2946
- * @param scene the scene the objects should be added to
2947
- * @param data the OBJ data to load
2948
- * @param rootUrl root url to load from
2949
- * @returns a promise which completes when objects have been loaded to the scene
2950
- */
2951
- loadAsync(scene, data, rootUrl) {
2952
- //Get the 3D model
2953
- return this.importMeshAsync(null, scene, data, rootUrl).then(() => {
2954
- // return void
2955
- });
2956
- }
2957
- /**
2958
- * Code from https://github.com/dylanebert/gsplat.js/blob/main/src/loaders/PLYLoader.ts Under MIT license
2959
- * Converts a .ply data array buffer to splat
2960
- * if data array buffer is not ply, returns the original buffer
2961
- * @param data the .ply data to load
2962
- * @returns the loaded splat buffer
2963
- */
2964
- static _ConvertPLYToSplat(data) {
2965
- const ubuf = new Uint8Array(data);
2966
- const header = new TextDecoder().decode(ubuf.slice(0, 1024 * 10));
2967
- const headerEnd = "end_header\n";
2968
- const headerEndIndex = header.indexOf(headerEnd);
2969
- if (headerEndIndex < 0 || !header) {
2970
- // standard splat
2971
- return { mode: 0 /* Mode.Splat */, data: data };
2972
- }
2973
- const vertexCount = parseInt(/element vertex (\d+)\n/.exec(header)[1]);
2974
- const faceElement = /element face (\d+)\n/.exec(header);
2975
- let faceCount = 0;
2976
- if (faceElement) {
2977
- faceCount = parseInt(faceElement[1]);
2978
- }
2979
- let rowOffset = 0;
2980
- const offsets = {
2981
- double: 8,
2982
- int: 4,
2983
- uint: 4,
2984
- float: 4,
2985
- short: 2,
2986
- ushort: 2,
2987
- uchar: 1,
2988
- list: 0,
2989
- };
2990
- const properties = [];
2991
- const filtered = header
2992
- .slice(0, headerEndIndex)
2993
- .split("\n")
2994
- .filter((k) => k.startsWith("property "));
2995
- for (const prop of filtered) {
2996
- const [, type, name] = prop.split(" ");
2997
- properties.push({ name, type, offset: rowOffset });
2998
- if (offsets[type]) {
2999
- rowOffset += offsets[type];
3000
- }
3001
- else {
3002
- Logger.Warn(`Unsupported property type: ${type}.`);
3003
- }
3004
- }
3005
- const rowLength = 3 * 4 + 3 * 4 + 4 + 4;
3006
- const SH_C0 = 0.28209479177387814;
3007
- const dataView = new DataView(data, headerEndIndex + headerEnd.length);
3008
- const buffer = new ArrayBuffer(rowLength * vertexCount);
3009
- const q = new Quaternion();
3010
- for (let i = 0; i < vertexCount; i++) {
3011
- const position = new Float32Array(buffer, i * rowLength, 3);
3012
- const scale = new Float32Array(buffer, i * rowLength + 12, 3);
3013
- const rgba = new Uint8ClampedArray(buffer, i * rowLength + 24, 4);
3014
- const rot = new Uint8ClampedArray(buffer, i * rowLength + 28, 4);
3015
- let r0 = 255;
3016
- let r1 = 0;
3017
- let r2 = 0;
3018
- let r3 = 0;
3019
- for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {
3020
- const property = properties[propertyIndex];
3021
- let value;
3022
- switch (property.type) {
3023
- case "float":
3024
- value = dataView.getFloat32(property.offset + i * rowOffset, true);
3025
- break;
3026
- case "int":
3027
- value = dataView.getInt32(property.offset + i * rowOffset, true);
3028
- break;
3029
- case "uint":
3030
- value = dataView.getUint32(property.offset + i * rowOffset, true);
3031
- break;
3032
- case "double":
3033
- value = dataView.getFloat64(property.offset + i * rowOffset, true);
3034
- break;
3035
- case "uchar":
3036
- value = dataView.getUint8(property.offset + i * rowOffset);
3037
- break;
3038
- default:
3039
- //throw new Error(`Unsupported property type: ${property.type}`);
3040
- continue;
3041
- }
3042
- switch (property.name) {
3043
- case "x":
3044
- position[0] = value;
3045
- break;
3046
- case "y":
3047
- position[1] = value;
3048
- break;
3049
- case "z":
3050
- position[2] = value;
3051
- break;
3052
- case "scale_0":
3053
- scale[0] = Math.exp(value);
3054
- break;
3055
- case "scale_1":
3056
- scale[1] = Math.exp(value);
3057
- break;
3058
- case "scale_2":
3059
- scale[2] = Math.exp(value);
3060
- break;
3061
- case "diffuse_red":
3062
- case "red":
3063
- rgba[0] = value;
3064
- break;
3065
- case "diffuse_green":
3066
- case "green":
3067
- rgba[1] = value;
3068
- break;
3069
- case "diffuse_blue":
3070
- case "blue":
3071
- rgba[2] = value;
3072
- break;
3073
- case "f_dc_0":
3074
- rgba[0] = (0.5 + SH_C0 * value) * 255;
3075
- break;
3076
- case "f_dc_1":
3077
- rgba[1] = (0.5 + SH_C0 * value) * 255;
3078
- break;
3079
- case "f_dc_2":
3080
- rgba[2] = (0.5 + SH_C0 * value) * 255;
3081
- break;
3082
- case "f_dc_3":
3083
- rgba[3] = (0.5 + SH_C0 * value) * 255;
3084
- break;
3085
- case "opacity":
3086
- rgba[3] = (1 / (1 + Math.exp(-value))) * 255;
3087
- break;
3088
- case "rot_0":
3089
- r0 = value;
3090
- break;
3091
- case "rot_1":
3092
- r1 = value;
3093
- break;
3094
- case "rot_2":
3095
- r2 = value;
3096
- break;
3097
- case "rot_3":
3098
- r3 = value;
3099
- break;
3100
- }
3101
- }
3102
- q.set(r1, r2, r3, r0);
3103
- q.normalize();
3104
- rot[0] = q.w * 128 + 128;
3105
- rot[1] = q.x * 128 + 128;
3106
- rot[2] = q.y * 128 + 128;
3107
- rot[3] = q.z * 128 + 128;
3108
- }
3109
- // faces
3110
- const faces = [];
3111
- if (faceCount) {
3112
- let offset = rowOffset * vertexCount;
3113
- for (let i = 0; i < faceCount; i++) {
3114
- const faceVertexCount = dataView.getUint8(offset);
3115
- if (faceVertexCount != 3) {
3116
- continue; // only support triangles
3117
- }
3118
- offset += 1;
3119
- for (let j = 0; j < faceVertexCount; j++) {
3120
- const vertexIndex = dataView.getUint32(offset + (2 - j) * 4, true); // change face winding
3121
- faces.push(vertexIndex);
3122
- }
3123
- offset += 12;
3124
- }
3125
- }
3126
- // count available properties. if all necessary are present then it's a splat. Otherwise, it's a point cloud
3127
- // if faces are found, then it's a standard mesh
3128
- let propertyCount = 0;
3129
- let propertyColorCount = 0;
3130
- const splatProperties = ["x", "y", "z", "scale_0", "scale_1", "scale_2", "opacity", "rot_0", "rot_1", "rot_2", "rot_3"];
3131
- const splatColorProperties = ["red", "green", "blue", "f_dc_0", "f_dc_1", "f_dc_2"];
3132
- for (let propertyIndex = 0; propertyIndex < properties.length; propertyIndex++) {
3133
- const property = properties[propertyIndex];
3134
- if (splatProperties.includes(property.name)) {
3135
- propertyCount++;
3136
- }
3137
- if (splatColorProperties.includes(property.name)) {
3138
- propertyColorCount++;
3139
- }
3140
- }
3141
- const hasMandatoryProperties = propertyCount == splatProperties.length && propertyColorCount == 3;
3142
- const currentMode = faceCount ? 2 /* Mode.Mesh */ : hasMandatoryProperties ? 0 /* Mode.Splat */ : 1 /* Mode.PointCloud */;
3143
- // parsed ready ready to be used as a splat
3144
- return { mode: currentMode, data: buffer, faces: faces, hasVertexColors: !!propertyColorCount };
3145
- }
3146
- }
3147
- SPLATFileLoader._DefaultLoadingOptions = {
3148
- keepInRam: false,
3149
- };
3150
- // Add this loader into the register plugin
3151
- registerSceneLoaderPlugin(new SPLATFileLoader());
3152
-
3153
- export { SPLATFileLoader };
3154
- //# sourceMappingURL=splatFileLoader-hdSfXVdE.esm.js.map