@2112-lab/central-plant 0.3.25 → 0.3.27
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 +948 -137
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/core/centralPlantInternals.js +56 -14
- package/dist/cjs/src/core/sceneViewer.js +55 -2
- package/dist/cjs/src/managers/behaviors/IoAnimationManager.js +29 -2
- package/dist/cjs/src/managers/behaviors/IoOutlineManager.js +258 -0
- package/dist/cjs/src/managers/controls/transformControlsManager.js +319 -43
- package/dist/cjs/src/managers/scene/animationManager.js +9 -2
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +198 -31
- package/dist/cjs/src/managers/scene/modelManager.js +17 -2
- package/dist/cjs/src/utils/boundingBoxUtils.js +38 -40
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/core/centralPlantInternals.js +57 -15
- package/dist/esm/src/core/sceneViewer.js +55 -2
- package/dist/esm/src/managers/behaviors/IoAnimationManager.js +29 -2
- package/dist/esm/src/managers/behaviors/IoOutlineManager.js +234 -0
- package/dist/esm/src/managers/controls/transformControlsManager.js +319 -43
- package/dist/esm/src/managers/scene/animationManager.js +9 -2
- package/dist/esm/src/managers/scene/componentTooltipManager.js +199 -32
- package/dist/esm/src/managers/scene/modelManager.js +18 -3
- package/dist/esm/src/utils/boundingBoxUtils.js +39 -42
- package/package.json +1 -1
|
@@ -168,6 +168,169 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
168
168
|
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
// ── IO device drag-to-state ─────────────────────────────────────────────
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Begin tracking a drag gesture on an IO device mesh.
|
|
175
|
+
* Records the initial state of each animation data point so that
|
|
176
|
+
* `updateIODeviceDrag` can compute relative offsets from it.
|
|
177
|
+
*
|
|
178
|
+
* @param {THREE.Object3D} ioDeviceObject
|
|
179
|
+
*/
|
|
180
|
+
}, {
|
|
181
|
+
key: "startIODeviceDrag",
|
|
182
|
+
value: function startIODeviceDrag(ioDeviceObject) {
|
|
183
|
+
var _this$sceneViewer3,
|
|
184
|
+
_this2 = this;
|
|
185
|
+
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
186
|
+
var ud = ioDeviceObject.userData;
|
|
187
|
+
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
188
|
+
if (!attachmentId) return;
|
|
189
|
+
var parentUuid = null;
|
|
190
|
+
var obj = ioDeviceObject.parent;
|
|
191
|
+
while (obj) {
|
|
192
|
+
var _obj$userData2;
|
|
193
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'component') {
|
|
194
|
+
parentUuid = obj.uuid;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
obj = obj.parent;
|
|
198
|
+
}
|
|
199
|
+
var scopedAttachmentId = this._getScopedAttachmentKey(attachmentId, parentUuid);
|
|
200
|
+
var ioAnimMgr = (_this$sceneViewer3 = this.sceneViewer) === null || _this$sceneViewer3 === void 0 || (_this$sceneViewer3 = _this$sceneViewer3.managers) === null || _this$sceneViewer3 === void 0 ? void 0 : _this$sceneViewer3.ioAnimationManager;
|
|
201
|
+
var dataPoints = ((ioAnimMgr === null || ioAnimMgr === void 0 ? void 0 : ioAnimMgr.getAnimationDataPoints(parentUuid, attachmentId)) || []).concat((ud === null || ud === void 0 ? void 0 : ud.dataPoints) || [])
|
|
202
|
+
// deduplicate by id
|
|
203
|
+
.filter(function (dp, i, arr) {
|
|
204
|
+
return arr.findIndex(function (d) {
|
|
205
|
+
return d.id === dp.id;
|
|
206
|
+
}) === i;
|
|
207
|
+
});
|
|
208
|
+
var dpSessions = [];
|
|
209
|
+
var _iterator = _rollupPluginBabelHelpers.createForOfIteratorHelper(dataPoints),
|
|
210
|
+
_step;
|
|
211
|
+
try {
|
|
212
|
+
var _loop = function _loop() {
|
|
213
|
+
var _this2$_stateAdapter$;
|
|
214
|
+
var dp = _step.value;
|
|
215
|
+
var stateType = (dp.stateType || '').toLowerCase();
|
|
216
|
+
if (stateType !== 'binary' && stateType !== 'boolean' && stateType !== 'enum') return 1; // continue
|
|
217
|
+
var curVal = (_this2$_stateAdapter$ = _this2._stateAdapter.getState(scopedAttachmentId, dp.id)) !== null && _this2$_stateAdapter$ !== void 0 ? _this2$_stateAdapter$ : dp.defaultValue;
|
|
218
|
+
if (stateType === 'binary' || stateType === 'boolean') {
|
|
219
|
+
dpSessions.push({
|
|
220
|
+
dp: dp,
|
|
221
|
+
scopedAttachmentId: scopedAttachmentId,
|
|
222
|
+
attachmentId: attachmentId,
|
|
223
|
+
parentUuid: parentUuid,
|
|
224
|
+
stateType: 'binary',
|
|
225
|
+
lastApplied: curVal
|
|
226
|
+
});
|
|
227
|
+
} else {
|
|
228
|
+
var _dp$stateConfig;
|
|
229
|
+
var opts = ((_dp$stateConfig = dp.stateConfig) === null || _dp$stateConfig === void 0 ? void 0 : _dp$stateConfig.options) || [];
|
|
230
|
+
var curIdx = opts.findIndex(function (o) {
|
|
231
|
+
return String(o) === String(curVal);
|
|
232
|
+
});
|
|
233
|
+
dpSessions.push({
|
|
234
|
+
dp: dp,
|
|
235
|
+
scopedAttachmentId: scopedAttachmentId,
|
|
236
|
+
attachmentId: attachmentId,
|
|
237
|
+
parentUuid: parentUuid,
|
|
238
|
+
stateType: 'enum',
|
|
239
|
+
opts: opts,
|
|
240
|
+
startIdx: curIdx >= 0 ? curIdx : 0,
|
|
241
|
+
lastAppliedIdx: curIdx >= 0 ? curIdx : 0
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
246
|
+
if (_loop()) continue;
|
|
247
|
+
}
|
|
248
|
+
} catch (err) {
|
|
249
|
+
_iterator.e(err);
|
|
250
|
+
} finally {
|
|
251
|
+
_iterator.f();
|
|
252
|
+
}
|
|
253
|
+
this._ioDragSession = dpSessions.length ? {
|
|
254
|
+
dpSessions: dpSessions
|
|
255
|
+
} : null;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Update animated mesh state while a drag is in progress.
|
|
260
|
+
* Called continuously during pointermove.
|
|
261
|
+
*
|
|
262
|
+
* Sign convention: up/right = positive `signedDelta`.
|
|
263
|
+
* - Binary: > +20 px → true/on state, < −20 px → false/off state.
|
|
264
|
+
* - Enum: each ±30 px step advances/retreats one option in the list.
|
|
265
|
+
*
|
|
266
|
+
* @param {number} signedDelta - Cumulative signed pixel displacement since drag start
|
|
267
|
+
*/
|
|
268
|
+
}, {
|
|
269
|
+
key: "updateIODeviceDrag",
|
|
270
|
+
value: function updateIODeviceDrag(signedDelta) {
|
|
271
|
+
var session = this._ioDragSession;
|
|
272
|
+
if (!session) return;
|
|
273
|
+
var BINARY_THRESHOLD = 20;
|
|
274
|
+
var ENUM_STEP_PX = 30;
|
|
275
|
+
var _iterator2 = _rollupPluginBabelHelpers.createForOfIteratorHelper(session.dpSessions),
|
|
276
|
+
_step2;
|
|
277
|
+
try {
|
|
278
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
279
|
+
var dps = _step2.value;
|
|
280
|
+
if (dps.stateType === 'binary') {
|
|
281
|
+
var newVal = void 0;
|
|
282
|
+
if (signedDelta > BINARY_THRESHOLD) {
|
|
283
|
+
newVal = true;
|
|
284
|
+
} else if (signedDelta < -BINARY_THRESHOLD) {
|
|
285
|
+
newVal = false;
|
|
286
|
+
} else {
|
|
287
|
+
continue; // dead zone
|
|
288
|
+
}
|
|
289
|
+
if (newVal === dps.lastApplied) continue;
|
|
290
|
+
dps.lastApplied = newVal;
|
|
291
|
+
this._applyDpState(dps, newVal);
|
|
292
|
+
} else if (dps.stateType === 'enum') {
|
|
293
|
+
var steps = Math.round(signedDelta / ENUM_STEP_PX);
|
|
294
|
+
var newIdx = Math.max(0, Math.min(dps.opts.length - 1, dps.startIdx + steps));
|
|
295
|
+
if (newIdx === dps.lastAppliedIdx) continue;
|
|
296
|
+
dps.lastAppliedIdx = newIdx;
|
|
297
|
+
this._applyDpState(dps, dps.opts[newIdx]);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
} catch (err) {
|
|
301
|
+
_iterator2.e(err);
|
|
302
|
+
} finally {
|
|
303
|
+
_iterator2.f();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Clean up drag session state on pointerup.
|
|
309
|
+
*/
|
|
310
|
+
}, {
|
|
311
|
+
key: "endIODeviceDrag",
|
|
312
|
+
value: function endIODeviceDrag() {
|
|
313
|
+
this._ioDragSession = null;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Apply a new value to a data point, updating Vuex state and firing behavior/animation triggers.
|
|
318
|
+
* @private
|
|
319
|
+
*/
|
|
320
|
+
}, {
|
|
321
|
+
key: "_applyDpState",
|
|
322
|
+
value: function _applyDpState(_ref2, newVal) {
|
|
323
|
+
var _this$_stateAdapter, _this$sceneViewer4, _this$sceneViewer5;
|
|
324
|
+
var scopedAttachmentId = _ref2.scopedAttachmentId,
|
|
325
|
+
attachmentId = _ref2.attachmentId,
|
|
326
|
+
parentUuid = _ref2.parentUuid,
|
|
327
|
+
dp = _ref2.dp;
|
|
328
|
+
var dpId = dp.id;
|
|
329
|
+
(_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 || _this$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
330
|
+
(_this$sceneViewer4 = this.sceneViewer) === null || _this$sceneViewer4 === void 0 || (_this$sceneViewer4 = _this$sceneViewer4.managers) === null || _this$sceneViewer4 === void 0 || (_this$sceneViewer4 = _this$sceneViewer4.behaviorManager) === null || _this$sceneViewer4 === void 0 || _this$sceneViewer4.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
331
|
+
(_this$sceneViewer5 = this.sceneViewer) === null || _this$sceneViewer5 === void 0 || (_this$sceneViewer5 = _this$sceneViewer5.managers) === null || _this$sceneViewer5 === void 0 || (_this$sceneViewer5 = _this$sceneViewer5.ioAnimationManager) === null || _this$sceneViewer5 === void 0 || _this$sceneViewer5.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
332
|
+
}
|
|
333
|
+
|
|
171
334
|
/**
|
|
172
335
|
* Should be called when an object is selected or deselected.
|
|
173
336
|
* @param {THREE.Object3D|null} object
|
|
@@ -281,26 +444,30 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
281
444
|
}, {
|
|
282
445
|
key: "_getIODevices",
|
|
283
446
|
value: function _getIODevices(object) {
|
|
284
|
-
var
|
|
447
|
+
var _this3 = this;
|
|
285
448
|
var devices = [];
|
|
286
449
|
var parentUuid = object.uuid; // The component's own UUID
|
|
287
450
|
object.traverse(function (child) {
|
|
288
451
|
var _child$userData;
|
|
289
452
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
290
|
-
var
|
|
453
|
+
var _this3$sceneViewer$ma, _this3$sceneViewer;
|
|
291
454
|
var attachmentId = child.userData.attachmentId || '';
|
|
292
455
|
|
|
293
|
-
//
|
|
294
|
-
//
|
|
295
|
-
var
|
|
296
|
-
|
|
456
|
+
// Use only data points from the animate window (animationConfig).
|
|
457
|
+
// The static ioConfig.states[] snapshot on userData is intentionally ignored.
|
|
458
|
+
var dataPoints = (_this3$sceneViewer$ma = (_this3$sceneViewer = _this3.sceneViewer) === null || _this3$sceneViewer === void 0 || (_this3$sceneViewer = _this3$sceneViewer.managers) === null || _this3$sceneViewer === void 0 || (_this3$sceneViewer = _this3$sceneViewer.ioAnimationManager) === null || _this3$sceneViewer === void 0 ? void 0 : _this3$sceneViewer.getAnimationDataPoints(parentUuid, attachmentId)) !== null && _this3$sceneViewer$ma !== void 0 ? _this3$sceneViewer$ma : [];
|
|
459
|
+
|
|
460
|
+
// When data points come from animationConfig they already carry direction:'input'.
|
|
461
|
+
// Pass null so _buildDataPointRow uses the per-dp direction instead of the
|
|
462
|
+
// device-level ioDirection (which may be 'output' and would hide controls).
|
|
463
|
+
var deviceDirection = dataPoints.length > 0 ? null : child.userData.ioDirection || 'output';
|
|
297
464
|
devices.push({
|
|
298
465
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
299
466
|
deviceId: child.userData.deviceId || '',
|
|
300
467
|
attachmentId: attachmentId,
|
|
301
|
-
scopedAttachmentId:
|
|
468
|
+
scopedAttachmentId: _this3._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
302
469
|
dataPoints: dataPoints,
|
|
303
|
-
direction:
|
|
470
|
+
direction: deviceDirection
|
|
304
471
|
});
|
|
305
472
|
}
|
|
306
473
|
});
|
|
@@ -314,7 +481,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
314
481
|
}, {
|
|
315
482
|
key: "_buildTooltip",
|
|
316
483
|
value: function _buildTooltip(object) {
|
|
317
|
-
var
|
|
484
|
+
var _this4 = this;
|
|
318
485
|
// Remove any existing tooltip first
|
|
319
486
|
this.hide();
|
|
320
487
|
// Re-assign selected object since hide() clears it
|
|
@@ -385,7 +552,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
385
552
|
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
386
553
|
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
387
554
|
device.dataPoints.forEach(function (dp) {
|
|
388
|
-
var row =
|
|
555
|
+
var row = _this4._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
389
556
|
list.appendChild(row);
|
|
390
557
|
});
|
|
391
558
|
}
|
|
@@ -396,11 +563,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
396
563
|
// Hover expand/collapse
|
|
397
564
|
trigger.addEventListener('mouseenter', function () {
|
|
398
565
|
ioSection.classList.add('expanded');
|
|
399
|
-
|
|
566
|
+
_this4._ioExpanded = true;
|
|
400
567
|
});
|
|
401
568
|
ioSection.addEventListener('mouseleave', function () {
|
|
402
569
|
ioSection.classList.remove('expanded');
|
|
403
|
-
|
|
570
|
+
_this4._ioExpanded = false;
|
|
404
571
|
});
|
|
405
572
|
card.appendChild(ioSection);
|
|
406
573
|
} else {
|
|
@@ -444,11 +611,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
444
611
|
}, {
|
|
445
612
|
key: "_positionTooltip",
|
|
446
613
|
value: function _positionTooltip() {
|
|
447
|
-
var _this$
|
|
614
|
+
var _this$sceneViewer6, _this$sceneViewer7;
|
|
448
615
|
if (!this.tooltipEl || !this.selectedObject) return;
|
|
449
616
|
var container = this._getContainer();
|
|
450
|
-
var camera = (_this$
|
|
451
|
-
var renderer = (_this$
|
|
617
|
+
var camera = (_this$sceneViewer6 = this.sceneViewer) === null || _this$sceneViewer6 === void 0 ? void 0 : _this$sceneViewer6.camera;
|
|
618
|
+
var renderer = (_this$sceneViewer7 = this.sceneViewer) === null || _this$sceneViewer7 === void 0 ? void 0 : _this$sceneViewer7.renderer;
|
|
452
619
|
if (!container || !camera || !renderer) return;
|
|
453
620
|
|
|
454
621
|
// Compute bounding box to position above the component
|
|
@@ -485,8 +652,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
485
652
|
}, {
|
|
486
653
|
key: "_getContainer",
|
|
487
654
|
value: function _getContainer() {
|
|
488
|
-
var _this$
|
|
489
|
-
return ((_this$
|
|
655
|
+
var _this$sceneViewer8;
|
|
656
|
+
return ((_this$sceneViewer8 = this.sceneViewer) === null || _this$sceneViewer8 === void 0 || (_this$sceneViewer8 = _this$sceneViewer8.renderer) === null || _this$sceneViewer8 === void 0 || (_this$sceneViewer8 = _this$sceneViewer8.domElement) === null || _this$sceneViewer8 === void 0 ? void 0 : _this$sceneViewer8.parentElement) || null;
|
|
490
657
|
}
|
|
491
658
|
|
|
492
659
|
// -----------------------------------------------------------------------
|
|
@@ -508,10 +675,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
508
675
|
}, {
|
|
509
676
|
key: "_buildDataPointRow",
|
|
510
677
|
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
511
|
-
var
|
|
678
|
+
var _ref3,
|
|
512
679
|
_this$_stateAdapter$g,
|
|
513
|
-
_this$
|
|
514
|
-
|
|
680
|
+
_this$_stateAdapter2,
|
|
681
|
+
_this5 = this;
|
|
515
682
|
var row = document.createElement('div');
|
|
516
683
|
row.className = 'cp-tooltip__dp-row';
|
|
517
684
|
var nameEl = document.createElement('span');
|
|
@@ -523,18 +690,18 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
523
690
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
524
691
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
525
692
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
526
|
-
var currentVal = (
|
|
693
|
+
var currentVal = (_ref3 = (_this$_stateAdapter$g = (_this$_stateAdapter2 = this._stateAdapter) === null || _this$_stateAdapter2 === void 0 ? void 0 : _this$_stateAdapter2.getState(scopedAttachmentId, dpId)) !== null && _this$_stateAdapter$g !== void 0 ? _this$_stateAdapter$g : dp.defaultValue) !== null && _ref3 !== void 0 ? _ref3 : null;
|
|
527
694
|
if (isInput) {
|
|
528
695
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
529
|
-
var
|
|
530
|
-
(
|
|
696
|
+
var _this5$_stateAdapter, _this5$selectedObject, _this5$sceneViewer, _this5$sceneViewer2;
|
|
697
|
+
(_this5$_stateAdapter = _this5._stateAdapter) === null || _this5$_stateAdapter === void 0 || _this5$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
531
698
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
532
699
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
533
700
|
// don't bleed across clones that share the same attachmentId.
|
|
534
701
|
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
535
|
-
var parentUuid = ((
|
|
536
|
-
(
|
|
537
|
-
(
|
|
702
|
+
var parentUuid = ((_this5$selectedObject = _this5.selectedObject) === null || _this5$selectedObject === void 0 ? void 0 : _this5$selectedObject.uuid) || null;
|
|
703
|
+
(_this5$sceneViewer = _this5.sceneViewer) === null || _this5$sceneViewer === void 0 || (_this5$sceneViewer = _this5$sceneViewer.managers) === null || _this5$sceneViewer === void 0 || (_this5$sceneViewer = _this5$sceneViewer.behaviorManager) === null || _this5$sceneViewer === void 0 || _this5$sceneViewer.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
704
|
+
(_this5$sceneViewer2 = _this5.sceneViewer) === null || _this5$sceneViewer2 === void 0 || (_this5$sceneViewer2 = _this5$sceneViewer2.managers) === null || _this5$sceneViewer2 === void 0 || (_this5$sceneViewer2 = _this5$sceneViewer2.ioAnimationManager) === null || _this5$sceneViewer2 === void 0 || _this5$sceneViewer2.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
538
705
|
});
|
|
539
706
|
row.appendChild(ctrl);
|
|
540
707
|
this._stateElements.set(key, {
|
|
@@ -543,9 +710,9 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
543
710
|
isInput: true
|
|
544
711
|
});
|
|
545
712
|
} else {
|
|
546
|
-
var _dp$
|
|
713
|
+
var _dp$stateConfig2;
|
|
547
714
|
// unit suffix (optional, shown between name and badge)
|
|
548
|
-
var unit = (_dp$
|
|
715
|
+
var unit = (_dp$stateConfig2 = dp.stateConfig) === null || _dp$stateConfig2 === void 0 ? void 0 : _dp$stateConfig2.unit;
|
|
549
716
|
if (unit) {
|
|
550
717
|
var unitEl = document.createElement('span');
|
|
551
718
|
unitEl.className = 'cp-tooltip__dp-unit';
|
|
@@ -690,7 +857,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
690
857
|
}, {
|
|
691
858
|
key: "_refreshStateDisplays",
|
|
692
859
|
value: function _refreshStateDisplays() {
|
|
693
|
-
var
|
|
860
|
+
var _this6 = this;
|
|
694
861
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
695
862
|
this._stateElements.forEach(function (entry, key) {
|
|
696
863
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
@@ -699,8 +866,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
699
866
|
if (sepIdx === -1) return;
|
|
700
867
|
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
701
868
|
var dataPointId = key.slice(sepIdx + 2);
|
|
702
|
-
var val =
|
|
703
|
-
|
|
869
|
+
var val = _this6._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
870
|
+
_this6._applyBadgeValue(entry.el, val, entry.dp);
|
|
704
871
|
});
|
|
705
872
|
}
|
|
706
873
|
}]);
|
|
@@ -77,7 +77,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
77
77
|
key: "loadLibraryModel",
|
|
78
78
|
value: function () {
|
|
79
79
|
var _loadLibraryModel = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
|
|
80
|
-
var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioAnimMgr, _loop, _i, _Object$entries, _jsonEntry$userData4, _t;
|
|
80
|
+
var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioAnimMgr, _loop, _i, _Object$entries, warmFn, _jsonEntry$userData4, _t;
|
|
81
81
|
return _rollupPluginBabelHelpers.regenerator().w(function (_context2) {
|
|
82
82
|
while (1) switch (_context2.n) {
|
|
83
83
|
case 0:
|
|
@@ -127,13 +127,14 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
127
127
|
break;
|
|
128
128
|
}
|
|
129
129
|
_loop = /*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _loop() {
|
|
130
|
-
var _modelPreloader$compo;
|
|
130
|
+
var _modelPreloader$compo, _deviceData$animation;
|
|
131
131
|
var _Object$entries$_i, attachmentId, attachment, deviceData, deviceRoot;
|
|
132
132
|
return _rollupPluginBabelHelpers.regenerator().w(function (_context) {
|
|
133
133
|
while (1) switch (_context.n) {
|
|
134
134
|
case 0:
|
|
135
135
|
_Object$entries$_i = _rollupPluginBabelHelpers.slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
|
|
136
136
|
deviceData = (_modelPreloader$compo = modelPreloader["default"].componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
|
|
137
|
+
console.log("[ModelManager] attachment \"".concat(attachmentId, "\" \u2192 deviceId \"").concat(attachment.deviceId, "\" \u2192 animationConfig:"), (_deviceData$animation = deviceData === null || deviceData === void 0 ? void 0 : deviceData.animationConfig) !== null && _deviceData$animation !== void 0 ? _deviceData$animation : 'NONE');
|
|
137
138
|
if (deviceData !== null && deviceData !== void 0 && deviceData.animationConfig) {
|
|
138
139
|
_context.n = 1;
|
|
139
140
|
break;
|
|
@@ -173,6 +174,20 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
173
174
|
case 8:
|
|
174
175
|
// Replace mesh in scene
|
|
175
176
|
this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
|
|
177
|
+
|
|
178
|
+
// Pre-warm the filtered bounding-box cache for smart components so the
|
|
179
|
+
// first selection is instant. Deferred to idle time so it does not
|
|
180
|
+
// block the current frame.
|
|
181
|
+
if (componentData.isSmart) {
|
|
182
|
+
warmFn = function warmFn() {
|
|
183
|
+
return boundingBoxUtils.computeFilteredBoundingBoxCached(libraryModel, ['io-device', 'connector']);
|
|
184
|
+
};
|
|
185
|
+
if (typeof requestIdleCallback !== 'undefined') {
|
|
186
|
+
requestIdleCallback(warmFn);
|
|
187
|
+
} else {
|
|
188
|
+
setTimeout(warmFn, 0);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
176
191
|
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"));
|
|
177
192
|
return _context2.a(2, libraryModel);
|
|
178
193
|
case 9:
|
|
@@ -233,6 +233,34 @@ function computeIODeviceBoundingBoxes(componentObject) {
|
|
|
233
233
|
* const helpers = createSelectionBoxHelpers(pumpModel, 0x00ff00)
|
|
234
234
|
* helpers.forEach(h => scene.add(h))
|
|
235
235
|
*/
|
|
236
|
+
/**
|
|
237
|
+
* Returns a filtered bounding box for `object`, using a cache stored on
|
|
238
|
+
* `object.userData._filteredBBoxCache`. The cache key is the serialised
|
|
239
|
+
* world-matrix elements string; if the object has moved the cache is
|
|
240
|
+
* automatically invalidated and recomputed.
|
|
241
|
+
*
|
|
242
|
+
* This avoids the expensive full-traverse on every selection event for
|
|
243
|
+
* large smart components with many child meshes.
|
|
244
|
+
*
|
|
245
|
+
* @param {THREE.Object3D} object
|
|
246
|
+
* @param {string[]} excludeTypes
|
|
247
|
+
* @returns {THREE.Box3}
|
|
248
|
+
*/
|
|
249
|
+
function computeFilteredBoundingBoxCached(object, excludeTypes) {
|
|
250
|
+
object.updateMatrixWorld(true);
|
|
251
|
+
var matrixKey = object.matrixWorld.elements.join(',');
|
|
252
|
+
var cache = object.userData._filteredBBoxCache;
|
|
253
|
+
if (cache && cache.matrixKey === matrixKey) {
|
|
254
|
+
return new THREE__namespace.Box3(_rollupPluginBabelHelpers.construct(THREE__namespace.Vector3, _rollupPluginBabelHelpers.toConsumableArray(cache.min)), _rollupPluginBabelHelpers.construct(THREE__namespace.Vector3, _rollupPluginBabelHelpers.toConsumableArray(cache.max)));
|
|
255
|
+
}
|
|
256
|
+
var box = computeFilteredBoundingBox(object, excludeTypes);
|
|
257
|
+
object.userData._filteredBBoxCache = {
|
|
258
|
+
matrixKey: matrixKey,
|
|
259
|
+
min: box.min.toArray(),
|
|
260
|
+
max: box.max.toArray()
|
|
261
|
+
};
|
|
262
|
+
return box;
|
|
263
|
+
}
|
|
236
264
|
function createSelectionBoxHelpers(object) {
|
|
237
265
|
var _object$children;
|
|
238
266
|
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x00ff00;
|
|
@@ -246,7 +274,7 @@ function createSelectionBoxHelpers(object) {
|
|
|
246
274
|
});
|
|
247
275
|
if (hasIODevices) {
|
|
248
276
|
// 1. Create filtered helper for the component body
|
|
249
|
-
var filteredBox =
|
|
277
|
+
var filteredBox = computeFilteredBoundingBoxCached(object, excludeTypes);
|
|
250
278
|
var componentHelper = _createBoxHelperFromBox3(filteredBox, color);
|
|
251
279
|
componentHelper.isHelper = true;
|
|
252
280
|
componentHelper.userData = {
|
|
@@ -256,33 +284,6 @@ function createSelectionBoxHelpers(object) {
|
|
|
256
284
|
excludeTypes: excludeTypes
|
|
257
285
|
};
|
|
258
286
|
helpers.push(componentHelper);
|
|
259
|
-
|
|
260
|
-
// 2. Create individual helpers for each io-device
|
|
261
|
-
var _iterator2 = _rollupPluginBabelHelpers.createForOfIteratorHelper(object.children),
|
|
262
|
-
_step2;
|
|
263
|
-
try {
|
|
264
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
265
|
-
var _child$userData3;
|
|
266
|
-
var child = _step2.value;
|
|
267
|
-
if (((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) !== 'io-device') continue;
|
|
268
|
-
var deviceBox = new THREE__namespace.Box3().setFromObject(child);
|
|
269
|
-
if (deviceBox.isEmpty()) continue;
|
|
270
|
-
var deviceHelper = _createBoxHelperFromBox3(deviceBox, color);
|
|
271
|
-
deviceHelper.isHelper = true;
|
|
272
|
-
deviceHelper.userData = {
|
|
273
|
-
isBoundingBox: true,
|
|
274
|
-
sourceObjectUuid: child.uuid,
|
|
275
|
-
isFiltered: false,
|
|
276
|
-
isIODevice: true,
|
|
277
|
-
parentComponentUuid: object.uuid
|
|
278
|
-
};
|
|
279
|
-
helpers.push(deviceHelper);
|
|
280
|
-
}
|
|
281
|
-
} catch (err) {
|
|
282
|
-
_iterator2.e(err);
|
|
283
|
-
} finally {
|
|
284
|
-
_iterator2.f();
|
|
285
|
-
}
|
|
286
287
|
} else {
|
|
287
288
|
// Standard BoxHelper for non-smart objects
|
|
288
289
|
var boxHelper = new THREE__namespace.BoxHelper(object, color);
|
|
@@ -306,11 +307,11 @@ function createSelectionBoxHelpers(object) {
|
|
|
306
307
|
* @param {THREE.Scene} scene - The scene (for finding objects by uuid)
|
|
307
308
|
*/
|
|
308
309
|
function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
309
|
-
var
|
|
310
|
-
|
|
310
|
+
var _iterator2 = _rollupPluginBabelHelpers.createForOfIteratorHelper(helpers),
|
|
311
|
+
_step2;
|
|
311
312
|
try {
|
|
312
313
|
var _loop = function _loop() {
|
|
313
|
-
var helper =
|
|
314
|
+
var helper = _step2.value;
|
|
314
315
|
var _helper$userData = helper.userData,
|
|
315
316
|
sourceObjectUuid = _helper$userData.sourceObjectUuid,
|
|
316
317
|
isFiltered = _helper$userData.isFiltered,
|
|
@@ -333,29 +334,26 @@ function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
|
333
334
|
if (!sourceObject) return 1; // continue
|
|
334
335
|
sourceObject.updateMatrixWorld(true);
|
|
335
336
|
if (isFiltered && excludeTypes) {
|
|
336
|
-
// Recompute filtered bbox
|
|
337
|
-
var box =
|
|
337
|
+
// Recompute filtered bbox (uses cache when the object hasn't moved)
|
|
338
|
+
var box = computeFilteredBoundingBoxCached(sourceObject, excludeTypes);
|
|
338
339
|
_updateBoxHelperPositions(helper, box);
|
|
339
|
-
} else if (isIODevice) {
|
|
340
|
-
// Recompute io-device bbox
|
|
341
|
-
var _box = new THREE__namespace.Box3().setFromObject(sourceObject);
|
|
342
|
-
_updateBoxHelperPositions(helper, _box);
|
|
343
340
|
} else if (helper.update) {
|
|
344
341
|
// Standard BoxHelper — use built-in update
|
|
345
342
|
helper.update();
|
|
346
343
|
}
|
|
347
344
|
};
|
|
348
|
-
for (
|
|
345
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
349
346
|
if (_loop()) continue;
|
|
350
347
|
}
|
|
351
348
|
} catch (err) {
|
|
352
|
-
|
|
349
|
+
_iterator2.e(err);
|
|
353
350
|
} finally {
|
|
354
|
-
|
|
351
|
+
_iterator2.f();
|
|
355
352
|
}
|
|
356
353
|
}
|
|
357
354
|
|
|
358
355
|
exports.computeFilteredBoundingBox = computeFilteredBoundingBox;
|
|
356
|
+
exports.computeFilteredBoundingBoxCached = computeFilteredBoundingBoxCached;
|
|
359
357
|
exports.computeIODeviceBoundingBoxes = computeIODeviceBoundingBoxes;
|
|
360
358
|
exports.createSelectionBoxHelpers = createSelectionBoxHelpers;
|
|
361
359
|
exports.updateSelectionBoxHelpers = updateSelectionBoxHelpers;
|
|
@@ -31,7 +31,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
31
31
|
* Initialize the CentralPlant manager
|
|
32
32
|
*
|
|
33
33
|
* @constructor
|
|
34
|
-
* @version 0.3.
|
|
34
|
+
* @version 0.3.27
|
|
35
35
|
* @updated 2025-10-22
|
|
36
36
|
*
|
|
37
37
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|