@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
|
@@ -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,26 +420,30 @@ 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
|
-
//
|
|
270
|
-
//
|
|
271
|
-
var
|
|
272
|
-
|
|
432
|
+
// Use only data points from the animate window (animationConfig).
|
|
433
|
+
// The static ioConfig.states[] snapshot on userData is intentionally ignored.
|
|
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 : [];
|
|
435
|
+
|
|
436
|
+
// When data points come from animationConfig they already carry direction:'input'.
|
|
437
|
+
// Pass null so _buildDataPointRow uses the per-dp direction instead of the
|
|
438
|
+
// device-level ioDirection (which may be 'output' and would hide controls).
|
|
439
|
+
var deviceDirection = dataPoints.length > 0 ? null : child.userData.ioDirection || 'output';
|
|
273
440
|
devices.push({
|
|
274
441
|
label: child.userData.attachmentLabel || child.name || child.userData.deviceId || 'Unknown Device',
|
|
275
442
|
deviceId: child.userData.deviceId || '',
|
|
276
443
|
attachmentId: attachmentId,
|
|
277
|
-
scopedAttachmentId:
|
|
444
|
+
scopedAttachmentId: _this3._getScopedAttachmentKey(attachmentId, parentUuid),
|
|
278
445
|
dataPoints: dataPoints,
|
|
279
|
-
direction:
|
|
446
|
+
direction: deviceDirection
|
|
280
447
|
});
|
|
281
448
|
}
|
|
282
449
|
});
|
|
@@ -290,7 +457,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
290
457
|
}, {
|
|
291
458
|
key: "_buildTooltip",
|
|
292
459
|
value: function _buildTooltip(object) {
|
|
293
|
-
var
|
|
460
|
+
var _this4 = this;
|
|
294
461
|
// Remove any existing tooltip first
|
|
295
462
|
this.hide();
|
|
296
463
|
// Re-assign selected object since hide() clears it
|
|
@@ -361,7 +528,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
361
528
|
// Use scopedAttachmentId to ensure state is isolated per component instance
|
|
362
529
|
if (device.scopedAttachmentId && device.dataPoints.length > 0) {
|
|
363
530
|
device.dataPoints.forEach(function (dp) {
|
|
364
|
-
var row =
|
|
531
|
+
var row = _this4._buildDataPointRow(device.scopedAttachmentId, dp, device.direction, device.attachmentId);
|
|
365
532
|
list.appendChild(row);
|
|
366
533
|
});
|
|
367
534
|
}
|
|
@@ -372,11 +539,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
372
539
|
// Hover expand/collapse
|
|
373
540
|
trigger.addEventListener('mouseenter', function () {
|
|
374
541
|
ioSection.classList.add('expanded');
|
|
375
|
-
|
|
542
|
+
_this4._ioExpanded = true;
|
|
376
543
|
});
|
|
377
544
|
ioSection.addEventListener('mouseleave', function () {
|
|
378
545
|
ioSection.classList.remove('expanded');
|
|
379
|
-
|
|
546
|
+
_this4._ioExpanded = false;
|
|
380
547
|
});
|
|
381
548
|
card.appendChild(ioSection);
|
|
382
549
|
} else {
|
|
@@ -420,11 +587,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
420
587
|
}, {
|
|
421
588
|
key: "_positionTooltip",
|
|
422
589
|
value: function _positionTooltip() {
|
|
423
|
-
var _this$
|
|
590
|
+
var _this$sceneViewer6, _this$sceneViewer7;
|
|
424
591
|
if (!this.tooltipEl || !this.selectedObject) return;
|
|
425
592
|
var container = this._getContainer();
|
|
426
|
-
var camera = (_this$
|
|
427
|
-
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;
|
|
428
595
|
if (!container || !camera || !renderer) return;
|
|
429
596
|
|
|
430
597
|
// Compute bounding box to position above the component
|
|
@@ -461,8 +628,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
461
628
|
}, {
|
|
462
629
|
key: "_getContainer",
|
|
463
630
|
value: function _getContainer() {
|
|
464
|
-
var _this$
|
|
465
|
-
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;
|
|
466
633
|
}
|
|
467
634
|
|
|
468
635
|
// -----------------------------------------------------------------------
|
|
@@ -484,10 +651,10 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
484
651
|
}, {
|
|
485
652
|
key: "_buildDataPointRow",
|
|
486
653
|
value: function _buildDataPointRow(scopedAttachmentId, dp, deviceDirection, originalAttachmentId) {
|
|
487
|
-
var
|
|
654
|
+
var _ref3,
|
|
488
655
|
_this$_stateAdapter$g,
|
|
489
|
-
_this$
|
|
490
|
-
|
|
656
|
+
_this$_stateAdapter2,
|
|
657
|
+
_this5 = this;
|
|
491
658
|
var row = document.createElement('div');
|
|
492
659
|
row.className = 'cp-tooltip__dp-row';
|
|
493
660
|
var nameEl = document.createElement('span');
|
|
@@ -499,18 +666,18 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
499
666
|
// Device-level direction takes precedence; fall back to per-dp direction
|
|
500
667
|
var resolvedDirection = deviceDirection || dp.direction || 'output';
|
|
501
668
|
var isInput = resolvedDirection === 'input' || resolvedDirection === 'bidirectional';
|
|
502
|
-
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;
|
|
503
670
|
if (isInput) {
|
|
504
671
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
505
|
-
var
|
|
506
|
-
(
|
|
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);
|
|
507
674
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
508
675
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
509
676
|
// don't bleed across clones that share the same attachmentId.
|
|
510
677
|
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
511
|
-
var parentUuid = ((
|
|
512
|
-
(
|
|
513
|
-
(
|
|
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);
|
|
514
681
|
});
|
|
515
682
|
row.appendChild(ctrl);
|
|
516
683
|
this._stateElements.set(key, {
|
|
@@ -519,9 +686,9 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
519
686
|
isInput: true
|
|
520
687
|
});
|
|
521
688
|
} else {
|
|
522
|
-
var _dp$
|
|
689
|
+
var _dp$stateConfig2;
|
|
523
690
|
// unit suffix (optional, shown between name and badge)
|
|
524
|
-
var unit = (_dp$
|
|
691
|
+
var unit = (_dp$stateConfig2 = dp.stateConfig) === null || _dp$stateConfig2 === void 0 ? void 0 : _dp$stateConfig2.unit;
|
|
525
692
|
if (unit) {
|
|
526
693
|
var unitEl = document.createElement('span');
|
|
527
694
|
unitEl.className = 'cp-tooltip__dp-unit';
|
|
@@ -666,7 +833,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
666
833
|
}, {
|
|
667
834
|
key: "_refreshStateDisplays",
|
|
668
835
|
value: function _refreshStateDisplays() {
|
|
669
|
-
var
|
|
836
|
+
var _this6 = this;
|
|
670
837
|
if (!this._stateAdapter || !this._stateElements.size) return;
|
|
671
838
|
this._stateElements.forEach(function (entry, key) {
|
|
672
839
|
if (entry.isInput) return; // interactive controls are user-driven; don't overwrite
|
|
@@ -675,8 +842,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
675
842
|
if (sepIdx === -1) return;
|
|
676
843
|
var scopedAttachmentId = key.slice(0, sepIdx);
|
|
677
844
|
var dataPointId = key.slice(sepIdx + 2);
|
|
678
|
-
var val =
|
|
679
|
-
|
|
845
|
+
var val = _this6._stateAdapter.getState(scopedAttachmentId, dataPointId);
|
|
846
|
+
_this6._applyBadgeValue(entry.el, val, entry.dp);
|
|
680
847
|
});
|
|
681
848
|
}
|
|
682
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:
|
|
@@ -103,13 +103,14 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
103
103
|
break;
|
|
104
104
|
}
|
|
105
105
|
_loop = /*#__PURE__*/_regenerator().m(function _loop() {
|
|
106
|
-
var _modelPreloader$compo;
|
|
106
|
+
var _modelPreloader$compo, _deviceData$animation;
|
|
107
107
|
var _Object$entries$_i, attachmentId, attachment, deviceData, deviceRoot;
|
|
108
108
|
return _regenerator().w(function (_context) {
|
|
109
109
|
while (1) switch (_context.n) {
|
|
110
110
|
case 0:
|
|
111
111
|
_Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), attachmentId = _Object$entries$_i[0], attachment = _Object$entries$_i[1];
|
|
112
112
|
deviceData = (_modelPreloader$compo = modelPreloader.componentDictionary) === null || _modelPreloader$compo === void 0 ? void 0 : _modelPreloader$compo[attachment.deviceId];
|
|
113
|
+
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');
|
|
113
114
|
if (deviceData !== null && deviceData !== void 0 && deviceData.animationConfig) {
|
|
114
115
|
_context.n = 1;
|
|
115
116
|
break;
|
|
@@ -149,6 +150,20 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
149
150
|
case 8:
|
|
150
151
|
// Replace mesh in scene
|
|
151
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
|
+
}
|
|
152
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"));
|
|
153
168
|
return _context2.a(2, libraryModel);
|
|
154
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 };
|