@buley/hexgrid-3d 3.1.0 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. package/dist/HexGridEnhanced.d.ts +15 -0
  2. package/dist/HexGridEnhanced.d.ts.map +1 -0
  3. package/dist/HexGridEnhanced.js +1 -0
  4. package/dist/Snapshot.d.ts +594 -0
  5. package/dist/Snapshot.d.ts.map +1 -0
  6. package/dist/Snapshot.js +757 -0
  7. package/dist/adapters/DashAdapter.d.ts +18 -0
  8. package/dist/adapters/DashAdapter.d.ts.map +1 -0
  9. package/dist/adapters/DashAdapter.js +42 -0
  10. package/dist/adapters.d.ts +53 -0
  11. package/dist/adapters.d.ts.map +1 -0
  12. package/dist/adapters.js +14 -0
  13. package/dist/algorithms/AdvancedStatistics.d.ts +52 -0
  14. package/dist/algorithms/AdvancedStatistics.d.ts.map +1 -0
  15. package/dist/algorithms/AdvancedStatistics.js +307 -0
  16. package/dist/algorithms/BayesianStatistics.d.ts +86 -0
  17. package/dist/algorithms/BayesianStatistics.d.ts.map +1 -0
  18. package/dist/algorithms/BayesianStatistics.js +263 -0
  19. package/dist/algorithms/FlowField.d.ts +55 -0
  20. package/dist/algorithms/FlowField.d.ts.map +1 -0
  21. package/dist/algorithms/FlowField.js +80 -0
  22. package/dist/algorithms/FlowField3D.d.ts +166 -0
  23. package/dist/algorithms/FlowField3D.d.ts.map +1 -0
  24. package/dist/algorithms/FlowField3D.js +327 -0
  25. package/dist/algorithms/FluidEngineFactory.d.ts +15 -0
  26. package/dist/algorithms/FluidEngineFactory.d.ts.map +1 -0
  27. package/dist/algorithms/FluidEngineFactory.js +41 -0
  28. package/dist/algorithms/FluidSimulation.d.ts +41 -0
  29. package/dist/algorithms/FluidSimulation.d.ts.map +1 -0
  30. package/dist/algorithms/FluidSimulation.js +74 -0
  31. package/dist/algorithms/FluidSimulation3D.d.ts +137 -0
  32. package/dist/algorithms/FluidSimulation3D.d.ts.map +1 -0
  33. package/dist/algorithms/FluidSimulation3D.js +464 -0
  34. package/dist/algorithms/FluidSimulation3DGPU.d.ts +41 -0
  35. package/dist/algorithms/FluidSimulation3DGPU.d.ts.map +1 -0
  36. package/dist/algorithms/FluidSimulation3DGPU.js +328 -0
  37. package/dist/algorithms/FluidSimulationWebNN.d.ts +56 -0
  38. package/dist/algorithms/FluidSimulationWebNN.d.ts.map +1 -0
  39. package/dist/algorithms/FluidSimulationWebNN.js +84 -0
  40. package/dist/algorithms/GraphAlgorithms.d.ts +48 -0
  41. package/dist/algorithms/GraphAlgorithms.d.ts.map +1 -0
  42. package/dist/algorithms/GraphAlgorithms.js +122 -0
  43. package/dist/algorithms/OutlierDetection.d.ts +49 -0
  44. package/dist/algorithms/OutlierDetection.d.ts.map +1 -0
  45. package/dist/algorithms/OutlierDetection.js +284 -0
  46. package/dist/algorithms/ParticleSystem.d.ts +36 -0
  47. package/dist/algorithms/ParticleSystem.d.ts.map +1 -0
  48. package/dist/algorithms/ParticleSystem.js +59 -0
  49. package/dist/algorithms/ParticleSystem3D.d.ts +206 -0
  50. package/dist/algorithms/ParticleSystem3D.d.ts.map +1 -0
  51. package/dist/algorithms/ParticleSystem3D.js +371 -0
  52. package/dist/algorithms/index.d.ts +16 -0
  53. package/dist/algorithms/index.d.ts.map +1 -0
  54. package/{src/algorithms/index.ts → dist/algorithms/index.js} +0 -2
  55. package/dist/compat.d.ts +24 -0
  56. package/dist/compat.d.ts.map +1 -0
  57. package/dist/compat.js +88 -0
  58. package/dist/components/HexGrid.d.ts +5 -0
  59. package/dist/components/HexGrid.d.ts.map +1 -0
  60. package/dist/components/HexGrid.js +39 -0
  61. package/dist/components/NarrationOverlay.d.ts +16 -0
  62. package/dist/components/NarrationOverlay.d.ts.map +1 -0
  63. package/dist/components/NarrationOverlay.js +132 -0
  64. package/{src/components/index.ts → dist/components/index.d.ts} +1 -0
  65. package/dist/components/index.d.ts.map +1 -0
  66. package/dist/components/index.js +1 -0
  67. package/dist/features.d.ts +54 -0
  68. package/dist/features.d.ts.map +1 -0
  69. package/dist/features.js +74 -0
  70. package/dist/index.d.ts +12 -0
  71. package/dist/index.d.ts.map +1 -0
  72. package/{src/index.ts → dist/index.js} +0 -9
  73. package/dist/lib/narration.d.ts +12 -0
  74. package/dist/lib/narration.d.ts.map +1 -0
  75. package/dist/lib/narration.js +8 -0
  76. package/dist/lib/stats-tracker.d.ts +7 -0
  77. package/dist/lib/stats-tracker.d.ts.map +1 -0
  78. package/dist/lib/stats-tracker.js +22 -0
  79. package/dist/lib/theme-colors.d.ts +7 -0
  80. package/dist/lib/theme-colors.d.ts.map +1 -0
  81. package/dist/lib/theme-colors.js +10 -0
  82. package/dist/math/HexCoordinates.d.ts +140 -0
  83. package/dist/math/HexCoordinates.d.ts.map +1 -0
  84. package/dist/math/HexCoordinates.js +741 -0
  85. package/dist/math/Matrix4.d.ts +9 -0
  86. package/dist/math/Matrix4.d.ts.map +1 -0
  87. package/dist/math/Matrix4.js +19 -0
  88. package/dist/math/Quaternion.d.ts +11 -0
  89. package/dist/math/Quaternion.d.ts.map +1 -0
  90. package/dist/math/Quaternion.js +23 -0
  91. package/dist/math/SpatialIndex.d.ts +34 -0
  92. package/dist/math/SpatialIndex.d.ts.map +1 -0
  93. package/dist/math/SpatialIndex.js +75 -0
  94. package/dist/math/Vector3.d.ts +110 -0
  95. package/dist/math/Vector3.d.ts.map +1 -0
  96. package/dist/math/Vector3.js +426 -0
  97. package/dist/math/index.d.ts +11 -0
  98. package/dist/math/index.d.ts.map +1 -0
  99. package/{src/math/index.ts → dist/math/index.js} +0 -1
  100. package/dist/note-adapter.d.ts +44 -0
  101. package/dist/note-adapter.d.ts.map +1 -0
  102. package/dist/note-adapter.js +86 -0
  103. package/dist/ontology-adapter.d.ts +13 -0
  104. package/dist/ontology-adapter.d.ts.map +1 -0
  105. package/dist/ontology-adapter.js +65 -0
  106. package/dist/stores/index.d.ts +2 -0
  107. package/dist/stores/index.d.ts.map +1 -0
  108. package/dist/stores/uiStore.d.ts +18 -0
  109. package/dist/stores/uiStore.d.ts.map +1 -0
  110. package/dist/stores/uiStore.js +77 -0
  111. package/dist/types/index.d.ts +4 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/types/index.js +1 -0
  114. package/dist/types.d.ts +126 -0
  115. package/dist/types.d.ts.map +1 -0
  116. package/dist/types.js +4 -0
  117. package/dist/utils/image-utils.d.ts +13 -0
  118. package/dist/utils/image-utils.d.ts.map +1 -0
  119. package/dist/utils/image-utils.js +23 -0
  120. package/dist/wasm/HexGridWasmWrapper.d.ts +131 -0
  121. package/dist/wasm/HexGridWasmWrapper.d.ts.map +1 -0
  122. package/dist/wasm/HexGridWasmWrapper.js +610 -0
  123. package/dist/wasm/index.d.ts +7 -0
  124. package/dist/wasm/index.d.ts.map +1 -0
  125. package/{src/wasm/index.ts → dist/wasm/index.js} +0 -1
  126. package/dist/webgpu/WebGPUContext.d.ts +20 -0
  127. package/dist/webgpu/WebGPUContext.d.ts.map +1 -0
  128. package/dist/webgpu/WebGPUContext.js +60 -0
  129. package/dist/webnn/WebNNContext.d.ts +38 -0
  130. package/dist/webnn/WebNNContext.d.ts.map +1 -0
  131. package/dist/webnn/WebNNContext.js +66 -0
  132. package/dist/workers/hexgrid-math.d.ts +79 -0
  133. package/dist/workers/hexgrid-math.d.ts.map +1 -0
  134. package/dist/workers/hexgrid-math.js +136 -0
  135. package/dist/workers/hexgrid-worker.worker.d.ts +35 -0
  136. package/dist/workers/hexgrid-worker.worker.d.ts.map +1 -0
  137. package/dist/workers/hexgrid-worker.worker.js +2014 -0
  138. package/package.json +20 -7
  139. package/.eslintrc.json +0 -28
  140. package/build_log.txt +0 -500
  141. package/build_src_log.txt +0 -8
  142. package/examples/basic-usage.tsx +0 -52
  143. package/public/hexgrid-worker.js +0 -2475
  144. package/rust/Cargo.toml +0 -41
  145. package/rust/src/lib.rs +0 -740
  146. package/rust/src/math.rs +0 -574
  147. package/rust/src/spatial.rs +0 -245
  148. package/rust/src/statistics.rs +0 -496
  149. package/site/.eslintrc.json +0 -3
  150. package/site/DEPLOYMENT.md +0 -196
  151. package/site/INDEX.md +0 -127
  152. package/site/QUICK_START.md +0 -86
  153. package/site/README.md +0 -85
  154. package/site/SITE_SUMMARY.md +0 -180
  155. package/site/next.config.js +0 -12
  156. package/site/package.json +0 -26
  157. package/site/src/app/docs/page.tsx +0 -272
  158. package/site/src/app/examples/page.tsx +0 -151
  159. package/site/src/app/globals.css +0 -160
  160. package/site/src/app/layout.tsx +0 -39
  161. package/site/src/app/page.tsx +0 -235
  162. package/site/tsconfig.json +0 -29
  163. package/site/vercel.json +0 -6
  164. package/src/HexGridEnhanced.ts +0 -16
  165. package/src/Snapshot.ts +0 -1607
  166. package/src/adapters/DashAdapter.ts +0 -57
  167. package/src/adapters.ts +0 -63
  168. package/src/algorithms/AdvancedStatistics.ts +0 -362
  169. package/src/algorithms/BayesianStatistics.ts +0 -348
  170. package/src/algorithms/FlowField.ts +0 -150
  171. package/src/algorithms/FlowField3D.ts +0 -573
  172. package/src/algorithms/FluidEngineFactory.ts +0 -44
  173. package/src/algorithms/FluidSimulation.ts +0 -115
  174. package/src/algorithms/FluidSimulation3D.ts +0 -664
  175. package/src/algorithms/FluidSimulation3DGPU.ts +0 -408
  176. package/src/algorithms/FluidSimulationWebNN.ts +0 -141
  177. package/src/algorithms/GraphAlgorithms.ts +0 -191
  178. package/src/algorithms/OutlierDetection.ts +0 -425
  179. package/src/algorithms/ParticleSystem.ts +0 -95
  180. package/src/algorithms/ParticleSystem3D.ts +0 -567
  181. package/src/compat.ts +0 -96
  182. package/src/components/HexGrid.tsx +0 -61
  183. package/src/components/NarrationOverlay.tsx +0 -309
  184. package/src/features.ts +0 -125
  185. package/src/lib/narration.ts +0 -17
  186. package/src/lib/stats-tracker.ts +0 -25
  187. package/src/lib/theme-colors.ts +0 -12
  188. package/src/math/HexCoordinates.ts +0 -863
  189. package/src/math/Matrix4.ts +0 -25
  190. package/src/math/Quaternion.ts +0 -37
  191. package/src/math/SpatialIndex.ts +0 -114
  192. package/src/math/Vector3.ts +0 -540
  193. package/src/note-adapter.ts +0 -132
  194. package/src/ontology-adapter.ts +0 -84
  195. package/src/stores/uiStore.ts +0 -85
  196. package/src/types/index.ts +0 -3
  197. package/src/types/shared-utils.d.ts +0 -10
  198. package/src/types/wgsl.d.ts +0 -4
  199. package/src/types.ts +0 -164
  200. package/src/utils/image-utils.ts +0 -28
  201. package/src/wasm/HexGridWasmWrapper.ts +0 -801
  202. package/src/webgpu/WebGPUContext.ts +0 -71
  203. package/src/webgpu/shaders/fluid_sim.wgsl +0 -140
  204. package/src/webnn/WebNNContext.ts +0 -99
  205. package/src/workers/hexgrid-math.ts +0 -182
  206. package/src/workers/hexgrid-worker.worker.ts +0 -2781
  207. package/tsconfig.json +0 -26
  208. /package/{src/stores/index.ts → dist/stores/index.js} +0 -0
@@ -0,0 +1,327 @@
1
+ /**
2
+ * 3D Flow Field
3
+ *
4
+ * A 3D vector field supporting vortices, attractors, and streamline tracing.
5
+ * Used for creating swirling "fluid soup" motion in the Pensieve.
6
+ */
7
+ import { Vector3 } from '../math/Vector3';
8
+ /**
9
+ * 3D Flow Field with vortices, attractors, and sources
10
+ */
11
+ export class FlowField3D {
12
+ constructor(config) {
13
+ // Sources
14
+ this.vortices = [];
15
+ this.attractors = [];
16
+ this.sources = [];
17
+ // Noise for turbulence
18
+ this.noiseTime = 0;
19
+ this.width = Math.max(1, Math.round(config.width));
20
+ this.height = Math.max(1, Math.round(config.height));
21
+ this.depth = Math.max(1, Math.round(config.depth));
22
+ this.resolution = config.resolution;
23
+ this.size = this.width * this.height * this.depth;
24
+ this.fieldX = new Float32Array(this.size);
25
+ this.fieldY = new Float32Array(this.size);
26
+ this.fieldZ = new Float32Array(this.size);
27
+ }
28
+ /**
29
+ * Add a vortex to the field
30
+ */
31
+ addVortex(center, axis, strength, radius, falloff = 'quadratic') {
32
+ // Normalize axis
33
+ const len = Math.sqrt(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z);
34
+ const normalizedAxis = new Vector3(axis.x / len, axis.y / len, axis.z / len);
35
+ this.vortices.push({
36
+ center,
37
+ axis: normalizedAxis,
38
+ strength,
39
+ radius,
40
+ falloff,
41
+ });
42
+ }
43
+ /**
44
+ * Add an attractor (positive strength) or repeller (negative strength)
45
+ */
46
+ addAttractor(center, strength, radius = 10, falloff = 'inverse-square') {
47
+ this.attractors.push({
48
+ center,
49
+ strength,
50
+ radius,
51
+ falloff,
52
+ });
53
+ }
54
+ /**
55
+ * Add a directional source
56
+ */
57
+ addSource(position, velocity, strength, radius = 5) {
58
+ // Normalize direction
59
+ const len = Math.sqrt(velocity.x * velocity.x +
60
+ velocity.y * velocity.y +
61
+ velocity.z * velocity.z);
62
+ const direction = len > 0
63
+ ? new Vector3(velocity.x / len, velocity.y / len, velocity.z / len)
64
+ : new Vector3(0, 1, 0);
65
+ this.sources.push({
66
+ position,
67
+ direction,
68
+ strength,
69
+ radius,
70
+ });
71
+ }
72
+ /**
73
+ * Clear all sources
74
+ */
75
+ clearSources() {
76
+ this.vortices = [];
77
+ this.attractors = [];
78
+ this.sources = [];
79
+ }
80
+ /**
81
+ * Sample the velocity at a world position
82
+ */
83
+ sample(position) {
84
+ let vx = 0;
85
+ let vy = 0;
86
+ let vz = 0;
87
+ // Contribution from vortices
88
+ for (const vortex of this.vortices) {
89
+ const contribution = this.sampleVortex(position, vortex);
90
+ vx += contribution.x;
91
+ vy += contribution.y;
92
+ vz += contribution.z;
93
+ }
94
+ // Contribution from attractors
95
+ for (const attractor of this.attractors) {
96
+ const contribution = this.sampleAttractor(position, attractor);
97
+ vx += contribution.x;
98
+ vy += contribution.y;
99
+ vz += contribution.z;
100
+ }
101
+ // Contribution from directional sources
102
+ for (const source of this.sources) {
103
+ const contribution = this.sampleSource(position, source);
104
+ vx += contribution.x;
105
+ vy += contribution.y;
106
+ vz += contribution.z;
107
+ }
108
+ return new Vector3(vx, vy, vz);
109
+ }
110
+ /**
111
+ * Sample the full field including curl and divergence
112
+ */
113
+ sampleFull(position) {
114
+ const velocity = this.sample(position);
115
+ // Compute curl numerically
116
+ const h = this.resolution * 0.5;
117
+ const vxp = this.sample(new Vector3(position.x + h, position.y, position.z));
118
+ const vxm = this.sample(new Vector3(position.x - h, position.y, position.z));
119
+ const vyp = this.sample(new Vector3(position.x, position.y + h, position.z));
120
+ const vym = this.sample(new Vector3(position.x, position.y - h, position.z));
121
+ const vzp = this.sample(new Vector3(position.x, position.y, position.z + h));
122
+ const vzm = this.sample(new Vector3(position.x, position.y, position.z - h));
123
+ const curl = new Vector3((vyp.z - vym.z - vzp.y + vzm.y) / (2 * h), (vzp.x - vzm.x - vxp.z + vxm.z) / (2 * h), (vxp.y - vxm.y - vyp.x + vym.x) / (2 * h));
124
+ const divergence = (vxp.x - vxm.x + vyp.y - vym.y + vzp.z - vzm.z) / (2 * h);
125
+ return { velocity, curl, divergence };
126
+ }
127
+ /**
128
+ * Trace a streamline from a starting point
129
+ */
130
+ traceStreamline(start, options = {}) {
131
+ const maxSteps = options.maxSteps ?? 100;
132
+ const stepSize = options.stepSize ?? this.resolution;
133
+ const minVelocity = options.minVelocity ?? 0.001;
134
+ const bidirectional = options.bidirectional ?? false;
135
+ const points = [start];
136
+ // Trace forward
137
+ let pos = new Vector3(start.x, start.y, start.z);
138
+ for (let i = 0; i < maxSteps; i++) {
139
+ const vel = this.sample(pos);
140
+ const speed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z);
141
+ if (speed < minVelocity)
142
+ break;
143
+ // Normalize and step
144
+ pos = new Vector3(pos.x + (vel.x / speed) * stepSize, pos.y + (vel.y / speed) * stepSize, pos.z + (vel.z / speed) * stepSize);
145
+ points.push(pos);
146
+ }
147
+ // Trace backward
148
+ if (bidirectional) {
149
+ pos = new Vector3(start.x, start.y, start.z);
150
+ const backwardPoints = [];
151
+ for (let i = 0; i < maxSteps; i++) {
152
+ const vel = this.sample(pos);
153
+ const speed = Math.sqrt(vel.x * vel.x + vel.y * vel.y + vel.z * vel.z);
154
+ if (speed < minVelocity)
155
+ break;
156
+ // Normalize and step backward
157
+ pos = new Vector3(pos.x - (vel.x / speed) * stepSize, pos.y - (vel.y / speed) * stepSize, pos.z - (vel.z / speed) * stepSize);
158
+ backwardPoints.unshift(pos);
159
+ }
160
+ return [...backwardPoints, ...points];
161
+ }
162
+ return points;
163
+ }
164
+ /**
165
+ * Update the flow field (for time-varying fields)
166
+ */
167
+ update(dt) {
168
+ this.noiseTime += dt;
169
+ }
170
+ /**
171
+ * Get field dimensions
172
+ */
173
+ getDimensions() {
174
+ return {
175
+ width: this.width,
176
+ height: this.height,
177
+ depth: this.depth,
178
+ resolution: this.resolution,
179
+ };
180
+ }
181
+ // =========================================================================
182
+ // PRIVATE METHODS
183
+ // =========================================================================
184
+ sampleVortex(pos, vortex) {
185
+ // Vector from vortex center to position
186
+ const dx = pos.x - vortex.center.x;
187
+ const dy = pos.y - vortex.center.y;
188
+ const dz = pos.z - vortex.center.z;
189
+ // Project onto plane perpendicular to axis
190
+ // p_proj = p - (p . axis) * axis
191
+ const dot = dx * vortex.axis.x + dy * vortex.axis.y + dz * vortex.axis.z;
192
+ const px = dx - dot * vortex.axis.x;
193
+ const py = dy - dot * vortex.axis.y;
194
+ const pz = dz - dot * vortex.axis.z;
195
+ // Distance in plane
196
+ const planeDist = Math.sqrt(px * px + py * py + pz * pz);
197
+ if (planeDist < 0.001) {
198
+ return new Vector3(0, 0, 0);
199
+ }
200
+ // Calculate falloff
201
+ let falloff;
202
+ const normalizedDist = planeDist / vortex.radius;
203
+ if (normalizedDist > 1) {
204
+ falloff = 0;
205
+ }
206
+ else {
207
+ switch (vortex.falloff) {
208
+ case 'linear':
209
+ falloff = 1 - normalizedDist;
210
+ break;
211
+ case 'quadratic':
212
+ falloff = (1 - normalizedDist) * (1 - normalizedDist);
213
+ break;
214
+ case 'gaussian':
215
+ falloff = Math.exp(-normalizedDist * normalizedDist * 3);
216
+ break;
217
+ default:
218
+ falloff = 1 - normalizedDist;
219
+ }
220
+ }
221
+ // Cross product: axis x (pos - center) gives tangent direction
222
+ // This creates circular motion around the axis
223
+ const tx = vortex.axis.y * pz - vortex.axis.z * py;
224
+ const ty = vortex.axis.z * px - vortex.axis.x * pz;
225
+ const tz = vortex.axis.x * py - vortex.axis.y * px;
226
+ // Normalize and apply strength
227
+ const tLen = Math.sqrt(tx * tx + ty * ty + tz * tz);
228
+ if (tLen < 0.001) {
229
+ return new Vector3(0, 0, 0);
230
+ }
231
+ const strength = vortex.strength * falloff;
232
+ return new Vector3((tx / tLen) * strength, (ty / tLen) * strength, (tz / tLen) * strength);
233
+ }
234
+ sampleAttractor(pos, attractor) {
235
+ const dx = attractor.center.x - pos.x;
236
+ const dy = attractor.center.y - pos.y;
237
+ const dz = attractor.center.z - pos.z;
238
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
239
+ if (dist < 0.001 || dist > attractor.radius) {
240
+ return new Vector3(0, 0, 0);
241
+ }
242
+ // Calculate falloff
243
+ let strength;
244
+ const normalizedDist = dist / attractor.radius;
245
+ switch (attractor.falloff) {
246
+ case 'linear':
247
+ strength = attractor.strength * (1 - normalizedDist);
248
+ break;
249
+ case 'quadratic':
250
+ strength =
251
+ attractor.strength * (1 - normalizedDist) * (1 - normalizedDist);
252
+ break;
253
+ case 'inverse-square':
254
+ // Clamped inverse square to avoid singularity
255
+ strength = attractor.strength / Math.max(1, dist * dist);
256
+ break;
257
+ default:
258
+ strength = attractor.strength * (1 - normalizedDist);
259
+ }
260
+ // Direction towards/away from attractor
261
+ const invDist = 1 / dist;
262
+ return new Vector3(dx * invDist * strength, dy * invDist * strength, dz * invDist * strength);
263
+ }
264
+ sampleSource(pos, source) {
265
+ const dx = pos.x - source.position.x;
266
+ const dy = pos.y - source.position.y;
267
+ const dz = pos.z - source.position.z;
268
+ const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
269
+ if (dist > source.radius) {
270
+ return new Vector3(0, 0, 0);
271
+ }
272
+ const falloff = 1 - dist / source.radius;
273
+ const strength = source.strength * falloff;
274
+ return new Vector3(source.direction.x * strength, source.direction.y * strength, source.direction.z * strength);
275
+ }
276
+ }
277
+ /**
278
+ * Pensieve-specific flow field with aesthetic presets
279
+ */
280
+ export class PensieveFlowField extends FlowField3D {
281
+ constructor(size = 100) {
282
+ super({
283
+ width: size,
284
+ height: size,
285
+ depth: size,
286
+ resolution: 1,
287
+ });
288
+ // Add default swirling vortices for the pensieve "soup" effect
289
+ this.addDefaultVortices();
290
+ }
291
+ /**
292
+ * Add default vortices for pensieve aesthetic
293
+ */
294
+ addDefaultVortices() {
295
+ const dims = this.getDimensions();
296
+ const center = dims.width / 2;
297
+ // Central upward spiral
298
+ this.addVortex(new Vector3(center, center * 0.3, center), new Vector3(0, 1, 0), 2, center * 0.8, 'gaussian');
299
+ // Secondary horizontal vortices
300
+ this.addVortex(new Vector3(center * 0.7, center, center), new Vector3(1, 0.3, 0), 1, center * 0.4, 'quadratic');
301
+ this.addVortex(new Vector3(center * 1.3, center, center), new Vector3(-1, 0.3, 0), 1, center * 0.4, 'quadratic');
302
+ // Gentle central attractor to keep particles from flying away
303
+ this.addAttractor(new Vector3(center, center, center), 0.5, center * 1.5, 'linear');
304
+ }
305
+ /**
306
+ * Add mouse interaction force
307
+ */
308
+ addMouseForce(position, direction, strength = 5) {
309
+ // Temporarily add a directional source
310
+ this.addSource(position, direction, strength, 10);
311
+ }
312
+ /**
313
+ * Clear mouse forces (call after interaction ends)
314
+ */
315
+ clearMouseForces() {
316
+ // Remove all directional sources but keep vortices and attractors
317
+ const vorticesCopy = [...this.vortices];
318
+ const attractorsCopy = [...this.attractors];
319
+ this.clearSources();
320
+ for (const v of vorticesCopy) {
321
+ this.addVortex(v.center, v.axis, v.strength, v.radius, v.falloff);
322
+ }
323
+ for (const a of attractorsCopy) {
324
+ this.addAttractor(a.center, a.strength, a.radius, a.falloff);
325
+ }
326
+ }
327
+ }
@@ -0,0 +1,15 @@
1
+ import { StableFluids3D, FluidConfig3D } from './FluidSimulation3D';
2
+ import { FluidSimulationWebNN } from './FluidSimulationWebNN';
3
+ import { FluidSimulation3DGPU } from './FluidSimulation3DGPU';
4
+ export type FluidEngine = StableFluids3D | FluidSimulationWebNN | FluidSimulation3DGPU;
5
+ /**
6
+ * Factory to select the best available Fluid Engine.
7
+ * Priority:
8
+ * 1. WebNN (NPU)
9
+ * 2. WebGPU (GPU)
10
+ * 3. CPU (Fallback)
11
+ */
12
+ export declare class FluidEngineFactory {
13
+ static create(config: FluidConfig3D): Promise<FluidEngine>;
14
+ }
15
+ //# sourceMappingURL=FluidEngineFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FluidEngineFactory.d.ts","sourceRoot":"","sources":["../../src/algorithms/FluidEngineFactory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,oBAAoB,GAAG,oBAAoB,CAAC;AAEvF;;;;;;GAMG;AACH,qBAAa,kBAAkB;WAChB,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC;CA6BjE"}
@@ -0,0 +1,41 @@
1
+ import { StableFluids3D } from './FluidSimulation3D';
2
+ import { FluidSimulationWebNN } from './FluidSimulationWebNN';
3
+ import { FluidSimulation3DGPU } from './FluidSimulation3DGPU';
4
+ /**
5
+ * Factory to select the best available Fluid Engine.
6
+ * Priority:
7
+ * 1. WebNN (NPU)
8
+ * 2. WebGPU (GPU)
9
+ * 3. CPU (Fallback)
10
+ */
11
+ export class FluidEngineFactory {
12
+ static async create(config) {
13
+ // 1. Try WebNN
14
+ try {
15
+ const webnn = new FluidSimulationWebNN(config);
16
+ const webnnSupported = await webnn.initialize();
17
+ if (webnnSupported) {
18
+ console.log("Fluid Engine: Using WebNN (NPU)");
19
+ return webnn;
20
+ }
21
+ }
22
+ catch (e) {
23
+ console.warn("Fluid Engine: WebNN init failed", e);
24
+ }
25
+ // 2. Try WebGPU
26
+ try {
27
+ const webgpu = new FluidSimulation3DGPU(config);
28
+ const webgpuSupported = await webgpu.initialize();
29
+ if (webgpuSupported) {
30
+ console.log("Fluid Engine: Using WebGPU");
31
+ return webgpu;
32
+ }
33
+ }
34
+ catch (e) {
35
+ console.warn("Fluid Engine: WebGPU init failed", e);
36
+ }
37
+ // 3. Fallback to CPU
38
+ console.log("Fluid Engine: using CPU Fallback");
39
+ return new StableFluids3D(config);
40
+ }
41
+ }
@@ -0,0 +1,41 @@
1
+ export interface FluidConfig {
2
+ width: number;
3
+ height: number;
4
+ viscosity: number;
5
+ diffusion: number;
6
+ }
7
+ export declare class StableFluids {
8
+ private width;
9
+ private height;
10
+ private density;
11
+ private velocityX;
12
+ private velocityY;
13
+ constructor(config: FluidConfig);
14
+ addDensity(x: number, y: number, amount: number, radius: number): void;
15
+ addForce(x: number, y: number, vx: number, vy: number, _radius: number): void;
16
+ step(_deltaTime: number): void;
17
+ getDensity(x: number, y: number): number;
18
+ getVelocity(x: number, y: number): {
19
+ x: number;
20
+ y: number;
21
+ };
22
+ getDensityField(): Float32Array;
23
+ getVelocityField(): {
24
+ x: Float32Array;
25
+ y: Float32Array;
26
+ };
27
+ clear(): void;
28
+ private indexFor;
29
+ }
30
+ export declare class LatticeBoltzmann {
31
+ constructor(_width: number, _height: number);
32
+ }
33
+ export declare class InfectionFluidSimulator {
34
+ private fluid;
35
+ constructor(width: number, height: number);
36
+ registerTerritory(_ownerId: number, x: number, y: number, intensity: number): void;
37
+ update(deltaTime: number): void;
38
+ getFluid(): StableFluids;
39
+ clear(): void;
40
+ }
41
+ //# sourceMappingURL=FluidSimulation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FluidSimulation.d.ts","sourceRoot":"","sources":["../../src/algorithms/FluidSimulation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAe;gBAEpB,MAAM,EAAE,WAAW;IAS/B,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IAKtE,QAAQ,CACN,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,GACd,IAAI;IAMP,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQ9B,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM;IAIxC,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAK3D,eAAe,IAAI,YAAY;IAI/B,gBAAgB,IAAI;QAAE,CAAC,EAAE,YAAY,CAAC;QAAC,CAAC,EAAE,YAAY,CAAA;KAAE;IAIxD,KAAK,IAAI,IAAI;IAMb,OAAO,CAAC,QAAQ;CAKjB;AAED,qBAAa,gBAAgB;gBACf,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAC5C;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,KAAK,CAAe;gBAEhB,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IASzC,iBAAiB,CACf,QAAQ,EAAE,MAAM,EAChB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,SAAS,EAAE,MAAM,GAChB,IAAI;IAIP,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI/B,QAAQ,IAAI,YAAY;IAIxB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,74 @@
1
+ export class StableFluids {
2
+ constructor(config) {
3
+ this.width = Math.max(1, Math.round(config.width));
4
+ this.height = Math.max(1, Math.round(config.height));
5
+ const size = this.width * this.height;
6
+ this.density = new Float32Array(size);
7
+ this.velocityX = new Float32Array(size);
8
+ this.velocityY = new Float32Array(size);
9
+ }
10
+ addDensity(x, y, amount, radius) {
11
+ const index = this.indexFor(x, y);
12
+ this.density[index] += amount;
13
+ }
14
+ addForce(x, y, vx, vy, _radius) {
15
+ const index = this.indexFor(x, y);
16
+ this.velocityX[index] += vx;
17
+ this.velocityY[index] += vy;
18
+ }
19
+ step(_deltaTime) {
20
+ // Simple damping
21
+ for (let i = 0; i < this.velocityX.length; i++) {
22
+ this.velocityX[i] *= 0.98;
23
+ this.velocityY[i] *= 0.98;
24
+ }
25
+ }
26
+ getDensity(x, y) {
27
+ return this.density[this.indexFor(x, y)] || 0;
28
+ }
29
+ getVelocity(x, y) {
30
+ const index = this.indexFor(x, y);
31
+ return { x: this.velocityX[index] || 0, y: this.velocityY[index] || 0 };
32
+ }
33
+ getDensityField() {
34
+ return this.density;
35
+ }
36
+ getVelocityField() {
37
+ return { x: this.velocityX, y: this.velocityY };
38
+ }
39
+ clear() {
40
+ this.density.fill(0);
41
+ this.velocityX.fill(0);
42
+ this.velocityY.fill(0);
43
+ }
44
+ indexFor(x, y) {
45
+ const ix = Math.min(this.width - 1, Math.max(0, Math.floor(x)));
46
+ const iy = Math.min(this.height - 1, Math.max(0, Math.floor(y)));
47
+ return iy * this.width + ix;
48
+ }
49
+ }
50
+ export class LatticeBoltzmann {
51
+ constructor(_width, _height) { }
52
+ }
53
+ export class InfectionFluidSimulator {
54
+ constructor(width, height) {
55
+ this.fluid = new StableFluids({
56
+ width,
57
+ height,
58
+ viscosity: 0,
59
+ diffusion: 0,
60
+ });
61
+ }
62
+ registerTerritory(_ownerId, x, y, intensity) {
63
+ this.fluid.addDensity(x, y, intensity, 1);
64
+ }
65
+ update(deltaTime) {
66
+ this.fluid.step(deltaTime);
67
+ }
68
+ getFluid() {
69
+ return this.fluid;
70
+ }
71
+ clear() {
72
+ this.fluid.clear();
73
+ }
74
+ }
@@ -0,0 +1,137 @@
1
+ /**
2
+ * 3D Stable Fluids Implementation
3
+ *
4
+ * Based on Jos Stam's "Stable Fluids" paper (SIGGRAPH 1999)
5
+ * Extended to 3D for the Pensieve particle visualization.
6
+ *
7
+ * Key operations:
8
+ * 1. Add sources (density, velocity)
9
+ * 2. Diffuse (spread quantities)
10
+ * 3. Advect (move quantities along velocity field)
11
+ * 4. Project (make velocity field divergence-free)
12
+ */
13
+ import { Vector3 } from '../math/Vector3';
14
+ export interface FluidConfig3D {
15
+ /** Grid width in cells */
16
+ width: number;
17
+ /** Grid height in cells */
18
+ height: number;
19
+ /** Grid depth in cells */
20
+ depth: number;
21
+ /** Viscosity coefficient (0 = inviscid, higher = more viscous) */
22
+ viscosity: number;
23
+ /** Diffusion rate for density (0 = no diffusion) */
24
+ diffusion: number;
25
+ /** Number of iterations for linear solver (higher = more accurate but slower) */
26
+ iterations?: number;
27
+ }
28
+ /**
29
+ * 3D Stable Fluids solver for realistic fluid dynamics
30
+ */
31
+ export declare class StableFluids3D {
32
+ private width;
33
+ private height;
34
+ private depth;
35
+ private size;
36
+ private viscosity;
37
+ private diffusion;
38
+ private iterations;
39
+ private density;
40
+ private velocityX;
41
+ private velocityY;
42
+ private velocityZ;
43
+ private density0;
44
+ private velocityX0;
45
+ private velocityY0;
46
+ private velocityZ0;
47
+ constructor(config: FluidConfig3D);
48
+ /**
49
+ * Add density at a point with radius falloff
50
+ */
51
+ addDensity(x: number, y: number, z: number, amount: number, radius: number): void;
52
+ /**
53
+ * Add force at a point with radius falloff
54
+ */
55
+ addForce(pos: Vector3, force: Vector3, radius: number): void;
56
+ /**
57
+ * Step the simulation forward by dt seconds
58
+ */
59
+ step(dt: number): void;
60
+ /**
61
+ * Get velocity at a point (with trilinear interpolation)
62
+ */
63
+ getVelocityAt(pos: Vector3): Vector3;
64
+ /**
65
+ * Get density at a point (with trilinear interpolation)
66
+ */
67
+ getDensityAt(pos: Vector3): number;
68
+ /**
69
+ * Get the raw velocity fields for direct access
70
+ */
71
+ getVelocityFields(): {
72
+ x: Float32Array;
73
+ y: Float32Array;
74
+ z: Float32Array;
75
+ };
76
+ /**
77
+ * Get the raw density field
78
+ */
79
+ getDensityField(): Float32Array;
80
+ /**
81
+ * Get grid dimensions
82
+ */
83
+ getDimensions(): {
84
+ width: number;
85
+ height: number;
86
+ depth: number;
87
+ };
88
+ /**
89
+ * Clear all fields
90
+ */
91
+ clear(): void;
92
+ private velocityStep;
93
+ private densityStep;
94
+ private addSource;
95
+ private diffuse;
96
+ private advect;
97
+ private project;
98
+ private linearSolve;
99
+ private setBoundary;
100
+ private sampleField;
101
+ private indexFor;
102
+ private indexForClamped;
103
+ private swap;
104
+ }
105
+ /**
106
+ * Pensieve-specific fluid simulator with aesthetic presets
107
+ */
108
+ export declare class PensieveFluidSimulator {
109
+ private fluid;
110
+ private time;
111
+ constructor(size?: number);
112
+ /**
113
+ * Add a "memory splash" - when a particle enters the pensieve
114
+ */
115
+ addMemorySplash(position: Vector3, intensity: number): void;
116
+ /**
117
+ * Add ambient swirling motion
118
+ */
119
+ addSwirl(dt: number): void;
120
+ /**
121
+ * Step the simulation
122
+ */
123
+ step(dt: number): void;
124
+ /**
125
+ * Get velocity at a point for particle advection
126
+ */
127
+ getVelocityAt(pos: Vector3): Vector3;
128
+ /**
129
+ * Get the underlying fluid for direct access
130
+ */
131
+ getFluid(): StableFluids3D;
132
+ /**
133
+ * Clear the simulation
134
+ */
135
+ clear(): void;
136
+ }
137
+ //# sourceMappingURL=FluidSimulation3D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FluidSimulation3D.d.ts","sourceRoot":"","sources":["../../src/algorithms/FluidSimulation3D.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,WAAW,aAAa;IAC5B,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,iFAAiF;IACjF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,UAAU,CAAS;IAG3B,OAAO,CAAC,OAAO,CAAe;IAC9B,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAe;IAGhC,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,UAAU,CAAe;gBAErB,MAAM,EAAE,aAAa;IAqBjC;;OAEG;IACH,UAAU,CACR,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,IAAI;IA0BP;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA4B5D;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAQtB;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAQpC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM;IAIlC;;OAEG;IACH,iBAAiB,IAAI;QAAE,CAAC,EAAE,YAAY,CAAC;QAAC,CAAC,EAAE,YAAY,CAAC;QAAC,CAAC,EAAE,YAAY,CAAA;KAAE;IAI1E;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;OAEG;IACH,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAIjE;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,YAAY;IAmEpB,OAAO,CAAC,WAAW;IAqBnB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,MAAM;IAqCd,OAAO,CAAC,OAAO;IA4Df,OAAO,CAAC,WAAW;IA+BnB,OAAO,CAAC,WAAW;IA8EnB,OAAO,CAAC,WAAW;IAyCnB,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,IAAI;CAMb;AAED;;GAEG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,IAAI,CAAa;gBAEb,IAAI,GAAE,MAAW;IAW7B;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAY3D;;OAEG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAiB1B;;OAEG;IACH,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKtB;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO;IAIpC;;OAEG;IACH,QAAQ,IAAI,cAAc;IAI1B;;OAEG;IACH,KAAK,IAAI,IAAI;CAId"}