@stowkit/three-loader 0.1.28 → 0.1.29
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.
|
@@ -237,12 +237,7 @@ class MeshParser {
|
|
|
237
237
|
reject(new Error(`Failed to decode Draco geometry: ${error}`));
|
|
238
238
|
});
|
|
239
239
|
});
|
|
240
|
-
//
|
|
241
|
-
const boundsStart = performance.now();
|
|
242
|
-
geometry.computeBoundingSphere();
|
|
243
|
-
geometry.computeBoundingBox();
|
|
244
|
-
const boundsEnd = performance.now();
|
|
245
|
-
reader.PerfLogger.log(`[Perf] Bounds computation: ${(boundsEnd - boundsStart).toFixed(2)}ms`);
|
|
240
|
+
// Bounds will be computed automatically by Three.js when needed
|
|
246
241
|
const totalTime = performance.now();
|
|
247
242
|
reader.PerfLogger.log(`[Perf] Total geometry creation: ${(totalTime - startTime).toFixed(2)}ms`);
|
|
248
243
|
return geometry;
|
|
@@ -254,6 +249,11 @@ class MeshParser {
|
|
|
254
249
|
const root = new THREE__namespace.Group();
|
|
255
250
|
root.name = 'StowKitMesh';
|
|
256
251
|
const { geometries, materials, nodes, meshIndices } = parsedData;
|
|
252
|
+
// Pre-load ALL geometries in parallel for maximum speed
|
|
253
|
+
reader.PerfLogger.log(`[Perf] Starting parallel Draco decode of ${geometries.length} geometries...`);
|
|
254
|
+
const geometryPromises = geometries.map(geoInfo => this.createGeometry(geoInfo, dataBlob, dracoLoader));
|
|
255
|
+
const loadedGeometries = await Promise.all(geometryPromises);
|
|
256
|
+
reader.PerfLogger.log(`[Perf] All Draco decodes complete`);
|
|
257
257
|
// Create all Three.js objects for nodes
|
|
258
258
|
const nodeObjects = [];
|
|
259
259
|
for (const node of nodes) {
|
|
@@ -269,7 +269,7 @@ class MeshParser {
|
|
|
269
269
|
const meshIndex = meshIndices[meshIndexArrayPos];
|
|
270
270
|
if (meshIndex < geometries.length) {
|
|
271
271
|
const geoInfo = geometries[meshIndex];
|
|
272
|
-
const geometry =
|
|
272
|
+
const geometry = loadedGeometries[meshIndex];
|
|
273
273
|
// Use assigned material if valid, otherwise create default
|
|
274
274
|
let material;
|
|
275
275
|
if (geoInfo.materialIndex < materials.length) {
|
|
@@ -300,11 +300,11 @@ class MeshParser {
|
|
|
300
300
|
root.add(obj);
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
|
-
// If no nodes, create
|
|
303
|
+
// If no nodes, create meshes from all geometries
|
|
304
304
|
if (nodes.length === 0 && geometries.length > 0) {
|
|
305
305
|
for (let index = 0; index < geometries.length; index++) {
|
|
306
306
|
const geoInfo = geometries[index];
|
|
307
|
-
const geometry =
|
|
307
|
+
const geometry = loadedGeometries[index];
|
|
308
308
|
// Use assigned material if valid, otherwise create default
|
|
309
309
|
let material;
|
|
310
310
|
if (geoInfo.materialIndex < materials.length) {
|
|
@@ -727,7 +727,7 @@ class StowKitPack {
|
|
|
727
727
|
throw new Error(`Failed to read texture data: ${assetPath}`);
|
|
728
728
|
}
|
|
729
729
|
// Load as KTX2
|
|
730
|
-
return await this.loadKTX2Texture(data);
|
|
730
|
+
return await this.loadKTX2Texture(data, assetPath);
|
|
731
731
|
})();
|
|
732
732
|
this.textureCache.set(assetPath, loadPromise);
|
|
733
733
|
return loadPromise;
|
|
@@ -1048,19 +1048,19 @@ class StowKitPack {
|
|
|
1048
1048
|
}
|
|
1049
1049
|
return Array.from(uniqueTextures);
|
|
1050
1050
|
}
|
|
1051
|
-
async loadKTX2Texture(data) {
|
|
1052
|
-
|
|
1051
|
+
async loadKTX2Texture(data, textureName) {
|
|
1052
|
+
reader.PerfLogger.log(`[Perf] KTX2/Basis texture size: ${data.byteLength} bytes${textureName ? ` (${textureName})` : ''}`);
|
|
1053
|
+
// Create blob URL - KTX2Loader requires a URL, can't use ArrayBuffer directly
|
|
1053
1054
|
const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
1054
1055
|
const blob = new Blob([arrayBuffer]);
|
|
1055
1056
|
const url = URL.createObjectURL(blob);
|
|
1056
|
-
reader.PerfLogger.log(`[Perf] KTX2/Basis texture size: ${data.byteLength} bytes`);
|
|
1057
1057
|
try {
|
|
1058
1058
|
return await new Promise((resolve, reject) => {
|
|
1059
1059
|
const loadStart = performance.now();
|
|
1060
1060
|
this.ktx2Loader.load(url, (texture) => {
|
|
1061
1061
|
URL.revokeObjectURL(url);
|
|
1062
1062
|
const loadEnd = performance.now();
|
|
1063
|
-
reader.PerfLogger.log(`[Perf] Basis transcode: ${(loadEnd - loadStart).toFixed(2)}ms (resolution: ${texture.image?.width || '?'}x${texture.image?.height || '?'})`);
|
|
1063
|
+
reader.PerfLogger.log(`[Perf] Basis transcode: ${(loadEnd - loadStart).toFixed(2)}ms (${textureName || 'unknown'}, resolution: ${texture.image?.width || '?'}x${texture.image?.height || '?'})`);
|
|
1064
1064
|
texture.needsUpdate = true;
|
|
1065
1065
|
resolve(texture);
|
|
1066
1066
|
}, undefined, (error) => {
|