@2112-lab/central-plant 0.1.90 → 0.1.91
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 +144 -82
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +9 -6
- package/dist/cjs/src/utils/ioDeviceUtils.js +133 -74
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +9 -6
- package/dist/esm/src/utils/ioDeviceUtils.js +134 -75
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -28570,91 +28570,150 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28570
28570
|
* Attach IO device models to a smart component from cached models.
|
|
28571
28571
|
* Each device referenced in componentData.attachedDevices is looked up
|
|
28572
28572
|
* in the model preloader cache, cloned, positioned, and added as a child.
|
|
28573
|
+
* If a device model is not in cache, it will be preloaded first.
|
|
28573
28574
|
*
|
|
28574
28575
|
* @param {THREE.Object3D} componentModel - The parent component model
|
|
28575
28576
|
* @param {Object} componentData - Component dictionary entry (has attachedDevices)
|
|
28576
28577
|
* @param {Object} modelPreloader - ModelPreloader instance with cache and componentDictionary
|
|
28577
28578
|
* @param {string} parentComponentId - The parent component's UUID
|
|
28578
|
-
* @returns {void}
|
|
28579
|
+
* @returns {Promise<void>}
|
|
28579
28580
|
*/
|
|
28580
|
-
function attachIODevicesToComponent(
|
|
28581
|
-
|
|
28582
|
-
|
|
28583
|
-
|
|
28584
|
-
|
|
28585
|
-
|
|
28586
|
-
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
|
|
28590
|
-
|
|
28591
|
-
|
|
28592
|
-
|
|
28593
|
-
|
|
28594
|
-
|
|
28595
|
-
|
|
28596
|
-
|
|
28597
|
-
|
|
28598
|
-
|
|
28599
|
-
|
|
28600
|
-
|
|
28601
|
-
|
|
28602
|
-
|
|
28603
|
-
|
|
28604
|
-
|
|
28605
|
-
|
|
28606
|
-
|
|
28607
|
-
|
|
28608
|
-
|
|
28609
|
-
|
|
28610
|
-
|
|
28611
|
-
|
|
28612
|
-
|
|
28613
|
-
|
|
28581
|
+
function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
28582
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
28583
|
+
}
|
|
28584
|
+
function _attachIODevicesToComponent() {
|
|
28585
|
+
_attachIODevicesToComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentModel, componentData, modelPreloader, parentComponentId) {
|
|
28586
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t, _t2;
|
|
28587
|
+
return _regenerator().w(function (_context) {
|
|
28588
|
+
while (1) switch (_context.n) {
|
|
28589
|
+
case 0:
|
|
28590
|
+
attachedDevices = componentData.attachedDevices;
|
|
28591
|
+
if (!(!attachedDevices || Object.keys(attachedDevices).length === 0)) {
|
|
28592
|
+
_context.n = 1;
|
|
28593
|
+
break;
|
|
28594
|
+
}
|
|
28595
|
+
return _context.a(2);
|
|
28596
|
+
case 1:
|
|
28597
|
+
console.log("\uD83D\uDD0C attachIODevicesToComponent(): Attaching ".concat(Object.keys(attachedDevices).length, " IO devices to smart component"));
|
|
28598
|
+
_i = 0, _Object$entries = Object.entries(attachedDevices);
|
|
28599
|
+
case 2:
|
|
28600
|
+
if (!(_i < _Object$entries.length)) {
|
|
28601
|
+
_context.n = 14;
|
|
28602
|
+
break;
|
|
28603
|
+
}
|
|
28604
|
+
_Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
|
|
28605
|
+
_context.p = 3;
|
|
28606
|
+
deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
|
|
28607
|
+
if (!(!deviceData || !deviceData.modelKey)) {
|
|
28608
|
+
_context.n = 4;
|
|
28609
|
+
break;
|
|
28610
|
+
}
|
|
28611
|
+
console.warn("\u26A0\uFE0F IO device ".concat(attachment.deviceId, " not found in dictionary, skipping"));
|
|
28612
|
+
return _context.a(3, 13);
|
|
28613
|
+
case 4:
|
|
28614
|
+
// Try to get from cache first
|
|
28615
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId); // If not in cache, try to preload it
|
|
28616
|
+
if (cachedDevice) {
|
|
28617
|
+
_context.n = 10;
|
|
28618
|
+
break;
|
|
28619
|
+
}
|
|
28620
|
+
console.log("\uD83D\uDD04 IO device model not in cache, preloading: ".concat(deviceData.modelKey));
|
|
28621
|
+
_context.p = 5;
|
|
28622
|
+
if (!((_modelPreloader$loadi = modelPreloader.loadingPromises) !== null && _modelPreloader$loadi !== void 0 && _modelPreloader$loadi.has(deviceData.modelKey))) {
|
|
28623
|
+
_context.n = 7;
|
|
28624
|
+
break;
|
|
28625
|
+
}
|
|
28626
|
+
_context.n = 6;
|
|
28627
|
+
return modelPreloader.loadingPromises.get(deviceData.modelKey);
|
|
28628
|
+
case 6:
|
|
28629
|
+
_context.n = 8;
|
|
28630
|
+
break;
|
|
28631
|
+
case 7:
|
|
28632
|
+
_context.n = 8;
|
|
28633
|
+
return modelPreloader.preloadSingleModel(deviceData.modelKey);
|
|
28634
|
+
case 8:
|
|
28635
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId);
|
|
28636
|
+
_context.n = 10;
|
|
28637
|
+
break;
|
|
28638
|
+
case 9:
|
|
28639
|
+
_context.p = 9;
|
|
28640
|
+
_t = _context.v;
|
|
28641
|
+
console.warn("\u26A0\uFE0F Failed to preload IO device model ".concat(deviceData.modelKey, ":"), _t);
|
|
28642
|
+
case 10:
|
|
28643
|
+
if (cachedDevice) {
|
|
28644
|
+
_context.n = 11;
|
|
28645
|
+
break;
|
|
28646
|
+
}
|
|
28647
|
+
console.warn("\u26A0\uFE0F IO device model could not be loaded: ".concat(deviceData.modelKey, ", skipping"));
|
|
28648
|
+
return _context.a(3, 13);
|
|
28649
|
+
case 11:
|
|
28650
|
+
// Clone so each component instance owns its own io-device subtree and materials.
|
|
28651
|
+
// Without this, all placed copies of the same smart component share the cached
|
|
28652
|
+
// object, causing material mutations (from behaviors) to bleed across instances.
|
|
28653
|
+
deviceModel = cachedDevice.clone();
|
|
28654
|
+
deviceModel.traverse(function (child) {
|
|
28655
|
+
if (child.isMesh && child.material) {
|
|
28656
|
+
child.material = Array.isArray(child.material) ? child.material.map(function (m) {
|
|
28657
|
+
return m.clone();
|
|
28658
|
+
}) : child.material.clone();
|
|
28659
|
+
}
|
|
28660
|
+
});
|
|
28614
28661
|
|
|
28615
|
-
|
|
28616
|
-
|
|
28617
|
-
|
|
28618
|
-
// Set user data for identification — include ioConfig data points so the
|
|
28619
|
-
// component tooltip can render state displays without an extra lookup.
|
|
28620
|
-
deviceModel.userData = {
|
|
28621
|
-
objectType: 'io-device',
|
|
28622
|
-
deviceId: attachment.deviceId,
|
|
28623
|
-
attachmentId: attachmentId,
|
|
28624
|
-
attachmentLabel: attachment.attachmentLabel,
|
|
28625
|
-
parentComponentId: parentComponentId,
|
|
28626
|
-
deviceName: deviceData.name || '',
|
|
28627
|
-
// Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
|
|
28628
|
-
// ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
|
|
28629
|
-
dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
|
|
28630
|
-
// Device-level I/O direction: 'input' means the user can write state via the tooltip
|
|
28631
|
-
ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
|
|
28632
|
-
// Signal wiring sourced from this attachment (for state propagation reference)
|
|
28633
|
-
signalOutputs: attachment.signalOutputs || []
|
|
28634
|
-
};
|
|
28662
|
+
// Name the device model
|
|
28663
|
+
deviceModel.name = "".concat(attachment.attachmentLabel || 'IO Device', " (").concat(attachmentId, ")");
|
|
28635
28664
|
|
|
28636
|
-
|
|
28637
|
-
|
|
28638
|
-
|
|
28639
|
-
|
|
28640
|
-
|
|
28665
|
+
// Set user data for identification — include ioConfig data points so the
|
|
28666
|
+
// component tooltip can render state displays without an extra lookup.
|
|
28667
|
+
deviceModel.userData = {
|
|
28668
|
+
objectType: 'io-device',
|
|
28669
|
+
deviceId: attachment.deviceId,
|
|
28670
|
+
attachmentId: attachmentId,
|
|
28671
|
+
attachmentLabel: attachment.attachmentLabel,
|
|
28672
|
+
parentComponentId: parentComponentId,
|
|
28673
|
+
deviceName: deviceData.name || '',
|
|
28674
|
+
// Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
|
|
28675
|
+
// ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
|
|
28676
|
+
dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
|
|
28677
|
+
// Device-level I/O direction: 'input' means the user can write state via the tooltip
|
|
28678
|
+
ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
|
|
28679
|
+
// Signal wiring sourced from this attachment (for state propagation reference)
|
|
28680
|
+
signalOutputs: attachment.signalOutputs || []
|
|
28681
|
+
};
|
|
28641
28682
|
|
|
28642
|
-
|
|
28643
|
-
|
|
28644
|
-
|
|
28645
|
-
|
|
28646
|
-
|
|
28683
|
+
// Position at the attachment point
|
|
28684
|
+
if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
|
|
28685
|
+
pos = attachment.attachmentPoint.position;
|
|
28686
|
+
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
28687
|
+
}
|
|
28647
28688
|
|
|
28648
|
-
|
|
28649
|
-
|
|
28650
|
-
|
|
28651
|
-
|
|
28652
|
-
|
|
28653
|
-
|
|
28654
|
-
|
|
28655
|
-
|
|
28656
|
-
|
|
28657
|
-
|
|
28689
|
+
// IO device models are authored at the same real-world unit scale
|
|
28690
|
+
// as the host component, so keep them at their natural (1:1) size.
|
|
28691
|
+
// Note: attachmentPoint.scale is the connector marker sphere size,
|
|
28692
|
+
// NOT a desired device model scale.
|
|
28693
|
+
deviceModel.scale.setScalar(1);
|
|
28694
|
+
|
|
28695
|
+
// Add as child of the component
|
|
28696
|
+
componentModel.add(deviceModel);
|
|
28697
|
+
console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
|
|
28698
|
+
position: deviceModel.position,
|
|
28699
|
+
scale: deviceModel.scale
|
|
28700
|
+
});
|
|
28701
|
+
_context.n = 13;
|
|
28702
|
+
break;
|
|
28703
|
+
case 12:
|
|
28704
|
+
_context.p = 12;
|
|
28705
|
+
_t2 = _context.v;
|
|
28706
|
+
console.error("\u274C Error attaching IO device ".concat(attachment.deviceId, ":"), _t2);
|
|
28707
|
+
case 13:
|
|
28708
|
+
_i++;
|
|
28709
|
+
_context.n = 2;
|
|
28710
|
+
break;
|
|
28711
|
+
case 14:
|
|
28712
|
+
return _context.a(2);
|
|
28713
|
+
}
|
|
28714
|
+
}, _callee, null, [[5, 9], [3, 12]]);
|
|
28715
|
+
}));
|
|
28716
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
28658
28717
|
}
|
|
28659
28718
|
|
|
28660
28719
|
var ModelManager = /*#__PURE__*/function () {
|
|
@@ -28741,21 +28800,24 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
28741
28800
|
});
|
|
28742
28801
|
|
|
28743
28802
|
// Attach IO devices for smart components (import flow)
|
|
28744
|
-
if (componentData.isSmart && componentData.attachedDevices) {
|
|
28745
|
-
|
|
28803
|
+
if (!(componentData.isSmart && componentData.attachedDevices)) {
|
|
28804
|
+
_context.n = 4;
|
|
28805
|
+
break;
|
|
28746
28806
|
}
|
|
28747
|
-
|
|
28807
|
+
_context.n = 4;
|
|
28808
|
+
return attachIODevicesToComponent(libraryModel, componentData, modelPreloader, originalProps.uuid);
|
|
28809
|
+
case 4:
|
|
28748
28810
|
// Replace mesh in scene
|
|
28749
28811
|
this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
|
|
28750
28812
|
console.log("\uD83C\uDF89 ".concat((_jsonEntry$userData3 = jsonEntry.userData) === null || _jsonEntry$userData3 === void 0 ? void 0 : _jsonEntry$userData3.libraryId, " GLB model successfully rendered in scene"));
|
|
28751
28813
|
return _context.a(2, libraryModel);
|
|
28752
|
-
case
|
|
28753
|
-
_context.p =
|
|
28814
|
+
case 5:
|
|
28815
|
+
_context.p = 5;
|
|
28754
28816
|
_t = _context.v;
|
|
28755
28817
|
console.error("\u274C Error loading ".concat((_jsonEntry$userData4 = jsonEntry.userData) === null || _jsonEntry$userData4 === void 0 ? void 0 : _jsonEntry$userData4.libraryId, " GLB model:"), _t);
|
|
28756
28818
|
return _context.a(2, targetMesh);
|
|
28757
28819
|
}
|
|
28758
|
-
}, _callee, this, [[1,
|
|
28820
|
+
}, _callee, this, [[1, 5]]);
|
|
28759
28821
|
}));
|
|
28760
28822
|
function loadLibraryModel(_x, _x2, _x3) {
|
|
28761
28823
|
return _loadLibraryModel.apply(this, arguments);
|
|
@@ -36814,7 +36876,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
36814
36876
|
* Initialize the CentralPlant manager
|
|
36815
36877
|
*
|
|
36816
36878
|
* @constructor
|
|
36817
|
-
* @version 0.1.
|
|
36879
|
+
* @version 0.1.91
|
|
36818
36880
|
* @updated 2025-10-22
|
|
36819
36881
|
*
|
|
36820
36882
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19
19
|
* Initialize the CentralPlant manager
|
|
20
20
|
*
|
|
21
21
|
* @constructor
|
|
22
|
-
* @version 0.1.
|
|
22
|
+
* @version 0.1.91
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -111,21 +111,24 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
// Attach IO devices for smart components (import flow)
|
|
114
|
-
if (componentData.isSmart && componentData.attachedDevices) {
|
|
115
|
-
|
|
114
|
+
if (!(componentData.isSmart && componentData.attachedDevices)) {
|
|
115
|
+
_context.n = 4;
|
|
116
|
+
break;
|
|
116
117
|
}
|
|
117
|
-
|
|
118
|
+
_context.n = 4;
|
|
119
|
+
return ioDeviceUtils.attachIODevicesToComponent(libraryModel, componentData, modelPreloader["default"], originalProps.uuid);
|
|
120
|
+
case 4:
|
|
118
121
|
// Replace mesh in scene
|
|
119
122
|
this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
|
|
120
123
|
console.log("\uD83C\uDF89 ".concat((_jsonEntry$userData3 = jsonEntry.userData) === null || _jsonEntry$userData3 === void 0 ? void 0 : _jsonEntry$userData3.libraryId, " GLB model successfully rendered in scene"));
|
|
121
124
|
return _context.a(2, libraryModel);
|
|
122
|
-
case
|
|
123
|
-
_context.p =
|
|
125
|
+
case 5:
|
|
126
|
+
_context.p = 5;
|
|
124
127
|
_t = _context.v;
|
|
125
128
|
console.error("\u274C Error loading ".concat((_jsonEntry$userData4 = jsonEntry.userData) === null || _jsonEntry$userData4 === void 0 ? void 0 : _jsonEntry$userData4.libraryId, " GLB model:"), _t);
|
|
126
129
|
return _context.a(2, targetMesh);
|
|
127
130
|
}
|
|
128
|
-
}, _callee, this, [[1,
|
|
131
|
+
}, _callee, this, [[1, 5]]);
|
|
129
132
|
}));
|
|
130
133
|
function loadLibraryModel(_x, _x2, _x3) {
|
|
131
134
|
return _loadLibraryModel.apply(this, arguments);
|
|
@@ -14,91 +14,150 @@ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelper
|
|
|
14
14
|
* Attach IO device models to a smart component from cached models.
|
|
15
15
|
* Each device referenced in componentData.attachedDevices is looked up
|
|
16
16
|
* in the model preloader cache, cloned, positioned, and added as a child.
|
|
17
|
+
* If a device model is not in cache, it will be preloaded first.
|
|
17
18
|
*
|
|
18
19
|
* @param {THREE.Object3D} componentModel - The parent component model
|
|
19
20
|
* @param {Object} componentData - Component dictionary entry (has attachedDevices)
|
|
20
21
|
* @param {Object} modelPreloader - ModelPreloader instance with cache and componentDictionary
|
|
21
22
|
* @param {string} parentComponentId - The parent component's UUID
|
|
22
|
-
* @returns {void}
|
|
23
|
+
* @returns {Promise<void>}
|
|
23
24
|
*/
|
|
24
|
-
function attachIODevicesToComponent(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
25
|
+
function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
26
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
27
|
+
}
|
|
28
|
+
function _attachIODevicesToComponent() {
|
|
29
|
+
_attachIODevicesToComponent = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee(componentModel, componentData, modelPreloader, parentComponentId) {
|
|
30
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t, _t2;
|
|
31
|
+
return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
|
|
32
|
+
while (1) switch (_context.n) {
|
|
33
|
+
case 0:
|
|
34
|
+
attachedDevices = componentData.attachedDevices;
|
|
35
|
+
if (!(!attachedDevices || Object.keys(attachedDevices).length === 0)) {
|
|
36
|
+
_context.n = 1;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
return _context.a(2);
|
|
40
|
+
case 1:
|
|
41
|
+
console.log("\uD83D\uDD0C attachIODevicesToComponent(): Attaching ".concat(Object.keys(attachedDevices).length, " IO devices to smart component"));
|
|
42
|
+
_i = 0, _Object$entries = Object.entries(attachedDevices);
|
|
43
|
+
case 2:
|
|
44
|
+
if (!(_i < _Object$entries.length)) {
|
|
45
|
+
_context.n = 14;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
_Object$entries$_i = _rollupPluginBabelHelpers.slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
|
|
49
|
+
_context.p = 3;
|
|
50
|
+
deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
|
|
51
|
+
if (!(!deviceData || !deviceData.modelKey)) {
|
|
52
|
+
_context.n = 4;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
console.warn("\u26A0\uFE0F IO device ".concat(attachment.deviceId, " not found in dictionary, skipping"));
|
|
56
|
+
return _context.a(3, 13);
|
|
57
|
+
case 4:
|
|
58
|
+
// Try to get from cache first
|
|
59
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId); // If not in cache, try to preload it
|
|
60
|
+
if (cachedDevice) {
|
|
61
|
+
_context.n = 10;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
console.log("\uD83D\uDD04 IO device model not in cache, preloading: ".concat(deviceData.modelKey));
|
|
65
|
+
_context.p = 5;
|
|
66
|
+
if (!((_modelPreloader$loadi = modelPreloader.loadingPromises) !== null && _modelPreloader$loadi !== void 0 && _modelPreloader$loadi.has(deviceData.modelKey))) {
|
|
67
|
+
_context.n = 7;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
_context.n = 6;
|
|
71
|
+
return modelPreloader.loadingPromises.get(deviceData.modelKey);
|
|
72
|
+
case 6:
|
|
73
|
+
_context.n = 8;
|
|
74
|
+
break;
|
|
75
|
+
case 7:
|
|
76
|
+
_context.n = 8;
|
|
77
|
+
return modelPreloader.preloadSingleModel(deviceData.modelKey);
|
|
78
|
+
case 8:
|
|
79
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId);
|
|
80
|
+
_context.n = 10;
|
|
81
|
+
break;
|
|
82
|
+
case 9:
|
|
83
|
+
_context.p = 9;
|
|
84
|
+
_t = _context.v;
|
|
85
|
+
console.warn("\u26A0\uFE0F Failed to preload IO device model ".concat(deviceData.modelKey, ":"), _t);
|
|
86
|
+
case 10:
|
|
87
|
+
if (cachedDevice) {
|
|
88
|
+
_context.n = 11;
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
console.warn("\u26A0\uFE0F IO device model could not be loaded: ".concat(deviceData.modelKey, ", skipping"));
|
|
92
|
+
return _context.a(3, 13);
|
|
93
|
+
case 11:
|
|
94
|
+
// Clone so each component instance owns its own io-device subtree and materials.
|
|
95
|
+
// Without this, all placed copies of the same smart component share the cached
|
|
96
|
+
// object, causing material mutations (from behaviors) to bleed across instances.
|
|
97
|
+
deviceModel = cachedDevice.clone();
|
|
98
|
+
deviceModel.traverse(function (child) {
|
|
99
|
+
if (child.isMesh && child.material) {
|
|
100
|
+
child.material = Array.isArray(child.material) ? child.material.map(function (m) {
|
|
101
|
+
return m.clone();
|
|
102
|
+
}) : child.material.clone();
|
|
103
|
+
}
|
|
104
|
+
});
|
|
58
105
|
|
|
59
|
-
|
|
60
|
-
|
|
106
|
+
// Name the device model
|
|
107
|
+
deviceModel.name = "".concat(attachment.attachmentLabel || 'IO Device', " (").concat(attachmentId, ")");
|
|
61
108
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
109
|
+
// Set user data for identification — include ioConfig data points so the
|
|
110
|
+
// component tooltip can render state displays without an extra lookup.
|
|
111
|
+
deviceModel.userData = {
|
|
112
|
+
objectType: 'io-device',
|
|
113
|
+
deviceId: attachment.deviceId,
|
|
114
|
+
attachmentId: attachmentId,
|
|
115
|
+
attachmentLabel: attachment.attachmentLabel,
|
|
116
|
+
parentComponentId: parentComponentId,
|
|
117
|
+
deviceName: deviceData.name || '',
|
|
118
|
+
// Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
|
|
119
|
+
// ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
|
|
120
|
+
dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
|
|
121
|
+
// Device-level I/O direction: 'input' means the user can write state via the tooltip
|
|
122
|
+
ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
|
|
123
|
+
// Signal wiring sourced from this attachment (for state propagation reference)
|
|
124
|
+
signalOutputs: attachment.signalOutputs || []
|
|
125
|
+
};
|
|
79
126
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
127
|
+
// Position at the attachment point
|
|
128
|
+
if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
|
|
129
|
+
pos = attachment.attachmentPoint.position;
|
|
130
|
+
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
131
|
+
}
|
|
85
132
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
133
|
+
// IO device models are authored at the same real-world unit scale
|
|
134
|
+
// as the host component, so keep them at their natural (1:1) size.
|
|
135
|
+
// Note: attachmentPoint.scale is the connector marker sphere size,
|
|
136
|
+
// NOT a desired device model scale.
|
|
137
|
+
deviceModel.scale.setScalar(1);
|
|
91
138
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
139
|
+
// Add as child of the component
|
|
140
|
+
componentModel.add(deviceModel);
|
|
141
|
+
console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
|
|
142
|
+
position: deviceModel.position,
|
|
143
|
+
scale: deviceModel.scale
|
|
144
|
+
});
|
|
145
|
+
_context.n = 13;
|
|
146
|
+
break;
|
|
147
|
+
case 12:
|
|
148
|
+
_context.p = 12;
|
|
149
|
+
_t2 = _context.v;
|
|
150
|
+
console.error("\u274C Error attaching IO device ".concat(attachment.deviceId, ":"), _t2);
|
|
151
|
+
case 13:
|
|
152
|
+
_i++;
|
|
153
|
+
_context.n = 2;
|
|
154
|
+
break;
|
|
155
|
+
case 14:
|
|
156
|
+
return _context.a(2);
|
|
157
|
+
}
|
|
158
|
+
}, _callee, null, [[5, 9], [3, 12]]);
|
|
159
|
+
}));
|
|
160
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
102
161
|
}
|
|
103
162
|
|
|
104
163
|
exports.attachIODevicesToComponent = attachIODevicesToComponent;
|
|
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
15
15
|
* Initialize the CentralPlant manager
|
|
16
16
|
*
|
|
17
17
|
* @constructor
|
|
18
|
-
* @version 0.1.
|
|
18
|
+
* @version 0.1.91
|
|
19
19
|
* @updated 2025-10-22
|
|
20
20
|
*
|
|
21
21
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -87,21 +87,24 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
87
87
|
});
|
|
88
88
|
|
|
89
89
|
// Attach IO devices for smart components (import flow)
|
|
90
|
-
if (componentData.isSmart && componentData.attachedDevices) {
|
|
91
|
-
|
|
90
|
+
if (!(componentData.isSmart && componentData.attachedDevices)) {
|
|
91
|
+
_context.n = 4;
|
|
92
|
+
break;
|
|
92
93
|
}
|
|
93
|
-
|
|
94
|
+
_context.n = 4;
|
|
95
|
+
return attachIODevicesToComponent(libraryModel, componentData, modelPreloader, originalProps.uuid);
|
|
96
|
+
case 4:
|
|
94
97
|
// Replace mesh in scene
|
|
95
98
|
this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
|
|
96
99
|
console.log("\uD83C\uDF89 ".concat((_jsonEntry$userData3 = jsonEntry.userData) === null || _jsonEntry$userData3 === void 0 ? void 0 : _jsonEntry$userData3.libraryId, " GLB model successfully rendered in scene"));
|
|
97
100
|
return _context.a(2, libraryModel);
|
|
98
|
-
case
|
|
99
|
-
_context.p =
|
|
101
|
+
case 5:
|
|
102
|
+
_context.p = 5;
|
|
100
103
|
_t = _context.v;
|
|
101
104
|
console.error("\u274C Error loading ".concat((_jsonEntry$userData4 = jsonEntry.userData) === null || _jsonEntry$userData4 === void 0 ? void 0 : _jsonEntry$userData4.libraryId, " GLB model:"), _t);
|
|
102
105
|
return _context.a(2, targetMesh);
|
|
103
106
|
}
|
|
104
|
-
}, _callee, this, [[1,
|
|
107
|
+
}, _callee, this, [[1, 5]]);
|
|
105
108
|
}));
|
|
106
109
|
function loadLibraryModel(_x, _x2, _x3) {
|
|
107
110
|
return _loadLibraryModel.apply(this, arguments);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
1
|
+
import { asyncToGenerator as _asyncToGenerator, regenerator as _regenerator, slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* IO Device Utilities
|
|
@@ -10,91 +10,150 @@ import { slicedToArray as _slicedToArray } from '../../_virtual/_rollupPluginBab
|
|
|
10
10
|
* Attach IO device models to a smart component from cached models.
|
|
11
11
|
* Each device referenced in componentData.attachedDevices is looked up
|
|
12
12
|
* in the model preloader cache, cloned, positioned, and added as a child.
|
|
13
|
+
* If a device model is not in cache, it will be preloaded first.
|
|
13
14
|
*
|
|
14
15
|
* @param {THREE.Object3D} componentModel - The parent component model
|
|
15
16
|
* @param {Object} componentData - Component dictionary entry (has attachedDevices)
|
|
16
17
|
* @param {Object} modelPreloader - ModelPreloader instance with cache and componentDictionary
|
|
17
18
|
* @param {string} parentComponentId - The parent component's UUID
|
|
18
|
-
* @returns {void}
|
|
19
|
+
* @returns {Promise<void>}
|
|
19
20
|
*/
|
|
20
|
-
function attachIODevicesToComponent(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
21
|
+
function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
22
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
23
|
+
}
|
|
24
|
+
function _attachIODevicesToComponent() {
|
|
25
|
+
_attachIODevicesToComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentModel, componentData, modelPreloader, parentComponentId) {
|
|
26
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t, _t2;
|
|
27
|
+
return _regenerator().w(function (_context) {
|
|
28
|
+
while (1) switch (_context.n) {
|
|
29
|
+
case 0:
|
|
30
|
+
attachedDevices = componentData.attachedDevices;
|
|
31
|
+
if (!(!attachedDevices || Object.keys(attachedDevices).length === 0)) {
|
|
32
|
+
_context.n = 1;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
return _context.a(2);
|
|
36
|
+
case 1:
|
|
37
|
+
console.log("\uD83D\uDD0C attachIODevicesToComponent(): Attaching ".concat(Object.keys(attachedDevices).length, " IO devices to smart component"));
|
|
38
|
+
_i = 0, _Object$entries = Object.entries(attachedDevices);
|
|
39
|
+
case 2:
|
|
40
|
+
if (!(_i < _Object$entries.length)) {
|
|
41
|
+
_context.n = 14;
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
_Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
|
|
45
|
+
_context.p = 3;
|
|
46
|
+
deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
|
|
47
|
+
if (!(!deviceData || !deviceData.modelKey)) {
|
|
48
|
+
_context.n = 4;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
console.warn("\u26A0\uFE0F IO device ".concat(attachment.deviceId, " not found in dictionary, skipping"));
|
|
52
|
+
return _context.a(3, 13);
|
|
53
|
+
case 4:
|
|
54
|
+
// Try to get from cache first
|
|
55
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId); // If not in cache, try to preload it
|
|
56
|
+
if (cachedDevice) {
|
|
57
|
+
_context.n = 10;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
console.log("\uD83D\uDD04 IO device model not in cache, preloading: ".concat(deviceData.modelKey));
|
|
61
|
+
_context.p = 5;
|
|
62
|
+
if (!((_modelPreloader$loadi = modelPreloader.loadingPromises) !== null && _modelPreloader$loadi !== void 0 && _modelPreloader$loadi.has(deviceData.modelKey))) {
|
|
63
|
+
_context.n = 7;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
_context.n = 6;
|
|
67
|
+
return modelPreloader.loadingPromises.get(deviceData.modelKey);
|
|
68
|
+
case 6:
|
|
69
|
+
_context.n = 8;
|
|
70
|
+
break;
|
|
71
|
+
case 7:
|
|
72
|
+
_context.n = 8;
|
|
73
|
+
return modelPreloader.preloadSingleModel(deviceData.modelKey);
|
|
74
|
+
case 8:
|
|
75
|
+
cachedDevice = modelPreloader.getCachedModelWithDimensions(deviceData.modelKey, attachment.deviceId);
|
|
76
|
+
_context.n = 10;
|
|
77
|
+
break;
|
|
78
|
+
case 9:
|
|
79
|
+
_context.p = 9;
|
|
80
|
+
_t = _context.v;
|
|
81
|
+
console.warn("\u26A0\uFE0F Failed to preload IO device model ".concat(deviceData.modelKey, ":"), _t);
|
|
82
|
+
case 10:
|
|
83
|
+
if (cachedDevice) {
|
|
84
|
+
_context.n = 11;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
console.warn("\u26A0\uFE0F IO device model could not be loaded: ".concat(deviceData.modelKey, ", skipping"));
|
|
88
|
+
return _context.a(3, 13);
|
|
89
|
+
case 11:
|
|
90
|
+
// Clone so each component instance owns its own io-device subtree and materials.
|
|
91
|
+
// Without this, all placed copies of the same smart component share the cached
|
|
92
|
+
// object, causing material mutations (from behaviors) to bleed across instances.
|
|
93
|
+
deviceModel = cachedDevice.clone();
|
|
94
|
+
deviceModel.traverse(function (child) {
|
|
95
|
+
if (child.isMesh && child.material) {
|
|
96
|
+
child.material = Array.isArray(child.material) ? child.material.map(function (m) {
|
|
97
|
+
return m.clone();
|
|
98
|
+
}) : child.material.clone();
|
|
99
|
+
}
|
|
100
|
+
});
|
|
54
101
|
|
|
55
|
-
|
|
56
|
-
|
|
102
|
+
// Name the device model
|
|
103
|
+
deviceModel.name = "".concat(attachment.attachmentLabel || 'IO Device', " (").concat(attachmentId, ")");
|
|
57
104
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
105
|
+
// Set user data for identification — include ioConfig data points so the
|
|
106
|
+
// component tooltip can render state displays without an extra lookup.
|
|
107
|
+
deviceModel.userData = {
|
|
108
|
+
objectType: 'io-device',
|
|
109
|
+
deviceId: attachment.deviceId,
|
|
110
|
+
attachmentId: attachmentId,
|
|
111
|
+
attachmentLabel: attachment.attachmentLabel,
|
|
112
|
+
parentComponentId: parentComponentId,
|
|
113
|
+
deviceName: deviceData.name || '',
|
|
114
|
+
// Snapshot of the device's data point definitions (stateType, stateConfig, direction, etc.)
|
|
115
|
+
// ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
|
|
116
|
+
dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
|
|
117
|
+
// Device-level I/O direction: 'input' means the user can write state via the tooltip
|
|
118
|
+
ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output',
|
|
119
|
+
// Signal wiring sourced from this attachment (for state propagation reference)
|
|
120
|
+
signalOutputs: attachment.signalOutputs || []
|
|
121
|
+
};
|
|
75
122
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
123
|
+
// Position at the attachment point
|
|
124
|
+
if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
|
|
125
|
+
pos = attachment.attachmentPoint.position;
|
|
126
|
+
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
127
|
+
}
|
|
81
128
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
129
|
+
// IO device models are authored at the same real-world unit scale
|
|
130
|
+
// as the host component, so keep them at their natural (1:1) size.
|
|
131
|
+
// Note: attachmentPoint.scale is the connector marker sphere size,
|
|
132
|
+
// NOT a desired device model scale.
|
|
133
|
+
deviceModel.scale.setScalar(1);
|
|
87
134
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
135
|
+
// Add as child of the component
|
|
136
|
+
componentModel.add(deviceModel);
|
|
137
|
+
console.log("\u2705 Attached IO device: ".concat(attachment.attachmentLabel || attachment.deviceId, " at"), {
|
|
138
|
+
position: deviceModel.position,
|
|
139
|
+
scale: deviceModel.scale
|
|
140
|
+
});
|
|
141
|
+
_context.n = 13;
|
|
142
|
+
break;
|
|
143
|
+
case 12:
|
|
144
|
+
_context.p = 12;
|
|
145
|
+
_t2 = _context.v;
|
|
146
|
+
console.error("\u274C Error attaching IO device ".concat(attachment.deviceId, ":"), _t2);
|
|
147
|
+
case 13:
|
|
148
|
+
_i++;
|
|
149
|
+
_context.n = 2;
|
|
150
|
+
break;
|
|
151
|
+
case 14:
|
|
152
|
+
return _context.a(2);
|
|
153
|
+
}
|
|
154
|
+
}, _callee, null, [[5, 9], [3, 12]]);
|
|
155
|
+
}));
|
|
156
|
+
return _attachIODevicesToComponent.apply(this, arguments);
|
|
98
157
|
}
|
|
99
158
|
|
|
100
159
|
export { attachIODevicesToComponent };
|