@carbonenginejs/runtime-utils 0.1.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.
- package/LICENSE +21 -0
- package/NOTICE +23 -0
- package/README.md +56 -0
- package/THIRD-PARTY-NOTICES.md +38 -0
- package/docs/README.md +81 -0
- package/docs/architecture.md +101 -0
- package/docs/concepts/foundation-consolidation.md +86 -0
- package/docs/const-kb.md +92 -0
- package/docs/core-types/DECORATOR-TODOS.md +25 -0
- package/docs/core-types/README.md +203 -0
- package/docs/reference/api.md +70 -0
- package/docs/reference/classes/README.md +115 -0
- package/package.json +132 -0
- package/src/arrays.js +5 -0
- package/src/audio/audioFormats.js +34 -0
- package/src/audio/index.js +1 -0
- package/src/box3.js +1385 -0
- package/src/bytes.js +56 -0
- package/src/compression.js +56 -0
- package/src/constants/index.js +6 -0
- package/src/constants.js +15 -0
- package/src/curve.js +419 -0
- package/src/d3d/dxgiFormats.js +46 -0
- package/src/d3d/index.js +2 -0
- package/src/d3d/primitiveTopology.js +11 -0
- package/src/document/CjsCarbonDocument.js +212 -0
- package/src/document/CjsClassRegistry.js +373 -0
- package/src/document/CjsDocumentDehydrator.js +142 -0
- package/src/document/CjsDocumentHydrator.js +156 -0
- package/src/document/CjsStructRegistry.js +348 -0
- package/src/document/hydrationAdapter.js +129 -0
- package/src/document/index.js +6 -0
- package/src/geometry/box.js +137 -0
- package/src/geometry/cylinder.js +244 -0
- package/src/geometry/helpers/LICENSE +15 -0
- package/src/geometry/helpers/earcut.js +766 -0
- package/src/geometry/helpers/misc.js +103 -0
- package/src/geometry/index.js +8 -0
- package/src/geometry/json.js +165 -0
- package/src/geometry/lathe.js +172 -0
- package/src/geometry/octahedron.js +0 -0
- package/src/geometry/plane.js +81 -0
- package/src/geometry/shape.js +95 -0
- package/src/geometry/sphere.js +123 -0
- package/src/geometry/torus.js +96 -0
- package/src/graphics/colorSpaces.js +22 -0
- package/src/graphics/index.js +4 -0
- package/src/graphics/pixelFormats.js +158 -0
- package/src/graphics/textureDimensions.js +22 -0
- package/src/graphics/trinityEnums.js +87 -0
- package/src/index.js +58 -0
- package/src/is.js +524 -0
- package/src/json.js +23 -0
- package/src/lifecycle/CjsLifecycleState.js +77 -0
- package/src/lifecycle/index.js +1 -0
- package/src/lne3.js +497 -0
- package/src/lookup.js +48 -0
- package/src/mat3.js +131 -0
- package/src/mat4.js +699 -0
- package/src/math/index.js +25 -0
- package/src/math/scalar.js +63 -0
- package/src/media/index.js +1 -0
- package/src/media/mediaTypes.js +50 -0
- package/src/mesh.js +394 -0
- package/src/model/CjsEventEmitter.js +333 -0
- package/src/model/CjsModel.js +1544 -0
- package/src/model/CjsModelState.js +72 -0
- package/src/model/index.js +4 -0
- package/src/model/sourceRecordUtils.js +54 -0
- package/src/noise.js +310 -0
- package/src/num.js +827 -0
- package/src/path.js +21 -0
- package/src/pln.js +762 -0
- package/src/pool.js +160 -0
- package/src/quat.js +144 -0
- package/src/ray3.js +1085 -0
- package/src/renderContext/formats.js +145 -0
- package/src/renderContext/index.js +5 -0
- package/src/renderContext/presentation.js +125 -0
- package/src/renderContext/resources.js +27 -0
- package/src/renderContext/upscaling.js +22 -0
- package/src/renderContext/window.js +20 -0
- package/src/runtime/CjsRuntimeState.js +50 -0
- package/src/schema/CjsSchema.js +1009 -0
- package/src/schema/index.js +17 -0
- package/src/shader/index.js +1 -0
- package/src/shader/shaderStages.js +37 -0
- package/src/sph3.js +754 -0
- package/src/tangent.js +288 -0
- package/src/text.js +40 -0
- package/src/tri3.js +650 -0
- package/src/types/carbonTypes.js +635 -0
- package/src/types/index.js +2 -0
- package/src/utils.js +58 -0
- package/src/validation.js +46 -0
- package/src/vec2.js +229 -0
- package/src/vec3.js +1172 -0
- package/src/vec4.js +347 -0
- package/src/vertex.js +108 -0
- package/src/webgpu/index.js +1 -0
- package/src/webgpu/textureFormats.js +121 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-model runtime state. One instance per model at `__state`.
|
|
3
|
+
*
|
|
4
|
+
* Ownership and clearing rules (kb section 8):
|
|
5
|
+
* - `dirty` is the only generically managed member: mutations mark it, and
|
|
6
|
+
* `UpdateValues` (the settle) is the only thing that clears it. The
|
|
7
|
+
* pipeline is cooperative - anything mutating outside `SetValues`
|
|
8
|
+
* (direct writes, Object.assign, reader adapters) owes a `MarkDirty()`
|
|
9
|
+
* or an explicit `UpdateValues()` ("I made changes, apply please").
|
|
10
|
+
* - `flags` holds lazy invalidations ("bounds is stale"). Written at
|
|
11
|
+
* mutation time from `@io.flag` field metadata or by class code; cleared
|
|
12
|
+
* ONLY by the getter that recomputes the derived value. Never
|
|
13
|
+
* auto-cleared - deferring until needed is their whole point.
|
|
14
|
+
* - `rebuild` holds scheduled work requirements ("vertices need
|
|
15
|
+
* rebuilding"). Written at mutation time from `@io.rebuild` field
|
|
16
|
+
* metadata or by class code; cleared ONLY by the specific work method
|
|
17
|
+
* that succeeds (e.g. RebuildVertices), typically driven from Update /
|
|
18
|
+
* per-frame passes. Never auto-cleared.
|
|
19
|
+
* - Future transient runtime state (lifecycle links, revision counters)
|
|
20
|
+
* lands here rather than growing new underscore properties.
|
|
21
|
+
*/
|
|
22
|
+
export class CjsModelState
|
|
23
|
+
{
|
|
24
|
+
|
|
25
|
+
/** Something changed; the next settle applies it. @type {boolean} */
|
|
26
|
+
dirty = false;
|
|
27
|
+
|
|
28
|
+
/** Lazy invalidations - consumers clear when they recompute. @type {Set<string>} */
|
|
29
|
+
flags = new Set();
|
|
30
|
+
|
|
31
|
+
/** Scheduled work requirements - work methods clear on success. @type {Set<string>} */
|
|
32
|
+
rebuild = new Set();
|
|
33
|
+
|
|
34
|
+
/** Settle re-entrancy guard. @type {boolean} */
|
|
35
|
+
updating = false;
|
|
36
|
+
|
|
37
|
+
/** Construction/teardown event gate (counted). @type {number} */
|
|
38
|
+
suppressEvents = 0;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Checks whether a settle is owed.
|
|
42
|
+
*
|
|
43
|
+
* @returns {boolean}
|
|
44
|
+
*/
|
|
45
|
+
IsDirty()
|
|
46
|
+
{
|
|
47
|
+
return this.dirty;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Marks the model as changed ("apply at the next settle").
|
|
52
|
+
*
|
|
53
|
+
* @returns {CjsModelState} This state.
|
|
54
|
+
*/
|
|
55
|
+
MarkDirty()
|
|
56
|
+
{
|
|
57
|
+
this.dirty = true;
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Clears the dirty mark. The settle calls this; class code rarely should.
|
|
63
|
+
*
|
|
64
|
+
* @returns {CjsModelState} This state.
|
|
65
|
+
*/
|
|
66
|
+
ClearDirty()
|
|
67
|
+
{
|
|
68
|
+
this.dirty = false;
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { CjsModel } from "./CjsModel.js";
|
|
2
|
+
|
|
3
|
+
export function asArray(value)
|
|
4
|
+
{
|
|
5
|
+
if (!value) return [];
|
|
6
|
+
if (value instanceof Map) return Array.from(value.values());
|
|
7
|
+
return Array.isArray(value) ? value : [value];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function firstDefined(...values)
|
|
11
|
+
{
|
|
12
|
+
for (const value of values)
|
|
13
|
+
{
|
|
14
|
+
if (value !== undefined && value !== null) return value;
|
|
15
|
+
}
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function getField(object, ...names)
|
|
20
|
+
{
|
|
21
|
+
if (!object) return null;
|
|
22
|
+
for (const name of names)
|
|
23
|
+
{
|
|
24
|
+
if (Object.prototype.hasOwnProperty.call(object, name)) return object[name];
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function objectFromMap(map)
|
|
30
|
+
{
|
|
31
|
+
return Object.fromEntries(map.entries());
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function collectionValues(value)
|
|
35
|
+
{
|
|
36
|
+
if (!value) return [];
|
|
37
|
+
if (value instanceof Map) return Array.from(value.values());
|
|
38
|
+
if (Array.isArray(value)) return value;
|
|
39
|
+
if (typeof value === "object") return Object.values(value);
|
|
40
|
+
return [value];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function clonePlain(value)
|
|
44
|
+
{
|
|
45
|
+
if (value instanceof CjsModel) return value.GetValues();
|
|
46
|
+
if (ArrayBuffer.isView(value)) return Array.from(value);
|
|
47
|
+
if (value instanceof Map) return new Map(Array.from(value.entries()).map(([key, item]) => [key, clonePlain(item)]));
|
|
48
|
+
if (Array.isArray(value)) return value.map(clonePlain);
|
|
49
|
+
if (value && typeof value === "object")
|
|
50
|
+
{
|
|
51
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clonePlain(item)]));
|
|
52
|
+
}
|
|
53
|
+
return value;
|
|
54
|
+
}
|
package/src/noise.js
ADDED
|
@@ -0,0 +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;
|