fl-web-component 2.0.17 → 2.0.19-beta.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/README.md +2 -0
- package/dist/fl-web-component.common.1.js.map +1 -1
- package/dist/fl-web-component.common.2.js.map +1 -1
- package/dist/fl-web-component.common.js +1439 -872
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +4 -3
- package/packages/components/com-graphics/index.vue +87 -7
- package/packages/components/com-graphics/mock.json +115 -0
- package/packages/utils/StreamLoader.js +250 -107
- package/packages/utils/StreamLoaderParser.worker.js +184 -76
- package/src/utils/flgltf-parser.js +21 -9
- package/src/utils/instance-parser.js +75 -75
- package/src/utils/threejs/measure-clear-distance.js +346 -0
- package/packages/components/com-graphics/box.json +0 -77
|
@@ -159,7 +159,7 @@ export class StreamLoader {
|
|
|
159
159
|
|
|
160
160
|
async parseStreamImmediate(reader, list, range, abortSignal = null, streamId = null) {
|
|
161
161
|
const batchMeshes = [];
|
|
162
|
-
const
|
|
162
|
+
const batchPrimitiveGroups = [];
|
|
163
163
|
const batchSize = this.batchSize;
|
|
164
164
|
let batchStart = 0;
|
|
165
165
|
const streamStats = {
|
|
@@ -168,8 +168,31 @@ export class StreamLoader {
|
|
|
168
168
|
totalPrimitives: 0,
|
|
169
169
|
};
|
|
170
170
|
|
|
171
|
-
const
|
|
171
|
+
const flattenPrimitiveGroups = primitiveGroups => {
|
|
172
|
+
if (!primitiveGroups || primitiveGroups.length === 0) return [];
|
|
173
|
+
const primitivesToProcess = [];
|
|
174
|
+
const usedIds = new Set();
|
|
175
|
+
|
|
176
|
+
primitiveGroups.forEach(group => {
|
|
177
|
+
const primitives = Array.isArray(group) ? group : [group];
|
|
178
|
+
primitives.forEach(primitive => {
|
|
179
|
+
if (!primitive) return;
|
|
180
|
+
if (primitive.id == null) {
|
|
181
|
+
primitivesToProcess.push(primitive);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
if (usedIds.has(primitive.id)) return;
|
|
185
|
+
usedIds.add(primitive.id);
|
|
186
|
+
primitivesToProcess.push(primitive);
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
return primitivesToProcess;
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
const processStreamBatch = async (meshesToProcess, primitiveGroupsToProcess) => {
|
|
172
194
|
if (!meshesToProcess || meshesToProcess.length === 0) return;
|
|
195
|
+
const primitivesToProcess = flattenPrimitiveGroups(primitiveGroupsToProcess);
|
|
173
196
|
await this.processBatchData(meshesToProcess, primitivesToProcess, list, range, abortSignal);
|
|
174
197
|
streamStats.totalBatches += 1;
|
|
175
198
|
streamStats.totalMeshes += meshesToProcess.length;
|
|
@@ -225,7 +248,7 @@ export class StreamLoader {
|
|
|
225
248
|
const flushed = await this.workerRequest('streamFlush', { streamId: localStreamId });
|
|
226
249
|
if (flushed?.meshes?.length) {
|
|
227
250
|
batchMeshes.push(...flushed.meshes);
|
|
228
|
-
|
|
251
|
+
batchPrimitiveGroups.push(...flushed.primitives);
|
|
229
252
|
}
|
|
230
253
|
|
|
231
254
|
while (batchMeshes.length - batchStart >= batchSize) {
|
|
@@ -234,9 +257,12 @@ export class StreamLoader {
|
|
|
234
257
|
const interactionPromiseInBatch = ensureNotInteracting();
|
|
235
258
|
if (interactionPromiseInBatch) await interactionPromiseInBatch;
|
|
236
259
|
const meshesToProcess = batchMeshes.slice(batchStart, batchStart + batchSize);
|
|
237
|
-
const
|
|
260
|
+
const primitiveGroupsToProcess = batchPrimitiveGroups.slice(
|
|
261
|
+
batchStart,
|
|
262
|
+
batchStart + batchSize
|
|
263
|
+
);
|
|
238
264
|
batchStart += batchSize;
|
|
239
|
-
await processStreamBatch(meshesToProcess,
|
|
265
|
+
await processStreamBatch(meshesToProcess, primitiveGroupsToProcess);
|
|
240
266
|
}
|
|
241
267
|
|
|
242
268
|
if (batchMeshes.length - batchStart > 0) {
|
|
@@ -245,9 +271,9 @@ export class StreamLoader {
|
|
|
245
271
|
const interactionPromiseInBatch = ensureNotInteracting();
|
|
246
272
|
if (interactionPromiseInBatch) await interactionPromiseInBatch;
|
|
247
273
|
const meshesToProcess = batchMeshes.slice(batchStart);
|
|
248
|
-
const
|
|
274
|
+
const primitiveGroupsToProcess = batchPrimitiveGroups.slice(batchStart);
|
|
249
275
|
batchStart = batchMeshes.length;
|
|
250
|
-
await processStreamBatch(meshesToProcess,
|
|
276
|
+
await processStreamBatch(meshesToProcess, primitiveGroupsToProcess);
|
|
251
277
|
}
|
|
252
278
|
break;
|
|
253
279
|
}
|
|
@@ -266,7 +292,7 @@ export class StreamLoader {
|
|
|
266
292
|
|
|
267
293
|
if (parsed?.meshes?.length) {
|
|
268
294
|
batchMeshes.push(...parsed.meshes);
|
|
269
|
-
|
|
295
|
+
batchPrimitiveGroups.push(...parsed.primitives);
|
|
270
296
|
}
|
|
271
297
|
|
|
272
298
|
while (batchMeshes.length - batchStart >= batchSize) {
|
|
@@ -275,14 +301,17 @@ export class StreamLoader {
|
|
|
275
301
|
const interactionPromiseInBatch = ensureNotInteracting();
|
|
276
302
|
if (interactionPromiseInBatch) await interactionPromiseInBatch;
|
|
277
303
|
const meshesToProcess = batchMeshes.slice(batchStart, batchStart + batchSize);
|
|
278
|
-
const
|
|
304
|
+
const primitiveGroupsToProcess = batchPrimitiveGroups.slice(
|
|
305
|
+
batchStart,
|
|
306
|
+
batchStart + batchSize
|
|
307
|
+
);
|
|
279
308
|
batchStart += batchSize;
|
|
280
|
-
await processStreamBatch(meshesToProcess,
|
|
309
|
+
await processStreamBatch(meshesToProcess, primitiveGroupsToProcess);
|
|
281
310
|
}
|
|
282
311
|
|
|
283
312
|
if (batchStart >= batchSize * 4) {
|
|
284
313
|
batchMeshes.splice(0, batchStart);
|
|
285
|
-
|
|
314
|
+
batchPrimitiveGroups.splice(0, batchStart);
|
|
286
315
|
batchStart = 0;
|
|
287
316
|
}
|
|
288
317
|
}
|
|
@@ -297,10 +326,127 @@ export class StreamLoader {
|
|
|
297
326
|
const decoder = new TextDecoder('utf-8');
|
|
298
327
|
let buffer = new Uint8Array();
|
|
299
328
|
|
|
300
|
-
|
|
301
|
-
let
|
|
329
|
+
let expectingMesh = true;
|
|
330
|
+
let pendingMesh = null;
|
|
331
|
+
let pendingPrimitiveIds = new Set();
|
|
332
|
+
let pendingPrimitiveGroups = [];
|
|
333
|
+
let pendingMatchedPrimitiveIds = new Set();
|
|
302
334
|
let isFullProps = true;
|
|
303
335
|
|
|
336
|
+
const normalizeMesh = mesh => {
|
|
337
|
+
this._applyPrefixId(mesh, 'id');
|
|
338
|
+
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
339
|
+
meshList.forEach(item => {
|
|
340
|
+
if (!item) return;
|
|
341
|
+
if (!Array.isArray(item.primitives)) {
|
|
342
|
+
item.primitives = [];
|
|
343
|
+
}
|
|
344
|
+
this._applyPrefixId(item.primitives, 'prmid', item.documentId);
|
|
345
|
+
});
|
|
346
|
+
return mesh;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
const collectMeshPrimitiveIds = mesh => {
|
|
350
|
+
const ids = [];
|
|
351
|
+
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
352
|
+
meshList.forEach(item => {
|
|
353
|
+
if (!item || !Array.isArray(item.primitives)) return;
|
|
354
|
+
item.primitives.forEach(primitive => {
|
|
355
|
+
if (primitive && primitive.prmid != null) {
|
|
356
|
+
ids.push(primitive.prmid);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
return ids;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const isValidStreamMesh = mesh => {
|
|
364
|
+
const meshList = Array.isArray(mesh) ? mesh : [mesh];
|
|
365
|
+
if (meshList.length === 0) return false;
|
|
366
|
+
return meshList.every(
|
|
367
|
+
item => item && typeof item === 'object' && Array.isArray(item.primitives)
|
|
368
|
+
);
|
|
369
|
+
};
|
|
370
|
+
|
|
371
|
+
const tryParseMeshFromBuffer = () => {
|
|
372
|
+
if (buffer.length < 4) {
|
|
373
|
+
return { status: 'incomplete' };
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const length = new DataView(buffer.buffer, buffer.byteOffset).getUint32(0, false);
|
|
377
|
+
if (length <= 0 || length > 10 * 1024 * 1024) {
|
|
378
|
+
return { status: 'invalid' };
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const totalLen = 4 + length;
|
|
382
|
+
if (buffer.length < totalLen) {
|
|
383
|
+
return { status: 'incomplete' };
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
const data = buffer.slice(4, totalLen);
|
|
388
|
+
const parsedMesh = JSON.parse(decoder.decode(data));
|
|
389
|
+
if (!isValidStreamMesh(parsedMesh)) {
|
|
390
|
+
return { status: 'invalid' };
|
|
391
|
+
}
|
|
392
|
+
const mesh = normalizeMesh(parsedMesh);
|
|
393
|
+
return { status: 'success', mesh, totalLen };
|
|
394
|
+
} catch (e) {
|
|
395
|
+
return { status: 'invalid' };
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
|
|
399
|
+
const parsePrimitiveFromBuffer = () => {
|
|
400
|
+
const dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
401
|
+
const primitiveResult = this.parsePrimitive(dataView, buffer, 0, isFullProps);
|
|
402
|
+
const primitiveData = primitiveResult.primitive;
|
|
403
|
+
|
|
404
|
+
this._applyPrefixId(primitiveData, 'id');
|
|
405
|
+
this._applyPrefixId(primitiveData, 'material');
|
|
406
|
+
|
|
407
|
+
if (isFullProps) {
|
|
408
|
+
const { position, normal, posindex, nolindex, indices } =
|
|
409
|
+
this.parsePrimitiveData(primitiveData);
|
|
410
|
+
const formatted = this.formatPrimitiveData({ position, normal, posindex, nolindex });
|
|
411
|
+
|
|
412
|
+
delete primitiveData.nolindex;
|
|
413
|
+
delete primitiveData.posindex;
|
|
414
|
+
|
|
415
|
+
primitiveData.position = formatted.position;
|
|
416
|
+
primitiveData.normal = formatted.normal;
|
|
417
|
+
primitiveData.indices = indices;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return {
|
|
421
|
+
primitive: primitiveData,
|
|
422
|
+
consumedBytes: primitiveResult.offset,
|
|
423
|
+
};
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
const commitPendingMesh = async () => {
|
|
427
|
+
if (!pendingMesh) return;
|
|
428
|
+
|
|
429
|
+
const meshList = Array.isArray(pendingMesh) ? pendingMesh : [pendingMesh];
|
|
430
|
+
meshList.forEach(mesh => {
|
|
431
|
+
batchMeshes.push(mesh);
|
|
432
|
+
batchPrimitiveGroups.push(pendingPrimitiveGroups);
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
pendingMesh = null;
|
|
436
|
+
pendingPrimitiveIds = new Set();
|
|
437
|
+
pendingPrimitiveGroups = [];
|
|
438
|
+
pendingMatchedPrimitiveIds = new Set();
|
|
439
|
+
|
|
440
|
+
if (batchMeshes.length >= this.batchSize) {
|
|
441
|
+
await ensureNotAborted();
|
|
442
|
+
await this.ensureNotInteracting(abortSignal);
|
|
443
|
+
await processStreamBatch(batchMeshes, batchPrimitiveGroups);
|
|
444
|
+
|
|
445
|
+
batchMeshes.length = 0;
|
|
446
|
+
batchPrimitiveGroups.length = 0;
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
|
|
304
450
|
while (true) {
|
|
305
451
|
await ensureNotAborted();
|
|
306
452
|
|
|
@@ -319,11 +465,12 @@ export class StreamLoader {
|
|
|
319
465
|
const { done, value } = content;
|
|
320
466
|
if (done) {
|
|
321
467
|
await ensureNotAborted();
|
|
468
|
+
await commitPendingMesh();
|
|
322
469
|
|
|
323
470
|
if (batchMeshes.length > 0) {
|
|
324
471
|
await ensureNotAborted();
|
|
325
472
|
await this.ensureNotInteracting(abortSignal);
|
|
326
|
-
await processStreamBatch(batchMeshes,
|
|
473
|
+
await processStreamBatch(batchMeshes, batchPrimitiveGroups);
|
|
327
474
|
}
|
|
328
475
|
break;
|
|
329
476
|
}
|
|
@@ -335,103 +482,55 @@ export class StreamLoader {
|
|
|
335
482
|
|
|
336
483
|
while (buffer.length > 0) {
|
|
337
484
|
await ensureNotAborted();
|
|
338
|
-
if (
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
const dataView = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
|
|
343
|
-
const primitiveResult = this.parsePrimitive(dataView, buffer, 0, isFullProps);
|
|
344
|
-
let primitiveData = primitiveResult.primitive;
|
|
345
|
-
|
|
346
|
-
this._applyPrefixId(primitiveData, 'id');
|
|
347
|
-
this._applyPrefixId(primitiveData, 'material');
|
|
348
|
-
const consumedBytes = primitiveResult.offset;
|
|
349
|
-
|
|
350
|
-
if (isFullProps) {
|
|
351
|
-
const { position, normal, posindex, nolindex, indices } =
|
|
352
|
-
this.parsePrimitiveData(primitiveData);
|
|
353
|
-
const formatted = this.formatPrimitiveData({ position, normal, posindex, nolindex });
|
|
354
|
-
|
|
355
|
-
delete primitiveData.nolindex;
|
|
356
|
-
delete primitiveData.posindex;
|
|
357
|
-
|
|
358
|
-
primitiveData.position = formatted.position;
|
|
359
|
-
primitiveData.normal = formatted.normal;
|
|
360
|
-
primitiveData.indices = indices;
|
|
361
|
-
}
|
|
362
|
-
const docId = primitiveData.id;
|
|
363
|
-
|
|
364
|
-
pendingPrimitives.set(docId, primitiveData);
|
|
365
|
-
|
|
366
|
-
expectingPrimitive = false;
|
|
367
|
-
buffer = buffer.slice(consumedBytes);
|
|
368
|
-
} catch (e) {
|
|
485
|
+
if (expectingMesh) {
|
|
486
|
+
const meshResult = tryParseMeshFromBuffer();
|
|
487
|
+
if (meshResult.status === 'incomplete') break;
|
|
488
|
+
if (meshResult.status === 'invalid') {
|
|
369
489
|
break;
|
|
370
490
|
}
|
|
371
|
-
} else {
|
|
372
|
-
if (buffer.length < 4) break;
|
|
373
491
|
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
492
|
+
await commitPendingMesh();
|
|
493
|
+
pendingMesh = meshResult.mesh;
|
|
494
|
+
pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(pendingMesh));
|
|
495
|
+
pendingPrimitiveGroups = [];
|
|
496
|
+
pendingMatchedPrimitiveIds = new Set();
|
|
497
|
+
expectingMesh = false;
|
|
498
|
+
buffer = buffer.slice(meshResult.totalLen);
|
|
499
|
+
} else {
|
|
500
|
+
const nextMeshResult = tryParseMeshFromBuffer();
|
|
501
|
+
if (nextMeshResult.status === 'success') {
|
|
502
|
+
await commitPendingMesh();
|
|
503
|
+
pendingMesh = nextMeshResult.mesh;
|
|
504
|
+
pendingPrimitiveIds = new Set(collectMeshPrimitiveIds(pendingMesh));
|
|
505
|
+
expectingMesh = false;
|
|
506
|
+
buffer = buffer.slice(nextMeshResult.totalLen);
|
|
378
507
|
continue;
|
|
379
508
|
}
|
|
380
509
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
if (buffer.length < totalLen) break;
|
|
384
|
-
|
|
385
|
-
const data = buffer.slice(4, totalLen);
|
|
386
|
-
let mesh = null;
|
|
510
|
+
if (buffer.length < 12) break;
|
|
387
511
|
|
|
512
|
+
let primitiveResult = null;
|
|
388
513
|
try {
|
|
389
|
-
|
|
390
|
-
mesh = JSON.parse(jsonStr);
|
|
514
|
+
primitiveResult = parsePrimitiveFromBuffer();
|
|
391
515
|
} catch (e) {
|
|
392
|
-
|
|
393
|
-
continue;
|
|
516
|
+
break;
|
|
394
517
|
}
|
|
395
518
|
|
|
396
|
-
|
|
397
|
-
isFullProps = true;
|
|
519
|
+
const primitiveData = primitiveResult.primitive;
|
|
398
520
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
});
|
|
404
|
-
} else {
|
|
405
|
-
this._applyPrefixId(mesh.primitives, 'prmid', mesh.documentId);
|
|
406
|
-
}
|
|
521
|
+
if (pendingPrimitiveIds.has(primitiveData.id)) {
|
|
522
|
+
pendingPrimitiveGroups.push(primitiveData);
|
|
523
|
+
pendingMatchedPrimitiveIds.add(primitiveData.id);
|
|
524
|
+
}
|
|
407
525
|
|
|
408
|
-
|
|
409
|
-
const meshToPrimId = mesh.primitives.map(item => item.prmid);
|
|
410
|
-
const hasPendingPrimitive = meshToPrimId.some(item => pendingPrimitives.has(item));
|
|
411
|
-
const hasPendingMesh = pendingPrimitives.has(docId);
|
|
412
|
-
|
|
413
|
-
if (hasPendingMesh || hasPendingPrimitive) {
|
|
414
|
-
let primitiveData = pendingPrimitives.get(docId);
|
|
415
|
-
if (!hasPendingMesh && hasPendingPrimitive) {
|
|
416
|
-
const primId = meshToPrimId[0];
|
|
417
|
-
primitiveData = pendingPrimitives.get(primId);
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
batchMeshes.push(mesh);
|
|
421
|
-
batchPrimitives.push(primitiveData);
|
|
422
|
-
|
|
423
|
-
if (batchMeshes.length >= this.batchSize) {
|
|
424
|
-
await ensureNotAborted();
|
|
425
|
-
await this.ensureNotInteracting(abortSignal);
|
|
426
|
-
await processStreamBatch(batchMeshes, batchPrimitives);
|
|
427
|
-
|
|
428
|
-
batchMeshes.length = 0;
|
|
429
|
-
batchPrimitives.length = 0;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
526
|
+
buffer = buffer.slice(primitiveResult.consumedBytes);
|
|
432
527
|
|
|
433
|
-
|
|
434
|
-
|
|
528
|
+
if (
|
|
529
|
+
pendingPrimitiveIds.size > 0 &&
|
|
530
|
+
pendingMatchedPrimitiveIds.size >= pendingPrimitiveIds.size
|
|
531
|
+
) {
|
|
532
|
+
await commitPendingMesh();
|
|
533
|
+
expectingMesh = true;
|
|
435
534
|
}
|
|
436
535
|
}
|
|
437
536
|
}
|
|
@@ -448,10 +547,18 @@ export class StreamLoader {
|
|
|
448
547
|
if (abortSignal && abortSignal.aborted) {
|
|
449
548
|
throw new DOMException('Request was aborted', 'AbortError');
|
|
450
549
|
}
|
|
451
|
-
const renderResult = await this.renderModelData(
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
550
|
+
const renderResult = await this.renderModelData(
|
|
551
|
+
meshes,
|
|
552
|
+
primitives,
|
|
553
|
+
list,
|
|
554
|
+
range,
|
|
555
|
+
null,
|
|
556
|
+
undefined,
|
|
557
|
+
{
|
|
558
|
+
suppressLoadComplete: true,
|
|
559
|
+
source: 'inRangeDis2',
|
|
560
|
+
}
|
|
561
|
+
);
|
|
455
562
|
if (renderResult && renderResult.canceled) {
|
|
456
563
|
throw new DOMException('Batch loading was canceled', 'AbortError');
|
|
457
564
|
}
|
|
@@ -849,7 +956,12 @@ export class StreamLoader {
|
|
|
849
956
|
async fetchJsonStream(list, range, abortSignal = null, requestId = null) {
|
|
850
957
|
try {
|
|
851
958
|
const loadStartTime = Date.now();
|
|
852
|
-
const streamResult = await this.fetchPrimitiveBufferByStream(
|
|
959
|
+
const streamResult = await this.fetchPrimitiveBufferByStream(
|
|
960
|
+
range,
|
|
961
|
+
list,
|
|
962
|
+
abortSignal,
|
|
963
|
+
requestId
|
|
964
|
+
);
|
|
853
965
|
return {
|
|
854
966
|
...(streamResult || {}),
|
|
855
967
|
duration: Date.now() - loadStartTime,
|
|
@@ -939,8 +1051,20 @@ export class StreamLoader {
|
|
|
939
1051
|
if (dataView.byteLength < offset + 12) {
|
|
940
1052
|
throw new Error('Insufficient data for primitive header');
|
|
941
1053
|
}
|
|
942
|
-
|
|
1054
|
+
const primitiveIdTextLen = dataView.getUint32(offset, false);
|
|
943
1055
|
offset += 4;
|
|
1056
|
+
if (primitiveIdTextLen === 0xffffffff) {
|
|
1057
|
+
primitive.id = null;
|
|
1058
|
+
} else if (primitiveIdTextLen > 0) {
|
|
1059
|
+
if (dataView.byteLength < offset + primitiveIdTextLen) {
|
|
1060
|
+
throw new Error('Insufficient data for primitive id content');
|
|
1061
|
+
}
|
|
1062
|
+
const textBytes = uint8Array.subarray(offset, offset + primitiveIdTextLen);
|
|
1063
|
+
primitive.id = new TextDecoder('utf-8').decode(textBytes);
|
|
1064
|
+
offset += primitiveIdTextLen;
|
|
1065
|
+
} else {
|
|
1066
|
+
primitive.id = '';
|
|
1067
|
+
}
|
|
944
1068
|
|
|
945
1069
|
if (dataView.byteLength < offset + 4) {
|
|
946
1070
|
throw new Error('Insufficient data for GeomText length');
|
|
@@ -960,8 +1084,23 @@ export class StreamLoader {
|
|
|
960
1084
|
primitive.documentId = '';
|
|
961
1085
|
}
|
|
962
1086
|
|
|
963
|
-
|
|
1087
|
+
if (dataView.byteLength < offset + 4) {
|
|
1088
|
+
throw new Error('Insufficient data for Material length');
|
|
1089
|
+
}
|
|
1090
|
+
const materialTextLen = dataView.getUint32(offset, false);
|
|
964
1091
|
offset += 4;
|
|
1092
|
+
if (materialTextLen === 0xffffffff) {
|
|
1093
|
+
primitive.material = null;
|
|
1094
|
+
} else if (materialTextLen > 0) {
|
|
1095
|
+
if (dataView.byteLength < offset + materialTextLen) {
|
|
1096
|
+
throw new Error('Insufficient data for Material content');
|
|
1097
|
+
}
|
|
1098
|
+
const textBytes = uint8Array.subarray(offset, offset + materialTextLen);
|
|
1099
|
+
primitive.material = new TextDecoder('utf-8').decode(textBytes);
|
|
1100
|
+
offset += materialTextLen;
|
|
1101
|
+
} else {
|
|
1102
|
+
primitive.material = '';
|
|
1103
|
+
}
|
|
965
1104
|
|
|
966
1105
|
if (dataView.byteLength < offset + 4) {
|
|
967
1106
|
throw new Error('Insufficient data for GeomText length');
|
|
@@ -1311,10 +1450,10 @@ export class StreamLoader {
|
|
|
1311
1450
|
}
|
|
1312
1451
|
}
|
|
1313
1452
|
|
|
1314
|
-
async getBox({ id, projectId = this.projectId || 0 }) {
|
|
1453
|
+
async getBox({ id, projectId = this.projectId || 0, isDebug }) {
|
|
1315
1454
|
// 1. 尝试从 IndexedDB 读取
|
|
1316
1455
|
const cached = await this._getFromDB(id, projectId);
|
|
1317
|
-
if (cached) {
|
|
1456
|
+
if (cached && !isDebug) {
|
|
1318
1457
|
return cached;
|
|
1319
1458
|
}
|
|
1320
1459
|
|
|
@@ -1539,7 +1678,11 @@ export class StreamLoader {
|
|
|
1539
1678
|
this.sceneBox = sceneBox;
|
|
1540
1679
|
|
|
1541
1680
|
// 获取BoxIndex
|
|
1542
|
-
const boxIndex = await this.getBox({
|
|
1681
|
+
const boxIndex = await this.getBox({
|
|
1682
|
+
id: item.id,
|
|
1683
|
+
projectId: this.projectId,
|
|
1684
|
+
isDebug: this.debug,
|
|
1685
|
+
});
|
|
1543
1686
|
this.boxIndex = boxIndex;
|
|
1544
1687
|
|
|
1545
1688
|
// 将 mergeMaterialData 覆盖到 materialData(按 id 覆盖 color/transp)
|