@2112-lab/central-plant 0.2.3 → 0.2.5
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 +93 -6
- package/dist/cjs/src/core/centralPlant.js +66 -3
- package/dist/cjs/src/managers/behaviors/BehaviorManager.js +11 -1
- package/dist/cjs/src/managers/controls/componentDragManager.js +8 -1
- package/dist/cjs/src/utils/ioDeviceUtils.js +8 -1
- package/dist/esm/src/core/centralPlant.js +66 -3
- package/dist/esm/src/managers/behaviors/BehaviorManager.js +11 -1
- package/dist/esm/src/managers/controls/componentDragManager.js +8 -1
- package/dist/esm/src/utils/ioDeviceUtils.js +8 -1
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -28480,7 +28480,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28480
28480
|
if (_this4._testCondition(condition.when, value)) {
|
|
28481
28481
|
if (Array.isArray(condition.actions)) {
|
|
28482
28482
|
condition.actions.forEach(function (action) {
|
|
28483
|
-
_this4._applyAction(output, action.set, action.value);
|
|
28483
|
+
_this4._applyAction(output, action.set, action.value, action.relative === true);
|
|
28484
28484
|
});
|
|
28485
28485
|
}
|
|
28486
28486
|
}
|
|
@@ -28558,6 +28558,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28558
28558
|
}, {
|
|
28559
28559
|
key: "_applyAction",
|
|
28560
28560
|
value: function _applyAction(object, propertyPath, value) {
|
|
28561
|
+
var relative = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
28561
28562
|
if (!object || typeof propertyPath !== 'string') return;
|
|
28562
28563
|
var parts = propertyPath.split('.');
|
|
28563
28564
|
|
|
@@ -28583,6 +28584,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
28583
28584
|
return;
|
|
28584
28585
|
}
|
|
28585
28586
|
|
|
28587
|
+
// If relative, capture the mesh's original value on first execution and offset from it.
|
|
28588
|
+
if (relative) {
|
|
28589
|
+
var baselineKey = "_baseline_".concat(propertyPath.replace(/\./g, '_'));
|
|
28590
|
+
if (!(baselineKey in object.userData)) {
|
|
28591
|
+
object.userData[baselineKey] = target[lastKey];
|
|
28592
|
+
}
|
|
28593
|
+
value = object.userData[baselineKey] + parseFloat(value);
|
|
28594
|
+
}
|
|
28595
|
+
|
|
28586
28596
|
// THREE.Color objects must be mutated via .set() rather than replaced
|
|
28587
28597
|
var existing = target[lastKey];
|
|
28588
28598
|
if (existing && existing.isColor && typeof value === 'string') {
|
|
@@ -28635,7 +28645,7 @@ function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
|
28635
28645
|
}
|
|
28636
28646
|
function _attachIODevicesToComponent() {
|
|
28637
28647
|
_attachIODevicesToComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(componentModel, componentData, modelPreloader, parentComponentId) {
|
|
28638
|
-
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;
|
|
28648
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t, _t2;
|
|
28639
28649
|
return _regenerator().w(function (_context) {
|
|
28640
28650
|
while (1) switch (_context.n) {
|
|
28641
28651
|
case 0:
|
|
@@ -28736,6 +28746,13 @@ function _attachIODevicesToComponent() {
|
|
|
28736
28746
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
28737
28747
|
}
|
|
28738
28748
|
|
|
28749
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
28750
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
28751
|
+
rot = attachment.attachmentPoint.rotation;
|
|
28752
|
+
deg2rad = Math.PI / 180;
|
|
28753
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
28754
|
+
}
|
|
28755
|
+
|
|
28739
28756
|
// IO device models are authored at the same real-world unit scale
|
|
28740
28757
|
// as the host component, so keep them at their natural (1:1) size.
|
|
28741
28758
|
// Note: attachmentPoint.scale is the connector marker sphere size,
|
|
@@ -32575,7 +32592,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
32575
32592
|
key: "_attachIODeviceModelsToPreview",
|
|
32576
32593
|
value: (function () {
|
|
32577
32594
|
var _attachIODeviceModelsToPreview2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(parentObject, componentData, modelPreloader) {
|
|
32578
|
-
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t3;
|
|
32595
|
+
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t3;
|
|
32579
32596
|
return _regenerator().w(function (_context3) {
|
|
32580
32597
|
while (1) switch (_context3.n) {
|
|
32581
32598
|
case 0:
|
|
@@ -32650,6 +32667,13 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
32650
32667
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
32651
32668
|
}
|
|
32652
32669
|
|
|
32670
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
32671
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
32672
|
+
rot = attachment.attachmentPoint.rotation;
|
|
32673
|
+
deg2rad = Math.PI / 180;
|
|
32674
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
32675
|
+
}
|
|
32676
|
+
|
|
32653
32677
|
// IO device models use their natural (1:1) scale — the stored
|
|
32654
32678
|
// attachmentPoint.scale value is for the connector marker sphere.
|
|
32655
32679
|
deviceModel.scale.setScalar(1);
|
|
@@ -37214,7 +37238,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37214
37238
|
* Initialize the CentralPlant manager
|
|
37215
37239
|
*
|
|
37216
37240
|
* @constructor
|
|
37217
|
-
* @version 0.2.
|
|
37241
|
+
* @version 0.2.5
|
|
37218
37242
|
* @updated 2025-10-22
|
|
37219
37243
|
*
|
|
37220
37244
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -38248,6 +38272,69 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38248
38272
|
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
38249
38273
|
}
|
|
38250
38274
|
|
|
38275
|
+
/**
|
|
38276
|
+
* Set the state of an I/O device instance in the Three.js scene.
|
|
38277
|
+
*
|
|
38278
|
+
* This is the primary public API for driving IO device state changes from
|
|
38279
|
+
* external code (real-time data feeds, AI agents, automated tests, etc.).
|
|
38280
|
+
* It performs three coordinated actions in order:
|
|
38281
|
+
* 1. Persists the new value through the state adapter (Vuex in sandbox,
|
|
38282
|
+
* or any custom adapter injected via componentTooltipManager.configure())
|
|
38283
|
+
* so that the host application's store stays consistent.
|
|
38284
|
+
* 2. Evaluates all behaviors whose input matches this (attachmentId, stateId)
|
|
38285
|
+
* pair and applies the resulting property changes to Three.js meshes.
|
|
38286
|
+
* 3. Emits an 'io-device-state-changed' event on the sceneViewer so that
|
|
38287
|
+
* host applications without a Vuex store (e.g. cp3d-viewer) can react.
|
|
38288
|
+
*
|
|
38289
|
+
* @param {string} attachmentId - The attachment ID of the IO device (matches
|
|
38290
|
+
* the `attachmentId` stored in the Three.js object's userData)
|
|
38291
|
+
* @param {string} stateId - The data-point / state ID on the device (e.g. 'power', 'level')
|
|
38292
|
+
* @param {*} value - The new state value (boolean, number, string, etc.)
|
|
38293
|
+
* @param {string} [parentUuid] - UUID of the parent component instance.
|
|
38294
|
+
* Required when multiple instances of the same smart component share the
|
|
38295
|
+
* same attachmentId — prevents cross-instance state bleed.
|
|
38296
|
+
* @returns {boolean} True if the behavior system was reached; false if unavailable.
|
|
38297
|
+
* @example
|
|
38298
|
+
* // Toggle a push-button on a specific pump instance
|
|
38299
|
+
* centralPlant.setIoDeviceState('pump-push-button-01', 'power', true, pumpUuid)
|
|
38300
|
+
*
|
|
38301
|
+
* // Drive an analog level sensor (no parentUuid needed when only one instance)
|
|
38302
|
+
* centralPlant.setIoDeviceState('chiller-level-sensor-01', 'level', 0.75)
|
|
38303
|
+
*/
|
|
38304
|
+
}, {
|
|
38305
|
+
key: "setIoDeviceState",
|
|
38306
|
+
value: function setIoDeviceState(attachmentId, stateId, value, parentUuid) {
|
|
38307
|
+
var _this$sceneViewer0, _this$sceneViewer1, _this$sceneViewer10;
|
|
38308
|
+
var bm = (_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 || (_this$sceneViewer0 = _this$sceneViewer0.managers) === null || _this$sceneViewer0 === void 0 ? void 0 : _this$sceneViewer0.behaviorManager;
|
|
38309
|
+
if (!bm) {
|
|
38310
|
+
console.warn('⚠️ setIoDeviceState(): BehaviorManager not available');
|
|
38311
|
+
return false;
|
|
38312
|
+
}
|
|
38313
|
+
|
|
38314
|
+
// 1. Persist via state adapter if one has been configured
|
|
38315
|
+
var stateAdapter = (_this$sceneViewer1 = this.sceneViewer) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.managers) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.componentTooltipManager) === null || _this$sceneViewer1 === void 0 ? void 0 : _this$sceneViewer1._stateAdapter;
|
|
38316
|
+
if (stateAdapter !== null && stateAdapter !== void 0 && stateAdapter.setState) {
|
|
38317
|
+
var scopedKey = parentUuid ? "".concat(parentUuid, "::").concat(attachmentId) : attachmentId;
|
|
38318
|
+
try {
|
|
38319
|
+
stateAdapter.setState(scopedKey, stateId, value);
|
|
38320
|
+
} catch (err) {
|
|
38321
|
+
console.warn('⚠️ setIoDeviceState(): stateAdapter.setState() threw:', err);
|
|
38322
|
+
}
|
|
38323
|
+
}
|
|
38324
|
+
|
|
38325
|
+
// 2. Apply Three.js behavior changes
|
|
38326
|
+
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
38327
|
+
|
|
38328
|
+
// 3. Emit event for host apps that don't use the state adapter (e.g. cp3d-viewer)
|
|
38329
|
+
(_this$sceneViewer10 = this.sceneViewer) === null || _this$sceneViewer10 === void 0 || _this$sceneViewer10.emit('io-device-state-changed', {
|
|
38330
|
+
attachmentId: attachmentId,
|
|
38331
|
+
stateId: stateId,
|
|
38332
|
+
value: value,
|
|
38333
|
+
parentUuid: parentUuid || null
|
|
38334
|
+
});
|
|
38335
|
+
return true;
|
|
38336
|
+
}
|
|
38337
|
+
|
|
38251
38338
|
/**
|
|
38252
38339
|
* Return all io-device attachments present in the current Three.js scene.
|
|
38253
38340
|
* Each entry carries the attachmentId, an optional label, and the parent
|
|
@@ -38261,8 +38348,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38261
38348
|
}, {
|
|
38262
38349
|
key: "getSceneAttachments",
|
|
38263
38350
|
value: function getSceneAttachments() {
|
|
38264
|
-
var _this$
|
|
38265
|
-
var scene = (_this$
|
|
38351
|
+
var _this$sceneViewer11;
|
|
38352
|
+
var scene = (_this$sceneViewer11 = this.sceneViewer) === null || _this$sceneViewer11 === void 0 ? void 0 : _this$sceneViewer11.scene;
|
|
38266
38353
|
if (!scene) return [];
|
|
38267
38354
|
var results = [];
|
|
38268
38355
|
scene.traverse(function (obj) {
|
|
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19
19
|
* Initialize the CentralPlant manager
|
|
20
20
|
*
|
|
21
21
|
* @constructor
|
|
22
|
-
* @version 0.2.
|
|
22
|
+
* @version 0.2.5
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -1053,6 +1053,69 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1053
1053
|
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
1054
1054
|
}
|
|
1055
1055
|
|
|
1056
|
+
/**
|
|
1057
|
+
* Set the state of an I/O device instance in the Three.js scene.
|
|
1058
|
+
*
|
|
1059
|
+
* This is the primary public API for driving IO device state changes from
|
|
1060
|
+
* external code (real-time data feeds, AI agents, automated tests, etc.).
|
|
1061
|
+
* It performs three coordinated actions in order:
|
|
1062
|
+
* 1. Persists the new value through the state adapter (Vuex in sandbox,
|
|
1063
|
+
* or any custom adapter injected via componentTooltipManager.configure())
|
|
1064
|
+
* so that the host application's store stays consistent.
|
|
1065
|
+
* 2. Evaluates all behaviors whose input matches this (attachmentId, stateId)
|
|
1066
|
+
* pair and applies the resulting property changes to Three.js meshes.
|
|
1067
|
+
* 3. Emits an 'io-device-state-changed' event on the sceneViewer so that
|
|
1068
|
+
* host applications without a Vuex store (e.g. cp3d-viewer) can react.
|
|
1069
|
+
*
|
|
1070
|
+
* @param {string} attachmentId - The attachment ID of the IO device (matches
|
|
1071
|
+
* the `attachmentId` stored in the Three.js object's userData)
|
|
1072
|
+
* @param {string} stateId - The data-point / state ID on the device (e.g. 'power', 'level')
|
|
1073
|
+
* @param {*} value - The new state value (boolean, number, string, etc.)
|
|
1074
|
+
* @param {string} [parentUuid] - UUID of the parent component instance.
|
|
1075
|
+
* Required when multiple instances of the same smart component share the
|
|
1076
|
+
* same attachmentId — prevents cross-instance state bleed.
|
|
1077
|
+
* @returns {boolean} True if the behavior system was reached; false if unavailable.
|
|
1078
|
+
* @example
|
|
1079
|
+
* // Toggle a push-button on a specific pump instance
|
|
1080
|
+
* centralPlant.setIoDeviceState('pump-push-button-01', 'power', true, pumpUuid)
|
|
1081
|
+
*
|
|
1082
|
+
* // Drive an analog level sensor (no parentUuid needed when only one instance)
|
|
1083
|
+
* centralPlant.setIoDeviceState('chiller-level-sensor-01', 'level', 0.75)
|
|
1084
|
+
*/
|
|
1085
|
+
}, {
|
|
1086
|
+
key: "setIoDeviceState",
|
|
1087
|
+
value: function setIoDeviceState(attachmentId, stateId, value, parentUuid) {
|
|
1088
|
+
var _this$sceneViewer0, _this$sceneViewer1, _this$sceneViewer10;
|
|
1089
|
+
var bm = (_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 || (_this$sceneViewer0 = _this$sceneViewer0.managers) === null || _this$sceneViewer0 === void 0 ? void 0 : _this$sceneViewer0.behaviorManager;
|
|
1090
|
+
if (!bm) {
|
|
1091
|
+
console.warn('⚠️ setIoDeviceState(): BehaviorManager not available');
|
|
1092
|
+
return false;
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
// 1. Persist via state adapter if one has been configured
|
|
1096
|
+
var stateAdapter = (_this$sceneViewer1 = this.sceneViewer) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.managers) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.componentTooltipManager) === null || _this$sceneViewer1 === void 0 ? void 0 : _this$sceneViewer1._stateAdapter;
|
|
1097
|
+
if (stateAdapter !== null && stateAdapter !== void 0 && stateAdapter.setState) {
|
|
1098
|
+
var scopedKey = parentUuid ? "".concat(parentUuid, "::").concat(attachmentId) : attachmentId;
|
|
1099
|
+
try {
|
|
1100
|
+
stateAdapter.setState(scopedKey, stateId, value);
|
|
1101
|
+
} catch (err) {
|
|
1102
|
+
console.warn('⚠️ setIoDeviceState(): stateAdapter.setState() threw:', err);
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// 2. Apply Three.js behavior changes
|
|
1107
|
+
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
1108
|
+
|
|
1109
|
+
// 3. Emit event for host apps that don't use the state adapter (e.g. cp3d-viewer)
|
|
1110
|
+
(_this$sceneViewer10 = this.sceneViewer) === null || _this$sceneViewer10 === void 0 || _this$sceneViewer10.emit('io-device-state-changed', {
|
|
1111
|
+
attachmentId: attachmentId,
|
|
1112
|
+
stateId: stateId,
|
|
1113
|
+
value: value,
|
|
1114
|
+
parentUuid: parentUuid || null
|
|
1115
|
+
});
|
|
1116
|
+
return true;
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1056
1119
|
/**
|
|
1057
1120
|
* Return all io-device attachments present in the current Three.js scene.
|
|
1058
1121
|
* Each entry carries the attachmentId, an optional label, and the parent
|
|
@@ -1066,8 +1129,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1066
1129
|
}, {
|
|
1067
1130
|
key: "getSceneAttachments",
|
|
1068
1131
|
value: function getSceneAttachments() {
|
|
1069
|
-
var _this$
|
|
1070
|
-
var scene = (_this$
|
|
1132
|
+
var _this$sceneViewer11;
|
|
1133
|
+
var scene = (_this$sceneViewer11 = this.sceneViewer) === null || _this$sceneViewer11 === void 0 ? void 0 : _this$sceneViewer11.scene;
|
|
1071
1134
|
if (!scene) return [];
|
|
1072
1135
|
var results = [];
|
|
1073
1136
|
scene.traverse(function (obj) {
|
|
@@ -264,7 +264,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
264
264
|
if (_this4._testCondition(condition.when, value)) {
|
|
265
265
|
if (Array.isArray(condition.actions)) {
|
|
266
266
|
condition.actions.forEach(function (action) {
|
|
267
|
-
_this4._applyAction(output, action.set, action.value);
|
|
267
|
+
_this4._applyAction(output, action.set, action.value, action.relative === true);
|
|
268
268
|
});
|
|
269
269
|
}
|
|
270
270
|
}
|
|
@@ -342,6 +342,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
342
342
|
}, {
|
|
343
343
|
key: "_applyAction",
|
|
344
344
|
value: function _applyAction(object, propertyPath, value) {
|
|
345
|
+
var relative = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
345
346
|
if (!object || typeof propertyPath !== 'string') return;
|
|
346
347
|
var parts = propertyPath.split('.');
|
|
347
348
|
|
|
@@ -367,6 +368,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
367
368
|
return;
|
|
368
369
|
}
|
|
369
370
|
|
|
371
|
+
// If relative, capture the mesh's original value on first execution and offset from it.
|
|
372
|
+
if (relative) {
|
|
373
|
+
var baselineKey = "_baseline_".concat(propertyPath.replace(/\./g, '_'));
|
|
374
|
+
if (!(baselineKey in object.userData)) {
|
|
375
|
+
object.userData[baselineKey] = target[lastKey];
|
|
376
|
+
}
|
|
377
|
+
value = object.userData[baselineKey] + parseFloat(value);
|
|
378
|
+
}
|
|
379
|
+
|
|
370
380
|
// THREE.Color objects must be mutated via .set() rather than replaced
|
|
371
381
|
var existing = target[lastKey];
|
|
372
382
|
if (existing && existing.isColor && typeof value === 'string') {
|
|
@@ -345,7 +345,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
345
345
|
key: "_attachIODeviceModelsToPreview",
|
|
346
346
|
value: (function () {
|
|
347
347
|
var _attachIODeviceModelsToPreview2 = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee3(parentObject, componentData, modelPreloader) {
|
|
348
|
-
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t3;
|
|
348
|
+
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t3;
|
|
349
349
|
return _rollupPluginBabelHelpers.regenerator().w(function (_context3) {
|
|
350
350
|
while (1) switch (_context3.n) {
|
|
351
351
|
case 0:
|
|
@@ -420,6 +420,13 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
420
420
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
424
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
425
|
+
rot = attachment.attachmentPoint.rotation;
|
|
426
|
+
deg2rad = Math.PI / 180;
|
|
427
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
428
|
+
}
|
|
429
|
+
|
|
423
430
|
// IO device models use their natural (1:1) scale — the stored
|
|
424
431
|
// attachmentPoint.scale value is for the connector marker sphere.
|
|
425
432
|
deviceModel.scale.setScalar(1);
|
|
@@ -27,7 +27,7 @@ function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
|
27
27
|
}
|
|
28
28
|
function _attachIODevicesToComponent() {
|
|
29
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;
|
|
30
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t, _t2;
|
|
31
31
|
return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
|
|
32
32
|
while (1) switch (_context.n) {
|
|
33
33
|
case 0:
|
|
@@ -128,6 +128,13 @@ function _attachIODevicesToComponent() {
|
|
|
128
128
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
132
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
133
|
+
rot = attachment.attachmentPoint.rotation;
|
|
134
|
+
deg2rad = Math.PI / 180;
|
|
135
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
136
|
+
}
|
|
137
|
+
|
|
131
138
|
// IO device models are authored at the same real-world unit scale
|
|
132
139
|
// as the host component, so keep them at their natural (1:1) size.
|
|
133
140
|
// Note: attachmentPoint.scale is the connector marker sphere size,
|
|
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
15
15
|
* Initialize the CentralPlant manager
|
|
16
16
|
*
|
|
17
17
|
* @constructor
|
|
18
|
-
* @version 0.2.
|
|
18
|
+
* @version 0.2.5
|
|
19
19
|
* @updated 2025-10-22
|
|
20
20
|
*
|
|
21
21
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -1049,6 +1049,69 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1049
1049
|
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
1050
1050
|
}
|
|
1051
1051
|
|
|
1052
|
+
/**
|
|
1053
|
+
* Set the state of an I/O device instance in the Three.js scene.
|
|
1054
|
+
*
|
|
1055
|
+
* This is the primary public API for driving IO device state changes from
|
|
1056
|
+
* external code (real-time data feeds, AI agents, automated tests, etc.).
|
|
1057
|
+
* It performs three coordinated actions in order:
|
|
1058
|
+
* 1. Persists the new value through the state adapter (Vuex in sandbox,
|
|
1059
|
+
* or any custom adapter injected via componentTooltipManager.configure())
|
|
1060
|
+
* so that the host application's store stays consistent.
|
|
1061
|
+
* 2. Evaluates all behaviors whose input matches this (attachmentId, stateId)
|
|
1062
|
+
* pair and applies the resulting property changes to Three.js meshes.
|
|
1063
|
+
* 3. Emits an 'io-device-state-changed' event on the sceneViewer so that
|
|
1064
|
+
* host applications without a Vuex store (e.g. cp3d-viewer) can react.
|
|
1065
|
+
*
|
|
1066
|
+
* @param {string} attachmentId - The attachment ID of the IO device (matches
|
|
1067
|
+
* the `attachmentId` stored in the Three.js object's userData)
|
|
1068
|
+
* @param {string} stateId - The data-point / state ID on the device (e.g. 'power', 'level')
|
|
1069
|
+
* @param {*} value - The new state value (boolean, number, string, etc.)
|
|
1070
|
+
* @param {string} [parentUuid] - UUID of the parent component instance.
|
|
1071
|
+
* Required when multiple instances of the same smart component share the
|
|
1072
|
+
* same attachmentId — prevents cross-instance state bleed.
|
|
1073
|
+
* @returns {boolean} True if the behavior system was reached; false if unavailable.
|
|
1074
|
+
* @example
|
|
1075
|
+
* // Toggle a push-button on a specific pump instance
|
|
1076
|
+
* centralPlant.setIoDeviceState('pump-push-button-01', 'power', true, pumpUuid)
|
|
1077
|
+
*
|
|
1078
|
+
* // Drive an analog level sensor (no parentUuid needed when only one instance)
|
|
1079
|
+
* centralPlant.setIoDeviceState('chiller-level-sensor-01', 'level', 0.75)
|
|
1080
|
+
*/
|
|
1081
|
+
}, {
|
|
1082
|
+
key: "setIoDeviceState",
|
|
1083
|
+
value: function setIoDeviceState(attachmentId, stateId, value, parentUuid) {
|
|
1084
|
+
var _this$sceneViewer0, _this$sceneViewer1, _this$sceneViewer10;
|
|
1085
|
+
var bm = (_this$sceneViewer0 = this.sceneViewer) === null || _this$sceneViewer0 === void 0 || (_this$sceneViewer0 = _this$sceneViewer0.managers) === null || _this$sceneViewer0 === void 0 ? void 0 : _this$sceneViewer0.behaviorManager;
|
|
1086
|
+
if (!bm) {
|
|
1087
|
+
console.warn('⚠️ setIoDeviceState(): BehaviorManager not available');
|
|
1088
|
+
return false;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// 1. Persist via state adapter if one has been configured
|
|
1092
|
+
var stateAdapter = (_this$sceneViewer1 = this.sceneViewer) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.managers) === null || _this$sceneViewer1 === void 0 || (_this$sceneViewer1 = _this$sceneViewer1.componentTooltipManager) === null || _this$sceneViewer1 === void 0 ? void 0 : _this$sceneViewer1._stateAdapter;
|
|
1093
|
+
if (stateAdapter !== null && stateAdapter !== void 0 && stateAdapter.setState) {
|
|
1094
|
+
var scopedKey = parentUuid ? "".concat(parentUuid, "::").concat(attachmentId) : attachmentId;
|
|
1095
|
+
try {
|
|
1096
|
+
stateAdapter.setState(scopedKey, stateId, value);
|
|
1097
|
+
} catch (err) {
|
|
1098
|
+
console.warn('⚠️ setIoDeviceState(): stateAdapter.setState() threw:', err);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
// 2. Apply Three.js behavior changes
|
|
1103
|
+
bm.triggerState(attachmentId, stateId, value, parentUuid);
|
|
1104
|
+
|
|
1105
|
+
// 3. Emit event for host apps that don't use the state adapter (e.g. cp3d-viewer)
|
|
1106
|
+
(_this$sceneViewer10 = this.sceneViewer) === null || _this$sceneViewer10 === void 0 || _this$sceneViewer10.emit('io-device-state-changed', {
|
|
1107
|
+
attachmentId: attachmentId,
|
|
1108
|
+
stateId: stateId,
|
|
1109
|
+
value: value,
|
|
1110
|
+
parentUuid: parentUuid || null
|
|
1111
|
+
});
|
|
1112
|
+
return true;
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1052
1115
|
/**
|
|
1053
1116
|
* Return all io-device attachments present in the current Three.js scene.
|
|
1054
1117
|
* Each entry carries the attachmentId, an optional label, and the parent
|
|
@@ -1062,8 +1125,8 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1062
1125
|
}, {
|
|
1063
1126
|
key: "getSceneAttachments",
|
|
1064
1127
|
value: function getSceneAttachments() {
|
|
1065
|
-
var _this$
|
|
1066
|
-
var scene = (_this$
|
|
1128
|
+
var _this$sceneViewer11;
|
|
1129
|
+
var scene = (_this$sceneViewer11 = this.sceneViewer) === null || _this$sceneViewer11 === void 0 ? void 0 : _this$sceneViewer11.scene;
|
|
1067
1130
|
if (!scene) return [];
|
|
1068
1131
|
var results = [];
|
|
1069
1132
|
scene.traverse(function (obj) {
|
|
@@ -260,7 +260,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
260
260
|
if (_this4._testCondition(condition.when, value)) {
|
|
261
261
|
if (Array.isArray(condition.actions)) {
|
|
262
262
|
condition.actions.forEach(function (action) {
|
|
263
|
-
_this4._applyAction(output, action.set, action.value);
|
|
263
|
+
_this4._applyAction(output, action.set, action.value, action.relative === true);
|
|
264
264
|
});
|
|
265
265
|
}
|
|
266
266
|
}
|
|
@@ -338,6 +338,7 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
338
338
|
}, {
|
|
339
339
|
key: "_applyAction",
|
|
340
340
|
value: function _applyAction(object, propertyPath, value) {
|
|
341
|
+
var relative = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
|
|
341
342
|
if (!object || typeof propertyPath !== 'string') return;
|
|
342
343
|
var parts = propertyPath.split('.');
|
|
343
344
|
|
|
@@ -363,6 +364,15 @@ var BehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
363
364
|
return;
|
|
364
365
|
}
|
|
365
366
|
|
|
367
|
+
// If relative, capture the mesh's original value on first execution and offset from it.
|
|
368
|
+
if (relative) {
|
|
369
|
+
var baselineKey = "_baseline_".concat(propertyPath.replace(/\./g, '_'));
|
|
370
|
+
if (!(baselineKey in object.userData)) {
|
|
371
|
+
object.userData[baselineKey] = target[lastKey];
|
|
372
|
+
}
|
|
373
|
+
value = object.userData[baselineKey] + parseFloat(value);
|
|
374
|
+
}
|
|
375
|
+
|
|
366
376
|
// THREE.Color objects must be mutated via .set() rather than replaced
|
|
367
377
|
var existing = target[lastKey];
|
|
368
378
|
if (existing && existing.isColor && typeof value === 'string') {
|
|
@@ -321,7 +321,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
321
321
|
key: "_attachIODeviceModelsToPreview",
|
|
322
322
|
value: (function () {
|
|
323
323
|
var _attachIODeviceModelsToPreview2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(parentObject, componentData, modelPreloader) {
|
|
324
|
-
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, _t3;
|
|
324
|
+
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t3;
|
|
325
325
|
return _regenerator().w(function (_context3) {
|
|
326
326
|
while (1) switch (_context3.n) {
|
|
327
327
|
case 0:
|
|
@@ -396,6 +396,13 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
396
396
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
397
397
|
}
|
|
398
398
|
|
|
399
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
400
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
401
|
+
rot = attachment.attachmentPoint.rotation;
|
|
402
|
+
deg2rad = Math.PI / 180;
|
|
403
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
404
|
+
}
|
|
405
|
+
|
|
399
406
|
// IO device models use their natural (1:1) scale — the stored
|
|
400
407
|
// attachmentPoint.scale value is for the connector marker sphere.
|
|
401
408
|
deviceModel.scale.setScalar(1);
|
|
@@ -23,7 +23,7 @@ function attachIODevicesToComponent(_x, _x2, _x3, _x4) {
|
|
|
23
23
|
}
|
|
24
24
|
function _attachIODevicesToComponent() {
|
|
25
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;
|
|
26
|
+
var attachedDevices, _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _deviceData$ioConfig, _deviceData$ioConfig2, _deviceData$ioConfig3, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t, _t2;
|
|
27
27
|
return _regenerator().w(function (_context) {
|
|
28
28
|
while (1) switch (_context.n) {
|
|
29
29
|
case 0:
|
|
@@ -124,6 +124,13 @@ function _attachIODevicesToComponent() {
|
|
|
124
124
|
deviceModel.position.set(pos.x || 0, pos.y || 0, pos.z || 0);
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
+
// Apply face-based rotation (stored in degrees, XYZ Euler order)
|
|
128
|
+
if ((_attachment$attachmen2 = attachment.attachmentPoint) !== null && _attachment$attachmen2 !== void 0 && _attachment$attachmen2.rotation) {
|
|
129
|
+
rot = attachment.attachmentPoint.rotation;
|
|
130
|
+
deg2rad = Math.PI / 180;
|
|
131
|
+
deviceModel.rotation.set((rot.x || 0) * deg2rad, (rot.y || 0) * deg2rad, (rot.z || 0) * deg2rad, 'XYZ');
|
|
132
|
+
}
|
|
133
|
+
|
|
127
134
|
// IO device models are authored at the same real-world unit scale
|
|
128
135
|
// as the host component, so keep them at their natural (1:1) size.
|
|
129
136
|
// Note: attachmentPoint.scale is the connector marker sphere size,
|