angular-three-soba 2.0.0-beta.9 → 2.0.0

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