@2112-lab/central-plant 0.3.36 → 0.3.37
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 +60 -17
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/behaviors/IoBehaviorManager.js +58 -15
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +1 -1
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/behaviors/IoBehaviorManager.js +58 -15
- package/dist/esm/src/managers/scene/componentTooltipManager.js +1 -1
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -36542,7 +36542,7 @@ var SceneTooltipsManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
36542
36542
|
// ---------------------------------------------------------------------------
|
|
36543
36543
|
// Inline styles (injected once into the document head)
|
|
36544
36544
|
// ---------------------------------------------------------------------------
|
|
36545
|
-
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n}\n\n.cp-tooltip__card {\n background: rgba(
|
|
36545
|
+
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n color-scheme: light;\n}\n\n.cp-tooltip__card {\n background: rgba(255, 255, 255, 0.97);\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__header {\n padding: 10px 14px;\n font-weight: 600;\n font-size: 14px;\n color: #2c3e50;\n background: rgba(0, 0, 0, 0.02);\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n letter-spacing: 0.2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 I/O Devices section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__io-section {\n position: relative;\n}\n\n.cp-tooltip__io-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n color: #666666;\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.cp-tooltip__io-trigger:hover {\n background: rgba(0, 0, 0, 0.04);\n color: #333333;\n}\n\n.cp-tooltip__io-trigger-label {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.6px;\n font-weight: 500;\n}\n\n.cp-tooltip__io-arrow {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__io-arrow {\n transform: rotate(90deg);\n}\n\n/* \u2500\u2500 Device list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__device-list {\n max-height: 0;\n overflow: hidden;\n transition: max-height 0.25s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__device-list {\n max-height: 300px;\n}\n\n.cp-tooltip__device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px 6px 20px;\n color: #555555;\n font-size: 12px;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n transition: background 0.1s ease;\n}\n\n.cp-tooltip__device-item:hover {\n background: rgba(0, 0, 0, 0.03);\n}\n\n.cp-tooltip__device-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #1976d2;\n flex-shrink: 0;\n}\n\n.cp-tooltip__device-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__no-devices {\n padding: 8px 14px;\n color: #888888;\n font-size: 12px;\n font-style: italic;\n}\n\n/* \u2500\u2500 Caret arrow pointing down \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__caret {\n width: 0;\n height: 0;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid rgba(255, 255, 255, 0.97);\n margin: 0 auto;\n position: relative;\n top: -1px;\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.1));\n}\n\n/* \u2500\u2500 Data point rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__dp-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 4px 12px 4px 30px;\n font-size: 11.5px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n min-height: 24px;\n}\n\n.cp-tooltip__dp-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #666666;\n}\n\n/* Read-only state badge */\n.cp-tooltip__dp-badge {\n font-size: 10.5px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 8px;\n flex-shrink: 0;\n background: #f0f2f5;\n color: #666666;\n min-width: 30px;\n text-align: center;\n letter-spacing: 0.2px;\n}\n\n.cp-tooltip__dp-badge.active {\n background: rgba(76, 175, 80, 0.15);\n color: #2e7d32;\n}\n\n/* Binary toggle button */\n.cp-tooltip__dp-toggle {\n font-size: 10.5px;\n font-weight: 600;\n padding: 2px 9px;\n border-radius: 8px;\n flex-shrink: 0;\n border: 1px solid #dddddd;\n background: #f8f9fa;\n color: #555555;\n cursor: pointer;\n min-width: 40px;\n text-align: center;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n}\n\n.cp-tooltip__dp-toggle:hover {\n background: #eeeeee;\n border-color: #cccccc;\n}\n\n.cp-tooltip__dp-toggle.on {\n background: rgba(76, 175, 80, 0.15);\n border-color: rgba(76, 175, 80, 0.45);\n color: #2e7d32;\n}\n\n/* Number / float input */\n.cp-tooltip__dp-input {\n width: 62px;\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 5px;\n text-align: right;\n outline: none;\n flex-shrink: 0;\n}\n\n.cp-tooltip__dp-input:focus {\n border-color: #1976d2;\n}\n\n/* Enum select */\n.cp-tooltip__dp-select {\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 4px;\n outline: none;\n flex-shrink: 0;\n max-width: 96px;\n cursor: pointer;\n}\n\n.cp-tooltip__dp-select:focus {\n border-color: #1976d2;\n}\n\n/* Unit suffix */\n.cp-tooltip__dp-unit {\n font-size: 10px;\n color: #888888;\n flex-shrink: 0;\n margin-left: -4px;\n}\n";
|
|
36546
36546
|
var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
36547
36547
|
/**
|
|
36548
36548
|
* @param {Object} sceneViewer - The sceneViewer instance
|
|
@@ -37474,6 +37474,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37474
37474
|
entries.push({
|
|
37475
37475
|
anim: anim,
|
|
37476
37476
|
mesh: mesh,
|
|
37477
|
+
deviceModelRoot: deviceModelRoot,
|
|
37477
37478
|
origPos: mesh.position.clone(),
|
|
37478
37479
|
origRot: mesh.rotation.clone(),
|
|
37479
37480
|
origWorldPos: worldPos,
|
|
@@ -38224,13 +38225,9 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38224
38225
|
value: function _applyAnimation(entry, value) {
|
|
38225
38226
|
var anim = entry.anim,
|
|
38226
38227
|
mesh = entry.mesh,
|
|
38227
|
-
origPos = entry.origPos
|
|
38228
|
-
|
|
38229
|
-
|
|
38230
|
-
origWorldQuat = entry.origWorldQuat,
|
|
38231
|
-
origWorldCenter = entry.origWorldCenter,
|
|
38232
|
-
deviceWorldQuat = entry.deviceWorldQuat,
|
|
38233
|
-
viewerMaxDim = entry.viewerMaxDim;
|
|
38228
|
+
origPos = entry.origPos;
|
|
38229
|
+
entry.origRot;
|
|
38230
|
+
var viewerMaxDim = entry.viewerMaxDim;
|
|
38234
38231
|
var mapping = this._resolveMapping(anim, value);
|
|
38235
38232
|
if (!mapping) return;
|
|
38236
38233
|
var types = anim.transformTypes || [];
|
|
@@ -38242,7 +38239,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38242
38239
|
if (type === 'translation') {
|
|
38243
38240
|
this._applyTranslation(mesh, origPos, mapping.transform);
|
|
38244
38241
|
} else if (type === 'rotation') {
|
|
38245
|
-
this._applyRotation(
|
|
38242
|
+
this._applyRotation(entry, anim, mapping.rotationTransform, viewerMaxDim);
|
|
38246
38243
|
} else if (type === 'color') {
|
|
38247
38244
|
this._applyColor(mesh, mapping.colorTransform);
|
|
38248
38245
|
}
|
|
@@ -38386,25 +38383,71 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
38386
38383
|
mesh.position.set(origPos.x - ((_transform$x = transform.x) !== null && _transform$x !== void 0 ? _transform$x : 0), origPos.y - ((_transform$y = transform.y) !== null && _transform$y !== void 0 ? _transform$y : 0), origPos.z + ((_transform$z = transform.z) !== null && _transform$z !== void 0 ? _transform$z : 0));
|
|
38387
38384
|
}
|
|
38388
38385
|
|
|
38386
|
+
/**
|
|
38387
|
+
* Recompute world-space rest-pose transforms for a behavior entry using the
|
|
38388
|
+
* current parent/device world matrix. origPos/origRot are local rest pose and
|
|
38389
|
+
* stay valid after parent moves; world anchors must be derived at apply time.
|
|
38390
|
+
*
|
|
38391
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
38392
|
+
* @returns {{ origWorldPos: THREE.Vector3, origWorldQuat: THREE.Quaternion, origWorldCenter: THREE.Vector3, deviceWorldQuat: THREE.Quaternion }|null}
|
|
38393
|
+
*/
|
|
38394
|
+
}, {
|
|
38395
|
+
key: "_getRestWorldTransforms",
|
|
38396
|
+
value: function _getRestWorldTransforms(entry) {
|
|
38397
|
+
var mesh = entry.mesh,
|
|
38398
|
+
origPos = entry.origPos,
|
|
38399
|
+
origRot = entry.origRot,
|
|
38400
|
+
deviceModelRoot = entry.deviceModelRoot;
|
|
38401
|
+
if (!mesh || !origPos || !origRot) return null;
|
|
38402
|
+
var savedPos = mesh.position.clone();
|
|
38403
|
+
var savedQuat = mesh.quaternion.clone();
|
|
38404
|
+
mesh.position.copy(origPos);
|
|
38405
|
+
mesh.rotation.copy(origRot);
|
|
38406
|
+
mesh.updateMatrixWorld(true);
|
|
38407
|
+
var origWorldPos = new THREE__namespace.Vector3();
|
|
38408
|
+
mesh.getWorldPosition(origWorldPos);
|
|
38409
|
+
var origWorldQuat = new THREE__namespace.Quaternion();
|
|
38410
|
+
mesh.getWorldQuaternion(origWorldQuat);
|
|
38411
|
+
var box = new THREE__namespace.Box3().setFromObject(mesh);
|
|
38412
|
+
var origWorldCenter = new THREE__namespace.Vector3();
|
|
38413
|
+
if (!box.isEmpty()) box.getCenter(origWorldCenter);else origWorldCenter.copy(origWorldPos);
|
|
38414
|
+
var deviceWorldQuat = new THREE__namespace.Quaternion();
|
|
38415
|
+
if (deviceModelRoot) {
|
|
38416
|
+
deviceModelRoot.getWorldQuaternion(deviceWorldQuat);
|
|
38417
|
+
}
|
|
38418
|
+
mesh.position.copy(savedPos);
|
|
38419
|
+
mesh.quaternion.copy(savedQuat);
|
|
38420
|
+
return {
|
|
38421
|
+
origWorldPos: origWorldPos,
|
|
38422
|
+
origWorldQuat: origWorldQuat,
|
|
38423
|
+
origWorldCenter: origWorldCenter,
|
|
38424
|
+
deviceWorldQuat: deviceWorldQuat
|
|
38425
|
+
};
|
|
38426
|
+
}
|
|
38427
|
+
|
|
38389
38428
|
/**
|
|
38390
38429
|
* Apply a rotation around an arbitrary pivot point using world-space quaternion
|
|
38391
38430
|
* math matching the ReconstructionViewer's setMeshPreviewRotationAxis approach.
|
|
38392
38431
|
* This ensures the runtime axis/pivot matches what the user configured in the
|
|
38393
38432
|
* animation dialog, regardless of the device's parent transform in the scene.
|
|
38394
38433
|
*
|
|
38395
|
-
* @param {
|
|
38396
|
-
* @param {THREE.Vector3} origPos - local position at load time (unused, kept for signature compat)
|
|
38397
|
-
* @param {THREE.Euler} origRot - local rotation at load time (unused)
|
|
38434
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
38398
38435
|
* @param {Object} anim
|
|
38399
38436
|
* @param {number} angleDeg - Degrees
|
|
38400
|
-
* @param {
|
|
38401
|
-
* @param {THREE.Quaternion} origWorldQuat - world quaternion at load time
|
|
38402
|
-
* @param {THREE.Vector3} origWorldCenter - world bounding-box center at load time
|
|
38437
|
+
* @param {number} viewerMaxDim
|
|
38403
38438
|
*/
|
|
38404
38439
|
}, {
|
|
38405
38440
|
key: "_applyRotation",
|
|
38406
|
-
value: function _applyRotation(
|
|
38441
|
+
value: function _applyRotation(entry, anim, angleDeg, viewerMaxDim) {
|
|
38407
38442
|
var _anim$rotAxis, _anim$rotAxisOffset;
|
|
38443
|
+
var mesh = entry.mesh,
|
|
38444
|
+
origPos = entry.origPos,
|
|
38445
|
+
origRot = entry.origRot;
|
|
38446
|
+
var restWorld = this._getRestWorldTransforms(entry);
|
|
38447
|
+
var origWorldPos = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldPos;
|
|
38448
|
+
var origWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldQuat;
|
|
38449
|
+
var origWorldCenter = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldCenter;
|
|
38450
|
+
var deviceWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.deviceWorldQuat;
|
|
38408
38451
|
var angle = THREE__namespace.MathUtils.degToRad(typeof angleDeg === 'number' ? angleDeg : 0);
|
|
38409
38452
|
var axis = ((_anim$rotAxis = anim.rotAxis) !== null && _anim$rotAxis !== void 0 ? _anim$rotAxis : 'x').toLowerCase();
|
|
38410
38453
|
var off = (_anim$rotAxisOffset = anim.rotAxisOffset) !== null && _anim$rotAxisOffset !== void 0 ? _anim$rotAxisOffset : {
|
|
@@ -40151,7 +40194,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
40151
40194
|
* Initialize the CentralPlant manager
|
|
40152
40195
|
*
|
|
40153
40196
|
* @constructor
|
|
40154
|
-
* @version 0.3.
|
|
40197
|
+
* @version 0.3.37
|
|
40155
40198
|
* @updated 2025-10-22
|
|
40156
40199
|
*
|
|
40157
40200
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -35,7 +35,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
35
35
|
* Initialize the CentralPlant manager
|
|
36
36
|
*
|
|
37
37
|
* @constructor
|
|
38
|
-
* @version 0.3.
|
|
38
|
+
* @version 0.3.37
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -121,6 +121,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
121
121
|
entries.push({
|
|
122
122
|
anim: anim,
|
|
123
123
|
mesh: mesh,
|
|
124
|
+
deviceModelRoot: deviceModelRoot,
|
|
124
125
|
origPos: mesh.position.clone(),
|
|
125
126
|
origRot: mesh.rotation.clone(),
|
|
126
127
|
origWorldPos: worldPos,
|
|
@@ -871,13 +872,9 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
871
872
|
value: function _applyAnimation(entry, value) {
|
|
872
873
|
var anim = entry.anim,
|
|
873
874
|
mesh = entry.mesh,
|
|
874
|
-
origPos = entry.origPos
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
origWorldQuat = entry.origWorldQuat,
|
|
878
|
-
origWorldCenter = entry.origWorldCenter,
|
|
879
|
-
deviceWorldQuat = entry.deviceWorldQuat,
|
|
880
|
-
viewerMaxDim = entry.viewerMaxDim;
|
|
875
|
+
origPos = entry.origPos;
|
|
876
|
+
entry.origRot;
|
|
877
|
+
var viewerMaxDim = entry.viewerMaxDim;
|
|
881
878
|
var mapping = this._resolveMapping(anim, value);
|
|
882
879
|
if (!mapping) return;
|
|
883
880
|
var types = anim.transformTypes || [];
|
|
@@ -889,7 +886,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
889
886
|
if (type === 'translation') {
|
|
890
887
|
this._applyTranslation(mesh, origPos, mapping.transform);
|
|
891
888
|
} else if (type === 'rotation') {
|
|
892
|
-
this._applyRotation(
|
|
889
|
+
this._applyRotation(entry, anim, mapping.rotationTransform, viewerMaxDim);
|
|
893
890
|
} else if (type === 'color') {
|
|
894
891
|
this._applyColor(mesh, mapping.colorTransform);
|
|
895
892
|
}
|
|
@@ -1033,25 +1030,71 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1033
1030
|
mesh.position.set(origPos.x - ((_transform$x = transform.x) !== null && _transform$x !== void 0 ? _transform$x : 0), origPos.y - ((_transform$y = transform.y) !== null && _transform$y !== void 0 ? _transform$y : 0), origPos.z + ((_transform$z = transform.z) !== null && _transform$z !== void 0 ? _transform$z : 0));
|
|
1034
1031
|
}
|
|
1035
1032
|
|
|
1033
|
+
/**
|
|
1034
|
+
* Recompute world-space rest-pose transforms for a behavior entry using the
|
|
1035
|
+
* current parent/device world matrix. origPos/origRot are local rest pose and
|
|
1036
|
+
* stay valid after parent moves; world anchors must be derived at apply time.
|
|
1037
|
+
*
|
|
1038
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
1039
|
+
* @returns {{ origWorldPos: THREE.Vector3, origWorldQuat: THREE.Quaternion, origWorldCenter: THREE.Vector3, deviceWorldQuat: THREE.Quaternion }|null}
|
|
1040
|
+
*/
|
|
1041
|
+
}, {
|
|
1042
|
+
key: "_getRestWorldTransforms",
|
|
1043
|
+
value: function _getRestWorldTransforms(entry) {
|
|
1044
|
+
var mesh = entry.mesh,
|
|
1045
|
+
origPos = entry.origPos,
|
|
1046
|
+
origRot = entry.origRot,
|
|
1047
|
+
deviceModelRoot = entry.deviceModelRoot;
|
|
1048
|
+
if (!mesh || !origPos || !origRot) return null;
|
|
1049
|
+
var savedPos = mesh.position.clone();
|
|
1050
|
+
var savedQuat = mesh.quaternion.clone();
|
|
1051
|
+
mesh.position.copy(origPos);
|
|
1052
|
+
mesh.rotation.copy(origRot);
|
|
1053
|
+
mesh.updateMatrixWorld(true);
|
|
1054
|
+
var origWorldPos = new THREE__namespace.Vector3();
|
|
1055
|
+
mesh.getWorldPosition(origWorldPos);
|
|
1056
|
+
var origWorldQuat = new THREE__namespace.Quaternion();
|
|
1057
|
+
mesh.getWorldQuaternion(origWorldQuat);
|
|
1058
|
+
var box = new THREE__namespace.Box3().setFromObject(mesh);
|
|
1059
|
+
var origWorldCenter = new THREE__namespace.Vector3();
|
|
1060
|
+
if (!box.isEmpty()) box.getCenter(origWorldCenter);else origWorldCenter.copy(origWorldPos);
|
|
1061
|
+
var deviceWorldQuat = new THREE__namespace.Quaternion();
|
|
1062
|
+
if (deviceModelRoot) {
|
|
1063
|
+
deviceModelRoot.getWorldQuaternion(deviceWorldQuat);
|
|
1064
|
+
}
|
|
1065
|
+
mesh.position.copy(savedPos);
|
|
1066
|
+
mesh.quaternion.copy(savedQuat);
|
|
1067
|
+
return {
|
|
1068
|
+
origWorldPos: origWorldPos,
|
|
1069
|
+
origWorldQuat: origWorldQuat,
|
|
1070
|
+
origWorldCenter: origWorldCenter,
|
|
1071
|
+
deviceWorldQuat: deviceWorldQuat
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
|
|
1036
1075
|
/**
|
|
1037
1076
|
* Apply a rotation around an arbitrary pivot point using world-space quaternion
|
|
1038
1077
|
* math matching the ReconstructionViewer's setMeshPreviewRotationAxis approach.
|
|
1039
1078
|
* This ensures the runtime axis/pivot matches what the user configured in the
|
|
1040
1079
|
* animation dialog, regardless of the device's parent transform in the scene.
|
|
1041
1080
|
*
|
|
1042
|
-
* @param {
|
|
1043
|
-
* @param {THREE.Vector3} origPos - local position at load time (unused, kept for signature compat)
|
|
1044
|
-
* @param {THREE.Euler} origRot - local rotation at load time (unused)
|
|
1081
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
1045
1082
|
* @param {Object} anim
|
|
1046
1083
|
* @param {number} angleDeg - Degrees
|
|
1047
|
-
* @param {
|
|
1048
|
-
* @param {THREE.Quaternion} origWorldQuat - world quaternion at load time
|
|
1049
|
-
* @param {THREE.Vector3} origWorldCenter - world bounding-box center at load time
|
|
1084
|
+
* @param {number} viewerMaxDim
|
|
1050
1085
|
*/
|
|
1051
1086
|
}, {
|
|
1052
1087
|
key: "_applyRotation",
|
|
1053
|
-
value: function _applyRotation(
|
|
1088
|
+
value: function _applyRotation(entry, anim, angleDeg, viewerMaxDim) {
|
|
1054
1089
|
var _anim$rotAxis, _anim$rotAxisOffset;
|
|
1090
|
+
var mesh = entry.mesh,
|
|
1091
|
+
origPos = entry.origPos,
|
|
1092
|
+
origRot = entry.origRot;
|
|
1093
|
+
var restWorld = this._getRestWorldTransforms(entry);
|
|
1094
|
+
var origWorldPos = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldPos;
|
|
1095
|
+
var origWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldQuat;
|
|
1096
|
+
var origWorldCenter = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldCenter;
|
|
1097
|
+
var deviceWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.deviceWorldQuat;
|
|
1055
1098
|
var angle = THREE__namespace.MathUtils.degToRad(typeof angleDeg === 'number' ? angleDeg : 0);
|
|
1056
1099
|
var axis = ((_anim$rotAxis = anim.rotAxis) !== null && _anim$rotAxis !== void 0 ? _anim$rotAxis : 'x').toLowerCase();
|
|
1057
1100
|
var off = (_anim$rotAxisOffset = anim.rotAxisOffset) !== null && _anim$rotAxisOffset !== void 0 ? _anim$rotAxisOffset : {
|
|
@@ -29,7 +29,7 @@ var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
|
29
29
|
// ---------------------------------------------------------------------------
|
|
30
30
|
// Inline styles (injected once into the document head)
|
|
31
31
|
// ---------------------------------------------------------------------------
|
|
32
|
-
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n}\n\n.cp-tooltip__card {\n background: rgba(
|
|
32
|
+
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n color-scheme: light;\n}\n\n.cp-tooltip__card {\n background: rgba(255, 255, 255, 0.97);\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__header {\n padding: 10px 14px;\n font-weight: 600;\n font-size: 14px;\n color: #2c3e50;\n background: rgba(0, 0, 0, 0.02);\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n letter-spacing: 0.2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 I/O Devices section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__io-section {\n position: relative;\n}\n\n.cp-tooltip__io-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n color: #666666;\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.cp-tooltip__io-trigger:hover {\n background: rgba(0, 0, 0, 0.04);\n color: #333333;\n}\n\n.cp-tooltip__io-trigger-label {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.6px;\n font-weight: 500;\n}\n\n.cp-tooltip__io-arrow {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__io-arrow {\n transform: rotate(90deg);\n}\n\n/* \u2500\u2500 Device list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__device-list {\n max-height: 0;\n overflow: hidden;\n transition: max-height 0.25s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__device-list {\n max-height: 300px;\n}\n\n.cp-tooltip__device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px 6px 20px;\n color: #555555;\n font-size: 12px;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n transition: background 0.1s ease;\n}\n\n.cp-tooltip__device-item:hover {\n background: rgba(0, 0, 0, 0.03);\n}\n\n.cp-tooltip__device-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #1976d2;\n flex-shrink: 0;\n}\n\n.cp-tooltip__device-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__no-devices {\n padding: 8px 14px;\n color: #888888;\n font-size: 12px;\n font-style: italic;\n}\n\n/* \u2500\u2500 Caret arrow pointing down \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__caret {\n width: 0;\n height: 0;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid rgba(255, 255, 255, 0.97);\n margin: 0 auto;\n position: relative;\n top: -1px;\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.1));\n}\n\n/* \u2500\u2500 Data point rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__dp-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 4px 12px 4px 30px;\n font-size: 11.5px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n min-height: 24px;\n}\n\n.cp-tooltip__dp-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #666666;\n}\n\n/* Read-only state badge */\n.cp-tooltip__dp-badge {\n font-size: 10.5px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 8px;\n flex-shrink: 0;\n background: #f0f2f5;\n color: #666666;\n min-width: 30px;\n text-align: center;\n letter-spacing: 0.2px;\n}\n\n.cp-tooltip__dp-badge.active {\n background: rgba(76, 175, 80, 0.15);\n color: #2e7d32;\n}\n\n/* Binary toggle button */\n.cp-tooltip__dp-toggle {\n font-size: 10.5px;\n font-weight: 600;\n padding: 2px 9px;\n border-radius: 8px;\n flex-shrink: 0;\n border: 1px solid #dddddd;\n background: #f8f9fa;\n color: #555555;\n cursor: pointer;\n min-width: 40px;\n text-align: center;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n}\n\n.cp-tooltip__dp-toggle:hover {\n background: #eeeeee;\n border-color: #cccccc;\n}\n\n.cp-tooltip__dp-toggle.on {\n background: rgba(76, 175, 80, 0.15);\n border-color: rgba(76, 175, 80, 0.45);\n color: #2e7d32;\n}\n\n/* Number / float input */\n.cp-tooltip__dp-input {\n width: 62px;\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 5px;\n text-align: right;\n outline: none;\n flex-shrink: 0;\n}\n\n.cp-tooltip__dp-input:focus {\n border-color: #1976d2;\n}\n\n/* Enum select */\n.cp-tooltip__dp-select {\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 4px;\n outline: none;\n flex-shrink: 0;\n max-width: 96px;\n cursor: pointer;\n}\n\n.cp-tooltip__dp-select:focus {\n border-color: #1976d2;\n}\n\n/* Unit suffix */\n.cp-tooltip__dp-unit {\n font-size: 10px;\n color: #888888;\n flex-shrink: 0;\n margin-left: -4px;\n}\n";
|
|
33
33
|
var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
34
34
|
/**
|
|
35
35
|
* @param {Object} sceneViewer - The sceneViewer instance
|
|
@@ -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.37
|
|
35
35
|
* @updated 2025-10-22
|
|
36
36
|
*
|
|
37
37
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -97,6 +97,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
97
97
|
entries.push({
|
|
98
98
|
anim: anim,
|
|
99
99
|
mesh: mesh,
|
|
100
|
+
deviceModelRoot: deviceModelRoot,
|
|
100
101
|
origPos: mesh.position.clone(),
|
|
101
102
|
origRot: mesh.rotation.clone(),
|
|
102
103
|
origWorldPos: worldPos,
|
|
@@ -847,13 +848,9 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
847
848
|
value: function _applyAnimation(entry, value) {
|
|
848
849
|
var anim = entry.anim,
|
|
849
850
|
mesh = entry.mesh,
|
|
850
|
-
origPos = entry.origPos
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
origWorldQuat = entry.origWorldQuat,
|
|
854
|
-
origWorldCenter = entry.origWorldCenter,
|
|
855
|
-
deviceWorldQuat = entry.deviceWorldQuat,
|
|
856
|
-
viewerMaxDim = entry.viewerMaxDim;
|
|
851
|
+
origPos = entry.origPos;
|
|
852
|
+
entry.origRot;
|
|
853
|
+
var viewerMaxDim = entry.viewerMaxDim;
|
|
857
854
|
var mapping = this._resolveMapping(anim, value);
|
|
858
855
|
if (!mapping) return;
|
|
859
856
|
var types = anim.transformTypes || [];
|
|
@@ -865,7 +862,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
865
862
|
if (type === 'translation') {
|
|
866
863
|
this._applyTranslation(mesh, origPos, mapping.transform);
|
|
867
864
|
} else if (type === 'rotation') {
|
|
868
|
-
this._applyRotation(
|
|
865
|
+
this._applyRotation(entry, anim, mapping.rotationTransform, viewerMaxDim);
|
|
869
866
|
} else if (type === 'color') {
|
|
870
867
|
this._applyColor(mesh, mapping.colorTransform);
|
|
871
868
|
}
|
|
@@ -1009,25 +1006,71 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
1009
1006
|
mesh.position.set(origPos.x - ((_transform$x = transform.x) !== null && _transform$x !== void 0 ? _transform$x : 0), origPos.y - ((_transform$y = transform.y) !== null && _transform$y !== void 0 ? _transform$y : 0), origPos.z + ((_transform$z = transform.z) !== null && _transform$z !== void 0 ? _transform$z : 0));
|
|
1010
1007
|
}
|
|
1011
1008
|
|
|
1009
|
+
/**
|
|
1010
|
+
* Recompute world-space rest-pose transforms for a behavior entry using the
|
|
1011
|
+
* current parent/device world matrix. origPos/origRot are local rest pose and
|
|
1012
|
+
* stay valid after parent moves; world anchors must be derived at apply time.
|
|
1013
|
+
*
|
|
1014
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
1015
|
+
* @returns {{ origWorldPos: THREE.Vector3, origWorldQuat: THREE.Quaternion, origWorldCenter: THREE.Vector3, deviceWorldQuat: THREE.Quaternion }|null}
|
|
1016
|
+
*/
|
|
1017
|
+
}, {
|
|
1018
|
+
key: "_getRestWorldTransforms",
|
|
1019
|
+
value: function _getRestWorldTransforms(entry) {
|
|
1020
|
+
var mesh = entry.mesh,
|
|
1021
|
+
origPos = entry.origPos,
|
|
1022
|
+
origRot = entry.origRot,
|
|
1023
|
+
deviceModelRoot = entry.deviceModelRoot;
|
|
1024
|
+
if (!mesh || !origPos || !origRot) return null;
|
|
1025
|
+
var savedPos = mesh.position.clone();
|
|
1026
|
+
var savedQuat = mesh.quaternion.clone();
|
|
1027
|
+
mesh.position.copy(origPos);
|
|
1028
|
+
mesh.rotation.copy(origRot);
|
|
1029
|
+
mesh.updateMatrixWorld(true);
|
|
1030
|
+
var origWorldPos = new THREE.Vector3();
|
|
1031
|
+
mesh.getWorldPosition(origWorldPos);
|
|
1032
|
+
var origWorldQuat = new THREE.Quaternion();
|
|
1033
|
+
mesh.getWorldQuaternion(origWorldQuat);
|
|
1034
|
+
var box = new THREE.Box3().setFromObject(mesh);
|
|
1035
|
+
var origWorldCenter = new THREE.Vector3();
|
|
1036
|
+
if (!box.isEmpty()) box.getCenter(origWorldCenter);else origWorldCenter.copy(origWorldPos);
|
|
1037
|
+
var deviceWorldQuat = new THREE.Quaternion();
|
|
1038
|
+
if (deviceModelRoot) {
|
|
1039
|
+
deviceModelRoot.getWorldQuaternion(deviceWorldQuat);
|
|
1040
|
+
}
|
|
1041
|
+
mesh.position.copy(savedPos);
|
|
1042
|
+
mesh.quaternion.copy(savedQuat);
|
|
1043
|
+
return {
|
|
1044
|
+
origWorldPos: origWorldPos,
|
|
1045
|
+
origWorldQuat: origWorldQuat,
|
|
1046
|
+
origWorldCenter: origWorldCenter,
|
|
1047
|
+
deviceWorldQuat: deviceWorldQuat
|
|
1048
|
+
};
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1012
1051
|
/**
|
|
1013
1052
|
* Apply a rotation around an arbitrary pivot point using world-space quaternion
|
|
1014
1053
|
* math matching the ReconstructionViewer's setMeshPreviewRotationAxis approach.
|
|
1015
1054
|
* This ensures the runtime axis/pivot matches what the user configured in the
|
|
1016
1055
|
* animation dialog, regardless of the device's parent transform in the scene.
|
|
1017
1056
|
*
|
|
1018
|
-
* @param {
|
|
1019
|
-
* @param {THREE.Vector3} origPos - local position at load time (unused, kept for signature compat)
|
|
1020
|
-
* @param {THREE.Euler} origRot - local rotation at load time (unused)
|
|
1057
|
+
* @param {{ mesh, origPos, origRot, deviceModelRoot }} entry
|
|
1021
1058
|
* @param {Object} anim
|
|
1022
1059
|
* @param {number} angleDeg - Degrees
|
|
1023
|
-
* @param {
|
|
1024
|
-
* @param {THREE.Quaternion} origWorldQuat - world quaternion at load time
|
|
1025
|
-
* @param {THREE.Vector3} origWorldCenter - world bounding-box center at load time
|
|
1060
|
+
* @param {number} viewerMaxDim
|
|
1026
1061
|
*/
|
|
1027
1062
|
}, {
|
|
1028
1063
|
key: "_applyRotation",
|
|
1029
|
-
value: function _applyRotation(
|
|
1064
|
+
value: function _applyRotation(entry, anim, angleDeg, viewerMaxDim) {
|
|
1030
1065
|
var _anim$rotAxis, _anim$rotAxisOffset;
|
|
1066
|
+
var mesh = entry.mesh,
|
|
1067
|
+
origPos = entry.origPos,
|
|
1068
|
+
origRot = entry.origRot;
|
|
1069
|
+
var restWorld = this._getRestWorldTransforms(entry);
|
|
1070
|
+
var origWorldPos = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldPos;
|
|
1071
|
+
var origWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldQuat;
|
|
1072
|
+
var origWorldCenter = restWorld === null || restWorld === void 0 ? void 0 : restWorld.origWorldCenter;
|
|
1073
|
+
var deviceWorldQuat = restWorld === null || restWorld === void 0 ? void 0 : restWorld.deviceWorldQuat;
|
|
1031
1074
|
var angle = THREE.MathUtils.degToRad(typeof angleDeg === 'number' ? angleDeg : 0);
|
|
1032
1075
|
var axis = ((_anim$rotAxis = anim.rotAxis) !== null && _anim$rotAxis !== void 0 ? _anim$rotAxis : 'x').toLowerCase();
|
|
1033
1076
|
var off = (_anim$rotAxisOffset = anim.rotAxisOffset) !== null && _anim$rotAxisOffset !== void 0 ? _anim$rotAxisOffset : {
|
|
@@ -5,7 +5,7 @@ import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
|
5
5
|
// ---------------------------------------------------------------------------
|
|
6
6
|
// Inline styles (injected once into the document head)
|
|
7
7
|
// ---------------------------------------------------------------------------
|
|
8
|
-
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n}\n\n.cp-tooltip__card {\n background: rgba(
|
|
8
|
+
var TOOLTIP_STYLES = "\n.cp-tooltip {\n position: absolute;\n pointer-events: auto;\n z-index: 10000;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n font-size: 13px;\n line-height: 1.4;\n user-select: none;\n min-width: 200px;\n max-width: 280px;\n transform: translate(-50%, -100%);\n margin-top: -12px;\n transition: opacity 0.15s ease;\n color-scheme: light;\n}\n\n.cp-tooltip__card {\n background: rgba(255, 255, 255, 0.97);\n border: 1px solid rgba(0, 0, 0, 0.1);\n border-radius: 10px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n}\n\n/* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__header {\n padding: 10px 14px;\n font-weight: 600;\n font-size: 14px;\n color: #2c3e50;\n background: rgba(0, 0, 0, 0.02);\n border-bottom: 1px solid rgba(0, 0, 0, 0.08);\n letter-spacing: 0.2px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 I/O Devices section \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__io-section {\n position: relative;\n}\n\n.cp-tooltip__io-trigger {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 8px 14px;\n color: #666666;\n cursor: pointer;\n transition: background 0.12s ease, color 0.12s ease;\n}\n\n.cp-tooltip__io-trigger:hover {\n background: rgba(0, 0, 0, 0.04);\n color: #333333;\n}\n\n.cp-tooltip__io-trigger-label {\n font-size: 12px;\n text-transform: uppercase;\n letter-spacing: 0.6px;\n font-weight: 500;\n}\n\n.cp-tooltip__io-arrow {\n font-size: 10px;\n transition: transform 0.2s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__io-arrow {\n transform: rotate(90deg);\n}\n\n/* \u2500\u2500 Device list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__device-list {\n max-height: 0;\n overflow: hidden;\n transition: max-height 0.25s ease;\n}\n\n.cp-tooltip__io-section.expanded .cp-tooltip__device-list {\n max-height: 300px;\n}\n\n.cp-tooltip__device-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 6px 14px 6px 20px;\n color: #555555;\n font-size: 12px;\n border-top: 1px solid rgba(0, 0, 0, 0.06);\n transition: background 0.1s ease;\n}\n\n.cp-tooltip__device-item:hover {\n background: rgba(0, 0, 0, 0.03);\n}\n\n.cp-tooltip__device-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: #1976d2;\n flex-shrink: 0;\n}\n\n.cp-tooltip__device-name {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n/* \u2500\u2500 Empty state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__no-devices {\n padding: 8px 14px;\n color: #888888;\n font-size: 12px;\n font-style: italic;\n}\n\n/* \u2500\u2500 Caret arrow pointing down \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__caret {\n width: 0;\n height: 0;\n border-left: 7px solid transparent;\n border-right: 7px solid transparent;\n border-top: 7px solid rgba(255, 255, 255, 0.97);\n margin: 0 auto;\n position: relative;\n top: -1px;\n filter: drop-shadow(0 1px 0 rgba(0, 0, 0, 0.1));\n}\n\n/* \u2500\u2500 Data point rows \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n.cp-tooltip__dp-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 4px 12px 4px 30px;\n font-size: 11.5px;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n min-height: 24px;\n}\n\n.cp-tooltip__dp-name {\n flex: 1;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n color: #666666;\n}\n\n/* Read-only state badge */\n.cp-tooltip__dp-badge {\n font-size: 10.5px;\n font-weight: 600;\n padding: 1px 7px;\n border-radius: 8px;\n flex-shrink: 0;\n background: #f0f2f5;\n color: #666666;\n min-width: 30px;\n text-align: center;\n letter-spacing: 0.2px;\n}\n\n.cp-tooltip__dp-badge.active {\n background: rgba(76, 175, 80, 0.15);\n color: #2e7d32;\n}\n\n/* Binary toggle button */\n.cp-tooltip__dp-toggle {\n font-size: 10.5px;\n font-weight: 600;\n padding: 2px 9px;\n border-radius: 8px;\n flex-shrink: 0;\n border: 1px solid #dddddd;\n background: #f8f9fa;\n color: #555555;\n cursor: pointer;\n min-width: 40px;\n text-align: center;\n transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;\n}\n\n.cp-tooltip__dp-toggle:hover {\n background: #eeeeee;\n border-color: #cccccc;\n}\n\n.cp-tooltip__dp-toggle.on {\n background: rgba(76, 175, 80, 0.15);\n border-color: rgba(76, 175, 80, 0.45);\n color: #2e7d32;\n}\n\n/* Number / float input */\n.cp-tooltip__dp-input {\n width: 62px;\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 5px;\n text-align: right;\n outline: none;\n flex-shrink: 0;\n}\n\n.cp-tooltip__dp-input:focus {\n border-color: #1976d2;\n}\n\n/* Enum select */\n.cp-tooltip__dp-select {\n background: #f8f9fa;\n border: 1px solid #dddddd;\n border-radius: 4px;\n color: #333333;\n font-size: 11px;\n padding: 2px 4px;\n outline: none;\n flex-shrink: 0;\n max-width: 96px;\n cursor: pointer;\n}\n\n.cp-tooltip__dp-select:focus {\n border-color: #1976d2;\n}\n\n/* Unit suffix */\n.cp-tooltip__dp-unit {\n font-size: 10px;\n color: #888888;\n flex-shrink: 0;\n margin-left: -4px;\n}\n";
|
|
9
9
|
var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
10
10
|
/**
|
|
11
11
|
* @param {Object} sceneViewer - The sceneViewer instance
|