@2112-lab/central-plant 0.1.4 → 0.1.5

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.
Files changed (87) hide show
  1. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +432 -1
  2. package/dist/cjs/node_modules/@2112-lab/pathfinder/dist/index.esm.js +1448 -1
  3. package/dist/cjs/node_modules/three/examples/jsm/controls/OrbitControls.js +1853 -1
  4. package/dist/cjs/node_modules/three/examples/jsm/exporters/GLTFExporter.js +3537 -1
  5. package/dist/cjs/node_modules/three/examples/jsm/exporters/OBJExporter.js +305 -1
  6. package/dist/cjs/node_modules/three/examples/jsm/exporters/PLYExporter.js +542 -1
  7. package/dist/cjs/node_modules/three/examples/jsm/exporters/STLExporter.js +218 -1
  8. package/dist/cjs/node_modules/three/examples/jsm/loaders/DRACOLoader.js +683 -1
  9. package/dist/cjs/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4811 -1
  10. package/dist/cjs/node_modules/three/examples/jsm/loaders/RGBELoader.js +480 -1
  11. package/dist/cjs/node_modules/three/examples/jsm/renderers/CSS2DRenderer.js +309 -1
  12. package/dist/cjs/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +120 -1
  13. package/dist/cjs/src/analysis/analysis.js +560 -1
  14. package/dist/cjs/src/analysis/testing.js +958 -1
  15. package/dist/cjs/src/core/centralPlant.js +1149 -1
  16. package/dist/cjs/src/core/debugLogger.js +175 -1
  17. package/dist/cjs/src/core/mathUtils.js +574 -1
  18. package/dist/cjs/src/core/nameUtils.js +93 -1
  19. package/dist/cjs/src/data/export.js +716 -1
  20. package/dist/cjs/src/data/import.js +380 -1
  21. package/dist/cjs/src/data/numerics.js +522 -1
  22. package/dist/cjs/src/helpers/sceneHelper.js +572 -1
  23. package/dist/cjs/src/index.js +69 -1
  24. package/dist/cjs/src/managers/components/animationManager.js +123 -1
  25. package/dist/cjs/src/managers/components/componentManager.js +332 -1
  26. package/dist/cjs/src/managers/components/pathfindingManager.js +1441 -1
  27. package/dist/cjs/src/managers/controls/TransformControls.js +1063 -1
  28. package/dist/cjs/src/managers/controls/cameraControlsManager.js +79 -1
  29. package/dist/cjs/src/managers/controls/dragDropManager.js +1026 -1
  30. package/dist/cjs/src/managers/controls/keyboardControlsManager.js +395 -1
  31. package/dist/cjs/src/managers/controls/transformControlsManager.js +1807 -1
  32. package/dist/cjs/src/managers/environment/environmentManager.js +714 -1
  33. package/dist/cjs/src/managers/environment/textureConfig.js +229 -1
  34. package/dist/cjs/src/managers/scene/sceneExportManager.js +264 -1
  35. package/dist/cjs/src/managers/scene/sceneInitializationManager.js +346 -1
  36. package/dist/cjs/src/managers/scene/sceneOperationsManager.js +1509 -1
  37. package/dist/cjs/src/managers/scene/sceneTooltipsManager.js +661 -1
  38. package/dist/cjs/src/managers/system/disposalManager.js +444 -1
  39. package/dist/cjs/src/managers/system/hotReloadManager.js +291 -1
  40. package/dist/cjs/src/managers/system/performanceMonitor.js +863 -1
  41. package/dist/cjs/src/rendering/modelPreloader.js +369 -1
  42. package/dist/cjs/src/rendering/rendering2D.js +631 -1
  43. package/dist/cjs/src/rendering/rendering3D.js +685 -1
  44. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +396 -1
  45. package/dist/esm/node_modules/@2112-lab/pathfinder/dist/index.esm.js +1444 -1
  46. package/dist/esm/node_modules/three/examples/jsm/controls/OrbitControls.js +1849 -1
  47. package/dist/esm/node_modules/three/examples/jsm/exporters/GLTFExporter.js +3533 -1
  48. package/dist/esm/node_modules/three/examples/jsm/exporters/OBJExporter.js +301 -1
  49. package/dist/esm/node_modules/three/examples/jsm/exporters/PLYExporter.js +538 -1
  50. package/dist/esm/node_modules/three/examples/jsm/exporters/STLExporter.js +214 -1
  51. package/dist/esm/node_modules/three/examples/jsm/loaders/DRACOLoader.js +679 -1
  52. package/dist/esm/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4807 -1
  53. package/dist/esm/node_modules/three/examples/jsm/loaders/RGBELoader.js +476 -1
  54. package/dist/esm/node_modules/three/examples/jsm/renderers/CSS2DRenderer.js +304 -1
  55. package/dist/esm/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +116 -1
  56. package/dist/esm/src/analysis/analysis.js +536 -1
  57. package/dist/esm/src/analysis/testing.js +954 -1
  58. package/dist/esm/src/core/centralPlant.js +1144 -1
  59. package/dist/esm/src/core/debugLogger.js +167 -1
  60. package/dist/esm/src/core/mathUtils.js +570 -1
  61. package/dist/esm/src/core/nameUtils.js +87 -1
  62. package/dist/esm/src/data/export.js +712 -1
  63. package/dist/esm/src/data/import.js +356 -1
  64. package/dist/esm/src/data/numerics.js +518 -1
  65. package/dist/esm/src/helpers/sceneHelper.js +547 -1
  66. package/dist/esm/src/index.js +35 -1
  67. package/dist/esm/src/managers/components/animationManager.js +119 -1
  68. package/dist/esm/src/managers/components/componentManager.js +328 -1
  69. package/dist/esm/src/managers/components/pathfindingManager.js +1417 -1
  70. package/dist/esm/src/managers/controls/TransformControls.js +1057 -1
  71. package/dist/esm/src/managers/controls/cameraControlsManager.js +75 -1
  72. package/dist/esm/src/managers/controls/dragDropManager.js +1002 -1
  73. package/dist/esm/src/managers/controls/keyboardControlsManager.js +371 -1
  74. package/dist/esm/src/managers/controls/transformControlsManager.js +1782 -1
  75. package/dist/esm/src/managers/environment/environmentManager.js +690 -1
  76. package/dist/esm/src/managers/environment/textureConfig.js +202 -1
  77. package/dist/esm/src/managers/scene/sceneExportManager.js +260 -1
  78. package/dist/esm/src/managers/scene/sceneInitializationManager.js +322 -1
  79. package/dist/esm/src/managers/scene/sceneOperationsManager.js +1485 -1
  80. package/dist/esm/src/managers/scene/sceneTooltipsManager.js +637 -1
  81. package/dist/esm/src/managers/system/disposalManager.js +440 -1
  82. package/dist/esm/src/managers/system/hotReloadManager.js +287 -1
  83. package/dist/esm/src/managers/system/performanceMonitor.js +858 -1
  84. package/dist/esm/src/rendering/modelPreloader.js +364 -1
  85. package/dist/esm/src/rendering/rendering2D.js +627 -1
  86. package/dist/esm/src/rendering/rendering3D.js +661 -1
  87. package/package.json +1 -1
@@ -1 +1,1782 @@
1
- import{createClass as t,createForOfIteratorHelper as i,objectSpread2 as s,classCallCheck as e}from"../../../_virtual/_rollupPluginBabelHelpers.js";import*as n from"three";import{TransformControls as h}from"./TransformControls.js";var o=function(){return t(function t(i,s,n){var h=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null;e(this,t),this.scene=i,this.camera=s,this.renderer=n,this.orbitControls=h,this.transformControls=null,this.boundingBoxHelper=null,this.boundingBoxCache=new WeakMap,this.selectedObject=null,this.currentMode="translate",this.currentSpace="world",this.forceInvisible=!1,this.eventHandlers={keydown:null,click:null,transformStart:null,transformEnd:null,transforming:null},this.clickTiming={lastClickTime:0,lastClickedObject:null,doubleClickDelay:300},this.transformState={isTransforming:!1,initialTransform:null,currentTransform:null},this.config={size:1,enabled:!0,showX:!0,showY:!0,showZ:!0,snap:null,translationSnap:null,rotationSnap:null,scaleSnap:null,showBoundingBox:!0,boundingBoxColor:65280,useBoundingBoxSelection:!0},this.callbacks={onObjectSelect:null,onTransformStart:null,onTransform:null,onTransformEnd:null,onModeChange:null,onObjectRemoved:null},this.init()},[{key:"init",value:function(){this.createTransformControls(),this.setupEventListeners(),this.setupKeyboardControls()}},{key:"on",value:function(t){t.onObjectSelect&&(this.callbacks.onObjectSelect=t.onObjectSelect),t.onTransformStart&&(this.callbacks.onTransformStart=t.onTransformStart),t.onTransform&&(this.callbacks.onTransform=t.onTransform),t.onTransformEnd&&(this.callbacks.onTransformEnd=t.onTransformEnd),t.onModeChange&&(this.callbacks.onModeChange=t.onModeChange),t.onObjectRemoved&&(this.callbacks.onObjectRemoved=t.onObjectRemoved)}},{key:"createTransformControls",value:function(){this.transformControls=new h(this.camera,this.renderer.domElement),this.transformControls.setMode(this.currentMode),this.transformControls.setSpace(this.currentSpace),this.transformControls.setSize(this.config.size),this.transformControls.setDelay(this.clickTiming),this.transformControls.showX=this.config.showX,this.transformControls.showY=this.config.showY,this.transformControls.showZ=this.config.showZ,this.transformControls.showXY=!1,this.transformControls.showYZ=!1,this.transformControls.showXZ=!1,this.transformControls.isTransformControls=!0,this.transformControls.userData={isTransformControls:!0},this.scene.add(this.transformControls),this.transformControls.enabled=!1,this.t()}},{key:"setupEventListeners",value:function(){var t=this;this.eventHandlers.transformStart=function(){t.transformState.isTransforming=!0,t.selectedObject&&(t.transformState.initialTransform={position:t.selectedObject.position.clone(),rotation:t.selectedObject.rotation.clone(),scale:t.selectedObject.scale.clone()}),t.orbitControls&&(t.orbitControls.enabled=!1),t.callbacks.onTransformStart&&t.callbacks.onTransformStart(t.selectedObject,t.currentMode)},this.eventHandlers.transformEnd=function(){if(t.transformState.isTransforming=!1,t.orbitControls&&(t.orbitControls.enabled=!0),t.selectedObject&&(t.transformState.currentTransform={position:t.selectedObject.position.clone(),rotation:t.selectedObject.rotation.clone(),scale:t.selectedObject.scale.clone()},t.boundingBoxCache.has(t.selectedObject)&&t.boundingBoxCache.delete(t.selectedObject)),t.callbacks.onTransformEnd&&t.callbacks.onTransformEnd(t.selectedObject,t.transformState.initialTransform,t.transformState.currentTransform,t.currentMode),"undefined"!=typeof window){var i,s=new CustomEvent("sceneUpdateComplete",{detail:{timestamp:Date.now(),transformType:t.currentMode,objectName:(null===(i=t.selectedObject)||void 0===i?void 0:i.name)||"unknown"}});window.dispatchEvent(s)}},this.eventHandlers.transforming=function(){if(t.selectedObject&&t.boundingBoxCache.has(t.selectedObject)&&t.boundingBoxCache.delete(t.selectedObject),t.updateBoundingBox(),t.callbacks.onTransform&&t.callbacks.onTransform(t.selectedObject,t.currentMode),"undefined"!=typeof window){var i,s=new CustomEvent("sceneUpdateComplete",{detail:{timestamp:Date.now(),transformType:t.currentMode,objectName:(null===(i=t.selectedObject)||void 0===i?void 0:i.name)||"unknown",isTransforming:!0}});window.dispatchEvent(s)}},this.transformControls&&(this.eventHandlers.transformStart&&this.transformControls.removeEventListener("mouseDown",this.eventHandlers.transformStart),this.eventHandlers.transformEnd&&this.transformControls.removeEventListener("mouseUp",this.eventHandlers.transformEnd),this.eventHandlers.transforming&&this.transformControls.removeEventListener("objectChange",this.eventHandlers.transforming),this.transformControls.addEventListener("mouseDown",this.eventHandlers.transformStart),this.transformControls.addEventListener("mouseUp",this.eventHandlers.transformEnd),this.transformControls.addEventListener("objectChange",this.eventHandlers.transforming))}},{key:"setupKeyboardControls",value:function(){var t=this;this.eventHandlers.keydown=function(i){if(t.transformControls.enabled&&!t.transformState.isTransforming&&(!i.ctrlKey||"KeyZ"!==i.code))switch(i.code){case"KeyG":t.setMode("translate");break;case"KeyR":t.setMode("rotate");break;case"KeyS":t.setMode("scale");break;case"KeyW":t.setSpace("world");break;case"KeyL":t.setSpace("local");break;case"Escape":t.deselectObject();break;case"KeyX":t.setAxisConstraint("X");break;case"KeyY":t.setAxisConstraint("Y");break;case"KeyZ":i.ctrlKey||t.setAxisConstraint("Z");break;case"ShiftLeft":case"ShiftRight":t.clearAxisConstraint();break;case"Backspace":t.handleObjectRemoval()}},window.addEventListener("keydown",this.eventHandlers.keydown)}},{key:"setupObjectSelection",value:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,s=new n.Raycaster,e=new n.Vector2;this.eventHandlers.click=function(n){if(!t.transformState.isTransforming){var h=Date.now(),o=h-t.clickTiming.lastClickTime;t.i(n,e),s.setFromCamera(e,t.camera);var a=t.h(s,i),l=a===t.clickTiming.lastClickedObject,r=o<t.clickTiming.doubleClickDelay;l&&r&&null!==a?(t.selectObject(a),t.clickTiming.lastClickTime=0,t.clickTiming.lastClickedObject=null):(t.deselectObject(),a&&t.selectObjectForTransformOnly(a),t.clickTiming.lastClickTime=h,t.clickTiming.lastClickedObject=a)}},this.renderer.domElement.addEventListener("click",this.eventHandlers.click)}},{key:"_calculateMousePosition",value:function(t,i){var s=this.renderer.domElement.getBoundingClientRect();i.x=(t.clientX-s.left)/s.width*2-1,i.y=-(t.clientY-s.top)/s.height*2+1}},{key:"_findTargetObject",value:function(t,i){if(this.config.useBoundingBoxSelection){var s=this.o(t,i);if(s)return s}return this.l(t,i)}},{key:"_findTargetViaBoundingBox",value:function(t,i){var s=this.intersectObjectsBoundingBoxes(t,i);if(s.length>0){var e=s[0].object;if(this.u(e))return e}return null}},{key:"_findTargetViaMesh",value:function(t,i){var s=t.intersectObjects(this.scene.children,!0);if(s.length>0){var e=s[0].object;if(e=this.v(e),(i?i(e):this.isSelectableObject(e))&&this.u(e)){this.config.useBoundingBoxSelection;return e}}return null}},{key:"_resolveHierarchyTarget",value:function(t){var i,s,e;return this.isConnectorOrb(t)?t:null!==(i=t.parent)&&void 0!==i&&null!==(i=i.name)&&void 0!==i&&i.includes(" Component")?t.parent:null!==(s=t.parent)&&void 0!==s&&null!==(s=s.parent)&&void 0!==s&&null!==(s=s.name)&&void 0!==s&&s.includes(" Component")?t.parent.parent:(null!==(e=t.userData)&&void 0!==e&&e.isPipeSegment,t)}},{key:"_isValidSelectableObject",value:function(t){return!(!t||!t.parent)&&!!(t.position&&t.rotation&&t.scale&&t.updateMatrixWorld)}},{key:"isConnectorOrb",value:function(t){if(!t||!t.isObject3D)return!1;if(!t.isMesh||!t.geometry)return!1;var i="CONNECTOR-GEO"===t.geometry.uuid,s="SphereGeometry"===t.geometry.type&&t.geometry.parameters&&.2===t.geometry.parameters.radius,e=t.name&&t.name.toLowerCase().includes("connector");return(i||s)&&e}},{key:"isSelectableObject",value:function(t){var i,s,e,n,h,o,a,l;if(!t||!t.isObject3D)return!1;if(t.userData&&t.userData.isPipeSegment,t.isTransformControls||t.isTransformControlsPlane||t.isTransformControlsGizmo)return!1;var r=t.isHelper||(null===(i=t.userData)||void 0===i?void 0:i.isHelper)||(null===(s=t.userData)||void 0===s?void 0:s.isBoundingBox),u=null===(e=t.userData)||void 0===e?void 0:e.isBaseGround,c=null===(n=t.userData)||void 0===n?void 0:n.isBrickWall;if(r||u||c||!t.visible)return!1;if(t.name&&t.name.toLowerCase().includes("polyline")&&(null===(h=t.userData)||void 0===h||!h.isPipeSegment)&&(null===(o=t.userData)||void 0===o||!o.isPipeJunction))return!1;var v=!0===(null===(a=t.userData)||void 0===a?void 0:a.isPipeSegment),f=!0===(null===(l=t.userData)||void 0===l?void 0:l.isPipeJunction),d=t.name&&t.name.includes(" Component"),y=this.isConnectorOrb(t);return d||y||v||f}},{key:"selectObject",value:function(t){if(!t||!t.isObject3D)return!1;this.selectedObject=t,t.updateMatrixWorld(!0);var i=(new n.Box3).setFromObject(t);return this.boundingBoxCache.set(t,i),this.transformControls.attach(t),this.transformControls.updateInteractionTime&&this.transformControls.updateInteractionTime(),this.createBoundingBox(t),this.forceInvisible?(this.transformControls.enabled=!1,this.t()):(this.transformControls.enabled=this.config.enabled,this.k()),this.callbacks.onObjectSelect&&this.callbacks.onObjectSelect(t),!0}},{key:"selectObjectForTransformOnly",value:function(t){if(!t||!t.isObject3D)return!1;this.selectedObject=t,t.updateMatrixWorld(!0);var i=(new n.Box3).setFromObject(t);return this.boundingBoxCache.set(t,i),this.transformControls.attach(t),this.transformControls.updateInteractionTime&&this.transformControls.updateInteractionTime(),this.createBoundingBox(t),this.forceInvisible?(this.transformControls.enabled=!1,this.t()):(this.transformControls.enabled=!0,this.k()),!0}},{key:"deselectObject",value:function(){this.selectedObject,this.removeBoundingBox(),this.selectedObject=null,this.transformControls&&(this.transformControls.detach(),this.transformControls.enabled=!1,this.t()),this.callbacks.onObjectSelect&&this.callbacks.onObjectSelect(null)}},{key:"createBoundingBox",value:function(t){if(this.config.showBoundingBox&&(this.removeBoundingBox(),t))try{this.boundingBoxHelper=new n.BoxHelper(t,this.config.boundingBoxColor),this.boundingBoxHelper.isHelper=!0,this.boundingBoxHelper.userData={isBoundingBox:!0},this.scene.add(this.boundingBoxHelper)}catch(t){}}},{key:"removeBoundingBox",value:function(){if(this.boundingBoxHelper)try{this.boundingBoxHelper.parent&&this.boundingBoxHelper.parent.remove(this.boundingBoxHelper),this.boundingBoxHelper.geometry&&this.boundingBoxHelper.geometry.dispose(),this.boundingBoxHelper.material&&this.boundingBoxHelper.material.dispose()}catch(t){}finally{this.boundingBoxHelper=null}}},{key:"updateBoundingBox",value:function(){if(this.boundingBoxHelper&&this.selectedObject)try{if(this.selectedObject.updateMatrixWorld(!0),this.boundingBoxHelper.update(),this.boundingBoxCache.has(this.selectedObject)){var t=(new n.Box3).setFromObject(this.selectedObject);this.boundingBoxCache.set(this.selectedObject,t)}}catch(t){this.createBoundingBox(this.selectedObject)}}},{key:"setBoundingBoxVisibility",value:function(t){this.config.showBoundingBox=t,t&&this.selectedObject&&!this.boundingBoxHelper?this.createBoundingBox(this.selectedObject):!t&&this.boundingBoxHelper&&this.removeBoundingBox()}},{key:"setBoundingBoxColor",value:function(t){this.config.boundingBoxColor=t,this.boundingBoxHelper&&this.boundingBoxHelper.material&&this.boundingBoxHelper.material.color.setHex(t)}},{key:"setMode",value:function(t){if(["translate","rotate","scale"].includes(t)){var i=this.currentMode;this.currentMode=t,this.transformControls.setMode(t),this.callbacks.onModeChange&&this.callbacks.onModeChange(t,i)}}},{key:"setSpace",value:function(t){if(["world","local"].includes(t)){this.currentSpace;this.currentSpace=t,this.transformControls.setSpace(t)}}},{key:"setAxisConstraint",value:function(t){["X","Y","Z"].includes(t)&&(this.transformControls.showX=!1,this.transformControls.showY=!1,this.transformControls.showZ=!1,this.transformControls["show".concat(t)]=!0)}},{key:"clearAxisConstraint",value:function(){this.transformControls.showX=this.config.showX,this.transformControls.showY=this.config.showY,this.transformControls.showZ=this.config.showZ}},{key:"setSnap",value:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};void 0!==t.translation&&(this.config.translationSnap=t.translation,this.transformControls.setTranslationSnap(t.translation)),void 0!==t.rotation&&(this.config.rotationSnap=t.rotation,this.transformControls.setRotationSnap(t.rotation)),void 0!==t.scale&&(this.config.scaleSnap=t.scale,this.transformControls.setScaleSnap(t.scale))}},{key:"snapValues",get:function(){return{translation:this.config.translationSnap||.5,rotation:this.config.rotationSnap||Math.PI/2,scale:this.config.scaleSnap||.1}}},{key:"setSize",value:function(t){this.config.size=t,this.transformControls.setSize(t)}},{key:"setEnabled",value:function(t){this.config.enabled=t,this.selectedObject&&(this.transformControls.enabled=t)}},{key:"setShowPlanes",value:function(t){return!!this.transformControls&&(this.transformControls.showXY=t,this.transformControls.showYZ=t,this.transformControls.showXZ=t,!0)}},{key:"ensureSceneAttachment",value:function(){var t=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];return!this.transformControls&&this.scene&&this.camera&&this.renderer?(this.createTransformControls(),this.setupEventListeners(),t||(this.transformControls.visible=!1),!0):!(!this.transformControls||!this.scene)&&(this.scene.children.includes(this.transformControls)?!this.transformControls.visible&&t?(this.transformControls.visible=!0,!0):this.transformControls.visible&&!t?(this.transformControls.visible=!1,!0):!(!this.transformControls.parent||this.transformControls.parent===this.scene)&&(this.transformControls.parent.remove(this.transformControls),this.scene.add(this.transformControls),!0):(this.scene.add(this.transformControls),this.transformControls.enabled=!1,this.selectedObject&&(this.transformControls.attach(this.selectedObject),this.transformControls.enabled=this.config.enabled),t||(this.transformControls.visible=!1),!0))}},{key:"getTransformData",value:function(){if(!this.selectedObject)return null;var t={position:this.selectedObject.position.clone(),rotation:this.selectedObject.rotation.clone(),scale:this.selectedObject.scale.clone()},i=this.getWorldTransformData();return{object:this.selectedObject,position:t.position,rotation:t.rotation,scale:t.scale,worldPosition:i.position,worldRotation:i.rotation,worldScale:i.scale,mode:this.currentMode,space:this.currentSpace,isTransforming:this.transformState.isTransforming}}},{key:"getWorldTransformData",value:function(){if(!this.selectedObject)return null;this.selectedObject.updateMatrixWorld(!0);var t=new n.Vector3;this.selectedObject.getWorldPosition(t);var i=new n.Quaternion;this.selectedObject.getWorldQuaternion(i);var s=new n.Euler;s.setFromQuaternion(i);var e=new n.Vector3;return this.selectedObject.getWorldScale(e),{position:t,rotation:s,scale:e}}},{key:"updateObjectTransform",value:function(t,i,s){var e=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if(this.selectedObject){var n=this.selectedObject,h=parseFloat(s);if(!isNaN(h)){if(e)this.updateWorldTransform(n,t,i,h);else switch(t){case"position":n.position[i]=h;break;case"rotation":n.rotation[i]=h*(Math.PI/180);break;case"scale":n.scale[i]=h;break;default:return}this.transformControls&&this.transformControls.updateMatrixWorld(),this.updateBoundingBox()}}}},{key:"updateWorldTransform",value:function(t,i,s,e){switch(t.updateMatrixWorld(!0),i){case"position":this.setWorldPosition(t,s,e);break;case"rotation":this.setWorldRotation(t,s,e);break;case"scale":this.setWorldScale(t,s,e)}}},{key:"setWorldPosition",value:function(t,i,s){var e=new n.Vector3;if(t.getWorldPosition(e),e[i]=s,t.parent){var h=new n.Matrix4;h.copy(t.parent.matrixWorld).invert(),e.applyMatrix4(h)}t.position.copy(e)}},{key:"setWorldRotation",value:function(t,i,s){var e=new n.Quaternion;t.getWorldQuaternion(e);var h=new n.Euler;h.setFromQuaternion(e),h[i]=s*(Math.PI/180);var o=new n.Quaternion;if(o.setFromEuler(h),t.parent){var a=new n.Quaternion;t.parent.getWorldQuaternion(a),a.invert(),o.premultiply(a)}t.quaternion.copy(o)}},{key:"setWorldScale",value:function(t,i,s){var e=new n.Vector3;t.getWorldScale(e);var h=s/e[i];t.scale[i]*=h}},{key:"getSelectableObjectsWithBounds",value:function(){var t=this,i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null,s=[];return this.scene.traverse(function(e){var h,o;if(e&&e.isObject3D&&!(e.isTransformControls||e.isTransformControlsPlane||e.isTransformControlsGizmo||e.isHelper||null!==(h=e.userData)&&void 0!==h&&h.isHelper||null!==(o=e.userData)&&void 0!==o&&o.isBoundingBox))try{if(i?i(e):t.isSelectableObject(e)){e.updateMatrixWorld(!0);var a=t.boundingBoxCache.get(e);a&&e!==t.selectedObject||(a=(new n.Box3).setFromObject(e),t.boundingBoxCache.set(e,a)),s.push({object:e,boundingBox:a})}}catch(t){}}),s}},{key:"intersectObjectsBoundingBoxes",value:function(t){var s,e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,h=this.getSelectableObjectsWithBounds(e),o=[],a=i(h);try{for(a.s();!(s=a.n()).done;){var l=s.value,r=l.object,u=l.boundingBox,c=t.ray.intersectBox(u,new n.Vector3);if(c){var v=t.ray.origin.distanceTo(c);o.push({object:r,point:c,distance:v,boundingBox:u})}}}catch(t){a.e(t)}finally{a.f()}return o.sort(function(t,i){return t.distance-i.distance}),o}},{key:"setBoundingBoxSelection",value:function(t){this.config.useBoundingBoxSelection=t}},{key:"handleObjectRemoval",value:function(){var t;this.selectedObject&&"gateway"===(null===(t=this.selectedObject.userData)||void 0===t?void 0:t.componentType)&&this.handleGatewayRemoval()}},{key:"handleGatewayRemoval",value:function(){var t,i=this.selectedObject,e={uuid:i.uuid,userData:s({},i.userData),position:i.position.clone(),connections:(null===(t=i.userData)||void 0===t?void 0:t.connections)||null};i.userData.origin="computed",this.deselectObject(),this.callbacks.onObjectRemoved&&this.callbacks.onObjectRemoved(e)}},{key:"dispose",value:function(){this.eventHandlers.keydown&&window.removeEventListener("keydown",this.eventHandlers.keydown),this.eventHandlers.click&&this.renderer.domElement.removeEventListener("click",this.eventHandlers.click),this.removeBoundingBox(),this.selectedObject&&this.deselectObject(),this.transformControls&&(this.eventHandlers.transformStart&&this.transformControls.removeEventListener("mouseDown",this.eventHandlers.transformStart),this.eventHandlers.transformEnd&&this.transformControls.removeEventListener("mouseUp",this.eventHandlers.transformEnd),this.eventHandlers.transforming&&this.transformControls.removeEventListener("objectChange",this.eventHandlers.transforming),this.transformControls.detach(),this.scene&&this.transformControls.parent===this.scene&&this.scene.remove(this.transformControls),this.transformControls.dispose(),this.transformControls=null),this.selectedObject=null,this.orbitControls=null}},{key:"forceHide",value:function(){this.transformControls&&(this.t(),this.transformControls.enabled=!1)}},{key:"_hideTransformControls",value:function(){this.transformControls&&(this.transformControls.visible=!1,this.transformControls.m&&(this.transformControls.m.visible=!1),this.transformControls.p&&(this.transformControls.p.visible=!1))}},{key:"_showTransformControls",value:function(){this.transformControls&&(this.transformControls.visible=!0,this.transformControls.m&&(this.transformControls.m.visible=!0),this.transformControls.p&&(this.transformControls.p.visible=!0))}},{key:"getVisibilityState",value:function(){var t;return this.transformControls?{exists:!0,visible:this.transformControls.visible,enabled:this.transformControls.enabled,gizmoVisible:this.transformControls.m?this.transformControls.m.visible:"N/A",planeVisible:this.transformControls.p?this.transformControls.p.visible:"N/A",hasSelectedObject:!!this.selectedObject,selectedObjectName:(null===(t=this.selectedObject)||void 0===t?void 0:t.name)||"none"}:{exists:!1}}},{key:"_forceHideAllGizmoComponents",value:function(){if(this.transformControls&&this.transformControls.m){var t=this.transformControls.m;t.visible=!1,t.gizmo&&Object.keys(t.gizmo).forEach(function(i){t.gizmo[i]&&(t.gizmo[i].visible=!1)}),t.helper&&Object.keys(t.helper).forEach(function(i){t.helper[i]&&(t.helper[i].visible=!1)}),this.transformControls.p&&(this.transformControls.p.visible=!1)}}},{key:"_hidePlaneHelpers",value:function(){if(this.transformControls&&this.transformControls.m){var t=this.transformControls.m;if(t.gizmo&&t.gizmo.translate)t.gizmo.translate.traverse(function(t){"XY"!==t.name&&"YZ"!==t.name&&"XZ"!==t.name||(t.visible=!1)});if(t.picker&&t.picker.translate)t.picker.translate.traverse(function(t){"XY"!==t.name&&"YZ"!==t.name&&"XZ"!==t.name||(t.visible=!1)})}}},{key:"_showPlaneHelpers",value:function(){if(this.transformControls&&this.transformControls.m){var t=this.transformControls.m;if(t.gizmo&&t.gizmo.translate)t.gizmo.translate.traverse(function(t){"XY"!==t.name&&"YZ"!==t.name&&"XZ"!==t.name||(t.visible=!0)});if(t.picker&&t.picker.translate)t.picker.translate.traverse(function(t){"XY"!==t.name&&"YZ"!==t.name&&"XZ"!==t.name||(t.visible=!0)})}}}])}();function a(t,i,s){return new o(t,i,s,arguments.length>3&&void 0!==arguments[3]?arguments[3]:null)}export{o as TransformControlsManager,a as createTransformControls};
1
+ import { createClass as _createClass, createForOfIteratorHelper as _createForOfIteratorHelper, objectSpread2 as _objectSpread2, classCallCheck as _classCallCheck } from '../../../_virtual/_rollupPluginBabelHelpers.js';
2
+ import * as THREE from 'three';
3
+ import { TransformControls } from './TransformControls.js';
4
+
5
+ var TransformControlsManager = /*#__PURE__*/function () {
6
+ function TransformControlsManager(scene, camera, renderer) {
7
+ var orbitControls = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
8
+ _classCallCheck(this, TransformControlsManager);
9
+ this.scene = scene;
10
+ this.camera = camera;
11
+ this.renderer = renderer;
12
+ this.orbitControls = orbitControls;
13
+ // Transform control instance
14
+ this.transformControls = null;
15
+ // Bounding box helper for visual feedback
16
+ this.boundingBoxHelper = null;
17
+
18
+ // Cache for object bounding boxes to improve performance
19
+ this.boundingBoxCache = new WeakMap();
20
+
21
+ // Currently selected object
22
+ this.selectedObject = null;
23
+
24
+ // Transform mode: 'translate', 'rotate', 'scale'
25
+ this.currentMode = 'translate';
26
+
27
+ // Transform space: 'world' or 'local'
28
+ this.currentSpace = 'world';
29
+
30
+ // Flag to force controls to stay invisible (used during scene loading)
31
+ this.forceInvisible = false;
32
+
33
+ // Event handlers storage
34
+ this.eventHandlers = {
35
+ keydown: null,
36
+ click: null,
37
+ transformStart: null,
38
+ transformEnd: null,
39
+ transforming: null
40
+ };
41
+
42
+ // Click timing for double-click detection
43
+ this.clickTiming = {
44
+ lastClickTime: 0,
45
+ lastClickedObject: null,
46
+ doubleClickDelay: 300 // milliseconds
47
+ };
48
+
49
+ // Transform state tracking
50
+ this.transformState = {
51
+ isTransforming: false,
52
+ initialTransform: null,
53
+ currentTransform: null
54
+ };
55
+
56
+ // Configuration options
57
+ this.config = {
58
+ size: 1,
59
+ enabled: true,
60
+ showX: true,
61
+ showY: true,
62
+ showZ: true,
63
+ snap: null,
64
+ // Snap value for transformations
65
+ translationSnap: null,
66
+ rotationSnap: null,
67
+ scaleSnap: null,
68
+ showBoundingBox: true,
69
+ // Show bounding box on selection
70
+ boundingBoxColor: 0x00ff00,
71
+ // Green bounding box by default
72
+ useBoundingBoxSelection: true // Use bounding box-based selection instead of mesh selection
73
+ };
74
+
75
+ // Callbacks for external event handling
76
+ this.callbacks = {
77
+ onObjectSelect: null,
78
+ onTransformStart: null,
79
+ onTransform: null,
80
+ onTransformEnd: null,
81
+ onModeChange: null,
82
+ onObjectRemoved: null
83
+ };
84
+ this.init();
85
+ }
86
+
87
+ /**
88
+ * Initialize the transform controls
89
+ */
90
+ return _createClass(TransformControlsManager, [{
91
+ key: "init",
92
+ value: function init() {
93
+ this.createTransformControls();
94
+ this.setupEventListeners();
95
+ this.setupKeyboardControls();
96
+ }
97
+
98
+ /**
99
+ * Register event callbacks
100
+ * @param {Object} callbacks - Object containing callback functions
101
+ * @param {Function} callbacks.onObjectSelect - Called when an object is selected/deselected
102
+ * @param {Function} callbacks.onTransformStart - Called when transform starts
103
+ * @param {Function} callbacks.onTransform - Called during transform
104
+ * @param {Function} callbacks.onTransformEnd - Called when transform ends
105
+ * @param {Function} callbacks.onModeChange - Called when transform mode changes
106
+ * @param {Function} callbacks.onObjectRemoved - Called when an object is removed
107
+ */
108
+ }, {
109
+ key: "on",
110
+ value: function on(callbacks) {
111
+ if (callbacks.onObjectSelect) {
112
+ this.callbacks.onObjectSelect = callbacks.onObjectSelect;
113
+ }
114
+ if (callbacks.onTransformStart) {
115
+ this.callbacks.onTransformStart = callbacks.onTransformStart;
116
+ }
117
+ if (callbacks.onTransform) {
118
+ this.callbacks.onTransform = callbacks.onTransform;
119
+ }
120
+ if (callbacks.onTransformEnd) {
121
+ this.callbacks.onTransformEnd = callbacks.onTransformEnd;
122
+ }
123
+ if (callbacks.onModeChange) {
124
+ this.callbacks.onModeChange = callbacks.onModeChange;
125
+ }
126
+ if (callbacks.onObjectRemoved) {
127
+ this.callbacks.onObjectRemoved = callbacks.onObjectRemoved;
128
+ }
129
+ console.log('🔗 Transform controls callbacks registered');
130
+ }
131
+ /**
132
+ * Create and configure transform controls
133
+ */
134
+ }, {
135
+ key: "createTransformControls",
136
+ value: function createTransformControls() {
137
+ this.transformControls = new TransformControls(this.camera, this.renderer.domElement);
138
+ this.transformControls.setMode(this.currentMode);
139
+ this.transformControls.setSpace(this.currentSpace);
140
+ this.transformControls.setSize(this.config.size);
141
+ this.transformControls.setDelay(this.clickTiming);
142
+
143
+ // Configure axes visibility
144
+ this.transformControls.showX = this.config.showX;
145
+ this.transformControls.showY = this.config.showY;
146
+ this.transformControls.showZ = this.config.showZ;
147
+
148
+ // Hide multi-axis plane helpers by default (only allow single-axis translation)
149
+ this.transformControls.showXY = false;
150
+ this.transformControls.showYZ = false;
151
+ this.transformControls.showXZ = false;
152
+
153
+ // Mark as transform controls for scene filtering
154
+ this.transformControls.isTransformControls = true;
155
+ this.transformControls.userData = {
156
+ isTransformControls: true
157
+ };
158
+ // Add to scene
159
+ this.scene.add(this.transformControls);
160
+
161
+ // Initially disabled and invisible
162
+ this.transformControls.enabled = false;
163
+ this._hideTransformControls();
164
+ }
165
+
166
+ /**
167
+ * Setup event listeners for transform controls
168
+ */
169
+ }, {
170
+ key: "setupEventListeners",
171
+ value: function setupEventListeners() {
172
+ var _this = this;
173
+ // Transform start event
174
+ this.eventHandlers.transformStart = function () {
175
+ console.log("transformControls transformStart");
176
+ _this.transformState.isTransforming = true;
177
+ if (_this.selectedObject) {
178
+ // Store initial transform state
179
+ _this.transformState.initialTransform = {
180
+ position: _this.selectedObject.position.clone(),
181
+ rotation: _this.selectedObject.rotation.clone(),
182
+ scale: _this.selectedObject.scale.clone()
183
+ };
184
+ }
185
+
186
+ // Disable orbit controls during transformation
187
+ if (_this.orbitControls) {
188
+ _this.orbitControls.enabled = false;
189
+ }
190
+
191
+ // Execute callback
192
+ if (_this.callbacks.onTransformStart) {
193
+ _this.callbacks.onTransformStart(_this.selectedObject, _this.currentMode);
194
+ }
195
+ console.log("\uD83D\uDD27 Transform started: ".concat(_this.currentMode, " mode"));
196
+ };
197
+
198
+ // Transform end event
199
+ this.eventHandlers.transformEnd = function () {
200
+ _this.transformState.isTransforming = false;
201
+
202
+ // Re-enable orbit controls
203
+ if (_this.orbitControls) {
204
+ _this.orbitControls.enabled = true;
205
+ }
206
+
207
+ // Store final transform state
208
+ if (_this.selectedObject) {
209
+ _this.transformState.currentTransform = {
210
+ position: _this.selectedObject.position.clone(),
211
+ rotation: _this.selectedObject.rotation.clone(),
212
+ scale: _this.selectedObject.scale.clone()
213
+ };
214
+
215
+ // Clear bounding box cache for the transformed object to ensure selection uses updated position
216
+ if (_this.boundingBoxCache.has(_this.selectedObject)) {
217
+ _this.boundingBoxCache.delete(_this.selectedObject);
218
+ }
219
+ }
220
+
221
+ // Execute callback
222
+ if (_this.callbacks.onTransformEnd) {
223
+ _this.callbacks.onTransformEnd(_this.selectedObject, _this.transformState.initialTransform, _this.transformState.currentTransform, _this.currentMode);
224
+ }
225
+
226
+ // Dispatch custom scene update event after transform completes
227
+ if (typeof window !== 'undefined') {
228
+ var _this$selectedObject;
229
+ console.log('📡 Dispatching sceneUpdateComplete event after transform');
230
+ var sceneCompleteEvent = new CustomEvent('sceneUpdateComplete', {
231
+ detail: {
232
+ timestamp: Date.now(),
233
+ transformType: _this.currentMode,
234
+ objectName: ((_this$selectedObject = _this.selectedObject) === null || _this$selectedObject === void 0 ? void 0 : _this$selectedObject.name) || 'unknown'
235
+ }
236
+ });
237
+ window.dispatchEvent(sceneCompleteEvent);
238
+ }
239
+ console.log("\u2705 Transform completed: ".concat(_this.currentMode, " mode"));
240
+ };
241
+ // Transform changing event
242
+ this.eventHandlers.transforming = function () {
243
+ // Clear the bounding box cache for the selected object during transformation
244
+ if (_this.selectedObject && _this.boundingBoxCache.has(_this.selectedObject)) {
245
+ _this.boundingBoxCache.delete(_this.selectedObject);
246
+ }
247
+
248
+ // Update bounding box during transformation
249
+ _this.updateBoundingBox();
250
+ if (_this.callbacks.onTransform) {
251
+ _this.callbacks.onTransform(_this.selectedObject, _this.currentMode);
252
+ }
253
+
254
+ // Dispatch custom scene update event during transform (optional - fires continuously)
255
+ if (typeof window !== 'undefined') {
256
+ var _this$selectedObject2;
257
+ var sceneCompleteEvent = new CustomEvent('sceneUpdateComplete', {
258
+ detail: {
259
+ timestamp: Date.now(),
260
+ transformType: _this.currentMode,
261
+ objectName: ((_this$selectedObject2 = _this.selectedObject) === null || _this$selectedObject2 === void 0 ? void 0 : _this$selectedObject2.name) || 'unknown',
262
+ isTransforming: true
263
+ }
264
+ });
265
+ window.dispatchEvent(sceneCompleteEvent);
266
+ }
267
+ };
268
+ // First remove any existing listeners to prevent duplicates
269
+ if (this.transformControls) {
270
+ // Remove existing listeners if they exist
271
+ if (this.eventHandlers.transformStart) {
272
+ this.transformControls.removeEventListener('mouseDown', this.eventHandlers.transformStart);
273
+ }
274
+ if (this.eventHandlers.transformEnd) {
275
+ this.transformControls.removeEventListener('mouseUp', this.eventHandlers.transformEnd);
276
+ }
277
+ if (this.eventHandlers.transforming) {
278
+ this.transformControls.removeEventListener('objectChange', this.eventHandlers.transforming);
279
+ }
280
+
281
+ // Add event listeners
282
+ this.transformControls.addEventListener('mouseDown', this.eventHandlers.transformStart);
283
+ this.transformControls.addEventListener('mouseUp', this.eventHandlers.transformEnd);
284
+ this.transformControls.addEventListener('objectChange', this.eventHandlers.transforming);
285
+ }
286
+ }
287
+ /**
288
+ * Setup keyboard controls for transform modes
289
+ */
290
+ }, {
291
+ key: "setupKeyboardControls",
292
+ value: function setupKeyboardControls() {
293
+ var _this2 = this;
294
+ this.eventHandlers.keydown = function (event) {
295
+ // Only handle keys when transform controls are active
296
+ if (!_this2.transformControls.enabled || _this2.transformState.isTransforming) {
297
+ return;
298
+ }
299
+
300
+ // Check for Ctrl+Z (undo) - don't handle it here, let it pass through
301
+ if (event.ctrlKey && event.code === 'KeyZ') {
302
+ return; // Let the KeyboardControlsManager handle Ctrl+Z
303
+ }
304
+ switch (event.code) {
305
+ case 'KeyG':
306
+ // Translate mode
307
+ _this2.setMode('translate');
308
+ break;
309
+ case 'KeyR':
310
+ // Rotate mode
311
+ _this2.setMode('rotate');
312
+ break;
313
+ case 'KeyS':
314
+ // Scale mode
315
+ _this2.setMode('scale');
316
+ break;
317
+ case 'KeyW':
318
+ // World space
319
+ _this2.setSpace('world');
320
+ break;
321
+ case 'KeyL':
322
+ // Local space
323
+ _this2.setSpace('local');
324
+ break;
325
+ case 'Escape':
326
+ // Deselect object
327
+ _this2.deselectObject();
328
+ break;
329
+ case 'KeyX':
330
+ // X-axis constraint
331
+ _this2.setAxisConstraint('X');
332
+ break;
333
+ case 'KeyY':
334
+ // Y-axis constraint
335
+ _this2.setAxisConstraint('Y');
336
+ break;
337
+ case 'KeyZ':
338
+ // Z-axis constraint (only if not Ctrl+Z)
339
+ if (!event.ctrlKey) {
340
+ _this2.setAxisConstraint('Z');
341
+ }
342
+ break;
343
+ case 'ShiftLeft':
344
+ case 'ShiftRight':
345
+ // Multi-axis constraint
346
+ _this2.clearAxisConstraint();
347
+ break;
348
+ case 'Backspace':
349
+ // Remove selected object
350
+ _this2.handleObjectRemoval();
351
+ break;
352
+ }
353
+ };
354
+ window.addEventListener('keydown', this.eventHandlers.keydown);
355
+ }
356
+ /**
357
+ * Setup mouse-based object selection
358
+ * @param {Function} objectFilter - Optional function to filter selectable objects
359
+ */
360
+ }, {
361
+ key: "setupObjectSelection",
362
+ value: function setupObjectSelection() {
363
+ var _this3 = this;
364
+ var objectFilter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
365
+ var raycaster = new THREE.Raycaster();
366
+ var mouse = new THREE.Vector2();
367
+
368
+ // Single click handler with double-click detection
369
+ this.eventHandlers.click = function (event) {
370
+ // Skip if currently transforming
371
+ if (_this3.transformState.isTransforming) {
372
+ return;
373
+ }
374
+ var currentTime = Date.now();
375
+ var timeSinceLastClick = currentTime - _this3.clickTiming.lastClickTime;
376
+
377
+ // Calculate mouse position and set up raycaster
378
+ _this3._calculateMousePosition(event, mouse);
379
+ raycaster.setFromCamera(mouse, _this3.camera);
380
+
381
+ // Find target object using appropriate selection method
382
+ var targetObject = _this3._findTargetObject(raycaster, objectFilter);
383
+
384
+ // Check if this is a double-click: same object clicked within delay time
385
+ var isSameObject = targetObject === _this3.clickTiming.lastClickedObject;
386
+ var isWithinDelay = timeSinceLastClick < _this3.clickTiming.doubleClickDelay;
387
+ var isDoubleClick = isSameObject && isWithinDelay && targetObject !== null;
388
+ if (isDoubleClick) {
389
+ // Double-click on same object: Full selection including tooltips
390
+ _this3.selectObject(targetObject);
391
+
392
+ // Reset click timing to prevent triple-click issues
393
+ _this3.clickTiming.lastClickTime = 0;
394
+ _this3.clickTiming.lastClickedObject = null;
395
+ } else {
396
+ // Single click: Transform controls and bounding box only
397
+ // Always deselect first (this clears tooltips via the callback)
398
+ _this3.deselectObject();
399
+
400
+ // Then select the new object if there is one (this shows transform controls and bounding box)
401
+ if (targetObject) {
402
+ _this3.selectObjectForTransformOnly(targetObject);
403
+ }
404
+
405
+ // Update click timing
406
+ _this3.clickTiming.lastClickTime = currentTime;
407
+ _this3.clickTiming.lastClickedObject = targetObject;
408
+ }
409
+ };
410
+ this.renderer.domElement.addEventListener('click', this.eventHandlers.click);
411
+ }
412
+
413
+ /**
414
+ * Calculate normalized mouse position from click event
415
+ * @param {Event} event - The click event (single or double)
416
+ * @param {THREE.Vector2} mouse - Vector2 to store mouse position
417
+ * @private
418
+ */
419
+ }, {
420
+ key: "_calculateMousePosition",
421
+ value: function _calculateMousePosition(event, mouse) {
422
+ var rect = this.renderer.domElement.getBoundingClientRect();
423
+ mouse.x = (event.clientX - rect.left) / rect.width * 2 - 1;
424
+ mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
425
+ }
426
+
427
+ /**
428
+ * Find the target object for selection using configured selection method
429
+ * @param {THREE.Raycaster} raycaster - The raycaster for intersection testing
430
+ * @param {Function} objectFilter - Optional function to filter selectable objects
431
+ * @returns {THREE.Object3D|null} The target object or null if nothing selectable
432
+ * @private
433
+ */
434
+ }, {
435
+ key: "_findTargetObject",
436
+ value: function _findTargetObject(raycaster, objectFilter) {
437
+ // Try bounding box selection first if enabled
438
+ if (this.config.useBoundingBoxSelection) {
439
+ var targetObject = this._findTargetViaBoundingBox(raycaster, objectFilter);
440
+ if (targetObject) {
441
+ return targetObject;
442
+ }
443
+ }
444
+
445
+ // Fall back to mesh-based selection
446
+ return this._findTargetViaMesh(raycaster, objectFilter);
447
+ }
448
+
449
+ /**
450
+ * Find target object using bounding box intersection
451
+ * @param {THREE.Raycaster} raycaster - The raycaster for intersection testing
452
+ * @param {Function} objectFilter - Optional function to filter selectable objects
453
+ * @returns {THREE.Object3D|null} The target object or null if nothing found
454
+ * @private
455
+ */
456
+ }, {
457
+ key: "_findTargetViaBoundingBox",
458
+ value: function _findTargetViaBoundingBox(raycaster, objectFilter) {
459
+ var intersections = this.intersectObjectsBoundingBoxes(raycaster, objectFilter);
460
+ if (intersections.length > 0) {
461
+ var targetObject = intersections[0].object;
462
+ if (this._isValidSelectableObject(targetObject)) {
463
+ console.log("\uD83D\uDCE6 Object selected via bounding box: ".concat(targetObject.name || targetObject.uuid));
464
+ return targetObject;
465
+ }
466
+ }
467
+ return null;
468
+ }
469
+
470
+ /**
471
+ * Find target object using mesh intersection
472
+ * @param {THREE.Raycaster} raycaster - The raycaster for intersection testing
473
+ * @param {Function} objectFilter - Optional function to filter selectable objects
474
+ * @returns {THREE.Object3D|null} The target object or null if nothing found
475
+ * @private
476
+ */
477
+ }, {
478
+ key: "_findTargetViaMesh",
479
+ value: function _findTargetViaMesh(raycaster, objectFilter) {
480
+ var intersections = raycaster.intersectObjects(this.scene.children, true);
481
+ if (intersections.length > 0) {
482
+ var targetObject = intersections[0].object;
483
+
484
+ // Resolve the correct object in the hierarchy
485
+ targetObject = this._resolveHierarchyTarget(targetObject);
486
+
487
+ // Check if selectable
488
+ var isSelectable = objectFilter ? objectFilter(targetObject) : this.isSelectableObject(targetObject);
489
+ if (isSelectable && this._isValidSelectableObject(targetObject)) {
490
+ var method = this.config.useBoundingBoxSelection ? ' (fallback)' : '';
491
+ console.log("\uD83C\uDFAF Object selected via mesh".concat(method, ": ").concat(targetObject.name || targetObject.uuid));
492
+ return targetObject;
493
+ }
494
+ }
495
+ return null;
496
+ }
497
+
498
+ /**
499
+ * Resolve the correct target object in the hierarchy
500
+ * @param {THREE.Object3D} object - The initially intersected object
501
+ * @returns {THREE.Object3D} The resolved target object
502
+ * @private
503
+ */
504
+ }, {
505
+ key: "_resolveHierarchyTarget",
506
+ value: function _resolveHierarchyTarget(object) {
507
+ var _object$parent, _object$parent2, _object$userData;
508
+ // Keep connector orbs as direct targets
509
+ if (this.isConnectorOrb(object)) {
510
+ console.log('🔴 Connector orb clicked directly - using connector for transform controls');
511
+ return object;
512
+ }
513
+
514
+ // Look for component parent in hierarchy
515
+ if ((_object$parent = object.parent) !== null && _object$parent !== void 0 && (_object$parent = _object$parent.name) !== null && _object$parent !== void 0 && _object$parent.includes(' Component')) {
516
+ console.log('🎯 Using parent GLB model for transform controls');
517
+ return object.parent;
518
+ }
519
+ if ((_object$parent2 = object.parent) !== null && _object$parent2 !== void 0 && (_object$parent2 = _object$parent2.parent) !== null && _object$parent2 !== void 0 && (_object$parent2 = _object$parent2.name) !== null && _object$parent2 !== void 0 && _object$parent2.includes(' Component')) {
520
+ console.log('🎯 Using grandparent GLB model for transform controls');
521
+ return object.parent.parent;
522
+ }
523
+
524
+ // Debug logging for pipe segments
525
+ if ((_object$userData = object.userData) !== null && _object$userData !== void 0 && _object$userData.isPipeSegment) {
526
+ console.log('🔍 Found pipe segment in selection:', object.name, object.userData);
527
+ }
528
+ return object;
529
+ }
530
+
531
+ /**
532
+ * Check if an object is valid for selection (has required properties and is in scene)
533
+ * @param {THREE.Object3D} object - The object to validate
534
+ * @returns {boolean} Whether the object is valid for selection
535
+ * @private
536
+ */
537
+ }, {
538
+ key: "_isValidSelectableObject",
539
+ value: function _isValidSelectableObject(object) {
540
+ // Safety check: ensure object is still valid and in the scene
541
+ if (!object || !object.parent) {
542
+ console.warn('⚠️ Selected object is no longer valid or in scene');
543
+ return false;
544
+ }
545
+
546
+ // Verify object has all required Three.js properties
547
+ if (!object.position || !object.rotation || !object.scale || !object.updateMatrixWorld) {
548
+ console.warn('❌ Object missing required Three.js properties for transform controls');
549
+ return false;
550
+ }
551
+ return true;
552
+ }
553
+
554
+ /**
555
+ * Check if an object is a connector orb
556
+ * @param {THREE.Object3D} object - The object to check
557
+ * @returns {boolean} Whether the object is a connector orb
558
+ */
559
+ }, {
560
+ key: "isConnectorOrb",
561
+ value: function isConnectorOrb(object) {
562
+ // Basic safety checks
563
+ if (!object || !object.isObject3D) {
564
+ return false;
565
+ }
566
+
567
+ // Check if it's a mesh with connector geometry
568
+ if (!object.isMesh || !object.geometry) {
569
+ return false;
570
+ }
571
+
572
+ // Check for CONNECTOR-GEO geometry uuid
573
+ var hasConnectorGeometry = object.geometry.uuid === 'CONNECTOR-GEO';
574
+
575
+ // Check for SphereGeometry with radius 0.2
576
+ var isSphereConnector = object.geometry.type === 'SphereGeometry' && object.geometry.parameters && object.geometry.parameters.radius === 0.2;
577
+
578
+ // Check if name includes connector
579
+ var hasConnectorName = object.name && object.name.toLowerCase().includes('connector');
580
+ return (hasConnectorGeometry || isSphereConnector) && hasConnectorName;
581
+ }
582
+ /**
583
+ * Default object selection filter
584
+ * @param {THREE.Object3D} object - The object to check
585
+ * @returns {boolean} Whether the object can be selected
586
+ */
587
+ }, {
588
+ key: "isSelectableObject",
589
+ value: function isSelectableObject(object) {
590
+ var _object$userData2, _object$userData3, _object$userData4, _object$userData5, _object$userData6, _object$userData7, _object$userData8, _object$userData9;
591
+ // Basic safety checks
592
+ if (!object || !object.isObject3D) {
593
+ return false;
594
+ }
595
+
596
+ // Debug logging for pipe segments
597
+ if (object.userData && object.userData.isPipeSegment) {
598
+ console.log('🔍 Found pipe segment in selection check:', object.name, object.userData);
599
+ }
600
+
601
+ // Skip transform controls and their children
602
+ if (object.isTransformControls || object.isTransformControlsPlane || object.isTransformControlsGizmo) {
603
+ return false;
604
+ }
605
+
606
+ // Skip helpers and special objects
607
+ var isHelper = object.isHelper || ((_object$userData2 = object.userData) === null || _object$userData2 === void 0 ? void 0 : _object$userData2.isHelper) || ((_object$userData3 = object.userData) === null || _object$userData3 === void 0 ? void 0 : _object$userData3.isBoundingBox);
608
+ var isBaseGround = (_object$userData4 = object.userData) === null || _object$userData4 === void 0 ? void 0 : _object$userData4.isBaseGround;
609
+ var isBrickWall = (_object$userData5 = object.userData) === null || _object$userData5 === void 0 ? void 0 : _object$userData5.isBrickWall;
610
+ if (isHelper || isBaseGround || isBrickWall || !object.visible) {
611
+ return false;
612
+ }
613
+
614
+ // Allow pipe segments and junctions to be selected, but exclude parent polyline objects
615
+ if (object.name && object.name.toLowerCase().includes('polyline') && !((_object$userData6 = object.userData) !== null && _object$userData6 !== void 0 && _object$userData6.isPipeSegment) && !((_object$userData7 = object.userData) !== null && _object$userData7 !== void 0 && _object$userData7.isPipeJunction)) {
616
+ console.log('❌ Polyline parent object excluded from selection:', object.name);
617
+ return false;
618
+ }
619
+
620
+ // Check for pipe segments and junctions
621
+ var isPipeSegment = ((_object$userData8 = object.userData) === null || _object$userData8 === void 0 ? void 0 : _object$userData8.isPipeSegment) === true;
622
+ var isPipeJunction = ((_object$userData9 = object.userData) === null || _object$userData9 === void 0 ? void 0 : _object$userData9.isPipeJunction) === true;
623
+
624
+ // Check for GLB models
625
+ var isGLBModel = object.name && object.name.includes(' Component');
626
+
627
+ // Check for connector orbs
628
+ var isConnector = this.isConnectorOrb(object);
629
+ return isGLBModel || isConnector || isPipeSegment || isPipeJunction;
630
+ }
631
+ /**
632
+ * Select an object for transformation
633
+ * @param {THREE.Object3D} object - The object to select
634
+ */
635
+ }, {
636
+ key: "selectObject",
637
+ value: function selectObject(object) {
638
+ if (!object || !object.isObject3D) {
639
+ console.warn('⚠️ Invalid object provided for selection');
640
+ return false;
641
+ }
642
+ this.selectedObject = object;
643
+
644
+ // Force object matrix update to ensure correct transforms
645
+ object.updateMatrixWorld(true);
646
+
647
+ // Refresh bounding box cache for this object
648
+ var updatedBoundingBox = new THREE.Box3().setFromObject(object);
649
+ this.boundingBoxCache.set(object, updatedBoundingBox);
650
+
651
+ // Attach transform controls
652
+ this.transformControls.attach(object);
653
+
654
+ // Update interaction time to reset delay
655
+ if (this.transformControls.updateInteractionTime) {
656
+ this.transformControls.updateInteractionTime();
657
+ }
658
+
659
+ // Create and show bounding box if enabled
660
+ this.createBoundingBox(object);
661
+
662
+ // Only enable if not forcing invisibility
663
+ if (!this.forceInvisible) {
664
+ this.transformControls.enabled = this.config.enabled;
665
+ this._showTransformControls();
666
+ } else {
667
+ console.log('🔒 Transform controls kept invisible despite object selection');
668
+ this.transformControls.enabled = false;
669
+ this._hideTransformControls();
670
+ }
671
+
672
+ // Execute callback
673
+ if (this.callbacks.onObjectSelect) {
674
+ this.callbacks.onObjectSelect(object);
675
+ }
676
+ console.log("\uD83C\uDFAF Object selected: ".concat(object.name || object.uuid));
677
+ return true;
678
+ } /**
679
+ * Select object for transform controls and bounding box only (no tooltip callback)
680
+ * @param {THREE.Object3D} object - The object to select
681
+ * @returns {boolean} True if selection successful
682
+ */
683
+ }, {
684
+ key: "selectObjectForTransformOnly",
685
+ value: function selectObjectForTransformOnly(object) {
686
+ if (!object || !object.isObject3D) {
687
+ console.warn('⚠️ Invalid object provided for selection');
688
+ return false;
689
+ }
690
+ this.selectedObject = object;
691
+
692
+ // Force object matrix update to ensure correct transforms
693
+ object.updateMatrixWorld(true);
694
+
695
+ // Refresh bounding box cache for this object
696
+ var updatedBoundingBox = new THREE.Box3().setFromObject(object);
697
+ this.boundingBoxCache.set(object, updatedBoundingBox);
698
+
699
+ // Attach transform controls
700
+ this.transformControls.attach(object);
701
+
702
+ // Update interaction time to reset delay
703
+ if (this.transformControls.updateInteractionTime) {
704
+ this.transformControls.updateInteractionTime();
705
+ }
706
+
707
+ // Create and show bounding box if enabled
708
+ this.createBoundingBox(object);
709
+
710
+ // Only enable if not forcing invisibility
711
+ if (!this.forceInvisible) {
712
+ this.transformControls.enabled = true;
713
+ this._showTransformControls();
714
+ } else {
715
+ console.log('🔒 Transform controls kept invisible despite object selection');
716
+ this.transformControls.enabled = false;
717
+ this._hideTransformControls();
718
+ }
719
+
720
+ // NOTE: We deliberately do NOT call any callback here
721
+ // This allows transform controls and bounding box to show without triggering tooltips
722
+
723
+ console.log("\uD83C\uDFAF Object selected for transform only: ".concat(object.name || object.uuid));
724
+ return true;
725
+ }
726
+
727
+ /**
728
+ * Deselect the currently selected object
729
+ */
730
+ }, {
731
+ key: "deselectObject",
732
+ value: function deselectObject() {
733
+ if (this.selectedObject) {
734
+ console.log("\uD83D\uDD04 Object deselected: ".concat(this.selectedObject.name || this.selectedObject.uuid));
735
+ }
736
+
737
+ // Remove bounding box
738
+ this.removeBoundingBox();
739
+ this.selectedObject = null;
740
+ // Detach and hide transform controls
741
+ if (this.transformControls) {
742
+ // First detach from object
743
+ this.transformControls.detach();
744
+ this.transformControls.enabled = false;
745
+
746
+ // Properly hide all transform control components
747
+ this._hideTransformControls();
748
+ console.log("\uD83D\uDD12 Transform controls hidden after deselection");
749
+ }
750
+
751
+ // Execute callback
752
+ if (this.callbacks.onObjectSelect) {
753
+ this.callbacks.onObjectSelect(null);
754
+ }
755
+ }
756
+
757
+ /**
758
+ * Create and display a bounding box for the selected object
759
+ * @param {THREE.Object3D} object - The object to create a bounding box for
760
+ */
761
+ }, {
762
+ key: "createBoundingBox",
763
+ value: function createBoundingBox(object) {
764
+ // Skip if bounding box is disabled
765
+ if (!this.config.showBoundingBox) {
766
+ return;
767
+ }
768
+
769
+ // Remove any existing bounding box first
770
+ this.removeBoundingBox();
771
+ if (!object) {
772
+ return;
773
+ }
774
+ try {
775
+ // Create a BoxHelper to show the bounding box
776
+ this.boundingBoxHelper = new THREE.BoxHelper(object, this.config.boundingBoxColor);
777
+
778
+ // Mark it as a helper to avoid selection
779
+ this.boundingBoxHelper.isHelper = true;
780
+ this.boundingBoxHelper.userData = {
781
+ isBoundingBox: true
782
+ };
783
+ console.log("this.boundingBoxHelper object:", object);
784
+
785
+ // Add to scene
786
+ this.scene.add(this.boundingBoxHelper);
787
+ console.log("\uD83D\uDCE6 Bounding box created for: ".concat(object.name || object.uuid));
788
+ } catch (error) {
789
+ console.warn('⚠️ Failed to create bounding box:', error);
790
+ }
791
+ }
792
+
793
+ /**
794
+ * Remove the current bounding box helper
795
+ */
796
+ }, {
797
+ key: "removeBoundingBox",
798
+ value: function removeBoundingBox() {
799
+ if (this.boundingBoxHelper) {
800
+ try {
801
+ // Remove from scene
802
+ if (this.boundingBoxHelper.parent) {
803
+ this.boundingBoxHelper.parent.remove(this.boundingBoxHelper);
804
+ }
805
+
806
+ // Dispose geometry and material if they exist
807
+ if (this.boundingBoxHelper.geometry) {
808
+ this.boundingBoxHelper.geometry.dispose();
809
+ }
810
+ if (this.boundingBoxHelper.material) {
811
+ this.boundingBoxHelper.material.dispose();
812
+ }
813
+ console.log('📦 Bounding box removed');
814
+ } catch (error) {
815
+ console.warn('⚠️ Error removing bounding box:', error);
816
+ } finally {
817
+ this.boundingBoxHelper = null;
818
+ }
819
+ }
820
+ }
821
+
822
+ /**
823
+ * Update the bounding box to match the current object state
824
+ * Call this after any transformation to keep the bounding box in sync
825
+ */
826
+ }, {
827
+ key: "updateBoundingBox",
828
+ value: function updateBoundingBox() {
829
+ if (this.boundingBoxHelper && this.selectedObject) {
830
+ try {
831
+ // Force object matrix update to ensure correct bounding box
832
+ this.selectedObject.updateMatrixWorld(true);
833
+
834
+ // Update bounding box
835
+ this.boundingBoxHelper.update();
836
+
837
+ // Also update the cached bounding box if it exists
838
+ if (this.boundingBoxCache.has(this.selectedObject)) {
839
+ var updatedBoundingBox = new THREE.Box3().setFromObject(this.selectedObject);
840
+ this.boundingBoxCache.set(this.selectedObject, updatedBoundingBox);
841
+ }
842
+ } catch (error) {
843
+ console.warn('⚠️ Error updating bounding box:', error);
844
+ // If update fails, recreate the bounding box
845
+ this.createBoundingBox(this.selectedObject);
846
+ }
847
+ }
848
+ }
849
+
850
+ /**
851
+ * Set bounding box visibility
852
+ * @param {boolean} show - Whether to show the bounding box
853
+ */
854
+ }, {
855
+ key: "setBoundingBoxVisibility",
856
+ value: function setBoundingBoxVisibility(show) {
857
+ this.config.showBoundingBox = show;
858
+ if (show && this.selectedObject && !this.boundingBoxHelper) {
859
+ // Create bounding box if it doesn't exist and we have a selected object
860
+ this.createBoundingBox(this.selectedObject);
861
+ } else if (!show && this.boundingBoxHelper) {
862
+ // Remove bounding box if it exists and we're hiding it
863
+ this.removeBoundingBox();
864
+ }
865
+ console.log("\uD83D\uDCE6 Bounding box visibility: ".concat(show ? 'enabled' : 'disabled'));
866
+ }
867
+
868
+ /**
869
+ * Set bounding box color
870
+ * @param {number} color - The color value (hex)
871
+ */
872
+ }, {
873
+ key: "setBoundingBoxColor",
874
+ value: function setBoundingBoxColor(color) {
875
+ this.config.boundingBoxColor = color;
876
+
877
+ // Update existing bounding box color if it exists
878
+ if (this.boundingBoxHelper && this.boundingBoxHelper.material) {
879
+ this.boundingBoxHelper.material.color.setHex(color);
880
+ }
881
+ console.log("\uD83D\uDCE6 Bounding box color set to: 0x".concat(color.toString(16).padStart(6, '0')));
882
+ }
883
+
884
+ /**
885
+ * Set the transformation mode
886
+ * @param {'translate' | 'rotate' | 'scale'} mode - The transformation mode
887
+ */
888
+ }, {
889
+ key: "setMode",
890
+ value: function setMode(mode) {
891
+ if (!['translate', 'rotate', 'scale'].includes(mode)) {
892
+ console.warn("\u26A0\uFE0F Invalid transform mode: ".concat(mode));
893
+ return;
894
+ }
895
+ var previousMode = this.currentMode;
896
+ this.currentMode = mode;
897
+ this.transformControls.setMode(mode);
898
+
899
+ // Execute callback
900
+ if (this.callbacks.onModeChange) {
901
+ this.callbacks.onModeChange(mode, previousMode);
902
+ }
903
+ console.log("\uD83D\uDD27 Transform mode changed: ".concat(previousMode, " \u2192 ").concat(mode));
904
+ }
905
+
906
+ /**
907
+ * Set the transformation space
908
+ * @param {'world' | 'local'} space - The transformation space
909
+ */
910
+ }, {
911
+ key: "setSpace",
912
+ value: function setSpace(space) {
913
+ if (!['world', 'local'].includes(space)) {
914
+ console.warn("\u26A0\uFE0F Invalid transform space: ".concat(space));
915
+ return;
916
+ }
917
+ var previousSpace = this.currentSpace;
918
+ this.currentSpace = space;
919
+ this.transformControls.setSpace(space);
920
+ console.log("\uD83C\uDF10 Transform space changed: ".concat(previousSpace, " \u2192 ").concat(space));
921
+ }
922
+
923
+ /**
924
+ * Set axis constraint for transformations
925
+ * @param {'X' | 'Y' | 'Z'} axis - The axis to constrain to
926
+ */
927
+ }, {
928
+ key: "setAxisConstraint",
929
+ value: function setAxisConstraint(axis) {
930
+ if (!['X', 'Y', 'Z'].includes(axis)) {
931
+ console.warn("\u26A0\uFE0F Invalid axis constraint: ".concat(axis));
932
+ return;
933
+ }
934
+
935
+ // Reset all axes first
936
+ this.transformControls.showX = false;
937
+ this.transformControls.showY = false;
938
+ this.transformControls.showZ = false;
939
+
940
+ // Enable only the specified axis
941
+ this.transformControls["show".concat(axis)] = true;
942
+ console.log("\uD83D\uDD12 Axis constraint set: ".concat(axis, "-axis only"));
943
+ }
944
+
945
+ /**
946
+ * Clear axis constraints (show all axes)
947
+ */
948
+ }, {
949
+ key: "clearAxisConstraint",
950
+ value: function clearAxisConstraint() {
951
+ this.transformControls.showX = this.config.showX;
952
+ this.transformControls.showY = this.config.showY;
953
+ this.transformControls.showZ = this.config.showZ;
954
+ console.log('🔓 Axis constraints cleared');
955
+ }
956
+
957
+ /**
958
+ * Set snapping values for transformations
959
+ * @param {Object} snapConfig - Snap configuration
960
+ * @param {number} snapConfig.translation - Translation snap value
961
+ * @param {number} snapConfig.rotation - Rotation snap value (in radians)
962
+ * @param {number} snapConfig.scale - Scale snap value
963
+ */
964
+ }, {
965
+ key: "setSnap",
966
+ value: function setSnap() {
967
+ var snapConfig = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
968
+ if (snapConfig.translation !== undefined) {
969
+ this.config.translationSnap = snapConfig.translation;
970
+ this.transformControls.setTranslationSnap(snapConfig.translation);
971
+ }
972
+ if (snapConfig.rotation !== undefined) {
973
+ this.config.rotationSnap = snapConfig.rotation;
974
+ this.transformControls.setRotationSnap(snapConfig.rotation);
975
+ }
976
+ if (snapConfig.scale !== undefined) {
977
+ this.config.scaleSnap = snapConfig.scale;
978
+ this.transformControls.setScaleSnap(snapConfig.scale);
979
+ }
980
+ console.log('📏 Snap values updated:', snapConfig);
981
+ }
982
+
983
+ /**
984
+ * Get the current snap values
985
+ * @return {Object} The current snap values for translation, rotation, and scale
986
+ */
987
+ }, {
988
+ key: "snapValues",
989
+ get: function get() {
990
+ return {
991
+ translation: this.config.translationSnap || 0.5,
992
+ // Default to 0.5 if not set
993
+ rotation: this.config.rotationSnap || Math.PI / 2,
994
+ // Default to 90 degrees if not set
995
+ scale: this.config.scaleSnap || 0.1 // Default to 0.1 if not set
996
+ };
997
+ }
998
+
999
+ /**
1000
+ * Set the size of the transform controls
1001
+ * @param {number} size - The size of the transform controls
1002
+ */
1003
+ }, {
1004
+ key: "setSize",
1005
+ value: function setSize(size) {
1006
+ this.config.size = size;
1007
+ this.transformControls.setSize(size);
1008
+ console.log("\uD83D\uDCCF Transform controls size set to: ".concat(size));
1009
+ }
1010
+ /**
1011
+ * Enable or disable the transform controls
1012
+ * @param {boolean} enabled - Whether to enable the controls
1013
+ */
1014
+ }, {
1015
+ key: "setEnabled",
1016
+ value: function setEnabled(enabled) {
1017
+ this.config.enabled = enabled;
1018
+ if (this.selectedObject) {
1019
+ this.transformControls.enabled = enabled;
1020
+ }
1021
+ console.log("\uD83D\uDD04 Transform controls ".concat(enabled ? 'enabled' : 'disabled'));
1022
+ }
1023
+
1024
+ /**
1025
+ * Configure whether multi-axis plane helpers are shown
1026
+ * @param {boolean} showPlanes - Whether to show multi-axis translation planes (XY, YZ, XZ)
1027
+ */
1028
+ }, {
1029
+ key: "setShowPlanes",
1030
+ value: function setShowPlanes(showPlanes) {
1031
+ if (!this.transformControls) {
1032
+ console.warn('⚠️ Cannot configure plane helpers: transform controls not available');
1033
+ return false;
1034
+ }
1035
+
1036
+ // Set the plane visibility properties directly
1037
+ this.transformControls.showXY = showPlanes;
1038
+ this.transformControls.showYZ = showPlanes;
1039
+ this.transformControls.showXZ = showPlanes;
1040
+ console.log("\uD83D\uDD27 Multi-axis planes ".concat(showPlanes ? 'enabled' : 'disabled'));
1041
+ return true;
1042
+ }
1043
+ /**
1044
+ * Ensure transform controls are properly attached to the scene
1045
+ * This method helps recover from scene operations that might detach the controls
1046
+ */
1047
+ }, {
1048
+ key: "ensureSceneAttachment",
1049
+ value: function ensureSceneAttachment() {
1050
+ var allowVisible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
1051
+ // If transform controls don't exist, recreate them
1052
+ if (!this.transformControls && this.scene && this.camera && this.renderer) {
1053
+ console.log('🔧 Transform controls missing, recreating...');
1054
+ this.createTransformControls();
1055
+ this.setupEventListeners();
1056
+ console.log('✅ Transform controls recreated and attached to scene');
1057
+ if (!allowVisible) {
1058
+ this.transformControls.visible = false;
1059
+ console.log('🔧 Setting newly created transform controls to invisible');
1060
+ }
1061
+ return true;
1062
+ }
1063
+ if (!this.transformControls || !this.scene) {
1064
+ console.warn('⚠️ Cannot ensure attachment: missing transform controls or scene');
1065
+ return false;
1066
+ }
1067
+
1068
+ // Check if transform controls are still in the scene
1069
+ var isAttached = this.scene.children.includes(this.transformControls);
1070
+ if (!isAttached) {
1071
+ console.log('🔧 Re-attaching transform controls to scene...');
1072
+ this.scene.add(this.transformControls);
1073
+
1074
+ // Reset state after reattachment
1075
+ this.transformControls.enabled = false;
1076
+ if (this.selectedObject) {
1077
+ // If there was a selected object, reattach it
1078
+ this.transformControls.attach(this.selectedObject);
1079
+ this.transformControls.enabled = this.config.enabled;
1080
+ }
1081
+
1082
+ // Control visibility based on allowVisible parameter
1083
+ if (!allowVisible) {
1084
+ this.transformControls.visible = false;
1085
+ console.log('🔧 Keeping reattached transform controls invisible');
1086
+ }
1087
+ console.log('✅ Transform controls reattached to scene');
1088
+ return true;
1089
+ }
1090
+ // Only make visible if allowVisible is true
1091
+ if (!this.transformControls.visible && allowVisible) {
1092
+ console.log('🔧 Transform controls were invisible, making visible');
1093
+ this.transformControls.visible = true;
1094
+ return true;
1095
+ } else if (this.transformControls.visible && !allowVisible) {
1096
+ console.log('🔧 Transform controls were visible, making invisible');
1097
+ this.transformControls.visible = false;
1098
+ return true;
1099
+ }
1100
+
1101
+ // Check if the transform controls have a parent but it's not the scene
1102
+ if (this.transformControls.parent && this.transformControls.parent !== this.scene) {
1103
+ console.log('🔧 Transform controls have wrong parent, re-attaching to scene...');
1104
+ this.transformControls.parent.remove(this.transformControls);
1105
+ this.scene.add(this.transformControls);
1106
+ return true;
1107
+ }
1108
+ return false;
1109
+ }
1110
+
1111
+ /**
1112
+ * Get the current transformation data
1113
+ * @returns {Object} Current transformation state
1114
+ */
1115
+ }, {
1116
+ key: "getTransformData",
1117
+ value: function getTransformData() {
1118
+ if (!this.selectedObject) {
1119
+ return null;
1120
+ }
1121
+
1122
+ // Get local transforms (existing)
1123
+ var localTransforms = {
1124
+ position: this.selectedObject.position.clone(),
1125
+ rotation: this.selectedObject.rotation.clone(),
1126
+ scale: this.selectedObject.scale.clone()
1127
+ };
1128
+
1129
+ // Get world transforms (new)
1130
+ var worldTransforms = this.getWorldTransformData();
1131
+ return {
1132
+ object: this.selectedObject,
1133
+ position: localTransforms.position,
1134
+ rotation: localTransforms.rotation,
1135
+ scale: localTransforms.scale,
1136
+ worldPosition: worldTransforms.position,
1137
+ worldRotation: worldTransforms.rotation,
1138
+ worldScale: worldTransforms.scale,
1139
+ mode: this.currentMode,
1140
+ space: this.currentSpace,
1141
+ isTransforming: this.transformState.isTransforming
1142
+ };
1143
+ }
1144
+
1145
+ /**
1146
+ * Get world transformation data for the selected object
1147
+ * @returns {Object} World transformation data
1148
+ */
1149
+ }, {
1150
+ key: "getWorldTransformData",
1151
+ value: function getWorldTransformData() {
1152
+ if (!this.selectedObject) {
1153
+ return null;
1154
+ }
1155
+
1156
+ // Ensure the object's world matrix is up to date
1157
+ this.selectedObject.updateMatrixWorld(true);
1158
+
1159
+ // Get world position
1160
+ var worldPosition = new THREE.Vector3();
1161
+ this.selectedObject.getWorldPosition(worldPosition);
1162
+
1163
+ // Get world quaternion
1164
+ var worldQuaternion = new THREE.Quaternion();
1165
+ this.selectedObject.getWorldQuaternion(worldQuaternion);
1166
+
1167
+ // Convert quaternion to Euler rotation
1168
+ var worldRotation = new THREE.Euler();
1169
+ worldRotation.setFromQuaternion(worldQuaternion);
1170
+
1171
+ // Get world scale
1172
+ var worldScale = new THREE.Vector3();
1173
+ this.selectedObject.getWorldScale(worldScale);
1174
+ return {
1175
+ position: worldPosition,
1176
+ rotation: worldRotation,
1177
+ scale: worldScale
1178
+ };
1179
+ }
1180
+
1181
+ /**
1182
+ * Update object transform using world coordinates
1183
+ * @param {string} type - Transform type: 'position', 'rotation', 'scale'
1184
+ * @param {string} axis - Axis: 'x', 'y', 'z'
1185
+ * @param {number|string} value - The world coordinate value to set
1186
+ * @param {boolean} useWorldCoords - Whether to interpret the value as world coordinates
1187
+ */
1188
+ }, {
1189
+ key: "updateObjectTransform",
1190
+ value: function updateObjectTransform(type, axis, value) {
1191
+ var useWorldCoords = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
1192
+ if (!this.selectedObject) {
1193
+ console.warn('⚠️ No object selected for transformation');
1194
+ return;
1195
+ }
1196
+ var object = this.selectedObject;
1197
+ var numericValue = parseFloat(value);
1198
+ if (isNaN(numericValue)) {
1199
+ console.warn('⚠️ Invalid numeric value for transform:', value);
1200
+ return;
1201
+ }
1202
+ if (useWorldCoords) {
1203
+ // Update using world coordinates
1204
+ this.updateWorldTransform(object, type, axis, numericValue);
1205
+ } else {
1206
+ // Update using local coordinates (existing behavior)
1207
+ switch (type) {
1208
+ case 'position':
1209
+ object.position[axis] = numericValue;
1210
+ break;
1211
+ case 'rotation':
1212
+ // Convert from degrees to radians
1213
+ object.rotation[axis] = numericValue * (Math.PI / 180);
1214
+ break;
1215
+ case 'scale':
1216
+ object.scale[axis] = numericValue;
1217
+ break;
1218
+ default:
1219
+ console.warn("\u26A0\uFE0F Unknown transform type: ".concat(type));
1220
+ return;
1221
+ }
1222
+ } // Update transform controls to reflect the change
1223
+ if (this.transformControls) {
1224
+ this.transformControls.updateMatrixWorld();
1225
+ }
1226
+
1227
+ // Update bounding box to reflect the change
1228
+ this.updateBoundingBox();
1229
+ var coordType = useWorldCoords ? 'world' : 'local';
1230
+ console.log("\uD83D\uDD04 Updated ".concat(coordType, " ").concat(type, ".").concat(axis, " to ").concat(numericValue, " for ").concat(object.name));
1231
+ }
1232
+
1233
+ /**
1234
+ * Update object transform using world coordinates
1235
+ * @param {THREE.Object3D} object - The object to transform
1236
+ * @param {string} type - Transform type: 'position', 'rotation', 'scale'
1237
+ * @param {string} axis - Axis: 'x', 'y', 'z'
1238
+ * @param {number} worldValue - The world coordinate value
1239
+ */
1240
+ }, {
1241
+ key: "updateWorldTransform",
1242
+ value: function updateWorldTransform(object, type, axis, worldValue) {
1243
+ // Ensure matrices are up to date
1244
+ object.updateMatrixWorld(true);
1245
+ switch (type) {
1246
+ case 'position':
1247
+ this.setWorldPosition(object, axis, worldValue);
1248
+ break;
1249
+ case 'rotation':
1250
+ this.setWorldRotation(object, axis, worldValue);
1251
+ break;
1252
+ case 'scale':
1253
+ this.setWorldScale(object, axis, worldValue);
1254
+ break;
1255
+ default:
1256
+ console.warn("\u26A0\uFE0F Unknown transform type: ".concat(type));
1257
+ }
1258
+ }
1259
+
1260
+ /**
1261
+ * Set world position for a specific axis
1262
+ * @param {THREE.Object3D} object - The object
1263
+ * @param {string} axis - The axis ('x', 'y', or 'z')
1264
+ * @param {number} worldValue - The world position value
1265
+ */
1266
+ }, {
1267
+ key: "setWorldPosition",
1268
+ value: function setWorldPosition(object, axis, worldValue) {
1269
+ // Get current world position
1270
+ var currentWorldPos = new THREE.Vector3();
1271
+ object.getWorldPosition(currentWorldPos);
1272
+
1273
+ // Update the specific axis
1274
+ currentWorldPos[axis] = worldValue;
1275
+
1276
+ // Convert world position back to local position
1277
+ if (object.parent) {
1278
+ var parentMatrixInverse = new THREE.Matrix4();
1279
+ parentMatrixInverse.copy(object.parent.matrixWorld).invert();
1280
+ currentWorldPos.applyMatrix4(parentMatrixInverse);
1281
+ }
1282
+
1283
+ // Set the local position
1284
+ object.position.copy(currentWorldPos);
1285
+ }
1286
+
1287
+ /**
1288
+ * Set world rotation for a specific axis
1289
+ * @param {THREE.Object3D} object - The object
1290
+ * @param {string} axis - The axis ('x', 'y', or 'z')
1291
+ * @param {number} worldValue - The world rotation value in degrees
1292
+ */
1293
+ }, {
1294
+ key: "setWorldRotation",
1295
+ value: function setWorldRotation(object, axis, worldValue) {
1296
+ // Get current world quaternion
1297
+ var currentWorldQuat = new THREE.Quaternion();
1298
+ object.getWorldQuaternion(currentWorldQuat);
1299
+
1300
+ // Convert to Euler
1301
+ var currentWorldEuler = new THREE.Euler();
1302
+ currentWorldEuler.setFromQuaternion(currentWorldQuat);
1303
+
1304
+ // Update the specific axis (convert degrees to radians)
1305
+ currentWorldEuler[axis] = worldValue * (Math.PI / 180);
1306
+
1307
+ // Convert back to quaternion
1308
+ var newWorldQuat = new THREE.Quaternion();
1309
+ newWorldQuat.setFromEuler(currentWorldEuler);
1310
+
1311
+ // Convert world quaternion back to local rotation
1312
+ if (object.parent) {
1313
+ var parentWorldQuat = new THREE.Quaternion();
1314
+ object.parent.getWorldQuaternion(parentWorldQuat);
1315
+ parentWorldQuat.invert();
1316
+ newWorldQuat.premultiply(parentWorldQuat);
1317
+ }
1318
+
1319
+ // Set the local rotation
1320
+ object.quaternion.copy(newWorldQuat);
1321
+ }
1322
+
1323
+ /**
1324
+ * Set world scale for a specific axis
1325
+ * @param {THREE.Object3D} object - The object
1326
+ * @param {string} axis - The axis ('x', 'y', or 'z')
1327
+ * @param {number} worldValue - The world scale value
1328
+ */
1329
+ }, {
1330
+ key: "setWorldScale",
1331
+ value: function setWorldScale(object, axis, worldValue) {
1332
+ // Get current world scale
1333
+ var currentWorldScale = new THREE.Vector3();
1334
+ object.getWorldScale(currentWorldScale);
1335
+
1336
+ // Calculate the scale factor needed
1337
+ var scaleFactor = worldValue / currentWorldScale[axis];
1338
+
1339
+ // Apply to local scale
1340
+ object.scale[axis] *= scaleFactor;
1341
+ }
1342
+ /**
1343
+ * Get selectable objects with their bounding boxes for ray intersection testing
1344
+ * @param {Function} objectFilter - Optional function to filter selectable objects
1345
+ * @returns {Array} Array of objects with their bounding boxes
1346
+ */
1347
+ }, {
1348
+ key: "getSelectableObjectsWithBounds",
1349
+ value: function getSelectableObjectsWithBounds() {
1350
+ var _this4 = this;
1351
+ var objectFilter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
1352
+ var objectsWithBounds = [];
1353
+
1354
+ // Traverse scene to find selectable objects
1355
+ this.scene.traverse(function (object) {
1356
+ var _object$userData0, _object$userData1;
1357
+ // Skip invalid objects and helpers early
1358
+ if (!object || !object.isObject3D) {
1359
+ return;
1360
+ }
1361
+
1362
+ // Skip transform controls and their children
1363
+ if (object.isTransformControls || object.isTransformControlsPlane || object.isTransformControlsGizmo) {
1364
+ return;
1365
+ }
1366
+
1367
+ // Skip other helpers and special objects
1368
+ if (object.isHelper || (_object$userData0 = object.userData) !== null && _object$userData0 !== void 0 && _object$userData0.isHelper || (_object$userData1 = object.userData) !== null && _object$userData1 !== void 0 && _object$userData1.isBoundingBox) {
1369
+ return;
1370
+ }
1371
+ try {
1372
+ // Apply filter (use provided filter or default isSelectableObject method)
1373
+ var isSelectable = objectFilter ? objectFilter(object) : _this4.isSelectableObject(object);
1374
+ if (isSelectable) {
1375
+ // Force object matrix update to ensure correct bounding box
1376
+ object.updateMatrixWorld(true);
1377
+
1378
+ // Get or compute bounding box
1379
+ var boundingBox = _this4.boundingBoxCache.get(object);
1380
+
1381
+ // Always recompute bounding box for recently transformed objects
1382
+ // or if no cached bounding box exists
1383
+ if (!boundingBox || object === _this4.selectedObject) {
1384
+ // Compute and cache bounding box
1385
+ boundingBox = new THREE.Box3().setFromObject(object);
1386
+ _this4.boundingBoxCache.set(object, boundingBox);
1387
+ }
1388
+ objectsWithBounds.push({
1389
+ object: object,
1390
+ boundingBox: boundingBox
1391
+ });
1392
+ }
1393
+ } catch (error) {
1394
+ // Silently skip objects that cause errors during filtering
1395
+ console.warn('⚠️ Skipping object due to filter error:', object.type || 'unknown', error.message);
1396
+ }
1397
+ });
1398
+ return objectsWithBounds;
1399
+ }
1400
+
1401
+ /**
1402
+ * Test ray intersection with object bounding boxes
1403
+ * @param {THREE.Raycaster} raycaster - The raycaster to test intersections with
1404
+ * @param {Function} objectFilter - Optional function to filter selectable objects
1405
+ * @returns {Array} Array of intersection results sorted by distance
1406
+ */
1407
+ }, {
1408
+ key: "intersectObjectsBoundingBoxes",
1409
+ value: function intersectObjectsBoundingBoxes(raycaster) {
1410
+ var objectFilter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
1411
+ var objectsWithBounds = this.getSelectableObjectsWithBounds(objectFilter);
1412
+ var intersections = [];
1413
+ var _iterator = _createForOfIteratorHelper(objectsWithBounds),
1414
+ _step;
1415
+ try {
1416
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
1417
+ var item = _step.value;
1418
+ var object = item.object,
1419
+ boundingBox = item.boundingBox;
1420
+
1421
+ // Test ray intersection with bounding box
1422
+ var intersection = raycaster.ray.intersectBox(boundingBox, new THREE.Vector3());
1423
+ if (intersection) {
1424
+ // Calculate distance from ray origin to intersection point
1425
+ var distance = raycaster.ray.origin.distanceTo(intersection);
1426
+ intersections.push({
1427
+ object: object,
1428
+ point: intersection,
1429
+ distance: distance,
1430
+ boundingBox: boundingBox
1431
+ });
1432
+ }
1433
+ }
1434
+
1435
+ // Sort by distance (closest first)
1436
+ } catch (err) {
1437
+ _iterator.e(err);
1438
+ } finally {
1439
+ _iterator.f();
1440
+ }
1441
+ intersections.sort(function (a, b) {
1442
+ return a.distance - b.distance;
1443
+ });
1444
+ return intersections;
1445
+ }
1446
+
1447
+ /**
1448
+ * Toggle between bounding box-based and mesh-based selection
1449
+ * @param {boolean} useBoundingBox - Whether to use bounding box selection
1450
+ */
1451
+ }, {
1452
+ key: "setBoundingBoxSelection",
1453
+ value: function setBoundingBoxSelection(useBoundingBox) {
1454
+ this.config.useBoundingBoxSelection = useBoundingBox;
1455
+ console.log("\uD83C\uDFAF Selection method: ".concat(useBoundingBox ? 'Bounding Box' : 'Mesh-based'));
1456
+ }
1457
+
1458
+ /**
1459
+ * Handle object removal when backspace is pressed
1460
+ */
1461
+ }, {
1462
+ key: "handleObjectRemoval",
1463
+ value: function handleObjectRemoval() {
1464
+ var _this$selectedObject$;
1465
+ if (!this.selectedObject) {
1466
+ return;
1467
+ }
1468
+
1469
+ // Check if the object is a gateway
1470
+ if (((_this$selectedObject$ = this.selectedObject.userData) === null || _this$selectedObject$ === void 0 ? void 0 : _this$selectedObject$.componentType) === 'gateway') {
1471
+ console.log('🔧 Gateway detected - converting from declared to computed');
1472
+ this.handleGatewayRemoval();
1473
+ }
1474
+ }
1475
+
1476
+ /**
1477
+ * Handle gateway removal by converting from declared to computed
1478
+ */
1479
+ }, {
1480
+ key: "handleGatewayRemoval",
1481
+ value: function handleGatewayRemoval() {
1482
+ var _gateway$userData;
1483
+ var gateway = this.selectedObject;
1484
+
1485
+ // Store gateway information before removal
1486
+ var gatewayInfo = {
1487
+ uuid: gateway.uuid,
1488
+ userData: _objectSpread2({}, gateway.userData),
1489
+ position: gateway.position.clone(),
1490
+ connections: ((_gateway$userData = gateway.userData) === null || _gateway$userData === void 0 ? void 0 : _gateway$userData.connections) || null
1491
+ };
1492
+ console.log('🔧 Converting gateway from declared to computed:', gatewayInfo);
1493
+
1494
+ // Change origin from 'declared' to 'computed'
1495
+ gateway.userData.origin = 'computed';
1496
+
1497
+ // Deselect the object
1498
+ this.deselectObject();
1499
+
1500
+ // Emit the object removed event
1501
+ if (this.callbacks.onObjectRemoved) {
1502
+ this.callbacks.onObjectRemoved(gatewayInfo);
1503
+ }
1504
+ }
1505
+
1506
+ /**
1507
+ * Cleanup and dispose of the transform controls
1508
+ */
1509
+ }, {
1510
+ key: "dispose",
1511
+ value: function dispose() {
1512
+ // Remove event listeners
1513
+ if (this.eventHandlers.keydown) {
1514
+ window.removeEventListener('keydown', this.eventHandlers.keydown);
1515
+ }
1516
+ if (this.eventHandlers.click) {
1517
+ this.renderer.domElement.removeEventListener('click', this.eventHandlers.click);
1518
+ }
1519
+
1520
+ // Remove bounding box helper
1521
+ this.removeBoundingBox();
1522
+
1523
+ // Deselect any object first
1524
+ if (this.selectedObject) {
1525
+ this.deselectObject();
1526
+ }
1527
+
1528
+ // Dispose transform controls
1529
+ if (this.transformControls) {
1530
+ // Remove event listeners from transform controls
1531
+ if (this.eventHandlers.transformStart) {
1532
+ this.transformControls.removeEventListener('mouseDown', this.eventHandlers.transformStart);
1533
+ }
1534
+ if (this.eventHandlers.transformEnd) {
1535
+ this.transformControls.removeEventListener('mouseUp', this.eventHandlers.transformEnd);
1536
+ }
1537
+ if (this.eventHandlers.transforming) {
1538
+ this.transformControls.removeEventListener('objectChange', this.eventHandlers.transforming);
1539
+ }
1540
+
1541
+ // Detach from any objects
1542
+ this.transformControls.detach();
1543
+
1544
+ // Remove from scene if still attached
1545
+ if (this.scene && this.transformControls.parent === this.scene) {
1546
+ this.scene.remove(this.transformControls);
1547
+ }
1548
+
1549
+ // Dispose and null the reference
1550
+ this.transformControls.dispose();
1551
+ this.transformControls = null;
1552
+ }
1553
+
1554
+ // Clear references - but keep scene, camera, and renderer references for reuse
1555
+ this.selectedObject = null;
1556
+ // Don't null these out: this.scene, this.camera, this.renderer
1557
+ this.orbitControls = null;
1558
+ console.log('🧹 Transform controls disposed');
1559
+ }
1560
+ /**
1561
+ * Force hide the transform controls (debugging method)
1562
+ */
1563
+ }, {
1564
+ key: "forceHide",
1565
+ value: function forceHide() {
1566
+ if (this.transformControls) {
1567
+ this._hideTransformControls();
1568
+ this.transformControls.enabled = false;
1569
+ console.log('🔒 Transform controls force hidden');
1570
+ }
1571
+ }
1572
+
1573
+ /**
1574
+ * Properly hide transform controls including all child components
1575
+ * @private
1576
+ */
1577
+ }, {
1578
+ key: "_hideTransformControls",
1579
+ value: function _hideTransformControls() {
1580
+ if (!this.transformControls) return;
1581
+
1582
+ // Hide main transform controls
1583
+ this.transformControls.visible = false;
1584
+
1585
+ // Also hide gizmo and plane components explicitly
1586
+ if (this.transformControls._gizmo) {
1587
+ this.transformControls._gizmo.visible = false;
1588
+ }
1589
+ if (this.transformControls._plane) {
1590
+ this.transformControls._plane.visible = false;
1591
+ }
1592
+ }
1593
+
1594
+ /**
1595
+ * Properly show transform controls including all child components
1596
+ * @private
1597
+ */
1598
+ }, {
1599
+ key: "_showTransformControls",
1600
+ value: function _showTransformControls() {
1601
+ if (!this.transformControls) return;
1602
+
1603
+ // Show main transform controls
1604
+ this.transformControls.visible = true;
1605
+
1606
+ // Also show gizmo and plane components explicitly
1607
+ if (this.transformControls._gizmo) {
1608
+ this.transformControls._gizmo.visible = true;
1609
+ }
1610
+ if (this.transformControls._plane) {
1611
+ this.transformControls._plane.visible = true;
1612
+ }
1613
+ }
1614
+
1615
+ /**
1616
+ * Check the current visibility state of transform controls (debugging method)
1617
+ */
1618
+ }, {
1619
+ key: "getVisibilityState",
1620
+ value: function getVisibilityState() {
1621
+ var _this$selectedObject3;
1622
+ if (!this.transformControls) {
1623
+ return {
1624
+ exists: false
1625
+ };
1626
+ }
1627
+ return {
1628
+ exists: true,
1629
+ visible: this.transformControls.visible,
1630
+ enabled: this.transformControls.enabled,
1631
+ gizmoVisible: this.transformControls._gizmo ? this.transformControls._gizmo.visible : 'N/A',
1632
+ planeVisible: this.transformControls._plane ? this.transformControls._plane.visible : 'N/A',
1633
+ hasSelectedObject: !!this.selectedObject,
1634
+ selectedObjectName: ((_this$selectedObject3 = this.selectedObject) === null || _this$selectedObject3 === void 0 ? void 0 : _this$selectedObject3.name) || 'none'
1635
+ };
1636
+ }
1637
+ /**
1638
+ * Force hide all gizmo components to prevent any visibility override
1639
+ * This is necessary because Three.js TransformControls has internal logic that can show gizmos
1640
+ */
1641
+ }, {
1642
+ key: "_forceHideAllGizmoComponents",
1643
+ value: function _forceHideAllGizmoComponents() {
1644
+ if (!this.transformControls || !this.transformControls._gizmo) {
1645
+ return;
1646
+ }
1647
+ var gizmo = this.transformControls._gizmo;
1648
+
1649
+ // Hide main gizmo
1650
+ gizmo.visible = false;
1651
+
1652
+ // Hide all mode-specific gizmos
1653
+ if (gizmo.gizmo) {
1654
+ Object.keys(gizmo.gizmo).forEach(function (mode) {
1655
+ if (gizmo.gizmo[mode]) {
1656
+ gizmo.gizmo[mode].visible = false;
1657
+ }
1658
+ });
1659
+ }
1660
+
1661
+ // Hide all helpers
1662
+ if (gizmo.helper) {
1663
+ Object.keys(gizmo.helper).forEach(function (mode) {
1664
+ if (gizmo.helper[mode]) {
1665
+ gizmo.helper[mode].visible = false;
1666
+ }
1667
+ });
1668
+ }
1669
+
1670
+ // Also hide the plane
1671
+ if (this.transformControls._plane) {
1672
+ this.transformControls._plane.visible = false;
1673
+ }
1674
+ console.log('🔒 All gizmo components force hidden');
1675
+ }
1676
+
1677
+ /**
1678
+ * Hide multi-axis plane helpers (XY, YZ, XZ) to only allow single-axis translation
1679
+ * @private
1680
+ */
1681
+ }, {
1682
+ key: "_hidePlaneHelpers",
1683
+ value: function _hidePlaneHelpers() {
1684
+ console.log('🔧 _hidePlaneHelpers called');
1685
+ if (!this.transformControls) {
1686
+ console.warn('⚠️ Cannot hide plane helpers: transform controls not available');
1687
+ return;
1688
+ }
1689
+ if (!this.transformControls._gizmo) {
1690
+ console.warn('⚠️ Cannot hide plane helpers: gizmo not available');
1691
+ return;
1692
+ }
1693
+ var gizmo = this.transformControls._gizmo;
1694
+ console.log('🔍 Gizmo structure:', {
1695
+ hasGizmo: !!gizmo.gizmo,
1696
+ hasTranslate: !!(gizmo.gizmo && gizmo.gizmo.translate),
1697
+ hasPicker: !!gizmo.picker,
1698
+ hasTranslatePicker: !!(gizmo.picker && gizmo.picker.translate)
1699
+ });
1700
+ var hiddenCount = 0;
1701
+
1702
+ // Hide plane helpers in translate gizmo
1703
+ if (gizmo.gizmo && gizmo.gizmo.translate) {
1704
+ var translateGizmo = gizmo.gizmo.translate;
1705
+ console.log('🔍 Translate gizmo children count:', translateGizmo.children.length);
1706
+ translateGizmo.traverse(function (child) {
1707
+ if (child.name === 'XY' || child.name === 'YZ' || child.name === 'XZ') {
1708
+ child.visible = false;
1709
+ hiddenCount++;
1710
+ console.log("\uD83D\uDD12 Hidden plane helper: ".concat(child.name));
1711
+ }
1712
+ });
1713
+ }
1714
+
1715
+ // Hide plane helpers in translate picker
1716
+ if (gizmo.picker && gizmo.picker.translate) {
1717
+ var translatePicker = gizmo.picker.translate;
1718
+ console.log('🔍 Translate picker children count:', translatePicker.children.length);
1719
+ translatePicker.traverse(function (child) {
1720
+ if (child.name === 'XY' || child.name === 'YZ' || child.name === 'XZ') {
1721
+ child.visible = false;
1722
+ hiddenCount++;
1723
+ console.log("\uD83D\uDD12 Hidden plane picker: ".concat(child.name));
1724
+ }
1725
+ });
1726
+ }
1727
+ console.log("\u2705 Multi-axis plane helpers hidden - total hidden: ".concat(hiddenCount));
1728
+ }
1729
+
1730
+ /**
1731
+ * Show multi-axis plane helpers (XY, YZ, XZ) to allow multi-axis translation
1732
+ * @private
1733
+ */
1734
+ }, {
1735
+ key: "_showPlaneHelpers",
1736
+ value: function _showPlaneHelpers() {
1737
+ if (!this.transformControls || !this.transformControls._gizmo) {
1738
+ console.warn('⚠️ Cannot show plane helpers: transform controls or gizmo not available');
1739
+ return;
1740
+ }
1741
+ var gizmo = this.transformControls._gizmo;
1742
+
1743
+ // Show plane helpers in translate gizmo
1744
+ if (gizmo.gizmo && gizmo.gizmo.translate) {
1745
+ var translateGizmo = gizmo.gizmo.translate;
1746
+ translateGizmo.traverse(function (child) {
1747
+ if (child.name === 'XY' || child.name === 'YZ' || child.name === 'XZ') {
1748
+ child.visible = true;
1749
+ console.log("\uD83D\uDC41\uFE0F Shown plane helper: ".concat(child.name));
1750
+ }
1751
+ });
1752
+ }
1753
+
1754
+ // Show plane helpers in translate picker
1755
+ if (gizmo.picker && gizmo.picker.translate) {
1756
+ var translatePicker = gizmo.picker.translate;
1757
+ translatePicker.traverse(function (child) {
1758
+ if (child.name === 'XY' || child.name === 'YZ' || child.name === 'XZ') {
1759
+ child.visible = true;
1760
+ console.log("\uD83D\uDC41\uFE0F Shown plane picker: ".concat(child.name));
1761
+ }
1762
+ });
1763
+ }
1764
+ console.log('✅ Multi-axis plane helpers shown - multi-axis translation enabled');
1765
+ }
1766
+ }]);
1767
+ }();
1768
+
1769
+ /**
1770
+ * Utility function to create a transform controls manager
1771
+ * @param {THREE.Scene} scene - The Three.js scene
1772
+ * @param {THREE.Camera} camera - The camera
1773
+ * @param {THREE.WebGLRenderer} renderer - The renderer
1774
+ * @param {OrbitControls} orbitControls - Optional orbit controls to disable during transformation
1775
+ * @returns {TransformControlsManager} Transform controls manager instance
1776
+ */
1777
+ function createTransformControls(scene, camera, renderer) {
1778
+ var orbitControls = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
1779
+ return new TransformControlsManager(scene, camera, renderer, orbitControls);
1780
+ }
1781
+
1782
+ export { TransformControlsManager, createTransformControls };