angular-three-soba 1.0.2 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/esm2020/controls/lib/orbit-controls/orbit-controls.mjs +3 -3
  2. package/esm2020/loaders/index.mjs +4 -1
  3. package/esm2020/loaders/lib/loader/loader.mjs +133 -0
  4. package/esm2020/loaders/lib/progress/progress.mjs +39 -0
  5. package/esm2020/loaders/lib/texture-loader/texture-loader.mjs +19 -0
  6. package/esm2020/misc/angular-three-soba-misc.mjs +5 -0
  7. package/esm2020/misc/index.mjs +2 -0
  8. package/esm2020/misc/lib/bake-shadows/bake-shadows.mjs +25 -0
  9. package/esm2020/performance/angular-three-soba-performance.mjs +5 -0
  10. package/esm2020/performance/index.mjs +5 -0
  11. package/esm2020/performance/lib/adaptive/adaptive-dpr.mjs +46 -0
  12. package/esm2020/performance/lib/adaptive/adaptive-events.mjs +36 -0
  13. package/esm2020/performance/lib/detailed/detailed.mjs +50 -0
  14. package/esm2020/performance/lib/stats/stats.mjs +63 -0
  15. package/esm2020/shaders/angular-three-soba-shaders.mjs +5 -0
  16. package/esm2020/shaders/index.mjs +2 -0
  17. package/esm2020/shaders/lib/shader-material/shader-material.mjs +34 -0
  18. package/esm2020/staging/angular-three-soba-staging.mjs +5 -0
  19. package/esm2020/staging/index.mjs +13 -0
  20. package/esm2020/staging/lib/accumulative-shadows/accumulative-shadows.mjs +276 -0
  21. package/esm2020/staging/lib/accumulative-shadows/progressive-light-map.mjs +109 -0
  22. package/esm2020/staging/lib/accumulative-shadows/randomized-lights.mjs +196 -0
  23. package/esm2020/staging/lib/bounds/bounds.mjs +283 -0
  24. package/esm2020/staging/lib/center/center.mjs +142 -0
  25. package/esm2020/staging/lib/contact-shadows/contact-shadows.mjs +227 -0
  26. package/esm2020/staging/lib/environment/assets.mjs +13 -0
  27. package/esm2020/staging/lib/environment/environment-cube.mjs +40 -0
  28. package/esm2020/staging/lib/environment/environment-ground.mjs +66 -0
  29. package/esm2020/staging/lib/environment/environment-inputs.mjs +86 -0
  30. package/esm2020/staging/lib/environment/environment-map.mjs +38 -0
  31. package/esm2020/staging/lib/environment/environment-portal.mjs +110 -0
  32. package/esm2020/staging/lib/environment/environment.mjs +163 -0
  33. package/esm2020/staging/lib/environment/utils.mjs +70 -0
  34. package/esm2020/staging/lib/float/float.mjs +76 -0
  35. package/esm2020/staging/lib/sky/sky.mjs +111 -0
  36. package/esm2020/staging/lib/sparkles/sparkles.mjs +209 -0
  37. package/esm2020/staging/lib/stage/stage.mjs +369 -0
  38. package/esm2020/staging/lib/stars/stars.mjs +171 -0
  39. package/fesm2015/angular-three-soba-controls.mjs +3 -3
  40. package/fesm2015/angular-three-soba-loaders.mjs +187 -3
  41. package/fesm2015/angular-three-soba-loaders.mjs.map +1 -1
  42. package/fesm2015/angular-three-soba-misc.mjs +32 -0
  43. package/fesm2015/angular-three-soba-misc.mjs.map +1 -0
  44. package/fesm2015/angular-three-soba-performance.mjs +191 -0
  45. package/fesm2015/angular-three-soba-performance.mjs.map +1 -0
  46. package/fesm2015/angular-three-soba-shaders.mjs +38 -0
  47. package/fesm2015/angular-three-soba-shaders.mjs.map +1 -0
  48. package/fesm2015/angular-three-soba-staging.mjs +2647 -0
  49. package/fesm2015/angular-three-soba-staging.mjs.map +1 -0
  50. package/fesm2020/angular-three-soba-controls.mjs +3 -3
  51. package/fesm2020/angular-three-soba-loaders.mjs +186 -3
  52. package/fesm2020/angular-three-soba-loaders.mjs.map +1 -1
  53. package/fesm2020/angular-three-soba-misc.mjs +32 -0
  54. package/fesm2020/angular-three-soba-misc.mjs.map +1 -0
  55. package/fesm2020/angular-three-soba-performance.mjs +191 -0
  56. package/fesm2020/angular-three-soba-performance.mjs.map +1 -0
  57. package/fesm2020/angular-three-soba-shaders.mjs +41 -0
  58. package/fesm2020/angular-three-soba-shaders.mjs.map +1 -0
  59. package/fesm2020/angular-three-soba-staging.mjs +2654 -0
  60. package/fesm2020/angular-three-soba-staging.mjs.map +1 -0
  61. package/loaders/index.d.ts +3 -0
  62. package/loaders/lib/loader/loader.d.ts +26 -0
  63. package/loaders/lib/progress/progress.d.ts +16 -0
  64. package/loaders/lib/texture-loader/texture-loader.d.ts +5 -0
  65. package/misc/README.md +3 -0
  66. package/misc/index.d.ts +1 -0
  67. package/misc/lib/bake-shadows/bake-shadows.d.ts +9 -0
  68. package/package.json +37 -2
  69. package/performance/README.md +3 -0
  70. package/performance/index.d.ts +4 -0
  71. package/performance/lib/adaptive/adaptive-dpr.d.ts +11 -0
  72. package/performance/lib/adaptive/adaptive-events.d.ts +10 -0
  73. package/performance/lib/detailed/detailed.d.ts +12 -0
  74. package/performance/lib/stats/stats.d.ts +14 -0
  75. package/plugin/package.json +1 -1
  76. package/plugin/src/generators/init/init.js +13 -17
  77. package/plugin/src/generators/init/init.js.map +1 -1
  78. package/shaders/README.md +3 -0
  79. package/shaders/index.d.ts +1 -0
  80. package/shaders/lib/shader-material/shader-material.d.ts +6 -0
  81. package/staging/README.md +3 -0
  82. package/staging/index.d.ts +12 -0
  83. package/staging/lib/accumulative-shadows/accumulative-shadows.d.ts +64 -0
  84. package/staging/lib/accumulative-shadows/progressive-light-map.d.ts +34 -0
  85. package/staging/lib/accumulative-shadows/randomized-lights.d.ts +42 -0
  86. package/staging/lib/bounds/bounds.d.ts +48 -0
  87. package/staging/lib/center/center.d.ts +40 -0
  88. package/staging/lib/contact-shadows/contact-shadows.d.ts +29 -0
  89. package/staging/lib/environment/assets.d.ts +13 -0
  90. package/staging/lib/environment/environment-cube.d.ts +11 -0
  91. package/staging/lib/environment/environment-ground.d.ts +9 -0
  92. package/staging/lib/environment/environment-inputs.d.ts +28 -0
  93. package/staging/lib/environment/environment-map.d.ts +10 -0
  94. package/staging/lib/environment/environment-portal.d.ts +15 -0
  95. package/staging/lib/environment/environment.d.ts +12 -0
  96. package/staging/lib/environment/utils.d.ts +8 -0
  97. package/staging/lib/float/float.d.ts +16 -0
  98. package/staging/lib/sky/sky.d.ts +21 -0
  99. package/staging/lib/sparkles/sparkles.d.ts +29 -0
  100. package/staging/lib/stage/stage.d.ts +87 -0
  101. package/staging/lib/stars/stars.d.ts +20 -0
@@ -0,0 +1,2654 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, inject, Directive, Component, CUSTOM_ELEMENTS_SCHEMA, Input, EventEmitter, Output, TemplateRef, ContentChild, ChangeDetectorRef } from '@angular/core';
3
+ import { extend, NgtStore, getLocalState, injectBeforeRender, NgtRxStore, injectNgtRef, is, NgtPush, NgtArgs, injectNgtDestroy, injectNgtLoader, startWithUndefined, prepare, NgtPortal, NgtPortalContent } from 'angular-three';
4
+ import { shaderMaterial } from 'angular-three-soba/shaders';
5
+ import { combineLatest, switchMap, isObservable, of, debounceTime, map, takeUntil, startWith, withLatestFrom } from 'rxjs';
6
+ import * as THREE from 'three';
7
+ import { Group, Mesh, PlaneGeometry, DirectionalLight, OrthographicCamera, Vector2, Box3, Vector3, Sphere, MeshBasicMaterial, CubeTextureLoader, CubeReflectionMapping, EquirectangularReflectionMapping, sRGBEncoding, LinearEncoding, CubeCamera, HalfFloatType, Points, BufferGeometry, BufferAttribute, Vector4, Color, MathUtils, AmbientLight, SpotLight, PointLight, Spherical, AdditiveBlending } from 'three';
8
+ import { NgIf, NgTemplateOutlet } from '@angular/common';
9
+ import { HorizontalBlurShader, VerticalBlurShader, RGBELoader, GroundProjectedEnv, Sky } from 'three-stdlib';
10
+
11
+ function isLight(object) {
12
+ return object.isLight;
13
+ }
14
+ function isGeometry(object) {
15
+ return !!object.geometry;
16
+ }
17
+ const DiscardMaterial = shaderMaterial({}, 'void main() { gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }', 'void main() { discard; }');
18
+ class ProgressiveLightMap {
19
+ constructor(renderer, scene, res = 1024) {
20
+ this.renderer = renderer;
21
+ this.res = res;
22
+ this.scene = scene;
23
+ this.buffer1Active = false;
24
+ this.lights = [];
25
+ this.meshes = [];
26
+ this.object = null;
27
+ this.clearColor = new THREE.Color();
28
+ this.clearAlpha = 0;
29
+ // Create the Progressive LightMap Texture
30
+ const format = /(Android|iPad|iPhone|iPod)/g.test(navigator.userAgent) ? THREE.HalfFloatType : THREE.FloatType;
31
+ this.progressiveLightMap1 = new THREE.WebGLRenderTarget(this.res, this.res, {
32
+ type: format,
33
+ encoding: renderer.outputEncoding,
34
+ });
35
+ this.progressiveLightMap2 = new THREE.WebGLRenderTarget(this.res, this.res, {
36
+ type: format,
37
+ encoding: renderer.outputEncoding,
38
+ });
39
+ // Inject some spicy new logic into a standard phong material
40
+ this.discardMat = new DiscardMaterial();
41
+ this.targetMat = new THREE.MeshLambertMaterial({ fog: false });
42
+ this.previousShadowMap = { value: this.progressiveLightMap1.texture };
43
+ this.averagingWindow = { value: 100 };
44
+ this.targetMat.onBeforeCompile = (shader) => {
45
+ // Vertex Shader: Set Vertex Positions to the Unwrapped UV Positions
46
+ shader.vertexShader =
47
+ 'varying vec2 vUv;\n' +
48
+ shader.vertexShader.slice(0, -1) +
49
+ 'vUv = uv; gl_Position = vec4((uv - 0.5) * 2.0, 1.0, 1.0); }';
50
+ // Fragment Shader: Set Pixels to average in the Previous frame's Shadows
51
+ const bodyStart = shader.fragmentShader.indexOf('void main() {');
52
+ shader.fragmentShader =
53
+ 'varying vec2 vUv;\n' +
54
+ shader.fragmentShader.slice(0, bodyStart) +
55
+ 'uniform sampler2D previousShadowMap;\n uniform float averagingWindow;\n' +
56
+ shader.fragmentShader.slice(bodyStart - 1, -1) +
57
+ `\nvec3 texelOld = texture2D(previousShadowMap, vUv).rgb;
58
+ gl_FragColor.rgb = mix(texelOld, gl_FragColor.rgb, 1.0/ averagingWindow);
59
+ }`;
60
+ // Set the Previous Frame's Texture Buffer and Averaging Window
61
+ shader.uniforms['previousShadowMap'] = this.previousShadowMap;
62
+ shader.uniforms['averagingWindow'] = this.averagingWindow;
63
+ };
64
+ }
65
+ clear() {
66
+ this.renderer.getClearColor(this.clearColor);
67
+ this.clearAlpha = this.renderer.getClearAlpha();
68
+ this.renderer.setClearColor('black', 1);
69
+ this.renderer.setRenderTarget(this.progressiveLightMap1);
70
+ this.renderer.clear();
71
+ this.renderer.setRenderTarget(this.progressiveLightMap2);
72
+ this.renderer.clear();
73
+ this.renderer.setRenderTarget(null);
74
+ this.renderer.setClearColor(this.clearColor, this.clearAlpha);
75
+ this.lights = [];
76
+ this.meshes = [];
77
+ this.scene.traverse((object) => {
78
+ if (isGeometry(object)) {
79
+ this.meshes.push({ object, material: object.material });
80
+ }
81
+ else if (isLight(object)) {
82
+ this.lights.push({ object, intensity: object.intensity });
83
+ }
84
+ });
85
+ }
86
+ prepare() {
87
+ this.lights.forEach((light) => (light.object.intensity = 0));
88
+ this.meshes.forEach((mesh) => (mesh.object.material = this.discardMat));
89
+ }
90
+ finish() {
91
+ this.lights.forEach((light) => (light.object.intensity = light.intensity));
92
+ this.meshes.forEach((mesh) => (mesh.object.material = mesh.material));
93
+ }
94
+ configure(object) {
95
+ this.object = object;
96
+ }
97
+ update(camera, blendWindow = 100) {
98
+ if (!this.object)
99
+ return;
100
+ // Set each object's material to the UV Unwrapped Surface Mapping Version
101
+ this.averagingWindow.value = blendWindow;
102
+ this.object.material = this.targetMat;
103
+ // Ping-pong two surface buffers for reading/writing
104
+ const activeMap = this.buffer1Active ? this.progressiveLightMap1 : this.progressiveLightMap2;
105
+ const inactiveMap = this.buffer1Active ? this.progressiveLightMap2 : this.progressiveLightMap1;
106
+ // Render the object's surface maps
107
+ const oldBg = this.scene.background;
108
+ this.scene.background = null;
109
+ this.renderer.setRenderTarget(activeMap);
110
+ this.previousShadowMap.value = inactiveMap.texture;
111
+ this.buffer1Active = !this.buffer1Active;
112
+ this.renderer.render(this.scene, camera);
113
+ this.renderer.setRenderTarget(null);
114
+ this.scene.background = oldBg;
115
+ }
116
+ }
117
+
118
+ const SoftShadowMaterial = shaderMaterial({
119
+ color: new THREE.Color(),
120
+ blend: 2.0,
121
+ alphaTest: 0.75,
122
+ opacity: 0,
123
+ map: null,
124
+ },
125
+ // language=GLSL
126
+ `
127
+ varying vec2 vUv;
128
+ void main() {
129
+ gl_Position = projectionMatrix * viewMatrix * modeLMatrix * vec4(position, 1.);
130
+ vUv = uv;
131
+ }
132
+ `,
133
+ // language=GLSL
134
+ `
135
+ varying vec2 vUv;
136
+ uniform sampler2D map;
137
+ uniform vec3 color;
138
+ uniform float blend;
139
+ uniform float opacity;
140
+ uniform float alphaTest;
141
+ void main() {
142
+ vec4 sampleDiffuseColor = texture2D(map, vUv):
143
+ gl_FragColor = vec4(color * sampledDiffuseColor.r * blend, max(0.0, (1.0 - (sampledDiffuseColor.r + sampledDiffuseColor.g + sampledDiffuseColor.b) / alphaTest)) * opacity);
144
+ #include <tonemapping_fragment>
145
+ #include <encodings_fragment>
146
+ }
147
+ `);
148
+ extend({ SoftShadowMaterial, Group, Mesh, PlaneGeometry });
149
+ const NGTS_ACCUMULATIVE_SHADOWS_API = new InjectionToken('NgtsAccumulativeShadows API');
150
+ function accumulativeShadowsApiFactory(accumulativeShadows) {
151
+ const store = inject(NgtStore);
152
+ const api = {
153
+ lights: new Map(),
154
+ count: 0,
155
+ getMesh: () => accumulativeShadows.meshRef.nativeElement,
156
+ reset: () => {
157
+ accumulativeShadows.pLM.clear();
158
+ const material = api.getMesh().material;
159
+ material.opacity = 0;
160
+ material.alphaTest = 0;
161
+ api.count = 0;
162
+ },
163
+ update: (frames = 1) => {
164
+ // adapt the opacity blend ratio to the number of frames
165
+ const material = api.getMesh().material;
166
+ if (!api.temporal) {
167
+ material.opacity = accumulativeShadows.get('opacity');
168
+ material.alphaTest = accumulativeShadows.get('alphaTest');
169
+ }
170
+ else {
171
+ material.opacity = Math.min(accumulativeShadows.get('opacity'), material.opacity + accumulativeShadows.get('opacity') / api.blend);
172
+ material.alphaTest = Math.min(accumulativeShadows.get('alphaTest'), material.alphaTest + accumulativeShadows.get('alphaTest') / api.blend);
173
+ }
174
+ // switch accumulative lights on
175
+ accumulativeShadows.accumulativeShadowsRef.nativeElement.visible = true;
176
+ // collect scene lights and meshes
177
+ accumulativeShadows.pLM.prepare();
178
+ // update the lightmap and the accumulative lights
179
+ for (let i = 0; i < frames; i++) {
180
+ api.lights.forEach((light) => light.update());
181
+ accumulativeShadows.pLM.update(store.get('camera'), api.blend);
182
+ }
183
+ // switch lights off
184
+ accumulativeShadows.accumulativeShadowsRef.nativeElement.visible = false;
185
+ // restore lights and meshes
186
+ accumulativeShadows.pLM.finish();
187
+ },
188
+ };
189
+ Object.defineProperties(api, {
190
+ temporal: {
191
+ get: () => !!accumulativeShadows.get('temporal'),
192
+ },
193
+ frames: {
194
+ get: () => Math.max(2, accumulativeShadows.get('frames')),
195
+ },
196
+ blend: {
197
+ get: () => Math.max(2, accumulativeShadows.get('frames') === Infinity
198
+ ? accumulativeShadows.get('blend')
199
+ : accumulativeShadows.get('frames')),
200
+ },
201
+ });
202
+ accumulativeShadows.hold(accumulativeShadows.meshRef.$, (mesh) => {
203
+ accumulativeShadows.pLM.configure(mesh);
204
+ accumulativeShadows.hold(combineLatest([accumulativeShadows.select(), getLocalState(store.get('scene')).objects]), () => {
205
+ // reset internals, buffers, ...
206
+ api.reset();
207
+ // update lightmap
208
+ if (!api.temporal && api.frames !== Infinity)
209
+ api.update(api.blend);
210
+ });
211
+ });
212
+ injectBeforeRender(() => {
213
+ const limit = accumulativeShadows.get('limit');
214
+ if (api.getMesh() && (api.temporal || api.frames === Infinity) && api.count < api.frames && api.count < limit) {
215
+ api.update();
216
+ api.count++;
217
+ }
218
+ });
219
+ return api;
220
+ }
221
+ class AccumulativeShadowsConsumer {
222
+ constructor() {
223
+ inject(NGTS_ACCUMULATIVE_SHADOWS_API);
224
+ }
225
+ }
226
+ AccumulativeShadowsConsumer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: AccumulativeShadowsConsumer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
227
+ AccumulativeShadowsConsumer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: AccumulativeShadowsConsumer, isStandalone: true, selector: "ngts-accumulative-shadows-consumer", ngImport: i0 });
228
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: AccumulativeShadowsConsumer, decorators: [{
229
+ type: Directive,
230
+ args: [{ selector: 'ngts-accumulative-shadows-consumer', standalone: true }]
231
+ }], ctorParameters: function () { return []; } });
232
+ class NgtsAccumulativeShadows extends NgtRxStore {
233
+ constructor() {
234
+ super(...arguments);
235
+ this.nullTraverse = () => null;
236
+ this.Math = Math;
237
+ this.store = inject(NgtStore);
238
+ this.pLM = new ProgressiveLightMap(this.store.get('gl'), this.store.get('scene'), this.get('resolution'));
239
+ this.accumulativeShadowsRef = injectNgtRef();
240
+ this.meshRef = injectNgtRef();
241
+ }
242
+ /** How many frames it can render, more yields cleaner results but takes more time, 40 */
243
+ set frames(frames) {
244
+ this.set({ frames });
245
+ }
246
+ /** If frames === Infinity blend controls the refresh ratio, 100 */
247
+ set blend(blend) {
248
+ this.set({ blend });
249
+ }
250
+ /** Can limit the amount of frames rendered if frames === Infinity, usually to get some performance back once a movable scene has settled, Infinity */
251
+ set limit(limit) {
252
+ this.set({ limit });
253
+ }
254
+ /** Scale of the plane, */
255
+ set scale(scale) {
256
+ this.set({ scale });
257
+ }
258
+ /** Temporal accumulates shadows over time which is more performant but has a visual regression over instant results, false */
259
+ set temporal(temporal) {
260
+ this.set({ temporal });
261
+ }
262
+ /** Opacity of the plane, 1 */
263
+ set opacity(opacity) {
264
+ this.set({ opacity });
265
+ }
266
+ /** Discards alpha pixels, 0.65 */
267
+ set alphaTest(alphaTest) {
268
+ this.set({ alphaTest });
269
+ }
270
+ /** Shadow color, black */
271
+ set color(color) {
272
+ this.set({ color });
273
+ }
274
+ /** Colorblend, how much colors turn to black, 0 is black, 2 */
275
+ set colorBlend(colorBlend) {
276
+ this.set({ colorBlend });
277
+ }
278
+ /** Buffer resolution, 1024 */
279
+ set resolution(resolution) {
280
+ this.set({ resolution });
281
+ }
282
+ /** Texture tonemapping */
283
+ set toneMapped(toneMapped) {
284
+ this.set({ toneMapped });
285
+ }
286
+ initialize() {
287
+ super.initialize();
288
+ this.set({
289
+ frames: 40,
290
+ limit: Infinity,
291
+ blend: 20,
292
+ scale: 10,
293
+ opacity: 1,
294
+ alphaTest: 0.75,
295
+ color: 'black',
296
+ colorBlend: 2,
297
+ resolution: 1024,
298
+ toneMapped: true,
299
+ });
300
+ }
301
+ }
302
+ NgtsAccumulativeShadows.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsAccumulativeShadows, deps: null, target: i0.ɵɵFactoryTarget.Component });
303
+ NgtsAccumulativeShadows.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsAccumulativeShadows, isStandalone: true, selector: "ngts-accumulative-shadows", inputs: { frames: "frames", blend: "blend", limit: "limit", scale: "scale", temporal: "temporal", opacity: "opacity", alphaTest: "alphaTest", color: "color", colorBlend: "colorBlend", resolution: "resolution", toneMapped: "toneMapped" }, providers: [
304
+ {
305
+ provide: NGTS_ACCUMULATIVE_SHADOWS_API,
306
+ useFactory: accumulativeShadowsApiFactory,
307
+ deps: [NgtsAccumulativeShadows],
308
+ },
309
+ ], usesInheritance: true, ngImport: i0, template: `
310
+ <ngt-group ngtCompound>
311
+ <ngt-group [ref]="accumulativeShadowsRef" [traverse]="nullTraverse">
312
+ <ng-content />
313
+ <ngts-accumulative-shadows-consumer />
314
+ </ngt-group>
315
+ <ngt-mesh [receiveShadow]="true" [ref]="meshRef" [scale]="get('scale')" [rotation]="[-Math.PI / 2, 0, 0]">
316
+ <ngt-plane-geometry />
317
+ <ngt-soft-shadow-material
318
+ [transparent]="true"
319
+ [depthWrite]="false"
320
+ [color]="get('color')"
321
+ [toneMapped]="get('toneMapped')"
322
+ [blend]="get('colorBlend')"
323
+ [map]="pLM.progressiveLightMap2.texture"
324
+ />
325
+ </ngt-mesh>
326
+ </ngt-group>
327
+ `, isInline: true, dependencies: [{ kind: "directive", type: AccumulativeShadowsConsumer, selector: "ngts-accumulative-shadows-consumer" }] });
328
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsAccumulativeShadows, decorators: [{
329
+ type: Component,
330
+ args: [{
331
+ selector: 'ngts-accumulative-shadows',
332
+ standalone: true,
333
+ template: `
334
+ <ngt-group ngtCompound>
335
+ <ngt-group [ref]="accumulativeShadowsRef" [traverse]="nullTraverse">
336
+ <ng-content />
337
+ <ngts-accumulative-shadows-consumer />
338
+ </ngt-group>
339
+ <ngt-mesh [receiveShadow]="true" [ref]="meshRef" [scale]="get('scale')" [rotation]="[-Math.PI / 2, 0, 0]">
340
+ <ngt-plane-geometry />
341
+ <ngt-soft-shadow-material
342
+ [transparent]="true"
343
+ [depthWrite]="false"
344
+ [color]="get('color')"
345
+ [toneMapped]="get('toneMapped')"
346
+ [blend]="get('colorBlend')"
347
+ [map]="pLM.progressiveLightMap2.texture"
348
+ />
349
+ </ngt-mesh>
350
+ </ngt-group>
351
+ `,
352
+ imports: [AccumulativeShadowsConsumer],
353
+ providers: [
354
+ {
355
+ provide: NGTS_ACCUMULATIVE_SHADOWS_API,
356
+ useFactory: accumulativeShadowsApiFactory,
357
+ deps: [NgtsAccumulativeShadows],
358
+ },
359
+ ],
360
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
361
+ }]
362
+ }], propDecorators: { frames: [{
363
+ type: Input
364
+ }], blend: [{
365
+ type: Input
366
+ }], limit: [{
367
+ type: Input
368
+ }], scale: [{
369
+ type: Input
370
+ }], temporal: [{
371
+ type: Input
372
+ }], opacity: [{
373
+ type: Input
374
+ }], alphaTest: [{
375
+ type: Input
376
+ }], color: [{
377
+ type: Input
378
+ }], colorBlend: [{
379
+ type: Input
380
+ }], resolution: [{
381
+ type: Input
382
+ }], toneMapped: [{
383
+ type: Input
384
+ }] } });
385
+
386
+ extend({ Group, DirectionalLight, OrthographicCamera, Vector2 });
387
+ const NGTS_RANDOMIZED_LIGHTS_API = new InjectionToken('NgtsRandomizedLights API');
388
+ function randomizedLightsApiFactory(randomizedLights) {
389
+ const accumulativeApi = inject(NGTS_ACCUMULATIVE_SHADOWS_API);
390
+ const update = () => {
391
+ let light;
392
+ if (randomizedLights.lightsRef.nativeElement) {
393
+ for (let l = 0; l < randomizedLights.lightsRef.nativeElement.children.length; l++) {
394
+ light = randomizedLights.lightsRef.nativeElement.children[l];
395
+ if (Math.random() > randomizedLights.get('ambient')) {
396
+ const position = randomizedLights.get('position');
397
+ const radius = randomizedLights.get('radius');
398
+ light.position.set(position[0] + THREE.MathUtils.randFloatSpread(radius), position[1] + THREE.MathUtils.randFloatSpread(radius), position[2] + THREE.MathUtils.randFloatSpread(radius));
399
+ }
400
+ else {
401
+ const lambda = Math.acos(2 * Math.random() - 1) - Math.PI / 2.0;
402
+ const phi = 2 * Math.PI * Math.random();
403
+ const length = randomizedLights.get('length');
404
+ light.position.set(Math.cos(lambda) * Math.cos(phi) * length, Math.abs(Math.cos(lambda) * Math.sin(phi) * length), Math.sin(lambda) * length);
405
+ }
406
+ }
407
+ }
408
+ };
409
+ const api = { update };
410
+ randomizedLights.effect(combineLatest([
411
+ randomizedLights.lightsRef.$,
412
+ randomizedLights.select('position'),
413
+ randomizedLights.select('radius'),
414
+ randomizedLights.select('length'),
415
+ randomizedLights.select('ambient'),
416
+ ]), ([group]) => {
417
+ if (accumulativeApi)
418
+ accumulativeApi.lights.set(group.uuid, api);
419
+ return () => accumulativeApi.lights.delete(group.uuid);
420
+ });
421
+ return api;
422
+ }
423
+ class RandomizedLightsConsumer {
424
+ constructor() {
425
+ inject(NGTS_RANDOMIZED_LIGHTS_API);
426
+ }
427
+ }
428
+ RandomizedLightsConsumer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: RandomizedLightsConsumer, deps: [], target: i0.ɵɵFactoryTarget.Directive });
429
+ RandomizedLightsConsumer.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: RandomizedLightsConsumer, isStandalone: true, selector: "ngts-randomized-lights-consumer", ngImport: i0 });
430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: RandomizedLightsConsumer, decorators: [{
431
+ type: Directive,
432
+ args: [{ selector: 'ngts-randomized-lights-consumer', standalone: true }]
433
+ }], ctorParameters: function () { return []; } });
434
+ class NgtsRandomizedLights extends NgtRxStore {
435
+ constructor() {
436
+ super(...arguments);
437
+ this.lightsRef = injectNgtRef();
438
+ }
439
+ /** How many frames it will jiggle the lights, 1.
440
+ * Frames is context aware, if a provider like AccumulativeShadows exists, frames will be taken from there! */
441
+ set frames(frames) {
442
+ this.set({ frames });
443
+ }
444
+ /** Light position, [0, 0, 0] */
445
+ set position(position) {
446
+ this.set({ position });
447
+ }
448
+ /** Radius of the jiggle, higher values make softer light, 5 */
449
+ set radius(radius) {
450
+ this.set({ radius });
451
+ }
452
+ /** Amount of lights, 8 */
453
+ set amount(amount) {
454
+ this.set({ amount });
455
+ }
456
+ /** Light intensity, 1 */
457
+ set intensity(intensity) {
458
+ this.set({ intensity });
459
+ }
460
+ /** Ambient occlusion, lower values mean less AO, hight more, you can mix AO and directional light, 0.5 */
461
+ set ambient(ambient) {
462
+ this.set({ ambient });
463
+ }
464
+ /** If the lights cast shadows, this is true by default */
465
+ set castShadow(castShadow) {
466
+ this.set({ castShadow });
467
+ }
468
+ /** Default shadow bias, 0 */
469
+ set bias(bias) {
470
+ this.set({ bias });
471
+ }
472
+ /** Default map size, 512 */
473
+ set mapSize(mapSize) {
474
+ this.set({ mapSize });
475
+ }
476
+ /** Default size of the shadow camera, 10 */
477
+ set size(size) {
478
+ this.set({ size });
479
+ }
480
+ /** Default shadow camera near, 0.5 */
481
+ set near(near) {
482
+ this.set({ near });
483
+ }
484
+ /** Default shadow camera far, 500 */
485
+ set far(far) {
486
+ this.set({ far });
487
+ }
488
+ initialize() {
489
+ super.initialize();
490
+ this.set({
491
+ castShadow: true,
492
+ bias: 0.001,
493
+ mapSize: 512,
494
+ size: 5,
495
+ near: 0.5,
496
+ far: 500,
497
+ frames: 1,
498
+ position: [0, 0, 0],
499
+ radius: 1,
500
+ amount: 8,
501
+ intensity: 1,
502
+ ambient: 0.5,
503
+ });
504
+ this.connect('cameraArgs', this.select(['size', 'near', 'far'], ({ size, near, far }) => [-size, size, size, -size, near, far]));
505
+ this.connect('length', this.select(['position'], ({ position }) => new THREE.Vector3(...position).length()));
506
+ }
507
+ }
508
+ NgtsRandomizedLights.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsRandomizedLights, deps: null, target: i0.ɵɵFactoryTarget.Component });
509
+ NgtsRandomizedLights.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsRandomizedLights, isStandalone: true, selector: "ngts-randomized-lights", inputs: { lightsRef: "lightsRef", frames: "frames", position: "position", radius: "radius", amount: "amount", intensity: "intensity", ambient: "ambient", castShadow: "castShadow", bias: "bias", mapSize: "mapSize", size: "size", near: "near", far: "far" }, providers: [
510
+ { provide: NGTS_RANDOMIZED_LIGHTS_API, useFactory: randomizedLightsApiFactory, deps: [NgtsRandomizedLights] },
511
+ ], usesInheritance: true, ngImport: i0, template: `
512
+ <ngt-group ngtCompound [ref]="lightsRef">
513
+ <ngt-directional-light
514
+ *ngFor="let i; repeat: get('amount')"
515
+ [castShadow]="get('castShadow')"
516
+ [intensity]="get('intensity') / get('amount')"
517
+ >
518
+ <ngt-value [rawValue]="get('bias')" attach="shadow.bias" />
519
+ <ngt-vector2 *args="[get('mapSize'), get('mapSize')]" attach="shadow.mapSize" />
520
+ <ngt-orthographic-camera *args="get('cameraArgs')" attach="shadow.camera" />
521
+ </ngt-directional-light>
522
+ </ngt-group>
523
+ `, isInline: true });
524
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsRandomizedLights, decorators: [{
525
+ type: Component,
526
+ args: [{
527
+ selector: 'ngts-randomized-lights',
528
+ standalone: true,
529
+ template: `
530
+ <ngt-group ngtCompound [ref]="lightsRef">
531
+ <ngt-directional-light
532
+ *ngFor="let i; repeat: get('amount')"
533
+ [castShadow]="get('castShadow')"
534
+ [intensity]="get('intensity') / get('amount')"
535
+ >
536
+ <ngt-value [rawValue]="get('bias')" attach="shadow.bias" />
537
+ <ngt-vector2 *args="[get('mapSize'), get('mapSize')]" attach="shadow.mapSize" />
538
+ <ngt-orthographic-camera *args="get('cameraArgs')" attach="shadow.camera" />
539
+ </ngt-directional-light>
540
+ </ngt-group>
541
+ `,
542
+ providers: [
543
+ { provide: NGTS_RANDOMIZED_LIGHTS_API, useFactory: randomizedLightsApiFactory, deps: [NgtsRandomizedLights] },
544
+ ],
545
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
546
+ }]
547
+ }], propDecorators: { lightsRef: [{
548
+ type: Input
549
+ }], frames: [{
550
+ type: Input
551
+ }], position: [{
552
+ type: Input
553
+ }], radius: [{
554
+ type: Input
555
+ }], amount: [{
556
+ type: Input
557
+ }], intensity: [{
558
+ type: Input
559
+ }], ambient: [{
560
+ type: Input
561
+ }], castShadow: [{
562
+ type: Input
563
+ }], bias: [{
564
+ type: Input
565
+ }], mapSize: [{
566
+ type: Input
567
+ }], size: [{
568
+ type: Input
569
+ }], near: [{
570
+ type: Input
571
+ }], far: [{
572
+ type: Input
573
+ }] } });
574
+
575
+ const isBox3 = (def) => !!def && def.isBox3;
576
+ function equals(a, b, eps) {
577
+ return Math.abs(a.x - b.x) < eps && Math.abs(a.y - b.y) < eps && Math.abs(a.z - b.z) < eps;
578
+ }
579
+ function damp(v, t, lambda, delta) {
580
+ v.x = THREE.MathUtils.damp(v.x, t.x, lambda, delta);
581
+ v.y = THREE.MathUtils.damp(v.y, t.y, lambda, delta);
582
+ v.z = THREE.MathUtils.damp(v.z, t.z, lambda, delta);
583
+ }
584
+ const NGTS_BOUNDS_API = new InjectionToken('NgtsBounds API');
585
+ function boundsApiFactory(bounds) {
586
+ const store = inject(NgtStore);
587
+ const box = new THREE.Box3();
588
+ function getSize() {
589
+ const camera = store.get('camera');
590
+ const margin = bounds.get('margin');
591
+ const size = box.getSize(new THREE.Vector3());
592
+ const center = box.getCenter(new THREE.Vector3());
593
+ const maxSize = Math.max(size.x, size.y, size.z);
594
+ const fitHeightDistance = is.orthographicCamera(camera)
595
+ ? maxSize * 4
596
+ : maxSize / (2 * Math.atan((Math.PI * camera.fov) / 360));
597
+ const fitWidthDistance = is.orthographicCamera(camera) ? maxSize * 4 : fitHeightDistance / camera.aspect;
598
+ const distance = margin * Math.max(fitHeightDistance, fitWidthDistance);
599
+ return { box, size, center, distance };
600
+ }
601
+ const api = {
602
+ getSize,
603
+ refresh(object) {
604
+ const { camera, controls: storeControls } = store.get();
605
+ const controls = storeControls;
606
+ if (isBox3(object))
607
+ box.copy(object);
608
+ else {
609
+ const target = object || bounds.boundsRef.nativeElement;
610
+ if (target) {
611
+ target.updateWorldMatrix(true, true);
612
+ box.setFromObject(target);
613
+ }
614
+ }
615
+ if (box.isEmpty()) {
616
+ const max = camera.position.length() || 10;
617
+ box.setFromCenterAndSize(new THREE.Vector3(), new THREE.Vector3(max, max, max));
618
+ }
619
+ if (controls?.constructor.name === 'OrthographicTrackballControls') {
620
+ // put camera on a sphere along which it would move
621
+ const { distance } = getSize();
622
+ const direction = camera.position.clone().sub(controls.target).normalize().multiplyScalar(distance);
623
+ const newPos = controls.target.clone().add(direction);
624
+ camera.position.copy(newPos);
625
+ }
626
+ return this;
627
+ },
628
+ clip() {
629
+ const { distance } = getSize();
630
+ const { camera, controls: storeControls, invalidate } = store.get();
631
+ const controls = storeControls;
632
+ if (controls)
633
+ controls.maxDistance = distance * 10;
634
+ camera.near = distance / 100;
635
+ camera.far = distance * 100;
636
+ camera.updateProjectionMatrix();
637
+ if (controls)
638
+ controls.update();
639
+ invalidate();
640
+ return this;
641
+ },
642
+ to({ position, target }) {
643
+ const { camera } = store.get();
644
+ const { damping } = bounds.get();
645
+ bounds.current.camera.copy(camera.position);
646
+ const { center } = getSize();
647
+ bounds.goal.camera.set(...position);
648
+ if (target) {
649
+ bounds.goal.focus.set(...target);
650
+ }
651
+ else {
652
+ bounds.goal.focus.copy(center);
653
+ }
654
+ if (damping) {
655
+ bounds.current.animating = true;
656
+ }
657
+ else {
658
+ camera.position.set(...position);
659
+ }
660
+ return this;
661
+ },
662
+ fit() {
663
+ const { camera, controls: storeControls, invalidate } = store.get();
664
+ const controls = storeControls;
665
+ const { damping, margin } = bounds.get();
666
+ bounds.current.camera.copy(camera.position);
667
+ if (controls)
668
+ bounds.current.focus.copy(controls.target);
669
+ const { center, distance } = getSize();
670
+ const direction = center.clone().sub(camera.position).normalize().multiplyScalar(distance);
671
+ bounds.goal.camera.copy(center).sub(direction);
672
+ bounds.goal.focus.copy(center);
673
+ if (is.orthographicCamera(camera)) {
674
+ bounds.current.zoom = camera.zoom;
675
+ let maxHeight = 0, maxWidth = 0;
676
+ const vertices = [
677
+ new THREE.Vector3(box.min.x, box.min.y, box.min.z),
678
+ new THREE.Vector3(box.min.x, box.max.y, box.min.z),
679
+ new THREE.Vector3(box.min.x, box.min.y, box.max.z),
680
+ new THREE.Vector3(box.min.x, box.max.y, box.max.z),
681
+ new THREE.Vector3(box.max.x, box.max.y, box.max.z),
682
+ new THREE.Vector3(box.max.x, box.max.y, box.min.z),
683
+ new THREE.Vector3(box.max.x, box.min.y, box.max.z),
684
+ new THREE.Vector3(box.max.x, box.min.y, box.min.z),
685
+ ];
686
+ // Transform the center and each corner to camera space
687
+ center.applyMatrix4(camera.matrixWorldInverse);
688
+ for (const v of vertices) {
689
+ v.applyMatrix4(camera.matrixWorldInverse);
690
+ maxHeight = Math.max(maxHeight, Math.abs(v.y - center.y));
691
+ maxWidth = Math.max(maxWidth, Math.abs(v.x - center.x));
692
+ }
693
+ maxHeight *= 2;
694
+ maxWidth *= 2;
695
+ const zoomForHeight = (camera.top - camera.bottom) / maxHeight;
696
+ const zoomForWidth = (camera.right - camera.left) / maxWidth;
697
+ bounds.goal.zoom = Math.min(zoomForHeight, zoomForWidth) / margin;
698
+ if (!damping) {
699
+ camera.zoom = bounds.goal.zoom;
700
+ camera.updateProjectionMatrix();
701
+ }
702
+ }
703
+ if (damping) {
704
+ bounds.current.animating = true;
705
+ }
706
+ else {
707
+ camera.position.copy(bounds.goal.camera);
708
+ camera.lookAt(bounds.goal.focus);
709
+ if (controls) {
710
+ controls.target.copy(bounds.goal.focus);
711
+ controls.update();
712
+ }
713
+ }
714
+ if (bounds.fitted.observed)
715
+ bounds.fitted.emit(this.getSize());
716
+ invalidate();
717
+ return this;
718
+ },
719
+ };
720
+ let count = 0;
721
+ bounds.hold(bounds.boundsRef.$.pipe(switchMap(() => combineLatest([
722
+ bounds.select('clip'),
723
+ bounds.select('fit'),
724
+ bounds.select('observe'),
725
+ store.select('camera'),
726
+ store.select('controls'),
727
+ store.select('size'),
728
+ bounds.boundsRef.children$(),
729
+ ]))), ([clip, fit, observe]) => {
730
+ if (observe || count++ === 0) {
731
+ api.refresh();
732
+ if (fit)
733
+ api.fit();
734
+ if (clip)
735
+ api.clip();
736
+ }
737
+ });
738
+ injectBeforeRender(({ delta }) => {
739
+ if (bounds.current.animating) {
740
+ const { damping, eps } = bounds.get();
741
+ const { camera, controls: storeControls, invalidate } = store.get();
742
+ const controls = storeControls;
743
+ damp(bounds.current.focus, bounds.goal.focus, damping, delta);
744
+ damp(bounds.current.camera, bounds.goal.camera, damping, delta);
745
+ bounds.current.zoom = THREE.MathUtils.damp(bounds.current.zoom, bounds.goal.zoom, damping, delta);
746
+ camera.position.copy(bounds.current.camera);
747
+ if (is.orthographicCamera(camera)) {
748
+ camera.zoom = bounds.current.zoom;
749
+ camera.updateProjectionMatrix();
750
+ }
751
+ if (!controls) {
752
+ camera.lookAt(bounds.current.focus);
753
+ }
754
+ else {
755
+ controls.target.copy(bounds.current.focus);
756
+ controls.update();
757
+ }
758
+ invalidate();
759
+ if (is.orthographicCamera(camera) && !(Math.abs(bounds.current.zoom - bounds.goal.zoom) < eps))
760
+ return;
761
+ if (!is.orthographicCamera(camera) && !equals(bounds.current.camera, bounds.goal.camera, eps))
762
+ return;
763
+ if (controls && !equals(bounds.current.focus, bounds.goal.focus, eps))
764
+ return;
765
+ bounds.current.animating = false;
766
+ }
767
+ });
768
+ return api;
769
+ }
770
+ extend({ Group });
771
+ class NgtsBounds extends NgtRxStore {
772
+ constructor() {
773
+ super(...arguments);
774
+ this.boundsRef = injectNgtRef();
775
+ this.fitted = new EventEmitter();
776
+ this.store = inject(NgtStore);
777
+ this.current = { animating: false, focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
778
+ this.goal = { focus: new THREE.Vector3(), camera: new THREE.Vector3(), zoom: 1 };
779
+ }
780
+ set damping(damping) {
781
+ this.set({ damping });
782
+ }
783
+ set fit(fit) {
784
+ this.set({ fit });
785
+ }
786
+ set clip(clip) {
787
+ this.set({ clip });
788
+ }
789
+ set observe(observe) {
790
+ this.set({ observe });
791
+ }
792
+ set margin(margin) {
793
+ this.set({ margin });
794
+ }
795
+ set eps(eps) {
796
+ this.set({ eps });
797
+ }
798
+ initialize() {
799
+ super.initialize();
800
+ this.set({ damping: 6, fit: false, clip: false, observe: false, margin: 1.2, eps: 0.01 });
801
+ }
802
+ ngOnInit() {
803
+ this.preventDragHijacking();
804
+ }
805
+ preventDragHijacking() {
806
+ this.effect(this.store.select('controls'), (controls) => {
807
+ if (controls) {
808
+ const callback = () => (this.current.animating = false);
809
+ controls.addEventListener('start', callback);
810
+ return () => controls.removeEventListener('start', callback);
811
+ }
812
+ });
813
+ }
814
+ }
815
+ NgtsBounds.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsBounds, deps: null, target: i0.ɵɵFactoryTarget.Component });
816
+ NgtsBounds.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsBounds, isStandalone: true, selector: "ngts-bounds", inputs: { boundsRef: "boundsRef", damping: "damping", fit: "fit", clip: "clip", observe: "observe", margin: "margin", eps: "eps" }, outputs: { fitted: "fitted" }, providers: [{ provide: NGTS_BOUNDS_API, useFactory: boundsApiFactory, deps: [NgtsBounds] }], usesInheritance: true, ngImport: i0, template: `
817
+ <ngt-group ngtCompound [ref]="boundsRef">
818
+ <ng-content />
819
+ </ngt-group>
820
+ `, isInline: true });
821
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsBounds, decorators: [{
822
+ type: Component,
823
+ args: [{
824
+ selector: 'ngts-bounds',
825
+ standalone: true,
826
+ template: `
827
+ <ngt-group ngtCompound [ref]="boundsRef">
828
+ <ng-content />
829
+ </ngt-group>
830
+ `,
831
+ providers: [{ provide: NGTS_BOUNDS_API, useFactory: boundsApiFactory, deps: [NgtsBounds] }],
832
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
833
+ }]
834
+ }], propDecorators: { boundsRef: [{
835
+ type: Input
836
+ }], damping: [{
837
+ type: Input
838
+ }], fit: [{
839
+ type: Input
840
+ }], clip: [{
841
+ type: Input
842
+ }], observe: [{
843
+ type: Input
844
+ }], margin: [{
845
+ type: Input
846
+ }], eps: [{
847
+ type: Input
848
+ }], fitted: [{
849
+ type: Output
850
+ }] } });
851
+
852
+ extend({ Group });
853
+ class NgtsCenter extends NgtRxStore {
854
+ constructor() {
855
+ super(...arguments);
856
+ this.centerRef = injectNgtRef();
857
+ this.outerRef = injectNgtRef();
858
+ this.innerRef = injectNgtRef();
859
+ this.centered = new EventEmitter();
860
+ }
861
+ set top(top) {
862
+ this.set({ top });
863
+ }
864
+ set right(right) {
865
+ this.set({ right });
866
+ }
867
+ set bottom(bottom) {
868
+ this.set({ bottom });
869
+ }
870
+ set left(left) {
871
+ this.set({ left });
872
+ }
873
+ set front(front) {
874
+ this.set({ front });
875
+ }
876
+ set back(back) {
877
+ this.set({ back });
878
+ }
879
+ set disableX(disableX) {
880
+ this.set({ disableX });
881
+ }
882
+ set disableY(disableY) {
883
+ this.set({ disableY });
884
+ }
885
+ set disableZ(disableZ) {
886
+ this.set({ disableZ });
887
+ }
888
+ set disabled(disabled) {
889
+ this.set({ disabled });
890
+ }
891
+ set precise(precise) {
892
+ this.set({ precise });
893
+ }
894
+ initialize() {
895
+ super.initialize();
896
+ this.set({ precise: true });
897
+ }
898
+ ngOnInit() {
899
+ this.setPosition();
900
+ }
901
+ setPosition() {
902
+ this.hold(combineLatest([this.innerRef.$, this.innerRef.children$()]), ([innerGroup]) => {
903
+ const { precise, top, left, front, disabled, disableX, disableY, disableZ, back, bottom, right } = this.get();
904
+ this.outerRef.nativeElement.matrixWorld.identity();
905
+ const box3 = new Box3().setFromObject(innerGroup, precise);
906
+ const center = new Vector3();
907
+ const sphere = new Sphere();
908
+ const width = box3.max.x - box3.min.x;
909
+ const height = box3.max.y - box3.min.y;
910
+ const depth = box3.max.z - box3.min.z;
911
+ box3.getCenter(center);
912
+ box3.getBoundingSphere(sphere);
913
+ const vAlign = top ? height / 2 : bottom ? -height / 2 : 0;
914
+ const hAlign = left ? -width / 2 : right ? width / 2 : 0;
915
+ const dAlign = front ? depth / 2 : back ? -depth / 2 : 0;
916
+ this.outerRef.nativeElement.position.set(disabled || disableX ? 0 : -center.x + hAlign, disabled || disableY ? 0 : -center.y + vAlign, disabled || disableZ ? 0 : -center.z + dAlign);
917
+ if (this.centered.observed) {
918
+ this.centered.emit({
919
+ parent: this.centerRef.nativeElement.parent,
920
+ container: this.centerRef.nativeElement,
921
+ width,
922
+ height,
923
+ depth,
924
+ boundingBox: box3,
925
+ boundingSphere: sphere,
926
+ center: center,
927
+ verticalAlignment: vAlign,
928
+ horizontalAlignment: hAlign,
929
+ depthAlignment: dAlign,
930
+ });
931
+ }
932
+ });
933
+ }
934
+ }
935
+ NgtsCenter.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsCenter, deps: null, target: i0.ɵɵFactoryTarget.Component });
936
+ NgtsCenter.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsCenter, isStandalone: true, selector: "ngts-center", inputs: { centerRef: "centerRef", top: "top", right: "right", bottom: "bottom", left: "left", front: "front", back: "back", disableX: "disableX", disableY: "disableY", disableZ: "disableZ", disabled: "disabled", precise: "precise" }, outputs: { centered: "centered" }, usesInheritance: true, ngImport: i0, template: `
937
+ <ngt-group ngtCompound [ref]="centerRef">
938
+ <ngt-group [ref]="outerRef">
939
+ <ngt-group [ref]="innerRef">
940
+ <ng-content />
941
+ </ngt-group>
942
+ </ngt-group>
943
+ </ngt-group>
944
+ `, isInline: true });
945
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsCenter, decorators: [{
946
+ type: Component,
947
+ args: [{
948
+ selector: 'ngts-center',
949
+ standalone: true,
950
+ template: `
951
+ <ngt-group ngtCompound [ref]="centerRef">
952
+ <ngt-group [ref]="outerRef">
953
+ <ngt-group [ref]="innerRef">
954
+ <ng-content />
955
+ </ngt-group>
956
+ </ngt-group>
957
+ </ngt-group>
958
+ `,
959
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
960
+ }]
961
+ }], propDecorators: { centerRef: [{
962
+ type: Input
963
+ }], top: [{
964
+ type: Input
965
+ }], right: [{
966
+ type: Input
967
+ }], bottom: [{
968
+ type: Input
969
+ }], left: [{
970
+ type: Input
971
+ }], front: [{
972
+ type: Input
973
+ }], back: [{
974
+ type: Input
975
+ }], disableX: [{
976
+ type: Input
977
+ }], disableY: [{
978
+ type: Input
979
+ }], disableZ: [{
980
+ type: Input
981
+ }], disabled: [{
982
+ type: Input
983
+ }], precise: [{
984
+ type: Input
985
+ }], centered: [{
986
+ type: Output
987
+ }] } });
988
+
989
+ extend({ Group, Mesh, MeshBasicMaterial, OrthographicCamera });
990
+ class NgtsContactShadows extends NgtRxStore {
991
+ set opacity(opacity) {
992
+ this.set({ opacity });
993
+ }
994
+ set width(width) {
995
+ this.set({ width });
996
+ }
997
+ set height(height) {
998
+ this.set({ height });
999
+ }
1000
+ set blur(blur) {
1001
+ this.set({ blur });
1002
+ }
1003
+ set far(far) {
1004
+ this.set({ far });
1005
+ }
1006
+ set smooth(smooth) {
1007
+ this.set({ smooth });
1008
+ }
1009
+ set resolution(resolution) {
1010
+ this.set({ resolution });
1011
+ }
1012
+ set frames(frames) {
1013
+ this.set({ frames });
1014
+ }
1015
+ set scale(scale) {
1016
+ this.set({ scale });
1017
+ }
1018
+ set color(color) {
1019
+ this.set({ color });
1020
+ }
1021
+ set depthWrite(depthWrite) {
1022
+ this.set({ depthWrite });
1023
+ }
1024
+ set renderOrder(renderOrder) {
1025
+ this.set({ renderOrder });
1026
+ }
1027
+ constructor() {
1028
+ super();
1029
+ this.store = inject(NgtStore);
1030
+ this.shadowCameraRef = injectNgtRef();
1031
+ this.encoding = this.store.get('gl', 'outputEncoding');
1032
+ this.contactShadows$ = this.select('contactShadows');
1033
+ this.Math = Math;
1034
+ this.contactShadowsRef = injectNgtRef();
1035
+ injectBeforeRender(this.onBeforeRender.bind(this, 0));
1036
+ }
1037
+ initialize() {
1038
+ super.initialize();
1039
+ this.set({
1040
+ scale: 10,
1041
+ frames: Infinity,
1042
+ opacity: 1,
1043
+ width: 1,
1044
+ height: 1,
1045
+ blur: 1,
1046
+ far: 10,
1047
+ resolution: 512,
1048
+ smooth: true,
1049
+ color: '#000000',
1050
+ depthWrite: false,
1051
+ renderOrder: 0,
1052
+ });
1053
+ this.connect('scaledWidth', this.select(['width', 'scale'], ({ width, scale }) => width * (Array.isArray(scale) ? scale[0] : scale || 1)));
1054
+ this.connect('scaledHeight', this.select(['height', 'scale'], ({ height, scale }) => height * (Array.isArray(scale) ? scale[1] : scale || 1)));
1055
+ this.connect('cameraArgs', this.select(['scaledWidth', 'scaledHeight', 'far'], ({ scaledWidth: width, scaledHeight: height, far }) => {
1056
+ return [-width / 2, width / 2, height / 2, -height / 2, 0, far];
1057
+ }));
1058
+ this.connect('contactShadows', this.select(['resolution', 'scaledWidth', 'scaledHeight', 'scale', 'color'], ({ resolution, scaledWidth: width, scaledHeight: height, color }) => {
1059
+ const renderTarget = new THREE.WebGLRenderTarget(resolution, resolution);
1060
+ const renderTargetBlur = new THREE.WebGLRenderTarget(resolution, resolution);
1061
+ renderTargetBlur.texture.generateMipmaps = renderTarget.texture.generateMipmaps = false;
1062
+ const planeGeometry = new THREE.PlaneGeometry(width, height).rotateX(Math.PI / 2);
1063
+ const blurPlane = new Mesh(planeGeometry);
1064
+ const depthMaterial = new THREE.MeshDepthMaterial();
1065
+ depthMaterial.depthTest = depthMaterial.depthWrite = false;
1066
+ depthMaterial.onBeforeCompile = (shader) => {
1067
+ shader.uniforms = {
1068
+ ...shader.uniforms,
1069
+ ucolor: { value: new THREE.Color(color) },
1070
+ };
1071
+ shader.fragmentShader = shader.fragmentShader.replace(`void main() {`, //
1072
+ `uniform vec3 ucolor;
1073
+ void main() {
1074
+ `);
1075
+ shader.fragmentShader = shader.fragmentShader.replace('vec4( vec3( 1.0 - fragCoordZ ), opacity );',
1076
+ // Colorize the shadow, multiply by the falloff so that the center can remain darker
1077
+ 'vec4( ucolor * fragCoordZ * 2.0, ( 1.0 - fragCoordZ ) * 1.0 );');
1078
+ };
1079
+ const horizontalBlurMaterial = new THREE.ShaderMaterial(HorizontalBlurShader);
1080
+ const verticalBlurMaterial = new THREE.ShaderMaterial(VerticalBlurShader);
1081
+ verticalBlurMaterial.depthTest = horizontalBlurMaterial.depthTest = false;
1082
+ return {
1083
+ renderTarget,
1084
+ planeGeometry,
1085
+ depthMaterial,
1086
+ blurPlane,
1087
+ horizontalBlurMaterial,
1088
+ verticalBlurMaterial,
1089
+ renderTargetBlur,
1090
+ };
1091
+ }));
1092
+ }
1093
+ onBeforeRender(count, { scene, gl }) {
1094
+ const { frames, blur, contactShadows: { depthMaterial, renderTarget }, smooth, } = this.get();
1095
+ if (this.shadowCameraRef.nativeElement && (frames === Infinity || count < frames)) {
1096
+ const initialBackground = scene.background;
1097
+ scene.background = null;
1098
+ const initialOverrideMaterial = scene.overrideMaterial;
1099
+ scene.overrideMaterial = depthMaterial;
1100
+ gl.setRenderTarget(renderTarget);
1101
+ gl.render(scene, this.shadowCameraRef.nativeElement);
1102
+ scene.overrideMaterial = initialOverrideMaterial;
1103
+ this.blurShadows(blur);
1104
+ if (smooth)
1105
+ this.blurShadows(blur * 0.4);
1106
+ gl.setRenderTarget(null);
1107
+ scene.background = initialBackground;
1108
+ count++;
1109
+ }
1110
+ }
1111
+ blurShadows(blur) {
1112
+ const { blurPlane, horizontalBlurMaterial, verticalBlurMaterial, renderTargetBlur, renderTarget } = this.get('contactShadows');
1113
+ const gl = this.store.get('gl');
1114
+ blurPlane.visible = true;
1115
+ blurPlane.material = horizontalBlurMaterial;
1116
+ horizontalBlurMaterial.uniforms.tDiffuse.value = renderTarget.texture;
1117
+ horizontalBlurMaterial.uniforms.h.value = (blur * 1) / 256;
1118
+ gl.setRenderTarget(renderTargetBlur);
1119
+ gl.render(blurPlane, this.shadowCameraRef.nativeElement);
1120
+ blurPlane.material = verticalBlurMaterial;
1121
+ verticalBlurMaterial.uniforms.tDiffuse.value = renderTargetBlur.texture;
1122
+ verticalBlurMaterial.uniforms.v.value = (blur * 1) / 256;
1123
+ gl.setRenderTarget(renderTarget);
1124
+ gl.render(blurPlane, this.shadowCameraRef.nativeElement);
1125
+ blurPlane.visible = false;
1126
+ }
1127
+ }
1128
+ NgtsContactShadows.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsContactShadows, deps: [], target: i0.ɵɵFactoryTarget.Component });
1129
+ NgtsContactShadows.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsContactShadows, isStandalone: true, selector: "ngts-contact-shadows", inputs: { contactShadowsRef: "contactShadowsRef", opacity: "opacity", width: "width", height: "height", blur: "blur", far: "far", smooth: "smooth", resolution: "resolution", frames: "frames", scale: "scale", color: "color", depthWrite: "depthWrite", renderOrder: "renderOrder" }, usesInheritance: true, ngImport: i0, template: `
1130
+ <ngt-group ngtCompound [ref]="contactShadowsRef" [rotation]="[Math.PI / 2, 0, 0]">
1131
+ <ng-container *ngIf="contactShadows$ | ngtPush : null as contactShadows">
1132
+ <ngt-mesh
1133
+ [renderOrder]="get('renderOrder')"
1134
+ [geometry]="contactShadows.planeGeometry"
1135
+ [scale]="[1, -1, 1]"
1136
+ [rotation]="[-Math.PI / 2, 0, 0]"
1137
+ >
1138
+ <ngt-mesh-basic-material
1139
+ [map]="contactShadows.renderTarget.texture"
1140
+ transparent
1141
+ [opacity]="get('opacity')"
1142
+ [depthWrite]="get('depthWrite')"
1143
+ >
1144
+ <ngt-value [rawValue]="encoding" attach="map.encoding" />
1145
+ </ngt-mesh-basic-material>
1146
+ </ngt-mesh>
1147
+ <ngt-orthographic-camera *args="get('cameraArgs')" [ref]="shadowCameraRef" />
1148
+ </ng-container>
1149
+ </ngt-group>
1150
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: NgtPush, name: "ngtPush" }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] });
1151
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsContactShadows, decorators: [{
1152
+ type: Component,
1153
+ args: [{
1154
+ selector: 'ngts-contact-shadows',
1155
+ standalone: true,
1156
+ template: `
1157
+ <ngt-group ngtCompound [ref]="contactShadowsRef" [rotation]="[Math.PI / 2, 0, 0]">
1158
+ <ng-container *ngIf="contactShadows$ | ngtPush : null as contactShadows">
1159
+ <ngt-mesh
1160
+ [renderOrder]="get('renderOrder')"
1161
+ [geometry]="contactShadows.planeGeometry"
1162
+ [scale]="[1, -1, 1]"
1163
+ [rotation]="[-Math.PI / 2, 0, 0]"
1164
+ >
1165
+ <ngt-mesh-basic-material
1166
+ [map]="contactShadows.renderTarget.texture"
1167
+ transparent
1168
+ [opacity]="get('opacity')"
1169
+ [depthWrite]="get('depthWrite')"
1170
+ >
1171
+ <ngt-value [rawValue]="encoding" attach="map.encoding" />
1172
+ </ngt-mesh-basic-material>
1173
+ </ngt-mesh>
1174
+ <ngt-orthographic-camera *args="get('cameraArgs')" [ref]="shadowCameraRef" />
1175
+ </ng-container>
1176
+ </ngt-group>
1177
+ `,
1178
+ imports: [NgIf, NgtPush, NgtArgs],
1179
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1180
+ }]
1181
+ }], ctorParameters: function () { return []; }, propDecorators: { contactShadowsRef: [{
1182
+ type: Input
1183
+ }], opacity: [{
1184
+ type: Input
1185
+ }], width: [{
1186
+ type: Input
1187
+ }], height: [{
1188
+ type: Input
1189
+ }], blur: [{
1190
+ type: Input
1191
+ }], far: [{
1192
+ type: Input
1193
+ }], smooth: [{
1194
+ type: Input
1195
+ }], resolution: [{
1196
+ type: Input
1197
+ }], frames: [{
1198
+ type: Input
1199
+ }], scale: [{
1200
+ type: Input
1201
+ }], color: [{
1202
+ type: Input
1203
+ }], depthWrite: [{
1204
+ type: Input
1205
+ }], renderOrder: [{
1206
+ type: Input
1207
+ }] } });
1208
+
1209
+ const ngtsEnvironmentPresetsObj = {
1210
+ sunset: 'venice/venice_sunset_1k.hdr',
1211
+ dawn: 'kiara/kiara_1_dawn_1k.hdr',
1212
+ night: 'dikhololo/dikhololo_night_1k.hdr',
1213
+ warehouse: 'empty-wharehouse/empty_warehouse_01_1k.hdr',
1214
+ forest: 'forrest-slope/forest_slope_1k.hdr',
1215
+ apartment: 'lebombo/lebombo_1k.hdr',
1216
+ studio: 'studio-small-3/studio_small_03_1k.hdr',
1217
+ city: 'potsdamer-platz/potsdamer_platz_1k.hdr',
1218
+ park: 'rooitou/rooitou_park_1k.hdr',
1219
+ lobby: 'st-fagans/st_fagans_interior_1k.hdr',
1220
+ };
1221
+
1222
+ class NgtsEnvironmentInputs extends NgtRxStore {
1223
+ constructor() {
1224
+ super(...arguments);
1225
+ this.store = inject(NgtStore);
1226
+ }
1227
+ set frames(frames) {
1228
+ this.set({ frames });
1229
+ }
1230
+ set near(near) {
1231
+ this.set({ near });
1232
+ }
1233
+ set far(far) {
1234
+ this.set({ far });
1235
+ }
1236
+ set resolution(resolution) {
1237
+ this.set({ resolution });
1238
+ }
1239
+ set background(background) {
1240
+ this.set({ background });
1241
+ }
1242
+ set blur(blur) {
1243
+ this.set({ blur });
1244
+ }
1245
+ set map(map) {
1246
+ this.set({ map });
1247
+ }
1248
+ set files(files) {
1249
+ this.set({ files });
1250
+ }
1251
+ set path(path) {
1252
+ this.set({ path });
1253
+ }
1254
+ set preset(preset) {
1255
+ this.set({ preset });
1256
+ }
1257
+ set scene(scene) {
1258
+ this.set({ scene });
1259
+ }
1260
+ set extensions(extensions) {
1261
+ this.set({ extensions });
1262
+ }
1263
+ set ground(ground) {
1264
+ this.set({ ground });
1265
+ }
1266
+ set encoding(encoding) {
1267
+ this.set({ encoding });
1268
+ }
1269
+ }
1270
+ NgtsEnvironmentInputs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentInputs, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1271
+ NgtsEnvironmentInputs.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentInputs, inputs: { frames: "frames", near: "near", far: "far", resolution: "resolution", background: "background", blur: "blur", map: "map", files: "files", path: "path", preset: "preset", scene: "scene", extensions: "extensions", ground: "ground", encoding: "encoding" }, usesInheritance: true, ngImport: i0 });
1272
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentInputs, decorators: [{
1273
+ type: Directive
1274
+ }], propDecorators: { frames: [{
1275
+ type: Input
1276
+ }], near: [{
1277
+ type: Input
1278
+ }], far: [{
1279
+ type: Input
1280
+ }], resolution: [{
1281
+ type: Input
1282
+ }], background: [{
1283
+ type: Input
1284
+ }], blur: [{
1285
+ type: Input
1286
+ }], map: [{
1287
+ type: Input
1288
+ }], files: [{
1289
+ type: Input
1290
+ }], path: [{
1291
+ type: Input
1292
+ }], preset: [{
1293
+ type: Input
1294
+ }], scene: [{
1295
+ type: Input
1296
+ }], extensions: [{
1297
+ type: Input
1298
+ }], ground: [{
1299
+ type: Input
1300
+ }], encoding: [{
1301
+ type: Input
1302
+ }] } });
1303
+
1304
+ function resolveScene(scene) {
1305
+ return is.ref(scene) ? scene.nativeElement : scene;
1306
+ }
1307
+ function setEnvProps(background, scene, defaultScene, texture, blur = 0) {
1308
+ const target = resolveScene(scene || defaultScene);
1309
+ const oldbg = target.background;
1310
+ const oldenv = target.environment;
1311
+ const oldBlur = target.backgroundBlurriness || 0;
1312
+ if (background !== 'only')
1313
+ target.environment = texture;
1314
+ if (background)
1315
+ target.background = texture;
1316
+ if (background && target.backgroundBlurriness !== undefined)
1317
+ target.backgroundBlurriness = blur;
1318
+ return () => {
1319
+ if (background !== 'only')
1320
+ target.environment = oldenv;
1321
+ if (background)
1322
+ target.background = oldbg;
1323
+ if (background && target.backgroundBlurriness !== undefined)
1324
+ target.backgroundBlurriness = oldBlur;
1325
+ };
1326
+ }
1327
+ const CUBEMAP_ROOT = 'https://market-assets.fra1.cdn.digitaloceanspaces.com/market-assets/hdris/';
1328
+ function injectNgtsEnvironment(paramsFactory) {
1329
+ let p = {
1330
+ files: ['/px.png', '/nx.png', '/py.png', '/ny.png', '/pz.png', '/nz.png'],
1331
+ path: '',
1332
+ preset: undefined,
1333
+ encoding: undefined,
1334
+ };
1335
+ const params = paramsFactory(p);
1336
+ const params$ = isObservable(params) ? params : of(params);
1337
+ const textureRef = injectNgtRef();
1338
+ const { destroy$ } = injectNgtDestroy(() => {
1339
+ textureRef.nativeElement?.dispose();
1340
+ });
1341
+ const loaderResult = injectNgtLoader((inputs) => (Array.isArray(inputs) ? CubeTextureLoader : RGBELoader), params$.pipe(debounceTime(0), map((data) => {
1342
+ p = data;
1343
+ return p;
1344
+ }), map((data) => {
1345
+ if (data.preset) {
1346
+ if (!(data.preset in ngtsEnvironmentPresetsObj))
1347
+ throw new Error('Preset must be one of: ' + Object.keys(ngtsEnvironmentPresetsObj).join(', '));
1348
+ data.files = ngtsEnvironmentPresetsObj[data.preset];
1349
+ data.path = CUBEMAP_ROOT;
1350
+ }
1351
+ return Array.isArray(data.files) ? [data.files] : data.files;
1352
+ })), (loader) => {
1353
+ if (p.path) {
1354
+ loader.setPath(p.path);
1355
+ }
1356
+ if (p.extensions) {
1357
+ p.extensions(loader);
1358
+ }
1359
+ });
1360
+ loaderResult.pipe(takeUntil(destroy$)).subscribe((results) => {
1361
+ const texture = Array.isArray(p.files) ? results[0] : results;
1362
+ texture.mapping = Array.isArray(p.files) ? CubeReflectionMapping : EquirectangularReflectionMapping;
1363
+ texture.encoding = (p.encoding ?? Array.isArray(p.files)) ? sRGBEncoding : LinearEncoding;
1364
+ textureRef.nativeElement = texture;
1365
+ });
1366
+ return textureRef;
1367
+ }
1368
+
1369
+ class NgtsEnvironmentCube extends NgtsEnvironmentInputs {
1370
+ constructor() {
1371
+ super(...arguments);
1372
+ this.textureRef = injectNgtsEnvironment((params) => this.select().pipe(startWith(params)));
1373
+ }
1374
+ initialize() {
1375
+ super.initialize();
1376
+ this.set({ background: false });
1377
+ }
1378
+ ngOnInit() {
1379
+ this.setEnvProps();
1380
+ }
1381
+ setEnvProps() {
1382
+ this.effect(combineLatest([
1383
+ this.store.select('scene'),
1384
+ this.select('scene').pipe(startWithUndefined()),
1385
+ this.select('background'),
1386
+ this.select('blur').pipe(startWithUndefined()),
1387
+ this.textureRef.$,
1388
+ ]), ([defaultScene, scene, background, blur, texture]) => {
1389
+ return setEnvProps(background, scene, defaultScene, texture, blur);
1390
+ });
1391
+ }
1392
+ }
1393
+ NgtsEnvironmentCube.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentCube, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1394
+ NgtsEnvironmentCube.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentCube, isStandalone: true, selector: "ngts-environment-cube", usesInheritance: true, ngImport: i0 });
1395
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentCube, decorators: [{
1396
+ type: Directive,
1397
+ args: [{
1398
+ selector: 'ngts-environment-cube',
1399
+ standalone: true,
1400
+ }]
1401
+ }] });
1402
+
1403
+ class NgtsEnvironmentMap extends NgtsEnvironmentInputs {
1404
+ initialize() {
1405
+ super.initialize();
1406
+ this.set({ background: false });
1407
+ }
1408
+ ngOnInit() {
1409
+ this.setEnvProps();
1410
+ }
1411
+ setEnvProps() {
1412
+ this.effect(combineLatest([
1413
+ this.store.select('scene'),
1414
+ this.select('map'),
1415
+ this.select('scene').pipe(startWithUndefined()),
1416
+ this.select('background'),
1417
+ this.select('blur').pipe(startWithUndefined()),
1418
+ ]), ([defaultScene, map, scene, background, blur]) => {
1419
+ if (map) {
1420
+ return setEnvProps(background, scene, defaultScene, map, blur);
1421
+ }
1422
+ });
1423
+ }
1424
+ }
1425
+ NgtsEnvironmentMap.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentMap, deps: null, target: i0.ɵɵFactoryTarget.Directive });
1426
+ NgtsEnvironmentMap.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentMap, isStandalone: true, selector: "ngts-environment-map", usesInheritance: true, ngImport: i0 });
1427
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentMap, decorators: [{
1428
+ type: Directive,
1429
+ args: [{
1430
+ selector: 'ngts-environment-map',
1431
+ standalone: true,
1432
+ }]
1433
+ }] });
1434
+
1435
+ extend({ GroundProjectedEnv });
1436
+ class NgtsEnvironmentGround extends NgtsEnvironmentInputs {
1437
+ constructor() {
1438
+ super(...arguments);
1439
+ this.defaultTexture = injectNgtsEnvironment((params) => this.select().pipe(startWith(params)));
1440
+ }
1441
+ ngOnInit() {
1442
+ this.connect('texture', combineLatest([this.select('map').pipe(startWithUndefined()), this.defaultTexture.$]).pipe(map(([map, texture]) => map || texture)));
1443
+ this.connect('groundArgs', this.select('texture').pipe(map((texture) => [texture])));
1444
+ this.connect('groundHeight', this.select(['ground'], ({ ground }) => ground?.height));
1445
+ this.connect('groundRadius', this.select(['ground'], ({ ground }) => ground?.radius));
1446
+ this.connect('groundScale', this.select(['ground'], ({ ground }) => ground?.scale ?? 1000));
1447
+ }
1448
+ }
1449
+ NgtsEnvironmentGround.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentGround, deps: null, target: i0.ɵɵFactoryTarget.Component });
1450
+ NgtsEnvironmentGround.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentGround, isStandalone: true, selector: "ngts-environment-ground", usesInheritance: true, ngImport: i0, template: `
1451
+ <ngts-environment-map
1452
+ [background]="get('background')"
1453
+ [blur]="get('blur')"
1454
+ [scene]="get('scene')"
1455
+ [map]="get('texture')"
1456
+ />
1457
+ <ng-container *ngIf="get('groundArgs') as groundArgs">
1458
+ <ngt-ground-projected-env
1459
+ *args="groundArgs"
1460
+ [scale]="get('groundScale')"
1461
+ [height]="get('groundHeight')"
1462
+ [radius]="get('groundRadius')"
1463
+ />
1464
+ </ng-container>
1465
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
1466
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentGround, decorators: [{
1467
+ type: Component,
1468
+ args: [{
1469
+ selector: 'ngts-environment-ground',
1470
+ standalone: true,
1471
+ template: `
1472
+ <ngts-environment-map
1473
+ [background]="get('background')"
1474
+ [blur]="get('blur')"
1475
+ [scene]="get('scene')"
1476
+ [map]="get('texture')"
1477
+ />
1478
+ <ng-container *ngIf="get('groundArgs') as groundArgs">
1479
+ <ngt-ground-projected-env
1480
+ *args="groundArgs"
1481
+ [scale]="get('groundScale')"
1482
+ [height]="get('groundHeight')"
1483
+ [radius]="get('groundRadius')"
1484
+ />
1485
+ </ng-container>
1486
+ `,
1487
+ imports: [NgtsEnvironmentMap, NgtArgs, NgIf],
1488
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1489
+ }]
1490
+ }] });
1491
+
1492
+ extend({ CubeCamera });
1493
+ class NgtsEnvironmentPortal extends NgtsEnvironmentInputs {
1494
+ initialize() {
1495
+ super.initialize();
1496
+ this.set({ near: 1, far: 1000, resolution: 256, frames: 1, background: false, preset: undefined });
1497
+ this.connect('fbo', this.select(['resolution'], ({ resolution }) => {
1498
+ const fbo = new THREE.WebGLCubeRenderTarget(resolution);
1499
+ fbo.texture.type = HalfFloatType;
1500
+ return fbo;
1501
+ }));
1502
+ this.connect('cameraArgs', this.select(['fbo', 'near', 'far'], ({ near, far, fbo }) => [near, far, fbo]));
1503
+ }
1504
+ constructor() {
1505
+ super();
1506
+ this.virtualSceneRef = injectNgtRef(prepare(new THREE.Scene()));
1507
+ this.cubeCameraRef = injectNgtRef();
1508
+ injectBeforeRender(this.onBeforeRender.bind(this, 1));
1509
+ }
1510
+ ngOnInit() {
1511
+ this.setEnvProps();
1512
+ }
1513
+ setEnvProps() {
1514
+ this.effect(combineLatest([
1515
+ this.store.select('gl'),
1516
+ this.store.select('scene'),
1517
+ this.select('fbo'),
1518
+ this.select('scene'),
1519
+ this.select('background'),
1520
+ this.select('frames'),
1521
+ this.select('blur'),
1522
+ this.virtualSceneRef.$,
1523
+ this.cubeCameraRef.$,
1524
+ ]), ([gl, defaultScene, fbo, scene, background, frames, blur, virtualScene, camera]) => {
1525
+ if (frames === 1)
1526
+ camera.update(gl, virtualScene);
1527
+ return setEnvProps(background, scene, defaultScene, fbo.texture, blur);
1528
+ });
1529
+ }
1530
+ onBeforeRender(count, { gl }) {
1531
+ const { frames } = this.get();
1532
+ if (frames === Infinity || count < frames) {
1533
+ if (this.cubeCameraRef.nativeElement) {
1534
+ this.cubeCameraRef.nativeElement.update(gl, this.virtualSceneRef.nativeElement);
1535
+ count++;
1536
+ }
1537
+ }
1538
+ }
1539
+ }
1540
+ NgtsEnvironmentPortal.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentPortal, deps: [], target: i0.ɵɵFactoryTarget.Component });
1541
+ NgtsEnvironmentPortal.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentPortal, isStandalone: true, selector: "ngts-environment-portal", usesInheritance: true, ngImport: i0, template: `
1542
+ <ngt-portal [container]="virtualSceneRef">
1543
+ <ng-template ngtPortalContent>
1544
+ <ng-content />
1545
+ <ngt-cube-camera *args="get('cameraArgs')" [ref]="cubeCameraRef" />
1546
+ <ng-container *ngIf="get('files') || get('preset'); else environmentMap">
1547
+ <ngts-environment-cube
1548
+ [background]="true"
1549
+ [files]="get('files')"
1550
+ [preset]="get('preset')"
1551
+ [path]="get('path')"
1552
+ [extensions]="get('extensions')"
1553
+ />
1554
+ </ng-container>
1555
+ <ng-template #environmentMap>
1556
+ <ngts-environment-map [background]="true" [map]="get('map')" [extensions]="get('extensions')" />
1557
+ </ng-template>
1558
+ </ng-template>
1559
+ </ngt-portal>
1560
+ `, isInline: true, dependencies: [{ kind: "component", type: NgtPortal, selector: "ngt-portal", inputs: ["container", "state", "autoRender", "autoRenderPriority"], outputs: ["beforeRender"] }, { kind: "directive", type: NgtPortalContent, selector: "ng-template[ngtPortalContent]" }, { kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] });
1561
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentPortal, decorators: [{
1562
+ type: Component,
1563
+ args: [{
1564
+ selector: 'ngts-environment-portal',
1565
+ standalone: true,
1566
+ template: `
1567
+ <ngt-portal [container]="virtualSceneRef">
1568
+ <ng-template ngtPortalContent>
1569
+ <ng-content />
1570
+ <ngt-cube-camera *args="get('cameraArgs')" [ref]="cubeCameraRef" />
1571
+ <ng-container *ngIf="get('files') || get('preset'); else environmentMap">
1572
+ <ngts-environment-cube
1573
+ [background]="true"
1574
+ [files]="get('files')"
1575
+ [preset]="get('preset')"
1576
+ [path]="get('path')"
1577
+ [extensions]="get('extensions')"
1578
+ />
1579
+ </ng-container>
1580
+ <ng-template #environmentMap>
1581
+ <ngts-environment-map [background]="true" [map]="get('map')" [extensions]="get('extensions')" />
1582
+ </ng-template>
1583
+ </ng-template>
1584
+ </ngt-portal>
1585
+ `,
1586
+ imports: [NgtPortal, NgtPortalContent, NgtsEnvironmentMap, NgtsEnvironmentCube, NgIf, NgtArgs],
1587
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1588
+ }]
1589
+ }], ctorParameters: function () { return []; } });
1590
+
1591
+ class NgtsEnvironmentContent {
1592
+ }
1593
+ NgtsEnvironmentContent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentContent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1594
+ NgtsEnvironmentContent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironmentContent, isStandalone: true, selector: "ng-template[ngtsEnvironmentContent]", ngImport: i0 });
1595
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironmentContent, decorators: [{
1596
+ type: Directive,
1597
+ args: [{ selector: 'ng-template[ngtsEnvironmentContent]', standalone: true }]
1598
+ }] });
1599
+ class NgtsEnvironment extends NgtsEnvironmentInputs {
1600
+ }
1601
+ NgtsEnvironment.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironment, deps: null, target: i0.ɵɵFactoryTarget.Component });
1602
+ NgtsEnvironment.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsEnvironment, isStandalone: true, selector: "ngts-environment", queries: [{ propertyName: "content", first: true, predicate: NgtsEnvironmentContent, descendants: true, read: TemplateRef }], usesInheritance: true, ngImport: i0, template: `
1603
+ <ngts-environment-ground
1604
+ *ngIf="get('ground'); else noGround"
1605
+ [ground]="get('ground')"
1606
+ [map]="get('map')"
1607
+ [scene]="get('scene')"
1608
+ [blur]="get('blur')"
1609
+ [background]="get('background')"
1610
+ [preset]="get('preset')"
1611
+ [frames]="get('frames')"
1612
+ [far]="get('far')"
1613
+ [near]="get('near')"
1614
+ [resolution]="get('resolution')"
1615
+ [files]="get('files')"
1616
+ [path]="get('path')"
1617
+ [extensions]="get('extensions')"
1618
+ />
1619
+ <ng-template #noGround>
1620
+ <ngts-environment-map
1621
+ *ngIf="get('map'); else noMap"
1622
+ [map]="get('map')"
1623
+ [scene]="get('scene')"
1624
+ [blur]="get('blur')"
1625
+ [background]="get('background')"
1626
+ />
1627
+ <ng-template #noMap>
1628
+ <ngts-environment-portal
1629
+ *ngIf="content; else noPortal"
1630
+ [frames]="get('frames')"
1631
+ [far]="get('far')"
1632
+ [near]="get('near')"
1633
+ [resolution]="get('resolution')"
1634
+ [map]="get('map')"
1635
+ [background]="get('background')"
1636
+ [blur]="get('blur')"
1637
+ [scene]="get('scene')"
1638
+ [files]="get('files')"
1639
+ [path]="get('path')"
1640
+ [preset]="get('preset')"
1641
+ [extensions]="get('extensions')"
1642
+ >
1643
+ <ng-container *ngTemplateOutlet="content" />
1644
+ </ngts-environment-portal>
1645
+ <ng-template #noPortal>
1646
+ <ngts-environment-cube
1647
+ [frames]="get('frames')"
1648
+ [far]="get('far')"
1649
+ [near]="get('near')"
1650
+ [resolution]="get('resolution')"
1651
+ [map]="get('map')"
1652
+ [background]="get('background')"
1653
+ [blur]="get('blur')"
1654
+ [scene]="get('scene')"
1655
+ [files]="get('files')"
1656
+ [path]="get('path')"
1657
+ [preset]="get('preset')"
1658
+ [extensions]="get('extensions')"
1659
+ />
1660
+ </ng-template>
1661
+ </ng-template>
1662
+ </ng-template>
1663
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtsEnvironmentMap, selector: "ngts-environment-map" }, { kind: "component", type: NgtsEnvironmentGround, selector: "ngts-environment-ground" }, { kind: "directive", type: NgtsEnvironmentCube, selector: "ngts-environment-cube" }, { kind: "component", type: NgtsEnvironmentPortal, selector: "ngts-environment-portal" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1664
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsEnvironment, decorators: [{
1665
+ type: Component,
1666
+ args: [{
1667
+ selector: 'ngts-environment',
1668
+ standalone: true,
1669
+ template: `
1670
+ <ngts-environment-ground
1671
+ *ngIf="get('ground'); else noGround"
1672
+ [ground]="get('ground')"
1673
+ [map]="get('map')"
1674
+ [scene]="get('scene')"
1675
+ [blur]="get('blur')"
1676
+ [background]="get('background')"
1677
+ [preset]="get('preset')"
1678
+ [frames]="get('frames')"
1679
+ [far]="get('far')"
1680
+ [near]="get('near')"
1681
+ [resolution]="get('resolution')"
1682
+ [files]="get('files')"
1683
+ [path]="get('path')"
1684
+ [extensions]="get('extensions')"
1685
+ />
1686
+ <ng-template #noGround>
1687
+ <ngts-environment-map
1688
+ *ngIf="get('map'); else noMap"
1689
+ [map]="get('map')"
1690
+ [scene]="get('scene')"
1691
+ [blur]="get('blur')"
1692
+ [background]="get('background')"
1693
+ />
1694
+ <ng-template #noMap>
1695
+ <ngts-environment-portal
1696
+ *ngIf="content; else noPortal"
1697
+ [frames]="get('frames')"
1698
+ [far]="get('far')"
1699
+ [near]="get('near')"
1700
+ [resolution]="get('resolution')"
1701
+ [map]="get('map')"
1702
+ [background]="get('background')"
1703
+ [blur]="get('blur')"
1704
+ [scene]="get('scene')"
1705
+ [files]="get('files')"
1706
+ [path]="get('path')"
1707
+ [preset]="get('preset')"
1708
+ [extensions]="get('extensions')"
1709
+ >
1710
+ <ng-container *ngTemplateOutlet="content" />
1711
+ </ngts-environment-portal>
1712
+ <ng-template #noPortal>
1713
+ <ngts-environment-cube
1714
+ [frames]="get('frames')"
1715
+ [far]="get('far')"
1716
+ [near]="get('near')"
1717
+ [resolution]="get('resolution')"
1718
+ [map]="get('map')"
1719
+ [background]="get('background')"
1720
+ [blur]="get('blur')"
1721
+ [scene]="get('scene')"
1722
+ [files]="get('files')"
1723
+ [path]="get('path')"
1724
+ [preset]="get('preset')"
1725
+ [extensions]="get('extensions')"
1726
+ />
1727
+ </ng-template>
1728
+ </ng-template>
1729
+ </ng-template>
1730
+ `,
1731
+ imports: [
1732
+ NgtsEnvironmentMap,
1733
+ NgtsEnvironmentGround,
1734
+ NgtsEnvironmentCube,
1735
+ NgtsEnvironmentPortal,
1736
+ NgIf,
1737
+ NgTemplateOutlet,
1738
+ ],
1739
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1740
+ }]
1741
+ }], propDecorators: { content: [{
1742
+ type: ContentChild,
1743
+ args: [NgtsEnvironmentContent, { read: TemplateRef }]
1744
+ }] } });
1745
+
1746
+ extend({ Group });
1747
+ class NgtsFloat extends NgtRxStore {
1748
+ set speed(speed) {
1749
+ this.set({ speed });
1750
+ }
1751
+ set rotationIntensity(rotationIntensity) {
1752
+ this.set({ rotationIntensity });
1753
+ }
1754
+ set floatIntensity(floatIntensity) {
1755
+ this.set({ floatIntensity });
1756
+ }
1757
+ set floatingRange(floatingRange) {
1758
+ this.set({ floatingRange });
1759
+ }
1760
+ initialize() {
1761
+ super.initialize();
1762
+ this.set({ speed: 1, rotationIntensity: 1, floatIntensity: 1, floatingRange: [-0.1, 0.1] });
1763
+ }
1764
+ constructor() {
1765
+ super();
1766
+ this.offset = Math.random() * 10000;
1767
+ this.floatRef = injectNgtRef();
1768
+ injectBeforeRender(this.onBeforeRender.bind(this));
1769
+ }
1770
+ onBeforeRender({ clock }) {
1771
+ if (!this.floatRef.nativeElement)
1772
+ return;
1773
+ const { speed, floatingRange, floatIntensity, rotationIntensity } = this.get();
1774
+ const t = this.offset + clock.getElapsedTime();
1775
+ this.floatRef.nativeElement.rotation.x = (Math.cos((t / 4) * speed) / 8) * rotationIntensity;
1776
+ this.floatRef.nativeElement.rotation.y = (Math.sin((t / 4) * speed) / 8) * rotationIntensity;
1777
+ this.floatRef.nativeElement.rotation.z = (Math.sin((t / 4) * speed) / 20) * rotationIntensity;
1778
+ let yPosition = Math.sin((t / 4) * speed) / 10;
1779
+ yPosition = THREE.MathUtils.mapLinear(yPosition, -0.1, 0.1, floatingRange[0] ?? -0.1, floatingRange[1] ?? 0.1);
1780
+ this.floatRef.nativeElement.position.y = yPosition * floatIntensity;
1781
+ }
1782
+ }
1783
+ NgtsFloat.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsFloat, deps: [], target: i0.ɵɵFactoryTarget.Component });
1784
+ NgtsFloat.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsFloat, isStandalone: true, selector: "ngts-float", inputs: { floatRef: "floatRef", speed: "speed", rotationIntensity: "rotationIntensity", floatIntensity: "floatIntensity", floatingRange: "floatingRange" }, usesInheritance: true, ngImport: i0, template: `
1785
+ <ngt-group ngtCompound>
1786
+ <ngt-group [ref]="floatRef">
1787
+ <ng-content />
1788
+ </ngt-group>
1789
+ </ngt-group>
1790
+ `, isInline: true });
1791
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsFloat, decorators: [{
1792
+ type: Component,
1793
+ args: [{
1794
+ selector: 'ngts-float',
1795
+ standalone: true,
1796
+ template: `
1797
+ <ngt-group ngtCompound>
1798
+ <ngt-group [ref]="floatRef">
1799
+ <ng-content />
1800
+ </ngt-group>
1801
+ </ngt-group>
1802
+ `,
1803
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1804
+ }]
1805
+ }], ctorParameters: function () { return []; }, propDecorators: { floatRef: [{
1806
+ type: Input
1807
+ }], speed: [{
1808
+ type: Input
1809
+ }], rotationIntensity: [{
1810
+ type: Input
1811
+ }], floatIntensity: [{
1812
+ type: Input
1813
+ }], floatingRange: [{
1814
+ type: Input
1815
+ }] } });
1816
+
1817
+ function calcPosFromAngles(inclination, azimuth, vector = new Vector3()) {
1818
+ const theta = Math.PI * (inclination - 0.5);
1819
+ const phi = 2 * Math.PI * (azimuth - 0.5);
1820
+ vector.x = Math.cos(phi);
1821
+ vector.y = Math.sin(theta);
1822
+ vector.z = Math.sin(phi);
1823
+ return vector;
1824
+ }
1825
+ class NgtsSky extends NgtRxStore {
1826
+ constructor() {
1827
+ super(...arguments);
1828
+ this.skyRef = injectNgtRef();
1829
+ }
1830
+ set distance(distance) {
1831
+ this.set({ distance });
1832
+ }
1833
+ set sunPosition(sunPosition) {
1834
+ this.set({ sunPosition });
1835
+ }
1836
+ set inclination(inclination) {
1837
+ this.set({ inclination });
1838
+ }
1839
+ set azimuth(azimuth) {
1840
+ this.set({ azimuth });
1841
+ }
1842
+ set mieCoefficient(mieCoefficient) {
1843
+ this.set({ mieCoefficient });
1844
+ }
1845
+ set mieDirectionalG(mieDirectionalG) {
1846
+ this.set({ mieDirectionalG });
1847
+ }
1848
+ set rayleigh(rayleigh) {
1849
+ this.set({ rayleigh });
1850
+ }
1851
+ set turbidity(turbidity) {
1852
+ this.set({ turbidity });
1853
+ }
1854
+ initialize() {
1855
+ super.initialize();
1856
+ const inclination = 0.6;
1857
+ const azimuth = 0.1;
1858
+ this.set({
1859
+ inclination,
1860
+ azimuth,
1861
+ distance: 1000,
1862
+ mieCoefficient: 0.005,
1863
+ mieDirectionalG: 0.8,
1864
+ rayleigh: 0.5,
1865
+ turbidity: 10,
1866
+ sunPosition: calcPosFromAngles(inclination, azimuth),
1867
+ });
1868
+ this.connect('sunPosition', this.select(['inclination', 'azimuth'], ({ inclination, azimuth }) => calcPosFromAngles(inclination, azimuth)));
1869
+ this.connect('scale', this.select(['distance'], ({ distance }) => new Vector3().setScalar(distance)));
1870
+ }
1871
+ ngOnInit() {
1872
+ if (!this.skyRef.nativeElement)
1873
+ this.skyRef.nativeElement = new Sky();
1874
+ }
1875
+ }
1876
+ NgtsSky.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsSky, deps: null, target: i0.ɵɵFactoryTarget.Component });
1877
+ NgtsSky.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsSky, isStandalone: true, selector: "ngts-sky", inputs: { skyRef: "skyRef", distance: "distance", sunPosition: "sunPosition", inclination: "inclination", azimuth: "azimuth", mieCoefficient: "mieCoefficient", mieDirectionalG: "mieDirectionalG", rayleigh: "rayleigh", turbidity: "turbidity" }, usesInheritance: true, ngImport: i0, template: `
1878
+ <ngt-primitive *args="[skyRef.nativeElement]" ngtCompound [ref]="skyRef" [scale]="get('scale')">
1879
+ <ngt-value [rawValue]="get('mieCoefficient')" attach="material.uniforms.mieCoefficient.value" />
1880
+ <ngt-value [rawValue]="get('mieDirectionalG')" attach="material.uniforms.mieDirectionalG.value" />
1881
+ <ngt-value [rawValue]="get('rayleigh')" attach="material.uniforms.rayleigh.value" />
1882
+ <ngt-value [rawValue]="get('sunPosition')" attach="material.uniforms.sunPosition.value" />
1883
+ <ngt-value [rawValue]="get('turbidity')" attach="material.uniforms.turbidity.value" />
1884
+ </ngt-primitive>
1885
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] });
1886
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsSky, decorators: [{
1887
+ type: Component,
1888
+ args: [{
1889
+ selector: 'ngts-sky',
1890
+ standalone: true,
1891
+ template: `
1892
+ <ngt-primitive *args="[skyRef.nativeElement]" ngtCompound [ref]="skyRef" [scale]="get('scale')">
1893
+ <ngt-value [rawValue]="get('mieCoefficient')" attach="material.uniforms.mieCoefficient.value" />
1894
+ <ngt-value [rawValue]="get('mieDirectionalG')" attach="material.uniforms.mieDirectionalG.value" />
1895
+ <ngt-value [rawValue]="get('rayleigh')" attach="material.uniforms.rayleigh.value" />
1896
+ <ngt-value [rawValue]="get('sunPosition')" attach="material.uniforms.sunPosition.value" />
1897
+ <ngt-value [rawValue]="get('turbidity')" attach="material.uniforms.turbidity.value" />
1898
+ </ngt-primitive>
1899
+ `,
1900
+ imports: [NgtArgs],
1901
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
1902
+ }]
1903
+ }], propDecorators: { skyRef: [{
1904
+ type: Input
1905
+ }], distance: [{
1906
+ type: Input
1907
+ }], sunPosition: [{
1908
+ type: Input
1909
+ }], inclination: [{
1910
+ type: Input
1911
+ }], azimuth: [{
1912
+ type: Input
1913
+ }], mieCoefficient: [{
1914
+ type: Input
1915
+ }], mieDirectionalG: [{
1916
+ type: Input
1917
+ }], rayleigh: [{
1918
+ type: Input
1919
+ }], turbidity: [{
1920
+ type: Input
1921
+ }] } });
1922
+
1923
+ const SparklesMaterial = shaderMaterial({ time: 0, pixelRatio: 1 },
1924
+ // language=GLSL
1925
+ `
1926
+ uniform float pixelRatio;
1927
+ uniform float time;
1928
+
1929
+ attribute float size;
1930
+ attribute float speed;
1931
+ attribute float opacity;
1932
+ attribute vec3 noise;
1933
+ attribute vec3 color;
1934
+
1935
+ varying vec3 vColor;
1936
+ varying float vOpacity;
1937
+
1938
+ void main() {
1939
+ vec4 modelPosition = modelMatrix * vec4(position, 1.0);
1940
+
1941
+ modelPosition.y += sin(time * speed + modelPosition.x * noise.x * 100.0) * 0.2;
1942
+ modelPosition.z += cos(time * speed + modelPosition.x * noise.y * 100.0) * 0.2;
1943
+ modelPosition.x += cos(time * speed + modelPosition.x * noise.z * 100.0) * 0.2;
1944
+
1945
+ vec4 viewPosition = viewMatrix * modelPosition;
1946
+ vec4 projectionPostion = projectionMatrix * viewPosition;
1947
+
1948
+ gl_Position = projectionPostion;
1949
+ gl_PointSize = size * 25. * pixelRatio;
1950
+ gl_PointSize *= (1.0 / - viewPosition.z);
1951
+
1952
+ vColor = color;
1953
+ vOpacity = opacity;
1954
+ }
1955
+ `,
1956
+ // language=GLSL
1957
+ `
1958
+ varying vec3 vColor;
1959
+ varying float vOpacity;
1960
+
1961
+ void main() {
1962
+ float distanceToCenter = distance(gl_PointCoord, vec2(0.5));
1963
+ float strength = 0.05 / distanceToCenter - 0.1;
1964
+
1965
+ gl_FragColor = vec4(vColor, strength * vOpacity);
1966
+ }
1967
+ `);
1968
+ extend({ SparklesMaterial, Points, BufferGeometry, BufferAttribute });
1969
+ const isFloat32Array = (def) => def && def.constructor === Float32Array;
1970
+ const expandColor = (v) => [v.r, v.g, v.b];
1971
+ const isVector = (v) => v instanceof Vector2 || v instanceof Vector3 || v instanceof Vector4;
1972
+ const normalizeVector = (v) => {
1973
+ if (Array.isArray(v))
1974
+ return v;
1975
+ else if (isVector(v))
1976
+ return v.toArray();
1977
+ return [v, v, v];
1978
+ };
1979
+ function usePropAsIsOrAsAttribute(count, prop, setDefault) {
1980
+ if (prop !== undefined) {
1981
+ if (isFloat32Array(prop)) {
1982
+ return prop;
1983
+ }
1984
+ else {
1985
+ if (prop instanceof Color) {
1986
+ const a = Array.from({ length: count * 3 }, () => expandColor(prop)).flat();
1987
+ return Float32Array.from(a);
1988
+ }
1989
+ else if (isVector(prop) || Array.isArray(prop)) {
1990
+ const a = Array.from({ length: count * 3 }, () => normalizeVector(prop)).flat();
1991
+ return Float32Array.from(a);
1992
+ }
1993
+ return Float32Array.from({ length: count }, () => prop);
1994
+ }
1995
+ }
1996
+ return Float32Array.from({ length: count }, setDefault);
1997
+ }
1998
+ class NgtsSparkles extends NgtRxStore {
1999
+ /** Number of particles (default: 100) */
2000
+ set count(count) {
2001
+ this.set({ count });
2002
+ }
2003
+ /** Speed of particles (default: 1) */
2004
+ set speed(speed) {
2005
+ this.set({ speed });
2006
+ }
2007
+ /** Opacity of particles (default: 1) */
2008
+ set opacity(opacity) {
2009
+ this.set({ opacity });
2010
+ }
2011
+ /** Color of particles (default: 100) */
2012
+ set color(color) {
2013
+ this.set({ color });
2014
+ }
2015
+ /** Size of particles (default: randomized between 0 and 1) */
2016
+ set size(size) {
2017
+ this.set({ size });
2018
+ }
2019
+ /** The space the particles occupy (default: 1) */
2020
+ set scale(scale) {
2021
+ this.set({ scale });
2022
+ }
2023
+ /** Movement factor (default: 1) */
2024
+ set noise(noise) {
2025
+ this.set({ noise });
2026
+ }
2027
+ initialize() {
2028
+ super.initialize();
2029
+ this.set({
2030
+ noise: 1,
2031
+ count: 100,
2032
+ speed: 1,
2033
+ opacity: 1,
2034
+ scale: 1,
2035
+ });
2036
+ this.connect('positions', this.select(['count', 'scale'], ({ count, scale }) => Float32Array.from(Array.from({ length: count }, () => normalizeVector(scale).map(MathUtils.randFloatSpread)).flat())));
2037
+ this.connect('sizes', this.getAttribute$('size', { setDefault: Math.random }));
2038
+ this.connect('opacities', this.getAttribute$('opacity'));
2039
+ this.connect('speeds', this.getAttribute$('speed'));
2040
+ this.connect('noises', this.getAttribute$('noise', {
2041
+ countValue: (_, count) => count * 3,
2042
+ }));
2043
+ this.connect('colors', this.getAttribute$('color', {
2044
+ keyValue: (color) => (!isFloat32Array(color) ? new Color(color) : color),
2045
+ countValue: (color, count) => (color === undefined ? count * 3 : count),
2046
+ setDefault: () => 1,
2047
+ }));
2048
+ }
2049
+ constructor() {
2050
+ super();
2051
+ this.store = inject(NgtStore);
2052
+ this.dpr = this.store.get('viewport', 'dpr');
2053
+ this.materialRef = injectNgtRef();
2054
+ this.pointsRef = injectNgtRef();
2055
+ injectBeforeRender(this.onBeforeRender.bind(this));
2056
+ }
2057
+ onBeforeRender({ clock }) {
2058
+ if (!this.materialRef.nativeElement)
2059
+ return;
2060
+ this.materialRef.nativeElement.uniforms['time'].value = clock.elapsedTime;
2061
+ }
2062
+ getAttribute$(key, options) {
2063
+ options ?? (options = {});
2064
+ if (!options.keyValue) {
2065
+ options.keyValue = (value) => value;
2066
+ }
2067
+ if (!options.countValue) {
2068
+ options.countValue = (_, count) => count;
2069
+ }
2070
+ return this.select(key).pipe(startWith(this.get(key) || undefined), withLatestFrom(this.select('count')), map(([value, count]) => usePropAsIsOrAsAttribute(options.countValue(value, count), options.keyValue(value, count), options?.setDefault)));
2071
+ }
2072
+ }
2073
+ NgtsSparkles.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsSparkles, deps: [], target: i0.ɵɵFactoryTarget.Component });
2074
+ NgtsSparkles.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsSparkles, isStandalone: true, selector: "ngts-sparkles", inputs: { pointsRef: "pointsRef", count: "count", speed: "speed", opacity: "opacity", color: "color", size: "size", scale: "scale", noise: "noise" }, usesInheritance: true, ngImport: i0, template: `
2075
+ <ngt-points ngtCompount [ref]="pointsRef">
2076
+ <ngt-buffer-geometry>
2077
+ <ngt-buffer-attribute *args="[get('positions'), 3]" attach="attributes.position" />
2078
+ <ngt-buffer-attribute *args="[get('sizes'), 1]" attach="attributes.size" />
2079
+ <ngt-buffer-attribute *args="[get('opacities'), 1]" attach="attributes.opacity" />
2080
+ <ngt-buffer-attribute *args="[get('speeds'), 1]" attach="attributes.speed" />
2081
+ <ngt-buffer-attribute *args="[get('colors'), 3]" attach="attributes.color" />
2082
+ <ngt-buffer-attribute *args="[get('noises'), 3]" attach="attributes.noise" />
2083
+ </ngt-buffer-geometry>
2084
+ <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr" />
2085
+ </ngt-points>
2086
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] });
2087
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsSparkles, decorators: [{
2088
+ type: Component,
2089
+ args: [{
2090
+ selector: 'ngts-sparkles',
2091
+ standalone: true,
2092
+ template: `
2093
+ <ngt-points ngtCompount [ref]="pointsRef">
2094
+ <ngt-buffer-geometry>
2095
+ <ngt-buffer-attribute *args="[get('positions'), 3]" attach="attributes.position" />
2096
+ <ngt-buffer-attribute *args="[get('sizes'), 1]" attach="attributes.size" />
2097
+ <ngt-buffer-attribute *args="[get('opacities'), 1]" attach="attributes.opacity" />
2098
+ <ngt-buffer-attribute *args="[get('speeds'), 1]" attach="attributes.speed" />
2099
+ <ngt-buffer-attribute *args="[get('colors'), 3]" attach="attributes.color" />
2100
+ <ngt-buffer-attribute *args="[get('noises'), 3]" attach="attributes.noise" />
2101
+ </ngt-buffer-geometry>
2102
+ <ngt-sparkles-material [ref]="materialRef" [transparent]="true" [depthWrite]="false" [pixelRatio]="dpr" />
2103
+ </ngt-points>
2104
+ `,
2105
+ imports: [NgtArgs],
2106
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
2107
+ }]
2108
+ }], ctorParameters: function () { return []; }, propDecorators: { pointsRef: [{
2109
+ type: Input
2110
+ }], count: [{
2111
+ type: Input
2112
+ }], speed: [{
2113
+ type: Input
2114
+ }], opacity: [{
2115
+ type: Input
2116
+ }], color: [{
2117
+ type: Input
2118
+ }], size: [{
2119
+ type: Input
2120
+ }], scale: [{
2121
+ type: Input
2122
+ }], noise: [{
2123
+ type: Input
2124
+ }] } });
2125
+
2126
+ const presets = {
2127
+ rembrandt: {
2128
+ main: [1, 2, 1],
2129
+ fill: [-2, -0.5, -2],
2130
+ },
2131
+ portrait: {
2132
+ main: [-1, 2, 0.5],
2133
+ fill: [-1, 0.5, -1.5],
2134
+ },
2135
+ upfront: {
2136
+ main: [0, 2, 1],
2137
+ fill: [-1, 0.5, -1.5],
2138
+ },
2139
+ soft: {
2140
+ main: [-2, 4, 4],
2141
+ fill: [-1, 0.5, -1.5],
2142
+ },
2143
+ };
2144
+ class NgtsStageRefit {
2145
+ constructor() {
2146
+ this.boundsApi = inject(NGTS_BOUNDS_API);
2147
+ this.radius = 0;
2148
+ this.adjustCamera = true;
2149
+ }
2150
+ ngOnChanges() {
2151
+ if (this.adjustCamera) {
2152
+ this.boundsApi.refresh().clip().fit();
2153
+ }
2154
+ }
2155
+ }
2156
+ NgtsStageRefit.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStageRefit, deps: [], target: i0.ɵɵFactoryTarget.Directive });
2157
+ NgtsStageRefit.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.1.3", type: NgtsStageRefit, isStandalone: true, selector: "ngts-stage-refit", inputs: { radius: "radius", adjustCamera: "adjustCamera" }, usesOnChanges: true, ngImport: i0 });
2158
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStageRefit, decorators: [{
2159
+ type: Directive,
2160
+ args: [{
2161
+ selector: 'ngts-stage-refit',
2162
+ standalone: true,
2163
+ }]
2164
+ }], propDecorators: { radius: [{
2165
+ type: Input
2166
+ }], adjustCamera: [{
2167
+ type: Input
2168
+ }] } });
2169
+ extend({ AmbientLight, SpotLight, Vector2, PointLight, Group });
2170
+ class NgtsStage extends NgtRxStore {
2171
+ constructor() {
2172
+ super(...arguments);
2173
+ this.cdr = inject(ChangeDetectorRef);
2174
+ this.Number = Number;
2175
+ this.centered = new EventEmitter();
2176
+ }
2177
+ set preset(preset) {
2178
+ this.set({ preset });
2179
+ }
2180
+ set shadows(shadows) {
2181
+ this.set({ shadows });
2182
+ }
2183
+ set adjustCamera(adjustCamera) {
2184
+ this.set({ adjustCamera });
2185
+ }
2186
+ set environment(environment) {
2187
+ this.set({ environment });
2188
+ }
2189
+ set intensity(intensity) {
2190
+ this.set({ intensity });
2191
+ }
2192
+ set center(center) {
2193
+ this.set({ center });
2194
+ }
2195
+ initialize() {
2196
+ super.initialize();
2197
+ this.set({
2198
+ adjustCamera: true,
2199
+ intensity: 0.5,
2200
+ shadows: 'contact',
2201
+ environment: 'city',
2202
+ preset: 'rembrandt',
2203
+ radius: 0,
2204
+ width: 0,
2205
+ height: 0,
2206
+ depth: 0,
2207
+ });
2208
+ this.connect('config', this.select('preset').pipe(map((preset) => (typeof preset === 'string' ? presets[preset] : preset))));
2209
+ this.connect('shadowsInfo', this.select('shadows').pipe(map((shadows) => {
2210
+ return {
2211
+ contactShadow: shadows === 'contact' || shadows?.type === 'contact',
2212
+ accumulativeShadow: shadows === 'accumulative' || shadows?.type === 'accumulative',
2213
+ shadowBias: shadows?.bias ?? -0.0001,
2214
+ normalBias: shadows?.normalBias ?? 0,
2215
+ shadowSize: shadows?.size ?? 1024,
2216
+ shadowOffset: shadows?.offset ?? 0,
2217
+ ...(typeof shadows === 'string' ? {} : shadows || {}),
2218
+ };
2219
+ })));
2220
+ this.connect('spotLightPosition', this.select(['config', 'radius'], ({ config, radius }) => [
2221
+ config.main[0] * radius,
2222
+ config.main[1] * radius,
2223
+ config.main[2] * radius,
2224
+ ]));
2225
+ this.connect('pointLightPosition', this.select(['config', 'radius'], ({ config, radius }) => [
2226
+ config.fill[0] * radius,
2227
+ config.fill[1] * radius,
2228
+ config.fill[2] * radius,
2229
+ ]));
2230
+ this.connect('environmentInfo', this.select('environment').pipe(map((environment) => {
2231
+ if (!environment)
2232
+ return null;
2233
+ if (typeof environment === 'string')
2234
+ return { preset: environment };
2235
+ return environment;
2236
+ })));
2237
+ }
2238
+ onCentered(props) {
2239
+ const { boundingSphere, width, height, depth } = props;
2240
+ this.set({ radius: boundingSphere.radius, width, height, depth });
2241
+ this.cdr.detectChanges();
2242
+ if (this.centered.observed)
2243
+ this.centered.emit(props);
2244
+ }
2245
+ }
2246
+ NgtsStage.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStage, deps: null, target: i0.ɵɵFactoryTarget.Component });
2247
+ NgtsStage.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsStage, isStandalone: true, selector: "ngts-stage", inputs: { preset: "preset", shadows: "shadows", adjustCamera: "adjustCamera", environment: "environment", intensity: "intensity", center: "center" }, outputs: { centered: "centered" }, usesInheritance: true, ngImport: i0, template: `
2248
+ <ngt-ambient-light [intensity]="get('intensity')! / 3" />
2249
+ <ngt-spot-light
2250
+ [penumbra]="1"
2251
+ [position]="get('spotLightPosition')"
2252
+ [intensity]="get('intensity')! * 2"
2253
+ [castShadow]="!!get('shadows')"
2254
+ >
2255
+ <ngt-value [rawValue]="get('shadowsInfo').shadowBias" attach="shadow.bias" />
2256
+ <ngt-value [rawValue]="get('shadowsInfo').normalBias" attach="shadow.normalBias" />
2257
+ <ngt-vector2
2258
+ *args="[get('shadowsInfo').shadowSize, get('shadowsInfo').shadowSize]"
2259
+ attach="shadow.mapSize"
2260
+ />
2261
+ </ngt-spot-light>
2262
+ <ngt-point-light [position]="get('pointLightPosition')" [intensity]="get('intensity')" />
2263
+
2264
+ <ngts-bounds
2265
+ [fit]="!!get('adjustCamera')"
2266
+ [clip]="!!get('adjustCamera')"
2267
+ [margin]="Number(get('adjustCamera'))"
2268
+ [observe]="true"
2269
+ >
2270
+ <ngts-stage-refit [radius]="get('radius')" [adjustCamera]="!!get('adjustCamera')" />
2271
+ <ngts-center
2272
+ [position]="[0, get('shadowsInfo').shadowOffset / 2, 0]"
2273
+ [top]="!!get('center')?.top"
2274
+ [right]="!!get('center')?.right"
2275
+ [bottom]="!!get('center')?.bottom"
2276
+ [left]="!!get('center')?.left"
2277
+ [front]="!!get('center')?.front"
2278
+ [back]="!!get('center')?.back"
2279
+ [disableX]="!!get('center')?.disableX"
2280
+ [disableY]="!!get('center')?.disableY"
2281
+ [disableZ]="!!get('center')?.disableZ"
2282
+ [precise]="!!get('center')?.precise"
2283
+ (centered)="onCentered($event)"
2284
+ >
2285
+ <ng-content />
2286
+ </ngts-center>
2287
+ </ngts-bounds>
2288
+ <ngt-group [position]="[0, -get('height') / 2 - get('shadowsInfo').shadowOffset / 2, 0]">
2289
+ <ngts-contact-shadows
2290
+ *ngIf="get('shadowsInfo').contactShadow"
2291
+ [scale]="get('radius') * 4"
2292
+ [far]="get('radius')"
2293
+ [blur]="2"
2294
+ [opacity]="get('shadowsInfo').opacity"
2295
+ [width]="get('shadowsInfo').width"
2296
+ [height]="get('shadowsInfo').height"
2297
+ [smooth]="get('shadowsInfo').smooth"
2298
+ [resolution]="get('shadowsInfo').resolution"
2299
+ [frames]="get('shadowsInfo').frames"
2300
+ [scale]="get('shadowsInfo').scale"
2301
+ [color]="get('shadowsInfo').color"
2302
+ [depthWrite]="get('shadowsInfo').depthWrite"
2303
+ [renderOrder]="get('shadowsInfo').renderOrder"
2304
+ />
2305
+ <ngts-accumulative-shadows
2306
+ *ngIf="get('shadowsInfo').accumulativeShadow"
2307
+ [temporal]="true"
2308
+ [frames]="100"
2309
+ [alphaTest]="0.9"
2310
+ [toneMapped]="true"
2311
+ [scale]="get('radius') * 4"
2312
+ [opacity]="get('shadowsInfo').opacity"
2313
+ [alphaTest]="get('shadowsInfo').alphaTest"
2314
+ [color]="get('shadowsInfo').color"
2315
+ [colorBlend]="get('shadowsInfo').colorBlend"
2316
+ [resolution]="get('shadowsInfo').resolution"
2317
+ >
2318
+ <ngts-randomized-lights
2319
+ [amount]="get('shadowsInfo').amount ?? 8"
2320
+ [radius]="get('shadowsInfo').radius ?? get('radius')"
2321
+ [ambient]="get('shadowsInfo').ambient ?? 0.5"
2322
+ [intensity]="get('shadowsInfo').intensity ?? 1"
2323
+ [position]="get('spotLightPosition')"
2324
+ [size]="get('radius') * 4"
2325
+ [bias]="-get('shadowsInfo').shadowBias"
2326
+ [mapSize]="get('shadowsInfo').shadowSize"
2327
+ />
2328
+ </ngts-accumulative-shadows>
2329
+ </ngt-group>
2330
+ <ngts-environment
2331
+ *ngIf="get('environmentInfo')"
2332
+ [frames]="get('environmentInfo').frames"
2333
+ [near]="get('environmentInfo').near"
2334
+ [far]="get('environmentInfo').far"
2335
+ [resolution]="get('environmentInfo').resolution"
2336
+ [background]="get('environmentInfo').background"
2337
+ [blur]="get('environmentInfo').blur"
2338
+ [map]="get('environmentInfo').map"
2339
+ [files]="get('environmentInfo').files"
2340
+ [path]="get('environmentInfo').path"
2341
+ [preset]="get('environmentInfo').preset"
2342
+ [scene]="get('environmentInfo').scene"
2343
+ [extensions]="get('environmentInfo').extensions"
2344
+ [ground]="get('environmentInfo').ground"
2345
+ [encoding]="get('environmentInfo').encoding"
2346
+ />
2347
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }, { kind: "component", type: NgtsBounds, selector: "ngts-bounds", inputs: ["boundsRef", "damping", "fit", "clip", "observe", "margin", "eps"], outputs: ["fitted"] }, { kind: "directive", type: NgtsStageRefit, selector: "ngts-stage-refit", inputs: ["radius", "adjustCamera"] }, { kind: "component", type: NgtsCenter, selector: "ngts-center", inputs: ["centerRef", "top", "right", "bottom", "left", "front", "back", "disableX", "disableY", "disableZ", "disabled", "precise"], outputs: ["centered"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgtsContactShadows, selector: "ngts-contact-shadows", inputs: ["contactShadowsRef", "opacity", "width", "height", "blur", "far", "smooth", "resolution", "frames", "scale", "color", "depthWrite", "renderOrder"] }, { kind: "component", type: NgtsAccumulativeShadows, selector: "ngts-accumulative-shadows", inputs: ["frames", "blend", "limit", "scale", "temporal", "opacity", "alphaTest", "color", "colorBlend", "resolution", "toneMapped"] }, { kind: "component", type: NgtsRandomizedLights, selector: "ngts-randomized-lights", inputs: ["lightsRef", "frames", "position", "radius", "amount", "intensity", "ambient", "castShadow", "bias", "mapSize", "size", "near", "far"] }, { kind: "component", type: NgtsEnvironment, selector: "ngts-environment" }] });
2348
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStage, decorators: [{
2349
+ type: Component,
2350
+ args: [{
2351
+ selector: 'ngts-stage',
2352
+ standalone: true,
2353
+ template: `
2354
+ <ngt-ambient-light [intensity]="get('intensity')! / 3" />
2355
+ <ngt-spot-light
2356
+ [penumbra]="1"
2357
+ [position]="get('spotLightPosition')"
2358
+ [intensity]="get('intensity')! * 2"
2359
+ [castShadow]="!!get('shadows')"
2360
+ >
2361
+ <ngt-value [rawValue]="get('shadowsInfo').shadowBias" attach="shadow.bias" />
2362
+ <ngt-value [rawValue]="get('shadowsInfo').normalBias" attach="shadow.normalBias" />
2363
+ <ngt-vector2
2364
+ *args="[get('shadowsInfo').shadowSize, get('shadowsInfo').shadowSize]"
2365
+ attach="shadow.mapSize"
2366
+ />
2367
+ </ngt-spot-light>
2368
+ <ngt-point-light [position]="get('pointLightPosition')" [intensity]="get('intensity')" />
2369
+
2370
+ <ngts-bounds
2371
+ [fit]="!!get('adjustCamera')"
2372
+ [clip]="!!get('adjustCamera')"
2373
+ [margin]="Number(get('adjustCamera'))"
2374
+ [observe]="true"
2375
+ >
2376
+ <ngts-stage-refit [radius]="get('radius')" [adjustCamera]="!!get('adjustCamera')" />
2377
+ <ngts-center
2378
+ [position]="[0, get('shadowsInfo').shadowOffset / 2, 0]"
2379
+ [top]="!!get('center')?.top"
2380
+ [right]="!!get('center')?.right"
2381
+ [bottom]="!!get('center')?.bottom"
2382
+ [left]="!!get('center')?.left"
2383
+ [front]="!!get('center')?.front"
2384
+ [back]="!!get('center')?.back"
2385
+ [disableX]="!!get('center')?.disableX"
2386
+ [disableY]="!!get('center')?.disableY"
2387
+ [disableZ]="!!get('center')?.disableZ"
2388
+ [precise]="!!get('center')?.precise"
2389
+ (centered)="onCentered($event)"
2390
+ >
2391
+ <ng-content />
2392
+ </ngts-center>
2393
+ </ngts-bounds>
2394
+ <ngt-group [position]="[0, -get('height') / 2 - get('shadowsInfo').shadowOffset / 2, 0]">
2395
+ <ngts-contact-shadows
2396
+ *ngIf="get('shadowsInfo').contactShadow"
2397
+ [scale]="get('radius') * 4"
2398
+ [far]="get('radius')"
2399
+ [blur]="2"
2400
+ [opacity]="get('shadowsInfo').opacity"
2401
+ [width]="get('shadowsInfo').width"
2402
+ [height]="get('shadowsInfo').height"
2403
+ [smooth]="get('shadowsInfo').smooth"
2404
+ [resolution]="get('shadowsInfo').resolution"
2405
+ [frames]="get('shadowsInfo').frames"
2406
+ [scale]="get('shadowsInfo').scale"
2407
+ [color]="get('shadowsInfo').color"
2408
+ [depthWrite]="get('shadowsInfo').depthWrite"
2409
+ [renderOrder]="get('shadowsInfo').renderOrder"
2410
+ />
2411
+ <ngts-accumulative-shadows
2412
+ *ngIf="get('shadowsInfo').accumulativeShadow"
2413
+ [temporal]="true"
2414
+ [frames]="100"
2415
+ [alphaTest]="0.9"
2416
+ [toneMapped]="true"
2417
+ [scale]="get('radius') * 4"
2418
+ [opacity]="get('shadowsInfo').opacity"
2419
+ [alphaTest]="get('shadowsInfo').alphaTest"
2420
+ [color]="get('shadowsInfo').color"
2421
+ [colorBlend]="get('shadowsInfo').colorBlend"
2422
+ [resolution]="get('shadowsInfo').resolution"
2423
+ >
2424
+ <ngts-randomized-lights
2425
+ [amount]="get('shadowsInfo').amount ?? 8"
2426
+ [radius]="get('shadowsInfo').radius ?? get('radius')"
2427
+ [ambient]="get('shadowsInfo').ambient ?? 0.5"
2428
+ [intensity]="get('shadowsInfo').intensity ?? 1"
2429
+ [position]="get('spotLightPosition')"
2430
+ [size]="get('radius') * 4"
2431
+ [bias]="-get('shadowsInfo').shadowBias"
2432
+ [mapSize]="get('shadowsInfo').shadowSize"
2433
+ />
2434
+ </ngts-accumulative-shadows>
2435
+ </ngt-group>
2436
+ <ngts-environment
2437
+ *ngIf="get('environmentInfo')"
2438
+ [frames]="get('environmentInfo').frames"
2439
+ [near]="get('environmentInfo').near"
2440
+ [far]="get('environmentInfo').far"
2441
+ [resolution]="get('environmentInfo').resolution"
2442
+ [background]="get('environmentInfo').background"
2443
+ [blur]="get('environmentInfo').blur"
2444
+ [map]="get('environmentInfo').map"
2445
+ [files]="get('environmentInfo').files"
2446
+ [path]="get('environmentInfo').path"
2447
+ [preset]="get('environmentInfo').preset"
2448
+ [scene]="get('environmentInfo').scene"
2449
+ [extensions]="get('environmentInfo').extensions"
2450
+ [ground]="get('environmentInfo').ground"
2451
+ [encoding]="get('environmentInfo').encoding"
2452
+ />
2453
+ `,
2454
+ imports: [
2455
+ NgtArgs,
2456
+ NgtsBounds,
2457
+ NgtsStageRefit,
2458
+ NgtsCenter,
2459
+ NgIf,
2460
+ NgtsContactShadows,
2461
+ NgtsAccumulativeShadows,
2462
+ NgtsRandomizedLights,
2463
+ NgtsEnvironment,
2464
+ ],
2465
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
2466
+ }]
2467
+ }], propDecorators: { preset: [{
2468
+ type: Input
2469
+ }], shadows: [{
2470
+ type: Input
2471
+ }], adjustCamera: [{
2472
+ type: Input
2473
+ }], environment: [{
2474
+ type: Input
2475
+ }], intensity: [{
2476
+ type: Input
2477
+ }], center: [{
2478
+ type: Input
2479
+ }], centered: [{
2480
+ type: Output
2481
+ }] } });
2482
+
2483
+ const StarFieldMaterial = shaderMaterial({
2484
+ time: 0.0,
2485
+ fade: 0.0,
2486
+ },
2487
+ // language=GLSL
2488
+ `
2489
+ uniform float time;
2490
+ attribute float size;
2491
+ varying vec3 vColor;
2492
+ void main() {
2493
+ vColor = color;
2494
+ vec4 mvPosition = modelViewMatrix * vec4(position, 0.5);
2495
+ gl_PointSize = size * (30.0 / -mvPosition.z) * (3.0 + sin(time + 100.0));
2496
+ gl_Position = projectionMatrix * mvPosition;
2497
+ }
2498
+ `,
2499
+ // language=GLSL
2500
+ `
2501
+ uniform sampler2D pointTexture;
2502
+ uniform float fade;
2503
+ varying vec3 vColor;
2504
+ void main() {
2505
+ float opacity = 1.0;
2506
+ if (fade == 1.0) {
2507
+ float d = distance(gl_PointCoord, vec2(0.5, 0.5));
2508
+ opacity = 1.0 / (1.0 + exp(16.0 * (d - 0.25)));
2509
+ }
2510
+ gl_FragColor = vec4(vColor, opacity);
2511
+
2512
+ #include <tonemapping_fragment>
2513
+ #include <encodings_fragment>
2514
+ }
2515
+ `);
2516
+ extend({ Points, BufferGeometry, BufferAttribute });
2517
+ const genStar = (r) => {
2518
+ return new Vector3().setFromSpherical(new Spherical(r, Math.acos(1 - Math.random() * 2), Math.random() * 2 * Math.PI));
2519
+ };
2520
+ class NgtsStars extends NgtRxStore {
2521
+ set radius(radius) {
2522
+ this.set({ radius });
2523
+ }
2524
+ set depth(depth) {
2525
+ this.set({ depth });
2526
+ }
2527
+ set count(count) {
2528
+ this.set({ count });
2529
+ }
2530
+ set factor(factor) {
2531
+ this.set({ factor });
2532
+ }
2533
+ set saturation(saturation) {
2534
+ this.set({ saturation });
2535
+ }
2536
+ set fade(fade) {
2537
+ this.set({ fade });
2538
+ }
2539
+ set speed(speed) {
2540
+ this.set({ speed });
2541
+ }
2542
+ initialize() {
2543
+ super.initialize();
2544
+ this.set({
2545
+ radius: 100,
2546
+ depth: 50,
2547
+ count: 5000,
2548
+ saturation: 0,
2549
+ factor: 4,
2550
+ fade: false,
2551
+ speed: 1,
2552
+ });
2553
+ this.connect('bufferAttributes', this.select(['count', 'depth', 'factor', 'radius', 'saturation'], ({ count, depth, factor, radius, saturation }) => {
2554
+ const positions = [];
2555
+ const colors = [];
2556
+ const sizes = Array.from({ length: count }, () => (0.5 + 0.5 * Math.random()) * factor);
2557
+ const color = new Color();
2558
+ let r = radius + depth;
2559
+ const increment = depth / count;
2560
+ for (let i = 0; i < count; i++) {
2561
+ r -= increment * Math.random();
2562
+ positions.push(...genStar(r).toArray());
2563
+ color.setHSL(i / count, saturation, 0.9);
2564
+ colors.push(color.r, color.g, color.b);
2565
+ }
2566
+ return {
2567
+ positions: new Float32Array(positions),
2568
+ colors: new Float32Array(colors),
2569
+ sizes: new Float32Array(sizes),
2570
+ };
2571
+ }));
2572
+ }
2573
+ constructor() {
2574
+ super();
2575
+ this.AdditiveBlending = AdditiveBlending;
2576
+ this.material = new StarFieldMaterial();
2577
+ this.starsRef = injectNgtRef();
2578
+ injectBeforeRender(this.onBeforeRender.bind(this));
2579
+ }
2580
+ onBeforeRender({ clock }) {
2581
+ this.material.uniforms['time'].value = clock.getElapsedTime() * this.get('speed');
2582
+ }
2583
+ }
2584
+ NgtsStars.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStars, deps: [], target: i0.ɵɵFactoryTarget.Component });
2585
+ NgtsStars.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.1.3", type: NgtsStars, isStandalone: true, selector: "ngts-stars", inputs: { starsRef: "starsRef", radius: "radius", depth: "depth", count: "count", factor: "factor", saturation: "saturation", fade: "fade", speed: "speed" }, usesInheritance: true, ngImport: i0, template: `
2586
+ <ngt-points [ref]="starsRef">
2587
+ <ngt-buffer-geometry>
2588
+ <ngt-buffer-attribute attach="attributes.position" *args="[get('bufferAttributes').positions, 3]" />
2589
+ <ngt-buffer-attribute attach="attributes.color" *args="[get('bufferAttributes').colors, 3]" />
2590
+ <ngt-buffer-attribute attach="attributes.size" *args="[get('bufferAttributes').sizes, 1]" />
2591
+ </ngt-buffer-geometry>
2592
+ <ngt-primitive
2593
+ *args="[material]"
2594
+ attach="material"
2595
+ [blending]="AdditiveBlending"
2596
+ [depthWrite]="false"
2597
+ [transparent]="true"
2598
+ [vertexColors]="true"
2599
+ >
2600
+ <ngt-value attach="uniforms.fade.value" [rawValue]="get('fade')" />
2601
+ </ngt-primitive>
2602
+ </ngt-points>
2603
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgtArgs, selector: "[args]", inputs: ["args"] }] });
2604
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.1.3", ngImport: i0, type: NgtsStars, decorators: [{
2605
+ type: Component,
2606
+ args: [{
2607
+ selector: 'ngts-stars',
2608
+ standalone: true,
2609
+ template: `
2610
+ <ngt-points [ref]="starsRef">
2611
+ <ngt-buffer-geometry>
2612
+ <ngt-buffer-attribute attach="attributes.position" *args="[get('bufferAttributes').positions, 3]" />
2613
+ <ngt-buffer-attribute attach="attributes.color" *args="[get('bufferAttributes').colors, 3]" />
2614
+ <ngt-buffer-attribute attach="attributes.size" *args="[get('bufferAttributes').sizes, 1]" />
2615
+ </ngt-buffer-geometry>
2616
+ <ngt-primitive
2617
+ *args="[material]"
2618
+ attach="material"
2619
+ [blending]="AdditiveBlending"
2620
+ [depthWrite]="false"
2621
+ [transparent]="true"
2622
+ [vertexColors]="true"
2623
+ >
2624
+ <ngt-value attach="uniforms.fade.value" [rawValue]="get('fade')" />
2625
+ </ngt-primitive>
2626
+ </ngt-points>
2627
+ `,
2628
+ imports: [NgtArgs],
2629
+ schemas: [CUSTOM_ELEMENTS_SCHEMA],
2630
+ }]
2631
+ }], ctorParameters: function () { return []; }, propDecorators: { starsRef: [{
2632
+ type: Input
2633
+ }], radius: [{
2634
+ type: Input
2635
+ }], depth: [{
2636
+ type: Input
2637
+ }], count: [{
2638
+ type: Input
2639
+ }], factor: [{
2640
+ type: Input
2641
+ }], saturation: [{
2642
+ type: Input
2643
+ }], fade: [{
2644
+ type: Input
2645
+ }], speed: [{
2646
+ type: Input
2647
+ }] } });
2648
+
2649
+ /**
2650
+ * Generated bundle index. Do not edit.
2651
+ */
2652
+
2653
+ export { NGTS_BOUNDS_API, NgtsAccumulativeShadows, NgtsBounds, NgtsCenter, NgtsContactShadows, NgtsEnvironment, NgtsEnvironmentContent, NgtsFloat, NgtsRandomizedLights, NgtsSky, NgtsSparkles, NgtsStage, NgtsStageRefit, NgtsStars, calcPosFromAngles, ngtsEnvironmentPresetsObj };
2654
+ //# sourceMappingURL=angular-three-soba-staging.mjs.map