@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,635 @@
|
|
|
1
|
+
export const CARBON_META = Symbol.for("carbonenginejs.type");
|
|
2
|
+
export const CARBON_RAW_STRUCT_TYPE = Symbol.for("carbonenginejs.rawStructType");
|
|
3
|
+
|
|
4
|
+
export const CARBON_TYPE = Object.freeze({
|
|
5
|
+
UNKNOWN: "unknown",
|
|
6
|
+
BOOLEAN: "boolean",
|
|
7
|
+
STRING: "string",
|
|
8
|
+
PATH: "path",
|
|
9
|
+
EXPRESSION: "expression",
|
|
10
|
+
ENUM: "enum",
|
|
11
|
+
FLOAT32: "float32",
|
|
12
|
+
FLOAT64: "float64",
|
|
13
|
+
INT8: "int8",
|
|
14
|
+
UINT8: "uint8",
|
|
15
|
+
INT16: "int16",
|
|
16
|
+
UINT16: "uint16",
|
|
17
|
+
INT32: "int32",
|
|
18
|
+
UINT32: "uint32",
|
|
19
|
+
INT64: "int64",
|
|
20
|
+
UINT64: "uint64",
|
|
21
|
+
VECTOR2: "vector2",
|
|
22
|
+
VECTOR3: "vector3",
|
|
23
|
+
VECTOR4: "vector4",
|
|
24
|
+
COLOR: "color",
|
|
25
|
+
QUATERNION: "quaternion",
|
|
26
|
+
MATRIX3: "matrix3",
|
|
27
|
+
MATRIX4: "matrix4",
|
|
28
|
+
ARRAY: "array",
|
|
29
|
+
MAP: "map",
|
|
30
|
+
SET: "set",
|
|
31
|
+
MODEL: "model",
|
|
32
|
+
OBJECT_REF: "objectRef",
|
|
33
|
+
STRUCT: "struct",
|
|
34
|
+
RAW_STRUCT: "rawStruct",
|
|
35
|
+
TYPED_ARRAY: "typedArray"
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const FLOAT32_VECTOR_DEFINITIONS = Object.freeze({
|
|
39
|
+
[CARBON_TYPE.VECTOR2]: Object.freeze({ kind: CARBON_TYPE.VECTOR2, js: "vec2", scalar: CARBON_TYPE.FLOAT32, length: 2, default: [0, 0] }),
|
|
40
|
+
[CARBON_TYPE.VECTOR3]: Object.freeze({ kind: CARBON_TYPE.VECTOR3, js: "vec3", scalar: CARBON_TYPE.FLOAT32, length: 3, default: [0, 0, 0] }),
|
|
41
|
+
[CARBON_TYPE.VECTOR4]: Object.freeze({ kind: CARBON_TYPE.VECTOR4, js: "vec4", scalar: CARBON_TYPE.FLOAT32, length: 4, default: [0, 0, 0, 0] }),
|
|
42
|
+
[CARBON_TYPE.COLOR]: Object.freeze({ kind: CARBON_TYPE.COLOR, js: "vec4", semantic: CARBON_TYPE.COLOR, scalar: CARBON_TYPE.FLOAT32, length: 4, default: [0, 0, 0, 0] }),
|
|
43
|
+
[CARBON_TYPE.QUATERNION]: Object.freeze({ kind: CARBON_TYPE.QUATERNION, js: "quat", scalar: CARBON_TYPE.FLOAT32, length: 4, default: [0, 0, 0, 1] }),
|
|
44
|
+
[CARBON_TYPE.MATRIX3]: Object.freeze({ kind: CARBON_TYPE.MATRIX3, js: "mat3", scalar: CARBON_TYPE.FLOAT32, length: 9, default: [1, 0, 0, 0, 1, 0, 0, 0, 1] }),
|
|
45
|
+
[CARBON_TYPE.MATRIX4]: Object.freeze({ kind: CARBON_TYPE.MATRIX4, js: "mat4", scalar: CARBON_TYPE.FLOAT32, length: 16, default: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] })
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const TYPE_DEFINITIONS = Object.freeze({
|
|
49
|
+
[CARBON_TYPE.UNKNOWN]: Object.freeze({ kind: CARBON_TYPE.UNKNOWN, js: "*" }),
|
|
50
|
+
[CARBON_TYPE.BOOLEAN]: Object.freeze({ kind: CARBON_TYPE.BOOLEAN, js: "boolean" }),
|
|
51
|
+
[CARBON_TYPE.STRING]: Object.freeze({ kind: CARBON_TYPE.STRING, js: "string" }),
|
|
52
|
+
[CARBON_TYPE.PATH]: Object.freeze({ kind: CARBON_TYPE.PATH, js: "string" }),
|
|
53
|
+
[CARBON_TYPE.EXPRESSION]: Object.freeze({ kind: CARBON_TYPE.EXPRESSION, js: "string", semantic: CARBON_TYPE.EXPRESSION }),
|
|
54
|
+
[CARBON_TYPE.ENUM]: Object.freeze({ kind: CARBON_TYPE.ENUM, js: "number|string|null" }),
|
|
55
|
+
[CARBON_TYPE.FLOAT32]: Object.freeze({ kind: CARBON_TYPE.FLOAT32, js: "number", bits: 32, signed: true, floating: true }),
|
|
56
|
+
[CARBON_TYPE.FLOAT64]: Object.freeze({ kind: CARBON_TYPE.FLOAT64, js: "number", bits: 64, signed: true, floating: true }),
|
|
57
|
+
[CARBON_TYPE.INT8]: Object.freeze({ kind: CARBON_TYPE.INT8, js: "number", bits: 8, signed: true, integer: true }),
|
|
58
|
+
[CARBON_TYPE.UINT8]: Object.freeze({ kind: CARBON_TYPE.UINT8, js: "number", bits: 8, signed: false, integer: true }),
|
|
59
|
+
[CARBON_TYPE.INT16]: Object.freeze({ kind: CARBON_TYPE.INT16, js: "number", bits: 16, signed: true, integer: true }),
|
|
60
|
+
[CARBON_TYPE.UINT16]: Object.freeze({ kind: CARBON_TYPE.UINT16, js: "number", bits: 16, signed: false, integer: true }),
|
|
61
|
+
[CARBON_TYPE.INT32]: Object.freeze({ kind: CARBON_TYPE.INT32, js: "number", bits: 32, signed: true, integer: true }),
|
|
62
|
+
[CARBON_TYPE.UINT32]: Object.freeze({ kind: CARBON_TYPE.UINT32, js: "number", bits: 32, signed: false, integer: true }),
|
|
63
|
+
[CARBON_TYPE.INT64]: Object.freeze({ kind: CARBON_TYPE.INT64, js: "bigint", bits: 64, signed: true, integer: true }),
|
|
64
|
+
[CARBON_TYPE.UINT64]: Object.freeze({ kind: CARBON_TYPE.UINT64, js: "bigint", bits: 64, signed: false, integer: true }),
|
|
65
|
+
[CARBON_TYPE.ARRAY]: Object.freeze({ kind: CARBON_TYPE.ARRAY, js: "Array" }),
|
|
66
|
+
[CARBON_TYPE.MAP]: Object.freeze({ kind: CARBON_TYPE.MAP, js: "Map" }),
|
|
67
|
+
[CARBON_TYPE.SET]: Object.freeze({ kind: CARBON_TYPE.SET, js: "Set" }),
|
|
68
|
+
[CARBON_TYPE.MODEL]: Object.freeze({ kind: CARBON_TYPE.MODEL, js: "object|null" }),
|
|
69
|
+
[CARBON_TYPE.OBJECT_REF]: Object.freeze({ kind: CARBON_TYPE.OBJECT_REF, js: "object|null" }),
|
|
70
|
+
[CARBON_TYPE.STRUCT]: Object.freeze({ kind: CARBON_TYPE.STRUCT, js: "object" }),
|
|
71
|
+
[CARBON_TYPE.RAW_STRUCT]: Object.freeze({ kind: CARBON_TYPE.RAW_STRUCT, js: "object" }),
|
|
72
|
+
[CARBON_TYPE.TYPED_ARRAY]: Object.freeze({ kind: CARBON_TYPE.TYPED_ARRAY, js: "TypedArray" }),
|
|
73
|
+
...FLOAT32_VECTOR_DEFINITIONS
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const TYPE_ALIASES = Object.freeze({
|
|
77
|
+
bool: CARBON_TYPE.BOOLEAN,
|
|
78
|
+
float: CARBON_TYPE.FLOAT32,
|
|
79
|
+
double: CARBON_TYPE.FLOAT64,
|
|
80
|
+
vec2: CARBON_TYPE.VECTOR2,
|
|
81
|
+
vec3: CARBON_TYPE.VECTOR3,
|
|
82
|
+
vec4: CARBON_TYPE.VECTOR4,
|
|
83
|
+
quat: CARBON_TYPE.QUATERNION,
|
|
84
|
+
mat3: CARBON_TYPE.MATRIX3,
|
|
85
|
+
mat4: CARBON_TYPE.MATRIX4
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
const TYPED_ARRAY_CTORS = Object.freeze({
|
|
89
|
+
Int8Array,
|
|
90
|
+
Uint8Array,
|
|
91
|
+
Uint8ClampedArray,
|
|
92
|
+
Int16Array,
|
|
93
|
+
Uint16Array,
|
|
94
|
+
Int32Array,
|
|
95
|
+
Uint32Array,
|
|
96
|
+
Float32Array,
|
|
97
|
+
Float64Array,
|
|
98
|
+
BigInt64Array,
|
|
99
|
+
BigUint64Array
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
const num = Object.freeze({
|
|
103
|
+
int8,
|
|
104
|
+
uint8,
|
|
105
|
+
int16,
|
|
106
|
+
uint16,
|
|
107
|
+
int32,
|
|
108
|
+
uint32,
|
|
109
|
+
int64,
|
|
110
|
+
uint64,
|
|
111
|
+
float32,
|
|
112
|
+
float64
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const CARBON_MATH_KINDS = new Set(Object.keys(FLOAT32_VECTOR_DEFINITIONS));
|
|
116
|
+
|
|
117
|
+
export function createCarbonMathValue(type, value = undefined)
|
|
118
|
+
{
|
|
119
|
+
const descriptor = normalizeCarbonTypeDescriptor(type);
|
|
120
|
+
const values = normalizeMathValues(value, descriptor.length, descriptor.default);
|
|
121
|
+
|
|
122
|
+
// Carbon math values are plain Float32Arrays. Their descriptors remain
|
|
123
|
+
// independent of the gl-matrix-backed math helpers. Defaults already
|
|
124
|
+
// encode identity/zero, matching gl-matrix's create() output.
|
|
125
|
+
return CARBON_MATH_KINDS.has(descriptor.kind) ? Float32Array.from(values) : values;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Coerce a math value INTO an existing Float32Array target, in place, with no
|
|
130
|
+
* allocation. Returns `true`/`false` (whether any element changed) when the fast
|
|
131
|
+
* path applies — a math kind, `target` a compatible Float32Array, and `value`
|
|
132
|
+
* array-like. Returns `null` when it does not apply (non-math kind, incompatible
|
|
133
|
+
* or absent target, or a null/undefined value) so the caller falls back to a
|
|
134
|
+
* normal allocating assignment.
|
|
135
|
+
*/
|
|
136
|
+
export function coerceCarbonMathInto(target, value, type)
|
|
137
|
+
{
|
|
138
|
+
const descriptor = normalizeCarbonTypeDescriptor(type);
|
|
139
|
+
if (!CARBON_MATH_KINDS.has(descriptor.kind)) return null;
|
|
140
|
+
if (!(target instanceof Float32Array) || target.length !== descriptor.length) return null;
|
|
141
|
+
|
|
142
|
+
const source = ArrayBuffer.isView(value) || Array.isArray(value) ? value : null;
|
|
143
|
+
if (!source) return null;
|
|
144
|
+
|
|
145
|
+
const defaults = descriptor.default;
|
|
146
|
+
let changed = false;
|
|
147
|
+
for (let i = 0; i < descriptor.length; i++)
|
|
148
|
+
{
|
|
149
|
+
const next = num.float32(i < source.length ? source[i] : defaults[i]);
|
|
150
|
+
if (target[i] !== next)
|
|
151
|
+
{
|
|
152
|
+
target[i] = next;
|
|
153
|
+
changed = true;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return changed;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function getCarbonTypeDefinition(type)
|
|
160
|
+
{
|
|
161
|
+
const descriptor = normalizeCarbonTypeDescriptor(type);
|
|
162
|
+
return TYPE_DEFINITIONS[descriptor.kind] || TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export function normalizeCarbonTypeDescriptor(type)
|
|
166
|
+
{
|
|
167
|
+
if (!type) return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
168
|
+
if (typeof type === "string") return carbonTypeDefinitionForKind(type);
|
|
169
|
+
if (type.kind) return mergeCarbonTypeDefinition(type);
|
|
170
|
+
if (type.jsType) return normalizeCarbonTypeDescriptor(type.jsType);
|
|
171
|
+
if (type.cppType) return inferCarbonTypeFromCpp(type.cppType, type.name);
|
|
172
|
+
if (type.pythonType) return inferCarbonTypeFromPython(type.pythonType);
|
|
173
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function inferCarbonTypeFromCpp(cppType, propertyName = "")
|
|
177
|
+
{
|
|
178
|
+
const original = String(cppType || "").trim();
|
|
179
|
+
const type = normalizeCppType(original);
|
|
180
|
+
const named = normalizeCppTypeName(original);
|
|
181
|
+
|
|
182
|
+
if (!type) return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
183
|
+
if (type.includes("std::vector") || /(?:Vector|List)$/.test(named)) return containerDescriptor(CARBON_TYPE.ARRAY, original);
|
|
184
|
+
if (type.includes("std::map") || /(?:Map)$/.test(named)) return containerDescriptor(CARBON_TYPE.MAP, original);
|
|
185
|
+
if (type.includes("std::set") || /(?:Set)$/.test(named)) return containerDescriptor(CARBON_TYPE.SET, original);
|
|
186
|
+
if (/\*$/.test(type) || /^P(?:I)?[A-Z]\w+$/.test(named) || /(?:Ptr|Ref)$/.test(named)) return objectRefDescriptor(original);
|
|
187
|
+
|
|
188
|
+
switch (named)
|
|
189
|
+
{
|
|
190
|
+
case "bool":
|
|
191
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.BOOLEAN];
|
|
192
|
+
case "char":
|
|
193
|
+
case "int8_t":
|
|
194
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.INT8];
|
|
195
|
+
case "uint8_t":
|
|
196
|
+
case "byte":
|
|
197
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UINT8];
|
|
198
|
+
case "int16_t":
|
|
199
|
+
case "short":
|
|
200
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.INT16];
|
|
201
|
+
case "uint16_t":
|
|
202
|
+
case "ushort":
|
|
203
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UINT16];
|
|
204
|
+
case "int":
|
|
205
|
+
case "int32_t":
|
|
206
|
+
case "long":
|
|
207
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.INT32];
|
|
208
|
+
case "uint":
|
|
209
|
+
case "uint32_t":
|
|
210
|
+
case "ulong":
|
|
211
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UINT32];
|
|
212
|
+
case "int64_t":
|
|
213
|
+
case "longlong":
|
|
214
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.INT64];
|
|
215
|
+
case "uint64_t":
|
|
216
|
+
case "size_t":
|
|
217
|
+
case "ulonglong":
|
|
218
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UINT64];
|
|
219
|
+
case "float":
|
|
220
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.FLOAT32];
|
|
221
|
+
case "double":
|
|
222
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.FLOAT64];
|
|
223
|
+
case "std::string":
|
|
224
|
+
case "std::wstring":
|
|
225
|
+
case "BlueSharedString":
|
|
226
|
+
return isExpressionLike(propertyName) ? TYPE_DEFINITIONS[CARBON_TYPE.EXPRESSION] : TYPE_DEFINITIONS[CARBON_TYPE.STRING];
|
|
227
|
+
case "Vector2":
|
|
228
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.VECTOR2];
|
|
229
|
+
case "Vector3":
|
|
230
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.VECTOR3];
|
|
231
|
+
case "Vector4":
|
|
232
|
+
return isRotationLike(propertyName) ? TYPE_DEFINITIONS[CARBON_TYPE.QUATERNION] : TYPE_DEFINITIONS[CARBON_TYPE.VECTOR4];
|
|
233
|
+
case "Color":
|
|
234
|
+
case "ColorRGBA":
|
|
235
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.COLOR];
|
|
236
|
+
case "Quaternion":
|
|
237
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.QUATERNION];
|
|
238
|
+
case "Matrix3":
|
|
239
|
+
case "Mat3":
|
|
240
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.MATRIX3];
|
|
241
|
+
case "Matrix":
|
|
242
|
+
case "Matrix4":
|
|
243
|
+
case "Mat4":
|
|
244
|
+
case "TriMatrix":
|
|
245
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.MATRIX4];
|
|
246
|
+
default:
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (/::[A-Za-z_]\w*(?:Type|Usage|Mode|Enum)$/.test(type)) return TYPE_DEFINITIONS[CARBON_TYPE.ENUM];
|
|
251
|
+
if (type.includes("::")) return rawStructDescriptor(original);
|
|
252
|
+
if (/^[A-Z]\w*(?:Type|Usage|Mode|Enum)?$/.test(named)) return TYPE_DEFINITIONS[CARBON_TYPE.ENUM];
|
|
253
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
export function inferCarbonTypeFromPython(pythonType)
|
|
257
|
+
{
|
|
258
|
+
const type = String(pythonType || "").trim().toLowerCase();
|
|
259
|
+
if (!type) return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
260
|
+
if (type === "bool" || type === "boolean") return TYPE_DEFINITIONS[CARBON_TYPE.BOOLEAN];
|
|
261
|
+
if (type === "str" || type === "unicode" || type === "bytes") return TYPE_DEFINITIONS[CARBON_TYPE.STRING];
|
|
262
|
+
if (type === "float") return TYPE_DEFINITIONS[CARBON_TYPE.FLOAT64];
|
|
263
|
+
if (type === "int" || type === "long") return TYPE_DEFINITIONS[CARBON_TYPE.INT64];
|
|
264
|
+
if (type === "list" || type === "tuple") return TYPE_DEFINITIONS[CARBON_TYPE.ARRAY];
|
|
265
|
+
if (type === "dict") return TYPE_DEFINITIONS[CARBON_TYPE.MAP];
|
|
266
|
+
if (type === "set") return TYPE_DEFINITIONS[CARBON_TYPE.SET];
|
|
267
|
+
if (type === "none" || type === "nonetype") return objectRefDescriptor("NoneType");
|
|
268
|
+
return TYPE_DEFINITIONS[CARBON_TYPE.UNKNOWN];
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function defaultValueForCarbonField(field)
|
|
272
|
+
{
|
|
273
|
+
if (field && field.default && field.default.kind !== "expression")
|
|
274
|
+
{
|
|
275
|
+
return normalizeCarbonValue(field.default.json, field);
|
|
276
|
+
}
|
|
277
|
+
return defaultCarbonValue(field);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export function defaultCarbonValue(type)
|
|
281
|
+
{
|
|
282
|
+
const descriptor = normalizeCarbonTypeDescriptor(type);
|
|
283
|
+
switch (descriptor.kind)
|
|
284
|
+
{
|
|
285
|
+
case CARBON_TYPE.BOOLEAN:
|
|
286
|
+
return false;
|
|
287
|
+
case CARBON_TYPE.STRING:
|
|
288
|
+
case CARBON_TYPE.PATH:
|
|
289
|
+
case CARBON_TYPE.EXPRESSION:
|
|
290
|
+
return "";
|
|
291
|
+
case CARBON_TYPE.FLOAT32:
|
|
292
|
+
return num.float32(0);
|
|
293
|
+
case CARBON_TYPE.FLOAT64:
|
|
294
|
+
return num.float64(0);
|
|
295
|
+
case CARBON_TYPE.INT8:
|
|
296
|
+
return num.int8(0);
|
|
297
|
+
case CARBON_TYPE.UINT8:
|
|
298
|
+
return num.uint8(0);
|
|
299
|
+
case CARBON_TYPE.INT16:
|
|
300
|
+
return num.int16(0);
|
|
301
|
+
case CARBON_TYPE.UINT16:
|
|
302
|
+
return num.uint16(0);
|
|
303
|
+
case CARBON_TYPE.INT32:
|
|
304
|
+
return num.int32(0);
|
|
305
|
+
case CARBON_TYPE.UINT32:
|
|
306
|
+
return num.uint32(0);
|
|
307
|
+
case CARBON_TYPE.INT64:
|
|
308
|
+
return num.int64(0);
|
|
309
|
+
case CARBON_TYPE.UINT64:
|
|
310
|
+
return num.uint64(0);
|
|
311
|
+
case CARBON_TYPE.VECTOR2:
|
|
312
|
+
case CARBON_TYPE.VECTOR3:
|
|
313
|
+
case CARBON_TYPE.VECTOR4:
|
|
314
|
+
case CARBON_TYPE.COLOR:
|
|
315
|
+
case CARBON_TYPE.QUATERNION:
|
|
316
|
+
case CARBON_TYPE.MATRIX3:
|
|
317
|
+
case CARBON_TYPE.MATRIX4:
|
|
318
|
+
return createCarbonMathValue(descriptor);
|
|
319
|
+
case CARBON_TYPE.ARRAY:
|
|
320
|
+
return [];
|
|
321
|
+
case CARBON_TYPE.MAP:
|
|
322
|
+
return new Map();
|
|
323
|
+
case CARBON_TYPE.SET:
|
|
324
|
+
return new Set();
|
|
325
|
+
case CARBON_TYPE.ENUM:
|
|
326
|
+
case CARBON_TYPE.MODEL:
|
|
327
|
+
case CARBON_TYPE.OBJECT_REF:
|
|
328
|
+
case CARBON_TYPE.STRUCT:
|
|
329
|
+
case CARBON_TYPE.RAW_STRUCT:
|
|
330
|
+
case CARBON_TYPE.UNKNOWN:
|
|
331
|
+
default:
|
|
332
|
+
return null;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export function normalizeCarbonValue(value, type)
|
|
337
|
+
{
|
|
338
|
+
const descriptor = normalizeCarbonTypeDescriptor(type);
|
|
339
|
+
if (value === undefined) return defaultCarbonValue(descriptor);
|
|
340
|
+
if (value === null) return null;
|
|
341
|
+
|
|
342
|
+
switch (descriptor.kind)
|
|
343
|
+
{
|
|
344
|
+
case CARBON_TYPE.BOOLEAN:
|
|
345
|
+
return Boolean(value);
|
|
346
|
+
case CARBON_TYPE.STRING:
|
|
347
|
+
case CARBON_TYPE.PATH:
|
|
348
|
+
case CARBON_TYPE.EXPRESSION:
|
|
349
|
+
return String(value);
|
|
350
|
+
case CARBON_TYPE.FLOAT32:
|
|
351
|
+
return num.float32(value);
|
|
352
|
+
case CARBON_TYPE.FLOAT64:
|
|
353
|
+
return num.float64(value);
|
|
354
|
+
case CARBON_TYPE.INT8:
|
|
355
|
+
return num.int8(value);
|
|
356
|
+
case CARBON_TYPE.UINT8:
|
|
357
|
+
return num.uint8(value);
|
|
358
|
+
case CARBON_TYPE.INT16:
|
|
359
|
+
return num.int16(value);
|
|
360
|
+
case CARBON_TYPE.UINT16:
|
|
361
|
+
return num.uint16(value);
|
|
362
|
+
case CARBON_TYPE.INT32:
|
|
363
|
+
return num.int32(value);
|
|
364
|
+
case CARBON_TYPE.UINT32:
|
|
365
|
+
return num.uint32(value);
|
|
366
|
+
case CARBON_TYPE.INT64:
|
|
367
|
+
return num.int64(value);
|
|
368
|
+
case CARBON_TYPE.UINT64:
|
|
369
|
+
return num.uint64(value);
|
|
370
|
+
case CARBON_TYPE.VECTOR2:
|
|
371
|
+
case CARBON_TYPE.VECTOR3:
|
|
372
|
+
case CARBON_TYPE.VECTOR4:
|
|
373
|
+
case CARBON_TYPE.COLOR:
|
|
374
|
+
case CARBON_TYPE.QUATERNION:
|
|
375
|
+
case CARBON_TYPE.MATRIX3:
|
|
376
|
+
case CARBON_TYPE.MATRIX4:
|
|
377
|
+
return createCarbonMathValue(descriptor, value);
|
|
378
|
+
case CARBON_TYPE.ARRAY:
|
|
379
|
+
return Array.isArray(value) ? value.map(cloneCarbonValue) : [cloneCarbonValue(value)];
|
|
380
|
+
case CARBON_TYPE.MAP:
|
|
381
|
+
return value instanceof Map ? cloneCarbonValue(value) : new Map(Object.entries(value || {}));
|
|
382
|
+
case CARBON_TYPE.SET:
|
|
383
|
+
return value instanceof Set ? new Set(value) : new Set(Array.isArray(value) ? value : [value]);
|
|
384
|
+
default:
|
|
385
|
+
return cloneCarbonValue(value);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export function cloneCarbonValue(value)
|
|
390
|
+
{
|
|
391
|
+
if (ArrayBuffer.isView(value)) return new value.constructor(value);
|
|
392
|
+
if (typeof value === "bigint") return value;
|
|
393
|
+
if (isSourceShapedObject(value)) return value;
|
|
394
|
+
if (value instanceof Map) return new Map(Array.from(value.entries()).map(([key, item]) => [key, cloneCarbonValue(item)]));
|
|
395
|
+
if (value instanceof Set) return new Set(Array.from(value.values()).map(cloneCarbonValue));
|
|
396
|
+
if (Array.isArray(value)) return value.map(cloneCarbonValue);
|
|
397
|
+
if (value && typeof value === "object")
|
|
398
|
+
{
|
|
399
|
+
const result = Object.fromEntries(Object.entries(value).map(([key, item]) => [key, cloneCarbonValue(item)]));
|
|
400
|
+
if (isCarbonRawStruct(value)) return createCarbonRawStruct(getCarbonRawStructType(value), result);
|
|
401
|
+
return result;
|
|
402
|
+
}
|
|
403
|
+
return value;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
export function exportCarbonValue(value)
|
|
407
|
+
{
|
|
408
|
+
if (ArrayBuffer.isView(value)) return Array.from(value, item => typeof item === "bigint" ? item.toString() : item);
|
|
409
|
+
if (typeof value === "bigint") return value.toString();
|
|
410
|
+
if (value instanceof Map) return Object.fromEntries(Array.from(value.entries()).map(([key, item]) => [key, exportCarbonValue(item)]));
|
|
411
|
+
if (value instanceof Set) return Array.from(value.values()).map(exportCarbonValue);
|
|
412
|
+
if (Array.isArray(value)) return value.map(exportCarbonValue);
|
|
413
|
+
if (value && typeof value === "object")
|
|
414
|
+
{
|
|
415
|
+
const result = Object.fromEntries(
|
|
416
|
+
Object.entries(value)
|
|
417
|
+
.filter(([key]) => !key.startsWith("_"))
|
|
418
|
+
.map(([key, item]) => [key, exportCarbonValue(item)])
|
|
419
|
+
);
|
|
420
|
+
if (isCarbonRawStruct(value)) result.$type = getCarbonRawStructType(value);
|
|
421
|
+
return result;
|
|
422
|
+
}
|
|
423
|
+
return value;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
export function createCarbonRawStruct(typeName, values = {})
|
|
427
|
+
{
|
|
428
|
+
const result = { ...values };
|
|
429
|
+
Object.defineProperty(result, CARBON_META, {
|
|
430
|
+
value: CARBON_TYPE.RAW_STRUCT,
|
|
431
|
+
enumerable: false,
|
|
432
|
+
configurable: true
|
|
433
|
+
});
|
|
434
|
+
Object.defineProperty(result, CARBON_RAW_STRUCT_TYPE, {
|
|
435
|
+
value: typeName || null,
|
|
436
|
+
enumerable: false,
|
|
437
|
+
configurable: true
|
|
438
|
+
});
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
export function isCarbonRawStruct(value)
|
|
443
|
+
{
|
|
444
|
+
return Boolean(value && typeof value === "object" && value[CARBON_META] === CARBON_TYPE.RAW_STRUCT);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
export function getCarbonRawStructType(value)
|
|
448
|
+
{
|
|
449
|
+
return isCarbonRawStruct(value) ? value[CARBON_RAW_STRUCT_TYPE] : null;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
export function carbonValueToJsExpression(value)
|
|
453
|
+
{
|
|
454
|
+
if (ArrayBuffer.isView(value))
|
|
455
|
+
{
|
|
456
|
+
const values = Array.from(value, item => typeof item === "bigint" ? `${item}n` : formatJsNumber(item));
|
|
457
|
+
return `new ${value.constructor.name}([${values.join(", ")}])`;
|
|
458
|
+
}
|
|
459
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
460
|
+
if (value instanceof Map) return "new Map()";
|
|
461
|
+
if (value instanceof Set) return "new Set()";
|
|
462
|
+
if (Array.isArray(value)) return `[${value.map(item => carbonValueToJsExpression(item)).join(", ")}]`;
|
|
463
|
+
if (value && typeof value === "object") return JSON.stringify(exportCarbonValue(value), null, 4);
|
|
464
|
+
return JSON.stringify(value);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
export function typedArrayConstructor(name)
|
|
468
|
+
{
|
|
469
|
+
return TYPED_ARRAY_CTORS[name] || null;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function carbonTypeDefinitionForKind(kind)
|
|
473
|
+
{
|
|
474
|
+
const normalized = TYPE_ALIASES[kind] || kind;
|
|
475
|
+
return TYPE_DEFINITIONS[normalized] || Object.freeze({ kind: normalized, js: "*" });
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function mergeCarbonTypeDefinition(type)
|
|
479
|
+
{
|
|
480
|
+
const definition = carbonTypeDefinitionForKind(type.kind);
|
|
481
|
+
return Object.freeze({ ...definition, ...type, kind: definition.kind });
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
function uint8(value)
|
|
485
|
+
{
|
|
486
|
+
return Number(value) & 0xff;
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
function int8(value)
|
|
490
|
+
{
|
|
491
|
+
const result = uint8(value);
|
|
492
|
+
return result > 0x7f ? result - 0x100 : result;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function uint16(value)
|
|
496
|
+
{
|
|
497
|
+
return Number(value) & 0xffff;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function int16(value)
|
|
501
|
+
{
|
|
502
|
+
const result = uint16(value);
|
|
503
|
+
return result > 0x7fff ? result - 0x10000 : result;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function uint32(value)
|
|
507
|
+
{
|
|
508
|
+
return Number(value) >>> 0;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
function int32(value)
|
|
512
|
+
{
|
|
513
|
+
return Number(value) | 0;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
function uint64(value)
|
|
517
|
+
{
|
|
518
|
+
return toBigInt(value, false);
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
function int64(value)
|
|
522
|
+
{
|
|
523
|
+
return toBigInt(value, true);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
function float32(value)
|
|
527
|
+
{
|
|
528
|
+
const result = Number(value);
|
|
529
|
+
return Number.isFinite(result) ? result : 0;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
function float64(value)
|
|
533
|
+
{
|
|
534
|
+
const result = Number(value);
|
|
535
|
+
return Number.isFinite(result) ? result : 0;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
function toBigInt(value, signed)
|
|
539
|
+
{
|
|
540
|
+
let result = 0n;
|
|
541
|
+
if (typeof value === "bigint") result = value;
|
|
542
|
+
else if (typeof value === "number" && Number.isFinite(value)) result = BigInt(Math.trunc(value));
|
|
543
|
+
else if (typeof value === "string" && value.trim()) result = BigInt(value.trim());
|
|
544
|
+
|
|
545
|
+
// Clamp unsigned negatives but FALL THROUGH so safe-range values export
|
|
546
|
+
// as ordinary numbers (an early BigInt return here leaked '0' strings
|
|
547
|
+
// into values interchange - fixed 2026-07-23).
|
|
548
|
+
if (!signed && result < 0n) result = 0n;
|
|
549
|
+
|
|
550
|
+
// Safe-range 64-bit values stay ordinary numbers so a JSON round trip
|
|
551
|
+
// (GetValues → SetValues) reproduces the exported representation; BigInt
|
|
552
|
+
// is reserved for magnitudes JSON numbers cannot hold.
|
|
553
|
+
if (result >= MIN_SAFE_BIGINT && result <= MAX_SAFE_BIGINT) return Number(result);
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
const MAX_SAFE_BIGINT = BigInt(Number.MAX_SAFE_INTEGER);
|
|
558
|
+
|
|
559
|
+
const MIN_SAFE_BIGINT = BigInt(Number.MIN_SAFE_INTEGER);
|
|
560
|
+
|
|
561
|
+
function containerDescriptor(kind, cppType)
|
|
562
|
+
{
|
|
563
|
+
const elementCppType = extractTemplateArgument(cppType);
|
|
564
|
+
return Object.freeze({
|
|
565
|
+
kind,
|
|
566
|
+
js: kind === CARBON_TYPE.MAP ? "Map" : kind === CARBON_TYPE.SET ? "Set" : "Array",
|
|
567
|
+
cppType,
|
|
568
|
+
elementType: elementCppType ? inferCarbonTypeFromCpp(elementCppType) : undefined
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
function objectRefDescriptor(cppType)
|
|
573
|
+
{
|
|
574
|
+
return Object.freeze({ ...TYPE_DEFINITIONS[CARBON_TYPE.OBJECT_REF], cppType });
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
function rawStructDescriptor(cppType)
|
|
578
|
+
{
|
|
579
|
+
return Object.freeze({ ...TYPE_DEFINITIONS[CARBON_TYPE.RAW_STRUCT], cppType });
|
|
580
|
+
}
|
|
581
|
+
|
|
582
|
+
function extractTemplateArgument(cppType)
|
|
583
|
+
{
|
|
584
|
+
const match = String(cppType || "").match(/<(.+)>/);
|
|
585
|
+
return match ? match[1].trim() : null;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
function normalizeCppType(cppType)
|
|
589
|
+
{
|
|
590
|
+
return String(cppType || "")
|
|
591
|
+
.replace(/\bconst\b/g, "")
|
|
592
|
+
.replace(/&/g, "")
|
|
593
|
+
.replace(/\s+/g, " ")
|
|
594
|
+
.trim();
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
function normalizeCppTypeName(cppType)
|
|
598
|
+
{
|
|
599
|
+
return normalizeCppType(cppType)
|
|
600
|
+
.replace(/\s*\*+$/, "")
|
|
601
|
+
.replace(/\bstd::basic_string\s*<[^>]+>/g, "std::string")
|
|
602
|
+
.trim();
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function isRotationLike(name)
|
|
606
|
+
{
|
|
607
|
+
return /(?:^|[^A-Za-z0-9])(?:rotation|quat|quaternion)|(?:rotation|quat|quaternion)/i.test(String(name || ""));
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function isExpressionLike(name)
|
|
611
|
+
{
|
|
612
|
+
return /(?:^|[^A-Za-z0-9])expression(?:$|[^A-Za-z0-9])|expression/i.test(String(name || ""));
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
function normalizeMathValues(value, length, defaults)
|
|
616
|
+
{
|
|
617
|
+
const result = Array.isArray(defaults) ? defaults.slice() : new Array(length).fill(0);
|
|
618
|
+
const source = ArrayBuffer.isView(value) || Array.isArray(value) ? value : [];
|
|
619
|
+
for (let i = 0; i < result.length && i < source.length; i++)
|
|
620
|
+
{
|
|
621
|
+
result[i] = num.float32(source[i]);
|
|
622
|
+
}
|
|
623
|
+
return result;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
function formatJsNumber(value)
|
|
627
|
+
{
|
|
628
|
+
if (Object.is(value, -0)) return "-0";
|
|
629
|
+
return Number.isFinite(value) ? String(value) : "0";
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
function isSourceShapedObject(value)
|
|
633
|
+
{
|
|
634
|
+
return Boolean(value && typeof value === "object" && typeof value._sourceClassName === "string");
|
|
635
|
+
}
|
package/src/utils.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Convert a nullable, scalar, or array-like value into an array.
|
|
4
|
+
*
|
|
5
|
+
* Kept local so geometry helpers do not depend on the old ccpwgl `utils`
|
|
6
|
+
* webpack alias.
|
|
7
|
+
*
|
|
8
|
+
* @param {any} value Value to normalize.
|
|
9
|
+
* @returns {Array} Normalized array.
|
|
10
|
+
*/
|
|
11
|
+
export function toArray(value)
|
|
12
|
+
{
|
|
13
|
+
if (value === undefined || value === null) return [];
|
|
14
|
+
return Array.isArray(value) ? value : [ value ];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Copies array-like values into a writable indexed target.
|
|
19
|
+
*
|
|
20
|
+
* @template T
|
|
21
|
+
* @param {T} target Writable indexed target.
|
|
22
|
+
* @param {ArrayLike<any>} value Source values.
|
|
23
|
+
* @returns {T} The target.
|
|
24
|
+
*/
|
|
25
|
+
export function copyArrayLike(target, value)
|
|
26
|
+
{
|
|
27
|
+
const
|
|
28
|
+
length = Math.min(target.length, value.length),
|
|
29
|
+
source = new Array(length);
|
|
30
|
+
|
|
31
|
+
for (let i = 0; i < length; i++)
|
|
32
|
+
{
|
|
33
|
+
source[i] = value[i];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
for (let i = 0; i < length; i++)
|
|
37
|
+
{
|
|
38
|
+
target[i] = source[i];
|
|
39
|
+
}
|
|
40
|
+
return target;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Fills a writable indexed target with a scalar value.
|
|
45
|
+
*
|
|
46
|
+
* @template T
|
|
47
|
+
* @param {T} target Writable indexed target.
|
|
48
|
+
* @param {number} value Fill value.
|
|
49
|
+
* @returns {T} The target.
|
|
50
|
+
*/
|
|
51
|
+
export function fillArrayLike(target, value)
|
|
52
|
+
{
|
|
53
|
+
for (let i = 0; i < target.length; i++)
|
|
54
|
+
{
|
|
55
|
+
target[i] = value;
|
|
56
|
+
}
|
|
57
|
+
return target;
|
|
58
|
+
}
|