@2112-lab/central-plant 0.1.13 → 0.1.15
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/dist/bundle/index.js +1619 -82
- package/dist/cjs/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +462 -0
- package/dist/cjs/src/index.js +4 -0
- package/dist/cjs/src/rendering/modelPreloader.js +241 -81
- package/dist/cjs/src/rendering/objProcessor.js +703 -0
- package/dist/cjs/src/testing/objProcessingDemo.js +254 -0
- package/dist/esm/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +461 -2
- package/dist/esm/src/index.js +2 -0
- package/dist/esm/src/rendering/modelPreloader.js +241 -81
- package/dist/esm/src/rendering/objProcessor.js +678 -0
- package/dist/esm/src/testing/objProcessingDemo.js +249 -0
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -4315,6 +4315,465 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
4315
4315
|
}]);
|
|
4316
4316
|
}();
|
|
4317
4317
|
|
|
4318
|
+
/**
|
|
4319
|
+
* Merges a set of geometries into a single instance. All geometries must have compatible attributes.
|
|
4320
|
+
*
|
|
4321
|
+
* @param {Array<BufferGeometry>} geometries - The geometries to merge.
|
|
4322
|
+
* @param {boolean} [useGroups=false] - Whether to use groups or not.
|
|
4323
|
+
* @return {?BufferGeometry} The merged geometry. Returns `null` if the merge does not succeed.
|
|
4324
|
+
*/
|
|
4325
|
+
function mergeGeometries( geometries, useGroups = false ) {
|
|
4326
|
+
|
|
4327
|
+
const isIndexed = geometries[ 0 ].index !== null;
|
|
4328
|
+
|
|
4329
|
+
const attributesUsed = new Set( Object.keys( geometries[ 0 ].attributes ) );
|
|
4330
|
+
const morphAttributesUsed = new Set( Object.keys( geometries[ 0 ].morphAttributes ) );
|
|
4331
|
+
|
|
4332
|
+
const attributes = {};
|
|
4333
|
+
const morphAttributes = {};
|
|
4334
|
+
|
|
4335
|
+
const morphTargetsRelative = geometries[ 0 ].morphTargetsRelative;
|
|
4336
|
+
|
|
4337
|
+
const mergedGeometry = new THREE.BufferGeometry();
|
|
4338
|
+
|
|
4339
|
+
let offset = 0;
|
|
4340
|
+
|
|
4341
|
+
for ( let i = 0; i < geometries.length; ++ i ) {
|
|
4342
|
+
|
|
4343
|
+
const geometry = geometries[ i ];
|
|
4344
|
+
let attributesCount = 0;
|
|
4345
|
+
|
|
4346
|
+
// ensure that all geometries are indexed, or none
|
|
4347
|
+
|
|
4348
|
+
if ( isIndexed !== ( geometry.index !== null ) ) {
|
|
4349
|
+
|
|
4350
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them.' );
|
|
4351
|
+
return null;
|
|
4352
|
+
|
|
4353
|
+
}
|
|
4354
|
+
|
|
4355
|
+
// gather attributes, exit early if they're different
|
|
4356
|
+
|
|
4357
|
+
for ( const name in geometry.attributes ) {
|
|
4358
|
+
|
|
4359
|
+
if ( ! attributesUsed.has( name ) ) {
|
|
4360
|
+
|
|
4361
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. All geometries must have compatible attributes; make sure "' + name + '" attribute exists among all geometries, or in none of them.' );
|
|
4362
|
+
return null;
|
|
4363
|
+
|
|
4364
|
+
}
|
|
4365
|
+
|
|
4366
|
+
if ( attributes[ name ] === undefined ) attributes[ name ] = [];
|
|
4367
|
+
|
|
4368
|
+
attributes[ name ].push( geometry.attributes[ name ] );
|
|
4369
|
+
|
|
4370
|
+
attributesCount ++;
|
|
4371
|
+
|
|
4372
|
+
}
|
|
4373
|
+
|
|
4374
|
+
// ensure geometries have the same number of attributes
|
|
4375
|
+
|
|
4376
|
+
if ( attributesCount !== attributesUsed.size ) {
|
|
4377
|
+
|
|
4378
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. Make sure all geometries have the same number of attributes.' );
|
|
4379
|
+
return null;
|
|
4380
|
+
|
|
4381
|
+
}
|
|
4382
|
+
|
|
4383
|
+
// gather morph attributes, exit early if they're different
|
|
4384
|
+
|
|
4385
|
+
if ( morphTargetsRelative !== geometry.morphTargetsRelative ) {
|
|
4386
|
+
|
|
4387
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphTargetsRelative must be consistent throughout all geometries.' );
|
|
4388
|
+
return null;
|
|
4389
|
+
|
|
4390
|
+
}
|
|
4391
|
+
|
|
4392
|
+
for ( const name in geometry.morphAttributes ) {
|
|
4393
|
+
|
|
4394
|
+
if ( ! morphAttributesUsed.has( name ) ) {
|
|
4395
|
+
|
|
4396
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. .morphAttributes must be consistent throughout all geometries.' );
|
|
4397
|
+
return null;
|
|
4398
|
+
|
|
4399
|
+
}
|
|
4400
|
+
|
|
4401
|
+
if ( morphAttributes[ name ] === undefined ) morphAttributes[ name ] = [];
|
|
4402
|
+
|
|
4403
|
+
morphAttributes[ name ].push( geometry.morphAttributes[ name ] );
|
|
4404
|
+
|
|
4405
|
+
}
|
|
4406
|
+
|
|
4407
|
+
if ( useGroups ) {
|
|
4408
|
+
|
|
4409
|
+
let count;
|
|
4410
|
+
|
|
4411
|
+
if ( isIndexed ) {
|
|
4412
|
+
|
|
4413
|
+
count = geometry.index.count;
|
|
4414
|
+
|
|
4415
|
+
} else if ( geometry.attributes.position !== undefined ) {
|
|
4416
|
+
|
|
4417
|
+
count = geometry.attributes.position.count;
|
|
4418
|
+
|
|
4419
|
+
} else {
|
|
4420
|
+
|
|
4421
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index ' + i + '. The geometry must have either an index or a position attribute' );
|
|
4422
|
+
return null;
|
|
4423
|
+
|
|
4424
|
+
}
|
|
4425
|
+
|
|
4426
|
+
mergedGeometry.addGroup( offset, count, i );
|
|
4427
|
+
|
|
4428
|
+
offset += count;
|
|
4429
|
+
|
|
4430
|
+
}
|
|
4431
|
+
|
|
4432
|
+
}
|
|
4433
|
+
|
|
4434
|
+
// merge indices
|
|
4435
|
+
|
|
4436
|
+
if ( isIndexed ) {
|
|
4437
|
+
|
|
4438
|
+
let indexOffset = 0;
|
|
4439
|
+
const mergedIndex = [];
|
|
4440
|
+
|
|
4441
|
+
for ( let i = 0; i < geometries.length; ++ i ) {
|
|
4442
|
+
|
|
4443
|
+
const index = geometries[ i ].index;
|
|
4444
|
+
|
|
4445
|
+
for ( let j = 0; j < index.count; ++ j ) {
|
|
4446
|
+
|
|
4447
|
+
mergedIndex.push( index.getX( j ) + indexOffset );
|
|
4448
|
+
|
|
4449
|
+
}
|
|
4450
|
+
|
|
4451
|
+
indexOffset += geometries[ i ].attributes.position.count;
|
|
4452
|
+
|
|
4453
|
+
}
|
|
4454
|
+
|
|
4455
|
+
mergedGeometry.setIndex( mergedIndex );
|
|
4456
|
+
|
|
4457
|
+
}
|
|
4458
|
+
|
|
4459
|
+
// merge attributes
|
|
4460
|
+
|
|
4461
|
+
for ( const name in attributes ) {
|
|
4462
|
+
|
|
4463
|
+
const mergedAttribute = mergeAttributes( attributes[ name ] );
|
|
4464
|
+
|
|
4465
|
+
if ( ! mergedAttribute ) {
|
|
4466
|
+
|
|
4467
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' attribute.' );
|
|
4468
|
+
return null;
|
|
4469
|
+
|
|
4470
|
+
}
|
|
4471
|
+
|
|
4472
|
+
mergedGeometry.setAttribute( name, mergedAttribute );
|
|
4473
|
+
|
|
4474
|
+
}
|
|
4475
|
+
|
|
4476
|
+
// merge morph attributes
|
|
4477
|
+
|
|
4478
|
+
for ( const name in morphAttributes ) {
|
|
4479
|
+
|
|
4480
|
+
const numMorphTargets = morphAttributes[ name ][ 0 ].length;
|
|
4481
|
+
|
|
4482
|
+
if ( numMorphTargets === 0 ) break;
|
|
4483
|
+
|
|
4484
|
+
mergedGeometry.morphAttributes = mergedGeometry.morphAttributes || {};
|
|
4485
|
+
mergedGeometry.morphAttributes[ name ] = [];
|
|
4486
|
+
|
|
4487
|
+
for ( let i = 0; i < numMorphTargets; ++ i ) {
|
|
4488
|
+
|
|
4489
|
+
const morphAttributesToMerge = [];
|
|
4490
|
+
|
|
4491
|
+
for ( let j = 0; j < morphAttributes[ name ].length; ++ j ) {
|
|
4492
|
+
|
|
4493
|
+
morphAttributesToMerge.push( morphAttributes[ name ][ j ][ i ] );
|
|
4494
|
+
|
|
4495
|
+
}
|
|
4496
|
+
|
|
4497
|
+
const mergedMorphAttribute = mergeAttributes( morphAttributesToMerge );
|
|
4498
|
+
|
|
4499
|
+
if ( ! mergedMorphAttribute ) {
|
|
4500
|
+
|
|
4501
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the ' + name + ' morphAttribute.' );
|
|
4502
|
+
return null;
|
|
4503
|
+
|
|
4504
|
+
}
|
|
4505
|
+
|
|
4506
|
+
mergedGeometry.morphAttributes[ name ].push( mergedMorphAttribute );
|
|
4507
|
+
|
|
4508
|
+
}
|
|
4509
|
+
|
|
4510
|
+
}
|
|
4511
|
+
|
|
4512
|
+
return mergedGeometry;
|
|
4513
|
+
|
|
4514
|
+
}
|
|
4515
|
+
|
|
4516
|
+
/**
|
|
4517
|
+
* Merges a set of attributes into a single instance. All attributes must have compatible properties and types.
|
|
4518
|
+
* Instances of {@link InterleavedBufferAttribute} are not supported.
|
|
4519
|
+
*
|
|
4520
|
+
* @param {Array<BufferAttribute>} attributes - The attributes to merge.
|
|
4521
|
+
* @return {?BufferAttribute} The merged attribute. Returns `null` if the merge does not succeed.
|
|
4522
|
+
*/
|
|
4523
|
+
function mergeAttributes( attributes ) {
|
|
4524
|
+
|
|
4525
|
+
let TypedArray;
|
|
4526
|
+
let itemSize;
|
|
4527
|
+
let normalized;
|
|
4528
|
+
let gpuType = - 1;
|
|
4529
|
+
let arrayLength = 0;
|
|
4530
|
+
|
|
4531
|
+
for ( let i = 0; i < attributes.length; ++ i ) {
|
|
4532
|
+
|
|
4533
|
+
const attribute = attributes[ i ];
|
|
4534
|
+
|
|
4535
|
+
if ( TypedArray === undefined ) TypedArray = attribute.array.constructor;
|
|
4536
|
+
if ( TypedArray !== attribute.array.constructor ) {
|
|
4537
|
+
|
|
4538
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes.' );
|
|
4539
|
+
return null;
|
|
4540
|
+
|
|
4541
|
+
}
|
|
4542
|
+
|
|
4543
|
+
if ( itemSize === undefined ) itemSize = attribute.itemSize;
|
|
4544
|
+
if ( itemSize !== attribute.itemSize ) {
|
|
4545
|
+
|
|
4546
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes.' );
|
|
4547
|
+
return null;
|
|
4548
|
+
|
|
4549
|
+
}
|
|
4550
|
+
|
|
4551
|
+
if ( normalized === undefined ) normalized = attribute.normalized;
|
|
4552
|
+
if ( normalized !== attribute.normalized ) {
|
|
4553
|
+
|
|
4554
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes.' );
|
|
4555
|
+
return null;
|
|
4556
|
+
|
|
4557
|
+
}
|
|
4558
|
+
|
|
4559
|
+
if ( gpuType === - 1 ) gpuType = attribute.gpuType;
|
|
4560
|
+
if ( gpuType !== attribute.gpuType ) {
|
|
4561
|
+
|
|
4562
|
+
console.error( 'THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes.' );
|
|
4563
|
+
return null;
|
|
4564
|
+
|
|
4565
|
+
}
|
|
4566
|
+
|
|
4567
|
+
arrayLength += attribute.count * itemSize;
|
|
4568
|
+
|
|
4569
|
+
}
|
|
4570
|
+
|
|
4571
|
+
const array = new TypedArray( arrayLength );
|
|
4572
|
+
const result = new THREE.BufferAttribute( array, itemSize, normalized );
|
|
4573
|
+
let offset = 0;
|
|
4574
|
+
|
|
4575
|
+
for ( let i = 0; i < attributes.length; ++ i ) {
|
|
4576
|
+
|
|
4577
|
+
const attribute = attributes[ i ];
|
|
4578
|
+
if ( attribute.isInterleavedBufferAttribute ) {
|
|
4579
|
+
|
|
4580
|
+
const tupleOffset = offset / itemSize;
|
|
4581
|
+
for ( let j = 0, l = attribute.count; j < l; j ++ ) {
|
|
4582
|
+
|
|
4583
|
+
for ( let c = 0; c < itemSize; c ++ ) {
|
|
4584
|
+
|
|
4585
|
+
const value = attribute.getComponent( j, c );
|
|
4586
|
+
result.setComponent( j + tupleOffset, c, value );
|
|
4587
|
+
|
|
4588
|
+
}
|
|
4589
|
+
|
|
4590
|
+
}
|
|
4591
|
+
|
|
4592
|
+
} else {
|
|
4593
|
+
|
|
4594
|
+
array.set( attribute.array, offset );
|
|
4595
|
+
|
|
4596
|
+
}
|
|
4597
|
+
|
|
4598
|
+
offset += attribute.count * itemSize;
|
|
4599
|
+
|
|
4600
|
+
}
|
|
4601
|
+
|
|
4602
|
+
if ( gpuType !== undefined ) {
|
|
4603
|
+
|
|
4604
|
+
result.gpuType = gpuType;
|
|
4605
|
+
|
|
4606
|
+
}
|
|
4607
|
+
|
|
4608
|
+
return result;
|
|
4609
|
+
|
|
4610
|
+
}
|
|
4611
|
+
|
|
4612
|
+
/**
|
|
4613
|
+
* Returns a new geometry with vertices for which all similar vertex attributes (within tolerance) are merged.
|
|
4614
|
+
*
|
|
4615
|
+
* @param {BufferGeometry} geometry - The geometry to merge vertices for.
|
|
4616
|
+
* @param {number} [tolerance=1e-4] - The tolerance value.
|
|
4617
|
+
* @return {BufferGeometry} - The new geometry with merged vertices.
|
|
4618
|
+
*/
|
|
4619
|
+
function mergeVertices( geometry, tolerance = 1e-4 ) {
|
|
4620
|
+
|
|
4621
|
+
tolerance = Math.max( tolerance, Number.EPSILON );
|
|
4622
|
+
|
|
4623
|
+
// Generate an index buffer if the geometry doesn't have one, or optimize it
|
|
4624
|
+
// if it's already available.
|
|
4625
|
+
const hashToIndex = {};
|
|
4626
|
+
const indices = geometry.getIndex();
|
|
4627
|
+
const positions = geometry.getAttribute( 'position' );
|
|
4628
|
+
const vertexCount = indices ? indices.count : positions.count;
|
|
4629
|
+
|
|
4630
|
+
// next value for triangle indices
|
|
4631
|
+
let nextIndex = 0;
|
|
4632
|
+
|
|
4633
|
+
// attributes and new attribute arrays
|
|
4634
|
+
const attributeNames = Object.keys( geometry.attributes );
|
|
4635
|
+
const tmpAttributes = {};
|
|
4636
|
+
const tmpMorphAttributes = {};
|
|
4637
|
+
const newIndices = [];
|
|
4638
|
+
const getters = [ 'getX', 'getY', 'getZ', 'getW' ];
|
|
4639
|
+
const setters = [ 'setX', 'setY', 'setZ', 'setW' ];
|
|
4640
|
+
|
|
4641
|
+
// Initialize the arrays, allocating space conservatively. Extra
|
|
4642
|
+
// space will be trimmed in the last step.
|
|
4643
|
+
for ( let i = 0, l = attributeNames.length; i < l; i ++ ) {
|
|
4644
|
+
|
|
4645
|
+
const name = attributeNames[ i ];
|
|
4646
|
+
const attr = geometry.attributes[ name ];
|
|
4647
|
+
|
|
4648
|
+
tmpAttributes[ name ] = new attr.constructor(
|
|
4649
|
+
new attr.array.constructor( attr.count * attr.itemSize ),
|
|
4650
|
+
attr.itemSize,
|
|
4651
|
+
attr.normalized
|
|
4652
|
+
);
|
|
4653
|
+
|
|
4654
|
+
const morphAttributes = geometry.morphAttributes[ name ];
|
|
4655
|
+
if ( morphAttributes ) {
|
|
4656
|
+
|
|
4657
|
+
if ( ! tmpMorphAttributes[ name ] ) tmpMorphAttributes[ name ] = [];
|
|
4658
|
+
morphAttributes.forEach( ( morphAttr, i ) => {
|
|
4659
|
+
|
|
4660
|
+
const array = new morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize );
|
|
4661
|
+
tmpMorphAttributes[ name ][ i ] = new morphAttr.constructor( array, morphAttr.itemSize, morphAttr.normalized );
|
|
4662
|
+
|
|
4663
|
+
} );
|
|
4664
|
+
|
|
4665
|
+
}
|
|
4666
|
+
|
|
4667
|
+
}
|
|
4668
|
+
|
|
4669
|
+
// convert the error tolerance to an amount of decimal places to truncate to
|
|
4670
|
+
const halfTolerance = tolerance * 0.5;
|
|
4671
|
+
const exponent = Math.log10( 1 / tolerance );
|
|
4672
|
+
const hashMultiplier = Math.pow( 10, exponent );
|
|
4673
|
+
const hashAdditive = halfTolerance * hashMultiplier;
|
|
4674
|
+
for ( let i = 0; i < vertexCount; i ++ ) {
|
|
4675
|
+
|
|
4676
|
+
const index = indices ? indices.getX( i ) : i;
|
|
4677
|
+
|
|
4678
|
+
// Generate a hash for the vertex attributes at the current index 'i'
|
|
4679
|
+
let hash = '';
|
|
4680
|
+
for ( let j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
4681
|
+
|
|
4682
|
+
const name = attributeNames[ j ];
|
|
4683
|
+
const attribute = geometry.getAttribute( name );
|
|
4684
|
+
const itemSize = attribute.itemSize;
|
|
4685
|
+
|
|
4686
|
+
for ( let k = 0; k < itemSize; k ++ ) {
|
|
4687
|
+
|
|
4688
|
+
// double tilde truncates the decimal value
|
|
4689
|
+
hash += `${ ~ ~ ( attribute[ getters[ k ] ]( index ) * hashMultiplier + hashAdditive ) },`;
|
|
4690
|
+
|
|
4691
|
+
}
|
|
4692
|
+
|
|
4693
|
+
}
|
|
4694
|
+
|
|
4695
|
+
// Add another reference to the vertex if it's already
|
|
4696
|
+
// used by another index
|
|
4697
|
+
if ( hash in hashToIndex ) {
|
|
4698
|
+
|
|
4699
|
+
newIndices.push( hashToIndex[ hash ] );
|
|
4700
|
+
|
|
4701
|
+
} else {
|
|
4702
|
+
|
|
4703
|
+
// copy data to the new index in the temporary attributes
|
|
4704
|
+
for ( let j = 0, l = attributeNames.length; j < l; j ++ ) {
|
|
4705
|
+
|
|
4706
|
+
const name = attributeNames[ j ];
|
|
4707
|
+
const attribute = geometry.getAttribute( name );
|
|
4708
|
+
const morphAttributes = geometry.morphAttributes[ name ];
|
|
4709
|
+
const itemSize = attribute.itemSize;
|
|
4710
|
+
const newArray = tmpAttributes[ name ];
|
|
4711
|
+
const newMorphArrays = tmpMorphAttributes[ name ];
|
|
4712
|
+
|
|
4713
|
+
for ( let k = 0; k < itemSize; k ++ ) {
|
|
4714
|
+
|
|
4715
|
+
const getterFunc = getters[ k ];
|
|
4716
|
+
const setterFunc = setters[ k ];
|
|
4717
|
+
newArray[ setterFunc ]( nextIndex, attribute[ getterFunc ]( index ) );
|
|
4718
|
+
|
|
4719
|
+
if ( morphAttributes ) {
|
|
4720
|
+
|
|
4721
|
+
for ( let m = 0, ml = morphAttributes.length; m < ml; m ++ ) {
|
|
4722
|
+
|
|
4723
|
+
newMorphArrays[ m ][ setterFunc ]( nextIndex, morphAttributes[ m ][ getterFunc ]( index ) );
|
|
4724
|
+
|
|
4725
|
+
}
|
|
4726
|
+
|
|
4727
|
+
}
|
|
4728
|
+
|
|
4729
|
+
}
|
|
4730
|
+
|
|
4731
|
+
}
|
|
4732
|
+
|
|
4733
|
+
hashToIndex[ hash ] = nextIndex;
|
|
4734
|
+
newIndices.push( nextIndex );
|
|
4735
|
+
nextIndex ++;
|
|
4736
|
+
|
|
4737
|
+
}
|
|
4738
|
+
|
|
4739
|
+
}
|
|
4740
|
+
|
|
4741
|
+
// generate result BufferGeometry
|
|
4742
|
+
const result = geometry.clone();
|
|
4743
|
+
for ( const name in geometry.attributes ) {
|
|
4744
|
+
|
|
4745
|
+
const tmpAttribute = tmpAttributes[ name ];
|
|
4746
|
+
|
|
4747
|
+
result.setAttribute( name, new tmpAttribute.constructor(
|
|
4748
|
+
tmpAttribute.array.slice( 0, nextIndex * tmpAttribute.itemSize ),
|
|
4749
|
+
tmpAttribute.itemSize,
|
|
4750
|
+
tmpAttribute.normalized,
|
|
4751
|
+
) );
|
|
4752
|
+
|
|
4753
|
+
if ( ! ( name in tmpMorphAttributes ) ) continue;
|
|
4754
|
+
|
|
4755
|
+
for ( let j = 0; j < tmpMorphAttributes[ name ].length; j ++ ) {
|
|
4756
|
+
|
|
4757
|
+
const tmpMorphAttribute = tmpMorphAttributes[ name ][ j ];
|
|
4758
|
+
|
|
4759
|
+
result.morphAttributes[ name ][ j ] = new tmpMorphAttribute.constructor(
|
|
4760
|
+
tmpMorphAttribute.array.slice( 0, nextIndex * tmpMorphAttribute.itemSize ),
|
|
4761
|
+
tmpMorphAttribute.itemSize,
|
|
4762
|
+
tmpMorphAttribute.normalized,
|
|
4763
|
+
);
|
|
4764
|
+
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4767
|
+
}
|
|
4768
|
+
|
|
4769
|
+
// indices
|
|
4770
|
+
|
|
4771
|
+
result.setIndex( newIndices );
|
|
4772
|
+
|
|
4773
|
+
return result;
|
|
4774
|
+
|
|
4775
|
+
}
|
|
4776
|
+
|
|
4318
4777
|
/**
|
|
4319
4778
|
* Returns a new indexed geometry based on `TrianglesDrawMode` draw mode.
|
|
4320
4779
|
* This mode corresponds to the `gl.TRIANGLES` primitive in WebGL.
|
|
@@ -10165,7 +10624,680 @@ class OBJLoader extends THREE.Loader {
|
|
|
10165
10624
|
|
|
10166
10625
|
}
|
|
10167
10626
|
|
|
10168
|
-
}
|
|
10627
|
+
}
|
|
10628
|
+
|
|
10629
|
+
var ObjProcessor = /*#__PURE__*/function () {
|
|
10630
|
+
function ObjProcessor() {
|
|
10631
|
+
_classCallCheck(this, ObjProcessor);
|
|
10632
|
+
this.indexedGeometryCache = new Map(); // Cache for indexed geometries
|
|
10633
|
+
this.geometrySizeCache = new Map(); // Cache for geometry sizes
|
|
10634
|
+
this.idbSupported = this.checkIndexedDBSupport();
|
|
10635
|
+
this.dbName = 'CentralPlantGeometryDB';
|
|
10636
|
+
this.dbVersion = 1;
|
|
10637
|
+
this.storeName = 'indexedGeometries';
|
|
10638
|
+
console.log('🔧 ObjProcessor initialized');
|
|
10639
|
+
console.log("\uD83D\uDCE6 IndexedDB supported: ".concat(this.idbSupported));
|
|
10640
|
+
}
|
|
10641
|
+
|
|
10642
|
+
/**
|
|
10643
|
+
* Check if IndexedDB is supported
|
|
10644
|
+
* @returns {boolean} True if IndexedDB is supported
|
|
10645
|
+
*/
|
|
10646
|
+
return _createClass(ObjProcessor, [{
|
|
10647
|
+
key: "checkIndexedDBSupport",
|
|
10648
|
+
value: function checkIndexedDBSupport() {
|
|
10649
|
+
if (typeof window === 'undefined') return false;
|
|
10650
|
+
return 'indexedDB' in window && window.indexedDB !== null;
|
|
10651
|
+
}
|
|
10652
|
+
|
|
10653
|
+
/**
|
|
10654
|
+
* Initialize IndexedDB for geometry storage
|
|
10655
|
+
* @returns {Promise<IDBDatabase>} Promise that resolves to the database
|
|
10656
|
+
*/
|
|
10657
|
+
}, {
|
|
10658
|
+
key: "initializeIDB",
|
|
10659
|
+
value: (function () {
|
|
10660
|
+
var _initializeIDB = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
10661
|
+
var _this = this;
|
|
10662
|
+
return _regenerator().w(function (_context) {
|
|
10663
|
+
while (1) switch (_context.n) {
|
|
10664
|
+
case 0:
|
|
10665
|
+
if (this.idbSupported) {
|
|
10666
|
+
_context.n = 1;
|
|
10667
|
+
break;
|
|
10668
|
+
}
|
|
10669
|
+
throw new Error('IndexedDB not supported');
|
|
10670
|
+
case 1:
|
|
10671
|
+
return _context.a(2, new Promise(function (resolve, reject) {
|
|
10672
|
+
var request = indexedDB.open(_this.dbName, _this.dbVersion);
|
|
10673
|
+
request.onerror = function () {
|
|
10674
|
+
console.error('❌ Failed to open IndexedDB');
|
|
10675
|
+
reject(request.error);
|
|
10676
|
+
};
|
|
10677
|
+
request.onsuccess = function () {
|
|
10678
|
+
console.log('✅ IndexedDB opened successfully');
|
|
10679
|
+
resolve(request.result);
|
|
10680
|
+
};
|
|
10681
|
+
request.onupgradeneeded = function (event) {
|
|
10682
|
+
console.log('🔄 Upgrading IndexedDB schema');
|
|
10683
|
+
var db = event.target.result;
|
|
10684
|
+
|
|
10685
|
+
// Create object store for indexed geometries
|
|
10686
|
+
if (!db.objectStoreNames.contains(_this.storeName)) {
|
|
10687
|
+
var store = db.createObjectStore(_this.storeName, {
|
|
10688
|
+
keyPath: 'modelKey'
|
|
10689
|
+
});
|
|
10690
|
+
store.createIndex('modelType', 'modelType', {
|
|
10691
|
+
unique: false
|
|
10692
|
+
});
|
|
10693
|
+
store.createIndex('sizeKB', 'sizeKB', {
|
|
10694
|
+
unique: false
|
|
10695
|
+
});
|
|
10696
|
+
console.log('📦 Created geometry object store');
|
|
10697
|
+
}
|
|
10698
|
+
};
|
|
10699
|
+
}));
|
|
10700
|
+
}
|
|
10701
|
+
}, _callee, this);
|
|
10702
|
+
}));
|
|
10703
|
+
function initializeIDB() {
|
|
10704
|
+
return _initializeIDB.apply(this, arguments);
|
|
10705
|
+
}
|
|
10706
|
+
return initializeIDB;
|
|
10707
|
+
}()
|
|
10708
|
+
/**
|
|
10709
|
+
* Convert OBJ object to indexed BufferGeometry
|
|
10710
|
+
* @param {THREE.Object3D} objObject - The loaded OBJ object from THREE.OBJLoader
|
|
10711
|
+
* @param {string} modelKey - The model key for identification
|
|
10712
|
+
* @returns {Object} Object containing indexed geometry and metadata
|
|
10713
|
+
*/
|
|
10714
|
+
)
|
|
10715
|
+
}, {
|
|
10716
|
+
key: "objToIndexedBufferGeometry",
|
|
10717
|
+
value: function objToIndexedBufferGeometry(objObject, modelKey) {
|
|
10718
|
+
var _this2 = this;
|
|
10719
|
+
console.log("\uD83D\uDD04 Converting OBJ to indexed BufferGeometry: ".concat(modelKey));
|
|
10720
|
+
var geometries = [];
|
|
10721
|
+
var materials = [];
|
|
10722
|
+
|
|
10723
|
+
// Traverse the OBJ object and collect all geometries
|
|
10724
|
+
objObject.traverse(function (child) {
|
|
10725
|
+
if (child.isMesh && child.geometry) {
|
|
10726
|
+
// Clone the geometry to avoid modifying the original
|
|
10727
|
+
var geometry = child.geometry.clone();
|
|
10728
|
+
|
|
10729
|
+
// Ensure the geometry has proper attributes
|
|
10730
|
+
if (!geometry.attributes.position) {
|
|
10731
|
+
console.warn("\u26A0\uFE0F Geometry missing position attribute: ".concat(modelKey));
|
|
10732
|
+
return;
|
|
10733
|
+
}
|
|
10734
|
+
|
|
10735
|
+
// Compute normals if missing
|
|
10736
|
+
if (!geometry.attributes.normal) {
|
|
10737
|
+
geometry.computeVertexNormals();
|
|
10738
|
+
console.log("\uD83D\uDCD0 Computed normals for geometry: ".concat(modelKey));
|
|
10739
|
+
}
|
|
10740
|
+
|
|
10741
|
+
// Compute UVs if missing (simple planar mapping)
|
|
10742
|
+
if (!geometry.attributes.uv) {
|
|
10743
|
+
_this2.computeSimpleUVs(geometry);
|
|
10744
|
+
console.log("\uD83D\uDDFA\uFE0F Computed UVs for geometry: ".concat(modelKey));
|
|
10745
|
+
}
|
|
10746
|
+
geometries.push(geometry);
|
|
10747
|
+
materials.push(child.material);
|
|
10748
|
+
}
|
|
10749
|
+
});
|
|
10750
|
+
if (geometries.length === 0) {
|
|
10751
|
+
console.warn("\u26A0\uFE0F No valid geometries found in OBJ: ".concat(modelKey));
|
|
10752
|
+
return null;
|
|
10753
|
+
}
|
|
10754
|
+
|
|
10755
|
+
// Merge all geometries into one
|
|
10756
|
+
var mergedGeometry;
|
|
10757
|
+
if (geometries.length === 1) {
|
|
10758
|
+
mergedGeometry = geometries[0];
|
|
10759
|
+
} else {
|
|
10760
|
+
console.log("\uD83D\uDD17 Merging ".concat(geometries.length, " geometries for: ").concat(modelKey));
|
|
10761
|
+
mergedGeometry = mergeGeometries(geometries);
|
|
10762
|
+
}
|
|
10763
|
+
|
|
10764
|
+
// Convert to indexed geometry if not already indexed
|
|
10765
|
+
var indexedGeometry = mergedGeometry;
|
|
10766
|
+
var originalGeometry = mergedGeometry; // Keep reference to original for comparison
|
|
10767
|
+
|
|
10768
|
+
if (!mergedGeometry.index) {
|
|
10769
|
+
console.log("\uD83D\uDCCA Converting to indexed geometry: ".concat(modelKey));
|
|
10770
|
+
indexedGeometry = mergeVertices(mergedGeometry);
|
|
10771
|
+
}
|
|
10772
|
+
|
|
10773
|
+
// Calculate geometry statistics with original geometry for comparison
|
|
10774
|
+
var stats = this.calculateGeometryStats(indexedGeometry, modelKey, originalGeometry);
|
|
10775
|
+
|
|
10776
|
+
// Prepare serializable data for storage
|
|
10777
|
+
var geometryData = this.serializeGeometry(indexedGeometry, modelKey, stats);
|
|
10778
|
+
console.log("\u2705 Successfully converted OBJ to indexed BufferGeometry: ".concat(modelKey));
|
|
10779
|
+
console.log("\uD83D\uDCCA Vertices: ".concat(stats.vertexCount, ", Faces: ").concat(stats.faceCount));
|
|
10780
|
+
console.log("\uD83D\uDCBE Indexed Size: ".concat(stats.indexedSizeKB, "KB"));
|
|
10781
|
+
if (stats.nonIndexedSizeKB > 0) {
|
|
10782
|
+
console.log("\uD83D\uDCBE Non-Indexed Size: ".concat(stats.nonIndexedSizeKB, "KB"));
|
|
10783
|
+
console.log("\uD83D\uDD04 Memory Reduction: ".concat(stats.memoryReduction, "% (").concat(stats.compressionRatio, "x smaller)"));
|
|
10784
|
+
}
|
|
10785
|
+
return {
|
|
10786
|
+
geometry: indexedGeometry,
|
|
10787
|
+
geometryData: geometryData,
|
|
10788
|
+
stats: stats,
|
|
10789
|
+
materials: materials[0] || new THREE__namespace.MeshStandardMaterial({
|
|
10790
|
+
color: 0x888888
|
|
10791
|
+
})
|
|
10792
|
+
};
|
|
10793
|
+
}
|
|
10794
|
+
|
|
10795
|
+
/**
|
|
10796
|
+
* Compute simple planar UVs for geometry
|
|
10797
|
+
* @param {THREE.BufferGeometry} geometry - The geometry to compute UVs for
|
|
10798
|
+
*/
|
|
10799
|
+
}, {
|
|
10800
|
+
key: "computeSimpleUVs",
|
|
10801
|
+
value: function computeSimpleUVs(geometry) {
|
|
10802
|
+
var positions = geometry.attributes.position;
|
|
10803
|
+
var uvs = new Float32Array(positions.count * 2);
|
|
10804
|
+
|
|
10805
|
+
// Simple planar projection on XZ plane
|
|
10806
|
+
for (var i = 0; i < positions.count; i++) {
|
|
10807
|
+
var x = positions.getX(i);
|
|
10808
|
+
var z = positions.getZ(i);
|
|
10809
|
+
|
|
10810
|
+
// Normalize to 0-1 range (simple box projection)
|
|
10811
|
+
uvs[i * 2] = (x + 1) * 0.5;
|
|
10812
|
+
uvs[i * 2 + 1] = (z + 1) * 0.5;
|
|
10813
|
+
}
|
|
10814
|
+
geometry.setAttribute('uv', new THREE__namespace.BufferAttribute(uvs, 2));
|
|
10815
|
+
}
|
|
10816
|
+
|
|
10817
|
+
/**
|
|
10818
|
+
* Calculate geometry statistics
|
|
10819
|
+
* @param {THREE.BufferGeometry} geometry - The geometry to analyze
|
|
10820
|
+
* @param {string} modelKey - The model key for logging
|
|
10821
|
+
* @param {THREE.BufferGeometry} originalGeometry - Optional original non-indexed geometry for comparison
|
|
10822
|
+
* @returns {Object} Statistics object
|
|
10823
|
+
*/
|
|
10824
|
+
}, {
|
|
10825
|
+
key: "calculateGeometryStats",
|
|
10826
|
+
value: function calculateGeometryStats(geometry, modelKey) {
|
|
10827
|
+
var originalGeometry = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
|
|
10828
|
+
var vertexCount = geometry.attributes.position.count;
|
|
10829
|
+
var faceCount = geometry.index ? geometry.index.count / 3 : vertexCount / 3;
|
|
10830
|
+
|
|
10831
|
+
// Calculate indexed geometry memory usage
|
|
10832
|
+
var indexedBytes = 0;
|
|
10833
|
+
|
|
10834
|
+
// Position attribute (3 floats per vertex)
|
|
10835
|
+
if (geometry.attributes.position) {
|
|
10836
|
+
indexedBytes += geometry.attributes.position.array.byteLength;
|
|
10837
|
+
}
|
|
10838
|
+
|
|
10839
|
+
// Normal attribute (3 floats per vertex)
|
|
10840
|
+
if (geometry.attributes.normal) {
|
|
10841
|
+
indexedBytes += geometry.attributes.normal.array.byteLength;
|
|
10842
|
+
}
|
|
10843
|
+
|
|
10844
|
+
// UV attribute (2 floats per vertex)
|
|
10845
|
+
if (geometry.attributes.uv) {
|
|
10846
|
+
indexedBytes += geometry.attributes.uv.array.byteLength;
|
|
10847
|
+
}
|
|
10848
|
+
|
|
10849
|
+
// Index buffer (if indexed)
|
|
10850
|
+
if (geometry.index) {
|
|
10851
|
+
indexedBytes += geometry.index.array.byteLength;
|
|
10852
|
+
}
|
|
10853
|
+
var indexedSizeKB = (indexedBytes / 1024).toFixed(2);
|
|
10854
|
+
|
|
10855
|
+
// Calculate non-indexed geometry memory usage for comparison
|
|
10856
|
+
var nonIndexedBytes = 0;
|
|
10857
|
+
var nonIndexedSizeKB = 0;
|
|
10858
|
+
var memoryReduction = 0;
|
|
10859
|
+
var compressionRatio = 1;
|
|
10860
|
+
if (originalGeometry) {
|
|
10861
|
+
// Calculate what the memory would be without indexing
|
|
10862
|
+
var originalVertexCount = originalGeometry.attributes.position ? originalGeometry.attributes.position.count : vertexCount;
|
|
10863
|
+
|
|
10864
|
+
// Position: 3 floats per vertex
|
|
10865
|
+
nonIndexedBytes += originalVertexCount * 3 * 4; // 4 bytes per float32
|
|
10866
|
+
|
|
10867
|
+
// Normals: 3 floats per vertex (if present)
|
|
10868
|
+
if (originalGeometry.attributes.normal || geometry.attributes.normal) {
|
|
10869
|
+
nonIndexedBytes += originalVertexCount * 3 * 4;
|
|
10870
|
+
}
|
|
10871
|
+
|
|
10872
|
+
// UVs: 2 floats per vertex (if present)
|
|
10873
|
+
if (originalGeometry.attributes.uv || geometry.attributes.uv) {
|
|
10874
|
+
nonIndexedBytes += originalVertexCount * 2 * 4;
|
|
10875
|
+
}
|
|
10876
|
+
nonIndexedSizeKB = (nonIndexedBytes / 1024).toFixed(2);
|
|
10877
|
+
memoryReduction = ((nonIndexedBytes - indexedBytes) / nonIndexedBytes * 100).toFixed(1);
|
|
10878
|
+
compressionRatio = (nonIndexedBytes / indexedBytes).toFixed(2);
|
|
10879
|
+
} else if (geometry.index) {
|
|
10880
|
+
// Estimate non-indexed size based on face count
|
|
10881
|
+
var estimatedNonIndexedVertices = faceCount * 3; // Each face has 3 vertices
|
|
10882
|
+
|
|
10883
|
+
// Position: 3 floats per vertex
|
|
10884
|
+
nonIndexedBytes += estimatedNonIndexedVertices * 3 * 4;
|
|
10885
|
+
|
|
10886
|
+
// Normals: 3 floats per vertex (if present)
|
|
10887
|
+
if (geometry.attributes.normal) {
|
|
10888
|
+
nonIndexedBytes += estimatedNonIndexedVertices * 3 * 4;
|
|
10889
|
+
}
|
|
10890
|
+
|
|
10891
|
+
// UVs: 2 floats per vertex (if present)
|
|
10892
|
+
if (geometry.attributes.uv) {
|
|
10893
|
+
nonIndexedBytes += estimatedNonIndexedVertices * 2 * 4;
|
|
10894
|
+
}
|
|
10895
|
+
nonIndexedSizeKB = (nonIndexedBytes / 1024).toFixed(2);
|
|
10896
|
+
memoryReduction = ((nonIndexedBytes - indexedBytes) / nonIndexedBytes * 100).toFixed(1);
|
|
10897
|
+
compressionRatio = (nonIndexedBytes / indexedBytes).toFixed(2);
|
|
10898
|
+
}
|
|
10899
|
+
var stats = {
|
|
10900
|
+
modelKey: modelKey,
|
|
10901
|
+
vertexCount: vertexCount,
|
|
10902
|
+
faceCount: faceCount,
|
|
10903
|
+
// Indexed geometry stats
|
|
10904
|
+
indexedBytes: indexedBytes,
|
|
10905
|
+
indexedSizeKB: parseFloat(indexedSizeKB),
|
|
10906
|
+
// Non-indexed geometry stats (for comparison)
|
|
10907
|
+
nonIndexedBytes: nonIndexedBytes,
|
|
10908
|
+
nonIndexedSizeKB: parseFloat(nonIndexedSizeKB),
|
|
10909
|
+
// Compression metrics
|
|
10910
|
+
memoryReduction: parseFloat(memoryReduction),
|
|
10911
|
+
// Percentage reduction
|
|
10912
|
+
compressionRatio: parseFloat(compressionRatio),
|
|
10913
|
+
// How many times smaller
|
|
10914
|
+
// Legacy compatibility
|
|
10915
|
+
totalBytes: indexedBytes,
|
|
10916
|
+
// Keep for backward compatibility
|
|
10917
|
+
sizeKB: parseFloat(indexedSizeKB),
|
|
10918
|
+
// Keep for backward compatibility
|
|
10919
|
+
// Features
|
|
10920
|
+
indexed: !!geometry.index,
|
|
10921
|
+
hasNormals: !!geometry.attributes.normal,
|
|
10922
|
+
hasUVs: !!geometry.attributes.uv,
|
|
10923
|
+
timestamp: Date.now()
|
|
10924
|
+
};
|
|
10925
|
+
|
|
10926
|
+
// Cache the size info
|
|
10927
|
+
this.geometrySizeCache.set(modelKey, stats);
|
|
10928
|
+
return stats;
|
|
10929
|
+
}
|
|
10930
|
+
|
|
10931
|
+
/**
|
|
10932
|
+
* Serialize geometry for storage
|
|
10933
|
+
* @param {THREE.BufferGeometry} geometry - The geometry to serialize
|
|
10934
|
+
* @param {string} modelKey - The model key
|
|
10935
|
+
* @param {Object} stats - The geometry statistics
|
|
10936
|
+
* @returns {Object} Serializable geometry data
|
|
10937
|
+
*/
|
|
10938
|
+
}, {
|
|
10939
|
+
key: "serializeGeometry",
|
|
10940
|
+
value: function serializeGeometry(geometry, modelKey, stats) {
|
|
10941
|
+
var data = {
|
|
10942
|
+
modelKey: modelKey,
|
|
10943
|
+
modelType: 'obj',
|
|
10944
|
+
stats: stats,
|
|
10945
|
+
attributes: {}
|
|
10946
|
+
};
|
|
10947
|
+
|
|
10948
|
+
// Serialize position attribute
|
|
10949
|
+
if (geometry.attributes.position) {
|
|
10950
|
+
data.attributes.position = {
|
|
10951
|
+
array: Array.from(geometry.attributes.position.array),
|
|
10952
|
+
itemSize: geometry.attributes.position.itemSize,
|
|
10953
|
+
normalized: geometry.attributes.position.normalized
|
|
10954
|
+
};
|
|
10955
|
+
}
|
|
10956
|
+
|
|
10957
|
+
// Serialize normal attribute
|
|
10958
|
+
if (geometry.attributes.normal) {
|
|
10959
|
+
data.attributes.normal = {
|
|
10960
|
+
array: Array.from(geometry.attributes.normal.array),
|
|
10961
|
+
itemSize: geometry.attributes.normal.itemSize,
|
|
10962
|
+
normalized: geometry.attributes.normal.normalized
|
|
10963
|
+
};
|
|
10964
|
+
}
|
|
10965
|
+
|
|
10966
|
+
// Serialize UV attribute
|
|
10967
|
+
if (geometry.attributes.uv) {
|
|
10968
|
+
data.attributes.uv = {
|
|
10969
|
+
array: Array.from(geometry.attributes.uv.array),
|
|
10970
|
+
itemSize: geometry.attributes.uv.itemSize,
|
|
10971
|
+
normalized: geometry.attributes.uv.normalized
|
|
10972
|
+
};
|
|
10973
|
+
}
|
|
10974
|
+
|
|
10975
|
+
// Serialize index
|
|
10976
|
+
if (geometry.index) {
|
|
10977
|
+
data.index = {
|
|
10978
|
+
array: Array.from(geometry.index.array),
|
|
10979
|
+
itemSize: 1
|
|
10980
|
+
};
|
|
10981
|
+
}
|
|
10982
|
+
return data;
|
|
10983
|
+
}
|
|
10984
|
+
|
|
10985
|
+
/**
|
|
10986
|
+
* Deserialize geometry data back to BufferGeometry
|
|
10987
|
+
* @param {Object} geometryData - The serialized geometry data
|
|
10988
|
+
* @returns {THREE.BufferGeometry} The reconstructed geometry
|
|
10989
|
+
*/
|
|
10990
|
+
}, {
|
|
10991
|
+
key: "deserializeGeometry",
|
|
10992
|
+
value: function deserializeGeometry(geometryData) {
|
|
10993
|
+
var geometry = new THREE__namespace.BufferGeometry();
|
|
10994
|
+
|
|
10995
|
+
// Restore attributes
|
|
10996
|
+
Object.keys(geometryData.attributes).forEach(function (attributeName) {
|
|
10997
|
+
var attrData = geometryData.attributes[attributeName];
|
|
10998
|
+
var array = new Float32Array(attrData.array);
|
|
10999
|
+
var attribute = new THREE__namespace.BufferAttribute(array, attrData.itemSize, attrData.normalized);
|
|
11000
|
+
geometry.setAttribute(attributeName, attribute);
|
|
11001
|
+
});
|
|
11002
|
+
|
|
11003
|
+
// Restore index if present
|
|
11004
|
+
if (geometryData.index) {
|
|
11005
|
+
var indexArray = new Uint32Array(geometryData.index.array);
|
|
11006
|
+
geometry.setIndex(new THREE__namespace.BufferAttribute(indexArray, 1));
|
|
11007
|
+
}
|
|
11008
|
+
return geometry;
|
|
11009
|
+
}
|
|
11010
|
+
|
|
11011
|
+
/**
|
|
11012
|
+
* Store indexed geometry in IndexedDB
|
|
11013
|
+
* @param {Object} geometryData - The serialized geometry data
|
|
11014
|
+
* @returns {Promise} Promise that resolves when stored
|
|
11015
|
+
*/
|
|
11016
|
+
}, {
|
|
11017
|
+
key: "storeGeometryInIDB",
|
|
11018
|
+
value: (function () {
|
|
11019
|
+
var _storeGeometryInIDB = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(geometryData) {
|
|
11020
|
+
var _this3 = this;
|
|
11021
|
+
var db, _t;
|
|
11022
|
+
return _regenerator().w(function (_context2) {
|
|
11023
|
+
while (1) switch (_context2.n) {
|
|
11024
|
+
case 0:
|
|
11025
|
+
if (this.idbSupported) {
|
|
11026
|
+
_context2.n = 1;
|
|
11027
|
+
break;
|
|
11028
|
+
}
|
|
11029
|
+
console.warn('⚠️ IndexedDB not supported, skipping storage');
|
|
11030
|
+
return _context2.a(2);
|
|
11031
|
+
case 1:
|
|
11032
|
+
_context2.p = 1;
|
|
11033
|
+
_context2.n = 2;
|
|
11034
|
+
return this.initializeIDB();
|
|
11035
|
+
case 2:
|
|
11036
|
+
db = _context2.v;
|
|
11037
|
+
return _context2.a(2, new Promise(function (resolve, reject) {
|
|
11038
|
+
var transaction = db.transaction([_this3.storeName], 'readwrite');
|
|
11039
|
+
var store = transaction.objectStore(_this3.storeName);
|
|
11040
|
+
var request = store.put(geometryData);
|
|
11041
|
+
request.onsuccess = function () {
|
|
11042
|
+
console.log("\uD83D\uDCBE Stored geometry in IndexedDB: ".concat(geometryData.modelKey));
|
|
11043
|
+
resolve();
|
|
11044
|
+
};
|
|
11045
|
+
request.onerror = function () {
|
|
11046
|
+
console.error("\u274C Failed to store geometry: ".concat(geometryData.modelKey));
|
|
11047
|
+
reject(request.error);
|
|
11048
|
+
};
|
|
11049
|
+
}));
|
|
11050
|
+
case 3:
|
|
11051
|
+
_context2.p = 3;
|
|
11052
|
+
_t = _context2.v;
|
|
11053
|
+
console.error('❌ Error storing geometry in IndexedDB:', _t);
|
|
11054
|
+
throw _t;
|
|
11055
|
+
case 4:
|
|
11056
|
+
return _context2.a(2);
|
|
11057
|
+
}
|
|
11058
|
+
}, _callee2, this, [[1, 3]]);
|
|
11059
|
+
}));
|
|
11060
|
+
function storeGeometryInIDB(_x) {
|
|
11061
|
+
return _storeGeometryInIDB.apply(this, arguments);
|
|
11062
|
+
}
|
|
11063
|
+
return storeGeometryInIDB;
|
|
11064
|
+
}()
|
|
11065
|
+
/**
|
|
11066
|
+
* Load indexed geometry from IndexedDB
|
|
11067
|
+
* @param {string} modelKey - The model key to load
|
|
11068
|
+
* @returns {Promise<Object>} Promise that resolves to geometry data
|
|
11069
|
+
*/
|
|
11070
|
+
)
|
|
11071
|
+
}, {
|
|
11072
|
+
key: "loadGeometryFromIDB",
|
|
11073
|
+
value: (function () {
|
|
11074
|
+
var _loadGeometryFromIDB = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(modelKey) {
|
|
11075
|
+
var _this4 = this;
|
|
11076
|
+
var db, _t2;
|
|
11077
|
+
return _regenerator().w(function (_context3) {
|
|
11078
|
+
while (1) switch (_context3.n) {
|
|
11079
|
+
case 0:
|
|
11080
|
+
if (this.idbSupported) {
|
|
11081
|
+
_context3.n = 1;
|
|
11082
|
+
break;
|
|
11083
|
+
}
|
|
11084
|
+
console.warn('⚠️ IndexedDB not supported, cannot load');
|
|
11085
|
+
return _context3.a(2, null);
|
|
11086
|
+
case 1:
|
|
11087
|
+
_context3.p = 1;
|
|
11088
|
+
_context3.n = 2;
|
|
11089
|
+
return this.initializeIDB();
|
|
11090
|
+
case 2:
|
|
11091
|
+
db = _context3.v;
|
|
11092
|
+
return _context3.a(2, new Promise(function (resolve, reject) {
|
|
11093
|
+
var transaction = db.transaction([_this4.storeName], 'readonly');
|
|
11094
|
+
var store = transaction.objectStore(_this4.storeName);
|
|
11095
|
+
var request = store.get(modelKey);
|
|
11096
|
+
request.onsuccess = function () {
|
|
11097
|
+
if (request.result) {
|
|
11098
|
+
console.log("\uD83D\uDCE6 Loaded geometry from IndexedDB: ".concat(modelKey));
|
|
11099
|
+
resolve(request.result);
|
|
11100
|
+
} else {
|
|
11101
|
+
console.log("\uD83D\uDCED No geometry found in IndexedDB: ".concat(modelKey));
|
|
11102
|
+
resolve(null);
|
|
11103
|
+
}
|
|
11104
|
+
};
|
|
11105
|
+
request.onerror = function () {
|
|
11106
|
+
console.error("\u274C Failed to load geometry: ".concat(modelKey));
|
|
11107
|
+
reject(request.error);
|
|
11108
|
+
};
|
|
11109
|
+
}));
|
|
11110
|
+
case 3:
|
|
11111
|
+
_context3.p = 3;
|
|
11112
|
+
_t2 = _context3.v;
|
|
11113
|
+
console.error('❌ Error loading geometry from IndexedDB:', _t2);
|
|
11114
|
+
throw _t2;
|
|
11115
|
+
case 4:
|
|
11116
|
+
return _context3.a(2);
|
|
11117
|
+
}
|
|
11118
|
+
}, _callee3, this, [[1, 3]]);
|
|
11119
|
+
}));
|
|
11120
|
+
function loadGeometryFromIDB(_x2) {
|
|
11121
|
+
return _loadGeometryFromIDB.apply(this, arguments);
|
|
11122
|
+
}
|
|
11123
|
+
return loadGeometryFromIDB;
|
|
11124
|
+
}()
|
|
11125
|
+
/**
|
|
11126
|
+
* Create a custom mesh from indexed geometry
|
|
11127
|
+
* @param {string} modelKey - The model key
|
|
11128
|
+
* @param {THREE.Material} material - Optional material to use
|
|
11129
|
+
* @returns {THREE.Mesh|null} The created mesh or null if not found
|
|
11130
|
+
*/
|
|
11131
|
+
)
|
|
11132
|
+
}, {
|
|
11133
|
+
key: "createCustomMesh",
|
|
11134
|
+
value: function createCustomMesh(modelKey) {
|
|
11135
|
+
var material = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
11136
|
+
if (this.indexedGeometryCache.has(modelKey)) {
|
|
11137
|
+
var cachedData = this.indexedGeometryCache.get(modelKey);
|
|
11138
|
+
var geometry = cachedData.geometry.clone();
|
|
11139
|
+
var defaultMaterial = new THREE__namespace.MeshStandardMaterial({
|
|
11140
|
+
color: 0x888888,
|
|
11141
|
+
side: THREE__namespace.DoubleSide,
|
|
11142
|
+
wireframe: false
|
|
11143
|
+
});
|
|
11144
|
+
var mesh = new THREE__namespace.Mesh(geometry, material || defaultMaterial);
|
|
11145
|
+
mesh.userData.modelKey = modelKey;
|
|
11146
|
+
mesh.userData.stats = cachedData.stats;
|
|
11147
|
+
mesh.userData.isCustomGeometry = true;
|
|
11148
|
+
console.log("\uD83C\uDFAF Created custom mesh from indexed geometry: ".concat(modelKey));
|
|
11149
|
+
return mesh;
|
|
11150
|
+
}
|
|
11151
|
+
console.warn("\u26A0\uFE0F Indexed geometry not found in cache: ".concat(modelKey));
|
|
11152
|
+
return null;
|
|
11153
|
+
}
|
|
11154
|
+
|
|
11155
|
+
/**
|
|
11156
|
+
* Process an OBJ object and store the result
|
|
11157
|
+
* @param {THREE.Object3D} objObject - The loaded OBJ object
|
|
11158
|
+
* @param {string} modelKey - The model key
|
|
11159
|
+
* @param {boolean} storeInIDB - Whether to store in IndexedDB
|
|
11160
|
+
* @returns {Promise<Object>} Promise that resolves to the processed result
|
|
11161
|
+
*/
|
|
11162
|
+
}, {
|
|
11163
|
+
key: "processObjObject",
|
|
11164
|
+
value: (function () {
|
|
11165
|
+
var _processObjObject = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(objObject, modelKey) {
|
|
11166
|
+
var storeInIDB,
|
|
11167
|
+
result,
|
|
11168
|
+
_args4 = arguments,
|
|
11169
|
+
_t3;
|
|
11170
|
+
return _regenerator().w(function (_context4) {
|
|
11171
|
+
while (1) switch (_context4.n) {
|
|
11172
|
+
case 0:
|
|
11173
|
+
storeInIDB = _args4.length > 2 && _args4[2] !== undefined ? _args4[2] : true;
|
|
11174
|
+
_context4.p = 1;
|
|
11175
|
+
// Convert to indexed BufferGeometry
|
|
11176
|
+
result = this.objToIndexedBufferGeometry(objObject, modelKey);
|
|
11177
|
+
if (result) {
|
|
11178
|
+
_context4.n = 2;
|
|
11179
|
+
break;
|
|
11180
|
+
}
|
|
11181
|
+
throw new Error("Failed to convert OBJ to indexed geometry: ".concat(modelKey));
|
|
11182
|
+
case 2:
|
|
11183
|
+
// Cache the result
|
|
11184
|
+
this.indexedGeometryCache.set(modelKey, result);
|
|
11185
|
+
|
|
11186
|
+
// Store in IndexedDB if requested
|
|
11187
|
+
if (!(storeInIDB && result.geometryData)) {
|
|
11188
|
+
_context4.n = 3;
|
|
11189
|
+
break;
|
|
11190
|
+
}
|
|
11191
|
+
_context4.n = 3;
|
|
11192
|
+
return this.storeGeometryInIDB(result.geometryData);
|
|
11193
|
+
case 3:
|
|
11194
|
+
console.log("\u2705 Successfully processed OBJ: ".concat(modelKey));
|
|
11195
|
+
return _context4.a(2, result);
|
|
11196
|
+
case 4:
|
|
11197
|
+
_context4.p = 4;
|
|
11198
|
+
_t3 = _context4.v;
|
|
11199
|
+
console.error("\u274C Error processing OBJ: ".concat(modelKey), _t3);
|
|
11200
|
+
throw _t3;
|
|
11201
|
+
case 5:
|
|
11202
|
+
return _context4.a(2);
|
|
11203
|
+
}
|
|
11204
|
+
}, _callee4, this, [[1, 4]]);
|
|
11205
|
+
}));
|
|
11206
|
+
function processObjObject(_x3, _x4) {
|
|
11207
|
+
return _processObjObject.apply(this, arguments);
|
|
11208
|
+
}
|
|
11209
|
+
return processObjObject;
|
|
11210
|
+
}()
|
|
11211
|
+
/**
|
|
11212
|
+
* Get all processed geometry statistics
|
|
11213
|
+
* @returns {Array} Array of geometry statistics
|
|
11214
|
+
*/
|
|
11215
|
+
)
|
|
11216
|
+
}, {
|
|
11217
|
+
key: "getAllGeometryStats",
|
|
11218
|
+
value: function getAllGeometryStats() {
|
|
11219
|
+
var stats = [];
|
|
11220
|
+
this.geometrySizeCache.forEach(function (stat, modelKey) {
|
|
11221
|
+
stats.push(stat);
|
|
11222
|
+
});
|
|
11223
|
+
return stats.sort(function (a, b) {
|
|
11224
|
+
return b.sizeKB - a.sizeKB;
|
|
11225
|
+
}); // Sort by size descending
|
|
11226
|
+
}
|
|
11227
|
+
|
|
11228
|
+
/**
|
|
11229
|
+
* Get total memory usage of cached geometries
|
|
11230
|
+
* @returns {Object} Memory usage statistics
|
|
11231
|
+
*/
|
|
11232
|
+
}, {
|
|
11233
|
+
key: "getMemoryUsage",
|
|
11234
|
+
value: function getMemoryUsage() {
|
|
11235
|
+
var totalIndexedBytes = 0;
|
|
11236
|
+
var totalNonIndexedBytes = 0;
|
|
11237
|
+
var totalGeometries = 0;
|
|
11238
|
+
this.geometrySizeCache.forEach(function (stats) {
|
|
11239
|
+
totalIndexedBytes += stats.indexedBytes;
|
|
11240
|
+
totalNonIndexedBytes += stats.nonIndexedBytes;
|
|
11241
|
+
totalGeometries++;
|
|
11242
|
+
});
|
|
11243
|
+
var totalMemoryReduction = totalNonIndexedBytes > 0 ? ((totalNonIndexedBytes - totalIndexedBytes) / totalNonIndexedBytes * 100).toFixed(1) : 0;
|
|
11244
|
+
var totalCompressionRatio = totalIndexedBytes > 0 ? (totalNonIndexedBytes / totalIndexedBytes).toFixed(2) : 1;
|
|
11245
|
+
return {
|
|
11246
|
+
totalGeometries: totalGeometries,
|
|
11247
|
+
// Indexed geometry stats
|
|
11248
|
+
indexedBytes: totalIndexedBytes,
|
|
11249
|
+
indexedKB: (totalIndexedBytes / 1024).toFixed(2),
|
|
11250
|
+
indexedMB: (totalIndexedBytes / (1024 * 1024)).toFixed(3),
|
|
11251
|
+
// Non-indexed geometry stats
|
|
11252
|
+
nonIndexedBytes: totalNonIndexedBytes,
|
|
11253
|
+
nonIndexedKB: (totalNonIndexedBytes / 1024).toFixed(2),
|
|
11254
|
+
nonIndexedMB: (totalNonIndexedBytes / (1024 * 1024)).toFixed(3),
|
|
11255
|
+
// Compression stats
|
|
11256
|
+
memoryReduction: parseFloat(totalMemoryReduction),
|
|
11257
|
+
compressionRatio: parseFloat(totalCompressionRatio),
|
|
11258
|
+
// Legacy compatibility
|
|
11259
|
+
totalBytes: totalIndexedBytes,
|
|
11260
|
+
totalKB: (totalIndexedBytes / 1024).toFixed(2),
|
|
11261
|
+
totalMB: (totalIndexedBytes / (1024 * 1024)).toFixed(2)
|
|
11262
|
+
};
|
|
11263
|
+
}
|
|
11264
|
+
|
|
11265
|
+
/**
|
|
11266
|
+
* Clear all caches
|
|
11267
|
+
*/
|
|
11268
|
+
}, {
|
|
11269
|
+
key: "clearCaches",
|
|
11270
|
+
value: function clearCaches() {
|
|
11271
|
+
console.log('🧹 Clearing OBJ processor caches...');
|
|
11272
|
+
|
|
11273
|
+
// Dispose of cached geometries
|
|
11274
|
+
this.indexedGeometryCache.forEach(function (data, modelKey) {
|
|
11275
|
+
if (data.geometry) {
|
|
11276
|
+
data.geometry.dispose();
|
|
11277
|
+
}
|
|
11278
|
+
console.log("\uD83D\uDDD1\uFE0F Disposed cached geometry: ".concat(modelKey));
|
|
11279
|
+
});
|
|
11280
|
+
this.indexedGeometryCache.clear();
|
|
11281
|
+
this.geometrySizeCache.clear();
|
|
11282
|
+
console.log('✅ OBJ processor caches cleared');
|
|
11283
|
+
}
|
|
11284
|
+
|
|
11285
|
+
/**
|
|
11286
|
+
* Get processing status
|
|
11287
|
+
* @returns {Object} Status information
|
|
11288
|
+
*/
|
|
11289
|
+
}, {
|
|
11290
|
+
key: "getStatus",
|
|
11291
|
+
value: function getStatus() {
|
|
11292
|
+
return {
|
|
11293
|
+
cachedGeometries: Array.from(this.indexedGeometryCache.keys()),
|
|
11294
|
+
totalCached: this.indexedGeometryCache.size,
|
|
11295
|
+
idbSupported: this.idbSupported,
|
|
11296
|
+
memoryUsage: this.getMemoryUsage()
|
|
11297
|
+
};
|
|
11298
|
+
}
|
|
11299
|
+
}]);
|
|
11300
|
+
}(); // Export the class
|
|
10169
11301
|
|
|
10170
11302
|
var ModelPreloader = /*#__PURE__*/function () {
|
|
10171
11303
|
function ModelPreloader() {
|
|
@@ -10174,10 +11306,12 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10174
11306
|
this.loadingPromises = new Map(); // Track ongoing loads to prevent duplicates
|
|
10175
11307
|
this.gltfLoader = new GLTFLoader();
|
|
10176
11308
|
this.objLoader = new OBJLoader();
|
|
11309
|
+
this.objProcessor = new ObjProcessor(); // Initialize OBJ processor
|
|
10177
11310
|
this.isPreloading = false;
|
|
10178
11311
|
this.preloadingPromise = null;
|
|
10179
11312
|
this.componentDictionary = null;
|
|
10180
11313
|
console.log('🚀 ModelPreloader initialized with GLB and OBJ support');
|
|
11314
|
+
console.log('🔧 OBJ Processor integrated for indexed BufferGeometry conversion');
|
|
10181
11315
|
}
|
|
10182
11316
|
|
|
10183
11317
|
/**
|
|
@@ -10283,93 +11417,110 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10283
11417
|
}, {
|
|
10284
11418
|
key: "preloadSingleModel",
|
|
10285
11419
|
value: (function () {
|
|
10286
|
-
var _preloadSingleModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
11420
|
+
var _preloadSingleModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(modelKey) {
|
|
10287
11421
|
var _this2 = this;
|
|
10288
11422
|
var modelType,
|
|
10289
11423
|
loadPromise,
|
|
10290
|
-
|
|
10291
|
-
return _regenerator().w(function (
|
|
10292
|
-
while (1) switch (
|
|
11424
|
+
_args3 = arguments;
|
|
11425
|
+
return _regenerator().w(function (_context3) {
|
|
11426
|
+
while (1) switch (_context3.n) {
|
|
10293
11427
|
case 0:
|
|
10294
|
-
modelType =
|
|
11428
|
+
modelType = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : 'glb';
|
|
10295
11429
|
if (!this.modelCache.has(modelKey)) {
|
|
10296
|
-
|
|
11430
|
+
_context3.n = 1;
|
|
10297
11431
|
break;
|
|
10298
11432
|
}
|
|
10299
11433
|
console.log("\uD83C\uDFAF Model ".concat(modelKey, " already cached, skipping"));
|
|
10300
|
-
return
|
|
11434
|
+
return _context3.a(2, this.modelCache.get(modelKey));
|
|
10301
11435
|
case 1:
|
|
10302
11436
|
if (!this.loadingPromises.has(modelKey)) {
|
|
10303
|
-
|
|
11437
|
+
_context3.n = 2;
|
|
10304
11438
|
break;
|
|
10305
11439
|
}
|
|
10306
11440
|
console.log("\u23F3 Model ".concat(modelKey, " already loading, waiting for completion"));
|
|
10307
|
-
return
|
|
11441
|
+
return _context3.a(2, this.loadingPromises.get(modelKey));
|
|
10308
11442
|
case 2:
|
|
10309
11443
|
console.log("\uD83D\uDD04 Starting preload of ".concat(modelType.toUpperCase(), " model: ").concat(modelKey));
|
|
10310
11444
|
loadPromise = new Promise(function (resolve, reject) {
|
|
10311
11445
|
var modelPath = "/library/models/".concat(modelKey);
|
|
10312
11446
|
if (modelType === 'obj') {
|
|
10313
|
-
// Load OBJ model
|
|
10314
|
-
_this2.objLoader.load(modelPath, function (
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10339
|
-
|
|
10340
|
-
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10344
|
-
|
|
10345
|
-
|
|
10346
|
-
|
|
10347
|
-
|
|
10348
|
-
|
|
10349
|
-
|
|
10350
|
-
|
|
10351
|
-
|
|
11447
|
+
// Load OBJ model with advanced processing
|
|
11448
|
+
_this2.objLoader.load(modelPath, /*#__PURE__*/function () {
|
|
11449
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(object) {
|
|
11450
|
+
var processedResult, modelData, _t;
|
|
11451
|
+
return _regenerator().w(function (_context2) {
|
|
11452
|
+
while (1) switch (_context2.n) {
|
|
11453
|
+
case 0:
|
|
11454
|
+
_context2.p = 0;
|
|
11455
|
+
console.log("\u2705 Successfully loaded OBJ model: ".concat(modelKey));
|
|
11456
|
+
|
|
11457
|
+
// Process OBJ with the new processor for indexed BufferGeometry
|
|
11458
|
+
_context2.n = 1;
|
|
11459
|
+
return _this2.objProcessor.processObjObject(object, modelKey, true);
|
|
11460
|
+
case 1:
|
|
11461
|
+
processedResult = _context2.v;
|
|
11462
|
+
if (!processedResult) {
|
|
11463
|
+
_context2.n = 2;
|
|
11464
|
+
break;
|
|
11465
|
+
}
|
|
11466
|
+
console.log("\uD83D\uDD27 OBJ processed to indexed BufferGeometry: ".concat(modelKey));
|
|
11467
|
+
console.log("\uD83D\uDCCA Geometry stats:", processedResult.stats);
|
|
11468
|
+
|
|
11469
|
+
// Apply double-sided materials to original OBJ for compatibility
|
|
11470
|
+
object.traverse(function (child) {
|
|
11471
|
+
if (child.isMesh) {
|
|
11472
|
+
var solidMaterial = new THREE__namespace.MeshStandardMaterial({
|
|
11473
|
+
color: child.material.color || 0x888888,
|
|
11474
|
+
side: THREE__namespace.DoubleSide,
|
|
11475
|
+
wireframe: false
|
|
11476
|
+
});
|
|
11477
|
+
child.material = solidMaterial;
|
|
11478
|
+
}
|
|
11479
|
+
});
|
|
11480
|
+
|
|
11481
|
+
// Store both the original object and processed data
|
|
11482
|
+
modelData = {
|
|
11483
|
+
originalObject: object,
|
|
11484
|
+
processedGeometry: processedResult.geometry,
|
|
11485
|
+
geometryStats: processedResult.stats,
|
|
11486
|
+
materials: processedResult.materials,
|
|
11487
|
+
isObjModel: true
|
|
11488
|
+
}; // Cache the model data
|
|
11489
|
+
_this2.modelCache.set(modelKey, modelData);
|
|
11490
|
+
_this2.loadingPromises.delete(modelKey);
|
|
11491
|
+
resolve(modelData);
|
|
11492
|
+
_context2.n = 3;
|
|
11493
|
+
break;
|
|
11494
|
+
case 2:
|
|
11495
|
+
throw new Error('Failed to process OBJ to indexed geometry');
|
|
11496
|
+
case 3:
|
|
11497
|
+
_context2.n = 5;
|
|
11498
|
+
break;
|
|
11499
|
+
case 4:
|
|
11500
|
+
_context2.p = 4;
|
|
11501
|
+
_t = _context2.v;
|
|
11502
|
+
console.error("\u274C Error processing OBJ model ".concat(modelKey, ":"), _t);
|
|
11503
|
+
// Fallback: cache the original object without processing
|
|
11504
|
+
_this2.modelCache.set(modelKey, object);
|
|
11505
|
+
_this2.loadingPromises.delete(modelKey);
|
|
11506
|
+
resolve(object);
|
|
11507
|
+
case 5:
|
|
11508
|
+
return _context2.a(2);
|
|
10352
11509
|
}
|
|
10353
|
-
}
|
|
10354
|
-
});
|
|
10355
|
-
|
|
10356
|
-
|
|
10357
|
-
|
|
10358
|
-
|
|
10359
|
-
_this2.loadingPromises.delete(modelKey);
|
|
10360
|
-
resolve(object);
|
|
10361
|
-
}, function (progress) {
|
|
10362
|
-
// Optional: track loading progress
|
|
11510
|
+
}, _callee2, null, [[0, 4]]);
|
|
11511
|
+
}));
|
|
11512
|
+
return function (_x3) {
|
|
11513
|
+
return _ref.apply(this, arguments);
|
|
11514
|
+
};
|
|
11515
|
+
}(), function (progress) {
|
|
10363
11516
|
if (progress.lengthComputable) {
|
|
10364
11517
|
var percentage = progress.loaded / progress.total * 100;
|
|
10365
11518
|
if (percentage % 25 === 0) {
|
|
10366
|
-
// Log every 25%
|
|
10367
11519
|
console.log("\uD83D\uDCCA Loading OBJ ".concat(modelKey, ": ").concat(percentage.toFixed(0), "%"));
|
|
10368
11520
|
}
|
|
10369
11521
|
}
|
|
10370
11522
|
}, function (error) {
|
|
10371
11523
|
console.error("\u274C Failed to preload OBJ model ".concat(modelKey, ":"), error);
|
|
10372
|
-
// Remove from loading promises
|
|
10373
11524
|
_this2.loadingPromises.delete(modelKey);
|
|
10374
11525
|
reject(error);
|
|
10375
11526
|
});
|
|
@@ -10400,9 +11551,9 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10400
11551
|
}
|
|
10401
11552
|
}); // Cache the loading promise
|
|
10402
11553
|
this.loadingPromises.set(modelKey, loadPromise);
|
|
10403
|
-
return
|
|
11554
|
+
return _context3.a(2, loadPromise);
|
|
10404
11555
|
}
|
|
10405
|
-
},
|
|
11556
|
+
}, _callee3, this);
|
|
10406
11557
|
}));
|
|
10407
11558
|
function preloadSingleModel(_x2) {
|
|
10408
11559
|
return _preloadSingleModel.apply(this, arguments);
|
|
@@ -10412,18 +11563,42 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10412
11563
|
/**
|
|
10413
11564
|
* Get a cached model (cloned for use)
|
|
10414
11565
|
* @param {string} modelKey - The model key
|
|
11566
|
+
* @param {boolean} useIndexedGeometry - Whether to use indexed geometry for OBJ models
|
|
10415
11567
|
* @returns {THREE.Object3D|null} Cloned model or null if not found
|
|
10416
11568
|
*/
|
|
10417
11569
|
)
|
|
10418
11570
|
}, {
|
|
10419
11571
|
key: "getCachedModel",
|
|
10420
11572
|
value: function getCachedModel(modelKey) {
|
|
11573
|
+
var useIndexedGeometry = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
10421
11574
|
if (this.modelCache.has(modelKey)) {
|
|
10422
11575
|
console.log("\uD83C\uDFAF Returning cached model: ".concat(modelKey));
|
|
10423
|
-
var
|
|
11576
|
+
var cachedData = this.modelCache.get(modelKey);
|
|
11577
|
+
|
|
11578
|
+
// Handle OBJ models with processed geometry
|
|
11579
|
+
if (cachedData && cachedData.isObjModel && useIndexedGeometry && cachedData.processedGeometry) {
|
|
11580
|
+
console.log("\uD83D\uDD27 Using indexed BufferGeometry for OBJ: ".concat(modelKey));
|
|
11581
|
+
|
|
11582
|
+
// Create a mesh from the processed indexed geometry
|
|
11583
|
+
var mesh = new THREE__namespace.Mesh(cachedData.processedGeometry.clone(), cachedData.materials.clone());
|
|
10424
11584
|
|
|
10425
|
-
|
|
10426
|
-
|
|
11585
|
+
// Add metadata
|
|
11586
|
+
mesh.userData.modelKey = modelKey;
|
|
11587
|
+
mesh.userData.geometryStats = cachedData.geometryStats;
|
|
11588
|
+
mesh.userData.isIndexedGeometry = true;
|
|
11589
|
+
mesh.userData.originalSizeKB = cachedData.geometryStats.sizeKB;
|
|
11590
|
+
return mesh;
|
|
11591
|
+
}
|
|
11592
|
+
|
|
11593
|
+
// Handle regular models or OBJ models without indexed geometry
|
|
11594
|
+
var modelToClone = cachedData.isObjModel ? cachedData.originalObject : cachedData;
|
|
11595
|
+
var clonedModel = modelToClone.clone();
|
|
11596
|
+
|
|
11597
|
+
// Add OBJ stats if available
|
|
11598
|
+
if (cachedData.isObjModel && cachedData.geometryStats) {
|
|
11599
|
+
clonedModel.userData.geometryStats = cachedData.geometryStats;
|
|
11600
|
+
clonedModel.userData.isObjModel = true;
|
|
11601
|
+
}
|
|
10427
11602
|
return clonedModel;
|
|
10428
11603
|
}
|
|
10429
11604
|
console.warn("\u26A0\uFE0F Model ".concat(modelKey, " not found in cache"));
|
|
@@ -10531,41 +11706,41 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10531
11706
|
}, {
|
|
10532
11707
|
key: "reloadModel",
|
|
10533
11708
|
value: (function () {
|
|
10534
|
-
var _reloadModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function
|
|
11709
|
+
var _reloadModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(modelKey) {
|
|
10535
11710
|
var modelType,
|
|
10536
11711
|
_i,
|
|
10537
11712
|
_Object$keys,
|
|
10538
11713
|
componentType,
|
|
10539
11714
|
component,
|
|
10540
|
-
|
|
10541
|
-
return _regenerator().w(function (
|
|
10542
|
-
while (1) switch (
|
|
11715
|
+
_args4 = arguments;
|
|
11716
|
+
return _regenerator().w(function (_context4) {
|
|
11717
|
+
while (1) switch (_context4.n) {
|
|
10543
11718
|
case 0:
|
|
10544
|
-
modelType =
|
|
11719
|
+
modelType = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : null;
|
|
10545
11720
|
console.log("\uD83D\uDD04 Force reloading model: ".concat(modelKey));
|
|
10546
11721
|
|
|
10547
11722
|
// Try to determine model type from component dictionary if not provided
|
|
10548
11723
|
if (!(!modelType && this.componentDictionary)) {
|
|
10549
|
-
|
|
11724
|
+
_context4.n = 3;
|
|
10550
11725
|
break;
|
|
10551
11726
|
}
|
|
10552
11727
|
_i = 0, _Object$keys = Object.keys(this.componentDictionary);
|
|
10553
11728
|
case 1:
|
|
10554
11729
|
if (!(_i < _Object$keys.length)) {
|
|
10555
|
-
|
|
11730
|
+
_context4.n = 3;
|
|
10556
11731
|
break;
|
|
10557
11732
|
}
|
|
10558
11733
|
componentType = _Object$keys[_i];
|
|
10559
11734
|
component = this.componentDictionary[componentType];
|
|
10560
11735
|
if (!(component && component.modelKey === modelKey)) {
|
|
10561
|
-
|
|
11736
|
+
_context4.n = 2;
|
|
10562
11737
|
break;
|
|
10563
11738
|
}
|
|
10564
11739
|
modelType = component.modelType || 'glb';
|
|
10565
|
-
return
|
|
11740
|
+
return _context4.a(3, 3);
|
|
10566
11741
|
case 2:
|
|
10567
11742
|
_i++;
|
|
10568
|
-
|
|
11743
|
+
_context4.n = 1;
|
|
10569
11744
|
break;
|
|
10570
11745
|
case 3:
|
|
10571
11746
|
// Default to GLB if still not determined
|
|
@@ -10576,11 +11751,11 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10576
11751
|
this.loadingPromises.delete(modelKey);
|
|
10577
11752
|
|
|
10578
11753
|
// Preload again
|
|
10579
|
-
return
|
|
11754
|
+
return _context4.a(2, this.preloadSingleModel(modelKey, modelType));
|
|
10580
11755
|
}
|
|
10581
|
-
},
|
|
11756
|
+
}, _callee4, this);
|
|
10582
11757
|
}));
|
|
10583
|
-
function reloadModel(
|
|
11758
|
+
function reloadModel(_x4) {
|
|
10584
11759
|
return _reloadModel.apply(this, arguments);
|
|
10585
11760
|
}
|
|
10586
11761
|
return reloadModel;
|
|
@@ -10597,7 +11772,42 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10597
11772
|
// Dispose of all cached models
|
|
10598
11773
|
this.modelCache.forEach(function (model, modelKey) {
|
|
10599
11774
|
console.log("\uD83D\uDDD1\uFE0F Disposing cached model: ".concat(modelKey));
|
|
10600
|
-
if (model && model.
|
|
11775
|
+
if (model && model.isObjModel) {
|
|
11776
|
+
// Handle OBJ model data structure
|
|
11777
|
+
if (model.originalObject && model.originalObject.traverse) {
|
|
11778
|
+
model.originalObject.traverse(function (child) {
|
|
11779
|
+
if (child.geometry) {
|
|
11780
|
+
child.geometry.dispose();
|
|
11781
|
+
}
|
|
11782
|
+
if (child.material) {
|
|
11783
|
+
if (Array.isArray(child.material)) {
|
|
11784
|
+
child.material.forEach(function (material) {
|
|
11785
|
+
return material.dispose();
|
|
11786
|
+
});
|
|
11787
|
+
} else {
|
|
11788
|
+
child.material.dispose();
|
|
11789
|
+
}
|
|
11790
|
+
}
|
|
11791
|
+
});
|
|
11792
|
+
}
|
|
11793
|
+
|
|
11794
|
+
// Dispose processed geometry
|
|
11795
|
+
if (model.processedGeometry) {
|
|
11796
|
+
model.processedGeometry.dispose();
|
|
11797
|
+
}
|
|
11798
|
+
|
|
11799
|
+
// Dispose materials
|
|
11800
|
+
if (model.materials) {
|
|
11801
|
+
if (Array.isArray(model.materials)) {
|
|
11802
|
+
model.materials.forEach(function (material) {
|
|
11803
|
+
return material.dispose();
|
|
11804
|
+
});
|
|
11805
|
+
} else {
|
|
11806
|
+
model.materials.dispose();
|
|
11807
|
+
}
|
|
11808
|
+
}
|
|
11809
|
+
} else if (model && model.traverse) {
|
|
11810
|
+
// Handle regular model
|
|
10601
11811
|
model.traverse(function (child) {
|
|
10602
11812
|
if (child.geometry) {
|
|
10603
11813
|
child.geometry.dispose();
|
|
@@ -10618,6 +11828,9 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10618
11828
|
this.loadingPromises.clear();
|
|
10619
11829
|
this.isPreloading = false;
|
|
10620
11830
|
this.preloadingPromise = null;
|
|
11831
|
+
|
|
11832
|
+
// Clear OBJ processor caches
|
|
11833
|
+
this.objProcessor.clearCaches();
|
|
10621
11834
|
console.log('✅ Model preloader cache cleared');
|
|
10622
11835
|
}
|
|
10623
11836
|
|
|
@@ -10726,13 +11939,15 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10726
11939
|
totalModels: this.modelCache.size,
|
|
10727
11940
|
loadingModels: this.loadingPromises.size,
|
|
10728
11941
|
isPreloading: this.isPreloading,
|
|
10729
|
-
memoryUsage: 0
|
|
11942
|
+
memoryUsage: 0,
|
|
11943
|
+
objProcessorStats: this.objProcessor.getStatus()
|
|
10730
11944
|
};
|
|
10731
11945
|
|
|
10732
11946
|
// Estimate memory usage (rough calculation)
|
|
10733
11947
|
this.modelCache.forEach(function (model) {
|
|
10734
11948
|
if (model && model.traverse) {
|
|
10735
|
-
model.
|
|
11949
|
+
var modelToAnalyze = model.isObjModel ? model.originalObject : model;
|
|
11950
|
+
modelToAnalyze.traverse(function (child) {
|
|
10736
11951
|
if (child.geometry) {
|
|
10737
11952
|
var _child$geometry$attri;
|
|
10738
11953
|
stats.memoryUsage += (((_child$geometry$attri = child.geometry.attributes.position) === null || _child$geometry$attri === void 0 ? void 0 : _child$geometry$attri.count) || 0) * 12; // Rough estimate
|
|
@@ -10742,6 +11957,82 @@ var ModelPreloader = /*#__PURE__*/function () {
|
|
|
10742
11957
|
});
|
|
10743
11958
|
return stats;
|
|
10744
11959
|
}
|
|
11960
|
+
|
|
11961
|
+
/**
|
|
11962
|
+
* Get all OBJ geometry statistics
|
|
11963
|
+
* @returns {Array} Array of OBJ geometry statistics
|
|
11964
|
+
*/
|
|
11965
|
+
}, {
|
|
11966
|
+
key: "getObjGeometryStats",
|
|
11967
|
+
value: function getObjGeometryStats() {
|
|
11968
|
+
return this.objProcessor.getAllGeometryStats();
|
|
11969
|
+
}
|
|
11970
|
+
|
|
11971
|
+
/**
|
|
11972
|
+
* Get OBJ processor memory usage
|
|
11973
|
+
* @returns {Object} Memory usage statistics
|
|
11974
|
+
*/
|
|
11975
|
+
}, {
|
|
11976
|
+
key: "getObjMemoryUsage",
|
|
11977
|
+
value: function getObjMemoryUsage() {
|
|
11978
|
+
return this.objProcessor.getMemoryUsage();
|
|
11979
|
+
}
|
|
11980
|
+
|
|
11981
|
+
/**
|
|
11982
|
+
* Create a custom mesh from indexed OBJ geometry
|
|
11983
|
+
* @param {string} modelKey - The model key (must be an OBJ)
|
|
11984
|
+
* @param {THREE.Material} material - Optional material to use
|
|
11985
|
+
* @returns {THREE.Mesh|null} The created mesh or null if not found
|
|
11986
|
+
*/
|
|
11987
|
+
}, {
|
|
11988
|
+
key: "createCustomObjMesh",
|
|
11989
|
+
value: function createCustomObjMesh(modelKey) {
|
|
11990
|
+
var material = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
|
|
11991
|
+
return this.objProcessor.createCustomMesh(modelKey, material);
|
|
11992
|
+
}
|
|
11993
|
+
|
|
11994
|
+
/**
|
|
11995
|
+
* Get indexed geometry directly from processor
|
|
11996
|
+
* @param {string} modelKey - The model key
|
|
11997
|
+
* @returns {THREE.BufferGeometry|null} The indexed geometry or null
|
|
11998
|
+
*/
|
|
11999
|
+
}, {
|
|
12000
|
+
key: "getIndexedGeometry",
|
|
12001
|
+
value: function getIndexedGeometry(modelKey) {
|
|
12002
|
+
var result = this.objProcessor.indexedGeometryCache.get(modelKey);
|
|
12003
|
+
return result ? result.geometry.clone() : null;
|
|
12004
|
+
}
|
|
12005
|
+
|
|
12006
|
+
/**
|
|
12007
|
+
* Force reload and reprocess an OBJ model
|
|
12008
|
+
* @param {string} modelKey - The model key to reload
|
|
12009
|
+
* @returns {Promise} Promise that resolves with the reloaded model
|
|
12010
|
+
*/
|
|
12011
|
+
}, {
|
|
12012
|
+
key: "reloadObjModel",
|
|
12013
|
+
value: (function () {
|
|
12014
|
+
var _reloadObjModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(modelKey) {
|
|
12015
|
+
return _regenerator().w(function (_context5) {
|
|
12016
|
+
while (1) switch (_context5.n) {
|
|
12017
|
+
case 0:
|
|
12018
|
+
console.log("\uD83D\uDD04 Force reloading OBJ model: ".concat(modelKey));
|
|
12019
|
+
|
|
12020
|
+
// Clear from both caches
|
|
12021
|
+
this.modelCache.delete(modelKey);
|
|
12022
|
+
this.loadingPromises.delete(modelKey);
|
|
12023
|
+
this.objProcessor.indexedGeometryCache.delete(modelKey);
|
|
12024
|
+
this.objProcessor.geometrySizeCache.delete(modelKey);
|
|
12025
|
+
|
|
12026
|
+
// Reload with OBJ processing
|
|
12027
|
+
return _context5.a(2, this.preloadSingleModel(modelKey, 'obj'));
|
|
12028
|
+
}
|
|
12029
|
+
}, _callee5, this);
|
|
12030
|
+
}));
|
|
12031
|
+
function reloadObjModel(_x5) {
|
|
12032
|
+
return _reloadObjModel.apply(this, arguments);
|
|
12033
|
+
}
|
|
12034
|
+
return reloadObjModel;
|
|
12035
|
+
}())
|
|
10745
12036
|
}]);
|
|
10746
12037
|
}(); // Create singleton instance
|
|
10747
12038
|
var modelPreloader = new ModelPreloader();
|
|
@@ -35283,6 +36574,250 @@ var testing = /*#__PURE__*/Object.freeze({
|
|
|
35283
36574
|
Testing: Testing
|
|
35284
36575
|
});
|
|
35285
36576
|
|
|
36577
|
+
var ObjProcessingDemo = /*#__PURE__*/function () {
|
|
36578
|
+
function ObjProcessingDemo() {
|
|
36579
|
+
_classCallCheck(this, ObjProcessingDemo);
|
|
36580
|
+
this.objProcessor = new ObjProcessor();
|
|
36581
|
+
this.componentDictionary = null;
|
|
36582
|
+
this.processedResults = new Map();
|
|
36583
|
+
}
|
|
36584
|
+
|
|
36585
|
+
/**
|
|
36586
|
+
* Load component dictionary
|
|
36587
|
+
* @returns {Promise<Object>} Component dictionary
|
|
36588
|
+
*/
|
|
36589
|
+
return _createClass(ObjProcessingDemo, [{
|
|
36590
|
+
key: "loadComponentDictionary",
|
|
36591
|
+
value: (function () {
|
|
36592
|
+
var _loadComponentDictionary = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
36593
|
+
var response, _t;
|
|
36594
|
+
return _regenerator().w(function (_context) {
|
|
36595
|
+
while (1) switch (_context.n) {
|
|
36596
|
+
case 0:
|
|
36597
|
+
_context.p = 0;
|
|
36598
|
+
_context.n = 1;
|
|
36599
|
+
return fetch('/library/component-dictionary.json');
|
|
36600
|
+
case 1:
|
|
36601
|
+
response = _context.v;
|
|
36602
|
+
_context.n = 2;
|
|
36603
|
+
return response.json();
|
|
36604
|
+
case 2:
|
|
36605
|
+
this.componentDictionary = _context.v;
|
|
36606
|
+
return _context.a(2, this.componentDictionary);
|
|
36607
|
+
case 3:
|
|
36608
|
+
_context.p = 3;
|
|
36609
|
+
_t = _context.v;
|
|
36610
|
+
throw _t;
|
|
36611
|
+
case 4:
|
|
36612
|
+
return _context.a(2);
|
|
36613
|
+
}
|
|
36614
|
+
}, _callee, this, [[0, 3]]);
|
|
36615
|
+
}));
|
|
36616
|
+
function loadComponentDictionary() {
|
|
36617
|
+
return _loadComponentDictionary.apply(this, arguments);
|
|
36618
|
+
}
|
|
36619
|
+
return loadComponentDictionary;
|
|
36620
|
+
}()
|
|
36621
|
+
/**
|
|
36622
|
+
* Get all OBJ models from component dictionary
|
|
36623
|
+
* @returns {Array} Array of OBJ model configurations
|
|
36624
|
+
*/
|
|
36625
|
+
)
|
|
36626
|
+
}, {
|
|
36627
|
+
key: "getObjModels",
|
|
36628
|
+
value: function getObjModels() {
|
|
36629
|
+
var _this = this;
|
|
36630
|
+
if (!this.componentDictionary) {
|
|
36631
|
+
return [];
|
|
36632
|
+
}
|
|
36633
|
+
var objModels = [];
|
|
36634
|
+
Object.keys(this.componentDictionary).forEach(function (componentId) {
|
|
36635
|
+
var component = _this.componentDictionary[componentId];
|
|
36636
|
+
if (component.modelType === 'obj') {
|
|
36637
|
+
objModels.push({
|
|
36638
|
+
componentId: componentId,
|
|
36639
|
+
modelKey: component.modelKey,
|
|
36640
|
+
name: component.name,
|
|
36641
|
+
boundingBox: component.boundingBox
|
|
36642
|
+
});
|
|
36643
|
+
}
|
|
36644
|
+
});
|
|
36645
|
+
return objModels;
|
|
36646
|
+
}
|
|
36647
|
+
|
|
36648
|
+
/**
|
|
36649
|
+
* Process all OBJ models and store in IndexedDB
|
|
36650
|
+
* @returns {Promise<Array>} Array of processing results
|
|
36651
|
+
*/
|
|
36652
|
+
}, {
|
|
36653
|
+
key: "processAllObjModels",
|
|
36654
|
+
value: (function () {
|
|
36655
|
+
var _processAllObjModels = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
36656
|
+
var objModels, processingResults, _iterator, _step, objModel, cachedModelData, result, serializedData, _t3;
|
|
36657
|
+
return _regenerator().w(function (_context2) {
|
|
36658
|
+
while (1) switch (_context2.n) {
|
|
36659
|
+
case 0:
|
|
36660
|
+
if (this.componentDictionary) {
|
|
36661
|
+
_context2.n = 1;
|
|
36662
|
+
break;
|
|
36663
|
+
}
|
|
36664
|
+
_context2.n = 1;
|
|
36665
|
+
return this.loadComponentDictionary();
|
|
36666
|
+
case 1:
|
|
36667
|
+
// Get all OBJ models
|
|
36668
|
+
objModels = this.getObjModels();
|
|
36669
|
+
if (!(objModels.length === 0)) {
|
|
36670
|
+
_context2.n = 2;
|
|
36671
|
+
break;
|
|
36672
|
+
}
|
|
36673
|
+
return _context2.a(2, []);
|
|
36674
|
+
case 2:
|
|
36675
|
+
_context2.n = 3;
|
|
36676
|
+
return modelPreloader.preloadAllModels(this.componentDictionary);
|
|
36677
|
+
case 3:
|
|
36678
|
+
if (!this.objProcessor.idbSupported) {
|
|
36679
|
+
_context2.n = 4;
|
|
36680
|
+
break;
|
|
36681
|
+
}
|
|
36682
|
+
_context2.n = 4;
|
|
36683
|
+
return this.objProcessor.initializeIDB();
|
|
36684
|
+
case 4:
|
|
36685
|
+
processingResults = []; // Process each OBJ model
|
|
36686
|
+
_iterator = _createForOfIteratorHelper(objModels);
|
|
36687
|
+
_context2.p = 5;
|
|
36688
|
+
_iterator.s();
|
|
36689
|
+
case 6:
|
|
36690
|
+
if ((_step = _iterator.n()).done) {
|
|
36691
|
+
_context2.n = 12;
|
|
36692
|
+
break;
|
|
36693
|
+
}
|
|
36694
|
+
objModel = _step.value;
|
|
36695
|
+
_context2.p = 7;
|
|
36696
|
+
// Get the cached model from preloader
|
|
36697
|
+
cachedModelData = modelPreloader.modelCache.get(objModel.modelKey);
|
|
36698
|
+
if (!(!cachedModelData || !cachedModelData.isObjModel)) {
|
|
36699
|
+
_context2.n = 8;
|
|
36700
|
+
break;
|
|
36701
|
+
}
|
|
36702
|
+
return _context2.a(3, 11);
|
|
36703
|
+
case 8:
|
|
36704
|
+
// Extract processing results
|
|
36705
|
+
result = {
|
|
36706
|
+
componentId: objModel.componentId,
|
|
36707
|
+
modelKey: objModel.modelKey,
|
|
36708
|
+
name: objModel.name,
|
|
36709
|
+
boundingBox: objModel.boundingBox,
|
|
36710
|
+
stats: cachedModelData.geometryStats,
|
|
36711
|
+
originalObject: cachedModelData.originalObject,
|
|
36712
|
+
processedGeometry: cachedModelData.processedGeometry,
|
|
36713
|
+
materials: cachedModelData.materials
|
|
36714
|
+
};
|
|
36715
|
+
processingResults.push(result);
|
|
36716
|
+
this.processedResults.set(objModel.modelKey, result);
|
|
36717
|
+
|
|
36718
|
+
// Store in IndexedDB if supported
|
|
36719
|
+
if (!(this.objProcessor.idbSupported && result.processedGeometry)) {
|
|
36720
|
+
_context2.n = 9;
|
|
36721
|
+
break;
|
|
36722
|
+
}
|
|
36723
|
+
serializedData = this.objProcessor.serializeGeometry(result.processedGeometry);
|
|
36724
|
+
_context2.n = 9;
|
|
36725
|
+
return this.objProcessor.storeGeometryInIDB(objModel.modelKey, serializedData);
|
|
36726
|
+
case 9:
|
|
36727
|
+
_context2.n = 11;
|
|
36728
|
+
break;
|
|
36729
|
+
case 10:
|
|
36730
|
+
_context2.p = 10;
|
|
36731
|
+
_context2.v;
|
|
36732
|
+
return _context2.a(3, 11);
|
|
36733
|
+
case 11:
|
|
36734
|
+
_context2.n = 6;
|
|
36735
|
+
break;
|
|
36736
|
+
case 12:
|
|
36737
|
+
_context2.n = 14;
|
|
36738
|
+
break;
|
|
36739
|
+
case 13:
|
|
36740
|
+
_context2.p = 13;
|
|
36741
|
+
_t3 = _context2.v;
|
|
36742
|
+
_iterator.e(_t3);
|
|
36743
|
+
case 14:
|
|
36744
|
+
_context2.p = 14;
|
|
36745
|
+
_iterator.f();
|
|
36746
|
+
return _context2.f(14);
|
|
36747
|
+
case 15:
|
|
36748
|
+
return _context2.a(2, processingResults);
|
|
36749
|
+
}
|
|
36750
|
+
}, _callee2, this, [[7, 10], [5, 13, 14, 15]]);
|
|
36751
|
+
}));
|
|
36752
|
+
function processAllObjModels() {
|
|
36753
|
+
return _processAllObjModels.apply(this, arguments);
|
|
36754
|
+
}
|
|
36755
|
+
return processAllObjModels;
|
|
36756
|
+
}()
|
|
36757
|
+
/**
|
|
36758
|
+
* Run the simplified demo - process and store in IndexedDB
|
|
36759
|
+
* @returns {Promise<Object>} Demo results
|
|
36760
|
+
*/
|
|
36761
|
+
)
|
|
36762
|
+
}, {
|
|
36763
|
+
key: "run",
|
|
36764
|
+
value: (function () {
|
|
36765
|
+
var _run = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
36766
|
+
var processingResults, _t4;
|
|
36767
|
+
return _regenerator().w(function (_context3) {
|
|
36768
|
+
while (1) switch (_context3.n) {
|
|
36769
|
+
case 0:
|
|
36770
|
+
_context3.p = 0;
|
|
36771
|
+
_context3.n = 1;
|
|
36772
|
+
return this.processAllObjModels();
|
|
36773
|
+
case 1:
|
|
36774
|
+
processingResults = _context3.v;
|
|
36775
|
+
return _context3.a(2, {
|
|
36776
|
+
processingResults: processingResults,
|
|
36777
|
+
totalModelsProcessed: processingResults.length,
|
|
36778
|
+
success: true
|
|
36779
|
+
});
|
|
36780
|
+
case 2:
|
|
36781
|
+
_context3.p = 2;
|
|
36782
|
+
_t4 = _context3.v;
|
|
36783
|
+
return _context3.a(2, {
|
|
36784
|
+
processingResults: [],
|
|
36785
|
+
totalModelsProcessed: 0,
|
|
36786
|
+
success: false,
|
|
36787
|
+
error: _t4.message
|
|
36788
|
+
});
|
|
36789
|
+
}
|
|
36790
|
+
}, _callee3, this, [[0, 2]]);
|
|
36791
|
+
}));
|
|
36792
|
+
function run() {
|
|
36793
|
+
return _run.apply(this, arguments);
|
|
36794
|
+
}
|
|
36795
|
+
return run;
|
|
36796
|
+
}()
|
|
36797
|
+
/**
|
|
36798
|
+
* Get processing results for external use
|
|
36799
|
+
* @returns {Map} Map of processing results
|
|
36800
|
+
*/
|
|
36801
|
+
)
|
|
36802
|
+
}, {
|
|
36803
|
+
key: "getResults",
|
|
36804
|
+
value: function getResults() {
|
|
36805
|
+
return this.processedResults;
|
|
36806
|
+
}
|
|
36807
|
+
|
|
36808
|
+
/**
|
|
36809
|
+
* Get geometry by model key
|
|
36810
|
+
* @param {string} modelKey - The model key
|
|
36811
|
+
* @returns {Object|null} Processing result or null
|
|
36812
|
+
*/
|
|
36813
|
+
}, {
|
|
36814
|
+
key: "getGeometry",
|
|
36815
|
+
value: function getGeometry(modelKey) {
|
|
36816
|
+
return this.processedResults.get(modelKey) || null;
|
|
36817
|
+
}
|
|
36818
|
+
}]);
|
|
36819
|
+
}(); // Export for use
|
|
36820
|
+
|
|
35286
36821
|
exports.Analysis = analysis;
|
|
35287
36822
|
exports.AnimationManager = AnimationManager;
|
|
35288
36823
|
exports.CameraControlsManager = CameraControlsManager;
|
|
@@ -35298,6 +36833,8 @@ exports.ImportUtils = _import;
|
|
|
35298
36833
|
exports.KeyboardControlsManager = KeyboardControlsManager;
|
|
35299
36834
|
exports.MathUtils = MathUtils;
|
|
35300
36835
|
exports.Numerics = numerics;
|
|
36836
|
+
exports.ObjProcessingDemo = ObjProcessingDemo;
|
|
36837
|
+
exports.ObjProcessor = ObjProcessor;
|
|
35301
36838
|
exports.PathfindingManager = PathfindingManager;
|
|
35302
36839
|
exports.PerformanceMonitor = PerformanceMonitor;
|
|
35303
36840
|
exports.Rendering2D = rendering2D;
|