@2112-lab/central-plant 0.3.13 → 0.3.14

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.14
39
39
  * @updated 2025-10-22
40
40
  *
41
41
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -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;
@@ -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.14
35
35
  * @updated 2025-10-22
36
36
  *
37
37
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -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 };
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.14",
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",