@2112-lab/central-plant 0.1.44 → 0.1.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 +96 -16
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/components/transformOperationsManager.js +95 -15
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/components/transformOperationsManager.js +95 -15
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -18765,7 +18765,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
18765
18765
|
}, {
|
|
18766
18766
|
key: "translateSegment",
|
|
18767
18767
|
value: function translateSegment(segmentId, axis, value) {
|
|
18768
|
-
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$
|
|
18768
|
+
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$man3, _this$sceneViewer$man4, _this$sceneViewer$man5;
|
|
18769
18769
|
// Validate parameters
|
|
18770
18770
|
if (!segmentId || !axis || value === undefined || value === null) {
|
|
18771
18771
|
console.error('❌ translateSegment(): Invalid parameters');
|
|
@@ -18842,7 +18842,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
18842
18842
|
});
|
|
18843
18843
|
console.log("\uD83D\uDD0D After filtering, ".concat(componentConnectorsAtEndpoints.length, " component connectors at endpoints"));
|
|
18844
18844
|
if (componentConnectorsAtEndpoints.length > 0) {
|
|
18845
|
-
var _this$sceneViewer2;
|
|
18845
|
+
var _this$sceneViewer2, _this$sceneViewer$man2;
|
|
18846
18846
|
console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' has component connectors at endpoints."));
|
|
18847
18847
|
console.log(" Found ".concat(componentConnectorsAtEndpoints.length, " component connector(s):"), componentConnectorsAtEndpoints.map(function (c) {
|
|
18848
18848
|
var _c$parent3;
|
|
@@ -18858,9 +18858,45 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
18858
18858
|
console.warn('⚠️ Segment splitting is disabled. Cannot translate segments with component connectors at endpoints.');
|
|
18859
18859
|
return false;
|
|
18860
18860
|
}
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18861
|
+
|
|
18862
|
+
// Split the segment and translate the free half
|
|
18863
|
+
console.log('✂️ Splitting segment to enable translation of the free half...');
|
|
18864
|
+
|
|
18865
|
+
// Get sceneOperationsManager
|
|
18866
|
+
var _sceneOperationsManager = (_this$sceneViewer$man2 = this.sceneViewer.managers) === null || _this$sceneViewer$man2 === void 0 ? void 0 : _this$sceneViewer$man2.sceneOperationsManager;
|
|
18867
|
+
if (!_sceneOperationsManager) {
|
|
18868
|
+
console.error('❌ translateSegment(): SceneOperationsManager not available for splitting');
|
|
18869
|
+
return false;
|
|
18870
|
+
}
|
|
18871
|
+
try {
|
|
18872
|
+
var splitResult = _sceneOperationsManager.splitSegment(segment);
|
|
18873
|
+
if (splitResult && splitResult.segment1 && splitResult.segment2) {
|
|
18874
|
+
console.log("\u2705 Segment split: ".concat(splitResult.segment1.uuid, " (").concat(splitResult.segment1.geometry.parameters.height, "), ").concat(splitResult.segment2.uuid, " (").concat(splitResult.segment2.geometry.parameters.height, ")"));
|
|
18875
|
+
|
|
18876
|
+
// Determine which segment is the longer one (free side) to translate
|
|
18877
|
+
var segment1Length = splitResult.segment1.geometry.parameters.height;
|
|
18878
|
+
var segment2Length = splitResult.segment2.geometry.parameters.height;
|
|
18879
|
+
|
|
18880
|
+
// The longer segment is the one WITHOUT the component connector
|
|
18881
|
+
var segmentToTranslate = segment1Length > segment2Length ? splitResult.segment1 : splitResult.segment2;
|
|
18882
|
+
console.log("\uD83C\uDFAF Translating ".concat(segmentToTranslate.uuid, " (length: ").concat(segmentToTranslate.geometry.parameters.height, ") - the free segment"));
|
|
18883
|
+
|
|
18884
|
+
// Now translate the chosen segment (recursive call with the new segment)
|
|
18885
|
+
var translateSuccess = this.translateSegment(segmentToTranslate.uuid, axis, value);
|
|
18886
|
+
if (!translateSuccess) {
|
|
18887
|
+
console.error('❌ translateSegment(): Failed to translate split segment half');
|
|
18888
|
+
return false;
|
|
18889
|
+
}
|
|
18890
|
+
console.log('✅ Split and translate operation completed successfully');
|
|
18891
|
+
return true;
|
|
18892
|
+
} else {
|
|
18893
|
+
console.error('❌ translateSegment(): Split operation failed');
|
|
18894
|
+
return false;
|
|
18895
|
+
}
|
|
18896
|
+
} catch (error) {
|
|
18897
|
+
console.error('❌ translateSegment(): Error splitting segment:', error);
|
|
18898
|
+
return false;
|
|
18899
|
+
}
|
|
18864
18900
|
}
|
|
18865
18901
|
console.log("\uD83D\uDD04 translateSegment(): Translating segment ".concat(segmentId, " on ").concat(axis, " axis by ").concat(value));
|
|
18866
18902
|
|
|
@@ -18925,8 +18961,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
18925
18961
|
}
|
|
18926
18962
|
|
|
18927
18963
|
// Validate PathfindingManager and SceneOperationsManager availability
|
|
18928
|
-
var pathfindingManager = (_this$sceneViewer$
|
|
18929
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
18964
|
+
var pathfindingManager = (_this$sceneViewer$man3 = this.sceneViewer.managers) === null || _this$sceneViewer$man3 === void 0 ? void 0 : _this$sceneViewer$man3.pathfindingManager;
|
|
18965
|
+
var sceneOperationsManager = (_this$sceneViewer$man4 = this.sceneViewer.managers) === null || _this$sceneViewer$man4 === void 0 ? void 0 : _this$sceneViewer$man4.sceneOperationsManager;
|
|
18930
18966
|
if (!pathfindingManager || !sceneOperationsManager) {
|
|
18931
18967
|
console.error('❌ translateSegment(): PathfindingManager or SceneOperationsManager not available');
|
|
18932
18968
|
return false;
|
|
@@ -18961,7 +18997,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
18961
18997
|
|
|
18962
18998
|
// Store transform parameters using the OperationHistoryManager BEFORE updatePaths
|
|
18963
18999
|
// This is critical so that intersection detection can undo the operation
|
|
18964
|
-
if ((_this$sceneViewer$
|
|
19000
|
+
if ((_this$sceneViewer$man5 = this.sceneViewer.managers) !== null && _this$sceneViewer$man5 !== void 0 && _this$sceneViewer$man5.operationHistory) {
|
|
18965
19001
|
this.sceneViewer.managers.operationHistory.addToOperationHistory('translateSegment', {
|
|
18966
19002
|
segmentId: segmentId,
|
|
18967
19003
|
axis: axis,
|
|
@@ -19009,11 +19045,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19009
19045
|
}, {
|
|
19010
19046
|
key: "translateGateway",
|
|
19011
19047
|
value: function translateGateway(gatewayId, axis, value) {
|
|
19012
|
-
var _this$sceneViewer$
|
|
19048
|
+
var _this$sceneViewer$man6, _this$sceneViewer$man7;
|
|
19013
19049
|
console.log("[Pathfinder] translateGateway started");
|
|
19014
19050
|
|
|
19015
19051
|
// Store transform parameters using the OperationHistoryManager
|
|
19016
|
-
if ((_this$sceneViewer$
|
|
19052
|
+
if ((_this$sceneViewer$man6 = this.sceneViewer.managers) !== null && _this$sceneViewer$man6 !== void 0 && _this$sceneViewer$man6.operationHistoryManager) {
|
|
19017
19053
|
this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateGateway', {
|
|
19018
19054
|
gatewayId: gatewayId,
|
|
19019
19055
|
axis: axis,
|
|
@@ -19064,7 +19100,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19064
19100
|
|
|
19065
19101
|
// Handle manual gateway transformation (convert to declared and process connections)
|
|
19066
19102
|
console.log('🔧 Handling manual gateway transformation via SceneOperationsManager');
|
|
19067
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
19103
|
+
var sceneOperationsManager = (_this$sceneViewer$man7 = this.sceneViewer.managers) === null || _this$sceneViewer$man7 === void 0 ? void 0 : _this$sceneViewer$man7.sceneOperationsManager;
|
|
19068
19104
|
if (!sceneOperationsManager) {
|
|
19069
19105
|
console.error('❌ translateGateway(): SceneOperationsManager not available');
|
|
19070
19106
|
return false;
|
|
@@ -19543,6 +19579,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19543
19579
|
return null;
|
|
19544
19580
|
}
|
|
19545
19581
|
var collisionRadius = 0.5; // Radius around connector that triggers collision
|
|
19582
|
+
var endpointTolerance = 0.55; // Tolerance for determining if connector is at segment endpoint
|
|
19546
19583
|
|
|
19547
19584
|
// Get segment endpoints in world coordinates
|
|
19548
19585
|
var endpoints = this.calculateSegmentEndpoints(segment);
|
|
@@ -19561,6 +19598,13 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19561
19598
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
19562
19599
|
child.getWorldPosition(connectorWorldPos);
|
|
19563
19600
|
|
|
19601
|
+
// Skip connectors that are at the segment's endpoints (legitimate connection points)
|
|
19602
|
+
var distanceToStart = connectorWorldPos.distanceTo(startPoint);
|
|
19603
|
+
var distanceToEnd = connectorWorldPos.distanceTo(endPoint);
|
|
19604
|
+
if (distanceToStart <= endpointTolerance || distanceToEnd <= endpointTolerance) {
|
|
19605
|
+
return; // Skip this connector - it's at an endpoint
|
|
19606
|
+
}
|
|
19607
|
+
|
|
19564
19608
|
// Find the closest point on the segment to the connector
|
|
19565
19609
|
var segmentVector = new THREE__namespace.Vector3().subVectors(endPoint, startPoint);
|
|
19566
19610
|
var pointVector = new THREE__namespace.Vector3().subVectors(connectorWorldPos, startPoint);
|
|
@@ -19759,6 +19803,37 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19759
19803
|
return c1.distanceTo(c2);
|
|
19760
19804
|
}
|
|
19761
19805
|
|
|
19806
|
+
/**
|
|
19807
|
+
* Constrain a position to maintain orthogonal alignment with a reference position
|
|
19808
|
+
* Movement is restricted to only along the segment's direction vector
|
|
19809
|
+
* @param {THREE.Vector3} newPosition - The proposed new position
|
|
19810
|
+
* @param {THREE.Vector3} referencePosition - The stationary reference position
|
|
19811
|
+
* @param {THREE.Object3D} segment - The segment being adjusted
|
|
19812
|
+
* @returns {THREE.Vector3} Constrained position that maintains orthogonality
|
|
19813
|
+
* @private
|
|
19814
|
+
*/
|
|
19815
|
+
}, {
|
|
19816
|
+
key: "constrainPositionToOrthogonal",
|
|
19817
|
+
value: function constrainPositionToOrthogonal(newPosition, referencePosition, segment) {
|
|
19818
|
+
// Get the segment's direction vector
|
|
19819
|
+
var direction = new THREE__namespace.Vector3(0, 1, 0);
|
|
19820
|
+
direction.applyQuaternion(segment.quaternion);
|
|
19821
|
+
direction.normalize();
|
|
19822
|
+
|
|
19823
|
+
// Calculate vector from reference position to new position
|
|
19824
|
+
var moveVector = new THREE__namespace.Vector3().subVectors(newPosition, referencePosition);
|
|
19825
|
+
|
|
19826
|
+
// Project the move vector onto the segment's direction
|
|
19827
|
+
// This gives us the component of movement along the segment's axis only
|
|
19828
|
+
var projectionLength = moveVector.dot(direction);
|
|
19829
|
+
|
|
19830
|
+
// Constrained position = reference + (projection along segment direction)
|
|
19831
|
+
var constrainedPos = new THREE__namespace.Vector3().copy(referencePosition).add(direction.clone().multiplyScalar(projectionLength));
|
|
19832
|
+
console.log("\uD83D\uDD12 Constrained movement along segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
19833
|
+
console.log(" Projection length: ".concat(projectionLength.toFixed(3)));
|
|
19834
|
+
return constrainedPos;
|
|
19835
|
+
}
|
|
19836
|
+
|
|
19762
19837
|
/**
|
|
19763
19838
|
* Update adjacent segment connectors to follow the moved segment's new position
|
|
19764
19839
|
* Finds segments that were connected to the moved segment BEFORE the move,
|
|
@@ -19877,18 +19952,23 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
19877
19952
|
var stationaryWorldPos = new THREE__namespace.Vector3();
|
|
19878
19953
|
stationaryConnector.getWorldPosition(stationaryWorldPos);
|
|
19879
19954
|
|
|
19955
|
+
// Constrain movement to maintain orthogonal alignment
|
|
19956
|
+
// Horizontal segments: only adjust X and Y, keep Z constant
|
|
19957
|
+
// Vertical segments: only adjust Z, keep X and Y constant
|
|
19958
|
+
var constrainedPosition = _this2.constrainPositionToOrthogonal(pair.newPosition, stationaryWorldPos, adjacentSegment);
|
|
19959
|
+
|
|
19880
19960
|
// Recreate the segment mesh with new length using explicit endpoint positions
|
|
19881
19961
|
// Pass the intended positions, not the connector objects (which may have temporary positions)
|
|
19882
|
-
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors,
|
|
19962
|
+
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors, constrainedPosition, stationaryWorldPos);
|
|
19883
19963
|
|
|
19884
19964
|
// CRITICAL: After recreating the mesh, BOTH connectors need to be repositioned
|
|
19885
19965
|
// because the segment's center and rotation have changed
|
|
19886
19966
|
|
|
19887
|
-
// Position moving connector at the new position
|
|
19888
|
-
var movingLocalPos = adjacentSegment.worldToLocal(
|
|
19967
|
+
// Position moving connector at the constrained position (not the raw new position)
|
|
19968
|
+
var movingLocalPos = adjacentSegment.worldToLocal(constrainedPosition.clone());
|
|
19889
19969
|
movingConnector.position.copy(movingLocalPos);
|
|
19890
19970
|
movingConnector.updateMatrixWorld(true);
|
|
19891
|
-
_this2.updateConnectorPositionInSceneData(movingConnector,
|
|
19971
|
+
_this2.updateConnectorPositionInSceneData(movingConnector, constrainedPosition, adjacentSegment);
|
|
19892
19972
|
|
|
19893
19973
|
// Position stationary connector at its original world position
|
|
19894
19974
|
var stationaryLocalPos = adjacentSegment.worldToLocal(stationaryWorldPos.clone());
|
|
@@ -32488,7 +32568,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
32488
32568
|
* Initialize the CentralPlant manager
|
|
32489
32569
|
*
|
|
32490
32570
|
* @constructor
|
|
32491
|
-
* @version 0.1.
|
|
32571
|
+
* @version 0.1.46
|
|
32492
32572
|
* @updated 2025-10-22
|
|
32493
32573
|
*
|
|
32494
32574
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -19,7 +19,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
19
19
|
* Initialize the CentralPlant manager
|
|
20
20
|
*
|
|
21
21
|
* @constructor
|
|
22
|
-
* @version 0.1.
|
|
22
|
+
* @version 0.1.46
|
|
23
23
|
* @updated 2025-10-22
|
|
24
24
|
*
|
|
25
25
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -126,7 +126,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
126
126
|
}, {
|
|
127
127
|
key: "translateSegment",
|
|
128
128
|
value: function translateSegment(segmentId, axis, value) {
|
|
129
|
-
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$
|
|
129
|
+
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$man3, _this$sceneViewer$man4, _this$sceneViewer$man5;
|
|
130
130
|
// Validate parameters
|
|
131
131
|
if (!segmentId || !axis || value === undefined || value === null) {
|
|
132
132
|
console.error('❌ translateSegment(): Invalid parameters');
|
|
@@ -203,7 +203,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
203
203
|
});
|
|
204
204
|
console.log("\uD83D\uDD0D After filtering, ".concat(componentConnectorsAtEndpoints.length, " component connectors at endpoints"));
|
|
205
205
|
if (componentConnectorsAtEndpoints.length > 0) {
|
|
206
|
-
var _this$sceneViewer2;
|
|
206
|
+
var _this$sceneViewer2, _this$sceneViewer$man2;
|
|
207
207
|
console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' has component connectors at endpoints."));
|
|
208
208
|
console.log(" Found ".concat(componentConnectorsAtEndpoints.length, " component connector(s):"), componentConnectorsAtEndpoints.map(function (c) {
|
|
209
209
|
var _c$parent3;
|
|
@@ -219,9 +219,45 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
219
219
|
console.warn('⚠️ Segment splitting is disabled. Cannot translate segments with component connectors at endpoints.');
|
|
220
220
|
return false;
|
|
221
221
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
|
|
223
|
+
// Split the segment and translate the free half
|
|
224
|
+
console.log('✂️ Splitting segment to enable translation of the free half...');
|
|
225
|
+
|
|
226
|
+
// Get sceneOperationsManager
|
|
227
|
+
var _sceneOperationsManager = (_this$sceneViewer$man2 = this.sceneViewer.managers) === null || _this$sceneViewer$man2 === void 0 ? void 0 : _this$sceneViewer$man2.sceneOperationsManager;
|
|
228
|
+
if (!_sceneOperationsManager) {
|
|
229
|
+
console.error('❌ translateSegment(): SceneOperationsManager not available for splitting');
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
var splitResult = _sceneOperationsManager.splitSegment(segment);
|
|
234
|
+
if (splitResult && splitResult.segment1 && splitResult.segment2) {
|
|
235
|
+
console.log("\u2705 Segment split: ".concat(splitResult.segment1.uuid, " (").concat(splitResult.segment1.geometry.parameters.height, "), ").concat(splitResult.segment2.uuid, " (").concat(splitResult.segment2.geometry.parameters.height, ")"));
|
|
236
|
+
|
|
237
|
+
// Determine which segment is the longer one (free side) to translate
|
|
238
|
+
var segment1Length = splitResult.segment1.geometry.parameters.height;
|
|
239
|
+
var segment2Length = splitResult.segment2.geometry.parameters.height;
|
|
240
|
+
|
|
241
|
+
// The longer segment is the one WITHOUT the component connector
|
|
242
|
+
var segmentToTranslate = segment1Length > segment2Length ? splitResult.segment1 : splitResult.segment2;
|
|
243
|
+
console.log("\uD83C\uDFAF Translating ".concat(segmentToTranslate.uuid, " (length: ").concat(segmentToTranslate.geometry.parameters.height, ") - the free segment"));
|
|
244
|
+
|
|
245
|
+
// Now translate the chosen segment (recursive call with the new segment)
|
|
246
|
+
var translateSuccess = this.translateSegment(segmentToTranslate.uuid, axis, value);
|
|
247
|
+
if (!translateSuccess) {
|
|
248
|
+
console.error('❌ translateSegment(): Failed to translate split segment half');
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
console.log('✅ Split and translate operation completed successfully');
|
|
252
|
+
return true;
|
|
253
|
+
} else {
|
|
254
|
+
console.error('❌ translateSegment(): Split operation failed');
|
|
255
|
+
return false;
|
|
256
|
+
}
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error('❌ translateSegment(): Error splitting segment:', error);
|
|
259
|
+
return false;
|
|
260
|
+
}
|
|
225
261
|
}
|
|
226
262
|
console.log("\uD83D\uDD04 translateSegment(): Translating segment ".concat(segmentId, " on ").concat(axis, " axis by ").concat(value));
|
|
227
263
|
|
|
@@ -286,8 +322,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
286
322
|
}
|
|
287
323
|
|
|
288
324
|
// Validate PathfindingManager and SceneOperationsManager availability
|
|
289
|
-
var pathfindingManager = (_this$sceneViewer$
|
|
290
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
325
|
+
var pathfindingManager = (_this$sceneViewer$man3 = this.sceneViewer.managers) === null || _this$sceneViewer$man3 === void 0 ? void 0 : _this$sceneViewer$man3.pathfindingManager;
|
|
326
|
+
var sceneOperationsManager = (_this$sceneViewer$man4 = this.sceneViewer.managers) === null || _this$sceneViewer$man4 === void 0 ? void 0 : _this$sceneViewer$man4.sceneOperationsManager;
|
|
291
327
|
if (!pathfindingManager || !sceneOperationsManager) {
|
|
292
328
|
console.error('❌ translateSegment(): PathfindingManager or SceneOperationsManager not available');
|
|
293
329
|
return false;
|
|
@@ -322,7 +358,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
322
358
|
|
|
323
359
|
// Store transform parameters using the OperationHistoryManager BEFORE updatePaths
|
|
324
360
|
// This is critical so that intersection detection can undo the operation
|
|
325
|
-
if ((_this$sceneViewer$
|
|
361
|
+
if ((_this$sceneViewer$man5 = this.sceneViewer.managers) !== null && _this$sceneViewer$man5 !== void 0 && _this$sceneViewer$man5.operationHistory) {
|
|
326
362
|
this.sceneViewer.managers.operationHistory.addToOperationHistory('translateSegment', {
|
|
327
363
|
segmentId: segmentId,
|
|
328
364
|
axis: axis,
|
|
@@ -370,11 +406,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
370
406
|
}, {
|
|
371
407
|
key: "translateGateway",
|
|
372
408
|
value: function translateGateway(gatewayId, axis, value) {
|
|
373
|
-
var _this$sceneViewer$
|
|
409
|
+
var _this$sceneViewer$man6, _this$sceneViewer$man7;
|
|
374
410
|
console.log("[Pathfinder] translateGateway started");
|
|
375
411
|
|
|
376
412
|
// Store transform parameters using the OperationHistoryManager
|
|
377
|
-
if ((_this$sceneViewer$
|
|
413
|
+
if ((_this$sceneViewer$man6 = this.sceneViewer.managers) !== null && _this$sceneViewer$man6 !== void 0 && _this$sceneViewer$man6.operationHistoryManager) {
|
|
378
414
|
this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateGateway', {
|
|
379
415
|
gatewayId: gatewayId,
|
|
380
416
|
axis: axis,
|
|
@@ -425,7 +461,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
425
461
|
|
|
426
462
|
// Handle manual gateway transformation (convert to declared and process connections)
|
|
427
463
|
console.log('🔧 Handling manual gateway transformation via SceneOperationsManager');
|
|
428
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
464
|
+
var sceneOperationsManager = (_this$sceneViewer$man7 = this.sceneViewer.managers) === null || _this$sceneViewer$man7 === void 0 ? void 0 : _this$sceneViewer$man7.sceneOperationsManager;
|
|
429
465
|
if (!sceneOperationsManager) {
|
|
430
466
|
console.error('❌ translateGateway(): SceneOperationsManager not available');
|
|
431
467
|
return false;
|
|
@@ -904,6 +940,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
904
940
|
return null;
|
|
905
941
|
}
|
|
906
942
|
var collisionRadius = 0.5; // Radius around connector that triggers collision
|
|
943
|
+
var endpointTolerance = 0.55; // Tolerance for determining if connector is at segment endpoint
|
|
907
944
|
|
|
908
945
|
// Get segment endpoints in world coordinates
|
|
909
946
|
var endpoints = this.calculateSegmentEndpoints(segment);
|
|
@@ -922,6 +959,13 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
922
959
|
var connectorWorldPos = new THREE__namespace.Vector3();
|
|
923
960
|
child.getWorldPosition(connectorWorldPos);
|
|
924
961
|
|
|
962
|
+
// Skip connectors that are at the segment's endpoints (legitimate connection points)
|
|
963
|
+
var distanceToStart = connectorWorldPos.distanceTo(startPoint);
|
|
964
|
+
var distanceToEnd = connectorWorldPos.distanceTo(endPoint);
|
|
965
|
+
if (distanceToStart <= endpointTolerance || distanceToEnd <= endpointTolerance) {
|
|
966
|
+
return; // Skip this connector - it's at an endpoint
|
|
967
|
+
}
|
|
968
|
+
|
|
925
969
|
// Find the closest point on the segment to the connector
|
|
926
970
|
var segmentVector = new THREE__namespace.Vector3().subVectors(endPoint, startPoint);
|
|
927
971
|
var pointVector = new THREE__namespace.Vector3().subVectors(connectorWorldPos, startPoint);
|
|
@@ -1120,6 +1164,37 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1120
1164
|
return c1.distanceTo(c2);
|
|
1121
1165
|
}
|
|
1122
1166
|
|
|
1167
|
+
/**
|
|
1168
|
+
* Constrain a position to maintain orthogonal alignment with a reference position
|
|
1169
|
+
* Movement is restricted to only along the segment's direction vector
|
|
1170
|
+
* @param {THREE.Vector3} newPosition - The proposed new position
|
|
1171
|
+
* @param {THREE.Vector3} referencePosition - The stationary reference position
|
|
1172
|
+
* @param {THREE.Object3D} segment - The segment being adjusted
|
|
1173
|
+
* @returns {THREE.Vector3} Constrained position that maintains orthogonality
|
|
1174
|
+
* @private
|
|
1175
|
+
*/
|
|
1176
|
+
}, {
|
|
1177
|
+
key: "constrainPositionToOrthogonal",
|
|
1178
|
+
value: function constrainPositionToOrthogonal(newPosition, referencePosition, segment) {
|
|
1179
|
+
// Get the segment's direction vector
|
|
1180
|
+
var direction = new THREE__namespace.Vector3(0, 1, 0);
|
|
1181
|
+
direction.applyQuaternion(segment.quaternion);
|
|
1182
|
+
direction.normalize();
|
|
1183
|
+
|
|
1184
|
+
// Calculate vector from reference position to new position
|
|
1185
|
+
var moveVector = new THREE__namespace.Vector3().subVectors(newPosition, referencePosition);
|
|
1186
|
+
|
|
1187
|
+
// Project the move vector onto the segment's direction
|
|
1188
|
+
// This gives us the component of movement along the segment's axis only
|
|
1189
|
+
var projectionLength = moveVector.dot(direction);
|
|
1190
|
+
|
|
1191
|
+
// Constrained position = reference + (projection along segment direction)
|
|
1192
|
+
var constrainedPos = new THREE__namespace.Vector3().copy(referencePosition).add(direction.clone().multiplyScalar(projectionLength));
|
|
1193
|
+
console.log("\uD83D\uDD12 Constrained movement along segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
1194
|
+
console.log(" Projection length: ".concat(projectionLength.toFixed(3)));
|
|
1195
|
+
return constrainedPos;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1123
1198
|
/**
|
|
1124
1199
|
* Update adjacent segment connectors to follow the moved segment's new position
|
|
1125
1200
|
* Finds segments that were connected to the moved segment BEFORE the move,
|
|
@@ -1238,18 +1313,23 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1238
1313
|
var stationaryWorldPos = new THREE__namespace.Vector3();
|
|
1239
1314
|
stationaryConnector.getWorldPosition(stationaryWorldPos);
|
|
1240
1315
|
|
|
1316
|
+
// Constrain movement to maintain orthogonal alignment
|
|
1317
|
+
// Horizontal segments: only adjust X and Y, keep Z constant
|
|
1318
|
+
// Vertical segments: only adjust Z, keep X and Y constant
|
|
1319
|
+
var constrainedPosition = _this2.constrainPositionToOrthogonal(pair.newPosition, stationaryWorldPos, adjacentSegment);
|
|
1320
|
+
|
|
1241
1321
|
// Recreate the segment mesh with new length using explicit endpoint positions
|
|
1242
1322
|
// Pass the intended positions, not the connector objects (which may have temporary positions)
|
|
1243
|
-
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors,
|
|
1323
|
+
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors, constrainedPosition, stationaryWorldPos);
|
|
1244
1324
|
|
|
1245
1325
|
// CRITICAL: After recreating the mesh, BOTH connectors need to be repositioned
|
|
1246
1326
|
// because the segment's center and rotation have changed
|
|
1247
1327
|
|
|
1248
|
-
// Position moving connector at the new position
|
|
1249
|
-
var movingLocalPos = adjacentSegment.worldToLocal(
|
|
1328
|
+
// Position moving connector at the constrained position (not the raw new position)
|
|
1329
|
+
var movingLocalPos = adjacentSegment.worldToLocal(constrainedPosition.clone());
|
|
1250
1330
|
movingConnector.position.copy(movingLocalPos);
|
|
1251
1331
|
movingConnector.updateMatrixWorld(true);
|
|
1252
|
-
_this2.updateConnectorPositionInSceneData(movingConnector,
|
|
1332
|
+
_this2.updateConnectorPositionInSceneData(movingConnector, constrainedPosition, adjacentSegment);
|
|
1253
1333
|
|
|
1254
1334
|
// Position stationary connector at its original world position
|
|
1255
1335
|
var stationaryLocalPos = adjacentSegment.worldToLocal(stationaryWorldPos.clone());
|
|
@@ -15,7 +15,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
15
15
|
* Initialize the CentralPlant manager
|
|
16
16
|
*
|
|
17
17
|
* @constructor
|
|
18
|
-
* @version 0.1.
|
|
18
|
+
* @version 0.1.46
|
|
19
19
|
* @updated 2025-10-22
|
|
20
20
|
*
|
|
21
21
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -102,7 +102,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
102
102
|
}, {
|
|
103
103
|
key: "translateSegment",
|
|
104
104
|
value: function translateSegment(segmentId, axis, value) {
|
|
105
|
-
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$
|
|
105
|
+
var _segment$userData, _segment$userData2, _this$sceneViewer3, _this$sceneViewer$man3, _this$sceneViewer$man4, _this$sceneViewer$man5;
|
|
106
106
|
// Validate parameters
|
|
107
107
|
if (!segmentId || !axis || value === undefined || value === null) {
|
|
108
108
|
console.error('❌ translateSegment(): Invalid parameters');
|
|
@@ -179,7 +179,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
179
179
|
});
|
|
180
180
|
console.log("\uD83D\uDD0D After filtering, ".concat(componentConnectorsAtEndpoints.length, " component connectors at endpoints"));
|
|
181
181
|
if (componentConnectorsAtEndpoints.length > 0) {
|
|
182
|
-
var _this$sceneViewer2;
|
|
182
|
+
var _this$sceneViewer2, _this$sceneViewer$man2;
|
|
183
183
|
console.warn("\u26A0\uFE0F translateSegment(): Segment '".concat(segmentId, "' has component connectors at endpoints."));
|
|
184
184
|
console.log(" Found ".concat(componentConnectorsAtEndpoints.length, " component connector(s):"), componentConnectorsAtEndpoints.map(function (c) {
|
|
185
185
|
var _c$parent3;
|
|
@@ -195,9 +195,45 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
195
195
|
console.warn('⚠️ Segment splitting is disabled. Cannot translate segments with component connectors at endpoints.');
|
|
196
196
|
return false;
|
|
197
197
|
}
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
|
|
199
|
+
// Split the segment and translate the free half
|
|
200
|
+
console.log('✂️ Splitting segment to enable translation of the free half...');
|
|
201
|
+
|
|
202
|
+
// Get sceneOperationsManager
|
|
203
|
+
var _sceneOperationsManager = (_this$sceneViewer$man2 = this.sceneViewer.managers) === null || _this$sceneViewer$man2 === void 0 ? void 0 : _this$sceneViewer$man2.sceneOperationsManager;
|
|
204
|
+
if (!_sceneOperationsManager) {
|
|
205
|
+
console.error('❌ translateSegment(): SceneOperationsManager not available for splitting');
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
try {
|
|
209
|
+
var splitResult = _sceneOperationsManager.splitSegment(segment);
|
|
210
|
+
if (splitResult && splitResult.segment1 && splitResult.segment2) {
|
|
211
|
+
console.log("\u2705 Segment split: ".concat(splitResult.segment1.uuid, " (").concat(splitResult.segment1.geometry.parameters.height, "), ").concat(splitResult.segment2.uuid, " (").concat(splitResult.segment2.geometry.parameters.height, ")"));
|
|
212
|
+
|
|
213
|
+
// Determine which segment is the longer one (free side) to translate
|
|
214
|
+
var segment1Length = splitResult.segment1.geometry.parameters.height;
|
|
215
|
+
var segment2Length = splitResult.segment2.geometry.parameters.height;
|
|
216
|
+
|
|
217
|
+
// The longer segment is the one WITHOUT the component connector
|
|
218
|
+
var segmentToTranslate = segment1Length > segment2Length ? splitResult.segment1 : splitResult.segment2;
|
|
219
|
+
console.log("\uD83C\uDFAF Translating ".concat(segmentToTranslate.uuid, " (length: ").concat(segmentToTranslate.geometry.parameters.height, ") - the free segment"));
|
|
220
|
+
|
|
221
|
+
// Now translate the chosen segment (recursive call with the new segment)
|
|
222
|
+
var translateSuccess = this.translateSegment(segmentToTranslate.uuid, axis, value);
|
|
223
|
+
if (!translateSuccess) {
|
|
224
|
+
console.error('❌ translateSegment(): Failed to translate split segment half');
|
|
225
|
+
return false;
|
|
226
|
+
}
|
|
227
|
+
console.log('✅ Split and translate operation completed successfully');
|
|
228
|
+
return true;
|
|
229
|
+
} else {
|
|
230
|
+
console.error('❌ translateSegment(): Split operation failed');
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
} catch (error) {
|
|
234
|
+
console.error('❌ translateSegment(): Error splitting segment:', error);
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
201
237
|
}
|
|
202
238
|
console.log("\uD83D\uDD04 translateSegment(): Translating segment ".concat(segmentId, " on ").concat(axis, " axis by ").concat(value));
|
|
203
239
|
|
|
@@ -262,8 +298,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
262
298
|
}
|
|
263
299
|
|
|
264
300
|
// Validate PathfindingManager and SceneOperationsManager availability
|
|
265
|
-
var pathfindingManager = (_this$sceneViewer$
|
|
266
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
301
|
+
var pathfindingManager = (_this$sceneViewer$man3 = this.sceneViewer.managers) === null || _this$sceneViewer$man3 === void 0 ? void 0 : _this$sceneViewer$man3.pathfindingManager;
|
|
302
|
+
var sceneOperationsManager = (_this$sceneViewer$man4 = this.sceneViewer.managers) === null || _this$sceneViewer$man4 === void 0 ? void 0 : _this$sceneViewer$man4.sceneOperationsManager;
|
|
267
303
|
if (!pathfindingManager || !sceneOperationsManager) {
|
|
268
304
|
console.error('❌ translateSegment(): PathfindingManager or SceneOperationsManager not available');
|
|
269
305
|
return false;
|
|
@@ -298,7 +334,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
298
334
|
|
|
299
335
|
// Store transform parameters using the OperationHistoryManager BEFORE updatePaths
|
|
300
336
|
// This is critical so that intersection detection can undo the operation
|
|
301
|
-
if ((_this$sceneViewer$
|
|
337
|
+
if ((_this$sceneViewer$man5 = this.sceneViewer.managers) !== null && _this$sceneViewer$man5 !== void 0 && _this$sceneViewer$man5.operationHistory) {
|
|
302
338
|
this.sceneViewer.managers.operationHistory.addToOperationHistory('translateSegment', {
|
|
303
339
|
segmentId: segmentId,
|
|
304
340
|
axis: axis,
|
|
@@ -346,11 +382,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
346
382
|
}, {
|
|
347
383
|
key: "translateGateway",
|
|
348
384
|
value: function translateGateway(gatewayId, axis, value) {
|
|
349
|
-
var _this$sceneViewer$
|
|
385
|
+
var _this$sceneViewer$man6, _this$sceneViewer$man7;
|
|
350
386
|
console.log("[Pathfinder] translateGateway started");
|
|
351
387
|
|
|
352
388
|
// Store transform parameters using the OperationHistoryManager
|
|
353
|
-
if ((_this$sceneViewer$
|
|
389
|
+
if ((_this$sceneViewer$man6 = this.sceneViewer.managers) !== null && _this$sceneViewer$man6 !== void 0 && _this$sceneViewer$man6.operationHistoryManager) {
|
|
354
390
|
this.sceneViewer.managers.operationHistoryManager.addToOperationHistory('translateGateway', {
|
|
355
391
|
gatewayId: gatewayId,
|
|
356
392
|
axis: axis,
|
|
@@ -401,7 +437,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
401
437
|
|
|
402
438
|
// Handle manual gateway transformation (convert to declared and process connections)
|
|
403
439
|
console.log('🔧 Handling manual gateway transformation via SceneOperationsManager');
|
|
404
|
-
var sceneOperationsManager = (_this$sceneViewer$
|
|
440
|
+
var sceneOperationsManager = (_this$sceneViewer$man7 = this.sceneViewer.managers) === null || _this$sceneViewer$man7 === void 0 ? void 0 : _this$sceneViewer$man7.sceneOperationsManager;
|
|
405
441
|
if (!sceneOperationsManager) {
|
|
406
442
|
console.error('❌ translateGateway(): SceneOperationsManager not available');
|
|
407
443
|
return false;
|
|
@@ -880,6 +916,7 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
880
916
|
return null;
|
|
881
917
|
}
|
|
882
918
|
var collisionRadius = 0.5; // Radius around connector that triggers collision
|
|
919
|
+
var endpointTolerance = 0.55; // Tolerance for determining if connector is at segment endpoint
|
|
883
920
|
|
|
884
921
|
// Get segment endpoints in world coordinates
|
|
885
922
|
var endpoints = this.calculateSegmentEndpoints(segment);
|
|
@@ -898,6 +935,13 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
898
935
|
var connectorWorldPos = new THREE.Vector3();
|
|
899
936
|
child.getWorldPosition(connectorWorldPos);
|
|
900
937
|
|
|
938
|
+
// Skip connectors that are at the segment's endpoints (legitimate connection points)
|
|
939
|
+
var distanceToStart = connectorWorldPos.distanceTo(startPoint);
|
|
940
|
+
var distanceToEnd = connectorWorldPos.distanceTo(endPoint);
|
|
941
|
+
if (distanceToStart <= endpointTolerance || distanceToEnd <= endpointTolerance) {
|
|
942
|
+
return; // Skip this connector - it's at an endpoint
|
|
943
|
+
}
|
|
944
|
+
|
|
901
945
|
// Find the closest point on the segment to the connector
|
|
902
946
|
var segmentVector = new THREE.Vector3().subVectors(endPoint, startPoint);
|
|
903
947
|
var pointVector = new THREE.Vector3().subVectors(connectorWorldPos, startPoint);
|
|
@@ -1096,6 +1140,37 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1096
1140
|
return c1.distanceTo(c2);
|
|
1097
1141
|
}
|
|
1098
1142
|
|
|
1143
|
+
/**
|
|
1144
|
+
* Constrain a position to maintain orthogonal alignment with a reference position
|
|
1145
|
+
* Movement is restricted to only along the segment's direction vector
|
|
1146
|
+
* @param {THREE.Vector3} newPosition - The proposed new position
|
|
1147
|
+
* @param {THREE.Vector3} referencePosition - The stationary reference position
|
|
1148
|
+
* @param {THREE.Object3D} segment - The segment being adjusted
|
|
1149
|
+
* @returns {THREE.Vector3} Constrained position that maintains orthogonality
|
|
1150
|
+
* @private
|
|
1151
|
+
*/
|
|
1152
|
+
}, {
|
|
1153
|
+
key: "constrainPositionToOrthogonal",
|
|
1154
|
+
value: function constrainPositionToOrthogonal(newPosition, referencePosition, segment) {
|
|
1155
|
+
// Get the segment's direction vector
|
|
1156
|
+
var direction = new THREE.Vector3(0, 1, 0);
|
|
1157
|
+
direction.applyQuaternion(segment.quaternion);
|
|
1158
|
+
direction.normalize();
|
|
1159
|
+
|
|
1160
|
+
// Calculate vector from reference position to new position
|
|
1161
|
+
var moveVector = new THREE.Vector3().subVectors(newPosition, referencePosition);
|
|
1162
|
+
|
|
1163
|
+
// Project the move vector onto the segment's direction
|
|
1164
|
+
// This gives us the component of movement along the segment's axis only
|
|
1165
|
+
var projectionLength = moveVector.dot(direction);
|
|
1166
|
+
|
|
1167
|
+
// Constrained position = reference + (projection along segment direction)
|
|
1168
|
+
var constrainedPos = new THREE.Vector3().copy(referencePosition).add(direction.clone().multiplyScalar(projectionLength));
|
|
1169
|
+
console.log("\uD83D\uDD12 Constrained movement along segment direction: [".concat(direction.x.toFixed(3), ", ").concat(direction.y.toFixed(3), ", ").concat(direction.z.toFixed(3), "]"));
|
|
1170
|
+
console.log(" Projection length: ".concat(projectionLength.toFixed(3)));
|
|
1171
|
+
return constrainedPos;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1099
1174
|
/**
|
|
1100
1175
|
* Update adjacent segment connectors to follow the moved segment's new position
|
|
1101
1176
|
* Finds segments that were connected to the moved segment BEFORE the move,
|
|
@@ -1214,18 +1289,23 @@ var TransformOperationsManager = /*#__PURE__*/function () {
|
|
|
1214
1289
|
var stationaryWorldPos = new THREE.Vector3();
|
|
1215
1290
|
stationaryConnector.getWorldPosition(stationaryWorldPos);
|
|
1216
1291
|
|
|
1292
|
+
// Constrain movement to maintain orthogonal alignment
|
|
1293
|
+
// Horizontal segments: only adjust X and Y, keep Z constant
|
|
1294
|
+
// Vertical segments: only adjust Z, keep X and Y constant
|
|
1295
|
+
var constrainedPosition = _this2.constrainPositionToOrthogonal(pair.newPosition, stationaryWorldPos, adjacentSegment);
|
|
1296
|
+
|
|
1217
1297
|
// Recreate the segment mesh with new length using explicit endpoint positions
|
|
1218
1298
|
// Pass the intended positions, not the connector objects (which may have temporary positions)
|
|
1219
|
-
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors,
|
|
1299
|
+
_this2.recreateSegmentMeshWithNewLength(adjacentSegment, adjacentConnectors, constrainedPosition, stationaryWorldPos);
|
|
1220
1300
|
|
|
1221
1301
|
// CRITICAL: After recreating the mesh, BOTH connectors need to be repositioned
|
|
1222
1302
|
// because the segment's center and rotation have changed
|
|
1223
1303
|
|
|
1224
|
-
// Position moving connector at the new position
|
|
1225
|
-
var movingLocalPos = adjacentSegment.worldToLocal(
|
|
1304
|
+
// Position moving connector at the constrained position (not the raw new position)
|
|
1305
|
+
var movingLocalPos = adjacentSegment.worldToLocal(constrainedPosition.clone());
|
|
1226
1306
|
movingConnector.position.copy(movingLocalPos);
|
|
1227
1307
|
movingConnector.updateMatrixWorld(true);
|
|
1228
|
-
_this2.updateConnectorPositionInSceneData(movingConnector,
|
|
1308
|
+
_this2.updateConnectorPositionInSceneData(movingConnector, constrainedPosition, adjacentSegment);
|
|
1229
1309
|
|
|
1230
1310
|
// Position stationary connector at its original world position
|
|
1231
1311
|
var stationaryLocalPos = adjacentSegment.worldToLocal(stationaryWorldPos.clone());
|