@3driseai/3drise-core 1.0.10 → 1.0.12

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 (59) hide show
  1. package/dist/data/effectsDefaults.d.ts.map +1 -1
  2. package/dist/data/effectsDefaults.js +32 -8
  3. package/dist/data/index.d.ts +1 -0
  4. package/dist/data/index.d.ts.map +1 -1
  5. package/dist/data/index.js +1 -0
  6. package/dist/data/particlesDefaults.d.ts +6 -0
  7. package/dist/data/particlesDefaults.d.ts.map +1 -0
  8. package/dist/data/particlesDefaults.js +22 -0
  9. package/dist/shaders/ChladniGridMaterial.d.ts +77 -0
  10. package/dist/shaders/ChladniGridMaterial.d.ts.map +1 -0
  11. package/dist/shaders/ChladniGridMaterial.js +301 -0
  12. package/dist/shaders/FlowNetGridMaterial.d.ts +74 -0
  13. package/dist/shaders/FlowNetGridMaterial.d.ts.map +1 -0
  14. package/dist/shaders/FlowNetGridMaterial.js +269 -0
  15. package/dist/shaders/GirihGridMaterial.d.ts +77 -0
  16. package/dist/shaders/GirihGridMaterial.d.ts.map +1 -0
  17. package/dist/shaders/GirihGridMaterial.js +464 -0
  18. package/dist/shaders/GravWaveGridMaterial.d.ts +77 -0
  19. package/dist/shaders/GravWaveGridMaterial.d.ts.map +1 -0
  20. package/dist/shaders/GravWaveGridMaterial.js +479 -0
  21. package/dist/shaders/HyperbolicGridMaterial.d.ts +74 -0
  22. package/dist/shaders/HyperbolicGridMaterial.d.ts.map +1 -0
  23. package/dist/shaders/HyperbolicGridMaterial.js +298 -0
  24. package/dist/shaders/ReactionDiffusionGridMaterial.d.ts +80 -0
  25. package/dist/shaders/ReactionDiffusionGridMaterial.d.ts.map +1 -0
  26. package/dist/shaders/ReactionDiffusionGridMaterial.js +247 -0
  27. package/dist/shaders/WallpaperGridMaterial.d.ts +134 -0
  28. package/dist/shaders/WallpaperGridMaterial.d.ts.map +1 -0
  29. package/dist/shaders/WallpaperGridMaterial.js +433 -0
  30. package/dist/shaders/index.d.ts +7 -0
  31. package/dist/shaders/index.d.ts.map +1 -1
  32. package/dist/shaders/index.js +7 -0
  33. package/dist/types/gallery.d.ts +21 -0
  34. package/dist/types/gallery.d.ts.map +1 -1
  35. package/dist/types/generativeEffects.d.ts +270 -2
  36. package/dist/types/generativeEffects.d.ts.map +1 -1
  37. package/dist/types/generativeParticles.d.ts +253 -0
  38. package/dist/types/generativeParticles.d.ts.map +1 -0
  39. package/dist/types/generativeParticles.js +6 -0
  40. package/dist/types/index.d.ts +1 -0
  41. package/dist/types/index.d.ts.map +1 -1
  42. package/dist/types/mesh.d.ts +3 -0
  43. package/dist/types/mesh.d.ts.map +1 -1
  44. package/dist/types/objectSettings.d.ts +2 -1
  45. package/dist/types/objectSettings.d.ts.map +1 -1
  46. package/dist/utils/GalleryCreator.d.ts +4 -75
  47. package/dist/utils/GalleryCreator.d.ts.map +1 -1
  48. package/dist/utils/GalleryCreator.js +12 -461
  49. package/dist/utils/LayoutCreator.d.ts +125 -0
  50. package/dist/utils/LayoutCreator.d.ts.map +1 -0
  51. package/dist/utils/LayoutCreator.js +521 -0
  52. package/dist/utils/galleriesUtils.d.ts.map +1 -1
  53. package/dist/utils/galleriesUtils.js +3 -2
  54. package/dist/utils/handleTransformEffects.d.ts.map +1 -1
  55. package/dist/utils/handleTransformEffects.js +5 -3
  56. package/dist/utils/index.d.ts +1 -0
  57. package/dist/utils/index.d.ts.map +1 -1
  58. package/dist/utils/index.js +1 -0
  59. package/package.json +1 -1
@@ -1,465 +1,16 @@
1
+ import { LayoutCreator } from "./LayoutCreator.js";
2
+ /**
3
+ * Gallery frames: the layout slots from LayoutCreator with one image url stamped on each.
4
+ * The layout math itself lives in LayoutCreator so scene objects can share it.
5
+ */
1
6
  export class GalleryCreator {
2
- /**
3
- * Creates a scattered gallery layout with concentric circles
4
- * Center image + rings of images around it, with side images rotated inward
5
- */
6
- static scattered(imageUrls, spacing = 3.5, count) {
7
- const numImages = count || imageUrls.length;
8
- const frames = [];
9
- const actualCount = Math.min(numImages, imageUrls.length);
10
- if (actualCount === 0)
11
- return frames;
12
- // First image at center
13
- frames.push({
14
- url: imageUrls[0],
15
- position: [0, 0, 0],
16
- rotation: [0, 0, 0],
17
- videoSrc: null,
18
- });
19
- let imageIndex = 1;
20
- let ringNumber = 1;
21
- // Distribute remaining images across rings
22
- while (imageIndex < actualCount) {
23
- const radius = ringNumber * spacing;
24
- // Each ring can hold more images as radius increases
25
- const imagesInRing = Math.min(Math.ceil(6 + ringNumber * 2), // 8, 10, 12, 14... images per ring
26
- actualCount - imageIndex);
27
- for (let i = 0; i < imagesInRing && imageIndex < actualCount; i++) {
28
- const angle = (i / imagesInRing) * Math.PI * 2;
29
- const x = Math.cos(angle) * radius;
30
- const z = Math.sin(angle) * radius;
31
- frames.push({
32
- url: imageUrls[imageIndex],
33
- position: [x, 0, z],
34
- rotation: [0, 0, 0], // All images face forward for now
35
- videoSrc: null,
36
- });
37
- imageIndex++;
38
- }
39
- ringNumber++;
40
- }
41
- return frames;
42
- }
43
- /**
44
- * Creates a grid/tile layout with frames arranged in rows and columns
45
- */
46
- static tiles(imageUrls, columns = 3, spacing = 2.5) {
47
- const frames = [];
48
- const totalImages = imageUrls.length;
49
- const rows = Math.ceil(totalImages / columns);
50
- // Calculate centering offset to position gallery center at [0, 0, 0]
51
- const totalWidth = (columns - 1) * spacing;
52
- const totalHeight = (rows - 1) * spacing;
53
- const offsetX = -totalWidth / 2;
54
- const offsetY = -totalHeight / 2;
55
- for (let i = 0; i < totalImages; i++) {
56
- const row = Math.floor(i / columns);
57
- const col = i % columns;
58
- frames.push({
59
- url: imageUrls[i],
60
- position: [
61
- offsetX + col * spacing,
62
- offsetY + row * spacing,
63
- 0, // Centered at origin
64
- ],
65
- rotation: [0, 0, 0],
66
- videoSrc: null,
67
- });
68
- }
69
- return frames;
70
- }
71
- /**
72
- * Creates a horizontal row layout
73
- */
74
- static horizontal(imageUrls, spacing = 2.5, startX = 0) {
75
- const frames = [];
76
- const totalImages = imageUrls.length;
77
- // Calculate centering offset to position gallery center at [0, 0, 0]
78
- const totalWidth = (totalImages - 1) * spacing;
79
- const offsetX = startX - totalWidth / 2;
80
- for (let i = 0; i < totalImages; i++) {
81
- frames.push({
82
- url: imageUrls[i],
83
- position: [offsetX + i * spacing, 0, 0],
84
- rotation: [0, 0, 0],
85
- videoSrc: null,
86
- });
87
- }
88
- return frames;
89
- }
90
- /**
91
- * Creates a vertical column layout
92
- */
93
- static vertical(imageUrls, spacing = 2.0, startY = 0) {
94
- const frames = [];
95
- const totalImages = imageUrls.length;
96
- // Calculate centering offset to position gallery center at [0, 0, 0]
97
- const totalHeight = (totalImages - 1) * spacing;
98
- const offsetY = startY - totalHeight / 2;
99
- for (let i = 0; i < totalImages; i++) {
100
- frames.push({
101
- url: imageUrls[i],
102
- position: [0, offsetY + i * spacing, 0],
103
- rotation: [0, 0, 0],
104
- videoSrc: null,
105
- });
106
- }
107
- return frames;
108
- }
109
- /**
110
- * Creates a circular layout with images arranged in a ring
111
- */
112
- static circular(imageUrls, radius = 5) {
113
- const frames = [];
114
- const totalImages = imageUrls.length;
115
- for (let i = 0; i < totalImages; i++) {
116
- const angle = (i / totalImages) * Math.PI * 2;
117
- const x = Math.cos(angle) * radius;
118
- const z = Math.sin(angle) * radius;
119
- frames.push({
120
- url: imageUrls[i],
121
- position: [x, 0, z],
122
- rotation: [0, -angle, 0], // Face inward
123
- videoSrc: null,
124
- });
125
- }
126
- return frames;
127
- }
128
- /**
129
- * Creates a spiral layout ascending or expanding outward
130
- */
131
- static spiral(imageUrls, radius = 5, rotations = 2, heightIncrement = 0.5) {
132
- const frames = [];
133
- const totalImages = imageUrls.length;
134
- for (let i = 0; i < totalImages; i++) {
135
- const progress = i / totalImages;
136
- const angle = progress * rotations * Math.PI * 2;
137
- const currentRadius = radius * (1 - progress * 0.3); // Spiral inward slightly
138
- const x = Math.cos(angle) * currentRadius;
139
- const z = Math.sin(angle) * currentRadius;
140
- const y = progress * totalImages * heightIncrement - (totalImages * heightIncrement) / 2;
141
- frames.push({
142
- url: imageUrls[i],
143
- position: [x, y, z],
144
- rotation: [0, -angle, 0],
145
- videoSrc: null,
146
- });
147
- }
148
- return frames;
149
- }
150
- /**
151
- * Creates an arc/curved layout
152
- */
153
- static arc(imageUrls, radius = 5, arcAngle = Math.PI) {
154
- const frames = [];
155
- const totalImages = imageUrls.length;
156
- for (let i = 0; i < totalImages; i++) {
157
- const progress = i / (totalImages - 1 || 1);
158
- const angle = -arcAngle / 2 + progress * arcAngle;
159
- const x = Math.sin(angle) * radius;
160
- const z = Math.cos(angle) * radius;
161
- frames.push({
162
- url: imageUrls[i],
163
- position: [x, 0, z],
164
- rotation: [0, -angle, 0],
165
- videoSrc: null,
166
- });
167
- }
168
- return frames;
169
- }
170
- /**
171
- * Creates a pyramid stack layout
172
- */
173
- static pyramid(imageUrls, layers = 3, spacing = 2.5) {
174
- const frames = [];
175
- let imageIndex = 0;
176
- for (let layer = layers; layer > 0; layer--) {
177
- const itemsInLayer = layer;
178
- const layerY = (layers - layer) * spacing - (layers * spacing) / 2;
179
- const layerWidth = (itemsInLayer - 1) * spacing;
180
- const offsetX = -layerWidth / 2;
181
- for (let i = 0; i < itemsInLayer && imageIndex < imageUrls.length; i++) {
182
- frames.push({
183
- url: imageUrls[imageIndex],
184
- position: [offsetX + i * spacing, layerY, 0],
185
- rotation: [0, 0, 0],
186
- videoSrc: null,
187
- });
188
- imageIndex++;
189
- }
190
- }
191
- return frames;
192
- }
193
- /**
194
- * Creates a helix (DNA-style spiral)
195
- */
196
- static helix(imageUrls, radius = 3, rotations = 3, heightIncrement = 0.4) {
197
- const frames = [];
198
- const totalImages = imageUrls.length;
199
- for (let i = 0; i < totalImages; i++) {
200
- const progress = i / totalImages;
201
- const angle = progress * rotations * Math.PI * 2;
202
- const x = Math.cos(angle) * radius;
203
- const z = Math.sin(angle) * radius;
204
- const y = progress * totalImages * heightIncrement - (totalImages * heightIncrement) / 2;
205
- frames.push({
206
- url: imageUrls[i],
207
- position: [x, y, z],
208
- rotation: [0, -angle - Math.PI / 2, 0], // Tangent to helix
209
- videoSrc: null,
210
- });
211
- }
212
- return frames;
213
- }
214
- /**
215
- * Creates a 3D box layout with images on all 6 faces
216
- */
217
- static box(imageUrls, size = 5) {
218
- const frames = [];
219
- const imagesPerFace = Math.ceil(imageUrls.length / 6);
220
- let imageIndex = 0;
221
- // Define the 6 faces: Front, Back, Right, Left, Top, Bottom
222
- const faceConfigs = [
223
- { name: 'Front', basePos: [0, 0, size], baseRot: [0, 0, 0] },
224
- { name: 'Back', basePos: [0, 0, -size], baseRot: [0, Math.PI, 0] },
225
- { name: 'Right', basePos: [size, 0, 0], baseRot: [0, Math.PI / 2, 0] },
226
- { name: 'Left', basePos: [-size, 0, 0], baseRot: [0, -Math.PI / 2, 0] },
227
- { name: 'Top', basePos: [0, size, 0], baseRot: [-Math.PI / 2, 0, 0] },
228
- { name: 'Bottom', basePos: [0, -size, 0], baseRot: [Math.PI / 2, 0, 0] }
229
- ];
230
- for (let faceIndex = 0; faceIndex < 6 && imageIndex < imageUrls.length; faceIndex++) {
231
- const config = faceConfigs[faceIndex];
232
- const itemsOnFace = Math.min(imagesPerFace, imageUrls.length - imageIndex);
233
- const cols = Math.ceil(Math.sqrt(itemsOnFace));
234
- const rows = Math.ceil(itemsOnFace / cols);
235
- const spacing = (size * 1.8) / Math.max(cols, rows);
236
- for (let i = 0; i < itemsOnFace; i++) {
237
- const row = Math.floor(i / cols);
238
- const col = i % cols;
239
- const offsetX = (col - (cols - 1) / 2) * spacing;
240
- const offsetY = (row - (rows - 1) / 2) * spacing;
241
- // Calculate position based on face orientation
242
- let position;
243
- if (faceIndex === 0)
244
- position = [offsetX, offsetY, size]; // Front
245
- else if (faceIndex === 1)
246
- position = [-offsetX, offsetY, -size]; // Back (mirror X)
247
- else if (faceIndex === 2)
248
- position = [size, offsetY, -offsetX]; // Right (X fixed, offset in -Z)
249
- else if (faceIndex === 3)
250
- position = [-size, offsetY, offsetX]; // Left (X fixed, offset in +Z)
251
- else if (faceIndex === 4)
252
- position = [offsetX, size, -offsetY]; // Top (Y fixed, offset in -Z)
253
- else
254
- position = [offsetX, -size, offsetY]; // Bottom (Y fixed, offset in +Z)
255
- frames.push({
256
- url: imageUrls[imageIndex],
257
- position,
258
- rotation: config.baseRot,
259
- videoSrc: null,
260
- });
261
- imageIndex++;
262
- }
263
- }
264
- return frames;
265
- }
266
- /**
267
- * Creates a sphere layout with images distributed evenly on a sphere surface
268
- * Uses Fibonacci sphere algorithm for even distribution
269
- */
270
- static sphere(imageUrls, radius = 5) {
271
- const frames = [];
272
- const totalImages = imageUrls.length;
273
- const goldenRatio = (1 + Math.sqrt(5)) / 2;
274
- const angleIncrement = Math.PI * 2 * goldenRatio;
275
- for (let i = 0; i < totalImages; i++) {
276
- // Fibonacci sphere distribution
277
- const t = i / totalImages;
278
- const inclination = Math.acos(1 - 2 * t); // 0 to PI (theta - angle from north pole)
279
- const azimuth = angleIncrement * i; // phi - angle around equator
280
- // Convert spherical to Cartesian coordinates
281
- const x = radius * Math.sin(inclination) * Math.cos(azimuth);
282
- const y = radius * Math.cos(inclination);
283
- const z = radius * Math.sin(inclination) * Math.sin(azimuth);
284
- frames.push({
285
- url: imageUrls[i],
286
- position: [x, y, z],
287
- rotation: [0, 0, 0],
288
- videoSrc: null,
289
- });
290
- }
291
- return frames;
292
- }
293
- /**
294
- * Creates a fan/radial layout
295
- */
296
- static fan(imageUrls, radius = 5, arcAngle = Math.PI * 1.5) {
297
- const frames = [];
298
- const totalImages = imageUrls.length;
299
- for (let i = 0; i < totalImages; i++) {
300
- const progress = i / (totalImages - 1 || 1);
301
- const angle = -arcAngle / 2 + progress * arcAngle;
302
- const x = Math.sin(angle) * radius;
303
- const z = Math.cos(angle) * radius;
304
- frames.push({
305
- url: imageUrls[i],
306
- position: [x, 0, z],
307
- rotation: [0, -angle, 0], // All face center
308
- videoSrc: null,
309
- });
310
- }
311
- return frames;
312
- }
313
- /**
314
- * Creates a wave pattern layout
315
- */
316
- static wave(imageUrls, amplitude = 2, frequency = 2, spacing = 1.5) {
317
- const frames = [];
318
- const totalImages = imageUrls.length;
319
- const totalWidth = (totalImages - 1) * spacing;
320
- const offsetX = -totalWidth / 2;
321
- for (let i = 0; i < totalImages; i++) {
322
- const x = offsetX + i * spacing;
323
- const progress = i / totalImages;
324
- const y = Math.sin(progress * frequency * Math.PI * 2) * amplitude;
325
- frames.push({
326
- url: imageUrls[i],
327
- position: [x, y, 0],
328
- rotation: [0, 0, 0],
329
- videoSrc: null,
330
- });
331
- }
332
- return frames;
333
- }
334
- /**
335
- * Creates a tunnel/perspective layout
336
- */
337
- static tunnel(imageUrls, depth = 20, scaleFactor = 0.8) {
338
- const frames = [];
339
- const totalImages = imageUrls.length;
340
- for (let i = 0; i < totalImages; i++) {
341
- const progress = i / totalImages;
342
- const z = -progress * depth;
343
- const scale = Math.pow(scaleFactor, i);
344
- frames.push({
345
- url: imageUrls[i],
346
- position: [0, 0, z],
347
- rotation: [0, 0, 0],
348
- videoSrc: null,
349
- });
350
- }
351
- return frames;
352
- }
353
- /**
354
- * Creates a tunnel-pyramid layout combining depth perspective with pyramid stacking
355
- * Starts with 1 frame at front, expands as it recedes. All at y=0
356
- */
357
- static tunnelPyramid(imageUrls, depth = 20, layers = 6, spacing = 2.5) {
358
- const frames = [];
359
- let imageIndex = 0;
360
- let currentLayer = 1;
361
- // Continue adding layers until all images are placed
362
- while (imageIndex < imageUrls.length) {
363
- const itemsInLayer = currentLayer;
364
- const layerProgress = (currentLayer - 1) / (layers - 1 || 1);
365
- const z = -layerProgress * depth;
366
- const layerWidth = (itemsInLayer - 1) * spacing;
367
- const offsetX = -layerWidth / 2;
368
- for (let i = 0; i < itemsInLayer && imageIndex < imageUrls.length; i++) {
369
- frames.push({
370
- url: imageUrls[imageIndex],
371
- position: [offsetX + i * spacing, 0, z], // Y always 0
372
- rotation: [0, 0, 0],
373
- videoSrc: null,
374
- });
375
- imageIndex++;
376
- }
377
- currentLayer++;
378
- }
379
- return frames;
380
- }
381
- /**
382
- * Creates a tunnel-wave layout combining depth perspective with wave pattern
383
- * Wave pattern in X axis, all at y=0, receding in Z
384
- */
385
- static tunnelWave(imageUrls, depth = 20, amplitude = 2, frequency = 2, spacing = 1.5) {
386
- const frames = [];
387
- const totalImages = imageUrls.length;
388
- for (let i = 0; i < totalImages; i++) {
389
- const progress = i / totalImages;
390
- const x = Math.sin(progress * frequency * Math.PI * 2) * amplitude;
391
- const z = -progress * depth;
392
- frames.push({
393
- url: imageUrls[i],
394
- position: [x, 0, z], // Y always 0, wave in X
395
- rotation: [0, 0, 0],
396
- videoSrc: null,
397
- });
398
- }
399
- return frames;
400
- }
401
- /**
402
- * Creates a random/organic layout
403
- */
404
- static random(imageUrls, bounds = 8) {
405
- const frames = [];
406
- const totalImages = imageUrls.length;
407
- for (let i = 0; i < totalImages; i++) {
408
- const x = (Math.random() - 0.5) * bounds * 2;
409
- const y = (Math.random() - 0.5) * bounds;
410
- const z = (Math.random() - 0.5) * bounds * 2;
411
- const rotY = Math.random() * Math.PI * 2;
412
- frames.push({
413
- url: imageUrls[i],
414
- position: [x, y, z],
415
- rotation: [0, rotY, 0],
416
- videoSrc: null,
417
- });
418
- }
419
- return frames;
420
- }
421
- /**
422
- * Main method to generate gallery layout based on settings
423
- */
424
7
  static generateGallery(imageUrls, settings) {
425
- console.log('GalleryCreator.generate called with settings:', settings);
426
- switch (settings.layout) {
427
- case 'scattered':
428
- return this.scattered(imageUrls, settings.spacing || 3.5);
429
- case 'tiles':
430
- return this.tiles(imageUrls, settings.columns || 3, settings.spacing || 2.5);
431
- case 'horizontal':
432
- return this.horizontal(imageUrls, settings.spacing || 2.5, settings.startX || 0);
433
- case 'vertical':
434
- return this.vertical(imageUrls, settings.spacing || 2.0, settings.startY || 0);
435
- case 'circular':
436
- return this.circular(imageUrls, settings.radius || 5);
437
- case 'spiral':
438
- return this.spiral(imageUrls, settings.radius || 5, settings.rotations || 2, settings.heightIncrement || 0.5);
439
- case 'arc':
440
- return this.arc(imageUrls, settings.radius || 5, settings.arcAngle || Math.PI);
441
- case 'pyramid':
442
- return this.pyramid(imageUrls, settings.layers || 3, settings.spacing || 2.5);
443
- case 'helix':
444
- return this.helix(imageUrls, settings.radius || 3, settings.rotations || 3, settings.heightIncrement || 0.4);
445
- case 'box':
446
- return this.box(imageUrls, settings.size || 5);
447
- case 'sphere':
448
- return this.sphere(imageUrls, settings.radius || 5);
449
- case 'fan':
450
- return this.fan(imageUrls, settings.radius || 5, settings.arcAngle || Math.PI * 1.5);
451
- case 'wave':
452
- return this.wave(imageUrls, settings.amplitude || 2, settings.frequency || 2, settings.spacing || 1.5);
453
- case 'tunnel':
454
- return this.tunnel(imageUrls, settings.depth || 20, settings.scaleFactor || 0.8);
455
- case 'tunnelPyramid':
456
- return this.tunnelPyramid(imageUrls, settings.depth || 20, settings.layers || 3, settings.spacing || 2.5);
457
- case 'tunnelWave':
458
- return this.tunnelWave(imageUrls, settings.depth || 20, settings.amplitude || 2, settings.frequency || 2, settings.spacing || 1.5);
459
- case 'random':
460
- return this.random(imageUrls, settings.bounds || 8);
461
- default:
462
- return this.scattered(imageUrls);
463
- }
8
+ return LayoutCreator.generate(imageUrls.length, settings).map((slot, i) => ({
9
+ url: imageUrls[i],
10
+ position: slot.position,
11
+ rotation: slot.rotation ?? [0, 0, 0],
12
+ ...(slot.scale ? { scale: slot.scale } : {}),
13
+ videoSrc: null,
14
+ }));
464
15
  }
465
16
  }
@@ -0,0 +1,125 @@
1
+ import type { GalleryLayout, LayoutParams, LayoutSlot, ObjectLayoutSettings } from "../types/gallery";
2
+ import type { CreatedObjectSettings } from "../types/scene3d";
3
+ export declare class LayoutCreator {
4
+ /**
5
+ * Creates a scattered gallery layout with concentric circles
6
+ * Center image + rings of images around it, with side images rotated inward
7
+ */
8
+ static scattered(count: number, spacing?: number): LayoutSlot[];
9
+ /**
10
+ * Creates a grid/tile layout with frames arranged in rows and columns
11
+ */
12
+ static tiles(count: number, columns?: number, spacing?: number): LayoutSlot[];
13
+ /**
14
+ * Creates a horizontal row layout
15
+ */
16
+ static horizontal(count: number, spacing?: number, startX?: number): LayoutSlot[];
17
+ /**
18
+ * Creates a vertical column layout
19
+ */
20
+ static vertical(count: number, spacing?: number, startY?: number): LayoutSlot[];
21
+ /**
22
+ * Creates a circular layout with images arranged in a ring
23
+ */
24
+ static circular(count: number, radius?: number): LayoutSlot[];
25
+ /**
26
+ * Creates a spiral layout ascending or expanding outward
27
+ */
28
+ static spiral(count: number, radius?: number, rotations?: number, heightIncrement?: number): LayoutSlot[];
29
+ /**
30
+ * Creates an arc/curved layout
31
+ */
32
+ static arc(count: number, radius?: number, arcAngle?: number): LayoutSlot[];
33
+ /**
34
+ * Creates a pyramid stack layout
35
+ */
36
+ static pyramid(count: number, layers?: number, spacing?: number): LayoutSlot[];
37
+ /**
38
+ * Creates a helix (DNA-style spiral)
39
+ */
40
+ static helix(count: number, radius?: number, rotations?: number, heightIncrement?: number): LayoutSlot[];
41
+ /**
42
+ * Creates a 3D box layout with images on all 6 faces
43
+ */
44
+ static box(count: number, size?: number): LayoutSlot[];
45
+ /**
46
+ * Creates a sphere layout with images distributed evenly on a sphere surface
47
+ * Uses Fibonacci sphere algorithm for even distribution
48
+ */
49
+ static sphere(count: number, radius?: number): LayoutSlot[];
50
+ /**
51
+ * Creates a fan/radial layout
52
+ */
53
+ static fan(count: number, radius?: number, arcAngle?: number): LayoutSlot[];
54
+ /**
55
+ * Creates a wave pattern layout
56
+ */
57
+ static wave(count: number, amplitude?: number, frequency?: number, spacing?: number): LayoutSlot[];
58
+ /**
59
+ * Creates a tunnel/perspective layout
60
+ */
61
+ static tunnel(count: number, depth?: number, scaleFactor?: number): LayoutSlot[];
62
+ /**
63
+ * Creates a tunnel-pyramid layout combining depth perspective with pyramid stacking
64
+ * Starts with 1 frame at front, expands as it recedes. All at y=0
65
+ */
66
+ static tunnelPyramid(count: number, depth?: number, layers?: number, spacing?: number): LayoutSlot[];
67
+ /**
68
+ * Creates a tunnel-wave layout combining depth perspective with wave pattern
69
+ * Wave pattern in X axis, all at y=0, receding in Z
70
+ */
71
+ static tunnelWave(count: number, depth?: number, amplitude?: number, frequency?: number, spacing?: number): LayoutSlot[];
72
+ /**
73
+ * Creates a random/organic layout
74
+ */
75
+ static random(count: number, bounds?: number, seed?: number): LayoutSlot[];
76
+ /**
77
+ * Slots for `count` copies in the given layout. Reads only the fields the layout uses
78
+ * (see GALLERY_LAYOUT_CONFIGS); anything missing falls back to that layout's default.
79
+ */
80
+ static generate(count: number, settings: LayoutParams & {
81
+ layout?: GalleryLayout;
82
+ seed?: number;
83
+ }): LayoutSlot[];
84
+ }
85
+ export declare const generateLayoutSlots: (count: number, settings: LayoutParams & {
86
+ layout?: GalleryLayout;
87
+ seed?: number;
88
+ }) => LayoutSlot[];
89
+ /** Object types whose renderer output ObjectNode can repeat across layout slots. */
90
+ export declare const LAYOUT_CAPABLE_TYPES: ReadonlySet<string>;
91
+ export declare const DEFAULT_OBJECT_LAYOUT: ObjectLayoutSettings;
92
+ /**
93
+ * Saved objects predate this field. Absent means no layout at all — never the default —
94
+ * and a partial block is merged over the defaults so an added knob fills in.
95
+ */
96
+ export declare const normalizeObjectLayout: (layout: Partial<ObjectLayoutSettings> | null | undefined) => ObjectLayoutSettings | null;
97
+ /**
98
+ * Per-type ceilings on layout copies. Every copy is a full render of the object, so these
99
+ * track what each copy costs:
100
+ * - light: each one adds per-fragment cost to every lit material, and changing the light
101
+ * count recompiles every material (three.js keys programs on light counts).
102
+ * - effect: each copy is a whole particle / shader effect.
103
+ * - mesh in a points mode: each copy resamples its points (volumeFill raycasts in render).
104
+ * - model: geometry is shared with the cache master, but every part of every copy is its
105
+ * own draw call with its own material clone.
106
+ */
107
+ export declare const LAYOUT_COUNT_LIMITS: {
108
+ readonly mesh: 100;
109
+ readonly meshPoints: 12;
110
+ readonly model: 30;
111
+ readonly effect: 24;
112
+ readonly light: 8;
113
+ };
114
+ /** Light kinds a layout makes sense for: N directional copies are one brighter light, and
115
+ * an ambient light has no position. */
116
+ export declare const LAYOUT_LIGHT_KINDS: ReadonlySet<string>;
117
+ export interface ObjectLayoutSupport {
118
+ allowed: boolean;
119
+ /** Why not, in words the panel can show. */
120
+ reason?: string;
121
+ maxCount: number;
122
+ }
123
+ /** Whether this object can be repeated, and how many times. One answer for the viewer and the panel. */
124
+ export declare const getObjectLayoutSupport: (obj: Pick<CreatedObjectSettings, "type" | "config" | "modeConfig">) => ObjectLayoutSupport;
125
+ //# sourceMappingURL=LayoutCreator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LayoutCreator.d.ts","sourceRoot":"","sources":["../../src/utils/LayoutCreator.ts"],"names":[],"mappings":"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"}