@2112-lab/central-plant 0.3.13 → 0.3.15

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.
@@ -35,7 +35,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
35
35
  * Initialize the CentralPlant manager
36
36
  *
37
37
  * @constructor
38
- * @version 0.3.13
38
+ * @version 0.3.15
39
39
  * @updated 2025-10-22
40
40
  *
41
41
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -112,7 +112,11 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
112
112
  }, {
113
113
  key: "createGateways",
114
114
  value: function createGateways(pathfindingResult) {
115
- var _this2 = this;
115
+ var _this$sceneViewer$man,
116
+ _this$sceneViewer,
117
+ _this2 = this;
118
+ // Check current gateway visibility setting
119
+ var showGateways = (_this$sceneViewer$man = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.settingsManager) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.getSetting('scene', 'showGatewaySpheres')) !== null && _this$sceneViewer$man !== void 0 ? _this$sceneViewer$man : true;
116
120
  pathfindingResult.gateways.forEach(function (gateway) {
117
121
  if (!gateway.position) {
118
122
  console.warn("\u26A0\uFE0F Gateway ".concat(gateway.id, " missing position, skipping creation"));
@@ -157,6 +161,9 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
157
161
  }
158
162
  };
159
163
 
164
+ // Apply current visibility setting
165
+ gatewayMesh.visible = showGateways;
166
+
160
167
  // Add to scene
161
168
  _this2.sceneViewer.scene.add(gatewayMesh);
162
169
  console.log("\uD83D\uDD27 Created gateway: ".concat(gateway.id, " at [").concat(gatewayMesh.position.x.toFixed(2), ", ").concat(gatewayMesh.position.y.toFixed(2), ", ").concat(gatewayMesh.position.z.toFixed(2), "]"));
@@ -7,6 +7,7 @@ var THREE = require('three');
7
7
  var ioDeviceUtils = require('../../utils/ioDeviceUtils.js');
8
8
  var modelPreloader = require('../../rendering/modelPreloader.js');
9
9
  var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
10
+ var viewport2DManager = require('./viewport2DManager.js');
10
11
 
11
12
  function _interopNamespace(e) {
12
13
  if (e && e.__esModule) return e;
@@ -604,13 +605,9 @@ var ModelManager = /*#__PURE__*/function () {
604
605
  // Update both the JSON data object AND the live scene object
605
606
  jsonData.userData.worldBoundingBox = worldBoundingBox;
606
607
  glbModel.userData.worldBoundingBox = worldBoundingBox;
607
- // Snapshot the object's local position so viewport2DManager can compute
608
+ // Cache the object's position so viewport2DManager can compute
608
609
  // world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
609
- glbModel.userData._wbbBasePosition = {
610
- x: glbModel.position.x,
611
- y: glbModel.position.y,
612
- z: glbModel.position.z
613
- };
610
+ viewport2DManager.cacheBasePosition(glbModel, worldBoundingBox);
614
611
  });
615
612
 
616
613
  // Dispatch completion event
@@ -27,6 +27,29 @@ function _interopNamespace(e) {
27
27
 
28
28
  var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
29
29
 
30
+ /**
31
+ * WeakMap cache for storing base position data per Object3D.
32
+ * Used by _getOrComputeWorldBoundingBox() for O(1) bbox offset calculations.
33
+ * WeakMap ensures automatic cleanup when objects are garbage collected.
34
+ * @type {WeakMap<THREE.Object3D, {x: number, y: number, z: number, worldBoundingBox: {min: number[], max: number[]}}>}
35
+ */
36
+ var _basePositionCache = new WeakMap();
37
+
38
+ /**
39
+ * Store base position and worldBoundingBox for an Object3D.
40
+ * Called by modelManager after GLB loading to enable fast bbox updates.
41
+ * @param {THREE.Object3D} object - The loaded GLB model
42
+ * @param {{min: number[], max: number[]}} worldBoundingBox - Computed world bounding box
43
+ */
44
+ function cacheBasePosition(object, worldBoundingBox) {
45
+ _basePositionCache.set(object, {
46
+ x: object.position.x,
47
+ y: object.position.y,
48
+ z: object.position.z,
49
+ worldBoundingBox: worldBoundingBox
50
+ });
51
+ }
52
+
30
53
  /**
31
54
  * Viewport2DInstance
32
55
  * Represents a single 2D viewport with its own Konva stage and configuration
@@ -675,16 +698,15 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
675
698
  }, {
676
699
  key: "_getOrComputeWorldBoundingBox",
677
700
  value: function _getOrComputeWorldBoundingBox(object) {
678
- var _object$userData, _object$userData2;
679
701
  // Fast path: offset the stored world bbox by the position delta since load time.
680
702
  // Translation only shifts the bbox center — extents stay identical — so this is O(1)
681
703
  // instead of O(meshes × vertices) from a full geometry traversal.
682
- var stored = (_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.worldBoundingBox;
683
- var basePos = (_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2._wbbBasePosition;
684
- if (stored && basePos) {
685
- var dx = object.position.x - basePos.x;
686
- var dy = object.position.y - basePos.y;
687
- var dz = object.position.z - basePos.z;
704
+ var cached = _basePositionCache.get(object);
705
+ if (cached) {
706
+ var dx = object.position.x - cached.x;
707
+ var dy = object.position.y - cached.y;
708
+ var dz = object.position.z - cached.z;
709
+ var stored = cached.worldBoundingBox;
688
710
  if (dx === 0 && dy === 0 && dz === 0) return stored;
689
711
  return {
690
712
  min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
@@ -1091,10 +1113,10 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
1091
1113
  }
1092
1114
  var components = [];
1093
1115
  this.sceneViewer.scene.traverse(function (object) {
1094
- var _object$userData3, _object$userData4;
1116
+ var _object$userData, _object$userData2;
1095
1117
  // Only match the ROOT component object — must have both objectType:'component'
1096
1118
  // AND libraryId (inner GLB mesh nodes don't have libraryId)
1097
- if (((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.objectType) === 'component' && (_object$userData4 = object.userData) !== null && _object$userData4 !== void 0 && _object$userData4.libraryId) {
1119
+ if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'component' && (_object$userData2 = object.userData) !== null && _object$userData2 !== void 0 && _object$userData2.libraryId) {
1098
1120
  components.push(object);
1099
1121
  }
1100
1122
  });
@@ -1314,3 +1336,4 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
1314
1336
  }(baseDisposable.BaseDisposable);
1315
1337
 
1316
1338
  exports.Viewport2DManager = Viewport2DManager;
1339
+ exports.cacheBasePosition = cacheBasePosition;
@@ -12,6 +12,7 @@ var DEFAULT_SETTINGS = {
12
12
  scene: {
13
13
  autoRotation: false,
14
14
  checkUnderground: true,
15
+ showGatewaySpheres: false,
15
16
  splitSegmentsWithComponentConnectors: true
16
17
  },
17
18
  viewport: {
@@ -242,9 +243,37 @@ var SettingsManager = /*#__PURE__*/function (_BaseDisposable) {
242
243
  component.transformManager.checkUnderground = sceneSettings.checkUnderground;
243
244
  }
244
245
  }
246
+
247
+ // Handle gateway sphere visibility
248
+ if (sceneSettings.hasOwnProperty('showGatewaySpheres')) {
249
+ this.setGatewayVisibility(sceneSettings.showGatewaySpheres);
250
+ }
245
251
  console.log('🎬 Scene settings applied:', sceneSettings);
246
252
  }
247
253
 
254
+ /**
255
+ * Set visibility of all gateway spheres in the scene
256
+ * @param {boolean} visible - Whether gateways should be visible
257
+ */
258
+ }, {
259
+ key: "setGatewayVisibility",
260
+ value: function setGatewayVisibility(visible) {
261
+ var _this$sceneViewer;
262
+ if (!((_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.scene)) {
263
+ console.warn('⚠️ Scene not available for gateway visibility toggle');
264
+ return;
265
+ }
266
+ var gatewayCount = 0;
267
+ this.sceneViewer.scene.traverse(function (object) {
268
+ var _object$userData;
269
+ if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'gateway') {
270
+ object.visible = visible;
271
+ gatewayCount++;
272
+ }
273
+ });
274
+ console.log("\uD83D\uDD2E Gateway visibility set to ".concat(visible, " (").concat(gatewayCount, " gateways affected)"));
275
+ }
276
+
248
277
  /**
249
278
  * Apply viewport-specific settings
250
279
  * @param {Object} viewportSettings - Viewport settings
@@ -31,7 +31,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
31
31
  * Initialize the CentralPlant manager
32
32
  *
33
33
  * @constructor
34
- * @version 0.3.13
34
+ * @version 0.3.15
35
35
  * @updated 2025-10-22
36
36
  *
37
37
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -88,7 +88,11 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
88
88
  }, {
89
89
  key: "createGateways",
90
90
  value: function createGateways(pathfindingResult) {
91
- var _this2 = this;
91
+ var _this$sceneViewer$man,
92
+ _this$sceneViewer,
93
+ _this2 = this;
94
+ // Check current gateway visibility setting
95
+ var showGateways = (_this$sceneViewer$man = (_this$sceneViewer = this.sceneViewer) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.managers) === null || _this$sceneViewer === void 0 || (_this$sceneViewer = _this$sceneViewer.settingsManager) === null || _this$sceneViewer === void 0 ? void 0 : _this$sceneViewer.getSetting('scene', 'showGatewaySpheres')) !== null && _this$sceneViewer$man !== void 0 ? _this$sceneViewer$man : true;
92
96
  pathfindingResult.gateways.forEach(function (gateway) {
93
97
  if (!gateway.position) {
94
98
  console.warn("\u26A0\uFE0F Gateway ".concat(gateway.id, " missing position, skipping creation"));
@@ -133,6 +137,9 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
133
137
  }
134
138
  };
135
139
 
140
+ // Apply current visibility setting
141
+ gatewayMesh.visible = showGateways;
142
+
136
143
  // Add to scene
137
144
  _this2.sceneViewer.scene.add(gatewayMesh);
138
145
  console.log("\uD83D\uDD27 Created gateway: ".concat(gateway.id, " at [").concat(gatewayMesh.position.x.toFixed(2), ", ").concat(gatewayMesh.position.y.toFixed(2), ", ").concat(gatewayMesh.position.z.toFixed(2), "]"));
@@ -3,6 +3,7 @@ import * as THREE from 'three';
3
3
  import { attachIODevicesToComponent } from '../../utils/ioDeviceUtils.js';
4
4
  import modelPreloader from '../../rendering/modelPreloader.js';
5
5
  import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
6
+ import { cacheBasePosition } from './viewport2DManager.js';
6
7
 
7
8
  var ModelManager = /*#__PURE__*/function () {
8
9
  function ModelManager(sceneViewer) {
@@ -580,13 +581,9 @@ var ModelManager = /*#__PURE__*/function () {
580
581
  // Update both the JSON data object AND the live scene object
581
582
  jsonData.userData.worldBoundingBox = worldBoundingBox;
582
583
  glbModel.userData.worldBoundingBox = worldBoundingBox;
583
- // Snapshot the object's local position so viewport2DManager can compute
584
+ // Cache the object's position so viewport2DManager can compute
584
585
  // world-bbox updates via a fast O(1) position delta instead of re-traversing geometry
585
- glbModel.userData._wbbBasePosition = {
586
- x: glbModel.position.x,
587
- y: glbModel.position.y,
588
- z: glbModel.position.z
589
- };
586
+ cacheBasePosition(glbModel, worldBoundingBox);
590
587
  });
591
588
 
592
589
  // Dispatch completion event
@@ -3,6 +3,29 @@ import { BaseDisposable } from '../../core/baseDisposable.js';
3
3
  import * as THREE from 'three';
4
4
  import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
5
5
 
6
+ /**
7
+ * WeakMap cache for storing base position data per Object3D.
8
+ * Used by _getOrComputeWorldBoundingBox() for O(1) bbox offset calculations.
9
+ * WeakMap ensures automatic cleanup when objects are garbage collected.
10
+ * @type {WeakMap<THREE.Object3D, {x: number, y: number, z: number, worldBoundingBox: {min: number[], max: number[]}}>}
11
+ */
12
+ var _basePositionCache = new WeakMap();
13
+
14
+ /**
15
+ * Store base position and worldBoundingBox for an Object3D.
16
+ * Called by modelManager after GLB loading to enable fast bbox updates.
17
+ * @param {THREE.Object3D} object - The loaded GLB model
18
+ * @param {{min: number[], max: number[]}} worldBoundingBox - Computed world bounding box
19
+ */
20
+ function cacheBasePosition(object, worldBoundingBox) {
21
+ _basePositionCache.set(object, {
22
+ x: object.position.x,
23
+ y: object.position.y,
24
+ z: object.position.z,
25
+ worldBoundingBox: worldBoundingBox
26
+ });
27
+ }
28
+
6
29
  /**
7
30
  * Viewport2DInstance
8
31
  * Represents a single 2D viewport with its own Konva stage and configuration
@@ -651,16 +674,15 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
651
674
  }, {
652
675
  key: "_getOrComputeWorldBoundingBox",
653
676
  value: function _getOrComputeWorldBoundingBox(object) {
654
- var _object$userData, _object$userData2;
655
677
  // Fast path: offset the stored world bbox by the position delta since load time.
656
678
  // Translation only shifts the bbox center — extents stay identical — so this is O(1)
657
679
  // instead of O(meshes × vertices) from a full geometry traversal.
658
- var stored = (_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.worldBoundingBox;
659
- var basePos = (_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2._wbbBasePosition;
660
- if (stored && basePos) {
661
- var dx = object.position.x - basePos.x;
662
- var dy = object.position.y - basePos.y;
663
- var dz = object.position.z - basePos.z;
680
+ var cached = _basePositionCache.get(object);
681
+ if (cached) {
682
+ var dx = object.position.x - cached.x;
683
+ var dy = object.position.y - cached.y;
684
+ var dz = object.position.z - cached.z;
685
+ var stored = cached.worldBoundingBox;
664
686
  if (dx === 0 && dy === 0 && dz === 0) return stored;
665
687
  return {
666
688
  min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
@@ -1067,10 +1089,10 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
1067
1089
  }
1068
1090
  var components = [];
1069
1091
  this.sceneViewer.scene.traverse(function (object) {
1070
- var _object$userData3, _object$userData4;
1092
+ var _object$userData, _object$userData2;
1071
1093
  // Only match the ROOT component object — must have both objectType:'component'
1072
1094
  // AND libraryId (inner GLB mesh nodes don't have libraryId)
1073
- if (((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.objectType) === 'component' && (_object$userData4 = object.userData) !== null && _object$userData4 !== void 0 && _object$userData4.libraryId) {
1095
+ if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'component' && (_object$userData2 = object.userData) !== null && _object$userData2 !== void 0 && _object$userData2.libraryId) {
1074
1096
  components.push(object);
1075
1097
  }
1076
1098
  });
@@ -1289,4 +1311,4 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
1289
1311
  }]);
1290
1312
  }(BaseDisposable);
1291
1313
 
1292
- export { Viewport2DManager };
1314
+ export { Viewport2DManager, cacheBasePosition };
@@ -8,6 +8,7 @@ var DEFAULT_SETTINGS = {
8
8
  scene: {
9
9
  autoRotation: false,
10
10
  checkUnderground: true,
11
+ showGatewaySpheres: false,
11
12
  splitSegmentsWithComponentConnectors: true
12
13
  },
13
14
  viewport: {
@@ -238,9 +239,37 @@ var SettingsManager = /*#__PURE__*/function (_BaseDisposable) {
238
239
  component.transformManager.checkUnderground = sceneSettings.checkUnderground;
239
240
  }
240
241
  }
242
+
243
+ // Handle gateway sphere visibility
244
+ if (sceneSettings.hasOwnProperty('showGatewaySpheres')) {
245
+ this.setGatewayVisibility(sceneSettings.showGatewaySpheres);
246
+ }
241
247
  console.log('🎬 Scene settings applied:', sceneSettings);
242
248
  }
243
249
 
250
+ /**
251
+ * Set visibility of all gateway spheres in the scene
252
+ * @param {boolean} visible - Whether gateways should be visible
253
+ */
254
+ }, {
255
+ key: "setGatewayVisibility",
256
+ value: function setGatewayVisibility(visible) {
257
+ var _this$sceneViewer;
258
+ if (!((_this$sceneViewer = this.sceneViewer) !== null && _this$sceneViewer !== void 0 && _this$sceneViewer.scene)) {
259
+ console.warn('⚠️ Scene not available for gateway visibility toggle');
260
+ return;
261
+ }
262
+ var gatewayCount = 0;
263
+ this.sceneViewer.scene.traverse(function (object) {
264
+ var _object$userData;
265
+ if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'gateway') {
266
+ object.visible = visible;
267
+ gatewayCount++;
268
+ }
269
+ });
270
+ console.log("\uD83D\uDD2E Gateway visibility set to ".concat(visible, " (").concat(gatewayCount, " gateways affected)"));
271
+ }
272
+
244
273
  /**
245
274
  * Apply viewport-specific settings
246
275
  * @param {Object} viewportSettings - Viewport settings
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.13",
3
+ "version": "0.3.15",
4
4
  "description": "Utility modules for the Central Plant Application",
5
5
  "main": "dist/bundle/index.js",
6
6
  "module": "dist/esm/src/index.js",