@2112-lab/central-plant 0.3.57 → 0.3.58

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.
@@ -4109,6 +4109,12 @@ var TransformControlsManager = /*#__PURE__*/function () {
4109
4109
  // Update bounding box if the transformed object is in current selection
4110
4110
  if (_this.selectedObjects.includes(eventData.object)) {
4111
4111
  console.log('🔲 Updating bounding boxes for selected objects after transform');
4112
+ // Reposition the transform gizmo (and its selection group) to follow the
4113
+ // object's new position. Programmatic transforms (e.g. the Transform tab's
4114
+ // Translate/Rotate buttons) move the object directly without touching the
4115
+ // multi-selection group the gizmo is attached to, so without this the widget
4116
+ // would stay at the pre-transform centroid.
4117
+ _this.syncSelectionToObjects();
4112
4118
  _this.updateBoundingBox();
4113
4119
  }
4114
4120
  };
@@ -5215,6 +5221,59 @@ var TransformControlsManager = /*#__PURE__*/function () {
5215
5221
  console.log("\uD83D\uDCE6 Multi-selection group created at centroid:", centroid.toArray());
5216
5222
  }
5217
5223
 
5224
+ /**
5225
+ * Re-sync the multi-selection group (and the attached transform gizmo) to the
5226
+ * current world positions of the selected objects, in place.
5227
+ *
5228
+ * Used after a *programmatic* transform (e.g. the Transform tab's Translate /
5229
+ * Rotate buttons), which mutates the object directly and does not move the
5230
+ * selection group the gizmo is attached to. Unlike a full updateMultiSelection()
5231
+ * this keeps the same group instance so the gizmo doesn't detach/re-attach.
5232
+ *
5233
+ * It also refreshes the cached original transforms so a subsequent gizmo drag
5234
+ * computes its delta from the object's new position rather than jumping.
5235
+ */
5236
+ }, {
5237
+ key: "syncSelectionToObjects",
5238
+ value: function syncSelectionToObjects() {
5239
+ var _this$transformContro;
5240
+ if (!this.multiSelectionGroup || this.selectedObjects.length === 0) {
5241
+ return;
5242
+ }
5243
+
5244
+ // Recompute the centroid from the objects' current world positions.
5245
+ var centroid = new THREE__namespace.Vector3();
5246
+ this.selectedObjects.forEach(function (obj) {
5247
+ obj.updateMatrixWorld(true);
5248
+ var worldPos = new THREE__namespace.Vector3();
5249
+ obj.getWorldPosition(worldPos);
5250
+ centroid.add(worldPos);
5251
+ });
5252
+ centroid.divideScalar(this.selectedObjects.length);
5253
+
5254
+ // Move the group (and thus the attached gizmo) to the new centroid. Reset any
5255
+ // rotation so the gizmo matches the freshly-created-group convention.
5256
+ this.multiSelectionGroup.position.copy(centroid);
5257
+ this.multiSelectionGroup.rotation.set(0, 0, 0);
5258
+ this.multiSelectionGroup.updateMatrixWorld(true);
5259
+
5260
+ // Refresh cached originals so applyRealtimeTransform's delta stays correct on
5261
+ // the next drag (its "original centroid" is derived from these values).
5262
+ this.selectedObjects.forEach(function (obj) {
5263
+ obj.userData._multiSelectOriginalPosition = obj.position.clone();
5264
+ obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
5265
+ obj.userData._multiSelectOriginalScale = obj.scale.clone();
5266
+ var worldPos = new THREE__namespace.Vector3();
5267
+ obj.getWorldPosition(worldPos);
5268
+ obj.userData._multiSelectOriginalWorldPosition = worldPos;
5269
+ });
5270
+
5271
+ // Keep the gizmo's world matrix in sync with the repositioned group.
5272
+ if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
5273
+ this.transformControls.updateMatrixWorld(true);
5274
+ }
5275
+ }
5276
+
5218
5277
  /**
5219
5278
  * Create a bounding box that encompasses all selected objects
5220
5279
  */
@@ -5494,10 +5553,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
5494
5553
  }, {
5495
5554
  key: "toggleTransformMode",
5496
5555
  value: function toggleTransformMode() {
5497
- var _this$transformContro;
5556
+ var _this$transformContro2;
5498
5557
  var newMode = this.currentMode === 'translate' ? 'rotate' : 'translate';
5499
5558
  this.setMode(newMode);
5500
- if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
5559
+ if ((_this$transformContro2 = this.transformControls) !== null && _this$transformContro2 !== void 0 && _this$transformContro2.object) {
5501
5560
  this.transformControls.updateMatrixWorld(true);
5502
5561
  }
5503
5562
  }
@@ -41825,7 +41884,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
41825
41884
  * Initialize the CentralPlant manager
41826
41885
  *
41827
41886
  * @constructor
41828
- * @version 0.3.57
41887
+ * @version 0.3.58
41829
41888
  * @updated 2025-10-22
41830
41889
  *
41831
41890
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -58,7 +58,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
58
58
  * Initialize the CentralPlant manager
59
59
  *
60
60
  * @constructor
61
- * @version 0.3.57
61
+ * @version 0.3.58
62
62
  * @updated 2025-10-22
63
63
  *
64
64
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -164,6 +164,12 @@ var TransformControlsManager = /*#__PURE__*/function () {
164
164
  // Update bounding box if the transformed object is in current selection
165
165
  if (_this.selectedObjects.includes(eventData.object)) {
166
166
  console.log('🔲 Updating bounding boxes for selected objects after transform');
167
+ // Reposition the transform gizmo (and its selection group) to follow the
168
+ // object's new position. Programmatic transforms (e.g. the Transform tab's
169
+ // Translate/Rotate buttons) move the object directly without touching the
170
+ // multi-selection group the gizmo is attached to, so without this the widget
171
+ // would stay at the pre-transform centroid.
172
+ _this.syncSelectionToObjects();
167
173
  _this.updateBoundingBox();
168
174
  }
169
175
  };
@@ -1270,6 +1276,59 @@ var TransformControlsManager = /*#__PURE__*/function () {
1270
1276
  console.log("\uD83D\uDCE6 Multi-selection group created at centroid:", centroid.toArray());
1271
1277
  }
1272
1278
 
1279
+ /**
1280
+ * Re-sync the multi-selection group (and the attached transform gizmo) to the
1281
+ * current world positions of the selected objects, in place.
1282
+ *
1283
+ * Used after a *programmatic* transform (e.g. the Transform tab's Translate /
1284
+ * Rotate buttons), which mutates the object directly and does not move the
1285
+ * selection group the gizmo is attached to. Unlike a full updateMultiSelection()
1286
+ * this keeps the same group instance so the gizmo doesn't detach/re-attach.
1287
+ *
1288
+ * It also refreshes the cached original transforms so a subsequent gizmo drag
1289
+ * computes its delta from the object's new position rather than jumping.
1290
+ */
1291
+ }, {
1292
+ key: "syncSelectionToObjects",
1293
+ value: function syncSelectionToObjects() {
1294
+ var _this$transformContro;
1295
+ if (!this.multiSelectionGroup || this.selectedObjects.length === 0) {
1296
+ return;
1297
+ }
1298
+
1299
+ // Recompute the centroid from the objects' current world positions.
1300
+ var centroid = new THREE__namespace.Vector3();
1301
+ this.selectedObjects.forEach(function (obj) {
1302
+ obj.updateMatrixWorld(true);
1303
+ var worldPos = new THREE__namespace.Vector3();
1304
+ obj.getWorldPosition(worldPos);
1305
+ centroid.add(worldPos);
1306
+ });
1307
+ centroid.divideScalar(this.selectedObjects.length);
1308
+
1309
+ // Move the group (and thus the attached gizmo) to the new centroid. Reset any
1310
+ // rotation so the gizmo matches the freshly-created-group convention.
1311
+ this.multiSelectionGroup.position.copy(centroid);
1312
+ this.multiSelectionGroup.rotation.set(0, 0, 0);
1313
+ this.multiSelectionGroup.updateMatrixWorld(true);
1314
+
1315
+ // Refresh cached originals so applyRealtimeTransform's delta stays correct on
1316
+ // the next drag (its "original centroid" is derived from these values).
1317
+ this.selectedObjects.forEach(function (obj) {
1318
+ obj.userData._multiSelectOriginalPosition = obj.position.clone();
1319
+ obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
1320
+ obj.userData._multiSelectOriginalScale = obj.scale.clone();
1321
+ var worldPos = new THREE__namespace.Vector3();
1322
+ obj.getWorldPosition(worldPos);
1323
+ obj.userData._multiSelectOriginalWorldPosition = worldPos;
1324
+ });
1325
+
1326
+ // Keep the gizmo's world matrix in sync with the repositioned group.
1327
+ if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
1328
+ this.transformControls.updateMatrixWorld(true);
1329
+ }
1330
+ }
1331
+
1273
1332
  /**
1274
1333
  * Create a bounding box that encompasses all selected objects
1275
1334
  */
@@ -1549,10 +1608,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
1549
1608
  }, {
1550
1609
  key: "toggleTransformMode",
1551
1610
  value: function toggleTransformMode() {
1552
- var _this$transformContro;
1611
+ var _this$transformContro2;
1553
1612
  var newMode = this.currentMode === 'translate' ? 'rotate' : 'translate';
1554
1613
  this.setMode(newMode);
1555
- if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
1614
+ if ((_this$transformContro2 = this.transformControls) !== null && _this$transformContro2 !== void 0 && _this$transformContro2.object) {
1556
1615
  this.transformControls.updateMatrixWorld(true);
1557
1616
  }
1558
1617
  }
@@ -34,7 +34,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
34
34
  * Initialize the CentralPlant manager
35
35
  *
36
36
  * @constructor
37
- * @version 0.3.57
37
+ * @version 0.3.58
38
38
  * @updated 2025-10-22
39
39
  *
40
40
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -140,6 +140,12 @@ var TransformControlsManager = /*#__PURE__*/function () {
140
140
  // Update bounding box if the transformed object is in current selection
141
141
  if (_this.selectedObjects.includes(eventData.object)) {
142
142
  console.log('🔲 Updating bounding boxes for selected objects after transform');
143
+ // Reposition the transform gizmo (and its selection group) to follow the
144
+ // object's new position. Programmatic transforms (e.g. the Transform tab's
145
+ // Translate/Rotate buttons) move the object directly without touching the
146
+ // multi-selection group the gizmo is attached to, so without this the widget
147
+ // would stay at the pre-transform centroid.
148
+ _this.syncSelectionToObjects();
143
149
  _this.updateBoundingBox();
144
150
  }
145
151
  };
@@ -1246,6 +1252,59 @@ var TransformControlsManager = /*#__PURE__*/function () {
1246
1252
  console.log("\uD83D\uDCE6 Multi-selection group created at centroid:", centroid.toArray());
1247
1253
  }
1248
1254
 
1255
+ /**
1256
+ * Re-sync the multi-selection group (and the attached transform gizmo) to the
1257
+ * current world positions of the selected objects, in place.
1258
+ *
1259
+ * Used after a *programmatic* transform (e.g. the Transform tab's Translate /
1260
+ * Rotate buttons), which mutates the object directly and does not move the
1261
+ * selection group the gizmo is attached to. Unlike a full updateMultiSelection()
1262
+ * this keeps the same group instance so the gizmo doesn't detach/re-attach.
1263
+ *
1264
+ * It also refreshes the cached original transforms so a subsequent gizmo drag
1265
+ * computes its delta from the object's new position rather than jumping.
1266
+ */
1267
+ }, {
1268
+ key: "syncSelectionToObjects",
1269
+ value: function syncSelectionToObjects() {
1270
+ var _this$transformContro;
1271
+ if (!this.multiSelectionGroup || this.selectedObjects.length === 0) {
1272
+ return;
1273
+ }
1274
+
1275
+ // Recompute the centroid from the objects' current world positions.
1276
+ var centroid = new THREE.Vector3();
1277
+ this.selectedObjects.forEach(function (obj) {
1278
+ obj.updateMatrixWorld(true);
1279
+ var worldPos = new THREE.Vector3();
1280
+ obj.getWorldPosition(worldPos);
1281
+ centroid.add(worldPos);
1282
+ });
1283
+ centroid.divideScalar(this.selectedObjects.length);
1284
+
1285
+ // Move the group (and thus the attached gizmo) to the new centroid. Reset any
1286
+ // rotation so the gizmo matches the freshly-created-group convention.
1287
+ this.multiSelectionGroup.position.copy(centroid);
1288
+ this.multiSelectionGroup.rotation.set(0, 0, 0);
1289
+ this.multiSelectionGroup.updateMatrixWorld(true);
1290
+
1291
+ // Refresh cached originals so applyRealtimeTransform's delta stays correct on
1292
+ // the next drag (its "original centroid" is derived from these values).
1293
+ this.selectedObjects.forEach(function (obj) {
1294
+ obj.userData._multiSelectOriginalPosition = obj.position.clone();
1295
+ obj.userData._multiSelectOriginalRotation = obj.rotation.clone();
1296
+ obj.userData._multiSelectOriginalScale = obj.scale.clone();
1297
+ var worldPos = new THREE.Vector3();
1298
+ obj.getWorldPosition(worldPos);
1299
+ obj.userData._multiSelectOriginalWorldPosition = worldPos;
1300
+ });
1301
+
1302
+ // Keep the gizmo's world matrix in sync with the repositioned group.
1303
+ if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
1304
+ this.transformControls.updateMatrixWorld(true);
1305
+ }
1306
+ }
1307
+
1249
1308
  /**
1250
1309
  * Create a bounding box that encompasses all selected objects
1251
1310
  */
@@ -1525,10 +1584,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
1525
1584
  }, {
1526
1585
  key: "toggleTransformMode",
1527
1586
  value: function toggleTransformMode() {
1528
- var _this$transformContro;
1587
+ var _this$transformContro2;
1529
1588
  var newMode = this.currentMode === 'translate' ? 'rotate' : 'translate';
1530
1589
  this.setMode(newMode);
1531
- if ((_this$transformContro = this.transformControls) !== null && _this$transformContro !== void 0 && _this$transformContro.object) {
1590
+ if ((_this$transformContro2 = this.transformControls) !== null && _this$transformContro2 !== void 0 && _this$transformContro2.object) {
1532
1591
  this.transformControls.updateMatrixWorld(true);
1533
1592
  }
1534
1593
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.57",
3
+ "version": "0.3.58",
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",