@2112-lab/central-plant 0.3.16 → 0.3.18
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 +899 -50
- package/dist/cjs/node_modules/three/examples/jsm/loaders/DRACOLoader.js +683 -0
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/helpers/directionUtils.js +115 -0
- package/dist/cjs/src/managers/components/transformOperationsManager.js +42 -41
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +16 -0
- package/dist/cjs/src/managers/scene/modelManager.js +24 -7
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +27 -0
- package/dist/cjs/src/rendering/modelPreloader.js +7 -1
- package/dist/esm/node_modules/three/examples/jsm/loaders/DRACOLoader.js +679 -0
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/helpers/directionUtils.js +111 -0
- package/dist/esm/src/managers/components/transformOperationsManager.js +42 -41
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +16 -0
- package/dist/esm/src/managers/scene/modelManager.js +25 -8
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +27 -0
- package/dist/esm/src/rendering/modelPreloader.js +7 -1
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -18160,19 +18160,700 @@ function addPrimitiveAttributes( geometry, primitiveDef, parser ) {
|
|
|
18160
18160
|
|
|
18161
18161
|
}
|
|
18162
18162
|
|
|
18163
|
+
const _taskCache = new WeakMap();
|
|
18164
|
+
|
|
18165
|
+
/**
|
|
18166
|
+
* A loader for the Draco format.
|
|
18167
|
+
*
|
|
18168
|
+
* [Draco]{@link https://google.github.io/draco/} is an open source library for compressing
|
|
18169
|
+
* and decompressing 3D meshes and point clouds. Compressed geometry can be significantly smaller,
|
|
18170
|
+
* at the cost of additional decoding time on the client device.
|
|
18171
|
+
*
|
|
18172
|
+
* Standalone Draco files have a `.drc` extension, and contain vertex positions, normals, colors,
|
|
18173
|
+
* and other attributes. Draco files do not contain materials, textures, animation, or node hierarchies –
|
|
18174
|
+
* to use these features, embed Draco geometry inside of a glTF file. A normal glTF file can be converted
|
|
18175
|
+
* to a Draco-compressed glTF file using [glTF-Pipeline]{@link https://github.com/CesiumGS/gltf-pipeline}.
|
|
18176
|
+
* When using Draco with glTF, an instance of `DRACOLoader` will be used internally by {@link GLTFLoader}.
|
|
18177
|
+
*
|
|
18178
|
+
* It is recommended to create one DRACOLoader instance and reuse it to avoid loading and creating
|
|
18179
|
+
* multiple decoder instances.
|
|
18180
|
+
*
|
|
18181
|
+
* `DRACOLoader` will automatically use either the JS or the WASM decoding library, based on
|
|
18182
|
+
* browser capabilities.
|
|
18183
|
+
*
|
|
18184
|
+
* ```js
|
|
18185
|
+
* const loader = new DRACOLoader();
|
|
18186
|
+
* loader.setDecoderPath( '/examples/jsm/libs/draco/' );
|
|
18187
|
+
*
|
|
18188
|
+
* const geometry = await dracoLoader.loadAsync( 'models/draco/bunny.drc' );
|
|
18189
|
+
* geometry.computeVertexNormals(); // optional
|
|
18190
|
+
*
|
|
18191
|
+
* dracoLoader.dispose();
|
|
18192
|
+
* ```
|
|
18193
|
+
*
|
|
18194
|
+
* @augments Loader
|
|
18195
|
+
* @three_import import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
|
|
18196
|
+
*/
|
|
18197
|
+
class DRACOLoader extends THREE.Loader {
|
|
18198
|
+
|
|
18199
|
+
/**
|
|
18200
|
+
* Constructs a new Draco loader.
|
|
18201
|
+
*
|
|
18202
|
+
* @param {LoadingManager} [manager] - The loading manager.
|
|
18203
|
+
*/
|
|
18204
|
+
constructor( manager ) {
|
|
18205
|
+
|
|
18206
|
+
super( manager );
|
|
18207
|
+
|
|
18208
|
+
this.decoderPath = '';
|
|
18209
|
+
this.decoderConfig = {};
|
|
18210
|
+
this.decoderBinary = null;
|
|
18211
|
+
this.decoderPending = null;
|
|
18212
|
+
|
|
18213
|
+
this.workerLimit = 4;
|
|
18214
|
+
this.workerPool = [];
|
|
18215
|
+
this.workerNextTaskID = 1;
|
|
18216
|
+
this.workerSourceURL = '';
|
|
18217
|
+
|
|
18218
|
+
this.defaultAttributeIDs = {
|
|
18219
|
+
position: 'POSITION',
|
|
18220
|
+
normal: 'NORMAL',
|
|
18221
|
+
color: 'COLOR',
|
|
18222
|
+
uv: 'TEX_COORD'
|
|
18223
|
+
};
|
|
18224
|
+
this.defaultAttributeTypes = {
|
|
18225
|
+
position: 'Float32Array',
|
|
18226
|
+
normal: 'Float32Array',
|
|
18227
|
+
color: 'Float32Array',
|
|
18228
|
+
uv: 'Float32Array'
|
|
18229
|
+
};
|
|
18230
|
+
|
|
18231
|
+
}
|
|
18232
|
+
|
|
18233
|
+
/**
|
|
18234
|
+
* Provides configuration for the decoder libraries. Configuration cannot be changed after decoding begins.
|
|
18235
|
+
*
|
|
18236
|
+
* @param {string} path - The decoder path.
|
|
18237
|
+
* @return {DRACOLoader} A reference to this loader.
|
|
18238
|
+
*/
|
|
18239
|
+
setDecoderPath( path ) {
|
|
18240
|
+
|
|
18241
|
+
this.decoderPath = path;
|
|
18242
|
+
|
|
18243
|
+
return this;
|
|
18244
|
+
|
|
18245
|
+
}
|
|
18246
|
+
|
|
18247
|
+
/**
|
|
18248
|
+
* Provides configuration for the decoder libraries. Configuration cannot be changed after decoding begins.
|
|
18249
|
+
*
|
|
18250
|
+
* @param {{type:('js'|'wasm')}} config - The decoder config.
|
|
18251
|
+
* @return {DRACOLoader} A reference to this loader.
|
|
18252
|
+
*/
|
|
18253
|
+
setDecoderConfig( config ) {
|
|
18254
|
+
|
|
18255
|
+
this.decoderConfig = config;
|
|
18256
|
+
|
|
18257
|
+
return this;
|
|
18258
|
+
|
|
18259
|
+
}
|
|
18260
|
+
|
|
18261
|
+
/**
|
|
18262
|
+
* Sets the maximum number of Web Workers to be used during decoding.
|
|
18263
|
+
* A lower limit may be preferable if workers are also for other tasks in the application.
|
|
18264
|
+
*
|
|
18265
|
+
* @param {number} workerLimit - The worker limit.
|
|
18266
|
+
* @return {DRACOLoader} A reference to this loader.
|
|
18267
|
+
*/
|
|
18268
|
+
setWorkerLimit( workerLimit ) {
|
|
18269
|
+
|
|
18270
|
+
this.workerLimit = workerLimit;
|
|
18271
|
+
|
|
18272
|
+
return this;
|
|
18273
|
+
|
|
18274
|
+
}
|
|
18275
|
+
|
|
18276
|
+
/**
|
|
18277
|
+
* Starts loading from the given URL and passes the loaded Draco asset
|
|
18278
|
+
* to the `onLoad()` callback.
|
|
18279
|
+
*
|
|
18280
|
+
* @param {string} url - The path/URL of the file to be loaded. This can also be a data URI.
|
|
18281
|
+
* @param {function(BufferGeometry)} onLoad - Executed when the loading process has been finished.
|
|
18282
|
+
* @param {onProgressCallback} onProgress - Executed while the loading is in progress.
|
|
18283
|
+
* @param {onErrorCallback} onError - Executed when errors occur.
|
|
18284
|
+
*/
|
|
18285
|
+
load( url, onLoad, onProgress, onError ) {
|
|
18286
|
+
|
|
18287
|
+
const loader = new THREE.FileLoader( this.manager );
|
|
18288
|
+
|
|
18289
|
+
loader.setPath( this.path );
|
|
18290
|
+
loader.setResponseType( 'arraybuffer' );
|
|
18291
|
+
loader.setRequestHeader( this.requestHeader );
|
|
18292
|
+
loader.setWithCredentials( this.withCredentials );
|
|
18293
|
+
|
|
18294
|
+
loader.load( url, ( buffer ) => {
|
|
18295
|
+
|
|
18296
|
+
this.parse( buffer, onLoad, onError );
|
|
18297
|
+
|
|
18298
|
+
}, onProgress, onError );
|
|
18299
|
+
|
|
18300
|
+
}
|
|
18301
|
+
|
|
18302
|
+
/**
|
|
18303
|
+
* Parses the given Draco data.
|
|
18304
|
+
*
|
|
18305
|
+
* @param {ArrayBuffer} buffer - The raw Draco data as an array buffer.
|
|
18306
|
+
* @param {function(BufferGeometry)} onLoad - Executed when the loading/parsing process has been finished.
|
|
18307
|
+
* @param {onErrorCallback} onError - Executed when errors occur.
|
|
18308
|
+
*/
|
|
18309
|
+
parse( buffer, onLoad, onError = ()=>{} ) {
|
|
18310
|
+
|
|
18311
|
+
this.decodeDracoFile( buffer, onLoad, null, null, THREE.SRGBColorSpace, onError ).catch( onError );
|
|
18312
|
+
|
|
18313
|
+
}
|
|
18314
|
+
|
|
18315
|
+
//
|
|
18316
|
+
|
|
18317
|
+
decodeDracoFile( buffer, callback, attributeIDs, attributeTypes, vertexColorSpace = THREE.LinearSRGBColorSpace, onError = () => {} ) {
|
|
18318
|
+
|
|
18319
|
+
const taskConfig = {
|
|
18320
|
+
attributeIDs: attributeIDs || this.defaultAttributeIDs,
|
|
18321
|
+
attributeTypes: attributeTypes || this.defaultAttributeTypes,
|
|
18322
|
+
useUniqueIDs: !! attributeIDs,
|
|
18323
|
+
vertexColorSpace: vertexColorSpace,
|
|
18324
|
+
};
|
|
18325
|
+
|
|
18326
|
+
return this.decodeGeometry( buffer, taskConfig ).then( callback ).catch( onError );
|
|
18327
|
+
|
|
18328
|
+
}
|
|
18329
|
+
|
|
18330
|
+
decodeGeometry( buffer, taskConfig ) {
|
|
18331
|
+
|
|
18332
|
+
const taskKey = JSON.stringify( taskConfig );
|
|
18333
|
+
|
|
18334
|
+
// Check for an existing task using this buffer. A transferred buffer cannot be transferred
|
|
18335
|
+
// again from this thread.
|
|
18336
|
+
if ( _taskCache.has( buffer ) ) {
|
|
18337
|
+
|
|
18338
|
+
const cachedTask = _taskCache.get( buffer );
|
|
18339
|
+
|
|
18340
|
+
if ( cachedTask.key === taskKey ) {
|
|
18341
|
+
|
|
18342
|
+
return cachedTask.promise;
|
|
18343
|
+
|
|
18344
|
+
} else if ( buffer.byteLength === 0 ) {
|
|
18345
|
+
|
|
18346
|
+
// Technically, it would be possible to wait for the previous task to complete,
|
|
18347
|
+
// transfer the buffer back, and decode again with the second configuration. That
|
|
18348
|
+
// is complex, and I don't know of any reason to decode a Draco buffer twice in
|
|
18349
|
+
// different ways, so this is left unimplemented.
|
|
18350
|
+
throw new Error(
|
|
18351
|
+
|
|
18352
|
+
'THREE.DRACOLoader: Unable to re-decode a buffer with different ' +
|
|
18353
|
+
'settings. Buffer has already been transferred.'
|
|
18354
|
+
|
|
18355
|
+
);
|
|
18356
|
+
|
|
18357
|
+
}
|
|
18358
|
+
|
|
18359
|
+
}
|
|
18360
|
+
|
|
18361
|
+
//
|
|
18362
|
+
|
|
18363
|
+
let worker;
|
|
18364
|
+
const taskID = this.workerNextTaskID ++;
|
|
18365
|
+
const taskCost = buffer.byteLength;
|
|
18366
|
+
|
|
18367
|
+
// Obtain a worker and assign a task, and construct a geometry instance
|
|
18368
|
+
// when the task completes.
|
|
18369
|
+
const geometryPending = this._getWorker( taskID, taskCost )
|
|
18370
|
+
.then( ( _worker ) => {
|
|
18371
|
+
|
|
18372
|
+
worker = _worker;
|
|
18373
|
+
|
|
18374
|
+
return new Promise( ( resolve, reject ) => {
|
|
18375
|
+
|
|
18376
|
+
worker._callbacks[ taskID ] = { resolve, reject };
|
|
18377
|
+
|
|
18378
|
+
worker.postMessage( { type: 'decode', id: taskID, taskConfig, buffer }, [ buffer ] );
|
|
18379
|
+
|
|
18380
|
+
// this.debug();
|
|
18381
|
+
|
|
18382
|
+
} );
|
|
18383
|
+
|
|
18384
|
+
} )
|
|
18385
|
+
.then( ( message ) => this._createGeometry( message.geometry ) );
|
|
18386
|
+
|
|
18387
|
+
// Remove task from the task list.
|
|
18388
|
+
// Note: replaced '.finally()' with '.catch().then()' block - iOS 11 support (#19416)
|
|
18389
|
+
geometryPending
|
|
18390
|
+
.catch( () => true )
|
|
18391
|
+
.then( () => {
|
|
18392
|
+
|
|
18393
|
+
if ( worker && taskID ) {
|
|
18394
|
+
|
|
18395
|
+
this._releaseTask( worker, taskID );
|
|
18396
|
+
|
|
18397
|
+
// this.debug();
|
|
18398
|
+
|
|
18399
|
+
}
|
|
18400
|
+
|
|
18401
|
+
} );
|
|
18402
|
+
|
|
18403
|
+
// Cache the task result.
|
|
18404
|
+
_taskCache.set( buffer, {
|
|
18405
|
+
|
|
18406
|
+
key: taskKey,
|
|
18407
|
+
promise: geometryPending
|
|
18408
|
+
|
|
18409
|
+
} );
|
|
18410
|
+
|
|
18411
|
+
return geometryPending;
|
|
18412
|
+
|
|
18413
|
+
}
|
|
18414
|
+
|
|
18415
|
+
_createGeometry( geometryData ) {
|
|
18416
|
+
|
|
18417
|
+
const geometry = new THREE.BufferGeometry();
|
|
18418
|
+
|
|
18419
|
+
if ( geometryData.index ) {
|
|
18420
|
+
|
|
18421
|
+
geometry.setIndex( new THREE.BufferAttribute( geometryData.index.array, 1 ) );
|
|
18422
|
+
|
|
18423
|
+
}
|
|
18424
|
+
|
|
18425
|
+
for ( let i = 0; i < geometryData.attributes.length; i ++ ) {
|
|
18426
|
+
|
|
18427
|
+
const result = geometryData.attributes[ i ];
|
|
18428
|
+
const name = result.name;
|
|
18429
|
+
const array = result.array;
|
|
18430
|
+
const itemSize = result.itemSize;
|
|
18431
|
+
|
|
18432
|
+
const attribute = new THREE.BufferAttribute( array, itemSize );
|
|
18433
|
+
|
|
18434
|
+
if ( name === 'color' ) {
|
|
18435
|
+
|
|
18436
|
+
this._assignVertexColorSpace( attribute, result.vertexColorSpace );
|
|
18437
|
+
|
|
18438
|
+
attribute.normalized = ( array instanceof Float32Array ) === false;
|
|
18439
|
+
|
|
18440
|
+
}
|
|
18441
|
+
|
|
18442
|
+
geometry.setAttribute( name, attribute );
|
|
18443
|
+
|
|
18444
|
+
}
|
|
18445
|
+
|
|
18446
|
+
return geometry;
|
|
18447
|
+
|
|
18448
|
+
}
|
|
18449
|
+
|
|
18450
|
+
_assignVertexColorSpace( attribute, inputColorSpace ) {
|
|
18451
|
+
|
|
18452
|
+
// While .drc files do not specify colorspace, the only 'official' tooling
|
|
18453
|
+
// is PLY and OBJ converters, which use sRGB. We'll assume sRGB when a .drc
|
|
18454
|
+
// file is passed into .load() or .parse(). GLTFLoader uses internal APIs
|
|
18455
|
+
// to decode geometry, and vertex colors are already Linear-sRGB in there.
|
|
18456
|
+
|
|
18457
|
+
if ( inputColorSpace !== THREE.SRGBColorSpace ) return;
|
|
18458
|
+
|
|
18459
|
+
const _color = new THREE.Color();
|
|
18460
|
+
|
|
18461
|
+
for ( let i = 0, il = attribute.count; i < il; i ++ ) {
|
|
18462
|
+
|
|
18463
|
+
_color.fromBufferAttribute( attribute, i );
|
|
18464
|
+
THREE.ColorManagement.colorSpaceToWorking( _color, THREE.SRGBColorSpace );
|
|
18465
|
+
attribute.setXYZ( i, _color.r, _color.g, _color.b );
|
|
18466
|
+
|
|
18467
|
+
}
|
|
18468
|
+
|
|
18469
|
+
}
|
|
18470
|
+
|
|
18471
|
+
_loadLibrary( url, responseType ) {
|
|
18472
|
+
|
|
18473
|
+
const loader = new THREE.FileLoader( this.manager );
|
|
18474
|
+
loader.setPath( this.decoderPath );
|
|
18475
|
+
loader.setResponseType( responseType );
|
|
18476
|
+
loader.setWithCredentials( this.withCredentials );
|
|
18477
|
+
|
|
18478
|
+
return new Promise( ( resolve, reject ) => {
|
|
18479
|
+
|
|
18480
|
+
loader.load( url, resolve, undefined, reject );
|
|
18481
|
+
|
|
18482
|
+
} );
|
|
18483
|
+
|
|
18484
|
+
}
|
|
18485
|
+
|
|
18486
|
+
preload() {
|
|
18487
|
+
|
|
18488
|
+
this._initDecoder();
|
|
18489
|
+
|
|
18490
|
+
return this;
|
|
18491
|
+
|
|
18492
|
+
}
|
|
18493
|
+
|
|
18494
|
+
_initDecoder() {
|
|
18495
|
+
|
|
18496
|
+
if ( this.decoderPending ) return this.decoderPending;
|
|
18497
|
+
|
|
18498
|
+
const useJS = typeof WebAssembly !== 'object' || this.decoderConfig.type === 'js';
|
|
18499
|
+
const librariesPending = [];
|
|
18500
|
+
|
|
18501
|
+
if ( useJS ) {
|
|
18502
|
+
|
|
18503
|
+
librariesPending.push( this._loadLibrary( 'draco_decoder.js', 'text' ) );
|
|
18504
|
+
|
|
18505
|
+
} else {
|
|
18506
|
+
|
|
18507
|
+
librariesPending.push( this._loadLibrary( 'draco_wasm_wrapper.js', 'text' ) );
|
|
18508
|
+
librariesPending.push( this._loadLibrary( 'draco_decoder.wasm', 'arraybuffer' ) );
|
|
18509
|
+
|
|
18510
|
+
}
|
|
18511
|
+
|
|
18512
|
+
this.decoderPending = Promise.all( librariesPending )
|
|
18513
|
+
.then( ( libraries ) => {
|
|
18514
|
+
|
|
18515
|
+
const jsContent = libraries[ 0 ];
|
|
18516
|
+
|
|
18517
|
+
if ( ! useJS ) {
|
|
18518
|
+
|
|
18519
|
+
this.decoderConfig.wasmBinary = libraries[ 1 ];
|
|
18520
|
+
|
|
18521
|
+
}
|
|
18522
|
+
|
|
18523
|
+
const fn = DRACOWorker.toString();
|
|
18524
|
+
|
|
18525
|
+
const body = [
|
|
18526
|
+
'/* draco decoder */',
|
|
18527
|
+
jsContent,
|
|
18528
|
+
'',
|
|
18529
|
+
'/* worker */',
|
|
18530
|
+
fn.substring( fn.indexOf( '{' ) + 1, fn.lastIndexOf( '}' ) )
|
|
18531
|
+
].join( '\n' );
|
|
18532
|
+
|
|
18533
|
+
this.workerSourceURL = URL.createObjectURL( new Blob( [ body ] ) );
|
|
18534
|
+
|
|
18535
|
+
} );
|
|
18536
|
+
|
|
18537
|
+
return this.decoderPending;
|
|
18538
|
+
|
|
18539
|
+
}
|
|
18540
|
+
|
|
18541
|
+
_getWorker( taskID, taskCost ) {
|
|
18542
|
+
|
|
18543
|
+
return this._initDecoder().then( () => {
|
|
18544
|
+
|
|
18545
|
+
if ( this.workerPool.length < this.workerLimit ) {
|
|
18546
|
+
|
|
18547
|
+
const worker = new Worker( this.workerSourceURL );
|
|
18548
|
+
|
|
18549
|
+
worker._callbacks = {};
|
|
18550
|
+
worker._taskCosts = {};
|
|
18551
|
+
worker._taskLoad = 0;
|
|
18552
|
+
|
|
18553
|
+
worker.postMessage( { type: 'init', decoderConfig: this.decoderConfig } );
|
|
18554
|
+
|
|
18555
|
+
worker.onmessage = function ( e ) {
|
|
18556
|
+
|
|
18557
|
+
const message = e.data;
|
|
18558
|
+
|
|
18559
|
+
switch ( message.type ) {
|
|
18560
|
+
|
|
18561
|
+
case 'decode':
|
|
18562
|
+
worker._callbacks[ message.id ].resolve( message );
|
|
18563
|
+
break;
|
|
18564
|
+
|
|
18565
|
+
case 'error':
|
|
18566
|
+
worker._callbacks[ message.id ].reject( message );
|
|
18567
|
+
break;
|
|
18568
|
+
|
|
18569
|
+
default:
|
|
18570
|
+
console.error( 'THREE.DRACOLoader: Unexpected message, "' + message.type + '"' );
|
|
18571
|
+
|
|
18572
|
+
}
|
|
18573
|
+
|
|
18574
|
+
};
|
|
18575
|
+
|
|
18576
|
+
this.workerPool.push( worker );
|
|
18577
|
+
|
|
18578
|
+
} else {
|
|
18579
|
+
|
|
18580
|
+
this.workerPool.sort( function ( a, b ) {
|
|
18581
|
+
|
|
18582
|
+
return a._taskLoad > b._taskLoad ? - 1 : 1;
|
|
18583
|
+
|
|
18584
|
+
} );
|
|
18585
|
+
|
|
18586
|
+
}
|
|
18587
|
+
|
|
18588
|
+
const worker = this.workerPool[ this.workerPool.length - 1 ];
|
|
18589
|
+
worker._taskCosts[ taskID ] = taskCost;
|
|
18590
|
+
worker._taskLoad += taskCost;
|
|
18591
|
+
return worker;
|
|
18592
|
+
|
|
18593
|
+
} );
|
|
18594
|
+
|
|
18595
|
+
}
|
|
18596
|
+
|
|
18597
|
+
_releaseTask( worker, taskID ) {
|
|
18598
|
+
|
|
18599
|
+
worker._taskLoad -= worker._taskCosts[ taskID ];
|
|
18600
|
+
delete worker._callbacks[ taskID ];
|
|
18601
|
+
delete worker._taskCosts[ taskID ];
|
|
18602
|
+
|
|
18603
|
+
}
|
|
18604
|
+
|
|
18605
|
+
debug() {
|
|
18606
|
+
|
|
18607
|
+
console.log( 'Task load: ', this.workerPool.map( ( worker ) => worker._taskLoad ) );
|
|
18608
|
+
|
|
18609
|
+
}
|
|
18610
|
+
|
|
18611
|
+
dispose() {
|
|
18612
|
+
|
|
18613
|
+
for ( let i = 0; i < this.workerPool.length; ++ i ) {
|
|
18614
|
+
|
|
18615
|
+
this.workerPool[ i ].terminate();
|
|
18616
|
+
|
|
18617
|
+
}
|
|
18618
|
+
|
|
18619
|
+
this.workerPool.length = 0;
|
|
18620
|
+
|
|
18621
|
+
if ( this.workerSourceURL !== '' ) {
|
|
18622
|
+
|
|
18623
|
+
URL.revokeObjectURL( this.workerSourceURL );
|
|
18624
|
+
|
|
18625
|
+
}
|
|
18626
|
+
|
|
18627
|
+
return this;
|
|
18628
|
+
|
|
18629
|
+
}
|
|
18630
|
+
|
|
18631
|
+
}
|
|
18632
|
+
|
|
18633
|
+
/* WEB WORKER */
|
|
18634
|
+
|
|
18635
|
+
function DRACOWorker() {
|
|
18636
|
+
|
|
18637
|
+
let decoderConfig;
|
|
18638
|
+
let decoderPending;
|
|
18639
|
+
|
|
18640
|
+
onmessage = function ( e ) {
|
|
18641
|
+
|
|
18642
|
+
const message = e.data;
|
|
18643
|
+
|
|
18644
|
+
switch ( message.type ) {
|
|
18645
|
+
|
|
18646
|
+
case 'init':
|
|
18647
|
+
decoderConfig = message.decoderConfig;
|
|
18648
|
+
decoderPending = new Promise( function ( resolve/*, reject*/ ) {
|
|
18649
|
+
|
|
18650
|
+
decoderConfig.onModuleLoaded = function ( draco ) {
|
|
18651
|
+
|
|
18652
|
+
// Module is Promise-like. Wrap before resolving to avoid loop.
|
|
18653
|
+
resolve( { draco: draco } );
|
|
18654
|
+
|
|
18655
|
+
};
|
|
18656
|
+
|
|
18657
|
+
DracoDecoderModule( decoderConfig ); // eslint-disable-line no-undef
|
|
18658
|
+
|
|
18659
|
+
} );
|
|
18660
|
+
break;
|
|
18661
|
+
|
|
18662
|
+
case 'decode':
|
|
18663
|
+
const buffer = message.buffer;
|
|
18664
|
+
const taskConfig = message.taskConfig;
|
|
18665
|
+
decoderPending.then( ( module ) => {
|
|
18666
|
+
|
|
18667
|
+
const draco = module.draco;
|
|
18668
|
+
const decoder = new draco.Decoder();
|
|
18669
|
+
|
|
18670
|
+
try {
|
|
18671
|
+
|
|
18672
|
+
const geometry = decodeGeometry( draco, decoder, new Int8Array( buffer ), taskConfig );
|
|
18673
|
+
|
|
18674
|
+
const buffers = geometry.attributes.map( ( attr ) => attr.array.buffer );
|
|
18675
|
+
|
|
18676
|
+
if ( geometry.index ) buffers.push( geometry.index.array.buffer );
|
|
18677
|
+
|
|
18678
|
+
self.postMessage( { type: 'decode', id: message.id, geometry }, buffers );
|
|
18679
|
+
|
|
18680
|
+
} catch ( error ) {
|
|
18681
|
+
|
|
18682
|
+
console.error( error );
|
|
18683
|
+
|
|
18684
|
+
self.postMessage( { type: 'error', id: message.id, error: error.message } );
|
|
18685
|
+
|
|
18686
|
+
} finally {
|
|
18687
|
+
|
|
18688
|
+
draco.destroy( decoder );
|
|
18689
|
+
|
|
18690
|
+
}
|
|
18691
|
+
|
|
18692
|
+
} );
|
|
18693
|
+
break;
|
|
18694
|
+
|
|
18695
|
+
}
|
|
18696
|
+
|
|
18697
|
+
};
|
|
18698
|
+
|
|
18699
|
+
function decodeGeometry( draco, decoder, array, taskConfig ) {
|
|
18700
|
+
|
|
18701
|
+
const attributeIDs = taskConfig.attributeIDs;
|
|
18702
|
+
const attributeTypes = taskConfig.attributeTypes;
|
|
18703
|
+
|
|
18704
|
+
let dracoGeometry;
|
|
18705
|
+
let decodingStatus;
|
|
18706
|
+
|
|
18707
|
+
const geometryType = decoder.GetEncodedGeometryType( array );
|
|
18708
|
+
|
|
18709
|
+
if ( geometryType === draco.TRIANGULAR_MESH ) {
|
|
18710
|
+
|
|
18711
|
+
dracoGeometry = new draco.Mesh();
|
|
18712
|
+
decodingStatus = decoder.DecodeArrayToMesh( array, array.byteLength, dracoGeometry );
|
|
18713
|
+
|
|
18714
|
+
} else if ( geometryType === draco.POINT_CLOUD ) {
|
|
18715
|
+
|
|
18716
|
+
dracoGeometry = new draco.PointCloud();
|
|
18717
|
+
decodingStatus = decoder.DecodeArrayToPointCloud( array, array.byteLength, dracoGeometry );
|
|
18718
|
+
|
|
18719
|
+
} else {
|
|
18720
|
+
|
|
18721
|
+
throw new Error( 'THREE.DRACOLoader: Unexpected geometry type.' );
|
|
18722
|
+
|
|
18723
|
+
}
|
|
18724
|
+
|
|
18725
|
+
if ( ! decodingStatus.ok() || dracoGeometry.ptr === 0 ) {
|
|
18726
|
+
|
|
18727
|
+
throw new Error( 'THREE.DRACOLoader: Decoding failed: ' + decodingStatus.error_msg() );
|
|
18728
|
+
|
|
18729
|
+
}
|
|
18730
|
+
|
|
18731
|
+
const geometry = { index: null, attributes: [] };
|
|
18732
|
+
|
|
18733
|
+
// Gather all vertex attributes.
|
|
18734
|
+
for ( const attributeName in attributeIDs ) {
|
|
18735
|
+
|
|
18736
|
+
const attributeType = self[ attributeTypes[ attributeName ] ];
|
|
18737
|
+
|
|
18738
|
+
let attribute;
|
|
18739
|
+
let attributeID;
|
|
18740
|
+
|
|
18741
|
+
// A Draco file may be created with default vertex attributes, whose attribute IDs
|
|
18742
|
+
// are mapped 1:1 from their semantic name (POSITION, NORMAL, ...). Alternatively,
|
|
18743
|
+
// a Draco file may contain a custom set of attributes, identified by known unique
|
|
18744
|
+
// IDs. glTF files always do the latter, and `.drc` files typically do the former.
|
|
18745
|
+
if ( taskConfig.useUniqueIDs ) {
|
|
18746
|
+
|
|
18747
|
+
attributeID = attributeIDs[ attributeName ];
|
|
18748
|
+
attribute = decoder.GetAttributeByUniqueId( dracoGeometry, attributeID );
|
|
18749
|
+
|
|
18750
|
+
} else {
|
|
18751
|
+
|
|
18752
|
+
attributeID = decoder.GetAttributeId( dracoGeometry, draco[ attributeIDs[ attributeName ] ] );
|
|
18753
|
+
|
|
18754
|
+
if ( attributeID === - 1 ) continue;
|
|
18755
|
+
|
|
18756
|
+
attribute = decoder.GetAttribute( dracoGeometry, attributeID );
|
|
18757
|
+
|
|
18758
|
+
}
|
|
18759
|
+
|
|
18760
|
+
const attributeResult = decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute );
|
|
18761
|
+
|
|
18762
|
+
if ( attributeName === 'color' ) {
|
|
18763
|
+
|
|
18764
|
+
attributeResult.vertexColorSpace = taskConfig.vertexColorSpace;
|
|
18765
|
+
|
|
18766
|
+
}
|
|
18767
|
+
|
|
18768
|
+
geometry.attributes.push( attributeResult );
|
|
18769
|
+
|
|
18770
|
+
}
|
|
18771
|
+
|
|
18772
|
+
// Add index.
|
|
18773
|
+
if ( geometryType === draco.TRIANGULAR_MESH ) {
|
|
18774
|
+
|
|
18775
|
+
geometry.index = decodeIndex( draco, decoder, dracoGeometry );
|
|
18776
|
+
|
|
18777
|
+
}
|
|
18778
|
+
|
|
18779
|
+
draco.destroy( dracoGeometry );
|
|
18780
|
+
|
|
18781
|
+
return geometry;
|
|
18782
|
+
|
|
18783
|
+
}
|
|
18784
|
+
|
|
18785
|
+
function decodeIndex( draco, decoder, dracoGeometry ) {
|
|
18786
|
+
|
|
18787
|
+
const numFaces = dracoGeometry.num_faces();
|
|
18788
|
+
const numIndices = numFaces * 3;
|
|
18789
|
+
const byteLength = numIndices * 4;
|
|
18790
|
+
|
|
18791
|
+
const ptr = draco._malloc( byteLength );
|
|
18792
|
+
decoder.GetTrianglesUInt32Array( dracoGeometry, byteLength, ptr );
|
|
18793
|
+
const index = new Uint32Array( draco.HEAPF32.buffer, ptr, numIndices ).slice();
|
|
18794
|
+
draco._free( ptr );
|
|
18795
|
+
|
|
18796
|
+
return { array: index, itemSize: 1 };
|
|
18797
|
+
|
|
18798
|
+
}
|
|
18799
|
+
|
|
18800
|
+
function decodeAttribute( draco, decoder, dracoGeometry, attributeName, attributeType, attribute ) {
|
|
18801
|
+
|
|
18802
|
+
const numComponents = attribute.num_components();
|
|
18803
|
+
const numPoints = dracoGeometry.num_points();
|
|
18804
|
+
const numValues = numPoints * numComponents;
|
|
18805
|
+
const byteLength = numValues * attributeType.BYTES_PER_ELEMENT;
|
|
18806
|
+
const dataType = getDracoDataType( draco, attributeType );
|
|
18807
|
+
|
|
18808
|
+
const ptr = draco._malloc( byteLength );
|
|
18809
|
+
decoder.GetAttributeDataArrayForAllPoints( dracoGeometry, attribute, dataType, byteLength, ptr );
|
|
18810
|
+
const array = new attributeType( draco.HEAPF32.buffer, ptr, numValues ).slice();
|
|
18811
|
+
draco._free( ptr );
|
|
18812
|
+
|
|
18813
|
+
return {
|
|
18814
|
+
name: attributeName,
|
|
18815
|
+
array: array,
|
|
18816
|
+
itemSize: numComponents
|
|
18817
|
+
};
|
|
18818
|
+
|
|
18819
|
+
}
|
|
18820
|
+
|
|
18821
|
+
function getDracoDataType( draco, attributeType ) {
|
|
18822
|
+
|
|
18823
|
+
switch ( attributeType ) {
|
|
18824
|
+
|
|
18825
|
+
case Float32Array: return draco.DT_FLOAT32;
|
|
18826
|
+
case Int8Array: return draco.DT_INT8;
|
|
18827
|
+
case Int16Array: return draco.DT_INT16;
|
|
18828
|
+
case Int32Array: return draco.DT_INT32;
|
|
18829
|
+
case Uint8Array: return draco.DT_UINT8;
|
|
18830
|
+
case Uint16Array: return draco.DT_UINT16;
|
|
18831
|
+
case Uint32Array: return draco.DT_UINT32;
|
|
18832
|
+
|
|
18833
|
+
}
|
|
18834
|
+
|
|
18835
|
+
}
|
|
18836
|
+
|
|
18837
|
+
}
|
|
18838
|
+
|
|
18163
18839
|
var ModelPreloader = /*#__PURE__*/function () {
|
|
18164
18840
|
function ModelPreloader() {
|
|
18165
18841
|
_classCallCheck(this, ModelPreloader);
|
|
18166
18842
|
this.modelCache = new Map(); // Cache for loaded models
|
|
18167
18843
|
this.loadingPromises = new Map(); // Track ongoing loads to prevent duplicates
|
|
18168
18844
|
this.gltfLoader = new GLTFLoader();
|
|
18845
|
+
|
|
18846
|
+
// Setup DRACO decoder for compressed GLB files
|
|
18847
|
+
this.dracoLoader = new DRACOLoader();
|
|
18848
|
+
this.dracoLoader.setDecoderPath('/draco/');
|
|
18849
|
+
this.gltfLoader.setDRACOLoader(this.dracoLoader);
|
|
18169
18850
|
this.isPreloading = false;
|
|
18170
18851
|
this.preloadingPromise = null;
|
|
18171
18852
|
this.componentDictionary = null;
|
|
18172
18853
|
this.modelsBasePath = '/library/models/'; // Default local path
|
|
18173
18854
|
this.urlResolver = null; // Optional function to resolve model URLs (for S3 authentication)
|
|
18174
18855
|
|
|
18175
|
-
console.log('🚀 ModelPreloader initialized with GLB support');
|
|
18856
|
+
console.log('🚀 ModelPreloader initialized with GLB + DRACO support');
|
|
18176
18857
|
}
|
|
18177
18858
|
|
|
18178
18859
|
/**
|
|
@@ -19873,6 +20554,114 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19873
20554
|
}]);
|
|
19874
20555
|
}(BaseDisposable);
|
|
19875
20556
|
|
|
20557
|
+
/**
|
|
20558
|
+
* Utility function to update userData.direction for components after 90-degree rotation
|
|
20559
|
+
* This function handles the direction vector transformation for connectors when their parent component is rotated
|
|
20560
|
+
*
|
|
20561
|
+
* @param {THREE.Object3D} component - The component that was rotated
|
|
20562
|
+
* @param {string} axis - The axis of rotation ('x', 'y', or 'z')
|
|
20563
|
+
* @param {number} degrees - The rotation angle in degrees (should be multiple of 90)
|
|
20564
|
+
*/
|
|
20565
|
+
function updateDirectionAfterRotation(component, axis, degrees) {
|
|
20566
|
+
if (!component) {
|
|
20567
|
+
console.warn('⚠️ updateDirectionAfterRotation: No component provided');
|
|
20568
|
+
return;
|
|
20569
|
+
}
|
|
20570
|
+
|
|
20571
|
+
// Only handle 90-degree increments
|
|
20572
|
+
if (degrees % 90 !== 0) {
|
|
20573
|
+
console.warn('⚠️ updateDirectionAfterRotation: Only 90-degree increments are supported');
|
|
20574
|
+
return;
|
|
20575
|
+
}
|
|
20576
|
+
|
|
20577
|
+
// Normalize degrees to 0-360 range
|
|
20578
|
+
var normalizedDegrees = (degrees % 360 + 360) % 360;
|
|
20579
|
+
console.log("\uD83D\uDD04 Updating direction vectors for ".concat(component.name || component.uuid, " after ").concat(degrees, "\xB0 rotation around ").concat(axis, " axis"));
|
|
20580
|
+
|
|
20581
|
+
// Traverse all children (connectors) and update their direction vectors
|
|
20582
|
+
component.traverse(function (child) {
|
|
20583
|
+
var _child$userData, _child$userData2;
|
|
20584
|
+
var childType = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) || ((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType);
|
|
20585
|
+
if (child.userData && Array.isArray(child.userData.direction) && childType === 'connector') {
|
|
20586
|
+
var originalDirection = _toConsumableArray(child.userData.direction);
|
|
20587
|
+
var newDirection = rotateDirectionVector(originalDirection, axis, normalizedDegrees);
|
|
20588
|
+
|
|
20589
|
+
// Update the direction
|
|
20590
|
+
child.userData.direction = newDirection;
|
|
20591
|
+
console.log("\uD83D\uDCCD Updated connector ".concat(child.name || child.uuid, " direction:"), {
|
|
20592
|
+
original: originalDirection,
|
|
20593
|
+
new: newDirection,
|
|
20594
|
+
rotationAxis: axis,
|
|
20595
|
+
rotationDegrees: degrees
|
|
20596
|
+
});
|
|
20597
|
+
}
|
|
20598
|
+
});
|
|
20599
|
+
}
|
|
20600
|
+
|
|
20601
|
+
/**
|
|
20602
|
+
* Rotate a direction vector by 90-degree increments around a specific axis
|
|
20603
|
+
*
|
|
20604
|
+
* @param {Array<number>} direction - The original direction vector [x, y, z]
|
|
20605
|
+
* @param {string} axis - The axis of rotation ('x', 'y', or 'z')
|
|
20606
|
+
* @param {number} degrees - The rotation angle in degrees (must be multiple of 90)
|
|
20607
|
+
* @returns {Array<number>} The new direction vector [x, y, z]
|
|
20608
|
+
*/
|
|
20609
|
+
function rotateDirectionVector(direction, axis, degrees) {
|
|
20610
|
+
if (!Array.isArray(direction) || direction.length !== 3) {
|
|
20611
|
+
console.warn('⚠️ rotateDirectionVector: Invalid direction vector');
|
|
20612
|
+
return direction;
|
|
20613
|
+
}
|
|
20614
|
+
var _direction = _slicedToArray(direction, 3),
|
|
20615
|
+
x = _direction[0],
|
|
20616
|
+
y = _direction[1],
|
|
20617
|
+
z = _direction[2];
|
|
20618
|
+
var steps = degrees / 90; // Number of 90-degree steps
|
|
20619
|
+
|
|
20620
|
+
for (var i = 0; i < steps; i++) {
|
|
20621
|
+
var newX = x,
|
|
20622
|
+
newY = y,
|
|
20623
|
+
newZ = z;
|
|
20624
|
+
switch (axis) {
|
|
20625
|
+
case 'x':
|
|
20626
|
+
// Rotation around X-axis in Z-up system with flipped Y: Y becomes -Z, Z becomes Y
|
|
20627
|
+
newY = -z;
|
|
20628
|
+
newZ = y;
|
|
20629
|
+
break;
|
|
20630
|
+
case 'y':
|
|
20631
|
+
// Rotation around Y-axis in Z-up system with flipped Y: X becomes Z, Z becomes -X
|
|
20632
|
+
newX = z;
|
|
20633
|
+
newZ = -x;
|
|
20634
|
+
break;
|
|
20635
|
+
case 'z':
|
|
20636
|
+
// Rotation around Z-axis in Z-up system with flipped Y: X becomes -Y, Y becomes X
|
|
20637
|
+
newX = -y;
|
|
20638
|
+
newY = x;
|
|
20639
|
+
break;
|
|
20640
|
+
default:
|
|
20641
|
+
console.warn("\u26A0\uFE0F rotateDirectionVector: Invalid axis '".concat(axis, "'"));
|
|
20642
|
+
return direction;
|
|
20643
|
+
}
|
|
20644
|
+
x = newX;
|
|
20645
|
+
y = newY;
|
|
20646
|
+
z = newZ;
|
|
20647
|
+
}
|
|
20648
|
+
return [x, y, z];
|
|
20649
|
+
}
|
|
20650
|
+
|
|
20651
|
+
/**
|
|
20652
|
+
* Example usage in your rotate method:
|
|
20653
|
+
*
|
|
20654
|
+
* // After applying rotation to the component
|
|
20655
|
+
* component.rotation[axis] += radians
|
|
20656
|
+
*
|
|
20657
|
+
* // Update direction vectors for connectors
|
|
20658
|
+
* updateDirectionAfterRotation(component, axis, value)
|
|
20659
|
+
*
|
|
20660
|
+
* // Update matrices
|
|
20661
|
+
* component.updateMatrix()
|
|
20662
|
+
* component.updateMatrixWorld(true)
|
|
20663
|
+
*/
|
|
20664
|
+
|
|
19876
20665
|
var TransformOperationsManager = /*#__PURE__*/function () {
|
|
19877
20666
|
/**
|
|
19878
20667
|
* @param {Object} sceneViewer - The scene viewer instance
|
|
@@ -20564,16 +21353,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20564
21353
|
if (!component || degrees % 90 !== 0) {
|
|
20565
21354
|
return;
|
|
20566
21355
|
}
|
|
20567
|
-
console.log("\uD83D\uDD04 Updating connector directions after ".concat(degrees, "\xB0 rotation around ").concat(axis, " axis"));
|
|
20568
21356
|
|
|
20569
|
-
//
|
|
20570
|
-
|
|
20571
|
-
component.traverse(function (child) {
|
|
20572
|
-
var _child$userData5, _child$userData6;
|
|
20573
|
-
if (((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) === 'connector' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.direction) {
|
|
20574
|
-
console.log("\uD83D\uDCCD Connector ".concat(child.uuid, " direction may need verification after rotation"));
|
|
20575
|
-
}
|
|
20576
|
-
});
|
|
21357
|
+
// Use the direction utility to update direction vectors on Three.js connector objects
|
|
21358
|
+
updateDirectionAfterRotation(component, axis, degrees);
|
|
20577
21359
|
}
|
|
20578
21360
|
|
|
20579
21361
|
/**
|
|
@@ -20727,9 +21509,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20727
21509
|
|
|
20728
21510
|
// Traverse scene to find all connectors
|
|
20729
21511
|
this.sceneViewer.scene.traverse(function (child) {
|
|
20730
|
-
var _child$
|
|
21512
|
+
var _child$userData5;
|
|
20731
21513
|
// Check if this is a connector (component connector or manual segment connector)
|
|
20732
|
-
if (((_child$
|
|
21514
|
+
if (((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) === 'connector') {
|
|
20733
21515
|
// Get world position of connector
|
|
20734
21516
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
20735
21517
|
child.getWorldPosition(connectorWorldPos);
|
|
@@ -20780,8 +21562,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20780
21562
|
// Find all child connectors of the segment in the Three.js scene
|
|
20781
21563
|
var connectors = [];
|
|
20782
21564
|
segment.traverse(function (child) {
|
|
20783
|
-
var _child$
|
|
20784
|
-
if (((_child$
|
|
21565
|
+
var _child$userData6;
|
|
21566
|
+
if (((_child$userData6 = child.userData) === null || _child$userData6 === void 0 ? void 0 : _child$userData6.objectType) === 'segment-connector') {
|
|
20785
21567
|
connectors.push(child);
|
|
20786
21568
|
}
|
|
20787
21569
|
});
|
|
@@ -20845,17 +21627,17 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
20845
21627
|
|
|
20846
21628
|
// Check all segments in the scene
|
|
20847
21629
|
this.sceneViewer.scene.traverse(function (child) {
|
|
20848
|
-
var _child$
|
|
21630
|
+
var _child$userData7, _child$userData8;
|
|
20849
21631
|
// Skip the segment itself
|
|
20850
21632
|
if (child.uuid === segment.uuid) {
|
|
20851
21633
|
return;
|
|
20852
21634
|
}
|
|
20853
21635
|
|
|
20854
21636
|
// Only check computed segments in the scene
|
|
20855
|
-
if (((_child$
|
|
20856
|
-
var _segment$userData6, _child$
|
|
21637
|
+
if (((_child$userData7 = child.userData) === null || _child$userData7 === void 0 ? void 0 : _child$userData7.objectType) === 'segment' && (_child$userData8 = child.userData) !== null && _child$userData8 !== void 0 && _child$userData8.isDeclared) {
|
|
21638
|
+
var _segment$userData6, _child$userData9, _segment$userData7, _child$userData0;
|
|
20857
21639
|
// Check if segments are part of the same connection path
|
|
20858
|
-
var sameConnection = ((_segment$userData6 = segment.userData) === null || _segment$userData6 === void 0 ? void 0 : _segment$userData6.pathFrom) === ((_child$
|
|
21640
|
+
var sameConnection = ((_segment$userData6 = segment.userData) === null || _segment$userData6 === void 0 ? void 0 : _segment$userData6.pathFrom) === ((_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.pathFrom) && ((_segment$userData7 = segment.userData) === null || _segment$userData7 === void 0 ? void 0 : _segment$userData7.pathTo) === ((_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.pathTo);
|
|
20859
21641
|
|
|
20860
21642
|
// Get endpoints of the other segment (use stored endpoints if available)
|
|
20861
21643
|
var otherEndpoints = _this2.getSegmentEndpoints(child);
|
|
@@ -21076,11 +21858,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21076
21858
|
|
|
21077
21859
|
// Traverse scene to find all component connectors
|
|
21078
21860
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21079
|
-
var _child$
|
|
21861
|
+
var _child$userData1;
|
|
21080
21862
|
if (collision) return; // Stop if collision already found
|
|
21081
21863
|
|
|
21082
21864
|
// Check if this is a component connector (not a segment-connector)
|
|
21083
|
-
if (((_child$
|
|
21865
|
+
if (((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) === 'connector') {
|
|
21084
21866
|
var _segment$userData10, _segment$userData11;
|
|
21085
21867
|
// Skip connectors that are connected to this segment (pathFrom or pathTo)
|
|
21086
21868
|
var segmentPathFrom = (_segment$userData10 = segment.userData) === null || _segment$userData10 === void 0 ? void 0 : _segment$userData10.pathFrom;
|
|
@@ -21194,9 +21976,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21194
21976
|
|
|
21195
21977
|
// Traverse scene to find all component connectors
|
|
21196
21978
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21197
|
-
var _child$
|
|
21979
|
+
var _child$userData10;
|
|
21198
21980
|
// Check if this is a component connector (not a segment-connector)
|
|
21199
|
-
if (((_child$
|
|
21981
|
+
if (((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) === 'connector') {
|
|
21200
21982
|
// Get world position of connector
|
|
21201
21983
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
21202
21984
|
child.getWorldPosition(connectorWorldPos);
|
|
@@ -21253,11 +22035,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21253
22035
|
|
|
21254
22036
|
// Traverse scene to find all components
|
|
21255
22037
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21256
|
-
var _child$
|
|
22038
|
+
var _child$userData11, _child$userData12;
|
|
21257
22039
|
if (collision) return; // Stop if collision already found
|
|
21258
22040
|
|
|
21259
22041
|
// Check if this is a component (equipment)
|
|
21260
|
-
if (((_child$
|
|
22042
|
+
if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'component' && (_child$userData12 = child.userData) !== null && _child$userData12 !== void 0 && _child$userData12.libraryId) {
|
|
21261
22043
|
// Create bounding box for the component
|
|
21262
22044
|
var componentBBox = new THREE__namespace.Box3().setFromObject(child);
|
|
21263
22045
|
|
|
@@ -21296,11 +22078,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21296
22078
|
|
|
21297
22079
|
// Traverse scene to find all manual segments (isDeclared === true)
|
|
21298
22080
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21299
|
-
var _child$
|
|
22081
|
+
var _child$userData13, _child$userData14;
|
|
21300
22082
|
if (collision) return; // Stop if collision already found
|
|
21301
22083
|
|
|
21302
22084
|
// Only check manual segments (isDeclared === true)
|
|
21303
|
-
if (((_child$
|
|
22085
|
+
if (((_child$userData13 = child.userData) === null || _child$userData13 === void 0 ? void 0 : _child$userData13.objectType) === 'segment' && ((_child$userData14 = child.userData) === null || _child$userData14 === void 0 ? void 0 : _child$userData14.isDeclared) === true) {
|
|
21304
22086
|
// Get segment endpoints
|
|
21305
22087
|
var segmentEndpoints = _this3.getSegmentEndpoints(child);
|
|
21306
22088
|
|
|
@@ -21389,11 +22171,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21389
22171
|
|
|
21390
22172
|
// Traverse scene to find all manual segments (isDeclared === true)
|
|
21391
22173
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21392
|
-
var _child$
|
|
22174
|
+
var _child$userData15, _child$userData16;
|
|
21393
22175
|
if (collision) return; // Stop if collision already found
|
|
21394
22176
|
|
|
21395
22177
|
// Only check manual segments (isDeclared === true)
|
|
21396
|
-
if (((_child$
|
|
22178
|
+
if (((_child$userData15 = child.userData) === null || _child$userData15 === void 0 ? void 0 : _child$userData15.objectType) === 'segment' && ((_child$userData16 = child.userData) === null || _child$userData16 === void 0 ? void 0 : _child$userData16.isDeclared) === true) {
|
|
21397
22179
|
// Get segment endpoints
|
|
21398
22180
|
var segmentEndpoints = _this4.getSegmentEndpoints(child);
|
|
21399
22181
|
|
|
@@ -21450,11 +22232,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21450
22232
|
|
|
21451
22233
|
// Traverse scene to find all components
|
|
21452
22234
|
this.sceneViewer.scene.traverse(function (child) {
|
|
21453
|
-
var _child$
|
|
22235
|
+
var _child$userData17, _child$userData18;
|
|
21454
22236
|
if (collision) return; // Stop if collision already found
|
|
21455
22237
|
|
|
21456
22238
|
// Check if this is a component (equipment)
|
|
21457
|
-
if (((_child$
|
|
22239
|
+
if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.objectType) === 'component' && (_child$userData18 = child.userData) !== null && _child$userData18 !== void 0 && _child$userData18.libraryId) {
|
|
21458
22240
|
// Try to get worldBoundingBox from userData first (most up-to-date)
|
|
21459
22241
|
var bbox = null;
|
|
21460
22242
|
if (child.userData.worldBoundingBox) {
|
|
@@ -21599,8 +22381,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21599
22381
|
// Get the moved segment's connectors
|
|
21600
22382
|
var movedConnectors = [];
|
|
21601
22383
|
movedSegment.traverse(function (child) {
|
|
21602
|
-
var _child$
|
|
21603
|
-
if (((_child$
|
|
22384
|
+
var _child$userData19;
|
|
22385
|
+
if (((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.objectType) === 'segment-connector') {
|
|
21604
22386
|
movedConnectors.push(child);
|
|
21605
22387
|
}
|
|
21606
22388
|
});
|
|
@@ -21670,8 +22452,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21670
22452
|
// Get all connectors of the adjacent segment
|
|
21671
22453
|
var adjacentConnectors = [];
|
|
21672
22454
|
adjacentSegment.traverse(function (child) {
|
|
21673
|
-
var _child$
|
|
21674
|
-
if (((_child$
|
|
22455
|
+
var _child$userData20;
|
|
22456
|
+
if (((_child$userData20 = child.userData) === null || _child$userData20 === void 0 ? void 0 : _child$userData20.objectType) === 'segment-connector') {
|
|
21675
22457
|
adjacentConnectors.push(child);
|
|
21676
22458
|
}
|
|
21677
22459
|
});
|
|
@@ -21794,8 +22576,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21794
22576
|
// Also update child connectors' positions if they exist
|
|
21795
22577
|
if (sceneDataComponent.children) {
|
|
21796
22578
|
sceneDataComponent.children.forEach(function (child) {
|
|
21797
|
-
var _child$
|
|
21798
|
-
if (((_child$
|
|
22579
|
+
var _child$userData21;
|
|
22580
|
+
if (((_child$userData21 = child.userData) === null || _child$userData21 === void 0 ? void 0 : _child$userData21.objectType) === 'connector') {
|
|
21799
22581
|
// Find the actual connector object in the scene
|
|
21800
22582
|
var connectorObj = component.children.find(function (c) {
|
|
21801
22583
|
var _c$userData;
|
|
@@ -21857,14 +22639,15 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21857
22639
|
// Also update child connectors' positions if they exist (rotation moves them in world space)
|
|
21858
22640
|
if (sceneDataComponent.children) {
|
|
21859
22641
|
sceneDataComponent.children.forEach(function (child) {
|
|
21860
|
-
var _child$
|
|
21861
|
-
if (((_child$
|
|
22642
|
+
var _child$userData22;
|
|
22643
|
+
if (((_child$userData22 = child.userData) === null || _child$userData22 === void 0 ? void 0 : _child$userData22.objectType) === 'connector') {
|
|
21862
22644
|
// Find the actual connector object in the scene
|
|
21863
22645
|
var connectorObj = component.children.find(function (c) {
|
|
21864
22646
|
var _c$userData2;
|
|
21865
22647
|
return c.uuid === child.uuid || ((_c$userData2 = c.userData) === null || _c$userData2 === void 0 ? void 0 : _c$userData2.originalUuid) === child.uuid;
|
|
21866
22648
|
});
|
|
21867
22649
|
if (connectorObj) {
|
|
22650
|
+
var _connectorObj$userDat;
|
|
21868
22651
|
// Get world position of connector
|
|
21869
22652
|
var worldPos = new THREE__namespace.Vector3();
|
|
21870
22653
|
connectorObj.getWorldPosition(worldPos);
|
|
@@ -21875,6 +22658,12 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
21875
22658
|
}
|
|
21876
22659
|
child.userData.position = [cleanValue(worldPos.x), cleanValue(worldPos.y), cleanValue(worldPos.z)];
|
|
21877
22660
|
console.log(" \u21B3 Updated child connector ".concat(child.uuid, " position to [").concat(child.userData.position.join(', '), "]"));
|
|
22661
|
+
|
|
22662
|
+
// Update connector's direction in scene data from the Three.js object
|
|
22663
|
+
if ((_connectorObj$userDat = connectorObj.userData) !== null && _connectorObj$userDat !== void 0 && _connectorObj$userDat.direction && Array.isArray(connectorObj.userData.direction)) {
|
|
22664
|
+
child.userData.direction = _toConsumableArray(connectorObj.userData.direction);
|
|
22665
|
+
console.log(" \u21B3 Updated child connector ".concat(child.uuid, " direction to [").concat(child.userData.direction.join(', '), "]"));
|
|
22666
|
+
}
|
|
21878
22667
|
}
|
|
21879
22668
|
}
|
|
21880
22669
|
});
|
|
@@ -22187,8 +22976,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
22187
22976
|
// Check if either external connector belongs to the active segment
|
|
22188
22977
|
var activeSegmentConnectors = [];
|
|
22189
22978
|
activeSegment.traverse(function (child) {
|
|
22190
|
-
var _child$
|
|
22191
|
-
if (((_child$
|
|
22979
|
+
var _child$userData23;
|
|
22980
|
+
if (((_child$userData23 = child.userData) === null || _child$userData23 === void 0 ? void 0 : _child$userData23.objectType) === 'segment-connector') {
|
|
22192
22981
|
activeSegmentConnectors.push(child.uuid);
|
|
22193
22982
|
}
|
|
22194
22983
|
});
|
|
@@ -22236,8 +23025,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
22236
23025
|
// Get all connectors of the active segment
|
|
22237
23026
|
var activeConnectors = [];
|
|
22238
23027
|
activeSegment.traverse(function (child) {
|
|
22239
|
-
var _child$
|
|
22240
|
-
if (((_child$
|
|
23028
|
+
var _child$userData24;
|
|
23029
|
+
if (((_child$userData24 = child.userData) === null || _child$userData24 === void 0 ? void 0 : _child$userData24.objectType) === 'segment-connector') {
|
|
22241
23030
|
activeConnectors.push(child);
|
|
22242
23031
|
}
|
|
22243
23032
|
});
|
|
@@ -28065,6 +28854,22 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28065
28854
|
this.pathfinder = new pathfinder.Pathfinder(this.pathfinderConfig);
|
|
28066
28855
|
this.sceneViewer.pathfinder = this.pathfinder;
|
|
28067
28856
|
|
|
28857
|
+
// ── Early exit if no connections ───────────────────────────────────
|
|
28858
|
+
// Skip expensive bounding box computation when there's nothing to connect
|
|
28859
|
+
if (!(!connections || connections.length === 0)) {
|
|
28860
|
+
_context.n = 1;
|
|
28861
|
+
break;
|
|
28862
|
+
}
|
|
28863
|
+
console.log("\u23ED\uFE0F Skipping pathfinding - no connections [".concat(context, "]"));
|
|
28864
|
+
return _context.a(2, {
|
|
28865
|
+
paths: [],
|
|
28866
|
+
gateways: [],
|
|
28867
|
+
rewiredConnections: [],
|
|
28868
|
+
metrics: {
|
|
28869
|
+
total: 0
|
|
28870
|
+
}
|
|
28871
|
+
});
|
|
28872
|
+
case 1:
|
|
28068
28873
|
// ── Stage 1: Input Generation ──────────────────────────────────────
|
|
28069
28874
|
inputGenStart = performance.now(); // Ensure all matrices are up to date before bounding box calculations (for all pathfinding executions)
|
|
28070
28875
|
this.sceneViewer.scene.updateMatrixWorld(true);
|
|
@@ -30752,15 +31557,23 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30752
31557
|
if (child.userData) {
|
|
30753
31558
|
clonedConnector.userData = _objectSpread2({}, child.userData);
|
|
30754
31559
|
|
|
30755
|
-
// Deep copy critical data
|
|
31560
|
+
// Deep copy critical data - handle both array [x,y,z] and object {x,y,z} formats
|
|
30756
31561
|
if (child.userData.worldBoundingBox) {
|
|
31562
|
+
var wbb = child.userData.worldBoundingBox;
|
|
30757
31563
|
clonedConnector.userData.worldBoundingBox = {
|
|
30758
|
-
min: _toConsumableArray(
|
|
30759
|
-
max: _toConsumableArray(
|
|
31564
|
+
min: Array.isArray(wbb.min) ? _toConsumableArray(wbb.min) : _objectSpread2({}, wbb.min),
|
|
31565
|
+
max: Array.isArray(wbb.max) ? _toConsumableArray(wbb.max) : _objectSpread2({}, wbb.max)
|
|
30760
31566
|
};
|
|
30761
31567
|
}
|
|
30762
31568
|
if (child.userData.direction) {
|
|
30763
|
-
|
|
31569
|
+
// Handle both array [x,y,z] and object {x,y,z} formats
|
|
31570
|
+
if (Array.isArray(child.userData.direction)) {
|
|
31571
|
+
clonedConnector.userData.direction = _toConsumableArray(child.userData.direction);
|
|
31572
|
+
} else if (_typeof(child.userData.direction) === 'object') {
|
|
31573
|
+
clonedConnector.userData.direction = _objectSpread2({}, child.userData.direction);
|
|
31574
|
+
} else {
|
|
31575
|
+
clonedConnector.userData.direction = child.userData.direction;
|
|
31576
|
+
}
|
|
30764
31577
|
}
|
|
30765
31578
|
|
|
30766
31579
|
// Set originalUuid to match the actual uuid (maintains consistency)
|
|
@@ -30791,6 +31604,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30791
31604
|
_context2.n = 1;
|
|
30792
31605
|
break;
|
|
30793
31606
|
}
|
|
31607
|
+
console.log("\uD83C\uDFAF GLB cache HIT: ".concat(modelKey));
|
|
30794
31608
|
return _context2.a(2, gltfScene);
|
|
30795
31609
|
case 1:
|
|
30796
31610
|
// Check if preloading is in progress
|
|
@@ -30799,6 +31613,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30799
31613
|
_context2.n = 6;
|
|
30800
31614
|
break;
|
|
30801
31615
|
}
|
|
31616
|
+
console.log("\u23F3 Waiting for preloader: ".concat(modelKey));
|
|
30802
31617
|
_context2.p = 2;
|
|
30803
31618
|
_context2.n = 3;
|
|
30804
31619
|
return modelPreloader.preloadingPromise;
|
|
@@ -30808,6 +31623,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30808
31623
|
_context2.n = 4;
|
|
30809
31624
|
break;
|
|
30810
31625
|
}
|
|
31626
|
+
console.log("\uD83C\uDFAF GLB cache HIT (after preload): ".concat(modelKey));
|
|
30811
31627
|
return _context2.a(2, gltfScene);
|
|
30812
31628
|
case 4:
|
|
30813
31629
|
_context2.n = 6;
|
|
@@ -31135,7 +31951,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31135
31951
|
value: (function () {
|
|
31136
31952
|
var _replaceWithGLBModels = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(libraryObjectsToReplace) {
|
|
31137
31953
|
var _this3 = this;
|
|
31138
|
-
var glbLoadingPromises;
|
|
31954
|
+
var startTime, glbLoadingPromises;
|
|
31139
31955
|
return _regenerator().w(function (_context5) {
|
|
31140
31956
|
while (1) switch (_context5.n) {
|
|
31141
31957
|
case 0:
|
|
@@ -31145,23 +31961,29 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31145
31961
|
}
|
|
31146
31962
|
return _context5.a(2);
|
|
31147
31963
|
case 1:
|
|
31964
|
+
startTime = performance.now();
|
|
31148
31965
|
console.log("\uD83D\uDD04 Replacing ".concat(libraryObjectsToReplace.length, " objects with GLB models..."));
|
|
31149
31966
|
glbLoadingPromises = libraryObjectsToReplace.map(function (_ref, index) {
|
|
31150
31967
|
var basicObject = _ref.basicObject,
|
|
31151
31968
|
jsonData = _ref.jsonData,
|
|
31152
31969
|
componentData = _ref.componentData;
|
|
31970
|
+
var modelStart = performance.now();
|
|
31153
31971
|
return _this3.loadLibraryModel(basicObject, jsonData, componentData).then(function (libraryModel) {
|
|
31972
|
+
var _jsonData$userData;
|
|
31973
|
+
console.log("\u23F1\uFE0F GLB loaded: ".concat(((_jsonData$userData = jsonData.userData) === null || _jsonData$userData === void 0 ? void 0 : _jsonData$userData.libraryId) || jsonData.uuid, " in ").concat((performance.now() - modelStart).toFixed(0), "ms"));
|
|
31154
31974
|
libraryObjectsToReplace[index].glbModel = libraryModel;
|
|
31155
31975
|
return libraryModel;
|
|
31156
31976
|
}).catch(function (error) {
|
|
31157
|
-
var _jsonData$
|
|
31158
|
-
console.error("Failed to load ".concat((_jsonData$
|
|
31977
|
+
var _jsonData$userData2;
|
|
31978
|
+
console.error("Failed to load ".concat((_jsonData$userData2 = jsonData.userData) === null || _jsonData$userData2 === void 0 ? void 0 : _jsonData$userData2.libraryId, " GLB model:"), error);
|
|
31159
31979
|
return basicObject;
|
|
31160
31980
|
});
|
|
31161
31981
|
});
|
|
31162
31982
|
_context5.n = 2;
|
|
31163
31983
|
return Promise.all(glbLoadingPromises);
|
|
31164
31984
|
case 2:
|
|
31985
|
+
console.log("\u23F1\uFE0F All GLB models loaded in ".concat((performance.now() - startTime).toFixed(0), "ms"));
|
|
31986
|
+
|
|
31165
31987
|
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
31166
31988
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
31167
31989
|
var jsonData = _ref2.jsonData,
|
|
@@ -32547,9 +33369,13 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32547
33369
|
value: (function () {
|
|
32548
33370
|
var _loadSceneData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(data) {
|
|
32549
33371
|
var isImported,
|
|
33372
|
+
timers,
|
|
33373
|
+
totalStart,
|
|
33374
|
+
phaseStart,
|
|
32550
33375
|
_yield$this$_createBa,
|
|
32551
33376
|
crosscubeTextureSet,
|
|
32552
33377
|
libraryObjectsToReplace,
|
|
33378
|
+
totalTime,
|
|
32553
33379
|
_args4 = arguments,
|
|
32554
33380
|
_t3;
|
|
32555
33381
|
return _regenerator().w(function (_context4) {
|
|
@@ -32557,13 +33383,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32557
33383
|
case 0:
|
|
32558
33384
|
isImported = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : true;
|
|
32559
33385
|
this.sceneViewer;
|
|
33386
|
+
timers = {};
|
|
33387
|
+
totalStart = performance.now();
|
|
32560
33388
|
_context4.p = 1;
|
|
32561
33389
|
console.log("Loading scene data (".concat(isImported ? 'imported' : 'default', ")..."));
|
|
32562
33390
|
|
|
32563
33391
|
// Phase 1: Prepare scene
|
|
33392
|
+
phaseStart = performance.now();
|
|
32564
33393
|
_context4.n = 2;
|
|
32565
33394
|
return this._prepareSceneForLoading(data, isImported);
|
|
32566
33395
|
case 2:
|
|
33396
|
+
timers.phase1_prepare = performance.now() - phaseStart;
|
|
33397
|
+
|
|
33398
|
+
// Phase 2: Load dependencies and create basic objects
|
|
33399
|
+
phaseStart = performance.now();
|
|
32567
33400
|
_context4.n = 3;
|
|
32568
33401
|
return this._createBasicSceneObjects(data);
|
|
32569
33402
|
case 3:
|
|
@@ -32573,17 +33406,33 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32573
33406
|
_yield$this$_createBa.materials;
|
|
32574
33407
|
crosscubeTextureSet = _yield$this$_createBa.crosscubeTextureSet;
|
|
32575
33408
|
libraryObjectsToReplace = _yield$this$_createBa.libraryObjectsToReplace;
|
|
33409
|
+
timers.phase2_createObjects = performance.now() - phaseStart;
|
|
33410
|
+
|
|
33411
|
+
// Phase 3: Replace basic objects with GLB models (moved before pathfinding)
|
|
33412
|
+
phaseStart = performance.now();
|
|
32576
33413
|
_context4.n = 4;
|
|
32577
33414
|
return this.modelManager.replaceWithGLBModels(libraryObjectsToReplace);
|
|
32578
33415
|
case 4:
|
|
33416
|
+
timers.phase3_glbModels = performance.now() - phaseStart;
|
|
33417
|
+
|
|
33418
|
+
// Phase 4: Setup pathfinding (moved after GLB loading for consistent bounding boxes)
|
|
33419
|
+
phaseStart = performance.now();
|
|
32579
33420
|
_context4.n = 5;
|
|
32580
33421
|
return this._setupPathfinding(data, crosscubeTextureSet);
|
|
32581
33422
|
case 5:
|
|
33423
|
+
timers.phase4_pathfinding = performance.now() - phaseStart;
|
|
33424
|
+
|
|
32582
33425
|
// Phase 5: Finalize scene
|
|
33426
|
+
phaseStart = performance.now();
|
|
32583
33427
|
this._finalizeScene(data, crosscubeTextureSet, isImported);
|
|
33428
|
+
timers.phase5_finalize = performance.now() - phaseStart;
|
|
32584
33429
|
|
|
32585
33430
|
// Phase 6: Load behaviors (after GLB models are present so output objects can be resolved)
|
|
33431
|
+
phaseStart = performance.now();
|
|
32586
33432
|
this._processBehaviors(data);
|
|
33433
|
+
timers.phase6_behaviors = performance.now() - phaseStart;
|
|
33434
|
+
totalTime = performance.now() - totalStart;
|
|
33435
|
+
console.log("\u23F1\uFE0F Scene Loading Performance:\n Phase 1 (Prepare) : ".concat(timers.phase1_prepare.toFixed(0), "ms\n Phase 2 (Create Objects): ").concat(timers.phase2_createObjects.toFixed(0), "ms\n Phase 3 (GLB Models) : ").concat(timers.phase3_glbModels.toFixed(0), "ms\n Phase 4 (Pathfinding) : ").concat(timers.phase4_pathfinding.toFixed(0), "ms\n Phase 5 (Finalize) : ").concat(timers.phase5_finalize.toFixed(0), "ms\n Phase 6 (Behaviors) : ").concat(timers.phase6_behaviors.toFixed(0), "ms\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Total : ").concat(totalTime.toFixed(0), "ms"));
|
|
32587
33436
|
console.log('✅ Scene loaded successfully');
|
|
32588
33437
|
|
|
32589
33438
|
// Notify UI components (e.g. SceneHierarchy) that the scene is fully loaded
|
|
@@ -38089,7 +38938,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38089
38938
|
* Initialize the CentralPlant manager
|
|
38090
38939
|
*
|
|
38091
38940
|
* @constructor
|
|
38092
|
-
* @version 0.3.
|
|
38941
|
+
* @version 0.3.18
|
|
38093
38942
|
* @updated 2025-10-22
|
|
38094
38943
|
*
|
|
38095
38944
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|