@2112-lab/central-plant 0.3.4 → 0.3.6
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 +286 -272
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +20 -6
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +62 -132
- package/dist/cjs/src/managers/scene/viewport2DManager.js +203 -129
- package/dist/cjs/src/utils/sceneClearingUtility.js +2 -2
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +20 -6
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +63 -133
- package/dist/esm/src/managers/scene/viewport2DManager.js +202 -130
- package/dist/esm/src/utils/sceneClearingUtility.js +2 -2
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -29813,15 +29813,28 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29813
29813
|
_context5.n = 2;
|
|
29814
29814
|
return Promise.all(glbLoadingPromises);
|
|
29815
29815
|
case 2:
|
|
29816
|
-
// Update world bounding boxes for loaded models
|
|
29816
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
29817
29817
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
29818
|
-
var _jsonData$userData2;
|
|
29819
29818
|
var jsonData = _ref2.jsonData,
|
|
29820
29819
|
glbModel = _ref2.glbModel;
|
|
29821
|
-
if (glbModel
|
|
29822
|
-
|
|
29823
|
-
|
|
29824
|
-
|
|
29820
|
+
if (!glbModel) return;
|
|
29821
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
29822
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
29823
|
+
var filteredBox = computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
29824
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
29825
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
29826
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
29827
|
+
};
|
|
29828
|
+
// Update both the JSON data object AND the live scene object
|
|
29829
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
29830
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
29831
|
+
// Snapshot the object's local position so viewport2DManager can compute
|
|
29832
|
+
// world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
|
|
29833
|
+
glbModel.userData._wbbBasePosition = {
|
|
29834
|
+
x: glbModel.position.x,
|
|
29835
|
+
y: glbModel.position.y,
|
|
29836
|
+
z: glbModel.position.z
|
|
29837
|
+
};
|
|
29825
29838
|
});
|
|
29826
29839
|
|
|
29827
29840
|
// Dispatch completion event
|
|
@@ -30121,10 +30134,10 @@ var SceneClearingUtility = /*#__PURE__*/function () {
|
|
|
30121
30134
|
throw new Error('Scene not available for clearing');
|
|
30122
30135
|
case 1:
|
|
30123
30136
|
componentsToRemove = [];
|
|
30124
|
-
scene = this.sceneViewer.scene; // Collect
|
|
30137
|
+
scene = this.sceneViewer.scene; // Collect component, segment, and gateway objects
|
|
30125
30138
|
scene.traverse(function (child) {
|
|
30126
30139
|
if (child === scene) return;
|
|
30127
|
-
var isComponent = child.userData && (child.userData.objectType === 'component' || child.userData.objectType === '
|
|
30140
|
+
var isComponent = child.userData && (child.userData.objectType === 'component' || child.userData.objectType === 'segment' || child.userData.objectType === 'gateway' || child.userData.objectType === 'connector');
|
|
30128
30141
|
var isDirectChild = child.parent === scene;
|
|
30129
30142
|
if (isComponent && isDirectChild) {
|
|
30130
30143
|
componentsToRemove.push(child);
|
|
@@ -31117,123 +31130,52 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31117
31130
|
}
|
|
31118
31131
|
|
|
31119
31132
|
/**
|
|
31120
|
-
*
|
|
31121
|
-
*
|
|
31122
|
-
*
|
|
31123
|
-
|
|
31124
|
-
|
|
31125
|
-
|
|
31126
|
-
|
|
31127
|
-
|
|
31128
|
-
|
|
31129
|
-
|
|
31130
|
-
|
|
31131
|
-
|
|
31132
|
-
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31137
|
-
|
|
31138
|
-
|
|
31139
|
-
|
|
31140
|
-
|
|
31141
|
-
|
|
31142
|
-
|
|
31143
|
-
|
|
31144
|
-
|
|
31145
|
-
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
if (
|
|
31163
|
-
|
|
31164
|
-
// For components: compute filtered bounding box (excludes io-device and connector subtrees)
|
|
31165
|
-
var filteredBBox = computeFilteredBoundingBox(object, ['io-device', 'connector']);
|
|
31166
|
-
jsonObject.userData.worldBoundingBox = {
|
|
31167
|
-
min: filteredBBox.min.toArray(),
|
|
31168
|
-
max: filteredBBox.max.toArray()
|
|
31169
|
-
};
|
|
31170
|
-
console.log("Added filtered world bounding box for component:", jsonObject.userData.worldBoundingBox);
|
|
31171
|
-
|
|
31172
|
-
// Compute and inject separate io-device bounding boxes as children
|
|
31173
|
-
var ioDeviceBBoxes = computeIODeviceBoundingBoxes(object);
|
|
31174
|
-
if (ioDeviceBBoxes.length > 0) {
|
|
31175
|
-
if (!jsonObject.children) jsonObject.children = [];
|
|
31176
|
-
ioDeviceBBoxes.forEach(function (deviceBBox) {
|
|
31177
|
-
var existingIndex = jsonObject.children.findIndex(function (c) {
|
|
31178
|
-
return c.uuid === deviceBBox.uuid;
|
|
31179
|
-
});
|
|
31180
|
-
if (existingIndex >= 0) {
|
|
31181
|
-
// Update existing entry
|
|
31182
|
-
if (!jsonObject.children[existingIndex].userData) jsonObject.children[existingIndex].userData = {};
|
|
31183
|
-
jsonObject.children[existingIndex].userData.objectType = 'io-device';
|
|
31184
|
-
jsonObject.children[existingIndex].userData.worldBoundingBox = deviceBBox.worldBoundingBox;
|
|
31185
|
-
} else {
|
|
31186
|
-
// Create new entry
|
|
31187
|
-
jsonObject.children.push({
|
|
31188
|
-
uuid: deviceBBox.uuid,
|
|
31189
|
-
userData: _objectSpread2(_objectSpread2({}, deviceBBox.userData), {}, {
|
|
31190
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
31191
|
-
}),
|
|
31192
|
-
children: []
|
|
31193
|
-
});
|
|
31194
|
-
}
|
|
31195
|
-
});
|
|
31196
|
-
console.log("\uD83D\uDCE6 Injected ".concat(ioDeviceBBoxes.length, " io-device bbox(es) for component ").concat(jsonObject.uuid));
|
|
31197
|
-
}
|
|
31198
|
-
} else if (jsonObject.userData.objectType !== 'gateway') {
|
|
31199
|
-
// For non-component, non-gateway objects: standard bounding box
|
|
31200
|
-
var boundingBox = new THREE__namespace.Box3().setFromObject(object);
|
|
31201
|
-
jsonObject.userData.worldBoundingBox = {
|
|
31202
|
-
min: boundingBox.min.toArray(),
|
|
31203
|
-
max: boundingBox.max.toArray()
|
|
31204
|
-
};
|
|
31205
|
-
console.log("Added world bounding box:", jsonObject.userData.worldBoundingBox);
|
|
31206
|
-
}
|
|
31207
|
-
|
|
31208
|
-
// For gateways and connectors, ensure userData.position exists in scene data
|
|
31209
|
-
// This is REQUIRED for pathfinder compatibility
|
|
31210
|
-
if (jsonObject.userData.objectType === 'gateway' || jsonObject.userData.objectType === 'connector') {
|
|
31211
|
-
// Use the object's world position (from Three.js mesh)
|
|
31212
|
-
var worldPos = new THREE__namespace.Vector3();
|
|
31213
|
-
object.getWorldPosition(worldPos);
|
|
31214
|
-
|
|
31215
|
-
// ALWAYS update userData.position with world position
|
|
31216
|
-
// This is critical for manual segment connectors which start with local positions
|
|
31217
|
-
jsonObject.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
31218
|
-
console.log("\u2705 Set userData.position for ".concat(jsonObject.userData.objectType, " ").concat(jsonObject.uuid, ": [").concat(worldPos.x.toFixed(2), ", ").concat(worldPos.y.toFixed(2), ", ").concat(worldPos.z.toFixed(2), "]"));
|
|
31219
|
-
|
|
31220
|
-
// For gateways, ensure isDeclared flag is in scene data
|
|
31221
|
-
if (jsonObject.userData.objectType === 'gateway') {
|
|
31222
|
-
if (jsonObject.userData.isDeclared === undefined) {
|
|
31223
|
-
jsonObject.userData.isDeclared = true;
|
|
31224
|
-
}
|
|
31225
|
-
}
|
|
31226
|
-
|
|
31227
|
-
// For manual segment connectors, ensure isDeclared is set in scene data
|
|
31228
|
-
if (jsonObject.userData.objectType === 'segment-connector' && jsonObject.userData.isDeclared === undefined) {
|
|
31229
|
-
jsonObject.userData.isDeclared = true;
|
|
31230
|
-
console.log("\u2705 Set isDeclared=true for manual segment connector in scene data: ".concat(jsonObject.uuid));
|
|
31231
|
-
}
|
|
31232
|
-
|
|
31233
|
-
// Also sync the mesh's userData.position (belt and suspenders approach)
|
|
31234
|
-
object.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
31133
|
+
* Sync world-space positions and isDeclared flags for gateways and connectors
|
|
31134
|
+
* into the scene JSON data so the pathfinder can read them.
|
|
31135
|
+
*
|
|
31136
|
+
* Bounding boxes for components and segments are intentionally NOT computed here.
|
|
31137
|
+
* They are computed (with matrix-hash caching) by
|
|
31138
|
+
* PathfindingManager._enrichSceneDataWithBoundingBoxes(), which runs after GLB
|
|
31139
|
+
* models are fully loaded and therefore produces correct values.
|
|
31140
|
+
*/
|
|
31141
|
+
}, {
|
|
31142
|
+
key: "_syncPositionsForPathfinding",
|
|
31143
|
+
value: function _syncPositionsForPathfinding(data) {
|
|
31144
|
+
var scene = this.sceneViewer.scene;
|
|
31145
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
31146
|
+
var syncPosition = function syncPosition(jsonObject) {
|
|
31147
|
+
var _jsonObject$userData;
|
|
31148
|
+
var object = scene.getObjectByProperty('uuid', jsonObject.uuid) || scene.getObjectByProperty('uuid', (_jsonObject$userData = jsonObject.userData) === null || _jsonObject$userData === void 0 ? void 0 : _jsonObject$userData.originalUuid);
|
|
31149
|
+
if (!object) return;
|
|
31150
|
+
object.getWorldPosition(worldPos);
|
|
31151
|
+
var pos = [worldPos.x, worldPos.y, worldPos.z];
|
|
31152
|
+
jsonObject.userData.position = pos;
|
|
31153
|
+
object.userData.position = pos;
|
|
31154
|
+
};
|
|
31155
|
+
data.scene.children.forEach(function (jsonObject) {
|
|
31156
|
+
var _jsonObject$userData2;
|
|
31157
|
+
var type = (_jsonObject$userData2 = jsonObject.userData) === null || _jsonObject$userData2 === void 0 ? void 0 : _jsonObject$userData2.objectType;
|
|
31158
|
+
if (type === 'gateway') {
|
|
31159
|
+
syncPosition(jsonObject);
|
|
31160
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31161
|
+
jsonObject.userData.isDeclared = true;
|
|
31162
|
+
}
|
|
31163
|
+
} else if (type === 'connector') {
|
|
31164
|
+
syncPosition(jsonObject);
|
|
31165
|
+
} else if (type === 'segment-connector') {
|
|
31166
|
+
syncPosition(jsonObject);
|
|
31167
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
31168
|
+
jsonObject.userData.isDeclared = true;
|
|
31169
|
+
}
|
|
31170
|
+
} else if (type === 'component' && Array.isArray(jsonObject.children)) {
|
|
31171
|
+
// Connectors are injected as JSON children by _injectConnectorChildrenFromDictionary
|
|
31172
|
+
// and their Three.js objects exist in the scene, created recursively by createSceneObject
|
|
31173
|
+
jsonObject.children.forEach(function (childJson) {
|
|
31174
|
+
var _childJson$userData;
|
|
31175
|
+
if (((_childJson$userData = childJson.userData) === null || _childJson$userData === void 0 ? void 0 : _childJson$userData.objectType) === 'connector') {
|
|
31176
|
+
syncPosition(childJson);
|
|
31235
31177
|
}
|
|
31236
|
-
}
|
|
31178
|
+
});
|
|
31237
31179
|
}
|
|
31238
31180
|
});
|
|
31239
31181
|
}
|
|
@@ -31398,10 +31340,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31398
31340
|
var componentsProcessed = 0;
|
|
31399
31341
|
var connectorsInjected = 0;
|
|
31400
31342
|
data.scene.children.forEach(function (child) {
|
|
31401
|
-
var _child$
|
|
31402
|
-
var childType = ((_child$
|
|
31343
|
+
var _child$userData4, _child$userData5, _child$userData6;
|
|
31344
|
+
var childType = ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.objectType) || ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType);
|
|
31403
31345
|
// Only process components with libraryId
|
|
31404
|
-
if (childType === 'component' && (_child$
|
|
31346
|
+
if (childType === 'component' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.libraryId) {
|
|
31405
31347
|
var libraryId = child.userData.libraryId;
|
|
31406
31348
|
var dictEntry = componentDictionary[libraryId];
|
|
31407
31349
|
|
|
@@ -31558,23 +31500,25 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31558
31500
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
31559
31501
|
libraryObjectsToReplace = [];
|
|
31560
31502
|
data.scene.children.forEach(function (child, index) {
|
|
31561
|
-
var _child$
|
|
31503
|
+
var _child$userData7, _child$userData8;
|
|
31562
31504
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
31563
31505
|
_this4.sceneViewer.scene.add(createdObject);
|
|
31564
31506
|
|
|
31565
31507
|
// Track objects that need GLB model replacement
|
|
31566
|
-
if ((_child$
|
|
31567
|
-
var _child$
|
|
31508
|
+
if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.libraryId && componentDictionary[(_child$userData8 = child.userData) === null || _child$userData8 === void 0 ? void 0 : _child$userData8.libraryId]) {
|
|
31509
|
+
var _child$userData9;
|
|
31568
31510
|
libraryObjectsToReplace.push({
|
|
31569
31511
|
basicObject: createdObject,
|
|
31570
31512
|
jsonData: child,
|
|
31571
|
-
componentData: componentDictionary[(_child$
|
|
31513
|
+
componentData: componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]
|
|
31572
31514
|
});
|
|
31573
31515
|
}
|
|
31574
31516
|
});
|
|
31575
31517
|
|
|
31576
|
-
//
|
|
31577
|
-
|
|
31518
|
+
// Sync gateway/connector world positions into JSON before pathfinding.
|
|
31519
|
+
// Bounding boxes are computed later by PathfindingManager._enrichSceneDataWithBoundingBoxes
|
|
31520
|
+
// (after GLB models are loaded), so no bbox work is done here.
|
|
31521
|
+
this._syncPositionsForPathfinding(data);
|
|
31578
31522
|
this._saveOriginalWorldMatrices(this.sceneViewer.scene);
|
|
31579
31523
|
return _context6.a(2, {
|
|
31580
31524
|
componentDictionary: componentDictionary,
|
|
@@ -31720,8 +31664,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31720
31664
|
var instanceBehaviors = [];
|
|
31721
31665
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
31722
31666
|
data.scene.children.forEach(function (child) {
|
|
31723
|
-
var _child$
|
|
31724
|
-
var libraryId = (_child$
|
|
31667
|
+
var _child$userData0, _compData$defaultBeha;
|
|
31668
|
+
var libraryId = (_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId;
|
|
31725
31669
|
if (!libraryId) return;
|
|
31726
31670
|
var instanceUuid = child.uuid;
|
|
31727
31671
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -31917,8 +31861,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
31917
31861
|
key: "_saveOriginalWorldMatrices",
|
|
31918
31862
|
value: function _saveOriginalWorldMatrices(scene) {
|
|
31919
31863
|
scene.traverse(function (object) {
|
|
31920
|
-
var _object$
|
|
31921
|
-
if ((_object$
|
|
31864
|
+
var _object$userData;
|
|
31865
|
+
if ((_object$userData = object.userData) !== null && _object$userData !== void 0 && _object$userData.direction) {
|
|
31922
31866
|
var originalMatrix = new THREE__namespace.Matrix4();
|
|
31923
31867
|
originalMatrix.copy(object.matrixWorld);
|
|
31924
31868
|
}
|
|
@@ -32122,8 +32066,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32122
32066
|
// Process children (connectors, etc.) if they exist
|
|
32123
32067
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
32124
32068
|
componentModel.children.forEach(function (child) {
|
|
32125
|
-
var _child$
|
|
32126
|
-
var childType = ((_child$
|
|
32069
|
+
var _child$userData1, _child$userData10;
|
|
32070
|
+
var childType = ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) || ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType);
|
|
32127
32071
|
if (childType === 'connector') {
|
|
32128
32072
|
var _child$geometry;
|
|
32129
32073
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -32208,8 +32152,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
32208
32152
|
if (segment.children && segment.children.length > 0) {
|
|
32209
32153
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
32210
32154
|
childrenToRemove.forEach(function (child) {
|
|
32211
|
-
var _child$
|
|
32212
|
-
if ((_child$
|
|
32155
|
+
var _child$userData11;
|
|
32156
|
+
if ((_child$userData11 = child.userData) !== null && _child$userData11 !== void 0 && _child$userData11.isPipeElbow) {
|
|
32213
32157
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
32214
32158
|
segment.remove(child);
|
|
32215
32159
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -35479,6 +35423,18 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35479
35423
|
// Map of viewport instances by viewType or custom key
|
|
35480
35424
|
_this2.viewports = new Map();
|
|
35481
35425
|
|
|
35426
|
+
// Per-refresh-cycle bbox cache: keyed by object.uuid, cleared each refresh()
|
|
35427
|
+
// so each component bbox is computed once per cycle regardless of viewport count
|
|
35428
|
+
_this2._bboxCache = new Map();
|
|
35429
|
+
|
|
35430
|
+
// Per-refresh-cycle component list cache: eliminates redundant scene traversals
|
|
35431
|
+
// when all 3 viewports render in the same cycle
|
|
35432
|
+
_this2._componentListCache = null;
|
|
35433
|
+
|
|
35434
|
+
// rAF debounce flag — prevents multiple same-frame refresh() calls from
|
|
35435
|
+
// stacking up independent renderComponents() runs
|
|
35436
|
+
_this2._refreshPending = false;
|
|
35437
|
+
|
|
35482
35438
|
// Event listener reference for cleanup
|
|
35483
35439
|
_this2._objectTransformedListener = null;
|
|
35484
35440
|
console.log('🔲 Viewport2DManager initialized (multi-instance support)');
|
|
@@ -35500,7 +35456,6 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35500
35456
|
|
|
35501
35457
|
// Listen for object transformations to refresh all viewports
|
|
35502
35458
|
this._objectTransformedListener = function (eventData) {
|
|
35503
|
-
console.log('🔲 Viewport2DManager detected object transformation, refreshing all viewports');
|
|
35504
35459
|
_this3.refresh(); // Refresh all viewports
|
|
35505
35460
|
};
|
|
35506
35461
|
|
|
@@ -35566,6 +35521,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35566
35521
|
case 3:
|
|
35567
35522
|
// Create new viewport instance
|
|
35568
35523
|
viewport = new Viewport2DInstance(this.sceneViewer, this.Konva, viewType, container);
|
|
35524
|
+
viewport._instanceKey = key;
|
|
35569
35525
|
this.viewports.set(key, viewport);
|
|
35570
35526
|
|
|
35571
35527
|
// Initialize the stage for this viewport
|
|
@@ -35743,9 +35699,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35743
35699
|
viewport.stage.width(width);
|
|
35744
35700
|
viewport.stage.height(height);
|
|
35745
35701
|
|
|
35746
|
-
// Redraw
|
|
35702
|
+
// Redraw grid immediately; schedule debounced component render
|
|
35747
35703
|
this.drawGrid(viewport);
|
|
35748
|
-
this.
|
|
35704
|
+
this.refresh(viewport._instanceKey);
|
|
35749
35705
|
}
|
|
35750
35706
|
}
|
|
35751
35707
|
|
|
@@ -35922,32 +35878,19 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35922
35878
|
}, {
|
|
35923
35879
|
key: "renderComponent",
|
|
35924
35880
|
value: function renderComponent(viewport, component, centerX, centerY, scale) {
|
|
35925
|
-
|
|
35926
|
-
// Get component position and rotation
|
|
35927
|
-
var pos3D = {
|
|
35928
|
-
x: (_component$position$x = (_component$position = component.position) === null || _component$position === void 0 ? void 0 : _component$position.x) !== null && _component$position$x !== void 0 ? _component$position$x : 0,
|
|
35929
|
-
y: (_component$position$y = (_component$position2 = component.position) === null || _component$position2 === void 0 ? void 0 : _component$position2.y) !== null && _component$position$y !== void 0 ? _component$position$y : 0,
|
|
35930
|
-
z: (_component$position$z = (_component$position3 = component.position) === null || _component$position3 === void 0 ? void 0 : _component$position3.z) !== null && _component$position$z !== void 0 ? _component$position$z : 0
|
|
35931
|
-
};
|
|
35932
|
-
var rot3D = {
|
|
35933
|
-
x: (_component$rotation$x = (_component$rotation = component.rotation) === null || _component$rotation === void 0 ? void 0 : _component$rotation.x) !== null && _component$rotation$x !== void 0 ? _component$rotation$x : 0,
|
|
35934
|
-
y: (_component$rotation$y = (_component$rotation2 = component.rotation) === null || _component$rotation2 === void 0 ? void 0 : _component$rotation2.y) !== null && _component$rotation$y !== void 0 ? _component$rotation$y : 0,
|
|
35935
|
-
z: (_component$rotation$z = (_component$rotation3 = component.rotation) === null || _component$rotation3 === void 0 ? void 0 : _component$rotation3.z) !== null && _component$rotation$z !== void 0 ? _component$rotation$z : 0
|
|
35936
|
-
};
|
|
35937
|
-
|
|
35938
|
-
// Get bounding box dimensions
|
|
35881
|
+
// Get world-space bounding box dimensions and center
|
|
35939
35882
|
var _this$getComponentDim = this.getComponentDimensions(component),
|
|
35940
35883
|
worldWidth = _this$getComponentDim.worldWidth,
|
|
35941
35884
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
35942
|
-
worldHeight = _this$getComponentDim.worldHeight
|
|
35885
|
+
worldHeight = _this$getComponentDim.worldHeight,
|
|
35886
|
+
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
35943
35887
|
|
|
35944
|
-
// Project 3D
|
|
35945
|
-
var _this$project3DTo2D = this.project3DTo2D(viewport,
|
|
35888
|
+
// Project 3D bbox center to 2D based on view type
|
|
35889
|
+
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
35946
35890
|
posX = _this$project3DTo2D.posX,
|
|
35947
35891
|
posY = _this$project3DTo2D.posY,
|
|
35948
35892
|
rectWidth = _this$project3DTo2D.rectWidth,
|
|
35949
35893
|
rectHeight = _this$project3DTo2D.rectHeight;
|
|
35950
|
-
_this$project3DTo2D.rotationDegrees;
|
|
35951
35894
|
var screenX = centerX + posX * scale;
|
|
35952
35895
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
35953
35896
|
|
|
@@ -35991,105 +35934,156 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35991
35934
|
});
|
|
35992
35935
|
|
|
35993
35936
|
// Add mouse event handlers
|
|
35994
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight);
|
|
35937
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
35995
35938
|
componentGroup.add(rect);
|
|
35996
35939
|
componentGroup.add(label);
|
|
35997
35940
|
viewport.componentLayer.add(componentGroup);
|
|
35998
35941
|
}
|
|
35999
35942
|
|
|
36000
35943
|
/**
|
|
36001
|
-
*
|
|
35944
|
+
* Compute worldBoundingBox for a live Three.js Object3D using the same
|
|
35945
|
+
* vertex-accurate approach as computeFilteredBoundingBox (explicitly calls
|
|
35946
|
+
* geometry.computeBoundingBox() on each mesh before measuring).
|
|
35947
|
+
* @param {THREE.Object3D} object
|
|
35948
|
+
* @returns {{min: number[], max: number[]}}
|
|
35949
|
+
*/
|
|
35950
|
+
}, {
|
|
35951
|
+
key: "_getOrComputeWorldBoundingBox",
|
|
35952
|
+
value: function _getOrComputeWorldBoundingBox(object) {
|
|
35953
|
+
var _object$userData, _object$userData2;
|
|
35954
|
+
// Fast path: offset the stored world bbox by the position delta since load time.
|
|
35955
|
+
// Translation only shifts the bbox center — extents stay identical — so this is O(1)
|
|
35956
|
+
// instead of O(meshes × vertices) from a full geometry traversal.
|
|
35957
|
+
var stored = (_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.worldBoundingBox;
|
|
35958
|
+
var basePos = (_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2._wbbBasePosition;
|
|
35959
|
+
if (stored && basePos) {
|
|
35960
|
+
var dx = object.position.x - basePos.x;
|
|
35961
|
+
var dy = object.position.y - basePos.y;
|
|
35962
|
+
var dz = object.position.z - basePos.z;
|
|
35963
|
+
if (dx === 0 && dy === 0 && dz === 0) return stored;
|
|
35964
|
+
return {
|
|
35965
|
+
min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
|
|
35966
|
+
max: [stored.max[0] + dx, stored.max[1] + dy, stored.max[2] + dz]
|
|
35967
|
+
};
|
|
35968
|
+
}
|
|
35969
|
+
|
|
35970
|
+
// Slow path: full vertex-accurate traversal (fallback when userData not populated)
|
|
35971
|
+
if (this._bboxCache.has(object.uuid)) {
|
|
35972
|
+
return this._bboxCache.get(object.uuid);
|
|
35973
|
+
}
|
|
35974
|
+
var box = computeFilteredBoundingBox(object, []);
|
|
35975
|
+
var result;
|
|
35976
|
+
if (box.isEmpty()) {
|
|
35977
|
+
// Object has no geometry; fall back to a point at world position
|
|
35978
|
+
var wp = new THREE__namespace.Vector3();
|
|
35979
|
+
object.getWorldPosition(wp);
|
|
35980
|
+
result = {
|
|
35981
|
+
min: [wp.x, wp.y, wp.z],
|
|
35982
|
+
max: [wp.x, wp.y, wp.z]
|
|
35983
|
+
};
|
|
35984
|
+
} else {
|
|
35985
|
+
result = {
|
|
35986
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
35987
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
35988
|
+
};
|
|
35989
|
+
}
|
|
35990
|
+
this._bboxCache.set(object.uuid, result);
|
|
35991
|
+
return result;
|
|
35992
|
+
}
|
|
35993
|
+
|
|
35994
|
+
/**
|
|
35995
|
+
* Get component dimensions and world-space center from worldBoundingBox
|
|
36002
35996
|
*/
|
|
36003
35997
|
}, {
|
|
36004
35998
|
key: "getComponentDimensions",
|
|
36005
35999
|
value: function getComponentDimensions(component) {
|
|
36006
|
-
var _component$
|
|
36007
|
-
|
|
36008
|
-
|
|
36009
|
-
|
|
36010
|
-
|
|
36011
|
-
|
|
36012
|
-
if (
|
|
36013
|
-
var
|
|
36014
|
-
|
|
36015
|
-
|
|
36016
|
-
|
|
36017
|
-
|
|
36018
|
-
|
|
36019
|
-
|
|
36020
|
-
|
|
36021
|
-
|
|
36022
|
-
var
|
|
36023
|
-
|
|
36024
|
-
|
|
36025
|
-
|
|
36026
|
-
|
|
36027
|
-
|
|
36028
|
-
|
|
36029
|
-
|
|
36030
|
-
|
|
36031
|
-
|
|
36032
|
-
|
|
36000
|
+
var _component$getWorldPo;
|
|
36001
|
+
// Always recompute from the live Three.js object so that the rect reflects
|
|
36002
|
+
// the current world position after translate/drag operations.
|
|
36003
|
+
// userData.worldBoundingBox is a load-time snapshot and goes stale whenever
|
|
36004
|
+
// the object moves, so we cannot rely on it here.
|
|
36005
|
+
var wbb = this._getOrComputeWorldBoundingBox(component);
|
|
36006
|
+
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
36007
|
+
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
36008
|
+
minX = _wbb$min[0],
|
|
36009
|
+
minY = _wbb$min[1],
|
|
36010
|
+
minZ = _wbb$min[2];
|
|
36011
|
+
var _wbb$max = _slicedToArray(wbb.max, 3),
|
|
36012
|
+
maxX = _wbb$max[0],
|
|
36013
|
+
maxY = _wbb$max[1],
|
|
36014
|
+
maxZ = _wbb$max[2];
|
|
36015
|
+
var cx = (minX + maxX) / 2;
|
|
36016
|
+
var cy = (minY + maxY) / 2;
|
|
36017
|
+
var cz = (minZ + maxZ) / 2;
|
|
36018
|
+
// Guard against Infinity/NaN from empty or degenerate boxes
|
|
36019
|
+
if (isFinite(cx) && isFinite(cy) && isFinite(cz)) {
|
|
36020
|
+
return {
|
|
36021
|
+
worldWidth: Math.max(maxX - minX, 0.01),
|
|
36022
|
+
worldDepth: Math.max(maxY - minY, 0.01),
|
|
36023
|
+
worldHeight: Math.max(maxZ - minZ, 0.01),
|
|
36024
|
+
bboxCenter: {
|
|
36025
|
+
x: cx,
|
|
36026
|
+
y: cy,
|
|
36027
|
+
z: cz
|
|
36028
|
+
}
|
|
36029
|
+
};
|
|
36030
|
+
}
|
|
36033
36031
|
}
|
|
36032
|
+
// Fallback: world position of the object, unit dimensions
|
|
36033
|
+
var wp = new THREE__namespace.Vector3();
|
|
36034
|
+
(_component$getWorldPo = component.getWorldPosition) === null || _component$getWorldPo === void 0 || _component$getWorldPo.call(component, wp);
|
|
36034
36035
|
return {
|
|
36035
|
-
worldWidth:
|
|
36036
|
-
worldDepth:
|
|
36037
|
-
worldHeight:
|
|
36036
|
+
worldWidth: 1,
|
|
36037
|
+
worldDepth: 1,
|
|
36038
|
+
worldHeight: 1,
|
|
36039
|
+
bboxCenter: {
|
|
36040
|
+
x: wp.x,
|
|
36041
|
+
y: wp.y,
|
|
36042
|
+
z: wp.z
|
|
36043
|
+
}
|
|
36038
36044
|
};
|
|
36039
36045
|
}
|
|
36040
36046
|
|
|
36041
36047
|
/**
|
|
36042
|
-
* Project
|
|
36048
|
+
* Project world-space bbox center to 2D based on view type.
|
|
36049
|
+
* worldBoundingBox is an AABB so rotation is already encoded in the extents —
|
|
36050
|
+
* no separate rotation correction is needed.
|
|
36043
36051
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36052
|
+
* @param {Object} bboxCenter - World-space center {x, y, z}
|
|
36053
|
+
* @param {number} worldWidth - X extent (max[0] - min[0])
|
|
36054
|
+
* @param {number} worldDepth - Y extent (max[1] - min[1])
|
|
36055
|
+
* @param {number} worldHeight - Z extent (max[2] - min[2])
|
|
36044
36056
|
*/
|
|
36045
36057
|
}, {
|
|
36046
36058
|
key: "project3DTo2D",
|
|
36047
|
-
value: function project3DTo2D(viewport,
|
|
36048
|
-
var posX, posY, rectWidth, rectHeight;
|
|
36049
|
-
var rotationAngle = rot3D.z;
|
|
36050
|
-
var rotationDegrees = rotationAngle * 180 / Math.PI;
|
|
36059
|
+
value: function project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight) {
|
|
36051
36060
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
36061
|
+
var posX, posY, rectWidth, rectHeight;
|
|
36052
36062
|
switch (viewport.viewType) {
|
|
36053
36063
|
case 'top':
|
|
36054
|
-
//
|
|
36055
|
-
posX =
|
|
36056
|
-
posY =
|
|
36057
|
-
|
|
36058
|
-
|
|
36059
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36060
|
-
rectWidth = worldDepth * scale;
|
|
36061
|
-
rectHeight = worldWidth * scale;
|
|
36062
|
-
} else {
|
|
36063
|
-
rectWidth = worldWidth * scale;
|
|
36064
|
-
rectHeight = worldDepth * scale;
|
|
36065
|
-
}
|
|
36064
|
+
// Looking down Z-axis — X/Y plane
|
|
36065
|
+
posX = bboxCenter.x;
|
|
36066
|
+
posY = bboxCenter.y;
|
|
36067
|
+
rectWidth = worldWidth * scale;
|
|
36068
|
+
rectHeight = worldDepth * scale;
|
|
36066
36069
|
break;
|
|
36067
36070
|
case 'front':
|
|
36068
|
-
//
|
|
36069
|
-
posX =
|
|
36070
|
-
posY =
|
|
36071
|
-
|
|
36072
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36073
|
-
rectWidth = worldDepth * scale;
|
|
36074
|
-
} else {
|
|
36075
|
-
rectWidth = worldWidth * scale;
|
|
36076
|
-
}
|
|
36071
|
+
// Looking along Y-axis — X/Z plane
|
|
36072
|
+
posX = bboxCenter.x;
|
|
36073
|
+
posY = bboxCenter.z;
|
|
36074
|
+
rectWidth = worldWidth * scale;
|
|
36077
36075
|
rectHeight = worldHeight * scale;
|
|
36078
36076
|
break;
|
|
36079
36077
|
case 'side':
|
|
36080
|
-
//
|
|
36081
|
-
posX = -
|
|
36082
|
-
posY =
|
|
36083
|
-
|
|
36084
|
-
rectWidth = worldWidth * scale;
|
|
36085
|
-
} else {
|
|
36086
|
-
rectWidth = worldDepth * scale;
|
|
36087
|
-
}
|
|
36078
|
+
// Looking along X-axis — Y/Z plane (Y negated for left-right orientation)
|
|
36079
|
+
posX = -bboxCenter.y;
|
|
36080
|
+
posY = bboxCenter.z;
|
|
36081
|
+
rectWidth = worldDepth * scale;
|
|
36088
36082
|
rectHeight = worldHeight * scale;
|
|
36089
36083
|
break;
|
|
36090
36084
|
default:
|
|
36091
|
-
posX =
|
|
36092
|
-
posY =
|
|
36085
|
+
posX = bboxCenter.x;
|
|
36086
|
+
posY = bboxCenter.y;
|
|
36093
36087
|
rectWidth = worldWidth * scale;
|
|
36094
36088
|
rectHeight = worldDepth * scale;
|
|
36095
36089
|
}
|
|
@@ -36097,8 +36091,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36097
36091
|
posX: posX,
|
|
36098
36092
|
posY: posY,
|
|
36099
36093
|
rectWidth: rectWidth,
|
|
36100
|
-
rectHeight: rectHeight
|
|
36101
|
-
rotationDegrees: rotationDegrees
|
|
36094
|
+
rectHeight: rectHeight
|
|
36102
36095
|
};
|
|
36103
36096
|
}
|
|
36104
36097
|
|
|
@@ -36108,7 +36101,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36108
36101
|
*/
|
|
36109
36102
|
}, {
|
|
36110
36103
|
key: "addComponentInteractions",
|
|
36111
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight) {
|
|
36104
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
36112
36105
|
var _this6 = this;
|
|
36113
36106
|
if (!this.Konva) return;
|
|
36114
36107
|
var colors = this.generateComponentColor(component.id);
|
|
@@ -36120,7 +36113,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36120
36113
|
rect.stroke('#007bff');
|
|
36121
36114
|
rect.strokeWidth(3);
|
|
36122
36115
|
viewport.stage.container().style.cursor = 'grab';
|
|
36123
|
-
viewport.componentLayer.
|
|
36116
|
+
viewport.componentLayer.batchDraw();
|
|
36124
36117
|
}
|
|
36125
36118
|
});
|
|
36126
36119
|
rect.on('mouseleave', function () {
|
|
@@ -36129,7 +36122,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36129
36122
|
rect.stroke(colors.stroke);
|
|
36130
36123
|
rect.strokeWidth(2);
|
|
36131
36124
|
viewport.stage.container().style.cursor = 'default';
|
|
36132
|
-
viewport.componentLayer.
|
|
36125
|
+
viewport.componentLayer.batchDraw();
|
|
36133
36126
|
}
|
|
36134
36127
|
});
|
|
36135
36128
|
|
|
@@ -36173,7 +36166,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36173
36166
|
// Snap to grid
|
|
36174
36167
|
var snappedPos = _this6.snapScreenToGrid(viewport, currentPos.x, currentPos.y, scale, worldOriginX, worldOriginY);
|
|
36175
36168
|
componentGroup.position(snappedPos);
|
|
36176
|
-
viewport.componentLayer.
|
|
36169
|
+
viewport.componentLayer.batchDraw();
|
|
36177
36170
|
});
|
|
36178
36171
|
|
|
36179
36172
|
// DRAG END
|
|
@@ -36191,9 +36184,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36191
36184
|
// Convert screen to world coordinates
|
|
36192
36185
|
var worldCoords = _this6.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
36193
36186
|
|
|
36194
|
-
// Calculate new position
|
|
36187
|
+
// Calculate new position: delta from old bbox center to new bbox center
|
|
36195
36188
|
var currentPos = component.position;
|
|
36196
|
-
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos,
|
|
36189
|
+
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
36197
36190
|
|
|
36198
36191
|
// Apply translation via centralPlant API
|
|
36199
36192
|
var deltaX = newPosition.x - currentPos.x;
|
|
@@ -36296,37 +36289,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36296
36289
|
}
|
|
36297
36290
|
|
|
36298
36291
|
/**
|
|
36299
|
-
* Convert world coordinates to 3D object position
|
|
36292
|
+
* Convert dragged 2D world coordinates to a new 3D object position.
|
|
36293
|
+
* coord1/coord2 represent where the bbox CENTER should be in the view's 2D plane;
|
|
36294
|
+
* we compute the delta from the old bbox center and apply it to the pivot position.
|
|
36300
36295
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36296
|
+
* @param {{coord1, coord2}} worldCoords - Projected world coordinates from screen
|
|
36297
|
+
* @param {{x,y,z}} currentPosition - Current Three.js object position (pivot)
|
|
36298
|
+
* @param {{x,y,z}} bboxCenter - Old world-space bbox center
|
|
36301
36299
|
*/
|
|
36302
36300
|
}, {
|
|
36303
36301
|
key: "worldCoordsToObjectPosition",
|
|
36304
|
-
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition,
|
|
36302
|
+
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition, bboxCenter) {
|
|
36305
36303
|
var coord1 = worldCoords.coord1,
|
|
36306
36304
|
coord2 = worldCoords.coord2;
|
|
36307
36305
|
switch (viewport.viewType) {
|
|
36308
36306
|
case 'top':
|
|
36307
|
+
// coord1=X, coord2=Y in world space
|
|
36309
36308
|
return {
|
|
36310
|
-
x: coord1,
|
|
36311
|
-
y: coord2,
|
|
36309
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36310
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36312
36311
|
z: currentPosition.z
|
|
36313
36312
|
};
|
|
36314
36313
|
case 'front':
|
|
36314
|
+
// coord1=X, coord2=Z in world space
|
|
36315
36315
|
return {
|
|
36316
|
-
x: coord1,
|
|
36316
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36317
36317
|
y: currentPosition.y,
|
|
36318
|
-
z: coord2 -
|
|
36318
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36319
36319
|
};
|
|
36320
36320
|
case 'side':
|
|
36321
|
+
// coord1=-Y (negated), coord2=Z in world space
|
|
36321
36322
|
return {
|
|
36322
36323
|
x: currentPosition.x,
|
|
36323
|
-
y: -coord1,
|
|
36324
|
-
z: coord2 -
|
|
36324
|
+
y: currentPosition.y + (-coord1 - bboxCenter.y),
|
|
36325
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36325
36326
|
};
|
|
36326
36327
|
default:
|
|
36327
36328
|
return {
|
|
36328
|
-
x: coord1,
|
|
36329
|
-
y: coord2,
|
|
36329
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36330
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36330
36331
|
z: currentPosition.z
|
|
36331
36332
|
};
|
|
36332
36333
|
}
|
|
@@ -36338,17 +36339,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36338
36339
|
}, {
|
|
36339
36340
|
key: "getSceneComponents",
|
|
36340
36341
|
value: function getSceneComponents() {
|
|
36342
|
+
if (this._componentListCache) return this._componentListCache;
|
|
36341
36343
|
if (!this.sceneViewer || !this.sceneViewer.scene) {
|
|
36342
36344
|
return [];
|
|
36343
36345
|
}
|
|
36344
36346
|
var components = [];
|
|
36345
36347
|
this.sceneViewer.scene.traverse(function (object) {
|
|
36346
|
-
var _object$
|
|
36347
|
-
|
|
36348
|
-
|
|
36348
|
+
var _object$userData3, _object$userData4;
|
|
36349
|
+
// Only match the ROOT component object — must have both objectType:'component'
|
|
36350
|
+
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
36351
|
+
if (((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.objectType) === 'component' && (_object$userData4 = object.userData) !== null && _object$userData4 !== void 0 && _object$userData4.libraryId) {
|
|
36349
36352
|
components.push(object);
|
|
36350
36353
|
}
|
|
36351
36354
|
});
|
|
36355
|
+
this._componentListCache = components;
|
|
36352
36356
|
return components;
|
|
36353
36357
|
}
|
|
36354
36358
|
|
|
@@ -36454,35 +36458,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36454
36458
|
}
|
|
36455
36459
|
|
|
36456
36460
|
/**
|
|
36457
|
-
* Refresh a specific viewport or all viewports
|
|
36461
|
+
* Refresh a specific viewport or all viewports.
|
|
36462
|
+
* Debounced via requestAnimationFrame so multiple calls within the same
|
|
36463
|
+
* frame (e.g. from Viewport2D mount + refreshAll2DViews) collapse into one.
|
|
36458
36464
|
* @param {string} key - Optional viewport key. If not provided, refreshes all viewports
|
|
36459
36465
|
*/
|
|
36460
36466
|
}, {
|
|
36461
36467
|
key: "refresh",
|
|
36462
36468
|
value: function refresh() {
|
|
36469
|
+
var _this7 = this;
|
|
36463
36470
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
36464
|
-
if (
|
|
36465
|
-
|
|
36466
|
-
|
|
36467
|
-
|
|
36468
|
-
|
|
36469
|
-
|
|
36470
|
-
|
|
36471
|
-
|
|
36472
|
-
|
|
36473
|
-
|
|
36474
|
-
|
|
36475
|
-
|
|
36476
|
-
|
|
36477
|
-
|
|
36471
|
+
if (this._refreshPending) return;
|
|
36472
|
+
this._refreshPending = true;
|
|
36473
|
+
requestAnimationFrame(function () {
|
|
36474
|
+
_this7._refreshPending = false;
|
|
36475
|
+
// Clear per-cycle caches so each component is measured/traversed once per paint
|
|
36476
|
+
_this7._bboxCache.clear();
|
|
36477
|
+
_this7._componentListCache = null;
|
|
36478
|
+
if (key) {
|
|
36479
|
+
var viewport = _this7.viewports.get(key);
|
|
36480
|
+
if (viewport && viewport.isReady) {
|
|
36481
|
+
_this7.renderComponents(viewport);
|
|
36482
|
+
}
|
|
36483
|
+
} else {
|
|
36484
|
+
var _iterator = _createForOfIteratorHelper(_this7.viewports.values()),
|
|
36485
|
+
_step;
|
|
36486
|
+
try {
|
|
36487
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
36488
|
+
var _viewport = _step.value;
|
|
36489
|
+
if (_viewport.isReady) {
|
|
36490
|
+
_this7.renderComponents(_viewport);
|
|
36491
|
+
}
|
|
36478
36492
|
}
|
|
36493
|
+
} catch (err) {
|
|
36494
|
+
_iterator.e(err);
|
|
36495
|
+
} finally {
|
|
36496
|
+
_iterator.f();
|
|
36479
36497
|
}
|
|
36480
|
-
} catch (err) {
|
|
36481
|
-
_iterator.e(err);
|
|
36482
|
-
} finally {
|
|
36483
|
-
_iterator.f();
|
|
36484
36498
|
}
|
|
36485
|
-
}
|
|
36499
|
+
});
|
|
36486
36500
|
}
|
|
36487
36501
|
|
|
36488
36502
|
/**
|
|
@@ -37802,7 +37816,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37802
37816
|
* Initialize the CentralPlant manager
|
|
37803
37817
|
*
|
|
37804
37818
|
* @constructor
|
|
37805
|
-
* @version 0.3.
|
|
37819
|
+
* @version 0.3.6
|
|
37806
37820
|
* @updated 2025-10-22
|
|
37807
37821
|
*
|
|
37808
37822
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|