angular-three-soba 1.14.0 → 2.0.0-beta.3

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 (343) hide show
  1. package/README.md +2 -2
  2. package/abstractions/{lib/billboard → billboard}/billboard.d.ts +14 -4
  3. package/abstractions/catmull-rom-line/catmull-rom-line.d.ts +25 -0
  4. package/abstractions/cubic-bezier-line/cubic-bezier-line.d.ts +25 -0
  5. package/abstractions/{lib/edges → edges}/edges.d.ts +11 -7
  6. package/abstractions/{lib/gizmo-helper → gizmo-helper}/gizmo-helper.d.ts +16 -23
  7. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.d.ts +22 -0
  8. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.d.ts +30 -0
  9. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.d.ts +32 -0
  10. package/abstractions/{lib/gizmo-helper → gizmo-helper}/gizmo-viewcube/gizmo-viewcube.d.ts +2 -3
  11. package/abstractions/{lib/gizmo-helper → gizmo-helper}/gizmo-viewport/gizmo-viewport-axis.d.ts +28 -9
  12. package/abstractions/{lib/gizmo-helper → gizmo-helper}/gizmo-viewport/gizmo-viewport.d.ts +23 -4
  13. package/abstractions/index.d.ts +11 -11
  14. package/abstractions/line/line-input.d.ts +42 -0
  15. package/abstractions/line/line.d.ts +35 -0
  16. package/abstractions/{lib/quadratic-bezier-line → quadratic-bezier-line}/quadratic-bezier-line.d.ts +12 -8
  17. package/abstractions/text/text.d.ts +77 -0
  18. package/abstractions/text-3d/text-3d.d.ts +74 -0
  19. package/cameras/{lib/camera → camera}/camera-content.d.ts +1 -1
  20. package/cameras/{lib/camera → camera}/camera.d.ts +12 -8
  21. package/cameras/cube-camera/cube-camera.d.ts +42 -0
  22. package/cameras/index.d.ts +5 -4
  23. package/cameras/{lib/orthographic-camera → orthographic-camera}/orthographic-camera.d.ts +14 -5
  24. package/controls/index.d.ts +1 -1
  25. package/controls/{lib/orbit-controls → orbit-controls}/orbit-controls.d.ts +19 -11
  26. package/esm2022/abstractions/angular-three-soba-abstractions.mjs +1 -1
  27. package/esm2022/abstractions/billboard/billboard.mjs +71 -0
  28. package/esm2022/abstractions/catmull-rom-line/catmull-rom-line.mjs +131 -0
  29. package/esm2022/abstractions/cubic-bezier-line/cubic-bezier-line.mjs +113 -0
  30. package/esm2022/abstractions/edges/edges.mjs +93 -0
  31. package/esm2022/abstractions/gizmo-helper/gizmo-helper.mjs +210 -0
  32. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/constants.mjs +31 -0
  33. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.mjs +95 -0
  34. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.mjs +155 -0
  35. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.mjs +62 -0
  36. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube.mjs +80 -0
  37. package/esm2022/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.mjs +206 -0
  38. package/esm2022/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport.mjs +273 -0
  39. package/esm2022/abstractions/index.mjs +12 -12
  40. package/esm2022/abstractions/line/line-input.mjs +113 -0
  41. package/esm2022/abstractions/line/line.mjs +165 -0
  42. package/esm2022/abstractions/quadratic-bezier-line/quadratic-bezier-line.mjs +128 -0
  43. package/esm2022/abstractions/text/text.mjs +275 -0
  44. package/esm2022/abstractions/text-3d/text-3d.mjs +167 -0
  45. package/esm2022/angular-three-soba.mjs +1 -1
  46. package/esm2022/cameras/angular-three-soba-cameras.mjs +1 -1
  47. package/esm2022/cameras/camera/camera-content.mjs +21 -0
  48. package/esm2022/cameras/camera/camera.mjs +71 -0
  49. package/esm2022/cameras/cube-camera/cube-camera.mjs +131 -0
  50. package/esm2022/cameras/index.mjs +6 -5
  51. package/esm2022/cameras/orthographic-camera/orthographic-camera.mjs +99 -0
  52. package/esm2022/cameras/perspective-camera/perspective-camera.mjs +47 -0
  53. package/esm2022/controls/angular-three-soba-controls.mjs +1 -1
  54. package/esm2022/controls/index.mjs +2 -2
  55. package/esm2022/controls/orbit-controls/orbit-controls.mjs +165 -0
  56. package/esm2022/index.mjs +1 -1
  57. package/esm2022/loaders/angular-three-soba-loaders.mjs +1 -1
  58. package/esm2022/loaders/gltf-loader/gltf-loader.mjs +33 -0
  59. package/esm2022/loaders/index.mjs +5 -6
  60. package/esm2022/loaders/loader/loader.mjs +133 -0
  61. package/esm2022/loaders/progress/progress.mjs +52 -0
  62. package/esm2022/loaders/texture-loader/texture-loader.mjs +28 -0
  63. package/esm2022/materials/angular-three-soba-materials.mjs +1 -1
  64. package/esm2022/materials/index.mjs +6 -6
  65. package/esm2022/materials/mesh-distort-material/mesh-distort-material.mjs +73 -0
  66. package/esm2022/materials/mesh-reflector-material/mesh-reflector-material.mjs +383 -0
  67. package/esm2022/materials/mesh-refraction-material/mesh-refraction-material.mjs +168 -0
  68. package/esm2022/materials/mesh-transmission-material/mesh-transmission-material.mjs +257 -0
  69. package/esm2022/materials/mesh-wobble-material/mesh-wobble-material.mjs +66 -0
  70. package/esm2022/misc/angular-three-soba-misc.mjs +1 -1
  71. package/esm2022/misc/animations/animations.mjs +55 -0
  72. package/esm2022/misc/bake-shadows/bake-shadows.mjs +24 -0
  73. package/esm2022/misc/depth-buffer/depth-buffer.mjs +46 -0
  74. package/esm2022/misc/fbo/fbo.mjs +47 -0
  75. package/esm2022/misc/index.mjs +5 -5
  76. package/esm2022/performance/adaptive/adaptive-dpr.mjs +46 -0
  77. package/esm2022/performance/adaptive/adaptive-events.mjs +31 -0
  78. package/esm2022/performance/angular-three-soba-performance.mjs +1 -1
  79. package/esm2022/performance/detailed/detailed.mjs +61 -0
  80. package/esm2022/performance/index.mjs +7 -5
  81. package/esm2022/performance/instances/instance.mjs +48 -0
  82. package/esm2022/performance/instances/instances.mjs +189 -0
  83. package/esm2022/performance/instances/position-mesh.mjs +52 -0
  84. package/esm2022/performance/stats/stats.mjs +79 -0
  85. package/esm2022/shaders/angular-three-soba-shaders.mjs +1 -1
  86. package/esm2022/shaders/blur-pass/blur-pass.mjs +61 -0
  87. package/esm2022/shaders/caustics-material/caustics-material.mjs +128 -0
  88. package/esm2022/shaders/caustics-material/caustics-projection-material.mjs +33 -0
  89. package/esm2022/shaders/convolution-material/convolution-material.mjs +94 -0
  90. package/esm2022/shaders/discard-material/discard-material.mjs +3 -0
  91. package/esm2022/shaders/index.mjs +15 -15
  92. package/esm2022/shaders/mesh-distort-material/mesh-distort-material.mjs +55 -0
  93. package/esm2022/shaders/mesh-reflector-material/mesh-reflector-material.mjs +223 -0
  94. package/esm2022/shaders/mesh-refraction-material/mesh-refraction-material.mjs +170 -0
  95. package/esm2022/shaders/mesh-transmission-material/mesh-transmission-material.mjs +268 -0
  96. package/esm2022/shaders/mesh-wobble-material/mesh-wobble-material.mjs +37 -0
  97. package/esm2022/shaders/shader-material/shader-material.mjs +34 -0
  98. package/esm2022/shaders/soft-shadow-material/soft-shadow-material.mjs +33 -0
  99. package/esm2022/shaders/sparkles-material/sparkles-material.mjs +47 -0
  100. package/esm2022/shaders/spot-light-material/spot-light-material.mjs +86 -0
  101. package/esm2022/shaders/star-field-material/star-field-material.mjs +32 -0
  102. package/esm2022/staging/accumulative-shadows/accumulative-shadows.mjs +283 -0
  103. package/esm2022/staging/accumulative-shadows/progressive-light-map.mjs +108 -0
  104. package/esm2022/staging/accumulative-shadows/randomized-lights.mjs +208 -0
  105. package/esm2022/staging/angular-three-soba-staging.mjs +1 -1
  106. package/esm2022/staging/bounds/bounds.mjs +307 -0
  107. package/esm2022/staging/camera-shake/camera-shake.mjs +117 -0
  108. package/esm2022/staging/caustics/caustisc.mjs +384 -0
  109. package/esm2022/staging/center/center.mjs +148 -0
  110. package/esm2022/staging/cloud/cloud.mjs +164 -0
  111. package/esm2022/staging/contact-shadows/contact-shadows.mjs +249 -0
  112. package/esm2022/staging/environment/assets.mjs +13 -0
  113. package/esm2022/staging/environment/environment-cube.mjs +49 -0
  114. package/esm2022/staging/environment/environment-ground.mjs +43 -0
  115. package/esm2022/staging/environment/environment-input.mjs +106 -0
  116. package/esm2022/staging/environment/environment-map.mjs +53 -0
  117. package/esm2022/staging/environment/environment-portal.mjs +135 -0
  118. package/esm2022/staging/environment/environment.mjs +78 -0
  119. package/esm2022/staging/environment/utils.mjs +84 -0
  120. package/esm2022/staging/float/float.mjs +82 -0
  121. package/esm2022/staging/index.mjs +18 -18
  122. package/esm2022/staging/sky/sky.mjs +114 -0
  123. package/esm2022/staging/sparkles/sparkles.mjs +161 -0
  124. package/esm2022/staging/spot-light/spot-light-input.mjs +75 -0
  125. package/esm2022/staging/spot-light/spot-light-shadow-mesh-input.mjs +57 -0
  126. package/esm2022/staging/spot-light/spot-light-shadow-mesh.mjs +256 -0
  127. package/esm2022/staging/spot-light/spot-light.mjs +94 -0
  128. package/esm2022/staging/spot-light/volumetric-mesh.mjs +101 -0
  129. package/esm2022/staging/stage/stage.mjs +374 -0
  130. package/esm2022/staging/stars/stars.mjs +148 -0
  131. package/fesm2022/angular-three-soba-abstractions.mjs +1116 -890
  132. package/fesm2022/angular-three-soba-abstractions.mjs.map +1 -1
  133. package/fesm2022/angular-three-soba-cameras.mjs +126 -122
  134. package/fesm2022/angular-three-soba-cameras.mjs.map +1 -1
  135. package/fesm2022/angular-three-soba-controls.mjs +72 -54
  136. package/fesm2022/angular-three-soba-controls.mjs.map +1 -1
  137. package/fesm2022/angular-three-soba-loaders.mjs +147 -131
  138. package/fesm2022/angular-three-soba-loaders.mjs.map +1 -1
  139. package/fesm2022/angular-three-soba-materials.mjs +340 -258
  140. package/fesm2022/angular-three-soba-materials.mjs.map +1 -1
  141. package/fesm2022/angular-three-soba-misc.mjs +140 -123
  142. package/fesm2022/angular-three-soba-misc.mjs.map +1 -1
  143. package/fesm2022/angular-three-soba-performance.mjs +383 -106
  144. package/fesm2022/angular-three-soba-performance.mjs.map +1 -1
  145. package/fesm2022/angular-three-soba-shaders.mjs +57 -9
  146. package/fesm2022/angular-three-soba-shaders.mjs.map +1 -1
  147. package/fesm2022/angular-three-soba-staging.mjs +1609 -1561
  148. package/fesm2022/angular-three-soba-staging.mjs.map +1 -1
  149. package/fesm2022/angular-three-soba.mjs.map +1 -1
  150. package/loaders/gltf-loader/gltf-loader.d.ts +9 -0
  151. package/loaders/index.d.ts +4 -5
  152. package/loaders/{lib/loader → loader}/loader.d.ts +20 -15
  153. package/loaders/progress/progress.d.ts +9 -0
  154. package/loaders/texture-loader/texture-loader.d.ts +7 -0
  155. package/materials/index.d.ts +5 -5
  156. package/materials/{lib/mesh-distort-material → mesh-distort-material}/mesh-distort-material.d.ts +11 -5
  157. package/materials/mesh-reflector-material/mesh-reflector-material.d.ts +81 -0
  158. package/materials/mesh-refraction-material/mesh-refraction-material.d.ts +50 -0
  159. package/materials/{lib/mesh-transmission-material → mesh-transmission-material}/mesh-transmission-material.d.ts +51 -6
  160. package/materials/{lib/mesh-wobble-material → mesh-wobble-material}/mesh-wobble-material.d.ts +9 -3
  161. package/misc/animations/animations.d.ts +13 -0
  162. package/misc/{lib/bake-shadows → bake-shadows}/bake-shadows.d.ts +2 -5
  163. package/misc/depth-buffer/depth-buffer.d.ts +9 -0
  164. package/misc/{lib/fbo → fbo}/fbo.d.ts +4 -2
  165. package/misc/index.d.ts +4 -4
  166. package/package.json +25 -23
  167. package/performance/{lib/adaptive → adaptive}/adaptive-dpr.d.ts +4 -7
  168. package/performance/{lib/adaptive → adaptive}/adaptive-events.d.ts +2 -6
  169. package/performance/detailed/detailed.d.ts +20 -0
  170. package/performance/index.d.ts +6 -4
  171. package/performance/instances/instance.d.ts +9 -0
  172. package/performance/instances/instances.d.ts +35 -0
  173. package/performance/instances/position-mesh.d.ts +10 -0
  174. package/performance/{lib/stats → stats}/stats.d.ts +10 -7
  175. package/plugin/package.json +1 -1
  176. package/plugin/src/generators/init/compat.js.map +1 -1
  177. package/plugin/src/generators/init/init.d.ts +1 -1
  178. package/plugin/src/generators/init/init.js +1 -1
  179. package/plugin/src/generators/init/init.js.map +1 -1
  180. package/plugin/src/index.js.map +1 -1
  181. package/shaders/{lib/blur-pass → blur-pass}/blur-pass.d.ts +2 -2
  182. package/shaders/index.d.ts +14 -14
  183. package/shaders/{lib/mesh-distort-material → mesh-distort-material}/mesh-distort-material.d.ts +1 -1
  184. package/shaders/{lib/mesh-wobble-material → mesh-wobble-material}/mesh-wobble-material.d.ts +1 -0
  185. package/shaders/{lib/soft-shadow-material → soft-shadow-material}/soft-shadow-material.d.ts +2 -2
  186. package/shaders/sparkles-material/sparkles-material.d.ts +3 -0
  187. package/staging/{lib/accumulative-shadows → accumulative-shadows}/accumulative-shadows.d.ts +55 -17
  188. package/staging/{lib/accumulative-shadows → accumulative-shadows}/progressive-light-map.d.ts +2 -2
  189. package/staging/{lib/accumulative-shadows → accumulative-shadows}/randomized-lights.d.ts +45 -10
  190. package/staging/{lib/bounds → bounds}/bounds.d.ts +32 -22
  191. package/staging/{lib/camera-shake → camera-shake}/camera-shake.d.ts +15 -11
  192. package/staging/{lib/caustics/caustics.d.ts → caustics/caustisc.d.ts} +36 -13
  193. package/staging/{lib/center → center}/center.d.ts +30 -8
  194. package/staging/cloud/cloud.d.ts +48 -0
  195. package/staging/{lib/contact-shadows → contact-shadows}/contact-shadows.d.ts +38 -10
  196. package/staging/environment/environment-cube.d.ts +11 -0
  197. package/staging/environment/environment-ground.d.ts +13 -0
  198. package/staging/environment/environment-input.d.ts +68 -0
  199. package/staging/environment/environment-map.d.ts +11 -0
  200. package/staging/{lib/environment → environment}/environment-portal.d.ts +5 -7
  201. package/staging/{lib/environment → environment}/environment.d.ts +2 -2
  202. package/staging/environment/utils.d.ts +7 -0
  203. package/staging/float/float.d.ts +27 -0
  204. package/staging/index.d.ts +17 -17
  205. package/staging/{lib/sky → sky}/sky.d.ts +26 -5
  206. package/staging/{lib/sparkles → sparkles}/sparkles.d.ts +30 -10
  207. package/staging/{lib/spot-light → spot-light}/spot-light-input.d.ts +24 -2
  208. package/staging/{lib/spot-light/shadow-mesh-input.d.ts → spot-light/spot-light-shadow-mesh-input.d.ts} +18 -3
  209. package/staging/spot-light/spot-light-shadow-mesh.d.ts +38 -0
  210. package/staging/{lib/spot-light → spot-light}/spot-light.d.ts +11 -5
  211. package/staging/{lib/spot-light → spot-light}/volumetric-mesh.d.ts +8 -5
  212. package/staging/{lib/stage → stage}/stage.d.ts +33 -14
  213. package/staging/{lib/stars → stars}/stars.d.ts +21 -7
  214. package/abstractions/lib/catmull-rom-line/catmull-rom-line.d.ts +0 -15
  215. package/abstractions/lib/cubic-bezier-line/cubic-bezier-line.d.ts +0 -15
  216. package/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.d.ts +0 -16
  217. package/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.d.ts +0 -24
  218. package/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.d.ts +0 -14
  219. package/abstractions/lib/line/line-input.d.ts +0 -19
  220. package/abstractions/lib/line/line.d.ts +0 -21
  221. package/abstractions/lib/text/text.d.ts +0 -21
  222. package/abstractions/lib/text-3d/text-3d.d.ts +0 -39
  223. package/assets/default-spot-light-shadow.glsl +0 -10
  224. package/cameras/lib/cube-camera/cube-camera.d.ts +0 -27
  225. package/esm2022/abstractions/lib/billboard/billboard.mjs +0 -74
  226. package/esm2022/abstractions/lib/catmull-rom-line/catmull-rom-line.mjs +0 -120
  227. package/esm2022/abstractions/lib/cubic-bezier-line/cubic-bezier-line.mjs +0 -99
  228. package/esm2022/abstractions/lib/edges/edges.mjs +0 -96
  229. package/esm2022/abstractions/lib/gizmo-helper/gizmo-helper.mjs +0 -213
  230. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewcube/constants.mjs +0 -31
  231. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.mjs +0 -92
  232. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.mjs +0 -184
  233. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.mjs +0 -46
  234. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewcube/gizmo-viewcube.mjs +0 -134
  235. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.mjs +0 -195
  236. package/esm2022/abstractions/lib/gizmo-helper/gizmo-viewport/gizmo-viewport.mjs +0 -267
  237. package/esm2022/abstractions/lib/line/line-input.mjs +0 -76
  238. package/esm2022/abstractions/lib/line/line.mjs +0 -133
  239. package/esm2022/abstractions/lib/quadratic-bezier-line/quadratic-bezier-line.mjs +0 -128
  240. package/esm2022/abstractions/lib/text/text.mjs +0 -115
  241. package/esm2022/abstractions/lib/text-3d/text-3d.mjs +0 -145
  242. package/esm2022/cameras/lib/camera/camera-content.mjs +0 -21
  243. package/esm2022/cameras/lib/camera/camera.mjs +0 -75
  244. package/esm2022/cameras/lib/cube-camera/cube-camera.mjs +0 -131
  245. package/esm2022/cameras/lib/orthographic-camera/orthographic-camera.mjs +0 -93
  246. package/esm2022/cameras/lib/perspective-camera/perspective-camera.mjs +0 -47
  247. package/esm2022/controls/lib/orbit-controls/orbit-controls.mjs +0 -147
  248. package/esm2022/loaders/lib/cube-texture-loader/cube-texture-loader.mjs +0 -10
  249. package/esm2022/loaders/lib/gltf-loader/gltf-loader.mjs +0 -32
  250. package/esm2022/loaders/lib/loader/loader.mjs +0 -134
  251. package/esm2022/loaders/lib/progress/progress.mjs +0 -39
  252. package/esm2022/loaders/lib/texture-loader/texture-loader.mjs +0 -19
  253. package/esm2022/materials/lib/mesh-distort-material/mesh-distort-material.mjs +0 -75
  254. package/esm2022/materials/lib/mesh-reflector-material/mesh-reflector-material.mjs +0 -328
  255. package/esm2022/materials/lib/mesh-refraction-material/mesh-refraction-material.mjs +0 -158
  256. package/esm2022/materials/lib/mesh-transmission-material/mesh-transmission-material.mjs +0 -238
  257. package/esm2022/materials/lib/mesh-wobble-material/mesh-wobble-material.mjs +0 -68
  258. package/esm2022/misc/lib/animations/animations.mjs +0 -52
  259. package/esm2022/misc/lib/bake-shadows/bake-shadows.mjs +0 -26
  260. package/esm2022/misc/lib/depth-buffer/depth-buffer.mjs +0 -39
  261. package/esm2022/misc/lib/fbo/fbo.mjs +0 -39
  262. package/esm2022/performance/lib/adaptive/adaptive-dpr.mjs +0 -47
  263. package/esm2022/performance/lib/adaptive/adaptive-events.mjs +0 -37
  264. package/esm2022/performance/lib/detailed/detailed.mjs +0 -54
  265. package/esm2022/performance/lib/stats/stats.mjs +0 -80
  266. package/esm2022/shaders/lib/blur-pass/blur-pass.mjs +0 -61
  267. package/esm2022/shaders/lib/caustics-material/caustics-material.mjs +0 -128
  268. package/esm2022/shaders/lib/caustics-projection-material/caustics-projection-material.mjs +0 -33
  269. package/esm2022/shaders/lib/convolution-material/convolution-material.mjs +0 -94
  270. package/esm2022/shaders/lib/discard-material/discard-material.mjs +0 -3
  271. package/esm2022/shaders/lib/mesh-distort-material/mesh-distort-material.mjs +0 -55
  272. package/esm2022/shaders/lib/mesh-reflector-material/mesh-reflector-material.mjs +0 -223
  273. package/esm2022/shaders/lib/mesh-refraction-material/mesh-refraction-material.mjs +0 -169
  274. package/esm2022/shaders/lib/mesh-transmission-material/mesh-transmission-material.mjs +0 -268
  275. package/esm2022/shaders/lib/mesh-wobble-material/mesh-wobble-material.mjs +0 -37
  276. package/esm2022/shaders/lib/shader-material/shader-material.mjs +0 -34
  277. package/esm2022/shaders/lib/soft-shadow-material/soft-shadow-material.mjs +0 -33
  278. package/esm2022/shaders/lib/spot-light-material/spot-light-material.mjs +0 -86
  279. package/esm2022/shaders/lib/star-field-material/star-field-material.mjs +0 -32
  280. package/esm2022/staging/lib/accumulative-shadows/accumulative-shadows.mjs +0 -249
  281. package/esm2022/staging/lib/accumulative-shadows/progressive-light-map.mjs +0 -108
  282. package/esm2022/staging/lib/accumulative-shadows/randomized-lights.mjs +0 -201
  283. package/esm2022/staging/lib/bounds/bounds.mjs +0 -284
  284. package/esm2022/staging/lib/camera-shake/camera-shake.mjs +0 -122
  285. package/esm2022/staging/lib/caustics/caustics.mjs +0 -364
  286. package/esm2022/staging/lib/center/center.mjs +0 -143
  287. package/esm2022/staging/lib/cloud/cloud.mjs +0 -160
  288. package/esm2022/staging/lib/contact-shadows/contact-shadows.mjs +0 -228
  289. package/esm2022/staging/lib/environment/assets.mjs +0 -13
  290. package/esm2022/staging/lib/environment/environment-cube.mjs +0 -41
  291. package/esm2022/staging/lib/environment/environment-ground.mjs +0 -67
  292. package/esm2022/staging/lib/environment/environment-inputs.mjs +0 -87
  293. package/esm2022/staging/lib/environment/environment-map.mjs +0 -39
  294. package/esm2022/staging/lib/environment/environment-portal.mjs +0 -111
  295. package/esm2022/staging/lib/environment/environment.mjs +0 -165
  296. package/esm2022/staging/lib/environment/utils.mjs +0 -70
  297. package/esm2022/staging/lib/float/float.mjs +0 -77
  298. package/esm2022/staging/lib/sky/sky.mjs +0 -109
  299. package/esm2022/staging/lib/sparkles/sparkles.mjs +0 -210
  300. package/esm2022/staging/lib/spot-light/common.mjs +0 -42
  301. package/esm2022/staging/lib/spot-light/shadow-mesh-input.mjs +0 -51
  302. package/esm2022/staging/lib/spot-light/spot-light-input.mjs +0 -62
  303. package/esm2022/staging/lib/spot-light/spot-light-shadow-no-shader.mjs +0 -74
  304. package/esm2022/staging/lib/spot-light/spot-light-shadow-shader.mjs +0 -126
  305. package/esm2022/staging/lib/spot-light/spot-light-shadow.mjs +0 -63
  306. package/esm2022/staging/lib/spot-light/spot-light.mjs +0 -117
  307. package/esm2022/staging/lib/spot-light/volumetric-mesh.mjs +0 -86
  308. package/esm2022/staging/lib/stage/stage.mjs +0 -368
  309. package/esm2022/staging/lib/stars/stars.mjs +0 -140
  310. package/loaders/lib/cube-texture-loader/cube-texture-loader.d.ts +0 -3
  311. package/loaders/lib/gltf-loader/gltf-loader.d.ts +0 -8
  312. package/loaders/lib/progress/progress.d.ts +0 -16
  313. package/loaders/lib/texture-loader/texture-loader.d.ts +0 -5
  314. package/materials/lib/mesh-reflector-material/mesh-reflector-material.d.ts +0 -41
  315. package/materials/lib/mesh-refraction-material/mesh-refraction-material.d.ts +0 -28
  316. package/misc/lib/animations/animations.d.ts +0 -13
  317. package/misc/lib/depth-buffer/depth-buffer.d.ts +0 -7
  318. package/performance/lib/detailed/detailed.d.ts +0 -13
  319. package/staging/lib/cloud/cloud.d.ts +0 -23
  320. package/staging/lib/environment/environment-cube.d.ts +0 -11
  321. package/staging/lib/environment/environment-ground.d.ts +0 -9
  322. package/staging/lib/environment/environment-inputs.d.ts +0 -28
  323. package/staging/lib/environment/environment-map.d.ts +0 -10
  324. package/staging/lib/environment/utils.d.ts +0 -8
  325. package/staging/lib/float/float.d.ts +0 -16
  326. package/staging/lib/spot-light/common.d.ts +0 -3
  327. package/staging/lib/spot-light/spot-light-shadow-no-shader.d.ts +0 -14
  328. package/staging/lib/spot-light/spot-light-shadow-shader.d.ts +0 -25
  329. package/staging/lib/spot-light/spot-light-shadow.d.ts +0 -6
  330. /package/abstractions/{lib/gizmo-helper → gizmo-helper}/gizmo-viewcube/constants.d.ts +0 -0
  331. /package/cameras/{lib/perspective-camera → perspective-camera}/perspective-camera.d.ts +0 -0
  332. /package/plugin/{README.md → libs/plugin/README.md} +0 -0
  333. /package/shaders/{lib/caustics-material → caustics-material}/caustics-material.d.ts +0 -0
  334. /package/shaders/{lib/caustics-projection-material → caustics-material}/caustics-projection-material.d.ts +0 -0
  335. /package/shaders/{lib/convolution-material → convolution-material}/convolution-material.d.ts +0 -0
  336. /package/shaders/{lib/discard-material → discard-material}/discard-material.d.ts +0 -0
  337. /package/shaders/{lib/mesh-reflector-material → mesh-reflector-material}/mesh-reflector-material.d.ts +0 -0
  338. /package/shaders/{lib/mesh-refraction-material → mesh-refraction-material}/mesh-refraction-material.d.ts +0 -0
  339. /package/shaders/{lib/mesh-transmission-material → mesh-transmission-material}/mesh-transmission-material.d.ts +0 -0
  340. /package/shaders/{lib/shader-material → shader-material}/shader-material.d.ts +0 -0
  341. /package/shaders/{lib/spot-light-material → spot-light-material}/spot-light-material.d.ts +0 -0
  342. /package/shaders/{lib/star-field-material → star-field-material}/star-field-material.d.ts +0 -0
  343. /package/staging/{lib/environment → environment}/assets.d.ts +0 -0
@@ -1,10 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, inject, Directive, Component, CUSTOM_ELEMENTS_SCHEMA, Input, EventEmitter, Output, TemplateRef, ContentChild, ChangeDetectorRef } from '@angular/core';
3
- import { extend, NgtStore, getLocalState, NgtRxStore, injectNgtRef, NgtArgs, NgtRepeat, is, injectBeforeRender, NgtPush, injectNgtDestroy, injectNgtLoader, startWithUndefined, prepare, NgtPortal, NgtPortalContent, createRunInContext, checkUpdate } from 'angular-three';
4
- import { DiscardMaterial, SoftShadowMaterial, CausticsProjectionMaterial, CausticsMaterial, shaderMaterial, SpotLightMaterial, StarFieldMaterial } from 'angular-three-soba/shaders';
5
- import { Subject, combineLatest, switchMap, map, isObservable, of, debounceTime, takeUntil, startWith, withLatestFrom } from 'rxjs';
2
+ import { InjectionToken, inject, computed, untracked, effect, Component, CUSTOM_ELEMENTS_SCHEMA, Input, EventEmitter, Output, Directive, runInInjectionContext, ChangeDetectorRef, DestroyRef, TemplateRef, ContentChild, isSignal } from '@angular/core';
3
+ import { extend, NgtSignalStore, NgtStore, injectNgtRef, requestAnimationInInjectionContext, injectBeforeRender, getLocalState, NgtArgs, NgtRepeat, is, assertInjectionContext, injectNgtLoader, safeDetectChanges, prepare, NgtPortal, NgtPortalContent, checkUpdate, createSignal } from 'angular-three';
4
+ import { DiscardMaterial, SoftShadowMaterial, CausticsProjectionMaterial, CausticsMaterial, SparklesMaterial, SpotLightMaterial, StarFieldMaterial } from 'angular-three-soba/shaders';
6
5
  import * as THREE from 'three';
7
- import { Group, Mesh, PlaneGeometry, DirectionalLight, OrthographicCamera, Vector2, Scene, LineBasicMaterial, Box3, Vector3, Sphere, MeshStandardMaterial, MeshBasicMaterial, CubeTextureLoader, CubeReflectionMapping, EquirectangularReflectionMapping, sRGBEncoding, LinearEncoding, CubeCamera, HalfFloatType, Points, BufferGeometry, BufferAttribute, Vector4, Color, MathUtils, SpotLight, SpotLightHelper, AmbientLight, PointLight, Spherical } from 'three';
6
+ import { Group, Mesh, PlaneGeometry, DirectionalLight, OrthographicCamera, Vector2, Scene, LineBasicMaterial, Box3, Vector3, Sphere, MeshStandardMaterial, MeshBasicMaterial, CubeTextureLoader, CubeReflectionMapping, EquirectangularReflectionMapping, sRGBEncoding, LinearEncoding, CubeCamera, Points, BufferGeometry, BufferAttribute, Vector4, Color, MathUtils, SpotLight, SpotLightHelper, AmbientLight, PointLight } from 'three';
8
7
  import { SimplexNoise, FullScreenQuad, HorizontalBlurShader, VerticalBlurShader, RGBELoader, GroundProjectedEnv, Sky } from 'three-stdlib';
9
8
  import { NgIf, NgFor, NgTemplateOutlet } from '@angular/common';
10
9
  import { NgtsEdges, NgtsBillboard } from 'angular-three-soba/abstractions';
@@ -17,6 +16,7 @@ function isLight(object) {
17
16
  function isGeometry(object) {
18
17
  return !!object.geometry;
19
18
  }
19
+ // Based on "Progressive Light Map Accumulator", by [zalo](https://github.com/zalo/)
20
20
  class ProgressiveLightMap {
21
21
  constructor(renderer, scene, res = 1024) {
22
22
  this.renderer = renderer;
@@ -32,11 +32,9 @@ class ProgressiveLightMap {
32
32
  const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : THREE.FloatType;
33
33
  this.progressiveLightMap1 = new THREE.WebGLRenderTarget(this.res, this.res, {
34
34
  type: format,
35
- encoding: renderer.outputEncoding,
36
35
  });
37
36
  this.progressiveLightMap2 = new THREE.WebGLRenderTarget(this.res, this.res, {
38
37
  type: format,
39
- encoding: renderer.outputEncoding,
40
38
  });
41
39
  // Inject some spicy new logic into a standard phong material
42
40
  this.discardMat = new DiscardMaterial();
@@ -59,6 +57,7 @@ class ProgressiveLightMap {
59
57
  `\nvec3 texelOld = texture2D(previousShadowMap, vUv).rgb;
60
58
  gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/ averagingWindow);
61
59
  }`;
60
+ // Set the Previous Frame's Texture Buffer and Averaging Window
62
61
  // Set the Previous Frame's Texture Buffer and Averaging Window
63
62
  shader.uniforms['previousShadowMap'] = this.previousShadowMap;
64
63
  shader.uniforms['averagingWindow'] = this.averagingWindow;
@@ -119,100 +118,7 @@ class ProgressiveLightMap {
119
118
 
120
119
  extend({ SoftShadowMaterial, Group, Mesh, PlaneGeometry });
121
120
  const NGTS_ACCUMULATIVE_SHADOWS_API = new InjectionToken('NgtsAccumulativeShadows API');
122
- function accumulativeShadowsApiFactory(accumulativeShadows) {
123
- const store = inject(NgtStore);
124
- const api = {
125
- lights: new Map(),
126
- count: 0,
127
- getMesh: () => accumulativeShadows.meshRef.nativeElement,
128
- reset: () => {
129
- accumulativeShadows.pLM.clear();
130
- const material = api.getMesh().material;
131
- material.opacity = 0;
132
- material.alphaTest = 0;
133
- api.count = 0;
134
- },
135
- update: (frames = 1) => {
136
- // adapt the opacity blend ratio to the number of frames
137
- const material = api.getMesh().material;
138
- if (!api.temporal) {
139
- material.opacity = accumulativeShadows.get('opacity');
140
- material.alphaTest = accumulativeShadows.get('alphaTest');
141
- }
142
- else {
143
- material.opacity = Math.min(accumulativeShadows.get('opacity'), material.opacity + accumulativeShadows.get('opacity') / api.blend);
144
- material.alphaTest = Math.min(accumulativeShadows.get('alphaTest'), material.alphaTest + accumulativeShadows.get('alphaTest') / api.blend);
145
- }
146
- // switch accumulative lights on
147
- accumulativeShadows.accumulativeShadowsRef.nativeElement.visible = true;
148
- // collect scene lights and meshes
149
- accumulativeShadows.pLM.prepare();
150
- // update the lightmap and the accumulative lights
151
- for (let i = 0; i < frames; i++) {
152
- api.lights.forEach((light) => light.update());
153
- accumulativeShadows.pLM.update(store.get('camera'), api.blend);
154
- }
155
- // switch lights off
156
- accumulativeShadows.accumulativeShadowsRef.nativeElement.visible = false;
157
- // restore lights and meshes
158
- accumulativeShadows.pLM.finish();
159
- },
160
- };
161
- Object.defineProperties(api, {
162
- temporal: {
163
- get: () => !!accumulativeShadows.get('temporal'),
164
- },
165
- frames: {
166
- get: () => Math.max(2, accumulativeShadows.get('frames')),
167
- },
168
- blend: {
169
- get: () => Math.max(2, accumulativeShadows.get('frames') === Infinity
170
- ? accumulativeShadows.get('blend')
171
- : accumulativeShadows.get('frames')),
172
- },
173
- });
174
- const subject = new Subject();
175
- accumulativeShadows.hold(accumulativeShadows.meshRef.$, (mesh) => {
176
- accumulativeShadows.pLM.configure(mesh);
177
- accumulativeShadows.hold(combineLatest([accumulativeShadows.select(), getLocalState(store.get('scene')).objects]), () => {
178
- // reset internals, buffers, ...
179
- api.reset();
180
- // update lightmap
181
- if (!api.temporal && api.frames !== Infinity)
182
- api.update(api.blend);
183
- });
184
- accumulativeShadows.effect(subject, () => store.get('internal').subscribe(() => {
185
- const limit = accumulativeShadows.get('limit');
186
- if ((api.temporal || api.frames === Infinity) && api.count < api.frames && api.count < limit) {
187
- api.update();
188
- api.count++;
189
- }
190
- }));
191
- subject.next();
192
- });
193
- return api;
194
- }
195
- class AccumulativeShadowsConsumer {
196
- constructor() {
197
- inject(NGTS_ACCUMULATIVE_SHADOWS_API);
198
- }
199
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: AccumulativeShadowsConsumer, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
200
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: AccumulativeShadowsConsumer, isStandalone: true, selector: "[ngtsAccumulativeShadowsConsumer]", ngImport: i0 }); }
201
- }
202
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: AccumulativeShadowsConsumer, decorators: [{
203
- type: Directive,
204
- args: [{ selector: '[ngtsAccumulativeShadowsConsumer]', standalone: true }]
205
- }], ctorParameters: function () { return []; } });
206
- class NgtsAccumulativeShadows extends NgtRxStore {
207
- constructor() {
208
- super(...arguments);
209
- this.nullTraverse = () => null;
210
- this.Math = Math;
211
- this.store = inject(NgtStore);
212
- this.pLM = new ProgressiveLightMap(this.store.get('gl'), this.store.get('scene'), this.get('resolution'));
213
- this.accumulativeShadowsRef = injectNgtRef();
214
- this.meshRef = injectNgtRef();
215
- }
121
+ class NgtsAccumulativeShadows extends NgtSignalStore {
216
122
  /** How many frames it can render, more yields cleaner results but takes more time, 40 */
217
123
  set frames(frames) {
218
124
  this.set({ frames });
@@ -257,9 +163,18 @@ class NgtsAccumulativeShadows extends NgtRxStore {
257
163
  set toneMapped(toneMapped) {
258
164
  this.set({ toneMapped });
259
165
  }
260
- initialize() {
261
- super.initialize();
262
- this.set({
166
+ #store;
167
+ #gl;
168
+ #scene;
169
+ #camera;
170
+ #resolution;
171
+ #temporal;
172
+ #blend;
173
+ #frames;
174
+ #opacity;
175
+ #alphaTest;
176
+ constructor() {
177
+ super({
263
178
  frames: 40,
264
179
  limit: Infinity,
265
180
  blend: 20,
@@ -270,34 +185,151 @@ class NgtsAccumulativeShadows extends NgtRxStore {
270
185
  colorBlend: 2,
271
186
  resolution: 1024,
272
187
  toneMapped: true,
188
+ temporal: false,
273
189
  });
190
+ this.nullTraverse = () => null;
191
+ this.Math = Math;
192
+ this.#store = inject(NgtStore);
193
+ this.#gl = this.#store.select('gl');
194
+ this.#scene = this.#store.select('scene');
195
+ this.#camera = this.#store.select('camera');
196
+ this.#resolution = this.select('resolution');
197
+ this.#temporal = this.select('temporal');
198
+ this.#blend = this.select('blend');
199
+ this.#frames = this.select('frames');
200
+ this.#opacity = this.select('opacity');
201
+ this.#alphaTest = this.select('alphaTest');
202
+ this.accumulativeShadowsScale = this.select('scale');
203
+ this.accumulativeShadowsToneMapped = this.select('toneMapped');
204
+ this.accumulativeShadowsColor = this.select('color');
205
+ this.accumulativeShadowsColorBlend = this.select('colorBlend');
206
+ this.meshRef = injectNgtRef();
207
+ this.accumulativeShadowsRef = injectNgtRef();
208
+ this.pLM = computed(() => new ProgressiveLightMap(untracked(this.#gl), untracked(this.#scene), this.#resolution()));
209
+ this.api = computed(() => {
210
+ const pLM = this.pLM();
211
+ const alphaTest = this.#alphaTest();
212
+ const opacity = this.#opacity();
213
+ const camera = this.#camera();
214
+ return {
215
+ lights: new Map(),
216
+ temporal: this.#temporal(),
217
+ frames: Math.max(2, this.#frames()),
218
+ blend: Math.max(2, this.#frames() === Infinity ? this.#blend() : this.#frames()),
219
+ count: 0,
220
+ getMesh: () => this.meshRef.nativeElement,
221
+ reset: () => {
222
+ if (!this.meshRef.nativeElement)
223
+ return;
224
+ // Clear buffers, reset opacities, set frame count to 0
225
+ pLM.clear();
226
+ const material = this.meshRef.nativeElement.material;
227
+ material.opacity = 0;
228
+ material.alphaTest = 0;
229
+ this.api().count = 0;
230
+ },
231
+ update: (frames = 1) => {
232
+ if (!this.meshRef.nativeElement)
233
+ return;
234
+ // Adapt the opacity-blend ratio to the number of frames
235
+ const material = this.meshRef.nativeElement.material;
236
+ if (!this.api().temporal) {
237
+ material.opacity = opacity;
238
+ material.alphaTest = alphaTest;
239
+ }
240
+ else {
241
+ material.opacity = Math.min(opacity, material.opacity + opacity / this.api().blend);
242
+ material.alphaTest = Math.min(alphaTest, material.alphaTest + alphaTest / this.api().blend);
243
+ }
244
+ // Switch accumulative lights on
245
+ this.accumulativeShadowsRef.nativeElement.visible = true;
246
+ // Collect scene lights and meshes
247
+ pLM.prepare();
248
+ // Update the lightmap and the accumulative lights
249
+ for (let i = 0; i < frames; i++) {
250
+ this.api().lights.forEach((light) => light().update());
251
+ pLM.update(camera, this.api().blend);
252
+ }
253
+ // Switch lights off
254
+ this.accumulativeShadowsRef.nativeElement.visible = false;
255
+ // Restore lights and meshes
256
+ pLM.finish();
257
+ },
258
+ };
259
+ });
260
+ requestAnimationInInjectionContext(() => {
261
+ this.#configure();
262
+ this.#resetAndUpdate();
263
+ });
264
+ injectBeforeRender(this.#onBeforeRender.bind(this));
265
+ }
266
+ #onBeforeRender() {
267
+ const invalidate = this.#store.get('invalidate');
268
+ const limit = this.get('limit');
269
+ const api = this.api();
270
+ if ((api.temporal || api.frames === Infinity) && api.count < api.frames && api.count < limit) {
271
+ invalidate();
272
+ api.update();
273
+ api.count++;
274
+ }
274
275
  }
275
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsAccumulativeShadows, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
276
+ #configure() {
277
+ const trigger = computed(() => ({ pLM: this.pLM(), mesh: this.meshRef.nativeElement }));
278
+ effect(() => {
279
+ const { pLM, mesh } = trigger();
280
+ if (!mesh)
281
+ return;
282
+ pLM.configure(mesh);
283
+ });
284
+ }
285
+ #resetAndUpdate() {
286
+ const trigger = computed(() => ({
287
+ state: this.select()(),
288
+ objects: getLocalState(this.#store.get('scene')).objects(),
289
+ mesh: this.meshRef.nativeElement,
290
+ }));
291
+ effect(() => {
292
+ const { mesh } = trigger();
293
+ if (!mesh)
294
+ return;
295
+ const api = untracked(this.api);
296
+ // Reset internals, buffers, ...
297
+ api.reset();
298
+ // Update lightmap
299
+ if (!api.temporal && api.frames !== Infinity)
300
+ api.update(api.blend);
301
+ });
302
+ }
303
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsAccumulativeShadows, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
276
304
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsAccumulativeShadows, isStandalone: true, selector: "ngts-accumulative-shadows", inputs: { frames: "frames", blend: "blend", limit: "limit", scale: "scale", temporal: "temporal", opacity: "opacity", alphaTest: "alphaTest", color: "color", colorBlend: "colorBlend", resolution: "resolution", toneMapped: "toneMapped" }, providers: [
277
305
  {
278
306
  provide: NGTS_ACCUMULATIVE_SHADOWS_API,
279
- useFactory: accumulativeShadowsApiFactory,
307
+ useFactory: (shadows) => shadows.api,
280
308
  deps: [NgtsAccumulativeShadows],
281
309
  },
282
310
  ], usesInheritance: true, ngImport: i0, template: `
283
311
  <ngt-group ngtCompound>
284
312
  <ngt-group [ref]="accumulativeShadowsRef" [traverse]="nullTraverse">
285
313
  <ng-content />
286
- <ng-container ngtsAccumulativeShadowsConsumer />
287
314
  </ngt-group>
288
- <ngt-mesh [ref]="meshRef" [receiveShadow]="true" [scale]="get('scale')" [rotation]="[-Math.PI / 2, 0, 0]">
315
+ <ngt-mesh
316
+ [ref]="meshRef"
317
+ [receiveShadow]="true"
318
+ [scale]="accumulativeShadowsScale()"
319
+ [rotation]="[-Math.PI / 2, 0, 0]"
320
+ >
289
321
  <ngt-plane-geometry />
290
322
  <ngt-soft-shadow-material
291
323
  [transparent]="true"
292
324
  [depthWrite]="false"
293
- [color]="get('color')"
294
- [toneMapped]="get('toneMapped')"
295
- [blend]="get('colorBlend')"
296
- [map]="pLM.progressiveLightMap2.texture"
325
+ [toneMapped]="accumulativeShadowsToneMapped()"
326
+ [color]="accumulativeShadowsColor()"
327
+ [blend]="accumulativeShadowsColorBlend()"
328
+ [map]="pLM().progressiveLightMap2.texture"
297
329
  />
298
330
  </ngt-mesh>
299
331
  </ngt-group>
300
- `, isInline: true, dependencies: [{ kind: "directive", type: AccumulativeShadowsConsumer, selector: "[ngtsAccumulativeShadowsConsumer]" }] }); }
332
+ `, isInline: true }); }
301
333
  }
302
334
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsAccumulativeShadows, decorators: [{
303
335
  type: Component,
@@ -308,32 +340,35 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
308
340
  <ngt-group ngtCompound>
309
341
  <ngt-group [ref]="accumulativeShadowsRef" [traverse]="nullTraverse">
310
342
  <ng-content />
311
- <ng-container ngtsAccumulativeShadowsConsumer />
312
343
  </ngt-group>
313
- <ngt-mesh [ref]="meshRef" [receiveShadow]="true" [scale]="get('scale')" [rotation]="[-Math.PI / 2, 0, 0]">
344
+ <ngt-mesh
345
+ [ref]="meshRef"
346
+ [receiveShadow]="true"
347
+ [scale]="accumulativeShadowsScale()"
348
+ [rotation]="[-Math.PI / 2, 0, 0]"
349
+ >
314
350
  <ngt-plane-geometry />
315
351
  <ngt-soft-shadow-material
316
352
  [transparent]="true"
317
353
  [depthWrite]="false"
318
- [color]="get('color')"
319
- [toneMapped]="get('toneMapped')"
320
- [blend]="get('colorBlend')"
321
- [map]="pLM.progressiveLightMap2.texture"
354
+ [toneMapped]="accumulativeShadowsToneMapped()"
355
+ [color]="accumulativeShadowsColor()"
356
+ [blend]="accumulativeShadowsColorBlend()"
357
+ [map]="pLM().progressiveLightMap2.texture"
322
358
  />
323
359
  </ngt-mesh>
324
360
  </ngt-group>
325
361
  `,
326
- imports: [AccumulativeShadowsConsumer],
327
362
  providers: [
328
363
  {
329
364
  provide: NGTS_ACCUMULATIVE_SHADOWS_API,
330
- useFactory: accumulativeShadowsApiFactory,
365
+ useFactory: (shadows) => shadows.api,
331
366
  deps: [NgtsAccumulativeShadows],
332
367
  },
333
368
  ],
334
369
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
335
370
  }]
336
- }], propDecorators: { frames: [{
371
+ }], ctorParameters: function () { return []; }, propDecorators: { frames: [{
337
372
  type: Input
338
373
  }], blend: [{
339
374
  type: Input
@@ -358,58 +393,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
358
393
  }] } });
359
394
 
360
395
  extend({ Group, DirectionalLight, OrthographicCamera, Vector2 });
361
- const NGTS_RANDOMIZED_LIGHTS_API = new InjectionToken('NgtsRandomizedLights API');
362
- function randomizedLightsApiFactory(randomizedLights) {
363
- const accumulativeApi = inject(NGTS_ACCUMULATIVE_SHADOWS_API);
364
- const update = () => {
365
- let light;
366
- if (randomizedLights.lightsRef.nativeElement) {
367
- for (let l = 0; l < randomizedLights.lightsRef.nativeElement.children.length; l++) {
368
- light = randomizedLights.lightsRef.nativeElement.children[l];
369
- if (Math.random() > randomizedLights.get('ambient')) {
370
- const position = randomizedLights.get('position');
371
- const radius = randomizedLights.get('radius');
372
- light.position.set(position[0] + THREE.MathUtils.randFloatSpread(radius), position[1] + THREE.MathUtils.randFloatSpread(radius), position[2] + THREE.MathUtils.randFloatSpread(radius));
373
- }
374
- else {
375
- const lambda = Math.acos(2 * Math.random() - 1) - Math.PI / 2.0;
376
- const phi = 2 * Math.PI * Math.random();
377
- const length = randomizedLights.get('length');
378
- light.position.set(Math.cos(lambda) * Math.cos(phi) * length, Math.abs(Math.cos(lambda) * Math.sin(phi) * length), Math.sin(lambda) * length);
379
- }
380
- }
381
- }
382
- };
383
- const api = { update };
384
- randomizedLights.effect(combineLatest([
385
- randomizedLights.lightsRef.$,
386
- randomizedLights.select('position'),
387
- randomizedLights.select('radius'),
388
- randomizedLights.select('length'),
389
- randomizedLights.select('ambient'),
390
- ]), ([group]) => {
391
- if (accumulativeApi)
392
- accumulativeApi.lights.set(group.uuid, api);
393
- return () => accumulativeApi.lights.delete(group.uuid);
394
- });
395
- return api;
396
- }
397
- class RandomizedLightsConsumer {
398
- constructor() {
399
- inject(NGTS_RANDOMIZED_LIGHTS_API);
400
- }
401
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: RandomizedLightsConsumer, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
402
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: RandomizedLightsConsumer, isStandalone: true, selector: "[ngtsRandomizedLightsConsumer]", ngImport: i0 }); }
403
- }
404
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: RandomizedLightsConsumer, decorators: [{
405
- type: Directive,
406
- args: [{ selector: '[ngtsRandomizedLightsConsumer]', standalone: true }]
407
- }], ctorParameters: function () { return []; } });
408
- class NgtsRandomizedLights extends NgtRxStore {
409
- constructor() {
410
- super(...arguments);
411
- this.lightsRef = injectNgtRef();
412
- }
396
+ class NgtsRandomizedLights extends NgtSignalStore {
413
397
  /** How many frames it will jiggle the lights, 1.
414
398
  * Frames is context aware, if a provider like AccumulativeShadows exists, frames will be taken from there! */
415
399
  set frames(frames) {
@@ -459,9 +443,16 @@ class NgtsRandomizedLights extends NgtRxStore {
459
443
  set far(far) {
460
444
  this.set({ far });
461
445
  }
462
- initialize() {
463
- super.initialize();
464
- this.set({
446
+ #parent;
447
+ #size;
448
+ #near;
449
+ #far;
450
+ #mapSize;
451
+ #ambient;
452
+ #position;
453
+ #radius;
454
+ constructor() {
455
+ super({
465
456
  castShadow: true,
466
457
  bias: 0.001,
467
458
  mapSize: 512,
@@ -475,26 +466,83 @@ class NgtsRandomizedLights extends NgtRxStore {
475
466
  intensity: 1,
476
467
  ambient: 0.5,
477
468
  });
478
- this.connect('cameraArgs', this.select(['size', 'near', 'far'], ({ size, near, far }) => [-size, size, size, -size, near, far]));
479
- this.connect('length', this.select(['position'], ({ position }) => new THREE.Vector3(...position).length()));
469
+ this.lightsRef = injectNgtRef();
470
+ this.#parent = inject(NGTS_ACCUMULATIVE_SHADOWS_API);
471
+ this.#size = this.select('size');
472
+ this.#near = this.select('near');
473
+ this.#far = this.select('far');
474
+ this.#mapSize = this.select('mapSize');
475
+ this.#ambient = this.select('ambient');
476
+ this.#position = this.select('position');
477
+ this.#radius = this.select('radius');
478
+ this.lightsAmount = this.select('amount');
479
+ this.lightsCastShadow = this.select('castShadow');
480
+ this.lightsIntensity = this.select('intensity');
481
+ this.lightsBias = this.select('bias');
482
+ this.shadowMapSize = computed(() => [this.#mapSize(), this.#mapSize()]);
483
+ this.cameraArgs = computed(() => [
484
+ -this.#size(),
485
+ this.#size(),
486
+ this.#size(),
487
+ -this.#size(),
488
+ this.#near(),
489
+ this.#far(),
490
+ ]);
491
+ this.length = computed(() => new THREE.Vector3(...this.#position()).length());
492
+ this.api = computed(() => {
493
+ const radius = this.#radius();
494
+ const position = this.#position();
495
+ const ambient = this.#ambient();
496
+ const length = this.length();
497
+ const lights = this.lightsRef.nativeElement;
498
+ const update = () => {
499
+ let light;
500
+ if (lights) {
501
+ for (let l = 0; l < lights.children.length; l++) {
502
+ light = lights.children[l];
503
+ if (Math.random() > ambient) {
504
+ light.position.set(position[0] + THREE.MathUtils.randFloatSpread(radius), position[1] + THREE.MathUtils.randFloatSpread(radius), position[2] + THREE.MathUtils.randFloatSpread(radius));
505
+ }
506
+ else {
507
+ const lambda = Math.acos(2 * Math.random() - 1) - Math.PI / 2.0;
508
+ const phi = 2 * Math.PI * Math.random();
509
+ light.position.set(Math.cos(lambda) * Math.cos(phi) * length, Math.abs(Math.cos(lambda) * Math.sin(phi) * length), Math.sin(lambda) * length);
510
+ }
511
+ }
512
+ }
513
+ };
514
+ return { update };
515
+ });
516
+ requestAnimationInInjectionContext(() => {
517
+ this.#updateLightsMap();
518
+ });
480
519
  }
481
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsRandomizedLights, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
482
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsRandomizedLights, isStandalone: true, selector: "ngts-randomized-lights", inputs: { lightsRef: "lightsRef", frames: "frames", position: "position", radius: "radius", amount: "amount", intensity: "intensity", ambient: "ambient", castShadow: "castShadow", bias: "bias", mapSize: "mapSize", size: "size", near: "near", far: "far" }, providers: [
483
- { provide: NGTS_RANDOMIZED_LIGHTS_API, useFactory: randomizedLightsApiFactory, deps: [NgtsRandomizedLights] },
484
- ], usesInheritance: true, ngImport: i0, template: `
520
+ #updateLightsMap() {
521
+ effect((onCleanup) => {
522
+ const lights = this.lightsRef.nativeElement;
523
+ if (!lights)
524
+ return;
525
+ const parent = this.#parent();
526
+ if (parent) {
527
+ parent.lights.set(lights.uuid, this.api);
528
+ onCleanup(() => parent.lights.delete(lights.uuid));
529
+ }
530
+ });
531
+ }
532
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsRandomizedLights, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
533
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsRandomizedLights, isStandalone: true, selector: "ngts-randomized-lights", inputs: { lightsRef: "lightsRef", frames: "frames", position: "position", radius: "radius", amount: "amount", intensity: "intensity", ambient: "ambient", castShadow: "castShadow", bias: "bias", mapSize: "mapSize", size: "size", near: "near", far: "far" }, usesInheritance: true, ngImport: i0, template: `
485
534
  <ngt-group ngtCompound [ref]="lightsRef">
486
535
  <ngt-directional-light
487
- *ngFor="let i; repeat: get('amount')"
488
- [castShadow]="get('castShadow')"
489
- [intensity]="get('intensity') / get('amount')"
536
+ *ngFor="let i; repeat: lightsAmount()"
537
+ [castShadow]="lightsCastShadow()"
538
+ [intensity]="lightsIntensity() / lightsAmount()"
490
539
  >
491
- <ngt-value [rawValue]="get('bias')" attach="shadow.bias" />
492
- <ngt-vector2 *args="[get('mapSize'), get('mapSize')]" attach="shadow.mapSize" />
493
- <ngt-orthographic-camera *args="get('cameraArgs')" attach="shadow.camera" />
540
+ <ngt-value [rawValue]="lightsBias()" attach="shadow.bias" />
541
+ <ngt-vector2 *args="shadowMapSize()" attach="shadow.mapSize" />
542
+ <ngt-orthographic-camera *args="cameraArgs()" attach="shadow.camera" />
494
543
  </ngt-directional-light>
495
- <ng-container ngtsRandomizedLightsConsumer />
496
544
  </ngt-group>
497
- `, isInline: true, dependencies: [{ kind: "directive", type: RandomizedLightsConsumer, selector: "[ngtsRandomizedLightsConsumer]" }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "directive", type: NgtRepeat, selector: "[ngFor][ngForRepeat]", inputs: ["ngForRepeat"] }] }); }
545
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "directive", type: NgtRepeat, selector: "[ngFor][ngForRepeat]", inputs: ["ngForRepeat"] }] }); }
498
546
  }
499
547
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsRandomizedLights, decorators: [{
500
548
  type: Component,
@@ -504,24 +552,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
504
552
  template: `
505
553
  <ngt-group ngtCompound [ref]="lightsRef">
506
554
  <ngt-directional-light
507
- *ngFor="let i; repeat: get('amount')"
508
- [castShadow]="get('castShadow')"
509
- [intensity]="get('intensity') / get('amount')"
555
+ *ngFor="let i; repeat: lightsAmount()"
556
+ [castShadow]="lightsCastShadow()"
557
+ [intensity]="lightsIntensity() / lightsAmount()"
510
558
  >
511
- <ngt-value [rawValue]="get('bias')" attach="shadow.bias" />
512
- <ngt-vector2 *args="[get('mapSize'), get('mapSize')]" attach="shadow.mapSize" />
513
- <ngt-orthographic-camera *args="get('cameraArgs')" attach="shadow.camera" />
559
+ <ngt-value [rawValue]="lightsBias()" attach="shadow.bias" />
560
+ <ngt-vector2 *args="shadowMapSize()" attach="shadow.mapSize" />
561
+ <ngt-orthographic-camera *args="cameraArgs()" attach="shadow.camera" />
514
562
  </ngt-directional-light>
515
- <ng-container ngtsRandomizedLightsConsumer />
516
563
  </ngt-group>
517
564
  `,
518
- imports: [RandomizedLightsConsumer, NgtArgs, NgtRepeat],
519
- providers: [
520
- { provide: NGTS_RANDOMIZED_LIGHTS_API, useFactory: randomizedLightsApiFactory, deps: [NgtsRandomizedLights] },
521
- ],
565
+ imports: [NgtArgs, NgtRepeat],
522
566
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
523
567
  }]
524
- }], propDecorators: { lightsRef: [{
568
+ }], ctorParameters: function () { return []; }, propDecorators: { lightsRef: [{
525
569
  type: Input
526
570
  }], frames: [{
527
571
  type: Input
@@ -559,201 +603,8 @@ function damp(v, t, lambda, delta) {
559
603
  v.z = THREE.MathUtils.damp(v.z, t.z, lambda, delta);
560
604
  }
561
605
  const NGTS_BOUNDS_API = new InjectionToken('NgtsBounds API');
562
- function boundsApiFactory(bounds) {
563
- const store = inject(NgtStore);
564
- const box = new THREE.Box3();
565
- function getSize() {
566
- const camera = store.get('camera');
567
- const margin = bounds.get('margin');
568
- const size = box.getSize(new THREE.Vector3());
569
- const center = box.getCenter(new THREE.Vector3());
570
- const maxSize = Math.max(size.x, size.y, size.z);
571
- const fitHeightDistance = is.orthographicCamera(camera)
572
- ? maxSize * 4
573
- : maxSize / (2 * Math.atan((Math.PI * camera.fov) / 360));
574
- const fitWidthDistance = is.orthographicCamera(camera) ? maxSize * 4 : fitHeightDistance / camera.aspect;
575
- const distance = margin * Math.max(fitHeightDistance, fitWidthDistance);
576
- return { box, size, center, distance };
577
- }
578
- const api = {
579
- getSize,
580
- refresh(object) {
581
- const { camera, controls: storeControls } = store.get();
582
- const controls = storeControls;
583
- if (isBox3(object))
584
- box.copy(object);
585
- else {
586
- const target = object || bounds.boundsRef.nativeElement;
587
- if (target) {
588
- target.updateWorldMatrix(true, true);
589
- box.setFromObject(target);
590
- }
591
- }
592
- if (box.isEmpty()) {
593
- const max = camera.position.length() || 10;
594
- box.setFromCenterAndSize(new THREE.Vector3(), new THREE.Vector3(max, max, max));
595
- }
596
- if (controls?.constructor.name === 'OrthographicTrackballControls') {
597
- // put camera on a sphere along which it would move
598
- const { distance } = getSize();
599
- const direction = camera.position.clone().sub(controls.target).normalize().multiplyScalar(distance);
600
- const newPos = controls.target.clone().add(direction);
601
- camera.position.copy(newPos);
602
- }
603
- return this;
604
- },
605
- clip() {
606
- const { distance } = getSize();
607
- const { camera, controls: storeControls, invalidate } = store.get();
608
- const controls = storeControls;
609
- if (controls)
610
- controls.maxDistance = distance * 10;
611
- camera.near = distance / 100;
612
- camera.far = distance * 100;
613
- camera.updateProjectionMatrix();
614
- if (controls)
615
- controls.update();
616
- invalidate();
617
- return this;
618
- },
619
- to({ position, target }) {
620
- const { camera } = store.get();
621
- const { damping } = bounds.get();
622
- bounds.current.camera.copy(camera.position);
623
- const { center } = getSize();
624
- bounds.goal.camera.set(...position);
625
- if (target) {
626
- bounds.goal.focus.set(...target);
627
- }
628
- else {
629
- bounds.goal.focus.copy(center);
630
- }
631
- if (damping) {
632
- bounds.current.animating = true;
633
- }
634
- else {
635
- camera.position.set(...position);
636
- }
637
- return this;
638
- },
639
- fit() {
640
- const { camera, controls: storeControls, invalidate } = store.get();
641
- const controls = storeControls;
642
- const { damping, margin } = bounds.get();
643
- bounds.current.camera.copy(camera.position);
644
- if (controls)
645
- bounds.current.focus.copy(controls.target);
646
- const { center, distance } = getSize();
647
- const direction = center.clone().sub(camera.position).normalize().multiplyScalar(distance);
648
- bounds.goal.camera.copy(center).sub(direction);
649
- bounds.goal.focus.copy(center);
650
- if (is.orthographicCamera(camera)) {
651
- bounds.current.zoom = camera.zoom;
652
- let maxHeight = 0, maxWidth = 0;
653
- const vertices = [
654
- new THREE.Vector3(box.min.x, box.min.y, box.min.z),
655
- new THREE.Vector3(box.min.x, box.max.y, box.min.z),
656
- new THREE.Vector3(box.min.x, box.min.y, box.max.z),
657
- new THREE.Vector3(box.min.x, box.max.y, box.max.z),
658
- new THREE.Vector3(box.max.x, box.max.y, box.max.z),
659
- new THREE.Vector3(box.max.x, box.max.y, box.min.z),
660
- new THREE.Vector3(box.max.x, box.min.y, box.max.z),
661
- new THREE.Vector3(box.max.x, box.min.y, box.min.z),
662
- ];
663
- // Transform the center and each corner to camera space
664
- center.applyMatrix4(camera.matrixWorldInverse);
665
- for (const v of vertices) {
666
- v.applyMatrix4(camera.matrixWorldInverse);
667
- maxHeight = Math.max(maxHeight, Math.abs(v.y - center.y));
668
- maxWidth = Math.max(maxWidth, Math.abs(v.x - center.x));
669
- }
670
- maxHeight *= 2;
671
- maxWidth *= 2;
672
- const zoomForHeight = (camera.top - camera.bottom) / maxHeight;
673
- const zoomForWidth = (camera.right - camera.left) / maxWidth;
674
- bounds.goal.zoom = Math.min(zoomForHeight, zoomForWidth) / margin;
675
- if (!damping) {
676
- camera.zoom = bounds.goal.zoom;
677
- camera.updateProjectionMatrix();
678
- }
679
- }
680
- if (damping) {
681
- bounds.current.animating = true;
682
- }
683
- else {
684
- camera.position.copy(bounds.goal.camera);
685
- camera.lookAt(bounds.goal.focus);
686
- if (controls) {
687
- controls.target.copy(bounds.goal.focus);
688
- controls.update();
689
- }
690
- }
691
- if (bounds.fitted.observed)
692
- bounds.fitted.emit(this.getSize());
693
- invalidate();
694
- return this;
695
- },
696
- };
697
- let count = 0;
698
- bounds.hold(bounds.boundsRef.$.pipe(switchMap(() => combineLatest([
699
- bounds.select('clip'),
700
- bounds.select('fit'),
701
- bounds.select('observe'),
702
- store.select('camera'),
703
- store.select('controls'),
704
- store.select('size'),
705
- bounds.boundsRef.children$(),
706
- ]))), ([clip, fit, observe]) => {
707
- if (observe || count++ === 0) {
708
- api.refresh();
709
- if (fit)
710
- api.fit();
711
- if (clip)
712
- api.clip();
713
- }
714
- });
715
- injectBeforeRender(({ delta }) => {
716
- if (bounds.current.animating) {
717
- const { damping, eps } = bounds.get();
718
- const { camera, controls: storeControls, invalidate } = store.get();
719
- const controls = storeControls;
720
- damp(bounds.current.focus, bounds.goal.focus, damping, delta);
721
- damp(bounds.current.camera, bounds.goal.camera, damping, delta);
722
- bounds.current.zoom = THREE.MathUtils.damp(bounds.current.zoom, bounds.goal.zoom, damping, delta);
723
- camera.position.copy(bounds.current.camera);
724
- if (is.orthographicCamera(camera)) {
725
- camera.zoom = bounds.current.zoom;
726
- camera.updateProjectionMatrix();
727
- }
728
- if (!controls) {
729
- camera.lookAt(bounds.current.focus);
730
- }
731
- else {
732
- controls.target.copy(bounds.current.focus);
733
- controls.update();
734
- }
735
- invalidate();
736
- if (is.orthographicCamera(camera) && !(Math.abs(bounds.current.zoom - bounds.goal.zoom) < eps))
737
- return;
738
- if (!is.orthographicCamera(camera) && !equals(bounds.current.camera, bounds.goal.camera, eps))
739
- return;
740
- if (controls && !equals(bounds.current.focus, bounds.goal.focus, eps))
741
- return;
742
- bounds.current.animating = false;
743
- }
744
- });
745
- return api;
746
- }
747
606
  extend({ Group });
748
- class NgtsBounds extends NgtRxStore {
749
- constructor() {
750
- super(...arguments);
751
- this.boundsRef = injectNgtRef();
752
- this.fitted = new EventEmitter();
753
- this.store = inject(NgtStore);
754
- this.current = { animating: false, focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
755
- this.goal = { focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
756
- }
607
+ class NgtsBounds extends NgtSignalStore {
757
608
  set damping(damping) {
758
609
  this.set({ damping });
759
610
  }
@@ -772,24 +623,241 @@ class NgtsBounds extends NgtRxStore {
772
623
  set eps(eps) {
773
624
  this.set({ eps });
774
625
  }
775
- initialize() {
776
- super.initialize();
777
- this.set({ damping: 6, fit: false, clip: false, observe: false, margin: 1.2, eps: 0.01 });
626
+ #store;
627
+ #controls;
628
+ #camera;
629
+ #invalidate;
630
+ #size;
631
+ #current;
632
+ #goal;
633
+ #box;
634
+ #margin;
635
+ #damping;
636
+ #fit;
637
+ #clip;
638
+ #observe;
639
+ #count;
640
+ constructor() {
641
+ super({ damping: 6, fit: false, clip: false, observe: false, margin: 1.2, eps: 0.01 });
642
+ this.boundsRef = injectNgtRef();
643
+ this.fitted = new EventEmitter();
644
+ this.#store = inject(NgtStore);
645
+ this.#controls = this.#store.select('controls');
646
+ this.#camera = this.#store.select('camera');
647
+ this.#invalidate = this.#store.select('invalidate');
648
+ this.#size = this.#store.select('size');
649
+ this.#current = { animating: false, focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
650
+ this.#goal = { focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
651
+ this.#box = new THREE.Box3();
652
+ this.#margin = this.select('margin');
653
+ this.#damping = this.select('damping');
654
+ this.#fit = this.select('fit');
655
+ this.#clip = this.select('clip');
656
+ this.#observe = this.select('observe');
657
+ this.#count = 0;
658
+ this.api = computed(() => {
659
+ const margin = this.#margin();
660
+ const damping = this.#damping();
661
+ const camera = this.#camera();
662
+ const controls = this.#controls();
663
+ const invalidate = this.#invalidate();
664
+ const current = this.#current;
665
+ const goal = this.#goal;
666
+ const box = this.#box;
667
+ const ref = () => this.boundsRef.untracked;
668
+ const fitted = this.fitted;
669
+ function getSize() {
670
+ const size = box.getSize(new THREE.Vector3());
671
+ const center = box.getCenter(new THREE.Vector3());
672
+ const maxSize = Math.max(size.x, size.y, size.z);
673
+ const fitHeightDistance = is.orthographicCamera(camera)
674
+ ? maxSize * 4
675
+ : maxSize / (2 * Math.atan((Math.PI * camera.fov) / 360));
676
+ const fitWidthDistance = is.orthographicCamera(camera) ? maxSize * 4 : fitHeightDistance / camera.aspect;
677
+ const distance = margin * Math.max(fitHeightDistance, fitWidthDistance);
678
+ return { box, size, center, distance };
679
+ }
680
+ return {
681
+ getSize,
682
+ refresh(object) {
683
+ if (isBox3(object))
684
+ box.copy(object);
685
+ else {
686
+ const target = object || ref();
687
+ if (target) {
688
+ target.updateWorldMatrix(true, true);
689
+ box.setFromObject(target);
690
+ }
691
+ }
692
+ if (box.isEmpty()) {
693
+ const max = camera.position.length() || 10;
694
+ box.setFromCenterAndSize(new THREE.Vector3(), new THREE.Vector3(max, max, max));
695
+ }
696
+ if (controls?.constructor.name === 'OrthographicTrackballControls') {
697
+ // Put camera on a sphere along which it should move
698
+ const { distance } = getSize();
699
+ const direction = camera.position.clone().sub(controls.target).normalize().multiplyScalar(distance);
700
+ const newPos = controls.target.clone().add(direction);
701
+ camera.position.copy(newPos);
702
+ }
703
+ return this;
704
+ },
705
+ clip() {
706
+ const { distance } = getSize();
707
+ if (controls)
708
+ controls.maxDistance = distance * 10;
709
+ camera.near = distance / 100;
710
+ camera.far = distance * 100;
711
+ camera.updateProjectionMatrix();
712
+ if (controls)
713
+ controls.update();
714
+ invalidate();
715
+ return this;
716
+ },
717
+ to({ position, target }) {
718
+ current.camera.copy(camera.position);
719
+ const { center } = getSize();
720
+ goal.camera.set(...position);
721
+ if (target) {
722
+ goal.focus.set(...target);
723
+ }
724
+ else {
725
+ goal.focus.copy(center);
726
+ }
727
+ if (damping) {
728
+ current.animating = true;
729
+ }
730
+ else {
731
+ camera.position.set(...position);
732
+ }
733
+ return this;
734
+ },
735
+ fit() {
736
+ current.camera.copy(camera.position);
737
+ if (controls)
738
+ current.focus.copy(controls.target);
739
+ const { center, distance } = getSize();
740
+ const direction = center.clone().sub(camera.position).normalize().multiplyScalar(distance);
741
+ goal.camera.copy(center).sub(direction);
742
+ goal.focus.copy(center);
743
+ if (is.orthographicCamera(camera)) {
744
+ current.zoom = camera.zoom;
745
+ let maxHeight = 0, maxWidth = 0;
746
+ const vertices = [
747
+ new THREE.Vector3(box.min.x, box.min.y, box.min.z),
748
+ new THREE.Vector3(box.min.x, box.max.y, box.min.z),
749
+ new THREE.Vector3(box.min.x, box.min.y, box.max.z),
750
+ new THREE.Vector3(box.min.x, box.max.y, box.max.z),
751
+ new THREE.Vector3(box.max.x, box.max.y, box.max.z),
752
+ new THREE.Vector3(box.max.x, box.max.y, box.min.z),
753
+ new THREE.Vector3(box.max.x, box.min.y, box.max.z),
754
+ new THREE.Vector3(box.max.x, box.min.y, box.min.z),
755
+ ];
756
+ // Transform the center and each corner to camera space
757
+ center.applyMatrix4(camera.matrixWorldInverse);
758
+ for (const v of vertices) {
759
+ v.applyMatrix4(camera.matrixWorldInverse);
760
+ maxHeight = Math.max(maxHeight, Math.abs(v.y - center.y));
761
+ maxWidth = Math.max(maxWidth, Math.abs(v.x - center.x));
762
+ }
763
+ maxHeight *= 2;
764
+ maxWidth *= 2;
765
+ const zoomForHeight = (camera.top - camera.bottom) / maxHeight;
766
+ const zoomForWidth = (camera.right - camera.left) / maxWidth;
767
+ goal.zoom = Math.min(zoomForHeight, zoomForWidth) / margin;
768
+ if (!damping) {
769
+ camera.zoom = goal.zoom;
770
+ camera.updateProjectionMatrix();
771
+ }
772
+ }
773
+ if (damping) {
774
+ current.animating = true;
775
+ }
776
+ else {
777
+ camera.position.copy(goal.camera);
778
+ camera.lookAt(goal.focus);
779
+ if (controls) {
780
+ controls.target.copy(goal.focus);
781
+ controls.update();
782
+ }
783
+ }
784
+ if (fitted.observed)
785
+ fitted.emit(this.getSize());
786
+ invalidate();
787
+ return this;
788
+ },
789
+ };
790
+ });
791
+ this.#preventDragHijacking();
792
+ requestAnimationInInjectionContext(() => {
793
+ this.#scalePointer();
794
+ injectBeforeRender(this.#onBeforeRender.bind(this));
795
+ });
796
+ }
797
+ #scalePointer() {
798
+ const trigger = computed(() => ({
799
+ size: this.#size(),
800
+ fit: this.#fit(),
801
+ clip: this.#clip(),
802
+ observe: this.#observe(),
803
+ camera: this.#camera(),
804
+ controls: this.#controls(),
805
+ }));
806
+ effect(() => {
807
+ const { observe, fit, clip } = trigger();
808
+ const api = untracked(this.api);
809
+ if (observe || this.#count++ === 0) {
810
+ api.refresh();
811
+ if (fit)
812
+ api.fit();
813
+ if (clip)
814
+ api.clip();
815
+ }
816
+ });
778
817
  }
779
- ngOnInit() {
780
- this.preventDragHijacking();
818
+ #onBeforeRender({ delta }) {
819
+ const { damping, eps } = this.get();
820
+ const invalidate = this.#invalidate();
821
+ const camera = this.#camera();
822
+ const controls = this.#controls();
823
+ if (this.#current.animating) {
824
+ damp(this.#current.focus, this.#goal.focus, damping, delta);
825
+ damp(this.#current.camera, this.#goal.camera, damping, delta);
826
+ this.#current.zoom = THREE.MathUtils.damp(this.#current.zoom, this.#goal.zoom, damping, delta);
827
+ camera.position.copy(this.#current.camera);
828
+ if (is.orthographicCamera(camera)) {
829
+ camera.zoom = this.#current.zoom;
830
+ camera.updateProjectionMatrix();
831
+ }
832
+ if (!controls) {
833
+ camera.lookAt(this.#current.focus);
834
+ }
835
+ else {
836
+ controls.target.copy(this.#current.focus);
837
+ controls.update();
838
+ }
839
+ invalidate();
840
+ if (is.orthographicCamera(camera) && !(Math.abs(this.#current.zoom - this.#goal.zoom) < eps))
841
+ return;
842
+ if (!is.orthographicCamera(camera) && !equals(this.#current.camera, this.#goal.camera, eps))
843
+ return;
844
+ if (controls && !equals(this.#current.focus, this.#goal.focus, eps))
845
+ return;
846
+ this.#current.animating = false;
847
+ }
781
848
  }
782
- preventDragHijacking() {
783
- this.effect(this.store.select('controls'), (controls) => {
849
+ #preventDragHijacking() {
850
+ effect((onCleanup) => {
851
+ const controls = this.#controls();
784
852
  if (controls) {
785
- const callback = () => (this.current.animating = false);
853
+ const callback = () => (this.#current.animating = false);
786
854
  controls.addEventListener('start', callback);
787
- return () => controls.removeEventListener('start', callback);
855
+ onCleanup(() => controls.removeEventListener('start', callback));
788
856
  }
789
857
  });
790
858
  }
791
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsBounds, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
792
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsBounds, isStandalone: true, selector: "ngts-bounds", inputs: { boundsRef: "boundsRef", damping: "damping", fit: "fit", clip: "clip", observe: "observe", margin: "margin", eps: "eps" }, outputs: { fitted: "fitted" }, providers: [{ provide: NGTS_BOUNDS_API, useFactory: boundsApiFactory, deps: [NgtsBounds] }], usesInheritance: true, ngImport: i0, template: `
859
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsBounds, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
860
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsBounds, isStandalone: true, selector: "ngts-bounds", inputs: { boundsRef: "boundsRef", damping: "damping", fit: "fit", clip: "clip", observe: "observe", margin: "margin", eps: "eps" }, outputs: { fitted: "fitted" }, providers: [{ provide: NGTS_BOUNDS_API, useFactory: (bounds) => bounds.api, deps: [NgtsBounds] }], usesInheritance: true, ngImport: i0, template: `
793
861
  <ngt-group ngtCompound [ref]="boundsRef">
794
862
  <ng-content />
795
863
  </ngt-group>
@@ -805,10 +873,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
805
873
  <ng-content />
806
874
  </ngt-group>
807
875
  `,
808
- providers: [{ provide: NGTS_BOUNDS_API, useFactory: boundsApiFactory, deps: [NgtsBounds] }],
876
+ providers: [{ provide: NGTS_BOUNDS_API, useFactory: (bounds) => bounds.api, deps: [NgtsBounds] }],
809
877
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
810
878
  }]
811
- }], propDecorators: { boundsRef: [{
879
+ }], ctorParameters: function () { return []; }, propDecorators: { boundsRef: [{
812
880
  type: Input
813
881
  }], damping: [{
814
882
  type: Input
@@ -826,7 +894,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
826
894
  type: Output
827
895
  }] } });
828
896
 
829
- class NgtsCameraShake extends NgtRxStore {
897
+ class NgtsCameraShake extends NgtSignalStore {
898
+ #store = inject(NgtStore);
899
+ #initialRotation = this.#store.get('camera').rotation.clone();
900
+ #yawNoise = new SimplexNoise();
901
+ #rollNoise = new SimplexNoise();
902
+ #pitchNoise = new SimplexNoise();
830
903
  set intensity(intensity) {
831
904
  this.set({ intensity });
832
905
  }
@@ -854,9 +927,8 @@ class NgtsCameraShake extends NgtRxStore {
854
927
  set rollFrequency(rollFrequency) {
855
928
  this.set({ rollFrequency });
856
929
  }
857
- initialize() {
858
- super.initialize();
859
- this.set({
930
+ constructor() {
931
+ super({
860
932
  intensity: 1,
861
933
  decayRate: 0.65,
862
934
  maxYaw: 0.1,
@@ -866,37 +938,32 @@ class NgtsCameraShake extends NgtRxStore {
866
938
  pitchFrequency: 0.1,
867
939
  rollFrequency: 0.1,
868
940
  });
869
- }
870
- constructor() {
871
- super();
872
- this.store = inject(NgtStore);
873
- this.initialRotation = this.store.get('camera').rotation.clone();
874
- this.yawNoise = new SimplexNoise();
875
- this.pitchNoise = new SimplexNoise();
876
- this.rollNoise = new SimplexNoise();
877
941
  injectBeforeRender(({ clock, delta, camera }) => {
878
942
  const { intensity, maxYaw, maxPitch, maxRoll, yawFrequency, pitchFrequency, rollFrequency, decay, decayRate, } = this.get();
879
943
  const shake = Math.pow(intensity, 2);
880
- const yaw = maxYaw * shake * this.yawNoise.noise(clock.elapsedTime * yawFrequency, 1);
881
- const pitch = maxPitch * shake * this.pitchNoise.noise(clock.elapsedTime * pitchFrequency, 1);
882
- const roll = maxRoll * shake * this.rollNoise.noise(clock.elapsedTime * rollFrequency, 1);
883
- camera.rotation.set(this.initialRotation.x + pitch, this.initialRotation.y + yaw, this.initialRotation.z + roll);
944
+ const yaw = maxYaw * shake * this.#yawNoise.noise(clock.elapsedTime * yawFrequency, 1);
945
+ const pitch = maxPitch * shake * this.#pitchNoise.noise(clock.elapsedTime * pitchFrequency, 1);
946
+ const roll = maxRoll * shake * this.#rollNoise.noise(clock.elapsedTime * rollFrequency, 1);
947
+ camera.rotation.set(this.#initialRotation.x + pitch, this.#initialRotation.y + yaw, this.#initialRotation.z + roll);
884
948
  if (decay && intensity > 0) {
885
949
  this.set({ intensity: intensity - decayRate * delta });
886
- this.constraintIntensity();
950
+ this.#constraintIntensity();
887
951
  }
888
952
  });
889
- }
890
- ngOnInit() {
891
- this.setChangeEvent();
892
- }
893
- setChangeEvent() {
894
- this.effect(combineLatest([this.store.select('camera'), this.store.select('controls')]), ([camera, controls]) => {
953
+ this.#setChangeEvent();
954
+ }
955
+ ngOnInit() { }
956
+ #setChangeEvent() {
957
+ const camera = this.#store.select('camera');
958
+ const controls = this.#store.select('controls');
959
+ const trigger = computed(() => ({ camera: camera(), controls: controls() }));
960
+ effect((onCleanup) => {
961
+ const { camera, controls } = trigger();
895
962
  if (controls) {
896
- const callback = () => void (this.initialRotation = camera.rotation.clone());
963
+ const callback = () => void (this.#initialRotation = camera.rotation.clone());
897
964
  controls.addEventListener('change', callback);
898
965
  callback();
899
- return () => void controls.removeEventListener('change', callback);
966
+ onCleanup(() => void controls.removeEventListener('change', callback));
900
967
  }
901
968
  });
902
969
  }
@@ -905,9 +972,9 @@ class NgtsCameraShake extends NgtRxStore {
905
972
  }
906
973
  setIntensity(intensity) {
907
974
  this.set({ intensity });
908
- this.constraintIntensity();
975
+ this.#constraintIntensity();
909
976
  }
910
- constraintIntensity() {
977
+ #constraintIntensity() {
911
978
  const intensity = this.get('intensity');
912
979
  if (intensity < 0 || intensity > 1) {
913
980
  this.set({ intensity: intensity < 0 ? 0 : 1 });
@@ -918,10 +985,7 @@ class NgtsCameraShake extends NgtRxStore {
918
985
  }
919
986
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCameraShake, decorators: [{
920
987
  type: Directive,
921
- args: [{
922
- selector: 'ngts-camera-shake',
923
- standalone: true,
924
- }]
988
+ args: [{ selector: 'ngts-camera-shake', standalone: true }]
925
989
  }], ctorParameters: function () { return []; }, propDecorators: { intensity: [{
926
990
  type: Input
927
991
  }], decay: [{
@@ -973,23 +1037,7 @@ function createNormalMaterial(side = THREE.FrontSide) {
973
1037
  },
974
1038
  });
975
1039
  }
976
- class NgtsCaustics extends NgtRxStore {
977
- constructor() {
978
- super(...arguments);
979
- this.CustomBlending = THREE.CustomBlending;
980
- this.OneFactor = THREE.OneFactor;
981
- this.SrcAlphaFactor = THREE.SrcAlphaFactor;
982
- this.Math = Math;
983
- this.planeRef = injectNgtRef();
984
- this.sceneRef = injectNgtRef();
985
- this.cameraRef = injectNgtRef();
986
- this.causticsRef = injectNgtRef();
987
- this.normalTargetFbo = injectNgtsFBO(() => this.select('resolution').pipe(map((resolution) => ({ width: resolution, height: resolution, settings: NORMALPROPS }))));
988
- this.normalTargetBFbo = injectNgtsFBO(() => this.select('resolution').pipe(map((resolution) => ({ width: resolution, height: resolution, settings: NORMALPROPS }))));
989
- this.causticsTargetFbo = injectNgtsFBO(() => this.select('resolution').pipe(map((resolution) => ({ width: resolution, height: resolution, settings: CAUSTICPROPS }))));
990
- this.causticsTargetBFbo = injectNgtsFBO(() => this.select('resolution').pipe(map((resolution) => ({ width: resolution, height: resolution, settings: CAUSTICPROPS }))));
991
- this.store = inject(NgtStore);
992
- }
1040
+ class NgtsCaustics extends NgtSignalStore {
993
1041
  /** How many frames it will render, set it to Infinity for runtime, default: 1 */
994
1042
  set frames(frames) {
995
1043
  this.set({ frames });
@@ -1034,8 +1082,12 @@ class NgtsCaustics extends NgtRxStore {
1034
1082
  set lightSource(lightSource) {
1035
1083
  this.set({ lightSource });
1036
1084
  }
1037
- initialize() {
1038
- this.set({
1085
+ #resolution;
1086
+ #normalTargetSettings;
1087
+ #causticsTargetSettings;
1088
+ #store;
1089
+ constructor() {
1090
+ super({
1039
1091
  frames: 1,
1040
1092
  ior: 1.1,
1041
1093
  color: 'white',
@@ -1047,37 +1099,74 @@ class NgtsCaustics extends NgtRxStore {
1047
1099
  resolution: 2024,
1048
1100
  lightSource: [5, 5, 5],
1049
1101
  });
1102
+ this.CustomBlending = THREE.CustomBlending;
1103
+ this.OneFactor = THREE.OneFactor;
1104
+ this.SrcAlphaFactor = THREE.SrcAlphaFactor;
1105
+ this.Math = Math;
1106
+ this.planeRef = injectNgtRef();
1107
+ this.sceneRef = injectNgtRef();
1108
+ this.cameraRef = injectNgtRef();
1109
+ this.causticsRef = injectNgtRef();
1110
+ this.causticsColor = this.select('color');
1111
+ this.causticsDebug = this.select('debug');
1112
+ this.#resolution = this.select('resolution');
1113
+ this.#normalTargetSettings = computed(() => ({
1114
+ width: this.#resolution(),
1115
+ height: this.#resolution(),
1116
+ settings: NORMALPROPS,
1117
+ }));
1118
+ this.#causticsTargetSettings = computed(() => ({
1119
+ width: this.#resolution(),
1120
+ height: this.#resolution(),
1121
+ settings: CAUSTICPROPS,
1122
+ }));
1123
+ this.normalTargetFbo = injectNgtsFBO(this.#normalTargetSettings);
1124
+ this.normalTargetBFbo = injectNgtsFBO(this.#normalTargetSettings);
1125
+ this.causticsTargetFbo = injectNgtsFBO(this.#causticsTargetSettings);
1126
+ this.causticsTargetBFbo = injectNgtsFBO(this.#causticsTargetSettings);
1127
+ this.#store = inject(NgtStore);
1128
+ requestAnimationInInjectionContext(() => {
1129
+ this.#updateWorldMatrix();
1130
+ this.#setBeforeRender();
1131
+ });
1050
1132
  }
1051
- ngOnInit() {
1052
- this.updateWorldMatrix();
1053
- this.setBeforeRender();
1054
- }
1055
- updateWorldMatrix() {
1056
- this.hold(combineLatest([this.sceneRef.children$(), this.causticsRef.$, this.causticsRef.children$(), this.select()]), () => {
1057
- if (this.causticsRef.nativeElement) {
1058
- this.causticsRef.nativeElement.updateWorldMatrix(false, true);
1059
- }
1133
+ #updateWorldMatrix() {
1134
+ const trigger = computed(() => ({
1135
+ sceneChildren: this.sceneRef.children()(),
1136
+ caustics: this.causticsRef.nativeElement,
1137
+ causticsChildren: this.causticsRef.children()(),
1138
+ state: this.select()(),
1139
+ }));
1140
+ effect(() => {
1141
+ const { caustics } = trigger();
1142
+ if (!caustics)
1143
+ return;
1144
+ caustics.updateWorldMatrix(false, true);
1060
1145
  });
1061
1146
  }
1062
- setBeforeRender() {
1147
+ #setBeforeRender() {
1063
1148
  const causticsMaterial = new CausticsMaterial();
1064
1149
  const causticsQuad = new FullScreenQuad(causticsMaterial);
1065
1150
  const normalMaterial = createNormalMaterial();
1066
1151
  const normalMaterialB = createNormalMaterial(THREE.BackSide);
1067
- this.effect(combineLatest([
1068
- this.sceneRef.$,
1069
- this.sceneRef.children$(),
1070
- this.causticsRef.$,
1071
- this.cameraRef.$,
1072
- this.normalTargetFbo.$,
1073
- this.normalTargetBFbo.$,
1074
- this.causticsTargetFbo.$,
1075
- this.causticsTargetBFbo.$,
1076
- this.planeRef.$,
1077
- this.planeRef.children$('both'),
1078
- ]), ([scene, children, caustics, camera, normalTarget, normalTargetB, causticsTarget, causticsTargetB, plane,]) => {
1152
+ const trigger = computed(() => ({
1153
+ scene: this.sceneRef.nativeElement,
1154
+ sceneChildren: this.sceneRef.children()(),
1155
+ caustics: this.causticsRef.nativeElement,
1156
+ camera: this.cameraRef.nativeElement,
1157
+ normalTarget: this.normalTargetFbo(),
1158
+ normalTargetB: this.normalTargetBFbo(),
1159
+ causticsTarget: this.causticsTargetFbo(),
1160
+ causticsTargetB: this.causticsTargetBFbo(),
1161
+ plane: this.planeRef.nativeElement,
1162
+ planeChildren: this.planeRef.children('both')(),
1163
+ }));
1164
+ effect((onCleanup) => {
1165
+ const { caustics, sceneChildren, scene, camera, plane, normalTarget, normalTargetB, causticsTarget, causticsTargetB, } = trigger();
1166
+ if (!caustics)
1167
+ return;
1079
1168
  caustics.updateWorldMatrix(false, true);
1080
- if (children.length > 1) {
1169
+ if (sceneChildren.length > 1) {
1081
1170
  const v = new THREE.Vector3();
1082
1171
  const lpF = new THREE.Frustum();
1083
1172
  const lpM = new THREE.Matrix4();
@@ -1087,8 +1176,8 @@ class NgtsCaustics extends NgtRxStore {
1087
1176
  const bounds = new THREE.Box3();
1088
1177
  const focusPos = new THREE.Vector3();
1089
1178
  let count = 0;
1090
- return this.store.get('internal').subscribe(({ gl }) => {
1091
- const { frames, lightSource, resolution, worldRadius, intensity, backside, backsideIOR, ior, causticsOnly, debug, } = this.get();
1179
+ const sub = this.#store.get('internal').subscribe(({ gl }) => {
1180
+ const { frames, lightSource, resolution, worldRadius, intensity, backside, backsideIOR, ior, causticsOnly, } = this.get();
1092
1181
  if (frames === Infinity || count++ < frames) {
1093
1182
  if (Array.isArray(lightSource))
1094
1183
  lightDir.fromArray(lightSource).normalize();
@@ -1117,9 +1206,7 @@ class NgtsCaustics extends NgtRxStore {
1117
1206
  const radius = projectedVerts
1118
1207
  .map((v) => v.distanceTo(centralVert))
1119
1208
  .reduce((a, b) => Math.max(a, b));
1120
- const dirLength = boundsVertices
1121
- .map((x) => x.dot(lightDir))
1122
- .reduce((a, b) => Math.max(a, b));
1209
+ const dirLength = boundsVertices.map((x) => x.dot(lightDir)).reduce((a, b) => Math.max(a, b));
1123
1210
  // Shadows
1124
1211
  camera.position.copy(lightDir.clone().multiplyScalar(dirLength).add(focusPos));
1125
1212
  camera.lookAt(scene.localToWorld(focusPos.clone()));
@@ -1147,8 +1234,7 @@ class NgtsCaustics extends NgtRxStore {
1147
1234
  plane.position.copy(centerPos);
1148
1235
  // if (debug) helper.current?.update();
1149
1236
  // Inject uniforms
1150
- normalMaterialB.viewMatrix.value = normalMaterial.viewMatrix.value =
1151
- camera.matrixWorldInverse;
1237
+ normalMaterialB.viewMatrix.value = normalMaterial.viewMatrix.value = camera.matrixWorldInverse;
1152
1238
  const dirLightNearPlane = lpF.setFromProjectionMatrix(lpM.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)).planes[4];
1153
1239
  causticsMaterial.cameraMatrixWorld = camera.matrixWorld;
1154
1240
  causticsMaterial.cameraProjectionMatrixInv = camera.projectionMatrixInverse;
@@ -1179,10 +1265,8 @@ class NgtsCaustics extends NgtRxStore {
1179
1265
  scene.overrideMaterial = null;
1180
1266
  // Render front face caustics
1181
1267
  causticsMaterial.ior = ior;
1182
- plane.material.lightProjMatrix =
1183
- camera.projectionMatrix;
1184
- plane.material.lightViewMatrix =
1185
- camera.matrixWorldInverse;
1268
+ plane.material.lightProjMatrix = camera.projectionMatrix;
1269
+ plane.material.lightViewMatrix = camera.matrixWorldInverse;
1186
1270
  causticsMaterial.normalTexture = normalTarget.texture;
1187
1271
  causticsMaterial.depthTexture = normalTarget.depthTexture;
1188
1272
  gl.setRenderTarget(causticsTarget);
@@ -1203,10 +1287,11 @@ class NgtsCaustics extends NgtRxStore {
1203
1287
  scene.visible = false;
1204
1288
  }
1205
1289
  });
1290
+ onCleanup(() => sub());
1206
1291
  }
1207
1292
  });
1208
1293
  }
1209
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCaustics, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1294
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCaustics, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1210
1295
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsCaustics, isStandalone: true, selector: "ngts-caustics", inputs: { causticsRef: "causticsRef", frames: "frames", debug: "debug", causticsOnly: "causticsOnly", backside: "backside", ior: "ior", backsideIOR: "backsideIOR", worldRadius: "worldRadius", intensity: "intensity", color: "color", resolution: "resolution", lightSource: "lightSource" }, usesInheritance: true, ngImport: i0, template: `
1211
1296
  <ngt-group [ref]="causticsRef" ngtCompound>
1212
1297
  <ngt-scene [ref]="sceneRef">
@@ -1216,18 +1301,18 @@ class NgtsCaustics extends NgtRxStore {
1216
1301
  <ngt-mesh [renderOrder]="2" [ref]="planeRef" [rotation]="[-Math.PI / 2, 0, 0]">
1217
1302
  <ngt-plane-geometry />
1218
1303
  <ngt-caustics-projection-material
1219
- *ngIf="causticsTargetFbo.nativeElement && causticsTargetBFbo.nativeElement"
1304
+ *ngIf="causticsTargetFbo() && causticsTargetBFbo()"
1220
1305
  [transparent]="true"
1221
- [color]="get('color')"
1222
- [causticsTexture]="causticsTargetFbo.nativeElement.texture"
1223
- [causticsTextureB]="causticsTargetBFbo.nativeElement.texture"
1306
+ [color]="causticsColor()"
1307
+ [causticsTexture]="causticsTargetFbo().texture"
1308
+ [causticsTextureB]="causticsTargetBFbo().texture"
1224
1309
  [blending]="CustomBlending"
1225
1310
  [blendSrc]="OneFactor"
1226
1311
  [blendDst]="SrcAlphaFactor"
1227
1312
  [depthWrite]="false"
1228
1313
  />
1229
1314
 
1230
- <ngts-edges *ngIf="get('debug')" [withChildren]="true">
1315
+ <ngts-edges *ngIf="causticsDebug()" [withChildren]="true">
1231
1316
  <ngt-line-basic-material color="#ffff00" [toneMapped]="false" />
1232
1317
  </ngts-edges>
1233
1318
  </ngt-mesh>
@@ -1248,18 +1333,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1248
1333
  <ngt-mesh [renderOrder]="2" [ref]="planeRef" [rotation]="[-Math.PI / 2, 0, 0]">
1249
1334
  <ngt-plane-geometry />
1250
1335
  <ngt-caustics-projection-material
1251
- *ngIf="causticsTargetFbo.nativeElement && causticsTargetBFbo.nativeElement"
1336
+ *ngIf="causticsTargetFbo() && causticsTargetBFbo()"
1252
1337
  [transparent]="true"
1253
- [color]="get('color')"
1254
- [causticsTexture]="causticsTargetFbo.nativeElement.texture"
1255
- [causticsTextureB]="causticsTargetBFbo.nativeElement.texture"
1338
+ [color]="causticsColor()"
1339
+ [causticsTexture]="causticsTargetFbo().texture"
1340
+ [causticsTextureB]="causticsTargetBFbo().texture"
1256
1341
  [blending]="CustomBlending"
1257
1342
  [blendSrc]="OneFactor"
1258
1343
  [blendDst]="SrcAlphaFactor"
1259
1344
  [depthWrite]="false"
1260
1345
  />
1261
1346
 
1262
- <ngts-edges *ngIf="get('debug')" [withChildren]="true">
1347
+ <ngts-edges *ngIf="causticsDebug()" [withChildren]="true">
1263
1348
  <ngt-line-basic-material color="#ffff00" [toneMapped]="false" />
1264
1349
  </ngts-edges>
1265
1350
  </ngt-mesh>
@@ -1268,7 +1353,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1268
1353
  imports: [NgIf, NgtsEdges],
1269
1354
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
1270
1355
  }]
1271
- }], propDecorators: { causticsRef: [{
1356
+ }], ctorParameters: function () { return []; }, propDecorators: { causticsRef: [{
1272
1357
  type: Input
1273
1358
  }], frames: [{
1274
1359
  type: Input
@@ -1295,14 +1380,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1295
1380
  }] } });
1296
1381
 
1297
1382
  extend({ Group });
1298
- class NgtsCenter extends NgtRxStore {
1299
- constructor() {
1300
- super(...arguments);
1301
- this.centerRef = injectNgtRef();
1302
- this.outerRef = injectNgtRef();
1303
- this.innerRef = injectNgtRef();
1304
- this.centered = new EventEmitter();
1305
- }
1383
+ class NgtsCenter extends NgtSignalStore {
1306
1384
  set top(top) {
1307
1385
  this.set({ top });
1308
1386
  }
@@ -1330,24 +1408,37 @@ class NgtsCenter extends NgtRxStore {
1330
1408
  set disableZ(disableZ) {
1331
1409
  this.set({ disableZ });
1332
1410
  }
1333
- set disabled(disabled) {
1334
- this.set({ disabled });
1411
+ set disable(disable) {
1412
+ this.set({ disable });
1335
1413
  }
1336
1414
  set precise(precise) {
1337
1415
  this.set({ precise });
1338
1416
  }
1339
- initialize() {
1340
- super.initialize();
1341
- this.set({ precise: true });
1342
- }
1343
- ngOnInit() {
1344
- this.setPosition();
1417
+ constructor() {
1418
+ super({ precise: true });
1419
+ this.centerRef = injectNgtRef();
1420
+ this.outerRef = injectNgtRef();
1421
+ this.innerRef = injectNgtRef();
1422
+ this.centered = new EventEmitter();
1423
+ requestAnimationInInjectionContext(() => {
1424
+ this.#setPosition();
1425
+ });
1345
1426
  }
1346
- setPosition() {
1347
- this.hold(combineLatest([this.centerRef.$, this.outerRef.$, this.innerRef.$, this.innerRef.children$()]), ([centerGroup, outerGroup, innerGroup]) => {
1348
- const { precise, top, left, front, disabled, disableX, disableY, disableZ, back, bottom, right } = this.get();
1349
- outerGroup.matrixWorld.identity();
1350
- const box3 = new Box3().setFromObject(innerGroup, precise);
1427
+ #setPosition() {
1428
+ const trigger = computed(() => {
1429
+ const center = this.centerRef.nativeElement;
1430
+ const outer = this.outerRef.nativeElement;
1431
+ const inner = this.innerRef.nativeElement;
1432
+ const innerChildren = this.innerRef.children();
1433
+ return { center, outer, inner, innerChildren: innerChildren() };
1434
+ });
1435
+ effect(() => {
1436
+ const { center: centerGroup, outer, inner } = trigger();
1437
+ if (!outer || !inner)
1438
+ return;
1439
+ const { precise, top, left, front, disable, disableX, disableY, disableZ, back, bottom, right } = this.get();
1440
+ outer.matrixWorld.identity();
1441
+ const box3 = new Box3().setFromObject(inner, precise);
1351
1442
  const center = new Vector3();
1352
1443
  const sphere = new Sphere();
1353
1444
  const width = box3.max.x - box3.min.x;
@@ -1358,7 +1449,7 @@ class NgtsCenter extends NgtRxStore {
1358
1449
  const vAlign = top ? height / 2 : bottom ? -height / 2 : 0;
1359
1450
  const hAlign = left ? -width / 2 : right ? width / 2 : 0;
1360
1451
  const dAlign = front ? depth / 2 : back ? -depth / 2 : 0;
1361
- outerGroup.position.set(disabled || disableX ? 0 : -center.x + hAlign, disabled || disableY ? 0 : -center.y + vAlign, disabled || disableZ ? 0 : -center.z + dAlign);
1452
+ outer.position.set(disable || disableX ? 0 : -center.x + hAlign, disable || disableY ? 0 : -center.y + vAlign, disable || disableZ ? 0 : -center.z + dAlign);
1362
1453
  if (this.centered.observed) {
1363
1454
  this.centered.emit({
1364
1455
  parent: centerGroup.parent,
@@ -1376,8 +1467,8 @@ class NgtsCenter extends NgtRxStore {
1376
1467
  }
1377
1468
  });
1378
1469
  }
1379
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCenter, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1380
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsCenter, isStandalone: true, selector: "ngts-center", inputs: { centerRef: "centerRef", top: "top", right: "right", bottom: "bottom", left: "left", front: "front", back: "back", disableX: "disableX", disableY: "disableY", disableZ: "disableZ", disabled: "disabled", precise: "precise" }, outputs: { centered: "centered" }, usesInheritance: true, ngImport: i0, template: `
1470
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCenter, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1471
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsCenter, isStandalone: true, selector: "ngts-center", inputs: { centerRef: "centerRef", top: "top", right: "right", bottom: "bottom", left: "left", front: "front", back: "back", disableX: "disableX", disableY: "disableY", disableZ: "disableZ", disable: "disable", precise: "precise" }, outputs: { centered: "centered" }, usesInheritance: true, ngImport: i0, template: `
1381
1472
  <ngt-group ngtCompound [ref]="centerRef">
1382
1473
  <ngt-group [ref]="outerRef">
1383
1474
  <ngt-group [ref]="innerRef">
@@ -1403,7 +1494,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1403
1494
  `,
1404
1495
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
1405
1496
  }]
1406
- }], propDecorators: { centerRef: [{
1497
+ }], ctorParameters: function () { return []; }, propDecorators: { centerRef: [{
1407
1498
  type: Input
1408
1499
  }], top: [{
1409
1500
  type: Input
@@ -1423,7 +1514,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1423
1514
  type: Input
1424
1515
  }], disableZ: [{
1425
1516
  type: Input
1426
- }], disabled: [{
1517
+ }], disable: [{
1427
1518
  type: Input
1428
1519
  }], precise: [{
1429
1520
  type: Input
@@ -1432,16 +1523,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1432
1523
  }] } });
1433
1524
 
1434
1525
  const CLOUD_URL = 'https://rawcdn.githack.com/pmndrs/drei-assets/9225a9f1fbd449d9411125c2f419b843d0308c9f/cloud.png';
1526
+ injectNgtsTextureLoader.preload(() => CLOUD_URL);
1435
1527
  extend({ Group, Mesh, PlaneGeometry, MeshStandardMaterial });
1436
- class NgtsCloud extends NgtRxStore {
1437
- constructor() {
1438
- super(...arguments);
1439
- this.store = inject(NgtStore);
1440
- this.encoding = this.store.get('gl', 'outputEncoding');
1441
- this.groupRef = injectNgtRef();
1442
- this.clouds$ = this.select('clouds');
1443
- this.cloudTexture$ = injectNgtsTextureLoader(this.select('texture'));
1444
- }
1528
+ class NgtsCloud extends NgtSignalStore {
1445
1529
  set opacity(opacity) {
1446
1530
  this.set({ opacity });
1447
1531
  }
@@ -1466,9 +1550,11 @@ class NgtsCloud extends NgtRxStore {
1466
1550
  set depthTest(depthTest) {
1467
1551
  this.set({ depthTest });
1468
1552
  }
1469
- initialize() {
1470
- super.initialize();
1471
- this.set({
1553
+ #store;
1554
+ #width;
1555
+ #speed;
1556
+ constructor() {
1557
+ super({
1472
1558
  opacity: 0.5,
1473
1559
  speed: 0.4,
1474
1560
  width: 10,
@@ -1478,53 +1564,62 @@ class NgtsCloud extends NgtRxStore {
1478
1564
  color: '#ffffff',
1479
1565
  depthTest: true,
1480
1566
  });
1481
- this.connect('clouds', this.select(['width', 'segments', 'speed'], ({ width, segments, speed }) => {
1482
- return [...new Array(segments)].map((_, index) => ({
1483
- x: width / 2 - Math.random() * width,
1484
- y: width / 2 - Math.random() * width,
1485
- scale: 0.4 + Math.sin(((index + 1) / segments) * Math.PI) * ((0.2 + Math.random()) * 10),
1486
- density: Math.max(0.2, Math.random()),
1487
- rotation: Math.max(0.002, 0.005 * Math.random()) * speed,
1488
- }));
1489
- }));
1567
+ this.groupRef = injectNgtRef();
1568
+ this.#store = inject(NgtStore);
1569
+ this.#width = this.select('width');
1570
+ this.#speed = this.select('speed');
1571
+ this.cloudSegments = this.select('segments');
1572
+ this.cloudDepth = this.select('depth');
1573
+ this.cloudDepthTest = this.select('depthTest');
1574
+ this.cloudOpacity = this.select('opacity');
1575
+ this.cloudColor = this.select('color');
1576
+ this.encoding = this.#store.select('gl', 'outputEncoding');
1577
+ this.cloudTexture = injectNgtsTextureLoader(this.select('texture'));
1578
+ this.clouds = computed(() => [...new Array(this.cloudSegments())].map((_, index) => ({
1579
+ x: this.#width() / 2 - Math.random() * this.#width(),
1580
+ y: this.#width() / 2 - Math.random() * this.#width(),
1581
+ scale: 0.4 + Math.sin(((index + 1) / this.cloudSegments()) * Math.PI) * ((0.2 + Math.random()) * 10),
1582
+ density: Math.max(0.2, Math.random()),
1583
+ rotation: Math.max(0.002, 0.005 * Math.random()) * this.#speed(),
1584
+ })));
1490
1585
  }
1491
1586
  onBeforeRender({ state, object }) {
1492
- const clouds = this.get('clouds');
1587
+ const clouds = this.clouds();
1493
1588
  object.children.forEach((cloud, index) => {
1494
1589
  cloud.children[0].rotation.z += clouds[index].rotation;
1495
1590
  cloud.children[0].scale.setScalar(clouds[index].scale + (((1 + Math.sin(state.clock.getElapsedTime() / 10)) / 2) * index) / 10);
1496
1591
  });
1497
1592
  }
1498
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCloud, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
1593
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCloud, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1499
1594
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsCloud, isStandalone: true, selector: "ngts-cloud", inputs: { groupRef: "groupRef", opacity: "opacity", speed: "speed", width: "width", depth: "depth", segments: "segments", texture: "texture", color: "color", depthTest: "depthTest" }, usesInheritance: true, ngImport: i0, template: `
1500
1595
  <ngt-group ngtCompound [ref]="groupRef">
1501
1596
  <ngt-group
1502
- [position]="[0, 0, (get('segments') / 2) * get('depth')]"
1503
- (beforeRender)="onBeforeRender($any($event))"
1597
+ [position]="[0, 0, (cloudSegments() / 2) * cloudDepth()]"
1598
+ (beforeRender)="onBeforeRender($event)"
1504
1599
  >
1505
1600
  <ngts-billboard
1506
- *ngFor="let cloud of clouds$ | ngtPush : []; let i = index"
1507
- [position]="[cloud.x, cloud.y, -i * get('depth')]"
1601
+ *ngFor="let cloud of clouds(); let i = index"
1602
+ [position]="[cloud.x, cloud.y, -i * cloudDepth()]"
1508
1603
  >
1509
1604
  <ngt-mesh [scale]="cloud.scale" [rotation]="[0, 0, 0]">
1510
1605
  <ngt-plane-geometry />
1511
1606
  <!-- we use ngIf here for texture because by the time ngt-value is initialized -->
1512
- <!-- [map] has not been resolved yet. we ngIf it so that texture is available before -->
1607
+ <!-- [map] has not been resolved yet. we ngIf it so that texture is available before hand -->
1513
1608
  <ngt-mesh-standard-material
1514
- *ngIf="cloudTexture$ | ngtPush as cloudTexture"
1609
+ *ngIf="cloudTexture() as cloudTexture"
1515
1610
  [transparent]="true"
1516
1611
  [map]="cloudTexture"
1517
- [depthTest]="get('depthTest')"
1518
- [opacity]="(cloud.scale / 6) * cloud.density * get('opacity')"
1519
- [color]="get('color')"
1612
+ [depthTest]="cloudDepthTest()"
1613
+ [opacity]="(cloud.scale / 6) * cloud.density * cloudOpacity()"
1614
+ [color]="cloudColor()"
1520
1615
  >
1521
- <ngt-value [rawValue]="encoding" attach="map.encoding" />
1616
+ <ngt-value [rawValue]="encoding()" attach="map.encoding" />
1522
1617
  </ngt-mesh-standard-material>
1523
1618
  </ngt-mesh>
1524
1619
  </ngts-billboard>
1525
1620
  </ngt-group>
1526
1621
  </ngt-group>
1527
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "pipe", type: NgtPush, name: "ngtPush" }, { kind: "component", type: NgtsBillboard, selector: "ngts-billboard", inputs: ["billboardRef", "follow", "lockX", "lockY", "lockZ"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1622
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: NgtsBillboard, selector: "ngts-billboard", inputs: ["billboardRef", "follow", "lockX", "lockY", "lockZ"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
1528
1623
  }
1529
1624
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsCloud, decorators: [{
1530
1625
  type: Component,
@@ -1534,36 +1629,36 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1534
1629
  template: `
1535
1630
  <ngt-group ngtCompound [ref]="groupRef">
1536
1631
  <ngt-group
1537
- [position]="[0, 0, (get('segments') / 2) * get('depth')]"
1538
- (beforeRender)="onBeforeRender($any($event))"
1632
+ [position]="[0, 0, (cloudSegments() / 2) * cloudDepth()]"
1633
+ (beforeRender)="onBeforeRender($event)"
1539
1634
  >
1540
1635
  <ngts-billboard
1541
- *ngFor="let cloud of clouds$ | ngtPush : []; let i = index"
1542
- [position]="[cloud.x, cloud.y, -i * get('depth')]"
1636
+ *ngFor="let cloud of clouds(); let i = index"
1637
+ [position]="[cloud.x, cloud.y, -i * cloudDepth()]"
1543
1638
  >
1544
1639
  <ngt-mesh [scale]="cloud.scale" [rotation]="[0, 0, 0]">
1545
1640
  <ngt-plane-geometry />
1546
1641
  <!-- we use ngIf here for texture because by the time ngt-value is initialized -->
1547
- <!-- [map] has not been resolved yet. we ngIf it so that texture is available before -->
1642
+ <!-- [map] has not been resolved yet. we ngIf it so that texture is available before hand -->
1548
1643
  <ngt-mesh-standard-material
1549
- *ngIf="cloudTexture$ | ngtPush as cloudTexture"
1644
+ *ngIf="cloudTexture() as cloudTexture"
1550
1645
  [transparent]="true"
1551
1646
  [map]="cloudTexture"
1552
- [depthTest]="get('depthTest')"
1553
- [opacity]="(cloud.scale / 6) * cloud.density * get('opacity')"
1554
- [color]="get('color')"
1647
+ [depthTest]="cloudDepthTest()"
1648
+ [opacity]="(cloud.scale / 6) * cloud.density * cloudOpacity()"
1649
+ [color]="cloudColor()"
1555
1650
  >
1556
- <ngt-value [rawValue]="encoding" attach="map.encoding" />
1651
+ <ngt-value [rawValue]="encoding()" attach="map.encoding" />
1557
1652
  </ngt-mesh-standard-material>
1558
1653
  </ngt-mesh>
1559
1654
  </ngts-billboard>
1560
1655
  </ngt-group>
1561
1656
  </ngt-group>
1562
1657
  `,
1563
- imports: [NgFor, NgtPush, NgtsBillboard, NgIf],
1658
+ imports: [NgFor, NgtsBillboard, NgIf],
1564
1659
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
1565
1660
  }]
1566
- }], propDecorators: { groupRef: [{
1661
+ }], ctorParameters: function () { return []; }, propDecorators: { groupRef: [{
1567
1662
  type: Input
1568
1663
  }], opacity: [{
1569
1664
  type: Input
@@ -1584,7 +1679,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1584
1679
  }] } });
1585
1680
 
1586
1681
  extend({ Group, Mesh, MeshBasicMaterial, OrthographicCamera });
1587
- class NgtsContactShadows extends NgtRxStore {
1682
+ class NgtsContactShadows extends NgtSignalStore {
1588
1683
  set opacity(opacity) {
1589
1684
  this.set({ opacity });
1590
1685
  }
@@ -1619,21 +1714,19 @@ class NgtsContactShadows extends NgtRxStore {
1619
1714
  this.set({ depthWrite });
1620
1715
  }
1621
1716
  set renderOrder(renderOrder) {
1622
- this.set({ renderOrder });
1623
- }
1624
- constructor() {
1625
- super();
1626
- this.store = inject(NgtStore);
1627
- this.shadowCameraRef = injectNgtRef();
1628
- this.encoding = this.store.get('gl', 'outputEncoding');
1629
- this.contactShadows$ = this.select('contactShadows');
1630
- this.Math = Math;
1631
- this.contactShadowsRef = injectNgtRef();
1632
- injectBeforeRender(this.onBeforeRender.bind(this, 0));
1717
+ this.set({ renderOrder });
1633
1718
  }
1634
- initialize() {
1635
- super.initialize();
1636
- this.set({
1719
+ #store;
1720
+ #scale;
1721
+ #width;
1722
+ #height;
1723
+ #far;
1724
+ #resolution;
1725
+ #color;
1726
+ #scaledWidth;
1727
+ #scaledHeight;
1728
+ constructor() {
1729
+ super({
1637
1730
  scale: 10,
1638
1731
  frames: Infinity,
1639
1732
  opacity: 1,
@@ -1647,16 +1740,40 @@ class NgtsContactShadows extends NgtRxStore {
1647
1740
  depthWrite: false,
1648
1741
  renderOrder: 0,
1649
1742
  });
1650
- this.connect('scaledWidth', this.select(['width', 'scale'], ({ width, scale }) => width * (Array.isArray(scale) ? scale[0] : scale || 1)));
1651
- this.connect('scaledHeight', this.select(['height', 'scale'], ({ height, scale }) => height * (Array.isArray(scale) ? scale[1] : scale || 1)));
1652
- this.connect('cameraArgs', this.select(['scaledWidth', 'scaledHeight', 'far'], ({ scaledWidth: width, scaledHeight: height, far }) => {
1653
- return [-width / 2, width / 2, height / 2, -height / 2, 0, far];
1654
- }));
1655
- this.connect('contactShadows', this.select(['resolution', 'scaledWidth', 'scaledHeight', 'scale', 'color'], ({ resolution, scaledWidth: width, scaledHeight: height, color }) => {
1743
+ this.contactShadowsRef = injectNgtRef();
1744
+ this.Math = Math;
1745
+ this.#store = inject(NgtStore);
1746
+ this.shadowCameraRef = injectNgtRef();
1747
+ this.#scale = this.select('scale');
1748
+ this.#width = this.select('width');
1749
+ this.#height = this.select('height');
1750
+ this.#far = this.select('far');
1751
+ this.#resolution = this.select('resolution');
1752
+ this.#color = this.select('color');
1753
+ this.#scaledWidth = computed(() => {
1754
+ const scale = this.#scale();
1755
+ return this.#width() * (Array.isArray(scale) ? scale[0] : scale || 1);
1756
+ });
1757
+ this.#scaledHeight = computed(() => {
1758
+ const scale = this.#scale();
1759
+ return this.#height() * (Array.isArray(scale) ? scale[1] : scale || 1);
1760
+ });
1761
+ this.encoding = this.#store.select('gl', 'outputEncoding');
1762
+ this.shadowRenderOrder = this.select('renderOrder');
1763
+ this.shadowOpacity = this.select('opacity');
1764
+ this.shadowDepthWrite = this.select('depthWrite');
1765
+ this.cameraArgs = computed(() => {
1766
+ const width = this.#scaledWidth();
1767
+ const height = this.#scaledHeight();
1768
+ return [-width / 2, width / 2, height / 2, -height / 2, 0, this.#far()];
1769
+ });
1770
+ this.contactShadows = computed(() => {
1771
+ const color = this.#color();
1772
+ const resolution = this.#resolution();
1656
1773
  const renderTarget = new THREE.WebGLRenderTarget(resolution, resolution);
1657
1774
  const renderTargetBlur = new THREE.WebGLRenderTarget(resolution, resolution);
1658
1775
  renderTargetBlur.texture.generateMipmaps = renderTarget.texture.generateMipmaps = false;
1659
- const planeGeometry = new THREE.PlaneGeometry(width, height).rotateX(Math.PI / 2);
1776
+ const planeGeometry = new THREE.PlaneGeometry(this.#scaledWidth(), this.#scaledHeight()).rotateX(Math.PI / 2);
1660
1777
  const blurPlane = new Mesh(planeGeometry);
1661
1778
  const depthMaterial = new THREE.MeshDepthMaterial();
1662
1779
  depthMaterial.depthTest = depthMaterial.depthWrite = false;
@@ -1667,8 +1784,8 @@ class NgtsContactShadows extends NgtRxStore {
1667
1784
  };
1668
1785
  shader.fragmentShader = shader.fragmentShader.replace(`void main() {`, //
1669
1786
  `uniform vec3 ucolor;
1670
- void main() {
1671
- `);
1787
+ void main() {
1788
+ `);
1672
1789
  shader.fragmentShader = shader.fragmentShader.replace('vec4( vec3( 1.0 - fragCoordZ ), opacity );',
1673
1790
  // Colorize the shadow, multiply by the falloff so that the center can remain darker
1674
1791
  'vec4( ucolor * fragCoordZ * 2.0, ( 1.0 - fragCoordZ ) * 1.0 );');
@@ -1685,65 +1802,67 @@ class NgtsContactShadows extends NgtRxStore {
1685
1802
  verticalBlurMaterial,
1686
1803
  renderTargetBlur,
1687
1804
  };
1688
- }));
1805
+ });
1806
+ injectBeforeRender(this.#onBeforeRender.bind(this, 0));
1689
1807
  }
1690
- onBeforeRender(count, { scene, gl }) {
1691
- const { frames, blur, contactShadows: { depthMaterial, renderTarget }, smooth, } = this.get();
1692
- if (this.shadowCameraRef.nativeElement && (frames === Infinity || count < frames)) {
1808
+ #onBeforeRender(count, { scene, gl }) {
1809
+ const { frames = Infinity, blur = 1, smooth = true } = this.get();
1810
+ const { depthMaterial, renderTarget } = this.contactShadows();
1811
+ const shadowCamera = this.shadowCameraRef.nativeElement;
1812
+ if (shadowCamera && (frames === Infinity || count < frames)) {
1693
1813
  const initialBackground = scene.background;
1694
1814
  scene.background = null;
1695
1815
  const initialOverrideMaterial = scene.overrideMaterial;
1696
1816
  scene.overrideMaterial = depthMaterial;
1697
1817
  gl.setRenderTarget(renderTarget);
1698
- gl.render(scene, this.shadowCameraRef.nativeElement);
1818
+ gl.render(scene, shadowCamera);
1699
1819
  scene.overrideMaterial = initialOverrideMaterial;
1700
- this.blurShadows(blur);
1820
+ this.#blurShadows(blur);
1701
1821
  if (smooth)
1702
- this.blurShadows(blur * 0.4);
1822
+ this.#blurShadows(blur * 0.4);
1703
1823
  gl.setRenderTarget(null);
1704
1824
  scene.background = initialBackground;
1705
1825
  count++;
1706
1826
  }
1707
1827
  }
1708
- blurShadows(blur) {
1709
- const { blurPlane, horizontalBlurMaterial, verticalBlurMaterial, renderTargetBlur, renderTarget } = this.get('contactShadows');
1710
- const gl = this.store.get('gl');
1828
+ #blurShadows(blur) {
1829
+ const { blurPlane, horizontalBlurMaterial, verticalBlurMaterial, renderTargetBlur, renderTarget } = this.contactShadows();
1830
+ const gl = this.#store.get('gl');
1831
+ const shadowCamera = this.shadowCameraRef.nativeElement;
1711
1832
  blurPlane.visible = true;
1712
1833
  blurPlane.material = horizontalBlurMaterial;
1713
- horizontalBlurMaterial.uniforms.tDiffuse.value = renderTarget.texture;
1714
- horizontalBlurMaterial.uniforms.h.value = (blur * 1) / 256;
1834
+ horizontalBlurMaterial.uniforms['tDiffuse'].value = renderTarget.texture;
1835
+ horizontalBlurMaterial.uniforms['h'].value = (blur * 1) / 256;
1715
1836
  gl.setRenderTarget(renderTargetBlur);
1716
- gl.render(blurPlane, this.shadowCameraRef.nativeElement);
1837
+ gl.render(blurPlane, shadowCamera);
1717
1838
  blurPlane.material = verticalBlurMaterial;
1718
- verticalBlurMaterial.uniforms.tDiffuse.value = renderTargetBlur.texture;
1719
- verticalBlurMaterial.uniforms.v.value = (blur * 1) / 256;
1839
+ verticalBlurMaterial.uniforms['tDiffuse'].value = renderTargetBlur.texture;
1840
+ verticalBlurMaterial.uniforms['v'].value = (blur * 1) / 256;
1720
1841
  gl.setRenderTarget(renderTarget);
1721
- gl.render(blurPlane, this.shadowCameraRef.nativeElement);
1842
+ gl.render(blurPlane, shadowCamera);
1722
1843
  blurPlane.visible = false;
1723
1844
  }
1724
1845
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsContactShadows, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1725
1846
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsContactShadows, isStandalone: true, selector: "ngts-contact-shadows", inputs: { contactShadowsRef: "contactShadowsRef", opacity: "opacity", width: "width", height: "height", blur: "blur", far: "far", smooth: "smooth", resolution: "resolution", frames: "frames", scale: "scale", color: "color", depthWrite: "depthWrite", renderOrder: "renderOrder" }, usesInheritance: true, ngImport: i0, template: `
1726
1847
  <ngt-group ngtCompound [ref]="contactShadowsRef" [rotation]="[Math.PI / 2, 0, 0]">
1727
- <ng-container *ngIf="contactShadows$ | ngtPush : null as contactShadows">
1728
- <ngt-mesh
1729
- [renderOrder]="get('renderOrder')"
1730
- [geometry]="contactShadows.planeGeometry"
1731
- [scale]="[1, -1, 1]"
1732
- [rotation]="[-Math.PI / 2, 0, 0]"
1848
+ <ngt-mesh
1849
+ [renderOrder]="shadowRenderOrder() ?? 0"
1850
+ [geometry]="contactShadows().planeGeometry"
1851
+ [scale]="[1, -1, 1]"
1852
+ [rotation]="[-Math.PI / 2, 0, 0]"
1853
+ >
1854
+ <ngt-mesh-basic-material
1855
+ [map]="contactShadows().renderTarget.texture"
1856
+ [transparent]="true"
1857
+ [opacity]="shadowOpacity() ?? 1"
1858
+ [depthWrite]="shadowDepthWrite() ?? false"
1733
1859
  >
1734
- <ngt-mesh-basic-material
1735
- [map]="contactShadows.renderTarget.texture"
1736
- [transparent]="true"
1737
- [opacity]="get('opacity')"
1738
- [depthWrite]="get('depthWrite')"
1739
- >
1740
- <ngt-value [rawValue]="encoding" attach="map.encoding" />
1741
- </ngt-mesh-basic-material>
1742
- </ngt-mesh>
1743
- <ngt-orthographic-camera *args="get('cameraArgs')" [ref]="shadowCameraRef" />
1744
- </ng-container>
1860
+ <ngt-value [rawValue]="encoding()" attach="map.encoding" />
1861
+ </ngt-mesh-basic-material>
1862
+ </ngt-mesh>
1863
+ <ngt-orthographic-camera *args="cameraArgs()" [ref]="shadowCameraRef" />
1745
1864
  </ngt-group>
1746
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: NgtPush, name: "ngtPush" }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
1865
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
1747
1866
  }
1748
1867
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsContactShadows, decorators: [{
1749
1868
  type: Component,
@@ -1752,27 +1871,25 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1752
1871
  standalone: true,
1753
1872
  template: `
1754
1873
  <ngt-group ngtCompound [ref]="contactShadowsRef" [rotation]="[Math.PI / 2, 0, 0]">
1755
- <ng-container *ngIf="contactShadows$ | ngtPush : null as contactShadows">
1756
- <ngt-mesh
1757
- [renderOrder]="get('renderOrder')"
1758
- [geometry]="contactShadows.planeGeometry"
1759
- [scale]="[1, -1, 1]"
1760
- [rotation]="[-Math.PI / 2, 0, 0]"
1874
+ <ngt-mesh
1875
+ [renderOrder]="shadowRenderOrder() ?? 0"
1876
+ [geometry]="contactShadows().planeGeometry"
1877
+ [scale]="[1, -1, 1]"
1878
+ [rotation]="[-Math.PI / 2, 0, 0]"
1879
+ >
1880
+ <ngt-mesh-basic-material
1881
+ [map]="contactShadows().renderTarget.texture"
1882
+ [transparent]="true"
1883
+ [opacity]="shadowOpacity() ?? 1"
1884
+ [depthWrite]="shadowDepthWrite() ?? false"
1761
1885
  >
1762
- <ngt-mesh-basic-material
1763
- [map]="contactShadows.renderTarget.texture"
1764
- [transparent]="true"
1765
- [opacity]="get('opacity')"
1766
- [depthWrite]="get('depthWrite')"
1767
- >
1768
- <ngt-value [rawValue]="encoding" attach="map.encoding" />
1769
- </ngt-mesh-basic-material>
1770
- </ngt-mesh>
1771
- <ngt-orthographic-camera *args="get('cameraArgs')" [ref]="shadowCameraRef" />
1772
- </ng-container>
1886
+ <ngt-value [rawValue]="encoding()" attach="map.encoding" />
1887
+ </ngt-mesh-basic-material>
1888
+ </ngt-mesh>
1889
+ <ngt-orthographic-camera *args="cameraArgs()" [ref]="shadowCameraRef" />
1773
1890
  </ngt-group>
1774
1891
  `,
1775
- imports: [NgIf, NgtPush, NgtArgs],
1892
+ imports: [NgtArgs],
1776
1893
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
1777
1894
  }]
1778
1895
  }], ctorParameters: function () { return []; }, propDecorators: { contactShadowsRef: [{
@@ -1816,10 +1933,30 @@ const ngtsEnvironmentPresetsObj = {
1816
1933
  lobby: 'st-fagans/st_fagans_interior_1k.hdr',
1817
1934
  };
1818
1935
 
1819
- class NgtsEnvironmentInputs extends NgtRxStore {
1936
+ class NgtsEnvironmentInput extends NgtSignalStore {
1820
1937
  constructor() {
1821
1938
  super(...arguments);
1822
- this.store = inject(NgtStore);
1939
+ this.environmentFrames = this.select('frames');
1940
+ this.environmentNear = this.select('near');
1941
+ this.environmentFar = this.select('far');
1942
+ this.environmentResolution = this.select('resolution');
1943
+ this.environmentBackground = this.select('background');
1944
+ this.environmentBlur = this.select('blur');
1945
+ this.environmentMap = this.select('map');
1946
+ this.environmentFiles = this.select('files');
1947
+ this.environmentPath = this.select('path');
1948
+ this.environmentPreset = this.select('preset');
1949
+ this.environmentScene = this.select('scene');
1950
+ this.environmentExtensions = this.select('extensions');
1951
+ this.environmentGround = this.select('ground');
1952
+ this.environmentEncoding = this.select('encoding');
1953
+ this.environmentParams = computed(() => ({
1954
+ files: this.environmentFiles(),
1955
+ path: this.environmentPath(),
1956
+ preset: this.environmentPreset(),
1957
+ extensions: this.environmentExtensions(),
1958
+ encoding: this.environmentEncoding(),
1959
+ }));
1823
1960
  }
1824
1961
  set frames(frames) {
1825
1962
  this.set({ frames });
@@ -1863,10 +2000,10 @@ class NgtsEnvironmentInputs extends NgtRxStore {
1863
2000
  set encoding(encoding) {
1864
2001
  this.set({ encoding });
1865
2002
  }
1866
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentInputs, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1867
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentInputs, inputs: { frames: "frames", near: "near", far: "far", resolution: "resolution", background: "background", blur: "blur", map: "map", files: "files", path: "path", preset: "preset", scene: "scene", extensions: "extensions", ground: "ground", encoding: "encoding" }, usesInheritance: true, ngImport: i0 }); }
2003
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentInput, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2004
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentInput, inputs: { frames: "frames", near: "near", far: "far", resolution: "resolution", background: "background", blur: "blur", map: "map", files: "files", path: "path", preset: "preset", scene: "scene", extensions: "extensions", ground: "ground", encoding: "encoding" }, usesInheritance: true, ngImport: i0 }); }
1868
2005
  }
1869
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentInputs, decorators: [{
2006
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentInput, decorators: [{
1870
2007
  type: Directive
1871
2008
  }], propDecorators: { frames: [{
1872
2009
  type: Input
@@ -1922,72 +2059,93 @@ function setEnvProps(background, scene, defaultScene, texture, blur = 0) {
1922
2059
  };
1923
2060
  }
1924
2061
  const CUBEMAP_ROOT = 'https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/hdris/';
1925
- function injectNgtsEnvironment(paramsFactory) {
1926
- let p = {
1927
- files: ['/px.png', '/nx.png', '/py.png', '/ny.png', '/pz.png', '/nz.png'],
1928
- path: '',
1929
- preset: undefined,
1930
- encoding: undefined,
1931
- };
1932
- const params = paramsFactory(p);
1933
- const params$ = isObservable(params) ? params : of(params);
1934
- const textureRef = injectNgtRef();
1935
- const { destroy$ } = injectNgtDestroy(() => {
1936
- textureRef.nativeElement?.dispose();
1937
- });
1938
- const loaderResult = injectNgtLoader((inputs) => (Array.isArray(inputs) ? CubeTextureLoader : RGBELoader), params$.pipe(debounceTime(0), map((data) => {
1939
- p = data;
1940
- return p;
1941
- }), map((data) => {
1942
- if (data.preset) {
1943
- if (!(data.preset in ngtsEnvironmentPresetsObj))
1944
- throw new Error('Preset must be one of: ' + Object.keys(ngtsEnvironmentPresetsObj).join(', '));
1945
- data.files = ngtsEnvironmentPresetsObj[data.preset];
1946
- data.path = CUBEMAP_ROOT;
1947
- }
1948
- return Array.isArray(data.files) ? [data.files] : data.files;
1949
- })), (loader) => {
1950
- if (p.path) {
1951
- loader.setPath(p.path);
1952
- }
1953
- if (p.extensions) {
1954
- p.extensions(loader);
1955
- }
1956
- });
1957
- loaderResult.pipe(takeUntil(destroy$)).subscribe((results) => {
1958
- const texture = Array.isArray(p.files) ? results[0] : results;
1959
- texture.mapping = Array.isArray(p.files) ? CubeReflectionMapping : EquirectangularReflectionMapping;
1960
- texture.encoding = (p.encoding ?? Array.isArray(p.files)) ? sRGBEncoding : LinearEncoding;
1961
- textureRef.nativeElement = texture;
2062
+ function injectNgtsEnvironment(paramsFactory, injector) {
2063
+ injector = assertInjectionContext(injectNgtsEnvironment, injector);
2064
+ return runInInjectionContext(injector, () => {
2065
+ const cdr = inject(ChangeDetectorRef);
2066
+ const textureRef = injectNgtRef();
2067
+ inject(DestroyRef).onDestroy(() => {
2068
+ textureRef.untracked.dispose();
2069
+ });
2070
+ const params = computed(() => {
2071
+ let { files, preset, encoding, path, extensions } = paramsFactory();
2072
+ if (files == null) {
2073
+ files = ['/px.png', '/nx.png', '/py.png', '/ny.png', '/pz.png', '/nz.png'];
2074
+ }
2075
+ if (path == null) {
2076
+ path = '';
2077
+ }
2078
+ if (preset) {
2079
+ if (!(preset in ngtsEnvironmentPresetsObj))
2080
+ throw new Error('Preset must be one of: ' + Object.keys(ngtsEnvironmentPresetsObj).join(', '));
2081
+ files = ngtsEnvironmentPresetsObj[preset];
2082
+ path = CUBEMAP_ROOT;
2083
+ }
2084
+ return { files, preset, encoding, path, extensions };
2085
+ });
2086
+ const loaderResult = injectNgtLoader(
2087
+ // @ts-expect-error
2088
+ () => {
2089
+ const { files } = params();
2090
+ return Array.isArray(files) ? CubeTextureLoader : RGBELoader;
2091
+ }, () => {
2092
+ const { files } = params();
2093
+ return Array.isArray(files) ? [files] : files;
2094
+ }, {
2095
+ extensions: (loader) => {
2096
+ const { path, extensions } = params();
2097
+ loader.setPath(path);
2098
+ if (extensions)
2099
+ extensions(loader);
2100
+ },
2101
+ });
2102
+ effect(() => {
2103
+ const result = loaderResult();
2104
+ if (!result)
2105
+ return;
2106
+ const { files, encoding } = params();
2107
+ const texture = Array.isArray(files) ? result[0] : result;
2108
+ texture.mapping = Array.isArray(files) ? CubeReflectionMapping : EquirectangularReflectionMapping;
2109
+ texture.encoding = encoding ?? Array.isArray(files) ? sRGBEncoding : LinearEncoding;
2110
+ textureRef.nativeElement = texture;
2111
+ safeDetectChanges(cdr);
2112
+ }, { allowSignalWrites: true });
2113
+ return textureRef;
1962
2114
  });
1963
- return textureRef;
1964
2115
  }
1965
2116
 
1966
- class NgtsEnvironmentCube extends NgtsEnvironmentInputs {
1967
- constructor() {
1968
- super(...arguments);
1969
- this.textureRef = injectNgtsEnvironment((params) => this.select().pipe(startWith(params)));
1970
- }
1971
- initialize() {
1972
- super.initialize();
1973
- this.set({ background: false });
2117
+ class NgtsEnvironmentCube {
2118
+ #store;
2119
+ set background(background) {
2120
+ this.environmentInput.set({ background });
1974
2121
  }
1975
- ngOnInit() {
1976
- this.setEnvProps();
2122
+ constructor() {
2123
+ this.environmentInput = inject(NgtsEnvironmentInput);
2124
+ this.#store = inject(NgtStore);
2125
+ this.textureRef = injectNgtsEnvironment(this.environmentInput.environmentParams);
2126
+ this.environmentInput.patch({ background: false });
2127
+ requestAnimationInInjectionContext(() => {
2128
+ this.#setEnvProps();
2129
+ });
1977
2130
  }
1978
- setEnvProps() {
1979
- this.effect(combineLatest([
1980
- this.store.select('scene'),
1981
- this.select('scene').pipe(startWithUndefined()),
1982
- this.select('background'),
1983
- this.select('blur').pipe(startWithUndefined()),
1984
- this.textureRef.$,
1985
- ]), ([defaultScene, scene, background, blur, texture]) => {
1986
- return setEnvProps(background, scene, defaultScene, texture, blur);
2131
+ #setEnvProps() {
2132
+ const scene = this.#store.select('scene');
2133
+ const trigger = computed(() => ({
2134
+ defaultScene: scene(),
2135
+ scene: this.environmentInput.environmentScene(),
2136
+ background: this.environmentInput.environmentBackground(),
2137
+ blur: this.environmentInput.environmentBlur(),
2138
+ texture: this.textureRef.nativeElement,
2139
+ }));
2140
+ effect((onCleanup) => {
2141
+ const { background, defaultScene, scene, blur, texture } = trigger();
2142
+ if (!texture)
2143
+ return;
2144
+ onCleanup(setEnvProps(background, scene, defaultScene, texture, blur));
1987
2145
  });
1988
2146
  }
1989
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentCube, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
1990
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentCube, isStandalone: true, selector: "ngts-environment-cube", usesInheritance: true, ngImport: i0 }); }
2147
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentCube, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2148
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentCube, isStandalone: true, selector: "ngts-environment-cube", inputs: { background: "background" }, ngImport: i0 }); }
1991
2149
  }
1992
2150
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentCube, decorators: [{
1993
2151
  type: Directive,
@@ -1995,31 +2153,44 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
1995
2153
  selector: 'ngts-environment-cube',
1996
2154
  standalone: true,
1997
2155
  }]
1998
- }] });
2156
+ }], ctorParameters: function () { return []; }, propDecorators: { background: [{
2157
+ type: Input
2158
+ }] } });
1999
2159
 
2000
- class NgtsEnvironmentMap extends NgtsEnvironmentInputs {
2001
- initialize() {
2002
- super.initialize();
2003
- this.set({ background: false });
2004
- }
2005
- ngOnInit() {
2006
- this.setEnvProps();
2007
- }
2008
- setEnvProps() {
2009
- this.effect(combineLatest([
2010
- this.store.select('scene'),
2011
- this.select('map'),
2012
- this.select('scene').pipe(startWithUndefined()),
2013
- this.select('background'),
2014
- this.select('blur').pipe(startWithUndefined()),
2015
- ]), ([defaultScene, map, scene, background, blur]) => {
2016
- if (map) {
2017
- return setEnvProps(background, scene, defaultScene, map, blur);
2018
- }
2160
+ class NgtsEnvironmentMap {
2161
+ #store;
2162
+ set map(map) {
2163
+ this.environmentInput.set({ map });
2164
+ }
2165
+ set background(background) {
2166
+ this.environmentInput.set({ background });
2167
+ }
2168
+ constructor() {
2169
+ this.environmentInput = inject(NgtsEnvironmentInput);
2170
+ this.#store = inject(NgtStore);
2171
+ this.environmentInput.patch({ background: false });
2172
+ requestAnimationInInjectionContext(() => {
2173
+ this.#setEnvProps();
2174
+ });
2175
+ }
2176
+ #setEnvProps() {
2177
+ const scene = this.#store.select('scene');
2178
+ const trigger = computed(() => ({
2179
+ defaultScene: scene(),
2180
+ scene: this.environmentInput.environmentScene(),
2181
+ background: this.environmentInput.environmentBackground(),
2182
+ blur: this.environmentInput.environmentBlur(),
2183
+ texture: this.environmentInput.environmentMap(),
2184
+ }));
2185
+ effect((onCleanup) => {
2186
+ const { background, defaultScene, scene, blur, texture } = trigger();
2187
+ if (!texture)
2188
+ return;
2189
+ onCleanup(setEnvProps(background, scene, defaultScene, texture, blur));
2019
2190
  });
2020
2191
  }
2021
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentMap, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2022
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentMap, isStandalone: true, selector: "ngts-environment-map", usesInheritance: true, ngImport: i0 }); }
2192
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentMap, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
2193
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentMap, isStandalone: true, selector: "ngts-environment-map", inputs: { map: "map", background: "background" }, ngImport: i0 }); }
2023
2194
  }
2024
2195
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentMap, decorators: [{
2025
2196
  type: Directive,
@@ -2027,38 +2198,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2027
2198
  selector: 'ngts-environment-map',
2028
2199
  standalone: true,
2029
2200
  }]
2030
- }] });
2201
+ }], ctorParameters: function () { return []; }, propDecorators: { map: [{
2202
+ type: Input
2203
+ }], background: [{
2204
+ type: Input
2205
+ }] } });
2031
2206
 
2032
2207
  extend({ GroundProjectedEnv });
2033
- class NgtsEnvironmentGround extends NgtsEnvironmentInputs {
2208
+ class NgtsEnvironmentGround {
2034
2209
  constructor() {
2035
- super(...arguments);
2036
- this.defaultTexture = injectNgtsEnvironment((params) => this.select().pipe(startWith(params)));
2037
- }
2038
- ngOnInit() {
2039
- this.connect('texture', combineLatest([this.select('map').pipe(startWithUndefined()), this.defaultTexture.$]).pipe(map(([map, texture]) => map || texture)));
2040
- this.connect('groundArgs', this.select('texture').pipe(map((texture) => [texture])));
2041
- this.connect('groundHeight', this.select(['ground'], ({ ground }) => ground?.height));
2042
- this.connect('groundRadius', this.select(['ground'], ({ ground }) => ground?.radius));
2043
- this.connect('groundScale', this.select(['ground'], ({ ground }) => ground?.scale ?? 1000));
2044
- }
2045
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentGround, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2046
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentGround, isStandalone: true, selector: "ngts-environment-ground", usesInheritance: true, ngImport: i0, template: `
2047
- <ngts-environment-map
2048
- [background]="get('background')"
2049
- [blur]="get('blur')"
2050
- [scene]="get('scene')"
2051
- [map]="get('texture')"
2052
- />
2053
- <ng-container *ngIf="get('groundArgs') as groundArgs">
2054
- <ngt-ground-projected-env
2055
- *args="groundArgs"
2056
- [scale]="get('groundScale')"
2057
- [height]="get('groundHeight')"
2058
- [radius]="get('groundRadius')"
2059
- />
2060
- </ng-container>
2061
- `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
2210
+ this.environmentInput = inject(NgtsEnvironmentInput);
2211
+ this.#defaultTexture = injectNgtsEnvironment(this.environmentInput.environmentParams);
2212
+ this.texture = computed(() => {
2213
+ const defaultTexture = this.#defaultTexture.nativeElement;
2214
+ return this.environmentInput.environmentMap() || defaultTexture;
2215
+ });
2216
+ this.groundArgs = computed(() => (this.texture() ? [this.texture()] : []));
2217
+ this.height = computed(() => this.environmentInput.environmentGround()?.height);
2218
+ this.radius = computed(() => this.environmentInput.environmentGround()?.radius);
2219
+ this.scale = computed(() => this.environmentInput.environmentGround()?.scale ?? 1000);
2220
+ }
2221
+ #defaultTexture;
2222
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentGround, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2223
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentGround, isStandalone: true, selector: "ngts-environment-ground", ngImport: i0, template: `
2224
+ <ngts-environment-map [map]="texture()" [background]="!!environmentInput.environmentBackground()" />
2225
+ <ngt-ground-projected-env *args="groundArgs()" [scale]="scale()" [height]="height()" [radius]="radius()" />
2226
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map", inputs: ["map", "background"] }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
2062
2227
  }
2063
2228
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentGround, decorators: [{
2064
2229
  type: Component,
@@ -2066,94 +2231,104 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2066
2231
  selector: 'ngts-environment-ground',
2067
2232
  standalone: true,
2068
2233
  template: `
2069
- <ngts-environment-map
2070
- [background]="get('background')"
2071
- [blur]="get('blur')"
2072
- [scene]="get('scene')"
2073
- [map]="get('texture')"
2074
- />
2075
- <ng-container *ngIf="get('groundArgs') as groundArgs">
2076
- <ngt-ground-projected-env
2077
- *args="groundArgs"
2078
- [scale]="get('groundScale')"
2079
- [height]="get('groundHeight')"
2080
- [radius]="get('groundRadius')"
2081
- />
2082
- </ng-container>
2234
+ <ngts-environment-map [map]="texture()" [background]="!!environmentInput.environmentBackground()" />
2235
+ <ngt-ground-projected-env *args="groundArgs()" [scale]="scale()" [height]="height()" [radius]="radius()" />
2083
2236
  `,
2084
- imports: [NgtsEnvironmentMap, NgtArgs, NgIf],
2237
+ imports: [NgtsEnvironmentMap, NgtArgs],
2085
2238
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2086
2239
  }]
2087
2240
  }] });
2088
2241
 
2089
2242
  extend({ CubeCamera });
2090
- class NgtsEnvironmentPortal extends NgtsEnvironmentInputs {
2091
- initialize() {
2092
- super.initialize();
2093
- this.set({ near: 1, far: 1000, resolution: 256, frames: 1, background: false, preset: undefined });
2094
- this.connect('fbo', this.select(['resolution'], ({ resolution }) => {
2095
- const fbo = new THREE.WebGLCubeRenderTarget(resolution);
2096
- fbo.texture.type = HalfFloatType;
2097
- return fbo;
2098
- }));
2099
- this.connect('cameraArgs', this.select(['fbo', 'near', 'far'], ({ near, far, fbo }) => [near, far, fbo]));
2100
- }
2243
+ class NgtsEnvironmentPortal {
2244
+ #store;
2245
+ #fbo;
2101
2246
  constructor() {
2102
- super();
2247
+ this.environmentInput = inject(NgtsEnvironmentInput);
2248
+ this.#store = inject(NgtStore);
2103
2249
  this.virtualSceneRef = injectNgtRef(prepare(new THREE.Scene()));
2104
2250
  this.cubeCameraRef = injectNgtRef();
2105
- injectBeforeRender(this.onBeforeRender.bind(this, 1));
2106
- }
2107
- ngOnInit() {
2108
- this.setEnvProps();
2109
- }
2110
- setEnvProps() {
2111
- this.effect(combineLatest([
2112
- this.store.select('gl'),
2113
- this.store.select('scene'),
2114
- this.select('fbo'),
2115
- this.select('scene'),
2116
- this.select('background'),
2117
- this.select('frames'),
2118
- this.select('blur'),
2119
- this.virtualSceneRef.$,
2120
- this.cubeCameraRef.$,
2121
- ]), ([gl, defaultScene, fbo, scene, background, frames, blur, virtualScene, camera]) => {
2251
+ this.#fbo = computed(() => {
2252
+ const fbo = new THREE.WebGLCubeRenderTarget(this.environmentInput.environmentResolution());
2253
+ fbo.texture.type = THREE.HalfFloatType;
2254
+ return fbo;
2255
+ });
2256
+ this.cameraArgs = computed(() => [
2257
+ this.environmentInput.environmentNear(),
2258
+ this.environmentInput.environmentFar(),
2259
+ this.#fbo(),
2260
+ ]);
2261
+ this.environmentInput.patch({
2262
+ near: 1,
2263
+ far: 1000,
2264
+ resolution: 256,
2265
+ frames: 1,
2266
+ background: false,
2267
+ preset: undefined,
2268
+ });
2269
+ requestAnimationInInjectionContext(() => {
2270
+ this.#setEnvProps();
2271
+ });
2272
+ injectBeforeRender(this.#onBeforeRender.bind(this, 1));
2273
+ }
2274
+ #setEnvProps() {
2275
+ const gl = this.#store.select('gl');
2276
+ const scene = this.#store.select('scene');
2277
+ const trigger = computed(() => ({
2278
+ gl: gl(),
2279
+ defaultScene: scene(),
2280
+ fbo: this.#fbo(),
2281
+ scene: this.environmentInput.environmentScene(),
2282
+ background: this.environmentInput.environmentBackground(),
2283
+ frames: this.environmentInput.environmentFrames(),
2284
+ blur: this.environmentInput.environmentBlur(),
2285
+ virtualScene: this.virtualSceneRef.nativeElement,
2286
+ cubeCamera: this.cubeCameraRef.nativeElement,
2287
+ }));
2288
+ effect((onCleanup) => {
2289
+ const { virtualScene, blur, frames, background, scene, fbo, defaultScene, gl, cubeCamera } = trigger();
2290
+ if (!cubeCamera || !virtualScene)
2291
+ return;
2122
2292
  if (frames === 1)
2123
- camera.update(gl, virtualScene);
2124
- return setEnvProps(background, scene, defaultScene, fbo.texture, blur);
2293
+ cubeCamera.update(gl, virtualScene);
2294
+ onCleanup(setEnvProps(background, scene, defaultScene, fbo.texture, blur));
2125
2295
  });
2126
2296
  }
2127
- onBeforeRender(count, { gl }) {
2128
- const { frames } = this.get();
2297
+ #onBeforeRender(count, { gl }) {
2298
+ const { frames } = this.environmentInput.get();
2129
2299
  if (frames === Infinity || count < frames) {
2130
- if (this.cubeCameraRef.nativeElement) {
2131
- this.cubeCameraRef.nativeElement.update(gl, this.virtualSceneRef.nativeElement);
2300
+ const camera = this.cubeCameraRef.nativeElement;
2301
+ const virtualScene = this.virtualSceneRef.nativeElement;
2302
+ if (camera && virtualScene) {
2303
+ camera.update(gl, virtualScene);
2132
2304
  count++;
2133
2305
  }
2134
2306
  }
2135
2307
  }
2136
2308
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentPortal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2137
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentPortal, isStandalone: true, selector: "ngts-environment-portal", usesInheritance: true, ngImport: i0, template: `
2309
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironmentPortal, isStandalone: true, selector: "ngts-environment-portal", ngImport: i0, template: `
2138
2310
  <ngt-portal [container]="virtualSceneRef">
2139
2311
  <ng-template ngtPortalContent>
2140
2312
  <ng-content />
2141
- <ngt-cube-camera *args="get('cameraArgs')" [ref]="cubeCameraRef" />
2142
- <ng-container *ngIf="get('files') || get('preset'); else environmentMap">
2143
- <ngts-environment-cube
2144
- [background]="true"
2145
- [files]="get('files')"
2146
- [preset]="get('preset')"
2147
- [path]="get('path')"
2148
- [extensions]="get('extensions')"
2149
- />
2313
+ <ngt-cube-camera *args="cameraArgs()" [ref]="cubeCameraRef" />
2314
+ <ng-container
2315
+ *ngIf="
2316
+ environmentInput.environmentFiles() || environmentInput.environmentPreset();
2317
+ else environmentMap
2318
+ "
2319
+ >
2320
+ <ngts-environment-cube [background]="true" />
2150
2321
  </ng-container>
2151
2322
  <ng-template #environmentMap>
2152
- <ngts-environment-map [background]="true" [map]="get('map')" [extensions]="get('extensions')" />
2323
+ <ngts-environment-map
2324
+ *ngIf="environmentInput.environmentMap() as map"
2325
+ [background]="true"
2326
+ [map]="map"
2327
+ />
2153
2328
  </ng-template>
2154
2329
  </ng-template>
2155
2330
  </ngt-portal>
2156
- `, isInline: true, dependencies: [{ kind: "component", type: NgtPortal, selector: "ngt-portal", inputs: ["container", "state", "autoRender", "autoRenderPriority"], outputs: ["beforeRender"] }, { kind: "directive", type: NgtPortalContent, selector: "ng-template[ngtPortalContent]" }, { kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
2331
+ `, isInline: true, dependencies: [{ kind: "component", type: NgtPortal, selector: "ngt-portal", inputs: ["container", "state", "autoRender", "autoRenderPriority"], outputs: ["beforeRender"] }, { kind: "directive", type: NgtPortalContent, selector: "ng-template[ngtPortalContent]" }, { kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map", inputs: ["map", "background"] }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube", inputs: ["background"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
2157
2332
  }
2158
2333
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironmentPortal, decorators: [{
2159
2334
  type: Component,
@@ -2164,18 +2339,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2164
2339
  <ngt-portal [container]="virtualSceneRef">
2165
2340
  <ng-template ngtPortalContent>
2166
2341
  <ng-content />
2167
- <ngt-cube-camera *args="get('cameraArgs')" [ref]="cubeCameraRef" />
2168
- <ng-container *ngIf="get('files') || get('preset'); else environmentMap">
2169
- <ngts-environment-cube
2170
- [background]="true"
2171
- [files]="get('files')"
2172
- [preset]="get('preset')"
2173
- [path]="get('path')"
2174
- [extensions]="get('extensions')"
2175
- />
2342
+ <ngt-cube-camera *args="cameraArgs()" [ref]="cubeCameraRef" />
2343
+ <ng-container
2344
+ *ngIf="
2345
+ environmentInput.environmentFiles() || environmentInput.environmentPreset();
2346
+ else environmentMap
2347
+ "
2348
+ >
2349
+ <ngts-environment-cube [background]="true" />
2176
2350
  </ng-container>
2177
2351
  <ng-template #environmentMap>
2178
- <ngts-environment-map [background]="true" [map]="get('map')" [extensions]="get('extensions')" />
2352
+ <ngts-environment-map
2353
+ *ngIf="environmentInput.environmentMap() as map"
2354
+ [background]="true"
2355
+ [map]="map"
2356
+ />
2179
2357
  </ng-template>
2180
2358
  </ng-template>
2181
2359
  </ngt-portal>
@@ -2193,70 +2371,26 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2193
2371
  type: Directive,
2194
2372
  args: [{ selector: 'ng-template[ngtsEnvironmentContent]', standalone: true }]
2195
2373
  }] });
2196
- class NgtsEnvironment extends NgtsEnvironmentInputs {
2374
+ class NgtsEnvironment extends NgtsEnvironmentInput {
2197
2375
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironment, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2198
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironment, isStandalone: true, selector: "ngts-environment", queries: [{ propertyName: "content", first: true, predicate: NgtsEnvironmentContent, descendants: true, read: TemplateRef }], usesInheritance: true, ngImport: i0, template: `
2199
- <ngts-environment-ground
2200
- *ngIf="get('ground'); else noGround"
2201
- [ground]="get('ground')"
2202
- [map]="get('map')"
2203
- [scene]="get('scene')"
2204
- [blur]="get('blur')"
2205
- [background]="get('background')"
2206
- [preset]="get('preset')"
2207
- [frames]="get('frames')"
2208
- [far]="get('far')"
2209
- [near]="get('near')"
2210
- [resolution]="get('resolution')"
2211
- [files]="get('files')"
2212
- [path]="get('path')"
2213
- [extensions]="get('extensions')"
2214
- />
2376
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsEnvironment, isStandalone: true, selector: "ngts-environment", providers: [{ provide: NgtsEnvironmentInput, useExisting: NgtsEnvironment }], queries: [{ propertyName: "content", first: true, predicate: NgtsEnvironmentContent, descendants: true, read: TemplateRef }], usesInheritance: true, ngImport: i0, template: `
2377
+ <ngts-environment-ground *ngIf="environmentGround(); else noGround" />
2215
2378
  <ng-template #noGround>
2216
2379
  <ngts-environment-map
2217
- *ngIf="get('map'); else noMap"
2218
- [map]="get('map')"
2219
- [scene]="get('scene')"
2220
- [blur]="get('blur')"
2221
- [background]="get('background')"
2380
+ *ngIf="environmentMap() as map; else noMap"
2381
+ [map]="map"
2382
+ [background]="!!environmentBackground()"
2222
2383
  />
2223
2384
  <ng-template #noMap>
2224
- <ngts-environment-portal
2225
- *ngIf="content; else noPortal"
2226
- [frames]="get('frames')"
2227
- [far]="get('far')"
2228
- [near]="get('near')"
2229
- [resolution]="get('resolution')"
2230
- [map]="get('map')"
2231
- [background]="get('background')"
2232
- [blur]="get('blur')"
2233
- [scene]="get('scene')"
2234
- [files]="get('files')"
2235
- [path]="get('path')"
2236
- [preset]="get('preset')"
2237
- [extensions]="get('extensions')"
2238
- >
2385
+ <ngts-environment-portal *ngIf="content; else noPortal">
2239
2386
  <ng-container *ngTemplateOutlet="content" />
2240
2387
  </ngts-environment-portal>
2241
2388
  <ng-template #noPortal>
2242
- <ngts-environment-cube
2243
- [frames]="get('frames')"
2244
- [far]="get('far')"
2245
- [near]="get('near')"
2246
- [resolution]="get('resolution')"
2247
- [map]="get('map')"
2248
- [background]="get('background')"
2249
- [blur]="get('blur')"
2250
- [scene]="get('scene')"
2251
- [files]="get('files')"
2252
- [path]="get('path')"
2253
- [preset]="get('preset')"
2254
- [extensions]="get('extensions')"
2255
- />
2389
+ <ngts-environment-cube [background]="!!environmentBackground()" />
2256
2390
  </ng-template>
2257
2391
  </ng-template>
2258
2392
  </ng-template>
2259
- `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "component", type: NgtsEnvironmentGround, selector: "ngts-environment-ground" }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube" }, { kind: "component", type: NgtsEnvironmentPortal, selector: "ngts-environment-portal" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
2393
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map", inputs: ["map", "background"] }, { kind: "component", type: NgtsEnvironmentGround, selector: "ngts-environment-ground" }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube", inputs: ["background"] }, { kind: "component", type: NgtsEnvironmentPortal, selector: "ngts-environment-portal" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
2260
2394
  }
2261
2395
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsEnvironment, decorators: [{
2262
2396
  type: Component,
@@ -2264,63 +2398,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2264
2398
  selector: 'ngts-environment',
2265
2399
  standalone: true,
2266
2400
  template: `
2267
- <ngts-environment-ground
2268
- *ngIf="get('ground'); else noGround"
2269
- [ground]="get('ground')"
2270
- [map]="get('map')"
2271
- [scene]="get('scene')"
2272
- [blur]="get('blur')"
2273
- [background]="get('background')"
2274
- [preset]="get('preset')"
2275
- [frames]="get('frames')"
2276
- [far]="get('far')"
2277
- [near]="get('near')"
2278
- [resolution]="get('resolution')"
2279
- [files]="get('files')"
2280
- [path]="get('path')"
2281
- [extensions]="get('extensions')"
2282
- />
2401
+ <ngts-environment-ground *ngIf="environmentGround(); else noGround" />
2283
2402
  <ng-template #noGround>
2284
2403
  <ngts-environment-map
2285
- *ngIf="get('map'); else noMap"
2286
- [map]="get('map')"
2287
- [scene]="get('scene')"
2288
- [blur]="get('blur')"
2289
- [background]="get('background')"
2404
+ *ngIf="environmentMap() as map; else noMap"
2405
+ [map]="map"
2406
+ [background]="!!environmentBackground()"
2290
2407
  />
2291
2408
  <ng-template #noMap>
2292
- <ngts-environment-portal
2293
- *ngIf="content; else noPortal"
2294
- [frames]="get('frames')"
2295
- [far]="get('far')"
2296
- [near]="get('near')"
2297
- [resolution]="get('resolution')"
2298
- [map]="get('map')"
2299
- [background]="get('background')"
2300
- [blur]="get('blur')"
2301
- [scene]="get('scene')"
2302
- [files]="get('files')"
2303
- [path]="get('path')"
2304
- [preset]="get('preset')"
2305
- [extensions]="get('extensions')"
2306
- >
2409
+ <ngts-environment-portal *ngIf="content; else noPortal">
2307
2410
  <ng-container *ngTemplateOutlet="content" />
2308
2411
  </ngts-environment-portal>
2309
2412
  <ng-template #noPortal>
2310
- <ngts-environment-cube
2311
- [frames]="get('frames')"
2312
- [far]="get('far')"
2313
- [near]="get('near')"
2314
- [resolution]="get('resolution')"
2315
- [map]="get('map')"
2316
- [background]="get('background')"
2317
- [blur]="get('blur')"
2318
- [scene]="get('scene')"
2319
- [files]="get('files')"
2320
- [path]="get('path')"
2321
- [preset]="get('preset')"
2322
- [extensions]="get('extensions')"
2323
- />
2413
+ <ngts-environment-cube [background]="!!environmentBackground()" />
2324
2414
  </ng-template>
2325
2415
  </ng-template>
2326
2416
  </ng-template>
@@ -2333,6 +2423,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2333
2423
  NgIf,
2334
2424
  NgTemplateOutlet,
2335
2425
  ],
2426
+ providers: [{ provide: NgtsEnvironmentInput, useExisting: NgtsEnvironment }],
2336
2427
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2337
2428
  }]
2338
2429
  }], propDecorators: { content: [{
@@ -2341,7 +2432,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2341
2432
  }] } });
2342
2433
 
2343
2434
  extend({ Group });
2344
- class NgtsFloat extends NgtRxStore {
2435
+ class NgtsFloat extends NgtSignalStore {
2436
+ #offset;
2437
+ set enabled(enabled) {
2438
+ this.set({ enabled });
2439
+ }
2345
2440
  set speed(speed) {
2346
2441
  this.set({ speed });
2347
2442
  }
@@ -2354,30 +2449,29 @@ class NgtsFloat extends NgtRxStore {
2354
2449
  set floatingRange(floatingRange) {
2355
2450
  this.set({ floatingRange });
2356
2451
  }
2357
- initialize() {
2358
- super.initialize();
2359
- this.set({ speed: 1, rotationIntensity: 1, floatIntensity: 1, floatingRange: [-0.1, 0.1] });
2360
- }
2361
2452
  constructor() {
2362
- super();
2363
- this.offset = Math.random() * 10000;
2453
+ super({ speed: 1, rotationIntensity: 1, floatIntensity: 1, floatingRange: [-0.1, 0.1], enabled: true });
2454
+ this.#offset = Math.random() * 10000;
2364
2455
  this.floatRef = injectNgtRef();
2365
- injectBeforeRender(this.onBeforeRender.bind(this));
2456
+ injectBeforeRender(this.#onBeforeRender.bind(this));
2366
2457
  }
2367
- onBeforeRender({ clock }) {
2368
- if (!this.floatRef.nativeElement)
2458
+ #onBeforeRender({ clock }) {
2459
+ const float = this.floatRef.untracked;
2460
+ if (!float)
2461
+ return;
2462
+ const { enabled, speed, floatingRange, floatIntensity, rotationIntensity } = this.get();
2463
+ if (!enabled || speed === 0)
2369
2464
  return;
2370
- const { speed, floatingRange, floatIntensity, rotationIntensity } = this.get();
2371
- const t = this.offset + clock.getElapsedTime();
2372
- this.floatRef.nativeElement.rotation.x = (Math.cos((t / 4) * speed) / 8) * rotationIntensity;
2373
- this.floatRef.nativeElement.rotation.y = (Math.sin((t / 4) * speed) / 8) * rotationIntensity;
2374
- this.floatRef.nativeElement.rotation.z = (Math.sin((t / 4) * speed) / 20) * rotationIntensity;
2465
+ const t = this.#offset + clock.getElapsedTime();
2466
+ float.rotation.x = (Math.cos((t / 4) * speed) / 8) * rotationIntensity;
2467
+ float.rotation.y = (Math.sin((t / 4) * speed) / 8) * rotationIntensity;
2468
+ float.rotation.z = (Math.sin((t / 4) * speed) / 20) * rotationIntensity;
2375
2469
  let yPosition = Math.sin((t / 4) * speed) / 10;
2376
2470
  yPosition = THREE.MathUtils.mapLinear(yPosition, -0.1, 0.1, floatingRange[0] ?? -0.1, floatingRange[1] ?? 0.1);
2377
- this.floatRef.nativeElement.position.y = yPosition * floatIntensity;
2471
+ float.position.y = yPosition * floatIntensity;
2378
2472
  }
2379
2473
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsFloat, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2380
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsFloat, isStandalone: true, selector: "ngts-float", inputs: { floatRef: "floatRef", speed: "speed", rotationIntensity: "rotationIntensity", floatIntensity: "floatIntensity", floatingRange: "floatingRange" }, usesInheritance: true, ngImport: i0, template: `
2474
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsFloat, isStandalone: true, selector: "ngts-float", inputs: { floatRef: "floatRef", enabled: "enabled", speed: "speed", rotationIntensity: "rotationIntensity", floatIntensity: "floatIntensity", floatingRange: "floatingRange" }, usesInheritance: true, ngImport: i0, template: `
2381
2475
  <ngt-group ngtCompound>
2382
2476
  <ngt-group [ref]="floatRef">
2383
2477
  <ng-content />
@@ -2401,6 +2495,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2401
2495
  }]
2402
2496
  }], ctorParameters: function () { return []; }, propDecorators: { floatRef: [{
2403
2497
  type: Input
2498
+ }], enabled: [{
2499
+ type: Input
2404
2500
  }], speed: [{
2405
2501
  type: Input
2406
2502
  }], rotationIntensity: [{
@@ -2411,7 +2507,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2411
2507
  type: Input
2412
2508
  }] } });
2413
2509
 
2414
- function calcPosFromAngles(inclination, azimuth, vector = new Vector3()) {
2510
+ function calcPosFromAngles(inclination, azimuth, vector = new THREE.Vector3()) {
2415
2511
  const theta = Math.PI * (inclination - 0.5);
2416
2512
  const phi = 2 * Math.PI * (azimuth - 0.5);
2417
2513
  vector.x = Math.cos(phi);
@@ -2419,12 +2515,7 @@ function calcPosFromAngles(inclination, azimuth, vector = new Vector3()) {
2419
2515
  vector.z = Math.sin(phi);
2420
2516
  return vector;
2421
2517
  }
2422
- class NgtsSky extends NgtRxStore {
2423
- constructor() {
2424
- super(...arguments);
2425
- this.skyRef = injectNgtRef();
2426
- this.sky = new Sky();
2427
- }
2518
+ class NgtsSky extends NgtSignalStore {
2428
2519
  set distance(distance) {
2429
2520
  this.set({ distance });
2430
2521
  }
@@ -2449,31 +2540,41 @@ class NgtsSky extends NgtRxStore {
2449
2540
  set turbidity(turbidity) {
2450
2541
  this.set({ turbidity });
2451
2542
  }
2452
- initialize() {
2453
- super.initialize();
2454
- const inclination = 0.6;
2455
- const azimuth = 0.1;
2456
- this.set({
2457
- inclination,
2458
- azimuth,
2543
+ #inclination;
2544
+ #azimuth;
2545
+ #sunPosition;
2546
+ #distance;
2547
+ constructor() {
2548
+ super({
2549
+ inclination: 0.6,
2550
+ azimuth: 0.1,
2459
2551
  distance: 1000,
2460
2552
  mieCoefficient: 0.005,
2461
2553
  mieDirectionalG: 0.8,
2462
2554
  rayleigh: 0.5,
2463
2555
  turbidity: 10,
2464
- sunPosition: calcPosFromAngles(inclination, azimuth),
2465
2556
  });
2466
- this.connect('sunPosition', this.select(['inclination', 'azimuth'], ({ inclination, azimuth }) => calcPosFromAngles(inclination, azimuth)));
2467
- this.connect('scale', this.select(['distance'], ({ distance }) => new Vector3().setScalar(distance)));
2468
- }
2469
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSky, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2557
+ this.skyRef = injectNgtRef();
2558
+ this.#inclination = this.select('inclination');
2559
+ this.#azimuth = this.select('azimuth');
2560
+ this.#sunPosition = this.select('sunPosition');
2561
+ this.#distance = this.select('distance');
2562
+ this.sky = new Sky();
2563
+ this.skyMieCoefficient = this.select('mieCoefficient');
2564
+ this.skyMieDirectionalG = this.select('mieDirectionalG');
2565
+ this.skyRayleigh = this.select('rayleigh');
2566
+ this.skyTurbidity = this.select('turbidity');
2567
+ this.calculatedSunPosition = computed(() => this.#sunPosition() || calcPosFromAngles(this.#inclination(), this.#azimuth()));
2568
+ this.scale = computed(() => new THREE.Vector3().setScalar(this.#distance()));
2569
+ }
2570
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSky, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2470
2571
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSky, isStandalone: true, selector: "ngts-sky", inputs: { skyRef: "skyRef", distance: "distance", sunPosition: "sunPosition", inclination: "inclination", azimuth: "azimuth", mieCoefficient: "mieCoefficient", mieDirectionalG: "mieDirectionalG", rayleigh: "rayleigh", turbidity: "turbidity" }, usesInheritance: true, ngImport: i0, template: `
2471
- <ngt-primitive ngtCompound *args="[sky]" [ref]="skyRef" [scale]="get('scale')">
2472
- <ngt-value [rawValue]="get('mieCoefficient')" attach="material.uniforms.mieCoefficient.value" />
2473
- <ngt-value [rawValue]="get('mieDirectionalG')" attach="material.uniforms.mieDirectionalG.value" />
2474
- <ngt-value [rawValue]="get('rayleigh')" attach="material.uniforms.rayleigh.value" />
2475
- <ngt-value [rawValue]="get('sunPosition')" attach="material.uniforms.sunPosition.value" />
2476
- <ngt-value [rawValue]="get('turbidity')" attach="material.uniforms.turbidity.value" />
2572
+ <ngt-primitive ngtCompound *args="[sky]" [ref]="skyRef" [scale]="scale()">
2573
+ <ngt-value [rawValue]="skyMieCoefficient()" attach="material.uniforms.mieCoefficient.value" />
2574
+ <ngt-value [rawValue]="skyMieDirectionalG()" attach="material.uniforms.mieDirectionalG.value" />
2575
+ <ngt-value [rawValue]="skyRayleigh()" attach="material.uniforms.rayleigh.value" />
2576
+ <ngt-value [rawValue]="calculatedSunPosition()" attach="material.uniforms.sunPosition.value" />
2577
+ <ngt-value [rawValue]="skyTurbidity()" attach="material.uniforms.turbidity.value" />
2477
2578
  </ngt-primitive>
2478
2579
  `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
2479
2580
  }
@@ -2483,18 +2584,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2483
2584
  selector: 'ngts-sky',
2484
2585
  standalone: true,
2485
2586
  template: `
2486
- <ngt-primitive ngtCompound *args="[sky]" [ref]="skyRef" [scale]="get('scale')">
2487
- <ngt-value [rawValue]="get('mieCoefficient')" attach="material.uniforms.mieCoefficient.value" />
2488
- <ngt-value [rawValue]="get('mieDirectionalG')" attach="material.uniforms.mieDirectionalG.value" />
2489
- <ngt-value [rawValue]="get('rayleigh')" attach="material.uniforms.rayleigh.value" />
2490
- <ngt-value [rawValue]="get('sunPosition')" attach="material.uniforms.sunPosition.value" />
2491
- <ngt-value [rawValue]="get('turbidity')" attach="material.uniforms.turbidity.value" />
2587
+ <ngt-primitive ngtCompound *args="[sky]" [ref]="skyRef" [scale]="scale()">
2588
+ <ngt-value [rawValue]="skyMieCoefficient()" attach="material.uniforms.mieCoefficient.value" />
2589
+ <ngt-value [rawValue]="skyMieDirectionalG()" attach="material.uniforms.mieDirectionalG.value" />
2590
+ <ngt-value [rawValue]="skyRayleigh()" attach="material.uniforms.rayleigh.value" />
2591
+ <ngt-value [rawValue]="calculatedSunPosition()" attach="material.uniforms.sunPosition.value" />
2592
+ <ngt-value [rawValue]="skyTurbidity()" attach="material.uniforms.turbidity.value" />
2492
2593
  </ngt-primitive>
2493
2594
  `,
2494
2595
  imports: [NgtArgs],
2495
2596
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2496
2597
  }]
2497
- }], propDecorators: { skyRef: [{
2598
+ }], ctorParameters: function () { return []; }, propDecorators: { skyRef: [{
2498
2599
  type: Input
2499
2600
  }], distance: [{
2500
2601
  type: Input
@@ -2514,51 +2615,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2514
2615
  type: Input
2515
2616
  }] } });
2516
2617
 
2517
- const SparklesMaterial = shaderMaterial({ time: 0, pixelRatio: 1 },
2518
- // language=GLSL
2519
- `
2520
- uniform float pixelRatio;
2521
- uniform float time;
2522
-
2523
- attribute float size;
2524
- attribute float speed;
2525
- attribute float opacity;
2526
- attribute vec3 noise;
2527
- attribute vec3 color;
2528
-
2529
- varying vec3 vColor;
2530
- varying float vOpacity;
2531
-
2532
- void main() {
2533
- vec4 modelPosition = modelMatrix * vec4(position, 1.0);
2534
-
2535
- modelPosition.y += sin(time * speed + modelPosition.x * noise.x * 100.0) * 0.2;
2536
- modelPosition.z += cos(time * speed + modelPosition.x * noise.y * 100.0) * 0.2;
2537
- modelPosition.x += cos(time * speed + modelPosition.x * noise.z * 100.0) * 0.2;
2538
-
2539
- vec4 viewPosition = viewMatrix * modelPosition;
2540
- vec4 projectionPostion = projectionMatrix * viewPosition;
2541
-
2542
- gl_Position = projectionPostion;
2543
- gl_PointSize = size * 25. * pixelRatio;
2544
- gl_PointSize *= (1.0 / - viewPosition.z);
2545
-
2546
- vColor = color;
2547
- vOpacity = opacity;
2548
- }
2549
- `,
2550
- // language=GLSL
2551
- `
2552
- varying vec3 vColor;
2553
- varying float vOpacity;
2554
-
2555
- void main() {
2556
- float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
2557
- float strength = 0.05 / distanceToCenter - 0.1;
2558
-
2559
- gl_FragColor = vec4(vColor, strength * vOpacity);
2560
- }
2561
- `);
2562
2618
  extend({ SparklesMaterial, Points, BufferGeometry, BufferAttribute });
2563
2619
  const isFloat32Array = (def) => def && def.constructor === Float32Array;
2564
2620
  const expandColor = (v) => [v.r, v.g, v.b];
@@ -2589,7 +2645,7 @@ function usePropAsIsOrAsAttribute(count, prop, setDefault) {
2589
2645
  }
2590
2646
  return Float32Array.from({ length: count }, setDefault);
2591
2647
  }
2592
- class NgtsSparkles extends NgtRxStore {
2648
+ class NgtsSparkles extends NgtSignalStore {
2593
2649
  /** Number of particles (default: 100) */
2594
2650
  set count(count) {
2595
2651
  this.set({ count });
@@ -2618,63 +2674,59 @@ class NgtsSparkles extends NgtRxStore {
2618
2674
  set noise(noise) {
2619
2675
  this.set({ noise });
2620
2676
  }
2621
- initialize() {
2622
- super.initialize();
2623
- this.set({
2677
+ #store;
2678
+ #count;
2679
+ #scale;
2680
+ #color;
2681
+ #getComputed(nameOrComputed, count, setDefault) {
2682
+ const value = typeof nameOrComputed !== 'string' && isSignal(nameOrComputed)
2683
+ ? nameOrComputed
2684
+ : this.select(nameOrComputed);
2685
+ return computed(() => usePropAsIsOrAsAttribute(count(), value(), setDefault));
2686
+ }
2687
+ constructor() {
2688
+ super({
2624
2689
  noise: 1,
2625
2690
  count: 100,
2626
2691
  speed: 1,
2627
2692
  opacity: 1,
2628
2693
  scale: 1,
2629
2694
  });
2630
- this.connect('positions', this.select(['count', 'scale'], ({ count, scale }) => Float32Array.from(Array.from({ length: count }, () => normalizeVector(scale).map(MathUtils.randFloatSpread)).flat())));
2631
- this.connect('sizes', this.getAttribute$('size', { setDefault: Math.random }));
2632
- this.connect('opacities', this.getAttribute$('opacity'));
2633
- this.connect('speeds', this.getAttribute$('speed'));
2634
- this.connect('noises', this.getAttribute$('noise', {
2635
- countValue: (_, count) => count * 3,
2636
- }));
2637
- this.connect('colors', this.getAttribute$('color', {
2638
- keyValue: (color) => (!isFloat32Array(color) ? new Color(color) : color),
2639
- countValue: (color, count) => (color === undefined ? count * 3 : count),
2640
- setDefault: () => 1,
2641
- }));
2642
- }
2643
- constructor() {
2644
- super();
2645
- this.store = inject(NgtStore);
2646
- this.dpr = this.store.get('viewport', 'dpr');
2647
- this.materialRef = injectNgtRef();
2648
2695
  this.pointsRef = injectNgtRef();
2649
- injectBeforeRender(this.onBeforeRender.bind(this));
2650
- }
2651
- onBeforeRender({ clock }) {
2696
+ this.#store = inject(NgtStore);
2697
+ this.#count = this.select('count');
2698
+ this.#scale = this.select('scale');
2699
+ this.#color = this.select('color');
2700
+ this.materialRef = injectNgtRef();
2701
+ this.dpr = this.#store.select('viewport', 'dpr');
2702
+ this.positions = computed(() => Float32Array.from(Array.from({ length: this.#count() }, () => normalizeVector(this.#scale()).map(MathUtils.randFloatSpread)).flat()));
2703
+ this.sizes = this.#getComputed('size', this.#count, Math.random);
2704
+ this.opacities = this.#getComputed('opacity', this.#count);
2705
+ this.speeds = this.#getComputed('speed', this.#count);
2706
+ this.noises = this.#getComputed('noise', () => this.#count() * 3);
2707
+ this.colors = this.#getComputed(computed(() => {
2708
+ const color = this.#color();
2709
+ return !isFloat32Array(color) ? new THREE.Color(color) : color;
2710
+ }), () => (this.#color() === undefined ? this.#count() * 3 : this.#count()), () => 1);
2711
+ injectBeforeRender(this.#onBeforeRender.bind(this));
2712
+ }
2713
+ #onBeforeRender({ clock }) {
2652
2714
  if (!this.materialRef.nativeElement)
2653
2715
  return;
2654
2716
  this.materialRef.nativeElement.uniforms['time'].value = clock.elapsedTime;
2655
2717
  }
2656
- getAttribute$(key, options) {
2657
- options ??= {};
2658
- if (!options.keyValue) {
2659
- options.keyValue = (value) => value;
2660
- }
2661
- if (!options.countValue) {
2662
- options.countValue = (_, count) => count;
2663
- }
2664
- return this.select(key).pipe(startWith(this.get(key) || undefined), withLatestFrom(this.select('count')), map(([value, count]) => usePropAsIsOrAsAttribute(options.countValue(value, count), options.keyValue(value, count), options?.setDefault)));
2665
- }
2666
2718
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSparkles, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2667
2719
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSparkles, isStandalone: true, selector: "ngts-sparkles", inputs: { pointsRef: "pointsRef", count: "count", speed: "speed", opacity: "opacity", color: "color", size: "size", scale: "scale", noise: "noise" }, usesInheritance: true, ngImport: i0, template: `
2668
2720
  <ngt-points ngtCompount [ref]="pointsRef">
2669
2721
  <ngt-buffer-geometry>
2670
- <ngt-buffer-attribute *args="[get('positions'), 3]" attach="attributes.position" />
2671
- <ngt-buffer-attribute *args="[get('sizes'), 1]" attach="attributes.size" />
2672
- <ngt-buffer-attribute *args="[get('opacities'), 1]" attach="attributes.opacity" />
2673
- <ngt-buffer-attribute *args="[get('speeds'), 1]" attach="attributes.speed" />
2674
- <ngt-buffer-attribute *args="[get('colors'), 3]" attach="attributes.color" />
2675
- <ngt-buffer-attribute *args="[get('noises'), 3]" attach="attributes.noise" />
2722
+ <ngt-buffer-attribute *args="[positions(), 3]" attach="attributes.position" />
2723
+ <ngt-buffer-attribute *args="[sizes(), 1]" attach="attributes.size" />
2724
+ <ngt-buffer-attribute *args="[opacities(), 1]" attach="attributes.opacity" />
2725
+ <ngt-buffer-attribute *args="[speeds(), 1]" attach="attributes.speed" />
2726
+ <ngt-buffer-attribute *args="[colors(), 3]" attach="attributes.color" />
2727
+ <ngt-buffer-attribute *args="[noises(), 3]" attach="attributes.noise" />
2676
2728
  </ngt-buffer-geometry>
2677
- <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr" />
2729
+ <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr()" />
2678
2730
  </ngt-points>
2679
2731
  `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
2680
2732
  }
@@ -2686,14 +2738,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2686
2738
  template: `
2687
2739
  <ngt-points ngtCompount [ref]="pointsRef">
2688
2740
  <ngt-buffer-geometry>
2689
- <ngt-buffer-attribute *args="[get('positions'), 3]" attach="attributes.position" />
2690
- <ngt-buffer-attribute *args="[get('sizes'), 1]" attach="attributes.size" />
2691
- <ngt-buffer-attribute *args="[get('opacities'), 1]" attach="attributes.opacity" />
2692
- <ngt-buffer-attribute *args="[get('speeds'), 1]" attach="attributes.speed" />
2693
- <ngt-buffer-attribute *args="[get('colors'), 3]" attach="attributes.color" />
2694
- <ngt-buffer-attribute *args="[get('noises'), 3]" attach="attributes.noise" />
2741
+ <ngt-buffer-attribute *args="[positions(), 3]" attach="attributes.position" />
2742
+ <ngt-buffer-attribute *args="[sizes(), 1]" attach="attributes.size" />
2743
+ <ngt-buffer-attribute *args="[opacities(), 1]" attach="attributes.opacity" />
2744
+ <ngt-buffer-attribute *args="[speeds(), 1]" attach="attributes.speed" />
2745
+ <ngt-buffer-attribute *args="[colors(), 3]" attach="attributes.color" />
2746
+ <ngt-buffer-attribute *args="[noises(), 3]" attach="attributes.noise" />
2695
2747
  </ngt-buffer-geometry>
2696
- <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr" />
2748
+ <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr()" />
2697
2749
  </ngt-points>
2698
2750
  `,
2699
2751
  imports: [NgtArgs],
@@ -2717,7 +2769,20 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2717
2769
  type: Input
2718
2770
  }] } });
2719
2771
 
2720
- class NgtsSpotLightInput extends NgtRxStore {
2772
+ class NgtsSpotLightInput extends NgtSignalStore {
2773
+ constructor() {
2774
+ super(...arguments);
2775
+ this.lightDebug = this.select('debug');
2776
+ this.lightColor = this.select('color');
2777
+ this.lightOpacity = this.select('opacity');
2778
+ this.lightRadiusBottom = this.select('radiusBottom');
2779
+ this.lightRadiusTop = this.select('radiusTop');
2780
+ this.lightAnglePower = this.select('anglePower');
2781
+ this.lightAttenuation = this.select('attenuation');
2782
+ this.lightDistance = this.select('distance');
2783
+ this.lightAngle = this.select('angle');
2784
+ this.lightDepthBuffer = this.select('depthBuffer');
2785
+ }
2721
2786
  set depthBuffer(depthBuffer) {
2722
2787
  this.set({ depthBuffer });
2723
2788
  }
@@ -2776,54 +2841,70 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2776
2841
  }] } });
2777
2842
 
2778
2843
  extend({ Mesh });
2779
- class NgtsVolumetricMesh extends NgtsSpotLightInput {
2780
- initialize() {
2781
- super.initialize();
2782
- this.set({ opacity: 1, color: 'white', distance: 5, angle: 0.15, attenuation: 5, anglePower: 5 });
2783
- }
2844
+ class NgtsVolumetricMesh {
2845
+ #vec;
2846
+ #store;
2847
+ #camera;
2848
+ #size;
2849
+ #dpr;
2850
+ #normalizedRadiusTop;
2851
+ #normalizedRadiusBottom;
2784
2852
  constructor() {
2785
- super();
2853
+ this.spotLightInput = inject(NgtsSpotLightInput);
2786
2854
  this.mesh = injectNgtRef();
2787
2855
  this.material = new SpotLightMaterial();
2788
2856
  this.nullRaycast = () => null;
2789
- this.vec = new THREE.Vector3();
2790
- this.store = inject(NgtStore);
2791
- this.connect('normalizedRadiusTop', this.select('radiusTop').pipe(startWithUndefined(), map((radiusTop) => (radiusTop === undefined ? 0.1 : radiusTop))));
2792
- this.connect('normalizedRadiusBottom', combineLatest([this.select('radiusBottom').pipe(startWithUndefined()), this.select('angle')]).pipe(map(([radiusBottom, angle]) => (radiusBottom === undefined ? angle * 7 : radiusBottom))));
2793
- this.connect('geometry', combineLatest([
2794
- this.select('normalizedRadiusTop'),
2795
- this.select('normalizedRadiusBottom'),
2796
- this.select('distance'),
2797
- ]).pipe(map(([radiusTop, radiusBottom, distance]) => {
2857
+ this.#vec = new THREE.Vector3();
2858
+ this.#store = inject(NgtStore);
2859
+ this.#camera = this.#store.select('camera');
2860
+ this.#size = this.#store.select('size');
2861
+ this.#dpr = this.#store.select('viewport', 'dpr');
2862
+ this.#normalizedRadiusTop = computed(() => this.spotLightInput.lightRadiusTop() === undefined ? 0.1 : this.spotLightInput.lightRadiusTop());
2863
+ this.#normalizedRadiusBottom = computed(() => this.spotLightInput.lightRadiusBottom() === undefined
2864
+ ? this.spotLightInput.lightAngle() * 7
2865
+ : this.spotLightInput.lightRadiusBottom());
2866
+ this.geometry = computed(() => {
2867
+ const distance = this.spotLightInput.lightDistance();
2868
+ const radiusTop = this.#normalizedRadiusTop();
2869
+ const radiusBottom = this.#normalizedRadiusBottom();
2798
2870
  const geometry = new THREE.CylinderGeometry(radiusTop, radiusBottom, distance, 128, 64, true);
2799
2871
  geometry.applyMatrix4(new THREE.Matrix4().makeTranslation(0, -distance / 2, 0));
2800
2872
  geometry.applyMatrix4(new THREE.Matrix4().makeRotationX(-Math.PI / 2));
2801
2873
  return geometry;
2802
- })));
2803
- this.connect('cameraNear', this.store.select('camera').pipe(map((camera) => camera.near)));
2804
- this.connect('cameraFar', this.store.select('camera').pipe(map((camera) => camera.far)));
2805
- this.connect('resolution', combineLatest([
2806
- this.select('depthBuffer').pipe(startWithUndefined()),
2807
- this.store.select('size'),
2808
- this.store.select('viewport', 'dpr'),
2809
- ]).pipe(map(([depthBuffer, size, dpr]) => (depthBuffer ? [size.width * dpr, size.height * dpr] : [0, 0]))));
2874
+ });
2875
+ this.near = computed(() => this.#camera().near);
2876
+ this.far = computed(() => this.#camera().far);
2877
+ this.resolution = computed(() => this.spotLightInput.lightDepthBuffer()
2878
+ ? [this.#size().width * this.#dpr(), this.#size().height * this.#dpr()]
2879
+ : [0, 0]);
2880
+ this.spotLightInput.patch({
2881
+ opacity: 1,
2882
+ color: 'white',
2883
+ distance: 5,
2884
+ angle: 0.15,
2885
+ attenuation: 5,
2886
+ anglePower: 5,
2887
+ });
2810
2888
  injectBeforeRender(() => {
2811
- this.material.uniforms['spotPosition'].value.copy(this.mesh.nativeElement.getWorldPosition(this.vec));
2812
- this.mesh.nativeElement.lookAt(this.mesh.nativeElement.parent.target.getWorldPosition(this.vec));
2889
+ const mesh = this.mesh.nativeElement;
2890
+ if (!mesh)
2891
+ return;
2892
+ this.material.uniforms['spotPosition'].value.copy(mesh.getWorldPosition(this.#vec));
2893
+ mesh.lookAt(mesh.parent.target.getWorldPosition(this.#vec));
2813
2894
  });
2814
2895
  }
2815
2896
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsVolumetricMesh, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2816
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsVolumetricMesh, isStandalone: true, selector: "ngts-volumetric-mesh", usesInheritance: true, ngImport: i0, template: `
2817
- <ngt-mesh [ref]="mesh" [geometry]="get('geometry')" [raycast]="nullRaycast">
2897
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsVolumetricMesh, isStandalone: true, selector: "ngts-volumetric-mesh", ngImport: i0, template: `
2898
+ <ngt-mesh [ref]="mesh" [geometry]="geometry()" [raycast]="nullRaycast">
2818
2899
  <ngt-primitive *args="[material]" attach="material">
2819
- <ngt-value [rawValue]="get('opacity')" attach="uniforms.opacity.value" />
2820
- <ngt-value [rawValue]="get('color')" attach="uniforms.lightColor.value" />
2821
- <ngt-value [rawValue]="get('attenuation')" attach="uniforms.attenuation.value" />
2822
- <ngt-value [rawValue]="get('anglePower')" attach="uniforms.anglePower.value" />
2823
- <ngt-value [rawvalue]="get('depthBuffer')" attach="uniforms.depth.value" />
2824
- <ngt-value [rawvalue]="get('cameraNear')" attach="uniforms.cameraNear.value" />
2825
- <ngt-value [rawvalue]="get('cameraFar')" attach="uniforms.cameraFar.value" />
2826
- <ngt-value [rawvalue]="get('resolution')" attach="uniforms.resolution.value" />
2900
+ <ngt-value [rawValue]="spotLightInput.lightOpacity()" attach="uniforms.opacity.value" />
2901
+ <ngt-value [rawValue]="spotLightInput.lightColor()" attach="uniforms.lightColor.value" />
2902
+ <ngt-value [rawValue]="spotLightInput.lightAttenuation()" attach="uniforms.attenuation.value" />
2903
+ <ngt-value [rawValue]="spotLightInput.lightAnglePower()" attach="uniforms.anglePower.value" />
2904
+ <ngt-value [rawvalue]="spotLightInput.lightDepthBuffer()" attach="uniforms.depth.value" />
2905
+ <ngt-value [rawvalue]="near()" attach="uniforms.cameraNear.value" />
2906
+ <ngt-value [rawvalue]="far()" attach="uniforms.cameraFar.value" />
2907
+ <ngt-value [rawvalue]="resolution()" attach="uniforms.resolution.value" />
2827
2908
  </ngt-primitive>
2828
2909
  </ngt-mesh>
2829
2910
  `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
@@ -2834,16 +2915,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2834
2915
  selector: 'ngts-volumetric-mesh',
2835
2916
  standalone: true,
2836
2917
  template: `
2837
- <ngt-mesh [ref]="mesh" [geometry]="get('geometry')" [raycast]="nullRaycast">
2918
+ <ngt-mesh [ref]="mesh" [geometry]="geometry()" [raycast]="nullRaycast">
2838
2919
  <ngt-primitive *args="[material]" attach="material">
2839
- <ngt-value [rawValue]="get('opacity')" attach="uniforms.opacity.value" />
2840
- <ngt-value [rawValue]="get('color')" attach="uniforms.lightColor.value" />
2841
- <ngt-value [rawValue]="get('attenuation')" attach="uniforms.attenuation.value" />
2842
- <ngt-value [rawValue]="get('anglePower')" attach="uniforms.anglePower.value" />
2843
- <ngt-value [rawvalue]="get('depthBuffer')" attach="uniforms.depth.value" />
2844
- <ngt-value [rawvalue]="get('cameraNear')" attach="uniforms.cameraNear.value" />
2845
- <ngt-value [rawvalue]="get('cameraFar')" attach="uniforms.cameraFar.value" />
2846
- <ngt-value [rawvalue]="get('resolution')" attach="uniforms.resolution.value" />
2920
+ <ngt-value [rawValue]="spotLightInput.lightOpacity()" attach="uniforms.opacity.value" />
2921
+ <ngt-value [rawValue]="spotLightInput.lightColor()" attach="uniforms.lightColor.value" />
2922
+ <ngt-value [rawValue]="spotLightInput.lightAttenuation()" attach="uniforms.attenuation.value" />
2923
+ <ngt-value [rawValue]="spotLightInput.lightAnglePower()" attach="uniforms.anglePower.value" />
2924
+ <ngt-value [rawvalue]="spotLightInput.lightDepthBuffer()" attach="uniforms.depth.value" />
2925
+ <ngt-value [rawvalue]="near()" attach="uniforms.cameraNear.value" />
2926
+ <ngt-value [rawvalue]="far()" attach="uniforms.cameraFar.value" />
2927
+ <ngt-value [rawvalue]="resolution()" attach="uniforms.resolution.value" />
2847
2928
  </ngt-primitive>
2848
2929
  </ngt-mesh>
2849
2930
  `,
@@ -2855,24 +2936,19 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2855
2936
  extend({ SpotLight, SpotLightHelper, Group });
2856
2937
  const NGTS_SPOT_LIGHT_API = new InjectionToken('NgtsSpotLight API');
2857
2938
  function spotLightApiFactory(spotLight) {
2858
- const api = {
2939
+ return {
2859
2940
  spotLight: spotLight.spotLightRef,
2941
+ debug: spotLight.lightDebug,
2860
2942
  };
2861
- Object.defineProperty(api, 'debug', {
2862
- get: () => spotLight.get('debug'),
2863
- });
2864
- return api;
2865
2943
  }
2866
2944
  class NgtsSpotLight extends NgtsSpotLightInput {
2867
- constructor() {
2868
- super(...arguments);
2869
- this.spotLightRef = injectNgtRef();
2870
- }
2871
2945
  set volumetric(volumetric) {
2872
2946
  this.set({ volumetric });
2873
2947
  }
2874
- initialize() {
2875
- super.initialize();
2948
+ constructor() {
2949
+ super();
2950
+ this.spotLightRef = injectNgtRef();
2951
+ this.showVolumetric = this.select('volumetric');
2876
2952
  this.set({
2877
2953
  opacity: 1,
2878
2954
  color: 'white',
@@ -2884,33 +2960,24 @@ class NgtsSpotLight extends NgtsSpotLightInput {
2884
2960
  debug: false,
2885
2961
  });
2886
2962
  }
2887
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLight, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
2888
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLight, isStandalone: true, selector: "ngts-spot-light", inputs: { spotLightRef: "spotLightRef", volumetric: "volumetric" }, providers: [{ provide: NGTS_SPOT_LIGHT_API, useFactory: spotLightApiFactory, deps: [NgtsSpotLight] }], usesInheritance: true, ngImport: i0, template: `
2963
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLight, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2964
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLight, isStandalone: true, selector: "ngts-spot-light", inputs: { spotLightRef: "spotLightRef", volumetric: "volumetric" }, providers: [
2965
+ { provide: NGTS_SPOT_LIGHT_API, useFactory: spotLightApiFactory, deps: [NgtsSpotLight] },
2966
+ { provide: NgtsSpotLightInput, useExisting: NgtsSpotLight },
2967
+ ], usesInheritance: true, ngImport: i0, template: `
2889
2968
  <ngt-group>
2890
- <ng-container *ngIf="get('debug') && spotLightRef.nativeElement">
2969
+ <ng-container *ngIf="lightDebug() && spotLightRef.nativeElement">
2891
2970
  <ngt-spot-light-helper *args="[spotLightRef.nativeElement]" />
2892
2971
  </ng-container>
2893
2972
  <ngt-spot-light
2894
2973
  [ref]="spotLightRef"
2895
- [color]="get('color')"
2896
- [distance]="get('distance')"
2897
- [angle]="get('angle')"
2974
+ [color]="lightColor()"
2975
+ [distance]="lightDistance()"
2976
+ [angle]="lightAngle()"
2898
2977
  [castShadow]="true"
2899
2978
  ngtCompound
2900
2979
  >
2901
- <ngts-volumetric-mesh
2902
- *ngIf="get('volumetric')"
2903
- [debug]="get('debug')"
2904
- [opacity]="get('opacity')"
2905
- [radiusTop]="get('radiusTop')"
2906
- [radiusBottom]="get('radiusBottom')"
2907
- [depthBuffer]="get('depthBuffer')"
2908
- [color]="get('color')"
2909
- [distance]="get('distance')"
2910
- [angle]="get('angle')"
2911
- [attenuation]="get('attenuation')"
2912
- [anglePower]="get('anglePower')"
2913
- />
2980
+ <ngts-volumetric-mesh *ngIf="showVolumetric()" />
2914
2981
  </ngt-spot-light>
2915
2982
  <ng-content />
2916
2983
  </ngt-group>
@@ -2923,48 +2990,45 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
2923
2990
  standalone: true,
2924
2991
  template: `
2925
2992
  <ngt-group>
2926
- <ng-container *ngIf="get('debug') && spotLightRef.nativeElement">
2993
+ <ng-container *ngIf="lightDebug() && spotLightRef.nativeElement">
2927
2994
  <ngt-spot-light-helper *args="[spotLightRef.nativeElement]" />
2928
2995
  </ng-container>
2929
2996
  <ngt-spot-light
2930
2997
  [ref]="spotLightRef"
2931
- [color]="get('color')"
2932
- [distance]="get('distance')"
2933
- [angle]="get('angle')"
2998
+ [color]="lightColor()"
2999
+ [distance]="lightDistance()"
3000
+ [angle]="lightAngle()"
2934
3001
  [castShadow]="true"
2935
3002
  ngtCompound
2936
3003
  >
2937
- <ngts-volumetric-mesh
2938
- *ngIf="get('volumetric')"
2939
- [debug]="get('debug')"
2940
- [opacity]="get('opacity')"
2941
- [radiusTop]="get('radiusTop')"
2942
- [radiusBottom]="get('radiusBottom')"
2943
- [depthBuffer]="get('depthBuffer')"
2944
- [color]="get('color')"
2945
- [distance]="get('distance')"
2946
- [angle]="get('angle')"
2947
- [attenuation]="get('attenuation')"
2948
- [anglePower]="get('anglePower')"
2949
- />
3004
+ <ngts-volumetric-mesh *ngIf="showVolumetric()" />
2950
3005
  </ngt-spot-light>
2951
3006
  <ng-content />
2952
3007
  </ngt-group>
2953
3008
  `,
3009
+ providers: [
3010
+ { provide: NGTS_SPOT_LIGHT_API, useFactory: spotLightApiFactory, deps: [NgtsSpotLight] },
3011
+ { provide: NgtsSpotLightInput, useExisting: NgtsSpotLight },
3012
+ ],
2954
3013
  imports: [NgIf, NgtArgs, NgtsVolumetricMesh],
2955
- providers: [{ provide: NGTS_SPOT_LIGHT_API, useFactory: spotLightApiFactory, deps: [NgtsSpotLight] }],
2956
3014
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2957
3015
  }]
2958
- }], propDecorators: { spotLightRef: [{
3016
+ }], ctorParameters: function () { return []; }, propDecorators: { spotLightRef: [{
2959
3017
  type: Input
2960
3018
  }], volumetric: [{
2961
3019
  type: Input
2962
3020
  }] } });
2963
3021
 
2964
- class NgtsSpotLightShadowMeshInput extends NgtRxStore {
3022
+ class NgtsSpotLightShadowMeshInput extends NgtSignalStore {
2965
3023
  constructor() {
2966
3024
  super(...arguments);
2967
- this.map$ = this.select('map');
3025
+ this.shadowMeshDistance = this.select('distance');
3026
+ this.shadowMeshAlphaTest = this.select('alphaTest');
3027
+ this.shadowMeshScale = this.select('scale');
3028
+ this.shadowMeshMap = this.select('map');
3029
+ this.shadowMeshShader = this.select('shader');
3030
+ this.shadowMeshWidth = this.select('width');
3031
+ this.shadowMeshHeight = this.select('height');
2968
3032
  }
2969
3033
  set distance(distance) {
2970
3034
  this.set({ distance });
@@ -3011,210 +3075,212 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3011
3075
  const isSpotLight = (child) => {
3012
3076
  return child?.isSpotLight;
3013
3077
  };
3014
- function injectShadowMeshCommon(spotLight, mesh, width, height, distance) {
3015
- const pos = new THREE.Vector3();
3016
- const dir = new THREE.Vector3();
3017
- const commonEffect = (instance) => {
3018
- instance.hold(combineLatest([
3019
- spotLight.$,
3020
- instance.select('width').pipe(startWith(width)),
3021
- instance.select('height').pipe(startWith(height)),
3022
- ]), ([light, width, height]) => {
3023
- if (isSpotLight(light)) {
3024
- console.log('[NGTS] SpotLight instance -->', light);
3025
- light.shadow.mapSize.set(width, height);
3026
- light.shadow.needsUpdate = true;
3027
- }
3028
- else {
3029
- throw new Error('<ngts-spot-light-shadow> must be a child of a <ngts-spot-light>');
3078
+ function injectShadowMeshCommon(spotLightRef, meshRef, width, height, distance, injector) {
3079
+ injector = assertInjectionContext(injectShadowMeshCommon, injector);
3080
+ runInInjectionContext(injector, () => {
3081
+ const pos = new THREE.Vector3();
3082
+ const dir = new THREE.Vector3();
3083
+ requestAnimationInInjectionContext(() => {
3084
+ effect(() => {
3085
+ const spotLight = spotLightRef.nativeElement;
3086
+ if (!spotLight)
3087
+ return;
3088
+ if (isSpotLight(spotLight)) {
3089
+ spotLight.shadow.mapSize.set(width(), height());
3090
+ spotLight.shadow.map.setSize(width(), height());
3091
+ spotLight.shadow.needsUpdate = true;
3092
+ }
3093
+ else {
3094
+ throw new Error('<ngts-spot-light-shadow> must be a child of a <ngts-spot-light>');
3095
+ }
3096
+ });
3097
+ });
3098
+ injectBeforeRender(() => {
3099
+ const spotLight = spotLightRef.nativeElement;
3100
+ const mesh = meshRef.nativeElement;
3101
+ if (!spotLight)
3102
+ return;
3103
+ const A = spotLight.position;
3104
+ const B = spotLight.target.position;
3105
+ dir.copy(B).sub(A);
3106
+ const len = dir.length();
3107
+ dir.normalize().multiplyScalar(len * distance());
3108
+ pos.copy(A).add(dir);
3109
+ if (mesh) {
3110
+ mesh.position.copy(pos);
3111
+ mesh.lookAt(spotLight.target.position);
3030
3112
  }
3031
3113
  });
3032
- };
3033
- injectBeforeRender(() => {
3034
- if (!spotLight.nativeElement)
3035
- return;
3036
- const A = spotLight.nativeElement.position;
3037
- const B = spotLight.nativeElement.target.position;
3038
- dir.copy(B).sub(A);
3039
- const len = dir.length();
3040
- dir.normalize().multiplyScalar(len * distance);
3041
- pos.copy(A).add(dir);
3042
- if (mesh.nativeElement) {
3043
- mesh.nativeElement.position.copy(pos);
3044
- mesh.nativeElement.lookAt(spotLight.nativeElement.target.position);
3045
- }
3046
3114
  });
3047
- return commonEffect;
3048
3115
  }
3049
-
3050
3116
  extend({ Mesh, PlaneGeometry, MeshBasicMaterial });
3051
- class NgtsSpotLightShadowNoShader extends NgtsSpotLightShadowMeshInput {
3117
+ class NgtsSpotLightShadowMeshNoShader {
3118
+ #spotLightApi;
3052
3119
  constructor() {
3053
- super(...arguments);
3054
- this.mesh = injectNgtRef();
3055
- this.spotLightApi = inject(NGTS_SPOT_LIGHT_API);
3120
+ this.shadowMeshInput = inject(NgtsSpotLightShadowMeshInput);
3121
+ this.#spotLightApi = inject(NGTS_SPOT_LIGHT_API);
3122
+ this.meshRef = injectNgtRef();
3056
3123
  this.DoubleSide = THREE.DoubleSide;
3057
- this.runInContext = createRunInContext();
3058
- }
3059
- initialize() {
3060
- super.initialize();
3061
- this.set({ distance: 0.4, alphaTest: 0.5, width: 512, height: 512 });
3062
- this.hold(this.select('map'), (map) => {
3063
- if (map) {
3064
- map.wrapS = map.wrapT = THREE.RepeatWrapping;
3065
- checkUpdate(map);
3066
- }
3067
- });
3068
- }
3069
- ngOnInit() {
3070
- const commonEffect = this.runInContext(() => {
3071
- return injectShadowMeshCommon(this.spotLightApi.spotLight, this.mesh, this.get('width'), this.get('height'), this.get('distance'));
3124
+ this.debug = this.#spotLightApi.debug;
3125
+ this.shadowMeshInput.patch({ distance: 0.4, alphaTest: 0.5, width: 512, height: 512, scale: 1 });
3126
+ requestAnimationInInjectionContext(() => {
3127
+ effect(() => {
3128
+ const map = this.shadowMeshInput.shadowMeshMap();
3129
+ if (map) {
3130
+ map.wrapS = map.wrapT = THREE.RepeatWrapping;
3131
+ checkUpdate(map);
3132
+ }
3133
+ });
3072
3134
  });
3073
- commonEffect(this);
3135
+ injectShadowMeshCommon(this.#spotLightApi.spotLight, this.meshRef, this.shadowMeshInput.shadowMeshWidth, this.shadowMeshInput.shadowMeshHeight, this.shadowMeshInput.shadowMeshDistance);
3074
3136
  }
3075
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowNoShader, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3076
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadowNoShader, isStandalone: true, selector: "ngts-spot-light-shadow-no-shader", usesInheritance: true, ngImport: i0, template: `
3077
- <ngt-mesh [ref]="mesh" [scale]="get('scale')" [castShadow]="true">
3137
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowMeshNoShader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3138
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadowMeshNoShader, isStandalone: true, selector: "ngts-spot-light-shadow-mesh-no-shader", ngImport: i0, template: `
3139
+ <ngt-mesh [ref]="meshRef" [scale]="shadowMeshInput.shadowMeshScale()" [castShadow]="true">
3078
3140
  <ngt-plane-geometry />
3079
3141
  <ngt-mesh-basic-material
3080
3142
  [transparent]="true"
3081
3143
  [side]="DoubleSide"
3082
- [alphaTest]="get('alphaTest')"
3083
- [alphaMap]="map$ | ngtPush"
3084
- [opacity]="spotLightApi.debug ? 1 : 0"
3144
+ [alphaTest]="shadowMeshInput.shadowMeshAlphaTest()"
3145
+ [alphaMap]="shadowMeshInput.shadowMeshMap()"
3146
+ [opacity]="debug() ? 1 : 0"
3085
3147
  >
3086
3148
  <ng-content />
3087
3149
  </ngt-mesh-basic-material>
3088
3150
  </ngt-mesh>
3089
- `, isInline: true, dependencies: [{ kind: "pipe", type: NgtPush, name: "ngtPush" }] }); }
3151
+ `, isInline: true }); }
3090
3152
  }
3091
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowNoShader, decorators: [{
3153
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowMeshNoShader, decorators: [{
3092
3154
  type: Component,
3093
3155
  args: [{
3094
- selector: 'ngts-spot-light-shadow-no-shader',
3156
+ selector: 'ngts-spot-light-shadow-mesh-no-shader',
3095
3157
  standalone: true,
3096
3158
  template: `
3097
- <ngt-mesh [ref]="mesh" [scale]="get('scale')" [castShadow]="true">
3159
+ <ngt-mesh [ref]="meshRef" [scale]="shadowMeshInput.shadowMeshScale()" [castShadow]="true">
3098
3160
  <ngt-plane-geometry />
3099
3161
  <ngt-mesh-basic-material
3100
3162
  [transparent]="true"
3101
3163
  [side]="DoubleSide"
3102
- [alphaTest]="get('alphaTest')"
3103
- [alphaMap]="map$ | ngtPush"
3104
- [opacity]="spotLightApi.debug ? 1 : 0"
3164
+ [alphaTest]="shadowMeshInput.shadowMeshAlphaTest()"
3165
+ [alphaMap]="shadowMeshInput.shadowMeshMap()"
3166
+ [opacity]="debug() ? 1 : 0"
3105
3167
  >
3106
3168
  <ng-content />
3107
3169
  </ngt-mesh-basic-material>
3108
3170
  </ngt-mesh>
3109
3171
  `,
3110
- imports: [NgtPush],
3111
3172
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
3112
3173
  }]
3113
- }] });
3114
-
3115
- extend({ Mesh, PlaneGeometry, MeshBasicMaterial });
3116
- class NgtsSpotLightShadowShader extends NgtsSpotLightShadowMeshInput {
3117
- initialize() {
3118
- super.initialize();
3119
- this.set({ distance: 0.4, alphaTest: 0.5, width: 512, height: 512, scale: 1 });
3120
- }
3174
+ }], ctorParameters: function () { return []; } });
3175
+ class NgtsSpotLightShadowMeshShader {
3176
+ #spotLightApi;
3177
+ #fsQuad;
3121
3178
  constructor() {
3122
- super();
3123
- this.mesh = injectNgtRef();
3124
- this.spotLightApi = inject(NGTS_SPOT_LIGHT_API);
3179
+ this.shadowMeshInput = inject(NgtsSpotLightShadowMeshInput);
3180
+ this.meshRef = injectNgtRef();
3181
+ this.#spotLightApi = inject(NGTS_SPOT_LIGHT_API);
3125
3182
  this.DoubleSide = THREE.DoubleSide;
3126
3183
  this.RepeatWrapping = THREE.RepeatWrapping;
3127
- this.runInContext = createRunInContext();
3128
- this.texture$ = this.select('renderTarget', 'texture');
3129
- this.uniforms = {
3130
- uShadowMap: { value: this.get('map') },
3131
- uTime: { value: 0 },
3132
- };
3133
- this.connect('renderTarget', combineLatest([this.select('width'), this.select('height')]).pipe(map(([width, height]) => {
3184
+ this.debug = this.#spotLightApi.debug;
3185
+ this.renderTarget = computed(() => {
3186
+ const width = this.shadowMeshInput.shadowMeshWidth();
3187
+ const height = this.shadowMeshInput.shadowMeshHeight();
3134
3188
  return new THREE.WebGLRenderTarget(width, height, {
3135
3189
  format: THREE.RGBAFormat,
3136
3190
  encoding: THREE.LinearEncoding,
3137
3191
  stencilBuffer: false,
3138
3192
  // depthTexture: null!
3139
3193
  });
3140
- })));
3141
- this.connect('fsQuad', this.select('shader').pipe(map((shader) => {
3194
+ });
3195
+ this.uniforms = {
3196
+ uShadowMap: { value: this.shadowMeshInput.shadowMeshMap() },
3197
+ uTime: { value: 0 },
3198
+ };
3199
+ this.#fsQuad = computed(() => {
3200
+ const shader = this.shadowMeshInput.shadowMeshShader();
3201
+ if (!shader)
3202
+ return null;
3142
3203
  return new FullScreenQuad(new THREE.ShaderMaterial({
3143
3204
  uniforms: this.uniforms,
3144
3205
  vertexShader: /* glsl */ `
3145
- varying vec2 vUv;
3206
+ varying vec2 vUv;
3146
3207
 
3147
- void main() {
3148
- vUv = uv;
3149
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
3150
- }
3151
- `,
3208
+ void main() {
3209
+ vUv = uv;
3210
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
3211
+ }
3212
+ `,
3152
3213
  fragmentShader: shader,
3153
3214
  }));
3154
- })));
3155
- this.hold(this.select('map'), (map) => {
3156
- this.uniforms.uShadowMap.value = map;
3157
- });
3158
- this.effect(this.select('fsQuad'), (fsQuad) => {
3159
- return () => {
3160
- fsQuad.dispose();
3161
- fsQuad.material.dispose();
3162
- };
3163
- });
3164
- this.effect(this.select('renderTarget'), (renderTarget) => {
3165
- return () => {
3166
- renderTarget.dispose();
3167
- };
3168
3215
  });
3216
+ this.shadowMeshInput.patch({ distance: 0.4, alphaTest: 0.5, width: 512, height: 512, scale: 4 });
3217
+ injectShadowMeshCommon(this.#spotLightApi.spotLight, this.meshRef, this.shadowMeshInput.shadowMeshWidth, this.shadowMeshInput.shadowMeshHeight, this.shadowMeshInput.shadowMeshDistance);
3169
3218
  injectBeforeRender(({ delta, gl }) => {
3170
3219
  this.uniforms.uTime.value += delta;
3171
- const fsQuad = this.get('fsQuad');
3172
- const renderTarget = this.get('renderTarget');
3220
+ const fsQuad = this.#fsQuad();
3221
+ const renderTarget = this.renderTarget();
3173
3222
  if (fsQuad && renderTarget) {
3174
3223
  gl.setRenderTarget(renderTarget);
3175
3224
  fsQuad.render(gl);
3176
3225
  gl.setRenderTarget(null);
3177
3226
  }
3178
3227
  });
3179
- }
3180
- ngOnInit() {
3181
- const commonEffect = this.runInContext(() => {
3182
- return injectShadowMeshCommon(this.spotLightApi.spotLight, this.mesh, this.get('width'), this.get('height'), this.get('distance'));
3228
+ requestAnimationInInjectionContext(() => {
3229
+ effect(() => {
3230
+ const map = this.shadowMeshInput.shadowMeshMap();
3231
+ if (map) {
3232
+ this.uniforms.uShadowMap.value = map;
3233
+ }
3234
+ });
3235
+ effect((onCleanup) => {
3236
+ const fsQuad = this.#fsQuad();
3237
+ onCleanup(() => {
3238
+ if (fsQuad) {
3239
+ fsQuad.dispose();
3240
+ fsQuad.material.dispose();
3241
+ }
3242
+ });
3243
+ });
3244
+ effect((onCleanup) => {
3245
+ const renderTarget = this.renderTarget();
3246
+ onCleanup(() => {
3247
+ renderTarget.dispose();
3248
+ });
3249
+ });
3183
3250
  });
3184
- commonEffect(this);
3185
3251
  }
3186
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowShader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3187
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadowShader, isStandalone: true, selector: "ngts-spot-light-shadow-shader", usesInheritance: true, ngImport: i0, template: `
3188
- <ngt-mesh [ref]="mesh" [scale]="get('scale')" [castShadow]="true">
3252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowMeshShader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3253
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadowMeshShader, isStandalone: true, selector: "ngts-spot-light-shadow-mesh-shader", ngImport: i0, template: `
3254
+ <ngt-mesh [ref]="meshRef" [scale]="shadowMeshInput.shadowMeshScale()" [castShadow]="true">
3189
3255
  <ngt-plane-geometry />
3190
3256
  <ngt-mesh-basic-material
3191
3257
  [transparent]="true"
3192
3258
  [side]="DoubleSide"
3193
- [alphaTest]="get('alphaTest')"
3194
- [alphaMap]="texture$ | ngtPush"
3195
- [opacity]="spotLightApi.debug ? 1 : 0"
3259
+ [alphaTest]="shadowMeshInput.shadowMeshAlphaTest()"
3260
+ [alphaMap]="renderTarget().texture"
3261
+ [opacity]="debug() ? 1 : 0"
3196
3262
  >
3197
3263
  <ngt-value [rawValue]="RepeatWrapping" attach="alphaMap.wrapS" />
3198
3264
  <ngt-value [rawValue]="RepeatWrapping" attach="alphaMap.wrapT" />
3199
3265
  <ng-content />
3200
3266
  </ngt-mesh-basic-material>
3201
3267
  </ngt-mesh>
3202
- `, isInline: true, dependencies: [{ kind: "pipe", type: NgtPush, name: "ngtPush" }] }); }
3268
+ `, isInline: true }); }
3203
3269
  }
3204
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowShader, decorators: [{
3270
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadowMeshShader, decorators: [{
3205
3271
  type: Component,
3206
3272
  args: [{
3207
- selector: 'ngts-spot-light-shadow-shader',
3273
+ selector: 'ngts-spot-light-shadow-mesh-shader',
3208
3274
  standalone: true,
3209
3275
  template: `
3210
- <ngt-mesh [ref]="mesh" [scale]="get('scale')" [castShadow]="true">
3276
+ <ngt-mesh [ref]="meshRef" [scale]="shadowMeshInput.shadowMeshScale()" [castShadow]="true">
3211
3277
  <ngt-plane-geometry />
3212
3278
  <ngt-mesh-basic-material
3213
3279
  [transparent]="true"
3214
3280
  [side]="DoubleSide"
3215
- [alphaTest]="get('alphaTest')"
3216
- [alphaMap]="texture$ | ngtPush"
3217
- [opacity]="spotLightApi.debug ? 1 : 0"
3281
+ [alphaTest]="shadowMeshInput.shadowMeshAlphaTest()"
3282
+ [alphaMap]="renderTarget().texture"
3283
+ [opacity]="debug() ? 1 : 0"
3218
3284
  >
3219
3285
  <ngt-value [rawValue]="RepeatWrapping" attach="alphaMap.wrapS" />
3220
3286
  <ngt-value [rawValue]="RepeatWrapping" attach="alphaMap.wrapT" />
@@ -3222,35 +3288,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3222
3288
  </ngt-mesh-basic-material>
3223
3289
  </ngt-mesh>
3224
3290
  `,
3225
- imports: [NgtPush],
3226
3291
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
3227
3292
  }]
3228
3293
  }], ctorParameters: function () { return []; } });
3229
-
3230
3294
  class NgtsSpotLightShadow extends NgtsSpotLightShadowMeshInput {
3231
3295
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadow, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3232
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadow, isStandalone: true, selector: "ngts-spot-light-shadow", usesInheritance: true, ngImport: i0, template: `
3233
- <ngts-spot-light-shadow-shader
3234
- *ngIf="get('shader'); else noShader"
3235
- [distance]="get('distance')"
3236
- [shader]="get('shader')"
3237
- [alphaTest]="get('alphaTest')"
3238
- [scale]="get('scale')"
3239
- [map]="get('map')"
3240
- [width]="get('width')"
3241
- [height]="get('height')"
3242
- />
3296
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsSpotLightShadow, isStandalone: true, selector: "ngts-spot-light-shadow", providers: [{ provide: NgtsSpotLightShadowMeshInput, useExisting: NgtsSpotLightShadow }], usesInheritance: true, ngImport: i0, template: `
3297
+ <ngts-spot-light-shadow-mesh-shader *ngIf="shadowMeshShader(); else noShader" />
3243
3298
  <ng-template #noShader>
3244
- <ngts-spot-light-shadow-no-shader
3245
- [distance]="get('distance')"
3246
- [alphaTest]="get('alphaTest')"
3247
- [scale]="get('scale')"
3248
- [map]="get('map')"
3249
- [width]="get('width')"
3250
- [height]="get('height')"
3251
- />
3299
+ <ngts-spot-light-shadow-mesh-no-shader />
3252
3300
  </ng-template>
3253
- `, isInline: true, dependencies: [{ kind: "component", type: NgtsSpotLightShadowShader, selector: "ngts-spot-light-shadow-shader" }, { kind: "component", type: NgtsSpotLightShadowNoShader, selector: "ngts-spot-light-shadow-no-shader" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
3301
+ `, isInline: true, dependencies: [{ kind: "component", type: NgtsSpotLightShadowMeshShader, selector: "ngts-spot-light-shadow-mesh-shader" }, { kind: "component", type: NgtsSpotLightShadowMeshNoShader, selector: "ngts-spot-light-shadow-mesh-no-shader" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
3254
3302
  }
3255
3303
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsSpotLightShadow, decorators: [{
3256
3304
  type: Component,
@@ -3258,28 +3306,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3258
3306
  selector: 'ngts-spot-light-shadow',
3259
3307
  standalone: true,
3260
3308
  template: `
3261
- <ngts-spot-light-shadow-shader
3262
- *ngIf="get('shader'); else noShader"
3263
- [distance]="get('distance')"
3264
- [shader]="get('shader')"
3265
- [alphaTest]="get('alphaTest')"
3266
- [scale]="get('scale')"
3267
- [map]="get('map')"
3268
- [width]="get('width')"
3269
- [height]="get('height')"
3270
- />
3309
+ <ngts-spot-light-shadow-mesh-shader *ngIf="shadowMeshShader(); else noShader" />
3271
3310
  <ng-template #noShader>
3272
- <ngts-spot-light-shadow-no-shader
3273
- [distance]="get('distance')"
3274
- [alphaTest]="get('alphaTest')"
3275
- [scale]="get('scale')"
3276
- [map]="get('map')"
3277
- [width]="get('width')"
3278
- [height]="get('height')"
3279
- />
3311
+ <ngts-spot-light-shadow-mesh-no-shader />
3280
3312
  </ng-template>
3281
3313
  `,
3282
- imports: [NgtsSpotLightShadowShader, NgtsSpotLightShadowNoShader, NgIf],
3314
+ imports: [NgtsSpotLightShadowMeshShader, NgtsSpotLightShadowMeshNoShader, NgIf],
3315
+ providers: [{ provide: NgtsSpotLightShadowMeshInput, useExisting: NgtsSpotLightShadow }],
3283
3316
  }]
3284
3317
  }] });
3285
3318
 
@@ -3303,13 +3336,14 @@ const presets = {
3303
3336
  };
3304
3337
  class NgtsStageRefit {
3305
3338
  constructor() {
3306
- this.boundsApi = inject(NGTS_BOUNDS_API);
3339
+ this.#boundsApi = inject(NGTS_BOUNDS_API);
3307
3340
  this.radius = 0;
3308
3341
  this.adjustCamera = true;
3309
3342
  }
3343
+ #boundsApi;
3310
3344
  ngOnChanges() {
3311
3345
  if (this.adjustCamera) {
3312
- this.boundsApi.refresh().clip().fit();
3346
+ this.#boundsApi().refresh().clip().fit();
3313
3347
  }
3314
3348
  }
3315
3349
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsStageRefit, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
@@ -3324,13 +3358,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3324
3358
  type: Input
3325
3359
  }] } });
3326
3360
  extend({ AmbientLight, SpotLight, Vector2, PointLight, Group });
3327
- class NgtsStage extends NgtRxStore {
3328
- constructor() {
3329
- super(...arguments);
3330
- this.cdr = inject(ChangeDetectorRef);
3331
- this.Number = Number;
3332
- this.centered = new EventEmitter();
3333
- }
3361
+ class NgtsStage extends NgtSignalStore {
3362
+ #cdr;
3334
3363
  set preset(preset) {
3335
3364
  this.set({ preset });
3336
3365
  }
@@ -3349,21 +3378,33 @@ class NgtsStage extends NgtRxStore {
3349
3378
  set center(center) {
3350
3379
  this.set({ center });
3351
3380
  }
3352
- initialize() {
3353
- super.initialize();
3354
- this.set({
3381
+ #preset;
3382
+ #environment;
3383
+ constructor() {
3384
+ super({
3355
3385
  adjustCamera: true,
3356
3386
  intensity: 0.5,
3357
3387
  shadows: 'contact',
3358
3388
  environment: 'city',
3359
3389
  preset: 'rembrandt',
3360
- radius: 0,
3361
- width: 0,
3362
- height: 0,
3363
- depth: 0,
3364
3390
  });
3365
- this.connect('config', this.select('preset').pipe(map((preset) => (typeof preset === 'string' ? presets[preset] : preset))));
3366
- this.connect('shadowsInfo', this.select('shadows').pipe(map((shadows) => {
3391
+ this.#cdr = inject(ChangeDetectorRef);
3392
+ this.Number = Number;
3393
+ this.centered = new EventEmitter();
3394
+ this.boundingState = createSignal({ radius: 0, width: 0, height: 0, depth: 0 });
3395
+ this.#preset = this.select('preset');
3396
+ this.#environment = this.select('environment');
3397
+ this.stageShadows = this.select('shadows');
3398
+ this.stageIntensity = this.select('intensity');
3399
+ this.stageAdjustCamera = this.select('adjustCamera');
3400
+ this.stageCenter = this.select('center');
3401
+ this.config = computed(() => {
3402
+ const preset = this.#preset();
3403
+ return typeof preset === 'string' ? presets[preset] : preset;
3404
+ });
3405
+ this.shadowsInfo = computed(() => {
3406
+ const shadows = this.stageShadows();
3407
+ const restProps = typeof shadows === 'string' ? {} : shadows || {};
3367
3408
  return {
3368
3409
  contactShadow: shadows === 'contact' || shadows?.type === 'contact',
3369
3410
  accumulativeShadow: shadows === 'accumulative' || shadows?.type === 'accumulative',
@@ -3371,136 +3412,138 @@ class NgtsStage extends NgtRxStore {
3371
3412
  normalBias: shadows?.normalBias ?? 0,
3372
3413
  shadowSize: shadows?.size ?? 1024,
3373
3414
  shadowOffset: shadows?.offset ?? 0,
3374
- ...(typeof shadows === 'string' ? {} : shadows || {}),
3415
+ ...restProps,
3375
3416
  };
3376
- })));
3377
- this.connect('spotLightPosition', this.select(['config', 'radius'], ({ config, radius }) => [
3378
- config.main[0] * radius,
3379
- config.main[1] * radius,
3380
- config.main[2] * radius,
3381
- ]));
3382
- this.connect('pointLightPosition', this.select(['config', 'radius'], ({ config, radius }) => [
3383
- config.fill[0] * radius,
3384
- config.fill[1] * radius,
3385
- config.fill[2] * radius,
3386
- ]));
3387
- this.connect('environmentInfo', this.select('environment').pipe(map((environment) => {
3417
+ });
3418
+ this.spotLightPosition = computed(() => {
3419
+ const config = this.config();
3420
+ if (!config)
3421
+ return [0, 0, 0];
3422
+ const radius = this.boundingState().radius;
3423
+ return [config.main[0] * radius, config.main[1] * radius, config.main[2] * radius];
3424
+ });
3425
+ this.pointLightPosition = computed(() => {
3426
+ const config = this.config();
3427
+ if (!config)
3428
+ return [0, 0, 0];
3429
+ const radius = this.boundingState().radius;
3430
+ return [config.fill[0] * radius, config.fill[1] * radius, config.fill[2] * radius];
3431
+ });
3432
+ this.environmentInfo = computed(() => {
3433
+ const environment = this.#environment();
3388
3434
  if (!environment)
3389
3435
  return null;
3390
3436
  if (typeof environment === 'string')
3391
3437
  return { preset: environment };
3392
3438
  return environment;
3393
- })));
3439
+ });
3394
3440
  }
3395
3441
  onCentered(props) {
3396
3442
  const { boundingSphere, width, height, depth } = props;
3397
- this.set({ radius: boundingSphere.radius, width, height, depth });
3398
- this.cdr.detectChanges();
3443
+ this.boundingState.set({ radius: boundingSphere.radius, width, height, depth });
3444
+ safeDetectChanges(this.#cdr);
3399
3445
  if (this.centered.observed)
3400
3446
  this.centered.emit(props);
3401
3447
  }
3402
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsStage, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
3448
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsStage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3403
3449
  static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsStage, isStandalone: true, selector: "ngts-stage", inputs: { preset: "preset", shadows: "shadows", adjustCamera: "adjustCamera", environment: "environment", intensity: "intensity", center: "center" }, outputs: { centered: "centered" }, usesInheritance: true, ngImport: i0, template: `
3404
- <ngt-ambient-light [intensity]="get('intensity')! / 3" />
3450
+ <ngt-ambient-light [intensity]="stageIntensity() / 3" />
3405
3451
  <ngt-spot-light
3406
3452
  [penumbra]="1"
3407
- [position]="get('spotLightPosition')"
3408
- [intensity]="get('intensity')! * 2"
3409
- [castShadow]="!!get('shadows')"
3453
+ [position]="spotLightPosition()"
3454
+ [intensity]="stageIntensity() * 2"
3455
+ [castShadow]="!!stageShadows()"
3410
3456
  >
3411
- <ngt-value [rawValue]="get('shadowsInfo').shadowBias" attach="shadow.bias" />
3412
- <ngt-value [rawValue]="get('shadowsInfo').normalBias" attach="shadow.normalBias" />
3413
- <ngt-vector2
3414
- *args="[get('shadowsInfo').shadowSize, get('shadowsInfo').shadowSize]"
3415
- attach="shadow.mapSize"
3416
- />
3457
+ <ngt-value [rawValue]="shadowsInfo().shadowBias" attach="shadow.bias" />
3458
+ <ngt-value [rawValue]="shadowsInfo().normalBias" attach="shadow.normalBias" />
3459
+ <ngt-vector2 *args="[shadowsInfo().shadowSize, shadowsInfo().shadowSize]" attach="shadow.mapSize" />
3417
3460
  </ngt-spot-light>
3418
- <ngt-point-light [position]="get('pointLightPosition')" [intensity]="get('intensity')" />
3461
+ <ngt-point-light [position]="pointLightPosition()" [intensity]="stageIntensity()" />
3419
3462
 
3420
3463
  <ngts-bounds
3421
- [fit]="!!get('adjustCamera')"
3422
- [clip]="!!get('adjustCamera')"
3423
- [margin]="Number(get('adjustCamera'))"
3464
+ [fit]="!!stageAdjustCamera()"
3465
+ [clip]="!!stageAdjustCamera()"
3466
+ [margin]="Number(stageAdjustCamera())"
3424
3467
  [observe]="true"
3425
3468
  >
3426
- <ngts-stage-refit [radius]="get('radius')" [adjustCamera]="!!get('adjustCamera')" />
3469
+ <ngts-stage-refit [radius]="boundingState().radius" [adjustCamera]="!!stageAdjustCamera()" />
3427
3470
  <ngts-center
3428
- [position]="[0, get('shadowsInfo').shadowOffset / 2, 0]"
3429
- [top]="!!get('center')?.top"
3430
- [right]="!!get('center')?.right"
3431
- [bottom]="!!get('center')?.bottom"
3432
- [left]="!!get('center')?.left"
3433
- [front]="!!get('center')?.front"
3434
- [back]="!!get('center')?.back"
3435
- [disableX]="!!get('center')?.disableX"
3436
- [disableY]="!!get('center')?.disableY"
3437
- [disableZ]="!!get('center')?.disableZ"
3438
- [precise]="!!get('center')?.precise"
3471
+ [position]="[0, shadowsInfo().shadowOffset / 2, 0]"
3472
+ [top]="!!stageCenter()?.top"
3473
+ [right]="!!stageCenter()?.right"
3474
+ [bottom]="!!stageCenter()?.bottom"
3475
+ [left]="!!stageCenter()?.left"
3476
+ [front]="!!stageCenter()?.front"
3477
+ [back]="!!stageCenter()?.back"
3478
+ [disableX]="!!stageCenter()?.disableX"
3479
+ [disableY]="!!stageCenter()?.disableY"
3480
+ [disableZ]="!!stageCenter()?.disableZ"
3481
+ [precise]="!!stageCenter()?.precise"
3439
3482
  (centered)="onCentered($event)"
3440
3483
  >
3441
3484
  <ng-content />
3442
3485
  </ngts-center>
3443
3486
  </ngts-bounds>
3444
- <ngt-group [position]="[0, -get('height') / 2 - get('shadowsInfo').shadowOffset / 2, 0]">
3487
+ <ngt-group [position]="[0, -boundingState().height / 2 - shadowsInfo().shadowOffset / 2, 0]">
3445
3488
  <ngts-contact-shadows
3446
- *ngIf="get('shadowsInfo').contactShadow"
3447
- [scale]="get('radius') * 4"
3448
- [far]="get('radius')"
3489
+ *ngIf="shadowsInfo().contactShadow"
3490
+ [scale]="boundingState().radius * 4"
3491
+ [far]="boundingState().radius"
3449
3492
  [blur]="2"
3450
- [opacity]="get('shadowsInfo').opacity"
3451
- [width]="get('shadowsInfo').width"
3452
- [height]="get('shadowsInfo').height"
3453
- [smooth]="get('shadowsInfo').smooth"
3454
- [resolution]="get('shadowsInfo').resolution"
3455
- [frames]="get('shadowsInfo').frames"
3456
- [scale]="get('shadowsInfo').scale"
3457
- [color]="get('shadowsInfo').color"
3458
- [depthWrite]="get('shadowsInfo').depthWrite"
3459
- [renderOrder]="get('shadowsInfo').renderOrder"
3493
+ [opacity]="shadowsInfo().opacity"
3494
+ [width]="shadowsInfo().width"
3495
+ [height]="shadowsInfo().height"
3496
+ [smooth]="shadowsInfo().smooth"
3497
+ [resolution]="shadowsInfo().resolution"
3498
+ [frames]="shadowsInfo().frames"
3499
+ [scale]="shadowsInfo().scale"
3500
+ [color]="shadowsInfo().color"
3501
+ [depthWrite]="shadowsInfo().depthWrite"
3502
+ [renderOrder]="shadowsInfo().renderOrder"
3460
3503
  />
3461
3504
  <ngts-accumulative-shadows
3462
- *ngIf="get('shadowsInfo').accumulativeShadow"
3505
+ *ngIf="shadowsInfo().accumulativeShadow"
3463
3506
  [temporal]="true"
3464
3507
  [frames]="100"
3465
3508
  [alphaTest]="0.9"
3466
3509
  [toneMapped]="true"
3467
- [scale]="get('radius') * 4"
3468
- [opacity]="get('shadowsInfo').opacity"
3469
- [alphaTest]="get('shadowsInfo').alphaTest"
3470
- [color]="get('shadowsInfo').color"
3471
- [colorBlend]="get('shadowsInfo').colorBlend"
3472
- [resolution]="get('shadowsInfo').resolution"
3510
+ [scale]="boundingState().radius * 4"
3511
+ [opacity]="shadowsInfo().opacity"
3512
+ [alphaTest]="shadowsInfo().alphaTest"
3513
+ [color]="shadowsInfo().color"
3514
+ [colorBlend]="shadowsInfo().colorBlend"
3515
+ [resolution]="shadowsInfo().resolution"
3473
3516
  >
3474
3517
  <ngts-randomized-lights
3475
- [amount]="get('shadowsInfo').amount ?? 8"
3476
- [radius]="get('shadowsInfo').radius ?? get('radius')"
3477
- [ambient]="get('shadowsInfo').ambient ?? 0.5"
3478
- [intensity]="get('shadowsInfo').intensity ?? 1"
3479
- [position]="get('spotLightPosition')"
3480
- [size]="get('radius') * 4"
3481
- [bias]="-get('shadowsInfo').shadowBias"
3482
- [mapSize]="get('shadowsInfo').shadowSize"
3518
+ [amount]="shadowsInfo().amount ?? 8"
3519
+ [radius]="shadowsInfo().radius ?? boundingState().radius"
3520
+ [ambient]="shadowsInfo().ambient ?? 0.5"
3521
+ [intensity]="shadowsInfo().intensity ?? 1"
3522
+ [position]="spotLightPosition()"
3523
+ [size]="boundingState().radius * 4"
3524
+ [bias]="-shadowsInfo().shadowBias"
3525
+ [mapSize]="shadowsInfo().shadowSize"
3483
3526
  />
3484
3527
  </ngts-accumulative-shadows>
3485
3528
  </ngt-group>
3486
3529
  <ngts-environment
3487
- *ngIf="get('environmentInfo')"
3488
- [frames]="get('environmentInfo').frames"
3489
- [near]="get('environmentInfo').near"
3490
- [far]="get('environmentInfo').far"
3491
- [resolution]="get('environmentInfo').resolution"
3492
- [background]="get('environmentInfo').background"
3493
- [blur]="get('environmentInfo').blur"
3494
- [map]="get('environmentInfo').map"
3495
- [files]="get('environmentInfo').files"
3496
- [path]="get('environmentInfo').path"
3497
- [preset]="get('environmentInfo').preset"
3498
- [scene]="get('environmentInfo').scene"
3499
- [extensions]="get('environmentInfo').extensions"
3500
- [ground]="get('environmentInfo').ground"
3501
- [encoding]="get('environmentInfo').encoding"
3530
+ *ngIf="environmentInfo() as environmentInfo"
3531
+ [frames]="environmentInfo.frames"
3532
+ [near]="environmentInfo.near"
3533
+ [far]="environmentInfo.far"
3534
+ [resolution]="environmentInfo.resolution"
3535
+ [background]="environmentInfo.background"
3536
+ [blur]="environmentInfo.blur"
3537
+ [map]="environmentInfo.map"
3538
+ [files]="environmentInfo.files"
3539
+ [path]="environmentInfo.path"
3540
+ [preset]="environmentInfo.preset"
3541
+ [scene]="environmentInfo.scene"
3542
+ [extensions]="environmentInfo.extensions"
3543
+ [ground]="environmentInfo.ground"
3544
+ [encoding]="environmentInfo.encoding"
3502
3545
  />
3503
- `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "component", type: NgtsBounds, selector: "ngts-bounds", inputs: ["boundsRef", "damping", "fit", "clip", "observe", "margin", "eps"], outputs: ["fitted"] }, { kind: "directive", type: NgtsStageRefit, selector: "ngts-stage-refit", inputs: ["radius", "adjustCamera"] }, { kind: "component", type: NgtsCenter, selector: "ngts-center", inputs: ["centerRef", "top", "right", "bottom", "left", "front", "back", "disableX", "disableY", "disableZ", "disabled", "precise"], outputs: ["centered"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtsContactShadows, selector: "ngts-contact-shadows", inputs: ["contactShadowsRef", "opacity", "width", "height", "blur", "far", "smooth", "resolution", "frames", "scale", "color", "depthWrite", "renderOrder"] }, { kind: "component", type: NgtsAccumulativeShadows, selector: "ngts-accumulative-shadows", inputs: ["frames", "blend", "limit", "scale", "temporal", "opacity", "alphaTest", "color", "colorBlend", "resolution", "toneMapped"] }, { kind: "component", type: NgtsRandomizedLights, selector: "ngts-randomized-lights", inputs: ["lightsRef", "frames", "position", "radius", "amount", "intensity", "ambient", "castShadow", "bias", "mapSize", "size", "near", "far"] }, { kind: "component", type: NgtsEnvironment, selector: "ngts-environment" }] }); }
3546
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "component", type: NgtsBounds, selector: "ngts-bounds", inputs: ["boundsRef", "damping", "fit", "clip", "observe", "margin", "eps"], outputs: ["fitted"] }, { kind: "directive", type: NgtsStageRefit, selector: "ngts-stage-refit", inputs: ["radius", "adjustCamera"] }, { kind: "component", type: NgtsCenter, selector: "ngts-center", inputs: ["centerRef", "top", "right", "bottom", "left", "front", "back", "disableX", "disableY", "disableZ", "disable", "precise"], outputs: ["centered"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtsContactShadows, selector: "ngts-contact-shadows", inputs: ["contactShadowsRef", "opacity", "width", "height", "blur", "far", "smooth", "resolution", "frames", "scale", "color", "depthWrite", "renderOrder"] }, { kind: "component", type: NgtsAccumulativeShadows, selector: "ngts-accumulative-shadows", inputs: ["frames", "blend", "limit", "scale", "temporal", "opacity", "alphaTest", "color", "colorBlend", "resolution", "toneMapped"] }, { kind: "component", type: NgtsRandomizedLights, selector: "ngts-randomized-lights", inputs: ["lightsRef", "frames", "position", "radius", "amount", "intensity", "ambient", "castShadow", "bias", "mapSize", "size", "near", "far"] }, { kind: "component", type: NgtsEnvironment, selector: "ngts-environment" }] }); }
3504
3547
  }
3505
3548
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsStage, decorators: [{
3506
3549
  type: Component,
@@ -3508,104 +3551,101 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3508
3551
  selector: 'ngts-stage',
3509
3552
  standalone: true,
3510
3553
  template: `
3511
- <ngt-ambient-light [intensity]="get('intensity')! / 3" />
3554
+ <ngt-ambient-light [intensity]="stageIntensity() / 3" />
3512
3555
  <ngt-spot-light
3513
3556
  [penumbra]="1"
3514
- [position]="get('spotLightPosition')"
3515
- [intensity]="get('intensity')! * 2"
3516
- [castShadow]="!!get('shadows')"
3557
+ [position]="spotLightPosition()"
3558
+ [intensity]="stageIntensity() * 2"
3559
+ [castShadow]="!!stageShadows()"
3517
3560
  >
3518
- <ngt-value [rawValue]="get('shadowsInfo').shadowBias" attach="shadow.bias" />
3519
- <ngt-value [rawValue]="get('shadowsInfo').normalBias" attach="shadow.normalBias" />
3520
- <ngt-vector2
3521
- *args="[get('shadowsInfo').shadowSize, get('shadowsInfo').shadowSize]"
3522
- attach="shadow.mapSize"
3523
- />
3561
+ <ngt-value [rawValue]="shadowsInfo().shadowBias" attach="shadow.bias" />
3562
+ <ngt-value [rawValue]="shadowsInfo().normalBias" attach="shadow.normalBias" />
3563
+ <ngt-vector2 *args="[shadowsInfo().shadowSize, shadowsInfo().shadowSize]" attach="shadow.mapSize" />
3524
3564
  </ngt-spot-light>
3525
- <ngt-point-light [position]="get('pointLightPosition')" [intensity]="get('intensity')" />
3565
+ <ngt-point-light [position]="pointLightPosition()" [intensity]="stageIntensity()" />
3526
3566
 
3527
3567
  <ngts-bounds
3528
- [fit]="!!get('adjustCamera')"
3529
- [clip]="!!get('adjustCamera')"
3530
- [margin]="Number(get('adjustCamera'))"
3568
+ [fit]="!!stageAdjustCamera()"
3569
+ [clip]="!!stageAdjustCamera()"
3570
+ [margin]="Number(stageAdjustCamera())"
3531
3571
  [observe]="true"
3532
3572
  >
3533
- <ngts-stage-refit [radius]="get('radius')" [adjustCamera]="!!get('adjustCamera')" />
3573
+ <ngts-stage-refit [radius]="boundingState().radius" [adjustCamera]="!!stageAdjustCamera()" />
3534
3574
  <ngts-center
3535
- [position]="[0, get('shadowsInfo').shadowOffset / 2, 0]"
3536
- [top]="!!get('center')?.top"
3537
- [right]="!!get('center')?.right"
3538
- [bottom]="!!get('center')?.bottom"
3539
- [left]="!!get('center')?.left"
3540
- [front]="!!get('center')?.front"
3541
- [back]="!!get('center')?.back"
3542
- [disableX]="!!get('center')?.disableX"
3543
- [disableY]="!!get('center')?.disableY"
3544
- [disableZ]="!!get('center')?.disableZ"
3545
- [precise]="!!get('center')?.precise"
3575
+ [position]="[0, shadowsInfo().shadowOffset / 2, 0]"
3576
+ [top]="!!stageCenter()?.top"
3577
+ [right]="!!stageCenter()?.right"
3578
+ [bottom]="!!stageCenter()?.bottom"
3579
+ [left]="!!stageCenter()?.left"
3580
+ [front]="!!stageCenter()?.front"
3581
+ [back]="!!stageCenter()?.back"
3582
+ [disableX]="!!stageCenter()?.disableX"
3583
+ [disableY]="!!stageCenter()?.disableY"
3584
+ [disableZ]="!!stageCenter()?.disableZ"
3585
+ [precise]="!!stageCenter()?.precise"
3546
3586
  (centered)="onCentered($event)"
3547
3587
  >
3548
3588
  <ng-content />
3549
3589
  </ngts-center>
3550
3590
  </ngts-bounds>
3551
- <ngt-group [position]="[0, -get('height') / 2 - get('shadowsInfo').shadowOffset / 2, 0]">
3591
+ <ngt-group [position]="[0, -boundingState().height / 2 - shadowsInfo().shadowOffset / 2, 0]">
3552
3592
  <ngts-contact-shadows
3553
- *ngIf="get('shadowsInfo').contactShadow"
3554
- [scale]="get('radius') * 4"
3555
- [far]="get('radius')"
3593
+ *ngIf="shadowsInfo().contactShadow"
3594
+ [scale]="boundingState().radius * 4"
3595
+ [far]="boundingState().radius"
3556
3596
  [blur]="2"
3557
- [opacity]="get('shadowsInfo').opacity"
3558
- [width]="get('shadowsInfo').width"
3559
- [height]="get('shadowsInfo').height"
3560
- [smooth]="get('shadowsInfo').smooth"
3561
- [resolution]="get('shadowsInfo').resolution"
3562
- [frames]="get('shadowsInfo').frames"
3563
- [scale]="get('shadowsInfo').scale"
3564
- [color]="get('shadowsInfo').color"
3565
- [depthWrite]="get('shadowsInfo').depthWrite"
3566
- [renderOrder]="get('shadowsInfo').renderOrder"
3597
+ [opacity]="shadowsInfo().opacity"
3598
+ [width]="shadowsInfo().width"
3599
+ [height]="shadowsInfo().height"
3600
+ [smooth]="shadowsInfo().smooth"
3601
+ [resolution]="shadowsInfo().resolution"
3602
+ [frames]="shadowsInfo().frames"
3603
+ [scale]="shadowsInfo().scale"
3604
+ [color]="shadowsInfo().color"
3605
+ [depthWrite]="shadowsInfo().depthWrite"
3606
+ [renderOrder]="shadowsInfo().renderOrder"
3567
3607
  />
3568
3608
  <ngts-accumulative-shadows
3569
- *ngIf="get('shadowsInfo').accumulativeShadow"
3609
+ *ngIf="shadowsInfo().accumulativeShadow"
3570
3610
  [temporal]="true"
3571
3611
  [frames]="100"
3572
3612
  [alphaTest]="0.9"
3573
3613
  [toneMapped]="true"
3574
- [scale]="get('radius') * 4"
3575
- [opacity]="get('shadowsInfo').opacity"
3576
- [alphaTest]="get('shadowsInfo').alphaTest"
3577
- [color]="get('shadowsInfo').color"
3578
- [colorBlend]="get('shadowsInfo').colorBlend"
3579
- [resolution]="get('shadowsInfo').resolution"
3614
+ [scale]="boundingState().radius * 4"
3615
+ [opacity]="shadowsInfo().opacity"
3616
+ [alphaTest]="shadowsInfo().alphaTest"
3617
+ [color]="shadowsInfo().color"
3618
+ [colorBlend]="shadowsInfo().colorBlend"
3619
+ [resolution]="shadowsInfo().resolution"
3580
3620
  >
3581
3621
  <ngts-randomized-lights
3582
- [amount]="get('shadowsInfo').amount ?? 8"
3583
- [radius]="get('shadowsInfo').radius ?? get('radius')"
3584
- [ambient]="get('shadowsInfo').ambient ?? 0.5"
3585
- [intensity]="get('shadowsInfo').intensity ?? 1"
3586
- [position]="get('spotLightPosition')"
3587
- [size]="get('radius') * 4"
3588
- [bias]="-get('shadowsInfo').shadowBias"
3589
- [mapSize]="get('shadowsInfo').shadowSize"
3622
+ [amount]="shadowsInfo().amount ?? 8"
3623
+ [radius]="shadowsInfo().radius ?? boundingState().radius"
3624
+ [ambient]="shadowsInfo().ambient ?? 0.5"
3625
+ [intensity]="shadowsInfo().intensity ?? 1"
3626
+ [position]="spotLightPosition()"
3627
+ [size]="boundingState().radius * 4"
3628
+ [bias]="-shadowsInfo().shadowBias"
3629
+ [mapSize]="shadowsInfo().shadowSize"
3590
3630
  />
3591
3631
  </ngts-accumulative-shadows>
3592
3632
  </ngt-group>
3593
3633
  <ngts-environment
3594
- *ngIf="get('environmentInfo')"
3595
- [frames]="get('environmentInfo').frames"
3596
- [near]="get('environmentInfo').near"
3597
- [far]="get('environmentInfo').far"
3598
- [resolution]="get('environmentInfo').resolution"
3599
- [background]="get('environmentInfo').background"
3600
- [blur]="get('environmentInfo').blur"
3601
- [map]="get('environmentInfo').map"
3602
- [files]="get('environmentInfo').files"
3603
- [path]="get('environmentInfo').path"
3604
- [preset]="get('environmentInfo').preset"
3605
- [scene]="get('environmentInfo').scene"
3606
- [extensions]="get('environmentInfo').extensions"
3607
- [ground]="get('environmentInfo').ground"
3608
- [encoding]="get('environmentInfo').encoding"
3634
+ *ngIf="environmentInfo() as environmentInfo"
3635
+ [frames]="environmentInfo.frames"
3636
+ [near]="environmentInfo.near"
3637
+ [far]="environmentInfo.far"
3638
+ [resolution]="environmentInfo.resolution"
3639
+ [background]="environmentInfo.background"
3640
+ [blur]="environmentInfo.blur"
3641
+ [map]="environmentInfo.map"
3642
+ [files]="environmentInfo.files"
3643
+ [path]="environmentInfo.path"
3644
+ [preset]="environmentInfo.preset"
3645
+ [scene]="environmentInfo.scene"
3646
+ [extensions]="environmentInfo.extensions"
3647
+ [ground]="environmentInfo.ground"
3648
+ [encoding]="environmentInfo.encoding"
3609
3649
  />
3610
3650
  `,
3611
3651
  imports: [
@@ -3621,7 +3661,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3621
3661
  ],
3622
3662
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
3623
3663
  }]
3624
- }], propDecorators: { preset: [{
3664
+ }], ctorParameters: function () { return []; }, propDecorators: { preset: [{
3625
3665
  type: Input
3626
3666
  }], shadows: [{
3627
3667
  type: Input
@@ -3639,9 +3679,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3639
3679
 
3640
3680
  extend({ Points, BufferGeometry, BufferAttribute });
3641
3681
  const genStar = (r) => {
3642
- return new Vector3().setFromSpherical(new Spherical(r, Math.acos(1 - Math.random() * 2), Math.random() * 2 * Math.PI));
3682
+ return new THREE.Vector3().setFromSpherical(new THREE.Spherical(r, Math.acos(1 - Math.random() * 2), Math.random() * 2 * Math.PI));
3643
3683
  };
3644
- class NgtsStars extends NgtRxStore {
3684
+ class NgtsStars extends NgtSignalStore {
3645
3685
  set radius(radius) {
3646
3686
  this.set({ radius });
3647
3687
  }
@@ -3657,15 +3697,19 @@ class NgtsStars extends NgtRxStore {
3657
3697
  set saturation(saturation) {
3658
3698
  this.set({ saturation });
3659
3699
  }
3660
- set fade(fade) {
3700
+ set starsFade(fade) {
3661
3701
  this.set({ fade });
3662
3702
  }
3663
3703
  set speed(speed) {
3664
3704
  this.set({ speed });
3665
3705
  }
3666
- initialize() {
3667
- super.initialize();
3668
- this.set({
3706
+ #count;
3707
+ #depth;
3708
+ #factor;
3709
+ #radius;
3710
+ #saturation;
3711
+ constructor() {
3712
+ super({
3669
3713
  radius: 100,
3670
3714
  depth: 50,
3671
3715
  count: 5000,
@@ -3674,17 +3718,26 @@ class NgtsStars extends NgtRxStore {
3674
3718
  fade: false,
3675
3719
  speed: 1,
3676
3720
  });
3677
- this.connect('bufferAttributes', this.select(['count', 'depth', 'factor', 'radius', 'saturation'], ({ count, depth, factor, radius, saturation }) => {
3721
+ this.AdditiveBlending = THREE.AdditiveBlending;
3722
+ this.material = new StarFieldMaterial();
3723
+ this.starsRef = injectNgtRef();
3724
+ this.#count = this.select('count');
3725
+ this.#depth = this.select('depth');
3726
+ this.#factor = this.select('factor');
3727
+ this.#radius = this.select('radius');
3728
+ this.#saturation = this.select('saturation');
3729
+ this.fade = this.select('fade');
3730
+ this.bufferAttributes = computed(() => {
3678
3731
  const positions = [];
3679
3732
  const colors = [];
3680
- const sizes = Array.from({ length: count }, () => (0.5 + 0.5 * Math.random()) * factor);
3681
- const color = new Color();
3682
- let r = radius + depth;
3683
- const increment = depth / count;
3684
- for (let i = 0; i < count; i++) {
3733
+ const sizes = Array.from({ length: this.#count() }, () => (0.5 + 0.5 * Math.random()) * this.#factor());
3734
+ const color = new THREE.Color();
3735
+ let r = this.#radius() + this.#depth();
3736
+ const increment = this.#depth() / this.#count();
3737
+ for (let i = 0; i < this.#count(); i++) {
3685
3738
  r -= increment * Math.random();
3686
3739
  positions.push(...genStar(r).toArray());
3687
- color.setHSL(i / count, saturation, 0.9);
3740
+ color.setHSL(i / this.#count(), this.#saturation(), 0.9);
3688
3741
  colors.push(color.r, color.g, color.b);
3689
3742
  }
3690
3743
  return {
@@ -3692,25 +3745,19 @@ class NgtsStars extends NgtRxStore {
3692
3745
  colors: new Float32Array(colors),
3693
3746
  sizes: new Float32Array(sizes),
3694
3747
  };
3695
- }));
3696
- }
3697
- constructor() {
3698
- super();
3699
- this.AdditiveBlending = THREE.AdditiveBlending;
3700
- this.material = new StarFieldMaterial();
3701
- this.starsRef = injectNgtRef();
3702
- injectBeforeRender(this.onBeforeRender.bind(this));
3748
+ });
3749
+ injectBeforeRender(this.#onBeforeRender.bind(this));
3703
3750
  }
3704
- onBeforeRender({ clock }) {
3751
+ #onBeforeRender({ clock }) {
3705
3752
  this.material.uniforms['time'].value = clock.getElapsedTime() * this.get('speed');
3706
3753
  }
3707
3754
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsStars, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3708
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsStars, isStandalone: true, selector: "ngts-stars", inputs: { starsRef: "starsRef", radius: "radius", depth: "depth", count: "count", factor: "factor", saturation: "saturation", fade: "fade", speed: "speed" }, usesInheritance: true, ngImport: i0, template: `
3755
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.0.0", type: NgtsStars, isStandalone: true, selector: "ngts-stars", inputs: { starsRef: "starsRef", radius: "radius", depth: "depth", count: "count", factor: "factor", saturation: "saturation", starsFade: ["fade", "starsFade"], speed: "speed" }, usesInheritance: true, ngImport: i0, template: `
3709
3756
  <ngt-points [ref]="starsRef">
3710
3757
  <ngt-buffer-geometry>
3711
- <ngt-buffer-attribute attach="attributes.position" *args="[get('bufferAttributes').positions, 3]" />
3712
- <ngt-buffer-attribute attach="attributes.color" *args="[get('bufferAttributes').colors, 3]" />
3713
- <ngt-buffer-attribute attach="attributes.size" *args="[get('bufferAttributes').sizes, 1]" />
3758
+ <ngt-buffer-attribute attach="attributes.position" *args="[bufferAttributes().positions, 3]" />
3759
+ <ngt-buffer-attribute attach="attributes.color" *args="[bufferAttributes().colors, 3]" />
3760
+ <ngt-buffer-attribute attach="attributes.size" *args="[bufferAttributes().sizes, 1]" />
3714
3761
  </ngt-buffer-geometry>
3715
3762
  <ngt-primitive
3716
3763
  *args="[material]"
@@ -3720,7 +3767,7 @@ class NgtsStars extends NgtRxStore {
3720
3767
  [transparent]="true"
3721
3768
  [vertexColors]="true"
3722
3769
  >
3723
- <ngt-value attach="uniforms.fade.value" [rawValue]="get('fade')" />
3770
+ <ngt-value attach="uniforms.fade.value" [rawValue]="fade()" />
3724
3771
  </ngt-primitive>
3725
3772
  </ngt-points>
3726
3773
  `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] }); }
@@ -3733,9 +3780,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3733
3780
  template: `
3734
3781
  <ngt-points [ref]="starsRef">
3735
3782
  <ngt-buffer-geometry>
3736
- <ngt-buffer-attribute attach="attributes.position" *args="[get('bufferAttributes').positions, 3]" />
3737
- <ngt-buffer-attribute attach="attributes.color" *args="[get('bufferAttributes').colors, 3]" />
3738
- <ngt-buffer-attribute attach="attributes.size" *args="[get('bufferAttributes').sizes, 1]" />
3783
+ <ngt-buffer-attribute attach="attributes.position" *args="[bufferAttributes().positions, 3]" />
3784
+ <ngt-buffer-attribute attach="attributes.color" *args="[bufferAttributes().colors, 3]" />
3785
+ <ngt-buffer-attribute attach="attributes.size" *args="[bufferAttributes().sizes, 1]" />
3739
3786
  </ngt-buffer-geometry>
3740
3787
  <ngt-primitive
3741
3788
  *args="[material]"
@@ -3745,7 +3792,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3745
3792
  [transparent]="true"
3746
3793
  [vertexColors]="true"
3747
3794
  >
3748
- <ngt-value attach="uniforms.fade.value" [rawValue]="get('fade')" />
3795
+ <ngt-value attach="uniforms.fade.value" [rawValue]="fade()" />
3749
3796
  </ngt-primitive>
3750
3797
  </ngt-points>
3751
3798
  `,
@@ -3764,8 +3811,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3764
3811
  type: Input
3765
3812
  }], saturation: [{
3766
3813
  type: Input
3767
- }], fade: [{
3768
- type: Input
3814
+ }], starsFade: [{
3815
+ type: Input,
3816
+ args: ['fade']
3769
3817
  }], speed: [{
3770
3818
  type: Input
3771
3819
  }] } });
@@ -3774,5 +3822,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImpor
3774
3822
  * Generated bundle index. Do not edit.
3775
3823
  */
3776
3824
 
3777
- export { NGTS_BOUNDS_API, NGTS_SPOT_LIGHT_API, NgtsAccumulativeShadows, NgtsBounds, NgtsCameraShake, NgtsCaustics, NgtsCenter, NgtsCloud, NgtsContactShadows, NgtsEnvironment, NgtsEnvironmentContent, NgtsFloat, NgtsRandomizedLights, NgtsSky, NgtsSparkles, NgtsSpotLight, NgtsSpotLightShadow, NgtsStage, NgtsStageRefit, NgtsStars, calcPosFromAngles, ngtsEnvironmentPresetsObj };
3825
+ export { NGTS_ACCUMULATIVE_SHADOWS_API, NGTS_BOUNDS_API, NGTS_SPOT_LIGHT_API, NgtsAccumulativeShadows, NgtsBounds, NgtsCameraShake, NgtsCaustics, NgtsCenter, NgtsCloud, NgtsContactShadows, NgtsEnvironment, NgtsEnvironmentContent, NgtsFloat, NgtsRandomizedLights, NgtsSky, NgtsSparkles, NgtsSpotLight, NgtsSpotLightShadow, NgtsStage, NgtsStageRefit, NgtsStars, ngtsEnvironmentPresetsObj };
3778
3826
  //# sourceMappingURL=angular-three-soba-staging.mjs.map