angular-three 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (388) hide show
  1. package/attributes/README.md +3 -0
  2. package/attributes/index.d.ts +22 -0
  3. package/attributes/lib/buffer-attribute/buffer-attribute.d.ts +8 -0
  4. package/attributes/lib/color-attribute/color-attribute.d.ts +8 -0
  5. package/attributes/lib/float16-buffer-attribute/float16-buffer-attribute.d.ts +8 -0
  6. package/attributes/lib/float32-buffer-attribute/float32-buffer-attribute.d.ts +8 -0
  7. package/attributes/lib/float64-buffer-attribute/float64-buffer-attribute.d.ts +8 -0
  8. package/attributes/lib/fog-attribute/fog-attribute.d.ts +8 -0
  9. package/attributes/lib/fog-exp2-attribute/fog-exp2-attribute.d.ts +8 -0
  10. package/attributes/lib/instanced-buffer-attribute/instanced-buffer-attribute.d.ts +8 -0
  11. package/attributes/lib/int16-buffer-attribute/int16-buffer-attribute.d.ts +8 -0
  12. package/attributes/lib/int32-buffer-attribute/int32-buffer-attribute.d.ts +8 -0
  13. package/attributes/lib/int8-buffer-attribute/int8-buffer-attribute.d.ts +8 -0
  14. package/attributes/lib/interleaved-buffer-attribute/interleaved-buffer-attribute.d.ts +8 -0
  15. package/attributes/lib/matrix3-attribute/matrix3-attribute.d.ts +8 -0
  16. package/attributes/lib/matrix4-attribute/matrix4-attribute.d.ts +8 -0
  17. package/attributes/lib/uint16-buffer-attribute/uint16-buffer-attribute.d.ts +8 -0
  18. package/attributes/lib/uint32-buffer-attribute/uint32-buffer-attribute.d.ts +8 -0
  19. package/attributes/lib/uint8-buffer-attribute/uint8-buffer-attribute.d.ts +8 -0
  20. package/attributes/lib/uint8-clamped-buffer-attribute/uint8-clamped-buffer-attribute.d.ts +8 -0
  21. package/attributes/lib/value-attribute/value-attribute.d.ts +8 -0
  22. package/attributes/lib/vector2-attribute/vector2-attribute.d.ts +8 -0
  23. package/attributes/lib/vector3-attribute/vector3-attribute.d.ts +8 -0
  24. package/attributes/lib/vector4-attribute/vector4-attribute.d.ts +8 -0
  25. package/audios/README.md +3 -0
  26. package/audios/index.d.ts +3 -0
  27. package/audios/lib/audio/audio.d.ts +49 -0
  28. package/audios/lib/audio-listener/audio-listener.d.ts +35 -0
  29. package/audios/lib/positional-audio/positional-audio.d.ts +49 -0
  30. package/cameras/README.md +3 -0
  31. package/cameras/index.d.ts +5 -0
  32. package/cameras/lib/array-camera/array-camera.d.ts +56 -0
  33. package/cameras/lib/cube-camera/cube-camera.d.ts +36 -0
  34. package/cameras/lib/orthographic-camera/orthographic-camera.d.ts +54 -0
  35. package/cameras/lib/perspective-camera/perspective-camera.d.ts +55 -0
  36. package/cameras/lib/stereo-camera/stereo-camera.d.ts +42 -0
  37. package/esm2020/attributes/angular-three-attributes.mjs +5 -0
  38. package/esm2020/attributes/index.mjs +24 -0
  39. package/esm2020/attributes/lib/buffer-attribute/buffer-attribute.mjs +25 -0
  40. package/esm2020/attributes/lib/color-attribute/color-attribute.mjs +25 -0
  41. package/esm2020/attributes/lib/float16-buffer-attribute/float16-buffer-attribute.mjs +25 -0
  42. package/esm2020/attributes/lib/float32-buffer-attribute/float32-buffer-attribute.mjs +25 -0
  43. package/esm2020/attributes/lib/float64-buffer-attribute/float64-buffer-attribute.mjs +25 -0
  44. package/esm2020/attributes/lib/fog-attribute/fog-attribute.mjs +25 -0
  45. package/esm2020/attributes/lib/fog-exp2-attribute/fog-exp2-attribute.mjs +25 -0
  46. package/esm2020/attributes/lib/instanced-buffer-attribute/instanced-buffer-attribute.mjs +25 -0
  47. package/esm2020/attributes/lib/int16-buffer-attribute/int16-buffer-attribute.mjs +25 -0
  48. package/esm2020/attributes/lib/int32-buffer-attribute/int32-buffer-attribute.mjs +25 -0
  49. package/esm2020/attributes/lib/int8-buffer-attribute/int8-buffer-attribute.mjs +25 -0
  50. package/esm2020/attributes/lib/interleaved-buffer-attribute/interleaved-buffer-attribute.mjs +29 -0
  51. package/esm2020/attributes/lib/matrix3-attribute/matrix3-attribute.mjs +25 -0
  52. package/esm2020/attributes/lib/matrix4-attribute/matrix4-attribute.mjs +25 -0
  53. package/esm2020/attributes/lib/uint16-buffer-attribute/uint16-buffer-attribute.mjs +25 -0
  54. package/esm2020/attributes/lib/uint32-buffer-attribute/uint32-buffer-attribute.mjs +25 -0
  55. package/esm2020/attributes/lib/uint8-buffer-attribute/uint8-buffer-attribute.mjs +25 -0
  56. package/esm2020/attributes/lib/uint8-clamped-buffer-attribute/uint8-clamped-buffer-attribute.mjs +25 -0
  57. package/esm2020/attributes/lib/value-attribute/value-attribute.mjs +27 -0
  58. package/esm2020/attributes/lib/vector2-attribute/vector2-attribute.mjs +25 -0
  59. package/esm2020/attributes/lib/vector3-attribute/vector3-attribute.mjs +25 -0
  60. package/esm2020/attributes/lib/vector4-attribute/vector4-attribute.mjs +25 -0
  61. package/esm2020/audios/angular-three-audios.mjs +5 -0
  62. package/esm2020/audios/index.mjs +5 -0
  63. package/esm2020/audios/lib/audio/audio.mjs +68 -0
  64. package/esm2020/audios/lib/audio-listener/audio-listener.mjs +65 -0
  65. package/esm2020/audios/lib/positional-audio/positional-audio.mjs +68 -0
  66. package/esm2020/cameras/angular-three-cameras.mjs +5 -0
  67. package/esm2020/cameras/index.mjs +7 -0
  68. package/esm2020/cameras/lib/array-camera/array-camera.mjs +67 -0
  69. package/esm2020/cameras/lib/cube-camera/cube-camera.mjs +55 -0
  70. package/esm2020/cameras/lib/orthographic-camera/orthographic-camera.mjs +65 -0
  71. package/esm2020/cameras/lib/perspective-camera/perspective-camera.mjs +66 -0
  72. package/esm2020/cameras/lib/stereo-camera/stereo-camera.mjs +61 -0
  73. package/esm2020/geometries/angular-three-geometries.mjs +5 -0
  74. package/esm2020/geometries/index.mjs +25 -0
  75. package/esm2020/geometries/lib/box-geometry/box-geometry.mjs +25 -0
  76. package/esm2020/geometries/lib/buffer-geometry/buffer-geometry.mjs +25 -0
  77. package/esm2020/geometries/lib/capsule-geometry/capsule-geometry.mjs +25 -0
  78. package/esm2020/geometries/lib/circle-geometry/circle-geometry.mjs +25 -0
  79. package/esm2020/geometries/lib/cone-geometry/cone-geometry.mjs +25 -0
  80. package/esm2020/geometries/lib/cylinder-geometry/cylinder-geometry.mjs +25 -0
  81. package/esm2020/geometries/lib/dodecahedron-geometry/dodecahedron-geometry.mjs +25 -0
  82. package/esm2020/geometries/lib/edges-geometry/edges-geometry.mjs +25 -0
  83. package/esm2020/geometries/lib/extrude-geometry/extrude-geometry.mjs +25 -0
  84. package/esm2020/geometries/lib/icosahedron-geometry/icosahedron-geometry.mjs +25 -0
  85. package/esm2020/geometries/lib/instanced-buffer-geometry/instanced-buffer-geometry.mjs +25 -0
  86. package/esm2020/geometries/lib/lathe-geometry/lathe-geometry.mjs +25 -0
  87. package/esm2020/geometries/lib/octahedron-geometry/octahedron-geometry.mjs +25 -0
  88. package/esm2020/geometries/lib/plane-geometry/plane-geometry.mjs +25 -0
  89. package/esm2020/geometries/lib/polyhedron-geometry/polyhedron-geometry.mjs +25 -0
  90. package/esm2020/geometries/lib/ring-geometry/ring-geometry.mjs +25 -0
  91. package/esm2020/geometries/lib/shape-geometry/shape-geometry.mjs +25 -0
  92. package/esm2020/geometries/lib/sphere-geometry/sphere-geometry.mjs +25 -0
  93. package/esm2020/geometries/lib/tetrahedron-geometry/tetrahedron-geometry.mjs +25 -0
  94. package/esm2020/geometries/lib/torus-geometry/torus-geometry.mjs +25 -0
  95. package/esm2020/geometries/lib/torus-knot-geometry/torus-knot-geometry.mjs +25 -0
  96. package/esm2020/geometries/lib/tube-geometry/tube-geometry.mjs +25 -0
  97. package/esm2020/geometries/lib/wireframe-geometry/wireframe-geometry.mjs +25 -0
  98. package/esm2020/helpers/angular-three-helpers.mjs +5 -0
  99. package/esm2020/helpers/index.mjs +15 -0
  100. package/esm2020/helpers/lib/arrow-helper/arrow-helper.mjs +25 -0
  101. package/esm2020/helpers/lib/axes-helper/axes-helper.mjs +25 -0
  102. package/esm2020/helpers/lib/box-helper/box-helper.mjs +35 -0
  103. package/esm2020/helpers/lib/box3-helper/box3-helper.mjs +35 -0
  104. package/esm2020/helpers/lib/camera-helper/camera-helper.mjs +35 -0
  105. package/esm2020/helpers/lib/directional-light-helper/directional-light-helper.mjs +35 -0
  106. package/esm2020/helpers/lib/grid-helper/grid-helper.mjs +25 -0
  107. package/esm2020/helpers/lib/hemisphere-light-helper/hemisphere-light-helper.mjs +35 -0
  108. package/esm2020/helpers/lib/plane-helper/plane-helper.mjs +35 -0
  109. package/esm2020/helpers/lib/point-light-helper/point-light-helper.mjs +35 -0
  110. package/esm2020/helpers/lib/polar-grid-helper/polar-grid-helper.mjs +25 -0
  111. package/esm2020/helpers/lib/skeleton-helper/skeleton-helper.mjs +35 -0
  112. package/esm2020/helpers/lib/spot-light-helper/spot-light-helper.mjs +35 -0
  113. package/esm2020/index.mjs +12 -2
  114. package/esm2020/lib/canvas.mjs +227 -0
  115. package/esm2020/lib/di/resize.mjs +19 -0
  116. package/esm2020/lib/di/window.mjs +13 -0
  117. package/esm2020/lib/directives/args.mjs +30 -0
  118. package/esm2020/lib/events.mjs +53 -0
  119. package/esm2020/lib/instance.mjs +358 -0
  120. package/esm2020/lib/ref.mjs +15 -0
  121. package/esm2020/lib/services/loader.mjs +45 -0
  122. package/esm2020/lib/services/resize.mjs +127 -0
  123. package/esm2020/lib/stores/component-store.mjs +137 -0
  124. package/esm2020/lib/stores/store.mjs +433 -0
  125. package/esm2020/lib/types.mjs +2 -0
  126. package/esm2020/lib/utils/apply-props.mjs +135 -0
  127. package/esm2020/lib/utils/build-graph.mjs +15 -0
  128. package/esm2020/lib/utils/camera.mjs +28 -0
  129. package/esm2020/lib/utils/capitalize.mjs +4 -0
  130. package/esm2020/lib/utils/check-update.mjs +22 -0
  131. package/esm2020/lib/utils/events.mjs +353 -0
  132. package/esm2020/lib/utils/get-instance-local-state.mjs +6 -0
  133. package/esm2020/lib/utils/inject.mjs +18 -0
  134. package/esm2020/lib/utils/instance.mjs +35 -0
  135. package/esm2020/lib/utils/is.mjs +54 -0
  136. package/esm2020/lib/utils/loop.mjs +139 -0
  137. package/esm2020/lib/utils/make.mjs +30 -0
  138. package/esm2020/lib/utils/mutate.mjs +24 -0
  139. package/esm2020/lib/utils/proxy.mjs +99 -0
  140. package/esm2020/lib/utils/renderer.mjs +15 -0
  141. package/esm2020/lights/angular-three-lights.mjs +5 -0
  142. package/esm2020/lights/index.mjs +11 -0
  143. package/esm2020/lights/lib/ambient-light/ambient-light.mjs +68 -0
  144. package/esm2020/lights/lib/ambient-light-probe/ambient-light-probe.mjs +69 -0
  145. package/esm2020/lights/lib/directional-light/directional-light.mjs +69 -0
  146. package/esm2020/lights/lib/hemisphere-light/hemisphere-light.mjs +70 -0
  147. package/esm2020/lights/lib/hemisphere-light-probe/hemisphere-light-probe.mjs +71 -0
  148. package/esm2020/lights/lib/light-probe/light-probe.mjs +69 -0
  149. package/esm2020/lights/lib/point-light/point-light.mjs +71 -0
  150. package/esm2020/lights/lib/rect-area-light/rect-area-light.mjs +71 -0
  151. package/esm2020/lights/lib/spot-light/spot-light.mjs +74 -0
  152. package/esm2020/materials/angular-three-materials.mjs +5 -0
  153. package/esm2020/materials/index.mjs +19 -0
  154. package/esm2020/materials/lib/line-basic-material/line-basic-material.mjs +76 -0
  155. package/esm2020/materials/lib/line-dashed-material/line-dashed-material.mjs +79 -0
  156. package/esm2020/materials/lib/mesh-basic-material/mesh-basic-material.mjs +88 -0
  157. package/esm2020/materials/lib/mesh-depth-material/mesh-depth-material.mjs +79 -0
  158. package/esm2020/materials/lib/mesh-distance-material/mesh-distance-material.mjs +79 -0
  159. package/esm2020/materials/lib/mesh-lambert-material/mesh-lambert-material.mjs +99 -0
  160. package/esm2020/materials/lib/mesh-matcap-material/mesh-matcap-material.mjs +85 -0
  161. package/esm2020/materials/lib/mesh-normal-material/mesh-normal-material.mjs +82 -0
  162. package/esm2020/materials/lib/mesh-phong-material/mesh-phong-material.mjs +102 -0
  163. package/esm2020/materials/lib/mesh-physical-material/mesh-physical-material.mjs +118 -0
  164. package/esm2020/materials/lib/mesh-standard-material/mesh-standard-material.mjs +99 -0
  165. package/esm2020/materials/lib/mesh-toon-material/mesh-toon-material.mjs +95 -0
  166. package/esm2020/materials/lib/points-material/points-material.mjs +77 -0
  167. package/esm2020/materials/lib/raw-shader-material/raw-shader-material.mjs +82 -0
  168. package/esm2020/materials/lib/shader-material/shader-material.mjs +82 -0
  169. package/esm2020/materials/lib/shadow-material/shadow-material.mjs +73 -0
  170. package/esm2020/materials/lib/sprite-material/sprite-material.mjs +77 -0
  171. package/esm2020/objects/angular-three-objects.mjs +5 -0
  172. package/esm2020/objects/index.mjs +14 -0
  173. package/esm2020/objects/lib/bone/bone.mjs +54 -0
  174. package/esm2020/objects/lib/group/group.mjs +54 -0
  175. package/esm2020/objects/lib/instanced-mesh/instanced-mesh.mjs +63 -0
  176. package/esm2020/objects/lib/line/line.mjs +58 -0
  177. package/esm2020/objects/lib/line-loop/line-loop.mjs +58 -0
  178. package/esm2020/objects/lib/line-segments/line-segments.mjs +58 -0
  179. package/esm2020/objects/lib/lod/lod.mjs +57 -0
  180. package/esm2020/objects/lib/mesh/mesh.mjs +58 -0
  181. package/esm2020/objects/lib/points/points.mjs +58 -0
  182. package/esm2020/objects/lib/skeleton/skeleton.mjs +49 -0
  183. package/esm2020/objects/lib/skinned-mesh/skinned-mesh.mjs +62 -0
  184. package/esm2020/objects/lib/sprite/sprite.mjs +57 -0
  185. package/esm2020/primitives/angular-three-primitives.mjs +5 -0
  186. package/esm2020/primitives/index.mjs +3 -0
  187. package/esm2020/primitives/lib/object-primitive/object-primitive.mjs +54 -0
  188. package/esm2020/primitives/lib/primitive/primitive.mjs +37 -0
  189. package/esm2020/stats/angular-three-stats.mjs +5 -0
  190. package/esm2020/stats/index.mjs +2 -0
  191. package/esm2020/stats/lib/stats/stats.mjs +54 -0
  192. package/esm2020/textures/angular-three-textures.mjs +5 -0
  193. package/esm2020/textures/index.mjs +12 -0
  194. package/esm2020/textures/lib/canvas-texture/canvas-texture.mjs +25 -0
  195. package/esm2020/textures/lib/compressed-array-texture/compressed-array-texture.mjs +25 -0
  196. package/esm2020/textures/lib/compressed-texture/compressed-texture.mjs +25 -0
  197. package/esm2020/textures/lib/cube-texture/cube-texture.mjs +25 -0
  198. package/esm2020/textures/lib/data-array-texture/data-array-texture.mjs +25 -0
  199. package/esm2020/textures/lib/data-texture/data-texture.mjs +25 -0
  200. package/esm2020/textures/lib/data3-dtexture/data3-dtexture.mjs +25 -0
  201. package/esm2020/textures/lib/depth-texture/depth-texture.mjs +25 -0
  202. package/esm2020/textures/lib/framebuffer-texture/framebuffer-texture.mjs +25 -0
  203. package/esm2020/textures/lib/video-texture/video-texture.mjs +25 -0
  204. package/fesm2015/angular-three-attributes.mjs +462 -0
  205. package/fesm2015/angular-three-attributes.mjs.map +1 -0
  206. package/fesm2015/angular-three-audios.mjs +200 -0
  207. package/fesm2015/angular-three-audios.mjs.map +1 -0
  208. package/fesm2015/angular-three-cameras.mjs +304 -0
  209. package/fesm2015/angular-three-cameras.mjs.map +1 -0
  210. package/fesm2015/angular-three-geometries.mjs +475 -0
  211. package/fesm2015/angular-three-geometries.mjs.map +1 -0
  212. package/fesm2015/angular-three-helpers.mjs +365 -0
  213. package/fesm2015/angular-three-helpers.mjs.map +1 -0
  214. package/fesm2015/angular-three-lights.mjs +602 -0
  215. package/fesm2015/angular-three-lights.mjs.map +1 -0
  216. package/fesm2015/angular-three-materials.mjs +1402 -0
  217. package/fesm2015/angular-three-materials.mjs.map +1 -0
  218. package/fesm2015/angular-three-objects.mjs +641 -0
  219. package/fesm2015/angular-three-objects.mjs.map +1 -0
  220. package/fesm2015/angular-three-primitives.mjs +95 -0
  221. package/fesm2015/angular-three-primitives.mjs.map +1 -0
  222. package/fesm2015/angular-three-stats.mjs +62 -0
  223. package/fesm2015/angular-three-stats.mjs.map +1 -0
  224. package/fesm2015/angular-three-textures.mjs +215 -0
  225. package/fesm2015/angular-three-textures.mjs.map +1 -0
  226. package/fesm2015/angular-three.mjs +2327 -10
  227. package/fesm2015/angular-three.mjs.map +1 -1
  228. package/fesm2020/angular-three-attributes.mjs +462 -0
  229. package/fesm2020/angular-three-attributes.mjs.map +1 -0
  230. package/fesm2020/angular-three-audios.mjs +200 -0
  231. package/fesm2020/angular-three-audios.mjs.map +1 -0
  232. package/fesm2020/angular-three-cameras.mjs +304 -0
  233. package/fesm2020/angular-three-cameras.mjs.map +1 -0
  234. package/fesm2020/angular-three-geometries.mjs +475 -0
  235. package/fesm2020/angular-three-geometries.mjs.map +1 -0
  236. package/fesm2020/angular-three-helpers.mjs +365 -0
  237. package/fesm2020/angular-three-helpers.mjs.map +1 -0
  238. package/fesm2020/angular-three-lights.mjs +602 -0
  239. package/fesm2020/angular-three-lights.mjs.map +1 -0
  240. package/fesm2020/angular-three-materials.mjs +1402 -0
  241. package/fesm2020/angular-three-materials.mjs.map +1 -0
  242. package/fesm2020/angular-three-objects.mjs +641 -0
  243. package/fesm2020/angular-three-objects.mjs.map +1 -0
  244. package/fesm2020/angular-three-primitives.mjs +95 -0
  245. package/fesm2020/angular-three-primitives.mjs.map +1 -0
  246. package/fesm2020/angular-three-stats.mjs +62 -0
  247. package/fesm2020/angular-three-stats.mjs.map +1 -0
  248. package/fesm2020/angular-three-textures.mjs +215 -0
  249. package/fesm2020/angular-three-textures.mjs.map +1 -0
  250. package/fesm2020/angular-three.mjs +2344 -10
  251. package/fesm2020/angular-three.mjs.map +1 -1
  252. package/geometries/README.md +3 -0
  253. package/geometries/index.d.ts +23 -0
  254. package/geometries/lib/box-geometry/box-geometry.d.ts +8 -0
  255. package/geometries/lib/buffer-geometry/buffer-geometry.d.ts +8 -0
  256. package/geometries/lib/capsule-geometry/capsule-geometry.d.ts +8 -0
  257. package/geometries/lib/circle-geometry/circle-geometry.d.ts +8 -0
  258. package/geometries/lib/cone-geometry/cone-geometry.d.ts +8 -0
  259. package/geometries/lib/cylinder-geometry/cylinder-geometry.d.ts +8 -0
  260. package/geometries/lib/dodecahedron-geometry/dodecahedron-geometry.d.ts +8 -0
  261. package/geometries/lib/edges-geometry/edges-geometry.d.ts +8 -0
  262. package/geometries/lib/extrude-geometry/extrude-geometry.d.ts +8 -0
  263. package/geometries/lib/icosahedron-geometry/icosahedron-geometry.d.ts +8 -0
  264. package/geometries/lib/instanced-buffer-geometry/instanced-buffer-geometry.d.ts +8 -0
  265. package/geometries/lib/lathe-geometry/lathe-geometry.d.ts +8 -0
  266. package/geometries/lib/octahedron-geometry/octahedron-geometry.d.ts +8 -0
  267. package/geometries/lib/plane-geometry/plane-geometry.d.ts +8 -0
  268. package/geometries/lib/polyhedron-geometry/polyhedron-geometry.d.ts +8 -0
  269. package/geometries/lib/ring-geometry/ring-geometry.d.ts +8 -0
  270. package/geometries/lib/shape-geometry/shape-geometry.d.ts +8 -0
  271. package/geometries/lib/sphere-geometry/sphere-geometry.d.ts +8 -0
  272. package/geometries/lib/tetrahedron-geometry/tetrahedron-geometry.d.ts +8 -0
  273. package/geometries/lib/torus-geometry/torus-geometry.d.ts +8 -0
  274. package/geometries/lib/torus-knot-geometry/torus-knot-geometry.d.ts +8 -0
  275. package/geometries/lib/tube-geometry/tube-geometry.d.ts +8 -0
  276. package/geometries/lib/wireframe-geometry/wireframe-geometry.d.ts +8 -0
  277. package/helpers/README.md +3 -0
  278. package/helpers/index.d.ts +13 -0
  279. package/helpers/lib/arrow-helper/arrow-helper.d.ts +8 -0
  280. package/helpers/lib/axes-helper/axes-helper.d.ts +8 -0
  281. package/helpers/lib/box-helper/box-helper.d.ts +8 -0
  282. package/helpers/lib/box3-helper/box3-helper.d.ts +8 -0
  283. package/helpers/lib/camera-helper/camera-helper.d.ts +8 -0
  284. package/helpers/lib/directional-light-helper/directional-light-helper.d.ts +8 -0
  285. package/helpers/lib/grid-helper/grid-helper.d.ts +8 -0
  286. package/helpers/lib/hemisphere-light-helper/hemisphere-light-helper.d.ts +8 -0
  287. package/helpers/lib/plane-helper/plane-helper.d.ts +8 -0
  288. package/helpers/lib/point-light-helper/point-light-helper.d.ts +8 -0
  289. package/helpers/lib/polar-grid-helper/polar-grid-helper.d.ts +8 -0
  290. package/helpers/lib/skeleton-helper/skeleton-helper.d.ts +8 -0
  291. package/helpers/lib/spot-light-helper/spot-light-helper.d.ts +8 -0
  292. package/index.d.ts +11 -1
  293. package/lib/canvas.d.ts +46 -0
  294. package/lib/di/resize.d.ts +12 -0
  295. package/lib/di/window.d.ts +1 -0
  296. package/lib/directives/args.d.ts +19 -0
  297. package/lib/events.d.ts +2 -0
  298. package/lib/instance.d.ts +81 -0
  299. package/lib/ref.d.ts +5 -0
  300. package/lib/services/loader.d.ts +11 -0
  301. package/lib/services/resize.d.ts +19 -0
  302. package/lib/stores/component-store.d.ts +69 -0
  303. package/lib/stores/store.d.ts +32 -0
  304. package/lib/types.d.ts +358 -0
  305. package/lib/utils/apply-props.d.ts +6 -0
  306. package/lib/utils/build-graph.d.ts +3 -0
  307. package/lib/utils/camera.d.ts +4 -0
  308. package/lib/utils/capitalize.d.ts +1 -0
  309. package/lib/utils/check-update.d.ts +2 -0
  310. package/lib/utils/events.d.ts +6 -0
  311. package/lib/utils/get-instance-local-state.d.ts +2 -0
  312. package/lib/utils/inject.d.ts +9 -0
  313. package/lib/utils/instance.d.ts +4 -0
  314. package/lib/utils/is.d.ts +21 -0
  315. package/lib/utils/loop.d.ts +32 -0
  316. package/lib/utils/make.d.ts +4 -0
  317. package/lib/utils/mutate.d.ts +2 -0
  318. package/lib/utils/proxy.d.ts +7 -0
  319. package/lib/utils/renderer.d.ts +3 -0
  320. package/lights/README.md +3 -0
  321. package/lights/index.d.ts +9 -0
  322. package/lights/lib/ambient-light/ambient-light.d.ts +49 -0
  323. package/lights/lib/ambient-light-probe/ambient-light-probe.d.ts +50 -0
  324. package/lights/lib/directional-light/directional-light.d.ts +50 -0
  325. package/lights/lib/hemisphere-light/hemisphere-light.d.ts +51 -0
  326. package/lights/lib/hemisphere-light-probe/hemisphere-light-probe.d.ts +52 -0
  327. package/lights/lib/light-probe/light-probe.d.ts +50 -0
  328. package/lights/lib/point-light/point-light.d.ts +52 -0
  329. package/lights/lib/rect-area-light/rect-area-light.d.ts +52 -0
  330. package/lights/lib/spot-light/spot-light.d.ts +55 -0
  331. package/materials/README.md +3 -0
  332. package/materials/index.d.ts +17 -0
  333. package/materials/lib/line-basic-material/line-basic-material.d.ts +55 -0
  334. package/materials/lib/line-dashed-material/line-dashed-material.d.ts +58 -0
  335. package/materials/lib/mesh-basic-material/mesh-basic-material.d.ts +67 -0
  336. package/materials/lib/mesh-depth-material/mesh-depth-material.d.ts +58 -0
  337. package/materials/lib/mesh-distance-material/mesh-distance-material.d.ts +58 -0
  338. package/materials/lib/mesh-lambert-material/mesh-lambert-material.d.ts +78 -0
  339. package/materials/lib/mesh-matcap-material/mesh-matcap-material.d.ts +64 -0
  340. package/materials/lib/mesh-normal-material/mesh-normal-material.d.ts +61 -0
  341. package/materials/lib/mesh-phong-material/mesh-phong-material.d.ts +81 -0
  342. package/materials/lib/mesh-physical-material/mesh-physical-material.d.ts +97 -0
  343. package/materials/lib/mesh-standard-material/mesh-standard-material.d.ts +78 -0
  344. package/materials/lib/mesh-toon-material/mesh-toon-material.d.ts +74 -0
  345. package/materials/lib/points-material/points-material.d.ts +56 -0
  346. package/materials/lib/raw-shader-material/raw-shader-material.d.ts +68 -0
  347. package/materials/lib/shader-material/shader-material.d.ts +68 -0
  348. package/materials/lib/shadow-material/shadow-material.d.ts +52 -0
  349. package/materials/lib/sprite-material/sprite-material.d.ts +56 -0
  350. package/objects/README.md +3 -0
  351. package/objects/index.d.ts +12 -0
  352. package/objects/lib/bone/bone.d.ts +35 -0
  353. package/objects/lib/group/group.d.ts +35 -0
  354. package/objects/lib/instanced-mesh/instanced-mesh.d.ts +44 -0
  355. package/objects/lib/line/line.d.ts +41 -0
  356. package/objects/lib/line-loop/line-loop.d.ts +41 -0
  357. package/objects/lib/line-segments/line-segments.d.ts +41 -0
  358. package/objects/lib/lod/lod.d.ts +41 -0
  359. package/objects/lib/mesh/mesh.d.ts +41 -0
  360. package/objects/lib/points/points.d.ts +41 -0
  361. package/objects/lib/skeleton/skeleton.d.ts +17 -0
  362. package/objects/lib/skinned-mesh/skinned-mesh.d.ts +45 -0
  363. package/objects/lib/sprite/sprite.d.ts +38 -0
  364. package/package.json +93 -2
  365. package/primitives/README.md +3 -0
  366. package/primitives/index.d.ts +2 -0
  367. package/primitives/lib/object-primitive/object-primitive.d.ts +35 -0
  368. package/primitives/lib/primitive/primitive.d.ts +10 -0
  369. package/schematics/src/generators/init/generator.d.ts +1 -1
  370. package/schematics/src/generators/init/generator.js +4 -4
  371. package/schematics/src/generators/init/generator.js.map +1 -1
  372. package/stats/README.md +3 -0
  373. package/stats/index.d.ts +1 -0
  374. package/stats/lib/stats/stats.d.ts +16 -0
  375. package/textures/README.md +3 -0
  376. package/textures/index.d.ts +10 -0
  377. package/textures/lib/canvas-texture/canvas-texture.d.ts +8 -0
  378. package/textures/lib/compressed-array-texture/compressed-array-texture.d.ts +8 -0
  379. package/textures/lib/compressed-texture/compressed-texture.d.ts +8 -0
  380. package/textures/lib/cube-texture/cube-texture.d.ts +8 -0
  381. package/textures/lib/data-array-texture/data-array-texture.d.ts +8 -0
  382. package/textures/lib/data-texture/data-texture.d.ts +8 -0
  383. package/textures/lib/data3-dtexture/data3-dtexture.d.ts +8 -0
  384. package/textures/lib/depth-texture/depth-texture.d.ts +8 -0
  385. package/textures/lib/framebuffer-texture/framebuffer-texture.d.ts +8 -0
  386. package/textures/lib/video-texture/video-texture.d.ts +8 -0
  387. package/esm2020/lib/angular-three.module.mjs +0 -15
  388. package/lib/angular-three.module.d.ts +0 -7
@@ -1,22 +1,2356 @@
1
+ import { DOCUMENT, NgIf, NgTemplateOutlet, AsyncPipe } from '@angular/common';
1
2
  import * as i0 from '@angular/core';
2
- import { NgModule } from '@angular/core';
3
- import { CommonModule } from '@angular/common';
3
+ import { Injectable, InjectionToken, inject, NgZone, EventEmitter, Directive, Input, Output, ElementRef, Component, TemplateRef, ChangeDetectionStrategy, HostBinding, ViewChild, ContentChild, ViewContainerRef, Injector } from '@angular/core';
4
+ import * as THREE from 'three';
5
+ import { BehaviorSubject, filter, noop, tap, isObservable, combineLatest, Observable, Subject, pipe, debounceTime, takeUntil, fromEvent, share, ReplaySubject, from, retry, catchError, of, forkJoin, map } from 'rxjs';
6
+ import { ComponentStore } from '@ngrx/component-store';
4
7
 
5
- class AngularThreeModule {
8
+ function getInstanceLocalState(obj) {
9
+ if (!obj)
10
+ return undefined;
11
+ return obj['__ngt__'];
6
12
  }
7
- AngularThreeModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AngularThreeModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
8
- AngularThreeModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.0.0", ngImport: i0, type: AngularThreeModule, imports: [CommonModule] });
9
- AngularThreeModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AngularThreeModule, imports: [CommonModule] });
10
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: AngularThreeModule, decorators: [{
11
- type: NgModule,
13
+
14
+ const idCache = {};
15
+ function makeId(event) {
16
+ if (event) {
17
+ return (event.eventObject || event.object).uuid + '/' + event.index + event.instanceId;
18
+ }
19
+ const newId = THREE.MathUtils.generateUUID();
20
+ // ensure not already used
21
+ if (!idCache[newId]) {
22
+ idCache[newId] = true;
23
+ return newId;
24
+ }
25
+ return makeId();
26
+ }
27
+ function makeDpr(dpr, window) {
28
+ const target = window?.devicePixelRatio || 1;
29
+ return Array.isArray(dpr) ? Math.min(Math.max(dpr[0], target), dpr[1]) : dpr;
30
+ }
31
+ function make(type, input) {
32
+ if (!input)
33
+ return new type();
34
+ if (input instanceof type) {
35
+ return input;
36
+ }
37
+ if (!Array.isArray(input)) {
38
+ input = typeof input === 'number' ? [input, input, input, input] : [input];
39
+ }
40
+ return new type(...input);
41
+ }
42
+
43
+ /**
44
+ * Release pointer captures.
45
+ * This is called by releasePointerCapture in the API, and when an object is removed.
46
+ */
47
+ function releaseInternalPointerCapture(capturedMap, obj, captures, pointerId) {
48
+ const captureData = captures.get(obj);
49
+ if (captureData) {
50
+ captures.delete(obj);
51
+ // If this was the last capturing object for this pointer
52
+ if (captures.size === 0) {
53
+ capturedMap.delete(pointerId);
54
+ captureData.target.releasePointerCapture(pointerId);
55
+ }
56
+ }
57
+ }
58
+ function removeInteractivity(stateFactory, object) {
59
+ const { internal } = stateFactory();
60
+ // Removes every trace of an object from the data store
61
+ internal.interaction = internal.interaction.filter((o) => o !== object);
62
+ internal.initialHits = internal.initialHits.filter((o) => o !== object);
63
+ internal.hovered.forEach((value, key) => {
64
+ if (value.eventObject === object || value.object === object) {
65
+ // Clear out intersects, they are outdated by now
66
+ internal.hovered.delete(key);
67
+ }
68
+ });
69
+ internal.capturedMap.forEach((captures, pointerId) => {
70
+ releaseInternalPointerCapture(internal.capturedMap, object, captures, pointerId);
71
+ });
72
+ }
73
+ function createEvents(stateFactory) {
74
+ /** Calculates delta */
75
+ function calculateDistance(event) {
76
+ const { internal } = stateFactory();
77
+ const dx = event.offsetX - internal.initialClick[0];
78
+ const dy = event.offsetY - internal.initialClick[1];
79
+ return Math.round(Math.sqrt(dx * dx + dy * dy));
80
+ }
81
+ /** Returns true if an instance has a valid pointer-event registered, this excludes scroll, clicks etc */
82
+ function filterPointerEvents(objects) {
83
+ return objects.filter((obj) => ['move', 'over', 'enter', 'out', 'leave'].some((name) => {
84
+ const eventName = ('pointer' + name);
85
+ return getInstanceLocalState(obj)?.handlers[eventName];
86
+ }));
87
+ }
88
+ function intersect(event, filter) {
89
+ const state = stateFactory();
90
+ const duplicates = new Set();
91
+ const intersections = [];
92
+ // Allow callers to eliminate event objects
93
+ const eventsObjects = filter ? filter(state.internal.interaction) : state.internal.interaction;
94
+ // Reset all raycaster cameras to undefined
95
+ for (let i = 0; i < eventsObjects.length; i++) {
96
+ const instanceState = getInstanceLocalState(eventsObjects[i])?.stateFactory();
97
+ if (instanceState) {
98
+ instanceState.raycaster.camera = undefined;
99
+ }
100
+ }
101
+ if (!state.previousStateFactory) {
102
+ // Make sure root-level pointer and ray are set up
103
+ state.events.compute?.(event, () => state);
104
+ }
105
+ function handleRaycast(obj) {
106
+ const state = getInstanceLocalState(obj)?.stateFactory();
107
+ // Skip event handling when noEvents is set, or when the raycasters camera is null
108
+ if (!state || !state.events.enabled || state.raycaster.camera === null)
109
+ return [];
110
+ // When the camera is undefined we have to call the event layers update function
111
+ if (state.raycaster.camera === undefined) {
112
+ state.events.compute?.(event, () => state, state.previousStateFactory);
113
+ // If the camera is still undefined we have to skip this layer entirely
114
+ if (state.raycaster.camera === undefined)
115
+ state.raycaster.camera = null;
116
+ }
117
+ // Intersect object by object
118
+ return state.raycaster.camera ? state.raycaster.intersectObject(obj, true) : [];
119
+ }
120
+ // Collect events
121
+ let hits = eventsObjects
122
+ // Intersect objects
123
+ .flatMap(handleRaycast)
124
+ // Sort by event priority and distance
125
+ .sort((a, b) => {
126
+ const aState = getInstanceLocalState(a.object)?.stateFactory();
127
+ const bState = getInstanceLocalState(b.object)?.stateFactory();
128
+ if (!aState || !bState)
129
+ return 0;
130
+ return bState.events.priority - aState.events.priority || a.distance - b.distance;
131
+ })
132
+ // Filter out duplicates
133
+ .filter((item) => {
134
+ const id = makeId(item);
135
+ if (duplicates.has(id))
136
+ return false;
137
+ duplicates.add(id);
138
+ return true;
139
+ });
140
+ // https://github.com/mrdoob/three.js/issues/16031
141
+ // Allow custom userland intersect sort order, this likely only makes sense on the root filter
142
+ if (state.events.filter)
143
+ hits = state.events.filter(hits, () => state);
144
+ // Bubble up the events, find the event source (eventObject)
145
+ for (const hit of hits) {
146
+ let eventObject = hit.object;
147
+ // Bubble event up
148
+ while (eventObject) {
149
+ if (getInstanceLocalState(eventObject)?.eventCount)
150
+ intersections.push({ ...hit, eventObject });
151
+ eventObject = eventObject.parent;
152
+ }
153
+ }
154
+ // If the interaction is captured, make all capturing targets part of the intersect.
155
+ if ('pointerId' in event && state.internal.capturedMap.has(event.pointerId)) {
156
+ for (const captureData of state.internal.capturedMap.get(event.pointerId).values()) {
157
+ intersections.push(captureData.intersection);
158
+ }
159
+ }
160
+ return intersections;
161
+ }
162
+ /** Handles intersections by forwarding them to handlers */
163
+ function handleIntersects(intersections, event, delta, callback) {
164
+ const rootState = stateFactory();
165
+ // If anything has been found, forward it to the event listeners
166
+ if (intersections.length) {
167
+ const localState = { stopped: false };
168
+ for (const hit of intersections) {
169
+ const state = getInstanceLocalState(hit.object)?.stateFactory() || rootState;
170
+ const { raycaster, pointer, camera, internal } = state;
171
+ const unprojectedPoint = new THREE.Vector3(pointer.x, pointer.y, 0).unproject(camera);
172
+ const hasPointerCapture = (id) => internal.capturedMap.get(id)?.has(hit.eventObject) ?? false;
173
+ const setPointerCapture = (id) => {
174
+ const captureData = {
175
+ intersection: hit,
176
+ target: event.target,
177
+ };
178
+ if (internal.capturedMap.has(id)) {
179
+ // if the pointerId was previously captured, we add the hit to the
180
+ // event capturedMap.
181
+ internal.capturedMap.get(id).set(hit.eventObject, captureData);
182
+ }
183
+ else {
184
+ // if the pointerId was not previously captured, we create a map
185
+ // containing the hitObject, and the hit. hitObject is used for
186
+ // faster access.
187
+ internal.capturedMap.set(id, new Map([[hit.eventObject, captureData]]));
188
+ }
189
+ // Call the original event now
190
+ event.target.setPointerCapture(id);
191
+ };
192
+ const releasePointerCapture = (id) => {
193
+ const captures = internal.capturedMap.get(id);
194
+ if (captures) {
195
+ releaseInternalPointerCapture(internal.capturedMap, hit.eventObject, captures, id);
196
+ }
197
+ };
198
+ // Add native event props
199
+ const extractEventProps = {};
200
+ // This iterates over the event's properties including the inherited ones. Native PointerEvents have most of their props as getters which are inherited, but polyfilled PointerEvents have them all as their own properties (i.e. not inherited). We can't use Object.keys() or Object.entries() as they only return "own" properties; nor Object.getPrototypeOf(event) as that *doesn't* return "own" properties, only inherited ones.
201
+ for (const prop in event) {
202
+ const property = event[prop];
203
+ // Only copy over atomics, leave functions alone as these should be
204
+ // called as event.nativeEvent.fn()
205
+ if (typeof property !== 'function')
206
+ extractEventProps[prop] = property;
207
+ }
208
+ const raycastEvent = {
209
+ ...hit,
210
+ ...extractEventProps,
211
+ pointer,
212
+ intersections,
213
+ stopped: localState.stopped,
214
+ delta,
215
+ unprojectedPoint,
216
+ ray: raycaster.ray,
217
+ camera: camera,
218
+ // Hijack stopPropagation, which just sets a flag
219
+ stopPropagation() {
220
+ // https://github.com/pmndrs/react-three-fiber/issues/596
221
+ // Events are not allowed to stop propagation if the pointer has been captured
222
+ const capturesForPointer = 'pointerId' in event && internal.capturedMap.get(event.pointerId);
223
+ // We only authorize stopPropagation...
224
+ if (
225
+ // ...if this pointer hasn't been captured
226
+ !capturesForPointer ||
227
+ // ... or if the hit object is capturing the pointer
228
+ capturesForPointer.has(hit.eventObject)) {
229
+ raycastEvent.stopped = localState.stopped = true;
230
+ // Propagation is stopped, remove all other hover records
231
+ // An event handler is only allowed to flush other handlers if it is hovered itself
232
+ if (internal.hovered.size &&
233
+ Array.from(internal.hovered.values()).find((i) => i.eventObject === hit.eventObject)) {
234
+ // Objects cannot flush out higher up objects that have already caught the event
235
+ const higher = intersections.slice(0, intersections.indexOf(hit));
236
+ cancelPointer([...higher, hit]);
237
+ }
238
+ }
239
+ },
240
+ // there should be a distinction between target and currentTarget
241
+ target: {
242
+ hasPointerCapture,
243
+ setPointerCapture,
244
+ releasePointerCapture,
245
+ },
246
+ currentTarget: {
247
+ hasPointerCapture,
248
+ setPointerCapture,
249
+ releasePointerCapture,
250
+ },
251
+ nativeEvent: event,
252
+ };
253
+ // Call subscribers
254
+ callback(raycastEvent);
255
+ // Event bubbling may be interrupted by stopPropagation
256
+ if (localState.stopped === true)
257
+ break;
258
+ }
259
+ }
260
+ return intersections;
261
+ }
262
+ function cancelPointer(intersections) {
263
+ const { internal } = stateFactory();
264
+ for (const hoveredObj of internal.hovered.values()) {
265
+ // When no objects were hit or the hovered object wasn't found underneath the cursor
266
+ // we call onPointerOut and delete the object from the hovered-elements map
267
+ if (!intersections.length ||
268
+ !intersections.find((hit) => hit.object === hoveredObj.object &&
269
+ hit.index === hoveredObj.index &&
270
+ hit.instanceId === hoveredObj.instanceId)) {
271
+ const eventObject = hoveredObj.eventObject;
272
+ const instance = getInstanceLocalState(eventObject);
273
+ const handlers = instance?.handlers;
274
+ internal.hovered.delete(makeId(hoveredObj));
275
+ if (instance?.eventCount) {
276
+ // Clear out intersects, they are outdated by now
277
+ const data = { ...hoveredObj, intersections };
278
+ handlers?.pointerout?.(data);
279
+ handlers?.pointerleave?.(data);
280
+ }
281
+ }
282
+ }
283
+ }
284
+ function pointerMissed(event, objects) {
285
+ for (let i = 0; i < objects.length; i++) {
286
+ const instance = getInstanceLocalState(objects[i]);
287
+ instance?.handlers.pointermissed?.(event);
288
+ }
289
+ }
290
+ function handlePointer(name) {
291
+ // Deal with cancelation
292
+ switch (name) {
293
+ case 'pointerleave':
294
+ case 'pointercancel':
295
+ return () => cancelPointer([]);
296
+ case 'lostpointercapture':
297
+ return (event) => {
298
+ const { internal } = stateFactory();
299
+ if ('pointerId' in event && !internal.capturedMap.has(event.pointerId)) {
300
+ // If the object event interface had onLostPointerCapture, we'd call it here on every
301
+ // object that's getting removed.
302
+ internal.capturedMap.delete(event.pointerId);
303
+ cancelPointer([]);
304
+ }
305
+ };
306
+ }
307
+ // Any other pointer goes here ...
308
+ return function handleEvent(event) {
309
+ const { onPointerMissed, internal } = stateFactory();
310
+ // prepareRay(event)
311
+ internal.lastEvent = event;
312
+ // Get fresh intersects
313
+ const isPointerMove = name === 'pointermove';
314
+ const isClickEvent = name === 'click' || name === 'contextmenu' || name === 'dblclick';
315
+ const filter = isPointerMove ? filterPointerEvents : undefined;
316
+ // const hits = patchIntersects(intersect(filter), event)
317
+ const hits = intersect(event, filter);
318
+ const delta = isClickEvent ? calculateDistance(event) : 0;
319
+ // Save initial coordinates on pointer-down
320
+ if (name === 'pointerdown') {
321
+ internal.initialClick = [event.offsetX, event.offsetY];
322
+ internal.initialHits = hits.map((hit) => hit.eventObject);
323
+ }
324
+ // If a click yields no results, pass it back to the user as a miss
325
+ // Missed events have to come first in order to establish user-land side-effect clean up
326
+ if (isClickEvent && !hits.length) {
327
+ if (delta <= 2) {
328
+ pointerMissed(event, internal.interaction);
329
+ if (onPointerMissed)
330
+ onPointerMissed(event);
331
+ }
332
+ }
333
+ // Take care of unhover
334
+ if (isPointerMove)
335
+ cancelPointer(hits);
336
+ function onIntersect(data) {
337
+ const eventObject = data.eventObject;
338
+ const instance = getInstanceLocalState(eventObject);
339
+ const handlers = instance?.handlers;
340
+ // Check presence of handlers
341
+ if (!instance?.eventCount)
342
+ return;
343
+ if (isPointerMove) {
344
+ // Move event ...
345
+ if (handlers?.pointerover ||
346
+ handlers?.pointerenter ||
347
+ handlers?.pointerout ||
348
+ handlers?.pointerleave) {
349
+ // When enter or out is present take care of hover-state
350
+ const id = makeId(data);
351
+ const hoveredItem = internal.hovered.get(id);
352
+ if (!hoveredItem) {
353
+ // If the object wasn't previously hovered, book it and call its handler
354
+ internal.hovered.set(id, data);
355
+ handlers.pointerover?.(data);
356
+ handlers.pointerenter?.(data);
357
+ }
358
+ else if (hoveredItem.stopped) {
359
+ // If the object was previously hovered and stopped, we shouldn't allow other items to proceed
360
+ data.stopPropagation();
361
+ }
362
+ }
363
+ // Call mouse move
364
+ handlers?.pointermove?.(data);
365
+ }
366
+ else {
367
+ // All other events ...
368
+ const handler = handlers[name];
369
+ if (handler) {
370
+ // Forward all events back to their respective handlers with the exception of click events,
371
+ // which must use the initial target
372
+ if (!isClickEvent || internal.initialHits.includes(eventObject)) {
373
+ // Missed events have to come first
374
+ pointerMissed(event, internal.interaction.filter((object) => !internal.initialHits.includes(object)));
375
+ // Now call the handler
376
+ handler(data);
377
+ }
378
+ }
379
+ else {
380
+ // Trigger onPointerMissed on all elements that have pointer over/out handlers, but not click and weren't hit
381
+ if (isClickEvent && internal.initialHits.includes(eventObject)) {
382
+ pointerMissed(event, internal.interaction.filter((object) => !internal.initialHits.includes(object)));
383
+ }
384
+ }
385
+ }
386
+ }
387
+ handleIntersects(hits, event, delta, onIntersect);
388
+ };
389
+ }
390
+ return { handlePointer };
391
+ }
392
+
393
+ const DOM_EVENTS = {
394
+ click: false,
395
+ contextmenu: false,
396
+ dblclick: false,
397
+ wheel: false,
398
+ pointerdown: true,
399
+ pointerup: true,
400
+ pointerleave: true,
401
+ pointermove: true,
402
+ pointercancel: true,
403
+ lostpointercapture: true,
404
+ };
405
+ function createPointerEvents(stateFactory) {
406
+ const { handlePointer } = createEvents(stateFactory);
407
+ return {
408
+ priority: 1,
409
+ enabled: true,
410
+ compute: (event, rootFactory) => {
411
+ const state = rootFactory();
412
+ // https://github.com/pmndrs/react-three-fiber/pull/782
413
+ // Events trigger outside of canvas when moved, use offsetX/Y by default and allow overrides
414
+ state.pointer.set((event.offsetX / state.size.width) * 2 - 1, -(event.offsetY / state.size.height) * 2 + 1);
415
+ state.raycaster.setFromCamera(state.pointer, state.camera);
416
+ },
417
+ connected: undefined,
418
+ handlers: Object.keys(DOM_EVENTS).reduce((handlers, supportedEventName) => {
419
+ handlers[supportedEventName] = handlePointer(supportedEventName);
420
+ return handlers;
421
+ }, {}),
422
+ connect: (target) => {
423
+ const state = stateFactory();
424
+ state.events.disconnect?.();
425
+ state.setEvents({ connected: target });
426
+ Object.entries(state.events.handlers ?? {}).forEach(([eventName, eventHandler]) => {
427
+ const passive = DOM_EVENTS[eventName];
428
+ target.addEventListener(eventName, eventHandler, { passive });
429
+ });
430
+ },
431
+ disconnect: () => {
432
+ const { events, setEvents } = stateFactory();
433
+ if (events.connected) {
434
+ Object.entries(events.handlers ?? {}).forEach(([eventName, eventHandler]) => {
435
+ if (events.connected instanceof HTMLElement) {
436
+ events.connected.removeEventListener(eventName, eventHandler);
437
+ }
438
+ });
439
+ setEvents({ connected: undefined });
440
+ }
441
+ },
442
+ };
443
+ }
444
+
445
+ class NgtRef extends BehaviorSubject {
446
+ constructor(value) {
447
+ super(value ? value : null);
448
+ }
449
+ set(valueOrFactory) {
450
+ if (typeof valueOrFactory === 'function') {
451
+ this.next(valueOrFactory(this.value));
452
+ }
453
+ else {
454
+ this.next(valueOrFactory);
455
+ }
456
+ }
457
+ }
458
+
459
+ const is = {
460
+ obj: (a) => a === Object(a) && !Array.isArray(a) && typeof a !== 'function',
461
+ material: (a) => !!a && a.isMaterial,
462
+ geometry: (a) => !!a && a.isBufferGeometry,
463
+ mesh: (a) => !!a && a.isMesh,
464
+ color: (a) => !!a && a.isColor,
465
+ orthographic: (a) => !!a && a.isOrthographicCamera,
466
+ perspective: (a) => !!a && a.isPerspectiveCamera,
467
+ camera: (a) => !!a && a.isCamera,
468
+ glRenderer: (a) => !!a && a instanceof THREE.WebGLRenderer,
469
+ scene: (a) => !!a && a.isScene,
470
+ object3d: (a) => !!a && a.isObject3D,
471
+ instance: (a) => !!a && !!a['__ngt__'],
472
+ ref: (a) => !!a && a instanceof NgtRef,
473
+ supportColorManagement: () => 'ColorManagement' in THREE,
474
+ canvas: (a) => a instanceof HTMLCanvasElement,
475
+ equ(a, b, { arrays = 'shallow', objects = 'reference', strict = true } = {}) {
476
+ // Wrong type or one of the two undefined, doesn't match
477
+ if (typeof a !== typeof b || !!a !== !!b)
478
+ return false;
479
+ // Atomic, just compare a against b
480
+ if (typeof a === 'string' || typeof a === 'number')
481
+ return a === b;
482
+ const isObj = is.obj(a);
483
+ if (isObj && objects === 'reference')
484
+ return a === b;
485
+ const isArr = Array.isArray(a);
486
+ if (isArr && arrays === 'reference')
487
+ return a === b;
488
+ // Array or Object, shallow compare first to see if it's a match
489
+ if ((isArr || isObj) && a === b)
490
+ return true;
491
+ // Last resort, go through keys
492
+ let i;
493
+ for (i in a)
494
+ if (!(i in b))
495
+ return false;
496
+ for (i in strict ? b : a)
497
+ if (a[i] !== b[i])
498
+ return false;
499
+ if (i === void 0) {
500
+ if (isArr && a.length === 0 && b.length === 0)
501
+ return true;
502
+ if (isObj && Object.keys(a).length === 0 && Object.keys(b).length === 0)
503
+ return true;
504
+ if (a !== b)
505
+ return false;
506
+ }
507
+ return true;
508
+ },
509
+ };
510
+
511
+ /**
512
+ * a default Selector that consumers can quickly use for their selectors projector
513
+ */
514
+ const defaultProjector = () => ({});
515
+ /**
516
+ * A custom operator that skips the first undefined value but allows subsequent undefined values.
517
+ * NgRxComponentStore#select always emits the first value regardless of undefined or not after initialize
518
+ */
519
+ const skipFirstUndefined = () => filter((value, index) => index > 0 || value !== undefined);
520
+ /**
521
+ * An extended `tap` operator that accepts an `effectFn` which:
522
+ * - runs on every `next` notification from `source$`
523
+ * - can optionally return a `cleanUp` function that
524
+ * invokes from the 2nd `next` notification onward and on `unsubscribe` (destroyed)
525
+ *
526
+ *
527
+ * @example
528
+ * ```typescript
529
+ * source$.pipe(
530
+ * tapEffect((sourceValue) = {
531
+ * const cb = () => {
532
+ * doStuff(sourceValue);
533
+ * };
534
+ * addListener('event', cb);
535
+ *
536
+ * return () => {
537
+ * removeListener('event', cb);
538
+ * }
539
+ * })
540
+ * )
541
+ * ```
542
+ */
543
+ function tapEffect(effectFn) {
544
+ let cleanupFn = noop;
545
+ let firstRun = false;
546
+ let prev = undefined;
547
+ const teardown = (error) => {
548
+ return () => {
549
+ if (cleanupFn) {
550
+ cleanupFn({ prev, complete: true, error });
551
+ }
552
+ };
553
+ };
554
+ return tap({
555
+ next: (value) => {
556
+ if (cleanupFn && firstRun) {
557
+ cleanupFn({ prev, complete: false, error: false });
558
+ }
559
+ const cleanUpOrVoid = effectFn(value);
560
+ if (cleanUpOrVoid) {
561
+ cleanupFn = cleanUpOrVoid;
562
+ }
563
+ prev = value;
564
+ if (!firstRun) {
565
+ firstRun = true;
566
+ }
567
+ },
568
+ complete: teardown(false),
569
+ unsubscribe: teardown(false),
570
+ error: teardown(true),
571
+ });
572
+ }
573
+ class NgtComponentStore extends ComponentStore {
574
+ constructor() {
575
+ super({});
576
+ // exposing get since THREE is imperative at its core
577
+ // we need to imperatively get state sometimes for usages in Animation Loop
578
+ // we also bind "this" instance, so we don't have to bind it later
579
+ this.read = this.get.bind(this);
580
+ this.initialize();
581
+ }
582
+ /**
583
+ * A custom patchState that allows for:
584
+ * - Partial state updates and Observable of partial state updates like patchState
585
+ * - Pass a Record<string, ObservableInput> to update a specific key with an Observable.
586
+ * This is similar to `RxState.connect()` API
587
+ */
588
+ write(partialStateOrFactory) {
589
+ if (typeof partialStateOrFactory === 'function') {
590
+ return this.write(partialStateOrFactory(this.read()));
591
+ }
592
+ const partialState = partialStateOrFactory;
593
+ if (Object.keys(partialState).length === 0) {
594
+ return;
595
+ }
596
+ if (isObservable(partialState)) {
597
+ return this.patchState(partialState);
598
+ }
599
+ const entries = Object.entries(partialState);
600
+ const hasObservable = entries.some(([_, value]) => isObservable(value) && !is.ref(value));
601
+ if (!hasObservable) {
602
+ return this.patchState(partialState);
603
+ }
604
+ const [rawValues, observableValues] = entries.reduce((result, [key, value]) => {
605
+ if (isObservable(value)) {
606
+ result[1][key] = value;
607
+ }
608
+ else {
609
+ result[0][key] = value;
610
+ }
611
+ return result;
612
+ }, [{}, {}]);
613
+ if (Object.keys(rawValues).length > 0) {
614
+ this.patchState(rawValues);
615
+ }
616
+ if (Object.keys(observableValues).length > 0) {
617
+ this.patchState(combineLatest(observableValues));
618
+ }
619
+ }
620
+ initialize() {
621
+ return;
622
+ }
623
+ /**
624
+ * A utility class method to select a state on the template as Observable
625
+ * - This method always debounce the Observable
626
+ */
627
+ selectKey(key, skipFirst = false) {
628
+ return this.select((s) => s[key], { debounce: true }).pipe(skipFirst ? skipFirstUndefined() : (s) => s);
629
+ }
630
+ /**
631
+ * A utility class method to get a state on the template as imperative Value
632
+ */
633
+ readKey(key) {
634
+ return this.read((s) => s[key]);
635
+ }
636
+ }
637
+ NgtComponentStore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtComponentStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
638
+ NgtComponentStore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtComponentStore });
639
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtComponentStore, decorators: [{
640
+ type: Injectable
641
+ }], ctorParameters: function () { return []; } });
642
+
643
+ function createInjection(description, { defaultValueOrFactory, provideValueFactory, } = {}) {
644
+ const factory = (defaultValueOrFactory && typeof defaultValueOrFactory === 'function'
645
+ ? defaultValueOrFactory
646
+ : () => defaultValueOrFactory);
647
+ const injectionToken = new InjectionToken(description, { factory });
648
+ function injectFn(options = {}) {
649
+ return inject(injectionToken, options);
650
+ }
651
+ function provideFn(value) {
652
+ return {
653
+ provide: injectionToken,
654
+ useValue: provideValueFactory ? provideValueFactory(value) : value,
655
+ };
656
+ }
657
+ return [injectFn, provideFn, injectionToken];
658
+ }
659
+
660
+ const [injectWindow] = createInjection('window', {
661
+ defaultValueOrFactory: () => {
662
+ const { defaultView } = inject(DOCUMENT);
663
+ if (!defaultView) {
664
+ throw `window is not available!`;
665
+ }
666
+ return defaultView;
667
+ },
668
+ });
669
+
670
+ function checkNeedsUpdate(value) {
671
+ if (value !== null && is.obj(value) && 'needsUpdate' in value) {
672
+ value['needsUpdate'] = true;
673
+ if ('uniformsNeedUpdate' in value) {
674
+ value['uniformsNeedUpdate'] = true;
675
+ }
676
+ }
677
+ }
678
+ function checkUpdate(value) {
679
+ if (is.object3d(value)) {
680
+ value.updateMatrix();
681
+ }
682
+ else if (is.camera(value)) {
683
+ if (is.perspective(value) || is.orthographic(value)) {
684
+ value.updateProjectionMatrix();
685
+ }
686
+ value.updateMatrixWorld();
687
+ }
688
+ checkNeedsUpdate(value);
689
+ }
690
+
691
+ function invalidateInstance(instance) {
692
+ const state = getInstanceLocalState(instance)?.stateFactory();
693
+ if (state && state.internal.frames === 0)
694
+ state.invalidate();
695
+ checkUpdate(instance);
696
+ }
697
+ function prepare(instance, parentStateFactory, rootStateFactory, parentInstance, previousInstance, isPrimitive = false) {
698
+ const previousInstanceInternal = getInstanceLocalState(previousInstance?.value);
699
+ const parent = parentInstance
700
+ ? parentInstance
701
+ : previousInstanceInternal
702
+ ? previousInstanceInternal.parentRef
703
+ : undefined;
704
+ if (is.scene(instance)) {
705
+ applyProps(instance, { dispose: null });
706
+ }
707
+ return Object.assign(instance, {
708
+ __ngt__: {
709
+ stateFactory: parentStateFactory,
710
+ rootFactory: rootStateFactory,
711
+ isPrimitive: !isPrimitive ? previousInstanceInternal?.isPrimitive : isPrimitive,
712
+ eventCount: previousInstanceInternal?.eventCount ?? 0,
713
+ handlers: previousInstanceInternal?.handlers ?? {},
714
+ instancesRefs: previousInstanceInternal?.instancesRefs ?? new NgtRef([]),
715
+ objectsRefs: previousInstanceInternal?.objectsRefs ?? new NgtRef([]),
716
+ parentRef: parent ? (parent === instance || parent.value === instance ? null : parent) : null,
717
+ },
718
+ });
719
+ }
720
+
721
+ const DEFAULT = '__default';
722
+ function diffProps(instance, props, previousProps = {}, remove = false) {
723
+ const localState = getInstanceLocalState(instance) || {};
724
+ const propsEntries = Object.entries(props);
725
+ const changes = [];
726
+ // Catch removed props, prepend them, so they can be reset or removed
727
+ if (remove) {
728
+ const previousKeys = Object.keys(previousProps);
729
+ for (const previousKey of previousKeys) {
730
+ // @ts-ignore
731
+ if (!Object.hasOwn(props, previousKey)) {
732
+ propsEntries.unshift([previousKey, DEFAULT + 'remove']);
733
+ }
734
+ }
735
+ }
736
+ for (const [propKey, propValue] of propsEntries) {
737
+ if (is.equ(propValue, previousProps[propKey]))
738
+ continue;
739
+ changes.push([propKey, propValue]);
740
+ }
741
+ const memoized = { ...props };
742
+ if (localState.memoized && localState.memoized['args']) {
743
+ memoized['args'] = localState.memoized['args'];
744
+ }
745
+ if (localState.memoized && localState.memoized['attach']) {
746
+ memoized['attach'] = localState.memoized['attach'] || localState.attach;
747
+ }
748
+ return { changes, memoized };
749
+ }
750
+ function applyProps(instance, props) {
751
+ // props is empty
752
+ if (!Object.keys(props).length)
753
+ return instance;
754
+ // Filter equals, events and reserved props
755
+ const localState = getInstanceLocalState(instance) || {};
756
+ const rootState = localState.stateFactory?.();
757
+ const { changes, memoized } = diffProps(instance, props);
758
+ const instanceHandlers = localState.eventCount;
759
+ if (getInstanceLocalState(instance)) {
760
+ getInstanceLocalState(instance).memoized = memoized;
761
+ }
762
+ for (let i = 0; i < changes.length; i++) {
763
+ const key = changes[i][0];
764
+ const currentInstance = instance;
765
+ const targetProp = currentInstance[key];
766
+ let value = changes[i][1];
767
+ if (is.ref(value)) {
768
+ value = value.value;
769
+ }
770
+ if (value === DEFAULT + 'remove') {
771
+ if (targetProp && targetProp.constructor) {
772
+ // use the prop constructor to find the default it should be
773
+ value = new targetProp.constructor(...(memoized['args'] ?? []));
774
+ }
775
+ else if (currentInstance.constructor) {
776
+ const dummyInstance = new currentInstance.constructor(...(getInstanceLocalState(currentInstance)?.memoized?.['args'] || []));
777
+ value = dummyInstance[targetProp];
778
+ // destroy the instance
779
+ if (dummyInstance.dispose)
780
+ dummyInstance.dispose();
781
+ }
782
+ else {
783
+ value = 0;
784
+ }
785
+ }
786
+ // Special treatment for objects with support for set/copy, and layers
787
+ if (targetProp && targetProp['set'] && (targetProp['copy'] || targetProp instanceof THREE.Layers)) {
788
+ const isColor = targetProp instanceof THREE.Color;
789
+ // If value is an array
790
+ if (Array.isArray(value)) {
791
+ if (targetProp['fromArray'])
792
+ targetProp['fromArray'](value);
793
+ else
794
+ targetProp['set'](...value);
795
+ }
796
+ // Test again target.copy(class) next ...
797
+ else if (targetProp['copy'] &&
798
+ value &&
799
+ value.constructor &&
800
+ targetProp.constructor.name === value.constructor.name) {
801
+ targetProp['copy'](value);
802
+ if (!is.supportColorManagement() && !rootState.linear && isColor) {
803
+ targetProp['convertSRGBToLinear']();
804
+ }
805
+ }
806
+ // If nothing else fits, just set the single value, ignore undefined
807
+ // https://github.com/pmndrs/react-three-fiber/issues/274
808
+ else if (value !== undefined) {
809
+ const isColor = targetProp instanceof THREE.Color;
810
+ // Allow setting array scalars
811
+ if (!isColor && targetProp['setScalar'])
812
+ targetProp['setScalar'](value);
813
+ // Layers have no copy function, we must therefore copy the mask property
814
+ else if (targetProp instanceof THREE.Layers && value instanceof THREE.Layers)
815
+ targetProp.mask = value.mask;
816
+ // Otherwise just set ...
817
+ else
818
+ targetProp['set'](value);
819
+ // For versions of three which don't support THREE.ColorManagement,
820
+ // Auto-convert sRGB colors
821
+ // https://github.com/pmndrs/react-three-fiber/issues/344
822
+ if (!is.supportColorManagement() && !rootState.linear && isColor)
823
+ targetProp.convertSRGBToLinear();
824
+ }
825
+ // Else, just overwrite the value
826
+ }
827
+ else {
828
+ currentInstance[key] = value;
829
+ // Auto-convert sRGB textures, for now ...
830
+ // https://github.com/pmndrs/react-three-fiber/issues/344
831
+ if (!rootState?.linear && currentInstance[key] instanceof THREE.Texture) {
832
+ currentInstance[key]['encoding'] = THREE.sRGBEncoding;
833
+ }
834
+ }
835
+ checkNeedsUpdate(targetProp);
836
+ invalidateInstance(instance);
837
+ }
838
+ if (localState.parentRef &&
839
+ rootState.internal &&
840
+ instance['raycast'] &&
841
+ instanceHandlers !== localState.eventCount) {
842
+ // Pre-emptively remove the instance from the interaction manager
843
+ rootState.removeInteraction(instance['uuid']);
844
+ // Add the instance to the interaction manager only when it has handlers
845
+ if (localState.eventCount)
846
+ rootState.addInteraction(instance);
847
+ }
848
+ return instance;
849
+ }
850
+
851
+ function updateCamera(camera, size) {
852
+ // https://github.com/pmndrs/react-three-fiber/issues/92
853
+ // Do not mess with the camera if it belongs to the user
854
+ if (!camera.manual) {
855
+ if (is.orthographic(camera)) {
856
+ camera.left = size.width / -2;
857
+ camera.right = size.width / 2;
858
+ camera.top = size.height / 2;
859
+ camera.bottom = size.height / -2;
860
+ }
861
+ else {
862
+ camera.aspect = size.width / size.height;
863
+ }
864
+ camera.updateProjectionMatrix();
865
+ // https://github.com/pmndrs/react-three-fiber/issues/178
866
+ // Update matrix world since the renderer is a frame late
867
+ camera.updateMatrixWorld();
868
+ }
869
+ }
870
+ function createDefaultCamera(isOrthographic, size) {
871
+ if (isOrthographic) {
872
+ return new THREE.OrthographicCamera(0, 0, 0, 0, 0.1, 1000);
873
+ }
874
+ return new THREE.PerspectiveCamera(75, size.width / size.height, 0.1, 1000);
875
+ }
876
+
877
+ function createSubs(callback, subs) {
878
+ const sub = { callback };
879
+ subs.add(sub);
880
+ return () => void subs.delete(sub);
881
+ }
882
+ const globalEffects = new Set();
883
+ const globalAfterEffects = new Set();
884
+ const globalTailEffects = new Set();
885
+ /**
886
+ * Adds a global render callback which is called each frame.
887
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addEffect
888
+ */
889
+ const addEffect = (callback) => createSubs(callback, globalEffects);
890
+ /**
891
+ * Adds a global after-render callback which is called each frame.
892
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addAfterEffect
893
+ */
894
+ const addAfterEffect = (callback) => createSubs(callback, globalAfterEffects);
895
+ /**
896
+ * Adds a global callback which is called when rendering stops.
897
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#addTail
898
+ */
899
+ const addTail = (callback) => createSubs(callback, globalTailEffects);
900
+ function run(effects, timestamp) {
901
+ if (!effects.size)
902
+ return;
903
+ for (const { callback } of effects.values()) {
904
+ callback(timestamp);
905
+ }
906
+ }
907
+ function flushGlobalEffects(type, timestamp) {
908
+ switch (type) {
909
+ case 'before':
910
+ return run(globalEffects, timestamp);
911
+ case 'after':
912
+ return run(globalAfterEffects, timestamp);
913
+ case 'tail':
914
+ return run(globalTailEffects, timestamp);
915
+ }
916
+ }
917
+ function render(timestamp, stateFactory, frame) {
918
+ const state = stateFactory();
919
+ // Run local effects
920
+ let delta = state.clock.getDelta();
921
+ // In frameloop='never' mode, clock times are updated using the provided timestamp
922
+ if (state.frameloop === 'never' && typeof timestamp === 'number') {
923
+ delta = timestamp - state.clock.elapsedTime;
924
+ state.clock.oldTime = state.clock.elapsedTime;
925
+ state.clock.elapsedTime = timestamp;
926
+ }
927
+ // Call subscribers (useFrame)
928
+ // subscribers = state.internal.subscribers;
929
+ for (let i = 0; i < state.internal.subscribers.length; i++) {
930
+ const subscriber = state.internal.subscribers[i];
931
+ const object = is.ref(subscriber.obj) ? subscriber.obj.value : subscriber.obj;
932
+ subscriber.callback({ ...state, delta, frame }, object);
933
+ }
934
+ // Render content
935
+ if (!state.internal.priority && state.gl.render)
936
+ state.gl.render(state.scene, state.camera);
937
+ // Decrease frame count
938
+ state.internal.frames = Math.max(0, state.internal.frames - 1);
939
+ return state.frameloop === 'always' ? 1 : state.internal.frames;
940
+ }
941
+ function createLoop(roots) {
942
+ let running = false;
943
+ let repeat;
944
+ let frame;
945
+ let state;
946
+ function loop(timestamp) {
947
+ frame = requestAnimationFrame(loop);
948
+ running = true;
949
+ repeat = 0;
950
+ // Run effects
951
+ flushGlobalEffects('before', timestamp);
952
+ // Render all roots
953
+ for (const root of roots.values()) {
954
+ state = root();
955
+ // If the frameloop is invalidated, do not run another frame
956
+ if (state.internal.active &&
957
+ (state.frameloop === 'always' || state.internal.frames > 0) &&
958
+ !state.gl.xr?.isPresenting) {
959
+ repeat += render(timestamp, root);
960
+ }
961
+ }
962
+ // Run after-effects
963
+ flushGlobalEffects('after', timestamp);
964
+ // Stop the loop if nothing invalidates it
965
+ if (repeat === 0) {
966
+ // Tail call effects, they are called when rendering stops
967
+ flushGlobalEffects('tail', timestamp);
968
+ // Flag end of operation
969
+ running = false;
970
+ return cancelAnimationFrame(frame);
971
+ }
972
+ }
973
+ function invalidate(stateFactory, frames = 1) {
974
+ const stateToInvalidate = stateFactory?.();
975
+ if (!stateToInvalidate)
976
+ return roots.forEach((root) => invalidate(root, frames));
977
+ if (stateToInvalidate.gl.xr?.isPresenting ||
978
+ !stateToInvalidate.internal.active ||
979
+ stateToInvalidate.frameloop === 'never')
980
+ return;
981
+ // Increase frames, do not go higher than 60
982
+ stateToInvalidate.internal.frames = Math.min(60, stateToInvalidate.internal.frames + frames);
983
+ // If the render-loop isn't active, start it
984
+ if (!running) {
985
+ running = true;
986
+ requestAnimationFrame(loop);
987
+ }
988
+ }
989
+ function advance(timestamp, runGlobalEffects = true, stateFactory, frame) {
990
+ if (runGlobalEffects)
991
+ flushGlobalEffects('before', timestamp);
992
+ if (!stateFactory)
993
+ for (const root of roots.values())
994
+ render(timestamp, root);
995
+ else
996
+ render(timestamp, stateFactory, frame);
997
+ if (runGlobalEffects)
998
+ flushGlobalEffects('after', timestamp);
999
+ }
1000
+ return {
1001
+ loop,
1002
+ /**
1003
+ * Invalidates the view, requesting a frame to be rendered. Will globally invalidate unless passed a root's state.
1004
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#invalidate
1005
+ */
1006
+ invalidate,
1007
+ /**
1008
+ * Advances the frameloop and runs render effects, useful for when manually rendering via `frameloop="never"`.
1009
+ * @see https://docs.pmnd.rs/react-three-fiber/api/additional-exports#advance
1010
+ */
1011
+ advance,
1012
+ };
1013
+ }
1014
+
1015
+ function createRenderer(glOptions, canvasElement) {
1016
+ const customRenderer = (typeof glOptions === 'function' ? glOptions(canvasElement) : glOptions);
1017
+ if (customRenderer?.render != null) {
1018
+ return customRenderer;
1019
+ }
1020
+ return new THREE.WebGLRenderer({
1021
+ powerPreference: 'high-performance',
1022
+ canvas: canvasElement,
1023
+ antialias: true,
1024
+ alpha: true,
1025
+ ...(glOptions || {}),
1026
+ });
1027
+ }
1028
+
1029
+ const rootStateMap = new Map();
1030
+ const { invalidate, advance } = createLoop(rootStateMap);
1031
+ const shallowLoose = { objects: 'shallow', strict: false };
1032
+ class NgtStore extends NgtComponentStore {
1033
+ constructor() {
1034
+ super(...arguments);
1035
+ this.parentStore = inject(NgtStore, { optional: true, skipSelf: true });
1036
+ this.zone = inject(NgZone);
1037
+ this.window = injectWindow();
1038
+ this.position = new THREE.Vector3();
1039
+ this.defaultTarget = new THREE.Vector3();
1040
+ this.tempTarget = new THREE.Vector3();
1041
+ this.resize = this.effect(($) => {
1042
+ let oldSize = this.read((s) => s.size);
1043
+ let oldDpr = this.read((s) => s.viewport?.dpr);
1044
+ return $.pipe(tap(() => {
1045
+ const { camera, size, viewport, gl } = this.read();
1046
+ // Resize camera and renderer on changes to size and pixelratio
1047
+ if (size !== oldSize || viewport.dpr !== oldDpr) {
1048
+ oldSize = size;
1049
+ oldDpr = viewport.dpr;
1050
+ // Update camera & renderer
1051
+ updateCamera(camera, size);
1052
+ gl.setPixelRatio(viewport.dpr);
1053
+ gl.setSize(size.width, size.height, size.updateStyle);
1054
+ }
1055
+ }));
1056
+ });
1057
+ this.invalidate = this.effect(tap(() => void this.read((s) => s.invalidate)()));
1058
+ this.isInit = false;
1059
+ this.isConfigured = false;
1060
+ this.addInteraction = (interaction) => {
1061
+ this.write((state) => ({
1062
+ ...state,
1063
+ internal: {
1064
+ ...state.internal,
1065
+ interaction: [...state.internal.interaction, interaction],
1066
+ },
1067
+ }));
1068
+ };
1069
+ this.removeInteraction = (uuid) => {
1070
+ this.write((state) => ({
1071
+ ...state,
1072
+ internal: {
1073
+ ...state.internal,
1074
+ interaction: state.internal.interaction.filter((interaction) => interaction.uuid !== uuid),
1075
+ },
1076
+ }));
1077
+ };
1078
+ this.setPerformanceCurrent = (current) => {
1079
+ this.write((s) => ({ performance: { ...s.performance, current } }));
1080
+ };
1081
+ this.setEvents = (events) => {
1082
+ this.write((s) => ({ events: { ...s.events, ...events } }));
1083
+ };
1084
+ this.setSize = (width, height, top, left, updateStyle) => {
1085
+ const camera = this.read((s) => s.camera);
1086
+ const size = { width, height, top: top || 0, left: left || 0, updateStyle };
1087
+ this.write((state) => ({
1088
+ size,
1089
+ viewport: {
1090
+ ...state.viewport,
1091
+ ...this.getCurrentViewport(camera, this.defaultTarget, size),
1092
+ },
1093
+ }));
1094
+ };
1095
+ this.setCamera = (camera) => {
1096
+ this.write((s) => ({
1097
+ camera,
1098
+ viewport: {
1099
+ ...s.viewport,
1100
+ ...this.getCurrentViewport(camera),
1101
+ },
1102
+ }));
1103
+ this.read((s) => s.cameraRef).set(camera);
1104
+ };
1105
+ this.setDpr = (dpr) => {
1106
+ const resolved = makeDpr(dpr, this.window);
1107
+ this.write((s) => ({
1108
+ viewport: {
1109
+ ...s.viewport,
1110
+ dpr: resolved,
1111
+ initialDpr: s.viewport.initialDpr || resolved,
1112
+ },
1113
+ }));
1114
+ };
1115
+ this.setFrameloop = (frameloop = 'always') => {
1116
+ const clock = this.read((s) => s.clock);
1117
+ // if frameloop === "never" clock.elapsedTime is updated using advance(timestamp)
1118
+ clock.stop();
1119
+ clock.elapsedTime = 0;
1120
+ if (frameloop !== 'never') {
1121
+ clock.start();
1122
+ clock.elapsedTime = 0;
1123
+ }
1124
+ this.write({ frameloop });
1125
+ };
1126
+ this.getCurrentViewport = (camera = this.read((s) => s.camera), target = this.defaultTarget, size = this.read((s) => s.size)) => {
1127
+ const { width, height, top, left } = size;
1128
+ const aspect = width / height;
1129
+ if (target instanceof THREE.Vector3)
1130
+ this.tempTarget.copy(target);
1131
+ else
1132
+ this.tempTarget.set(...target);
1133
+ const distance = camera.getWorldPosition(this.position).distanceTo(this.tempTarget);
1134
+ if (is.orthographic(camera)) {
1135
+ return {
1136
+ width: width / camera.zoom,
1137
+ height: height / camera.zoom,
1138
+ top,
1139
+ left,
1140
+ factor: 1,
1141
+ distance,
1142
+ aspect,
1143
+ };
1144
+ }
1145
+ const fov = (camera.fov * Math.PI) / 180; // convert vertical fov to radians
1146
+ const h = 2 * Math.tan(fov / 2) * distance; // visible height
1147
+ const w = h * (width / height);
1148
+ return {
1149
+ width: w,
1150
+ height: h,
1151
+ top,
1152
+ left,
1153
+ factor: width / w,
1154
+ distance,
1155
+ aspect,
1156
+ };
1157
+ };
1158
+ }
1159
+ get rootStateFactory() {
1160
+ let root = this.read((s) => s.previousStateFactory);
1161
+ while (root && root().previousStateFactory) {
1162
+ root = root().previousStateFactory;
1163
+ }
1164
+ return root || this.read;
1165
+ }
1166
+ init() {
1167
+ if (!this.isInit) {
1168
+ const pointer = new THREE.Vector2();
1169
+ const scene = prepare(new THREE.Scene(), this.read, this.rootStateFactory, this.parentStore?.get((s) => s.sceneRef));
1170
+ let performanceTimeout;
1171
+ this.write({
1172
+ ready: false,
1173
+ cameraRef: new NgtRef(),
1174
+ scene,
1175
+ sceneRef: new NgtRef(scene),
1176
+ events: { priority: 1, enabled: true, connected: false },
1177
+ invalidate: (frames = 1) => invalidate(this.read, frames),
1178
+ advance: (timestamp, runGlobalEffects) => advance(timestamp, runGlobalEffects, this.read),
1179
+ legacy: false,
1180
+ linear: false,
1181
+ flat: false,
1182
+ controls: null,
1183
+ clock: new THREE.Clock(),
1184
+ pointer,
1185
+ frameloop: 'always',
1186
+ performance: {
1187
+ current: 1,
1188
+ min: 0.5,
1189
+ max: 1,
1190
+ debounce: 200,
1191
+ regress: () => {
1192
+ this.zone.runOutsideAngular(() => {
1193
+ const state = this.read();
1194
+ // Clear timeout
1195
+ if (performanceTimeout)
1196
+ clearTimeout(performanceTimeout);
1197
+ // Set lower bound performance
1198
+ if (state.performance.current !== state.performance.min)
1199
+ this.setPerformanceCurrent(state.performance.min);
1200
+ // Go back to upper bound performance after a while unless something regresses meanwhile
1201
+ performanceTimeout = setTimeout(() => this.setPerformanceCurrent(this.read((s) => s.performance)?.max || 1), state.performance.debounce);
1202
+ });
1203
+ },
1204
+ },
1205
+ size: { width: 0, height: 0, top: 0, left: 0, updateStyle: false },
1206
+ viewport: {
1207
+ initialDpr: 0,
1208
+ dpr: 0,
1209
+ width: 0,
1210
+ height: 0,
1211
+ top: 0,
1212
+ left: 0,
1213
+ aspect: 0,
1214
+ distance: 0,
1215
+ factor: 0,
1216
+ getCurrentViewport: this.getCurrentViewport,
1217
+ },
1218
+ previousStateFactory: this.parentStore?.read.bind(this.parentStore),
1219
+ internal: {
1220
+ active: false,
1221
+ priority: 0,
1222
+ frames: 0,
1223
+ lastEvent: null,
1224
+ interaction: [],
1225
+ hovered: new Map(),
1226
+ capturedMap: new Map(),
1227
+ animations: new Map(),
1228
+ subscribers: [],
1229
+ initialClick: [0, 0],
1230
+ initialHits: [],
1231
+ subscribe: (callback, priority = 0, stateFactory = this.read, obj) => {
1232
+ const internal = this.read((s) => s.internal);
1233
+ // If this subscription was given a priority, it takes rendering into its own hands
1234
+ // For that reason we switch off automatic rendering and increase the manual flag
1235
+ // As long as this flag is positive there can be no internal rendering at all
1236
+ // because there could be multiple render subscriptions
1237
+ internal.priority = internal.priority + (priority > 0 ? 1 : 0);
1238
+ internal.subscribers.push({ priority, stateFactory, callback, obj });
1239
+ // Register subscriber and sort layers from lowest to highest, meaning,
1240
+ // highest priority renders last (on top of the other frames)
1241
+ internal.subscribers.sort((a, b) => (a.priority || 0) - (b.priority || 0));
1242
+ return () => {
1243
+ const internalOnCleanUp = this.read((s) => s.internal);
1244
+ if (internalOnCleanUp.subscribers) {
1245
+ // Decrease manual flag if this subscription had a priority
1246
+ internalOnCleanUp.priority = internalOnCleanUp.priority - (priority > 0 ? 1 : 0);
1247
+ // Remove subscriber from list
1248
+ internalOnCleanUp.subscribers = internalOnCleanUp.subscribers.filter((s) => s.callback !== callback);
1249
+ }
1250
+ };
1251
+ },
1252
+ },
1253
+ setPerformanceCurrent: this.setPerformanceCurrent,
1254
+ setEvents: this.setEvents,
1255
+ setFrameloop: this.setFrameloop,
1256
+ setSize: this.setSize,
1257
+ setDpr: this.setDpr,
1258
+ setCamera: this.setCamera,
1259
+ addInteraction: this.addInteraction,
1260
+ removeInteraction: this.removeInteraction,
1261
+ });
1262
+ this.isInit = true;
1263
+ }
1264
+ }
1265
+ configure(inputs, canvasElement) {
1266
+ const { gl: glOptions, size: sizeOptions, camera: cameraOptions, raycaster: raycasterOptions, events, orthographic, lookAt, shadows, linear, flat, legacy, dpr, frameloop, performance, } = inputs;
1267
+ const state = this.read();
1268
+ // Set up renderer (one time only!)
1269
+ let gl = state.gl;
1270
+ if (!state.gl) {
1271
+ this.write({ gl: (gl = createRenderer(glOptions, canvasElement)) });
1272
+ }
1273
+ // Set up raycaster (one time only!)
1274
+ let raycaster = state.raycaster;
1275
+ if (!raycaster) {
1276
+ this.write({ raycaster: (raycaster = new THREE.Raycaster()) });
1277
+ }
1278
+ // Set raycaster options
1279
+ const { params, ...options } = raycasterOptions || {};
1280
+ if (!is.equ(options, raycaster, shallowLoose)) {
1281
+ applyProps(raycaster, { ...options });
1282
+ }
1283
+ if (!is.equ(params, raycaster.params, shallowLoose)) {
1284
+ applyProps(raycaster, {
1285
+ params: { ...raycaster.params, ...(params || {}) },
1286
+ });
1287
+ }
1288
+ // Create default camera (one time only!)
1289
+ if (!state.camera) {
1290
+ const isCamera = is.camera(cameraOptions);
1291
+ let camera = isCamera ? cameraOptions : createDefaultCamera(orthographic, state.size);
1292
+ if (!isCamera) {
1293
+ if (cameraOptions) {
1294
+ applyProps(camera, cameraOptions);
1295
+ }
1296
+ // Set position.z if position not passed in
1297
+ if (!cameraOptions?.position) {
1298
+ camera.position.z = 5;
1299
+ }
1300
+ // Always look at center or passed-in lookAt by default
1301
+ if (!cameraOptions?.rotation) {
1302
+ if (Array.isArray(lookAt)) {
1303
+ camera.lookAt(lookAt[0], lookAt[1], lookAt[2]);
1304
+ }
1305
+ else if (lookAt instanceof THREE.Vector3) {
1306
+ camera.lookAt(lookAt);
1307
+ }
1308
+ else {
1309
+ camera.lookAt(0, 0, 0);
1310
+ }
1311
+ }
1312
+ // Update projection matrix after applying props
1313
+ camera.updateProjectionMatrix();
1314
+ }
1315
+ if (!is.instance(camera)) {
1316
+ camera = prepare(camera, this.read, this.rootStateFactory, this.parentStore?.get((s) => s.cameraRef));
1317
+ }
1318
+ this.write({ camera });
1319
+ this.read((s) => s.cameraRef).set(camera);
1320
+ }
1321
+ // Set up XR (one time only!)
1322
+ if (!state.xr) {
1323
+ // Handle frame behavior in WebXR
1324
+ const handleXRFrame = (timestamp, frame) => {
1325
+ const state = this.read();
1326
+ if (state.frameloop === 'never')
1327
+ return;
1328
+ advance(timestamp, true, this.read, frame);
1329
+ };
1330
+ // Toggle render switching on session
1331
+ const handleSessionChange = () => {
1332
+ const state = this.read();
1333
+ state.gl.xr.enabled = state.gl.xr.isPresenting;
1334
+ state.gl.xr.setAnimationLoop(state.gl.xr.isPresenting ? handleXRFrame : null);
1335
+ if (!state.gl.xr.isPresenting)
1336
+ invalidate(this.read);
1337
+ };
1338
+ // WebXR session manager
1339
+ const xr = {
1340
+ connect: () => {
1341
+ const gl = this.read((s) => s.gl);
1342
+ gl.xr.addEventListener('sessionstart', handleSessionChange);
1343
+ gl.xr.addEventListener('sessionend', handleSessionChange);
1344
+ },
1345
+ disconnect: () => {
1346
+ const gl = this.read((s) => s.gl);
1347
+ gl.xr.removeEventListener('sessionstart', handleSessionChange);
1348
+ gl.xr.removeEventListener('sessionend', handleSessionChange);
1349
+ },
1350
+ };
1351
+ // Subscribe to WebXR session events
1352
+ if (gl.xr)
1353
+ xr.connect();
1354
+ this.write({ xr });
1355
+ }
1356
+ // Set shadowmap
1357
+ if (gl.shadowMap) {
1358
+ const isBoolean = typeof shadows === 'boolean';
1359
+ if ((isBoolean && gl.shadowMap.enabled !== shadows) || !is.equ(shadows, gl.shadowMap, shallowLoose)) {
1360
+ const old = gl.shadowMap.enabled;
1361
+ gl.shadowMap.enabled = !!shadows;
1362
+ if (!isBoolean)
1363
+ Object.assign(gl.shadowMap, shadows);
1364
+ else
1365
+ gl.shadowMap.type = THREE.PCFSoftShadowMap;
1366
+ if (old !== gl.shadowMap.enabled)
1367
+ checkNeedsUpdate(gl.shadowMap);
1368
+ }
1369
+ }
1370
+ // Safely set color management if available.
1371
+ // Avoid accessing THREE.ColorManagement to play nice with older versions
1372
+ if (is.supportColorManagement()) {
1373
+ THREE.ColorManagement.legacyMode = state.legacy;
1374
+ }
1375
+ const outputEncoding = linear ? THREE.LinearEncoding : THREE.sRGBEncoding;
1376
+ const toneMapping = flat ? THREE.NoToneMapping : THREE.ACESFilmicToneMapping;
1377
+ if (gl.outputEncoding !== outputEncoding)
1378
+ gl.outputEncoding = outputEncoding;
1379
+ if (gl.toneMapping !== toneMapping)
1380
+ gl.toneMapping = toneMapping;
1381
+ // Update color management state
1382
+ if (state.legacy !== legacy)
1383
+ this.write({ legacy });
1384
+ if (state.linear !== linear)
1385
+ this.write({ linear });
1386
+ if (state.flat !== flat)
1387
+ this.write({ flat });
1388
+ // Set gl props
1389
+ gl.setClearAlpha(0);
1390
+ gl.setPixelRatio(makeDpr(state.viewport.dpr));
1391
+ gl.setSize(state.size.width, state.size.height, state.size.updateStyle);
1392
+ if (is.obj(glOptions) &&
1393
+ !(typeof glOptions === 'function') &&
1394
+ !is.glRenderer(glOptions) &&
1395
+ !is.equ(glOptions, gl, shallowLoose)) {
1396
+ applyProps(gl, glOptions);
1397
+ }
1398
+ // Store events internally
1399
+ if (events && !state.events.handlers) {
1400
+ this.write({ events: events(this.read) });
1401
+ }
1402
+ // Check pixelratio
1403
+ if (dpr && state.viewport.dpr !== makeDpr(dpr)) {
1404
+ state.setDpr(dpr);
1405
+ }
1406
+ // Check size, allow it to take on container bounds initially
1407
+ const size = computeInitialSize(canvasElement, sizeOptions);
1408
+ if (!is.equ(size, state.size, shallowLoose)) {
1409
+ state.setSize(size.width, size.height, size.top, size.left);
1410
+ }
1411
+ // Check frameloop
1412
+ if (state.frameloop !== frameloop)
1413
+ state.setFrameloop(frameloop);
1414
+ // Check performance
1415
+ if (performance && !is.equ(performance, state.performance, shallowLoose)) {
1416
+ this.write((state) => ({
1417
+ performance: { ...state.performance, ...performance },
1418
+ }));
1419
+ }
1420
+ this.write({ ready: true });
1421
+ this.resize(this.select(this.select((s) => s.size), this.select((s) => s.viewport.dpr), defaultProjector, { debounce: true }));
1422
+ this.invalidate(this.select((s) => s, { debounce: true }));
1423
+ this.zone.run(() => {
1424
+ this.isConfigured = true;
1425
+ });
1426
+ }
1427
+ onReady(cb) {
1428
+ return this.effect(tapEffect(cb))(this.select((s) => s.ready).pipe(filter((ready) => ready)));
1429
+ }
1430
+ }
1431
+ NgtStore.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtStore, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
1432
+ NgtStore.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtStore });
1433
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtStore, decorators: [{
1434
+ type: Injectable
1435
+ }] });
1436
+ function computeInitialSize(canvas, defaultSize) {
1437
+ if (defaultSize) {
1438
+ return defaultSize;
1439
+ }
1440
+ if (is.canvas(canvas) && canvas.parentElement) {
1441
+ const { width, height, top, left } = canvas.parentElement.getBoundingClientRect();
1442
+ return { width, height, top, left };
1443
+ }
1444
+ return { width: 0, height: 0, top: 0, left: 0 };
1445
+ }
1446
+
1447
+ function mutate(object, value, paths = []) {
1448
+ const [base, ...remaining] = paths;
1449
+ if (!base)
1450
+ return;
1451
+ if (remaining.length === 0) {
1452
+ applyProps(object, { [base]: value });
1453
+ }
1454
+ else {
1455
+ // assign an empty object in order to spread object if undefined
1456
+ assignEmpty(object, base);
1457
+ // recursion
1458
+ mutate(object[base], value, remaining);
1459
+ }
1460
+ }
1461
+ function assignEmpty(obj, base) {
1462
+ if (
1463
+ // @ts-ignore
1464
+ (!Object.hasOwn(obj, base) && Reflect && !!Reflect.has && !Reflect.has(obj, base)) ||
1465
+ obj[base] === undefined) {
1466
+ obj[base] = {};
1467
+ }
1468
+ }
1469
+
1470
+ const NGT_PROXY_INSTANCE = Symbol.for('__ngt__proxy__instance__');
1471
+ const NGT_INSTANCE_REF_FACTORY = new InjectionToken('NgtInstance[instanceRef] factory');
1472
+ function provideInstanceRef(ctor, factory) {
1473
+ return {
1474
+ provide: NGT_INSTANCE_REF_FACTORY,
1475
+ useFactory: (instance) => {
1476
+ if (factory) {
1477
+ return () => factory(instance);
1478
+ }
1479
+ return () => instance['instanceRef'] || instance['instance']['instanceRef'];
1480
+ },
1481
+ deps: [ctor],
1482
+ };
1483
+ }
1484
+ function injectInstanceRef(options = {}) {
1485
+ return inject(NGT_INSTANCE_REF_FACTORY, options);
1486
+ }
1487
+ function injectInstance(options = {}) {
1488
+ return inject(NgtInstance, options);
1489
+ }
1490
+ const supportedEvents = [
1491
+ 'click',
1492
+ 'contextmenu',
1493
+ 'dblclick',
1494
+ 'pointerup',
1495
+ 'pointerdown',
1496
+ 'pointerover',
1497
+ 'pointerout',
1498
+ 'pointerenter',
1499
+ 'pointerleave',
1500
+ 'pointermove',
1501
+ 'pointermissed',
1502
+ 'pointercancel',
1503
+ 'wheel',
1504
+ ];
1505
+ class NgtInstance extends NgtComponentStore {
1506
+ constructor() {
1507
+ super(...arguments);
1508
+ this.priority = 0;
1509
+ this.click = new EventEmitter();
1510
+ this.contextmenu = new EventEmitter();
1511
+ this.dblclick = new EventEmitter();
1512
+ this.pointerup = new EventEmitter();
1513
+ this.pointerdown = new EventEmitter();
1514
+ this.pointerover = new EventEmitter();
1515
+ this.pointerout = new EventEmitter();
1516
+ this.pointerenter = new EventEmitter();
1517
+ this.pointerleave = new EventEmitter();
1518
+ this.pointermove = new EventEmitter();
1519
+ this.pointermissed = new EventEmitter();
1520
+ this.pointercancel = new EventEmitter();
1521
+ this.wheel = new EventEmitter();
1522
+ this.zone = inject(NgZone);
1523
+ this.store = inject(NgtStore);
1524
+ this.parentRef = injectInstanceRef({ skipSelf: true, optional: true });
1525
+ this._isRaw = false;
1526
+ this.hasEmittedAlready = false;
1527
+ this.instanceReady = this.effect(tapEffect(() => {
1528
+ this.handleEvents();
1529
+ let attachToParentSubscription;
1530
+ if (this.parentRef) {
1531
+ attachToParentSubscription = this.attachToParent(this.parent.pipe(filter((parent) => !!parent)));
1532
+ }
1533
+ let beforeRenderCleanUp;
1534
+ if (this.beforeRender && is.object3d(this.instanceValue) && is.object3d(this.proxyInstance)) {
1535
+ beforeRenderCleanUp = this.store
1536
+ .read((s) => s.internal)
1537
+ .subscribe((state, object) => this.beforeRender(state, object), this.priority, this.store.read, this.proxyInstance);
1538
+ }
1539
+ if (this.readyCallback)
1540
+ this.readyCallback(this.instanceValue);
1541
+ return () => {
1542
+ beforeRenderCleanUp?.();
1543
+ attachToParentSubscription?.unsubscribe();
1544
+ };
1545
+ }));
1546
+ this.handleEvents = this.effect(tapEffect(() => {
1547
+ if (this.instanceValue && is.object3d(this.instanceValue)) {
1548
+ const observedEvents = supportedEvents.reduce((result, event) => {
1549
+ const controllerEvent = this[event].observed ? this[event] : null;
1550
+ if (controllerEvent) {
1551
+ result.handlers[event] = this.eventNameToHandler(controllerEvent);
1552
+ result.eventCount += 1;
1553
+ }
1554
+ return result;
1555
+ }, { handlers: {}, eventCount: 0 });
1556
+ // patch __ngt__ with events
1557
+ applyProps(this.__ngt__, observedEvents);
1558
+ // add as an interaction if there are events observed
1559
+ if (observedEvents.eventCount > 0) {
1560
+ getInstanceLocalState(this.instanceValue)?.rootFactory().addInteraction(this.instanceValue);
1561
+ }
1562
+ }
1563
+ return () => {
1564
+ if (is.object3d(this.instanceValue) && this.__ngt__.eventCount > 0) {
1565
+ getInstanceLocalState(this.instanceValue)?.rootFactory().removeInteraction(this.instanceValue.uuid);
1566
+ }
1567
+ };
1568
+ }));
1569
+ this.attachToParent = this.effect(tap(() => {
1570
+ const attach = this.read((s) => s.attach);
1571
+ let parentInstanceRef = this.__ngt__?.parentRef;
1572
+ // if no parentInstance, try re-run the factory due to late init
1573
+ if (!parentInstanceRef || !parentInstanceRef.value) {
1574
+ // return early if failed to retrieve
1575
+ if (!this.parent?.value)
1576
+ return;
1577
+ // reassign on instance internal state
1578
+ if (this.__ngt__) {
1579
+ this.__ngt__.parentRef = this.parent;
1580
+ }
1581
+ parentInstanceRef = this.parent;
1582
+ }
1583
+ if (typeof attach === 'function') {
1584
+ const attachCleanUp = attach(parentInstanceRef, this.instanceRef, this.store.read);
1585
+ if (attachCleanUp) {
1586
+ this.__ngt__.attach = attachCleanUp;
1587
+ }
1588
+ }
1589
+ else {
1590
+ const propertyToAttach = [...attach];
1591
+ // if propertyToAttach is empty
1592
+ if (propertyToAttach.length === 0) {
1593
+ // this might be the case where we are attaching an object3D to the parent object3D
1594
+ if (is.object3d(this.instanceValue) &&
1595
+ is.object3d(this.proxyInstance) &&
1596
+ is.object3d(this.parent?.value)) {
1597
+ this.parent?.value.add(this.proxyInstance);
1598
+ }
1599
+ }
1600
+ else {
1601
+ // array material handling
1602
+ if (propertyToAttach[0] === 'material' &&
1603
+ propertyToAttach[1] &&
1604
+ typeof Number(propertyToAttach[1]) === 'number' &&
1605
+ is.material(this.instanceValue)) {
1606
+ if (!Array.isArray(parentInstanceRef.value.material)) {
1607
+ parentInstanceRef.value.material = [];
1608
+ }
1609
+ }
1610
+ // retrieve the current value on the parentInstance, so we can reset it later
1611
+ if (this.__ngt__) {
1612
+ this.__ngt__.attachValue = propertyToAttach.reduce((value, property) => value[property], parentInstanceRef.value);
1613
+ }
1614
+ // attach the instance value on the parent
1615
+ mutate(parentInstanceRef.value, this.proxyInstance, propertyToAttach);
1616
+ }
1617
+ // validate on the instance
1618
+ invalidateInstance(this.instanceValue);
1619
+ // validate on the parent
1620
+ if (getInstanceLocalState(parentInstanceRef.value)) {
1621
+ invalidateInstance(parentInstanceRef.value);
1622
+ }
1623
+ // save the attach
1624
+ if (this.__ngt__) {
1625
+ this.__ngt__.attach = propertyToAttach;
1626
+ }
1627
+ this.write({ attach: propertyToAttach });
1628
+ }
1629
+ }));
1630
+ }
1631
+ set ref(instance) {
1632
+ this.write({ instanceRef: is.ref(instance) ? instance : new NgtRef(instance) });
1633
+ }
1634
+ set skipWrapper(skipWrapper) {
1635
+ this.write({ skipWrapper });
1636
+ this.write({ skipWrapperExplicit: true });
1637
+ }
1638
+ set skipInit(skipInit) {
1639
+ this.write({ skipInit });
1640
+ this.write({ skipInitExplicit: true });
1641
+ }
1642
+ set noAttach(noAttach) {
1643
+ this.write({ noAttach });
1644
+ this.write({ noAttachExplicit: true });
1645
+ }
1646
+ set attach(value) {
1647
+ if (value) {
1648
+ const attach = typeof value === 'function'
1649
+ ? value
1650
+ : Array.isArray(value)
1651
+ ? value.map((item) => (typeof item === 'number' ? item.toString() : item))
1652
+ : [value];
1653
+ this.write({ attach, attachExplicit: true });
1654
+ }
1655
+ }
1656
+ set isRaw(val) {
1657
+ this._isRaw = val;
1658
+ }
1659
+ initialize() {
1660
+ super.initialize();
1661
+ this.write({
1662
+ instanceRef: new NgtRef(null),
1663
+ attach: [],
1664
+ noAttach: false,
1665
+ skipWrapper: false,
1666
+ skipInit: false,
1667
+ });
1668
+ }
1669
+ ngOnInit() {
1670
+ this.zone.runOutsideAngular(() => {
1671
+ this.store.onReady(() => {
1672
+ this.instanceReady(this.instanceRef.pipe(filter((instance) => !!instance)));
1673
+ });
1674
+ });
1675
+ }
1676
+ get instanceRef() {
1677
+ return this.read((s) => s.instanceRef);
1678
+ }
1679
+ get instanceValue() {
1680
+ if (!this.instanceRef.value)
1681
+ return this.instanceRef.value;
1682
+ return this._isRaw ? this.instanceRef.value?.valueOf() : this.instanceRef.value;
1683
+ }
1684
+ get proxyInstance() {
1685
+ return this.instanceValue?.[NGT_PROXY_INSTANCE];
1686
+ }
1687
+ get __ngt__() {
1688
+ return getInstanceLocalState(this._isRaw ? this.instanceRef.value : this.instanceValue);
1689
+ }
1690
+ get parent() {
1691
+ return this.parentRef?.();
1692
+ }
1693
+ ngOnDestroy() {
1694
+ this.zone.runOutsideAngular(() => {
1695
+ this.destroy();
1696
+ });
1697
+ super.ngOnDestroy();
1698
+ }
1699
+ destroy() {
1700
+ if (this.instanceValue) {
1701
+ if (is.object3d(this.instanceValue)) {
1702
+ const parentInstance = this.parent;
1703
+ if (parentInstance && is.object3d(parentInstance.value)) {
1704
+ removeInteractivity(this.__ngt__.stateFactory.bind(this.__ngt__), this.instanceValue);
1705
+ parentInstance.value.remove(this.instanceValue);
1706
+ invalidateInstance(parentInstance.value);
1707
+ }
1708
+ if (this.instanceValue.clear != null) {
1709
+ this.instanceValue.clear();
1710
+ }
1711
+ }
1712
+ else {
1713
+ if (this.__ngt__) {
1714
+ // non-scene objects
1715
+ const previousAttach = this.__ngt__.attach;
1716
+ if (previousAttach != null) {
1717
+ if (typeof previousAttach === 'function') {
1718
+ previousAttach();
1719
+ }
1720
+ else {
1721
+ const previousAttachValue = this.__ngt__.attachValue;
1722
+ if (this.__ngt__.parentRef && this.__ngt__.parentRef.value) {
1723
+ mutate(this.__ngt__.parentRef.value, previousAttachValue, previousAttach);
1724
+ }
1725
+ }
1726
+ if (this.__ngt__.parentRef && this.__ngt__.parentRef.value) {
1727
+ invalidateInstance(this.__ngt__.parentRef.value);
1728
+ }
1729
+ }
1730
+ }
1731
+ }
1732
+ const dispose = this.instanceValue['dispose'];
1733
+ if (dispose && typeof dispose === 'function') {
1734
+ dispose.apply(this.instanceValue);
1735
+ }
1736
+ }
1737
+ this.write({ attach: [] });
1738
+ this.instanceRef.complete();
1739
+ }
1740
+ eventNameToHandler(controllerEvent) {
1741
+ return (event) => {
1742
+ // go back into Angular Zone so that state updates on these events trigger CD
1743
+ this.zone.run(() => {
1744
+ controllerEvent.emit(event);
1745
+ });
1746
+ };
1747
+ }
1748
+ }
1749
+ NgtInstance.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtInstance, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1750
+ NgtInstance.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: NgtInstance, isStandalone: true, selector: "[ngtInstance]", inputs: { ref: "ref", skipWrapper: "skipWrapper", skipInit: "skipInit", noAttach: "noAttach", attach: "attach", priority: "priority", beforeRender: "beforeRender", readyCallback: "readyCallback", updateCallback: "updateCallback" }, outputs: { click: "click", contextmenu: "contextmenu", dblclick: "dblclick", pointerup: "pointerup", pointerdown: "pointerdown", pointerover: "pointerover", pointerout: "pointerout", pointerenter: "pointerenter", pointerleave: "pointerleave", pointermove: "pointermove", pointermissed: "pointermissed", pointercancel: "pointercancel", wheel: "wheel" }, exportAs: ["ngtInstance"], usesInheritance: true, ngImport: i0 });
1751
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtInstance, decorators: [{
1752
+ type: Directive,
12
1753
  args: [{
13
- imports: [CommonModule],
1754
+ selector: '[ngtInstance]',
1755
+ exportAs: 'ngtInstance',
1756
+ standalone: true,
14
1757
  }]
1758
+ }], propDecorators: { ref: [{
1759
+ type: Input
1760
+ }], skipWrapper: [{
1761
+ type: Input
1762
+ }], skipInit: [{
1763
+ type: Input
1764
+ }], noAttach: [{
1765
+ type: Input
1766
+ }], attach: [{
1767
+ type: Input
1768
+ }], priority: [{
1769
+ type: Input
1770
+ }], beforeRender: [{
1771
+ type: Input
1772
+ }], readyCallback: [{
1773
+ type: Input
1774
+ }], updateCallback: [{
1775
+ type: Input
1776
+ }], click: [{
1777
+ type: Output
1778
+ }], contextmenu: [{
1779
+ type: Output
1780
+ }], dblclick: [{
1781
+ type: Output
1782
+ }], pointerup: [{
1783
+ type: Output
1784
+ }], pointerdown: [{
1785
+ type: Output
1786
+ }], pointerover: [{
1787
+ type: Output
1788
+ }], pointerout: [{
1789
+ type: Output
1790
+ }], pointerenter: [{
1791
+ type: Output
1792
+ }], pointerleave: [{
1793
+ type: Output
1794
+ }], pointermove: [{
1795
+ type: Output
1796
+ }], pointermissed: [{
1797
+ type: Output
1798
+ }], pointercancel: [{
1799
+ type: Output
1800
+ }], wheel: [{
1801
+ type: Output
1802
+ }] } });
1803
+ const NGT_INSTANCE_INPUTS = [
1804
+ 'ref',
1805
+ 'attach',
1806
+ 'skipWrapper',
1807
+ 'skipInit',
1808
+ 'noAttach',
1809
+ 'beforeRender',
1810
+ 'priority',
1811
+ 'updateCallback',
1812
+ 'readyCallback',
1813
+ ];
1814
+ const NGT_INSTANCE_OUTPUTS = [...supportedEvents];
1815
+
1816
+ const defaultResizeOptions = {
1817
+ box: 'content-box',
1818
+ scroll: false,
1819
+ offsetSize: false,
1820
+ debounce: { scroll: 50, resize: 0 },
1821
+ };
1822
+ const [injectResizeOptions, provideResizeOptions] = createInjection('ngtResize Options', {
1823
+ defaultValueOrFactory: defaultResizeOptions,
1824
+ provideValueFactory: (value) => ({ ...defaultResizeOptions, ...value }),
1825
+ });
1826
+ const [injectResizeObserverSupport] = createInjection('Resize Observer API support', {
1827
+ defaultValueOrFactory: () => {
1828
+ const window = injectWindow();
1829
+ return 'ResizeObserver' in window && window['ResizeObserver'] != null;
1830
+ },
1831
+ });
1832
+
1833
+ class NgtResize extends Observable {
1834
+ constructor() {
1835
+ const { nativeElement } = inject(ElementRef);
1836
+ const zone = inject(NgZone);
1837
+ const document = inject(DOCUMENT);
1838
+ const window = injectWindow();
1839
+ const isSupport = injectResizeObserverSupport();
1840
+ const { box, offsetSize, scroll, debounce } = injectResizeOptions();
1841
+ let observer;
1842
+ let lastBounds;
1843
+ let lastEntries = [];
1844
+ const torndown$ = new Subject();
1845
+ const scrollContainers = findScrollContainers(nativeElement, document.body);
1846
+ // set actual debounce values early, so effects know if they should react accordingly
1847
+ const scrollDebounce = debounce ? (typeof debounce === 'number' ? debounce : debounce.scroll) : null;
1848
+ const resizeDebounce = debounce ? (typeof debounce === 'number' ? debounce : debounce.resize) : null;
1849
+ const debounceAndDestroy = (debounce) => {
1850
+ return pipe(debounceTime(debounce ?? 0), takeUntil(torndown$));
1851
+ };
1852
+ super((subscriber) => {
1853
+ if (!isSupport) {
1854
+ subscriber.error('ResizeObserver is not supported in your browser. Please use a polyfill');
1855
+ return;
1856
+ }
1857
+ zone.runOutsideAngular(() => {
1858
+ const callback = (entries) => {
1859
+ lastEntries = entries;
1860
+ const { left, top, width, height, bottom, right, x, y } = nativeElement.getBoundingClientRect();
1861
+ const size = {
1862
+ left,
1863
+ top,
1864
+ width,
1865
+ height,
1866
+ bottom,
1867
+ right,
1868
+ x,
1869
+ y,
1870
+ };
1871
+ if (nativeElement instanceof HTMLElement && offsetSize) {
1872
+ size.height = nativeElement.offsetHeight;
1873
+ size.width = nativeElement.offsetWidth;
1874
+ }
1875
+ Object.freeze(size);
1876
+ subscriber.next({
1877
+ entries,
1878
+ dpr: window.devicePixelRatio,
1879
+ ...size,
1880
+ });
1881
+ if (!areBoundsEqual(lastBounds || {}, size)) {
1882
+ lastBounds = size;
1883
+ }
1884
+ };
1885
+ const boundEntriesCallback = () => {
1886
+ callback(lastEntries);
1887
+ };
1888
+ observer = new ResizeObserver(callback);
1889
+ observer.observe(nativeElement, { box });
1890
+ if (scroll) {
1891
+ if (scrollContainers) {
1892
+ scrollContainers.forEach((scrollContainer) => {
1893
+ fromEvent(scrollContainer, 'scroll', {
1894
+ capture: true,
1895
+ passive: true,
1896
+ })
1897
+ .pipe(debounceAndDestroy(scrollDebounce))
1898
+ .subscribe(boundEntriesCallback);
1899
+ });
1900
+ }
1901
+ fromEvent(window, 'scroll', {
1902
+ capture: true,
1903
+ passive: true,
1904
+ })
1905
+ .pipe(debounceAndDestroy(scrollDebounce))
1906
+ .subscribe(boundEntriesCallback);
1907
+ }
1908
+ fromEvent(window, 'resize').pipe(debounceAndDestroy(resizeDebounce)).subscribe(boundEntriesCallback);
1909
+ });
1910
+ return () => {
1911
+ if (observer) {
1912
+ observer.unobserve(nativeElement);
1913
+ observer.disconnect();
1914
+ }
1915
+ torndown$.next();
1916
+ torndown$.complete();
1917
+ };
1918
+ });
1919
+ return this.pipe(debounceTime(scrollDebounce || 0), share({
1920
+ connector: () => new ReplaySubject(1),
1921
+ resetOnRefCountZero: true,
1922
+ resetOnComplete: true,
1923
+ }));
1924
+ }
1925
+ }
1926
+ NgtResize.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtResize, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1927
+ NgtResize.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtResize });
1928
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtResize, decorators: [{
1929
+ type: Injectable
1930
+ }], ctorParameters: function () { return []; } });
1931
+ // Returns a list of scroll offsets
1932
+ function findScrollContainers(element, documentBody) {
1933
+ const result = [];
1934
+ if (!element || element === documentBody)
1935
+ return result;
1936
+ const { overflow, overflowX, overflowY } = window.getComputedStyle(element);
1937
+ if ([overflow, overflowX, overflowY].some((prop) => prop === 'auto' || prop === 'scroll'))
1938
+ result.push(element);
1939
+ return [...result, ...findScrollContainers(element.parentElement, documentBody)];
1940
+ }
1941
+ // Checks if element boundaries are equal
1942
+ const keys = [
1943
+ 'x',
1944
+ 'y',
1945
+ 'top',
1946
+ 'bottom',
1947
+ 'left',
1948
+ 'right',
1949
+ 'width',
1950
+ 'height',
1951
+ ];
1952
+ const areBoundsEqual = (a, b) => keys.every((key) => a[key] === b[key]);
1953
+
1954
+ function buildGraph(object) {
1955
+ const data = { nodes: {}, materials: {} };
1956
+ if (object) {
1957
+ object.traverse((obj) => {
1958
+ if (obj.name)
1959
+ data.nodes[obj.name] = obj;
1960
+ if ('material' in obj && !data.materials[obj.material.name]) {
1961
+ data.materials[obj.material.name] = obj
1962
+ .material;
1963
+ }
1964
+ });
1965
+ }
1966
+ return data;
1967
+ }
1968
+
1969
+ class NgtLoader {
1970
+ constructor() {
1971
+ this.cached = new Map();
1972
+ }
1973
+ use(loadConstructor, input, extensions, onProgress) {
1974
+ const urls = Array.isArray(input) ? input : [input];
1975
+ const loader = new loadConstructor();
1976
+ if (extensions) {
1977
+ extensions(loader);
1978
+ }
1979
+ const observables$ = urls.map((url) => {
1980
+ if (!this.cached.has(url)) {
1981
+ this.cached.set(url, from(loader.loadAsync(url, onProgress)).pipe(tap((data) => {
1982
+ if (data.scene) {
1983
+ Object.assign(data, buildGraph(data.scene));
1984
+ }
1985
+ }), retry(2), catchError((err) => {
1986
+ console.error(`[NgtLoader]: Error loading ${url}: ${err.message}`);
1987
+ return of(null);
1988
+ }), share({
1989
+ connector: () => new ReplaySubject(1),
1990
+ resetOnComplete: true,
1991
+ resetOnRefCountZero: true,
1992
+ resetOnError: true,
1993
+ })));
1994
+ }
1995
+ return this.cached.get(url);
1996
+ });
1997
+ return forkJoin(observables$).pipe(map((results) => (Array.isArray(input) ? results : results[0])));
1998
+ }
1999
+ destroy() {
2000
+ this.cached.clear();
2001
+ }
2002
+ }
2003
+ NgtLoader.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
2004
+ NgtLoader.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtLoader, providedIn: 'root' });
2005
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtLoader, decorators: [{
2006
+ type: Injectable,
2007
+ args: [{ providedIn: 'root' }]
15
2008
  }] });
16
2009
 
2010
+ class NgtCanvasContainer {
2011
+ constructor() {
2012
+ this.resize = inject(NgtResize);
2013
+ }
2014
+ }
2015
+ NgtCanvasContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtCanvasContainer, deps: [], target: i0.ɵɵFactoryTarget.Component });
2016
+ NgtCanvasContainer.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: NgtCanvasContainer, isStandalone: true, selector: "ngt-canvas-container", outputs: { resize: "resize" }, providers: [NgtResize], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, styles: [":host{display:block;height:100%;width:100%}\n"] });
2017
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtCanvasContainer, decorators: [{
2018
+ type: Component,
2019
+ args: [{ selector: 'ngt-canvas-container', standalone: true, template: '<ng-content></ng-content>', providers: [NgtResize], styles: [":host{display:block;height:100%;width:100%}\n"] }]
2020
+ }], propDecorators: { resize: [{
2021
+ type: Output
2022
+ }] } });
2023
+ class NgtCanvas extends NgtComponentStore {
2024
+ constructor() {
2025
+ super(...arguments);
2026
+ this.hostClass = true;
2027
+ this.created = new EventEmitter();
2028
+ this.canvasPointerMissed = new EventEmitter();
2029
+ this.zone = inject(NgZone);
2030
+ this.loader = inject(NgtLoader);
2031
+ this.store = inject(NgtStore, { self: true });
2032
+ this.host = inject(ElementRef);
2033
+ }
2034
+ get pointerEvents() {
2035
+ return this.read((s) => s.eventSource) !== this.host.nativeElement ? 'none' : 'auto';
2036
+ }
2037
+ set linear(linear) {
2038
+ this.write({ linear });
2039
+ }
2040
+ set legacy(legacy) {
2041
+ this.write({ legacy });
2042
+ }
2043
+ set flat(flat) {
2044
+ this.write({ flat });
2045
+ }
2046
+ set orthographic(orthographic) {
2047
+ this.write({ orthographic });
2048
+ }
2049
+ set frameloop(frameloop) {
2050
+ this.write({ frameloop });
2051
+ }
2052
+ set dpr(dpr) {
2053
+ this.write({ dpr });
2054
+ }
2055
+ set raycaster(raycaster) {
2056
+ this.write({ raycaster });
2057
+ }
2058
+ set shadows(shadows) {
2059
+ this.write({
2060
+ shadows: typeof shadows === 'object' ? shadows : shadows,
2061
+ });
2062
+ }
2063
+ set camera(camera) {
2064
+ this.write({ camera });
2065
+ }
2066
+ set gl(gl) {
2067
+ this.write({ gl });
2068
+ }
2069
+ set eventSource(eventSource) {
2070
+ this.write({ eventSource });
2071
+ }
2072
+ set eventPrefix(eventPrefix) {
2073
+ this.write({ eventPrefix });
2074
+ }
2075
+ set lookAt(lookAt) {
2076
+ this.write({ lookAt });
2077
+ }
2078
+ set performance(performance) {
2079
+ this.write({ performance });
2080
+ }
2081
+ get sceneRef() {
2082
+ return this.store.read((s) => s.sceneRef);
2083
+ }
2084
+ get isConfigured() {
2085
+ return this.store.isConfigured;
2086
+ }
2087
+ initialize() {
2088
+ super.initialize();
2089
+ this.write({
2090
+ shadows: false,
2091
+ linear: false,
2092
+ flat: false,
2093
+ legacy: false,
2094
+ orthographic: false,
2095
+ frameloop: 'always',
2096
+ dpr: [1, 2],
2097
+ events: createPointerEvents,
2098
+ });
2099
+ }
2100
+ ngOnInit() {
2101
+ this.zone.runOutsideAngular(() => {
2102
+ if (!this.eventSource) {
2103
+ this.eventSource = this.host.nativeElement;
2104
+ }
2105
+ if (this.canvasPointerMissed.observed) {
2106
+ // update pointerMissed event
2107
+ this.store.write({
2108
+ onPointerMissed: (event) => {
2109
+ // go back into angular zone
2110
+ this.zone.run(() => {
2111
+ this.canvasPointerMissed.emit(event);
2112
+ });
2113
+ },
2114
+ });
2115
+ }
2116
+ // set rootStateMap
2117
+ rootStateMap.set(this.glCanvas.nativeElement, this.store.read);
2118
+ // setup canvas state
2119
+ this.store.init();
2120
+ this.store.onReady(() => {
2121
+ const state = this.store.read();
2122
+ const inputs = this.read();
2123
+ // canvas is ready
2124
+ this.store.write((s) => ({ internal: { ...s.internal, active: true } }));
2125
+ // Connect to eventsource
2126
+ state.events.connect?.(inputs.eventSource instanceof ElementRef ? inputs.eventSource.nativeElement : inputs.eventSource);
2127
+ // Set up compute function
2128
+ if (inputs.eventPrefix) {
2129
+ state.setEvents({
2130
+ compute: (event, stateGetter) => {
2131
+ const innerState = stateGetter();
2132
+ const x = event[(inputs.eventPrefix + 'X')];
2133
+ const y = event[(inputs.eventPrefix + 'Y')];
2134
+ innerState.pointer.set((x / innerState.size.width) * 2 - 1, -(y / innerState.size.height) * 2 + 1);
2135
+ innerState.raycaster.setFromCamera(innerState.pointer, innerState.camera);
2136
+ },
2137
+ });
2138
+ }
2139
+ if (this.created.observed) {
2140
+ this.zone.run(() => {
2141
+ this.created.emit(this.store.read());
2142
+ });
2143
+ }
2144
+ });
2145
+ });
2146
+ }
2147
+ onResize(resizeResult) {
2148
+ this.zone.runOutsideAngular(() => {
2149
+ const { width, height } = resizeResult;
2150
+ if (width > 0 && height > 0) {
2151
+ if (!this.store.isInit) {
2152
+ this.store.init();
2153
+ }
2154
+ this.store.configure(this.read(), this.glCanvas.nativeElement);
2155
+ }
2156
+ });
2157
+ }
2158
+ ngOnDestroy() {
2159
+ this.loader.destroy();
2160
+ super.ngOnDestroy();
2161
+ }
2162
+ }
2163
+ NgtCanvas.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtCanvas, deps: null, target: i0.ɵɵFactoryTarget.Component });
2164
+ NgtCanvas.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.0", type: NgtCanvas, isStandalone: true, selector: "ngt-canvas", inputs: { linear: "linear", legacy: "legacy", flat: "flat", orthographic: "orthographic", frameloop: "frameloop", dpr: "dpr", raycaster: "raycaster", shadows: "shadows", camera: "camera", gl: "gl", eventSource: "eventSource", eventPrefix: "eventPrefix", lookAt: "lookAt", performance: "performance" }, outputs: { created: "created", canvasPointerMissed: "canvasPointerMissed" }, host: { properties: { "class.ngt-canvas": "this.hostClass", "style.pointerEvents": "this.pointerEvents" } }, providers: [NgtStore, provideInstanceRef(NgtCanvas, (canvas) => canvas.sceneRef)], queries: [{ propertyName: "canvasContent", first: true, predicate: TemplateRef, descendants: true, static: true }], viewQueries: [{ propertyName: "glCanvas", first: true, predicate: ["glCanvas"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: `
2165
+ <ngt-canvas-container (resize)="onResize($event)">
2166
+ <canvas #glCanvas style="display: block">
2167
+ <ng-container *ngIf="isConfigured" [ngTemplateOutlet]="canvasContent"></ng-container>
2168
+ <ng-content></ng-content>
2169
+ </canvas>
2170
+ </ngt-canvas-container>
2171
+ `, isInline: true, styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}\n"], dependencies: [{ kind: "component", type: NgtCanvasContainer, selector: "ngt-canvas-container", outputs: ["resize"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
2172
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtCanvas, decorators: [{
2173
+ type: Component,
2174
+ args: [{ selector: 'ngt-canvas', standalone: true, template: `
2175
+ <ngt-canvas-container (resize)="onResize($event)">
2176
+ <canvas #glCanvas style="display: block">
2177
+ <ng-container *ngIf="isConfigured" [ngTemplateOutlet]="canvasContent"></ng-container>
2178
+ <ng-content></ng-content>
2179
+ </canvas>
2180
+ </ngt-canvas-container>
2181
+ `, changeDetection: ChangeDetectionStrategy.OnPush, imports: [NgtCanvasContainer, NgIf, NgTemplateOutlet, AsyncPipe], providers: [NgtStore, provideInstanceRef(NgtCanvas, (canvas) => canvas.sceneRef)], styles: [":host{display:block;position:relative;width:100%;height:100%;overflow:hidden}\n"] }]
2182
+ }], propDecorators: { hostClass: [{
2183
+ type: HostBinding,
2184
+ args: ['class.ngt-canvas']
2185
+ }], pointerEvents: [{
2186
+ type: HostBinding,
2187
+ args: ['style.pointerEvents']
2188
+ }], linear: [{
2189
+ type: Input
2190
+ }], legacy: [{
2191
+ type: Input
2192
+ }], flat: [{
2193
+ type: Input
2194
+ }], orthographic: [{
2195
+ type: Input
2196
+ }], frameloop: [{
2197
+ type: Input
2198
+ }], dpr: [{
2199
+ type: Input
2200
+ }], raycaster: [{
2201
+ type: Input
2202
+ }], shadows: [{
2203
+ type: Input
2204
+ }], camera: [{
2205
+ type: Input
2206
+ }], gl: [{
2207
+ type: Input
2208
+ }], eventSource: [{
2209
+ type: Input
2210
+ }], eventPrefix: [{
2211
+ type: Input
2212
+ }], lookAt: [{
2213
+ type: Input
2214
+ }], performance: [{
2215
+ type: Input
2216
+ }], created: [{
2217
+ type: Output
2218
+ }], canvasPointerMissed: [{
2219
+ type: Output
2220
+ }], glCanvas: [{
2221
+ type: ViewChild,
2222
+ args: ['glCanvas', { static: true }]
2223
+ }], canvasContent: [{
2224
+ type: ContentChild,
2225
+ args: [TemplateRef, { static: true }]
2226
+ }] } });
2227
+
2228
+ const NGT_ARGS = new InjectionToken('NgtArgs');
2229
+ function injectArgs(options = {}) {
2230
+ return inject(NGT_ARGS, options);
2231
+ }
2232
+ class NgtArgs {
2233
+ constructor() {
2234
+ this.templateRef = inject(TemplateRef);
2235
+ this.vcr = inject(ViewContainerRef);
2236
+ }
2237
+ set args(args) {
2238
+ if (this.view) {
2239
+ this.view.destroy();
2240
+ }
2241
+ this.view = this.vcr.createEmbeddedView(this.templateRef, {}, { injector: Injector.create({ providers: [{ provide: NGT_ARGS, useValue: args }] }) });
2242
+ }
2243
+ }
2244
+ NgtArgs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtArgs, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2245
+ NgtArgs.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: NgtArgs, isStandalone: true, selector: "[args]", inputs: { args: "args" }, ngImport: i0 });
2246
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: NgtArgs, decorators: [{
2247
+ type: Directive,
2248
+ args: [{
2249
+ selector: '[args]',
2250
+ standalone: true,
2251
+ }]
2252
+ }], propDecorators: { args: [{
2253
+ type: Input
2254
+ }] } });
2255
+
2256
+ function capitalize(str) {
2257
+ return str.charAt(0).toUpperCase() + str.slice(1);
2258
+ }
2259
+
2260
+ function proxify(instance, proxifyOptions = {}) {
2261
+ const ngtInstance = injectInstance({ host: true });
2262
+ const store = inject(NgtStore);
2263
+ const zone = inject(NgZone);
2264
+ const parentInstance = injectInstanceRef({ skipSelf: true, optional: true });
2265
+ return zone.runOutsideAngular(() => {
2266
+ // prep the instance w/ local state
2267
+ instance = prepare(instance, store.read, store.rootStateFactory, parentInstance?.(), ngtInstance.instanceValue ? ngtInstance.instanceRef : undefined, !!proxifyOptions.primitive);
2268
+ let storeReadySubscription;
2269
+ const newValueSubscriptionMap = new Map();
2270
+ function setProp(obj, prop, newValue) {
2271
+ const capitalizedProp = `set${capitalize(prop)}`;
2272
+ if (isObservable(newValue)) {
2273
+ const sub = newValue.subscribe((val) => {
2274
+ if (obj[capitalizedProp] && typeof obj[capitalizedProp] === 'function') {
2275
+ obj[capitalizedProp](val);
2276
+ }
2277
+ else {
2278
+ applyProps(obj, { [prop]: val });
2279
+ }
2280
+ ngtInstance.write({ [prop]: val });
2281
+ });
2282
+ return () => sub.unsubscribe();
2283
+ }
2284
+ if (obj[capitalizedProp] && typeof obj[capitalizedProp] === 'function') {
2285
+ obj[capitalizedProp](newValue);
2286
+ }
2287
+ else {
2288
+ applyProps(obj, { [prop]: newValue });
2289
+ }
2290
+ ngtInstance.write({ [prop]: newValue });
2291
+ return;
2292
+ }
2293
+ const handler = {
2294
+ get(target, p, receiver) {
2295
+ if (p === 'instanceRef')
2296
+ return ngtInstance.instanceRef;
2297
+ if (p === 'instance')
2298
+ return ngtInstance;
2299
+ if (p === NGT_PROXY_INSTANCE)
2300
+ return target;
2301
+ const capitalizedProp = `get${capitalize(p)}`;
2302
+ if (target[capitalizedProp] && typeof target[capitalizedProp] === 'function') {
2303
+ return target[capitalizedProp]();
2304
+ }
2305
+ return Reflect.get(target, p, receiver);
2306
+ },
2307
+ set(target, p, newValue, receiver) {
2308
+ const prop = p;
2309
+ if (storeReadySubscription)
2310
+ storeReadySubscription.unsubscribe();
2311
+ if (newValueSubscriptionMap.has(prop))
2312
+ newValueSubscriptionMap.get(prop)();
2313
+ // Angular sets this property
2314
+ if (p === '__ngContext__')
2315
+ return Reflect.set(target, p, newValue, receiver);
2316
+ return zone.runOutsideAngular(() => {
2317
+ // TODO: figure out what else we need to handle
2318
+ // we should handle if newValue is an Observable as well
2319
+ if (store.read((s) => s.ready)) {
2320
+ const cleanUp = setProp(instance, prop, newValue);
2321
+ if (cleanUp)
2322
+ newValueSubscriptionMap.set(prop, cleanUp);
2323
+ }
2324
+ else {
2325
+ storeReadySubscription = store.onReady(() => setProp(instance, prop, newValue));
2326
+ }
2327
+ // schedule updateCallback on next event loop
2328
+ queueMicrotask(() => {
2329
+ if (ngtInstance.updateCallback)
2330
+ ngtInstance.updateCallback(instance);
2331
+ });
2332
+ return true;
2333
+ });
2334
+ },
2335
+ };
2336
+ ngtInstance.effect(tapEffect(() => () => {
2337
+ if (storeReadySubscription)
2338
+ storeReadySubscription.unsubscribe();
2339
+ newValueSubscriptionMap.forEach((cleanUp) => cleanUp());
2340
+ }))();
2341
+ const proxied = new Proxy(instance, handler);
2342
+ if (proxifyOptions.attach)
2343
+ ngtInstance.attach = proxifyOptions.attach;
2344
+ if (proxifyOptions.created)
2345
+ proxifyOptions.created(proxied, store.read, ngtInstance);
2346
+ ngtInstance.instanceRef.set(proxied);
2347
+ return proxied;
2348
+ });
2349
+ }
2350
+
17
2351
  /**
18
2352
  * Generated bundle index. Do not edit.
19
2353
  */
20
2354
 
21
- export { AngularThreeModule };
2355
+ export { NGT_ARGS, NGT_INSTANCE_INPUTS, NGT_INSTANCE_OUTPUTS, NGT_INSTANCE_REF_FACTORY, NGT_PROXY_INSTANCE, NgtArgs, NgtCanvas, NgtCanvasContainer, NgtComponentStore, NgtInstance, NgtLoader, NgtResize, NgtStore, addAfterEffect, addEffect, addTail, createLoop, defaultProjector, defaultResizeOptions, flushGlobalEffects, injectArgs, injectInstance, injectInstanceRef, injectResizeObserverSupport, injectResizeOptions, provideInstanceRef, provideResizeOptions, proxify, rootStateMap, skipFirstUndefined, tapEffect };
22
2356
  //# sourceMappingURL=angular-three.mjs.map