@2112-lab/central-plant 0.3.26 → 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 +894 -117
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/core/centralPlantInternals.js +17 -0
- package/dist/cjs/src/core/sceneViewer.js +55 -2
- package/dist/cjs/src/managers/behaviors/IoAnimationManager.js +24 -1
- 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 +190 -27
- package/dist/cjs/src/managers/scene/modelManager.js +15 -1
- 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 +17 -0
- package/dist/esm/src/core/sceneViewer.js +55 -2
- package/dist/esm/src/managers/behaviors/IoAnimationManager.js +24 -1
- 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 +191 -28
- package/dist/esm/src/managers/scene/modelManager.js +16 -2
- package/dist/esm/src/utils/boundingBoxUtils.js +39 -42
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { inherits as _inherits, createClass as _createClass, classCallCheck as _classCallCheck, callSuper as _callSuper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
1
|
+
import { inherits as _inherits, createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, classCallCheck as _classCallCheck, callSuper as _callSuper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
4
4
|
|
|
@@ -144,6 +144,169 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
144
144
|
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
+
// ── IO device drag-to-state ─────────────────────────────────────────────
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Begin tracking a drag gesture on an IO device mesh.
|
|
151
|
+
* Records the initial state of each animation data point so that
|
|
152
|
+
* `updateIODeviceDrag` can compute relative offsets from it.
|
|
153
|
+
*
|
|
154
|
+
* @param {THREE.Object3D} ioDeviceObject
|
|
155
|
+
*/
|
|
156
|
+
}, {
|
|
157
|
+
key: "startIODeviceDrag",
|
|
158
|
+
value: function startIODeviceDrag(ioDeviceObject) {
|
|
159
|
+
var _this$sceneViewer3,
|
|
160
|
+
_this2 = this;
|
|
161
|
+
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
162
|
+
var ud = ioDeviceObject.userData;
|
|
163
|
+
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
164
|
+
if (!attachmentId) return;
|
|
165
|
+
var parentUuid = null;
|
|
166
|
+
var obj = ioDeviceObject.parent;
|
|
167
|
+
while (obj) {
|
|
168
|
+
var _obj$userData2;
|
|
169
|
+
if (((_obj$userData2 = obj.userData) === null || _obj$userData2 === void 0 ? void 0 : _obj$userData2.objectType) === 'component') {
|
|
170
|
+
parentUuid = obj.uuid;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
obj = obj.parent;
|
|
174
|
+
}
|
|
175
|
+
var scopedAttachmentId = this._getScopedAttachmentKey(attachmentId, parentUuid);
|
|
176
|
+
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;
|
|
177
|
+
var dataPoints = ((ioAnimMgr === null || ioAnimMgr === void 0 ? void 0 : ioAnimMgr.getAnimationDataPoints(parentUuid, attachmentId)) || []).concat((ud === null || ud === void 0 ? void 0 : ud.dataPoints) || [])
|
|
178
|
+
// deduplicate by id
|
|
179
|
+
.filter(function (dp, i, arr) {
|
|
180
|
+
return arr.findIndex(function (d) {
|
|
181
|
+
return d.id === dp.id;
|
|
182
|
+
}) === i;
|
|
183
|
+
});
|
|
184
|
+
var dpSessions = [];
|
|
185
|
+
var _iterator = _createForOfIteratorHelper(dataPoints),
|
|
186
|
+
_step;
|
|
187
|
+
try {
|
|
188
|
+
var _loop = function _loop() {
|
|
189
|
+
var _this2$_stateAdapter$;
|
|
190
|
+
var dp = _step.value;
|
|
191
|
+
var stateType = (dp.stateType || '').toLowerCase();
|
|
192
|
+
if (stateType !== 'binary' && stateType !== 'boolean' && stateType !== 'enum') return 1; // continue
|
|
193
|
+
var curVal = (_this2$_stateAdapter$ = _this2._stateAdapter.getState(scopedAttachmentId, dp.id)) !== null && _this2$_stateAdapter$ !== void 0 ? _this2$_stateAdapter$ : dp.defaultValue;
|
|
194
|
+
if (stateType === 'binary' || stateType === 'boolean') {
|
|
195
|
+
dpSessions.push({
|
|
196
|
+
dp: dp,
|
|
197
|
+
scopedAttachmentId: scopedAttachmentId,
|
|
198
|
+
attachmentId: attachmentId,
|
|
199
|
+
parentUuid: parentUuid,
|
|
200
|
+
stateType: 'binary',
|
|
201
|
+
lastApplied: curVal
|
|
202
|
+
});
|
|
203
|
+
} else {
|
|
204
|
+
var _dp$stateConfig;
|
|
205
|
+
var opts = ((_dp$stateConfig = dp.stateConfig) === null || _dp$stateConfig === void 0 ? void 0 : _dp$stateConfig.options) || [];
|
|
206
|
+
var curIdx = opts.findIndex(function (o) {
|
|
207
|
+
return String(o) === String(curVal);
|
|
208
|
+
});
|
|
209
|
+
dpSessions.push({
|
|
210
|
+
dp: dp,
|
|
211
|
+
scopedAttachmentId: scopedAttachmentId,
|
|
212
|
+
attachmentId: attachmentId,
|
|
213
|
+
parentUuid: parentUuid,
|
|
214
|
+
stateType: 'enum',
|
|
215
|
+
opts: opts,
|
|
216
|
+
startIdx: curIdx >= 0 ? curIdx : 0,
|
|
217
|
+
lastAppliedIdx: curIdx >= 0 ? curIdx : 0
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
222
|
+
if (_loop()) continue;
|
|
223
|
+
}
|
|
224
|
+
} catch (err) {
|
|
225
|
+
_iterator.e(err);
|
|
226
|
+
} finally {
|
|
227
|
+
_iterator.f();
|
|
228
|
+
}
|
|
229
|
+
this._ioDragSession = dpSessions.length ? {
|
|
230
|
+
dpSessions: dpSessions
|
|
231
|
+
} : null;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Update animated mesh state while a drag is in progress.
|
|
236
|
+
* Called continuously during pointermove.
|
|
237
|
+
*
|
|
238
|
+
* Sign convention: up/right = positive `signedDelta`.
|
|
239
|
+
* - Binary: > +20 px → true/on state, < −20 px → false/off state.
|
|
240
|
+
* - Enum: each ±30 px step advances/retreats one option in the list.
|
|
241
|
+
*
|
|
242
|
+
* @param {number} signedDelta - Cumulative signed pixel displacement since drag start
|
|
243
|
+
*/
|
|
244
|
+
}, {
|
|
245
|
+
key: "updateIODeviceDrag",
|
|
246
|
+
value: function updateIODeviceDrag(signedDelta) {
|
|
247
|
+
var session = this._ioDragSession;
|
|
248
|
+
if (!session) return;
|
|
249
|
+
var BINARY_THRESHOLD = 20;
|
|
250
|
+
var ENUM_STEP_PX = 30;
|
|
251
|
+
var _iterator2 = _createForOfIteratorHelper(session.dpSessions),
|
|
252
|
+
_step2;
|
|
253
|
+
try {
|
|
254
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
255
|
+
var dps = _step2.value;
|
|
256
|
+
if (dps.stateType === 'binary') {
|
|
257
|
+
var newVal = void 0;
|
|
258
|
+
if (signedDelta > BINARY_THRESHOLD) {
|
|
259
|
+
newVal = true;
|
|
260
|
+
} else if (signedDelta < -BINARY_THRESHOLD) {
|
|
261
|
+
newVal = false;
|
|
262
|
+
} else {
|
|
263
|
+
continue; // dead zone
|
|
264
|
+
}
|
|
265
|
+
if (newVal === dps.lastApplied) continue;
|
|
266
|
+
dps.lastApplied = newVal;
|
|
267
|
+
this._applyDpState(dps, newVal);
|
|
268
|
+
} else if (dps.stateType === 'enum') {
|
|
269
|
+
var steps = Math.round(signedDelta / ENUM_STEP_PX);
|
|
270
|
+
var newIdx = Math.max(0, Math.min(dps.opts.length - 1, dps.startIdx + steps));
|
|
271
|
+
if (newIdx === dps.lastAppliedIdx) continue;
|
|
272
|
+
dps.lastAppliedIdx = newIdx;
|
|
273
|
+
this._applyDpState(dps, dps.opts[newIdx]);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
} catch (err) {
|
|
277
|
+
_iterator2.e(err);
|
|
278
|
+
} finally {
|
|
279
|
+
_iterator2.f();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Clean up drag session state on pointerup.
|
|
285
|
+
*/
|
|
286
|
+
}, {
|
|
287
|
+
key: "endIODeviceDrag",
|
|
288
|
+
value: function endIODeviceDrag() {
|
|
289
|
+
this._ioDragSession = null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Apply a new value to a data point, updating Vuex state and firing behavior/animation triggers.
|
|
294
|
+
* @private
|
|
295
|
+
*/
|
|
296
|
+
}, {
|
|
297
|
+
key: "_applyDpState",
|
|
298
|
+
value: function _applyDpState(_ref2, newVal) {
|
|
299
|
+
var _this$_stateAdapter, _this$sceneViewer4, _this$sceneViewer5;
|
|
300
|
+
var scopedAttachmentId = _ref2.scopedAttachmentId,
|
|
301
|
+
attachmentId = _ref2.attachmentId,
|
|
302
|
+
parentUuid = _ref2.parentUuid,
|
|
303
|
+
dp = _ref2.dp;
|
|
304
|
+
var dpId = dp.id;
|
|
305
|
+
(_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 || _this$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
306
|
+
(_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);
|
|
307
|
+
(_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);
|
|
308
|
+
}
|
|
309
|
+
|
|
147
310
|
/**
|
|
148
311
|
* Should be called when an object is selected or deselected.
|
|
149
312
|
* @param {THREE.Object3D|null} object
|
|
@@ -257,18 +420,18 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
257
420
|
}, {
|
|
258
421
|
key: "_getIODevices",
|
|
259
422
|
value: function _getIODevices(object) {
|
|
260
|
-
var
|
|
423
|
+
var _this3 = this;
|
|
261
424
|
var devices = [];
|
|
262
425
|
var parentUuid = object.uuid; // The component's own UUID
|
|
263
426
|
object.traverse(function (child) {
|
|
264
427
|
var _child$userData;
|
|
265
428
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
266
|
-
var
|
|
429
|
+
var _this3$sceneViewer$ma, _this3$sceneViewer;
|
|
267
430
|
var attachmentId = child.userData.attachmentId || '';
|
|
268
431
|
|
|
269
432
|
// Use only data points from the animate window (animationConfig).
|
|
270
433
|
// The static ioConfig.states[] snapshot on userData is intentionally ignored.
|
|
271
|
-
var dataPoints = (
|
|
434
|
+
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 : [];
|
|
272
435
|
|
|
273
436
|
// When data points come from animationConfig they already carry direction:'input'.
|
|
274
437
|
// Pass null so _buildDataPointRow uses the per-dp direction instead of the
|
|
@@ -278,7 +441,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
278
441
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
279
442
|
deviceId: child.userData.deviceId || '',
|
|
280
443
|
attachmentId: attachmentId,
|
|
281
|
-
scopedAttachmentId:
|
|
444
|
+
scopedAttachmentId: _this3._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
282
445
|
dataPoints: dataPoints,
|
|
283
446
|
direction: deviceDirection
|
|
284
447
|
});
|
|
@@ -294,7 +457,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
294
457
|
}, {
|
|
295
458
|
key: "_buildTooltip",
|
|
296
459
|
value: function _buildTooltip(object) {
|
|
297
|
-
var
|
|
460
|
+
var _this4 = this;
|
|
298
461
|
// Remove any existing tooltip first
|
|
299
462
|
this.hide();
|
|
300
463
|
// Re-assign selected object since hide() clears it
|
|
@@ -365,7 +528,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
365
528
|
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
366
529
|
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
367
530
|
device.dataPoints.forEach(function (dp) {
|
|
368
|
-
var row =
|
|
531
|
+
var row = _this4._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
369
532
|
list.appendChild(row);
|
|
370
533
|
});
|
|
371
534
|
}
|
|
@@ -376,11 +539,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
376
539
|
// Hover expand/collapse
|
|
377
540
|
trigger.addEventListener('mouseenter', function () {
|
|
378
541
|
ioSection.classList.add('expanded');
|
|
379
|
-
|
|
542
|
+
_this4._ioExpanded = true;
|
|
380
543
|
});
|
|
381
544
|
ioSection.addEventListener('mouseleave', function () {
|
|
382
545
|
ioSection.classList.remove('expanded');
|
|
383
|
-
|
|
546
|
+
_this4._ioExpanded = false;
|
|
384
547
|
});
|
|
385
548
|
card.appendChild(ioSection);
|
|
386
549
|
} else {
|
|
@@ -424,11 +587,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
424
587
|
}, {
|
|
425
588
|
key: "_positionTooltip",
|
|
426
589
|
value: function _positionTooltip() {
|
|
427
|
-
var _this$
|
|
590
|
+
var _this$sceneViewer6, _this$sceneViewer7;
|
|
428
591
|
if (!this.tooltipEl || !this.selectedObject) return;
|
|
429
592
|
var container = this._getContainer();
|
|
430
|
-
var camera = (_this$
|
|
431
|
-
var renderer = (_this$
|
|
593
|
+
var camera = (_this$sceneViewer6 = this.sceneViewer) === null || _this$sceneViewer6 === void 0 ? void 0 : _this$sceneViewer6.camera;
|
|
594
|
+
var renderer = (_this$sceneViewer7 = this.sceneViewer) === null || _this$sceneViewer7 === void 0 ? void 0 : _this$sceneViewer7.renderer;
|
|
432
595
|
if (!container || !camera || !renderer) return;
|
|
433
596
|
|
|
434
597
|
// Compute bounding box to position above the component
|
|
@@ -465,8 +628,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
465
628
|
}, {
|
|
466
629
|
key: "_getContainer",
|
|
467
630
|
value: function _getContainer() {
|
|
468
|
-
var _this$
|
|
469
|
-
return ((_this$
|
|
631
|
+
var _this$sceneViewer8;
|
|
632
|
+
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;
|
|
470
633
|
}
|
|
471
634
|
|
|
472
635
|
// -----------------------------------------------------------------------
|
|
@@ -488,10 +651,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
488
651
|
}, {
|
|
489
652
|
key: "_buildDataPointRow",
|
|
490
653
|
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
491
|
-
var
|
|
654
|
+
var _ref3,
|
|
492
655
|
_this$_stateAdapter$g,
|
|
493
|
-
_this$
|
|
494
|
-
|
|
656
|
+
_this$_stateAdapter2,
|
|
657
|
+
_this5 = this;
|
|
495
658
|
var row = document.createElement('div');
|
|
496
659
|
row.className = 'cp-tooltip__dp-row';
|
|
497
660
|
var nameEl = document.createElement('span');
|
|
@@ -503,18 +666,18 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
503
666
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
504
667
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
505
668
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
506
|
-
var currentVal = (
|
|
669
|
+
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;
|
|
507
670
|
if (isInput) {
|
|
508
671
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
509
|
-
var
|
|
510
|
-
(
|
|
672
|
+
var _this5$_stateAdapter, _this5$selectedObject, _this5$sceneViewer, _this5$sceneViewer2;
|
|
673
|
+
(_this5$_stateAdapter = _this5._stateAdapter) === null || _this5$_stateAdapter === void 0 || _this5$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
511
674
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
512
675
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
513
676
|
// don't bleed across clones that share the same attachmentId.
|
|
514
677
|
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
515
|
-
var parentUuid = ((
|
|
516
|
-
(
|
|
517
|
-
(
|
|
678
|
+
var parentUuid = ((_this5$selectedObject = _this5.selectedObject) === null || _this5$selectedObject === void 0 ? void 0 : _this5$selectedObject.uuid) || null;
|
|
679
|
+
(_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);
|
|
680
|
+
(_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);
|
|
518
681
|
});
|
|
519
682
|
row.appendChild(ctrl);
|
|
520
683
|
this._stateElements.set(key, {
|
|
@@ -523,9 +686,9 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
523
686
|
isInput: true
|
|
524
687
|
});
|
|
525
688
|
} else {
|
|
526
|
-
var _dp$
|
|
689
|
+
var _dp$stateConfig2;
|
|
527
690
|
// unit suffix (optional, shown between name and badge)
|
|
528
|
-
var unit = (_dp$
|
|
691
|
+
var unit = (_dp$stateConfig2 = dp.stateConfig) === null || _dp$stateConfig2 === void 0 ? void 0 : _dp$stateConfig2.unit;
|
|
529
692
|
if (unit) {
|
|
530
693
|
var unitEl = document.createElement('span');
|
|
531
694
|
unitEl.className = 'cp-tooltip__dp-unit';
|
|
@@ -670,7 +833,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
670
833
|
}, {
|
|
671
834
|
key: "_refreshStateDisplays",
|
|
672
835
|
value: function _refreshStateDisplays() {
|
|
673
|
-
var
|
|
836
|
+
var _this6 = this;
|
|
674
837
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
675
838
|
this._stateElements.forEach(function (entry, key) {
|
|
676
839
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
@@ -679,8 +842,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
679
842
|
if (sepIdx === -1) return;
|
|
680
843
|
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
681
844
|
var dataPointId = key.slice(sepIdx + 2);
|
|
682
|
-
var val =
|
|
683
|
-
|
|
845
|
+
var val = _this6._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
846
|
+
_this6._applyBadgeValue(entry.el, val, entry.dp);
|
|
684
847
|
});
|
|
685
848
|
}
|
|
686
849
|
}]);
|
|
@@ -2,7 +2,7 @@ import { createClass as _createClass, objectSpread2 as _objectSpread2, toConsuma
|
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { attachIODevicesToComponent } from '../../utils/ioDeviceUtils.js';
|
|
4
4
|
import modelPreloader from '../../rendering/modelPreloader.js';
|
|
5
|
-
import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
|
|
5
|
+
import { computeFilteredBoundingBox, computeFilteredBoundingBoxCached } from '../../utils/boundingBoxUtils.js';
|
|
6
6
|
import { cacheBasePosition } from './viewport2DManager.js';
|
|
7
7
|
|
|
8
8
|
var ModelManager = /*#__PURE__*/function () {
|
|
@@ -53,7 +53,7 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
53
53
|
key: "loadLibraryModel",
|
|
54
54
|
value: function () {
|
|
55
55
|
var _loadLibraryModel = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(targetMesh, jsonEntry, componentData) {
|
|
56
|
-
var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioAnimMgr, _loop, _i, _Object$entries, _jsonEntry$userData4, _t;
|
|
56
|
+
var component, _jsonEntry$userData, _jsonEntry$userData2, _jsonEntry$userData3, originalProps, connectorChildren, gltfScene, libraryModel, _this$sceneViewer, ioAnimMgr, _loop, _i, _Object$entries, warmFn, _jsonEntry$userData4, _t;
|
|
57
57
|
return _regenerator().w(function (_context2) {
|
|
58
58
|
while (1) switch (_context2.n) {
|
|
59
59
|
case 0:
|
|
@@ -150,6 +150,20 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
150
150
|
case 8:
|
|
151
151
|
// Replace mesh in scene
|
|
152
152
|
this._replaceMeshInScene(targetMesh, libraryModel, originalProps.parent, component);
|
|
153
|
+
|
|
154
|
+
// Pre-warm the filtered bounding-box cache for smart components so the
|
|
155
|
+
// first selection is instant. Deferred to idle time so it does not
|
|
156
|
+
// block the current frame.
|
|
157
|
+
if (componentData.isSmart) {
|
|
158
|
+
warmFn = function warmFn() {
|
|
159
|
+
return computeFilteredBoundingBoxCached(libraryModel, ['io-device', 'connector']);
|
|
160
|
+
};
|
|
161
|
+
if (typeof requestIdleCallback !== 'undefined') {
|
|
162
|
+
requestIdleCallback(warmFn);
|
|
163
|
+
} else {
|
|
164
|
+
setTimeout(warmFn, 0);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
153
167
|
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"));
|
|
154
168
|
return _context2.a(2, libraryModel);
|
|
155
169
|
case 9:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createForOfIteratorHelper as _createForOfIteratorHelper } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
1
|
+
import { createForOfIteratorHelper as _createForOfIteratorHelper, construct as _construct, toConsumableArray as _toConsumableArray } from '../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -209,6 +209,34 @@ function computeIODeviceBoundingBoxes(componentObject) {
|
|
|
209
209
|
* const helpers = createSelectionBoxHelpers(pumpModel, 0x00ff00)
|
|
210
210
|
* helpers.forEach(h => scene.add(h))
|
|
211
211
|
*/
|
|
212
|
+
/**
|
|
213
|
+
* Returns a filtered bounding box for `object`, using a cache stored on
|
|
214
|
+
* `object.userData._filteredBBoxCache`. The cache key is the serialised
|
|
215
|
+
* world-matrix elements string; if the object has moved the cache is
|
|
216
|
+
* automatically invalidated and recomputed.
|
|
217
|
+
*
|
|
218
|
+
* This avoids the expensive full-traverse on every selection event for
|
|
219
|
+
* large smart components with many child meshes.
|
|
220
|
+
*
|
|
221
|
+
* @param {THREE.Object3D} object
|
|
222
|
+
* @param {string[]} excludeTypes
|
|
223
|
+
* @returns {THREE.Box3}
|
|
224
|
+
*/
|
|
225
|
+
function computeFilteredBoundingBoxCached(object, excludeTypes) {
|
|
226
|
+
object.updateMatrixWorld(true);
|
|
227
|
+
var matrixKey = object.matrixWorld.elements.join(',');
|
|
228
|
+
var cache = object.userData._filteredBBoxCache;
|
|
229
|
+
if (cache && cache.matrixKey === matrixKey) {
|
|
230
|
+
return new THREE.Box3(_construct(THREE.Vector3, _toConsumableArray(cache.min)), _construct(THREE.Vector3, _toConsumableArray(cache.max)));
|
|
231
|
+
}
|
|
232
|
+
var box = computeFilteredBoundingBox(object, excludeTypes);
|
|
233
|
+
object.userData._filteredBBoxCache = {
|
|
234
|
+
matrixKey: matrixKey,
|
|
235
|
+
min: box.min.toArray(),
|
|
236
|
+
max: box.max.toArray()
|
|
237
|
+
};
|
|
238
|
+
return box;
|
|
239
|
+
}
|
|
212
240
|
function createSelectionBoxHelpers(object) {
|
|
213
241
|
var _object$children;
|
|
214
242
|
var color = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0x00ff00;
|
|
@@ -222,7 +250,7 @@ function createSelectionBoxHelpers(object) {
|
|
|
222
250
|
});
|
|
223
251
|
if (hasIODevices) {
|
|
224
252
|
// 1. Create filtered helper for the component body
|
|
225
|
-
var filteredBox =
|
|
253
|
+
var filteredBox = computeFilteredBoundingBoxCached(object, excludeTypes);
|
|
226
254
|
var componentHelper = _createBoxHelperFromBox3(filteredBox, color);
|
|
227
255
|
componentHelper.isHelper = true;
|
|
228
256
|
componentHelper.userData = {
|
|
@@ -232,33 +260,6 @@ function createSelectionBoxHelpers(object) {
|
|
|
232
260
|
excludeTypes: excludeTypes
|
|
233
261
|
};
|
|
234
262
|
helpers.push(componentHelper);
|
|
235
|
-
|
|
236
|
-
// 2. Create individual helpers for each io-device
|
|
237
|
-
var _iterator2 = _createForOfIteratorHelper(object.children),
|
|
238
|
-
_step2;
|
|
239
|
-
try {
|
|
240
|
-
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
241
|
-
var _child$userData3;
|
|
242
|
-
var child = _step2.value;
|
|
243
|
-
if (((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) !== 'io-device') continue;
|
|
244
|
-
var deviceBox = new THREE.Box3().setFromObject(child);
|
|
245
|
-
if (deviceBox.isEmpty()) continue;
|
|
246
|
-
var deviceHelper = _createBoxHelperFromBox3(deviceBox, color);
|
|
247
|
-
deviceHelper.isHelper = true;
|
|
248
|
-
deviceHelper.userData = {
|
|
249
|
-
isBoundingBox: true,
|
|
250
|
-
sourceObjectUuid: child.uuid,
|
|
251
|
-
isFiltered: false,
|
|
252
|
-
isIODevice: true,
|
|
253
|
-
parentComponentUuid: object.uuid
|
|
254
|
-
};
|
|
255
|
-
helpers.push(deviceHelper);
|
|
256
|
-
}
|
|
257
|
-
} catch (err) {
|
|
258
|
-
_iterator2.e(err);
|
|
259
|
-
} finally {
|
|
260
|
-
_iterator2.f();
|
|
261
|
-
}
|
|
262
263
|
} else {
|
|
263
264
|
// Standard BoxHelper for non-smart objects
|
|
264
265
|
var boxHelper = new THREE.BoxHelper(object, color);
|
|
@@ -282,11 +283,11 @@ function createSelectionBoxHelpers(object) {
|
|
|
282
283
|
* @param {THREE.Scene} scene - The scene (for finding objects by uuid)
|
|
283
284
|
*/
|
|
284
285
|
function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
285
|
-
var
|
|
286
|
-
|
|
286
|
+
var _iterator2 = _createForOfIteratorHelper(helpers),
|
|
287
|
+
_step2;
|
|
287
288
|
try {
|
|
288
289
|
var _loop = function _loop() {
|
|
289
|
-
var helper =
|
|
290
|
+
var helper = _step2.value;
|
|
290
291
|
var _helper$userData = helper.userData,
|
|
291
292
|
sourceObjectUuid = _helper$userData.sourceObjectUuid,
|
|
292
293
|
isFiltered = _helper$userData.isFiltered,
|
|
@@ -309,26 +310,22 @@ function updateSelectionBoxHelpers(helpers, selectedObjects, scene) {
|
|
|
309
310
|
if (!sourceObject) return 1; // continue
|
|
310
311
|
sourceObject.updateMatrixWorld(true);
|
|
311
312
|
if (isFiltered && excludeTypes) {
|
|
312
|
-
// Recompute filtered bbox
|
|
313
|
-
var box =
|
|
313
|
+
// Recompute filtered bbox (uses cache when the object hasn't moved)
|
|
314
|
+
var box = computeFilteredBoundingBoxCached(sourceObject, excludeTypes);
|
|
314
315
|
_updateBoxHelperPositions(helper, box);
|
|
315
|
-
} else if (isIODevice) {
|
|
316
|
-
// Recompute io-device bbox
|
|
317
|
-
var _box = new THREE.Box3().setFromObject(sourceObject);
|
|
318
|
-
_updateBoxHelperPositions(helper, _box);
|
|
319
316
|
} else if (helper.update) {
|
|
320
317
|
// Standard BoxHelper — use built-in update
|
|
321
318
|
helper.update();
|
|
322
319
|
}
|
|
323
320
|
};
|
|
324
|
-
for (
|
|
321
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
325
322
|
if (_loop()) continue;
|
|
326
323
|
}
|
|
327
324
|
} catch (err) {
|
|
328
|
-
|
|
325
|
+
_iterator2.e(err);
|
|
329
326
|
} finally {
|
|
330
|
-
|
|
327
|
+
_iterator2.f();
|
|
331
328
|
}
|
|
332
329
|
}
|
|
333
330
|
|
|
334
|
-
export { computeFilteredBoundingBox, computeIODeviceBoundingBoxes, createSelectionBoxHelpers, updateSelectionBoxHelpers };
|
|
331
|
+
export { computeFilteredBoundingBox, computeFilteredBoundingBoxCached, computeIODeviceBoundingBoxes, createSelectionBoxHelpers, updateSelectionBoxHelpers };
|