@aura3d/assets 1.4.0 → 1.4.2

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 (69) hide show
  1. package/package.json +38 -5
  2. package/AGENTS.md +0 -46
  3. package/src/AdvancedAssetCorpus.ts +0 -454
  4. package/src/AssetBundleCacheFixtures.ts +0 -290
  5. package/src/AssetCache.ts +0 -76
  6. package/src/AssetCompatibility.ts +0 -224
  7. package/src/AssetCorpus.ts +0 -329
  8. package/src/AssetDependencyGraph.ts +0 -83
  9. package/src/AssetHandle.ts +0 -74
  10. package/src/AssetImportPreflight.ts +0 -179
  11. package/src/AssetInspection.ts +0 -706
  12. package/src/AssetLoader.ts +0 -36
  13. package/src/AssetManager.ts +0 -211
  14. package/src/AssetRegistry.ts +0 -44
  15. package/src/AssetRenderDefaults.ts +0 -36
  16. package/src/AudioLoader.ts +0 -41
  17. package/src/BlenderExportValidation.ts +0 -227
  18. package/src/CarConceptMaterialStability.ts +0 -1405
  19. package/src/EXRLoader.ts +0 -1
  20. package/src/ExternalParityGLTFCorpus.ts +0 -65
  21. package/src/GLTFAnimationRuntime.ts +0 -1416
  22. package/src/GLTFAutoFit.ts +0 -133
  23. package/src/GLTFCompressionDecoders.ts +0 -190
  24. package/src/GLTFExtensionSupport.ts +0 -138
  25. package/src/GLTFLoader.ts +0 -4060
  26. package/src/GLTFRenderResources.ts +0 -2270
  27. package/src/HDRLoader.ts +0 -1
  28. package/src/ImageLoader.ts +0 -52
  29. package/src/ImportPipeline.ts +0 -148
  30. package/src/KTX2BasisTextureTranscoder.ts +0 -225
  31. package/src/LoadContext.ts +0 -60
  32. package/src/MaterialLoader.ts +0 -166
  33. package/src/MeshOptimization.ts +0 -93
  34. package/src/OBJLoader.ts +0 -551
  35. package/src/SceneAnalysisFixtures.ts +0 -438
  36. package/src/SceneLoader.ts +0 -62
  37. package/src/ShaderLoader.ts +0 -30
  38. package/src/TextureLoader.ts +0 -30
  39. package/src/TexturePipeline.ts +0 -96
  40. package/src/TextureStreaming.ts +0 -20
  41. package/src/WorkerAssetJobs.ts +0 -56
  42. package/src/advanced-gallery/index.ts +0 -18
  43. package/src/asset-corpus/GLTFSceneLoader.ts +0 -9
  44. package/src/asset-corpus/ProductionAssetCorpus.ts +0 -230
  45. package/src/asset-corpus/ProductionAssetPipeline.ts +0 -5
  46. package/src/asset-corpus/ProductionGLTFRenderPipeline.ts +0 -182
  47. package/src/asset-corpus/ProductionHDRTextureLoader.ts +0 -2
  48. package/src/asset-corpus/ProductionKTX2TextureLoader.ts +0 -2
  49. package/src/asset-corpus/ProductionTextureLoader.ts +0 -2
  50. package/src/asset-corpus/index.ts +0 -29
  51. package/src/browser-index.ts +0 -229
  52. package/src/createRenderableScene.ts +0 -128
  53. package/src/index.ts +0 -325
  54. package/src/loadRenderableAsset.ts +0 -67
  55. package/src/loaders/CubeTextureLoader.ts +0 -8
  56. package/src/loaders/EXRLoader.ts +0 -10
  57. package/src/loaders/HDRLoader.ts +0 -7
  58. package/src/loaders/KTX2Loader.ts +0 -7
  59. package/src/loaders/LoaderDiagnostics.ts +0 -36
  60. package/src/loaders/MTLLoader.ts +0 -20
  61. package/src/loaders/OBJLoader.ts +0 -24
  62. package/src/loaders/TextureLoader.ts +0 -14
  63. package/src/loaders/ThreeCompatGLTFLoader.ts +0 -19
  64. package/src/loaders/index.ts +0 -14
  65. package/src/threejs-compatibility/ThreeCompatAssetProvenance.ts +0 -51
  66. package/src/threejs-compatibility/ThreeCompatAssetRegistry.ts +0 -61
  67. package/src/threejs-example-parity/index.ts +0 -262
  68. package/tests/assets.test.ts +0 -393
  69. package/tsconfig.json +0 -7
@@ -1,393 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import test from "node:test";
3
- import {
4
- AssetManager,
5
- computeAutoFitTransform,
6
- GLTFLoader,
7
- normalizeSkinWeights,
8
- OBJLoader,
9
- resolveGLTFClipName,
10
- type AssetLoader
11
- } from "../src/index";
12
-
13
- test("normalizeSkinWeights collapses degenerate (zero-sum) weights to a rigid binding", () => {
14
- const stats = { degenerate: 0, rescaled: 0 };
15
- assert.deepEqual(normalizeSkinWeights([0, 0, 0, 0], stats), [1, 0, 0, 0]);
16
- assert.equal(stats.degenerate, 1);
17
- assert.equal(stats.rescaled, 0);
18
- });
19
-
20
- test("normalizeSkinWeights rescales denormalized weights to sum 1 (FLOAT)", () => {
21
- const stats = { degenerate: 0, rescaled: 0 };
22
- const result = normalizeSkinWeights([2, 2, 0, 0], stats);
23
- assert.deepEqual(result, [0.5, 0.5, 0, 0]);
24
- assert.equal(stats.rescaled, 1);
25
- });
26
-
27
- test("normalizeSkinWeights rescales integer-encoded weights regardless of componentType scale", () => {
28
- // UNSIGNED_BYTE-style raw values (sum 255) and UNSIGNED_SHORT-style (sum 65535)
29
- // both normalize by proportion to the same result.
30
- assert.deepEqual(normalizeSkinWeights([255, 0, 0, 0]), [1, 0, 0, 0]);
31
- assert.deepEqual(normalizeSkinWeights([32767, 32768, 0, 0]).map((value) => Math.round(value * 100) / 100), [0.5, 0.5, 0, 0]);
32
- });
33
-
34
- test("normalizeSkinWeights clamps negative and non-finite components to zero", () => {
35
- assert.deepEqual(normalizeSkinWeights([1, -1, Number.NaN, Number.POSITIVE_INFINITY]), [1, 0, 0, 0]);
36
- });
37
-
38
- test("normalizeSkinWeights leaves already-normalized weights untouched", () => {
39
- const stats = { degenerate: 0, rescaled: 0 };
40
- assert.deepEqual(normalizeSkinWeights([0.6, 0.4, 0, 0], stats), [0.6, 0.4, 0, 0]);
41
- assert.equal(stats.degenerate, 0);
42
- assert.equal(stats.rescaled, 0);
43
- });
44
-
45
- test("resolveGLTFClipName matches exact (case/format-insensitive) first", () => {
46
- assert.equal(resolveGLTFClipName("Idle", ["Walk", "idle", "Run"]), "idle");
47
- assert.equal(resolveGLTFClipName("walk-cycle", ["Run", "Walk_Cycle"]), "Walk_Cycle");
48
- });
49
-
50
- test("resolveGLTFClipName resolves via synonym groups", () => {
51
- assert.equal(resolveGLTFClipName("idle", ["Loops", "Sprint"]), "Loops");
52
- assert.equal(resolveGLTFClipName("run", ["Loops", "Sprint"]), "Sprint");
53
- assert.equal(resolveGLTFClipName("wave", ["Greet", "Static"]), "Greet");
54
- });
55
-
56
- test("resolveGLTFClipName falls back to substring then first clip", () => {
57
- assert.equal(resolveGLTFClipName("walk", ["WalkForward", "Run"]), "WalkForward");
58
- assert.equal(resolveGLTFClipName("nonexistent", ["Take 001", "Other"]), "Take 001");
59
- assert.equal(resolveGLTFClipName("anything", []), undefined);
60
- });
61
-
62
- test("computeAutoFitTransform scales tall and tiny models to the target height", () => {
63
- const big = computeAutoFitTransform({ min: [-900, 0, -900], max: [900, 1821, 900] }, { targetHeight: 1.6 });
64
- assert.ok(Math.abs(big.fittedHeight - 1.6) < 1e-6);
65
- assert.ok(big.scale < 0.01);
66
-
67
- const tiny = computeAutoFitTransform({ min: [-0.5, 0, -0.5], max: [0.5, 1, 0.5] });
68
- assert.ok(Math.abs(tiny.fittedHeight - 1.6) < 1e-6);
69
- assert.ok(tiny.scale > 1);
70
- });
71
-
72
- test("computeAutoFitTransform recenters feet to y=0 and centers x/z", () => {
73
- const fit = computeAutoFitTransform({ min: [2, 4, 6], max: [4, 6, 8] }, { targetHeight: 2 });
74
- // height 2 -> scale 1; center (3,5,7), floor y=4
75
- assert.equal(fit.scale, 1);
76
- assert.deepEqual(fit.translation, [-3, -4, -7]);
77
- });
78
-
79
- test("computeAutoFitTransform applies z-up correction", () => {
80
- const fit = computeAutoFitTransform({ min: [-1, -1, 0], max: [1, 1, 4] }, { upAxis: "z", targetHeight: 4 });
81
- assert.equal(fit.upAxisCorrection, "z-to-y");
82
- // after z->y rotation the source z-extent (4) becomes height -> scale 1
83
- assert.ok(Math.abs(fit.fittedHeight - 4) < 1e-6);
84
- assert.notDeepEqual(fit.rotation, [0, 0, 0, 1]);
85
- });
86
-
87
- test("AssetManager shares duplicate in-flight loads and releases cached handles", async () => {
88
- let loads = 0;
89
- let disposes = 0;
90
- const loader: AssetLoader<{ readonly text: string }> = {
91
- type: "text",
92
- canLoad: () => true,
93
- async load(request) {
94
- loads += 1;
95
- await Promise.resolve();
96
- return { text: request.url };
97
- },
98
- dispose() {
99
- disposes += 1;
100
- }
101
- };
102
-
103
- const assets = new AssetManager({ baseUrl: "https://example.test/assets/" });
104
- assets.register(loader);
105
-
106
- const [a, b] = await Promise.all([assets.load("hero.txt", { type: "text" }), assets.load("hero.txt", { type: "text" })]);
107
- assert.equal(a, b);
108
- assert.equal(loads, 1);
109
- assert.equal(a.refCount, 2);
110
-
111
- await assets.release(a);
112
- assert.equal(disposes, 0);
113
- await assets.release(b);
114
- assert.equal(disposes, 1);
115
- assert.throws(() => a.value, /disposed/);
116
- });
117
-
118
- test("AssetManager retries after failed load instead of poisoning cache", async () => {
119
- let attempts = 0;
120
- const loader: AssetLoader<string> = {
121
- type: "text",
122
- canLoad: () => true,
123
- load() {
124
- attempts += 1;
125
- if (attempts === 1) {
126
- throw new Error("boom");
127
- }
128
- return "ok";
129
- }
130
- };
131
-
132
- const assets = new AssetManager();
133
- assets.register(loader);
134
-
135
- await assert.rejects(() => assets.load("retry.txt", { type: "text" }), /Failed to load asset/);
136
- const handle = await assets.load<string>("retry.txt", { type: "text" });
137
- assert.equal(handle.value, "ok");
138
- assert.equal(attempts, 2);
139
- });
140
-
141
- test("AssetManager releases dependencies through the dependency graph", async () => {
142
- const disposed: string[] = [];
143
- const leaf: AssetLoader<string> = {
144
- type: "leaf",
145
- canLoad: (request) => request.url.endsWith(".leaf"),
146
- load: (request) => request.url,
147
- dispose: (value) => {
148
- disposed.push(value);
149
- }
150
- };
151
- const parent: AssetLoader<string> = {
152
- type: "parent",
153
- canLoad: (request) => request.url.endsWith(".parent"),
154
- dependencies: () => ["child.leaf"],
155
- load: (request) => request.url,
156
- dispose: (value) => {
157
- disposed.push(value);
158
- }
159
- };
160
- const assets = new AssetManager();
161
- assets.register(leaf);
162
- assets.register(parent);
163
-
164
- const handle = await assets.load("root.parent", { type: "parent" });
165
- await assets.release(handle);
166
-
167
- assert.deepEqual(disposed.sort(), ["child.leaf", "root.parent"]);
168
- });
169
-
170
- test("GLTFLoader loads a triangle fixture into geometry and scene data", async () => {
171
- const buffer = Buffer.alloc(44);
172
- new Float32Array(buffer.buffer, buffer.byteOffset, 9).set([-0.5, -0.5, 0, 0.5, -0.5, 0, 0, 0.5, 0]);
173
- new Uint16Array(buffer.buffer, buffer.byteOffset + 36, 3).set([0, 1, 2]);
174
- const gltf = {
175
- asset: { version: "2.0" },
176
- buffers: [{ uri: `data:application/octet-stream;base64,${buffer.toString("base64")}`, byteLength: 44 }],
177
- bufferViews: [
178
- { buffer: 0, byteOffset: 0, byteLength: 36 },
179
- { buffer: 0, byteOffset: 36, byteLength: 6 }
180
- ],
181
- accessors: [
182
- { bufferView: 0, componentType: 5126, count: 3, type: "VEC3" },
183
- { bufferView: 1, componentType: 5123, count: 3, type: "SCALAR" }
184
- ],
185
- materials: [{ name: "mat" }],
186
- meshes: [{ name: "tri", primitives: [{ attributes: { POSITION: 0 }, indices: 1, material: 0 }] }],
187
- nodes: [{ name: "triangle", mesh: 0 }],
188
- scenes: [{ nodes: [0] }],
189
- scene: 0
190
- };
191
- const url = `data:model/gltf+json,${encodeURIComponent(JSON.stringify(gltf))}`;
192
- const asset = await new GLTFLoader().load({ url }, { throwIfAborted: () => undefined } as never);
193
-
194
- assert.equal(asset.meshes.length, 1);
195
- assert.equal(asset.meshes[0]?.geometry.vertexCount, 3);
196
- assert.equal(asset.meshes[0]?.positions.length, 3);
197
- assert.deepEqual(asset.meshes[0]?.indices, [0, 1, 2]);
198
- assert.equal(asset.createScene().collectRenderables().length, 1);
199
- });
200
-
201
- test("GLTFLoader loads a binary GLB fixture with a BIN chunk", async () => {
202
- const binary = Buffer.alloc(44);
203
- new Float32Array(binary.buffer, binary.byteOffset, 9).set([-1, 0, 0, 1, 0, 0, 0, 1, 0]);
204
- new Uint16Array(binary.buffer, binary.byteOffset + 36, 3).set([0, 1, 2]);
205
- const gltf = {
206
- asset: { version: "2.0" },
207
- buffers: [{ byteLength: 44 }],
208
- bufferViews: [
209
- { buffer: 0, byteOffset: 0, byteLength: 36 },
210
- { buffer: 0, byteOffset: 36, byteLength: 6 }
211
- ],
212
- accessors: [
213
- { bufferView: 0, componentType: 5126, count: 3, type: "VEC3" },
214
- { bufferView: 1, componentType: 5123, count: 3, type: "SCALAR" }
215
- ],
216
- meshes: [{ name: "glb-triangle", primitives: [{ attributes: { POSITION: 0 }, indices: 1 }] }],
217
- nodes: [{ name: "glb-node", mesh: 0 }],
218
- scenes: [{ nodes: [0] }]
219
- };
220
- const url = `data:model/gltf-binary;base64,${createGLB(gltf, binary).toString("base64")}`;
221
-
222
- const asset = await new GLTFLoader().load({ url }, { throwIfAborted: () => undefined } as never);
223
-
224
- assert.equal(asset.meshes[0]?.name, "glb-triangle");
225
- assert.equal(asset.meshes[0]?.geometry.indexCount, 3);
226
- assert.deepEqual(asset.meshes[0]?.positions[2], [0, 1, 0]);
227
- assert.equal(asset.createScene().findByName("glb-node").length, 1);
228
- });
229
-
230
- test("OBJLoader parses bounded geometry into the glTF render-resource path", async () => {
231
- const obj = [
232
- "v -0.5 -0.5 0",
233
- "v 0.5 -0.5 0",
234
- "v 0.5 0.5 0",
235
- "v -0.5 0.5 0",
236
- "vt 0 0",
237
- "vt 1 0",
238
- "vt 1 1",
239
- "vt 0 1",
240
- "f 1/1 2/2 3/3 4/4"
241
- ].join("\n");
242
- const url = `data:text/plain,${encodeURIComponent(obj)}`;
243
- const asset = await new OBJLoader().load({ url, type: "obj" }, { throwIfAborted: () => undefined } as never);
244
-
245
- assert.equal(asset.url, url);
246
- assert.equal(asset.meshes.length, 1);
247
- assert.equal(asset.meshes[0]?.geometry.vertexCount, 6);
248
- assert.equal(asset.meshes[0]?.geometry.indexCount, 6);
249
- assert.equal(asset.meshes[0]?.texcoords.length, 6);
250
- assert.equal(asset.meshes[0]?.normals.length, 6);
251
- assert.deepEqual(asset.meshes[0]?.geometry.bounds.min, [-0.5, -0.5, 0]);
252
- assert.deepEqual(asset.meshes[0]?.geometry.bounds.max, [0.5, 0.5, 0]);
253
- assert(asset.loaderDiagnostics.features.includes("obj-native-import"));
254
- assert(asset.loaderDiagnostics.features.includes("obj-generated-normals"));
255
- assert.equal(asset.createScene().collectRenderables().length, 1);
256
- });
257
-
258
- test("OBJLoader preserves mtllib/usemtl material groups through glTF primitives", async () => {
259
- const obj = [
260
- "mtllib sample.mtl",
261
- "v -0.5 -0.5 0",
262
- "v 0.5 -0.5 0",
263
- "v 0.5 0.5 0",
264
- "v -0.5 0.5 0",
265
- "usemtl amber",
266
- "f 1 2 3",
267
- "usemtl blue",
268
- "f 1 3 4"
269
- ].join("\n");
270
- const mtl = [
271
- "newmtl amber",
272
- "Kd 1.0 0.62 0.14",
273
- "Ns 64",
274
- "newmtl blue",
275
- "Kd 0.1 0.35 0.9",
276
- "d 0.75"
277
- ].join("\n");
278
- const url = `data:text/plain,${encodeURIComponent(obj)}`;
279
- const request = { url, type: "obj", materialLibraries: { "sample.mtl": mtl } };
280
- const asset = await new OBJLoader().load(request, { throwIfAborted: () => undefined } as never);
281
-
282
- assert.equal(asset.materials.length, 2);
283
- assert.deepEqual(asset.materials.map((material) => material.name), ["amber", "blue"]);
284
- assert.deepEqual(asset.materials[0]?.baseColorFactor, [1, 0.62, 0.14, 1]);
285
- assert.deepEqual(asset.materials[1]?.baseColorFactor, [0.1, 0.35, 0.9, 0.75]);
286
- assert.equal(asset.materials[1]?.alphaMode, "BLEND");
287
- assert.equal(asset.meshes.length, 2);
288
- assert.deepEqual(asset.meshes.map((mesh) => mesh.material), ["amber", "blue"]);
289
- assert(asset.loaderDiagnostics.features.includes("obj-mtllib"));
290
- assert(asset.loaderDiagnostics.features.includes("obj-multi-material"));
291
- assert.equal(asset.createScene().collectRenderables().length, 2);
292
- });
293
-
294
- test("GLTFLoader extracts material texture metadata and embedded image bytes from GLB", async () => {
295
- const meshBytes = Buffer.alloc(68);
296
- new Float32Array(meshBytes.buffer, meshBytes.byteOffset, 9).set([-1, 0, 0, 1, 0, 0, 0, 1, 0]);
297
- new Uint16Array(meshBytes.buffer, meshBytes.byteOffset + 36, 3).set([0, 1, 2]);
298
- new Float32Array(meshBytes.buffer, meshBytes.byteOffset + 44, 6).set([0, 0, 1, 0, 0.5, 1]);
299
- const imageBytes = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
300
- const binary = Buffer.concat([meshBytes, imageBytes]);
301
- const gltf = {
302
- asset: { version: "2.0" },
303
- buffers: [{ byteLength: binary.byteLength }],
304
- bufferViews: [
305
- { buffer: 0, byteOffset: 0, byteLength: 36 },
306
- { buffer: 0, byteOffset: 36, byteLength: 6 },
307
- { buffer: 0, byteOffset: 44, byteLength: 24 },
308
- { buffer: 0, byteOffset: 68, byteLength: imageBytes.byteLength }
309
- ],
310
- accessors: [
311
- { bufferView: 0, componentType: 5126, count: 3, type: "VEC3" },
312
- { bufferView: 1, componentType: 5123, count: 3, type: "SCALAR" },
313
- { bufferView: 2, componentType: 5126, count: 3, type: "VEC2" }
314
- ],
315
- images: [{ name: "embedded-base-color", bufferView: 3, mimeType: "image/png" }],
316
- samplers: [{ name: "linear-repeat", magFilter: 9729, minFilter: 9729, wrapS: 10497, wrapT: 10497 }],
317
- textures: [{ name: "base-color-texture", source: 0, sampler: 0 }],
318
- materials: [
319
- {
320
- name: "pbr-material",
321
- pbrMetallicRoughness: {
322
- baseColorFactor: [0.25, 0.5, 0.75, 1],
323
- baseColorTexture: { index: 0, texCoord: 1 },
324
- metallicFactor: 0.2,
325
- roughnessFactor: 0.8
326
- },
327
- doubleSided: true
328
- }
329
- ],
330
- meshes: [{ name: "textured-triangle", primitives: [{ attributes: { POSITION: 0, TEXCOORD_1: 2 }, indices: 1, material: 0 }] }],
331
- nodes: [{ name: "textured-node", mesh: 0 }],
332
- scenes: [{ nodes: [0] }]
333
- };
334
- const url = `data:model/gltf-binary;base64,${createGLB(gltf, binary).toString("base64")}`;
335
-
336
- const asset = await new GLTFLoader().load({ url }, { throwIfAborted: () => undefined } as never);
337
-
338
- assert.equal(asset.images[0]?.mimeType, "image/png");
339
- assert.deepEqual([...new Uint8Array(asset.images[0]?.data ?? new ArrayBuffer(0))], [...imageBytes]);
340
- assert.deepEqual(asset.materials[0]?.baseColorTexture, { texture: 0, image: 0, texCoord: 1 });
341
- assert.equal(asset.meshes[0]?.material, "pbr-material");
342
- });
343
-
344
- test("GLTFLoader rejects missing material texture references", async () => {
345
- const buffer = Buffer.alloc(36);
346
- new Float32Array(buffer.buffer, buffer.byteOffset, 9).set([-1, 0, 0, 1, 0, 0, 0, 1, 0]);
347
- const gltf = {
348
- asset: { version: "2.0" },
349
- buffers: [{ uri: `data:application/octet-stream;base64,${buffer.toString("base64")}`, byteLength: 36 }],
350
- bufferViews: [{ buffer: 0, byteOffset: 0, byteLength: 36 }],
351
- accessors: [{ bufferView: 0, componentType: 5126, count: 3, type: "VEC3" }],
352
- materials: [{ pbrMetallicRoughness: { baseColorTexture: { index: 4 } } }],
353
- meshes: [{ primitives: [{ attributes: { POSITION: 0 }, material: 0 }] }]
354
- };
355
- const url = `data:model/gltf+json,${encodeURIComponent(JSON.stringify(gltf))}`;
356
-
357
- await assert.rejects(
358
- () => new GLTFLoader().load({ url }, { throwIfAborted: () => undefined } as never),
359
- /baseColorTexture references missing texture 4/
360
- );
361
- });
362
-
363
- function createGLB(json: unknown, binary: Buffer): Buffer {
364
- const jsonBytes = pad4(Buffer.from(JSON.stringify(json), "utf8"), 0x20);
365
- const binaryBytes = pad4(binary, 0);
366
- const totalLength = 12 + 8 + jsonBytes.byteLength + 8 + binaryBytes.byteLength;
367
- const glb = Buffer.alloc(totalLength);
368
- let offset = 0;
369
- glb.writeUInt32LE(0x46546c67, offset);
370
- offset += 4;
371
- glb.writeUInt32LE(2, offset);
372
- offset += 4;
373
- glb.writeUInt32LE(totalLength, offset);
374
- offset += 4;
375
- glb.writeUInt32LE(jsonBytes.byteLength, offset);
376
- offset += 4;
377
- glb.writeUInt32LE(0x4e4f534a, offset);
378
- offset += 4;
379
- jsonBytes.copy(glb, offset);
380
- offset += jsonBytes.byteLength;
381
- glb.writeUInt32LE(binaryBytes.byteLength, offset);
382
- offset += 4;
383
- glb.writeUInt32LE(0x004e4942, offset);
384
- offset += 4;
385
- binaryBytes.copy(glb, offset);
386
- return glb;
387
- }
388
-
389
- function pad4(buffer: Buffer, fill: number): Buffer {
390
- const remainder = buffer.byteLength % 4;
391
- if (remainder === 0) return buffer;
392
- return Buffer.concat([buffer, Buffer.alloc(4 - remainder, fill)]);
393
- }
package/tsconfig.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "noEmit": true
5
- },
6
- "include": ["src/**/*.ts"]
7
- }