@2112-lab/central-plant 0.3.16 → 0.3.18

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.
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
+
7
+ /**
8
+ * Utility function to update userData.direction for components after 90-degree rotation
9
+ * This function handles the direction vector transformation for connectors when their parent component is rotated
10
+ *
11
+ * @param {THREE.Object3D} component - The component that was rotated
12
+ * @param {string} axis - The axis of rotation ('x', 'y', or 'z')
13
+ * @param {number} degrees - The rotation angle in degrees (should be multiple of 90)
14
+ */
15
+ function updateDirectionAfterRotation(component, axis, degrees) {
16
+ if (!component) {
17
+ console.warn('⚠️ updateDirectionAfterRotation: No component provided');
18
+ return;
19
+ }
20
+
21
+ // Only handle 90-degree increments
22
+ if (degrees % 90 !== 0) {
23
+ console.warn('⚠️ updateDirectionAfterRotation: Only 90-degree increments are supported');
24
+ return;
25
+ }
26
+
27
+ // Normalize degrees to 0-360 range
28
+ var normalizedDegrees = (degrees % 360 + 360) % 360;
29
+ console.log("\uD83D\uDD04 Updating direction vectors for ".concat(component.name || component.uuid, " after ").concat(degrees, "\xB0 rotation around ").concat(axis, " axis"));
30
+
31
+ // Traverse all children (connectors) and update their direction vectors
32
+ component.traverse(function (child) {
33
+ var _child$userData, _child$userData2;
34
+ var childType = ((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) || ((_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType);
35
+ if (child.userData && Array.isArray(child.userData.direction) && childType === 'connector') {
36
+ var originalDirection = _rollupPluginBabelHelpers.toConsumableArray(child.userData.direction);
37
+ var newDirection = rotateDirectionVector(originalDirection, axis, normalizedDegrees);
38
+
39
+ // Update the direction
40
+ child.userData.direction = newDirection;
41
+ console.log("\uD83D\uDCCD Updated connector ".concat(child.name || child.uuid, " direction:"), {
42
+ original: originalDirection,
43
+ new: newDirection,
44
+ rotationAxis: axis,
45
+ rotationDegrees: degrees
46
+ });
47
+ }
48
+ });
49
+ }
50
+
51
+ /**
52
+ * Rotate a direction vector by 90-degree increments around a specific axis
53
+ *
54
+ * @param {Array<number>} direction - The original direction vector [x, y, z]
55
+ * @param {string} axis - The axis of rotation ('x', 'y', or 'z')
56
+ * @param {number} degrees - The rotation angle in degrees (must be multiple of 90)
57
+ * @returns {Array<number>} The new direction vector [x, y, z]
58
+ */
59
+ function rotateDirectionVector(direction, axis, degrees) {
60
+ if (!Array.isArray(direction) || direction.length !== 3) {
61
+ console.warn('⚠️ rotateDirectionVector: Invalid direction vector');
62
+ return direction;
63
+ }
64
+ var _direction = _rollupPluginBabelHelpers.slicedToArray(direction, 3),
65
+ x = _direction[0],
66
+ y = _direction[1],
67
+ z = _direction[2];
68
+ var steps = degrees / 90; // Number of 90-degree steps
69
+
70
+ for (var i = 0; i < steps; i++) {
71
+ var newX = x,
72
+ newY = y,
73
+ newZ = z;
74
+ switch (axis) {
75
+ case 'x':
76
+ // Rotation around X-axis in Z-up system with flipped Y: Y becomes -Z, Z becomes Y
77
+ newY = -z;
78
+ newZ = y;
79
+ break;
80
+ case 'y':
81
+ // Rotation around Y-axis in Z-up system with flipped Y: X becomes Z, Z becomes -X
82
+ newX = z;
83
+ newZ = -x;
84
+ break;
85
+ case 'z':
86
+ // Rotation around Z-axis in Z-up system with flipped Y: X becomes -Y, Y becomes X
87
+ newX = -y;
88
+ newY = x;
89
+ break;
90
+ default:
91
+ console.warn("\u26A0\uFE0F rotateDirectionVector: Invalid axis '".concat(axis, "'"));
92
+ return direction;
93
+ }
94
+ x = newX;
95
+ y = newY;
96
+ z = newZ;
97
+ }
98
+ return [x, y, z];
99
+ }
100
+
101
+ /**
102
+ * Example usage in your rotate method:
103
+ *
104
+ * // After applying rotation to the component
105
+ * component.rotation[axis] += radians
106
+ *
107
+ * // Update direction vectors for connectors
108
+ * updateDirectionAfterRotation(component, axis, value)
109
+ *
110
+ * // Update matrices
111
+ * component.updateMatrix()
112
+ * component.updateMatrixWorld(true)
113
+ */
114
+
115
+ exports.updateDirectionAfterRotation = updateDirectionAfterRotation;
@@ -4,6 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
6
6
  var THREE = require('three');
7
+ var directionUtils = require('../../helpers/directionUtils.js');
7
8
 
8
9
  function _interopNamespace(e) {
9
10
  if (e && e.__esModule) return e;
@@ -716,16 +717,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
716
717
  if (!component || degrees % 90 !== 0) {
717
718
  return;
718
719
  }
719
- console.log("\uD83D\uDD04 Updating connector directions after ".concat(degrees, "\xB0 rotation around ").concat(axis, " axis"));
720
720
 
721
- // Simple approach: just log that directions may need manual verification
722
- // In most cases, Three.js world matrices handle the actual positioning correctly
723
- component.traverse(function (child) {
724
- var _child$userData5, _child$userData6;
725
- if (((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) === 'connector' && (_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.direction) {
726
- console.log("\uD83D\uDCCD Connector ".concat(child.uuid, " direction may need verification after rotation"));
727
- }
728
- });
721
+ // Use the direction utility to update direction vectors on Three.js connector objects
722
+ directionUtils.updateDirectionAfterRotation(component, axis, degrees);
729
723
  }
730
724
 
731
725
  /**
@@ -879,9 +873,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
879
873
 
880
874
  // Traverse scene to find all connectors
881
875
  this.sceneViewer.scene.traverse(function (child) {
882
- var _child$userData7;
876
+ var _child$userData5;
883
877
  // Check if this is a connector (component connector or manual segment connector)
884
- if (((_child$userData7 = child.userData) === null || _child$userData7 === void 0 ? void 0 : _child$userData7.objectType) === 'connector') {
878
+ if (((_child$userData5 = child.userData) === null || _child$userData5 === void 0 ? void 0 : _child$userData5.objectType) === 'connector') {
885
879
  // Get world position of connector
886
880
  var connectorWorldPos = new THREE__namespace.Vector3();
887
881
  child.getWorldPosition(connectorWorldPos);
@@ -932,8 +926,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
932
926
  // Find all child connectors of the segment in the Three.js scene
933
927
  var connectors = [];
934
928
  segment.traverse(function (child) {
935
- var _child$userData8;
936
- if (((_child$userData8 = child.userData) === null || _child$userData8 === void 0 ? void 0 : _child$userData8.objectType) === 'segment-connector') {
929
+ var _child$userData6;
930
+ if (((_child$userData6 = child.userData) === null || _child$userData6 === void 0 ? void 0 : _child$userData6.objectType) === 'segment-connector') {
937
931
  connectors.push(child);
938
932
  }
939
933
  });
@@ -997,17 +991,17 @@ var TransformOperationsManager = /*#__PURE__*/function () {
997
991
 
998
992
  // Check all segments in the scene
999
993
  this.sceneViewer.scene.traverse(function (child) {
1000
- var _child$userData9, _child$userData0;
994
+ var _child$userData7, _child$userData8;
1001
995
  // Skip the segment itself
1002
996
  if (child.uuid === segment.uuid) {
1003
997
  return;
1004
998
  }
1005
999
 
1006
1000
  // Only check computed segments in the scene
1007
- if (((_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.objectType) === 'segment' && (_child$userData0 = child.userData) !== null && _child$userData0 !== void 0 && _child$userData0.isDeclared) {
1008
- var _segment$userData6, _child$userData1, _segment$userData7, _child$userData10;
1001
+ if (((_child$userData7 = child.userData) === null || _child$userData7 === void 0 ? void 0 : _child$userData7.objectType) === 'segment' && (_child$userData8 = child.userData) !== null && _child$userData8 !== void 0 && _child$userData8.isDeclared) {
1002
+ var _segment$userData6, _child$userData9, _segment$userData7, _child$userData0;
1009
1003
  // Check if segments are part of the same connection path
1010
- var sameConnection = ((_segment$userData6 = segment.userData) === null || _segment$userData6 === void 0 ? void 0 : _segment$userData6.pathFrom) === ((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.pathFrom) && ((_segment$userData7 = segment.userData) === null || _segment$userData7 === void 0 ? void 0 : _segment$userData7.pathTo) === ((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.pathTo);
1004
+ var sameConnection = ((_segment$userData6 = segment.userData) === null || _segment$userData6 === void 0 ? void 0 : _segment$userData6.pathFrom) === ((_child$userData9 = child.userData) === null || _child$userData9 === void 0 ? void 0 : _child$userData9.pathFrom) && ((_segment$userData7 = segment.userData) === null || _segment$userData7 === void 0 ? void 0 : _segment$userData7.pathTo) === ((_child$userData0 = child.userData) === null || _child$userData0 === void 0 ? void 0 : _child$userData0.pathTo);
1011
1005
 
1012
1006
  // Get endpoints of the other segment (use stored endpoints if available)
1013
1007
  var otherEndpoints = _this2.getSegmentEndpoints(child);
@@ -1228,11 +1222,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1228
1222
 
1229
1223
  // Traverse scene to find all component connectors
1230
1224
  this.sceneViewer.scene.traverse(function (child) {
1231
- var _child$userData11;
1225
+ var _child$userData1;
1232
1226
  if (collision) return; // Stop if collision already found
1233
1227
 
1234
1228
  // Check if this is a component connector (not a segment-connector)
1235
- if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'connector') {
1229
+ if (((_child$userData1 = child.userData) === null || _child$userData1 === void 0 ? void 0 : _child$userData1.objectType) === 'connector') {
1236
1230
  var _segment$userData10, _segment$userData11;
1237
1231
  // Skip connectors that are connected to this segment (pathFrom or pathTo)
1238
1232
  var segmentPathFrom = (_segment$userData10 = segment.userData) === null || _segment$userData10 === void 0 ? void 0 : _segment$userData10.pathFrom;
@@ -1346,9 +1340,9 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1346
1340
 
1347
1341
  // Traverse scene to find all component connectors
1348
1342
  this.sceneViewer.scene.traverse(function (child) {
1349
- var _child$userData12;
1343
+ var _child$userData10;
1350
1344
  // Check if this is a component connector (not a segment-connector)
1351
- if (((_child$userData12 = child.userData) === null || _child$userData12 === void 0 ? void 0 : _child$userData12.objectType) === 'connector') {
1345
+ if (((_child$userData10 = child.userData) === null || _child$userData10 === void 0 ? void 0 : _child$userData10.objectType) === 'connector') {
1352
1346
  // Get world position of connector
1353
1347
  var connectorWorldPos = new THREE__namespace.Vector3();
1354
1348
  child.getWorldPosition(connectorWorldPos);
@@ -1405,11 +1399,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1405
1399
 
1406
1400
  // Traverse scene to find all components
1407
1401
  this.sceneViewer.scene.traverse(function (child) {
1408
- var _child$userData13, _child$userData14;
1402
+ var _child$userData11, _child$userData12;
1409
1403
  if (collision) return; // Stop if collision already found
1410
1404
 
1411
1405
  // Check if this is a component (equipment)
1412
- if (((_child$userData13 = child.userData) === null || _child$userData13 === void 0 ? void 0 : _child$userData13.objectType) === 'component' && (_child$userData14 = child.userData) !== null && _child$userData14 !== void 0 && _child$userData14.libraryId) {
1406
+ if (((_child$userData11 = child.userData) === null || _child$userData11 === void 0 ? void 0 : _child$userData11.objectType) === 'component' && (_child$userData12 = child.userData) !== null && _child$userData12 !== void 0 && _child$userData12.libraryId) {
1413
1407
  // Create bounding box for the component
1414
1408
  var componentBBox = new THREE__namespace.Box3().setFromObject(child);
1415
1409
 
@@ -1448,11 +1442,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1448
1442
 
1449
1443
  // Traverse scene to find all manual segments (isDeclared === true)
1450
1444
  this.sceneViewer.scene.traverse(function (child) {
1451
- var _child$userData15, _child$userData16;
1445
+ var _child$userData13, _child$userData14;
1452
1446
  if (collision) return; // Stop if collision already found
1453
1447
 
1454
1448
  // Only check manual segments (isDeclared === true)
1455
- if (((_child$userData15 = child.userData) === null || _child$userData15 === void 0 ? void 0 : _child$userData15.objectType) === 'segment' && ((_child$userData16 = child.userData) === null || _child$userData16 === void 0 ? void 0 : _child$userData16.isDeclared) === true) {
1449
+ if (((_child$userData13 = child.userData) === null || _child$userData13 === void 0 ? void 0 : _child$userData13.objectType) === 'segment' && ((_child$userData14 = child.userData) === null || _child$userData14 === void 0 ? void 0 : _child$userData14.isDeclared) === true) {
1456
1450
  // Get segment endpoints
1457
1451
  var segmentEndpoints = _this3.getSegmentEndpoints(child);
1458
1452
 
@@ -1541,11 +1535,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1541
1535
 
1542
1536
  // Traverse scene to find all manual segments (isDeclared === true)
1543
1537
  this.sceneViewer.scene.traverse(function (child) {
1544
- var _child$userData17, _child$userData18;
1538
+ var _child$userData15, _child$userData16;
1545
1539
  if (collision) return; // Stop if collision already found
1546
1540
 
1547
1541
  // Only check manual segments (isDeclared === true)
1548
- if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.objectType) === 'segment' && ((_child$userData18 = child.userData) === null || _child$userData18 === void 0 ? void 0 : _child$userData18.isDeclared) === true) {
1542
+ if (((_child$userData15 = child.userData) === null || _child$userData15 === void 0 ? void 0 : _child$userData15.objectType) === 'segment' && ((_child$userData16 = child.userData) === null || _child$userData16 === void 0 ? void 0 : _child$userData16.isDeclared) === true) {
1549
1543
  // Get segment endpoints
1550
1544
  var segmentEndpoints = _this4.getSegmentEndpoints(child);
1551
1545
 
@@ -1602,11 +1596,11 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1602
1596
 
1603
1597
  // Traverse scene to find all components
1604
1598
  this.sceneViewer.scene.traverse(function (child) {
1605
- var _child$userData19, _child$userData20;
1599
+ var _child$userData17, _child$userData18;
1606
1600
  if (collision) return; // Stop if collision already found
1607
1601
 
1608
1602
  // Check if this is a component (equipment)
1609
- if (((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.objectType) === 'component' && (_child$userData20 = child.userData) !== null && _child$userData20 !== void 0 && _child$userData20.libraryId) {
1603
+ if (((_child$userData17 = child.userData) === null || _child$userData17 === void 0 ? void 0 : _child$userData17.objectType) === 'component' && (_child$userData18 = child.userData) !== null && _child$userData18 !== void 0 && _child$userData18.libraryId) {
1610
1604
  // Try to get worldBoundingBox from userData first (most up-to-date)
1611
1605
  var bbox = null;
1612
1606
  if (child.userData.worldBoundingBox) {
@@ -1751,8 +1745,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1751
1745
  // Get the moved segment's connectors
1752
1746
  var movedConnectors = [];
1753
1747
  movedSegment.traverse(function (child) {
1754
- var _child$userData21;
1755
- if (((_child$userData21 = child.userData) === null || _child$userData21 === void 0 ? void 0 : _child$userData21.objectType) === 'segment-connector') {
1748
+ var _child$userData19;
1749
+ if (((_child$userData19 = child.userData) === null || _child$userData19 === void 0 ? void 0 : _child$userData19.objectType) === 'segment-connector') {
1756
1750
  movedConnectors.push(child);
1757
1751
  }
1758
1752
  });
@@ -1822,8 +1816,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1822
1816
  // Get all connectors of the adjacent segment
1823
1817
  var adjacentConnectors = [];
1824
1818
  adjacentSegment.traverse(function (child) {
1825
- var _child$userData22;
1826
- if (((_child$userData22 = child.userData) === null || _child$userData22 === void 0 ? void 0 : _child$userData22.objectType) === 'segment-connector') {
1819
+ var _child$userData20;
1820
+ if (((_child$userData20 = child.userData) === null || _child$userData20 === void 0 ? void 0 : _child$userData20.objectType) === 'segment-connector') {
1827
1821
  adjacentConnectors.push(child);
1828
1822
  }
1829
1823
  });
@@ -1946,8 +1940,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
1946
1940
  // Also update child connectors' positions if they exist
1947
1941
  if (sceneDataComponent.children) {
1948
1942
  sceneDataComponent.children.forEach(function (child) {
1949
- var _child$userData23;
1950
- if (((_child$userData23 = child.userData) === null || _child$userData23 === void 0 ? void 0 : _child$userData23.objectType) === 'connector') {
1943
+ var _child$userData21;
1944
+ if (((_child$userData21 = child.userData) === null || _child$userData21 === void 0 ? void 0 : _child$userData21.objectType) === 'connector') {
1951
1945
  // Find the actual connector object in the scene
1952
1946
  var connectorObj = component.children.find(function (c) {
1953
1947
  var _c$userData;
@@ -2009,14 +2003,15 @@ var TransformOperationsManager = /*#__PURE__*/function () {
2009
2003
  // Also update child connectors' positions if they exist (rotation moves them in world space)
2010
2004
  if (sceneDataComponent.children) {
2011
2005
  sceneDataComponent.children.forEach(function (child) {
2012
- var _child$userData24;
2013
- if (((_child$userData24 = child.userData) === null || _child$userData24 === void 0 ? void 0 : _child$userData24.objectType) === 'connector') {
2006
+ var _child$userData22;
2007
+ if (((_child$userData22 = child.userData) === null || _child$userData22 === void 0 ? void 0 : _child$userData22.objectType) === 'connector') {
2014
2008
  // Find the actual connector object in the scene
2015
2009
  var connectorObj = component.children.find(function (c) {
2016
2010
  var _c$userData2;
2017
2011
  return c.uuid === child.uuid || ((_c$userData2 = c.userData) === null || _c$userData2 === void 0 ? void 0 : _c$userData2.originalUuid) === child.uuid;
2018
2012
  });
2019
2013
  if (connectorObj) {
2014
+ var _connectorObj$userDat;
2020
2015
  // Get world position of connector
2021
2016
  var worldPos = new THREE__namespace.Vector3();
2022
2017
  connectorObj.getWorldPosition(worldPos);
@@ -2027,6 +2022,12 @@ var TransformOperationsManager = /*#__PURE__*/function () {
2027
2022
  }
2028
2023
  child.userData.position = [cleanValue(worldPos.x), cleanValue(worldPos.y), cleanValue(worldPos.z)];
2029
2024
  console.log(" \u21B3 Updated child connector ".concat(child.uuid, " position to [").concat(child.userData.position.join(', '), "]"));
2025
+
2026
+ // Update connector's direction in scene data from the Three.js object
2027
+ if ((_connectorObj$userDat = connectorObj.userData) !== null && _connectorObj$userDat !== void 0 && _connectorObj$userDat.direction && Array.isArray(connectorObj.userData.direction)) {
2028
+ child.userData.direction = _rollupPluginBabelHelpers.toConsumableArray(connectorObj.userData.direction);
2029
+ console.log(" \u21B3 Updated child connector ".concat(child.uuid, " direction to [").concat(child.userData.direction.join(', '), "]"));
2030
+ }
2030
2031
  }
2031
2032
  }
2032
2033
  });
@@ -2339,8 +2340,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
2339
2340
  // Check if either external connector belongs to the active segment
2340
2341
  var activeSegmentConnectors = [];
2341
2342
  activeSegment.traverse(function (child) {
2342
- var _child$userData25;
2343
- if (((_child$userData25 = child.userData) === null || _child$userData25 === void 0 ? void 0 : _child$userData25.objectType) === 'segment-connector') {
2343
+ var _child$userData23;
2344
+ if (((_child$userData23 = child.userData) === null || _child$userData23 === void 0 ? void 0 : _child$userData23.objectType) === 'segment-connector') {
2344
2345
  activeSegmentConnectors.push(child.uuid);
2345
2346
  }
2346
2347
  });
@@ -2388,8 +2389,8 @@ var TransformOperationsManager = /*#__PURE__*/function () {
2388
2389
  // Get all connectors of the active segment
2389
2390
  var activeConnectors = [];
2390
2391
  activeSegment.traverse(function (child) {
2391
- var _child$userData26;
2392
- if (((_child$userData26 = child.userData) === null || _child$userData26 === void 0 ? void 0 : _child$userData26.objectType) === 'segment-connector') {
2392
+ var _child$userData24;
2393
+ if (((_child$userData24 = child.userData) === null || _child$userData24 === void 0 ? void 0 : _child$userData24.objectType) === 'segment-connector') {
2393
2394
  activeConnectors.push(child);
2394
2395
  }
2395
2396
  });
@@ -444,6 +444,22 @@ var PathfindingManager = /*#__PURE__*/function (_BaseDisposable) {
444
444
  this.pathfinder = new pathfinder.Pathfinder(this.pathfinderConfig);
445
445
  this.sceneViewer.pathfinder = this.pathfinder;
446
446
 
447
+ // ── Early exit if no connections ───────────────────────────────────
448
+ // Skip expensive bounding box computation when there's nothing to connect
449
+ if (!(!connections || connections.length === 0)) {
450
+ _context.n = 1;
451
+ break;
452
+ }
453
+ console.log("\u23ED\uFE0F Skipping pathfinding - no connections [".concat(context, "]"));
454
+ return _context.a(2, {
455
+ paths: [],
456
+ gateways: [],
457
+ rewiredConnections: [],
458
+ metrics: {
459
+ total: 0
460
+ }
461
+ });
462
+ case 1:
447
463
  // ── Stage 1: Input Generation ──────────────────────────────────────
448
464
  inputGenStart = performance.now(); // Ensure all matrices are up to date before bounding box calculations (for all pathfinding executions)
449
465
  this.sceneViewer.scene.updateMatrixWorld(true);
@@ -171,15 +171,23 @@ var ModelManager = /*#__PURE__*/function () {
171
171
  if (child.userData) {
172
172
  clonedConnector.userData = _rollupPluginBabelHelpers.objectSpread2({}, child.userData);
173
173
 
174
- // Deep copy critical data
174
+ // Deep copy critical data - handle both array [x,y,z] and object {x,y,z} formats
175
175
  if (child.userData.worldBoundingBox) {
176
+ var wbb = child.userData.worldBoundingBox;
176
177
  clonedConnector.userData.worldBoundingBox = {
177
- min: _rollupPluginBabelHelpers.toConsumableArray(child.userData.worldBoundingBox.min),
178
- max: _rollupPluginBabelHelpers.toConsumableArray(child.userData.worldBoundingBox.max)
178
+ min: Array.isArray(wbb.min) ? _rollupPluginBabelHelpers.toConsumableArray(wbb.min) : _rollupPluginBabelHelpers.objectSpread2({}, wbb.min),
179
+ max: Array.isArray(wbb.max) ? _rollupPluginBabelHelpers.toConsumableArray(wbb.max) : _rollupPluginBabelHelpers.objectSpread2({}, wbb.max)
179
180
  };
180
181
  }
181
182
  if (child.userData.direction) {
182
- clonedConnector.userData.direction = _rollupPluginBabelHelpers.toConsumableArray(child.userData.direction);
183
+ // Handle both array [x,y,z] and object {x,y,z} formats
184
+ if (Array.isArray(child.userData.direction)) {
185
+ clonedConnector.userData.direction = _rollupPluginBabelHelpers.toConsumableArray(child.userData.direction);
186
+ } else if (_rollupPluginBabelHelpers["typeof"](child.userData.direction) === 'object') {
187
+ clonedConnector.userData.direction = _rollupPluginBabelHelpers.objectSpread2({}, child.userData.direction);
188
+ } else {
189
+ clonedConnector.userData.direction = child.userData.direction;
190
+ }
183
191
  }
184
192
 
185
193
  // Set originalUuid to match the actual uuid (maintains consistency)
@@ -210,6 +218,7 @@ var ModelManager = /*#__PURE__*/function () {
210
218
  _context2.n = 1;
211
219
  break;
212
220
  }
221
+ console.log("\uD83C\uDFAF GLB cache HIT: ".concat(modelKey));
213
222
  return _context2.a(2, gltfScene);
214
223
  case 1:
215
224
  // Check if preloading is in progress
@@ -218,6 +227,7 @@ var ModelManager = /*#__PURE__*/function () {
218
227
  _context2.n = 6;
219
228
  break;
220
229
  }
230
+ console.log("\u23F3 Waiting for preloader: ".concat(modelKey));
221
231
  _context2.p = 2;
222
232
  _context2.n = 3;
223
233
  return modelPreloader["default"].preloadingPromise;
@@ -227,6 +237,7 @@ var ModelManager = /*#__PURE__*/function () {
227
237
  _context2.n = 4;
228
238
  break;
229
239
  }
240
+ console.log("\uD83C\uDFAF GLB cache HIT (after preload): ".concat(modelKey));
230
241
  return _context2.a(2, gltfScene);
231
242
  case 4:
232
243
  _context2.n = 6;
@@ -554,7 +565,7 @@ var ModelManager = /*#__PURE__*/function () {
554
565
  value: (function () {
555
566
  var _replaceWithGLBModels = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee5(libraryObjectsToReplace) {
556
567
  var _this3 = this;
557
- var glbLoadingPromises;
568
+ var startTime, glbLoadingPromises;
558
569
  return _rollupPluginBabelHelpers.regenerator().w(function (_context5) {
559
570
  while (1) switch (_context5.n) {
560
571
  case 0:
@@ -564,23 +575,29 @@ var ModelManager = /*#__PURE__*/function () {
564
575
  }
565
576
  return _context5.a(2);
566
577
  case 1:
578
+ startTime = performance.now();
567
579
  console.log("\uD83D\uDD04 Replacing ".concat(libraryObjectsToReplace.length, " objects with GLB models..."));
568
580
  glbLoadingPromises = libraryObjectsToReplace.map(function (_ref, index) {
569
581
  var basicObject = _ref.basicObject,
570
582
  jsonData = _ref.jsonData,
571
583
  componentData = _ref.componentData;
584
+ var modelStart = performance.now();
572
585
  return _this3.loadLibraryModel(basicObject, jsonData, componentData).then(function (libraryModel) {
586
+ var _jsonData$userData;
587
+ console.log("\u23F1\uFE0F GLB loaded: ".concat(((_jsonData$userData = jsonData.userData) === null || _jsonData$userData === void 0 ? void 0 : _jsonData$userData.libraryId) || jsonData.uuid, " in ").concat((performance.now() - modelStart).toFixed(0), "ms"));
573
588
  libraryObjectsToReplace[index].glbModel = libraryModel;
574
589
  return libraryModel;
575
590
  }).catch(function (error) {
576
- var _jsonData$userData;
577
- console.error("Failed to load ".concat((_jsonData$userData = jsonData.userData) === null || _jsonData$userData === void 0 ? void 0 : _jsonData$userData.libraryId, " GLB model:"), error);
591
+ var _jsonData$userData2;
592
+ console.error("Failed to load ".concat((_jsonData$userData2 = jsonData.userData) === null || _jsonData$userData2 === void 0 ? void 0 : _jsonData$userData2.libraryId, " GLB model:"), error);
578
593
  return basicObject;
579
594
  });
580
595
  });
581
596
  _context5.n = 2;
582
597
  return Promise.all(glbLoadingPromises);
583
598
  case 2:
599
+ console.log("\u23F1\uFE0F All GLB models loaded in ".concat((performance.now() - startTime).toFixed(0), "ms"));
600
+
584
601
  // Update world bounding boxes for loaded models and propagate to the live Three.js objects
585
602
  libraryObjectsToReplace.forEach(function (_ref2) {
586
603
  var jsonData = _ref2.jsonData,
@@ -704,9 +704,13 @@ var SceneOperationsManager = /*#__PURE__*/function () {
704
704
  value: (function () {
705
705
  var _loadSceneData = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee4(data) {
706
706
  var isImported,
707
+ timers,
708
+ totalStart,
709
+ phaseStart,
707
710
  _yield$this$_createBa,
708
711
  crosscubeTextureSet,
709
712
  libraryObjectsToReplace,
713
+ totalTime,
710
714
  _args4 = arguments,
711
715
  _t3;
712
716
  return _rollupPluginBabelHelpers.regenerator().w(function (_context4) {
@@ -714,13 +718,20 @@ var SceneOperationsManager = /*#__PURE__*/function () {
714
718
  case 0:
715
719
  isImported = _args4.length > 1 && _args4[1] !== undefined ? _args4[1] : true;
716
720
  this.sceneViewer;
721
+ timers = {};
722
+ totalStart = performance.now();
717
723
  _context4.p = 1;
718
724
  console.log("Loading scene data (".concat(isImported ? 'imported' : 'default', ")..."));
719
725
 
720
726
  // Phase 1: Prepare scene
727
+ phaseStart = performance.now();
721
728
  _context4.n = 2;
722
729
  return this._prepareSceneForLoading(data, isImported);
723
730
  case 2:
731
+ timers.phase1_prepare = performance.now() - phaseStart;
732
+
733
+ // Phase 2: Load dependencies and create basic objects
734
+ phaseStart = performance.now();
724
735
  _context4.n = 3;
725
736
  return this._createBasicSceneObjects(data);
726
737
  case 3:
@@ -730,17 +741,33 @@ var SceneOperationsManager = /*#__PURE__*/function () {
730
741
  _yield$this$_createBa.materials;
731
742
  crosscubeTextureSet = _yield$this$_createBa.crosscubeTextureSet;
732
743
  libraryObjectsToReplace = _yield$this$_createBa.libraryObjectsToReplace;
744
+ timers.phase2_createObjects = performance.now() - phaseStart;
745
+
746
+ // Phase 3: Replace basic objects with GLB models (moved before pathfinding)
747
+ phaseStart = performance.now();
733
748
  _context4.n = 4;
734
749
  return this.modelManager.replaceWithGLBModels(libraryObjectsToReplace);
735
750
  case 4:
751
+ timers.phase3_glbModels = performance.now() - phaseStart;
752
+
753
+ // Phase 4: Setup pathfinding (moved after GLB loading for consistent bounding boxes)
754
+ phaseStart = performance.now();
736
755
  _context4.n = 5;
737
756
  return this._setupPathfinding(data, crosscubeTextureSet);
738
757
  case 5:
758
+ timers.phase4_pathfinding = performance.now() - phaseStart;
759
+
739
760
  // Phase 5: Finalize scene
761
+ phaseStart = performance.now();
740
762
  this._finalizeScene(data, crosscubeTextureSet, isImported);
763
+ timers.phase5_finalize = performance.now() - phaseStart;
741
764
 
742
765
  // Phase 6: Load behaviors (after GLB models are present so output objects can be resolved)
766
+ phaseStart = performance.now();
743
767
  this._processBehaviors(data);
768
+ timers.phase6_behaviors = performance.now() - phaseStart;
769
+ totalTime = performance.now() - totalStart;
770
+ console.log("\u23F1\uFE0F Scene Loading Performance:\n Phase 1 (Prepare) : ".concat(timers.phase1_prepare.toFixed(0), "ms\n Phase 2 (Create Objects): ").concat(timers.phase2_createObjects.toFixed(0), "ms\n Phase 3 (GLB Models) : ").concat(timers.phase3_glbModels.toFixed(0), "ms\n Phase 4 (Pathfinding) : ").concat(timers.phase4_pathfinding.toFixed(0), "ms\n Phase 5 (Finalize) : ").concat(timers.phase5_finalize.toFixed(0), "ms\n Phase 6 (Behaviors) : ").concat(timers.phase6_behaviors.toFixed(0), "ms\n \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n Total : ").concat(totalTime.toFixed(0), "ms"));
744
771
  console.log('✅ Scene loaded successfully');
745
772
 
746
773
  // Notify UI components (e.g. SceneHierarchy) that the scene is fully loaded
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
5
5
  var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
6
  var THREE = require('three');
7
7
  var GLTFLoader = require('../../node_modules/three/examples/jsm/loaders/GLTFLoader.js');
8
+ var DRACOLoader = require('../../node_modules/three/examples/jsm/loaders/DRACOLoader.js');
8
9
 
9
10
  function _interopNamespace(e) {
10
11
  if (e && e.__esModule) return e;
@@ -32,13 +33,18 @@ var ModelPreloader = /*#__PURE__*/function () {
32
33
  this.modelCache = new Map(); // Cache for loaded models
33
34
  this.loadingPromises = new Map(); // Track ongoing loads to prevent duplicates
34
35
  this.gltfLoader = new GLTFLoader.GLTFLoader();
36
+
37
+ // Setup DRACO decoder for compressed GLB files
38
+ this.dracoLoader = new DRACOLoader.DRACOLoader();
39
+ this.dracoLoader.setDecoderPath('/draco/');
40
+ this.gltfLoader.setDRACOLoader(this.dracoLoader);
35
41
  this.isPreloading = false;
36
42
  this.preloadingPromise = null;
37
43
  this.componentDictionary = null;
38
44
  this.modelsBasePath = '/library/models/'; // Default local path
39
45
  this.urlResolver = null; // Optional function to resolve model URLs (for S3 authentication)
40
46
 
41
- console.log('🚀 ModelPreloader initialized with GLB support');
47
+ console.log('🚀 ModelPreloader initialized with GLB + DRACO support');
42
48
  }
43
49
 
44
50
  /**