@holoscript/engine 6.0.3 → 6.0.4

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 (192) hide show
  1. package/dist/AutoMesher-CK47F6AV.js +17 -0
  2. package/dist/GPUBuffers-2LHBCD7X.js +9 -0
  3. package/dist/WebGPUContext-TNEUYU2Y.js +11 -0
  4. package/dist/animation/index.cjs +38 -38
  5. package/dist/animation/index.d.cts +1 -1
  6. package/dist/animation/index.d.ts +1 -1
  7. package/dist/animation/index.js +1 -1
  8. package/dist/audio/index.cjs +16 -6
  9. package/dist/audio/index.d.cts +1 -1
  10. package/dist/audio/index.d.ts +1 -1
  11. package/dist/audio/index.js +1 -1
  12. package/dist/camera/index.cjs +23 -23
  13. package/dist/camera/index.d.cts +1 -1
  14. package/dist/camera/index.d.ts +1 -1
  15. package/dist/camera/index.js +1 -1
  16. package/dist/character/index.cjs +6 -4
  17. package/dist/character/index.js +1 -1
  18. package/dist/choreography/index.cjs +1194 -0
  19. package/dist/choreography/index.d.cts +687 -0
  20. package/dist/choreography/index.d.ts +687 -0
  21. package/dist/choreography/index.js +1156 -0
  22. package/dist/chunk-2CSNRI2N.js +217 -0
  23. package/dist/chunk-33T2WINR.js +266 -0
  24. package/dist/chunk-35R73OFM.js +1257 -0
  25. package/dist/chunk-4MMDSUNP.js +1256 -0
  26. package/dist/chunk-5V6HOU72.js +319 -0
  27. package/dist/chunk-6QOP6PYF.js +1038 -0
  28. package/dist/chunk-7KMJVHIL.js +8944 -0
  29. package/dist/chunk-7VPUC62U.js +1106 -0
  30. package/dist/chunk-A2Y6RCAT.js +1878 -0
  31. package/dist/chunk-AHM42MK6.js +8944 -0
  32. package/dist/chunk-BL7IDTHE.js +218 -0
  33. package/dist/chunk-CITOMSWL.js +10462 -0
  34. package/dist/chunk-CXDPKW2K.js +8944 -0
  35. package/dist/chunk-CXZPLD4S.js +223 -0
  36. package/dist/chunk-CZYJE7IH.js +5169 -0
  37. package/dist/chunk-D2OP7YC7.js +6325 -0
  38. package/dist/chunk-EDRVQHUU.js +1544 -0
  39. package/dist/chunk-EJSLOOW2.js +3589 -0
  40. package/dist/chunk-F53SFGW5.js +1878 -0
  41. package/dist/chunk-HCFPELPY.js +919 -0
  42. package/dist/chunk-HNEE36PY.js +93 -0
  43. package/dist/chunk-HYXNV36F.js +1256 -0
  44. package/dist/chunk-IB7KHVFY.js +821 -0
  45. package/dist/chunk-IBBO7YYG.js +690 -0
  46. package/dist/chunk-ILIBGINU.js +5470 -0
  47. package/dist/chunk-IS4MHLKN.js +5479 -0
  48. package/dist/chunk-JT2PFKWD.js +5479 -0
  49. package/dist/chunk-K4CUB4NY.js +1038 -0
  50. package/dist/chunk-KATDQXRJ.js +10462 -0
  51. package/dist/chunk-KBQE6ZFJ.js +8944 -0
  52. package/dist/chunk-KBVD5K7E.js +560 -0
  53. package/dist/chunk-KCDPVQRY.js +4088 -0
  54. package/dist/chunk-KN4QJPKN.js +8944 -0
  55. package/dist/chunk-KWJ3ROSI.js +8944 -0
  56. package/dist/chunk-L45VF6DD.js +919 -0
  57. package/dist/chunk-LY4T37YK.js +307 -0
  58. package/dist/chunk-MDN5WZXA.js +1544 -0
  59. package/dist/chunk-MGCDP6VU.js +928 -0
  60. package/dist/chunk-NCX7X6G2.js +8681 -0
  61. package/dist/chunk-OF54BPVD.js +913 -0
  62. package/dist/chunk-OWSN2Q3Q.js +690 -0
  63. package/dist/chunk-PRRB5TTA.js +406 -0
  64. package/dist/chunk-PXWVQF76.js +4086 -0
  65. package/dist/chunk-PYCOIDT2.js +812 -0
  66. package/dist/chunk-PZCSADOV.js +928 -0
  67. package/dist/chunk-Q2XBVS2K.js +1038 -0
  68. package/dist/chunk-QDZRXWN5.js +1776 -0
  69. package/dist/chunk-RNWOZ6WQ.js +913 -0
  70. package/dist/chunk-ROLFT4CJ.js +1693 -0
  71. package/dist/chunk-SLTJRZ2N.js +266 -0
  72. package/dist/chunk-SRUS5XSU.js +4088 -0
  73. package/dist/chunk-TKCA3WZ5.js +5409 -0
  74. package/dist/chunk-TNRMXYI2.js +1650 -0
  75. package/dist/chunk-TQB3GJGM.js +9763 -0
  76. package/dist/chunk-TUFGXG6K.js +510 -0
  77. package/dist/chunk-U6KMTGQJ.js +632 -0
  78. package/dist/chunk-VMGJQST6.js +8681 -0
  79. package/dist/chunk-X4F4TCG4.js +5470 -0
  80. package/dist/chunk-ZIFROE75.js +1544 -0
  81. package/dist/chunk-ZIJQYHSQ.js +1204 -0
  82. package/dist/combat/index.cjs +4 -4
  83. package/dist/combat/index.d.cts +1 -1
  84. package/dist/combat/index.d.ts +1 -1
  85. package/dist/combat/index.js +1 -1
  86. package/dist/ecs/index.cjs +1 -1
  87. package/dist/ecs/index.js +1 -1
  88. package/dist/environment/index.cjs +14 -14
  89. package/dist/environment/index.d.cts +1 -1
  90. package/dist/environment/index.d.ts +1 -1
  91. package/dist/environment/index.js +1 -1
  92. package/dist/gpu/index.cjs +4810 -0
  93. package/dist/gpu/index.js +3714 -0
  94. package/dist/hologram/index.cjs +27 -1
  95. package/dist/hologram/index.js +1 -1
  96. package/dist/index-B2PIsAmR.d.cts +2180 -0
  97. package/dist/index-B2PIsAmR.d.ts +2180 -0
  98. package/dist/index-BHySEPX7.d.cts +2921 -0
  99. package/dist/index-BJV21zuy.d.cts +341 -0
  100. package/dist/index-BJV21zuy.d.ts +341 -0
  101. package/dist/index-BQutTphC.d.cts +790 -0
  102. package/dist/index-ByIq2XrS.d.cts +3910 -0
  103. package/dist/index-BysHjDSO.d.cts +224 -0
  104. package/dist/index-BysHjDSO.d.ts +224 -0
  105. package/dist/index-CKwAJGck.d.ts +455 -0
  106. package/dist/index-CUl3QstQ.d.cts +3006 -0
  107. package/dist/index-CUl3QstQ.d.ts +3006 -0
  108. package/dist/index-CmYtNiI-.d.cts +953 -0
  109. package/dist/index-CmYtNiI-.d.ts +953 -0
  110. package/dist/index-CnRzWxi_.d.cts +522 -0
  111. package/dist/index-CnRzWxi_.d.ts +522 -0
  112. package/dist/index-CwRWbSC7.d.ts +2921 -0
  113. package/dist/index-CxKIBstO.d.ts +790 -0
  114. package/dist/index-DJ6-R8vh.d.cts +455 -0
  115. package/dist/index-DQKisbcI.d.cts +4968 -0
  116. package/dist/index-DQKisbcI.d.ts +4968 -0
  117. package/dist/index-DRT2zJez.d.ts +3910 -0
  118. package/dist/index-DfNLiAka.d.cts +192 -0
  119. package/dist/index-DfNLiAka.d.ts +192 -0
  120. package/dist/index-nMvkoRm8.d.cts +405 -0
  121. package/dist/index-nMvkoRm8.d.ts +405 -0
  122. package/dist/index-s9yOFU37.d.cts +604 -0
  123. package/dist/index-s9yOFU37.d.ts +604 -0
  124. package/dist/index.cjs +22966 -6960
  125. package/dist/index.d.cts +864 -20
  126. package/dist/index.d.ts +864 -20
  127. package/dist/index.js +3062 -48
  128. package/dist/input/index.cjs +1 -1
  129. package/dist/input/index.js +1 -1
  130. package/dist/orbital/index.cjs +3 -3
  131. package/dist/orbital/index.d.cts +1 -1
  132. package/dist/orbital/index.d.ts +1 -1
  133. package/dist/orbital/index.js +1 -1
  134. package/dist/particles/index.cjs +16 -16
  135. package/dist/particles/index.d.cts +1 -1
  136. package/dist/particles/index.d.ts +1 -1
  137. package/dist/particles/index.js +1 -1
  138. package/dist/physics/index.cjs +2377 -21
  139. package/dist/physics/index.d.cts +1 -1
  140. package/dist/physics/index.d.ts +1 -1
  141. package/dist/physics/index.js +35 -1
  142. package/dist/postfx/index.cjs +3491 -0
  143. package/dist/postfx/index.js +93 -0
  144. package/dist/procedural/index.cjs +1 -1
  145. package/dist/procedural/index.js +1 -1
  146. package/dist/puppeteer-5VF6KDVO.js +52197 -0
  147. package/dist/puppeteer-IZVZ3SG4.js +52197 -0
  148. package/dist/rendering/index.cjs +33 -32
  149. package/dist/rendering/index.d.cts +1 -1
  150. package/dist/rendering/index.d.ts +1 -1
  151. package/dist/rendering/index.js +8 -6
  152. package/dist/runtime/index.cjs +23 -13
  153. package/dist/runtime/index.d.cts +1 -1
  154. package/dist/runtime/index.d.ts +1 -1
  155. package/dist/runtime/index.js +8 -6
  156. package/dist/runtime/protocols/index.cjs +349 -0
  157. package/dist/runtime/protocols/index.js +15 -0
  158. package/dist/scene/index.cjs +8 -8
  159. package/dist/scene/index.d.cts +1 -1
  160. package/dist/scene/index.d.ts +1 -1
  161. package/dist/scene/index.js +1 -1
  162. package/dist/shader/index.cjs +3087 -0
  163. package/dist/shader/index.js +3044 -0
  164. package/dist/simulation/index.cjs +10680 -0
  165. package/dist/simulation/index.d.cts +3 -0
  166. package/dist/simulation/index.d.ts +3 -0
  167. package/dist/simulation/index.js +307 -0
  168. package/dist/spatial/index.cjs +2443 -0
  169. package/dist/spatial/index.d.cts +1545 -0
  170. package/dist/spatial/index.d.ts +1545 -0
  171. package/dist/spatial/index.js +2400 -0
  172. package/dist/terrain/index.cjs +1 -1
  173. package/dist/terrain/index.d.cts +1 -1
  174. package/dist/terrain/index.d.ts +1 -1
  175. package/dist/terrain/index.js +1 -1
  176. package/dist/transformers.node-4NKAPD5U.js +45620 -0
  177. package/dist/vm/index.cjs +7 -8
  178. package/dist/vm/index.d.cts +1 -1
  179. package/dist/vm/index.d.ts +1 -1
  180. package/dist/vm/index.js +1 -1
  181. package/dist/vm-bridge/index.cjs +2 -2
  182. package/dist/vm-bridge/index.d.cts +2 -2
  183. package/dist/vm-bridge/index.d.ts +2 -2
  184. package/dist/vm-bridge/index.js +1 -1
  185. package/dist/vr/index.cjs +6 -6
  186. package/dist/vr/index.js +1 -1
  187. package/dist/world/index.cjs +3 -3
  188. package/dist/world/index.d.cts +1 -1
  189. package/dist/world/index.d.ts +1 -1
  190. package/dist/world/index.js +1 -1
  191. package/package.json +53 -21
  192. package/LICENSE +0 -21
@@ -0,0 +1,919 @@
1
+ import {
2
+ __export
3
+ } from "./chunk-AKLW2MUS.js";
4
+
5
+ // src/procedural/index.ts
6
+ var procedural_exports = {};
7
+ __export(procedural_exports, {
8
+ BuildingGenerator: () => BuildingGenerator,
9
+ DungeonGenerator: () => DungeonGenerator,
10
+ LSystemGenerator: () => LSystemGenerator,
11
+ NoiseGenerator: () => NoiseGenerator,
12
+ WaveFunction: () => WaveFunction
13
+ });
14
+
15
+ // src/procedural/NoiseGenerator.ts
16
+ var DEFAULT_CONFIG = {
17
+ seed: 42,
18
+ octaves: 6,
19
+ lacunarity: 2,
20
+ gain: 0.5,
21
+ scale: 0.01
22
+ };
23
+ var NoiseGenerator = class {
24
+ config;
25
+ perm;
26
+ constructor(config = {}) {
27
+ this.config = { ...DEFAULT_CONFIG, ...config };
28
+ this.perm = this.buildPermutationTable(this.config.seed);
29
+ }
30
+ // ---------------------------------------------------------------------------
31
+ // Base Noise
32
+ // ---------------------------------------------------------------------------
33
+ /**
34
+ * 2D value noise (smooth random values at integer lattice).
35
+ */
36
+ value2D(x, y) {
37
+ const ix = Math.floor(x);
38
+ const iy = Math.floor(y);
39
+ const fx = x - ix;
40
+ const fy = y - iy;
41
+ const sx = this.fade(fx);
42
+ const sy = this.fade(fy);
43
+ const n00 = this.hash2D(ix, iy);
44
+ const n10 = this.hash2D(ix + 1, iy);
45
+ const n01 = this.hash2D(ix, iy + 1);
46
+ const n11 = this.hash2D(ix + 1, iy + 1);
47
+ return this.lerp(this.lerp(n00, n10, sx), this.lerp(n01, n11, sx), sy);
48
+ }
49
+ /**
50
+ * 2D gradient noise (Perlin-like).
51
+ */
52
+ perlin2D(x, y) {
53
+ const ix = Math.floor(x);
54
+ const iy = Math.floor(y);
55
+ const fx = x - ix;
56
+ const fy = y - iy;
57
+ const u = this.fade(fx);
58
+ const v = this.fade(fy);
59
+ const g00 = this.grad2D(this.permAt(ix, iy), fx, fy);
60
+ const g10 = this.grad2D(this.permAt(ix + 1, iy), fx - 1, fy);
61
+ const g01 = this.grad2D(this.permAt(ix, iy + 1), fx, fy - 1);
62
+ const g11 = this.grad2D(this.permAt(ix + 1, iy + 1), fx - 1, fy - 1);
63
+ return this.lerp(this.lerp(g00, g10, u), this.lerp(g01, g11, u), v) * 0.5 + 0.5;
64
+ }
65
+ /**
66
+ * 3D value noise.
67
+ */
68
+ value3D(x, y, z) {
69
+ const ix = Math.floor(x);
70
+ const iy = Math.floor(y);
71
+ const iz = Math.floor(z);
72
+ const fx = x - ix;
73
+ const fy = y - iy;
74
+ const fz = z - iz;
75
+ const sx = this.fade(fx);
76
+ const sy = this.fade(fy);
77
+ const sz = this.fade(fz);
78
+ const n000 = this.hash3D(ix, iy, iz);
79
+ const n100 = this.hash3D(ix + 1, iy, iz);
80
+ const n010 = this.hash3D(ix, iy + 1, iz);
81
+ const n110 = this.hash3D(ix + 1, iy + 1, iz);
82
+ const n001 = this.hash3D(ix, iy, iz + 1);
83
+ const n101 = this.hash3D(ix + 1, iy, iz + 1);
84
+ const n011 = this.hash3D(ix, iy + 1, iz + 1);
85
+ const n111 = this.hash3D(ix + 1, iy + 1, iz + 1);
86
+ return this.lerp(
87
+ this.lerp(this.lerp(n000, n100, sx), this.lerp(n010, n110, sx), sy),
88
+ this.lerp(this.lerp(n001, n101, sx), this.lerp(n011, n111, sx), sy),
89
+ sz
90
+ );
91
+ }
92
+ /**
93
+ * Worley (cellular) noise — distance to nearest feature point.
94
+ */
95
+ worley2D(x, y, density = 1) {
96
+ let minDist = Infinity;
97
+ const ix = Math.floor(x);
98
+ const iy = Math.floor(y);
99
+ for (let dx = -1; dx <= 1; dx++) {
100
+ for (let dy = -1; dy <= 1; dy++) {
101
+ const cx = ix + dx;
102
+ const cy = iy + dy;
103
+ const hash = this.perm[(cx & 255) + this.perm[cy & 255] & 511];
104
+ const px = cx + hash / 255 * density;
105
+ const py = cy + this.perm[hash + 1 & 511] / 255 * density;
106
+ const dist = Math.sqrt((x - px) ** 2 + (y - py) ** 2);
107
+ if (dist < minDist) minDist = dist;
108
+ }
109
+ }
110
+ return Math.min(1, minDist);
111
+ }
112
+ // ---------------------------------------------------------------------------
113
+ // Fractal Noise
114
+ // ---------------------------------------------------------------------------
115
+ /**
116
+ * Fractal Brownian Motion (FBM) — layered octaves of noise.
117
+ */
118
+ fbm2D(x, y, type = "value") {
119
+ const { octaves, lacunarity, gain, scale } = this.config;
120
+ let value = 0;
121
+ let amplitude = 1;
122
+ let frequency = scale;
123
+ let maxValue = 0;
124
+ for (let i = 0; i < octaves; i++) {
125
+ const n = type === "perlin" ? this.perlin2D(x * frequency, y * frequency) : this.value2D(x * frequency, y * frequency);
126
+ value += n * amplitude;
127
+ maxValue += amplitude;
128
+ amplitude *= gain;
129
+ frequency *= lacunarity;
130
+ }
131
+ return value / maxValue;
132
+ }
133
+ /**
134
+ * Ridged multifractal noise — sharp ridges from inverted absolute values.
135
+ */
136
+ ridged2D(x, y) {
137
+ const { octaves, lacunarity, gain, scale } = this.config;
138
+ let value = 0;
139
+ let amplitude = 1;
140
+ let frequency = scale;
141
+ let weight = 1;
142
+ for (let i = 0; i < octaves; i++) {
143
+ let n = this.perlin2D(x * frequency, y * frequency);
144
+ n = 1 - Math.abs(n * 2 - 1);
145
+ n = n * n * weight;
146
+ weight = Math.min(1, n);
147
+ value += n * amplitude;
148
+ frequency *= lacunarity;
149
+ amplitude *= gain;
150
+ }
151
+ return value;
152
+ }
153
+ /**
154
+ * Domain-warped noise — distorts input coordinates for organic shapes.
155
+ */
156
+ warped2D(x, y, warpStrength = 4) {
157
+ const { scale } = this.config;
158
+ const qx = this.fbm2D(x, y);
159
+ const qy = this.fbm2D(x + 5.2, y + 1.3);
160
+ return this.fbm2D(x + qx * warpStrength / scale, y + qy * warpStrength / scale);
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // Multi-purpose Sample
164
+ // ---------------------------------------------------------------------------
165
+ /**
166
+ * Sample noise at a point using the specified type.
167
+ */
168
+ sample2D(x, y, type = "value") {
169
+ switch (type) {
170
+ case "value":
171
+ return this.fbm2D(x, y, "value");
172
+ case "perlin":
173
+ return this.fbm2D(x, y, "perlin");
174
+ case "ridged":
175
+ return this.ridged2D(x, y);
176
+ case "warped":
177
+ return this.warped2D(x, y);
178
+ case "worley":
179
+ return this.worley2D(x, y);
180
+ }
181
+ }
182
+ /**
183
+ * Generate a 2D noise map.
184
+ */
185
+ generateMap(width, height, type = "value") {
186
+ const map = new Float32Array(width * height);
187
+ for (let y = 0; y < height; y++) {
188
+ for (let x = 0; x < width; x++) {
189
+ map[y * width + x] = this.sample2D(x, y, type);
190
+ }
191
+ }
192
+ return map;
193
+ }
194
+ // ---------------------------------------------------------------------------
195
+ // Configuration
196
+ // ---------------------------------------------------------------------------
197
+ setSeed(seed) {
198
+ this.config.seed = seed;
199
+ this.perm = this.buildPermutationTable(seed);
200
+ }
201
+ setConfig(config) {
202
+ this.config = { ...this.config, ...config };
203
+ if (config.seed !== void 0) {
204
+ this.perm = this.buildPermutationTable(config.seed);
205
+ }
206
+ }
207
+ getConfig() {
208
+ return { ...this.config };
209
+ }
210
+ // ---------------------------------------------------------------------------
211
+ // Internal Utilities
212
+ // ---------------------------------------------------------------------------
213
+ fade(t) {
214
+ return t * t * t * (t * (t * 6 - 15) + 10);
215
+ }
216
+ lerp(a, b, t) {
217
+ return a + (b - a) * t;
218
+ }
219
+ hash2D(x, y) {
220
+ const idx = this.perm[x & 255] + y & 255;
221
+ return this.perm[idx] / 255;
222
+ }
223
+ hash3D(x, y, z) {
224
+ const idx = this.perm[this.perm[x & 255] + y & 255] + z & 255;
225
+ return this.perm[idx] / 255;
226
+ }
227
+ permAt(x, y) {
228
+ return this.perm[this.perm[x & 255] + y & 255];
229
+ }
230
+ grad2D(hash, x, y) {
231
+ const h = hash & 3;
232
+ switch (h) {
233
+ case 0:
234
+ return x + y;
235
+ case 1:
236
+ return -x + y;
237
+ case 2:
238
+ return x - y;
239
+ case 3:
240
+ return -x - y;
241
+ default:
242
+ return 0;
243
+ }
244
+ }
245
+ buildPermutationTable(seed) {
246
+ const table = new Uint8Array(512);
247
+ for (let i = 0; i < 256; i++) table[i] = i;
248
+ let s = seed;
249
+ for (let i = 255; i > 0; i--) {
250
+ s = s * 1103515245 + 12345 & 2147483647;
251
+ const j = s % (i + 1);
252
+ [table[i], table[j]] = [table[j], table[i]];
253
+ }
254
+ for (let i = 0; i < 256; i++) table[i + 256] = table[i];
255
+ return table;
256
+ }
257
+ };
258
+
259
+ // src/procedural/LSystemGenerator.ts
260
+ var LSystemGenerator = class {
261
+ seed;
262
+ rng;
263
+ constructor(seed = 42) {
264
+ this.seed = seed;
265
+ this.rng = this.createRng(seed);
266
+ }
267
+ // ---------------------------------------------------------------------------
268
+ // String Generation
269
+ // ---------------------------------------------------------------------------
270
+ /**
271
+ * Apply production rules to expand the axiom.
272
+ */
273
+ expand(config) {
274
+ let current = config.axiom;
275
+ for (let i = 0; i < config.iterations; i++) {
276
+ let next = "";
277
+ for (const char of current) {
278
+ const matching = config.rules.filter((r) => r.symbol === char);
279
+ if (matching.length === 0) {
280
+ next += char;
281
+ continue;
282
+ }
283
+ if (matching.length === 1 && (matching[0].probability === void 0 || matching[0].probability >= 1)) {
284
+ next += matching[0].replacement;
285
+ } else {
286
+ const roll = this.rng();
287
+ let cumulative = 0;
288
+ let chosen = matching[0].replacement;
289
+ for (const rule of matching) {
290
+ cumulative += rule.probability ?? 1;
291
+ if (roll <= cumulative) {
292
+ chosen = rule.replacement;
293
+ break;
294
+ }
295
+ }
296
+ next += chosen;
297
+ }
298
+ }
299
+ current = next;
300
+ }
301
+ return current;
302
+ }
303
+ // ---------------------------------------------------------------------------
304
+ // Turtle Interpretation
305
+ // ---------------------------------------------------------------------------
306
+ /**
307
+ * Interpret the L-system string using 3D turtle graphics.
308
+ */
309
+ interpret(lString, config) {
310
+ const segments = [];
311
+ const leaves = [];
312
+ const stack = [];
313
+ let state = {
314
+ position: [0, 0, 0],
315
+ direction: { x: 0, y: 1, z: 0 },
316
+ // Growing upward
317
+ up: { x: 0, y: 0, z: 1 },
318
+ length: config.length,
319
+ depth: 0
320
+ };
321
+ const angleRad = config.angle * Math.PI / 180;
322
+ const minBound = { x: 0, y: 0, z: 0 };
323
+ const maxBound = { x: 0, y: 0, z: 0 };
324
+ for (const char of lString) {
325
+ switch (char) {
326
+ case "F": {
327
+ const start = { ...state.position };
328
+ const end = {
329
+ x: state.position.x + state.direction.x * state.length,
330
+ y: state.position.y + state.direction.y * state.length,
331
+ z: state.position.z + state.direction.z * state.length
332
+ };
333
+ segments.push({
334
+ start,
335
+ end,
336
+ depth: state.depth,
337
+ radius: Math.max(0.02, 0.1 * Math.pow(config.lengthScale, state.depth))
338
+ });
339
+ state.position = end;
340
+ this.updateBounds(end, minBound, maxBound);
341
+ break;
342
+ }
343
+ case "+":
344
+ state.direction = this.rotateY(state.direction, angleRad);
345
+ break;
346
+ case "-":
347
+ state.direction = this.rotateY(state.direction, -angleRad);
348
+ break;
349
+ case "&":
350
+ state.direction = this.rotateX(state.direction, angleRad);
351
+ break;
352
+ case "^":
353
+ state.direction = this.rotateX(state.direction, -angleRad);
354
+ break;
355
+ case "[":
356
+ stack.push({
357
+ position: { ...state.position },
358
+ direction: { ...state.direction },
359
+ up: { ...state.up },
360
+ length: state.length * config.lengthScale,
361
+ depth: state.depth + 1
362
+ });
363
+ break;
364
+ case "]":
365
+ if (stack.length > 0) {
366
+ leaves.push({
367
+ position: { ...state.position },
368
+ normal: { ...state.direction },
369
+ size: 0.3 * Math.pow(config.lengthScale, state.depth)
370
+ });
371
+ state = stack.pop();
372
+ }
373
+ break;
374
+ case "X":
375
+ break;
376
+ }
377
+ }
378
+ return {
379
+ segments,
380
+ leaves,
381
+ boundingBox: { min: minBound, max: maxBound }
382
+ };
383
+ }
384
+ // ---------------------------------------------------------------------------
385
+ // High-Level API
386
+ // ---------------------------------------------------------------------------
387
+ /**
388
+ * Generate a complete L-system tree/plant.
389
+ */
390
+ generate(config) {
391
+ const lString = this.expand(config);
392
+ return this.interpret(lString, config);
393
+ }
394
+ // ---------------------------------------------------------------------------
395
+ // Internal Utilities
396
+ // ---------------------------------------------------------------------------
397
+ rotateY(dir, angle) {
398
+ const cos = Math.cos(angle);
399
+ const sin = Math.sin(angle);
400
+ return {
401
+ x: dir.x * cos - dir.z * sin,
402
+ y: dir.y,
403
+ z: dir.x * sin + dir.z * cos
404
+ };
405
+ }
406
+ rotateX(dir, angle) {
407
+ const cos = Math.cos(angle);
408
+ const sin = Math.sin(angle);
409
+ return {
410
+ x: dir.x,
411
+ y: dir.y * cos - dir.z * sin,
412
+ z: dir.y * sin + dir.z * cos
413
+ };
414
+ }
415
+ updateBounds(p, min, max) {
416
+ min.x = Math.min(min.x, p.x);
417
+ min.y = Math.min(min.y, p.y);
418
+ min.z = Math.min(min.z, p.z);
419
+ max.x = Math.max(max.x, p.x);
420
+ max.y = Math.max(max.y, p.y);
421
+ max.z = Math.max(max.z, p.z);
422
+ }
423
+ createRng(seed) {
424
+ let s = seed;
425
+ return () => {
426
+ s = s * 1103515245 + 12345 & 2147483647;
427
+ return s / 2147483647;
428
+ };
429
+ }
430
+ };
431
+
432
+ // src/procedural/BuildingGenerator.ts
433
+ var STYLE_PARAMS = {
434
+ residential: {
435
+ roomCountRange: [3, 6],
436
+ windowDensity: 0.6,
437
+ hasLobby: false,
438
+ roofType: "pitched",
439
+ wallThickness: 0.2
440
+ },
441
+ commercial: {
442
+ roomCountRange: [4, 10],
443
+ windowDensity: 0.8,
444
+ hasLobby: true,
445
+ roofType: "flat",
446
+ wallThickness: 0.15
447
+ },
448
+ industrial: {
449
+ roomCountRange: [1, 3],
450
+ windowDensity: 0.2,
451
+ hasLobby: false,
452
+ roofType: "flat",
453
+ wallThickness: 0.3
454
+ },
455
+ tower: {
456
+ roomCountRange: [2, 4],
457
+ windowDensity: 0.9,
458
+ hasLobby: true,
459
+ roofType: "flat",
460
+ wallThickness: 0.2
461
+ },
462
+ warehouse: {
463
+ roomCountRange: [1, 2],
464
+ windowDensity: 0.1,
465
+ hasLobby: false,
466
+ roofType: "pitched",
467
+ wallThickness: 0.25
468
+ }
469
+ };
470
+ var BuildingGenerator = class {
471
+ rng;
472
+ constructor(seed = 42) {
473
+ this.rng = this.createRng(seed);
474
+ }
475
+ // ---------------------------------------------------------------------------
476
+ // Generation
477
+ // ---------------------------------------------------------------------------
478
+ generate(config) {
479
+ this.rng = this.createRng(config.seed);
480
+ const style = STYLE_PARAMS[config.style];
481
+ const floorPlans = [];
482
+ for (let floor = 0; floor < config.floors; floor++) {
483
+ const plan = this.generateFloor(config, floor, style);
484
+ floorPlans.push(plan);
485
+ }
486
+ const meshData = this.generateMesh(config, floorPlans);
487
+ const halfW = config.footprint.width / 2;
488
+ const halfD = config.footprint.depth / 2;
489
+ return {
490
+ config,
491
+ floorPlans,
492
+ meshData,
493
+ boundingBox: {
494
+ min: { x: -halfW, y: 0, z: -halfD },
495
+ max: { x: halfW, y: config.floors * config.floorHeight, z: halfD }
496
+ }
497
+ };
498
+ }
499
+ // ---------------------------------------------------------------------------
500
+ // Floor Plan Generation
501
+ // ---------------------------------------------------------------------------
502
+ generateFloor(config, floorIndex, style) {
503
+ const rooms = [];
504
+ const walls = [];
505
+ const openings = [];
506
+ const w = config.footprint.width;
507
+ const d = config.footprint.depth;
508
+ const h = config.floorHeight;
509
+ if (floorIndex === 0 && style.hasLobby) {
510
+ rooms.push({
511
+ id: `lobby_${floorIndex}`,
512
+ type: "lobby",
513
+ bounds: { x: 0, z: 0, width: w, depth: d * 0.3 },
514
+ height: h
515
+ });
516
+ }
517
+ const roomCount = style.roomCountRange[0] + Math.floor(this.rng() * (style.roomCountRange[1] - style.roomCountRange[0] + 1));
518
+ const cols = Math.ceil(Math.sqrt(roomCount));
519
+ const rows = Math.ceil(roomCount / cols);
520
+ const roomW = w / cols;
521
+ const roomD = d / rows;
522
+ for (let r = 0; r < rows; r++) {
523
+ for (let c = 0; c < cols; c++) {
524
+ if (rooms.length >= roomCount) break;
525
+ const jitterX = (this.rng() - 0.5) * roomW * 0.1;
526
+ const jitterZ = (this.rng() - 0.5) * roomD * 0.1;
527
+ rooms.push({
528
+ id: `room_${floorIndex}_${r}_${c}`,
529
+ type: "room",
530
+ bounds: {
531
+ x: c * roomW + jitterX,
532
+ z: r * roomD + jitterZ,
533
+ width: roomW,
534
+ depth: roomD
535
+ },
536
+ height: h
537
+ });
538
+ }
539
+ }
540
+ rooms.push({
541
+ id: `stairwell_${floorIndex}`,
542
+ type: "stairwell",
543
+ bounds: { x: w - 2, z: d - 2, width: 2, depth: 2 },
544
+ height: h
545
+ });
546
+ const wallThick = style.wallThickness;
547
+ const _baseY = floorIndex * h;
548
+ walls.push({
549
+ start: { x: 0, z: 0 },
550
+ end: { x: w, z: 0 },
551
+ height: h,
552
+ thickness: wallThick,
553
+ isExterior: true
554
+ });
555
+ walls.push({
556
+ start: { x: 0, z: d },
557
+ end: { x: w, z: d },
558
+ height: h,
559
+ thickness: wallThick,
560
+ isExterior: true
561
+ });
562
+ walls.push({
563
+ start: { x: 0, z: 0 },
564
+ end: { x: 0, z: d },
565
+ height: h,
566
+ thickness: wallThick,
567
+ isExterior: true
568
+ });
569
+ walls.push({
570
+ start: { x: w, z: 0 },
571
+ end: { x: w, z: d },
572
+ height: h,
573
+ thickness: wallThick,
574
+ isExterior: true
575
+ });
576
+ for (let wi = 0; wi < walls.length; wi++) {
577
+ const wall = walls[wi];
578
+ if (!wall.isExterior) continue;
579
+ const wallLen = Math.sqrt(
580
+ Math.pow(wall.end.x - wall.start.x, 2) + Math.pow(wall.end.z - wall.start.z, 2)
581
+ );
582
+ const windowCount = Math.floor(wallLen * style.windowDensity);
583
+ for (let wn = 0; wn < windowCount; wn++) {
584
+ openings.push({
585
+ type: "window",
586
+ wall: wi,
587
+ position: (wn + 0.5) / windowCount,
588
+ width: 1,
589
+ height: 1.2,
590
+ sillHeight: 0.9
591
+ });
592
+ }
593
+ }
594
+ if (floorIndex === 0) {
595
+ openings.push({
596
+ type: "door",
597
+ wall: 0,
598
+ position: 0.5,
599
+ width: 1.2,
600
+ height: 2.2
601
+ });
602
+ }
603
+ return { floor: floorIndex, rooms, walls, openings };
604
+ }
605
+ // ---------------------------------------------------------------------------
606
+ // Mesh Generation (simplified box geometry)
607
+ // ---------------------------------------------------------------------------
608
+ generateMesh(config, _floorPlans) {
609
+ const vertices = [];
610
+ const faces = [];
611
+ const w = config.footprint.width;
612
+ const d = config.footprint.depth;
613
+ const h = config.floors * config.floorHeight;
614
+ const hw = w / 2;
615
+ const hd = d / 2;
616
+ const base = vertices.length;
617
+ vertices.push(
618
+ { x: -hw, y: 0, z: -hd },
619
+ // 0: bottom-front-left
620
+ { x: hw, y: 0, z: -hd },
621
+ // 1: bottom-front-right
622
+ { x: hw, y: 0, z: hd },
623
+ // 2: bottom-back-right
624
+ { x: -hw, y: 0, z: hd },
625
+ // 3: bottom-back-left
626
+ { x: -hw, y: h, z: -hd },
627
+ // 4: top-front-left
628
+ { x: hw, y: h, z: -hd },
629
+ // 5: top-front-right
630
+ { x: hw, y: h, z: hd },
631
+ // 6: top-back-right
632
+ { x: -hw, y: h, z: hd }
633
+ // 7: top-back-left
634
+ );
635
+ faces.push(base + 0, base + 1, base + 5, base + 0, base + 5, base + 4);
636
+ faces.push(base + 2, base + 3, base + 7, base + 2, base + 7, base + 6);
637
+ faces.push(base + 3, base + 0, base + 4, base + 3, base + 4, base + 7);
638
+ faces.push(base + 1, base + 2, base + 6, base + 1, base + 6, base + 5);
639
+ faces.push(base + 4, base + 5, base + 6, base + 4, base + 6, base + 7);
640
+ faces.push(base + 0, base + 3, base + 2, base + 0, base + 2, base + 1);
641
+ return { vertices, faces };
642
+ }
643
+ // ---------------------------------------------------------------------------
644
+ // Internal
645
+ // ---------------------------------------------------------------------------
646
+ createRng(seed) {
647
+ let s = seed;
648
+ return () => {
649
+ s = s * 1103515245 + 12345 & 2147483647;
650
+ return s / 2147483647;
651
+ };
652
+ }
653
+ };
654
+
655
+ // src/procedural/DungeonGenerator.ts
656
+ var DungeonGenerator = class {
657
+ config;
658
+ rooms = [];
659
+ corridors = [];
660
+ nextRoomId = 0;
661
+ rng;
662
+ constructor(config) {
663
+ this.config = {
664
+ width: config?.width ?? 64,
665
+ height: config?.height ?? 64,
666
+ minRoomSize: config?.minRoomSize ?? 4,
667
+ maxRoomSize: config?.maxRoomSize ?? 12,
668
+ maxRooms: config?.maxRooms ?? 15,
669
+ corridorWidth: config?.corridorWidth ?? 1,
670
+ seed: config?.seed ?? 42
671
+ };
672
+ let s = this.config.seed;
673
+ this.rng = () => {
674
+ s = s * 16807 % 2147483647;
675
+ return (s - 1) / 2147483646;
676
+ };
677
+ }
678
+ /**
679
+ * Generate a full dungeon
680
+ */
681
+ generate() {
682
+ this.rooms = [];
683
+ this.corridors = [];
684
+ this.nextRoomId = 0;
685
+ for (let i = 0; i < this.config.maxRooms * 3; i++) {
686
+ if (this.rooms.length >= this.config.maxRooms) break;
687
+ const w = this.randInt(this.config.minRoomSize, this.config.maxRoomSize);
688
+ const h = this.randInt(this.config.minRoomSize, this.config.maxRoomSize);
689
+ const x = this.randInt(1, this.config.width - w - 1);
690
+ const y = this.randInt(1, this.config.height - h - 1);
691
+ if (!this.overlaps(x, y, w, h)) {
692
+ this.rooms.push({ id: this.nextRoomId++, x, y, width: w, height: h, connected: [] });
693
+ }
694
+ }
695
+ for (let i = 1; i < this.rooms.length; i++) {
696
+ this.connectRooms(this.rooms[i - 1], this.rooms[i]);
697
+ }
698
+ return { rooms: [...this.rooms], corridors: [...this.corridors] };
699
+ }
700
+ overlaps(x, y, w, h) {
701
+ for (const room of this.rooms) {
702
+ if (x < room.x + room.width + 1 && x + w + 1 > room.x && y < room.y + room.height + 1 && y + h + 1 > room.y)
703
+ return true;
704
+ }
705
+ return false;
706
+ }
707
+ connectRooms(a, b) {
708
+ const ax = Math.floor(a.x + a.width / 2);
709
+ const ay = Math.floor(a.y + a.height / 2);
710
+ const bx = Math.floor(b.x + b.width / 2);
711
+ const by = Math.floor(b.y + b.height / 2);
712
+ const points = [];
713
+ if (this.rng() > 0.5) {
714
+ for (let x = Math.min(ax, bx); x <= Math.max(ax, bx); x++) points.push({ x, y: ay });
715
+ for (let y = Math.min(ay, by); y <= Math.max(ay, by); y++) points.push({ x: bx, y });
716
+ } else {
717
+ for (let y = Math.min(ay, by); y <= Math.max(ay, by); y++) points.push({ x: ax, y });
718
+ for (let x = Math.min(ax, bx); x <= Math.max(ax, bx); x++) points.push({ x, y: by });
719
+ }
720
+ a.connected.push(b.id);
721
+ b.connected.push(a.id);
722
+ this.corridors.push({ from: a.id, to: b.id, points });
723
+ }
724
+ randInt(min, max) {
725
+ return Math.floor(this.rng() * (max - min + 1)) + min;
726
+ }
727
+ /**
728
+ * Check if all rooms are connected
729
+ */
730
+ isFullyConnected() {
731
+ if (this.rooms.length === 0) return true;
732
+ const visited = /* @__PURE__ */ new Set();
733
+ const queue = [this.rooms[0].id];
734
+ visited.add(this.rooms[0].id);
735
+ while (queue.length > 0) {
736
+ const current = queue.shift();
737
+ const room = this.rooms.find((r) => r.id === current);
738
+ for (const neighbor of room.connected) {
739
+ if (!visited.has(neighbor)) {
740
+ visited.add(neighbor);
741
+ queue.push(neighbor);
742
+ }
743
+ }
744
+ }
745
+ return visited.size === this.rooms.length;
746
+ }
747
+ getRooms() {
748
+ return [...this.rooms];
749
+ }
750
+ getCorridors() {
751
+ return [...this.corridors];
752
+ }
753
+ getRoomCount() {
754
+ return this.rooms.length;
755
+ }
756
+ };
757
+
758
+ // src/procedural/WaveFunction.ts
759
+ var WaveFunction = class {
760
+ tiles = /* @__PURE__ */ new Map();
761
+ grid = [];
762
+ width;
763
+ height;
764
+ rng;
765
+ contradictions = 0;
766
+ constructor(width, height, seed = 42) {
767
+ this.width = width;
768
+ this.height = height;
769
+ let s = seed;
770
+ this.rng = () => {
771
+ s = s * 16807 % 2147483647;
772
+ return (s - 1) / 2147483646;
773
+ };
774
+ }
775
+ /**
776
+ * Register a tile type
777
+ */
778
+ addTile(tile) {
779
+ this.tiles.set(tile.id, tile);
780
+ }
781
+ /**
782
+ * Initialize the grid with all options
783
+ */
784
+ initialize() {
785
+ const allIds = [...this.tiles.keys()];
786
+ this.grid = [];
787
+ for (let y = 0; y < this.height; y++) {
788
+ this.grid[y] = [];
789
+ for (let x = 0; x < this.width; x++) {
790
+ this.grid[y][x] = { x, y, collapsed: false, tileId: null, options: [...allIds] };
791
+ }
792
+ }
793
+ this.contradictions = 0;
794
+ }
795
+ /**
796
+ * Get the cell with lowest entropy (fewest options)
797
+ */
798
+ getLowestEntropy() {
799
+ let minEntropy = Infinity;
800
+ const candidates = [];
801
+ for (const row of this.grid) {
802
+ for (const cell of row) {
803
+ if (cell.collapsed) continue;
804
+ if (cell.options.length < minEntropy) {
805
+ minEntropy = cell.options.length;
806
+ candidates.length = 0;
807
+ candidates.push(cell);
808
+ } else if (cell.options.length === minEntropy) {
809
+ candidates.push(cell);
810
+ }
811
+ }
812
+ }
813
+ if (candidates.length === 0) return null;
814
+ return candidates[Math.floor(this.rng() * candidates.length)];
815
+ }
816
+ /**
817
+ * Collapse a cell to a single tile
818
+ */
819
+ collapse(cell) {
820
+ if (cell.options.length === 0) {
821
+ this.contradictions++;
822
+ return false;
823
+ }
824
+ let totalWeight = 0;
825
+ for (const tileId of cell.options) {
826
+ totalWeight += this.tiles.get(tileId)?.weight ?? 1;
827
+ }
828
+ let rand = this.rng() * totalWeight;
829
+ for (const tileId of cell.options) {
830
+ rand -= this.tiles.get(tileId)?.weight ?? 1;
831
+ if (rand <= 0) {
832
+ cell.tileId = tileId;
833
+ cell.options = [tileId];
834
+ cell.collapsed = true;
835
+ return true;
836
+ }
837
+ }
838
+ cell.tileId = cell.options[0];
839
+ cell.options = [cell.tileId];
840
+ cell.collapsed = true;
841
+ return true;
842
+ }
843
+ /**
844
+ * Propagate constraints from a collapsed cell
845
+ */
846
+ propagate(cell) {
847
+ const stack = [cell];
848
+ while (stack.length > 0) {
849
+ const current = stack.pop();
850
+ const neighbors = this.getNeighbors(current.x, current.y);
851
+ for (const [dir, neighbor] of neighbors) {
852
+ if (neighbor.collapsed) continue;
853
+ const validOptions = /* @__PURE__ */ new Set();
854
+ for (const optionId of current.options) {
855
+ const tile = this.tiles.get(optionId);
856
+ if (tile) {
857
+ const allowed = tile.adjacency[dir];
858
+ for (const a of allowed) validOptions.add(a);
859
+ }
860
+ }
861
+ const before = neighbor.options.length;
862
+ neighbor.options = neighbor.options.filter((o) => validOptions.has(o));
863
+ if (neighbor.options.length < before) {
864
+ stack.push(neighbor);
865
+ }
866
+ }
867
+ }
868
+ }
869
+ /**
870
+ * Solve the entire grid
871
+ */
872
+ solve(maxIterations = 1e4) {
873
+ this.initialize();
874
+ let iterations = 0;
875
+ while (iterations < maxIterations) {
876
+ const cell = this.getLowestEntropy();
877
+ if (!cell) return true;
878
+ if (!this.collapse(cell)) return false;
879
+ this.propagate(cell);
880
+ iterations++;
881
+ }
882
+ return false;
883
+ }
884
+ getNeighbors(x, y) {
885
+ const result = [];
886
+ if (y > 0) result.push(["up", this.grid[y - 1][x]]);
887
+ if (y < this.height - 1) result.push(["down", this.grid[y + 1][x]]);
888
+ if (x > 0) result.push(["left", this.grid[y][x - 1]]);
889
+ if (x < this.width - 1) result.push(["right", this.grid[y][x + 1]]);
890
+ return result;
891
+ }
892
+ getCell(x, y) {
893
+ return this.grid[y]?.[x];
894
+ }
895
+ getGrid() {
896
+ return this.grid.map((row) => row.map((c) => ({ ...c })));
897
+ }
898
+ isComplete() {
899
+ return this.grid.every((row) => row.every((c) => c.collapsed));
900
+ }
901
+ getContradictions() {
902
+ return this.contradictions;
903
+ }
904
+ getWidth() {
905
+ return this.width;
906
+ }
907
+ getHeight() {
908
+ return this.height;
909
+ }
910
+ };
911
+
912
+ export {
913
+ NoiseGenerator,
914
+ LSystemGenerator,
915
+ BuildingGenerator,
916
+ DungeonGenerator,
917
+ WaveFunction,
918
+ procedural_exports
919
+ };