@vib3code/sdk 2.0.1

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 (258) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +34 -0
  3. package/DOCS/CI_TESTING.md +38 -0
  4. package/DOCS/CLI_ONBOARDING.md +75 -0
  5. package/DOCS/CONTROL_REFERENCE.md +64 -0
  6. package/DOCS/DEV_TRACK_ANALYSIS.md +77 -0
  7. package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +42 -0
  8. package/DOCS/DEV_TRACK_SESSION_2026-01-31.md +220 -0
  9. package/DOCS/ENV_SETUP.md +189 -0
  10. package/DOCS/EXPORT_FORMATS.md +417 -0
  11. package/DOCS/GPU_DISPOSAL_GUIDE.md +21 -0
  12. package/DOCS/LICENSING_TIERS.md +275 -0
  13. package/DOCS/MASTER_PLAN_2026-01-31.md +570 -0
  14. package/DOCS/OBS_SETUP_GUIDE.md +98 -0
  15. package/DOCS/PROJECT_SETUP.md +66 -0
  16. package/DOCS/RENDERER_LIFECYCLE.md +40 -0
  17. package/DOCS/REPO_MANIFEST.md +121 -0
  18. package/DOCS/SESSION_014_PLAN.md +195 -0
  19. package/DOCS/SESSION_LOG_2026-01-07.md +56 -0
  20. package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +72 -0
  21. package/DOCS/SYSTEM_AUDIT_2026-01-30.md +738 -0
  22. package/DOCS/SYSTEM_INVENTORY.md +520 -0
  23. package/DOCS/TELEMETRY_EXPORTS.md +34 -0
  24. package/DOCS/WEBGPU_STATUS.md +38 -0
  25. package/DOCS/XR_BENCHMARKS.md +608 -0
  26. package/LICENSE +21 -0
  27. package/README.md +426 -0
  28. package/docs/.nojekyll +0 -0
  29. package/docs/01-dissolution_of_euclidean_hegemony.html +346 -0
  30. package/docs/02-hyperspatial_ego_death.html +346 -0
  31. package/docs/03-post_cartesian_sublime.html +346 -0
  32. package/docs/04-crystalline_void_meditation.html +346 -0
  33. package/docs/05-quantum_decoherence_ballet.html +346 -0
  34. package/docs/06-dissolution_of_euclidean_hegemony.html +346 -0
  35. package/docs/07-hyperspatial_ego_death.html +346 -0
  36. package/docs/08-post_cartesian_sublime.html +346 -0
  37. package/docs/09-crystalline_void_meditation.html +346 -0
  38. package/docs/10-quantum_decoherence_ballet.html +346 -0
  39. package/docs/11-dissolution_of_euclidean_hegemony.html +346 -0
  40. package/docs/12-hyperspatial_ego_death.html +346 -0
  41. package/docs/13-post_cartesian_sublime.html +346 -0
  42. package/docs/index.html +794 -0
  43. package/docs/test-hub.html +441 -0
  44. package/docs/url-state.js +102 -0
  45. package/docs/vib3-exports/01-quantum-quantum-tetrahedron-lattice.html +489 -0
  46. package/docs/vib3-exports/02-quantum-quantum-hypersphere-matrix.html +489 -0
  47. package/docs/vib3-exports/03-quantum-quantum-hypertetra-fractal.html +489 -0
  48. package/docs/vib3-exports/04-faceted-faceted-crystal-structure.html +407 -0
  49. package/docs/vib3-exports/05-faceted-faceted-klein-bottle.html +407 -0
  50. package/docs/vib3-exports/06-faceted-faceted-hypertetra-torus.html +407 -0
  51. package/docs/vib3-exports/07-holographic-holographic-wave-field.html +457 -0
  52. package/docs/vib3-exports/08-holographic-holographic-hypersphere-sphere.html +457 -0
  53. package/docs/vib3-exports/09-holographic-holographic-hypertetra-crystal.html +457 -0
  54. package/docs/vib3-exports/index.html +238 -0
  55. package/docs/webgpu-live.html +702 -0
  56. package/package.json +367 -0
  57. package/src/advanced/AIPresetGenerator.js +777 -0
  58. package/src/advanced/MIDIController.js +703 -0
  59. package/src/advanced/OffscreenWorker.js +1051 -0
  60. package/src/advanced/WebGPUCompute.js +1051 -0
  61. package/src/advanced/WebXRRenderer.js +680 -0
  62. package/src/agent/cli/AgentCLI.js +615 -0
  63. package/src/agent/cli/index.js +14 -0
  64. package/src/agent/index.js +73 -0
  65. package/src/agent/mcp/MCPServer.js +950 -0
  66. package/src/agent/mcp/index.js +9 -0
  67. package/src/agent/mcp/tools.js +548 -0
  68. package/src/agent/telemetry/EventStream.js +669 -0
  69. package/src/agent/telemetry/Instrumentation.js +618 -0
  70. package/src/agent/telemetry/TelemetryExporters.js +427 -0
  71. package/src/agent/telemetry/TelemetryService.js +464 -0
  72. package/src/agent/telemetry/index.js +52 -0
  73. package/src/benchmarks/BenchmarkRunner.js +381 -0
  74. package/src/benchmarks/MetricsCollector.js +299 -0
  75. package/src/benchmarks/index.js +9 -0
  76. package/src/benchmarks/scenes.js +259 -0
  77. package/src/cli/index.js +675 -0
  78. package/src/config/ApiConfig.js +88 -0
  79. package/src/core/CanvasManager.js +217 -0
  80. package/src/core/ErrorReporter.js +117 -0
  81. package/src/core/ParameterMapper.js +333 -0
  82. package/src/core/Parameters.js +396 -0
  83. package/src/core/RendererContracts.js +200 -0
  84. package/src/core/UnifiedResourceManager.js +370 -0
  85. package/src/core/VIB3Engine.js +636 -0
  86. package/src/core/renderers/FacetedRendererAdapter.js +32 -0
  87. package/src/core/renderers/HolographicRendererAdapter.js +29 -0
  88. package/src/core/renderers/QuantumRendererAdapter.js +29 -0
  89. package/src/core/renderers/RendererLifecycleManager.js +63 -0
  90. package/src/creative/ColorPresetsSystem.js +980 -0
  91. package/src/creative/ParameterTimeline.js +1061 -0
  92. package/src/creative/PostProcessingPipeline.js +1113 -0
  93. package/src/creative/TransitionAnimator.js +683 -0
  94. package/src/export/CSSExporter.js +226 -0
  95. package/src/export/CardGeneratorBase.js +279 -0
  96. package/src/export/ExportManager.js +580 -0
  97. package/src/export/FacetedCardGenerator.js +279 -0
  98. package/src/export/HolographicCardGenerator.js +543 -0
  99. package/src/export/LottieExporter.js +552 -0
  100. package/src/export/QuantumCardGenerator.js +315 -0
  101. package/src/export/SVGExporter.js +519 -0
  102. package/src/export/ShaderExporter.js +903 -0
  103. package/src/export/TradingCardGenerator.js +3055 -0
  104. package/src/export/TradingCardManager.js +181 -0
  105. package/src/export/VIB3PackageExporter.js +559 -0
  106. package/src/export/index.js +14 -0
  107. package/src/export/systems/TradingCardSystemFaceted.js +494 -0
  108. package/src/export/systems/TradingCardSystemHolographic.js +452 -0
  109. package/src/export/systems/TradingCardSystemQuantum.js +411 -0
  110. package/src/faceted/FacetedSystem.js +963 -0
  111. package/src/features/CollectionManager.js +433 -0
  112. package/src/gallery/CollectionManager.js +240 -0
  113. package/src/gallery/GallerySystem.js +485 -0
  114. package/src/geometry/GeometryFactory.js +314 -0
  115. package/src/geometry/GeometryLibrary.js +72 -0
  116. package/src/geometry/buffers/BufferBuilder.js +338 -0
  117. package/src/geometry/buffers/index.js +18 -0
  118. package/src/geometry/generators/Crystal.js +420 -0
  119. package/src/geometry/generators/Fractal.js +298 -0
  120. package/src/geometry/generators/KleinBottle.js +197 -0
  121. package/src/geometry/generators/Sphere.js +192 -0
  122. package/src/geometry/generators/Tesseract.js +160 -0
  123. package/src/geometry/generators/Tetrahedron.js +225 -0
  124. package/src/geometry/generators/Torus.js +304 -0
  125. package/src/geometry/generators/Wave.js +341 -0
  126. package/src/geometry/index.js +142 -0
  127. package/src/geometry/warp/HypersphereCore.js +211 -0
  128. package/src/geometry/warp/HypertetraCore.js +386 -0
  129. package/src/geometry/warp/index.js +57 -0
  130. package/src/holograms/HolographicVisualizer.js +1073 -0
  131. package/src/holograms/RealHolographicSystem.js +966 -0
  132. package/src/holograms/variantRegistry.js +69 -0
  133. package/src/integrations/FigmaPlugin.js +854 -0
  134. package/src/integrations/OBSMode.js +754 -0
  135. package/src/integrations/ThreeJsPackage.js +660 -0
  136. package/src/integrations/TouchDesignerExport.js +552 -0
  137. package/src/integrations/frameworks/Vib3React.js +591 -0
  138. package/src/integrations/frameworks/Vib3Svelte.js +654 -0
  139. package/src/integrations/frameworks/Vib3Vue.js +628 -0
  140. package/src/llm/LLMParameterInterface.js +240 -0
  141. package/src/llm/LLMParameterUI.js +577 -0
  142. package/src/math/Mat4x4.js +708 -0
  143. package/src/math/Projection.js +341 -0
  144. package/src/math/Rotor4D.js +637 -0
  145. package/src/math/Vec4.js +476 -0
  146. package/src/math/constants.js +164 -0
  147. package/src/math/index.js +68 -0
  148. package/src/math/projections.js +54 -0
  149. package/src/math/rotations.js +196 -0
  150. package/src/quantum/QuantumEngine.js +906 -0
  151. package/src/quantum/QuantumVisualizer.js +1103 -0
  152. package/src/reactivity/ReactivityConfig.js +499 -0
  153. package/src/reactivity/ReactivityManager.js +586 -0
  154. package/src/reactivity/SpatialInputSystem.js +1783 -0
  155. package/src/reactivity/index.js +93 -0
  156. package/src/render/CommandBuffer.js +465 -0
  157. package/src/render/MultiCanvasBridge.js +340 -0
  158. package/src/render/RenderCommand.js +514 -0
  159. package/src/render/RenderResourceRegistry.js +523 -0
  160. package/src/render/RenderState.js +552 -0
  161. package/src/render/RenderTarget.js +512 -0
  162. package/src/render/ShaderLoader.js +253 -0
  163. package/src/render/ShaderProgram.js +599 -0
  164. package/src/render/UnifiedRenderBridge.js +496 -0
  165. package/src/render/backends/WebGLBackend.js +1108 -0
  166. package/src/render/backends/WebGPUBackend.js +1409 -0
  167. package/src/render/commands/CommandBufferExecutor.js +607 -0
  168. package/src/render/commands/RenderCommandBuffer.js +661 -0
  169. package/src/render/commands/index.js +17 -0
  170. package/src/render/index.js +367 -0
  171. package/src/scene/Disposable.js +498 -0
  172. package/src/scene/MemoryPool.js +618 -0
  173. package/src/scene/Node4D.js +697 -0
  174. package/src/scene/ResourceManager.js +599 -0
  175. package/src/scene/Scene4D.js +540 -0
  176. package/src/scene/index.js +98 -0
  177. package/src/schemas/error.schema.json +84 -0
  178. package/src/schemas/extension.schema.json +88 -0
  179. package/src/schemas/index.js +214 -0
  180. package/src/schemas/parameters.schema.json +142 -0
  181. package/src/schemas/tool-pack.schema.json +44 -0
  182. package/src/schemas/tool-response.schema.json +127 -0
  183. package/src/shaders/common/fullscreen.vert.glsl +5 -0
  184. package/src/shaders/common/fullscreen.vert.wgsl +17 -0
  185. package/src/shaders/common/geometry24.glsl +65 -0
  186. package/src/shaders/common/geometry24.wgsl +54 -0
  187. package/src/shaders/common/rotation4d.glsl +85 -0
  188. package/src/shaders/common/rotation4d.wgsl +86 -0
  189. package/src/shaders/common/uniforms.glsl +44 -0
  190. package/src/shaders/common/uniforms.wgsl +48 -0
  191. package/src/shaders/faceted/faceted.frag.glsl +129 -0
  192. package/src/shaders/faceted/faceted.frag.wgsl +164 -0
  193. package/src/shaders/holographic/holographic.frag.glsl +406 -0
  194. package/src/shaders/holographic/holographic.frag.wgsl +185 -0
  195. package/src/shaders/quantum/quantum.frag.glsl +513 -0
  196. package/src/shaders/quantum/quantum.frag.wgsl +361 -0
  197. package/src/testing/ParallelTestFramework.js +519 -0
  198. package/src/testing/__snapshots__/exportFormats.test.js.snap +24 -0
  199. package/src/testing/exportFormats.test.js +8 -0
  200. package/src/testing/projections.test.js +14 -0
  201. package/src/testing/rotations.test.js +37 -0
  202. package/src/ui/InteractivityMenu.js +516 -0
  203. package/src/ui/StatusManager.js +96 -0
  204. package/src/ui/adaptive/renderers/webgpu/BufferLayout.ts +252 -0
  205. package/src/ui/adaptive/renderers/webgpu/PolytopeInstanceBuffer.ts +144 -0
  206. package/src/ui/adaptive/renderers/webgpu/TripleBufferedUniform.ts +170 -0
  207. package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +735 -0
  208. package/src/ui/adaptive/renderers/webgpu/index.ts +112 -0
  209. package/src/variations/VariationManager.js +431 -0
  210. package/src/viewer/AudioReactivity.js +505 -0
  211. package/src/viewer/CardBending.js +481 -0
  212. package/src/viewer/GalleryUI.js +832 -0
  213. package/src/viewer/ReactivityManager.js +590 -0
  214. package/src/viewer/TradingCardExporter.js +600 -0
  215. package/src/viewer/ViewerPortal.js +374 -0
  216. package/src/viewer/index.js +12 -0
  217. package/src/wasm/WasmLoader.js +296 -0
  218. package/src/wasm/index.js +132 -0
  219. package/tools/agentic/mcpTools.js +88 -0
  220. package/tools/cli/agent-cli.js +92 -0
  221. package/tools/export/formats.js +24 -0
  222. package/tools/math/rotation-baseline.mjs +64 -0
  223. package/tools/shader-sync-verify.js +937 -0
  224. package/tools/telemetry/manifestPipeline.js +141 -0
  225. package/tools/telemetry/telemetryEvents.js +35 -0
  226. package/types/adaptive-sdk.d.ts +185 -0
  227. package/types/advanced/AIPresetGenerator.d.ts +81 -0
  228. package/types/advanced/MIDIController.d.ts +100 -0
  229. package/types/advanced/OffscreenWorker.d.ts +82 -0
  230. package/types/advanced/WebGPUCompute.d.ts +52 -0
  231. package/types/advanced/WebXRRenderer.d.ts +77 -0
  232. package/types/advanced/index.d.ts +46 -0
  233. package/types/core/ErrorReporter.d.ts +50 -0
  234. package/types/core/VIB3Engine.d.ts +204 -0
  235. package/types/creative/ColorPresetsSystem.d.ts +91 -0
  236. package/types/creative/ParameterTimeline.d.ts +74 -0
  237. package/types/creative/PostProcessingPipeline.d.ts +109 -0
  238. package/types/creative/TransitionAnimator.d.ts +71 -0
  239. package/types/creative/index.d.ts +35 -0
  240. package/types/integrations/FigmaPlugin.d.ts +46 -0
  241. package/types/integrations/OBSMode.d.ts +74 -0
  242. package/types/integrations/ThreeJsPackage.d.ts +62 -0
  243. package/types/integrations/TouchDesignerExport.d.ts +36 -0
  244. package/types/integrations/Vib3React.d.ts +74 -0
  245. package/types/integrations/Vib3Svelte.d.ts +63 -0
  246. package/types/integrations/Vib3Vue.d.ts +55 -0
  247. package/types/integrations/index.d.ts +52 -0
  248. package/types/reactivity/SpatialInputSystem.d.ts +173 -0
  249. package/types/reactivity/index.d.ts +394 -0
  250. package/types/render/CommandBuffer.d.ts +169 -0
  251. package/types/render/RenderCommand.d.ts +312 -0
  252. package/types/render/RenderState.d.ts +279 -0
  253. package/types/render/RenderTarget.d.ts +254 -0
  254. package/types/render/ShaderProgram.d.ts +277 -0
  255. package/types/render/UnifiedRenderBridge.d.ts +143 -0
  256. package/types/render/WebGLBackend.d.ts +168 -0
  257. package/types/render/WebGPUBackend.d.ts +186 -0
  258. package/types/render/index.d.ts +141 -0
@@ -0,0 +1,586 @@
1
+ /**
2
+ * VIB3+ ReactivityManager
3
+ *
4
+ * Coordinates all reactivity inputs (audio, tilt, interaction)
5
+ * and applies them to the visualization parameters.
6
+ *
7
+ * This is the central hub that:
8
+ * 1. Receives input from AudioReactivityEngine, TiltReactivityEngine, InteractionEngine
9
+ * 2. Applies configured mappings from ReactivityConfig
10
+ * 3. Updates visualization parameters through the parameter system
11
+ */
12
+
13
+ import { ReactivityConfig, TARGETABLE_PARAMETERS, BLEND_MODES } from './ReactivityConfig.js';
14
+
15
+ /**
16
+ * ReactivityManager - Coordinates all reactivity systems
17
+ */
18
+ export class ReactivityManager {
19
+ constructor(parameterUpdateFn = null) {
20
+ // Function to call when parameters need updating
21
+ this.updateParameter = parameterUpdateFn || window.updateParameter || this.defaultUpdateParameter.bind(this);
22
+
23
+ // ReactivityConfig instance
24
+ this.config = new ReactivityConfig();
25
+
26
+ // Current input values from various sources
27
+ this.inputState = {
28
+ audio: { bass: 0, mid: 0, high: 0, energy: 0 },
29
+ tilt: { alpha: 0, beta: 0, gamma: 0 },
30
+ mouse: { x: 0.5, y: 0.5, velocityX: 0, velocityY: 0 },
31
+ click: { intensity: 0, lastTime: 0 },
32
+ scroll: { delta: 0, accumulated: 0 },
33
+ touch: { touches: [], pinchScale: 1, rotation: 0 }
34
+ };
35
+
36
+ // Base parameter values (before reactivity applied)
37
+ this.baseParameters = {};
38
+
39
+ // Computed reactivity deltas
40
+ this.reactivityDeltas = {};
41
+
42
+ // Active state
43
+ this.isActive = false;
44
+ this.frameId = null;
45
+
46
+ // Event emitter for telemetry
47
+ this.listeners = new Map();
48
+
49
+ console.log('🎛️ ReactivityManager: Initialized');
50
+ }
51
+
52
+ /**
53
+ * Default parameter update function (fallback)
54
+ */
55
+ defaultUpdateParameter(name, value) {
56
+ console.log(`ReactivityManager: updateParameter(${name}, ${value})`);
57
+ // Store locally if no external handler
58
+ this.baseParameters[name] = value;
59
+ }
60
+
61
+ /**
62
+ * Set the parameter update function
63
+ */
64
+ setParameterUpdateFunction(fn) {
65
+ this.updateParameter = fn;
66
+ }
67
+
68
+ /**
69
+ * Load a ReactivityConfig
70
+ */
71
+ loadConfig(config) {
72
+ if (config instanceof ReactivityConfig) {
73
+ this.config = config;
74
+ } else {
75
+ this.config = new ReactivityConfig(config);
76
+ }
77
+
78
+ const validation = this.config.validate();
79
+ if (!validation.valid) {
80
+ console.warn('ReactivityManager: Config validation errors:', validation.errors);
81
+ }
82
+
83
+ this.emit('configChanged', this.config.getConfig());
84
+ console.log('🎛️ ReactivityManager: Config loaded');
85
+ return validation;
86
+ }
87
+
88
+ /**
89
+ * Get current config
90
+ */
91
+ getConfig() {
92
+ return this.config.getConfig();
93
+ }
94
+
95
+ /**
96
+ * Start the reactivity processing loop
97
+ */
98
+ start() {
99
+ if (this.isActive) return;
100
+
101
+ this.isActive = true;
102
+ this.processFrame();
103
+ console.log('🎛️ ReactivityManager: Started');
104
+ this.emit('started');
105
+ }
106
+
107
+ /**
108
+ * Stop the reactivity processing loop
109
+ */
110
+ stop() {
111
+ this.isActive = false;
112
+ if (this.frameId) {
113
+ cancelAnimationFrame(this.frameId);
114
+ this.frameId = null;
115
+ }
116
+ console.log('🎛️ ReactivityManager: Stopped');
117
+ this.emit('stopped');
118
+ }
119
+
120
+ /**
121
+ * Main processing loop
122
+ */
123
+ processFrame() {
124
+ if (!this.isActive) return;
125
+
126
+ // Process all input sources and compute deltas
127
+ this.computeReactivityDeltas();
128
+
129
+ // Apply deltas to parameters
130
+ this.applyDeltas();
131
+
132
+ // Schedule next frame
133
+ this.frameId = requestAnimationFrame(() => this.processFrame());
134
+ }
135
+
136
+ /**
137
+ * Compute reactivity deltas from all input sources
138
+ */
139
+ computeReactivityDeltas() {
140
+ // Reset deltas
141
+ this.reactivityDeltas = {};
142
+
143
+ const cfg = this.config.getConfig();
144
+
145
+ // Process audio reactivity
146
+ if (cfg.audio.enabled) {
147
+ this.processAudioReactivity(cfg.audio);
148
+ }
149
+
150
+ // Process tilt reactivity
151
+ if (cfg.tilt.enabled) {
152
+ this.processTiltReactivity(cfg.tilt);
153
+ }
154
+
155
+ // Process interaction reactivity
156
+ if (cfg.interaction.enabled) {
157
+ this.processInteractionReactivity(cfg.interaction);
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Process audio input and compute parameter deltas
163
+ */
164
+ processAudioReactivity(audioConfig) {
165
+ const audio = this.inputState.audio;
166
+ const globalSens = audioConfig.globalSensitivity;
167
+
168
+ for (const [bandName, bandConfig] of Object.entries(audioConfig.bands)) {
169
+ if (!bandConfig.enabled) continue;
170
+
171
+ const bandValue = audio[bandName] || 0;
172
+ const scaledValue = bandValue * bandConfig.sensitivity * globalSens;
173
+
174
+ for (const target of bandConfig.targets) {
175
+ this.addDelta(target.param, scaledValue * target.weight, target.mode);
176
+ }
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Process tilt input and compute parameter deltas
182
+ */
183
+ processTiltReactivity(tiltConfig) {
184
+ const tilt = this.inputState.tilt;
185
+ const mappings = tiltConfig.dramaticMode ? tiltConfig.dramaticMappings : tiltConfig.mappings;
186
+ const sens = tiltConfig.sensitivity;
187
+
188
+ for (const [axis, mapping] of Object.entries(mappings)) {
189
+ if (!mapping || !mapping.target) continue;
190
+
191
+ // Apply calibration offset
192
+ let axisValue = tilt[axis] || 0;
193
+ if (tiltConfig.calibrated && tiltConfig.calibrationOffset) {
194
+ axisValue -= tiltConfig.calibrationOffset[axis] || 0;
195
+ }
196
+
197
+ // Scale and clamp
198
+ let delta = axisValue * mapping.scale * sens;
199
+ if (mapping.clamp) {
200
+ delta = Math.max(mapping.clamp[0], Math.min(mapping.clamp[1], delta));
201
+ }
202
+
203
+ this.addDelta(mapping.target, delta, 'replace');
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Process mouse/click/scroll/touch and compute parameter deltas
209
+ */
210
+ processInteractionReactivity(interactionConfig) {
211
+ // Mouse movement
212
+ if (interactionConfig.mouse.enabled) {
213
+ this.processMouseReactivity(interactionConfig.mouse);
214
+ }
215
+
216
+ // Click effects
217
+ if (interactionConfig.click.enabled) {
218
+ this.processClickReactivity(interactionConfig.click);
219
+ }
220
+
221
+ // Scroll effects
222
+ if (interactionConfig.scroll.enabled) {
223
+ this.processScrollReactivity(interactionConfig.scroll);
224
+ }
225
+
226
+ // Touch effects
227
+ if (interactionConfig.touch.enabled) {
228
+ this.processTouchReactivity(interactionConfig.touch);
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Process mouse movement
234
+ */
235
+ processMouseReactivity(mouseConfig) {
236
+ const mouse = this.inputState.mouse;
237
+ const sens = mouseConfig.sensitivity;
238
+ const mode = mouseConfig.mode;
239
+
240
+ if (mode === 'none') return;
241
+
242
+ const targets = mouseConfig.targets || ['rot4dXY', 'rot4dYZ'];
243
+ const x = mouseConfig.invertX ? (1 - mouse.x) : mouse.x;
244
+ const y = mouseConfig.invertY ? (1 - mouse.y) : mouse.y;
245
+
246
+ switch (mode) {
247
+ case 'rotation':
248
+ // Map mouse position to rotation
249
+ if (targets[0]) this.addDelta(targets[0], (x - 0.5) * 2 * sens, 'replace');
250
+ if (targets[1]) this.addDelta(targets[1], (y - 0.5) * 2 * sens, 'replace');
251
+ break;
252
+
253
+ case 'velocity':
254
+ // Use mouse velocity
255
+ if (targets[0]) this.addDelta(targets[0], mouse.velocityX * sens * 0.1, 'add');
256
+ if (targets[1]) this.addDelta(targets[1], mouse.velocityY * sens * 0.1, 'add');
257
+ break;
258
+
259
+ case 'shimmer':
260
+ // High-frequency shimmer based on velocity magnitude
261
+ const velocity = Math.sqrt(mouse.velocityX ** 2 + mouse.velocityY ** 2);
262
+ this.addDelta('chaos', velocity * sens * 0.01, 'add');
263
+ break;
264
+
265
+ case 'attract':
266
+ // Pull visualization toward mouse
267
+ this.addDelta('morphFactor', (1 - Math.abs(x - 0.5) * 2) * sens, 'multiply');
268
+ break;
269
+
270
+ case 'repel':
271
+ // Push visualization away from mouse
272
+ this.addDelta('morphFactor', Math.abs(x - 0.5) * 2 * sens, 'multiply');
273
+ break;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Process click effects
279
+ */
280
+ processClickReactivity(clickConfig) {
281
+ const click = this.inputState.click;
282
+
283
+ // Decay click intensity
284
+ click.intensity *= clickConfig.decay;
285
+
286
+ if (click.intensity < 0.001) {
287
+ click.intensity = 0;
288
+ return;
289
+ }
290
+
291
+ const mode = clickConfig.mode;
292
+ const target = clickConfig.target;
293
+ const intensity = click.intensity * clickConfig.intensity;
294
+
295
+ switch (mode) {
296
+ case 'burst':
297
+ this.addDelta(target, intensity, 'add');
298
+ break;
299
+
300
+ case 'blast':
301
+ this.addDelta(target, intensity * 2, 'add');
302
+ this.addDelta('chaos', intensity * 0.5, 'add');
303
+ break;
304
+
305
+ case 'ripple':
306
+ this.addDelta(target, Math.sin(Date.now() * 0.01) * intensity, 'add');
307
+ break;
308
+
309
+ case 'pulse':
310
+ this.addDelta('intensity', intensity * 0.5, 'add');
311
+ this.addDelta('speed', intensity, 'add');
312
+ break;
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Process scroll effects
318
+ */
319
+ processScrollReactivity(scrollConfig) {
320
+ const scroll = this.inputState.scroll;
321
+
322
+ if (Math.abs(scroll.delta) < 0.001) return;
323
+
324
+ const mode = scrollConfig.mode;
325
+ const target = scrollConfig.target;
326
+ const sens = scrollConfig.sensitivity;
327
+
328
+ switch (mode) {
329
+ case 'cycle':
330
+ // Cycle through values (e.g., geometry)
331
+ scroll.accumulated += scroll.delta * sens * scrollConfig.step;
332
+ if (Math.abs(scroll.accumulated) >= 1) {
333
+ const steps = Math.floor(Math.abs(scroll.accumulated));
334
+ const direction = scroll.accumulated > 0 ? 1 : -1;
335
+ this.addDelta(target, steps * direction, 'add');
336
+ scroll.accumulated -= steps * direction;
337
+ }
338
+ break;
339
+
340
+ case 'wave':
341
+ this.addDelta(target, scroll.delta * sens * 0.1, 'add');
342
+ break;
343
+
344
+ case 'sweep':
345
+ this.addDelta('hue', scroll.delta * sens * 10, 'add');
346
+ break;
347
+
348
+ case 'zoom':
349
+ this.addDelta('dimension', scroll.delta * sens * 0.01, 'add');
350
+ break;
351
+
352
+ case 'morph':
353
+ this.addDelta('morphFactor', scroll.delta * sens * 0.1, 'add');
354
+ break;
355
+ }
356
+
357
+ // Decay scroll delta
358
+ scroll.delta *= 0.9;
359
+ }
360
+
361
+ /**
362
+ * Process touch gestures
363
+ */
364
+ processTouchReactivity(touchConfig) {
365
+ const touch = this.inputState.touch;
366
+
367
+ if (touchConfig.pinchZoom.enabled && touch.pinchScale !== 1) {
368
+ const delta = (touch.pinchScale - 1) * touchConfig.pinchZoom.sensitivity;
369
+ this.addDelta(touchConfig.pinchZoom.target, delta, 'add');
370
+ touch.pinchScale = 1 + (touch.pinchScale - 1) * 0.9; // Decay
371
+ }
372
+
373
+ if (touchConfig.twoFingerRotate.enabled && touch.rotation !== 0) {
374
+ const delta = touch.rotation * touchConfig.twoFingerRotate.sensitivity;
375
+ this.addDelta(touchConfig.twoFingerRotate.target, delta, 'add');
376
+ touch.rotation *= 0.9; // Decay
377
+ }
378
+ }
379
+
380
+ /**
381
+ * Add a delta to a parameter
382
+ */
383
+ addDelta(param, value, mode = 'add') {
384
+ if (!TARGETABLE_PARAMETERS.includes(param)) {
385
+ console.warn(`ReactivityManager: Unknown parameter "${param}"`);
386
+ return;
387
+ }
388
+
389
+ if (!this.reactivityDeltas[param]) {
390
+ this.reactivityDeltas[param] = { value: 0, mode: 'add' };
391
+ }
392
+
393
+ const delta = this.reactivityDeltas[param];
394
+
395
+ switch (mode) {
396
+ case 'add':
397
+ delta.value += value;
398
+ delta.mode = 'add';
399
+ break;
400
+
401
+ case 'multiply':
402
+ delta.value = (delta.value || 1) * value;
403
+ delta.mode = 'multiply';
404
+ break;
405
+
406
+ case 'replace':
407
+ delta.value = value;
408
+ delta.mode = 'replace';
409
+ break;
410
+
411
+ case 'max':
412
+ delta.value = Math.max(delta.value, value);
413
+ delta.mode = 'max';
414
+ break;
415
+
416
+ case 'min':
417
+ delta.value = Math.min(delta.value, value);
418
+ delta.mode = 'min';
419
+ break;
420
+ }
421
+ }
422
+
423
+ /**
424
+ * Apply computed deltas to parameters
425
+ */
426
+ applyDeltas() {
427
+ for (const [param, delta] of Object.entries(this.reactivityDeltas)) {
428
+ if (Math.abs(delta.value) < 0.0001 && delta.mode !== 'replace') continue;
429
+
430
+ const baseValue = this.baseParameters[param] || 0;
431
+ let newValue;
432
+
433
+ switch (delta.mode) {
434
+ case 'add':
435
+ newValue = baseValue + delta.value;
436
+ break;
437
+ case 'multiply':
438
+ newValue = baseValue * delta.value;
439
+ break;
440
+ case 'replace':
441
+ newValue = delta.value;
442
+ break;
443
+ case 'max':
444
+ newValue = Math.max(baseValue, delta.value);
445
+ break;
446
+ case 'min':
447
+ newValue = Math.min(baseValue, delta.value);
448
+ break;
449
+ default:
450
+ newValue = baseValue + delta.value;
451
+ }
452
+
453
+ // Guard against NaN propagation
454
+ if (!Number.isFinite(newValue)) continue;
455
+
456
+ // Apply the update
457
+ this.updateParameter(param, newValue);
458
+ }
459
+ }
460
+
461
+ // ==================== INPUT METHODS ====================
462
+
463
+ /**
464
+ * Update audio input values
465
+ */
466
+ setAudioInput(bass, mid, high, energy = null) {
467
+ this.inputState.audio.bass = Number.isFinite(bass) ? Math.max(0, Math.min(1, bass)) : 0;
468
+ this.inputState.audio.mid = Number.isFinite(mid) ? Math.max(0, Math.min(1, mid)) : 0;
469
+ this.inputState.audio.high = Number.isFinite(high) ? Math.max(0, Math.min(1, high)) : 0;
470
+ this.inputState.audio.energy = (energy !== null && Number.isFinite(energy))
471
+ ? energy
472
+ : (this.inputState.audio.bass + this.inputState.audio.mid + this.inputState.audio.high) / 3;
473
+ }
474
+
475
+ /**
476
+ * Update tilt input values
477
+ */
478
+ setTiltInput(alpha, beta, gamma) {
479
+ this.inputState.tilt.alpha = alpha;
480
+ this.inputState.tilt.beta = beta;
481
+ this.inputState.tilt.gamma = gamma;
482
+ }
483
+
484
+ /**
485
+ * Update mouse input values
486
+ */
487
+ setMouseInput(x, y, velocityX = 0, velocityY = 0) {
488
+ this.inputState.mouse.x = Number.isFinite(x) ? Math.max(0, Math.min(1, x)) : 0.5;
489
+ this.inputState.mouse.y = Number.isFinite(y) ? Math.max(0, Math.min(1, y)) : 0.5;
490
+ this.inputState.mouse.velocityX = Number.isFinite(velocityX) ? velocityX : 0;
491
+ this.inputState.mouse.velocityY = Number.isFinite(velocityY) ? velocityY : 0;
492
+ }
493
+
494
+ /**
495
+ * Trigger a click event
496
+ */
497
+ triggerClick(intensity = 1.0) {
498
+ this.inputState.click.intensity = Number.isFinite(intensity) ? Math.max(0, Math.min(2, intensity)) : 1.0;
499
+ this.inputState.click.lastTime = Date.now();
500
+ }
501
+
502
+ /**
503
+ * Update scroll delta
504
+ */
505
+ setScrollDelta(delta) {
506
+ if (Number.isFinite(delta)) {
507
+ this.inputState.scroll.delta += delta;
508
+ }
509
+ }
510
+
511
+ /**
512
+ * Update touch input
513
+ */
514
+ setTouchInput(touches, pinchScale = 1, rotation = 0) {
515
+ this.inputState.touch.touches = touches;
516
+ this.inputState.touch.pinchScale = pinchScale;
517
+ this.inputState.touch.rotation = rotation;
518
+ }
519
+
520
+ /**
521
+ * Set base parameter value (before reactivity)
522
+ */
523
+ setBaseParameter(param, value) {
524
+ this.baseParameters[param] = value;
525
+ }
526
+
527
+ /**
528
+ * Set all base parameters
529
+ */
530
+ setBaseParameters(params) {
531
+ this.baseParameters = { ...this.baseParameters, ...params };
532
+ }
533
+
534
+ // ==================== EVENT EMITTER ====================
535
+
536
+ /**
537
+ * Add event listener
538
+ */
539
+ on(event, callback) {
540
+ if (!this.listeners.has(event)) {
541
+ this.listeners.set(event, []);
542
+ }
543
+ this.listeners.get(event).push(callback);
544
+ }
545
+
546
+ /**
547
+ * Remove event listener
548
+ */
549
+ off(event, callback) {
550
+ if (this.listeners.has(event)) {
551
+ const callbacks = this.listeners.get(event);
552
+ const index = callbacks.indexOf(callback);
553
+ if (index > -1) {
554
+ callbacks.splice(index, 1);
555
+ }
556
+ }
557
+ }
558
+
559
+ /**
560
+ * Emit event
561
+ */
562
+ emit(event, data) {
563
+ if (this.listeners.has(event)) {
564
+ for (const callback of this.listeners.get(event)) {
565
+ try {
566
+ callback(data);
567
+ } catch (e) {
568
+ console.error(`ReactivityManager event handler error:`, e);
569
+ }
570
+ }
571
+ }
572
+ }
573
+
574
+ // ==================== CLEANUP ====================
575
+
576
+ /**
577
+ * Destroy and cleanup
578
+ */
579
+ destroy() {
580
+ this.stop();
581
+ this.listeners.clear();
582
+ console.log('🎛️ ReactivityManager: Destroyed');
583
+ }
584
+ }
585
+
586
+ export default ReactivityManager;