@2112-lab/central-plant 0.3.15 → 0.3.17
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 +741 -7
- 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/core/centralPlantInternals.js +3 -2
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +16 -0
- package/dist/cjs/src/managers/scene/modelManager.js +12 -3
- 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/core/centralPlantInternals.js +3 -2
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +16 -0
- package/dist/esm/src/managers/scene/modelManager.js +12 -3
- 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
|
/**
|
|
@@ -28065,6 +28746,22 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28065
28746
|
this.pathfinder = new pathfinder.Pathfinder(this.pathfinderConfig);
|
|
28066
28747
|
this.sceneViewer.pathfinder = this.pathfinder;
|
|
28067
28748
|
|
|
28749
|
+
// ── Early exit if no connections ───────────────────────────────────
|
|
28750
|
+
// Skip expensive bounding box computation when there's nothing to connect
|
|
28751
|
+
if (!(!connections || connections.length === 0)) {
|
|
28752
|
+
_context.n = 1;
|
|
28753
|
+
break;
|
|
28754
|
+
}
|
|
28755
|
+
console.log("\u23ED\uFE0F Skipping pathfinding - no connections [".concat(context, "]"));
|
|
28756
|
+
return _context.a(2, {
|
|
28757
|
+
paths: [],
|
|
28758
|
+
gateways: [],
|
|
28759
|
+
rewiredConnections: [],
|
|
28760
|
+
metrics: {
|
|
28761
|
+
total: 0
|
|
28762
|
+
}
|
|
28763
|
+
});
|
|
28764
|
+
case 1:
|
|
28068
28765
|
// ── Stage 1: Input Generation ──────────────────────────────────────
|
|
28069
28766
|
inputGenStart = performance.now(); // Ensure all matrices are up to date before bounding box calculations (for all pathfinding executions)
|
|
28070
28767
|
this.sceneViewer.scene.updateMatrixWorld(true);
|
|
@@ -30791,6 +31488,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30791
31488
|
_context2.n = 1;
|
|
30792
31489
|
break;
|
|
30793
31490
|
}
|
|
31491
|
+
console.log("\uD83C\uDFAF GLB cache HIT: ".concat(modelKey));
|
|
30794
31492
|
return _context2.a(2, gltfScene);
|
|
30795
31493
|
case 1:
|
|
30796
31494
|
// Check if preloading is in progress
|
|
@@ -30799,6 +31497,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30799
31497
|
_context2.n = 6;
|
|
30800
31498
|
break;
|
|
30801
31499
|
}
|
|
31500
|
+
console.log("\u23F3 Waiting for preloader: ".concat(modelKey));
|
|
30802
31501
|
_context2.p = 2;
|
|
30803
31502
|
_context2.n = 3;
|
|
30804
31503
|
return modelPreloader.preloadingPromise;
|
|
@@ -30808,6 +31507,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
30808
31507
|
_context2.n = 4;
|
|
30809
31508
|
break;
|
|
30810
31509
|
}
|
|
31510
|
+
console.log("\uD83C\uDFAF GLB cache HIT (after preload): ".concat(modelKey));
|
|
30811
31511
|
return _context2.a(2, gltfScene);
|
|
30812
31512
|
case 4:
|
|
30813
31513
|
_context2.n = 6;
|
|
@@ -31135,7 +31835,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31135
31835
|
value: (function () {
|
|
31136
31836
|
var _replaceWithGLBModels = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(libraryObjectsToReplace) {
|
|
31137
31837
|
var _this3 = this;
|
|
31138
|
-
var glbLoadingPromises;
|
|
31838
|
+
var startTime, glbLoadingPromises;
|
|
31139
31839
|
return _regenerator().w(function (_context5) {
|
|
31140
31840
|
while (1) switch (_context5.n) {
|
|
31141
31841
|
case 0:
|
|
@@ -31145,23 +31845,29 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
31145
31845
|
}
|
|
31146
31846
|
return _context5.a(2);
|
|
31147
31847
|
case 1:
|
|
31848
|
+
startTime = performance.now();
|
|
31148
31849
|
console.log("\uD83D\uDD04 Replacing ".concat(libraryObjectsToReplace.length, " objects with GLB models..."));
|
|
31149
31850
|
glbLoadingPromises = libraryObjectsToReplace.map(function (_ref, index) {
|
|
31150
31851
|
var basicObject = _ref.basicObject,
|
|
31151
31852
|
jsonData = _ref.jsonData,
|
|
31152
31853
|
componentData = _ref.componentData;
|
|
31854
|
+
var modelStart = performance.now();
|
|
31153
31855
|
return _this3.loadLibraryModel(basicObject, jsonData, componentData).then(function (libraryModel) {
|
|
31856
|
+
var _jsonData$userData;
|
|
31857
|
+
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
31858
|
libraryObjectsToReplace[index].glbModel = libraryModel;
|
|
31155
31859
|
return libraryModel;
|
|
31156
31860
|
}).catch(function (error) {
|
|
31157
|
-
var _jsonData$
|
|
31158
|
-
console.error("Failed to load ".concat((_jsonData$
|
|
31861
|
+
var _jsonData$userData2;
|
|
31862
|
+
console.error("Failed to load ".concat((_jsonData$userData2 = jsonData.userData) === null || _jsonData$userData2 === void 0 ? void 0 : _jsonData$userData2.libraryId, " GLB model:"), error);
|
|
31159
31863
|
return basicObject;
|
|
31160
31864
|
});
|
|
31161
31865
|
});
|
|
31162
31866
|
_context5.n = 2;
|
|
31163
31867
|
return Promise.all(glbLoadingPromises);
|
|
31164
31868
|
case 2:
|
|
31869
|
+
console.log("\u23F1\uFE0F All GLB models loaded in ".concat((performance.now() - startTime).toFixed(0), "ms"));
|
|
31870
|
+
|
|
31165
31871
|
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
31166
31872
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
31167
31873
|
var jsonData = _ref2.jsonData,
|
|
@@ -32547,9 +33253,13 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32547
33253
|
value: (function () {
|
|
32548
33254
|
var _loadSceneData = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(data) {
|
|
32549
33255
|
var isImported,
|
|
33256
|
+
timers,
|
|
33257
|
+
totalStart,
|
|
33258
|
+
phaseStart,
|
|
32550
33259
|
_yield$this$_createBa,
|
|
32551
33260
|
crosscubeTextureSet,
|
|
32552
33261
|
libraryObjectsToReplace,
|
|
33262
|
+
totalTime,
|
|
32553
33263
|
_args4 = arguments,
|
|
32554
33264
|
_t3;
|
|
32555
33265
|
return _regenerator().w(function (_context4) {
|
|
@@ -32557,13 +33267,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32557
33267
|
case 0:
|
|
32558
33268
|
isImported = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : true;
|
|
32559
33269
|
this.sceneViewer;
|
|
33270
|
+
timers = {};
|
|
33271
|
+
totalStart = performance.now();
|
|
32560
33272
|
_context4.p = 1;
|
|
32561
33273
|
console.log("Loading scene data (".concat(isImported ? 'imported' : 'default', ")..."));
|
|
32562
33274
|
|
|
32563
33275
|
// Phase 1: Prepare scene
|
|
33276
|
+
phaseStart = performance.now();
|
|
32564
33277
|
_context4.n = 2;
|
|
32565
33278
|
return this._prepareSceneForLoading(data, isImported);
|
|
32566
33279
|
case 2:
|
|
33280
|
+
timers.phase1_prepare = performance.now() - phaseStart;
|
|
33281
|
+
|
|
33282
|
+
// Phase 2: Load dependencies and create basic objects
|
|
33283
|
+
phaseStart = performance.now();
|
|
32567
33284
|
_context4.n = 3;
|
|
32568
33285
|
return this._createBasicSceneObjects(data);
|
|
32569
33286
|
case 3:
|
|
@@ -32573,17 +33290,33 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32573
33290
|
_yield$this$_createBa.materials;
|
|
32574
33291
|
crosscubeTextureSet = _yield$this$_createBa.crosscubeTextureSet;
|
|
32575
33292
|
libraryObjectsToReplace = _yield$this$_createBa.libraryObjectsToReplace;
|
|
33293
|
+
timers.phase2_createObjects = performance.now() - phaseStart;
|
|
33294
|
+
|
|
33295
|
+
// Phase 3: Replace basic objects with GLB models (moved before pathfinding)
|
|
33296
|
+
phaseStart = performance.now();
|
|
32576
33297
|
_context4.n = 4;
|
|
32577
33298
|
return this.modelManager.replaceWithGLBModels(libraryObjectsToReplace);
|
|
32578
33299
|
case 4:
|
|
33300
|
+
timers.phase3_glbModels = performance.now() - phaseStart;
|
|
33301
|
+
|
|
33302
|
+
// Phase 4: Setup pathfinding (moved after GLB loading for consistent bounding boxes)
|
|
33303
|
+
phaseStart = performance.now();
|
|
32579
33304
|
_context4.n = 5;
|
|
32580
33305
|
return this._setupPathfinding(data, crosscubeTextureSet);
|
|
32581
33306
|
case 5:
|
|
33307
|
+
timers.phase4_pathfinding = performance.now() - phaseStart;
|
|
33308
|
+
|
|
32582
33309
|
// Phase 5: Finalize scene
|
|
33310
|
+
phaseStart = performance.now();
|
|
32583
33311
|
this._finalizeScene(data, crosscubeTextureSet, isImported);
|
|
33312
|
+
timers.phase5_finalize = performance.now() - phaseStart;
|
|
32584
33313
|
|
|
32585
33314
|
// Phase 6: Load behaviors (after GLB models are present so output objects can be resolved)
|
|
33315
|
+
phaseStart = performance.now();
|
|
32586
33316
|
this._processBehaviors(data);
|
|
33317
|
+
timers.phase6_behaviors = performance.now() - phaseStart;
|
|
33318
|
+
totalTime = performance.now() - totalStart;
|
|
33319
|
+
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
33320
|
console.log('✅ Scene loaded successfully');
|
|
32588
33321
|
|
|
32589
33322
|
// Notify UI components (e.g. SceneHierarchy) that the scene is fully loaded
|
|
@@ -37736,7 +38469,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
37736
38469
|
}));
|
|
37737
38470
|
componentData.children.forEach(function (childData, index) {
|
|
37738
38471
|
try {
|
|
37739
|
-
var _childData$userData, _childData$userData2;
|
|
38472
|
+
var _childData$userData, _childData$userData2, _childData$userData3;
|
|
37740
38473
|
// Create connector geometry (simple sphere for now)
|
|
37741
38474
|
var connectorGeometry = new THREE__namespace.SphereGeometry(0.1, 8, 6);
|
|
37742
38475
|
var connectorMaterial = new THREE__namespace.MeshPhysicalMaterial({
|
|
@@ -37772,7 +38505,8 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
37772
38505
|
parentComponentId: componentId,
|
|
37773
38506
|
connectorIndex: index,
|
|
37774
38507
|
direction: ((_childData$userData = childData.userData) === null || _childData$userData === void 0 ? void 0 : _childData$userData.direction) || [0, 1, 0],
|
|
37775
|
-
|
|
38508
|
+
flow: ((_childData$userData2 = childData.userData) === null || _childData$userData2 === void 0 ? void 0 : _childData$userData2.flow) || 'bi',
|
|
38509
|
+
group: ((_childData$userData3 = childData.userData) === null || _childData$userData3 === void 0 ? void 0 : _childData$userData3.group) || null,
|
|
37776
38510
|
originalChildData: childData
|
|
37777
38511
|
};
|
|
37778
38512
|
|
|
@@ -38088,7 +38822,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38088
38822
|
* Initialize the CentralPlant manager
|
|
38089
38823
|
*
|
|
38090
38824
|
* @constructor
|
|
38091
|
-
* @version 0.3.
|
|
38825
|
+
* @version 0.3.17
|
|
38092
38826
|
* @updated 2025-10-22
|
|
38093
38827
|
*
|
|
38094
38828
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|