@2112-lab/central-plant 0.3.42 → 0.3.44

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.
@@ -2970,8 +2970,8 @@ var transformControls = /*#__PURE__*/function (_THREE$Object3D) {
2970
2970
  }, {
2971
2971
  key: "setMode",
2972
2972
  value: function setMode(mode) {
2973
- if (mode === 'scale') {
2974
- console.warn('transformControls: Scale mode has been removed. Using translate mode instead.');
2973
+ if (mode !== 'translate') {
2974
+ console.warn("transformControls: ".concat(mode, " mode is disabled. Locking to translate."));
2975
2975
  mode = 'translate';
2976
2976
  }
2977
2977
  this.mode = mode;
@@ -4335,10 +4335,6 @@ var TransformControlsManager = /*#__PURE__*/function () {
4335
4335
  // Translate mode
4336
4336
  _this3.setMode('translate');
4337
4337
  break;
4338
- case 'KeyR':
4339
- // Rotate mode
4340
- _this3.setMode('rotate');
4341
- break;
4342
4338
  }
4343
4339
  };
4344
4340
  window.addEventListener('keydown', this.eventHandlers.keydown);
@@ -5358,9 +5354,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
5358
5354
  }, {
5359
5355
  key: "setMode",
5360
5356
  value: function setMode(mode) {
5361
- if (!['translate', 'rotate', 'scale'].includes(mode)) {
5362
- console.warn("\u26A0\uFE0F Invalid transform mode: ".concat(mode));
5363
- return;
5357
+ // Only allow translate mode - lock rotation and scale controls
5358
+ if (mode !== 'translate') {
5359
+ console.warn("\u26A0\uFE0F Transform mode ".concat(mode, " is disabled. Locking to translate."));
5360
+ mode = 'translate';
5364
5361
  }
5365
5362
  var previousMode = this.currentMode;
5366
5363
  this.currentMode = mode;
@@ -27901,7 +27898,7 @@ var PathRenderingManager = /*#__PURE__*/function (_BaseDisposable) {
27901
27898
  }]);
27902
27899
  }(BaseDisposable);
27903
27900
 
27904
- var _excluded$1 = ["direction"];
27901
+ var _excluded$2 = ["direction"];
27905
27902
  var ConnectorManager = /*#__PURE__*/function (_BaseDisposable) {
27906
27903
  function ConnectorManager(sceneViewer) {
27907
27904
  var _this;
@@ -28046,7 +28043,7 @@ var ConnectorManager = /*#__PURE__*/function (_BaseDisposable) {
28046
28043
  // Filter out 'direction' attribute - manual segment connectors don't need it
28047
28044
  var _ref = connector.userData || {};
28048
28045
  _ref.direction;
28049
- var cleanedUserData = _objectWithoutProperties(_ref, _excluded$1);
28046
+ var cleanedUserData = _objectWithoutProperties(_ref, _excluded$2);
28050
28047
  var sceneDataConnector = {
28051
28048
  uuid: connector.uuid,
28052
28049
  userData: _objectSpread2(_objectSpread2({}, cleanedUserData), {}, {
@@ -32813,7 +32810,7 @@ var SceneClearingUtility = /*#__PURE__*/function () {
32813
32810
  }]);
32814
32811
  }();
32815
32812
 
32816
- var _excluded = ["direction"],
32813
+ var _excluded$1 = ["direction"],
32817
32814
  _excluded2 = ["direction"];
32818
32815
  var SceneOperationsManager = /*#__PURE__*/function () {
32819
32816
  function SceneOperationsManager(sceneViewer) {
@@ -33402,7 +33399,7 @@ var SceneOperationsManager = /*#__PURE__*/function () {
33402
33399
  // Initialize userData (filter out 'direction' - manual segment connectors don't need it)
33403
33400
  var _ref = connectorData.userData || {};
33404
33401
  _ref.direction;
33405
- var _cleanedUserData = _objectWithoutProperties(_ref, _excluded);
33402
+ var _cleanedUserData = _objectWithoutProperties(_ref, _excluded$1);
33406
33403
  _connectorMesh.userData = _objectSpread2(_objectSpread2({}, _cleanedUserData), {}, {
33407
33404
  originalUuid: connectorData.uuid,
33408
33405
  objectType: 'segment-connector',
@@ -37861,13 +37858,14 @@ function resolveAnimationDefaultValue(anim) {
37861
37858
  /**
37862
37859
  * @param {THREE.Object3D} modelRoot
37863
37860
  * @param {{ x?: number, y?: number, z?: number }|THREE.Vector3} offset
37861
+ * @param {THREE.Quaternion} [customQuat] - Optional override for model orientation
37864
37862
  * @returns {THREE.Vector3}
37865
37863
  */
37866
- function modelOffsetToWorldDelta(modelRoot, offset) {
37864
+ function modelOffsetToWorldDelta(modelRoot, offset, customQuat) {
37867
37865
  var _offset$x, _offset$y, _offset$z;
37868
37866
  var v = offset instanceof THREE__namespace.Vector3 ? offset.clone() : new THREE__namespace.Vector3((_offset$x = offset === null || offset === void 0 ? void 0 : offset.x) !== null && _offset$x !== void 0 ? _offset$x : 0, (_offset$y = offset === null || offset === void 0 ? void 0 : offset.y) !== null && _offset$y !== void 0 ? _offset$y : 0, (_offset$z = offset === null || offset === void 0 ? void 0 : offset.z) !== null && _offset$z !== void 0 ? _offset$z : 0);
37869
- var q = new THREE__namespace.Quaternion();
37870
- modelRoot.getWorldQuaternion(q);
37867
+ var q = customQuat ? customQuat.clone() : new THREE__namespace.Quaternion();
37868
+ if (!customQuat) modelRoot.getWorldQuaternion(q);
37871
37869
  return v.applyQuaternion(q);
37872
37870
  }
37873
37871
 
@@ -37878,14 +37876,15 @@ function modelOffsetToWorldDelta(modelRoot, offset) {
37878
37876
  * @param {THREE.Object3D} modelRoot
37879
37877
  * @param {THREE.Vector3} origLocalPos
37880
37878
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
37879
+ * @param {THREE.Quaternion} [customQuat]
37881
37880
  */
37882
- function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
37881
+ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset, customQuat) {
37883
37882
  if (!mesh || !modelRoot || !origLocalPos) return;
37884
37883
  mesh.position.copy(origLocalPos);
37885
37884
  mesh.updateMatrixWorld(true);
37886
37885
  var origWorldPos = new THREE__namespace.Vector3();
37887
37886
  mesh.getWorldPosition(origWorldPos);
37888
- var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset));
37887
+ var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
37889
37888
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
37890
37889
  mesh.position.copy(newWorldPos);
37891
37890
  }
@@ -37897,10 +37896,11 @@ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
37897
37896
  * @param {THREE.Object3D} modelRoot
37898
37897
  * @param {THREE.Vector3} baseWorldPos
37899
37898
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
37899
+ * @param {THREE.Quaternion} [customQuat]
37900
37900
  */
37901
- function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset) {
37901
+ function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset, customQuat) {
37902
37902
  if (!mesh || !modelRoot || !baseWorldPos) return;
37903
- var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset));
37903
+ var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
37904
37904
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
37905
37905
  mesh.position.copy(newWorldPos);
37906
37906
  }
@@ -40608,7 +40608,7 @@ var CentralPlantInternals = /*#__PURE__*/function () {
40608
40608
  /**
40609
40609
  * Scene-level behavior helpers: scan endpoints, register behaviors, cross-component links.
40610
40610
  */
40611
- function getComponentDictionary(centralPlant) {
40611
+ function getComponentDictionary$1(centralPlant) {
40612
40612
  var _centralPlant$getUtil, _centralPlant$manager;
40613
40613
  return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || null;
40614
40614
  }
@@ -40639,7 +40639,7 @@ function scanSceneIoEndpoints(centralPlant) {
40639
40639
  var _centralPlant$sceneVi;
40640
40640
  var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi = centralPlant.sceneViewer) === null || _centralPlant$sceneVi === void 0 ? void 0 : _centralPlant$sceneVi.scene;
40641
40641
  if (!scene) return [];
40642
- var dict = getComponentDictionary(centralPlant);
40642
+ var dict = getComponentDictionary$1(centralPlant);
40643
40643
  var endpoints = [];
40644
40644
  scene.traverse(function (obj) {
40645
40645
  var _obj$userData, _parent$userData, _parent$userData2;
@@ -40732,7 +40732,7 @@ function reregisterSceneBehaviors(centralPlant) {
40732
40732
  var _centralPlant$sceneVi4;
40733
40733
  var ioBehavMgr = getIoBehaviorManager(centralPlant === null || centralPlant === void 0 ? void 0 : centralPlant.sceneViewer);
40734
40734
  var scene = centralPlant === null || centralPlant === void 0 || (_centralPlant$sceneVi4 = centralPlant.sceneViewer) === null || _centralPlant$sceneVi4 === void 0 ? void 0 : _centralPlant$sceneVi4.scene;
40735
- var dict = getComponentDictionary(centralPlant);
40735
+ var dict = getComponentDictionary$1(centralPlant);
40736
40736
  if (!ioBehavMgr || !scene) return;
40737
40737
  var crossBehaviors = loadCrossComponentBehaviors(centralPlant);
40738
40738
  ioBehavMgr.setCrossComponentBehaviors(crossBehaviors);
@@ -40774,7 +40774,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
40774
40774
  * Initialize the CentralPlant manager
40775
40775
  *
40776
40776
  * @constructor
40777
- * @version 0.3.42
40777
+ * @version 0.3.44
40778
40778
  * @updated 2025-10-22
40779
40779
  *
40780
40780
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -43266,7 +43266,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
43266
43266
  key: "importScene",
43267
43267
  value: (function () {
43268
43268
  var _importScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10(jsonData) {
43269
- var validation, missingIds, resolved, _t4, _t5;
43269
+ var validation, embeddedCount, missingIds, resolved, _t4, _t5;
43270
43270
  return _regenerator().w(function (_context10) {
43271
43271
  while (1) switch (_context10.n) {
43272
43272
  case 0:
@@ -43287,64 +43287,78 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
43287
43287
  console.error('❌ Invalid scene data format:', validation.message);
43288
43288
  return _context10.a(2, false);
43289
43289
  case 2:
43290
+ if (!(jsonData.componentDefinitions && _typeof(jsonData.componentDefinitions) === 'object')) {
43291
+ _context10.n = 4;
43292
+ break;
43293
+ }
43294
+ embeddedCount = Object.keys(jsonData.componentDefinitions).length;
43295
+ if (!(embeddedCount > 0)) {
43296
+ _context10.n = 4;
43297
+ break;
43298
+ }
43299
+ _context10.n = 3;
43300
+ return this.extendComponentDictionary(jsonData.componentDefinitions);
43301
+ case 3:
43302
+ console.log("\uD83D\uDCE6 importScene(): Applied ".concat(embeddedCount, " embedded component definition(s)"));
43303
+ case 4:
43290
43304
  if (!this._componentDefinitionResolver) {
43291
- _context10.n = 8;
43305
+ _context10.n = 10;
43292
43306
  break;
43293
43307
  }
43294
43308
  missingIds = this.getMissingLibraryIds(jsonData);
43295
43309
  if (!(missingIds.length > 0)) {
43296
- _context10.n = 8;
43310
+ _context10.n = 10;
43297
43311
  break;
43298
43312
  }
43299
- _context10.p = 3;
43313
+ _context10.p = 5;
43300
43314
  console.log("\uD83D\uDD0D importScene(): Resolving ".concat(missingIds.length, " missing component definition(s)..."));
43301
- _context10.n = 4;
43315
+ _context10.n = 6;
43302
43316
  return this._componentDefinitionResolver(missingIds);
43303
- case 4:
43317
+ case 6:
43304
43318
  resolved = _context10.v;
43305
43319
  if (!(resolved && _typeof(resolved) === 'object' && Object.keys(resolved).length > 0)) {
43306
- _context10.n = 6;
43320
+ _context10.n = 8;
43307
43321
  break;
43308
43322
  }
43309
- _context10.n = 5;
43323
+ _context10.n = 7;
43310
43324
  return this.extendComponentDictionary(resolved);
43311
- case 5:
43325
+ case 7:
43312
43326
  console.log("\u2705 importScene(): Resolved ".concat(Object.keys(resolved).length, " component definition(s)"));
43313
- case 6:
43314
- _context10.n = 8;
43327
+ case 8:
43328
+ _context10.n = 10;
43315
43329
  break;
43316
- case 7:
43317
- _context10.p = 7;
43330
+ case 9:
43331
+ _context10.p = 9;
43318
43332
  _t4 = _context10.v;
43319
43333
  console.warn('⚠️ importScene(): Component definition resolver failed, continuing with existing dictionary:', _t4);
43320
- case 8:
43321
- _context10.n = 9;
43334
+ case 10:
43335
+ _context10.n = 11;
43322
43336
  return this.setImportedSceneData(jsonData);
43323
- case 9:
43337
+ case 11:
43324
43338
  if (!(this.sceneViewer && this.sceneViewer.sceneOperationsManager)) {
43325
- _context10.n = 11;
43339
+ _context10.n = 13;
43326
43340
  break;
43327
43341
  }
43328
- _context10.n = 10;
43342
+ _context10.n = 12;
43329
43343
  return this.sceneViewer.sceneOperationsManager.loadSceneFromData(jsonData);
43330
- case 10:
43344
+ case 12:
43331
43345
  console.log('✅ Scene imported successfully');
43332
43346
  return _context10.a(2, true);
43333
- case 11:
43347
+ case 13:
43334
43348
  console.error('❌ SceneViewer not available for scene loading');
43335
43349
  return _context10.a(2, false);
43336
- case 12:
43337
- _context10.n = 14;
43350
+ case 14:
43351
+ _context10.n = 16;
43338
43352
  break;
43339
- case 13:
43340
- _context10.p = 13;
43353
+ case 15:
43354
+ _context10.p = 15;
43341
43355
  _t5 = _context10.v;
43342
43356
  console.error('❌ Error importing scene:', _t5);
43343
43357
  return _context10.a(2, false);
43344
- case 14:
43358
+ case 16:
43345
43359
  return _context10.a(2);
43346
43360
  }
43347
- }, _callee10, this, [[3, 7], [1, 13]]);
43361
+ }, _callee10, this, [[5, 9], [1, 15]]);
43348
43362
  }));
43349
43363
  function importScene(_x6) {
43350
43364
  return _importScene.apply(this, arguments);
@@ -44982,6 +44996,88 @@ var SceneHierarchyManager = /*#__PURE__*/function (_BaseDisposable) {
44982
44996
  }]);
44983
44997
  }(BaseDisposable);
44984
44998
 
44999
+ var _excluded = ["componentDefinitions"];
45000
+ /**
45001
+ * Helpers for portable demo scene JSON (embedded component definitions).
45002
+ */
45003
+
45004
+ function cloneDefinition(def) {
45005
+ if (!def || _typeof(def) !== 'object') return null;
45006
+ try {
45007
+ return JSON.parse(JSON.stringify(def));
45008
+ } catch (_unused) {
45009
+ return _objectSpread2({}, def);
45010
+ }
45011
+ }
45012
+
45013
+ /**
45014
+ * Collect unique library IDs referenced by scene nodes.
45015
+ * @param {Object} sceneData
45016
+ * @returns {string[]}
45017
+ */
45018
+ function collectSceneLibraryIds(sceneData) {
45019
+ var _sceneData$scene;
45020
+ var ids = new Set();
45021
+ var _walk = function walk(nodes) {
45022
+ if (!Array.isArray(nodes)) return;
45023
+ nodes.forEach(function (node) {
45024
+ var _node$userData;
45025
+ var libraryId = node === null || node === void 0 || (_node$userData = node.userData) === null || _node$userData === void 0 ? void 0 : _node$userData.libraryId;
45026
+ if (libraryId) ids.add(libraryId);
45027
+ if (node.children) _walk(node.children);
45028
+ });
45029
+ };
45030
+ _walk(sceneData === null || sceneData === void 0 || (_sceneData$scene = sceneData.scene) === null || _sceneData$scene === void 0 ? void 0 : _sceneData$scene.children);
45031
+ return Array.from(ids);
45032
+ }
45033
+
45034
+ /**
45035
+ * Embed component/device definitions required by a scene into the JSON payload.
45036
+ * @param {Object} sceneData
45037
+ * @param {Record<string, Object>} componentDictionary
45038
+ * @returns {Object}
45039
+ */
45040
+ function embedComponentDefinitions(sceneData) {
45041
+ var componentDictionary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
45042
+ if (!sceneData || _typeof(sceneData) !== 'object') return sceneData;
45043
+ var libraryIds = collectSceneLibraryIds(sceneData);
45044
+ var componentDefinitions = {};
45045
+ var deviceIds = new Set();
45046
+ libraryIds.forEach(function (libraryId) {
45047
+ var def = componentDictionary[libraryId];
45048
+ if (!def) return;
45049
+ componentDefinitions[libraryId] = cloneDefinition(def);
45050
+ var attachedDevices = def.attachedDevices;
45051
+ if (!attachedDevices || _typeof(attachedDevices) !== 'object') return;
45052
+ Object.values(attachedDevices).forEach(function (att) {
45053
+ if (att !== null && att !== void 0 && att.deviceId) deviceIds.add(att.deviceId);
45054
+ });
45055
+ });
45056
+ deviceIds.forEach(function (deviceId) {
45057
+ if (componentDefinitions[deviceId]) return;
45058
+ var deviceDef = componentDictionary[deviceId];
45059
+ if (deviceDef) componentDefinitions[deviceId] = cloneDefinition(deviceDef);
45060
+ });
45061
+ if (!Object.keys(componentDefinitions).length) {
45062
+ sceneData.componentDefinitions;
45063
+ var rest = _objectWithoutProperties(sceneData, _excluded);
45064
+ return rest;
45065
+ }
45066
+ return _objectSpread2(_objectSpread2({}, sceneData), {}, {
45067
+ componentDefinitions: componentDefinitions
45068
+ });
45069
+ }
45070
+
45071
+ /**
45072
+ * Resolve the live component dictionary from a CentralPlant instance.
45073
+ * @param {Object} centralPlant
45074
+ * @returns {Record<string, Object>}
45075
+ */
45076
+ function getComponentDictionary(centralPlant) {
45077
+ var _centralPlant$getUtil, _centralPlant$manager;
45078
+ return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || {};
45079
+ }
45080
+
44985
45081
  /**
44986
45082
  * Generic Cache Management using Browser Cache API
44987
45083
  * Framework-agnostic implementation of caching logic
@@ -49462,8 +49558,10 @@ exports.cacheManager = cacheManager;
49462
49558
  exports.cleanExpiredCache = cleanExpiredCache;
49463
49559
  exports.cleanInvalidCacheEntries = cleanInvalidCacheEntries;
49464
49560
  exports.clearS3Cache = clearS3Cache;
49561
+ exports.collectSceneLibraryIds = collectSceneLibraryIds;
49465
49562
  exports.createPathfindingRequest = createPathfindingRequest;
49466
49563
  exports.createTransformControls = createTransformControls;
49564
+ exports.embedComponentDefinitions = embedComponentDefinitions;
49467
49565
  exports.findObjectByHardcodedUuid = findObjectByHardcodedUuid;
49468
49566
  exports.formatCacheExpiry = formatCacheExpiry;
49469
49567
  exports.generateUniqueComponentId = generateUniqueComponentId;
@@ -49478,6 +49576,7 @@ exports.getCachedLocalJson = getCachedLocalJson;
49478
49576
  exports.getCachedS3Json = getCachedS3Json;
49479
49577
  exports.getCachedS3Object = getCachedS3Object;
49480
49578
  exports.getCachedS3ObjectURL = getCachedS3ObjectURL;
49579
+ exports.getComponentDictionary = getComponentDictionary;
49481
49580
  exports.getCurrentCacheName = getCurrentCacheName;
49482
49581
  exports.getGlobalCacheStats = getGlobalCacheStats;
49483
49582
  exports.getGlobalOnlyCacheStats = getGlobalOnlyCacheStats;
@@ -37,7 +37,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
37
37
  * Initialize the CentralPlant manager
38
38
  *
39
39
  * @constructor
40
- * @version 0.3.42
40
+ * @version 0.3.44
41
41
  * @updated 2025-10-22
42
42
  *
43
43
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -2529,7 +2529,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2529
2529
  key: "importScene",
2530
2530
  value: (function () {
2531
2531
  var _importScene = _rollupPluginBabelHelpers.asyncToGenerator(/*#__PURE__*/_rollupPluginBabelHelpers.regenerator().m(function _callee10(jsonData) {
2532
- var validation, missingIds, resolved, _t4, _t5;
2532
+ var validation, embeddedCount, missingIds, resolved, _t4, _t5;
2533
2533
  return _rollupPluginBabelHelpers.regenerator().w(function (_context10) {
2534
2534
  while (1) switch (_context10.n) {
2535
2535
  case 0:
@@ -2550,64 +2550,78 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2550
2550
  console.error('❌ Invalid scene data format:', validation.message);
2551
2551
  return _context10.a(2, false);
2552
2552
  case 2:
2553
+ if (!(jsonData.componentDefinitions && _rollupPluginBabelHelpers["typeof"](jsonData.componentDefinitions) === 'object')) {
2554
+ _context10.n = 4;
2555
+ break;
2556
+ }
2557
+ embeddedCount = Object.keys(jsonData.componentDefinitions).length;
2558
+ if (!(embeddedCount > 0)) {
2559
+ _context10.n = 4;
2560
+ break;
2561
+ }
2562
+ _context10.n = 3;
2563
+ return this.extendComponentDictionary(jsonData.componentDefinitions);
2564
+ case 3:
2565
+ console.log("\uD83D\uDCE6 importScene(): Applied ".concat(embeddedCount, " embedded component definition(s)"));
2566
+ case 4:
2553
2567
  if (!this._componentDefinitionResolver) {
2554
- _context10.n = 8;
2568
+ _context10.n = 10;
2555
2569
  break;
2556
2570
  }
2557
2571
  missingIds = this.getMissingLibraryIds(jsonData);
2558
2572
  if (!(missingIds.length > 0)) {
2559
- _context10.n = 8;
2573
+ _context10.n = 10;
2560
2574
  break;
2561
2575
  }
2562
- _context10.p = 3;
2576
+ _context10.p = 5;
2563
2577
  console.log("\uD83D\uDD0D importScene(): Resolving ".concat(missingIds.length, " missing component definition(s)..."));
2564
- _context10.n = 4;
2578
+ _context10.n = 6;
2565
2579
  return this._componentDefinitionResolver(missingIds);
2566
- case 4:
2580
+ case 6:
2567
2581
  resolved = _context10.v;
2568
2582
  if (!(resolved && _rollupPluginBabelHelpers["typeof"](resolved) === 'object' && Object.keys(resolved).length > 0)) {
2569
- _context10.n = 6;
2583
+ _context10.n = 8;
2570
2584
  break;
2571
2585
  }
2572
- _context10.n = 5;
2586
+ _context10.n = 7;
2573
2587
  return this.extendComponentDictionary(resolved);
2574
- case 5:
2588
+ case 7:
2575
2589
  console.log("\u2705 importScene(): Resolved ".concat(Object.keys(resolved).length, " component definition(s)"));
2576
- case 6:
2577
- _context10.n = 8;
2590
+ case 8:
2591
+ _context10.n = 10;
2578
2592
  break;
2579
- case 7:
2580
- _context10.p = 7;
2593
+ case 9:
2594
+ _context10.p = 9;
2581
2595
  _t4 = _context10.v;
2582
2596
  console.warn('⚠️ importScene(): Component definition resolver failed, continuing with existing dictionary:', _t4);
2583
- case 8:
2584
- _context10.n = 9;
2597
+ case 10:
2598
+ _context10.n = 11;
2585
2599
  return this.setImportedSceneData(jsonData);
2586
- case 9:
2600
+ case 11:
2587
2601
  if (!(this.sceneViewer && this.sceneViewer.sceneOperationsManager)) {
2588
- _context10.n = 11;
2602
+ _context10.n = 13;
2589
2603
  break;
2590
2604
  }
2591
- _context10.n = 10;
2605
+ _context10.n = 12;
2592
2606
  return this.sceneViewer.sceneOperationsManager.loadSceneFromData(jsonData);
2593
- case 10:
2607
+ case 12:
2594
2608
  console.log('✅ Scene imported successfully');
2595
2609
  return _context10.a(2, true);
2596
- case 11:
2610
+ case 13:
2597
2611
  console.error('❌ SceneViewer not available for scene loading');
2598
2612
  return _context10.a(2, false);
2599
- case 12:
2600
- _context10.n = 14;
2613
+ case 14:
2614
+ _context10.n = 16;
2601
2615
  break;
2602
- case 13:
2603
- _context10.p = 13;
2616
+ case 15:
2617
+ _context10.p = 15;
2604
2618
  _t5 = _context10.v;
2605
2619
  console.error('❌ Error importing scene:', _t5);
2606
2620
  return _context10.a(2, false);
2607
- case 14:
2621
+ case 16:
2608
2622
  return _context10.a(2);
2609
2623
  }
2610
- }, _callee10, this, [[3, 7], [1, 13]]);
2624
+ }, _callee10, this, [[5, 9], [1, 15]]);
2611
2625
  }));
2612
2626
  function importScene(_x6) {
2613
2627
  return _importScene.apply(this, arguments);
@@ -18,6 +18,7 @@ var behaviorSchema = require('./utils/behaviorSchema.js');
18
18
  var behaviorRegistration = require('./utils/behaviorRegistration.js');
19
19
  var behaviorDispatch = require('./utils/behaviorDispatch.js');
20
20
  var behaviorSceneUtils = require('./utils/behaviorSceneUtils.js');
21
+ var demoSceneUtils = require('./utils/demoSceneUtils.js');
21
22
  var animationTransformUtils = require('./utils/animationTransformUtils.js');
22
23
  var componentManager = require('./managers/components/componentManager.js');
23
24
  var animationManager = require('./managers/scene/animationManager.js');
@@ -90,6 +91,9 @@ exports.loadCrossComponentBehaviors = behaviorSceneUtils.loadCrossComponentBehav
90
91
  exports.refreshSceneIntraBehaviors = behaviorSceneUtils.refreshSceneIntraBehaviors;
91
92
  exports.reregisterSceneBehaviors = behaviorSceneUtils.reregisterSceneBehaviors;
92
93
  exports.scanSceneIoEndpoints = behaviorSceneUtils.scanSceneIoEndpoints;
94
+ exports.collectSceneLibraryIds = demoSceneUtils.collectSceneLibraryIds;
95
+ exports.embedComponentDefinitions = demoSceneUtils.embedComponentDefinitions;
96
+ exports.getComponentDictionary = demoSceneUtils.getComponentDictionary;
93
97
  exports.applyModelRootTranslation = animationTransformUtils.applyModelRootTranslation;
94
98
  exports.applyModelRootTranslationFromWorldBase = animationTransformUtils.applyModelRootTranslationFromWorldBase;
95
99
  exports.modelOffsetToWorldDelta = animationTransformUtils.modelOffsetToWorldDelta;
@@ -514,8 +514,8 @@ var transformControls = /*#__PURE__*/function (_THREE$Object3D) {
514
514
  }, {
515
515
  key: "setMode",
516
516
  value: function setMode(mode) {
517
- if (mode === 'scale') {
518
- console.warn('transformControls: Scale mode has been removed. Using translate mode instead.');
517
+ if (mode !== 'translate') {
518
+ console.warn("transformControls: ".concat(mode, " mode is disabled. Locking to translate."));
519
519
  mode = 'translate';
520
520
  }
521
521
  this.mode = mode;
@@ -439,10 +439,6 @@ var TransformControlsManager = /*#__PURE__*/function () {
439
439
  // Translate mode
440
440
  _this3.setMode('translate');
441
441
  break;
442
- case 'KeyR':
443
- // Rotate mode
444
- _this3.setMode('rotate');
445
- break;
446
442
  }
447
443
  };
448
444
  window.addEventListener('keydown', this.eventHandlers.keydown);
@@ -1462,9 +1458,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
1462
1458
  }, {
1463
1459
  key: "setMode",
1464
1460
  value: function setMode(mode) {
1465
- if (!['translate', 'rotate', 'scale'].includes(mode)) {
1466
- console.warn("\u26A0\uFE0F Invalid transform mode: ".concat(mode));
1467
- return;
1461
+ // Only allow translate mode - lock rotation and scale controls
1462
+ if (mode !== 'translate') {
1463
+ console.warn("\u26A0\uFE0F Transform mode ".concat(mode, " is disabled. Locking to translate."));
1464
+ mode = 'translate';
1468
1465
  }
1469
1466
  var previousMode = this.currentMode;
1470
1467
  this.currentMode = mode;
@@ -33,13 +33,14 @@ var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
33
33
  /**
34
34
  * @param {THREE.Object3D} modelRoot
35
35
  * @param {{ x?: number, y?: number, z?: number }|THREE.Vector3} offset
36
+ * @param {THREE.Quaternion} [customQuat] - Optional override for model orientation
36
37
  * @returns {THREE.Vector3}
37
38
  */
38
- function modelOffsetToWorldDelta(modelRoot, offset) {
39
+ function modelOffsetToWorldDelta(modelRoot, offset, customQuat) {
39
40
  var _offset$x, _offset$y, _offset$z;
40
41
  var v = offset instanceof THREE__namespace.Vector3 ? offset.clone() : new THREE__namespace.Vector3((_offset$x = offset === null || offset === void 0 ? void 0 : offset.x) !== null && _offset$x !== void 0 ? _offset$x : 0, (_offset$y = offset === null || offset === void 0 ? void 0 : offset.y) !== null && _offset$y !== void 0 ? _offset$y : 0, (_offset$z = offset === null || offset === void 0 ? void 0 : offset.z) !== null && _offset$z !== void 0 ? _offset$z : 0);
41
- var q = new THREE__namespace.Quaternion();
42
- modelRoot.getWorldQuaternion(q);
42
+ var q = customQuat ? customQuat.clone() : new THREE__namespace.Quaternion();
43
+ if (!customQuat) modelRoot.getWorldQuaternion(q);
43
44
  return v.applyQuaternion(q);
44
45
  }
45
46
 
@@ -50,14 +51,15 @@ function modelOffsetToWorldDelta(modelRoot, offset) {
50
51
  * @param {THREE.Object3D} modelRoot
51
52
  * @param {THREE.Vector3} origLocalPos
52
53
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
54
+ * @param {THREE.Quaternion} [customQuat]
53
55
  */
54
- function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
56
+ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset, customQuat) {
55
57
  if (!mesh || !modelRoot || !origLocalPos) return;
56
58
  mesh.position.copy(origLocalPos);
57
59
  mesh.updateMatrixWorld(true);
58
60
  var origWorldPos = new THREE__namespace.Vector3();
59
61
  mesh.getWorldPosition(origWorldPos);
60
- var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset));
62
+ var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
61
63
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
62
64
  mesh.position.copy(newWorldPos);
63
65
  }
@@ -69,10 +71,11 @@ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
69
71
  * @param {THREE.Object3D} modelRoot
70
72
  * @param {THREE.Vector3} baseWorldPos
71
73
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
74
+ * @param {THREE.Quaternion} [customQuat]
72
75
  */
73
- function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset) {
76
+ function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset, customQuat) {
74
77
  if (!mesh || !modelRoot || !baseWorldPos) return;
75
- var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset));
78
+ var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
76
79
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
77
80
  mesh.position.copy(newWorldPos);
78
81
  }
@@ -0,0 +1,91 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
6
+
7
+ var _excluded = ["componentDefinitions"];
8
+ /**
9
+ * Helpers for portable demo scene JSON (embedded component definitions).
10
+ */
11
+
12
+ function cloneDefinition(def) {
13
+ if (!def || _rollupPluginBabelHelpers["typeof"](def) !== 'object') return null;
14
+ try {
15
+ return JSON.parse(JSON.stringify(def));
16
+ } catch (_unused) {
17
+ return _rollupPluginBabelHelpers.objectSpread2({}, def);
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Collect unique library IDs referenced by scene nodes.
23
+ * @param {Object} sceneData
24
+ * @returns {string[]}
25
+ */
26
+ function collectSceneLibraryIds(sceneData) {
27
+ var _sceneData$scene;
28
+ var ids = new Set();
29
+ var _walk = function walk(nodes) {
30
+ if (!Array.isArray(nodes)) return;
31
+ nodes.forEach(function (node) {
32
+ var _node$userData;
33
+ var libraryId = node === null || node === void 0 || (_node$userData = node.userData) === null || _node$userData === void 0 ? void 0 : _node$userData.libraryId;
34
+ if (libraryId) ids.add(libraryId);
35
+ if (node.children) _walk(node.children);
36
+ });
37
+ };
38
+ _walk(sceneData === null || sceneData === void 0 || (_sceneData$scene = sceneData.scene) === null || _sceneData$scene === void 0 ? void 0 : _sceneData$scene.children);
39
+ return Array.from(ids);
40
+ }
41
+
42
+ /**
43
+ * Embed component/device definitions required by a scene into the JSON payload.
44
+ * @param {Object} sceneData
45
+ * @param {Record<string, Object>} componentDictionary
46
+ * @returns {Object}
47
+ */
48
+ function embedComponentDefinitions(sceneData) {
49
+ var componentDictionary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
50
+ if (!sceneData || _rollupPluginBabelHelpers["typeof"](sceneData) !== 'object') return sceneData;
51
+ var libraryIds = collectSceneLibraryIds(sceneData);
52
+ var componentDefinitions = {};
53
+ var deviceIds = new Set();
54
+ libraryIds.forEach(function (libraryId) {
55
+ var def = componentDictionary[libraryId];
56
+ if (!def) return;
57
+ componentDefinitions[libraryId] = cloneDefinition(def);
58
+ var attachedDevices = def.attachedDevices;
59
+ if (!attachedDevices || _rollupPluginBabelHelpers["typeof"](attachedDevices) !== 'object') return;
60
+ Object.values(attachedDevices).forEach(function (att) {
61
+ if (att !== null && att !== void 0 && att.deviceId) deviceIds.add(att.deviceId);
62
+ });
63
+ });
64
+ deviceIds.forEach(function (deviceId) {
65
+ if (componentDefinitions[deviceId]) return;
66
+ var deviceDef = componentDictionary[deviceId];
67
+ if (deviceDef) componentDefinitions[deviceId] = cloneDefinition(deviceDef);
68
+ });
69
+ if (!Object.keys(componentDefinitions).length) {
70
+ sceneData.componentDefinitions;
71
+ var rest = _rollupPluginBabelHelpers.objectWithoutProperties(sceneData, _excluded);
72
+ return rest;
73
+ }
74
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, sceneData), {}, {
75
+ componentDefinitions: componentDefinitions
76
+ });
77
+ }
78
+
79
+ /**
80
+ * Resolve the live component dictionary from a CentralPlant instance.
81
+ * @param {Object} centralPlant
82
+ * @returns {Record<string, Object>}
83
+ */
84
+ function getComponentDictionary(centralPlant) {
85
+ var _centralPlant$getUtil, _centralPlant$manager;
86
+ return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || {};
87
+ }
88
+
89
+ exports.collectSceneLibraryIds = collectSceneLibraryIds;
90
+ exports.embedComponentDefinitions = embedComponentDefinitions;
91
+ exports.getComponentDictionary = getComponentDictionary;
@@ -33,7 +33,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
33
33
  * Initialize the CentralPlant manager
34
34
  *
35
35
  * @constructor
36
- * @version 0.3.42
36
+ * @version 0.3.44
37
37
  * @updated 2025-10-22
38
38
  *
39
39
  * @description Creates a new CentralPlant instance and initializes internal managers and utilities.
@@ -2525,7 +2525,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2525
2525
  key: "importScene",
2526
2526
  value: (function () {
2527
2527
  var _importScene = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee10(jsonData) {
2528
- var validation, missingIds, resolved, _t4, _t5;
2528
+ var validation, embeddedCount, missingIds, resolved, _t4, _t5;
2529
2529
  return _regenerator().w(function (_context10) {
2530
2530
  while (1) switch (_context10.n) {
2531
2531
  case 0:
@@ -2546,64 +2546,78 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
2546
2546
  console.error('❌ Invalid scene data format:', validation.message);
2547
2547
  return _context10.a(2, false);
2548
2548
  case 2:
2549
+ if (!(jsonData.componentDefinitions && _typeof(jsonData.componentDefinitions) === 'object')) {
2550
+ _context10.n = 4;
2551
+ break;
2552
+ }
2553
+ embeddedCount = Object.keys(jsonData.componentDefinitions).length;
2554
+ if (!(embeddedCount > 0)) {
2555
+ _context10.n = 4;
2556
+ break;
2557
+ }
2558
+ _context10.n = 3;
2559
+ return this.extendComponentDictionary(jsonData.componentDefinitions);
2560
+ case 3:
2561
+ console.log("\uD83D\uDCE6 importScene(): Applied ".concat(embeddedCount, " embedded component definition(s)"));
2562
+ case 4:
2549
2563
  if (!this._componentDefinitionResolver) {
2550
- _context10.n = 8;
2564
+ _context10.n = 10;
2551
2565
  break;
2552
2566
  }
2553
2567
  missingIds = this.getMissingLibraryIds(jsonData);
2554
2568
  if (!(missingIds.length > 0)) {
2555
- _context10.n = 8;
2569
+ _context10.n = 10;
2556
2570
  break;
2557
2571
  }
2558
- _context10.p = 3;
2572
+ _context10.p = 5;
2559
2573
  console.log("\uD83D\uDD0D importScene(): Resolving ".concat(missingIds.length, " missing component definition(s)..."));
2560
- _context10.n = 4;
2574
+ _context10.n = 6;
2561
2575
  return this._componentDefinitionResolver(missingIds);
2562
- case 4:
2576
+ case 6:
2563
2577
  resolved = _context10.v;
2564
2578
  if (!(resolved && _typeof(resolved) === 'object' && Object.keys(resolved).length > 0)) {
2565
- _context10.n = 6;
2579
+ _context10.n = 8;
2566
2580
  break;
2567
2581
  }
2568
- _context10.n = 5;
2582
+ _context10.n = 7;
2569
2583
  return this.extendComponentDictionary(resolved);
2570
- case 5:
2584
+ case 7:
2571
2585
  console.log("\u2705 importScene(): Resolved ".concat(Object.keys(resolved).length, " component definition(s)"));
2572
- case 6:
2573
- _context10.n = 8;
2586
+ case 8:
2587
+ _context10.n = 10;
2574
2588
  break;
2575
- case 7:
2576
- _context10.p = 7;
2589
+ case 9:
2590
+ _context10.p = 9;
2577
2591
  _t4 = _context10.v;
2578
2592
  console.warn('⚠️ importScene(): Component definition resolver failed, continuing with existing dictionary:', _t4);
2579
- case 8:
2580
- _context10.n = 9;
2593
+ case 10:
2594
+ _context10.n = 11;
2581
2595
  return this.setImportedSceneData(jsonData);
2582
- case 9:
2596
+ case 11:
2583
2597
  if (!(this.sceneViewer && this.sceneViewer.sceneOperationsManager)) {
2584
- _context10.n = 11;
2598
+ _context10.n = 13;
2585
2599
  break;
2586
2600
  }
2587
- _context10.n = 10;
2601
+ _context10.n = 12;
2588
2602
  return this.sceneViewer.sceneOperationsManager.loadSceneFromData(jsonData);
2589
- case 10:
2603
+ case 12:
2590
2604
  console.log('✅ Scene imported successfully');
2591
2605
  return _context10.a(2, true);
2592
- case 11:
2606
+ case 13:
2593
2607
  console.error('❌ SceneViewer not available for scene loading');
2594
2608
  return _context10.a(2, false);
2595
- case 12:
2596
- _context10.n = 14;
2609
+ case 14:
2610
+ _context10.n = 16;
2597
2611
  break;
2598
- case 13:
2599
- _context10.p = 13;
2612
+ case 15:
2613
+ _context10.p = 15;
2600
2614
  _t5 = _context10.v;
2601
2615
  console.error('❌ Error importing scene:', _t5);
2602
2616
  return _context10.a(2, false);
2603
- case 14:
2617
+ case 16:
2604
2618
  return _context10.a(2);
2605
2619
  }
2606
- }, _callee10, this, [[3, 7], [1, 13]]);
2620
+ }, _callee10, this, [[5, 9], [1, 15]]);
2607
2621
  }));
2608
2622
  function importScene(_x6) {
2609
2623
  return _importScene.apply(this, arguments);
@@ -14,6 +14,7 @@ export { buildCrossBehavior, buildIntraBehavior, normalizeBehavior, parseCrossBe
14
14
  export { registerBehaviorsForComponent, reloadBehaviorsForDeviceAsset } from './utils/behaviorRegistration.js';
15
15
  export { applyDefaultIoDeviceStates, getIoBehaviorManager, getScopedAttachmentKey, resolveDataPoints } from './utils/behaviorDispatch.js';
16
16
  export { applyCrossComponentBehaviors, loadCrossComponentBehaviors, refreshSceneIntraBehaviors, reregisterSceneBehaviors, scanSceneIoEndpoints } from './utils/behaviorSceneUtils.js';
17
+ export { collectSceneLibraryIds, embedComponentDefinitions, getComponentDictionary } from './utils/demoSceneUtils.js';
17
18
  export { applyModelRootTranslation, applyModelRootTranslationFromWorldBase, modelOffsetToWorldDelta } from './utils/animationTransformUtils.js';
18
19
  export { ComponentManager } from './managers/components/componentManager.js';
19
20
  export { AnimationManager } from './managers/scene/animationManager.js';
@@ -490,8 +490,8 @@ var transformControls = /*#__PURE__*/function (_THREE$Object3D) {
490
490
  }, {
491
491
  key: "setMode",
492
492
  value: function setMode(mode) {
493
- if (mode === 'scale') {
494
- console.warn('transformControls: Scale mode has been removed. Using translate mode instead.');
493
+ if (mode !== 'translate') {
494
+ console.warn("transformControls: ".concat(mode, " mode is disabled. Locking to translate."));
495
495
  mode = 'translate';
496
496
  }
497
497
  this.mode = mode;
@@ -415,10 +415,6 @@ var TransformControlsManager = /*#__PURE__*/function () {
415
415
  // Translate mode
416
416
  _this3.setMode('translate');
417
417
  break;
418
- case 'KeyR':
419
- // Rotate mode
420
- _this3.setMode('rotate');
421
- break;
422
418
  }
423
419
  };
424
420
  window.addEventListener('keydown', this.eventHandlers.keydown);
@@ -1438,9 +1434,10 @@ var TransformControlsManager = /*#__PURE__*/function () {
1438
1434
  }, {
1439
1435
  key: "setMode",
1440
1436
  value: function setMode(mode) {
1441
- if (!['translate', 'rotate', 'scale'].includes(mode)) {
1442
- console.warn("\u26A0\uFE0F Invalid transform mode: ".concat(mode));
1443
- return;
1437
+ // Only allow translate mode - lock rotation and scale controls
1438
+ if (mode !== 'translate') {
1439
+ console.warn("\u26A0\uFE0F Transform mode ".concat(mode, " is disabled. Locking to translate."));
1440
+ mode = 'translate';
1444
1441
  }
1445
1442
  var previousMode = this.currentMode;
1446
1443
  this.currentMode = mode;
@@ -9,13 +9,14 @@ import * as THREE from 'three';
9
9
  /**
10
10
  * @param {THREE.Object3D} modelRoot
11
11
  * @param {{ x?: number, y?: number, z?: number }|THREE.Vector3} offset
12
+ * @param {THREE.Quaternion} [customQuat] - Optional override for model orientation
12
13
  * @returns {THREE.Vector3}
13
14
  */
14
- function modelOffsetToWorldDelta(modelRoot, offset) {
15
+ function modelOffsetToWorldDelta(modelRoot, offset, customQuat) {
15
16
  var _offset$x, _offset$y, _offset$z;
16
17
  var v = offset instanceof THREE.Vector3 ? offset.clone() : new THREE.Vector3((_offset$x = offset === null || offset === void 0 ? void 0 : offset.x) !== null && _offset$x !== void 0 ? _offset$x : 0, (_offset$y = offset === null || offset === void 0 ? void 0 : offset.y) !== null && _offset$y !== void 0 ? _offset$y : 0, (_offset$z = offset === null || offset === void 0 ? void 0 : offset.z) !== null && _offset$z !== void 0 ? _offset$z : 0);
17
- var q = new THREE.Quaternion();
18
- modelRoot.getWorldQuaternion(q);
18
+ var q = customQuat ? customQuat.clone() : new THREE.Quaternion();
19
+ if (!customQuat) modelRoot.getWorldQuaternion(q);
19
20
  return v.applyQuaternion(q);
20
21
  }
21
22
 
@@ -26,14 +27,15 @@ function modelOffsetToWorldDelta(modelRoot, offset) {
26
27
  * @param {THREE.Object3D} modelRoot
27
28
  * @param {THREE.Vector3} origLocalPos
28
29
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
30
+ * @param {THREE.Quaternion} [customQuat]
29
31
  */
30
- function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
32
+ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset, customQuat) {
31
33
  if (!mesh || !modelRoot || !origLocalPos) return;
32
34
  mesh.position.copy(origLocalPos);
33
35
  mesh.updateMatrixWorld(true);
34
36
  var origWorldPos = new THREE.Vector3();
35
37
  mesh.getWorldPosition(origWorldPos);
36
- var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset));
38
+ var newWorldPos = origWorldPos.add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
37
39
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
38
40
  mesh.position.copy(newWorldPos);
39
41
  }
@@ -45,10 +47,11 @@ function applyModelRootTranslation(mesh, modelRoot, origLocalPos, modelOffset) {
45
47
  * @param {THREE.Object3D} modelRoot
46
48
  * @param {THREE.Vector3} baseWorldPos
47
49
  * @param {{ x?: number, y?: number, z?: number }} modelOffset
50
+ * @param {THREE.Quaternion} [customQuat]
48
51
  */
49
- function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset) {
52
+ function applyModelRootTranslationFromWorldBase(mesh, modelRoot, baseWorldPos, modelOffset, customQuat) {
50
53
  if (!mesh || !modelRoot || !baseWorldPos) return;
51
- var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset));
54
+ var newWorldPos = baseWorldPos.clone().add(modelOffsetToWorldDelta(modelRoot, modelOffset, customQuat));
52
55
  if (mesh.parent) mesh.parent.worldToLocal(newWorldPos);
53
56
  mesh.position.copy(newWorldPos);
54
57
  }
@@ -0,0 +1,85 @@
1
+ import { typeof as _typeof, objectWithoutProperties as _objectWithoutProperties, objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
2
+
3
+ var _excluded = ["componentDefinitions"];
4
+ /**
5
+ * Helpers for portable demo scene JSON (embedded component definitions).
6
+ */
7
+
8
+ function cloneDefinition(def) {
9
+ if (!def || _typeof(def) !== 'object') return null;
10
+ try {
11
+ return JSON.parse(JSON.stringify(def));
12
+ } catch (_unused) {
13
+ return _objectSpread2({}, def);
14
+ }
15
+ }
16
+
17
+ /**
18
+ * Collect unique library IDs referenced by scene nodes.
19
+ * @param {Object} sceneData
20
+ * @returns {string[]}
21
+ */
22
+ function collectSceneLibraryIds(sceneData) {
23
+ var _sceneData$scene;
24
+ var ids = new Set();
25
+ var _walk = function walk(nodes) {
26
+ if (!Array.isArray(nodes)) return;
27
+ nodes.forEach(function (node) {
28
+ var _node$userData;
29
+ var libraryId = node === null || node === void 0 || (_node$userData = node.userData) === null || _node$userData === void 0 ? void 0 : _node$userData.libraryId;
30
+ if (libraryId) ids.add(libraryId);
31
+ if (node.children) _walk(node.children);
32
+ });
33
+ };
34
+ _walk(sceneData === null || sceneData === void 0 || (_sceneData$scene = sceneData.scene) === null || _sceneData$scene === void 0 ? void 0 : _sceneData$scene.children);
35
+ return Array.from(ids);
36
+ }
37
+
38
+ /**
39
+ * Embed component/device definitions required by a scene into the JSON payload.
40
+ * @param {Object} sceneData
41
+ * @param {Record<string, Object>} componentDictionary
42
+ * @returns {Object}
43
+ */
44
+ function embedComponentDefinitions(sceneData) {
45
+ var componentDictionary = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
46
+ if (!sceneData || _typeof(sceneData) !== 'object') return sceneData;
47
+ var libraryIds = collectSceneLibraryIds(sceneData);
48
+ var componentDefinitions = {};
49
+ var deviceIds = new Set();
50
+ libraryIds.forEach(function (libraryId) {
51
+ var def = componentDictionary[libraryId];
52
+ if (!def) return;
53
+ componentDefinitions[libraryId] = cloneDefinition(def);
54
+ var attachedDevices = def.attachedDevices;
55
+ if (!attachedDevices || _typeof(attachedDevices) !== 'object') return;
56
+ Object.values(attachedDevices).forEach(function (att) {
57
+ if (att !== null && att !== void 0 && att.deviceId) deviceIds.add(att.deviceId);
58
+ });
59
+ });
60
+ deviceIds.forEach(function (deviceId) {
61
+ if (componentDefinitions[deviceId]) return;
62
+ var deviceDef = componentDictionary[deviceId];
63
+ if (deviceDef) componentDefinitions[deviceId] = cloneDefinition(deviceDef);
64
+ });
65
+ if (!Object.keys(componentDefinitions).length) {
66
+ sceneData.componentDefinitions;
67
+ var rest = _objectWithoutProperties(sceneData, _excluded);
68
+ return rest;
69
+ }
70
+ return _objectSpread2(_objectSpread2({}, sceneData), {}, {
71
+ componentDefinitions: componentDefinitions
72
+ });
73
+ }
74
+
75
+ /**
76
+ * Resolve the live component dictionary from a CentralPlant instance.
77
+ * @param {Object} centralPlant
78
+ * @returns {Record<string, Object>}
79
+ */
80
+ function getComponentDictionary(centralPlant) {
81
+ var _centralPlant$getUtil, _centralPlant$manager;
82
+ return (centralPlant === null || centralPlant === void 0 || (_centralPlant$getUtil = centralPlant.getUtility) === null || _centralPlant$getUtil === void 0 || (_centralPlant$getUtil = _centralPlant$getUtil.call(centralPlant, 'modelPreloader')) === null || _centralPlant$getUtil === void 0 ? void 0 : _centralPlant$getUtil.componentDictionary) || (centralPlant === null || centralPlant === void 0 || (_centralPlant$manager = centralPlant.managers) === null || _centralPlant$manager === void 0 || (_centralPlant$manager = _centralPlant$manager.componentDataManager) === null || _centralPlant$manager === void 0 ? void 0 : _centralPlant$manager.componentDictionary) || {};
83
+ }
84
+
85
+ export { collectSceneLibraryIds, embedComponentDefinitions, getComponentDictionary };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2112-lab/central-plant",
3
- "version": "0.3.42",
3
+ "version": "0.3.44",
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",