@carbonenginejs/runtime-resource 0.8.0 → 0.9.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 -21
- package/NOTICE +29 -29
- package/README.md +67 -548
- package/dist/CjsMotherLode.js +1271 -1271
- package/dist/CjsResMan.js +3005 -3005
- package/dist/CjsResManQueue.js +214 -214
- package/dist/CjsResource.js +566 -566
- package/dist/CjsResourceSource.js +59 -59
- package/dist/_virtual/_rollupPluginBabelHelpers.js +153 -153
- package/dist/format/CjsBlueReader.js +269 -269
- package/dist/format/CjsFormat.js +192 -192
- package/dist/format/CjsReader.js +18 -18
- package/dist/format/CjsResourceProbe.js +277 -277
- package/dist/format/payloadContract.js +173 -173
- package/dist/formats/black/CjsBlackFormat.js +278 -278
- package/dist/formats/black/core/CjsBlackBinaryReader.js +153 -153
- package/dist/formats/black/core/CjsBlackPropertyReaders.js +382 -382
- package/dist/formats/black/core/CjsBlackReader.js +639 -639
- package/dist/formats/black/core/CjsBlackSchemaRegistry.js +433 -433
- package/dist/formats/black/core/black-schema-v1-2026-07-11.json.js +4 -4
- package/dist/formats/black/core/blackConstants.js +7 -7
- package/dist/formats/black/core/blackDefinitions.js +10 -10
- package/dist/formats/black/core/blackEnums.js +6 -6
- package/dist/formats/black/core/blackSchema.js +3 -3
- package/dist/formats/black/core/blackVersion.js +22 -22
- package/dist/formats/black/core/helpers.js +182 -182
- package/dist/formats/black/core/schema.js +4 -4
- package/dist/formats/black/index.js +2 -2
- package/dist/formats/bnk/CjsBnkFormat.js +125 -125
- package/dist/formats/bnk/core/graph.js +140 -140
- package/dist/formats/bnk/core/helpers.js +409 -409
- package/dist/formats/bnk/core/musicNodes.js +489 -489
- package/dist/formats/bnk/core/soundbanksInfo.js +246 -246
- package/dist/formats/bnk/index.js +2 -2
- package/dist/formats/cmf/CjsCmfFormat.js +497 -497
- package/dist/formats/cmf/core/binary.js +118 -118
- package/dist/formats/cmf/core/buffers.js +233 -233
- package/dist/formats/cmf/core/constants.js +47 -47
- package/dist/formats/cmf/core/gr2Anim.js +453 -453
- package/dist/formats/cmf/core/helpers.js +287 -287
- package/dist/formats/cmf/core/pack.js +276 -276
- package/dist/formats/cmf/core/schema.js +364 -364
- package/dist/formats/cmf/core/shared.js +268 -268
- package/dist/formats/cmf/core/writer.js +517 -517
- package/dist/formats/cmf/index.js +2 -2
- package/dist/formats/dds/CjsDdsFormat.js +193 -193
- package/dist/formats/dds/core/bc6h.js +288 -288
- package/dist/formats/dds/core/bc7.js +251 -251
- package/dist/formats/dds/core/helpers.js +815 -815
- package/dist/formats/dds/index.js +2 -2
- package/dist/formats/fbx/CjsFbxFormat.js +266 -266
- package/dist/formats/fbx/core/helpers.js +3901 -3901
- package/dist/formats/fbx/index.js +2 -2
- package/dist/formats/flac/CjsFlacFormat.js +87 -87
- package/dist/formats/flac/core/helpers.js +295 -295
- package/dist/formats/flac/index.js +2 -2
- package/dist/formats/gif/CjsGifFormat.js +87 -87
- package/dist/formats/gif/core/helpers.js +360 -360
- package/dist/formats/gif/index.js +2 -2
- package/dist/formats/gltf/CjsGltfFormat.js +290 -290
- package/dist/formats/gltf/core/helpers.js +292 -292
- package/dist/formats/gltf/core/json.js +79 -79
- package/dist/formats/gltf/core/parser.js +666 -666
- package/dist/formats/gltf/core/targets.js +163 -163
- package/dist/formats/gltf/index.js +2 -2
- package/dist/formats/gr2/CjsGr2Format.js +46 -0
- package/dist/formats/gr2/CjsGr2Format.js.map +1 -0
- package/dist/formats/gr2/core/CjsFormatGr2.js +273 -0
- package/dist/formats/gr2/core/CjsFormatGr2.js.map +1 -0
- package/dist/formats/gr2/core/bitknit2.js +280 -0
- package/dist/formats/gr2/core/bitknit2.js.map +1 -0
- package/dist/formats/gr2/core/curves.js +1047 -0
- package/dist/formats/gr2/core/curves.js.map +1 -0
- package/dist/formats/gr2/core/gsf.js +72 -0
- package/dist/formats/gr2/core/gsf.js.map +1 -0
- package/dist/formats/gr2/core/helpers.js +332 -0
- package/dist/formats/gr2/core/helpers.js.map +1 -0
- package/dist/formats/gr2/core/json.js +622 -0
- package/dist/formats/gr2/core/json.js.map +1 -0
- package/dist/formats/gr2/core/oodle1.js +388 -0
- package/dist/formats/gr2/core/oodle1.js.map +1 -0
- package/dist/formats/gr2/core/reader.js +617 -0
- package/dist/formats/gr2/core/reader.js.map +1 -0
- package/dist/formats/gr2/core/tangents.js +48 -0
- package/dist/formats/gr2/core/tangents.js.map +1 -0
- package/dist/formats/gr2/core/targets.js +351 -0
- package/dist/formats/gr2/core/targets.js.map +1 -0
- package/dist/formats/gr2/index.js +3 -0
- package/dist/formats/gr2/index.js.map +1 -0
- package/dist/formats/index.js +30 -23
- package/dist/formats/index.js.map +1 -1
- package/dist/formats/jpeg/CjsJpegFormat.js +206 -206
- package/dist/formats/jpeg/core/helpers.js +350 -350
- package/dist/formats/jpeg/core/jpeg.js +377 -377
- package/dist/formats/jpeg/index.js +2 -2
- package/dist/formats/mp3/CjsMp3Format.js +192 -192
- package/dist/formats/mp3/core/helpers.js +338 -338
- package/dist/formats/mp3/index.js +2 -2
- package/dist/formats/mp4/CjsMp4Format.js +191 -191
- package/dist/formats/mp4/core/helpers.js +449 -449
- package/dist/formats/mp4/index.js +2 -2
- package/dist/formats/obj/CjsObjFormat.js +253 -253
- package/dist/formats/obj/core/helpers.js +573 -573
- package/dist/formats/obj/core/json.js +64 -64
- package/dist/formats/obj/core/parser.js +321 -321
- package/dist/formats/obj/index.js +2 -2
- package/dist/formats/ogg/CjsOggFormat.js +88 -88
- package/dist/formats/ogg/core/helpers.js +387 -387
- package/dist/formats/ogg/core/imdct.js +178 -178
- package/dist/formats/ogg/core/vorbis.js +999 -999
- package/dist/formats/ogg/index.js +2 -2
- package/dist/formats/png/CjsPngFormat.js +195 -195
- package/dist/formats/png/core/helpers.js +583 -583
- package/dist/formats/png/index.js +2 -2
- package/dist/formats/red/CjsRedFormat.js +261 -261
- package/dist/formats/red/core/CjsRedReader.js +194 -194
- package/dist/formats/red/core/blackDefinitions.js +3 -3
- package/dist/formats/red/core/helpers.js +139 -139
- package/dist/formats/red/core/redGraph.js +68 -68
- package/dist/formats/red/core/schema.js +4 -4
- package/dist/formats/red/index.js +2 -2
- package/dist/formats/stl/CjsStlFormat.js +365 -365
- package/dist/formats/stl/core/helpers.js +261 -261
- package/dist/formats/stl/core/json.js +51 -51
- package/dist/formats/stl/core/stl.js +629 -629
- package/dist/formats/stl/core/targets.js +163 -163
- package/dist/formats/stl/index.js +2 -2
- package/dist/formats/tga/CjsTgaFormat.js +192 -192
- package/dist/formats/tga/core/helpers.js +446 -446
- package/dist/formats/tga/index.js +2 -2
- package/dist/formats/wav/CjsWavFormat.js +192 -192
- package/dist/formats/wav/core/helpers.js +328 -328
- package/dist/formats/wav/index.js +2 -2
- package/dist/formats/webm/CjsWebmFormat.js +191 -191
- package/dist/formats/webm/core/helpers.js +537 -537
- package/dist/formats/webm/index.js +2 -2
- package/dist/formats/webp/CjsWebpFormat.js +86 -86
- package/dist/formats/webp/core/helpers.js +214 -214
- package/dist/formats/webp/index.js +2 -2
- package/dist/formats/wem/CjsWemFormat.js +241 -241
- package/dist/formats/wem/core/bitStream.js +259 -259
- package/dist/formats/wem/core/codebookLibrary.js +164 -164
- package/dist/formats/wem/core/helpers.js +417 -417
- package/dist/formats/wem/core/packedCodebooksAotuv603.js +30 -30
- package/dist/formats/wem/core/ptadpcm.js +77 -77
- package/dist/formats/wem/core/resolve.js +121 -121
- package/dist/formats/wem/core/wemToOgg.js +485 -485
- package/dist/formats/wem/index.js +2 -2
- package/dist/formats/yaml/CjsYamlFormat.js +83 -83
- package/dist/formats/yaml/core/CjsYamlReader.js +305 -305
- package/dist/formats/yaml/core/helpers.js +160 -160
- package/dist/formats/yaml/index.js +2 -2
- package/dist/index.js +49 -48
- package/dist/index.js.map +1 -1
- package/dist/resourcePath.js +18 -18
- package/dist/resourceStates.js +9 -9
- package/dist/resources/AudioGeometryResData.js +47 -47
- package/dist/resources/GStateBindingCallbackData.js +31 -31
- package/dist/resources/MeshDecalData.js +37 -37
- package/dist/resources/MeshDecalLodData.js +34 -34
- package/dist/resources/Tr2EffectRes.js +71 -71
- package/dist/resources/Tr2GrannyIntersectionResult.js +60 -60
- package/dist/resources/Tr2GrannyStateRes.js +44 -44
- package/dist/resources/Tr2ImageRes.js +114 -114
- package/dist/resources/Tr2LightProfileRes.js +40 -40
- package/dist/resources/Tr2MaterialArea.js +34 -34
- package/dist/resources/Tr2MaterialMesh.js +31 -31
- package/dist/resources/Tr2MaterialRes.js +34 -34
- package/dist/resources/Tr2ShaderPermutation.js +43 -43
- package/dist/resources/Tr2TextureLodManager.js +80 -80
- package/dist/resources/Tr2TextureLodUpdateRequest.js +37 -37
- package/dist/resources/Tr2TexturePackChannel.js +37 -37
- package/dist/resources/Tr2TexturePipeline.js +52 -52
- package/dist/resources/Tr2TexturePipelineParams.js +34 -34
- package/dist/resources/Tr2TexturePipelineStepCompress.js +40 -40
- package/dist/resources/Tr2TexturePipelineStepGenerateMips.js +22 -0
- package/dist/resources/Tr2TexturePipelineStepGenerateMips.js.map +1 -0
- package/dist/resources/Tr2TexturePipelineStepLimitSize.js +34 -34
- package/dist/resources/Tr2TexturePipelineStepLoad.js +31 -31
- package/dist/resources/Tr2TexturePipelineStepPack.js +43 -43
- package/dist/resources/TriGeometryRes.js +239 -239
- package/dist/resources/TriGeometryResAreaData.js +59 -59
- package/dist/resources/TriGeometryResJointData.js +38 -38
- package/dist/resources/TriGeometryResLodData.js +88 -88
- package/dist/resources/TriGeometryResMeshData.js +63 -63
- package/dist/resources/TriGeometryResSkeletonData.js +34 -34
- package/dist/resources/TriGrannyRes.js +43 -43
- package/dist/resources/TriJointBinding.js +38 -38
- package/dist/resources/TriMorphTargetGeometryConstants.js +46 -46
- package/dist/resources/TriRtGeometryConstants.js +88 -88
- package/dist/resources/TriTextureRes.js +304 -304
- package/dist/resources/enums.js +18 -18
- package/dist/resources/resourceBoundary.js +47 -47
- package/dist/resources/texturePipelineBehavior.js +308 -308
- package/dist/texture/CjsTextureArrayRes.js +406 -406
- package/dist/texture/CjsTextureParameterProxy.js +133 -133
- package/docs/README.md +69 -0
- package/docs/architecture.md +86 -0
- package/docs/concepts/resource-lifecycle.md +217 -0
- package/docs/formats/README.md +104 -0
- package/{FORMAT-PROVENANCE.md → docs/formats/provenance.md} +173 -155
- package/docs/formats/stl.md +37 -0
- package/docs/formats/wwise.md +44 -0
- package/docs/reference/events.md +92 -0
- package/docs/reference/motherlode-cache.md +244 -0
- package/docs/reference/queues.md +102 -0
- package/docs/reference/reload.md +107 -0
- package/docs/reference/texture-arrays.md +113 -0
- package/docs/reference/texture-pipeline.md +53 -0
- package/docs/roadmap.md +104 -0
- package/format-notices/black/LICENSE +21 -21
- package/format-notices/black/NOTICE +47 -47
- package/format-notices/bnk/LICENSE +21 -21
- package/format-notices/bnk/NOTICE +20 -20
- package/format-notices/cmf/LICENSE +21 -21
- package/format-notices/cmf/NOTICE +36 -36
- package/format-notices/dds/LICENSE +21 -21
- package/format-notices/dds/NOTICE +14 -14
- package/format-notices/fbx/LICENSE +21 -21
- package/format-notices/fbx/NOTICE +14 -14
- package/format-notices/flac/LICENSE +21 -21
- package/format-notices/flac/NOTICE +14 -14
- package/format-notices/gif/LICENSE +21 -21
- package/format-notices/gif/NOTICE +14 -14
- package/format-notices/gltf/LICENSE +21 -21
- package/format-notices/gltf/NOTICE +27 -27
- package/format-notices/gr2/LICENSE +21 -0
- package/format-notices/gr2/NOTICE +60 -0
- package/format-notices/gr2/THIRD-PARTY-NOTICES.md +93 -0
- package/format-notices/jpeg/LICENSE +21 -21
- package/format-notices/jpeg/NOTICE +14 -14
- package/format-notices/mp3/LICENSE +21 -21
- package/format-notices/mp3/NOTICE +14 -14
- package/format-notices/mp4/LICENSE +21 -21
- package/format-notices/mp4/NOTICE +14 -14
- package/format-notices/obj/LICENSE +21 -21
- package/format-notices/obj/NOTICE +26 -26
- package/format-notices/ogg/LICENSE +21 -21
- package/format-notices/ogg/NOTICE +28 -28
- package/format-notices/png/LICENSE +21 -21
- package/format-notices/png/NOTICE +14 -14
- package/format-notices/red/LICENSE +21 -21
- package/format-notices/red/NOTICE +31 -31
- package/format-notices/stl/LICENSE +21 -21
- package/format-notices/stl/NOTICE +21 -21
- package/format-notices/tga/LICENSE +21 -21
- package/format-notices/tga/NOTICE +14 -14
- package/format-notices/wav/LICENSE +21 -21
- package/format-notices/wav/NOTICE +14 -14
- package/format-notices/webm/LICENSE +21 -21
- package/format-notices/webm/NOTICE +14 -14
- package/format-notices/webp/LICENSE +21 -21
- package/format-notices/webp/NOTICE +14 -14
- package/format-notices/wem/LICENSE +57 -57
- package/format-notices/wem/NOTICE +33 -33
- package/format-notices/yaml/LICENSE +21 -21
- package/format-notices/yaml/NOTICE +44 -44
- package/package.json +52 -51
- package/resource-lifecycle.md +0 -679
|
@@ -1,276 +1,276 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* GPU-buffer packing for CMF writing.
|
|
3
|
-
*
|
|
4
|
-
* `buildCmfFromShared` (and hand-built graphs) carry deinterleaved vertex
|
|
5
|
-
* channels and index groups but no GPU bytes. This packer interleaves each
|
|
6
|
-
* LOD's channels per the mesh declaration, packs index groups, assigns
|
|
7
|
-
* unique buffer indices across the whole graph, and returns a graph + buffer
|
|
8
|
-
* list ready for `writeCmf`. Skeletons and animations must already be
|
|
9
|
-
* CMF-native shaped; GR2-shaped skeletons are rejected with a clear error
|
|
10
|
-
* (GR2 bone/track conversion is a separate adapter).
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const CHANNEL_NAMES = Object.freeze({
|
|
14
|
-
Position: "position",
|
|
15
|
-
Normal: "normal",
|
|
16
|
-
Tangent: "tangent",
|
|
17
|
-
Binormal: "binormal",
|
|
18
|
-
TexCoord: "texcoord",
|
|
19
|
-
Color: "color",
|
|
20
|
-
BoneIndices: "blendIndice",
|
|
21
|
-
BoneWeights: "blendWeight",
|
|
22
|
-
PackedTangent: "packedTangent",
|
|
23
|
-
PackedTangentLegacy: "packedTangentLegacy"
|
|
24
|
-
});
|
|
25
|
-
function packError(message) {
|
|
26
|
-
const error = new Error(`CMF pack: ${message}`);
|
|
27
|
-
error.code = "CJS_FORMAT_WRITE_ERROR";
|
|
28
|
-
return error;
|
|
29
|
-
}
|
|
30
|
-
function channelName(element) {
|
|
31
|
-
const base = CHANNEL_NAMES[element.usage];
|
|
32
|
-
if (!base) throw packError(`unknown vertex usage ${JSON.stringify(element.usage)}`);
|
|
33
|
-
if (element.usage === "TexCoord" || element.usage === "Color") return `${base}${element.usageIndex}`;
|
|
34
|
-
if (element.usageIndex > 0) return `${base}${element.usageIndex}`;
|
|
35
|
-
return base;
|
|
36
|
-
}
|
|
37
|
-
function elementTypeSize(type) {
|
|
38
|
-
switch (type) {
|
|
39
|
-
case "Float32":
|
|
40
|
-
return 4;
|
|
41
|
-
case "Float16":
|
|
42
|
-
case "UInt16Norm":
|
|
43
|
-
case "UInt16":
|
|
44
|
-
case "Int16Norm":
|
|
45
|
-
case "Int16":
|
|
46
|
-
return 2;
|
|
47
|
-
case "UInt8Norm":
|
|
48
|
-
case "UInt8":
|
|
49
|
-
case "Int8Norm":
|
|
50
|
-
case "Int8":
|
|
51
|
-
return 1;
|
|
52
|
-
default:
|
|
53
|
-
throw packError(`unsupported vertex element type ${JSON.stringify(type)}`);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function floatToHalf(value) {
|
|
57
|
-
if (Number.isNaN(value)) return 0x7e00;
|
|
58
|
-
if (value === Infinity) return 0x7c00;
|
|
59
|
-
if (value === -Infinity) return 0xfc00;
|
|
60
|
-
const sign = value < 0 || Object.is(value, -0) ? 0x8000 : 0;
|
|
61
|
-
let v = Math.abs(value);
|
|
62
|
-
if (v >= 65520) return sign | 0x7c00;
|
|
63
|
-
if (v < Math.pow(2, -24)) return sign;
|
|
64
|
-
if (v < Math.pow(2, -14)) {
|
|
65
|
-
return sign | Math.round(v / Math.pow(2, -24));
|
|
66
|
-
}
|
|
67
|
-
const exponent = Math.floor(Math.log2(v));
|
|
68
|
-
const mantissa = Math.round((v / Math.pow(2, exponent) - 1) * 1024);
|
|
69
|
-
if (mantissa === 1024) return sign | exponent + 16 << 10;
|
|
70
|
-
return sign | exponent + 15 << 10 | mantissa;
|
|
71
|
-
}
|
|
72
|
-
function writeComponent(view, offset, type, value) {
|
|
73
|
-
switch (type) {
|
|
74
|
-
case "Float32":
|
|
75
|
-
view.setFloat32(offset, value || 0, true);
|
|
76
|
-
break;
|
|
77
|
-
case "Float16":
|
|
78
|
-
view.setUint16(offset, floatToHalf(value || 0), true);
|
|
79
|
-
break;
|
|
80
|
-
case "UInt16Norm":
|
|
81
|
-
view.setUint16(offset, clampRound(value * 65535, 0, 65535), true);
|
|
82
|
-
break;
|
|
83
|
-
case "UInt16":
|
|
84
|
-
view.setUint16(offset, clampRound(value, 0, 65535), true);
|
|
85
|
-
break;
|
|
86
|
-
case "Int16Norm":
|
|
87
|
-
view.setInt16(offset, clampRound(value * 32767, -32767, 32767), true);
|
|
88
|
-
break;
|
|
89
|
-
case "Int16":
|
|
90
|
-
view.setInt16(offset, clampRound(value, -32768, 32767), true);
|
|
91
|
-
break;
|
|
92
|
-
case "UInt8Norm":
|
|
93
|
-
view.setUint8(offset, clampRound(value * 255, 0, 255));
|
|
94
|
-
break;
|
|
95
|
-
case "UInt8":
|
|
96
|
-
view.setUint8(offset, clampRound(value, 0, 255));
|
|
97
|
-
break;
|
|
98
|
-
case "Int8Norm":
|
|
99
|
-
view.setInt8(offset, clampRound(value * 127, -127, 127));
|
|
100
|
-
break;
|
|
101
|
-
case "Int8":
|
|
102
|
-
view.setInt8(offset, clampRound(value, -128, 127));
|
|
103
|
-
break;
|
|
104
|
-
default:
|
|
105
|
-
throw packError(`unsupported vertex element type ${JSON.stringify(type)}`);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
function clampRound(value, min, max) {
|
|
109
|
-
const rounded = Math.round(value || 0);
|
|
110
|
-
return rounded < min ? min : rounded > max ? max : rounded;
|
|
111
|
-
}
|
|
112
|
-
function vertexCountFor(decl, vertex) {
|
|
113
|
-
let count = 0;
|
|
114
|
-
for (const element of decl) {
|
|
115
|
-
const channel = vertex[channelName(element)];
|
|
116
|
-
if (!Array.isArray(channel) || channel.length === 0) continue;
|
|
117
|
-
const channelCount = Math.floor(channel.length / element.elementCount);
|
|
118
|
-
count = count === 0 ? channelCount : Math.min(count, channelCount);
|
|
119
|
-
}
|
|
120
|
-
return count;
|
|
121
|
-
}
|
|
122
|
-
function strideFor(decl) {
|
|
123
|
-
return decl.reduce((stride, element) => Math.max(stride, (element.offset || 0) + element.elementCount * elementTypeSize(element.type)), 0);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Interleave deinterleaved channels into vertex-buffer bytes per `decl`.
|
|
128
|
-
*
|
|
129
|
-
* @param {Array<object>} decl Vertex declaration.
|
|
130
|
-
* @param {object} vertex Channel-name-keyed flat arrays.
|
|
131
|
-
* @returns {object} `{ bytes, stride, count }`.
|
|
132
|
-
*/
|
|
133
|
-
function packVertexBuffer(decl, vertex) {
|
|
134
|
-
const stride = strideFor(decl);
|
|
135
|
-
const count = vertexCountFor(decl, vertex || {});
|
|
136
|
-
const bytes = new Uint8Array(count * stride);
|
|
137
|
-
const view = new DataView(bytes.buffer);
|
|
138
|
-
for (const element of decl) {
|
|
139
|
-
const channel = (vertex || {})[channelName(element)];
|
|
140
|
-
if (!Array.isArray(channel) || channel.length === 0) continue;
|
|
141
|
-
const size = elementTypeSize(element.type);
|
|
142
|
-
for (let i = 0; i < count; i++) {
|
|
143
|
-
const base = i * stride + (element.offset || 0);
|
|
144
|
-
for (let component = 0; component < element.elementCount; component++) {
|
|
145
|
-
writeComponent(view, base + component * size, element.type, channel[i * element.elementCount + component]);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return {
|
|
150
|
-
bytes,
|
|
151
|
-
stride,
|
|
152
|
-
count
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Concatenate index groups into index-buffer bytes.
|
|
158
|
-
*
|
|
159
|
-
* @param {Array<object>} groups Index groups with `faces` arrays.
|
|
160
|
-
* @returns {object} `{ bytes, stride, count }` (u16 unless any index needs u32).
|
|
161
|
-
*/
|
|
162
|
-
function packIndexBuffer(groups) {
|
|
163
|
-
const faces = [];
|
|
164
|
-
for (const group of groups || []) {
|
|
165
|
-
for (const index of group.faces || []) faces.push(index);
|
|
166
|
-
}
|
|
167
|
-
const wide = groups?.some(group => group.bytesPerIndex === 4) || faces.some(index => index > 0xffff);
|
|
168
|
-
const stride = wide ? 4 : 2;
|
|
169
|
-
const bytes = new Uint8Array(faces.length * stride);
|
|
170
|
-
const view = new DataView(bytes.buffer);
|
|
171
|
-
for (let i = 0; i < faces.length; i++) {
|
|
172
|
-
if (wide) view.setUint32(i * stride, faces[i], true);else view.setUint16(i * stride, faces[i], true);
|
|
173
|
-
}
|
|
174
|
-
return {
|
|
175
|
-
bytes,
|
|
176
|
-
stride,
|
|
177
|
-
count: faces.length
|
|
178
|
-
};
|
|
179
|
-
}
|
|
180
|
-
function assertCmfNativeSkeleton(skeleton) {
|
|
181
|
-
const bonesAreNames = Array.isArray(skeleton?.bones) && skeleton.bones.every(bone => typeof bone === "string");
|
|
182
|
-
if (!bonesAreNames) {
|
|
183
|
-
throw packError("skeletons must be CMF-native shaped (bones as name strings with parents/restTransforms); " + "GR2-shaped skeletons need conversion before writing");
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* Pack a channel-carrying CMF-native graph into a writable graph + buffers.
|
|
189
|
-
*
|
|
190
|
-
* Buffer indices are reassigned uniquely across all meshes/LODs/morph
|
|
191
|
-
* targets; BufferViews are rebuilt from the packed bytes.
|
|
192
|
-
*
|
|
193
|
-
* @param {object} graph CMF-native graph carrying `vertex`/`indices` channel data.
|
|
194
|
-
* @returns {object} `{ graph, buffers }` ready for `writeCmf`.
|
|
195
|
-
*/
|
|
196
|
-
function packGraphBuffers(graph) {
|
|
197
|
-
const buffers = [null];
|
|
198
|
-
const allocate = bytes => {
|
|
199
|
-
const index = buffers.length;
|
|
200
|
-
buffers.push({
|
|
201
|
-
index,
|
|
202
|
-
data: bytes
|
|
203
|
-
});
|
|
204
|
-
return index;
|
|
205
|
-
};
|
|
206
|
-
for (const skeleton of graph.skeletons || []) assertCmfNativeSkeleton(skeleton);
|
|
207
|
-
const meshes = (graph.meshes || []).map(mesh => {
|
|
208
|
-
const decl = mesh.decl || [];
|
|
209
|
-
const morphDecl = mesh.morphTargets?.decl || [];
|
|
210
|
-
const lods = (mesh.lods || []).map(lod => {
|
|
211
|
-
const vertexSource = lod.vertex ?? mesh.vertex ?? {};
|
|
212
|
-
const indexSource = lod.indices ?? mesh.indices ?? [];
|
|
213
|
-
const packedVb = packVertexBuffer(decl, vertexSource);
|
|
214
|
-
const packedIb = packIndexBuffer(indexSource);
|
|
215
|
-
const vb = packedVb.count ? {
|
|
216
|
-
index: allocate(packedVb.bytes),
|
|
217
|
-
offset: 0,
|
|
218
|
-
size: packedVb.bytes.byteLength,
|
|
219
|
-
stride: packedVb.stride
|
|
220
|
-
} : {
|
|
221
|
-
index: 0,
|
|
222
|
-
offset: 0,
|
|
223
|
-
size: 0,
|
|
224
|
-
stride: 0
|
|
225
|
-
};
|
|
226
|
-
const ib = packedIb.count ? {
|
|
227
|
-
index: allocate(packedIb.bytes),
|
|
228
|
-
offset: 0,
|
|
229
|
-
size: packedIb.bytes.byteLength,
|
|
230
|
-
stride: packedIb.stride
|
|
231
|
-
} : {
|
|
232
|
-
index: 0,
|
|
233
|
-
offset: 0,
|
|
234
|
-
size: 0,
|
|
235
|
-
stride: 0
|
|
236
|
-
};
|
|
237
|
-
const morphTargets = (lod.morphTargets || []).map(target => {
|
|
238
|
-
const packed = packVertexBuffer(morphDecl, target.vertex || {});
|
|
239
|
-
return {
|
|
240
|
-
vb: packed.count ? {
|
|
241
|
-
index: allocate(packed.bytes),
|
|
242
|
-
offset: 0,
|
|
243
|
-
size: packed.bytes.byteLength,
|
|
244
|
-
stride: packed.stride
|
|
245
|
-
} : {
|
|
246
|
-
index: 0,
|
|
247
|
-
offset: 0,
|
|
248
|
-
size: 0,
|
|
249
|
-
stride: 0
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
});
|
|
253
|
-
return {
|
|
254
|
-
vb,
|
|
255
|
-
ib,
|
|
256
|
-
areas: lod.areas || [],
|
|
257
|
-
morphTargets,
|
|
258
|
-
threshold: lod.threshold ?? 0xffffffff
|
|
259
|
-
};
|
|
260
|
-
});
|
|
261
|
-
return {
|
|
262
|
-
...mesh,
|
|
263
|
-
lods
|
|
264
|
-
};
|
|
265
|
-
});
|
|
266
|
-
return {
|
|
267
|
-
graph: {
|
|
268
|
-
...graph,
|
|
269
|
-
meshes
|
|
270
|
-
},
|
|
271
|
-
buffers
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
export { packGraphBuffers, packIndexBuffer, packVertexBuffer };
|
|
276
|
-
//# sourceMappingURL=pack.js.map
|
|
1
|
+
/**
|
|
2
|
+
* GPU-buffer packing for CMF writing.
|
|
3
|
+
*
|
|
4
|
+
* `buildCmfFromShared` (and hand-built graphs) carry deinterleaved vertex
|
|
5
|
+
* channels and index groups but no GPU bytes. This packer interleaves each
|
|
6
|
+
* LOD's channels per the mesh declaration, packs index groups, assigns
|
|
7
|
+
* unique buffer indices across the whole graph, and returns a graph + buffer
|
|
8
|
+
* list ready for `writeCmf`. Skeletons and animations must already be
|
|
9
|
+
* CMF-native shaped; GR2-shaped skeletons are rejected with a clear error
|
|
10
|
+
* (GR2 bone/track conversion is a separate adapter).
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const CHANNEL_NAMES = Object.freeze({
|
|
14
|
+
Position: "position",
|
|
15
|
+
Normal: "normal",
|
|
16
|
+
Tangent: "tangent",
|
|
17
|
+
Binormal: "binormal",
|
|
18
|
+
TexCoord: "texcoord",
|
|
19
|
+
Color: "color",
|
|
20
|
+
BoneIndices: "blendIndice",
|
|
21
|
+
BoneWeights: "blendWeight",
|
|
22
|
+
PackedTangent: "packedTangent",
|
|
23
|
+
PackedTangentLegacy: "packedTangentLegacy"
|
|
24
|
+
});
|
|
25
|
+
function packError(message) {
|
|
26
|
+
const error = new Error(`CMF pack: ${message}`);
|
|
27
|
+
error.code = "CJS_FORMAT_WRITE_ERROR";
|
|
28
|
+
return error;
|
|
29
|
+
}
|
|
30
|
+
function channelName(element) {
|
|
31
|
+
const base = CHANNEL_NAMES[element.usage];
|
|
32
|
+
if (!base) throw packError(`unknown vertex usage ${JSON.stringify(element.usage)}`);
|
|
33
|
+
if (element.usage === "TexCoord" || element.usage === "Color") return `${base}${element.usageIndex}`;
|
|
34
|
+
if (element.usageIndex > 0) return `${base}${element.usageIndex}`;
|
|
35
|
+
return base;
|
|
36
|
+
}
|
|
37
|
+
function elementTypeSize(type) {
|
|
38
|
+
switch (type) {
|
|
39
|
+
case "Float32":
|
|
40
|
+
return 4;
|
|
41
|
+
case "Float16":
|
|
42
|
+
case "UInt16Norm":
|
|
43
|
+
case "UInt16":
|
|
44
|
+
case "Int16Norm":
|
|
45
|
+
case "Int16":
|
|
46
|
+
return 2;
|
|
47
|
+
case "UInt8Norm":
|
|
48
|
+
case "UInt8":
|
|
49
|
+
case "Int8Norm":
|
|
50
|
+
case "Int8":
|
|
51
|
+
return 1;
|
|
52
|
+
default:
|
|
53
|
+
throw packError(`unsupported vertex element type ${JSON.stringify(type)}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function floatToHalf(value) {
|
|
57
|
+
if (Number.isNaN(value)) return 0x7e00;
|
|
58
|
+
if (value === Infinity) return 0x7c00;
|
|
59
|
+
if (value === -Infinity) return 0xfc00;
|
|
60
|
+
const sign = value < 0 || Object.is(value, -0) ? 0x8000 : 0;
|
|
61
|
+
let v = Math.abs(value);
|
|
62
|
+
if (v >= 65520) return sign | 0x7c00;
|
|
63
|
+
if (v < Math.pow(2, -24)) return sign;
|
|
64
|
+
if (v < Math.pow(2, -14)) {
|
|
65
|
+
return sign | Math.round(v / Math.pow(2, -24));
|
|
66
|
+
}
|
|
67
|
+
const exponent = Math.floor(Math.log2(v));
|
|
68
|
+
const mantissa = Math.round((v / Math.pow(2, exponent) - 1) * 1024);
|
|
69
|
+
if (mantissa === 1024) return sign | exponent + 16 << 10;
|
|
70
|
+
return sign | exponent + 15 << 10 | mantissa;
|
|
71
|
+
}
|
|
72
|
+
function writeComponent(view, offset, type, value) {
|
|
73
|
+
switch (type) {
|
|
74
|
+
case "Float32":
|
|
75
|
+
view.setFloat32(offset, value || 0, true);
|
|
76
|
+
break;
|
|
77
|
+
case "Float16":
|
|
78
|
+
view.setUint16(offset, floatToHalf(value || 0), true);
|
|
79
|
+
break;
|
|
80
|
+
case "UInt16Norm":
|
|
81
|
+
view.setUint16(offset, clampRound(value * 65535, 0, 65535), true);
|
|
82
|
+
break;
|
|
83
|
+
case "UInt16":
|
|
84
|
+
view.setUint16(offset, clampRound(value, 0, 65535), true);
|
|
85
|
+
break;
|
|
86
|
+
case "Int16Norm":
|
|
87
|
+
view.setInt16(offset, clampRound(value * 32767, -32767, 32767), true);
|
|
88
|
+
break;
|
|
89
|
+
case "Int16":
|
|
90
|
+
view.setInt16(offset, clampRound(value, -32768, 32767), true);
|
|
91
|
+
break;
|
|
92
|
+
case "UInt8Norm":
|
|
93
|
+
view.setUint8(offset, clampRound(value * 255, 0, 255));
|
|
94
|
+
break;
|
|
95
|
+
case "UInt8":
|
|
96
|
+
view.setUint8(offset, clampRound(value, 0, 255));
|
|
97
|
+
break;
|
|
98
|
+
case "Int8Norm":
|
|
99
|
+
view.setInt8(offset, clampRound(value * 127, -127, 127));
|
|
100
|
+
break;
|
|
101
|
+
case "Int8":
|
|
102
|
+
view.setInt8(offset, clampRound(value, -128, 127));
|
|
103
|
+
break;
|
|
104
|
+
default:
|
|
105
|
+
throw packError(`unsupported vertex element type ${JSON.stringify(type)}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function clampRound(value, min, max) {
|
|
109
|
+
const rounded = Math.round(value || 0);
|
|
110
|
+
return rounded < min ? min : rounded > max ? max : rounded;
|
|
111
|
+
}
|
|
112
|
+
function vertexCountFor(decl, vertex) {
|
|
113
|
+
let count = 0;
|
|
114
|
+
for (const element of decl) {
|
|
115
|
+
const channel = vertex[channelName(element)];
|
|
116
|
+
if (!Array.isArray(channel) || channel.length === 0) continue;
|
|
117
|
+
const channelCount = Math.floor(channel.length / element.elementCount);
|
|
118
|
+
count = count === 0 ? channelCount : Math.min(count, channelCount);
|
|
119
|
+
}
|
|
120
|
+
return count;
|
|
121
|
+
}
|
|
122
|
+
function strideFor(decl) {
|
|
123
|
+
return decl.reduce((stride, element) => Math.max(stride, (element.offset || 0) + element.elementCount * elementTypeSize(element.type)), 0);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Interleave deinterleaved channels into vertex-buffer bytes per `decl`.
|
|
128
|
+
*
|
|
129
|
+
* @param {Array<object>} decl Vertex declaration.
|
|
130
|
+
* @param {object} vertex Channel-name-keyed flat arrays.
|
|
131
|
+
* @returns {object} `{ bytes, stride, count }`.
|
|
132
|
+
*/
|
|
133
|
+
function packVertexBuffer(decl, vertex) {
|
|
134
|
+
const stride = strideFor(decl);
|
|
135
|
+
const count = vertexCountFor(decl, vertex || {});
|
|
136
|
+
const bytes = new Uint8Array(count * stride);
|
|
137
|
+
const view = new DataView(bytes.buffer);
|
|
138
|
+
for (const element of decl) {
|
|
139
|
+
const channel = (vertex || {})[channelName(element)];
|
|
140
|
+
if (!Array.isArray(channel) || channel.length === 0) continue;
|
|
141
|
+
const size = elementTypeSize(element.type);
|
|
142
|
+
for (let i = 0; i < count; i++) {
|
|
143
|
+
const base = i * stride + (element.offset || 0);
|
|
144
|
+
for (let component = 0; component < element.elementCount; component++) {
|
|
145
|
+
writeComponent(view, base + component * size, element.type, channel[i * element.elementCount + component]);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
bytes,
|
|
151
|
+
stride,
|
|
152
|
+
count
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Concatenate index groups into index-buffer bytes.
|
|
158
|
+
*
|
|
159
|
+
* @param {Array<object>} groups Index groups with `faces` arrays.
|
|
160
|
+
* @returns {object} `{ bytes, stride, count }` (u16 unless any index needs u32).
|
|
161
|
+
*/
|
|
162
|
+
function packIndexBuffer(groups) {
|
|
163
|
+
const faces = [];
|
|
164
|
+
for (const group of groups || []) {
|
|
165
|
+
for (const index of group.faces || []) faces.push(index);
|
|
166
|
+
}
|
|
167
|
+
const wide = groups?.some(group => group.bytesPerIndex === 4) || faces.some(index => index > 0xffff);
|
|
168
|
+
const stride = wide ? 4 : 2;
|
|
169
|
+
const bytes = new Uint8Array(faces.length * stride);
|
|
170
|
+
const view = new DataView(bytes.buffer);
|
|
171
|
+
for (let i = 0; i < faces.length; i++) {
|
|
172
|
+
if (wide) view.setUint32(i * stride, faces[i], true);else view.setUint16(i * stride, faces[i], true);
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
bytes,
|
|
176
|
+
stride,
|
|
177
|
+
count: faces.length
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function assertCmfNativeSkeleton(skeleton) {
|
|
181
|
+
const bonesAreNames = Array.isArray(skeleton?.bones) && skeleton.bones.every(bone => typeof bone === "string");
|
|
182
|
+
if (!bonesAreNames) {
|
|
183
|
+
throw packError("skeletons must be CMF-native shaped (bones as name strings with parents/restTransforms); " + "GR2-shaped skeletons need conversion before writing");
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Pack a channel-carrying CMF-native graph into a writable graph + buffers.
|
|
189
|
+
*
|
|
190
|
+
* Buffer indices are reassigned uniquely across all meshes/LODs/morph
|
|
191
|
+
* targets; BufferViews are rebuilt from the packed bytes.
|
|
192
|
+
*
|
|
193
|
+
* @param {object} graph CMF-native graph carrying `vertex`/`indices` channel data.
|
|
194
|
+
* @returns {object} `{ graph, buffers }` ready for `writeCmf`.
|
|
195
|
+
*/
|
|
196
|
+
function packGraphBuffers(graph) {
|
|
197
|
+
const buffers = [null];
|
|
198
|
+
const allocate = bytes => {
|
|
199
|
+
const index = buffers.length;
|
|
200
|
+
buffers.push({
|
|
201
|
+
index,
|
|
202
|
+
data: bytes
|
|
203
|
+
});
|
|
204
|
+
return index;
|
|
205
|
+
};
|
|
206
|
+
for (const skeleton of graph.skeletons || []) assertCmfNativeSkeleton(skeleton);
|
|
207
|
+
const meshes = (graph.meshes || []).map(mesh => {
|
|
208
|
+
const decl = mesh.decl || [];
|
|
209
|
+
const morphDecl = mesh.morphTargets?.decl || [];
|
|
210
|
+
const lods = (mesh.lods || []).map(lod => {
|
|
211
|
+
const vertexSource = lod.vertex ?? mesh.vertex ?? {};
|
|
212
|
+
const indexSource = lod.indices ?? mesh.indices ?? [];
|
|
213
|
+
const packedVb = packVertexBuffer(decl, vertexSource);
|
|
214
|
+
const packedIb = packIndexBuffer(indexSource);
|
|
215
|
+
const vb = packedVb.count ? {
|
|
216
|
+
index: allocate(packedVb.bytes),
|
|
217
|
+
offset: 0,
|
|
218
|
+
size: packedVb.bytes.byteLength,
|
|
219
|
+
stride: packedVb.stride
|
|
220
|
+
} : {
|
|
221
|
+
index: 0,
|
|
222
|
+
offset: 0,
|
|
223
|
+
size: 0,
|
|
224
|
+
stride: 0
|
|
225
|
+
};
|
|
226
|
+
const ib = packedIb.count ? {
|
|
227
|
+
index: allocate(packedIb.bytes),
|
|
228
|
+
offset: 0,
|
|
229
|
+
size: packedIb.bytes.byteLength,
|
|
230
|
+
stride: packedIb.stride
|
|
231
|
+
} : {
|
|
232
|
+
index: 0,
|
|
233
|
+
offset: 0,
|
|
234
|
+
size: 0,
|
|
235
|
+
stride: 0
|
|
236
|
+
};
|
|
237
|
+
const morphTargets = (lod.morphTargets || []).map(target => {
|
|
238
|
+
const packed = packVertexBuffer(morphDecl, target.vertex || {});
|
|
239
|
+
return {
|
|
240
|
+
vb: packed.count ? {
|
|
241
|
+
index: allocate(packed.bytes),
|
|
242
|
+
offset: 0,
|
|
243
|
+
size: packed.bytes.byteLength,
|
|
244
|
+
stride: packed.stride
|
|
245
|
+
} : {
|
|
246
|
+
index: 0,
|
|
247
|
+
offset: 0,
|
|
248
|
+
size: 0,
|
|
249
|
+
stride: 0
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
});
|
|
253
|
+
return {
|
|
254
|
+
vb,
|
|
255
|
+
ib,
|
|
256
|
+
areas: lod.areas || [],
|
|
257
|
+
morphTargets,
|
|
258
|
+
threshold: lod.threshold ?? 0xffffffff
|
|
259
|
+
};
|
|
260
|
+
});
|
|
261
|
+
return {
|
|
262
|
+
...mesh,
|
|
263
|
+
lods
|
|
264
|
+
};
|
|
265
|
+
});
|
|
266
|
+
return {
|
|
267
|
+
graph: {
|
|
268
|
+
...graph,
|
|
269
|
+
meshes
|
|
270
|
+
},
|
|
271
|
+
buffers
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export { packGraphBuffers, packIndexBuffer, packVertexBuffer };
|
|
276
|
+
//# sourceMappingURL=pack.js.map
|