@3driseai/3drise-viewer 0.1.21 → 0.1.23

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 (107) hide show
  1. package/dist/components/CreatedObject.d.ts.map +1 -1
  2. package/dist/components/CreatedObject.js +6 -1
  3. package/dist/components/LightObject.d.ts.map +1 -1
  4. package/dist/components/LightObject.js +24 -9
  5. package/dist/components/ModelPrimitive.d.ts.map +1 -1
  6. package/dist/components/ModelPrimitive.js +10 -1
  7. package/dist/components/ObjectNode.js +1 -1
  8. package/dist/components/ParticlesGenerator.d.ts +3 -1
  9. package/dist/components/ParticlesGenerator.d.ts.map +1 -1
  10. package/dist/components/ParticlesGenerator.js +2 -2
  11. package/dist/components/ProjectLoader.js +1 -1
  12. package/dist/components/SceneBuilder.d.ts.map +1 -1
  13. package/dist/components/SceneBuilder.js +5 -1
  14. package/dist/components/fluorescentTube/FluorescentTube.d.ts +14 -0
  15. package/dist/components/fluorescentTube/FluorescentTube.d.ts.map +1 -0
  16. package/dist/components/fluorescentTube/FluorescentTube.js +262 -0
  17. package/dist/components/fluorescentTube/index.d.ts +5 -0
  18. package/dist/components/fluorescentTube/index.d.ts.map +1 -0
  19. package/dist/components/fluorescentTube/index.js +3 -0
  20. package/dist/components/fluorescentTube/tubeMaterials.d.ts +34 -0
  21. package/dist/components/fluorescentTube/tubeMaterials.d.ts.map +1 -0
  22. package/dist/components/fluorescentTube/tubeMaterials.js +185 -0
  23. package/dist/components/index.d.ts +4 -0
  24. package/dist/components/index.d.ts.map +1 -1
  25. package/dist/components/index.js +4 -0
  26. package/dist/components/ledArray/LedArray.d.ts +14 -0
  27. package/dist/components/ledArray/LedArray.d.ts.map +1 -0
  28. package/dist/components/ledArray/LedArray.js +243 -0
  29. package/dist/components/ledArray/index.d.ts +7 -0
  30. package/dist/components/ledArray/index.d.ts.map +1 -0
  31. package/dist/components/ledArray/index.js +4 -0
  32. package/dist/components/ledArray/ledLayout.d.ts +22 -0
  33. package/dist/components/ledArray/ledLayout.d.ts.map +1 -0
  34. package/dist/components/ledArray/ledLayout.js +59 -0
  35. package/dist/components/ledArray/ledMaterials.d.ts +14 -0
  36. package/dist/components/ledArray/ledMaterials.d.ts.map +1 -0
  37. package/dist/components/ledArray/ledMaterials.js +151 -0
  38. package/dist/components/lightBulb/LightBulb.d.ts +16 -0
  39. package/dist/components/lightBulb/LightBulb.d.ts.map +1 -0
  40. package/dist/components/lightBulb/LightBulb.js +141 -0
  41. package/dist/components/lightBulb/bulbMaterials.d.ts +27 -0
  42. package/dist/components/lightBulb/bulbMaterials.d.ts.map +1 -0
  43. package/dist/components/lightBulb/bulbMaterials.js +133 -0
  44. package/dist/components/lightBulb/bulbShapes.d.ts +15 -0
  45. package/dist/components/lightBulb/bulbShapes.d.ts.map +1 -0
  46. package/dist/components/lightBulb/bulbShapes.js +180 -0
  47. package/dist/components/lightBulb/index.d.ts +5 -0
  48. package/dist/components/lightBulb/index.d.ts.map +1 -0
  49. package/dist/components/lightBulb/index.js +3 -0
  50. package/dist/components/lightBulb/kelvin.d.ts +7 -0
  51. package/dist/components/lightBulb/kelvin.d.ts.map +1 -0
  52. package/dist/components/lightBulb/kelvin.js +21 -0
  53. package/dist/components/lightBulb/types.d.ts +2 -0
  54. package/dist/components/lightBulb/types.d.ts.map +1 -0
  55. package/dist/components/lightBulb/types.js +1 -0
  56. package/dist/components/particles/BioluminescentWakeParticles.d.ts +3 -1
  57. package/dist/components/particles/BioluminescentWakeParticles.d.ts.map +1 -1
  58. package/dist/components/particles/BioluminescentWakeParticles.js +7 -3
  59. package/dist/components/particles/BrownianDustParticles.d.ts +3 -1
  60. package/dist/components/particles/BrownianDustParticles.d.ts.map +1 -1
  61. package/dist/components/particles/BrownianDustParticles.js +7 -3
  62. package/dist/components/particles/ChladniSandParticles.d.ts +3 -1
  63. package/dist/components/particles/ChladniSandParticles.d.ts.map +1 -1
  64. package/dist/components/particles/ChladniSandParticles.js +7 -3
  65. package/dist/components/particles/ElectronOrbitalsParticles.d.ts +3 -1
  66. package/dist/components/particles/ElectronOrbitalsParticles.d.ts.map +1 -1
  67. package/dist/components/particles/ElectronOrbitalsParticles.js +7 -3
  68. package/dist/components/particles/FaradayPowderParticles.d.ts +3 -1
  69. package/dist/components/particles/FaradayPowderParticles.d.ts.map +1 -1
  70. package/dist/components/particles/FaradayPowderParticles.js +7 -3
  71. package/dist/components/particles/GrinderSparksParticles.d.ts +3 -1
  72. package/dist/components/particles/GrinderSparksParticles.d.ts.map +1 -1
  73. package/dist/components/particles/GrinderSparksParticles.js +7 -3
  74. package/dist/components/particles/NeonRainParticles.d.ts +3 -1
  75. package/dist/components/particles/NeonRainParticles.d.ts.map +1 -1
  76. package/dist/components/particles/NeonRainParticles.js +7 -3
  77. package/dist/components/particles/TidalStreamParticles.d.ts +3 -1
  78. package/dist/components/particles/TidalStreamParticles.d.ts.map +1 -1
  79. package/dist/components/particles/TidalStreamParticles.js +7 -3
  80. package/dist/components/spotBeam/SpotBeam.d.ts +14 -0
  81. package/dist/components/spotBeam/SpotBeam.d.ts.map +1 -0
  82. package/dist/components/spotBeam/SpotBeam.js +244 -0
  83. package/dist/components/spotBeam/beamPatterns.d.ts +11 -0
  84. package/dist/components/spotBeam/beamPatterns.d.ts.map +1 -0
  85. package/dist/components/spotBeam/beamPatterns.js +106 -0
  86. package/dist/components/spotBeam/index.d.ts +7 -0
  87. package/dist/components/spotBeam/index.d.ts.map +1 -0
  88. package/dist/components/spotBeam/index.js +4 -0
  89. package/dist/components/spotBeam/spotBeamMaterials.d.ts +16 -0
  90. package/dist/components/spotBeam/spotBeamMaterials.d.ts.map +1 -0
  91. package/dist/components/spotBeam/spotBeamMaterials.js +307 -0
  92. package/dist/hooks/index.d.ts +4 -1
  93. package/dist/hooks/index.d.ts.map +1 -1
  94. package/dist/hooks/index.js +3 -1
  95. package/dist/hooks/useConfigLive.d.ts +2 -2
  96. package/dist/hooks/useConfigLive.d.ts.map +1 -1
  97. package/dist/hooks/useConfigLive.js +1 -1
  98. package/dist/hooks/useLightConfig.d.ts +25 -0
  99. package/dist/hooks/useLightConfig.d.ts.map +1 -0
  100. package/dist/hooks/useLightConfig.js +125 -0
  101. package/dist/hooks/useLightLive.d.ts +12 -0
  102. package/dist/hooks/useLightLive.d.ts.map +1 -0
  103. package/dist/hooks/useLightLive.js +53 -0
  104. package/dist/hooks/useShadowApplication.d.ts +8 -0
  105. package/dist/hooks/useShadowApplication.d.ts.map +1 -1
  106. package/dist/hooks/useShadowApplication.js +33 -9
  107. package/package.json +2 -2
@@ -0,0 +1,180 @@
1
+ // =============================================================================
2
+ // bulbShapes — glass profiles, filaments and supports for each LightBulbShape
3
+ // =============================================================================
4
+ //
5
+ // Units: the glass is ~1 unit tall; object scale comes from the CreatedObject
6
+ // wrapper. "Bulb space" has the neck at y = 0 and the glass growing up +Y; the
7
+ // screw base hangs below it. LightBulb shifts the whole bulb down by
8
+ // `filamentCenterY` so the light (and the object's origin) sits on the filament.
9
+ //
10
+ // Lathe profiles run bottom → top. Reversed, the normals face inward and the
11
+ // point light lights the inside of the far wall instead of the near one.
12
+ //
13
+ import { CatmullRomCurve3, Curve, LatheGeometry, TubeGeometry, Vector2, Vector3 } from 'three';
14
+ const LATHE_SEGMENTS = 64;
15
+ /** A tightly wound coil along an arbitrary path. */
16
+ class CoiledCurve extends Curve {
17
+ path;
18
+ turns;
19
+ radius;
20
+ tmpT = new Vector3();
21
+ tmpN = new Vector3();
22
+ tmpB = new Vector3();
23
+ constructor(path, turns, radius) {
24
+ super();
25
+ this.path = path;
26
+ this.turns = turns;
27
+ this.radius = radius;
28
+ }
29
+ getPoint(t, target = new Vector3()) {
30
+ const p = this.path.getPoint(t, target);
31
+ const tangent = this.path.getTangent(t, this.tmpT);
32
+ // Any vector not parallel to the tangent gives a stable frame for these gentle paths.
33
+ const ref = Math.abs(tangent.y) < 0.9 ? this.tmpN.set(0, 1, 0) : this.tmpN.set(1, 0, 0);
34
+ const b = this.tmpB.crossVectors(tangent, ref).normalize();
35
+ const n = ref.crossVectors(b, tangent).normalize();
36
+ const a = t * Math.PI * 2 * this.turns;
37
+ return p.addScaledVector(n, Math.cos(a) * this.radius).addScaledVector(b, Math.sin(a) * this.radius);
38
+ }
39
+ }
40
+ const coil = (points, turns, radius = 0.02, wire = 0.0045) => new TubeGeometry(new CoiledCurve(new CatmullRomCurve3(points), turns, radius), turns * 28, wire, 5, false);
41
+ const wire = (from, to, bend = 0) => {
42
+ const mid = from.clone().lerp(to, 0.5);
43
+ mid.x += bend;
44
+ return new TubeGeometry(new CatmullRomCurve3([from, mid, to]), 16, 0.0035, 5, false);
45
+ };
46
+ /** Glass stem rising from the neck: a short flared cone. */
47
+ const stemProfile = (top, r = 0.035) => new LatheGeometry([
48
+ new Vector2(0.09, -0.02), new Vector2(0.05, 0.03), new Vector2(r * 0.9, top * 0.6), new Vector2(r, top), new Vector2(0.001, top + 0.01),
49
+ ], 24);
50
+ /** Screw base below the neck. */
51
+ function baseGeometry(neckRadius) {
52
+ const pts = [new Vector2(0.001, -0.36), new Vector2(0.05, -0.355), new Vector2(neckRadius * 0.62, -0.33)];
53
+ const threads = 22;
54
+ for (let i = 0; i <= threads; i++) {
55
+ const y = -0.3 + (i / threads) * 0.3;
56
+ pts.push(new Vector2(neckRadius + Math.abs(Math.sin(i * Math.PI / 4)) * 0.018, y));
57
+ }
58
+ pts.push(new Vector2(neckRadius * 0.98, 0.012));
59
+ return new LatheGeometry(pts, LATHE_SEGMENTS);
60
+ }
61
+ const lathe = (pts) => {
62
+ const g = new LatheGeometry(pts, LATHE_SEGMENTS);
63
+ g.computeVertexNormals();
64
+ return g;
65
+ };
66
+ const smooth = (e0, e1, x) => {
67
+ const t = Math.min(Math.max((x - e0) / (e1 - e0), 0), 1);
68
+ return t * t * (3 - 2 * t);
69
+ };
70
+ // ---------------------------------------------------------------------------
71
+ function classic() {
72
+ // A19: narrow neck swelling into a pear, round crown.
73
+ const neck = 0.17, pts = [];
74
+ for (let i = 0; i <= 64; i++) {
75
+ const t = i / 64, y = t * 0.97;
76
+ let r;
77
+ if (t < 0.22)
78
+ r = neck + Math.pow(t / 0.22, 1.6) * 0.07;
79
+ else {
80
+ const u = (t - 0.22) / 0.78;
81
+ r = 0.24 + Math.sin(u * Math.PI * 0.62) * 0.16;
82
+ if (u > 0.62)
83
+ r *= Math.sqrt(Math.max(0, 1 - Math.pow((u - 0.62) / 0.38, 2)));
84
+ }
85
+ pts.push(new Vector2(Math.max(r, 0.0005), y));
86
+ }
87
+ const cy = 0.55, half = 0.1;
88
+ const ends = [new Vector3(-half, cy, 0), new Vector3(half, cy, 0)];
89
+ return {
90
+ glass: lathe(pts),
91
+ filament: coil([ends[0], new Vector3(0, cy - 0.03, 0), ends[1]], 14),
92
+ supports: [stemProfile(0.26), wire(new Vector3(-0.02, 0.26, 0), ends[0], -0.03), wire(new Vector3(0.02, 0.26, 0), ends[1], 0.03)],
93
+ base: baseGeometry(neck),
94
+ filamentCenterY: cy,
95
+ haloRadius: 1.1,
96
+ };
97
+ }
98
+ function globe() {
99
+ // G25: short neck, near-perfect sphere.
100
+ const neck = 0.17, R = 0.42, c = 0.52;
101
+ const join = c - Math.sqrt(R * R - neck * neck);
102
+ const pts = [new Vector2(neck, 0)];
103
+ for (let i = 0; i <= 64; i++) {
104
+ const y = join + (i / 64) * (c + R - join);
105
+ pts.push(new Vector2(Math.max(Math.sqrt(Math.max(R * R - (y - c) * (y - c), 0)), 0.0005), y));
106
+ }
107
+ const half = 0.1;
108
+ const ends = [new Vector3(-half, c, 0), new Vector3(half, c, 0)];
109
+ return {
110
+ glass: lathe(pts),
111
+ filament: coil([ends[0], new Vector3(0, c - 0.03, 0), ends[1]], 14),
112
+ supports: [stemProfile(0.3), wire(new Vector3(-0.02, 0.3, 0), ends[0], -0.03), wire(new Vector3(0.02, 0.3, 0), ends[1], 0.03)],
113
+ base: baseGeometry(neck),
114
+ filamentCenterY: c,
115
+ haloRadius: 1.25,
116
+ };
117
+ }
118
+ function edison() {
119
+ // ST64: tall teardrop with a squirrel-cage filament.
120
+ const neck = 0.17, top = 1.35, pts = [];
121
+ for (let i = 0; i <= 80; i++) {
122
+ const y = (i / 80) * top;
123
+ let r = neck + (0.33 - neck) * smooth(0.02, 0.8, y);
124
+ if (y > 0.86)
125
+ r *= Math.sqrt(Math.max(0, 1 - Math.pow((y - 0.86) / (top - 0.86), 2)));
126
+ pts.push(new Vector2(Math.max(r, 0.0005), y));
127
+ }
128
+ // Zig-zag between a lower and an upper ring: the vintage "cage".
129
+ const strands = 7, lowY = 0.42, highY = 1.02, lowR = 0.035, highR = 0.12;
130
+ const cage = [];
131
+ for (let i = 0; i < strands * 2; i++) {
132
+ const a = (i / (strands * 2)) * Math.PI * 2;
133
+ const up = i % 2 === 1;
134
+ const r = up ? highR : lowR;
135
+ cage.push(new Vector3(Math.cos(a) * r, up ? highY : lowY, Math.sin(a) * r));
136
+ }
137
+ const filament = new TubeGeometry(new CatmullRomCurve3(cage, true, 'catmullrom', 0.15), 420, 0.004, 5, true);
138
+ const supports = [stemProfile(lowY - 0.02, 0.03)];
139
+ // A centre rod up to the top ring, with spokes out to each upper vertex.
140
+ supports.push(wire(new Vector3(0, lowY, 0), new Vector3(0, highY + 0.04, 0)));
141
+ for (let i = 1; i < strands * 2; i += 2)
142
+ supports.push(wire(new Vector3(0, highY + 0.04, 0), cage[i]));
143
+ return {
144
+ glass: lathe(pts),
145
+ filament,
146
+ supports,
147
+ base: baseGeometry(neck),
148
+ filamentCenterY: (lowY + highY) / 2,
149
+ haloRadius: 1.3,
150
+ };
151
+ }
152
+ function tube() {
153
+ // T10: straight tube, rounded crown, long axial coil.
154
+ const R = 0.14, top = 1.4, pts = [];
155
+ for (let i = 0; i <= 64; i++) {
156
+ const y = (i / 64) * top;
157
+ const crown = top - R;
158
+ const r = y < crown ? R : Math.sqrt(Math.max(R * R - (y - crown) * (y - crown), 0));
159
+ pts.push(new Vector2(Math.max(r, 0.0005), y));
160
+ }
161
+ const lo = new Vector3(0, 0.3, 0), hi = new Vector3(0, 1.2, 0);
162
+ return {
163
+ glass: lathe(pts),
164
+ filament: coil([lo, new Vector3(0.005, 0.75, 0), hi], 60, 0.014, 0.0035),
165
+ supports: [stemProfile(0.24, 0.028), wire(new Vector3(0, 0.24, 0), lo), wire(new Vector3(0.03, 0.2, 0), new Vector3(0.09, 0.75, 0), 0.02), wire(new Vector3(0.09, 0.75, 0), hi, 0.02)],
166
+ base: baseGeometry(R),
167
+ filamentCenterY: 0.75,
168
+ haloRadius: 1.2,
169
+ };
170
+ }
171
+ const BUILDERS = { classic, globe, edison, tube };
172
+ export function buildBulbShape(shape) {
173
+ return (BUILDERS[shape ?? 'classic'] ?? classic)();
174
+ }
175
+ export function disposeBulbShape(g) {
176
+ g.glass.dispose();
177
+ g.filament.dispose();
178
+ g.base.dispose();
179
+ g.supports.forEach((s) => s.dispose());
180
+ }
@@ -0,0 +1,5 @@
1
+ export { default as LightBulb } from './LightBulb';
2
+ export type { LightBulbProps } from './LightBulb';
3
+ export type { LightBulbConfig, LightBulbShape, LightBulbGlass, LightBulbColorMode } from './types';
4
+ export { kelvinToColor } from './kelvin';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/lightBulb/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ // Visible light bulbs (createdObject type 'light', config.type 'lightBulb'), rendered by LightObject.
2
+ export { default as LightBulb } from './LightBulb.js';
3
+ export { kelvinToColor } from './kelvin.js';
@@ -0,0 +1,7 @@
1
+ import { Color } from 'three';
2
+ /**
3
+ * Colour temperature → colour (Tanner Helland's blackbody fit, sRGB).
4
+ * Writes into `target` and returns it.
5
+ */
6
+ export declare function kelvinToColor(kelvin: number, target?: Color): Color;
7
+ //# sourceMappingURL=kelvin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kelvin.d.ts","sourceRoot":"","sources":["../../../src/components/lightBulb/kelvin.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,OAAO,CAAC;AAE9C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,KAAmB,GAAG,KAAK,CAehF"}
@@ -0,0 +1,21 @@
1
+ import { Color, SRGBColorSpace } from 'three';
2
+ /**
3
+ * Colour temperature → colour (Tanner Helland's blackbody fit, sRGB).
4
+ * Writes into `target` and returns it.
5
+ */
6
+ export function kelvinToColor(kelvin, target = new Color()) {
7
+ const t = Math.min(Math.max(kelvin, 1000), 40000) / 100;
8
+ let r, g, b;
9
+ if (t <= 66) {
10
+ r = 255;
11
+ g = 99.4708025861 * Math.log(t) - 161.1195681661;
12
+ b = t <= 19 ? 0 : 138.5177312231 * Math.log(t - 10) - 305.0447927307;
13
+ }
14
+ else {
15
+ r = 329.698727446 * Math.pow(t - 60, -0.1332047592);
16
+ g = 288.1221695283 * Math.pow(t - 60, -0.0755148492);
17
+ b = 255;
18
+ }
19
+ const c = (v) => Math.min(Math.max(v, 0), 255) / 255;
20
+ return target.setRGB(c(r), c(g), c(b), SRGBColorSpace);
21
+ }
@@ -0,0 +1,2 @@
1
+ export type { LightBulbConfig, LightBulbShape, LightBulbGlass, LightBulbColorMode } from '@3driseai/3drise-core';
2
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/lightBulb/types.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, BioluminescentWakeParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, BioluminescentWakeParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface BioluminescentWakeParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"BioluminescentWakeParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/BioluminescentWakeParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAMjG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,gCAAiC,SAAQ,gBAAgB;IACtE,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iCAAiC,CAAC;IAC1C,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA09BD,QAAA,MAAM,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAAC,gCAAgC,CAiD3E,CAAC;AAEF,eAAe,2BAA2B,CAAC"}
1
+ {"version":3,"file":"BioluminescentWakeParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/BioluminescentWakeParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,iCAAiC,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMlH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,gCAAiC,SAAQ,gBAAgB;IACtE,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,iCAAiC,CAAC;IAC1C,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA09BD,QAAA,MAAM,2BAA2B,EAAE,KAAK,CAAC,EAAE,CAAC,gCAAgC,CAqD3E,CAAC;AAEF,eAAe,2BAA2B,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -1103,7 +1103,7 @@ const DEFAULTS = {
1103
1103
  const STRUCTURAL = ['particleCount', 'seed', 'quality'];
1104
1104
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
1105
1105
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.bioluminescentWake.map((p) => p.value));
1106
- const BioluminescentWakeParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
1106
+ const BioluminescentWakeParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
1107
1107
  const rootRef = useRef(null);
1108
1108
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
1109
1109
  const s = size > 0 ? size : 1;
@@ -1135,8 +1135,12 @@ const BioluminescentWakeParticles = ({ id, size, config, animations, onObjectRea
1135
1135
  const pointer = usePointerField();
1136
1136
  useFrame((state, delta) => {
1137
1137
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
1138
- if (keyframes?.length) {
1138
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
1139
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
1140
+ if (keyframes?.length || pointerBound) {
1139
1141
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
1142
+ if (pointerBound)
1143
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
1140
1144
  push(live.current);
1141
1145
  }
1142
1146
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, BrownianDustParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, BrownianDustParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface BrownianDustParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"BrownianDustParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/BrownianDustParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,MAAM,uBAAuB,CAAC;AAM3F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAChE,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,2BAA2B,CAAC;IACpC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA4qBD,QAAA,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAiD/D,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
1
+ {"version":3,"file":"BrownianDustParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/BrownianDustParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM5G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAChE,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,2BAA2B,CAAC;IACpC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA4qBD,QAAA,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAqD/D,CAAC;AAEF,eAAe,qBAAqB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -737,7 +737,7 @@ const DEFAULTS = {
737
737
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.brownianDust.map((p) => p.value));
738
738
  /** Knobs that rebuild the simulation: they change on commit, never through the live path. */
739
739
  const STRUCTURAL = ['particleCount'];
740
- const BrownianDustParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
740
+ const BrownianDustParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
741
741
  const rootRef = useRef(null);
742
742
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
743
743
  const s = size > 0 ? size : 1;
@@ -769,8 +769,12 @@ const BrownianDustParticles = ({ id, size, config, animations, onObjectReady, on
769
769
  const pointer = usePointerField();
770
770
  useFrame((state, delta) => {
771
771
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
772
- if (keyframes?.length) {
772
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
773
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
774
+ if (keyframes?.length || pointerBound) {
773
775
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
776
+ if (pointerBound)
777
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
774
778
  push(live.current);
775
779
  }
776
780
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, ChladniSandParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, ChladniSandParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface ChladniSandParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"ChladniSandParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/ChladniSandParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAM1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IAC/D,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAsvBD,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAiD7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"ChladniSandParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/ChladniSandParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IAC/D,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAsvBD,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAqD7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -870,7 +870,7 @@ const DEFAULTS = {
870
870
  const STRUCTURAL = ['particleCount', 'seed', 'quality'];
871
871
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
872
872
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.chladniSand.map((p) => p.value));
873
- const ChladniSandParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
873
+ const ChladniSandParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
874
874
  const rootRef = useRef(null);
875
875
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
876
876
  const s = size > 0 ? size : 1;
@@ -902,8 +902,12 @@ const ChladniSandParticles = ({ id, size, config, animations, onObjectReady, onO
902
902
  const pointer = usePointerField();
903
903
  useFrame((state, delta) => {
904
904
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
905
- if (keyframes?.length) {
905
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
906
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
907
+ if (keyframes?.length || pointerBound) {
906
908
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
909
+ if (pointerBound)
910
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
907
911
  push(live.current);
908
912
  }
909
913
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, ElectronOrbitalsParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, ElectronOrbitalsParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface ElectronOrbitalsParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"ElectronOrbitalsParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/ElectronOrbitalsParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC;AAM/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,8BAA+B,SAAQ,gBAAgB;IACpE,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,+BAA+B,CAAC;IACxC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA0xBD,QAAA,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAiDvE,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
1
+ {"version":3,"file":"ElectronOrbitalsParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/ElectronOrbitalsParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,+BAA+B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMhH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,8BAA+B,SAAQ,gBAAgB;IACpE,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,+BAA+B,CAAC;IACxC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA0xBD,QAAA,MAAM,yBAAyB,EAAE,KAAK,CAAC,EAAE,CAAC,8BAA8B,CAqDvE,CAAC;AAEF,eAAe,yBAAyB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -924,7 +924,7 @@ const DEFAULTS = {
924
924
  const STRUCTURAL = ['particleCount', 'stateA', 'stateB', 'seed', 'quality'];
925
925
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
926
926
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.electronOrbitals.map((p) => p.value));
927
- const ElectronOrbitalsParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
927
+ const ElectronOrbitalsParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
928
928
  const rootRef = useRef(null);
929
929
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
930
930
  const s = size > 0 ? size : 1;
@@ -956,8 +956,12 @@ const ElectronOrbitalsParticles = ({ id, size, config, animations, onObjectReady
956
956
  const pointer = usePointerField();
957
957
  useFrame((state, delta) => {
958
958
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
959
- if (keyframes?.length) {
959
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
960
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
961
+ if (keyframes?.length || pointerBound) {
960
962
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
963
+ if (pointerBound)
964
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
961
965
  push(live.current);
962
966
  }
963
967
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, FaradayPowderParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, FaradayPowderParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface FaradayPowderParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"FaradayPowderParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/FaradayPowderParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAM5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,2BAA4B,SAAQ,gBAAgB;IACjE,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAypBD,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAiDjE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"FaradayPowderParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/FaradayPowderParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,2BAA4B,SAAQ,gBAAgB;IACjE,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAypBD,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAqDjE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -741,7 +741,7 @@ const DEFAULTS = {
741
741
  const STRUCTURAL = ['particleCount', 'seed', 'quality'];
742
742
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
743
743
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.faradayPowder.map((p) => p.value));
744
- const FaradayPowderParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
744
+ const FaradayPowderParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
745
745
  const rootRef = useRef(null);
746
746
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
747
747
  const s = size > 0 ? size : 1;
@@ -773,8 +773,12 @@ const FaradayPowderParticles = ({ id, size, config, animations, onObjectReady, o
773
773
  const pointer = usePointerField();
774
774
  useFrame((state, delta) => {
775
775
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
776
- if (keyframes?.length) {
776
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
777
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
778
+ if (keyframes?.length || pointerBound) {
777
779
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
780
+ if (pointerBound)
781
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
778
782
  push(live.current);
779
783
  }
780
784
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, GrinderSparksParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, GrinderSparksParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface GrinderSparksParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"GrinderSparksParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/GrinderSparksParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAM5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,2BAA4B,SAAQ,gBAAgB;IACjE,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA8pBD,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAiDjE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"GrinderSparksParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/GrinderSparksParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,4BAA4B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM7G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,2BAA4B,SAAQ,gBAAgB;IACjE,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,4BAA4B,CAAC;IACrC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AA8pBD,QAAA,MAAM,sBAAsB,EAAE,KAAK,CAAC,EAAE,CAAC,2BAA2B,CAqDjE,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -726,7 +726,7 @@ const DEFAULTS = {
726
726
  const STRUCTURAL = ['particleCount', 'seed', 'quality'];
727
727
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
728
728
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.grinderSparks.map((p) => p.value));
729
- const GrinderSparksParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
729
+ const GrinderSparksParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
730
730
  const rootRef = useRef(null);
731
731
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
732
732
  const s = size > 0 ? size : 1;
@@ -758,8 +758,12 @@ const GrinderSparksParticles = ({ id, size, config, animations, onObjectReady, o
758
758
  const pointer = usePointerField();
759
759
  useFrame((state, delta) => {
760
760
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
761
- if (keyframes?.length) {
761
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
762
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
763
+ if (keyframes?.length || pointerBound) {
762
764
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
765
+ if (pointerBound)
766
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
763
767
  push(live.current);
764
768
  }
765
769
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, NeonRainParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, NeonRainParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface NeonRainParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"NeonRainParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/NeonRainParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAMvF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC5D,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,uBAAuB,CAAC;IAChC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAinBD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAiDvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
1
+ {"version":3,"file":"NeonRainParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/NeonRainParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAMxG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC5D,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,uBAAuB,CAAC;IAChC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAinBD,QAAA,MAAM,iBAAiB,EAAE,KAAK,CAAC,EAAE,CAAC,sBAAsB,CAqDvD,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
@@ -3,7 +3,7 @@ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef } from 'react'
3
3
  import * as THREE from 'three';
4
4
  import { useFrame } from '@react-three/fiber';
5
5
  import { GENERATIVE_PARTICLES_ANIMATABLE } from '@3driseai/3drise-core';
6
- import { applyConfigKeyframeAnimations } from '../../utils/configAnimations.js';
6
+ import { applyConfigKeyframeAnimations, applyConfigMouseMove } from '../../utils/configAnimations.js';
7
7
  import { createPointerUniforms, stepPointerField, usePointerField } from '../../utils/pointerField.js';
8
8
  import { createTrailUniforms, applyTrailConfig, createCpuTrail } from '../../utils/particleTrails.js';
9
9
  import { useObjectReady } from '../../hooks/useObjectReady.js';
@@ -674,7 +674,7 @@ const DEFAULTS = {
674
674
  const STRUCTURAL = ['particleCount', 'seed', 'quality'];
675
675
  /** Knobs an animation (or mouse move) may drive per frame — generated from applyConfig. */
676
676
  const ANIMATABLE = new Set(GENERATIVE_PARTICLES_ANIMATABLE.neonRain.map((p) => p.value));
677
- const NeonRainParticles = ({ id, size, config, animations, onObjectReady, onObjectDispose }) => {
677
+ const NeonRainParticles = ({ id, size, config, animations, mouseMove, onObjectReady, onObjectDispose }) => {
678
678
  const rootRef = useRef(null);
679
679
  useObjectReady(rootRef, config, onObjectReady, onObjectDispose);
680
680
  const s = size > 0 ? size : 1;
@@ -706,8 +706,12 @@ const NeonRainParticles = ({ id, size, config, animations, onObjectReady, onObje
706
706
  const pointer = usePointerField();
707
707
  useFrame((state, delta) => {
708
708
  instance.update(Math.min(delta, 0.1), state.camera, pointer);
709
- if (keyframes?.length) {
709
+ // Keyframes first, pointer on top: a knob bound to both follows the cursor.
710
+ const pointerBound = !!mouseMove?.enabled && !!mouseMove.properties?.length;
711
+ if (keyframes?.length || pointerBound) {
710
712
  applyConfigKeyframeAnimations(keyframes, animFrom.current, cfg, animOverride.current, performance.now() - animStart.current, ANIMATABLE);
713
+ if (pointerBound)
714
+ applyConfigMouseMove(mouseMove.properties, cfg, animOverride.current, state.pointer, ANIMATABLE);
711
715
  push(live.current);
712
716
  }
713
717
  });
@@ -1,7 +1,9 @@
1
1
  import React from 'react';
2
- import type { ObjectAnimations, TidalStreamParticlesConfig } from '@3driseai/3drise-core';
2
+ import type { ObjectAnimations, TidalStreamParticlesConfig, MouseMoveDomain } from '@3driseai/3drise-core';
3
3
  import type { ObjectReadyProps } from '../../types/objectReady';
4
4
  export interface TidalStreamParticlesProps extends ObjectReadyProps {
5
+ /** Pointer bindings for this object's config knobs (mouseMove.particles). */
6
+ mouseMove?: MouseMoveDomain;
5
7
  /** Scene object id: the controller finds the live-edit handle by it. */
6
8
  id?: string;
7
9
  /** World size of the object (units); the object's transform scales it further. */
@@ -1 +1 @@
1
- {"version":3,"file":"TidalStreamParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/TidalStreamParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AAM1F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IAC/D,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAmtBD,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAiD7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"TidalStreamParticles.d.ts","sourceRoot":"","sources":["../../../src/components/particles/TidalStreamParticles.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmE,MAAM,OAAO,CAAC;AAIxF,OAAO,KAAK,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAM3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,yBAA0B,SAAQ,gBAAgB;IAC/D,6EAA6E;IAC7E,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,wEAAwE;IACxE,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,kFAAkF;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,0BAA0B,CAAC;IACnC,sFAAsF;IACtF,UAAU,CAAC,EAAE,gBAAgB,CAAC;CACjC;AAmtBD,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CAqD7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}