@stowkit/three-loader 0.1.21 → 0.1.23

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/README.md CHANGED
@@ -40,6 +40,7 @@ function animate() {
40
40
  - ✅ **Animations** - Skeletal animations with automatic mixer setup
41
41
  - ✅ **Textures** - KTX2/Basis Universal GPU-compressed textures
42
42
  - ✅ **Audio** - OGG/MP3 audio with Three.js Audio integration
43
+ - ✅ **Multiple Packs** - Load multiple .stow files simultaneously with isolated state
43
44
  - ✅ **WASM Parsing** - All binary parsing done in WASM for performance
44
45
  - ✅ **Type Safe** - Full TypeScript support
45
46
  - ✅ **Zero Config** - Works out of the box
@@ -304,6 +305,39 @@ function animate() {
304
305
  animate();
305
306
  ```
306
307
 
308
+ ## Loading Multiple Packs
309
+
310
+ Each pack is fully isolated with its own state. You can load multiple packs simultaneously without any interference:
311
+
312
+ ```typescript
313
+ // Load multiple packs at once
314
+ const [environmentPack, characterPack, audioPack] = await Promise.all([
315
+ StowKitLoader.load('environment.stow'),
316
+ StowKitLoader.load('characters.stow'),
317
+ StowKitLoader.load('audio.stow')
318
+ ]);
319
+
320
+ // Load assets from different packs
321
+ const level = await environmentPack.loadMesh('level1');
322
+ const player = await characterPack.loadSkinnedMesh('player');
323
+ const bgm = await audioPack.loadAudio('theme', listener);
324
+
325
+ scene.add(level);
326
+ scene.add(player);
327
+ bgm.play();
328
+
329
+ // Each pack maintains its own asset catalog
330
+ console.log(`Environment: ${environmentPack.getAssetCount()} assets`);
331
+ console.log(`Characters: ${characterPack.getAssetCount()} assets`);
332
+ console.log(`Audio: ${audioPack.getAssetCount()} assets`);
333
+ ```
334
+
335
+ **Note:** Each pack creates its own WASM instance for isolated state. Dispose packs when no longer needed:
336
+
337
+ ```typescript
338
+ environmentPack.dispose();
339
+ ```
340
+
307
341
  ## Asset Types
308
342
 
309
343
  ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"MeshParser.d.ts","sourceRoot":"","sources":["../src/MeshParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,UAAU;IAEnB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY;IAyBxD;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG;QAClE,QAAQ,EAAE,YAAY,CAAC;QACvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;QAC/B,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5B,YAAY,EAAE,YAAY,EAAE,CAAC;QAC7B,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,WAAW,EAAE,WAAW,CAAC;KAC5B;IA4LD;;OAEG;WACU,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC;IAyCrI;;OAEG;WACU,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IA2FtJ;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;CAK5B"}
1
+ {"version":3,"file":"MeshParser.d.ts","sourceRoot":"","sources":["../src/MeshParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AAExE,MAAM,WAAW,gBAAgB;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,EAAE,MAAM,CAAC;IAC/B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,qBAAqB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,YAAY;IACzB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,UAAU;IAEnB;;OAEG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE,UAAU,GAAG,YAAY;IAyBxD;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,GAAG;QAClE,QAAQ,EAAE,YAAY,CAAC;QACvB,UAAU,EAAE,gBAAgB,EAAE,CAAC;QAC/B,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC5B,YAAY,EAAE,YAAY,EAAE,CAAC;QAC7B,KAAK,EAAE,IAAI,EAAE,CAAC;QACd,WAAW,EAAE,WAAW,CAAC;KAC5B;IAwLD;;OAEG;WACU,cAAc,CAAC,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC;IAwCrI;;OAEG;WACU,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,OAAO,UAAU,CAAC,aAAa,CAAC,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;IAuFtJ;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,UAAU;CAK5B"}
@@ -28,10 +28,10 @@ export interface StowKitLoaderOptions {
28
28
  * ```
29
29
  */
30
30
  export declare class StowKitLoader {
31
- private static reader;
32
31
  private static ktx2Loader;
33
32
  private static dracoLoader;
34
33
  private static initialized;
34
+ private static wasmPath;
35
35
  /**
36
36
  * Load a .stow pack file from a URL
37
37
  */
@@ -1 +1 @@
1
- {"version":3,"file":"StowKitLoader.d.ts","sourceRoot":"","sources":["../src/StowKitLoader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAC,MAAM,CAA8B;IACnD,OAAO,CAAC,MAAM,CAAC,UAAU,CAA2B;IACpD,OAAO,CAAC,MAAM,CAAC,WAAW,CAA4B;IACtD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IAEnC;;OAEG;WACU,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAqBpF;;OAEG;WACU,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAyBlH;;OAEG;mBACkB,UAAU;CAwBlC"}
1
+ {"version":3,"file":"StowKitLoader.d.ts","sourceRoot":"","sources":["../src/StowKitLoader.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAA2B;IACpD,OAAO,CAAC,MAAM,CAAC,WAAW,CAA4B;IACtD,OAAO,CAAC,MAAM,CAAC,WAAW,CAAS;IACnC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0C;IAEjE;;OAEG;WACU,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IAuBpF;;OAEG;WACU,cAAc,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,WAAW,CAAC;IA2BlH;;OAEG;mBACkB,UAAU;CAoBlC"}
@@ -123,18 +123,14 @@ class MeshParser {
123
123
  }
124
124
  // Parse mesh indices
125
125
  const totalMeshRefs = nodes.reduce((sum, node) => sum + node.meshCount, 0);
126
- console.log(`Parsing ${totalMeshRefs} mesh indices at offset ${offset}`);
127
126
  const meshIndices = new Uint32Array(totalMeshRefs);
128
127
  for (let i = 0; i < totalMeshRefs; i++) {
129
128
  if (offset + (i + 1) * 4 > sourceBlob.length) {
130
- console.warn(`Data truncated at mesh index ${i}/${totalMeshRefs}`);
131
129
  break;
132
130
  }
133
131
  meshIndices[i] = metaView.getUint32(offset + i * 4, true);
134
- console.log(` meshIndices[${i}] = ${meshIndices[i]}`);
135
132
  }
136
133
  offset += totalMeshRefs * 4;
137
- console.log(`After mesh indices, offset = ${offset}`);
138
134
  // Second pass: read material properties
139
135
  // MaterialPropertyValue: field_name[64] + value[4*4=16] + texture_id[64] = 144 bytes
140
136
  for (let i = 0; i < materialData.length; i++) {
@@ -213,7 +209,6 @@ class MeshParser {
213
209
  resolve(decoded);
214
210
  }, undefined, (error) => {
215
211
  URL.revokeObjectURL(url);
216
- console.error('Draco decode failed:', error);
217
212
  reject(new Error(`Failed to decode Draco geometry: ${error}`));
218
213
  });
219
214
  });
@@ -251,7 +246,6 @@ class MeshParser {
251
246
  material = materials[geoInfo.materialIndex];
252
247
  }
253
248
  else {
254
- console.warn(` Material index ${geoInfo.materialIndex} out of bounds, using default`);
255
249
  material = new THREE.MeshStandardMaterial({
256
250
  color: new THREE.Color(0.8, 0.8, 0.8),
257
251
  roughness: 0.5,
@@ -262,9 +256,6 @@ class MeshParser {
262
256
  const mesh = new THREE.Mesh(geometry, material);
263
257
  obj.add(mesh);
264
258
  }
265
- else {
266
- console.error(`Mesh index ${meshIndex} out of bounds (${geometries.length} geometries available)`);
267
- }
268
259
  }
269
260
  nodeObjects.push(obj);
270
261
  }
@@ -290,7 +281,6 @@ class MeshParser {
290
281
  material = materials[geoInfo.materialIndex];
291
282
  }
292
283
  else {
293
- console.warn(` Material index ${geoInfo.materialIndex} out of bounds, using default`);
294
284
  material = new THREE.MeshStandardMaterial({
295
285
  color: new THREE.Color(0.8, 0.8, 0.8),
296
286
  roughness: 0.5,
@@ -1063,10 +1053,12 @@ class StowKitLoader {
1063
1053
  throw new Error(`Failed to fetch ${url}: ${response.statusText}`);
1064
1054
  }
1065
1055
  const arrayBuffer = await response.arrayBuffer();
1066
- // Open pack
1067
- await this.reader.open(arrayBuffer);
1068
- // Return pack wrapper
1069
- return new StowKitPack(this.reader, this.ktx2Loader, this.dracoLoader);
1056
+ // Create a new reader instance for this pack
1057
+ const reader = new StowKitReader(this.wasmPath);
1058
+ await reader.init();
1059
+ await reader.open(arrayBuffer);
1060
+ // Return pack wrapper with its own dedicated reader
1061
+ return new StowKitPack(reader, this.ktx2Loader, this.dracoLoader);
1070
1062
  }
1071
1063
  /**
1072
1064
  * Load a .stow pack from memory (ArrayBuffer, Blob, or File)
@@ -1090,25 +1082,24 @@ class StowKitLoader {
1090
1082
  else {
1091
1083
  throw new Error('Data must be ArrayBuffer, Blob, or File');
1092
1084
  }
1093
- // Open pack
1094
- await this.reader.open(arrayBuffer);
1095
- // Return pack wrapper
1096
- return new StowKitPack(this.reader, this.ktx2Loader, this.dracoLoader);
1085
+ // Create a new reader instance for this pack
1086
+ const reader = new StowKitReader(this.wasmPath);
1087
+ await reader.init();
1088
+ await reader.open(arrayBuffer);
1089
+ // Return pack wrapper with its own dedicated reader
1090
+ return new StowKitPack(reader, this.ktx2Loader, this.dracoLoader);
1097
1091
  }
1098
1092
  /**
1099
1093
  * Initialize the loader (called automatically on first load)
1100
1094
  */
1101
1095
  static async initialize(options) {
1102
- const wasmPath = options?.wasmPath || '/stowkit/stowkit_reader.wasm';
1096
+ this.wasmPath = options?.wasmPath || '/stowkit/stowkit_reader.wasm';
1103
1097
  const basisPath = options?.basisPath || '/stowkit/basis/';
1104
1098
  const dracoPath = options?.dracoPath || '/stowkit/draco/';
1105
- // Initialize reader
1106
- this.reader = new StowKitReader(wasmPath);
1107
- await this.reader.init();
1108
- // Setup KTX2 loader
1099
+ // Setup KTX2 loader (shared across all packs)
1109
1100
  this.ktx2Loader = new KTX2Loader();
1110
1101
  this.ktx2Loader.setTranscoderPath(basisPath);
1111
- // Setup Draco loader
1102
+ // Setup Draco loader (shared across all packs)
1112
1103
  this.dracoLoader = new DRACOLoader();
1113
1104
  this.dracoLoader.setDecoderPath(dracoPath);
1114
1105
  // Detect support
@@ -1118,10 +1109,10 @@ class StowKitLoader {
1118
1109
  this.initialized = true;
1119
1110
  }
1120
1111
  }
1121
- StowKitLoader.reader = null;
1122
1112
  StowKitLoader.ktx2Loader = null;
1123
1113
  StowKitLoader.dracoLoader = null;
1124
1114
  StowKitLoader.initialized = false;
1115
+ StowKitLoader.wasmPath = '/stowkit/stowkit_reader.wasm';
1125
1116
 
1126
1117
  export { StowKitLoader, StowKitPack };
1127
1118
  //# sourceMappingURL=stowkit-three-loader.esm.js.map