@2112-lab/central-plant 0.3.45 → 0.3.46
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 +470 -262
- package/dist/cjs/src/core/centralPlant.js +340 -215
- package/dist/cjs/src/core/centralPlantInternals.js +2 -0
- package/dist/cjs/src/managers/controls/componentDragManager.js +2 -1
- package/dist/cjs/src/managers/scene/collisionManager.js +143 -0
- package/dist/cjs/src/managers/scene/sceneExportManager.js +2 -0
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +10 -46
- package/dist/esm/src/core/centralPlant.js +340 -215
- package/dist/esm/src/core/centralPlantInternals.js +2 -0
- package/dist/esm/src/managers/controls/componentDragManager.js +2 -1
- package/dist/esm/src/managers/scene/collisionManager.js +119 -0
- package/dist/esm/src/managers/scene/sceneExportManager.js +2 -0
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +10 -46
- package/package.json +1 -1
|
@@ -21,6 +21,7 @@ var keyboardControlsManager = require('../managers/controls/keyboardControlsMana
|
|
|
21
21
|
var pathfindingManager = require('../managers/pathfinding/pathfindingManager.js');
|
|
22
22
|
var PathFlowManager = require('../managers/pathfinding/PathFlowManager.js');
|
|
23
23
|
var sceneOperationsManager = require('../managers/scene/sceneOperationsManager.js');
|
|
24
|
+
var collisionManager = require('../managers/scene/collisionManager.js');
|
|
24
25
|
var animationManager = require('../managers/scene/animationManager.js');
|
|
25
26
|
var cameraControlsManager = require('../managers/controls/cameraControlsManager.js');
|
|
26
27
|
var componentDragManager = require('../managers/controls/componentDragManager.js');
|
|
@@ -169,6 +170,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
169
170
|
this.centralPlant.managers.keyboardControlsManager = new keyboardControlsManager.KeyboardControlsManager(this.centralPlant.sceneViewer);
|
|
170
171
|
this.centralPlant.managers.pathfindingManager = new pathfindingManager.PathfindingManager(this.centralPlant.sceneViewer);
|
|
171
172
|
this.centralPlant.managers.pathFlowManager = new PathFlowManager.PathFlowManager(this.centralPlant.sceneViewer);
|
|
173
|
+
this.centralPlant.managers.collisionManager = new collisionManager.CollisionManager(this.centralPlant.sceneViewer);
|
|
172
174
|
this.centralPlant.managers.sceneOperationsManager = new sceneOperationsManager.SceneOperationsManager(this.centralPlant.sceneViewer);
|
|
173
175
|
this.centralPlant.managers.animationManager = new animationManager.AnimationManager(this.centralPlant.sceneViewer);
|
|
174
176
|
this.centralPlant.managers.cameraControlsManager = new cameraControlsManager.CameraControlsManager(this.centralPlant.sceneViewer);
|
|
@@ -667,6 +667,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
667
667
|
// Find intersection with ground plane
|
|
668
668
|
var intersection = this.raycaster.ray.intersectPlane(this.dropPlane, this.dropIntersection);
|
|
669
669
|
if (intersection) {
|
|
670
|
+
var _this$sceneViewer$col;
|
|
670
671
|
// Apply 0.5 unit transform snapping to intersection point
|
|
671
672
|
var snappedPosition = this._applyTransformSnap(intersection);
|
|
672
673
|
this.dragData.previewObject.position.copy(snappedPosition);
|
|
@@ -674,7 +675,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
674
675
|
|
|
675
676
|
// Check for overlap and update color accordingly
|
|
676
677
|
var wasOverlapping = this.dragData.isOverlapping;
|
|
677
|
-
this.dragData.isOverlapping = this.
|
|
678
|
+
this.dragData.isOverlapping = !!((_this$sceneViewer$col = this.sceneViewer.collisionManager) !== null && _this$sceneViewer$col !== void 0 && _this$sceneViewer$col.checkCollision(this.dragData.previewObject));
|
|
678
679
|
|
|
679
680
|
// Update color if overlap state changed
|
|
680
681
|
if (wasOverlapping !== this.dragData.isOverlapping) {
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
|
|
6
|
+
var THREE = require('three');
|
|
7
|
+
|
|
8
|
+
function _interopNamespace(e) {
|
|
9
|
+
if (e && e.__esModule) return e;
|
|
10
|
+
var n = Object.create(null);
|
|
11
|
+
if (e) {
|
|
12
|
+
Object.keys(e).forEach(function (k) {
|
|
13
|
+
if (k !== 'default') {
|
|
14
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
get: function () { return e[k]; }
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
n["default"] = e;
|
|
23
|
+
return Object.freeze(n);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
27
|
+
|
|
28
|
+
var CollisionManager = /*#__PURE__*/function () {
|
|
29
|
+
/**
|
|
30
|
+
* @param {Object} sceneViewer - The scene viewer instance
|
|
31
|
+
*/
|
|
32
|
+
function CollisionManager(sceneViewer) {
|
|
33
|
+
_rollupPluginBabelHelpers.classCallCheck(this, CollisionManager);
|
|
34
|
+
this.sceneViewer = sceneViewer;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Check if a given object overlaps with any other relevant objects in the scene.
|
|
39
|
+
* @param {THREE.Object3D} object - The object to check for collisions
|
|
40
|
+
* @param {Array<string>} excludeTypes - Object types to exclude from checking (e.g. ['ground'])
|
|
41
|
+
* @returns {Object|null} Collision info {object, objectType} if collision detected, null otherwise
|
|
42
|
+
*/
|
|
43
|
+
return _rollupPluginBabelHelpers.createClass(CollisionManager, [{
|
|
44
|
+
key: "checkCollision",
|
|
45
|
+
value: function checkCollision(object) {
|
|
46
|
+
var _this$sceneViewer,
|
|
47
|
+
_this = this;
|
|
48
|
+
var excludeTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['isBaseGround', 'isBaseGrid', 'isBrickWall'];
|
|
49
|
+
if (!((_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.scene) || !object) return null;
|
|
50
|
+
|
|
51
|
+
// Compute high-quality bounding box for the object being checked
|
|
52
|
+
// We use setFromObject here because the target object just moved
|
|
53
|
+
var objectBBox = new THREE__namespace.Box3().setFromObject(object);
|
|
54
|
+
|
|
55
|
+
// Narrow down potential colliders
|
|
56
|
+
var collisionDetected = null;
|
|
57
|
+
|
|
58
|
+
// Optimization: Only check the root-level CP objects to avoid O(N^2) complexity with meshes
|
|
59
|
+
this.sceneViewer.scene.traverse(function (child) {
|
|
60
|
+
var _child$userData, _child$userData2, _child$userData3, _child$userData4, _child$userData5;
|
|
61
|
+
if (collisionDetected) return; // Short circuit
|
|
62
|
+
|
|
63
|
+
// Skip the object itself and its descendants
|
|
64
|
+
if (child === object || _this._isDescendantOf(object, child)) return;
|
|
65
|
+
|
|
66
|
+
// Filter by CP object types at the root level (skip internal meshes during traverse)
|
|
67
|
+
var isCPRootObject = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'component' || ((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'segment' || ((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'gateway' || ((_child$userData4 = child.userData) === null || _child$userData4 === void 0 ? void 0 : _child$userData4.objectType) === 'connector' || ((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.ioConfig); // IO Device
|
|
68
|
+
|
|
69
|
+
if (isCPRootObject && !_this._shouldExclude(child, excludeTypes)) {
|
|
70
|
+
// Use cached worldBoundingBox if available, otherwise compute it (and cache it)
|
|
71
|
+
var childBBox;
|
|
72
|
+
if (child.userData.worldBoundingBox && !child.userData.isMoving) {
|
|
73
|
+
var _min$x, _min$y, _min$z, _max$x, _max$y, _max$z;
|
|
74
|
+
// Use stored worldBoundingBox (handles array or Box3 format)
|
|
75
|
+
var min = child.userData.worldBoundingBox.min;
|
|
76
|
+
var max = child.userData.worldBoundingBox.max;
|
|
77
|
+
childBBox = new THREE__namespace.Box3(new THREE__namespace.Vector3((_min$x = min.x) !== null && _min$x !== void 0 ? _min$x : min[0], (_min$y = min.y) !== null && _min$y !== void 0 ? _min$y : min[1], (_min$z = min.z) !== null && _min$z !== void 0 ? _min$z : min[2]), new THREE__namespace.Vector3((_max$x = max.x) !== null && _max$x !== void 0 ? _max$x : max[0], (_max$y = max.y) !== null && _max$y !== void 0 ? _max$y : max[1], (_max$z = max.z) !== null && _max$z !== void 0 ? _max$z : max[2]));
|
|
78
|
+
} else {
|
|
79
|
+
// Fallback to high-quality computation for moving objects or first-time checks
|
|
80
|
+
childBBox = new THREE__namespace.Box3().setFromObject(child);
|
|
81
|
+
|
|
82
|
+
// Cache the result for next time (non-moving objects)
|
|
83
|
+
if (!child.userData.isMoving) {
|
|
84
|
+
child.userData.worldBoundingBox = {
|
|
85
|
+
min: [childBBox.min.x, childBBox.min.y, childBBox.min.z],
|
|
86
|
+
max: [childBBox.max.x, childBBox.max.y, childBBox.max.z]
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (objectBBox.intersectsBox(childBBox)) {
|
|
91
|
+
collisionDetected = {
|
|
92
|
+
object: child,
|
|
93
|
+
objectType: child.userData.objectType,
|
|
94
|
+
uuid: child.uuid,
|
|
95
|
+
name: child.name || child.userData.libraryId || child.uuid
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return collisionDetected;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Helper to check if a node is a descendant of a specific parent
|
|
105
|
+
* @private
|
|
106
|
+
*/
|
|
107
|
+
}, {
|
|
108
|
+
key: "_isDescendantOf",
|
|
109
|
+
value: function _isDescendantOf(parent, child) {
|
|
110
|
+
var node = child.parent;
|
|
111
|
+
while (node !== null) {
|
|
112
|
+
if (node === parent) return true;
|
|
113
|
+
node = node.parent;
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Helper to determine if an object should be excluded from collision checking
|
|
120
|
+
* @private
|
|
121
|
+
*/
|
|
122
|
+
}, {
|
|
123
|
+
key: "_shouldExclude",
|
|
124
|
+
value: function _shouldExclude(object, excludeTypes) {
|
|
125
|
+
if (object.userData.isPreview) return true;
|
|
126
|
+
var _iterator = _rollupPluginBabelHelpers.createForOfIteratorHelper(excludeTypes),
|
|
127
|
+
_step;
|
|
128
|
+
try {
|
|
129
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
130
|
+
var type = _step.value;
|
|
131
|
+
if (object.userData[type]) return true;
|
|
132
|
+
}
|
|
133
|
+
} catch (err) {
|
|
134
|
+
_iterator.e(err);
|
|
135
|
+
} finally {
|
|
136
|
+
_iterator.f();
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}]);
|
|
141
|
+
}();
|
|
142
|
+
|
|
143
|
+
exports.CollisionManager = CollisionManager;
|
|
@@ -167,6 +167,8 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
167
167
|
// Internal tracking - not needed in export
|
|
168
168
|
'initialPosition',
|
|
169
169
|
// Internal tracking - not needed in export
|
|
170
|
+
'attachedDevices',
|
|
171
|
+
// Stored in smart component dictionary, not scene JSON
|
|
170
172
|
// Exclude internal segment tracking properties
|
|
171
173
|
'segmentId',
|
|
172
174
|
// Internal tracking
|
|
@@ -1333,55 +1333,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1333
1333
|
y: componentModel.scale.y,
|
|
1334
1334
|
z: componentModel.scale.z
|
|
1335
1335
|
},
|
|
1336
|
-
userData: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({},
|
|
1336
|
+
userData: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, function () {
|
|
1337
|
+
var ud = _rollupPluginBabelHelpers.objectSpread2({}, componentModel.userData);
|
|
1338
|
+
delete ud.attachedDevices; // Instance data belongs in dictionary, not scene JSON
|
|
1339
|
+
delete ud.isDeclared; // Runtime flag
|
|
1340
|
+
delete ud.originalUuid; // Runtime tracking
|
|
1341
|
+
return ud;
|
|
1342
|
+
}()), {}, {
|
|
1337
1343
|
worldBoundingBox: {
|
|
1338
1344
|
min: boundingBox.min.toArray(),
|
|
1339
1345
|
max: boundingBox.max.toArray()
|
|
1340
1346
|
}
|
|
1341
|
-
})
|
|
1342
|
-
children: []
|
|
1347
|
+
})
|
|
1343
1348
|
};
|
|
1344
1349
|
|
|
1345
|
-
// Process children (connectors, etc.) if they exist
|
|
1346
|
-
if (componentModel.children && componentModel.children.length > 0) {
|
|
1347
|
-
componentModel.children.forEach(function (child) {
|
|
1348
|
-
var _child$userData0, _child$userData1;
|
|
1349
|
-
var childType = ((_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.objectType) || ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType);
|
|
1350
|
-
if (childType === 'connector') {
|
|
1351
|
-
var _child$geometry;
|
|
1352
|
-
var childBoundingBox = new THREE__namespace.Box3().setFromObject(child);
|
|
1353
|
-
var childSceneData = {
|
|
1354
|
-
uuid: child.uuid,
|
|
1355
|
-
name: child.name,
|
|
1356
|
-
type: child.type,
|
|
1357
|
-
position: {
|
|
1358
|
-
x: child.position.x,
|
|
1359
|
-
y: child.position.y,
|
|
1360
|
-
z: child.position.z
|
|
1361
|
-
},
|
|
1362
|
-
rotation: {
|
|
1363
|
-
x: THREE__namespace.MathUtils.radToDeg(child.rotation.x),
|
|
1364
|
-
y: THREE__namespace.MathUtils.radToDeg(child.rotation.y),
|
|
1365
|
-
z: THREE__namespace.MathUtils.radToDeg(child.rotation.z)
|
|
1366
|
-
},
|
|
1367
|
-
scale: {
|
|
1368
|
-
x: child.scale.x,
|
|
1369
|
-
y: child.scale.y,
|
|
1370
|
-
z: child.scale.z
|
|
1371
|
-
},
|
|
1372
|
-
userData: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, child.userData), {}, {
|
|
1373
|
-
worldBoundingBox: {
|
|
1374
|
-
min: childBoundingBox.min.toArray(),
|
|
1375
|
-
max: childBoundingBox.max.toArray()
|
|
1376
|
-
}
|
|
1377
|
-
}),
|
|
1378
|
-
geometry: ((_child$geometry = child.geometry) === null || _child$geometry === void 0 ? void 0 : _child$geometry.uuid) || 'CONNECTOR-GEO'
|
|
1379
|
-
};
|
|
1380
|
-
componentSceneData.children.push(childSceneData);
|
|
1381
|
-
}
|
|
1382
|
-
});
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
1350
|
// Add the component to the scene data
|
|
1386
1351
|
if (!currentSceneData.scene.children) {
|
|
1387
1352
|
currentSceneData.scene.children = [];
|
|
@@ -1390,7 +1355,6 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1390
1355
|
console.log('✅ addComponentToSceneData: Component added to scene data successfully', {
|
|
1391
1356
|
componentId: componentModel.uuid,
|
|
1392
1357
|
libraryId: (_componentModel$userD = componentModel.userData) === null || _componentModel$userD === void 0 ? void 0 : _componentModel$userD.libraryId,
|
|
1393
|
-
childrenCount: componentSceneData.children.length,
|
|
1394
1358
|
totalSceneChildren: currentSceneData.scene.children.length
|
|
1395
1359
|
});
|
|
1396
1360
|
return true;
|
|
@@ -1431,8 +1395,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1431
1395
|
if (segment.children && segment.children.length > 0) {
|
|
1432
1396
|
var childrenToRemove = _rollupPluginBabelHelpers.toConsumableArray(segment.children);
|
|
1433
1397
|
childrenToRemove.forEach(function (child) {
|
|
1434
|
-
var _child$
|
|
1435
|
-
if ((_child$
|
|
1398
|
+
var _child$userData0;
|
|
1399
|
+
if ((_child$userData0 = child.userData) !== null && _child$userData0 !== void 0 && _child$userData0.isPipeElbow) {
|
|
1436
1400
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
1437
1401
|
segment.remove(child);
|
|
1438
1402
|
if (child.geometry) child.geometry.dispose();
|