@stowkit/three-loader 0.1.33 → 0.1.35
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.
|
@@ -360,9 +360,14 @@ class MeshParser {
|
|
|
360
360
|
* Create Three.js BufferGeometry from Draco compressed mesh data
|
|
361
361
|
*/
|
|
362
362
|
static async createGeometry(geoInfo, dataBlob, dracoLoader, cacheKey, version) {
|
|
363
|
-
// Try loading from IndexedDB cache first
|
|
363
|
+
// Try loading from IndexedDB cache first (non-blocking - don't await in parallel loads)
|
|
364
|
+
let cachePromise = null;
|
|
364
365
|
if (cacheKey && version) {
|
|
365
|
-
|
|
366
|
+
cachePromise = AssetMemoryCache.getGeometry(cacheKey, version);
|
|
367
|
+
}
|
|
368
|
+
// Check if cache resolved while we were starting
|
|
369
|
+
if (cachePromise) {
|
|
370
|
+
const cached = await cachePromise;
|
|
366
371
|
if (cached) {
|
|
367
372
|
const geometry = new THREE__namespace.BufferGeometry();
|
|
368
373
|
geometry.setAttribute('position', new THREE__namespace.BufferAttribute(cached.positions, 3));
|
|
@@ -394,7 +399,7 @@ class MeshParser {
|
|
|
394
399
|
reject(new Error(`Failed to decode Draco geometry: ${error}`));
|
|
395
400
|
});
|
|
396
401
|
});
|
|
397
|
-
// Cache the decoded geometry
|
|
402
|
+
// Cache the decoded geometry (non-blocking)
|
|
398
403
|
if (cacheKey && version) {
|
|
399
404
|
const posAttr = geometry.getAttribute('position');
|
|
400
405
|
const normAttr = geometry.getAttribute('normal');
|
|
@@ -406,9 +411,7 @@ class MeshParser {
|
|
|
406
411
|
normals: (normAttr && 'array' in normAttr) ? normAttr.array : undefined,
|
|
407
412
|
uvs: (uvAttr && 'array' in uvAttr) ? uvAttr.array : undefined,
|
|
408
413
|
indices: indexAttr.array
|
|
409
|
-
}).catch(() => {
|
|
410
|
-
// Silent fail - caching is optional
|
|
411
|
-
});
|
|
414
|
+
}).catch(() => { });
|
|
412
415
|
}
|
|
413
416
|
}
|
|
414
417
|
return geometry;
|
|
@@ -1169,22 +1172,29 @@ class StowKitPack {
|
|
|
1169
1172
|
return Array.from(uniqueTextures);
|
|
1170
1173
|
}
|
|
1171
1174
|
async loadKTX2Texture(data, textureName) {
|
|
1172
|
-
//
|
|
1175
|
+
// Start cache check but don't block on it
|
|
1173
1176
|
const cacheKey = textureName ? `${this.packUrl}::${textureName}` : undefined;
|
|
1177
|
+
let cachePromise = null;
|
|
1174
1178
|
if (cacheKey) {
|
|
1175
|
-
|
|
1176
|
-
if (cached) {
|
|
1177
|
-
reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName}": 0ms (IndexedDB cache)`);
|
|
1178
|
-
const texture = new THREE__namespace.CompressedTexture([{ data: cached.data, width: cached.width, height: cached.height }], cached.width, cached.height, cached.format, THREE__namespace.UnsignedByteType);
|
|
1179
|
-
texture.needsUpdate = true;
|
|
1180
|
-
return texture;
|
|
1181
|
-
}
|
|
1179
|
+
cachePromise = AssetMemoryCache.getTexture(cacheKey, this.packVersion);
|
|
1182
1180
|
}
|
|
1183
|
-
//
|
|
1184
|
-
const decodeStart = performance.now();
|
|
1181
|
+
// Check cache while starting decode
|
|
1185
1182
|
const arrayBuffer = data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength);
|
|
1186
1183
|
const blob = new Blob([arrayBuffer]);
|
|
1187
1184
|
const url = URL.createObjectURL(blob);
|
|
1185
|
+
const decodeStart = performance.now();
|
|
1186
|
+
// Race cache check vs decode start
|
|
1187
|
+
const [cached, _] = await Promise.all([
|
|
1188
|
+
cachePromise || Promise.resolve(null),
|
|
1189
|
+
Promise.resolve() // Start decode immediately
|
|
1190
|
+
]);
|
|
1191
|
+
if (cached) {
|
|
1192
|
+
URL.revokeObjectURL(url);
|
|
1193
|
+
reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName}": 0ms (IndexedDB cache)`);
|
|
1194
|
+
const texture = new THREE__namespace.CompressedTexture([{ data: cached.data, width: cached.width, height: cached.height }], cached.width, cached.height, cached.format, THREE__namespace.UnsignedByteType);
|
|
1195
|
+
texture.needsUpdate = true;
|
|
1196
|
+
return texture;
|
|
1197
|
+
}
|
|
1188
1198
|
try {
|
|
1189
1199
|
const texture = await new Promise((resolve, reject) => {
|
|
1190
1200
|
this.ktx2Loader.load(url, (texture) => {
|
|
@@ -1198,7 +1208,7 @@ class StowKitPack {
|
|
|
1198
1208
|
});
|
|
1199
1209
|
const decodeTime = performance.now() - decodeStart;
|
|
1200
1210
|
reader.PerfLogger.log(`[Perf] ✓ Texture "${textureName || 'unknown'}": ${decodeTime.toFixed(2)}ms (Basis decode ${texture.image?.width}x${texture.image?.height})`);
|
|
1201
|
-
// Cache the transcoded texture data to IndexedDB
|
|
1211
|
+
// Cache the transcoded texture data to IndexedDB (non-blocking)
|
|
1202
1212
|
if (cacheKey && texture.mipmaps && texture.mipmaps.length > 0) {
|
|
1203
1213
|
const mipmap = texture.mipmaps[0];
|
|
1204
1214
|
const dataArray = new Uint8Array(mipmap.data.buffer, mipmap.data.byteOffset, mipmap.data.byteLength);
|
|
@@ -1209,9 +1219,7 @@ class StowKitPack {
|
|
|
1209
1219
|
format: texture.format,
|
|
1210
1220
|
internalFormat: texture.format,
|
|
1211
1221
|
compressed: true
|
|
1212
|
-
}).catch(() => {
|
|
1213
|
-
// Silent fail - caching is optional
|
|
1214
|
-
});
|
|
1222
|
+
}).catch(() => { });
|
|
1215
1223
|
}
|
|
1216
1224
|
return texture;
|
|
1217
1225
|
}
|