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

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 (321) hide show
  1. package/abstractions/billboard/billboard.d.ts +12 -8
  2. package/abstractions/detailed/detailed.d.ts +26 -0
  3. package/abstractions/edges/edges.d.ts +24 -12
  4. package/abstractions/grid/grid.d.ts +50 -0
  5. package/abstractions/index.d.ts +2 -7
  6. package/abstractions/text/text.d.ts +10 -5
  7. package/abstractions/text-3d/text-3d.d.ts +51 -41
  8. package/cameras/camera/camera-content.d.ts +1 -1
  9. package/cameras/camera/camera.d.ts +16 -13
  10. package/cameras/cube-camera/cube-camera.d.ts +50 -23
  11. package/cameras/index.d.ts +0 -1
  12. package/cameras/orthographic-camera/orthographic-camera.d.ts +29 -18
  13. package/cameras/perspective-camera/perspective-camera.d.ts +10 -1
  14. package/controls/orbit-controls/orbit-controls.d.ts +34 -15
  15. package/esm2022/abstractions/billboard/billboard.mjs +36 -33
  16. package/esm2022/abstractions/detailed/detailed.mjs +64 -0
  17. package/esm2022/abstractions/edges/edges.mjs +58 -63
  18. package/esm2022/abstractions/grid/grid.mjs +180 -0
  19. package/esm2022/abstractions/index.mjs +3 -8
  20. package/esm2022/abstractions/text/text.mjs +123 -124
  21. package/esm2022/abstractions/text-3d/text-3d.mjs +120 -115
  22. package/esm2022/cameras/camera/camera-content.mjs +6 -6
  23. package/esm2022/cameras/camera/camera.mjs +48 -42
  24. package/esm2022/cameras/cube-camera/cube-camera.mjs +130 -99
  25. package/esm2022/cameras/index.mjs +1 -2
  26. package/esm2022/cameras/orthographic-camera/orthographic-camera.mjs +78 -75
  27. package/esm2022/cameras/perspective-camera/perspective-camera.mjs +25 -26
  28. package/esm2022/controls/orbit-controls/orbit-controls.mjs +109 -85
  29. package/esm2022/gizmos/angular-three-soba-gizmos.mjs +5 -0
  30. package/esm2022/gizmos/gizmo-helper/gizmo-helper.mjs +198 -0
  31. package/esm2022/gizmos/gizmo-helper/gizmo-viewcube/constants.mjs +31 -0
  32. package/esm2022/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.mjs +93 -0
  33. package/esm2022/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.mjs +151 -0
  34. package/esm2022/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-input.mjs +66 -0
  35. package/esm2022/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube.mjs +71 -0
  36. package/esm2022/gizmos/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.mjs +195 -0
  37. package/esm2022/gizmos/gizmo-helper/gizmo-viewport/gizmo-viewport.mjs +272 -0
  38. package/esm2022/gizmos/index.mjs +4 -0
  39. package/esm2022/loaders/gltf-loader/gltf-loader.mjs +8 -6
  40. package/esm2022/loaders/loader/loader.mjs +92 -87
  41. package/esm2022/loaders/progress/progress.mjs +31 -30
  42. package/esm2022/loaders/texture-loader/texture-loader.mjs +6 -5
  43. package/esm2022/materials/index.mjs +2 -1
  44. package/esm2022/materials/mesh-distort-material/mesh-distort-material.mjs +60 -51
  45. package/esm2022/materials/mesh-reflector-material/mesh-reflector-material.mjs +239 -255
  46. package/esm2022/materials/mesh-refraction-material/mesh-refraction-material.mjs +102 -99
  47. package/esm2022/materials/mesh-transmission-material/mesh-transmission-material.mjs +167 -146
  48. package/esm2022/materials/mesh-wobble-material/mesh-wobble-material.mjs +44 -42
  49. package/esm2022/materials/point-material/point-material.mjs +50 -0
  50. package/esm2022/misc/animations/animations.mjs +39 -34
  51. package/esm2022/misc/bake-shadows/bake-shadows.mjs +13 -13
  52. package/esm2022/misc/caustics/caustics.mjs +387 -0
  53. package/esm2022/misc/decal/decal.mjs +187 -0
  54. package/esm2022/misc/depth-buffer/depth-buffer.mjs +35 -36
  55. package/esm2022/misc/example/example.mjs +161 -0
  56. package/esm2022/misc/fbo/fbo.mjs +37 -36
  57. package/esm2022/misc/html/html-wrapper.mjs +478 -0
  58. package/esm2022/misc/html/html.mjs +305 -0
  59. package/esm2022/misc/index.mjs +10 -1
  60. package/esm2022/misc/sampler/sampler.mjs +143 -0
  61. package/esm2022/misc/shadow/shadow.mjs +111 -0
  62. package/esm2022/misc/stats-gl/stats-gl.mjs +61 -0
  63. package/esm2022/misc/trail/trail.mjs +210 -0
  64. package/esm2022/misc/trail-texture/inject-trail-texture.mjs +18 -0
  65. package/esm2022/misc/trail-texture/trail-texture.mjs +106 -0
  66. package/esm2022/modifiers/angular-three-soba-modifiers.mjs +5 -0
  67. package/esm2022/modifiers/curve-modifier/curve-modifier.mjs +64 -0
  68. package/esm2022/modifiers/index.mjs +2 -0
  69. package/esm2022/performances/adaptive-dpr/adaptive-dpr.mjs +44 -0
  70. package/esm2022/performances/adaptive-events/adaptive-events.mjs +27 -0
  71. package/esm2022/performances/angular-three-soba-performances.mjs +5 -0
  72. package/esm2022/performances/index.mjs +8 -0
  73. package/esm2022/performances/instances/instances.mjs +221 -0
  74. package/esm2022/performances/instances/position-mesh.mjs +52 -0
  75. package/esm2022/performances/points/points-input.mjs +64 -0
  76. package/esm2022/performances/points/points.mjs +327 -0
  77. package/esm2022/performances/points/position-point.mjs +54 -0
  78. package/esm2022/performances/segments/segment-object.mjs +9 -0
  79. package/esm2022/performances/segments/segments.mjs +183 -0
  80. package/esm2022/shaders/blur-pass/blur-pass.mjs +2 -2
  81. package/esm2022/shaders/caustics/caustics-material.mjs +130 -0
  82. package/esm2022/shaders/caustics/caustics-projection-material.mjs +31 -0
  83. package/esm2022/shaders/convolution-material/convolution-material.mjs +1 -1
  84. package/esm2022/shaders/discard-material/discard-material.mjs +1 -1
  85. package/esm2022/shaders/grid-material/grid-material.mjs +77 -0
  86. package/esm2022/shaders/index.mjs +6 -3
  87. package/esm2022/shaders/mesh-distort-material/mesh-distort-material.mjs +42 -41
  88. package/esm2022/shaders/mesh-reflector-material/mesh-reflector-material.mjs +2 -2
  89. package/esm2022/shaders/mesh-refraction-material/mesh-refraction-material.mjs +2 -2
  90. package/esm2022/shaders/mesh-transmission-material/mesh-transmission-material.mjs +4 -4
  91. package/esm2022/shaders/mesh-wobble-material/mesh-wobble-material.mjs +1 -1
  92. package/esm2022/shaders/shader-material/shader-material.mjs +3 -5
  93. package/esm2022/shaders/soft-shadow-material/soft-shadow-material.mjs +17 -25
  94. package/esm2022/shaders/sparkles-material/sparkles-material.mjs +32 -46
  95. package/esm2022/shaders/spot-light-material/spot-light-material.mjs +7 -7
  96. package/esm2022/shaders/star-field-material/star-field-material.mjs +3 -2
  97. package/esm2022/shaders/wireframe-material/wireframe-material.mjs +247 -0
  98. package/esm2022/staging/accumulative-shadows/accumulative-shadows.mjs +161 -176
  99. package/esm2022/staging/accumulative-shadows/progressive-light-map.mjs +8 -8
  100. package/esm2022/staging/accumulative-shadows/randomized-lights.mjs +128 -129
  101. package/esm2022/staging/backdrop/backdrop.mjs +77 -0
  102. package/esm2022/staging/bb-anchor/bb-anchor.mjs +69 -0
  103. package/esm2022/staging/bounds/bounds.mjs +145 -143
  104. package/esm2022/staging/camera-shake/camera-shake.mjs +86 -80
  105. package/esm2022/staging/center/center.mjs +129 -112
  106. package/esm2022/staging/cloud/cloud.mjs +118 -124
  107. package/esm2022/staging/contact-shadows/contact-shadows.mjs +131 -136
  108. package/esm2022/staging/environment/assets.mjs +12 -12
  109. package/esm2022/staging/environment/environment-cube.mjs +28 -30
  110. package/esm2022/staging/environment/environment-ground.mjs +17 -19
  111. package/esm2022/staging/environment/environment-input.mjs +98 -85
  112. package/esm2022/staging/environment/environment-map.mjs +33 -33
  113. package/esm2022/staging/environment/environment-portal.mjs +75 -97
  114. package/esm2022/staging/environment/environment.mjs +34 -51
  115. package/esm2022/staging/environment/utils.mjs +40 -17
  116. package/esm2022/staging/float/float.mjs +70 -58
  117. package/esm2022/staging/index.mjs +7 -3
  118. package/esm2022/staging/matcap-texture/matcap-texture.mjs +64 -0
  119. package/esm2022/staging/normal-texture/normal-texture.mjs +53 -0
  120. package/esm2022/staging/sky/sky.mjs +85 -80
  121. package/esm2022/staging/sparkles/sparkles.mjs +108 -105
  122. package/esm2022/staging/spot-light/shadow-mesh-input.mjs +63 -0
  123. package/esm2022/staging/spot-light/shadow-mesh.mjs +267 -0
  124. package/esm2022/staging/spot-light/spot-light-input.mjs +67 -58
  125. package/esm2022/staging/spot-light/spot-light.mjs +51 -63
  126. package/esm2022/staging/spot-light/volumetric-mesh.mjs +67 -70
  127. package/esm2022/staging/stage/stage.mjs +305 -290
  128. package/esm2022/staging/stars/stars.mjs +101 -102
  129. package/esm2022/staging/wireframe/wireframe-input.mjs +191 -0
  130. package/esm2022/staging/wireframe/wireframe.mjs +228 -0
  131. package/esm2022/utils/angular-three-soba-utils.mjs +5 -0
  132. package/esm2022/utils/content/content.mjs +15 -0
  133. package/esm2022/utils/index.mjs +2 -0
  134. package/fesm2022/angular-three-soba-abstractions.mjs +514 -1947
  135. package/fesm2022/angular-three-soba-abstractions.mjs.map +1 -1
  136. package/fesm2022/angular-three-soba-cameras.mjs +303 -259
  137. package/fesm2022/angular-three-soba-cameras.mjs.map +1 -1
  138. package/fesm2022/angular-three-soba-controls.mjs +108 -83
  139. package/fesm2022/angular-three-soba-controls.mjs.map +1 -1
  140. package/fesm2022/angular-three-soba-gizmos.mjs +1045 -0
  141. package/fesm2022/angular-three-soba-gizmos.mjs.map +1 -0
  142. package/fesm2022/angular-three-soba-loaders.mjs +129 -119
  143. package/fesm2022/angular-three-soba-loaders.mjs.map +1 -1
  144. package/fesm2022/angular-three-soba-materials.mjs +662 -592
  145. package/fesm2022/angular-three-soba-materials.mjs.map +1 -1
  146. package/fesm2022/angular-three-soba-misc.mjs +2219 -108
  147. package/fesm2022/angular-three-soba-misc.mjs.map +1 -1
  148. package/fesm2022/angular-three-soba-modifiers.mjs +71 -0
  149. package/fesm2022/angular-three-soba-modifiers.mjs.map +1 -0
  150. package/fesm2022/angular-three-soba-performances.mjs +957 -0
  151. package/fesm2022/angular-three-soba-performances.mjs.map +1 -0
  152. package/fesm2022/angular-three-soba-shaders.mjs +551 -256
  153. package/fesm2022/angular-three-soba-shaders.mjs.map +1 -1
  154. package/fesm2022/angular-three-soba-staging.mjs +2910 -2573
  155. package/fesm2022/angular-three-soba-staging.mjs.map +1 -1
  156. package/fesm2022/angular-three-soba-utils.mjs +22 -0
  157. package/fesm2022/angular-three-soba-utils.mjs.map +1 -0
  158. package/gizmos/README.md +3 -0
  159. package/gizmos/gizmo-helper/gizmo-helper.d.ts +69 -0
  160. package/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.d.ts +22 -0
  161. package/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.d.ts +29 -0
  162. package/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube-input.d.ts +33 -0
  163. package/gizmos/gizmo-helper/gizmo-viewcube/gizmo-viewcube.d.ts +10 -0
  164. package/gizmos/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.d.ts +40 -0
  165. package/gizmos/gizmo-helper/gizmo-viewport/gizmo-viewport.d.ts +30 -0
  166. package/gizmos/index.d.ts +3 -0
  167. package/loaders/gltf-loader/gltf-loader.d.ts +4 -3
  168. package/loaders/loader/loader.d.ts +19 -17
  169. package/loaders/progress/progress.d.ts +1 -1
  170. package/loaders/texture-loader/texture-loader.d.ts +2 -2
  171. package/materials/index.d.ts +1 -0
  172. package/materials/mesh-distort-material/mesh-distort-material.d.ts +25 -15
  173. package/materials/mesh-reflector-material/mesh-reflector-material.d.ts +74 -56
  174. package/materials/mesh-refraction-material/mesh-refraction-material.d.ts +33 -21
  175. package/materials/mesh-transmission-material/mesh-transmission-material.d.ts +55 -39
  176. package/materials/mesh-wobble-material/mesh-wobble-material.d.ts +19 -10
  177. package/materials/point-material/point-material.d.ts +24 -0
  178. package/metadata.json +1 -0
  179. package/misc/animations/animations.d.ts +6 -4
  180. package/misc/caustics/caustics.d.ts +87 -0
  181. package/misc/decal/decal.d.ts +49 -0
  182. package/misc/depth-buffer/depth-buffer.d.ts +2 -2
  183. package/misc/example/example.d.ts +81 -0
  184. package/misc/fbo/fbo.d.ts +2 -2
  185. package/misc/html/html-wrapper.d.ts +559 -0
  186. package/misc/html/html.d.ts +214 -0
  187. package/misc/index.d.ts +9 -0
  188. package/misc/sampler/sampler.d.ts +67 -0
  189. package/misc/shadow/shadow.d.ts +37 -0
  190. package/misc/stats-gl/stats-gl.d.ts +24 -0
  191. package/misc/trail/trail.d.ts +57 -0
  192. package/misc/trail-texture/inject-trail-texture.d.ts +9 -0
  193. package/misc/trail-texture/trail-texture.d.ts +50 -0
  194. package/modifiers/README.md +3 -0
  195. package/modifiers/curve-modifier/curve-modifier.d.ts +23 -0
  196. package/modifiers/index.d.ts +1 -0
  197. package/package.json +42 -26
  198. package/performances/README.md +3 -0
  199. package/performances/adaptive-dpr/adaptive-dpr.d.ts +14 -0
  200. package/{performance/adaptive → performances/adaptive-events}/adaptive-events.d.ts +3 -0
  201. package/performances/index.d.ts +7 -0
  202. package/performances/instances/instances.d.ts +79 -0
  203. package/{performance → performances}/instances/position-mesh.d.ts +1 -1
  204. package/performances/points/points-input.d.ts +32 -0
  205. package/performances/points/points.d.ts +92 -0
  206. package/performances/points/position-point.d.ts +11 -0
  207. package/performances/segments/segment-object.d.ts +7 -0
  208. package/performances/segments/segments.d.ts +124 -0
  209. package/shaders/grid-material/grid-material.d.ts +37 -0
  210. package/shaders/index.d.ts +5 -2
  211. package/shaders/mesh-distort-material/mesh-distort-material.d.ts +173 -6
  212. package/shaders/mesh-transmission-material/mesh-transmission-material.d.ts +1 -1
  213. package/shaders/shader-material/shader-material.d.ts +2 -2
  214. package/shaders/soft-shadow-material/soft-shadow-material.d.ts +10 -1
  215. package/shaders/sparkles-material/sparkles-material.d.ts +15 -1
  216. package/shaders/spot-light-material/spot-light-material.d.ts +11 -2
  217. package/shaders/star-field-material/star-field-material.d.ts +11 -1
  218. package/shaders/wireframe-material/wireframe-material.d.ts +58 -0
  219. package/staging/accumulative-shadows/accumulative-shadows.d.ts +89 -39
  220. package/staging/accumulative-shadows/randomized-lights.d.ts +41 -28
  221. package/staging/backdrop/backdrop.d.ts +30 -0
  222. package/staging/bb-anchor/bb-anchor.d.ts +27 -0
  223. package/staging/bounds/bounds.d.ts +101 -25
  224. package/staging/camera-shake/camera-shake.d.ts +30 -19
  225. package/staging/center/center.d.ts +43 -35
  226. package/staging/cloud/cloud.d.ts +27 -24
  227. package/staging/contact-shadows/contact-shadows.d.ts +43 -30
  228. package/staging/environment/assets.d.ts +9 -9
  229. package/staging/environment/environment-cube.d.ts +9 -5
  230. package/staging/environment/environment-ground.d.ts +7 -7
  231. package/staging/environment/environment-input.d.ts +38 -38
  232. package/staging/environment/environment-map.d.ts +10 -5
  233. package/staging/environment/environment-portal.d.ts +10 -5
  234. package/staging/environment/environment.d.ts +0 -4
  235. package/staging/environment/utils.d.ts +2 -2
  236. package/staging/float/float.d.ts +15 -11
  237. package/staging/index.d.ts +6 -2
  238. package/staging/matcap-texture/matcap-texture.d.ts +13 -0
  239. package/staging/normal-texture/normal-texture.d.ts +16 -0
  240. package/staging/sky/sky.d.ts +28 -21
  241. package/staging/sparkles/sparkles.d.ts +36 -22
  242. package/staging/spot-light/shadow-mesh-input.d.ts +29 -0
  243. package/staging/spot-light/shadow-mesh.d.ts +37 -0
  244. package/staging/spot-light/spot-light-input.d.ts +25 -25
  245. package/staging/spot-light/spot-light.d.ts +31 -15
  246. package/staging/spot-light/volumetric-mesh.d.ts +15 -9
  247. package/staging/stage/stage.d.ts +89 -65
  248. package/staging/stars/stars.d.ts +28 -17
  249. package/staging/wireframe/wireframe-input.d.ts +65 -0
  250. package/staging/wireframe/wireframe.d.ts +28 -0
  251. package/utils/README.md +3 -0
  252. package/utils/content/content.d.ts +8 -0
  253. package/utils/index.d.ts +1 -0
  254. package/web-types.json +1 -0
  255. package/abstractions/catmull-rom-line/catmull-rom-line.d.ts +0 -25
  256. package/abstractions/cubic-bezier-line/cubic-bezier-line.d.ts +0 -25
  257. package/abstractions/gizmo-helper/gizmo-helper.d.ts +0 -34
  258. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.d.ts +0 -22
  259. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.d.ts +0 -30
  260. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.d.ts +0 -32
  261. package/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube.d.ts +0 -14
  262. package/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.d.ts +0 -47
  263. package/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport.d.ts +0 -40
  264. package/abstractions/line/line-input.d.ts +0 -42
  265. package/abstractions/line/line.d.ts +0 -35
  266. package/abstractions/quadratic-bezier-line/quadratic-bezier-line.d.ts +0 -23
  267. package/esm2022/abstractions/catmull-rom-line/catmull-rom-line.mjs +0 -131
  268. package/esm2022/abstractions/cubic-bezier-line/cubic-bezier-line.mjs +0 -113
  269. package/esm2022/abstractions/gizmo-helper/gizmo-helper.mjs +0 -210
  270. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/constants.mjs +0 -31
  271. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-edge.mjs +0 -95
  272. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-face.mjs +0 -155
  273. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube-inputs.mjs +0 -62
  274. package/esm2022/abstractions/gizmo-helper/gizmo-viewcube/gizmo-viewcube.mjs +0 -80
  275. package/esm2022/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport-axis.mjs +0 -206
  276. package/esm2022/abstractions/gizmo-helper/gizmo-viewport/gizmo-viewport.mjs +0 -273
  277. package/esm2022/abstractions/line/line-input.mjs +0 -113
  278. package/esm2022/abstractions/line/line.mjs +0 -165
  279. package/esm2022/abstractions/quadratic-bezier-line/quadratic-bezier-line.mjs +0 -128
  280. package/esm2022/performance/adaptive/adaptive-dpr.mjs +0 -46
  281. package/esm2022/performance/adaptive/adaptive-events.mjs +0 -31
  282. package/esm2022/performance/angular-three-soba-performance.mjs +0 -5
  283. package/esm2022/performance/detailed/detailed.mjs +0 -61
  284. package/esm2022/performance/index.mjs +0 -7
  285. package/esm2022/performance/instances/instance.mjs +0 -48
  286. package/esm2022/performance/instances/instances.mjs +0 -189
  287. package/esm2022/performance/instances/position-mesh.mjs +0 -52
  288. package/esm2022/performance/stats/stats.mjs +0 -79
  289. package/esm2022/shaders/caustics-material/caustics-material.mjs +0 -128
  290. package/esm2022/shaders/caustics-material/caustics-projection-material.mjs +0 -33
  291. package/esm2022/staging/caustics/caustisc.mjs +0 -384
  292. package/esm2022/staging/spot-light/spot-light-shadow-mesh-input.mjs +0 -57
  293. package/esm2022/staging/spot-light/spot-light-shadow-mesh.mjs +0 -256
  294. package/fesm2022/angular-three-soba-performance.mjs +0 -487
  295. package/fesm2022/angular-three-soba-performance.mjs.map +0 -1
  296. package/performance/README.md +0 -3
  297. package/performance/adaptive/adaptive-dpr.d.ts +0 -8
  298. package/performance/detailed/detailed.d.ts +0 -20
  299. package/performance/index.d.ts +0 -6
  300. package/performance/instances/instance.d.ts +0 -9
  301. package/performance/instances/instances.d.ts +0 -35
  302. package/performance/stats/stats.d.ts +0 -18
  303. package/plugin/generators.json +0 -19
  304. package/plugin/libs/plugin/README.md +0 -11
  305. package/plugin/package.json +0 -9
  306. package/plugin/src/generators/init/compat.d.ts +0 -2
  307. package/plugin/src/generators/init/compat.js +0 -6
  308. package/plugin/src/generators/init/compat.js.map +0 -1
  309. package/plugin/src/generators/init/init.d.ts +0 -4
  310. package/plugin/src/generators/init/init.js +0 -22
  311. package/plugin/src/generators/init/init.js.map +0 -1
  312. package/plugin/src/generators/init/schema.json +0 -6
  313. package/plugin/src/index.d.ts +0 -1
  314. package/plugin/src/index.js +0 -6
  315. package/plugin/src/index.js.map +0 -1
  316. package/staging/caustics/caustisc.d.ts +0 -70
  317. package/staging/spot-light/spot-light-shadow-mesh-input.d.ts +0 -29
  318. package/staging/spot-light/spot-light-shadow-mesh.d.ts +0 -38
  319. /package/{abstractions → gizmos}/gizmo-helper/gizmo-viewcube/constants.d.ts +0 -0
  320. /package/shaders/{caustics-material → caustics}/caustics-material.d.ts +0 -0
  321. /package/shaders/{caustics-material → caustics}/caustics-projection-material.d.ts +0 -0
@@ -1,10 +1,21 @@
1
1
  import * as i0 from '@angular/core';
2
- import { runInInjectionContext, inject, DestroyRef, effect, Directive, ChangeDetectorRef, signal, computed, untracked } from '@angular/core';
3
- import { assertInjectionContext, injectNgtRef, injectBeforeRender, NgtStore, safeDetectChanges } from 'angular-three';
2
+ import { runInInjectionContext, computed, effect, Directive, inject, ChangeDetectorRef, DestroyRef, Component, CUSTOM_ELEMENTS_SCHEMA, Input, forwardRef, signal, ViewContainerRef, untracked, ViewChild, EventEmitter, TemplateRef, ContentChild, Output, Injector } from '@angular/core';
3
+ import { injectNgtRef, injectBeforeRender, injectNgtStore, safeDetectChanges, extend, signalStore, is, applyProps, HTML, checkUpdate, NgtArgs, addEffect, addAfterEffect, NgtPortal, NgtPortalContent } from 'angular-three';
4
+ import { assertInjector } from 'ngxtension/assert-injector';
4
5
  import * as THREE from 'three';
6
+ import { Group, Scene, Mesh, PlaneGeometry, OrthographicCamera, LineBasicMaterial, BoxGeometry, MeshNormalMaterial, AxesHelper, MeshStandardMaterial, ShaderMaterial, CanvasTexture, MeshBasicMaterial, Texture } from 'three';
7
+ import { NgIf, DOCUMENT, NgTemplateOutlet } from '@angular/common';
8
+ import { NgtsEdges, NgtsText3D } from 'angular-three-soba/abstractions';
9
+ import { CausticsProjectionMaterial, CausticsMaterial } from 'angular-three-soba/shaders';
10
+ import { NgtsSobaContent } from 'angular-three-soba/utils';
11
+ import { FullScreenQuad, DecalGeometry, MeshSurfaceSampler } from 'three-stdlib';
12
+ import { NgtsCenter } from 'angular-three-soba/staging';
13
+ import { createInjectionToken } from 'ngxtension/create-injection-token';
14
+ import Stats from 'stats-gl';
15
+ import { MeshLineGeometry, MeshLineMaterial } from 'meshline';
5
16
 
6
- function injectNgtsAnimations(animationsFactory, { ref, injector }) {
7
- injector = assertInjectionContext(injectNgtsAnimations, injector);
17
+ function injectNgtsAnimations(animationsFactory, { ref, injector, playFirstClip = true, } = {}) {
18
+ injector = assertInjector(injectNgtsAnimations, injector);
8
19
  return runInInjectionContext(injector, () => {
9
20
  let actualRef = injectNgtRef();
10
21
  if (ref) {
@@ -18,152 +29,2252 @@ function injectNgtsAnimations(animationsFactory, { ref, injector }) {
18
29
  const mixer = new THREE.AnimationMixer(null);
19
30
  const actions = {};
20
31
  let cached = {};
32
+ let object = null;
21
33
  const clips = [];
22
34
  const names = [];
23
- inject(DestroyRef).onDestroy(() => {
24
- // clear cached
25
- cached = {};
26
- // uncache actions
27
- Object.values(actions).forEach((action) => {
28
- mixer.uncacheAction(action, actualRef.untracked);
29
- });
30
- // stop all actions
31
- mixer.stopAllAction();
32
- });
33
35
  injectBeforeRender(({ delta }) => mixer.update(delta));
34
- requestAnimationFrame(() => {
35
- effect(() => {
36
- const actual = actualRef.nativeElement;
37
- const animations = animationsFactory();
38
- for (let i = 0; i < animations.length; i++) {
39
- const clip = animations[i];
40
- names.push(clip.name);
41
- clips.push(clip);
42
- Object.defineProperty(actions, clip.name, {
43
- enumerable: true,
44
- get: () => {
45
- return cached[clip.name] || (cached[clip.name] = mixer.clipAction(clip, actual));
46
- },
47
- });
48
- if (i === 0) {
49
- actions[clip.name].play();
50
- }
36
+ const ready = computed(() => !!actualRef.nativeElement && !!animationsFactory().length);
37
+ effect((onCleanup) => {
38
+ const actual = actualRef.nativeElement;
39
+ if (!actual)
40
+ return;
41
+ object = actual;
42
+ const animations = animationsFactory();
43
+ for (let i = 0; i < animations.length; i++) {
44
+ const clip = animations[i];
45
+ names.push(clip.name);
46
+ clips.push(clip);
47
+ Object.defineProperty(actions, clip.name, {
48
+ enumerable: true,
49
+ get: () => {
50
+ return cached[clip.name] || (cached[clip.name] = mixer.clipAction(clip, actual));
51
+ },
52
+ });
53
+ if (i === 0 && playFirstClip) {
54
+ actions[clip.name].play();
51
55
  }
52
- }, { injector });
56
+ }
57
+ onCleanup(() => {
58
+ // clear cached
59
+ cached = {};
60
+ // stop all actions
61
+ mixer.stopAllAction();
62
+ // uncache actions
63
+ Object.values(actions).forEach((action) => {
64
+ mixer.uncacheAction(action, object);
65
+ });
66
+ object = null;
67
+ });
53
68
  });
54
- return { ref: actualRef, actions, mixer, names, clips };
69
+ return { ref: actualRef, actions, mixer, names, clips, ready };
55
70
  });
56
71
  }
57
72
 
58
73
  class NgtsBakeShadows {
59
74
  constructor() {
60
- const store = inject(NgtStore);
61
- const gl = store.select('gl');
75
+ const store = injectNgtStore();
76
+ const glShadowMap = store.select('gl', 'shadowMap');
62
77
  effect((onCleanup) => {
63
- gl().shadowMap.autoUpdate = false;
64
- gl().shadowMap.needsUpdate = true;
78
+ const shadowMap = glShadowMap();
79
+ shadowMap.autoUpdate = false;
80
+ shadowMap.needsUpdate = true;
65
81
  onCleanup(() => {
66
- gl().shadowMap.autoUpdate = gl().shadowMap.needsUpdate = true;
82
+ shadowMap.autoUpdate = shadowMap.needsUpdate = true;
67
83
  });
68
84
  });
69
85
  }
70
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsBakeShadows, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
71
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.0.0", type: NgtsBakeShadows, isStandalone: true, selector: "ngts-bake-shadows", ngImport: i0 }); }
86
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsBakeShadows, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
87
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtsBakeShadows, isStandalone: true, selector: "ngts-bake-shadows", ngImport: i0 }); }
72
88
  }
73
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: NgtsBakeShadows, decorators: [{
89
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsBakeShadows, decorators: [{
74
90
  type: Directive,
75
91
  args: [{ selector: 'ngts-bake-shadows', standalone: true }]
76
92
  }], ctorParameters: function () { return []; } });
77
93
 
78
94
  function injectNgtsFBO(fboParams, { injector } = {}) {
79
- injector = assertInjectionContext(injectNgtsFBO, injector);
95
+ injector = assertInjector(injectNgtsFBO, injector);
80
96
  return runInInjectionContext(injector, () => {
81
- const store = inject(NgtStore);
97
+ const store = injectNgtStore();
82
98
  const cdr = inject(ChangeDetectorRef);
83
- const targetRef = signal(null);
84
- inject(DestroyRef).onDestroy(() => targetRef().dispose());
85
- requestAnimationFrame(() => {
86
- const size = store.select('size');
87
- const dpr = store.select('viewport', 'dpr');
88
- const trigger = computed(() => {
89
- const { width, height, settings } = fboParams();
90
- const _width = typeof width === 'number' ? width : size().width * dpr();
91
- const _height = typeof height === 'number' ? height : size().height * dpr();
92
- const _settings = (typeof width === 'number' ? settings : width) || {};
93
- return { width: _width, height: _height, settings: _settings };
94
- });
95
- effect(() => {
96
- const { width, height, settings } = trigger();
97
- const { samples = 0, depth, ...targetSettings } = settings;
98
- let untrackedTarget = untracked(targetRef);
99
- if (!untrackedTarget) {
100
- const target = new THREE.WebGLRenderTarget(width, height, {
101
- minFilter: THREE.LinearFilter,
102
- magFilter: THREE.LinearFilter,
103
- type: THREE.HalfFloatType,
104
- ...targetSettings,
105
- });
106
- if (depth)
107
- target.depthTexture = new THREE.DepthTexture(width, height, THREE.FloatType);
108
- target.samples = samples;
109
- targetRef.set(target);
110
- untrackedTarget = untracked(targetRef);
111
- }
99
+ const targetRef = injectNgtRef(null);
100
+ inject(DestroyRef).onDestroy(() => targetRef.nativeElement?.dispose());
101
+ const size = store.select('size');
102
+ const dpr = store.select('viewport', 'dpr');
103
+ const fboSettings = computed(() => {
104
+ const { width, height, settings } = fboParams();
105
+ const _width = typeof width === 'number' ? width : size().width * dpr();
106
+ const _height = typeof height === 'number' ? height : size().height * dpr();
107
+ const _settings = (typeof width === 'number' ? settings : width) || {};
108
+ return { width: _width, height: _height, settings: _settings };
109
+ });
110
+ effect(() => {
111
+ const { width, height, settings } = fboSettings();
112
+ const { samples = 0, depth, ...targetSettings } = settings;
113
+ let untrackedTarget = targetRef.untracked;
114
+ if (!untrackedTarget) {
115
+ const target = new THREE.WebGLRenderTarget(width, height, {
116
+ minFilter: THREE.LinearFilter,
117
+ magFilter: THREE.LinearFilter,
118
+ type: THREE.HalfFloatType,
119
+ ...targetSettings,
120
+ });
121
+ if (depth)
122
+ target.depthTexture = new THREE.DepthTexture(width, height, THREE.FloatType);
123
+ target.samples = samples;
124
+ targetRef.nativeElement = target;
125
+ untrackedTarget = targetRef.untracked;
126
+ }
127
+ if (untrackedTarget) {
112
128
  untrackedTarget.setSize(width, height);
113
129
  if (samples)
114
130
  untrackedTarget.samples = samples;
115
131
  safeDetectChanges(cdr);
116
- }, { allowSignalWrites: true, injector });
132
+ }
117
133
  });
118
- return targetRef.asReadonly();
134
+ return targetRef;
119
135
  });
120
136
  }
121
137
 
138
+ extend({ Group, Scene, Mesh, PlaneGeometry, OrthographicCamera, CausticsProjectionMaterial, LineBasicMaterial });
139
+ const NORMALPROPS = {
140
+ depth: true,
141
+ minFilter: THREE.LinearFilter,
142
+ magFilter: THREE.LinearFilter,
143
+ type: THREE.UnsignedByteType,
144
+ };
145
+ const CAUSTICPROPS = {
146
+ minFilter: THREE.LinearMipmapLinearFilter,
147
+ magFilter: THREE.LinearFilter,
148
+ type: THREE.FloatType,
149
+ generateMipmaps: true,
150
+ };
151
+ function createNormalMaterial(side = THREE.FrontSide) {
152
+ const viewMatrix = { value: new THREE.Matrix4() };
153
+ return Object.assign(new THREE.MeshNormalMaterial({ side }), {
154
+ viewMatrix,
155
+ onBeforeCompile: (shader) => {
156
+ shader.uniforms.viewMatrix = viewMatrix;
157
+ shader.fragmentShader =
158
+ `vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
159
+ return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
160
+ }\n` +
161
+ shader.fragmentShader.replace('#include <normal_fragment_maps>', `#include <normal_fragment_maps>
162
+ normal = inverseTransformDirection( normal, viewMatrix );\n`);
163
+ },
164
+ });
165
+ }
166
+ class NgtsCaustics {
167
+ /** How many frames it will render, set it to Infinity for runtime, default: 1 */
168
+ set _frames(frames) {
169
+ this.inputs.set({ frames });
170
+ }
171
+ /** Enables visual cues to help you stage your scene, default: false */
172
+ set _debug(debug) {
173
+ this.inputs.set({ debug });
174
+ }
175
+ /** Will display caustics only and skip the models, default: false */
176
+ set _causticsOnly(causticsOnly) {
177
+ this.inputs.set({ causticsOnly });
178
+ }
179
+ /** Will include back faces and enable the backsideIOR prop, default: false */
180
+ set _backside(backside) {
181
+ this.inputs.set({ backside });
182
+ }
183
+ /** The IOR refraction index, default: 1.1 */
184
+ set _ior(ior) {
185
+ this.inputs.set({ ior });
186
+ }
187
+ /** The IOR refraction index for back faces (only available when backside is enabled), default: 1.1 */
188
+ set _backsideIOR(backsideIOR) {
189
+ this.inputs.set({ backsideIOR });
190
+ }
191
+ /** The texel size, default: 0.3125 */
192
+ set _worldRadius(worldRadius) {
193
+ this.inputs.set({ worldRadius });
194
+ }
195
+ /** Intensity of the prjected caustics, default: 0.05 */
196
+ set _intensity(intensity) {
197
+ this.inputs.set({ intensity });
198
+ }
199
+ /** Caustics color, default: white */
200
+ set _color(color) {
201
+ this.inputs.set({ color });
202
+ }
203
+ /** Buffer resolution, default: 2048 */
204
+ set _resolution(resolution) {
205
+ this.inputs.set({ resolution });
206
+ }
207
+ /** Camera position, it will point towards the contents bounds center, default: [5, 5, 5] */
208
+ set _lightSource(lightSource) {
209
+ this.inputs.set({ lightSource });
210
+ }
211
+ constructor() {
212
+ this.CustomBlending = THREE.CustomBlending;
213
+ this.OneFactor = THREE.OneFactor;
214
+ this.SrcAlphaFactor = THREE.SrcAlphaFactor;
215
+ this.Math = Math;
216
+ this.inputs = signalStore({
217
+ frames: 1,
218
+ ior: 1.1,
219
+ color: 'white',
220
+ causticsOnly: false,
221
+ backside: false,
222
+ backsideIOR: 1.1,
223
+ worldRadius: 0.3125,
224
+ intensity: 0.05,
225
+ resolution: 2024,
226
+ lightSource: [5, 5, 5],
227
+ });
228
+ this.causticsRef = injectNgtRef();
229
+ this.resolution = this.inputs.select('resolution');
230
+ this.normalTargetSettings = computed(() => ({
231
+ width: this.resolution(),
232
+ height: this.resolution(),
233
+ settings: NORMALPROPS,
234
+ }));
235
+ this.causticsTargetSettings = computed(() => ({
236
+ width: this.resolution(),
237
+ height: this.resolution(),
238
+ settings: CAUSTICPROPS,
239
+ }));
240
+ this.normalTargetFbo = injectNgtsFBO(this.normalTargetSettings);
241
+ this.normalTargetBFbo = injectNgtsFBO(this.normalTargetSettings);
242
+ this.causticsTargetFbo = injectNgtsFBO(this.causticsTargetSettings);
243
+ this.causticsTargetBFbo = injectNgtsFBO(this.causticsTargetSettings);
244
+ this.store = injectNgtStore();
245
+ this.color = this.inputs.select('color');
246
+ this.debug = this.inputs.select('debug');
247
+ this.planeRef = injectNgtRef();
248
+ this.sceneRef = injectNgtRef();
249
+ this.cameraRef = injectNgtRef();
250
+ this.sceneChildren = this.sceneRef.children();
251
+ this.planeChildren = this.planeRef.children('both');
252
+ this.causticsChildren = this.causticsRef.children();
253
+ this.updateWorldMatrix();
254
+ this.setBeforeRender();
255
+ }
256
+ updateWorldMatrix() {
257
+ effect(() => {
258
+ const [caustics] = [
259
+ this.causticsRef.nativeElement,
260
+ this.inputs.state(),
261
+ this.causticsChildren(),
262
+ this.sceneChildren(),
263
+ ];
264
+ if (!caustics)
265
+ return;
266
+ caustics.updateWorldMatrix(false, true);
267
+ });
268
+ }
269
+ setBeforeRender() {
270
+ const causticsMaterial = new CausticsMaterial();
271
+ const causticsQuad = new FullScreenQuad(causticsMaterial);
272
+ const normalMaterial = createNormalMaterial();
273
+ const normalMaterialB = createNormalMaterial(THREE.BackSide);
274
+ effect((onCleanup) => {
275
+ const [caustics, scene, camera, normalTarget, normalTargetB, causticsTarget, causticsTargetB, plane, sceneChildren,] = [
276
+ this.causticsRef.nativeElement,
277
+ this.sceneRef.nativeElement,
278
+ this.cameraRef.nativeElement,
279
+ this.normalTargetFbo.nativeElement,
280
+ this.normalTargetBFbo.nativeElement,
281
+ this.causticsTargetFbo.nativeElement,
282
+ this.causticsTargetBFbo.nativeElement,
283
+ this.planeRef.nativeElement,
284
+ this.sceneChildren(),
285
+ this.planeChildren(),
286
+ ];
287
+ if (!caustics)
288
+ return;
289
+ caustics.updateWorldMatrix(false, true);
290
+ if (sceneChildren.length > 1) {
291
+ const v = new THREE.Vector3();
292
+ const lpF = new THREE.Frustum();
293
+ const lpM = new THREE.Matrix4();
294
+ const lpP = new THREE.Plane();
295
+ const lightDir = new THREE.Vector3();
296
+ const lightDirInv = new THREE.Vector3();
297
+ const bounds = new THREE.Box3();
298
+ const focusPos = new THREE.Vector3();
299
+ let count = 0;
300
+ const sub = this.store.get('internal').subscribe(({ gl }) => {
301
+ const { frames, lightSource, resolution, worldRadius, intensity, backside, backsideIOR, ior, causticsOnly, } = this.inputs.get();
302
+ if (frames === Infinity || count++ < frames) {
303
+ if (Array.isArray(lightSource))
304
+ lightDir.fromArray(lightSource).normalize();
305
+ else
306
+ lightDir.copy(caustics.worldToLocal(lightSource.nativeElement.getWorldPosition(v)).normalize());
307
+ lightDirInv.copy(lightDir).multiplyScalar(-1);
308
+ let boundsVertices = [];
309
+ scene.parent?.matrixWorld.identity();
310
+ bounds.setFromObject(scene, true);
311
+ boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.min.y, bounds.min.z));
312
+ boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.min.y, bounds.max.z));
313
+ boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.max.y, bounds.min.z));
314
+ boundsVertices.push(new THREE.Vector3(bounds.min.x, bounds.max.y, bounds.max.z));
315
+ boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.min.y, bounds.min.z));
316
+ boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.min.y, bounds.max.z));
317
+ boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.max.y, bounds.min.z));
318
+ boundsVertices.push(new THREE.Vector3(bounds.max.x, bounds.max.y, bounds.max.z));
319
+ const worldVerts = boundsVertices.map((v) => v.clone());
320
+ bounds.getCenter(focusPos);
321
+ boundsVertices = boundsVertices.map((v) => v.clone().sub(focusPos));
322
+ const lightPlane = lpP.set(lightDirInv, 0);
323
+ const projectedVerts = boundsVertices.map((v) => lightPlane.projectPoint(v, new THREE.Vector3()));
324
+ const centralVert = projectedVerts
325
+ .reduce((a, b) => a.add(b), v.set(0, 0, 0))
326
+ .divideScalar(projectedVerts.length);
327
+ const radius = projectedVerts
328
+ .map((v) => v.distanceTo(centralVert))
329
+ .reduce((a, b) => Math.max(a, b));
330
+ const dirLength = boundsVertices.map((x) => x.dot(lightDir)).reduce((a, b) => Math.max(a, b));
331
+ // Shadows
332
+ camera.position.copy(lightDir.clone().multiplyScalar(dirLength).add(focusPos));
333
+ camera.lookAt(scene.localToWorld(focusPos.clone()));
334
+ const dirMatrix = lpM.lookAt(camera.position, focusPos, v.set(0, 1, 0));
335
+ camera.left = -radius;
336
+ camera.right = radius;
337
+ camera.top = radius;
338
+ camera.bottom = -radius;
339
+ const yOffset = v.set(0, radius, 0).applyMatrix4(dirMatrix);
340
+ const yTime = (camera.position.y + yOffset.y) / lightDir.y;
341
+ camera.near = 0.1;
342
+ camera.far = yTime;
343
+ camera.updateProjectionMatrix();
344
+ camera.updateMatrixWorld();
345
+ // Now find size of ground plane
346
+ const groundProjectedCoords = worldVerts.map((v) => v.add(lightDir.clone().multiplyScalar(-v.y / lightDir.y)));
347
+ const centerPos = groundProjectedCoords
348
+ .reduce((a, b) => a.add(b), v.set(0, 0, 0))
349
+ .divideScalar(groundProjectedCoords.length);
350
+ const maxSize = 2 *
351
+ groundProjectedCoords
352
+ .map((v) => Math.hypot(v.x - centerPos.x, v.z - centerPos.z))
353
+ .reduce((a, b) => Math.max(a, b));
354
+ plane.scale.setScalar(maxSize);
355
+ plane.position.copy(centerPos);
356
+ // if (debug) helper.current?.update();
357
+ // Inject uniforms
358
+ normalMaterialB.viewMatrix.value = normalMaterial.viewMatrix.value = camera.matrixWorldInverse;
359
+ const dirLightNearPlane = lpF.setFromProjectionMatrix(lpM.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)).planes[4];
360
+ causticsMaterial.cameraMatrixWorld = camera.matrixWorld;
361
+ causticsMaterial.cameraProjectionMatrixInv = camera.projectionMatrixInverse;
362
+ causticsMaterial.lightDir = lightDirInv;
363
+ causticsMaterial.lightPlaneNormal = dirLightNearPlane.normal;
364
+ causticsMaterial.lightPlaneConstant = dirLightNearPlane.constant;
365
+ causticsMaterial.near = camera.near;
366
+ causticsMaterial.far = camera.far;
367
+ causticsMaterial.resolution = resolution;
368
+ causticsMaterial.size = radius;
369
+ causticsMaterial.intensity = intensity;
370
+ causticsMaterial.worldRadius = worldRadius;
371
+ // Switch the scene on
372
+ scene.visible = true;
373
+ // Render front face normals
374
+ gl.setRenderTarget(normalTarget);
375
+ gl.clear();
376
+ scene.overrideMaterial = normalMaterial;
377
+ gl.render(scene, camera);
378
+ // Render back face normals, if enabled
379
+ gl.setRenderTarget(normalTargetB);
380
+ gl.clear();
381
+ if (backside) {
382
+ scene.overrideMaterial = normalMaterialB;
383
+ gl.render(scene, camera);
384
+ }
385
+ // Remove the override material
386
+ scene.overrideMaterial = null;
387
+ // Render front face caustics
388
+ causticsMaterial.ior = ior;
389
+ plane.material.lightProjMatrix = camera.projectionMatrix;
390
+ plane.material.lightViewMatrix = camera.matrixWorldInverse;
391
+ causticsMaterial.normalTexture = normalTarget?.texture;
392
+ causticsMaterial.depthTexture = normalTarget?.depthTexture;
393
+ gl.setRenderTarget(causticsTarget);
394
+ gl.clear();
395
+ causticsQuad.render(gl);
396
+ // Render back face caustics, if enabled
397
+ causticsMaterial.ior = backsideIOR;
398
+ causticsMaterial.normalTexture = normalTargetB?.texture;
399
+ causticsMaterial.depthTexture = normalTargetB?.depthTexture;
400
+ gl.setRenderTarget(causticsTargetB);
401
+ gl.clear();
402
+ if (backside)
403
+ causticsQuad.render(gl);
404
+ // Reset render target
405
+ gl.setRenderTarget(null);
406
+ // Switch the scene off if caustics is all that's wanted
407
+ if (causticsOnly)
408
+ scene.visible = false;
409
+ }
410
+ });
411
+ onCleanup(() => sub());
412
+ }
413
+ });
414
+ }
415
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsCaustics, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
416
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsCaustics, isStandalone: true, selector: "ngts-caustics", inputs: { causticsRef: "causticsRef", _frames: ["frames", "_frames"], _debug: ["debug", "_debug"], _causticsOnly: ["causticsOnly", "_causticsOnly"], _backside: ["backside", "_backside"], _ior: ["ior", "_ior"], _backsideIOR: ["backsideIOR", "_backsideIOR"], _worldRadius: ["worldRadius", "_worldRadius"], _intensity: ["intensity", "_intensity"], _color: ["color", "_color"], _resolution: ["resolution", "_resolution"], _lightSource: ["lightSource", "_lightSource"] }, ngImport: i0, template: `
417
+ <ngt-group [ref]="causticsRef" ngtCompound>
418
+ <ngt-scene [ref]="sceneRef">
419
+ <ngt-orthographic-camera [ref]="cameraRef" [up]="[0, 1, 0]" />
420
+ <ng-content />
421
+ </ngt-scene>
422
+ <ngt-mesh [renderOrder]="2" [ref]="planeRef" [rotation]="[-Math.PI / 2, 0, 0]">
423
+ <ngt-plane-geometry />
424
+ <ngt-caustics-projection-material
425
+ *ngIf="causticsTargetFbo.nativeElement && causticsTargetBFbo.nativeElement"
426
+ [transparent]="true"
427
+ [color]="color()"
428
+ [causticsTexture]="causticsTargetFbo.nativeElement.texture"
429
+ [causticsTextureB]="causticsTargetBFbo.nativeElement.texture"
430
+ [blending]="CustomBlending"
431
+ [blendSrc]="OneFactor"
432
+ [blendDst]="SrcAlphaFactor"
433
+ [depthWrite]="false"
434
+ />
435
+
436
+ <ngts-edges *ngIf="debug()">
437
+ <ngt-line-basic-material *ngtsSobaContent color="#ffff00" [toneMapped]="false" />
438
+ </ngts-edges>
439
+ </ngt-mesh>
440
+ </ngt-group>
441
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtsEdges, selector: "ngts-edges", inputs: ["edgesRef", "threshold", "color", "geometry", "userData"] }, { kind: "directive", type: NgtsSobaContent, selector: "ng-template[ngtsSobaContent]", exportAs: ["sobaContent"] }] }); }
442
+ }
443
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsCaustics, decorators: [{
444
+ type: Component,
445
+ args: [{
446
+ selector: 'ngts-caustics',
447
+ standalone: true,
448
+ template: `
449
+ <ngt-group [ref]="causticsRef" ngtCompound>
450
+ <ngt-scene [ref]="sceneRef">
451
+ <ngt-orthographic-camera [ref]="cameraRef" [up]="[0, 1, 0]" />
452
+ <ng-content />
453
+ </ngt-scene>
454
+ <ngt-mesh [renderOrder]="2" [ref]="planeRef" [rotation]="[-Math.PI / 2, 0, 0]">
455
+ <ngt-plane-geometry />
456
+ <ngt-caustics-projection-material
457
+ *ngIf="causticsTargetFbo.nativeElement && causticsTargetBFbo.nativeElement"
458
+ [transparent]="true"
459
+ [color]="color()"
460
+ [causticsTexture]="causticsTargetFbo.nativeElement.texture"
461
+ [causticsTextureB]="causticsTargetBFbo.nativeElement.texture"
462
+ [blending]="CustomBlending"
463
+ [blendSrc]="OneFactor"
464
+ [blendDst]="SrcAlphaFactor"
465
+ [depthWrite]="false"
466
+ />
467
+
468
+ <ngts-edges *ngIf="debug()">
469
+ <ngt-line-basic-material *ngtsSobaContent color="#ffff00" [toneMapped]="false" />
470
+ </ngts-edges>
471
+ </ngt-mesh>
472
+ </ngt-group>
473
+ `,
474
+ imports: [NgIf, NgtsEdges, NgtsSobaContent],
475
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
476
+ }]
477
+ }], ctorParameters: function () { return []; }, propDecorators: { causticsRef: [{
478
+ type: Input
479
+ }], _frames: [{
480
+ type: Input,
481
+ args: [{ alias: 'frames' }]
482
+ }], _debug: [{
483
+ type: Input,
484
+ args: [{ alias: 'debug' }]
485
+ }], _causticsOnly: [{
486
+ type: Input,
487
+ args: [{ alias: 'causticsOnly' }]
488
+ }], _backside: [{
489
+ type: Input,
490
+ args: [{ alias: 'backside' }]
491
+ }], _ior: [{
492
+ type: Input,
493
+ args: [{ alias: 'ior' }]
494
+ }], _backsideIOR: [{
495
+ type: Input,
496
+ args: [{ alias: 'backsideIOR' }]
497
+ }], _worldRadius: [{
498
+ type: Input,
499
+ args: [{ alias: 'worldRadius' }]
500
+ }], _intensity: [{
501
+ type: Input,
502
+ args: [{ alias: 'intensity' }]
503
+ }], _color: [{
504
+ type: Input,
505
+ args: [{ alias: 'color' }]
506
+ }], _resolution: [{
507
+ type: Input,
508
+ args: [{ alias: 'resolution' }]
509
+ }], _lightSource: [{
510
+ type: Input,
511
+ args: [{ alias: 'lightSource' }]
512
+ }] } });
513
+
514
+ extend({ Mesh, BoxGeometry, MeshNormalMaterial, AxesHelper });
515
+ function vecToArray(vec = [0, 0, 0]) {
516
+ if (Array.isArray(vec)) {
517
+ return vec;
518
+ }
519
+ if (vec instanceof THREE.Vector3 || vec instanceof THREE.Euler) {
520
+ return [vec.x, vec.y, vec.z];
521
+ }
522
+ return [vec, vec, vec];
523
+ }
524
+ class NgtsDecal {
525
+ set _debug(debug) {
526
+ this.inputs.set({ debug });
527
+ }
528
+ set _mesh(mesh) {
529
+ this.inputs.set({ mesh });
530
+ }
531
+ set _position(position) {
532
+ this.inputs.set({ position });
533
+ }
534
+ set _rotation(rotation) {
535
+ this.inputs.set({ rotation });
536
+ }
537
+ set _scale(scale) {
538
+ this.inputs.set({ scale });
539
+ }
540
+ set _map(map) {
541
+ this.inputs.set({ map });
542
+ }
543
+ set _polygonOffsetFactor(polygonOffsetFactor) {
544
+ this.inputs.set({ polygonOffsetFactor });
545
+ }
546
+ set _depthTest(depthTest) {
547
+ this.inputs.set({ depthTest });
548
+ }
549
+ constructor() {
550
+ this.inputs = signalStore({
551
+ debug: false,
552
+ depthTest: false,
553
+ polygonOffsetFactor: -10,
554
+ position: [0, 0, 0],
555
+ rotation: [0, 0, 0],
556
+ scale: 1,
557
+ });
558
+ this.decalRef = injectNgtRef();
559
+ this.mesh = this.inputs.select('mesh');
560
+ this.__position = this.inputs.select('position');
561
+ this.__rotation = this.inputs.select('rotation');
562
+ this.__scale = this.inputs.select('scale');
563
+ this.position = computed(() => vecToArray(this.__position()));
564
+ this.rotation = computed(() => vecToArray(this.__rotation()));
565
+ this.scale = computed(() => vecToArray(this.__scale()));
566
+ this.helperRef = injectNgtRef();
567
+ this.debug = this.inputs.select('debug');
568
+ this.depthTest = this.inputs.select('depthTest');
569
+ this.polygonOffsetFactor = this.inputs.select('polygonOffsetFactor');
570
+ this.map = this.inputs.select('map');
571
+ this.processDecal();
572
+ }
573
+ processDecal() {
574
+ effect((onCleanup) => {
575
+ const decal = this.decalRef.nativeElement;
576
+ if (!decal)
577
+ return;
578
+ const [mesh, position, rotation, scale, helper] = [
579
+ this.mesh(),
580
+ this.position(),
581
+ this.rotation(),
582
+ this.scale(),
583
+ this.helperRef.nativeElement,
584
+ ];
585
+ const parent = mesh ? (is.ref(mesh) ? mesh.nativeElement : mesh) : decal.parent;
586
+ if (!(parent instanceof Mesh)) {
587
+ throw new Error('[NGT] ngts-decal must have a ngt-mesh as parent or specify its "mesh" input');
588
+ }
589
+ const state = {
590
+ position: new THREE.Vector3(),
591
+ rotation: new THREE.Euler(),
592
+ scale: new THREE.Vector3(1, 1, 1),
593
+ };
594
+ if (parent) {
595
+ applyProps(state, { position, scale });
596
+ // Zero out the parents matrix world for this operation
597
+ const matrixWorld = parent.matrixWorld.clone();
598
+ parent.matrixWorld.identity();
599
+ if (!rotation || typeof rotation === 'number') {
600
+ const o = new THREE.Object3D();
601
+ o.position.copy(state.position);
602
+ o.lookAt(parent.position);
603
+ if (typeof rotation === 'number')
604
+ o.rotateZ(rotation);
605
+ applyProps(state, { rotation: o.rotation });
606
+ }
607
+ else {
608
+ applyProps(state, { rotation });
609
+ }
610
+ decal.geometry = new DecalGeometry(parent, state.position, state.rotation, state.scale);
611
+ if (helper) {
612
+ applyProps(helper, state);
613
+ // Prevent the helpers from blocking rays
614
+ helper.traverse((child) => (child.raycast = () => null));
615
+ }
616
+ // Reset parents matix-world
617
+ parent.matrixWorld = matrixWorld;
618
+ onCleanup(() => {
619
+ decal.geometry.dispose();
620
+ });
621
+ }
622
+ });
623
+ }
624
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsDecal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
625
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsDecal, isStandalone: true, selector: "ngts-decal", inputs: { decalRef: "decalRef", _debug: ["debug", "_debug"], _mesh: ["mesh", "_mesh"], _position: ["position", "_position"], _rotation: ["rotation", "_rotation"], _scale: ["scale", "_scale"], _map: ["map", "_map"], _polygonOffsetFactor: ["polygonOffsetFactor", "_polygonOffsetFactor"], _depthTest: ["depthTest", "_depthTest"] }, ngImport: i0, template: `
626
+ <ngt-mesh [ref]="decalRef" ngtCompound>
627
+ <ngt-value [rawValue]="true" attach="material.transparent" />
628
+ <ngt-value [rawValue]="true" attach="material.polygonOffset" />
629
+ <ngt-value [rawValue]="polygonOffsetFactor()" attach="material.polygonOffsetFactor" />
630
+ <ngt-value [rawValue]="depthTest()" attach="material.depthTest" />
631
+ <ngt-value [rawValue]="map()" attach="material.map" />
632
+ <ng-content />
633
+
634
+ <ngt-mesh *ngIf="debug()" [ref]="helperRef">
635
+ <ngt-box-geometry />
636
+ <ngt-mesh-normal-material [wireframe]="true" />
637
+ <ngt-axes-helper />
638
+ </ngt-mesh>
639
+ </ngt-mesh>
640
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
641
+ }
642
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsDecal, decorators: [{
643
+ type: Component,
644
+ args: [{
645
+ selector: 'ngts-decal',
646
+ standalone: true,
647
+ template: `
648
+ <ngt-mesh [ref]="decalRef" ngtCompound>
649
+ <ngt-value [rawValue]="true" attach="material.transparent" />
650
+ <ngt-value [rawValue]="true" attach="material.polygonOffset" />
651
+ <ngt-value [rawValue]="polygonOffsetFactor()" attach="material.polygonOffsetFactor" />
652
+ <ngt-value [rawValue]="depthTest()" attach="material.depthTest" />
653
+ <ngt-value [rawValue]="map()" attach="material.map" />
654
+ <ng-content />
655
+
656
+ <ngt-mesh *ngIf="debug()" [ref]="helperRef">
657
+ <ngt-box-geometry />
658
+ <ngt-mesh-normal-material [wireframe]="true" />
659
+ <ngt-axes-helper />
660
+ </ngt-mesh>
661
+ </ngt-mesh>
662
+ `,
663
+ imports: [NgIf],
664
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
665
+ }]
666
+ }], ctorParameters: function () { return []; }, propDecorators: { decalRef: [{
667
+ type: Input
668
+ }], _debug: [{
669
+ type: Input,
670
+ args: [{ alias: 'debug' }]
671
+ }], _mesh: [{
672
+ type: Input,
673
+ args: [{ alias: 'mesh' }]
674
+ }], _position: [{
675
+ type: Input,
676
+ args: [{ alias: 'position' }]
677
+ }], _rotation: [{
678
+ type: Input,
679
+ args: [{ alias: 'rotation' }]
680
+ }], _scale: [{
681
+ type: Input,
682
+ args: [{ alias: 'scale' }]
683
+ }], _map: [{
684
+ type: Input,
685
+ args: [{ alias: 'map' }]
686
+ }], _polygonOffsetFactor: [{
687
+ type: Input,
688
+ args: [{ alias: 'polygonOffsetFactor' }]
689
+ }], _depthTest: [{
690
+ type: Input,
691
+ args: [{ alias: 'depthTest' }]
692
+ }] } });
693
+
122
694
  function injectNgtsDepthBuffer(paramsFactory = () => ({}), { injector } = {}) {
123
- injector = assertInjectionContext(injectNgtsDepthBuffer, injector);
695
+ injector = assertInjector(injectNgtsDepthBuffer, injector);
124
696
  return runInInjectionContext(injector, () => {
125
- const depthBufferRef = signal(null);
126
- const store = inject(NgtStore);
697
+ const depthBufferRef = injectNgtRef(null);
698
+ const store = injectNgtStore();
127
699
  const cdr = inject(ChangeDetectorRef);
128
700
  const size = store.select('size');
129
701
  const dpr = store.select('viewport', 'dpr');
130
- requestAnimationFrame(() => {
131
- const fboParams = computed(() => {
132
- const params = { size: 256, frames: Infinity, ...paramsFactory() };
133
- const width = params.size || size().width * dpr();
134
- const height = params.size || size().height * dpr();
135
- const depthTexture = new THREE.DepthTexture(width, height);
136
- depthTexture.format = THREE.DepthFormat;
137
- depthTexture.type = THREE.UnsignedShortType;
138
- return { width, height, settings: { depthTexture } };
702
+ const fboParams = computed(() => {
703
+ const params = { size: 256, frames: Infinity, ...paramsFactory() };
704
+ const width = params.size || size().width * dpr();
705
+ const height = params.size || size().height * dpr();
706
+ const depthTexture = new THREE.DepthTexture(width, height);
707
+ depthTexture.format = THREE.DepthFormat;
708
+ depthTexture.type = THREE.UnsignedShortType;
709
+ return { width, height, settings: { depthTexture } };
710
+ });
711
+ const fboRef = injectNgtsFBO(fboParams, { injector });
712
+ effect(() => {
713
+ const fbo = fboRef.nativeElement;
714
+ if (fbo) {
715
+ depthBufferRef.nativeElement = fbo.depthTexture;
716
+ safeDetectChanges(cdr);
717
+ }
718
+ });
719
+ let count = 0;
720
+ injectBeforeRender(({ gl, scene, camera }) => {
721
+ const params = { size: 256, frames: Infinity, ...paramsFactory() };
722
+ const fbo = fboRef.untracked;
723
+ if ((params.frames === Infinity || count < params.frames) && fbo) {
724
+ gl.setRenderTarget(fbo);
725
+ gl.render(scene, camera);
726
+ gl.setRenderTarget(null);
727
+ count++;
728
+ }
729
+ }, { injector });
730
+ return depthBufferRef;
731
+ });
732
+ }
733
+
734
+ /**
735
+ * augment HTMLElementTagNameMap with the selector of the component.
736
+ * the type is usually the Inputs' state and the root THREE element
737
+
738
+ declare global {
739
+ interface HTMLElementTagNameMap {
740
+ \/**
741
+ * @extends ngt-group
742
+ *\/
743
+ 'ngts-example': NgtsExampleState & NgtGroup;
744
+ }
745
+ }
746
+
747
+ */
748
+ /**
749
+ * make sure soba's component extends all regular THREE entities that it needs
750
+ */
751
+ extend({ Group, MeshNormalMaterial, MeshStandardMaterial });
752
+ /**
753
+ * We can setup public API for this soba component with createInjectionToken + forwardRef
754
+ * the `example.api` is **usually** a computed property in the component class
755
+ *
756
+ * @see Bounds for example
757
+ */
758
+ const [injectNgtsExampleApi, provideNgtsExampleApi] = createInjectionToken((example) => example.api, { isRoot: false, deps: [forwardRef(() => NgtsExample)] });
759
+ /**
760
+ * @description this component is only for documentation purposes.
761
+ */
762
+ class NgtsExample {
763
+ constructor() {
764
+ /**
765
+ * use signalStore to store inputs with default inputs
766
+ */
767
+ this.inputs = signalStore({ color: '#cbcbcb', bevelSize: 0.04, debug: false });
768
+ /**
769
+ * a soba component usually has a Input for the component ref and this Input always has a default value with injectNgtRef
770
+ */
771
+ this.exampleRef = injectNgtRef();
772
+ /**
773
+ * exposes signals from inputs
774
+ */
775
+ this.bevelSize = this.inputs.select('bevelSize');
776
+ this.font = this.inputs.select('font');
777
+ this.debug = this.inputs.select('debug');
778
+ this.color = this.inputs.select('color');
779
+ /**
780
+ * can have internal state
781
+ */
782
+ this.count = signal(0);
783
+ /**
784
+ * Expose the public API for this soba component
785
+ */
786
+ this.api = computed(() => ({
787
+ bevelSize: this.bevelSize(),
788
+ increment: () => this.count.update((v) => v + 1),
789
+ decrement: () => this.count.update((v) => v - 1),
790
+ }));
791
+ }
792
+ /**
793
+ * setup Input for the Inputs state. Use alias to have an easier time to setup computed
794
+ *
795
+ * @example: this way "private font" and "set _font" won't conflict
796
+ * private font = this.inputs.select('font');
797
+ */
798
+ set _font(font) {
799
+ this.inputs.set({ font });
800
+ }
801
+ set _color(color) {
802
+ this.inputs.set({ color });
803
+ }
804
+ set _debug(debug) {
805
+ this.inputs.set({ debug });
806
+ }
807
+ set _bevelSize(bevelSize) {
808
+ this.inputs.set({ bevelSize });
809
+ }
810
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsExample, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
811
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsExample, isStandalone: true, selector: "ngts-example", inputs: { exampleRef: "exampleRef", _font: ["font", "_font"], _color: ["color", "_color"], _debug: ["debug", "_debug"], _bevelSize: ["bevelSize", "_bevelSize"] }, providers: [provideNgtsExampleApi()], ngImport: i0, template: `
812
+ <!-- ngtCompound is used by the Renderer to spread props from ngts-example down to ngt-group -->
813
+ <!-- i.e: <ngts-example [position]="[1, 1, 1]" />, [1, 1, 1] will be passed down to ngt-group -->
814
+ <!-- [ref] is used with the Input so that the consumer can pass an external ref and control this internal ngt-group -->
815
+ <ngt-group ngtCompound [ref]="exampleRef">
816
+ <ngts-center [top]="true">
817
+ <ngts-text-3d
818
+ [bevelEnabled]="true"
819
+ [bevelSize]="bevelSize()"
820
+ [font]="font()"
821
+ [text]="count().toString()"
822
+ >
823
+ <ngt-mesh-standard-material *ngIf="!debug(); else withDebug" [color]="color()" />
824
+ <ng-template #withDebug>
825
+ <ngt-mesh-normal-material [wireframe]="true" />
826
+ </ng-template>
827
+ </ngts-text-3d>
828
+ </ngts-center>
829
+ <!-- use Content Projection here so consumers can pass in children for ngt-group -->
830
+ <ng-content />
831
+ </ngt-group>
832
+ `, isInline: true, dependencies: [{ kind: "component", type: NgtsCenter, selector: "ngts-center", inputs: ["centerRef", "top", "right", "bottom", "left", "front", "back", "disableX", "disableY", "disableZ", "disable", "precise", "cacheKey"], outputs: ["centered"] }, { kind: "component", type: NgtsText3D, selector: "ngts-text-3d", inputs: ["textRef", "font", "text", "bevelEnabled", "bevelOffset", "bevelSize", "bevelThickness", "curveSegments", "bevelSegments", "height", "size", "lineHeight", "letterSpacing", "smooth"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); }
833
+ }
834
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsExample, decorators: [{
835
+ type: Component,
836
+ args: [{
837
+ selector: 'ngts-example',
838
+ standalone: true,
839
+ template: `
840
+ <!-- ngtCompound is used by the Renderer to spread props from ngts-example down to ngt-group -->
841
+ <!-- i.e: <ngts-example [position]="[1, 1, 1]" />, [1, 1, 1] will be passed down to ngt-group -->
842
+ <!-- [ref] is used with the Input so that the consumer can pass an external ref and control this internal ngt-group -->
843
+ <ngt-group ngtCompound [ref]="exampleRef">
844
+ <ngts-center [top]="true">
845
+ <ngts-text-3d
846
+ [bevelEnabled]="true"
847
+ [bevelSize]="bevelSize()"
848
+ [font]="font()"
849
+ [text]="count().toString()"
850
+ >
851
+ <ngt-mesh-standard-material *ngIf="!debug(); else withDebug" [color]="color()" />
852
+ <ng-template #withDebug>
853
+ <ngt-mesh-normal-material [wireframe]="true" />
854
+ </ng-template>
855
+ </ngts-text-3d>
856
+ </ngts-center>
857
+ <!-- use Content Projection here so consumers can pass in children for ngt-group -->
858
+ <ng-content />
859
+ </ngt-group>
860
+ `,
861
+ /**
862
+ * can definitely use other Soba components
863
+ */
864
+ imports: [NgtsCenter, NgtsText3D, NgIf],
865
+ /**
866
+ * call the API provider here to actually provide the API for the component's children
867
+ */
868
+ providers: [provideNgtsExampleApi()],
869
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
870
+ }]
871
+ }], propDecorators: { exampleRef: [{
872
+ type: Input
873
+ }], _font: [{
874
+ type: Input,
875
+ args: [{ alias: 'font', required: true }]
876
+ }], _color: [{
877
+ type: Input,
878
+ args: [{ alias: 'color' }]
879
+ }], _debug: [{
880
+ type: Input,
881
+ args: [{ alias: 'debug' }]
882
+ }], _bevelSize: [{
883
+ type: Input,
884
+ args: [{ alias: 'bevelSize' }]
885
+ }] } });
886
+
887
+ var _a;
888
+ const v1 = new THREE.Vector3();
889
+ const v2 = new THREE.Vector3();
890
+ const v3 = new THREE.Vector3();
891
+ function defaultCalculatePosition(el, camera, size) {
892
+ const objectPos = v1.setFromMatrixPosition(el.matrixWorld);
893
+ objectPos.project(camera);
894
+ const widthHalf = size.width / 2;
895
+ const heightHalf = size.height / 2;
896
+ return [objectPos.x * widthHalf + widthHalf, -(objectPos.y * heightHalf) + heightHalf];
897
+ }
898
+ function isObjectBehindCamera(el, camera) {
899
+ const objectPos = v1.setFromMatrixPosition(el.matrixWorld);
900
+ const cameraPos = v2.setFromMatrixPosition(camera.matrixWorld);
901
+ const deltaCamObj = objectPos.sub(cameraPos);
902
+ const camDir = camera.getWorldDirection(v3);
903
+ return deltaCamObj.angleTo(camDir) > Math.PI / 2;
904
+ }
905
+ function isObjectVisible(el, camera, raycaster, occlude) {
906
+ const elPos = v1.setFromMatrixPosition(el.matrixWorld);
907
+ const screenPos = elPos.clone();
908
+ screenPos.project(camera);
909
+ raycaster.setFromCamera(screenPos, camera);
910
+ const intersects = raycaster.intersectObjects(occlude, true);
911
+ if (intersects.length) {
912
+ const intersectionDistance = intersects[0].distance;
913
+ const pointDistance = elPos.distanceTo(raycaster.ray.origin);
914
+ return pointDistance < intersectionDistance;
915
+ }
916
+ return true;
917
+ }
918
+ function objectScale(el, camera) {
919
+ if (camera instanceof THREE.OrthographicCamera) {
920
+ return camera.zoom;
921
+ }
922
+ else if (camera instanceof THREE.PerspectiveCamera) {
923
+ const objectPos = v1.setFromMatrixPosition(el.matrixWorld);
924
+ const cameraPos = v2.setFromMatrixPosition(camera.matrixWorld);
925
+ const vFOV = (camera.fov * Math.PI) / 180;
926
+ const dist = objectPos.distanceTo(cameraPos);
927
+ const scaleFOV = 2 * Math.tan(vFOV / 2) * dist;
928
+ return 1 / scaleFOV;
929
+ }
930
+ else {
931
+ return 1;
932
+ }
933
+ }
934
+ function objectZIndex(el, camera, zIndexRange) {
935
+ if (camera instanceof THREE.PerspectiveCamera || camera instanceof THREE.OrthographicCamera) {
936
+ const objectPos = v1.setFromMatrixPosition(el.matrixWorld);
937
+ const cameraPos = v2.setFromMatrixPosition(camera.matrixWorld);
938
+ const dist = objectPos.distanceTo(cameraPos);
939
+ const A = (zIndexRange[1] - zIndexRange[0]) / (camera.far - camera.near);
940
+ const B = zIndexRange[1] - A * camera.far;
941
+ return Math.round(A * dist + B);
942
+ }
943
+ return undefined;
944
+ }
945
+ const epsilon = (value) => (Math.abs(value) < 1e-10 ? 0 : value);
946
+ function getCSSMatrix(matrix, multipliers, prepend = '') {
947
+ let matrix3d = 'matrix3d(';
948
+ for (let i = 0; i !== 16; i++) {
949
+ matrix3d += epsilon(multipliers[i] * matrix.elements[i]) + (i !== 15 ? ',' : ')');
950
+ }
951
+ return prepend + matrix3d;
952
+ }
953
+ const getCameraCSSMatrix = ((multipliers) => {
954
+ return (matrix) => getCSSMatrix(matrix, multipliers);
955
+ })([1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1]);
956
+ const getObjectCSSMatrix = ((scaleMultipliers) => {
957
+ return (matrix, factor) => getCSSMatrix(matrix, scaleMultipliers(factor), 'translate(-50%,-50%)');
958
+ })((f) => [1 / f, 1 / f, 1 / f, 1, -1 / f, -1 / f, -1 / f, -1, 1 / f, 1 / f, 1 / f, 1, 1, 1, 1, 1]);
959
+ class NgtsHtmlWrapper {
960
+ static { _a = HTML; }
961
+ static { this[_a] = true; }
962
+ constructor() {
963
+ this.htmlInputs = injectNgtsHtmlInputs();
964
+ this.store = injectNgtStore();
965
+ this.gl = this.store.select('gl');
966
+ this.connected = this.store.select('events', 'connected', { equal: Object.is });
967
+ this.viewport = this.store.select('viewport');
968
+ this.scene = this.store.select('scene');
969
+ this.camera = this.store.select('camera');
970
+ this.size = this.store.select('size');
971
+ this.raycaster = this.store.select('raycaster');
972
+ this.isMeshSizeSet = false;
973
+ this.document = inject(DOCUMENT);
974
+ this.vcr = inject(ViewContainerRef);
975
+ this.portalElement = computed(() => {
976
+ const portal = this.htmlInputs.portal();
977
+ if (!portal)
978
+ return null;
979
+ return is.ref(portal) ? portal.nativeElement : portal;
980
+ });
981
+ this.element = computed(() => this.document.createElement(this.htmlInputs.as()));
982
+ this.target = computed(() => {
983
+ const portalElement = this.portalElement();
984
+ if (portalElement)
985
+ return portalElement;
986
+ const connected = this.connected();
987
+ if (connected)
988
+ return connected;
989
+ return this.gl().domElement.parentElement;
990
+ });
991
+ this.styles = computed(() => {
992
+ const [style, center, transform, size, fullscreen] = [
993
+ this.htmlInputs.style(),
994
+ this.htmlInputs.center(),
995
+ this.htmlInputs.transform(),
996
+ this.size(),
997
+ this.htmlInputs.fullscreen(),
998
+ ];
999
+ if (transform) {
1000
+ return {
1001
+ position: 'absolute',
1002
+ top: 0,
1003
+ left: 0,
1004
+ width: size.width,
1005
+ height: size.height,
1006
+ transformStyle: 'preserve-3d',
1007
+ pointerEvents: 'none',
1008
+ };
1009
+ }
1010
+ return {
1011
+ position: 'absolute',
1012
+ transform: center ? 'translate3d(-50%,-50%,0)' : 'none',
1013
+ ...(fullscreen && {
1014
+ top: -size.height / 2,
1015
+ left: -size.width / 2,
1016
+ width: size.width,
1017
+ height: size.height,
1018
+ }),
1019
+ ...(style || {}),
1020
+ };
1021
+ });
1022
+ this.transformInnerStyles = computed(() => ({ position: 'absolute', pointerEvents: this.htmlInputs.pointerEvents() }));
1023
+ this.setCanvasElementStyle();
1024
+ this.appendElement();
1025
+ this.setWrapperClass();
1026
+ this.render();
1027
+ this.beforeRender();
1028
+ }
1029
+ setCanvasElementStyle() {
1030
+ effect(() => {
1031
+ const el = untracked(this.gl).domElement;
1032
+ const occlude = this.htmlInputs.occlude();
1033
+ if (occlude && occlude === 'blending') {
1034
+ el.style.zIndex = `${Math.floor(untracked(this.htmlInputs.zIndexRange)[0] / 2)}`;
1035
+ el.style.position = 'absolute';
1036
+ el.style.pointerEvents = 'none';
1037
+ }
1038
+ else {
1039
+ el.style.zIndex = null;
1040
+ el.style.position = null;
1041
+ el.style.pointerEvents = null;
1042
+ }
1043
+ });
1044
+ }
1045
+ appendElement() {
1046
+ effect((onCleanup) => {
1047
+ const [group, element] = [this.htmlInputs.groupRef.nativeElement, this.element()];
1048
+ if (group && element) {
1049
+ const [target, transform, scene, camera, size, calculatePosition, prepend] = [
1050
+ this.target(),
1051
+ this.htmlInputs.transform(),
1052
+ untracked(this.scene),
1053
+ untracked(this.camera),
1054
+ untracked(this.size),
1055
+ untracked(this.htmlInputs.calculatePosition),
1056
+ untracked(this.htmlInputs.prepend),
1057
+ ];
1058
+ scene.updateMatrixWorld();
1059
+ if (transform) {
1060
+ element.style.cssText = `position:absolute;top:0;left:0;pointer-events:none;overflow:hidden;`;
1061
+ }
1062
+ else {
1063
+ const vec = calculatePosition(group, camera, size);
1064
+ element.style.cssText = `position:absolute;top:0;left:0;transform:translate3d(${vec[0]}px,${vec[1]}px,0);transform-origin:0 0;`;
1065
+ }
1066
+ if (target) {
1067
+ if (prepend)
1068
+ target.prepend(element);
1069
+ else
1070
+ target.appendChild(element);
1071
+ }
1072
+ onCleanup(() => {
1073
+ if (target)
1074
+ target.removeChild(element);
1075
+ this.vcr.clear();
1076
+ });
1077
+ }
1078
+ });
1079
+ }
1080
+ setWrapperClass() {
1081
+ effect(() => {
1082
+ const [element, wrapperClass] = [this.element(), this.htmlInputs.wrapperClass()];
1083
+ if (element && wrapperClass) {
1084
+ element.className = wrapperClass;
1085
+ }
1086
+ });
1087
+ }
1088
+ render() {
1089
+ effect((onCleanup) => {
1090
+ const [{ transform }, element, content] = [
1091
+ this.htmlInputs.state(),
1092
+ this.element(),
1093
+ this.htmlInputs.content(),
1094
+ ];
1095
+ if (element) {
1096
+ this.isMeshSizeSet = false;
1097
+ const params = transform
1098
+ ? [this.transformTemplate, {}]
1099
+ : [this.renderTemplate, { styles: this.styles }];
1100
+ const ref = this.vcr.createEmbeddedView(...params);
1101
+ if (ref.rootNodes?.[0]) {
1102
+ if (element.hasChildNodes()) {
1103
+ element.replaceChildren(...ref.rootNodes);
1104
+ }
1105
+ else {
1106
+ element.append(...ref.rootNodes);
1107
+ }
1108
+ }
1109
+ safeDetectChanges(ref);
1110
+ let contentRef;
1111
+ let contentParent;
1112
+ /**
1113
+ * NOTE: utilizing rAF here so that renderAnchor (ViewContainerRef) has a chance to be resolved
1114
+ * TODO: Another approach is to call render() in ngOnInit and pass in an injector to the effect
1115
+ */
1116
+ const rAF = requestAnimationFrame(() => {
1117
+ if (content && this.renderAnchor) {
1118
+ contentRef = this.renderAnchor.createEmbeddedView(content);
1119
+ contentParent = ref.rootNodes[0].lastElementChild || ref.rootNodes[0];
1120
+ while (contentParent && contentParent.lastElementChild) {
1121
+ contentParent = contentParent.lastElementChild;
1122
+ }
1123
+ if (contentRef.rootNodes?.[0]) {
1124
+ if (contentParent.hasChildNodes()) {
1125
+ contentParent.replaceChildren(...contentRef.rootNodes);
1126
+ }
1127
+ else {
1128
+ contentParent.append(...contentRef.rootNodes);
1129
+ }
1130
+ }
1131
+ safeDetectChanges(contentRef);
1132
+ }
1133
+ });
1134
+ onCleanup(() => {
1135
+ cancelAnimationFrame(rAF);
1136
+ if (contentRef && contentParent) {
1137
+ contentRef.rootNodes.forEach((node) => {
1138
+ if (contentParent.hasChildNodes()) {
1139
+ contentParent.removeChild(node);
1140
+ }
1141
+ node.remove();
1142
+ });
1143
+ contentRef.destroy();
1144
+ }
1145
+ ref.rootNodes.forEach((node) => {
1146
+ if (element.hasChildNodes()) {
1147
+ element.removeChild(node);
1148
+ }
1149
+ node.remove();
1150
+ });
1151
+ ref.destroy();
1152
+ this.renderAnchor?.clear();
1153
+ this.vcr.clear();
1154
+ });
1155
+ }
1156
+ });
1157
+ }
1158
+ beforeRender() {
1159
+ let oldPosition = [0, 0];
1160
+ let oldZoom = 0;
1161
+ let visible = true;
1162
+ injectBeforeRender((gl) => {
1163
+ const [group, camera, transform, calculatePosition, size, eps, isRayCastOcclusion, occlude, scene, raycaster, element, zIndexRange, sprite, distanceFactor, occlusionMeshRef, geometry, viewport, scale,] = [
1164
+ this.htmlInputs.groupRef.nativeElement,
1165
+ this.camera(),
1166
+ this.htmlInputs.transform(),
1167
+ this.htmlInputs.calculatePosition(),
1168
+ this.size(),
1169
+ this.htmlInputs.eps(),
1170
+ this.htmlInputs.isRayCastOcclusion(),
1171
+ this.htmlInputs.occlude(),
1172
+ this.scene(),
1173
+ this.raycaster(),
1174
+ this.element(),
1175
+ this.htmlInputs.zIndexRange(),
1176
+ this.htmlInputs.sprite(),
1177
+ this.htmlInputs.distanceFactor(),
1178
+ this.htmlInputs.occlusionMeshRef.nativeElement,
1179
+ this.htmlInputs.geometry(),
1180
+ this.viewport(),
1181
+ this.htmlInputs.scale(),
1182
+ ];
1183
+ if (group && element) {
1184
+ camera.updateMatrixWorld();
1185
+ group.updateWorldMatrix(true, false);
1186
+ const vec = transform ? oldPosition : calculatePosition(group, camera, size);
1187
+ if (transform ||
1188
+ Math.abs(oldZoom - camera.zoom) > eps ||
1189
+ Math.abs(oldPosition[0] - vec[0]) > eps ||
1190
+ Math.abs(oldPosition[1] - vec[1]) > eps) {
1191
+ const isBehindCamera = isObjectBehindCamera(group, camera);
1192
+ let raytraceTarget = false;
1193
+ if (isRayCastOcclusion) {
1194
+ if (Array.isArray(occlude)) {
1195
+ raytraceTarget = occlude.map((item) => (is.ref(item) ? item.nativeElement : item));
1196
+ }
1197
+ else if (occlude !== 'blending') {
1198
+ raytraceTarget = [scene];
1199
+ }
1200
+ }
1201
+ const previouslyVisible = visible;
1202
+ if (raytraceTarget) {
1203
+ const isVisible = isObjectVisible(group, camera, raycaster, raytraceTarget);
1204
+ visible = isVisible && !isBehindCamera;
1205
+ }
1206
+ else {
1207
+ visible = !isBehindCamera;
1208
+ }
1209
+ if (previouslyVisible !== visible) {
1210
+ if (this.htmlInputs.occluded.observed) {
1211
+ this.htmlInputs.occluded.emit(!visible);
1212
+ }
1213
+ else {
1214
+ element.style.display = visible ? 'block' : 'none';
1215
+ }
1216
+ }
1217
+ const halfRange = Math.floor(zIndexRange[0] / 2);
1218
+ const zRange = occlude
1219
+ ? isRayCastOcclusion //
1220
+ ? [zIndexRange[0], halfRange]
1221
+ : [halfRange - 1, 0]
1222
+ : zIndexRange;
1223
+ element.style.zIndex = `${objectZIndex(group, camera, zRange)}`;
1224
+ if (transform) {
1225
+ const [widthHalf, heightHalf] = [size.width / 2, size.height / 2];
1226
+ const fov = camera.projectionMatrix.elements[5] * heightHalf;
1227
+ const { isOrthographicCamera, top, left, bottom, right } = camera;
1228
+ const cameraMatrix = getCameraCSSMatrix(camera.matrixWorldInverse);
1229
+ const cameraTransform = isOrthographicCamera
1230
+ ? `scale(${fov})translate(${epsilon(-(right + left) / 2)}px,${epsilon((top + bottom) / 2)}px)`
1231
+ : `translateZ(${fov}px)`;
1232
+ let matrix = group.matrixWorld;
1233
+ if (sprite) {
1234
+ matrix = camera.matrixWorldInverse
1235
+ .clone()
1236
+ .transpose()
1237
+ .copyPosition(matrix)
1238
+ .scale(group.scale);
1239
+ matrix.elements[3] = matrix.elements[7] = matrix.elements[11] = 0;
1240
+ matrix.elements[15] = 1;
1241
+ }
1242
+ element.style.width = size.width + 'px';
1243
+ element.style.height = size.height + 'px';
1244
+ element.style.perspective = isOrthographicCamera ? '' : `${fov}px`;
1245
+ if (this.outerDiv?.nativeElement && this.innerDiv?.nativeElement) {
1246
+ this.outerDiv.nativeElement.style.width = size.width + 'px';
1247
+ this.outerDiv.nativeElement.style.height = size.height + 'px';
1248
+ this.outerDiv.nativeElement.style.transform = `${cameraTransform}${cameraMatrix}translate(${widthHalf}px,${heightHalf}px)`;
1249
+ this.innerDiv.nativeElement.style.transform = getObjectCSSMatrix(matrix, 1 / ((distanceFactor || 10) / 400));
1250
+ }
1251
+ }
1252
+ else {
1253
+ const scale = distanceFactor === undefined ? 1 : objectScale(group, camera) * distanceFactor;
1254
+ element.style.transform = `translate3d(${vec[0]}px,${vec[1]}px,0) scale(${scale})`;
1255
+ }
1256
+ oldPosition = vec;
1257
+ oldZoom = camera.zoom;
1258
+ }
1259
+ }
1260
+ if (!isRayCastOcclusion && occlusionMeshRef && !this.isMeshSizeSet) {
1261
+ if (transform) {
1262
+ if (this.outerDiv?.nativeElement) {
1263
+ const el = this.outerDiv.nativeElement.children[0];
1264
+ if (el?.clientWidth && el?.clientHeight) {
1265
+ const { isOrthographicCamera } = camera;
1266
+ if (isOrthographicCamera || geometry) {
1267
+ if (scale !== 1) {
1268
+ if (!Array.isArray(scale)) {
1269
+ occlusionMeshRef.scale.setScalar(1 / scale);
1270
+ }
1271
+ else if (scale instanceof THREE.Vector3) {
1272
+ occlusionMeshRef.scale.copy(scale.clone().divideScalar(1));
1273
+ }
1274
+ else {
1275
+ occlusionMeshRef.scale.set(1 / scale[0], 1 / scale[1], 1 / scale[2]);
1276
+ }
1277
+ }
1278
+ }
1279
+ else {
1280
+ const ratio = (distanceFactor || 10) / 400;
1281
+ const w = el.clientWidth * ratio;
1282
+ const h = el.clientHeight * ratio;
1283
+ occlusionMeshRef.scale.set(w, h, 1);
1284
+ }
1285
+ this.isMeshSizeSet = true;
1286
+ }
1287
+ }
1288
+ }
1289
+ else {
1290
+ const ele = element.children[0];
1291
+ if (ele?.clientWidth && ele?.clientHeight) {
1292
+ const ratio = 1 / viewport.factor;
1293
+ const w = ele.clientWidth * ratio;
1294
+ const h = ele.clientHeight * ratio;
1295
+ occlusionMeshRef.scale.set(w, h, 1);
1296
+ this.isMeshSizeSet = true;
1297
+ }
1298
+ occlusionMeshRef.lookAt(gl.camera.position);
1299
+ }
1300
+ }
1301
+ });
1302
+ }
1303
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsHtmlWrapper, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1304
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsHtmlWrapper, isStandalone: true, selector: "ngts-html-wrapper", viewQueries: [{ propertyName: "transformTemplate", first: true, predicate: ["transformTemplate"], descendants: true, static: true }, { propertyName: "renderTemplate", first: true, predicate: ["renderTemplate"], descendants: true, static: true }, { propertyName: "outerDiv", first: true, predicate: ["transformedOuterDiv"], descendants: true }, { propertyName: "innerDiv", first: true, predicate: ["transformedInnerDiv"], descendants: true }, { propertyName: "renderAnchor", first: true, predicate: ["renderAnchor"], descendants: true, read: ViewContainerRef }], ngImport: i0, template: `
1305
+ <ng-template #transformTemplate>
1306
+ <div #transformedOuterDiv [style]="styles()">
1307
+ <div #transformedInnerDiv [style]="transformInnerStyles()">
1308
+ <ng-container *ngTemplateOutlet="renderTemplate; context: { styles: htmlInputs.style }" />
1309
+ </div>
1310
+ </div>
1311
+ </ng-template>
1312
+
1313
+ <ng-template #renderTemplate let-renderedStyles="styles">
1314
+ <div #renderedDiv [class]="htmlInputs.renderedDivClass()" [style]="renderedStyles()">
1315
+ <ng-container #renderAnchor />
1316
+ </div>
1317
+ </ng-template>
1318
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
1319
+ }
1320
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsHtmlWrapper, decorators: [{
1321
+ type: Component,
1322
+ args: [{
1323
+ selector: 'ngts-html-wrapper',
1324
+ standalone: true,
1325
+ template: `
1326
+ <ng-template #transformTemplate>
1327
+ <div #transformedOuterDiv [style]="styles()">
1328
+ <div #transformedInnerDiv [style]="transformInnerStyles()">
1329
+ <ng-container *ngTemplateOutlet="renderTemplate; context: { styles: htmlInputs.style }" />
1330
+ </div>
1331
+ </div>
1332
+ </ng-template>
1333
+
1334
+ <ng-template #renderTemplate let-renderedStyles="styles">
1335
+ <div #renderedDiv [class]="htmlInputs.renderedDivClass()" [style]="renderedStyles()">
1336
+ <ng-container #renderAnchor />
1337
+ </div>
1338
+ </ng-template>
1339
+ `,
1340
+ imports: [NgTemplateOutlet],
1341
+ }]
1342
+ }], ctorParameters: function () { return []; }, propDecorators: { transformTemplate: [{
1343
+ type: ViewChild,
1344
+ args: ['transformTemplate', { static: true }]
1345
+ }], renderTemplate: [{
1346
+ type: ViewChild,
1347
+ args: ['renderTemplate', { static: true }]
1348
+ }], outerDiv: [{
1349
+ type: ViewChild,
1350
+ args: ['transformedOuterDiv']
1351
+ }], innerDiv: [{
1352
+ type: ViewChild,
1353
+ args: ['transformedInnerDiv']
1354
+ }], renderAnchor: [{
1355
+ type: ViewChild,
1356
+ args: ['renderAnchor', { read: ViewContainerRef }]
1357
+ }] } });
1358
+
1359
+ extend({ Group, PlaneGeometry, Mesh, ShaderMaterial });
1360
+ const [injectNgtsHtmlInputs, provideNgtsHtmlInputs] = createInjectionToken((html) => ({ state: html.inputs.state, ...html.state }), { isRoot: false, deps: [forwardRef(() => NgtsHtml)] });
1361
+ class NgtsHtml {
1362
+ constructor() {
1363
+ this.DoubleSide = THREE.DoubleSide;
1364
+ this.inputs = signalStore({
1365
+ as: 'div',
1366
+ prepend: false,
1367
+ transform: false,
1368
+ fullscreen: false,
1369
+ center: false,
1370
+ sprite: false,
1371
+ zIndexRange: [16777271, 0],
1372
+ eps: 0.001,
1373
+ scale: 1,
1374
+ calculatePosition: defaultCalculatePosition,
1375
+ pointerEvents: 'auto',
1376
+ occlude: false,
1377
+ castShadow: false,
1378
+ receiveShadow: false,
1379
+ });
1380
+ this.groupRef = injectNgtRef();
1381
+ this.occluded = new EventEmitter();
1382
+ this.occlusionMeshRef = injectNgtRef();
1383
+ this.transform = this.inputs.select('transform');
1384
+ this.isRayCastOcclusion = computed(() => {
1385
+ const occlude = this.occlude();
1386
+ return ((occlude && occlude !== 'blending') || (Array.isArray(occlude) && !!occlude.length && is.ref(occlude[0])));
1387
+ });
1388
+ this.occlude = this.inputs.select('occlude');
1389
+ this.castShadow = this.inputs.select('castShadow');
1390
+ this.receiveShadow = this.inputs.select('receiveShadow');
1391
+ this.geometry = this.inputs.select('geometry');
1392
+ this.material = this.inputs.select('material');
1393
+ this.scale = this.inputs.select('scale');
1394
+ this.shaders = computed(() => {
1395
+ const transform = this.transform();
1396
+ return {
1397
+ vertexShader: !transform
1398
+ ? /* glsl */ `
1399
+ /*
1400
+ This shader is from the THREE's SpriteMaterial.
1401
+ We need to turn the backing plane into a Sprite
1402
+ (make it always face the camera) if "transfrom"
1403
+ is false.
1404
+ */
1405
+ #include <common>
1406
+
1407
+ void main() {
1408
+ vec2 center = vec2(0., 1.);
1409
+ float rotation = 0.0;
1410
+
1411
+ // This is somewhat arbitrary, but it seems to work well
1412
+ // Need to figure out how to derive this dynamically if it even matters
1413
+ float size = 0.03;
1414
+
1415
+ vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 );
1416
+ vec2 scale;
1417
+ scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) );
1418
+ scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) );
1419
+
1420
+ bool isPerspective = isPerspectiveMatrix( projectionMatrix );
1421
+ if ( isPerspective ) scale *= - mvPosition.z;
1422
+
1423
+ vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale * size;
1424
+ vec2 rotatedPosition;
1425
+ rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;
1426
+ rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;
1427
+ mvPosition.xy += rotatedPosition;
1428
+
1429
+ gl_Position = projectionMatrix * mvPosition;
1430
+ }
1431
+ `
1432
+ : undefined,
1433
+ fragmentShader: /* glsl */ `
1434
+ void main() {
1435
+ gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);
1436
+ }
1437
+ `,
1438
+ };
1439
+ });
1440
+ this.state = {
1441
+ zIndexRange: this.inputs.select('zIndexRange'),
1442
+ prepend: this.inputs.select('prepend'),
1443
+ transform: this.transform,
1444
+ center: this.inputs.select('center'),
1445
+ fullscreen: this.inputs.select('fullscreen'),
1446
+ calculatePosition: this.inputs.select('calculatePosition'),
1447
+ wrapperClass: this.inputs.select('wrapperClass'),
1448
+ renderedDivClass: this.inputs.select('renderedDivClass'),
1449
+ style: this.inputs.select('style'),
1450
+ pointerEvents: this.inputs.select('pointerEvents'),
1451
+ eps: this.inputs.select('eps'),
1452
+ distanceFactor: this.inputs.select('distanceFactor'),
1453
+ sprite: this.inputs.select('sprite'),
1454
+ as: this.inputs.select('as'),
1455
+ portal: this.inputs.select('portal'),
1456
+ content: this.inputs.select('content'),
1457
+ occlude: this.occlude,
1458
+ isRayCastOcclusion: this.isRayCastOcclusion,
1459
+ occlusionMeshRef: this.occlusionMeshRef,
1460
+ occluded: this.occluded,
1461
+ geometry: this.geometry,
1462
+ scale: this.scale,
1463
+ groupRef: this.groupRef,
1464
+ };
1465
+ }
1466
+ set content(content) {
1467
+ this.inputs.set({ content });
1468
+ }
1469
+ set _as(as) {
1470
+ this.inputs.set({ as });
1471
+ }
1472
+ set _zIndexRange(zIndexRange) {
1473
+ this.inputs.set({ zIndexRange });
1474
+ }
1475
+ set _portal(portal) {
1476
+ this.inputs.set({ portal });
1477
+ }
1478
+ set _occlude(occlude) {
1479
+ this.inputs.set({ occlude });
1480
+ }
1481
+ set _castShadow(castShadow) {
1482
+ this.inputs.set({ castShadow });
1483
+ }
1484
+ set _receiveShadow(receiveShadow) {
1485
+ this.inputs.set({ receiveShadow });
1486
+ }
1487
+ set _material(material) {
1488
+ this.inputs.set({ material });
1489
+ }
1490
+ set _geometry(geometry) {
1491
+ this.inputs.set({ geometry });
1492
+ }
1493
+ set _scale(scale) {
1494
+ this.inputs.set({ scale });
1495
+ }
1496
+ set _prepend(prepend) {
1497
+ this.inputs.set({ prepend });
1498
+ }
1499
+ set _transform(transform) {
1500
+ this.inputs.set({ transform });
1501
+ }
1502
+ set _center(center) {
1503
+ this.inputs.set({ center });
1504
+ }
1505
+ set _sprite(sprite) {
1506
+ this.inputs.set({ sprite });
1507
+ }
1508
+ set _fullscreen(fullscreen) {
1509
+ this.inputs.set({ fullscreen });
1510
+ }
1511
+ set _eps(eps) {
1512
+ this.inputs.set({ eps });
1513
+ }
1514
+ set _distanceFactor(distanceFactor) {
1515
+ this.inputs.set({ distanceFactor });
1516
+ }
1517
+ set _wrapperClass(wrapperClass) {
1518
+ this.inputs.set({ wrapperClass });
1519
+ }
1520
+ set _renderedDivClass(renderedDivClass) {
1521
+ this.inputs.set({ renderedDivClass });
1522
+ }
1523
+ set _style(style) {
1524
+ this.inputs.set({ style });
1525
+ }
1526
+ set _pointerEvents(pointerEvents) {
1527
+ this.inputs.set({ pointerEvents });
1528
+ }
1529
+ set _calculatePosition(calculatePosition) {
1530
+ this.inputs.set({ calculatePosition });
1531
+ }
1532
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsHtml, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1533
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsHtml, isStandalone: true, selector: "ngts-html", inputs: { groupRef: "groupRef", _as: ["as", "_as"], _zIndexRange: ["zIndexRange", "_zIndexRange"], _portal: ["portal", "_portal"], _occlude: ["occlude", "_occlude"], _castShadow: ["castShadow", "_castShadow"], _receiveShadow: ["receiveShadow", "_receiveShadow"], _material: ["material", "_material"], _geometry: ["geometry", "_geometry"], _scale: ["scale", "_scale"], _prepend: ["prepend", "_prepend"], _transform: ["transform", "_transform"], _center: ["center", "_center"], _sprite: ["sprite", "_sprite"], _fullscreen: ["fullscreen", "_fullscreen"], _eps: ["eps", "_eps"], _distanceFactor: ["distanceFactor", "_distanceFactor"], _wrapperClass: ["wrapperClass", "_wrapperClass"], _renderedDivClass: ["renderedDivClass", "_renderedDivClass"], _style: ["style", "_style"], _pointerEvents: ["pointerEvents", "_pointerEvents"], _calculatePosition: ["calculatePosition", "_calculatePosition"] }, outputs: { occluded: "occluded" }, providers: [provideNgtsHtmlInputs()], queries: [{ propertyName: "content", first: true, predicate: NgtsSobaContent, descendants: true, read: TemplateRef }], ngImport: i0, template: `
1534
+ <ngt-group ngtCompound [ref]="groupRef" [scale]="scale()">
1535
+ <ngt-mesh
1536
+ *ngIf="occlude() && !isRayCastOcclusion()"
1537
+ [castShadow]="castShadow()"
1538
+ [receiveShadow]="receiveShadow()"
1539
+ [ref]="occlusionMeshRef"
1540
+ >
1541
+ <ngt-plane-geometry *ngIf="geometry()" />
1542
+ <ngt-shader-material
1543
+ *ngIf="material()"
1544
+ [side]="DoubleSide"
1545
+ [vertexShader]="shaders().vertexShader"
1546
+ [fragmentShader]="shaders().fragmentShader"
1547
+ />
1548
+ </ngt-mesh>
1549
+ </ngt-group>
1550
+
1551
+ <ngts-html-wrapper />
1552
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtsHtmlWrapper, selector: "ngts-html-wrapper" }] }); }
1553
+ }
1554
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsHtml, decorators: [{
1555
+ type: Component,
1556
+ args: [{
1557
+ selector: 'ngts-html',
1558
+ standalone: true,
1559
+ template: `
1560
+ <ngt-group ngtCompound [ref]="groupRef" [scale]="scale()">
1561
+ <ngt-mesh
1562
+ *ngIf="occlude() && !isRayCastOcclusion()"
1563
+ [castShadow]="castShadow()"
1564
+ [receiveShadow]="receiveShadow()"
1565
+ [ref]="occlusionMeshRef"
1566
+ >
1567
+ <ngt-plane-geometry *ngIf="geometry()" />
1568
+ <ngt-shader-material
1569
+ *ngIf="material()"
1570
+ [side]="DoubleSide"
1571
+ [vertexShader]="shaders().vertexShader"
1572
+ [fragmentShader]="shaders().fragmentShader"
1573
+ />
1574
+ </ngt-mesh>
1575
+ </ngt-group>
1576
+
1577
+ <ngts-html-wrapper />
1578
+ `,
1579
+ imports: [NgIf, NgtsHtmlWrapper],
1580
+ providers: [provideNgtsHtmlInputs()],
1581
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1582
+ }]
1583
+ }], propDecorators: { content: [{
1584
+ type: ContentChild,
1585
+ args: [NgtsSobaContent, { read: TemplateRef }]
1586
+ }], groupRef: [{
1587
+ type: Input
1588
+ }], _as: [{
1589
+ type: Input,
1590
+ args: [{ alias: 'as' }]
1591
+ }], _zIndexRange: [{
1592
+ type: Input,
1593
+ args: [{ alias: 'zIndexRange' }]
1594
+ }], _portal: [{
1595
+ type: Input,
1596
+ args: [{ alias: 'portal' }]
1597
+ }], _occlude: [{
1598
+ type: Input,
1599
+ args: [{ alias: 'occlude' }]
1600
+ }], _castShadow: [{
1601
+ type: Input,
1602
+ args: [{ alias: 'castShadow' }]
1603
+ }], _receiveShadow: [{
1604
+ type: Input,
1605
+ args: [{ alias: 'receiveShadow' }]
1606
+ }], _material: [{
1607
+ type: Input,
1608
+ args: [{ alias: 'material' }]
1609
+ }], _geometry: [{
1610
+ type: Input,
1611
+ args: [{ alias: 'geometry' }]
1612
+ }], _scale: [{
1613
+ type: Input,
1614
+ args: [{ alias: 'scale' }]
1615
+ }], _prepend: [{
1616
+ type: Input,
1617
+ args: [{ alias: 'prepend' }]
1618
+ }], _transform: [{
1619
+ type: Input,
1620
+ args: [{ alias: 'transform' }]
1621
+ }], _center: [{
1622
+ type: Input,
1623
+ args: [{ alias: 'center' }]
1624
+ }], _sprite: [{
1625
+ type: Input,
1626
+ args: [{ alias: 'sprite' }]
1627
+ }], _fullscreen: [{
1628
+ type: Input,
1629
+ args: [{ alias: 'fullscreen' }]
1630
+ }], _eps: [{
1631
+ type: Input,
1632
+ args: [{ alias: 'eps' }]
1633
+ }], _distanceFactor: [{
1634
+ type: Input,
1635
+ args: [{ alias: 'distanceFactor' }]
1636
+ }], _wrapperClass: [{
1637
+ type: Input,
1638
+ args: [{ alias: 'wrapperClass' }]
1639
+ }], _renderedDivClass: [{
1640
+ type: Input,
1641
+ args: [{ alias: 'renderedDivClass' }]
1642
+ }], _style: [{
1643
+ type: Input,
1644
+ args: [{ alias: 'style' }]
1645
+ }], _pointerEvents: [{
1646
+ type: Input,
1647
+ args: [{ alias: 'pointerEvents' }]
1648
+ }], _calculatePosition: [{
1649
+ type: Input,
1650
+ args: [{ alias: 'calculatePosition' }]
1651
+ }], occluded: [{
1652
+ type: Output
1653
+ }] } });
1654
+
1655
+ const defaultState = {
1656
+ count: 16,
1657
+ };
1658
+ function injectNgtsSurfaceSampler(surfaceSamplerState, { injector } = {}) {
1659
+ injector = assertInjector(injectNgtsSurfaceSampler, injector);
1660
+ return runInInjectionContext(injector, () => {
1661
+ const state = computed(() => {
1662
+ const _state = surfaceSamplerState();
1663
+ if (!_state)
1664
+ return null;
1665
+ return { ...defaultState, ..._state };
1666
+ });
1667
+ const _buffer = signal((() => {
1668
+ const arr = Array.from({ length: state()?.count || defaultState.count }, () => [
1669
+ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
1670
+ ]).flat();
1671
+ return new THREE.InstancedBufferAttribute(Float32Array.from(arr), 16);
1672
+ })());
1673
+ effect(() => {
1674
+ const _state = state();
1675
+ if (!_state)
1676
+ return;
1677
+ const { mesh, count, transform, instancedMesh, weight } = _state;
1678
+ const meshObj = is.ref(mesh) ? mesh.nativeElement : mesh;
1679
+ if (!meshObj)
1680
+ return;
1681
+ const instancedMeshObj = is.ref(instancedMesh) ? instancedMesh.nativeElement : instancedMesh;
1682
+ const buffer = untracked(_buffer);
1683
+ const sampler = new MeshSurfaceSampler(meshObj);
1684
+ if (weight) {
1685
+ sampler.setWeightAttribute(weight);
1686
+ }
1687
+ sampler.build();
1688
+ const position = new THREE.Vector3();
1689
+ const normal = new THREE.Vector3();
1690
+ const color = new THREE.Color();
1691
+ const dummy = new THREE.Object3D();
1692
+ meshObj.updateMatrixWorld(true);
1693
+ for (let i = 0; i < count; i++) {
1694
+ sampler.sample(position, normal, color);
1695
+ if (typeof transform === 'function') {
1696
+ transform({ dummy, sampledMesh: meshObj, position, normal, color }, i);
1697
+ }
1698
+ else {
1699
+ dummy.position.copy(position);
1700
+ }
1701
+ dummy.updateMatrix();
1702
+ if (instancedMeshObj) {
1703
+ instancedMeshObj.setMatrixAt(i, dummy.matrix);
1704
+ }
1705
+ dummy.matrix.toArray(buffer.array, i * 16);
1706
+ }
1707
+ if (instancedMeshObj) {
1708
+ checkUpdate(instancedMeshObj.instanceMatrix);
1709
+ }
1710
+ checkUpdate(buffer);
1711
+ untracked(() => {
1712
+ _buffer.set(buffer.clone());
1713
+ });
1714
+ });
1715
+ return _buffer.asReadonly();
1716
+ });
1717
+ }
1718
+ extend({ Group });
1719
+ class NgtsSampler {
1720
+ set _count(count) {
1721
+ this.inputs.set({ count });
1722
+ }
1723
+ set _mesh(mesh) {
1724
+ this.inputs.set({ mesh });
1725
+ }
1726
+ set _transform(transform) {
1727
+ this.inputs.set({ transform });
1728
+ }
1729
+ set _weight(weight) {
1730
+ this.inputs.set({ weight });
1731
+ }
1732
+ set _instancedMesh(instancedMesh) {
1733
+ this.inputs.set({ instancedMesh });
1734
+ }
1735
+ constructor() {
1736
+ this.inputs = signalStore({ count: 16 });
1737
+ this.samplerRef = injectNgtRef();
1738
+ this.surfaceSamplerState = computed(() => {
1739
+ const sampler = this.samplerRef.nativeElement;
1740
+ if (!sampler)
1741
+ return null;
1742
+ const { count, weight, transform, mesh, instancedMesh } = this.inputs.state();
1743
+ const instancedMeshRef = instancedMesh ??
1744
+ sampler.children.find((child) => child.hasOwnProperty('instanceMatrix'));
1745
+ const meshRef = mesh ?? sampler.children.find((child) => child.type === 'Mesh');
1746
+ return { count, weight, transform, mesh: meshRef, instancedMesh: instancedMeshRef };
1747
+ });
1748
+ const injector = inject(Injector);
1749
+ effect(() => {
1750
+ injectNgtsSurfaceSampler(this.surfaceSamplerState, { injector });
1751
+ });
1752
+ }
1753
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsSampler, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1754
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsSampler, isStandalone: true, selector: "ngts-sampler", inputs: { samplerRef: "samplerRef", _count: ["count", "_count"], _mesh: ["mesh", "_mesh"], _transform: ["transform", "_transform"], _weight: ["weight", "_weight"], _instancedMesh: ["instancedMesh", "_instancedMesh"] }, ngImport: i0, template: `
1755
+ <ngt-group ngtCompound [ref]="samplerRef">
1756
+ <ng-content />
1757
+ </ngt-group>
1758
+ `, isInline: true }); }
1759
+ }
1760
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsSampler, decorators: [{
1761
+ type: Component,
1762
+ args: [{
1763
+ selector: 'ngts-sampler',
1764
+ standalone: true,
1765
+ template: `
1766
+ <ngt-group ngtCompound [ref]="samplerRef">
1767
+ <ng-content />
1768
+ </ngt-group>
1769
+ `,
1770
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1771
+ }]
1772
+ }], ctorParameters: function () { return []; }, propDecorators: { samplerRef: [{
1773
+ type: Input
1774
+ }], _count: [{
1775
+ type: Input,
1776
+ args: [{ alias: 'count' }]
1777
+ }], _mesh: [{
1778
+ type: Input,
1779
+ args: [{ alias: 'mesh' }]
1780
+ }], _transform: [{
1781
+ type: Input,
1782
+ args: [{ alias: 'transform' }]
1783
+ }], _weight: [{
1784
+ type: Input,
1785
+ args: [{ alias: 'weight' }]
1786
+ }], _instancedMesh: [{
1787
+ type: Input,
1788
+ args: [{ alias: 'instancedMesh' }]
1789
+ }] } });
1790
+
1791
+ extend({ Mesh, CanvasTexture, PlaneGeometry, MeshBasicMaterial });
1792
+ class NgtsShadow {
1793
+ constructor() {
1794
+ this.Math = Math;
1795
+ this.DoubleSide = THREE.DoubleSide;
1796
+ this.inputs = signalStore({
1797
+ fog: false,
1798
+ depthWrite: false,
1799
+ colorStop: 0.0,
1800
+ color: 'black',
1801
+ opacity: 0.5,
1802
+ });
1803
+ this.shadowRef = injectNgtRef();
1804
+ this.colorStop = this.inputs.select('colorStop');
1805
+ this.color = this.inputs.select('color');
1806
+ this.opacity = this.inputs.select('opacity');
1807
+ this.fog = this.inputs.select('fog');
1808
+ this.depthWrite = this.inputs.select('depthWrite');
1809
+ this.canvas = computed(() => {
1810
+ const [colorStop, color] = [this.colorStop(), this.color()];
1811
+ const canvas = document.createElement('canvas');
1812
+ canvas.width = 128;
1813
+ canvas.height = 128;
1814
+ const context = canvas.getContext('2d');
1815
+ const gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
1816
+ gradient.addColorStop(colorStop, new THREE.Color(color).getStyle());
1817
+ gradient.addColorStop(1, 'rgba(0,0,0,0)');
1818
+ context.fillStyle = gradient;
1819
+ context.fillRect(0, 0, canvas.width, canvas.height);
1820
+ return canvas;
1821
+ });
1822
+ }
1823
+ set _colorStop(colorStop) {
1824
+ this.inputs.set({ colorStop });
1825
+ }
1826
+ set _fog(fog) {
1827
+ this.inputs.set({ fog });
1828
+ }
1829
+ set _color(color) {
1830
+ this.inputs.set({ color });
1831
+ }
1832
+ set _opacity(opacity) {
1833
+ this.inputs.set({ opacity });
1834
+ }
1835
+ set _depthWrite(depthWrite) {
1836
+ this.inputs.set({ depthWrite });
1837
+ }
1838
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsShadow, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1839
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsShadow, isStandalone: true, selector: "ngts-shadow", inputs: { shadowRef: "shadowRef", _colorStop: ["colorStop", "_colorStop"], _fog: ["fog", "_fog"], _color: ["color", "_color"], _opacity: ["opacity", "_opacity"], _depthWrite: ["depthWrite", "_depthWrite"] }, ngImport: i0, template: `
1840
+ <ngt-mesh ngtCompound [ref]="shadowRef" [rotation]="[-Math.PI / 2, 0, 0]">
1841
+ <ngt-plane-geometry />
1842
+ <ngt-mesh-basic-material
1843
+ [transparent]="true"
1844
+ [opacity]="opacity()"
1845
+ [fog]="fog()"
1846
+ [depthWrite]="depthWrite()"
1847
+ [side]="DoubleSide"
1848
+ >
1849
+ <ngt-canvas-texture *args="[canvas()]" attach="map" />
1850
+ </ngt-mesh-basic-material>
1851
+ <ng-content />
1852
+ </ngt-mesh>
1853
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "ng-template[args]", inputs: ["args"] }] }); }
1854
+ }
1855
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsShadow, decorators: [{
1856
+ type: Component,
1857
+ args: [{
1858
+ selector: 'ngts-shadow',
1859
+ standalone: true,
1860
+ template: `
1861
+ <ngt-mesh ngtCompound [ref]="shadowRef" [rotation]="[-Math.PI / 2, 0, 0]">
1862
+ <ngt-plane-geometry />
1863
+ <ngt-mesh-basic-material
1864
+ [transparent]="true"
1865
+ [opacity]="opacity()"
1866
+ [fog]="fog()"
1867
+ [depthWrite]="depthWrite()"
1868
+ [side]="DoubleSide"
1869
+ >
1870
+ <ngt-canvas-texture *args="[canvas()]" attach="map" />
1871
+ </ngt-mesh-basic-material>
1872
+ <ng-content />
1873
+ </ngt-mesh>
1874
+ `,
1875
+ imports: [NgtArgs],
1876
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1877
+ }]
1878
+ }], propDecorators: { shadowRef: [{
1879
+ type: Input
1880
+ }], _colorStop: [{
1881
+ type: Input,
1882
+ args: [{ alias: 'colorStop' }]
1883
+ }], _fog: [{
1884
+ type: Input,
1885
+ args: [{ alias: 'fog' }]
1886
+ }], _color: [{
1887
+ type: Input,
1888
+ args: [{ alias: 'color' }]
1889
+ }], _opacity: [{
1890
+ type: Input,
1891
+ args: [{ alias: 'opacity' }]
1892
+ }], _depthWrite: [{
1893
+ type: Input,
1894
+ args: [{ alias: 'depthWrite' }]
1895
+ }] } });
1896
+
1897
+ class NgtsStatsGL {
1898
+ set _parent(parent) {
1899
+ this.inputs.set({ parent });
1900
+ }
1901
+ set _containerClass(containerClass) {
1902
+ this.inputs.set({ containerClass });
1903
+ }
1904
+ set _config(config) {
1905
+ this.inputs.set({ config });
1906
+ }
1907
+ constructor() {
1908
+ this.inputs = signalStore();
1909
+ this.document = inject(DOCUMENT);
1910
+ this.store = injectNgtStore();
1911
+ this.gl = this.store.select('gl');
1912
+ this.config = this.inputs.select('config');
1913
+ this.parent = this.inputs.select('parent');
1914
+ this.containerClass = this.inputs.select('containerClass');
1915
+ this.stats = computed(() => {
1916
+ const [config, gl] = [this.config() || {}, this.gl()];
1917
+ const stats = new Stats(config);
1918
+ stats.init(gl.domElement);
1919
+ return stats;
1920
+ });
1921
+ effect((onCleanup) => {
1922
+ const [parent, stats, containerClass] = [this.parent(), this.stats(), this.containerClass()];
1923
+ const node = parent ? (is.ref(parent) ? parent.nativeElement : parent) : this.document.body;
1924
+ node.appendChild(stats.container);
1925
+ if (containerClass)
1926
+ stats.container.classList.add(...containerClass.split(' ').filter(Boolean));
1927
+ const begin = addEffect(() => stats.begin());
1928
+ const end = addAfterEffect(() => stats.end());
1929
+ onCleanup(() => {
1930
+ node.removeChild(stats.container);
1931
+ begin();
1932
+ end();
139
1933
  });
140
- const fboRef = injectNgtsFBO(fboParams, { injector });
141
- effect(() => {
142
- const fbo = fboRef();
143
- if (fbo) {
144
- depthBufferRef.set(fbo.depthTexture);
145
- safeDetectChanges(cdr);
146
- }
147
- }, { allowSignalWrites: true, injector });
148
- let count = 0;
149
- injectBeforeRender(({ gl, scene, camera }) => {
150
- const params = { size: 256, frames: Infinity, ...paramsFactory() };
151
- const fbo = untracked(fboRef);
152
- if ((params.frames === Infinity || count < params.frames) && fbo) {
153
- gl.setRenderTarget(fbo);
154
- gl.render(scene, camera);
155
- gl.setRenderTarget(null);
156
- count++;
157
- }
158
- }, { injector });
159
- });
160
- return depthBufferRef.asReadonly();
1934
+ });
1935
+ }
1936
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsStatsGL, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
1937
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.3", type: NgtsStatsGL, isStandalone: true, selector: "ngts-stats-gl", inputs: { _parent: ["parent", "_parent"], _containerClass: ["containerClass", "_containerClass"], _config: ["config", "_config"] }, ngImport: i0 }); }
1938
+ }
1939
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsStatsGL, decorators: [{
1940
+ type: Directive,
1941
+ args: [{ selector: 'ngts-stats-gl', standalone: true }]
1942
+ }], ctorParameters: function () { return []; }, propDecorators: { _parent: [{
1943
+ type: Input,
1944
+ args: [{ alias: 'parent' }]
1945
+ }], _containerClass: [{
1946
+ type: Input,
1947
+ args: [{ alias: 'containerClass' }]
1948
+ }], _config: [{
1949
+ type: Input,
1950
+ args: [{ alias: 'config' }]
1951
+ }] } });
1952
+
1953
+ // default ease
1954
+ const easeCircleOut = (x) => Math.sqrt(1 - Math.pow(x - 1, 2));
1955
+ // smooth new sample (measurement) based on previous sample (current)
1956
+ function smoothAverage(current, measurement, smoothing = 0.9) {
1957
+ return measurement * smoothing + current * (1.0 - smoothing);
1958
+ }
1959
+ class TrailTexture {
1960
+ constructor({ size = 256, maxAge = 750, radius = 0.3, intensity = 0.2, interpolate = 0, smoothing = 0, minForce = 0.3, blend = 'screen', // source-over is canvas default. Others are slower
1961
+ ease = easeCircleOut, } = {}) {
1962
+ this.size = size;
1963
+ this.maxAge = maxAge;
1964
+ this.radius = radius;
1965
+ this.intensity = intensity;
1966
+ this.ease = ease;
1967
+ this.interpolate = interpolate;
1968
+ this.smoothing = smoothing;
1969
+ this.minForce = minForce;
1970
+ this.blend = blend;
1971
+ this.trail = [];
1972
+ this.force = 0;
1973
+ this.initTexture();
1974
+ }
1975
+ initTexture() {
1976
+ this.canvas = document.createElement('canvas');
1977
+ this.canvas.width = this.canvas.height = this.size;
1978
+ this.ctx = this.canvas.getContext('2d');
1979
+ this.ctx.fillStyle = 'black';
1980
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
1981
+ this.texture = new Texture(this.canvas);
1982
+ this.canvas.id = 'touchTexture';
1983
+ this.canvas.style.width = this.canvas.style.height = `${this.canvas.width}px`;
1984
+ }
1985
+ update(delta) {
1986
+ this.clear();
1987
+ // age points
1988
+ this.trail.forEach((point, i) => {
1989
+ point.age += delta * 1000;
1990
+ // remove old
1991
+ if (point.age > this.maxAge) {
1992
+ this.trail.splice(i, 1);
1993
+ }
1994
+ });
1995
+ // reset force when empty (when smoothing)
1996
+ if (!this.trail.length)
1997
+ this.force = 0;
1998
+ this.trail.forEach((point) => {
1999
+ this.drawTouch(point);
2000
+ });
2001
+ this.texture.needsUpdate = true;
2002
+ }
2003
+ clear() {
2004
+ this.ctx.globalCompositeOperation = 'source-over';
2005
+ this.ctx.fillStyle = 'black';
2006
+ this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
2007
+ }
2008
+ addTouch(point) {
2009
+ const last = this.trail[this.trail.length - 1];
2010
+ if (last) {
2011
+ const dx = last.x - point.x;
2012
+ const dy = last.y - point.y;
2013
+ const dd = dx * dx + dy * dy;
2014
+ const force = Math.max(this.minForce, Math.min(dd * 10000, 1));
2015
+ this.force = smoothAverage(force, this.force, this.smoothing);
2016
+ if (!!this.interpolate) {
2017
+ const lines = Math.ceil(dd / Math.pow((this.radius * 0.5) / this.interpolate, 2));
2018
+ if (lines > 1) {
2019
+ for (let i = 1; i < lines; i++) {
2020
+ this.trail.push({
2021
+ x: last.x - (dx / lines) * i,
2022
+ y: last.y - (dy / lines) * i,
2023
+ age: 0,
2024
+ force,
2025
+ });
2026
+ }
2027
+ }
2028
+ }
2029
+ }
2030
+ this.trail.push({ x: point.x, y: point.y, age: 0, force: this.force });
2031
+ }
2032
+ drawTouch(point) {
2033
+ const pos = {
2034
+ x: point.x * this.size,
2035
+ y: (1 - point.y) * this.size,
2036
+ };
2037
+ let intensity = 1;
2038
+ if (point.age < this.maxAge * 0.3) {
2039
+ intensity = this.ease(point.age / (this.maxAge * 0.3));
2040
+ }
2041
+ else {
2042
+ intensity = this.ease(1 - (point.age - this.maxAge * 0.3) / (this.maxAge * 0.7));
2043
+ }
2044
+ intensity *= point.force;
2045
+ // apply blending
2046
+ this.ctx.globalCompositeOperation = this.blend;
2047
+ const radius = this.size * this.radius * intensity;
2048
+ const grd = this.ctx.createRadialGradient(pos.x, pos.y, Math.max(0, radius * 0.25), pos.x, pos.y, Math.max(0, radius));
2049
+ grd.addColorStop(0, `rgba(255, 255, 255, ${this.intensity})`);
2050
+ grd.addColorStop(1, `rgba(0, 0, 0, 0.0)`);
2051
+ this.ctx.beginPath();
2052
+ this.ctx.fillStyle = grd;
2053
+ this.ctx.arc(pos.x, pos.y, Math.max(0, radius), 0, Math.PI * 2);
2054
+ this.ctx.fill();
2055
+ }
2056
+ }
2057
+
2058
+ function injectNgtsTrailTexture(trailConfigFn, { injector } = {}) {
2059
+ injector = assertInjector(injectNgtsTrailTexture, injector);
2060
+ return runInInjectionContext(injector, () => {
2061
+ const config = computed(() => trailConfigFn() || {});
2062
+ const trail = computed(() => new TrailTexture(config()));
2063
+ const texture = computed(() => trail().texture);
2064
+ injectBeforeRender(({ delta }) => {
2065
+ trail().update(delta);
2066
+ });
2067
+ const onMove = (ev) => trail().addTouch(ev.uv);
2068
+ return { texture, onMove };
2069
+ });
2070
+ }
2071
+
2072
+ const shiftLeft = (collection, steps = 1) => {
2073
+ collection.set(collection.subarray(steps));
2074
+ collection.fill(-Infinity, -steps);
2075
+ return collection;
2076
+ };
2077
+ const defaultSettings = {
2078
+ width: 0.2,
2079
+ length: 1,
2080
+ decay: 1,
2081
+ local: false,
2082
+ stride: 0,
2083
+ interval: 1,
2084
+ };
2085
+ function injectNgtsTrail(targetFactory, settingsFactory, { injector } = {}) {
2086
+ injector = assertInjector(injectNgtsTrail, injector);
2087
+ return runInInjectionContext(injector, () => {
2088
+ const points = injectNgtRef();
2089
+ let frameCount = 0;
2090
+ const prevPosition = new THREE.Vector3();
2091
+ const worldPosition = new THREE.Vector3();
2092
+ const _target = computed(() => {
2093
+ const _target = targetFactory();
2094
+ if (is.ref(_target))
2095
+ return _target.nativeElement;
2096
+ return _target;
2097
+ });
2098
+ const _settings = computed(() => ({ ...defaultSettings, ...settingsFactory() }));
2099
+ const _length = computed(() => _settings().length);
2100
+ effect(() => {
2101
+ const [target, length] = [_target(), _length()];
2102
+ if (target) {
2103
+ points.nativeElement = Float32Array.from({ length: length * 10 * 3 }, (_, i) => target.position.getComponent(i % 3));
2104
+ }
2105
+ });
2106
+ injectBeforeRender(() => {
2107
+ const [target, _points, { local, decay, stride, interval }] = [
2108
+ _target(),
2109
+ points.nativeElement,
2110
+ _settings(),
2111
+ ];
2112
+ if (!target)
2113
+ return;
2114
+ if (!_points)
2115
+ return;
2116
+ if (frameCount === 0) {
2117
+ let newPosition;
2118
+ if (local) {
2119
+ newPosition = target.position;
2120
+ }
2121
+ else {
2122
+ target.getWorldPosition(worldPosition);
2123
+ newPosition = worldPosition;
2124
+ }
2125
+ const steps = 1 * decay;
2126
+ for (let i = 0; i < steps; i++) {
2127
+ if (newPosition.distanceTo(prevPosition) < stride)
2128
+ continue;
2129
+ shiftLeft(_points, 3);
2130
+ _points.set(newPosition.toArray(), _points.length - 3);
2131
+ }
2132
+ prevPosition.copy(newPosition);
2133
+ }
2134
+ frameCount++;
2135
+ frameCount = frameCount % interval;
2136
+ });
2137
+ return points;
161
2138
  });
162
2139
  }
2140
+ extend({ Group, Mesh });
2141
+ class NgtsTrail {
2142
+ set _color(color) {
2143
+ this.inputs.set({ color });
2144
+ }
2145
+ set _attenuation(attenuation) {
2146
+ this.inputs.set({ attenuation });
2147
+ }
2148
+ set _target(target) {
2149
+ this.inputs.set({ target });
2150
+ }
2151
+ set _settings(settings) {
2152
+ this.inputs.set({ settings: { ...defaultSettings, ...settings } });
2153
+ }
2154
+ constructor() {
2155
+ this.inputs = signalStore({ settings: defaultSettings, color: 'hotpink' });
2156
+ this.trailRef = injectNgtRef();
2157
+ this.groupRef = injectNgtRef();
2158
+ this.children = this.groupRef.children('both');
2159
+ this.store = injectNgtStore();
2160
+ this.size = this.store.select('size');
2161
+ this.target = this.inputs.select('target');
2162
+ this.settings = this.inputs.select('settings');
2163
+ this.width = computed(() => this.settings().width);
2164
+ this.color = this.inputs.select('color');
2165
+ this.attenuation = this.inputs.select('attenuation');
2166
+ this.anchor = computed(() => {
2167
+ const target = this.target();
2168
+ if (target)
2169
+ return target;
2170
+ const group = this.groupRef.nativeElement;
2171
+ if (group) {
2172
+ return group.children.find((child) => child instanceof THREE.Object3D) || null;
2173
+ }
2174
+ return null;
2175
+ });
2176
+ this.points = injectNgtsTrail(this.anchor, this.settings);
2177
+ this.scene = this.store.select('scene');
2178
+ this.geometry = new MeshLineGeometry();
2179
+ this.material = computed(() => {
2180
+ const [width, color, size] = [this.width(), this.color(), this.size()];
2181
+ const m = new MeshLineMaterial({
2182
+ lineWidth: 0.1 * width,
2183
+ color,
2184
+ sizeAttenuation: 1,
2185
+ resolution: new THREE.Vector2(size.width, size.height),
2186
+ });
2187
+ // TODO: understand this first
2188
+ // Get and apply first <meshLineMaterial /> from children
2189
+ // let matOverride: React.ReactElement | undefined;
2190
+ // if (children) {
2191
+ // if (Array.isArray(children)) {
2192
+ // matOverride = children.find((child: React.ReactNode) => {
2193
+ // const c = child as React.ReactElement;
2194
+ // return typeof c.type === 'string' && c.type === 'meshLineMaterial';
2195
+ // }) as React.ReactElement | undefined;
2196
+ // } else {
2197
+ // const c = children as React.ReactElement;
2198
+ // if (typeof c.type === 'string' && c.type === 'meshLineMaterial') {
2199
+ // matOverride = c;
2200
+ // }
2201
+ // }
2202
+ // }
2203
+ // if (typeof matOverride?.props === 'object') {
2204
+ // m.setValues(matOverride.props);
2205
+ // }
2206
+ return m;
2207
+ });
2208
+ this.setMaterialSize();
2209
+ this.beforeRender();
2210
+ }
2211
+ setMaterialSize() {
2212
+ effect(() => {
2213
+ const [material, size] = [this.material(), this.size()];
2214
+ material.uniforms['resolution'].value.set(size.width, size.height);
2215
+ });
2216
+ }
2217
+ beforeRender() {
2218
+ injectBeforeRender(() => {
2219
+ const [points, attenuation] = [this.points.nativeElement, this.attenuation()];
2220
+ if (!points)
2221
+ return;
2222
+ this.geometry.setPoints(points, attenuation);
2223
+ });
2224
+ }
2225
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsTrail, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
2226
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.3", type: NgtsTrail, isStandalone: true, selector: "ngts-trail", inputs: { trailRef: "trailRef", _color: ["color", "_color"], _attenuation: ["attenuation", "_attenuation"], _target: ["target", "_target"], _settings: ["settings", "_settings"] }, ngImport: i0, template: `
2227
+ <ngt-group>
2228
+ <ngt-portal [container]="scene()" [autoRender]="false">
2229
+ <ng-template ngtPortalContent>
2230
+ <ngt-mesh [ref]="trailRef" [geometry]="geometry" [material]="material()" />
2231
+ </ng-template>
2232
+ </ngt-portal>
2233
+ <ngt-group [ref]="groupRef">
2234
+ <ng-content />
2235
+ </ngt-group>
2236
+ </ngt-group>
2237
+ `, 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]" }] }); }
2238
+ }
2239
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.3", ngImport: i0, type: NgtsTrail, decorators: [{
2240
+ type: Component,
2241
+ args: [{
2242
+ selector: 'ngts-trail',
2243
+ standalone: true,
2244
+ template: `
2245
+ <ngt-group>
2246
+ <ngt-portal [container]="scene()" [autoRender]="false">
2247
+ <ng-template ngtPortalContent>
2248
+ <ngt-mesh [ref]="trailRef" [geometry]="geometry" [material]="material()" />
2249
+ </ng-template>
2250
+ </ngt-portal>
2251
+ <ngt-group [ref]="groupRef">
2252
+ <ng-content />
2253
+ </ngt-group>
2254
+ </ngt-group>
2255
+ `,
2256
+ imports: [NgtPortal, NgtPortalContent],
2257
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
2258
+ }]
2259
+ }], ctorParameters: function () { return []; }, propDecorators: { trailRef: [{
2260
+ type: Input
2261
+ }], _color: [{
2262
+ type: Input,
2263
+ args: [{ alias: 'color' }]
2264
+ }], _attenuation: [{
2265
+ type: Input,
2266
+ args: [{ alias: 'attenuation' }]
2267
+ }], _target: [{
2268
+ type: Input,
2269
+ args: [{ alias: 'target' }]
2270
+ }], _settings: [{
2271
+ type: Input,
2272
+ args: [{ alias: 'settings' }]
2273
+ }] } });
163
2274
 
164
2275
  /**
165
2276
  * Generated bundle index. Do not edit.
166
2277
  */
167
2278
 
168
- export { NgtsBakeShadows, injectNgtsAnimations, injectNgtsDepthBuffer, injectNgtsFBO };
2279
+ export { NgtsBakeShadows, NgtsCaustics, NgtsDecal, NgtsExample, NgtsHtml, NgtsSampler, NgtsShadow, NgtsStatsGL, NgtsTrail, injectNgtsAnimations, injectNgtsDepthBuffer, injectNgtsExampleApi, injectNgtsFBO, injectNgtsHtmlInputs, injectNgtsSurfaceSampler, injectNgtsTrail, injectNgtsTrailTexture, provideNgtsExampleApi, provideNgtsHtmlInputs };
169
2280
  //# sourceMappingURL=angular-three-soba-misc.mjs.map