@carbonenginejs/runtime-utils 0.1.1 → 0.1.3

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 (104) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +23 -23
  3. package/README.md +69 -69
  4. package/THIRD-PARTY-NOTICES.md +64 -64
  5. package/docs/README.md +74 -73
  6. package/docs/architecture.md +101 -101
  7. package/docs/concepts/foundation-consolidation.md +85 -85
  8. package/docs/concepts/model-lifecycle.md +111 -0
  9. package/docs/const-kb.md +85 -87
  10. package/docs/core-types/DECORATOR-TODOS.md +25 -25
  11. package/docs/core-types/README.md +229 -168
  12. package/docs/reference/api.md +105 -102
  13. package/docs/reference/classes/README.md +135 -135
  14. package/package.json +139 -139
  15. package/src/arrays.js +5 -5
  16. package/src/audio/audioFormats.js +34 -34
  17. package/src/audio/index.js +1 -1
  18. package/src/box3.js +331 -331
  19. package/src/bytes.js +56 -56
  20. package/src/compression.js +56 -56
  21. package/src/constants/index.js +7 -7
  22. package/src/constants/trinity.js +13 -13
  23. package/src/constants.js +15 -15
  24. package/src/curve.js +79 -79
  25. package/src/d3d/dxgiFormats.js +46 -46
  26. package/src/d3d/index.js +2 -2
  27. package/src/d3d/primitiveTopology.js +11 -11
  28. package/src/document/CjsCarbonDocument.js +212 -212
  29. package/src/document/CjsClassRegistry.js +373 -373
  30. package/src/document/CjsDocumentDehydrator.js +142 -142
  31. package/src/document/CjsDocumentHydrator.js +156 -156
  32. package/src/document/CjsStructRegistry.js +348 -348
  33. package/src/document/hydrationAdapter.js +129 -129
  34. package/src/document/index.js +6 -6
  35. package/src/errors/CjsError.js +286 -286
  36. package/src/errors/index.js +5 -5
  37. package/src/geometry/box.js +22 -22
  38. package/src/geometry/cylinder.js +22 -22
  39. package/src/geometry/helpers/earcut.js +1 -1
  40. package/src/geometry/helpers/misc.js +3 -3
  41. package/src/geometry/index.js +8 -8
  42. package/src/geometry/json.js +67 -67
  43. package/src/geometry/lathe.js +44 -44
  44. package/src/geometry/plane.js +14 -14
  45. package/src/geometry/shape.js +4 -4
  46. package/src/geometry/sphere.js +24 -24
  47. package/src/geometry/torus.js +14 -14
  48. package/src/graphics/colorSpaces.js +22 -22
  49. package/src/graphics/index.js +4 -4
  50. package/src/graphics/pixelFormats.js +158 -158
  51. package/src/graphics/textureDimensions.js +22 -22
  52. package/src/graphics/trinityEnums.js +87 -87
  53. package/src/index.js +62 -62
  54. package/src/is.js +108 -46
  55. package/src/json.js +23 -23
  56. package/src/lifecycle/CjsLifecycleState.js +77 -77
  57. package/src/lifecycle/index.js +1 -1
  58. package/src/lne3.js +70 -70
  59. package/src/lookup.js +48 -48
  60. package/src/mat3.js +51 -51
  61. package/src/mat4.js +699 -699
  62. package/src/math/index.js +25 -25
  63. package/src/math/scalar.js +63 -63
  64. package/src/media/index.js +1 -1
  65. package/src/media/mediaTypes.js +50 -50
  66. package/src/mesh.js +424 -424
  67. package/src/model/CjsEventEmitter.js +333 -333
  68. package/src/model/CjsModel.js +1589 -1544
  69. package/src/model/CjsModelState.js +72 -72
  70. package/src/model/index.js +4 -4
  71. package/src/model/sourceRecordUtils.js +54 -54
  72. package/src/noise.js +310 -310
  73. package/src/num.js +827 -827
  74. package/src/object.js +39 -39
  75. package/src/path.js +53 -53
  76. package/src/pln.js +125 -125
  77. package/src/pool.js +9 -9
  78. package/src/quat.js +144 -144
  79. package/src/ray3.js +188 -188
  80. package/src/renderContext/formats.js +145 -145
  81. package/src/renderContext/index.js +5 -5
  82. package/src/renderContext/presentation.js +125 -125
  83. package/src/renderContext/resources.js +27 -27
  84. package/src/renderContext/upscaling.js +22 -22
  85. package/src/renderContext/window.js +20 -20
  86. package/src/runtime/CjsRuntimeState.js +50 -50
  87. package/src/schema/CjsSchema.js +555 -318
  88. package/src/schema/index.js +4 -4
  89. package/src/shader/index.js +1 -1
  90. package/src/shader/shaderStages.js +37 -37
  91. package/src/sph3.js +181 -181
  92. package/src/tangent.js +288 -288
  93. package/src/text.js +40 -40
  94. package/src/tri3.js +98 -98
  95. package/src/types/carbonTypes.js +635 -635
  96. package/src/types/index.js +2 -2
  97. package/src/utils.js +58 -58
  98. package/src/validation.js +46 -46
  99. package/src/vec2.js +229 -229
  100. package/src/vec3.js +1188 -1172
  101. package/src/vec4.js +347 -347
  102. package/src/vertex.js +108 -108
  103. package/src/webgpu/index.js +1 -1
  104. package/src/webgpu/textureFormats.js +121 -121
package/src/noise.js CHANGED
@@ -1,310 +1,310 @@
1
- import { vec3 } from "./vec3.js";
2
- import { vec4 } from "./vec4.js";
3
-
4
- export const noise = {};
5
-
6
- /**
7
- * Generates turbulent noise
8
- *
9
- * @param {vec4} out
10
- * @param {number} pos_0
11
- * @param {number} pos_1
12
- * @param {number} pos_2
13
- * @param {number} pos_3
14
- * @param {number} power
15
- * @returns {vec4} out
16
- */
17
- noise.turbulence = (function()
18
- {
19
- const
20
- s_noiseLookup = [],
21
- s_permutations = [],
22
- s_globalNoiseTemps = [];
23
-
24
- let s_initialized = false;
25
-
26
- /**
27
- * Initializes noise
28
- */
29
- function initialize()
30
- {
31
- for (let i = 0; i < 256; i++)
32
- {
33
- s_noiseLookup[i] = vec4.fromValues(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
34
- s_permutations[i] = i;
35
- }
36
-
37
- let i = 256;
38
- while (--i)
39
- {
40
- const
41
- tmp = s_permutations[i],
42
- index = Math.floor(Math.random() * 256);
43
-
44
- s_permutations[i] = s_permutations[index];
45
- s_permutations[index] = tmp;
46
- }
47
-
48
- for (let i = 0; i < 256; i++)
49
- {
50
- s_permutations[256 + i] = s_permutations[i];
51
- s_noiseLookup[256 + i] = s_noiseLookup[i];
52
- s_noiseLookup[256 * 2 + i] = s_noiseLookup[i];
53
- }
54
-
55
- for (let i = 0; i < 15; ++i)
56
- {
57
- s_globalNoiseTemps[i] = vec3.create();
58
- }
59
-
60
- s_initialized = true;
61
- }
62
-
63
- return function turbulence(out, pos_0, pos_1, pos_2, pos_3, power)
64
- {
65
- if (!s_initialized) initialize();
66
-
67
- pos_0 += 4096;
68
- pos_1 += 4096;
69
- pos_2 += 4096;
70
- pos_3 += 4096;
71
-
72
- let a_0 = Math.floor(pos_0),
73
- a_1 = Math.floor(pos_1),
74
- a_2 = Math.floor(pos_2),
75
- a_3 = Math.floor(pos_3);
76
-
77
- const
78
- t_0 = pos_0 - a_0,
79
- t_1 = pos_1 - a_1,
80
- t_2 = pos_2 - a_2,
81
- t_3 = pos_3 - a_3;
82
-
83
- a_0 &= 255;
84
- a_1 &= 255;
85
- a_2 &= 255;
86
- a_3 &= 255;
87
-
88
- const
89
- b_0 = a_0 + 1,
90
- b_1 = a_1 + 1,
91
- b_2 = a_2 + 1,
92
- b_3 = a_3 + 1;
93
-
94
- const
95
- i = s_permutations[a_0],
96
- j = s_permutations[b_0];
97
-
98
- const
99
- b00 = s_permutations[i + a_1],
100
- b10 = s_permutations[j + a_1],
101
- b01 = s_permutations[i + b_1],
102
- b11 = s_permutations[j + b_1];
103
-
104
- let c00 = vec3.lerp(s_globalNoiseTemps[0], s_noiseLookup[b00 + a_2 + a_3], s_noiseLookup[b10 + a_2 + a_3], t_0);
105
- let c10 = vec3.lerp(s_globalNoiseTemps[1], s_noiseLookup[b01 + a_2 + a_3], s_noiseLookup[b11 + a_2 + a_3], t_0);
106
- let c01 = vec3.lerp(s_globalNoiseTemps[2], s_noiseLookup[b00 + b_2 + a_3], s_noiseLookup[b10 + b_2 + a_3], t_0);
107
- let c11 = vec3.lerp(s_globalNoiseTemps[3], s_noiseLookup[b01 + b_2 + a_3], s_noiseLookup[b11 + b_2 + a_3], t_0); // Carbon Noise4D: b01/b11 corners (fixed 2026-07-23)
108
- let c0 = vec3.lerp(s_globalNoiseTemps[4], c00, c10, t_1);
109
- let c1 = vec3.lerp(s_globalNoiseTemps[5], c01, c11, t_1);
110
- const c = vec3.lerp(s_globalNoiseTemps[6], c0, c1, t_2);
111
-
112
- c00 = vec3.lerp(s_globalNoiseTemps[7], s_noiseLookup[b00 + a_2 + b_3], s_noiseLookup[b10 + a_2 + b_3], t_0);
113
- c10 = vec3.lerp(s_globalNoiseTemps[8], s_noiseLookup[b01 + a_2 + b_3], s_noiseLookup[b11 + a_2 + b_3], t_0);
114
- c01 = vec3.lerp(s_globalNoiseTemps[9], s_noiseLookup[b00 + b_2 + b_3], s_noiseLookup[b10 + b_2 + b_3], t_0);
115
- c11 = vec3.lerp(s_globalNoiseTemps[10], s_noiseLookup[b01 + b_2 + b_3], s_noiseLookup[b11 + b_2 + b_3], t_0); // Carbon Noise4D: b01/b11 corners (fixed 2026-07-23)
116
- c0 = vec3.lerp(s_globalNoiseTemps[11], c00, c10, t_1);
117
- c1 = vec3.lerp(s_globalNoiseTemps[12], c01, c11, t_1);
118
- const d = vec3.lerp(s_globalNoiseTemps[13], c0, c1, t_2);
119
- const r = vec3.lerp(s_globalNoiseTemps[14], c, d, t_3);
120
-
121
- out[0] += r[0] * power;
122
- out[1] += r[1] * power;
123
- out[2] += r[2] * power;
124
- return out;
125
- };
126
- })();
127
-
128
- /**
129
- * Creates Carbon's seeded one-dimensional Perlin-noise utility.
130
- *
131
- * This ports `TriPerlinNoise` from `TriMath.cpp`: gradients are generated by
132
- * `std::mt19937`, sampling uses Carbon's cubic S-curve, and the returned
133
- * object owns the native class's otherwise-private gradient table.
134
- *
135
- * @param {number} [seed]
136
- * @returns {{ sample: (x: number) => number, fractalSum: (x: number, octaves: number, amplitudeScale?: number, frequencyScale?: number) => number }}
137
- */
138
- noise.createPerlinNoise1D = function(seed = Math.floor(Math.random() * 0x100000000))
139
- {
140
- const state = new Uint32Array(624);
141
- state[0] = Number(seed) >>> 0;
142
- for (let index = 1; index < state.length; index++)
143
- {
144
- const previous = state[index - 1] ^ (state[index - 1] >>> 30);
145
- state[index] = (Math.imul(1812433253, previous) + index) >>> 0;
146
- }
147
-
148
- let cursor = state.length;
149
- const twist = () =>
150
- {
151
- for (let index = 0; index < state.length; index++)
152
- {
153
- const bits = (state[index] & 0x80000000) | (state[(index + 1) % state.length] & 0x7fffffff);
154
- state[index] = state[(index + 397) % state.length] ^ (bits >>> 1) ^ (bits & 1 ? 0x9908b0df : 0);
155
- }
156
- cursor = 0;
157
- };
158
- const next = () =>
159
- {
160
- if (cursor >= state.length) twist();
161
- let value = state[cursor++];
162
- value ^= value >>> 11;
163
- value ^= (value << 7) & 0x9d2c5680;
164
- value ^= (value << 15) & 0xefc60000;
165
- value ^= value >>> 18;
166
- return value >>> 0;
167
- };
168
- const gradients = Float64Array.from(
169
- { length: 256 },
170
- () => ((next() % 512) - 256) / 256
171
- );
172
-
173
- const sample = x =>
174
- {
175
- const floor = Math.floor(x),
176
- first = floor & 255,
177
- second = (first + 1) & 255,
178
- x0 = x - floor,
179
- x1 = x0 - 1,
180
- value0 = x0 * gradients[first],
181
- value1 = x1 * gradients[second],
182
- curve = x0 * x0 * (3 - 2 * x0);
183
-
184
- return value0 + curve * (value1 - value0);
185
- };
186
- const fractalSum = (x, octaves, amplitudeScale = 0.5, frequencyScale = 2) =>
187
- {
188
- let sum = 0,
189
- scale = 1;
190
- const count = Number.isFinite(octaves) ? Math.max(0, Math.trunc(octaves)) : 0;
191
-
192
- for (let index = 0; index < count; index++)
193
- {
194
- sum += sample(x) * scale;
195
- scale *= amplitudeScale;
196
- x *= frequencyScale;
197
- }
198
- return sum;
199
- };
200
-
201
- return Object.freeze({ sample, fractalSum });
202
- };
203
-
204
- const s_fixedPerlinNoise1D = noise.createPerlinNoise1D(0);
205
-
206
- /**
207
- * Evaluates Carbon's global fixed-seed `PerlinNoise1D` function.
208
- *
209
- * @param {number} x
210
- * @param {number} inverseAmplitude
211
- * @param {number} frequency
212
- * @param {number} octaves
213
- * @returns {number}
214
- */
215
- noise.carbonPerlin1D = function(x, inverseAmplitude, frequency, octaves)
216
- {
217
- return s_fixedPerlinNoise1D.fractalSum(x, octaves, 1 / inverseAmplitude, frequency);
218
- };
219
-
220
- /**
221
- * Legacy ccpwgl `Perlin_noise1` helper.
222
- *
223
- * This intentionally remains separate from Carbon's fixed-seed
224
- * `TriPerlinNoise` implementation above.
225
- *
226
- * @param {number} a
227
- * @returns {number}
228
- */
229
- noise.perlin1 = (function()
230
- {
231
- let initialized = false,
232
- permutations = null,
233
- gradients = null;
234
-
235
- function initialize()
236
- {
237
- permutations = new Array(514);
238
- gradients = new Array(514);
239
- let index = 0;
240
-
241
- for (; index < 256; index++)
242
- {
243
- permutations[index] = index;
244
- gradients[index] = Math.random() * 2 - 1;
245
- }
246
-
247
- while (--index)
248
- {
249
- const value = permutations[index],
250
- randomIndex = Math.floor(Math.random() * 256);
251
- permutations[index] = permutations[randomIndex];
252
- permutations[randomIndex] = value;
253
- }
254
-
255
- for (index = 0; index < 258; index++)
256
- {
257
- permutations[256 + index] = permutations[index];
258
- gradients[256 + index] = gradients[index];
259
- }
260
- initialized = true;
261
- }
262
-
263
- return function perlin1(a)
264
- {
265
- if (!initialized) initialize();
266
-
267
- const position = a + 4096,
268
- first = Math.floor(position) & 255,
269
- second = (first + 1) & 255,
270
- x0 = position - Math.floor(position),
271
- x1 = x0 - 1,
272
- curve = x0 * x0 * (3 - 2 * x0),
273
- value0 = x0 * gradients[permutations[first]],
274
- value1 = x1 * gradients[permutations[second]];
275
-
276
- return value0 + curve * (value1 - value0);
277
- };
278
- })();
279
-
280
- /**
281
- * Legacy ccpwgl fractal sum built on randomized `perlin1`.
282
- *
283
- * @param {number} x
284
- * @param {number} alpha
285
- * @param {number} beta
286
- * @param {number} octaves
287
- * @returns {number}
288
- */
289
- noise.perlin1D = function(x, alpha, beta, octaves)
290
- {
291
- let sum = 0,
292
- position = x,
293
- scale = 1;
294
-
295
- for (let index = 0; index < octaves; index++)
296
- {
297
- sum += noise.perlin1(position) / scale;
298
- scale *= alpha;
299
- position *= beta;
300
- }
301
- return sum;
302
- };
303
-
304
- export const {
305
- turbulence,
306
- createPerlinNoise1D,
307
- carbonPerlin1D,
308
- perlin1,
309
- perlin1D
310
- } = noise;
1
+ import { vec3 } from "./vec3.js";
2
+ import { vec4 } from "./vec4.js";
3
+
4
+ export const noise = {};
5
+
6
+ /**
7
+ * Generates turbulent noise
8
+ *
9
+ * @param {vec4} out
10
+ * @param {number} pos_0
11
+ * @param {number} pos_1
12
+ * @param {number} pos_2
13
+ * @param {number} pos_3
14
+ * @param {number} power
15
+ * @returns {vec4} out
16
+ */
17
+ noise.turbulence = (function()
18
+ {
19
+ const
20
+ s_noiseLookup = [],
21
+ s_permutations = [],
22
+ s_globalNoiseTemps = [];
23
+
24
+ let s_initialized = false;
25
+
26
+ /**
27
+ * Initializes noise
28
+ */
29
+ function initialize()
30
+ {
31
+ for (let i = 0; i < 256; i++)
32
+ {
33
+ s_noiseLookup[i] = vec4.fromValues(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
34
+ s_permutations[i] = i;
35
+ }
36
+
37
+ let i = 256;
38
+ while (--i)
39
+ {
40
+ const
41
+ tmp = s_permutations[i],
42
+ index = Math.floor(Math.random() * 256);
43
+
44
+ s_permutations[i] = s_permutations[index];
45
+ s_permutations[index] = tmp;
46
+ }
47
+
48
+ for (let i = 0; i < 256; i++)
49
+ {
50
+ s_permutations[256 + i] = s_permutations[i];
51
+ s_noiseLookup[256 + i] = s_noiseLookup[i];
52
+ s_noiseLookup[256 * 2 + i] = s_noiseLookup[i];
53
+ }
54
+
55
+ for (let i = 0; i < 15; ++i)
56
+ {
57
+ s_globalNoiseTemps[i] = vec3.create();
58
+ }
59
+
60
+ s_initialized = true;
61
+ }
62
+
63
+ return function turbulence(out, pos_0, pos_1, pos_2, pos_3, power)
64
+ {
65
+ if (!s_initialized) initialize();
66
+
67
+ pos_0 += 4096;
68
+ pos_1 += 4096;
69
+ pos_2 += 4096;
70
+ pos_3 += 4096;
71
+
72
+ let a_0 = Math.floor(pos_0),
73
+ a_1 = Math.floor(pos_1),
74
+ a_2 = Math.floor(pos_2),
75
+ a_3 = Math.floor(pos_3);
76
+
77
+ const
78
+ t_0 = pos_0 - a_0,
79
+ t_1 = pos_1 - a_1,
80
+ t_2 = pos_2 - a_2,
81
+ t_3 = pos_3 - a_3;
82
+
83
+ a_0 &= 255;
84
+ a_1 &= 255;
85
+ a_2 &= 255;
86
+ a_3 &= 255;
87
+
88
+ const
89
+ b_0 = a_0 + 1,
90
+ b_1 = a_1 + 1,
91
+ b_2 = a_2 + 1,
92
+ b_3 = a_3 + 1;
93
+
94
+ const
95
+ i = s_permutations[a_0],
96
+ j = s_permutations[b_0];
97
+
98
+ const
99
+ b00 = s_permutations[i + a_1],
100
+ b10 = s_permutations[j + a_1],
101
+ b01 = s_permutations[i + b_1],
102
+ b11 = s_permutations[j + b_1];
103
+
104
+ let c00 = vec3.lerp(s_globalNoiseTemps[0], s_noiseLookup[b00 + a_2 + a_3], s_noiseLookup[b10 + a_2 + a_3], t_0);
105
+ let c10 = vec3.lerp(s_globalNoiseTemps[1], s_noiseLookup[b01 + a_2 + a_3], s_noiseLookup[b11 + a_2 + a_3], t_0);
106
+ let c01 = vec3.lerp(s_globalNoiseTemps[2], s_noiseLookup[b00 + b_2 + a_3], s_noiseLookup[b10 + b_2 + a_3], t_0);
107
+ let c11 = vec3.lerp(s_globalNoiseTemps[3], s_noiseLookup[b01 + b_2 + a_3], s_noiseLookup[b11 + b_2 + a_3], t_0); // Carbon Noise4D: b01/b11 corners (fixed 2026-07-23)
108
+ let c0 = vec3.lerp(s_globalNoiseTemps[4], c00, c10, t_1);
109
+ let c1 = vec3.lerp(s_globalNoiseTemps[5], c01, c11, t_1);
110
+ const c = vec3.lerp(s_globalNoiseTemps[6], c0, c1, t_2);
111
+
112
+ c00 = vec3.lerp(s_globalNoiseTemps[7], s_noiseLookup[b00 + a_2 + b_3], s_noiseLookup[b10 + a_2 + b_3], t_0);
113
+ c10 = vec3.lerp(s_globalNoiseTemps[8], s_noiseLookup[b01 + a_2 + b_3], s_noiseLookup[b11 + a_2 + b_3], t_0);
114
+ c01 = vec3.lerp(s_globalNoiseTemps[9], s_noiseLookup[b00 + b_2 + b_3], s_noiseLookup[b10 + b_2 + b_3], t_0);
115
+ c11 = vec3.lerp(s_globalNoiseTemps[10], s_noiseLookup[b01 + b_2 + b_3], s_noiseLookup[b11 + b_2 + b_3], t_0); // Carbon Noise4D: b01/b11 corners (fixed 2026-07-23)
116
+ c0 = vec3.lerp(s_globalNoiseTemps[11], c00, c10, t_1);
117
+ c1 = vec3.lerp(s_globalNoiseTemps[12], c01, c11, t_1);
118
+ const d = vec3.lerp(s_globalNoiseTemps[13], c0, c1, t_2);
119
+ const r = vec3.lerp(s_globalNoiseTemps[14], c, d, t_3);
120
+
121
+ out[0] += r[0] * power;
122
+ out[1] += r[1] * power;
123
+ out[2] += r[2] * power;
124
+ return out;
125
+ };
126
+ })();
127
+
128
+ /**
129
+ * Creates Carbon's seeded one-dimensional Perlin-noise utility.
130
+ *
131
+ * This ports `TriPerlinNoise` from `TriMath.cpp`: gradients are generated by
132
+ * `std::mt19937`, sampling uses Carbon's cubic S-curve, and the returned
133
+ * object owns the native class's otherwise-private gradient table.
134
+ *
135
+ * @param {number} [seed]
136
+ * @returns {{ sample: (x: number) => number, fractalSum: (x: number, octaves: number, amplitudeScale?: number, frequencyScale?: number) => number }}
137
+ */
138
+ noise.createPerlinNoise1D = function(seed = Math.floor(Math.random() * 0x100000000))
139
+ {
140
+ const state = new Uint32Array(624);
141
+ state[0] = Number(seed) >>> 0;
142
+ for (let index = 1; index < state.length; index++)
143
+ {
144
+ const previous = state[index - 1] ^ (state[index - 1] >>> 30);
145
+ state[index] = (Math.imul(1812433253, previous) + index) >>> 0;
146
+ }
147
+
148
+ let cursor = state.length;
149
+ const twist = () =>
150
+ {
151
+ for (let index = 0; index < state.length; index++)
152
+ {
153
+ const bits = (state[index] & 0x80000000) | (state[(index + 1) % state.length] & 0x7fffffff);
154
+ state[index] = state[(index + 397) % state.length] ^ (bits >>> 1) ^ (bits & 1 ? 0x9908b0df : 0);
155
+ }
156
+ cursor = 0;
157
+ };
158
+ const next = () =>
159
+ {
160
+ if (cursor >= state.length) twist();
161
+ let value = state[cursor++];
162
+ value ^= value >>> 11;
163
+ value ^= (value << 7) & 0x9d2c5680;
164
+ value ^= (value << 15) & 0xefc60000;
165
+ value ^= value >>> 18;
166
+ return value >>> 0;
167
+ };
168
+ const gradients = Float64Array.from(
169
+ { length: 256 },
170
+ () => ((next() % 512) - 256) / 256
171
+ );
172
+
173
+ const sample = x =>
174
+ {
175
+ const floor = Math.floor(x),
176
+ first = floor & 255,
177
+ second = (first + 1) & 255,
178
+ x0 = x - floor,
179
+ x1 = x0 - 1,
180
+ value0 = x0 * gradients[first],
181
+ value1 = x1 * gradients[second],
182
+ curve = x0 * x0 * (3 - 2 * x0);
183
+
184
+ return value0 + curve * (value1 - value0);
185
+ };
186
+ const fractalSum = (x, octaves, amplitudeScale = 0.5, frequencyScale = 2) =>
187
+ {
188
+ let sum = 0,
189
+ scale = 1;
190
+ const count = Number.isFinite(octaves) ? Math.max(0, Math.trunc(octaves)) : 0;
191
+
192
+ for (let index = 0; index < count; index++)
193
+ {
194
+ sum += sample(x) * scale;
195
+ scale *= amplitudeScale;
196
+ x *= frequencyScale;
197
+ }
198
+ return sum;
199
+ };
200
+
201
+ return Object.freeze({ sample, fractalSum });
202
+ };
203
+
204
+ const s_fixedPerlinNoise1D = noise.createPerlinNoise1D(0);
205
+
206
+ /**
207
+ * Evaluates Carbon's global fixed-seed `PerlinNoise1D` function.
208
+ *
209
+ * @param {number} x
210
+ * @param {number} inverseAmplitude
211
+ * @param {number} frequency
212
+ * @param {number} octaves
213
+ * @returns {number}
214
+ */
215
+ noise.carbonPerlin1D = function(x, inverseAmplitude, frequency, octaves)
216
+ {
217
+ return s_fixedPerlinNoise1D.fractalSum(x, octaves, 1 / inverseAmplitude, frequency);
218
+ };
219
+
220
+ /**
221
+ * Legacy ccpwgl `Perlin_noise1` helper.
222
+ *
223
+ * This intentionally remains separate from Carbon's fixed-seed
224
+ * `TriPerlinNoise` implementation above.
225
+ *
226
+ * @param {number} a
227
+ * @returns {number}
228
+ */
229
+ noise.perlin1 = (function()
230
+ {
231
+ let initialized = false,
232
+ permutations = null,
233
+ gradients = null;
234
+
235
+ function initialize()
236
+ {
237
+ permutations = new Array(514);
238
+ gradients = new Array(514);
239
+ let index = 0;
240
+
241
+ for (; index < 256; index++)
242
+ {
243
+ permutations[index] = index;
244
+ gradients[index] = Math.random() * 2 - 1;
245
+ }
246
+
247
+ while (--index)
248
+ {
249
+ const value = permutations[index],
250
+ randomIndex = Math.floor(Math.random() * 256);
251
+ permutations[index] = permutations[randomIndex];
252
+ permutations[randomIndex] = value;
253
+ }
254
+
255
+ for (index = 0; index < 258; index++)
256
+ {
257
+ permutations[256 + index] = permutations[index];
258
+ gradients[256 + index] = gradients[index];
259
+ }
260
+ initialized = true;
261
+ }
262
+
263
+ return function perlin1(a)
264
+ {
265
+ if (!initialized) initialize();
266
+
267
+ const position = a + 4096,
268
+ first = Math.floor(position) & 255,
269
+ second = (first + 1) & 255,
270
+ x0 = position - Math.floor(position),
271
+ x1 = x0 - 1,
272
+ curve = x0 * x0 * (3 - 2 * x0),
273
+ value0 = x0 * gradients[permutations[first]],
274
+ value1 = x1 * gradients[permutations[second]];
275
+
276
+ return value0 + curve * (value1 - value0);
277
+ };
278
+ })();
279
+
280
+ /**
281
+ * Legacy ccpwgl fractal sum built on randomized `perlin1`.
282
+ *
283
+ * @param {number} x
284
+ * @param {number} alpha
285
+ * @param {number} beta
286
+ * @param {number} octaves
287
+ * @returns {number}
288
+ */
289
+ noise.perlin1D = function(x, alpha, beta, octaves)
290
+ {
291
+ let sum = 0,
292
+ position = x,
293
+ scale = 1;
294
+
295
+ for (let index = 0; index < octaves; index++)
296
+ {
297
+ sum += noise.perlin1(position) / scale;
298
+ scale *= alpha;
299
+ position *= beta;
300
+ }
301
+ return sum;
302
+ };
303
+
304
+ export const {
305
+ turbulence,
306
+ createPerlinNoise1D,
307
+ carbonPerlin1D,
308
+ perlin1,
309
+ perlin1D
310
+ } = noise;