@2112-lab/central-plant 0.3.21 → 0.3.23
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 +566 -131
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/core/centralPlantInternals.js +2 -0
- package/dist/cjs/src/core/sceneViewer.js +1 -1
- package/dist/cjs/src/index.js +2 -0
- package/dist/cjs/src/managers/behaviors/IoAnimationManager.js +422 -0
- package/dist/cjs/src/managers/cache/s3Timing.js +19 -32
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +9 -7
- package/dist/cjs/src/managers/scene/modelManager.js +141 -90
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/core/centralPlantInternals.js +2 -0
- package/dist/esm/src/core/sceneViewer.js +1 -1
- package/dist/esm/src/index.js +1 -0
- package/dist/esm/src/managers/behaviors/IoAnimationManager.js +398 -0
- package/dist/esm/src/managers/cache/s3Timing.js +19 -32
- package/dist/esm/src/managers/scene/componentTooltipManager.js +9 -7
- package/dist/esm/src/managers/scene/modelManager.js +142 -91
- package/package.json +2 -2
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
import { inherits as _inherits, createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, superPropGet as _superPropGet, toConsumableArray as _toConsumableArray, classCallCheck as _classCallCheck, callSuper as _callSuper } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
4
|
+
|
|
5
|
+
var IoAnimationManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
6
|
+
function IoAnimationManager(sceneViewer) {
|
|
7
|
+
var _this;
|
|
8
|
+
_classCallCheck(this, IoAnimationManager);
|
|
9
|
+
_this = _callSuper(this, IoAnimationManager);
|
|
10
|
+
_this.sceneViewer = sceneViewer;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Map: `${parentUuid}::${attachmentId}` → Array<{
|
|
14
|
+
* anim: Object,
|
|
15
|
+
* mesh: THREE.Object3D,
|
|
16
|
+
* origPos: THREE.Vector3,
|
|
17
|
+
* origRot: THREE.Euler
|
|
18
|
+
* }>
|
|
19
|
+
*/
|
|
20
|
+
_this._entries = new Map();
|
|
21
|
+
return _this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
25
|
+
// PUBLIC API
|
|
26
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Register animation entries for one attached I/O device.
|
|
30
|
+
* Should be called after the device GLB has been merged into the scene
|
|
31
|
+
* so that mesh references are live.
|
|
32
|
+
*
|
|
33
|
+
* @param {string} attachmentId - The attachment key (e.g. 'attch-switch-01')
|
|
34
|
+
* @param {Object|Array} animationConfig - Serialized config; either the full object
|
|
35
|
+
* { animations: [...] } or a plain array of animation entries.
|
|
36
|
+
* @param {THREE.Object3D} deviceModelRoot - The device's root Object3D as added to the scene
|
|
37
|
+
* @param {string} parentUuid - UUID of the host component Object3D
|
|
38
|
+
*/
|
|
39
|
+
_inherits(IoAnimationManager, _BaseDisposable);
|
|
40
|
+
return _createClass(IoAnimationManager, [{
|
|
41
|
+
key: "loadAnimations",
|
|
42
|
+
value: function loadAnimations(attachmentId, animationConfig, deviceModelRoot, parentUuid) {
|
|
43
|
+
var _animationConfig$anim;
|
|
44
|
+
if (!animationConfig || !deviceModelRoot) return;
|
|
45
|
+
var anims = Array.isArray(animationConfig) ? animationConfig : (_animationConfig$anim = animationConfig.animations) !== null && _animationConfig$anim !== void 0 ? _animationConfig$anim : [];
|
|
46
|
+
if (!anims.length) return;
|
|
47
|
+
var key = this._key(parentUuid, attachmentId);
|
|
48
|
+
var entries = [];
|
|
49
|
+
var _iterator = _createForOfIteratorHelper(anims),
|
|
50
|
+
_step;
|
|
51
|
+
try {
|
|
52
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
53
|
+
var anim = _step.value;
|
|
54
|
+
var mesh = this._resolveMesh(anim, deviceModelRoot);
|
|
55
|
+
if (!mesh) {
|
|
56
|
+
console.warn("[IoAnimationManager] Could not find mesh for animation \"".concat(anim.name || anim.stateVariable, "\" (uuid: ").concat(anim.meshUuid, ", name: \"").concat(anim.meshName, "\")"));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
entries.push({
|
|
60
|
+
anim: anim,
|
|
61
|
+
mesh: mesh,
|
|
62
|
+
origPos: mesh.position.clone(),
|
|
63
|
+
origRot: mesh.rotation.clone()
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
_iterator.e(err);
|
|
68
|
+
} finally {
|
|
69
|
+
_iterator.f();
|
|
70
|
+
}
|
|
71
|
+
if (entries.length) {
|
|
72
|
+
this._entries.set(key, entries);
|
|
73
|
+
console.log("[IoAnimationManager] Loaded ".concat(entries.length, " animation(s) for attachment \"").concat(attachmentId, "\" (parent: ").concat(parentUuid, ")"));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Apply animations triggered by an IO device state change.
|
|
79
|
+
* Should be called in parallel with BehaviorManager.triggerState().
|
|
80
|
+
*
|
|
81
|
+
* @param {string} attachmentId - Raw attachment key (not scoped)
|
|
82
|
+
* @param {string} dataPointId - The data point / state variable id that changed
|
|
83
|
+
* @param {*} value - New state value
|
|
84
|
+
* @param {string} parentUuid - UUID of the host component
|
|
85
|
+
*/
|
|
86
|
+
}, {
|
|
87
|
+
key: "triggerState",
|
|
88
|
+
value: function triggerState(attachmentId, dataPointId, value, parentUuid) {
|
|
89
|
+
var key = this._key(parentUuid, attachmentId);
|
|
90
|
+
var entries = this._entries.get(key);
|
|
91
|
+
if (!(entries !== null && entries !== void 0 && entries.length)) return;
|
|
92
|
+
var _iterator2 = _createForOfIteratorHelper(entries),
|
|
93
|
+
_step2;
|
|
94
|
+
try {
|
|
95
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
96
|
+
var entry = _step2.value;
|
|
97
|
+
if (entry.anim.stateVariable !== dataPointId) continue;
|
|
98
|
+
this._applyAnimation(entry, value);
|
|
99
|
+
}
|
|
100
|
+
} catch (err) {
|
|
101
|
+
_iterator2.e(err);
|
|
102
|
+
} finally {
|
|
103
|
+
_iterator2.f();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Remove all animation entries associated with a given host component.
|
|
109
|
+
* Call when a component is removed from the scene.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} parentUuid
|
|
112
|
+
*/
|
|
113
|
+
}, {
|
|
114
|
+
key: "unloadForComponent",
|
|
115
|
+
value: function unloadForComponent(parentUuid) {
|
|
116
|
+
var prefix = "".concat(parentUuid, "::");
|
|
117
|
+
var _iterator3 = _createForOfIteratorHelper(this._entries.keys()),
|
|
118
|
+
_step3;
|
|
119
|
+
try {
|
|
120
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
121
|
+
var key = _step3.value;
|
|
122
|
+
if (key.startsWith(prefix)) {
|
|
123
|
+
this._entries.delete(key);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
_iterator3.e(err);
|
|
128
|
+
} finally {
|
|
129
|
+
_iterator3.f();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}, {
|
|
133
|
+
key: "dispose",
|
|
134
|
+
value: function dispose() {
|
|
135
|
+
this._entries.clear();
|
|
136
|
+
_superPropGet(IoAnimationManager, "dispose", this, 3)([]);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
140
|
+
// PRIVATE HELPERS
|
|
141
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
142
|
+
}, {
|
|
143
|
+
key: "_key",
|
|
144
|
+
value: function _key(parentUuid, attachmentId) {
|
|
145
|
+
return "".concat(parentUuid, "::").concat(attachmentId);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Find the mesh inside `root` using UUID first, then name as fallback.
|
|
150
|
+
* GLTFLoader assigns fresh UUIDs on every load, so name is the reliable key.
|
|
151
|
+
* @param {Object} anim
|
|
152
|
+
* @param {THREE.Object3D} root
|
|
153
|
+
* @returns {THREE.Object3D|null}
|
|
154
|
+
*/
|
|
155
|
+
}, {
|
|
156
|
+
key: "_resolveMesh",
|
|
157
|
+
value: function _resolveMesh(anim, root) {
|
|
158
|
+
var found = null;
|
|
159
|
+
root.traverse(function (obj) {
|
|
160
|
+
if (found) return;
|
|
161
|
+
|
|
162
|
+
// Prefer UUID match (works when the device was cloned from a cached instance
|
|
163
|
+
// whose UUIDs were preserved)
|
|
164
|
+
if (anim.meshUuid && obj.uuid === anim.meshUuid) {
|
|
165
|
+
found = obj;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Reliable fallback: mesh name
|
|
170
|
+
if (anim.meshName && obj.name === anim.meshName) {
|
|
171
|
+
found = obj;
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
return found;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Resolve which mapping row to use and apply all declared transform types.
|
|
179
|
+
* @param {{ anim, mesh, origPos, origRot }} entry
|
|
180
|
+
* @param {*} value - Current state value
|
|
181
|
+
*/
|
|
182
|
+
}, {
|
|
183
|
+
key: "_applyAnimation",
|
|
184
|
+
value: function _applyAnimation(entry, value) {
|
|
185
|
+
var anim = entry.anim,
|
|
186
|
+
mesh = entry.mesh,
|
|
187
|
+
origPos = entry.origPos,
|
|
188
|
+
origRot = entry.origRot;
|
|
189
|
+
var mapping = this._resolveMapping(anim, value);
|
|
190
|
+
if (!mapping) return;
|
|
191
|
+
var types = anim.transformTypes || [];
|
|
192
|
+
var _iterator4 = _createForOfIteratorHelper(types),
|
|
193
|
+
_step4;
|
|
194
|
+
try {
|
|
195
|
+
for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
|
|
196
|
+
var type = _step4.value;
|
|
197
|
+
if (type === 'translation') {
|
|
198
|
+
this._applyTranslation(mesh, origPos, mapping.transform);
|
|
199
|
+
} else if (type === 'rotation') {
|
|
200
|
+
this._applyRotation(mesh, origPos, origRot, anim, mapping.rotationTransform);
|
|
201
|
+
} else if (type === 'color') {
|
|
202
|
+
this._applyColor(mesh, mapping.colorTransform);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} catch (err) {
|
|
206
|
+
_iterator4.e(err);
|
|
207
|
+
} finally {
|
|
208
|
+
_iterator4.f();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Find the mapping row that matches `value` for the given animation entry.
|
|
214
|
+
*
|
|
215
|
+
* - binary / enum: find where mapping.stateValue == value (loose equality so
|
|
216
|
+
* JSON-deserialised "true" matches boolean true)
|
|
217
|
+
* - continuous: linear interpolation between ordered anchor points
|
|
218
|
+
*
|
|
219
|
+
* @returns {Object|null} The matched/interpolated mapping row, or null.
|
|
220
|
+
*/
|
|
221
|
+
}, {
|
|
222
|
+
key: "_resolveMapping",
|
|
223
|
+
value: function _resolveMapping(anim, value) {
|
|
224
|
+
var stateType = anim.stateType,
|
|
225
|
+
mappings = anim.mappings;
|
|
226
|
+
if (!(mappings !== null && mappings !== void 0 && mappings.length)) return null;
|
|
227
|
+
if (stateType === 'binary' || stateType === 'enum') {
|
|
228
|
+
var _mappings$find;
|
|
229
|
+
// eslint-disable-next-line eqeqeq
|
|
230
|
+
return (_mappings$find = mappings.find(function (m) {
|
|
231
|
+
return m.stateValue == value;
|
|
232
|
+
})) !== null && _mappings$find !== void 0 ? _mappings$find : null;
|
|
233
|
+
}
|
|
234
|
+
if (stateType === 'continuous') {
|
|
235
|
+
var num = Number(value);
|
|
236
|
+
if (isNaN(num)) return null;
|
|
237
|
+
|
|
238
|
+
// Sort anchors by numeric stateValue
|
|
239
|
+
var sorted = _toConsumableArray(mappings).filter(function (m) {
|
|
240
|
+
return m.stateValue != null && !isNaN(Number(m.stateValue));
|
|
241
|
+
}).sort(function (a, b) {
|
|
242
|
+
return Number(a.stateValue) - Number(b.stateValue);
|
|
243
|
+
});
|
|
244
|
+
if (!sorted.length) return null;
|
|
245
|
+
if (sorted.length === 1) return sorted[0];
|
|
246
|
+
|
|
247
|
+
// Clamp to range
|
|
248
|
+
if (num <= Number(sorted[0].stateValue)) return sorted[0];
|
|
249
|
+
if (num >= Number(sorted[sorted.length - 1].stateValue)) return sorted[sorted.length - 1];
|
|
250
|
+
|
|
251
|
+
// Find surrounding anchors and interpolate
|
|
252
|
+
for (var i = 0; i < sorted.length - 1; i++) {
|
|
253
|
+
var lo = sorted[i];
|
|
254
|
+
var hi = sorted[i + 1];
|
|
255
|
+
var loVal = Number(lo.stateValue);
|
|
256
|
+
var hiVal = Number(hi.stateValue);
|
|
257
|
+
if (num >= loVal && num <= hiVal) {
|
|
258
|
+
var t = (num - loVal) / (hiVal - loVal);
|
|
259
|
+
return this._lerpMapping(lo, hi, t);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Linear-interpolate between two mapping rows.
|
|
268
|
+
* @param {Object} lo - lower anchor mapping
|
|
269
|
+
* @param {Object} hi - upper anchor mapping
|
|
270
|
+
* @param {number} t - 0..1
|
|
271
|
+
*/
|
|
272
|
+
}, {
|
|
273
|
+
key: "_lerpMapping",
|
|
274
|
+
value: function _lerpMapping(lo, hi, t) {
|
|
275
|
+
var _lo$transform$x, _lo$transform, _hi$transform$x, _hi$transform, _lo$transform$y, _lo$transform2, _hi$transform$y, _hi$transform2, _lo$transform$z, _lo$transform3, _hi$transform$z, _hi$transform3;
|
|
276
|
+
var lerp = function lerp(a, b) {
|
|
277
|
+
return a + (b - a) * t;
|
|
278
|
+
};
|
|
279
|
+
var transform = {
|
|
280
|
+
x: lerp((_lo$transform$x = (_lo$transform = lo.transform) === null || _lo$transform === void 0 ? void 0 : _lo$transform.x) !== null && _lo$transform$x !== void 0 ? _lo$transform$x : 0, (_hi$transform$x = (_hi$transform = hi.transform) === null || _hi$transform === void 0 ? void 0 : _hi$transform.x) !== null && _hi$transform$x !== void 0 ? _hi$transform$x : 0),
|
|
281
|
+
y: lerp((_lo$transform$y = (_lo$transform2 = lo.transform) === null || _lo$transform2 === void 0 ? void 0 : _lo$transform2.y) !== null && _lo$transform$y !== void 0 ? _lo$transform$y : 0, (_hi$transform$y = (_hi$transform2 = hi.transform) === null || _hi$transform2 === void 0 ? void 0 : _hi$transform2.y) !== null && _hi$transform$y !== void 0 ? _hi$transform$y : 0),
|
|
282
|
+
z: lerp((_lo$transform$z = (_lo$transform3 = lo.transform) === null || _lo$transform3 === void 0 ? void 0 : _lo$transform3.z) !== null && _lo$transform$z !== void 0 ? _lo$transform$z : 0, (_hi$transform$z = (_hi$transform3 = hi.transform) === null || _hi$transform3 === void 0 ? void 0 : _hi$transform3.z) !== null && _hi$transform$z !== void 0 ? _hi$transform$z : 0)
|
|
283
|
+
};
|
|
284
|
+
var rotationTransform = lerp(typeof lo.rotationTransform === 'number' ? lo.rotationTransform : 0, typeof hi.rotationTransform === 'number' ? hi.rotationTransform : 0);
|
|
285
|
+
|
|
286
|
+
// Color interpolation: convert hex → RGB components → lerp → back to hex
|
|
287
|
+
var colorTransform = this._lerpHex(lo.colorTransform, hi.colorTransform, t);
|
|
288
|
+
return {
|
|
289
|
+
stateValue: null,
|
|
290
|
+
transform: transform,
|
|
291
|
+
rotationTransform: rotationTransform,
|
|
292
|
+
colorTransform: colorTransform
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Interpolate between two hex colour strings.
|
|
298
|
+
*/
|
|
299
|
+
}, {
|
|
300
|
+
key: "_lerpHex",
|
|
301
|
+
value: function _lerpHex(hexA, hexB, t) {
|
|
302
|
+
try {
|
|
303
|
+
var ca = new THREE.Color(hexA);
|
|
304
|
+
var cb = new THREE.Color(hexB);
|
|
305
|
+
ca.lerp(cb, t);
|
|
306
|
+
return "#".concat(ca.getHexString());
|
|
307
|
+
} catch (_unused) {
|
|
308
|
+
return hexA !== null && hexA !== void 0 ? hexA : '#ffffff';
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
313
|
+
// TRANSFORM APPLIERS
|
|
314
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Apply a position delta relative to the mesh's original position.
|
|
318
|
+
* @param {THREE.Object3D} mesh
|
|
319
|
+
* @param {THREE.Vector3} origPos
|
|
320
|
+
* @param {{ x, y, z }} transform - Deltas
|
|
321
|
+
*/
|
|
322
|
+
}, {
|
|
323
|
+
key: "_applyTranslation",
|
|
324
|
+
value: function _applyTranslation(mesh, origPos, transform) {
|
|
325
|
+
var _transform$x, _transform$y, _transform$z;
|
|
326
|
+
if (!transform) return;
|
|
327
|
+
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));
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Apply a rotation around an arbitrary pivot point in device-local space,
|
|
332
|
+
* optionally also displacing the mesh position to simulate orbital motion.
|
|
333
|
+
*
|
|
334
|
+
* Math (all in device-local space):
|
|
335
|
+
* pivot = rotAxisOffset
|
|
336
|
+
* delta = origPos - pivot
|
|
337
|
+
* newDelta = rotate(delta, angle, axis)
|
|
338
|
+
* newPos = pivot + newDelta
|
|
339
|
+
* newRot[axis] = origRot[axis] + angle
|
|
340
|
+
*
|
|
341
|
+
* @param {THREE.Object3D} mesh
|
|
342
|
+
* @param {THREE.Vector3} origPos
|
|
343
|
+
* @param {THREE.Euler} origRot
|
|
344
|
+
* @param {Object} anim
|
|
345
|
+
* @param {number} angleDeg - Degrees
|
|
346
|
+
*/
|
|
347
|
+
}, {
|
|
348
|
+
key: "_applyRotation",
|
|
349
|
+
value: function _applyRotation(mesh, origPos, origRot, anim, angleDeg) {
|
|
350
|
+
var _anim$rotAxis, _anim$rotAxisOffset, _off$x, _off$y, _off$z;
|
|
351
|
+
var angle = THREE.MathUtils.degToRad(typeof angleDeg === 'number' ? angleDeg : 0);
|
|
352
|
+
var axis = ((_anim$rotAxis = anim.rotAxis) !== null && _anim$rotAxis !== void 0 ? _anim$rotAxis : 'x').toLowerCase();
|
|
353
|
+
var off = (_anim$rotAxisOffset = anim.rotAxisOffset) !== null && _anim$rotAxisOffset !== void 0 ? _anim$rotAxisOffset : {
|
|
354
|
+
x: 0,
|
|
355
|
+
y: 0,
|
|
356
|
+
z: 0
|
|
357
|
+
};
|
|
358
|
+
|
|
359
|
+
// Unit vector for the chosen axis
|
|
360
|
+
var axisVec = new THREE.Vector3(axis === 'x' ? 1 : 0, axis === 'y' ? 1 : 0, axis === 'z' ? 1 : 0);
|
|
361
|
+
var pivot = new THREE.Vector3((_off$x = off.x) !== null && _off$x !== void 0 ? _off$x : 0, (_off$y = off.y) !== null && _off$y !== void 0 ? _off$y : 0, (_off$z = off.z) !== null && _off$z !== void 0 ? _off$z : 0);
|
|
362
|
+
var delta = origPos.clone().sub(pivot);
|
|
363
|
+
delta.applyAxisAngle(axisVec, angle);
|
|
364
|
+
mesh.position.copy(pivot).add(delta);
|
|
365
|
+
mesh.rotation[axis] = origRot[axis] + angle;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Apply a colour to all Mesh descendants of `mesh`.
|
|
370
|
+
* Creates a cloned material per mesh on first call to avoid shared-material
|
|
371
|
+
* cross-contamination between different device instances.
|
|
372
|
+
*
|
|
373
|
+
* @param {THREE.Object3D} mesh
|
|
374
|
+
* @param {string} colorHex - e.g. '#ff0000'
|
|
375
|
+
*/
|
|
376
|
+
}, {
|
|
377
|
+
key: "_applyColor",
|
|
378
|
+
value: function _applyColor(mesh, colorHex) {
|
|
379
|
+
if (!colorHex) return;
|
|
380
|
+
mesh.traverse(function (obj) {
|
|
381
|
+
if (!obj.isMesh || !obj.material) return;
|
|
382
|
+
|
|
383
|
+
// Ensure this mesh has its own material instance
|
|
384
|
+
if (!obj.userData._materialCloned) {
|
|
385
|
+
obj.material = obj.material.clone();
|
|
386
|
+
obj.userData._materialCloned = true;
|
|
387
|
+
}
|
|
388
|
+
try {
|
|
389
|
+
obj.material.color.set(colorHex);
|
|
390
|
+
} catch (e) {
|
|
391
|
+
// Material may not have a color property (e.g. MeshDepthMaterial)
|
|
392
|
+
}
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
}]);
|
|
396
|
+
}(BaseDisposable);
|
|
397
|
+
|
|
398
|
+
export { IoAnimationManager };
|
|
@@ -30,8 +30,7 @@ function _measureS3Transfer() {
|
|
|
30
30
|
duration,
|
|
31
31
|
_args2 = arguments,
|
|
32
32
|
_t,
|
|
33
|
-
_t2
|
|
34
|
-
_t3;
|
|
33
|
+
_t2;
|
|
35
34
|
return _regenerator().w(function (_context2) {
|
|
36
35
|
while (1) switch (_context2.n) {
|
|
37
36
|
case 0:
|
|
@@ -77,7 +76,7 @@ function _measureS3Transfer() {
|
|
|
77
76
|
// error.message is 'The provided token has expired.' (no 'ExpiredToken' substring).
|
|
78
77
|
isExpiredToken = _t.code === 'ExpiredToken' || _t.Code === 'ExpiredToken' || _t.name === 'ExpiredToken' || _t.message && _t.message.toLowerCase().includes('token has expired');
|
|
79
78
|
if (!isExpiredToken) {
|
|
80
|
-
_context2.n =
|
|
79
|
+
_context2.n = 9;
|
|
81
80
|
break;
|
|
82
81
|
}
|
|
83
82
|
console.warn("\u26A0\uFE0F Token expired during ".concat(operation, ". Attempting session refresh and retry..."));
|
|
@@ -90,50 +89,38 @@ function _measureS3Transfer() {
|
|
|
90
89
|
throw _t;
|
|
91
90
|
case 4:
|
|
92
91
|
_context2.p = 4;
|
|
93
|
-
_context2.
|
|
94
|
-
|
|
95
|
-
return Auth.currentSession();
|
|
96
|
-
case 6:
|
|
97
|
-
console.log("\u2705 User Pool session refreshed for ".concat(operation, "."));
|
|
98
|
-
_context2.n = 8;
|
|
99
|
-
break;
|
|
100
|
-
case 7:
|
|
101
|
-
_context2.p = 7;
|
|
102
|
-
_t2 = _context2.v;
|
|
103
|
-
// If currentSession() fails the refresh token itself is expired —
|
|
104
|
-
// the user needs to sign in again. Surface that immediately.
|
|
105
|
-
console.error("\u274C Failed to refresh User Pool session during ".concat(operation, ":"), _t2);
|
|
106
|
-
throw _t2;
|
|
107
|
-
case 8:
|
|
108
|
-
_context2.n = 9;
|
|
109
|
-
return Auth.currentCredentials({
|
|
92
|
+
_context2.n = 5;
|
|
93
|
+
return Auth.currentSession({
|
|
110
94
|
bypassCache: true
|
|
111
95
|
});
|
|
112
|
-
case
|
|
113
|
-
|
|
96
|
+
case 5:
|
|
97
|
+
_context2.n = 6;
|
|
98
|
+
return Auth.currentCredentials();
|
|
99
|
+
case 6:
|
|
100
|
+
console.log("\u2705 Credentials refreshed. Retrying ".concat(operation, "..."));
|
|
114
101
|
|
|
115
102
|
// Reset timer for the retry
|
|
116
103
|
startTime = performance.now();
|
|
117
|
-
_context2.n =
|
|
104
|
+
_context2.n = 7;
|
|
118
105
|
return executeTransfer();
|
|
119
|
-
case
|
|
106
|
+
case 7:
|
|
120
107
|
return _context2.a(2, _context2.v);
|
|
121
|
-
case
|
|
122
|
-
_context2.p =
|
|
123
|
-
|
|
124
|
-
console.error("\u274C Retry failed for ".concat(operation, ":"),
|
|
108
|
+
case 8:
|
|
109
|
+
_context2.p = 8;
|
|
110
|
+
_t2 = _context2.v;
|
|
111
|
+
console.error("\u274C Retry failed for ".concat(operation, ":"), _t2);
|
|
125
112
|
// If retry fails, throw the Retry Error (likely unrelated or persistent auth issue)
|
|
126
|
-
throw
|
|
127
|
-
case
|
|
113
|
+
throw _t2;
|
|
114
|
+
case 9:
|
|
128
115
|
// Standard error handling for non-expired tokens (or if logic above didn't catch it)
|
|
129
116
|
endTime = performance.now();
|
|
130
117
|
duration = ((endTime - startTime) / 1000).toFixed(3);
|
|
131
118
|
console.error("\u274C S3 ".concat(operation, " failed after ").concat(duration, "s:"), _t);
|
|
132
119
|
throw _t;
|
|
133
|
-
case
|
|
120
|
+
case 10:
|
|
134
121
|
return _context2.a(2);
|
|
135
122
|
}
|
|
136
|
-
}, _callee2, null, [[
|
|
123
|
+
}, _callee2, null, [[4, 8], [1, 3]]);
|
|
137
124
|
}));
|
|
138
125
|
return _measureS3Transfer.apply(this, arguments);
|
|
139
126
|
}
|
|
@@ -105,7 +105,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
105
105
|
}, {
|
|
106
106
|
key: "toggleIODeviceBinaryState",
|
|
107
107
|
value: function toggleIODeviceBinaryState(ioDeviceObject) {
|
|
108
|
-
var _ref, _this$sceneViewer;
|
|
108
|
+
var _ref, _this$sceneViewer, _this$sceneViewer2;
|
|
109
109
|
if (!ioDeviceObject || !this._stateAdapter) return;
|
|
110
110
|
var ud = ioDeviceObject.userData;
|
|
111
111
|
var attachmentId = ud === null || ud === void 0 ? void 0 : ud.attachmentId;
|
|
@@ -140,6 +140,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
140
140
|
var newVal = !Boolean(currentVal);
|
|
141
141
|
this._stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
142
142
|
(_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.behaviorManager) === null || _this$sceneViewer === void 0 || _this$sceneViewer.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
143
|
+
(_this$sceneViewer2 = this.sceneViewer) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.managers) === null || _this$sceneViewer2 === void 0 || (_this$sceneViewer2 = _this$sceneViewer2.ioAnimationManager) === null || _this$sceneViewer2 === void 0 || _this$sceneViewer2.triggerState(attachmentId, dpId, newVal, parentUuid);
|
|
143
144
|
console.log("\uD83D\uDD04 [IODevice] Toggled ".concat(scopedAttachmentId, ".").concat(dpId, ": ").concat(currentVal, " \u2192 ").concat(newVal));
|
|
144
145
|
}
|
|
145
146
|
|
|
@@ -413,11 +414,11 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
413
414
|
}, {
|
|
414
415
|
key: "_positionTooltip",
|
|
415
416
|
value: function _positionTooltip() {
|
|
416
|
-
var _this$
|
|
417
|
+
var _this$sceneViewer3, _this$sceneViewer4;
|
|
417
418
|
if (!this.tooltipEl || !this.selectedObject) return;
|
|
418
419
|
var container = this._getContainer();
|
|
419
|
-
var camera = (_this$
|
|
420
|
-
var renderer = (_this$
|
|
420
|
+
var camera = (_this$sceneViewer3 = this.sceneViewer) === null || _this$sceneViewer3 === void 0 ? void 0 : _this$sceneViewer3.camera;
|
|
421
|
+
var renderer = (_this$sceneViewer4 = this.sceneViewer) === null || _this$sceneViewer4 === void 0 ? void 0 : _this$sceneViewer4.renderer;
|
|
421
422
|
if (!container || !camera || !renderer) return;
|
|
422
423
|
|
|
423
424
|
// Compute bounding box to position above the component
|
|
@@ -454,8 +455,8 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
454
455
|
}, {
|
|
455
456
|
key: "_getContainer",
|
|
456
457
|
value: function _getContainer() {
|
|
457
|
-
var _this$
|
|
458
|
-
return ((_this$
|
|
458
|
+
var _this$sceneViewer5;
|
|
459
|
+
return ((_this$sceneViewer5 = this.sceneViewer) === null || _this$sceneViewer5 === void 0 || (_this$sceneViewer5 = _this$sceneViewer5.renderer) === null || _this$sceneViewer5 === void 0 || (_this$sceneViewer5 = _this$sceneViewer5.domElement) === null || _this$sceneViewer5 === void 0 ? void 0 : _this$sceneViewer5.parentElement) || null;
|
|
459
460
|
}
|
|
460
461
|
|
|
461
462
|
// -----------------------------------------------------------------------
|
|
@@ -495,7 +496,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
495
496
|
var currentVal = (_ref2 = (_this$_stateAdapter$g = (_this$_stateAdapter = this._stateAdapter) === null || _this$_stateAdapter === void 0 ? void 0 : _this$_stateAdapter.getState(scopedAttachmentId, dpId)) !== null && _this$_stateAdapter$g !== void 0 ? _this$_stateAdapter$g : dp.defaultValue) !== null && _ref2 !== void 0 ? _ref2 : null;
|
|
496
497
|
if (isInput) {
|
|
497
498
|
var ctrl = this._buildInputControl(dp, currentVal, function (newVal) {
|
|
498
|
-
var _this4$_stateAdapter, _this4$selectedObject, _this4$sceneViewer;
|
|
499
|
+
var _this4$_stateAdapter, _this4$selectedObject, _this4$sceneViewer, _this4$sceneViewer2;
|
|
499
500
|
(_this4$_stateAdapter = _this4._stateAdapter) === null || _this4$_stateAdapter === void 0 || _this4$_stateAdapter.setState(scopedAttachmentId, dpId, newVal);
|
|
500
501
|
// Also fire BehaviorManager so any wired behaviors react immediately.
|
|
501
502
|
// Pass the parent component UUID so behaviors scoped to a specific instance
|
|
@@ -503,6 +504,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
503
504
|
// Use originalAttachmentId for behavior triggering as behaviors are keyed by original ID
|
|
504
505
|
var parentUuid = ((_this4$selectedObject = _this4.selectedObject) === null || _this4$selectedObject === void 0 ? void 0 : _this4$selectedObject.uuid) || null;
|
|
505
506
|
(_this4$sceneViewer = _this4.sceneViewer) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.managers) === null || _this4$sceneViewer === void 0 || (_this4$sceneViewer = _this4$sceneViewer.behaviorManager) === null || _this4$sceneViewer === void 0 || _this4$sceneViewer.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
507
|
+
(_this4$sceneViewer2 = _this4.sceneViewer) === null || _this4$sceneViewer2 === void 0 || (_this4$sceneViewer2 = _this4$sceneViewer2.managers) === null || _this4$sceneViewer2 === void 0 || (_this4$sceneViewer2 = _this4$sceneViewer2.ioAnimationManager) === null || _this4$sceneViewer2 === void 0 || _this4$sceneViewer2.triggerState(originalAttachmentId || scopedAttachmentId, dpId, newVal, parentUuid);
|
|
506
508
|
});
|
|
507
509
|
row.appendChild(ctrl);
|
|
508
510
|
this._stateElements.set(key, {
|