@3driseai/3drise-viewer 0.1.16 → 0.1.17

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 (116) hide show
  1. package/README.md +4 -3
  2. package/dist/components/ChladniGrid.d.ts +15 -0
  3. package/dist/components/ChladniGrid.d.ts.map +1 -0
  4. package/dist/components/ChladniGrid.js +62 -0
  5. package/dist/components/CustomPrimitive.d.ts +2 -0
  6. package/dist/components/CustomPrimitive.d.ts.map +1 -1
  7. package/dist/components/CustomPrimitive.js +2 -2
  8. package/dist/components/EffectsGenerator.d.ts.map +1 -1
  9. package/dist/components/EffectsGenerator.js +26 -2
  10. package/dist/components/FlowNetGrid.d.ts +15 -0
  11. package/dist/components/FlowNetGrid.d.ts.map +1 -0
  12. package/dist/components/FlowNetGrid.js +61 -0
  13. package/dist/components/GirihGrid.d.ts +15 -0
  14. package/dist/components/GirihGrid.d.ts.map +1 -0
  15. package/dist/components/GirihGrid.js +62 -0
  16. package/dist/components/GravWaveGrid.d.ts +15 -0
  17. package/dist/components/GravWaveGrid.d.ts.map +1 -0
  18. package/dist/components/GravWaveGrid.js +62 -0
  19. package/dist/components/GridsGenerator.d.ts +2 -2
  20. package/dist/components/GridsGenerator.d.ts.map +1 -1
  21. package/dist/components/GridsGenerator.js +21 -0
  22. package/dist/components/HyperbolicGrid.d.ts +15 -0
  23. package/dist/components/HyperbolicGrid.d.ts.map +1 -0
  24. package/dist/components/HyperbolicGrid.js +61 -0
  25. package/dist/components/LayoutInstances.d.ts +13 -0
  26. package/dist/components/LayoutInstances.d.ts.map +1 -0
  27. package/dist/components/LayoutInstances.js +39 -0
  28. package/dist/components/ModelPrimitive.d.ts +2 -0
  29. package/dist/components/ModelPrimitive.d.ts.map +1 -1
  30. package/dist/components/ModelPrimitive.js +3 -3
  31. package/dist/components/ObjectNode.d.ts.map +1 -1
  32. package/dist/components/ObjectNode.js +36 -8
  33. package/dist/components/ReactionDiffusionGrid.d.ts +15 -0
  34. package/dist/components/ReactionDiffusionGrid.d.ts.map +1 -0
  35. package/dist/components/ReactionDiffusionGrid.js +376 -0
  36. package/dist/components/WallpaperGrid.d.ts +15 -0
  37. package/dist/components/WallpaperGrid.d.ts.map +1 -0
  38. package/dist/components/WallpaperGrid.js +555 -0
  39. package/dist/components/cursor/CursorController.d.ts.map +1 -1
  40. package/dist/components/effects/BlackHoleEffect.d.ts +3 -3
  41. package/dist/components/effects/BlackHoleEffect.d.ts.map +1 -1
  42. package/dist/components/effects/BlackHoleEffect.js +293 -163
  43. package/dist/components/effects/DandelionSeedsEffect.d.ts +13 -0
  44. package/dist/components/effects/DandelionSeedsEffect.d.ts.map +1 -0
  45. package/dist/components/effects/DandelionSeedsEffect.js +510 -0
  46. package/dist/components/effects/FallingLeavesEffect.d.ts +13 -0
  47. package/dist/components/effects/FallingLeavesEffect.d.ts.map +1 -0
  48. package/dist/components/effects/FallingLeavesEffect.js +446 -0
  49. package/dist/components/effects/FieldLinesEffect.d.ts +11 -0
  50. package/dist/components/effects/FieldLinesEffect.d.ts.map +1 -0
  51. package/dist/components/effects/FieldLinesEffect.js +260 -0
  52. package/dist/components/effects/FireflySwarmEffect.d.ts +13 -0
  53. package/dist/components/effects/FireflySwarmEffect.d.ts.map +1 -0
  54. package/dist/components/effects/FireflySwarmEffect.js +408 -0
  55. package/dist/components/effects/GalaxyEffect.d.ts +13 -0
  56. package/dist/components/effects/GalaxyEffect.d.ts.map +1 -0
  57. package/dist/components/effects/GalaxyEffect.js +374 -0
  58. package/dist/components/effects/HarmonicShellEffect.d.ts +11 -0
  59. package/dist/components/effects/HarmonicShellEffect.d.ts.map +1 -0
  60. package/dist/components/effects/HarmonicShellEffect.js +209 -0
  61. package/dist/components/effects/IceCrystalsEffect.d.ts +3 -3
  62. package/dist/components/effects/IceCrystalsEffect.d.ts.map +1 -1
  63. package/dist/components/effects/IceCrystalsEffect.js +286 -166
  64. package/dist/components/effects/IceHaloEffect.d.ts +13 -0
  65. package/dist/components/effects/IceHaloEffect.d.ts.map +1 -0
  66. package/dist/components/effects/IceHaloEffect.js +306 -0
  67. package/dist/components/effects/LichtenbergEffect.d.ts +13 -0
  68. package/dist/components/effects/LichtenbergEffect.d.ts.map +1 -0
  69. package/dist/components/effects/LichtenbergEffect.js +517 -0
  70. package/dist/components/effects/MoleculesEffect.d.ts +3 -3
  71. package/dist/components/effects/MoleculesEffect.d.ts.map +1 -1
  72. package/dist/components/effects/MoleculesEffect.js +322 -164
  73. package/dist/components/effects/MurmurationEffect.d.ts +13 -0
  74. package/dist/components/effects/MurmurationEffect.d.ts.map +1 -0
  75. package/dist/components/effects/MurmurationEffect.js +539 -0
  76. package/dist/components/effects/PlanetaryRingsEffect.d.ts +13 -0
  77. package/dist/components/effects/PlanetaryRingsEffect.d.ts.map +1 -0
  78. package/dist/components/effects/PlanetaryRingsEffect.js +458 -0
  79. package/dist/components/effects/PortalEffect.d.ts +3 -3
  80. package/dist/components/effects/PortalEffect.d.ts.map +1 -1
  81. package/dist/components/effects/PortalEffect.js +240 -163
  82. package/dist/components/effects/ShockwaveEffect.d.ts +5 -3
  83. package/dist/components/effects/ShockwaveEffect.d.ts.map +1 -1
  84. package/dist/components/effects/ShockwaveEffect.js +538 -142
  85. package/dist/components/effects/SmokePlumeEffect.d.ts +3 -3
  86. package/dist/components/effects/SmokePlumeEffect.d.ts.map +1 -1
  87. package/dist/components/effects/SmokePlumeEffect.js +180 -116
  88. package/dist/components/effects/SmokeRingEffect.d.ts +3 -3
  89. package/dist/components/effects/SmokeRingEffect.d.ts.map +1 -1
  90. package/dist/components/effects/SmokeRingEffect.js +260 -135
  91. package/dist/components/effects/StrangeAttractorEffect.d.ts +11 -0
  92. package/dist/components/effects/StrangeAttractorEffect.d.ts.map +1 -0
  93. package/dist/components/effects/StrangeAttractorEffect.js +229 -0
  94. package/dist/components/effects/VolumetricFogEffect.d.ts +5 -3
  95. package/dist/components/effects/VolumetricFogEffect.d.ts.map +1 -1
  96. package/dist/components/effects/VolumetricFogEffect.js +211 -93
  97. package/dist/components/effects/WaterCausticsEffect.d.ts +13 -0
  98. package/dist/components/effects/WaterCausticsEffect.d.ts.map +1 -0
  99. package/dist/components/effects/WaterCausticsEffect.js +308 -0
  100. package/dist/components/effects/index.d.ts +9 -0
  101. package/dist/components/effects/index.d.ts.map +1 -1
  102. package/dist/components/effects/index.js +9 -0
  103. package/dist/components/index.d.ts +16 -0
  104. package/dist/components/index.d.ts.map +1 -1
  105. package/dist/components/index.js +8 -0
  106. package/dist/constants.d.ts +1 -1
  107. package/dist/constants.d.ts.map +1 -1
  108. package/dist/constants.js +1 -1
  109. package/dist/hooks/useModelObject.d.ts +6 -1
  110. package/dist/hooks/useModelObject.d.ts.map +1 -1
  111. package/dist/hooks/useModelObject.js +19 -6
  112. package/dist/types/gridConfigs.d.ts +98 -0
  113. package/dist/types/gridConfigs.d.ts.map +1 -1
  114. package/dist/types/index.d.ts +1 -1
  115. package/dist/types/index.d.ts.map +1 -1
  116. package/package.json +2 -2
@@ -0,0 +1,306 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useLayoutEffect, useMemo, useRef } from 'react';
3
+ import * as THREE from 'three';
4
+ import { useFrame } from '@react-three/fiber';
5
+ import { applyGenerativeAnimations } from '../../utils/handleGenerativeEffectsAnimations.js';
6
+ import { useObjectReady } from '../../hooks/useObjectReady.js';
7
+ /**
8
+ * Atmospheric ice optics around the object as a light source: a dispersed 22° halo, sun dogs, a parhelic circle and a light pillar. Use for cold skies, suns, lamps, magic light.
9
+ *
10
+ * D = 2·asin(n·sin30°) − 60° per channel (n 1.307→1.317) · parhelia use the Bravais index n′ = √(n²−sin²e)/cos e
11
+ */
12
+ const NOISE3 = /* glsl */ `
13
+ float hash13(vec3 p3){
14
+ p3 = fract(p3 * 0.1031);
15
+ p3 += dot(p3, p3.zyx + 31.32);
16
+ return fract((p3.x + p3.y) * p3.z);
17
+ }
18
+ float vnoise(vec3 p){
19
+ vec3 i = floor(p);
20
+ vec3 f = fract(p);
21
+ f = f * f * f * (f * (f * 6.0 - 15.0) + 10.0);
22
+ float n000 = hash13(i);
23
+ float n100 = hash13(i + vec3(1.0, 0.0, 0.0));
24
+ float n010 = hash13(i + vec3(0.0, 1.0, 0.0));
25
+ float n110 = hash13(i + vec3(1.0, 1.0, 0.0));
26
+ float n001 = hash13(i + vec3(0.0, 0.0, 1.0));
27
+ float n101 = hash13(i + vec3(1.0, 0.0, 1.0));
28
+ float n011 = hash13(i + vec3(0.0, 1.0, 1.0));
29
+ float n111 = hash13(i + vec3(1.0, 1.0, 1.0));
30
+ return mix(mix(mix(n000, n100, f.x), mix(n010, n110, f.x), f.y),
31
+ mix(mix(n001, n101, f.x), mix(n011, n111, f.x), f.y), f.z);
32
+ }
33
+ // low-frequency fBm; the rotation between octaves hides the lattice
34
+ const mat3 FBM_ROT = mat3(0.00, 0.80, 0.60, -0.80, 0.36, -0.48, -0.60, -0.48, 0.64);
35
+ float fbm3(vec3 p, int octaves){
36
+ float a = 0.5, s = 0.0;
37
+ for (int i = 0; i < 5; i++){
38
+ if (i >= octaves) break;
39
+ s += a * vnoise(p);
40
+ p = FBM_ROT * p * 2.02;
41
+ a *= 0.5;
42
+ }
43
+ return s;
44
+ }
45
+ `;
46
+ // ---------------------------------------------------------------------------
47
+ // Halos are refraction, not glow. A hexagonal ice prism has 60° side faces;
48
+ // a ray through two of them is deviated by at least D = 2 asin(n sin30°) - 60°,
49
+ // and randomly tumbling crystals pile light up at that minimum, so a ring of
50
+ // radius D appears around the light with a razor inner edge and a diffuse
51
+ // outer skirt. Ice is dispersive (n = 1.307 red, 1.317 blue), so the inner
52
+ // edge is red and the outside washes to white-blue; inside the ring no light
53
+ // is deviated at all, so the sky there is darker. The 90° prism faces give the
54
+ // same construction at 46°. Flat plate crystals drift with their faces level,
55
+ // so their 60° prisms act in the horizontal plane only: they put the same
56
+ // caustic left and right of the source at the Bravais index
57
+ // n' = sqrt(n^2 - sin^2 e)/cos e, which is why sun dogs sit a little further
58
+ // out as the source climbs, and vanish above e = 61°. Reflections off those
59
+ // same level faces give the parhelic circle and, off their ends, the pillar.
60
+ // Everything is drawn on one billboard by measuring, per pixel, the angle
61
+ // between the view ray and the direction to the source.
62
+ // ---------------------------------------------------------------------------
63
+ const haloVert = /* glsl */ `
64
+ uniform float uHaloScale;
65
+ uniform float uBound;
66
+ varying vec3 vViewPos;
67
+ varying vec3 vSunView;
68
+ varying float vScale;
69
+ varying float vHalf;
70
+ varying float vSrc;
71
+ void main(){
72
+ vec4 hostView = modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0);
73
+ float D = max(-hostView.z, 0.05);
74
+ // angular radius of the source; keep the 22 deg ring clear of it
75
+ float hostAng = atan(uBound / max(D, uBound * 1.02));
76
+ float s = max(uHaloScale, hostAng * 1.7 / 0.38397);
77
+ vScale = s;
78
+ float A = clamp(0.8029 * s * 1.3 + 0.10, 0.22, 1.31);
79
+ vHalf = A;
80
+ // apparent size of the source, in the same units the halo angles are measured in
81
+ vSrc = max(hostAng / s * 57.2957795, 0.6);
82
+ float zq = max(D - uBound * 1.05, 0.06);
83
+ vec3 c = hostView.xyz * (zq / D);
84
+ float hq = zq * tan(A) * 1.3;
85
+ vec3 p = c + vec3(position.x * hq, position.y * hq, 0.0);
86
+ vViewPos = p;
87
+ vSunView = hostView.xyz;
88
+ gl_Position = projectionMatrix * vec4(p, 1.0);
89
+ }
90
+ `;
91
+ const haloFrag = /* glsl */ `
92
+ uniform float uTime;
93
+ uniform vec3 uColor;
94
+ uniform float uIntensity;
95
+ uniform float uOpacity;
96
+ uniform float uSunDogs;
97
+ uniform float uOuterHalo;
98
+ uniform float uParhelicCircle;
99
+ uniform float uPillar;
100
+ uniform float uGlare;
101
+ ${NOISE3}
102
+ varying vec3 vViewPos;
103
+ varying vec3 vSunView;
104
+ varying float vScale;
105
+ varying float vHalf;
106
+ varying float vSrc;
107
+
108
+ const float DEG = 57.2957795;
109
+
110
+ // minimum deviation of a prism of apex angle 2*half (in degrees in, degrees out)
111
+ float minDev(float n, float sinHalf, float apex){
112
+ float q = n * sinHalf;
113
+ if (q >= 0.9999) return 999.0;
114
+ return 2.0 * asin(q) * DEG - apex;
115
+ }
116
+ // the caustic profile: nothing inside, a sharp edge, a 1/sqrt pile-up, a skirt
117
+ float ringProfile(float th, float d, float aa, float tail){
118
+ if (d > 500.0) return 0.0;
119
+ float x = th - d;
120
+ float e = smoothstep(-aa, aa, x);
121
+ return e * (0.45 / sqrt(max(x, 0.0) + 0.45)) * exp(-max(x, 0.0) / tail);
122
+ }
123
+
124
+ void main(){
125
+ vec3 d = normalize(vViewPos);
126
+ vec3 sV = normalize(vSunView);
127
+ // view space -> world space (the view matrix rotation is orthonormal)
128
+ vec3 dW = normalize((vec4(d, 0.0) * viewMatrix).xyz);
129
+ vec3 sW = normalize((vec4(sV, 0.0) * viewMatrix).xyz);
130
+ float cd = dot(dW, sW);
131
+ if (cd <= 0.05) discard;
132
+
133
+ // frame around the source: h horizontal (world XZ), vv upward
134
+ vec3 hx = cross(sW, vec3(0.0, 1.0, 0.0));
135
+ float hl = length(hx);
136
+ hx = hl > 0.02 ? hx / hl : normalize(cross(sW, vec3(1.0, 0.0, 0.0)));
137
+ vec3 vv = cross(hx, sW);
138
+
139
+ vec2 t = vec2(dot(dW, hx), dot(dW, vv)) / cd; // gnomonic tangent plane
140
+ float rho = atan(length(t));
141
+ float edgeFade = 1.0 - smoothstep(vHalf * 0.8, vHalf * 0.99, rho);
142
+ if (edgeFade <= 0.001) discard;
143
+ float rhoP = rho / max(vScale, 0.02); // physical angle from the source
144
+ float TH = rhoP * DEG;
145
+ vec2 dir = length(t) > 1e-6 ? normalize(t) : vec2(1.0, 0.0);
146
+ vec3 D3 = normalize(sW * cos(rhoP) + (hx * dir.x + vv * dir.y) * sin(rhoP));
147
+
148
+ float es = asin(clamp(sW.y, -1.0, 1.0));
149
+ float E = asin(clamp(D3.y, -1.0, 1.0));
150
+ vec2 a1 = vec2(D3.x, D3.z);
151
+ vec2 a0 = vec2(sW.x, sW.z);
152
+ float la1 = length(a1), la0 = length(a0);
153
+ a1 = la1 > 1e-4 ? a1 / la1 : vec2(1.0, 0.0);
154
+ a0 = la0 > 1e-4 ? a0 / la0 : vec2(1.0, 0.0);
155
+ float dphi = atan(a1.x * a0.y - a1.y * a0.x, dot(a1, a0)) * DEG;
156
+ float dE = (E - es) * DEG;
157
+
158
+ float aa = max(0.30, fwidth(TH) * 0.9);
159
+ // slow shimmer: crystal swarms drifting through the beam, never flickering
160
+ float shim = 0.86 + 0.3 * vnoise(vec3(dir * 2.1 + vec2(0.0, -uTime * 0.05), uTime * 0.09));
161
+
162
+ // ---- 22 deg halo, dispersed per channel ------------------------------
163
+ float nR = 1.307, nG = 1.3112, nB = 1.317;
164
+ float d22r = minDev(nR, 0.5, 60.0);
165
+ float d22g = minDev(nG, 0.5, 60.0);
166
+ float d22b = minDev(nB, 0.5, 60.0);
167
+ vec3 halo = vec3(ringProfile(TH, d22r, aa, 4.2),
168
+ ringProfile(TH, d22g, aa, 5.0),
169
+ ringProfile(TH, d22b, aa, 7.5)) * 0.8 * shim;
170
+
171
+ // ---- 46 deg halo from the 90 deg prism faces -------------------------
172
+ float s45 = 0.70710678;
173
+ vec3 halo46 = vec3(ringProfile(TH, minDev(nR, s45, 90.0), aa * 1.6, 7.0),
174
+ ringProfile(TH, minDev(nG, s45, 90.0), aa * 1.6, 8.0),
175
+ ringProfile(TH, minDev(nB, s45, 90.0), aa * 1.6, 11.0)) * 0.13 * uOuterHalo * shim;
176
+
177
+ // ---- sun dogs: the same caustic in the horizontal plane, Bravais index
178
+ float ce = max(cos(es), 0.05);
179
+ float se = sin(es);
180
+ float npR = sqrt(max(nR * nR - se * se, 0.0)) / ce;
181
+ float npG = sqrt(max(nG * nG - se * se, 0.0)) / ce;
182
+ float npB = sqrt(max(nB * nB - se * se, 0.0)) / ce;
183
+ float aph = abs(dphi);
184
+ float vert = exp(-dE * dE / (2.0 * 1.25 * 1.25)) * (1.0 - smoothstep(50.0, 61.0, abs(es) * DEG));
185
+ vec3 dogs = vec3(ringProfile(aph, minDev(npR, 0.5, 60.0), aa * 1.2, 5.0),
186
+ ringProfile(aph, minDev(npG, 0.5, 60.0), aa * 1.2, 6.5),
187
+ ringProfile(aph, minDev(npB, 0.5, 60.0), aa * 1.2, 11.0));
188
+ // the outward tail of a sun dog runs white along the parhelic circle
189
+ float tail = smoothstep(-aa, aa, aph - minDev(npG, 0.5, 60.0)) * exp(-max(aph - minDev(npG, 0.5, 60.0), 0.0) / 11.0);
190
+ dogs = (dogs + vec3(tail) * 0.12) * vert * 1.5 * uSunDogs * shim;
191
+
192
+ // ---- parhelic circle: reflection off the vertical faces of plates -----
193
+ float pc = exp(-dE * dE / (2.0 * 0.55 * 0.55)) / (1.0 + aph / 45.0);
194
+ pc *= uParhelicCircle * 0.085 * (0.8 + 0.4 * shim);
195
+
196
+ // ---- light pillar: reflection off the near-horizontal basal faces -----
197
+ float pilW = 1.1 + 0.06 * abs(dE);
198
+ float pil = exp(-pow(dphi * cos(E) / pilW, 2.0)) * (exp(-max(dE, 0.0) / 8.0) + 0.55 * exp(-max(-dE, 0.0) / 6.0));
199
+ pil *= uPillar * 0.5 * shim;
200
+
201
+ // ---- glare around the source -----------------------------------------
202
+ // the glare hugs the source, so it is sized by the source, not by a fixed angle
203
+ float G = vSrc;
204
+ float gl = uGlare * (0.95 * exp(-TH / (0.5 * G)) + 0.3 * exp(-TH / (1.5 * G)) + 0.07 * exp(-TH / (5.0 * G)));
205
+
206
+ vec3 tint = uColor;
207
+ vec3 col = (halo + halo46 + dogs) * mix(vec3(1.0), tint, 0.35)
208
+ + (pc + pil + gl) * tint;
209
+ col *= edgeFade * uIntensity * uOpacity;
210
+ float lum = max(col.r, max(col.g, col.b));
211
+ if (lum < 0.002) discard;
212
+ // premultiplied: the alpha follows the light, so the quad never shows as a rectangle
213
+ gl_FragColor = vec4(col, min(lum, 1.0));
214
+ }
215
+ `;
216
+ function createUniforms() {
217
+ return {
218
+ uTime: { value: 0 },
219
+ uSpeed: { value: 1 },
220
+ uIntensity: { value: 1 },
221
+ uOpacity: { value: 1 },
222
+ uColor: { value: new THREE.Color('#fff2dd') },
223
+ uHaloScale: { value: 0.35 },
224
+ uSunDogs: { value: 0.8 },
225
+ uOuterHalo: { value: 0.4 },
226
+ uParhelicCircle: { value: 0.35 },
227
+ uPillar: { value: 0.45 },
228
+ uGlare: { value: 0.9 },
229
+ uBound: { value: 1 },
230
+ };
231
+ }
232
+ function applyConfig(u, c, bound, env) {
233
+ u.uSpeed.value = c.speed;
234
+ u.uIntensity.value = c.intensity;
235
+ u.uOpacity.value = c.opacity;
236
+ u.uColor.value.set(c.color);
237
+ u.uHaloScale.value = c.haloScale;
238
+ u.uSunDogs.value = c.sunDogs;
239
+ u.uOuterHalo.value = c.outerHalo;
240
+ u.uParhelicCircle.value = c.parhelicCircle;
241
+ u.uPillar.value = c.pillar;
242
+ u.uGlare.value = c.glare;
243
+ u.uBound.value = bound;
244
+ }
245
+ function build(u, c, bound, env) {
246
+ const mat = new THREE.ShaderMaterial({
247
+ vertexShader: haloVert, fragmentShader: haloFrag, uniforms: u,
248
+ transparent: true, depthWrite: false, blending: THREE.AdditiveBlending, premultipliedAlpha: true, side: THREE.DoubleSide,
249
+ });
250
+ const quad = new THREE.PlaneGeometry(2, 2);
251
+ const sheet = new THREE.Mesh(quad, mat);
252
+ sheet.frustumCulled = false;
253
+ const group = new THREE.Group();
254
+ group.add(sheet);
255
+ return {
256
+ object: group,
257
+ materials: [mat],
258
+ apply(c2) {
259
+ },
260
+ update(dt, camera) {
261
+ u.uTime.value += dt * u.uSpeed.value;
262
+ },
263
+ dispose() {
264
+ quad.dispose();
265
+ mat.dispose();
266
+ },
267
+ };
268
+ }
269
+ /** Defaults for every knob, so an older saved config still renders. */
270
+ const DEFAULTS = {
271
+ intensity: 1,
272
+ speed: 1,
273
+ color: '#fff2dd',
274
+ opacity: 1,
275
+ haloScale: 0.35,
276
+ sunDogs: 0.8,
277
+ outerHalo: 0.4,
278
+ parhelicCircle: 0.35,
279
+ pillar: 0.45,
280
+ glare: 0.9,
281
+ };
282
+ const IceHaloEffect = ({ boundingRadius, config, animations, hasHost = false, onObjectReady, onObjectDispose }) => {
283
+ const rootRef = useRef(null);
284
+ const animCache = useRef({});
285
+ useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
286
+ // a standalone effect gets boundingRadius 1
287
+ const b = boundingRadius > 0 ? boundingRadius : 1;
288
+ const cfg = useMemo(() => ({ ...DEFAULTS, ...config }), [config]);
289
+ const env = useMemo(() => ({ hasHost: hasHost }), [hasHost]);
290
+ // uniforms outlive the objects, so keyframe animations survive a rebuild
291
+ const uniforms = useMemo(() => createUniforms(), []);
292
+ // rebuilt only when the host size or a structural knob changes
293
+ const instance = useMemo(() => build(uniforms, { ...DEFAULTS, ...config }, b, env), [uniforms, b, env]);
294
+ useEffect(() => () => instance.dispose(), [instance]);
295
+ useLayoutEffect(() => {
296
+ applyConfig(uniforms, cfg, b, env);
297
+ instance.apply(cfg);
298
+ }, [instance, uniforms, cfg, b, env]);
299
+ useFrame((state, delta) => {
300
+ instance.update(Math.min(delta, 0.1), state.camera);
301
+ if (animations?.length)
302
+ applyGenerativeAnimations(instance.materials, animations, animCache.current, Date.now(), false);
303
+ });
304
+ return (_jsx("group", { ref: rootRef, children: _jsx("primitive", { object: instance.object }) }));
305
+ };
306
+ export default IceHaloEffect;
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import type { AnimationOptions, LichtenbergConfig } from '@3driseai/3drise-core';
3
+ import type { ObjectReadyProps } from '../../types/objectReady';
4
+ export interface LichtenbergEffectProps extends ObjectReadyProps {
5
+ boundingRadius: number;
6
+ config: LichtenbergConfig;
7
+ animations?: AnimationOptions[];
8
+ /** True when the effect is attached to an object, so it can react to the host. */
9
+ hasHost?: boolean;
10
+ }
11
+ declare const LichtenbergEffect: React.FC<LichtenbergEffectProps>;
12
+ export default LichtenbergEffect;
13
+ //# sourceMappingURL=LichtenbergEffect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LichtenbergEffect.d.ts","sourceRoot":"","sources":["../../../src/components/effects/LichtenbergEffect.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsD,MAAM,OAAO,CAAC;AAG3E,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAGjF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,kFAAkF;IAClF,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AA6cD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CA+BvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}