@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
|
@@ -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.6
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -6,6 +6,7 @@ var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHel
|
|
|
6
6
|
var THREE = require('three');
|
|
7
7
|
var ioDeviceUtils = require('../../utils/ioDeviceUtils.js');
|
|
8
8
|
var modelPreloader = require('../../rendering/modelPreloader.js');
|
|
9
|
+
var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -579,15 +580,28 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
579
580
|
_context5.n = 2;
|
|
580
581
|
return Promise.all(glbLoadingPromises);
|
|
581
582
|
case 2:
|
|
582
|
-
// Update world bounding boxes for loaded models
|
|
583
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
583
584
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
584
|
-
var _jsonData$userData2;
|
|
585
585
|
var jsonData = _ref2.jsonData,
|
|
586
586
|
glbModel = _ref2.glbModel;
|
|
587
|
-
if (glbModel
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
587
|
+
if (!glbModel) return;
|
|
588
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
589
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
590
|
+
var filteredBox = boundingBoxUtils.computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
591
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
592
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
593
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
594
|
+
};
|
|
595
|
+
// Update both the JSON data object AND the live scene object
|
|
596
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
597
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
598
|
+
// Snapshot the object's local position so viewport2DManager can compute
|
|
599
|
+
// world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
|
|
600
|
+
glbModel.userData._wbbBasePosition = {
|
|
601
|
+
x: glbModel.position.x,
|
|
602
|
+
y: glbModel.position.y,
|
|
603
|
+
z: glbModel.position.z
|
|
604
|
+
};
|
|
591
605
|
});
|
|
592
606
|
|
|
593
607
|
// Dispatch completion event
|
|
@@ -7,7 +7,6 @@ var THREE = require('three');
|
|
|
7
7
|
var textureConfig = require('../environment/textureConfig.js');
|
|
8
8
|
var modelManager = require('./modelManager.js');
|
|
9
9
|
var sceneClearingUtility = require('../../utils/sceneClearingUtility.js');
|
|
10
|
-
var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
|
|
11
10
|
|
|
12
11
|
function _interopNamespace(e) {
|
|
13
12
|
if (e && e.__esModule) return e;
|
|
@@ -647,123 +646,52 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
647
646
|
}
|
|
648
647
|
|
|
649
648
|
/**
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
*
|
|
649
|
+
* Sync world-space positions and isDeclared flags for gateways and connectors
|
|
650
|
+
* into the scene JSON data so the pathfinder can read them.
|
|
651
|
+
*
|
|
652
|
+
* Bounding boxes for components and segments are intentionally NOT computed here.
|
|
653
|
+
* They are computed (with matrix-hash caching) by
|
|
654
|
+
* PathfindingManager._enrichSceneDataWithBoundingBoxes(), which runs after GLB
|
|
655
|
+
* models are fully loaded and therefore produces correct values.
|
|
653
656
|
*/
|
|
654
657
|
}, {
|
|
655
|
-
key: "
|
|
656
|
-
value: function
|
|
657
|
-
var
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
// Recursively search children
|
|
677
|
-
if (child.children) {
|
|
678
|
-
var found = _findJsonObject(child.children);
|
|
679
|
-
if (found) return found;
|
|
680
|
-
}
|
|
681
|
-
}
|
|
682
|
-
} catch (err) {
|
|
683
|
-
_iterator.e(err);
|
|
684
|
-
} finally {
|
|
685
|
-
_iterator.f();
|
|
686
|
-
}
|
|
687
|
-
return null;
|
|
688
|
-
};
|
|
689
|
-
jsonObject = _findJsonObject(data.scene.children);
|
|
690
|
-
if (jsonObject) {
|
|
691
|
-
// Store in JSON userData for pathfinder (skip for gateways - they're just routing points)
|
|
692
|
-
if (!jsonObject.userData) jsonObject.userData = {};
|
|
693
|
-
if (jsonObject.userData.objectType === 'component') {
|
|
694
|
-
// For components: compute filtered bounding box (excludes io-device and connector subtrees)
|
|
695
|
-
var filteredBBox = boundingBoxUtils.computeFilteredBoundingBox(object, ['io-device', 'connector']);
|
|
696
|
-
jsonObject.userData.worldBoundingBox = {
|
|
697
|
-
min: filteredBBox.min.toArray(),
|
|
698
|
-
max: filteredBBox.max.toArray()
|
|
699
|
-
};
|
|
700
|
-
console.log("Added filtered world bounding box for component:", jsonObject.userData.worldBoundingBox);
|
|
701
|
-
|
|
702
|
-
// Compute and inject separate io-device bounding boxes as children
|
|
703
|
-
var ioDeviceBBoxes = boundingBoxUtils.computeIODeviceBoundingBoxes(object);
|
|
704
|
-
if (ioDeviceBBoxes.length > 0) {
|
|
705
|
-
if (!jsonObject.children) jsonObject.children = [];
|
|
706
|
-
ioDeviceBBoxes.forEach(function (deviceBBox) {
|
|
707
|
-
var existingIndex = jsonObject.children.findIndex(function (c) {
|
|
708
|
-
return c.uuid === deviceBBox.uuid;
|
|
709
|
-
});
|
|
710
|
-
if (existingIndex >= 0) {
|
|
711
|
-
// Update existing entry
|
|
712
|
-
if (!jsonObject.children[existingIndex].userData) jsonObject.children[existingIndex].userData = {};
|
|
713
|
-
jsonObject.children[existingIndex].userData.objectType = 'io-device';
|
|
714
|
-
jsonObject.children[existingIndex].userData.worldBoundingBox = deviceBBox.worldBoundingBox;
|
|
715
|
-
} else {
|
|
716
|
-
// Create new entry
|
|
717
|
-
jsonObject.children.push({
|
|
718
|
-
uuid: deviceBBox.uuid,
|
|
719
|
-
userData: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, deviceBBox.userData), {}, {
|
|
720
|
-
worldBoundingBox: deviceBBox.worldBoundingBox
|
|
721
|
-
}),
|
|
722
|
-
children: []
|
|
723
|
-
});
|
|
724
|
-
}
|
|
725
|
-
});
|
|
726
|
-
console.log("\uD83D\uDCE6 Injected ".concat(ioDeviceBBoxes.length, " io-device bbox(es) for component ").concat(jsonObject.uuid));
|
|
727
|
-
}
|
|
728
|
-
} else if (jsonObject.userData.objectType !== 'gateway') {
|
|
729
|
-
// For non-component, non-gateway objects: standard bounding box
|
|
730
|
-
var boundingBox = new THREE__namespace.Box3().setFromObject(object);
|
|
731
|
-
jsonObject.userData.worldBoundingBox = {
|
|
732
|
-
min: boundingBox.min.toArray(),
|
|
733
|
-
max: boundingBox.max.toArray()
|
|
734
|
-
};
|
|
735
|
-
console.log("Added world bounding box:", jsonObject.userData.worldBoundingBox);
|
|
736
|
-
}
|
|
737
|
-
|
|
738
|
-
// For gateways and connectors, ensure userData.position exists in scene data
|
|
739
|
-
// This is REQUIRED for pathfinder compatibility
|
|
740
|
-
if (jsonObject.userData.objectType === 'gateway' || jsonObject.userData.objectType === 'connector') {
|
|
741
|
-
// Use the object's world position (from Three.js mesh)
|
|
742
|
-
var worldPos = new THREE__namespace.Vector3();
|
|
743
|
-
object.getWorldPosition(worldPos);
|
|
744
|
-
|
|
745
|
-
// ALWAYS update userData.position with world position
|
|
746
|
-
// This is critical for manual segment connectors which start with local positions
|
|
747
|
-
jsonObject.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
748
|
-
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), "]"));
|
|
749
|
-
|
|
750
|
-
// For gateways, ensure isDeclared flag is in scene data
|
|
751
|
-
if (jsonObject.userData.objectType === 'gateway') {
|
|
752
|
-
if (jsonObject.userData.isDeclared === undefined) {
|
|
753
|
-
jsonObject.userData.isDeclared = true;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
// For manual segment connectors, ensure isDeclared is set in scene data
|
|
758
|
-
if (jsonObject.userData.objectType === 'segment-connector' && jsonObject.userData.isDeclared === undefined) {
|
|
759
|
-
jsonObject.userData.isDeclared = true;
|
|
760
|
-
console.log("\u2705 Set isDeclared=true for manual segment connector in scene data: ".concat(jsonObject.uuid));
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
// Also sync the mesh's userData.position (belt and suspenders approach)
|
|
764
|
-
object.userData.position = [worldPos.x, worldPos.y, worldPos.z];
|
|
765
|
-
}
|
|
658
|
+
key: "_syncPositionsForPathfinding",
|
|
659
|
+
value: function _syncPositionsForPathfinding(data) {
|
|
660
|
+
var scene = this.sceneViewer.scene;
|
|
661
|
+
var worldPos = new THREE__namespace.Vector3();
|
|
662
|
+
var syncPosition = function syncPosition(jsonObject) {
|
|
663
|
+
var _jsonObject$userData;
|
|
664
|
+
var object = scene.getObjectByProperty('uuid', jsonObject.uuid) || scene.getObjectByProperty('uuid', (_jsonObject$userData = jsonObject.userData) === null || _jsonObject$userData === void 0 ? void 0 : _jsonObject$userData.originalUuid);
|
|
665
|
+
if (!object) return;
|
|
666
|
+
object.getWorldPosition(worldPos);
|
|
667
|
+
var pos = [worldPos.x, worldPos.y, worldPos.z];
|
|
668
|
+
jsonObject.userData.position = pos;
|
|
669
|
+
object.userData.position = pos;
|
|
670
|
+
};
|
|
671
|
+
data.scene.children.forEach(function (jsonObject) {
|
|
672
|
+
var _jsonObject$userData2;
|
|
673
|
+
var type = (_jsonObject$userData2 = jsonObject.userData) === null || _jsonObject$userData2 === void 0 ? void 0 : _jsonObject$userData2.objectType;
|
|
674
|
+
if (type === 'gateway') {
|
|
675
|
+
syncPosition(jsonObject);
|
|
676
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
677
|
+
jsonObject.userData.isDeclared = true;
|
|
766
678
|
}
|
|
679
|
+
} else if (type === 'connector') {
|
|
680
|
+
syncPosition(jsonObject);
|
|
681
|
+
} else if (type === 'segment-connector') {
|
|
682
|
+
syncPosition(jsonObject);
|
|
683
|
+
if (jsonObject.userData.isDeclared === undefined) {
|
|
684
|
+
jsonObject.userData.isDeclared = true;
|
|
685
|
+
}
|
|
686
|
+
} else if (type === 'component' && Array.isArray(jsonObject.children)) {
|
|
687
|
+
// Connectors are injected as JSON children by _injectConnectorChildrenFromDictionary
|
|
688
|
+
// and their Three.js objects exist in the scene, created recursively by createSceneObject
|
|
689
|
+
jsonObject.children.forEach(function (childJson) {
|
|
690
|
+
var _childJson$userData;
|
|
691
|
+
if (((_childJson$userData = childJson.userData) === null || _childJson$userData === void 0 ? void 0 : _childJson$userData.objectType) === 'connector') {
|
|
692
|
+
syncPosition(childJson);
|
|
693
|
+
}
|
|
694
|
+
});
|
|
767
695
|
}
|
|
768
696
|
});
|
|
769
697
|
}
|
|
@@ -928,10 +856,10 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
928
856
|
var componentsProcessed = 0;
|
|
929
857
|
var connectorsInjected = 0;
|
|
930
858
|
data.scene.children.forEach(function (child) {
|
|
931
|
-
var _child$
|
|
932
|
-
var childType = ((_child$
|
|
859
|
+
var _child$userData4, _child$userData5, _child$userData6;
|
|
860
|
+
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);
|
|
933
861
|
// Only process components with libraryId
|
|
934
|
-
if (childType === 'component' && (_child$
|
|
862
|
+
if (childType === 'component' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.libraryId) {
|
|
935
863
|
var libraryId = child.userData.libraryId;
|
|
936
864
|
var dictEntry = componentDictionary[libraryId];
|
|
937
865
|
|
|
@@ -1088,23 +1016,25 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1088
1016
|
geometries = this.createSceneGeometries(data, componentDictionary); // Create basic objects and track GLB replacements
|
|
1089
1017
|
libraryObjectsToReplace = [];
|
|
1090
1018
|
data.scene.children.forEach(function (child, index) {
|
|
1091
|
-
var _child$
|
|
1019
|
+
var _child$userData7, _child$userData8;
|
|
1092
1020
|
var createdObject = _this4.createSceneObject(child, geometries, materials, componentDictionary);
|
|
1093
1021
|
_this4.sceneViewer.scene.add(createdObject);
|
|
1094
1022
|
|
|
1095
1023
|
// Track objects that need GLB model replacement
|
|
1096
|
-
if ((_child$
|
|
1097
|
-
var _child$
|
|
1024
|
+
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]) {
|
|
1025
|
+
var _child$userData9;
|
|
1098
1026
|
libraryObjectsToReplace.push({
|
|
1099
1027
|
basicObject: createdObject,
|
|
1100
1028
|
jsonData: child,
|
|
1101
|
-
componentData: componentDictionary[(_child$
|
|
1029
|
+
componentData: componentDictionary[(_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.libraryId]
|
|
1102
1030
|
});
|
|
1103
1031
|
}
|
|
1104
1032
|
});
|
|
1105
1033
|
|
|
1106
|
-
//
|
|
1107
|
-
|
|
1034
|
+
// Sync gateway/connector world positions into JSON before pathfinding.
|
|
1035
|
+
// Bounding boxes are computed later by PathfindingManager._enrichSceneDataWithBoundingBoxes
|
|
1036
|
+
// (after GLB models are loaded), so no bbox work is done here.
|
|
1037
|
+
this._syncPositionsForPathfinding(data);
|
|
1108
1038
|
this._saveOriginalWorldMatrices(this.sceneViewer.scene);
|
|
1109
1039
|
return _context6.a(2, {
|
|
1110
1040
|
componentDictionary: componentDictionary,
|
|
@@ -1250,8 +1180,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1250
1180
|
var instanceBehaviors = [];
|
|
1251
1181
|
if (Array.isArray(data === null || data === void 0 || (_data$scene3 = data.scene) === null || _data$scene3 === void 0 ? void 0 : _data$scene3.children)) {
|
|
1252
1182
|
data.scene.children.forEach(function (child) {
|
|
1253
|
-
var _child$
|
|
1254
|
-
var libraryId = (_child$
|
|
1183
|
+
var _child$userData0, _compData$defaultBeha;
|
|
1184
|
+
var libraryId = (_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.libraryId;
|
|
1255
1185
|
if (!libraryId) return;
|
|
1256
1186
|
var instanceUuid = child.uuid;
|
|
1257
1187
|
// Skip instances whose defaults were already resolved by Step A
|
|
@@ -1447,8 +1377,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1447
1377
|
key: "_saveOriginalWorldMatrices",
|
|
1448
1378
|
value: function _saveOriginalWorldMatrices(scene) {
|
|
1449
1379
|
scene.traverse(function (object) {
|
|
1450
|
-
var _object$
|
|
1451
|
-
if ((_object$
|
|
1380
|
+
var _object$userData;
|
|
1381
|
+
if ((_object$userData = object.userData) !== null && _object$userData !== void 0 && _object$userData.direction) {
|
|
1452
1382
|
var originalMatrix = new THREE__namespace.Matrix4();
|
|
1453
1383
|
originalMatrix.copy(object.matrixWorld);
|
|
1454
1384
|
}
|
|
@@ -1652,8 +1582,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1652
1582
|
// Process children (connectors, etc.) if they exist
|
|
1653
1583
|
if (componentModel.children && componentModel.children.length > 0) {
|
|
1654
1584
|
componentModel.children.forEach(function (child) {
|
|
1655
|
-
var _child$
|
|
1656
|
-
var childType = ((_child$
|
|
1585
|
+
var _child$userData1, _child$userData10;
|
|
1586
|
+
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);
|
|
1657
1587
|
if (childType === 'connector') {
|
|
1658
1588
|
var _child$geometry;
|
|
1659
1589
|
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
@@ -1738,8 +1668,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1738
1668
|
if (segment.children && segment.children.length > 0) {
|
|
1739
1669
|
var childrenToRemove = _rollupPluginBabelHelpers.toConsumableArray(segment.children);
|
|
1740
1670
|
childrenToRemove.forEach(function (child) {
|
|
1741
|
-
var _child$
|
|
1742
|
-
if ((_child$
|
|
1671
|
+
var _child$userData11;
|
|
1672
|
+
if ((_child$userData11 = child.userData) !== null && _child$userData11 !== void 0 && _child$userData11.isPipeElbow) {
|
|
1743
1673
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
1744
1674
|
segment.remove(child);
|
|
1745
1675
|
if (child.geometry) child.geometry.dispose();
|