@2112-lab/central-plant 0.3.45 → 0.3.47
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 +635 -337
- package/dist/cjs/src/core/centralPlant.js +342 -218
- package/dist/cjs/src/core/centralPlantInternals.js +2 -0
- package/dist/cjs/src/core/sceneViewer.js +0 -1
- package/dist/cjs/src/managers/behaviors/IoBehaviorManager.js +1 -2
- package/dist/cjs/src/managers/components/componentDataManager.js +0 -1
- package/dist/cjs/src/managers/controls/componentDragManager.js +4 -8
- package/dist/cjs/src/managers/pathfinding/pathfindingManager.js +55 -1
- package/dist/cjs/src/managers/scene/collisionManager.js +142 -0
- package/dist/cjs/src/managers/scene/componentTooltipManager.js +2 -3
- package/dist/cjs/src/managers/scene/sceneExportManager.js +32 -11
- package/dist/cjs/src/managers/scene/sceneOperationsManager.js +17 -33
- package/dist/cjs/src/utils/behaviorDispatch.js +11 -42
- package/dist/cjs/src/utils/boundingBoxUtils.js +54 -8
- package/dist/cjs/src/utils/ioDeviceUtils.js +3 -9
- package/dist/esm/src/core/centralPlant.js +342 -218
- package/dist/esm/src/core/centralPlantInternals.js +2 -0
- package/dist/esm/src/core/sceneViewer.js +0 -1
- package/dist/esm/src/managers/behaviors/IoBehaviorManager.js +1 -2
- package/dist/esm/src/managers/components/componentDataManager.js +0 -1
- package/dist/esm/src/managers/controls/componentDragManager.js +4 -8
- package/dist/esm/src/managers/pathfinding/pathfindingManager.js +56 -2
- package/dist/esm/src/managers/scene/collisionManager.js +118 -0
- package/dist/esm/src/managers/scene/componentTooltipManager.js +2 -3
- package/dist/esm/src/managers/scene/sceneExportManager.js +33 -12
- package/dist/esm/src/managers/scene/sceneOperationsManager.js +17 -33
- package/dist/esm/src/utils/behaviorDispatch.js +11 -42
- package/dist/esm/src/utils/boundingBoxUtils.js +55 -10
- package/dist/esm/src/utils/ioDeviceUtils.js +3 -9
- package/dist/index.d.ts +0 -6
- package/package.json +1 -1
|
@@ -17,6 +17,7 @@ import { KeyboardControlsManager } from '../managers/controls/keyboardControlsMa
|
|
|
17
17
|
import { PathfindingManager } from '../managers/pathfinding/pathfindingManager.js';
|
|
18
18
|
import { PathFlowManager } from '../managers/pathfinding/PathFlowManager.js';
|
|
19
19
|
import { SceneOperationsManager } from '../managers/scene/sceneOperationsManager.js';
|
|
20
|
+
import { CollisionManager } from '../managers/scene/collisionManager.js';
|
|
20
21
|
import { AnimationManager } from '../managers/scene/animationManager.js';
|
|
21
22
|
import { CameraControlsManager } from '../managers/controls/cameraControlsManager.js';
|
|
22
23
|
import { ComponentDragManager } from '../managers/controls/componentDragManager.js';
|
|
@@ -145,6 +146,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
|
|
|
145
146
|
this.centralPlant.managers.keyboardControlsManager = new KeyboardControlsManager(this.centralPlant.sceneViewer);
|
|
146
147
|
this.centralPlant.managers.pathfindingManager = new PathfindingManager(this.centralPlant.sceneViewer);
|
|
147
148
|
this.centralPlant.managers.pathFlowManager = new PathFlowManager(this.centralPlant.sceneViewer);
|
|
149
|
+
this.centralPlant.managers.collisionManager = new CollisionManager(this.centralPlant.sceneViewer);
|
|
148
150
|
this.centralPlant.managers.sceneOperationsManager = new SceneOperationsManager(this.centralPlant.sceneViewer);
|
|
149
151
|
this.centralPlant.managers.animationManager = new AnimationManager(this.centralPlant.sceneViewer);
|
|
150
152
|
this.centralPlant.managers.cameraControlsManager = new CameraControlsManager(this.centralPlant.sceneViewer);
|
|
@@ -643,7 +643,6 @@ var sceneViewer = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
643
643
|
}, {
|
|
644
644
|
key: "updatePaths",
|
|
645
645
|
value: function updatePaths() {
|
|
646
|
-
console.log("updatePaths started");
|
|
647
646
|
// Delegate pathfinding update to PathfindingManager
|
|
648
647
|
if (this.pathfindingManager) {
|
|
649
648
|
this.pathfindingManager.updatePathfindingAfterTransform(this.currentSceneData);
|
|
@@ -513,8 +513,7 @@ var IoBehaviorManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
513
513
|
/**
|
|
514
514
|
* Return tooltip-compatible data point definitions derived from the loaded
|
|
515
515
|
* animation entries for a given attachment. Used by componentTooltipManager
|
|
516
|
-
* to
|
|
517
|
-
* state definitions created in the Animate window.
|
|
516
|
+
* to provide the richer animation state definitions created in the Animate window.
|
|
518
517
|
*
|
|
519
518
|
* One dp object is emitted per unique stateVariable; multiple mesh entries
|
|
520
519
|
* that share the same stateVariable are collapsed into one.
|
|
@@ -864,7 +864,6 @@ var ComponentDataManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
864
864
|
};
|
|
865
865
|
return _objectSpread2(_objectSpread2({}, baseData), {}, {
|
|
866
866
|
metadata: component.metadata || {},
|
|
867
|
-
ioConfig: component.ioConfig || null,
|
|
868
867
|
boundingBox: component.boundingBox || null,
|
|
869
868
|
adaptedBoundingBox: component.adaptedBoundingBox || null,
|
|
870
869
|
children: component.children || [],
|
|
@@ -321,7 +321,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
321
321
|
key: "_attachIODeviceModelsToPreview",
|
|
322
322
|
value: (function () {
|
|
323
323
|
var _attachIODeviceModelsToPreview2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3(parentObject, componentData, modelPreloader) {
|
|
324
|
-
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo,
|
|
324
|
+
var _i, _Object$entries, _Object$entries$_i, attachmentId, attachment, _modelPreloader$compo, _attachment$attachmen, _attachment$attachmen2, deviceData, cachedDevice, _modelPreloader$loadi, deviceModel, pos, rot, deg2rad, _t3;
|
|
325
325
|
return _regenerator().w(function (_context3) {
|
|
326
326
|
while (1) switch (_context3.n) {
|
|
327
327
|
case 0:
|
|
@@ -384,12 +384,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
384
384
|
deviceId: attachment.deviceId,
|
|
385
385
|
attachmentId: attachmentId,
|
|
386
386
|
attachmentLabel: attachment.attachmentLabel,
|
|
387
|
-
deviceName: deviceData.name || ''
|
|
388
|
-
// Snapshot of data point definitions so the tooltip can render state
|
|
389
|
-
// ioConfig can use either 'states' (preferred) or legacy 'dataPoints' as the array key
|
|
390
|
-
dataPoints: ((_deviceData$ioConfig = deviceData.ioConfig) === null || _deviceData$ioConfig === void 0 ? void 0 : _deviceData$ioConfig.states) || ((_deviceData$ioConfig2 = deviceData.ioConfig) === null || _deviceData$ioConfig2 === void 0 ? void 0 : _deviceData$ioConfig2.dataPoints) || [],
|
|
391
|
-
// Device-level I/O direction: 'input' means the user can write state via the tooltip
|
|
392
|
-
ioDirection: ((_deviceData$ioConfig3 = deviceData.ioConfig) === null || _deviceData$ioConfig3 === void 0 ? void 0 : _deviceData$ioConfig3.direction) || 'output'
|
|
387
|
+
deviceName: deviceData.name || ''
|
|
393
388
|
};
|
|
394
389
|
if ((_attachment$attachmen = attachment.attachmentPoint) !== null && _attachment$attachmen !== void 0 && _attachment$attachmen.position) {
|
|
395
390
|
pos = attachment.attachmentPoint.position;
|
|
@@ -643,6 +638,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
643
638
|
// Find intersection with ground plane
|
|
644
639
|
var intersection = this.raycaster.ray.intersectPlane(this.dropPlane, this.dropIntersection);
|
|
645
640
|
if (intersection) {
|
|
641
|
+
var _this$sceneViewer$col;
|
|
646
642
|
// Apply 0.5 unit transform snapping to intersection point
|
|
647
643
|
var snappedPosition = this._applyTransformSnap(intersection);
|
|
648
644
|
this.dragData.previewObject.position.copy(snappedPosition);
|
|
@@ -650,7 +646,7 @@ var ComponentDragManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
650
646
|
|
|
651
647
|
// Check for overlap and update color accordingly
|
|
652
648
|
var wasOverlapping = this.dragData.isOverlapping;
|
|
653
|
-
this.dragData.isOverlapping = this.
|
|
649
|
+
this.dragData.isOverlapping = !!((_this$sceneViewer$col = this.sceneViewer.collisionManager) !== null && _this$sceneViewer$col !== void 0 && _this$sceneViewer$col.checkCollision(this.dragData.previewObject));
|
|
654
650
|
|
|
655
651
|
// Update color if overlap state changed
|
|
656
652
|
if (wasOverlapping !== this.dragData.isOverlapping) {
|
|
@@ -3,7 +3,7 @@ import * as THREE from 'three';
|
|
|
3
3
|
import { Pathfinder } from '@2112-lab/pathfinder';
|
|
4
4
|
import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
5
5
|
import { PathData } from '../../core/pathfindingData.js';
|
|
6
|
-
import { computeFilteredBoundingBox, computeIODeviceBoundingBoxes } from '../../utils/boundingBoxUtils.js';
|
|
6
|
+
import { computeFilteredBoundingBox, computeIODeviceBoundingBoxes, computeConnectorBoundingBoxes } from '../../utils/boundingBoxUtils.js';
|
|
7
7
|
import { SceneDataManager } from './sceneDataManager.js';
|
|
8
8
|
import { PathRenderingManager } from './PathRenderingManager.js';
|
|
9
9
|
import { ConnectorManager } from './ConnectorManager.js';
|
|
@@ -304,6 +304,31 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
304
304
|
}
|
|
305
305
|
});
|
|
306
306
|
}
|
|
307
|
+
|
|
308
|
+
// Also reinject connectors from cache
|
|
309
|
+
if (_cached.connectorBBoxes && _cached.connectorBBoxes.length > 0) {
|
|
310
|
+
if (!_enrichedChild.children) _enrichedChild.children = [];
|
|
311
|
+
_cached.connectorBBoxes.forEach(function (connBBox) {
|
|
312
|
+
var existingIndex = _enrichedChild.children.findIndex(function (c) {
|
|
313
|
+
return c.uuid === connBBox.uuid;
|
|
314
|
+
});
|
|
315
|
+
if (existingIndex >= 0) {
|
|
316
|
+
_enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex]), {}, {
|
|
317
|
+
userData: _objectSpread2(_objectSpread2({}, _enrichedChild.children[existingIndex].userData), {}, {
|
|
318
|
+
worldBoundingBox: connBBox.worldBoundingBox
|
|
319
|
+
})
|
|
320
|
+
});
|
|
321
|
+
} else {
|
|
322
|
+
_enrichedChild.children.push({
|
|
323
|
+
uuid: connBBox.uuid,
|
|
324
|
+
userData: _objectSpread2(_objectSpread2({}, connBBox.userData), {}, {
|
|
325
|
+
worldBoundingBox: connBBox.worldBoundingBox
|
|
326
|
+
}),
|
|
327
|
+
children: []
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
}
|
|
307
332
|
return _enrichedChild;
|
|
308
333
|
}
|
|
309
334
|
|
|
@@ -361,11 +386,40 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
361
386
|
console.log("\uD83D\uDCE6 Injected ".concat(ioDeviceBBoxes.length, " io-device bounding box(es) for component ").concat(child.uuid));
|
|
362
387
|
}
|
|
363
388
|
|
|
389
|
+
// PHASE 2: Enrich Connectors (CRITICAL for pathfinding API)
|
|
390
|
+
// Also compute world bounding boxes for connectors and inject into children.
|
|
391
|
+
// This ensures endpoints have world coordinates in sceneDataCopy.
|
|
392
|
+
var connectorBBoxes = computeConnectorBoundingBoxes(componentObject);
|
|
393
|
+
if (connectorBBoxes.length > 0) {
|
|
394
|
+
if (!enrichedChild.children) enrichedChild.children = [];
|
|
395
|
+
connectorBBoxes.forEach(function (connBBox) {
|
|
396
|
+
var existingIndex = enrichedChild.children.findIndex(function (c) {
|
|
397
|
+
return c.uuid === connBBox.uuid;
|
|
398
|
+
});
|
|
399
|
+
if (existingIndex >= 0) {
|
|
400
|
+
enrichedChild.children[existingIndex] = _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex]), {}, {
|
|
401
|
+
userData: _objectSpread2(_objectSpread2({}, enrichedChild.children[existingIndex].userData), {}, {
|
|
402
|
+
worldBoundingBox: connBBox.worldBoundingBox
|
|
403
|
+
})
|
|
404
|
+
});
|
|
405
|
+
} else {
|
|
406
|
+
enrichedChild.children.push({
|
|
407
|
+
uuid: connBBox.uuid,
|
|
408
|
+
userData: _objectSpread2(_objectSpread2({}, connBBox.userData), {}, {
|
|
409
|
+
worldBoundingBox: connBBox.worldBoundingBox
|
|
410
|
+
}),
|
|
411
|
+
children: []
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
|
|
364
417
|
// Store in cache
|
|
365
418
|
_this3._bboxCache.set(child.uuid, {
|
|
366
419
|
matrixHash: _hash,
|
|
367
420
|
filteredBBox: _bboxData,
|
|
368
|
-
ioDeviceBBoxes: ioDeviceBBoxes
|
|
421
|
+
ioDeviceBBoxes: ioDeviceBBoxes,
|
|
422
|
+
connectorBBoxes: connectorBBoxes
|
|
369
423
|
});
|
|
370
424
|
return enrichedChild;
|
|
371
425
|
} else {
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, classCallCheck as _classCallCheck } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
|
|
4
|
+
var CollisionManager = /*#__PURE__*/function () {
|
|
5
|
+
/**
|
|
6
|
+
* @param {Object} sceneViewer - The scene viewer instance
|
|
7
|
+
*/
|
|
8
|
+
function CollisionManager(sceneViewer) {
|
|
9
|
+
_classCallCheck(this, CollisionManager);
|
|
10
|
+
this.sceneViewer = sceneViewer;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Check if a given object overlaps with any other relevant objects in the scene.
|
|
15
|
+
* @param {THREE.Object3D} object - The object to check for collisions
|
|
16
|
+
* @param {Array<string>} excludeTypes - Object types to exclude from checking (e.g. ['ground'])
|
|
17
|
+
* @returns {Object|null} Collision info {object, objectType} if collision detected, null otherwise
|
|
18
|
+
*/
|
|
19
|
+
return _createClass(CollisionManager, [{
|
|
20
|
+
key: "checkCollision",
|
|
21
|
+
value: function checkCollision(object) {
|
|
22
|
+
var _this$sceneViewer,
|
|
23
|
+
_this = this;
|
|
24
|
+
var excludeTypes = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ['isBaseGround', 'isBaseGrid', 'isBrickWall'];
|
|
25
|
+
if (!((_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.scene) || !object) return null;
|
|
26
|
+
|
|
27
|
+
// Compute high-quality bounding box for the object being checked
|
|
28
|
+
// We use setFromObject here because the target object just moved
|
|
29
|
+
var objectBBox = new THREE.Box3().setFromObject(object);
|
|
30
|
+
|
|
31
|
+
// Narrow down potential colliders
|
|
32
|
+
var collisionDetected = null;
|
|
33
|
+
|
|
34
|
+
// Optimization: Only check the root-level CP objects to avoid O(N^2) complexity with meshes
|
|
35
|
+
this.sceneViewer.scene.traverse(function (child) {
|
|
36
|
+
var _child$userData, _child$userData2, _child$userData3, _child$userData4, _child$userData5;
|
|
37
|
+
if (collisionDetected) return; // Short circuit
|
|
38
|
+
|
|
39
|
+
// Skip the object itself and its descendants
|
|
40
|
+
if (child === object || _this._isDescendantOf(object, child)) return;
|
|
41
|
+
|
|
42
|
+
// Filter by CP object types at the root level (skip internal meshes during traverse)
|
|
43
|
+
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.objectType) === 'io-device';
|
|
44
|
+
if (isCPRootObject && !_this._shouldExclude(child, excludeTypes)) {
|
|
45
|
+
// Use cached worldBoundingBox if available, otherwise compute it (and cache it)
|
|
46
|
+
var childBBox;
|
|
47
|
+
if (child.userData.worldBoundingBox && !child.userData.isMoving) {
|
|
48
|
+
var _min$x, _min$y, _min$z, _max$x, _max$y, _max$z;
|
|
49
|
+
// Use stored worldBoundingBox (handles array or Box3 format)
|
|
50
|
+
var min = child.userData.worldBoundingBox.min;
|
|
51
|
+
var max = child.userData.worldBoundingBox.max;
|
|
52
|
+
childBBox = new THREE.Box3(new THREE.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.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]));
|
|
53
|
+
} else {
|
|
54
|
+
// Fallback to high-quality computation for moving objects or first-time checks
|
|
55
|
+
childBBox = new THREE.Box3().setFromObject(child);
|
|
56
|
+
|
|
57
|
+
// Cache the result for next time (non-moving objects)
|
|
58
|
+
if (!child.userData.isMoving) {
|
|
59
|
+
child.userData.worldBoundingBox = {
|
|
60
|
+
min: [childBBox.min.x, childBBox.min.y, childBBox.min.z],
|
|
61
|
+
max: [childBBox.max.x, childBBox.max.y, childBBox.max.z]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (objectBBox.intersectsBox(childBBox)) {
|
|
66
|
+
collisionDetected = {
|
|
67
|
+
object: child,
|
|
68
|
+
objectType: child.userData.objectType,
|
|
69
|
+
uuid: child.uuid,
|
|
70
|
+
name: child.name || child.userData.libraryId || child.uuid
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return collisionDetected;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Helper to check if a node is a descendant of a specific parent
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
}, {
|
|
83
|
+
key: "_isDescendantOf",
|
|
84
|
+
value: function _isDescendantOf(parent, child) {
|
|
85
|
+
var node = child.parent;
|
|
86
|
+
while (node !== null) {
|
|
87
|
+
if (node === parent) return true;
|
|
88
|
+
node = node.parent;
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Helper to determine if an object should be excluded from collision checking
|
|
95
|
+
* @private
|
|
96
|
+
*/
|
|
97
|
+
}, {
|
|
98
|
+
key: "_shouldExclude",
|
|
99
|
+
value: function _shouldExclude(object, excludeTypes) {
|
|
100
|
+
if (object.userData.isPreview) return true;
|
|
101
|
+
var _iterator = _createForOfIteratorHelper(excludeTypes),
|
|
102
|
+
_step;
|
|
103
|
+
try {
|
|
104
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
105
|
+
var type = _step.value;
|
|
106
|
+
if (object.userData[type]) return true;
|
|
107
|
+
}
|
|
108
|
+
} catch (err) {
|
|
109
|
+
_iterator.e(err);
|
|
110
|
+
} finally {
|
|
111
|
+
_iterator.f();
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
}]);
|
|
116
|
+
}();
|
|
117
|
+
|
|
118
|
+
export { CollisionManager };
|
|
@@ -458,8 +458,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
458
458
|
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'io-device') {
|
|
459
459
|
var attachmentId = child.userData.attachmentId || '';
|
|
460
460
|
|
|
461
|
-
// Use
|
|
462
|
-
// The static ioConfig.states[] snapshot on userData is intentionally ignored.
|
|
461
|
+
// Use data points from the animate window (behaviorConfig).
|
|
463
462
|
var dataPoints = resolveDataPoints(parentUuid, attachmentId, child.userData, getIoBehaviorManager(_this3.sceneViewer));
|
|
464
463
|
|
|
465
464
|
// When data points come from behaviorConfig they already carry direction:'input'.
|
|
@@ -672,7 +671,7 @@ var ComponentTooltipManager = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
672
671
|
* Input / bidirectional → shows an interactive control.
|
|
673
672
|
*
|
|
674
673
|
* @param {string} scopedAttachmentId - Scoped attachment ID (parentUuid::attachmentId) for state isolation
|
|
675
|
-
* @param {Object} dp - data point definition
|
|
674
|
+
* @param {Object} dp - data point definition
|
|
676
675
|
* @param {string} [deviceDirection] - device-level direction ('input'|'output'), overrides dp.direction
|
|
677
676
|
* @param {string} [originalAttachmentId] - Original attachment ID for behavior triggering
|
|
678
677
|
* @returns {HTMLElement}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createClass as _createClass, classCallCheck as _classCallCheck, toConsumableArray as _toConsumableArray, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
1
|
+
import { createClass as _createClass, classCallCheck as _classCallCheck, toConsumableArray as _toConsumableArray, objectSpread2 as _objectSpread2, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import 'three';
|
|
3
3
|
import { GLTFExporter } from '../../../node_modules/three/examples/jsm/exporters/GLTFExporter.js';
|
|
4
4
|
import { getHardcodedUuid } from '../../utils/nameUtils.js';
|
|
@@ -145,6 +145,8 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
145
145
|
// Internal tracking - not needed in export
|
|
146
146
|
'initialPosition',
|
|
147
147
|
// Internal tracking - not needed in export
|
|
148
|
+
'attachedDevices',
|
|
149
|
+
// Stored in smart component dictionary, not scene JSON
|
|
148
150
|
// Exclude internal segment tracking properties
|
|
149
151
|
'segmentId',
|
|
150
152
|
// Internal tracking
|
|
@@ -217,11 +219,11 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
217
219
|
};
|
|
218
220
|
}
|
|
219
221
|
|
|
220
|
-
// For components:
|
|
221
|
-
//
|
|
222
|
-
//
|
|
223
|
-
// and would leave the pathfinder with connectors in incompatible local-position format.
|
|
222
|
+
// For components: only export child connectors if they were manually added/defined.
|
|
223
|
+
// Most connectors are injected from dictionary at import time, but some (like manually placed ones)
|
|
224
|
+
// need to be persisted to maintain connections in the exported scene.
|
|
224
225
|
if (threeObject.children && threeObject.children.length > 0) {
|
|
226
|
+
var _threeObject$userData11;
|
|
225
227
|
var exportableChildren = [];
|
|
226
228
|
if (isManualSegment) {
|
|
227
229
|
// For manual segments, export their connector children
|
|
@@ -235,6 +237,25 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
235
237
|
}
|
|
236
238
|
}
|
|
237
239
|
});
|
|
240
|
+
} else if (((_threeObject$userData11 = threeObject.userData) === null || _threeObject$userData11 === void 0 ? void 0 : _threeObject$userData11.objectType) === 'component') {
|
|
241
|
+
// For components, only export connectors that have objectType='connector'
|
|
242
|
+
// Standard dictionary-injected connectors should be exported so connections work on re-import
|
|
243
|
+
threeObject.children.forEach(function (child) {
|
|
244
|
+
var _child$userData2;
|
|
245
|
+
if (((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType) === 'connector') {
|
|
246
|
+
exportableChildren.push({
|
|
247
|
+
uuid: child.uuid,
|
|
248
|
+
name: child.name,
|
|
249
|
+
type: 'Mesh',
|
|
250
|
+
position: {
|
|
251
|
+
x: roundIfClose(child.position.x),
|
|
252
|
+
y: roundIfClose(child.position.y),
|
|
253
|
+
z: roundIfClose(child.position.z)
|
|
254
|
+
},
|
|
255
|
+
userData: _objectSpread2({}, child.userData)
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
});
|
|
238
259
|
}
|
|
239
260
|
if (exportableChildren.length > 0) {
|
|
240
261
|
jsonObject.children = exportableChildren;
|
|
@@ -249,9 +270,9 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
249
270
|
// Extract main scene objects (components and standalone connectors)
|
|
250
271
|
var sceneChildren = [];
|
|
251
272
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
252
|
-
var _child$
|
|
273
|
+
var _child$userData3;
|
|
253
274
|
// Only export components and connectors; skip segments, gateways, polylines, etc.
|
|
254
|
-
var objectType = (_child$
|
|
275
|
+
var objectType = (_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType;
|
|
255
276
|
if (objectType !== 'component' && objectType !== 'connector') {
|
|
256
277
|
return;
|
|
257
278
|
}
|
|
@@ -415,14 +436,14 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
415
436
|
BufferGeometryUtils = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
|
|
416
437
|
exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
|
|
417
438
|
shouldExport = function shouldExport(child) {
|
|
418
|
-
var _child$name, _child$
|
|
439
|
+
var _child$name, _child$userData4, _child$userData5, _child$userData6, _child$userData7;
|
|
419
440
|
if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
|
|
420
441
|
if (child.name === 'fogPlane') return false; // Skip fog plane
|
|
421
|
-
if ((_child$
|
|
422
|
-
if ((_child$
|
|
423
|
-
if ((_child$
|
|
442
|
+
if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBrickWall) return false; // Skip environment
|
|
443
|
+
if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGround) return false; // Skip environment
|
|
444
|
+
if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isBaseGrid) return false; // Skip environment
|
|
424
445
|
if (child.isLight) return false; // Skip lights
|
|
425
|
-
if ((_child$
|
|
446
|
+
if ((_child$userData7 = child.userData) !== null && _child$userData7 !== void 0 && _child$userData7.isTransformControls) return false; // Skip transform controls
|
|
426
447
|
if (child.isTransformControls) return false; // Skip transform controls
|
|
427
448
|
if (child.type && child.type.includes('TransformControls')) return false;
|
|
428
449
|
if (child.type && child.type.includes('Helper')) return false; // Skip helpers
|
|
@@ -1309,51 +1309,36 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1309
1309
|
y: componentModel.scale.y,
|
|
1310
1310
|
z: componentModel.scale.z
|
|
1311
1311
|
},
|
|
1312
|
-
userData: _objectSpread2(_objectSpread2({},
|
|
1312
|
+
userData: _objectSpread2(_objectSpread2({}, function () {
|
|
1313
|
+
var ud = _objectSpread2({}, componentModel.userData);
|
|
1314
|
+
delete ud.attachedDevices; // Instance data belongs in dictionary, not scene JSON
|
|
1315
|
+
delete ud.isDeclared; // Runtime flag
|
|
1316
|
+
delete ud.originalUuid; // Runtime tracking
|
|
1317
|
+
return ud;
|
|
1318
|
+
}()), {}, {
|
|
1313
1319
|
worldBoundingBox: {
|
|
1314
1320
|
min: boundingBox.min.toArray(),
|
|
1315
1321
|
max: boundingBox.max.toArray()
|
|
1316
1322
|
}
|
|
1317
1323
|
}),
|
|
1318
|
-
children: []
|
|
1324
|
+
children: [] // Initialize children array
|
|
1319
1325
|
};
|
|
1320
1326
|
|
|
1321
|
-
//
|
|
1322
|
-
if (componentModel.children
|
|
1327
|
+
// Collect children that are connectors
|
|
1328
|
+
if (componentModel.children) {
|
|
1323
1329
|
componentModel.children.forEach(function (child) {
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
if (childType === 'connector') {
|
|
1327
|
-
var _child$geometry;
|
|
1328
|
-
var childBoundingBox = new THREE.Box3().setFromObject(child);
|
|
1329
|
-
var childSceneData = {
|
|
1330
|
+
if (child.userData && child.userData.objectType === 'connector') {
|
|
1331
|
+
componentSceneData.children.push({
|
|
1330
1332
|
uuid: child.uuid,
|
|
1331
1333
|
name: child.name,
|
|
1332
|
-
type:
|
|
1334
|
+
type: 'Mesh',
|
|
1333
1335
|
position: {
|
|
1334
1336
|
x: child.position.x,
|
|
1335
1337
|
y: child.position.y,
|
|
1336
1338
|
z: child.position.z
|
|
1337
1339
|
},
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
y: THREE.MathUtils.radToDeg(child.rotation.y),
|
|
1341
|
-
z: THREE.MathUtils.radToDeg(child.rotation.z)
|
|
1342
|
-
},
|
|
1343
|
-
scale: {
|
|
1344
|
-
x: child.scale.x,
|
|
1345
|
-
y: child.scale.y,
|
|
1346
|
-
z: child.scale.z
|
|
1347
|
-
},
|
|
1348
|
-
userData: _objectSpread2(_objectSpread2({}, child.userData), {}, {
|
|
1349
|
-
worldBoundingBox: {
|
|
1350
|
-
min: childBoundingBox.min.toArray(),
|
|
1351
|
-
max: childBoundingBox.max.toArray()
|
|
1352
|
-
}
|
|
1353
|
-
}),
|
|
1354
|
-
geometry: ((_child$geometry = child.geometry) === null || _child$geometry === void 0 ? void 0 : _child$geometry.uuid) || 'CONNECTOR-GEO'
|
|
1355
|
-
};
|
|
1356
|
-
componentSceneData.children.push(childSceneData);
|
|
1340
|
+
userData: _objectSpread2({}, child.userData)
|
|
1341
|
+
});
|
|
1357
1342
|
}
|
|
1358
1343
|
});
|
|
1359
1344
|
}
|
|
@@ -1366,7 +1351,6 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1366
1351
|
console.log('✅ addComponentToSceneData: Component added to scene data successfully', {
|
|
1367
1352
|
componentId: componentModel.uuid,
|
|
1368
1353
|
libraryId: (_componentModel$userD = componentModel.userData) === null || _componentModel$userD === void 0 ? void 0 : _componentModel$userD.libraryId,
|
|
1369
|
-
childrenCount: componentSceneData.children.length,
|
|
1370
1354
|
totalSceneChildren: currentSceneData.scene.children.length
|
|
1371
1355
|
});
|
|
1372
1356
|
return true;
|
|
@@ -1407,8 +1391,8 @@ var SceneOperationsManager = /*#__PURE__*/function () {
|
|
|
1407
1391
|
if (segment.children && segment.children.length > 0) {
|
|
1408
1392
|
var childrenToRemove = _toConsumableArray(segment.children);
|
|
1409
1393
|
childrenToRemove.forEach(function (child) {
|
|
1410
|
-
var _child$
|
|
1411
|
-
if ((_child$
|
|
1394
|
+
var _child$userData0;
|
|
1395
|
+
if ((_child$userData0 = child.userData) !== null && _child$userData0 !== void 0 && _child$userData0.isPipeElbow) {
|
|
1412
1396
|
console.log("\uD83D\uDDD1\uFE0F Removing elbow child from segment before manualization: ".concat(child.uuid));
|
|
1413
1397
|
segment.remove(child);
|
|
1414
1398
|
if (child.geometry) child.geometry.dispose();
|
|
@@ -26,11 +26,11 @@ function getIoBehaviorManager(sceneViewer) {
|
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Resolve tooltip/drag data points for an I/O device attachment.
|
|
29
|
-
* Prefers behaviorConfig-driven animation data points
|
|
29
|
+
* Prefers behaviorConfig-driven animation data points.
|
|
30
30
|
*
|
|
31
31
|
* @param {string} parentUuid
|
|
32
32
|
* @param {string} attachmentId
|
|
33
|
-
* @param {Object} userData - io-device userData
|
|
33
|
+
* @param {Object} userData - io-device userData
|
|
34
34
|
* @param {import('../managers/behaviors/IoBehaviorManager.js').IoBehaviorManager|null} ioBehaviorManager
|
|
35
35
|
* @param {THREE.Object3D|null} [hitMesh]
|
|
36
36
|
* @returns {Object[]}
|
|
@@ -38,21 +38,7 @@ function getIoBehaviorManager(sceneViewer) {
|
|
|
38
38
|
function resolveDataPoints(parentUuid, attachmentId, userData, ioBehaviorManager) {
|
|
39
39
|
var hitMesh = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : null;
|
|
40
40
|
var fromAnimations = (ioBehaviorManager === null || ioBehaviorManager === void 0 ? void 0 : ioBehaviorManager.getAnimationDataPoints(parentUuid, attachmentId, hitMesh)) || [];
|
|
41
|
-
|
|
42
|
-
var legacy = (userData === null || userData === void 0 ? void 0 : userData.dataPoints) || [];
|
|
43
|
-
return legacy.map(function (dp) {
|
|
44
|
-
var _dp$defaultValue;
|
|
45
|
-
return {
|
|
46
|
-
id: dp.id || dp.name,
|
|
47
|
-
name: dp.name || dp.id,
|
|
48
|
-
stateType: dp.stateType || 'binary',
|
|
49
|
-
stateConfig: dp.stateConfig || {},
|
|
50
|
-
defaultValue: (_dp$defaultValue = dp.defaultValue) !== null && _dp$defaultValue !== void 0 ? _dp$defaultValue : null,
|
|
51
|
-
direction: dp.direction || (userData === null || userData === void 0 ? void 0 : userData.ioDirection) || 'output'
|
|
52
|
-
};
|
|
53
|
-
}).filter(function (dp) {
|
|
54
|
-
return dp.id;
|
|
55
|
-
});
|
|
41
|
+
return fromAnimations;
|
|
56
42
|
}
|
|
57
43
|
|
|
58
44
|
/**
|
|
@@ -83,35 +69,18 @@ function applyDefaultIoDeviceStates(centralPlant) {
|
|
|
83
69
|
if (seen.has(scopedKey)) return;
|
|
84
70
|
seen.add(scopedKey);
|
|
85
71
|
var dps = ioBehavMgr.getAnimationDataPoints(objParentUuid, objAttachmentId) || [];
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
_step;
|
|
89
|
-
try {
|
|
90
|
-
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
91
|
-
var dp = _step.value;
|
|
92
|
-
if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
|
|
93
|
-
centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
|
|
94
|
-
}
|
|
95
|
-
} catch (err) {
|
|
96
|
-
_iterator.e(err);
|
|
97
|
-
} finally {
|
|
98
|
-
_iterator.f();
|
|
99
|
-
}
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
var _iterator2 = _createForOfIteratorHelper(obj.userData.dataPoints || []),
|
|
103
|
-
_step2;
|
|
72
|
+
var _iterator = _createForOfIteratorHelper(dps),
|
|
73
|
+
_step;
|
|
104
74
|
try {
|
|
105
|
-
for (
|
|
106
|
-
var
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
centralPlant.setIoDeviceState(objAttachmentId, dpId, _dp.defaultValue, objParentUuid);
|
|
75
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
76
|
+
var dp = _step.value;
|
|
77
|
+
if (!(dp !== null && dp !== void 0 && dp.id) || dp.defaultValue === undefined || dp.defaultValue === null) continue;
|
|
78
|
+
centralPlant.setIoDeviceState(objAttachmentId, dp.id, dp.defaultValue, objParentUuid);
|
|
110
79
|
}
|
|
111
80
|
} catch (err) {
|
|
112
|
-
|
|
81
|
+
_iterator.e(err);
|
|
113
82
|
} finally {
|
|
114
|
-
|
|
83
|
+
_iterator.f();
|
|
115
84
|
}
|
|
116
85
|
});
|
|
117
86
|
}
|