@2112-lab/central-plant 0.1.0

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 (54) hide show
  1. package/README.md +0 -0
  2. package/dist/bundle/index.js +14259 -0
  3. package/dist/cjs/_virtual/_rollupPluginBabelHelpers.js +353 -0
  4. package/dist/cjs/node_modules/three/examples/jsm/controls/OrbitControls.js +1292 -0
  5. package/dist/cjs/node_modules/three/examples/jsm/controls/TransformControls.js +1543 -0
  6. package/dist/cjs/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4374 -0
  7. package/dist/cjs/node_modules/three/examples/jsm/loaders/RGBELoader.js +465 -0
  8. package/dist/cjs/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +117 -0
  9. package/dist/cjs/src/ConnectionManager.js +114 -0
  10. package/dist/cjs/src/Pathfinder.js +88 -0
  11. package/dist/cjs/src/animationManager.js +121 -0
  12. package/dist/cjs/src/componentManager.js +151 -0
  13. package/dist/cjs/src/debugLogger.js +176 -0
  14. package/dist/cjs/src/disposalManager.js +185 -0
  15. package/dist/cjs/src/environmentManager.js +1015 -0
  16. package/dist/cjs/src/hotReloadManager.js +252 -0
  17. package/dist/cjs/src/index.js +126 -0
  18. package/dist/cjs/src/keyboardControlsManager.js +206 -0
  19. package/dist/cjs/src/modelPreloader.js +360 -0
  20. package/dist/cjs/src/nameUtils.js +106 -0
  21. package/dist/cjs/src/pathfindingManager.js +321 -0
  22. package/dist/cjs/src/performanceMonitor.js +718 -0
  23. package/dist/cjs/src/sceneExportManager.js +292 -0
  24. package/dist/cjs/src/sceneInitializationManager.js +540 -0
  25. package/dist/cjs/src/sceneOperationsManager.js +560 -0
  26. package/dist/cjs/src/textureConfig.js +195 -0
  27. package/dist/cjs/src/transformControlsManager.js +851 -0
  28. package/dist/esm/_virtual/_rollupPluginBabelHelpers.js +328 -0
  29. package/dist/esm/node_modules/three/examples/jsm/controls/OrbitControls.js +1287 -0
  30. package/dist/esm/node_modules/three/examples/jsm/controls/TransformControls.js +1537 -0
  31. package/dist/esm/node_modules/three/examples/jsm/loaders/GLTFLoader.js +4370 -0
  32. package/dist/esm/node_modules/three/examples/jsm/loaders/RGBELoader.js +461 -0
  33. package/dist/esm/node_modules/three/examples/jsm/utils/BufferGeometryUtils.js +113 -0
  34. package/dist/esm/src/ConnectionManager.js +110 -0
  35. package/dist/esm/src/Pathfinder.js +84 -0
  36. package/dist/esm/src/animationManager.js +112 -0
  37. package/dist/esm/src/componentManager.js +123 -0
  38. package/dist/esm/src/debugLogger.js +167 -0
  39. package/dist/esm/src/disposalManager.js +155 -0
  40. package/dist/esm/src/environmentManager.js +989 -0
  41. package/dist/esm/src/hotReloadManager.js +244 -0
  42. package/dist/esm/src/index.js +117 -0
  43. package/dist/esm/src/keyboardControlsManager.js +196 -0
  44. package/dist/esm/src/modelPreloader.js +337 -0
  45. package/dist/esm/src/nameUtils.js +99 -0
  46. package/dist/esm/src/pathfindingManager.js +295 -0
  47. package/dist/esm/src/performanceMonitor.js +712 -0
  48. package/dist/esm/src/sceneExportManager.js +286 -0
  49. package/dist/esm/src/sceneInitializationManager.js +513 -0
  50. package/dist/esm/src/sceneOperationsManager.js +536 -0
  51. package/dist/esm/src/textureConfig.js +168 -0
  52. package/dist/esm/src/transformControlsManager.js +827 -0
  53. package/dist/index.d.ts +259 -0
  54. package/package.json +53 -0
@@ -0,0 +1,827 @@
1
+ import { createClass as _createClass, classCallCheck as _classCallCheck, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../_virtual/_rollupPluginBabelHelpers.js';
2
+
3
+ /**
4
+ * Transform Controls Manager for Three.js
5
+ * Provides modular object transformation capabilities with position, rotation, and scale controls
6
+ */
7
+
8
+ var THREE;
9
+ var TransformControls;
10
+
11
+ /**
12
+ * Dynamically import ThreeJS and TransformControls when in browser environment
13
+ */
14
+ function importDependencies() {
15
+ return _importDependencies.apply(this, arguments);
16
+ }
17
+ /**
18
+ * Class for managing object transform controls in a 3D scene
19
+ */
20
+ function _importDependencies() {
21
+ _importDependencies = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
22
+ var transformModule, customModule, _t2;
23
+ return _regenerator().w(function (_context2) {
24
+ while (1) switch (_context2.n) {
25
+ case 0:
26
+ if (!(typeof window !== 'undefined')) {
27
+ _context2.n = 9;
28
+ break;
29
+ }
30
+ _context2.p = 1;
31
+ _context2.n = 2;
32
+ return import('three');
33
+ case 2:
34
+ THREE = _context2.v;
35
+ _context2.p = 3;
36
+ _context2.n = 4;
37
+ return import('../node_modules/three/examples/jsm/controls/TransformControls.js');
38
+ case 4:
39
+ transformModule = _context2.v;
40
+ TransformControls = transformModule.TransformControls;
41
+ _context2.n = 7;
42
+ break;
43
+ case 5:
44
+ _context2.p = 5;
45
+ _context2.v;
46
+ console.log('Using fallback path for TransformControls');
47
+ // Fallback to the custom plugin path if available
48
+ if (!(typeof window.__transformControlsCustomPath === 'string')) {
49
+ _context2.n = 7;
50
+ break;
51
+ }
52
+ _context2.n = 6;
53
+ return import(window.__transformControlsCustomPath);
54
+ case 6:
55
+ customModule = _context2.v;
56
+ TransformControls = customModule.TransformControls;
57
+ case 7:
58
+ _context2.n = 9;
59
+ break;
60
+ case 8:
61
+ _context2.p = 8;
62
+ _t2 = _context2.v;
63
+ console.error('Failed to load Transform Controls dependencies:', _t2);
64
+ throw new Error('TransformControlsManager: Required dependencies could not be loaded');
65
+ case 9:
66
+ return _context2.a(2);
67
+ }
68
+ }, _callee2, null, [[3, 5], [1, 8]]);
69
+ }));
70
+ return _importDependencies.apply(this, arguments);
71
+ }
72
+ var TransformControlsManager = /*#__PURE__*/function () {
73
+ /**
74
+ * Create a TransformControlsManager
75
+ * @param {THREE.Scene} scene - The Three.js scene
76
+ * @param {THREE.Camera} camera - The Three.js camera
77
+ * @param {THREE.WebGLRenderer} renderer - The Three.js renderer
78
+ * @param {THREE.OrbitControls} orbitControls - Optional orbit controls for camera
79
+ */
80
+ function TransformControlsManager(scene, camera, renderer) {
81
+ var _this = this;
82
+ var orbitControls = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
83
+ _classCallCheck(this, TransformControlsManager);
84
+ this.scene = scene;
85
+ this.camera = camera;
86
+ this.renderer = renderer;
87
+ this.orbitControls = orbitControls;
88
+
89
+ // Transform control instance
90
+ this.transformControls = null;
91
+
92
+ // Bounding box helper for visual feedback
93
+ this.boundingBoxHelper = null;
94
+
95
+ // Cache for object bounding boxes to improve performance
96
+ this.boundingBoxCache = new WeakMap();
97
+
98
+ // Currently selected object
99
+ this.selectedObject = null;
100
+
101
+ // Transform mode: 'translate', 'rotate', 'scale'
102
+ this.currentMode = 'translate';
103
+
104
+ // Transform space: 'world' or 'local'
105
+ this.currentSpace = 'world';
106
+
107
+ // Flag to force controls to stay invisible (used during scene loading)
108
+ this.forceInvisible = false;
109
+
110
+ // Event handlers storage
111
+ this.eventHandlers = {
112
+ keydown: null,
113
+ pointerdown: null,
114
+ pointerup: null,
115
+ transformStart: null,
116
+ transformEnd: null,
117
+ transforming: null
118
+ };
119
+
120
+ // Transform state tracking
121
+ this.transformState = {
122
+ isTransforming: false,
123
+ initialTransform: null,
124
+ currentTransform: null
125
+ };
126
+
127
+ // Configuration options
128
+ this.config = {
129
+ size: 1,
130
+ enabled: true,
131
+ showX: true,
132
+ showY: true,
133
+ showZ: true,
134
+ snap: null,
135
+ // Snap value for transformations
136
+ translationSnap: null,
137
+ rotationSnap: null,
138
+ scaleSnap: null,
139
+ showBoundingBox: true,
140
+ // Show bounding box on selection
141
+ boundingBoxColor: 0x00ff00,
142
+ // Green bounding box by default
143
+ useBoundingBoxSelection: true // Use bounding box-based selection instead of mesh selection
144
+ };
145
+
146
+ // Callbacks for external event handling
147
+ this.callbacks = {
148
+ onObjectSelect: null,
149
+ onTransformStart: null,
150
+ onTransform: null,
151
+ onTransformEnd: null,
152
+ onModeChange: null
153
+ };
154
+
155
+ // Initialize asynchronously if needed
156
+ if (typeof window !== 'undefined') {
157
+ importDependencies().then(function () {
158
+ return _this.init();
159
+ });
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Initialize the transform controls
165
+ */
166
+ return _createClass(TransformControlsManager, [{
167
+ key: "init",
168
+ value: (function () {
169
+ var _init = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
170
+ return _regenerator().w(function (_context) {
171
+ while (1) switch (_context.n) {
172
+ case 0:
173
+ if (!(typeof window !== 'undefined' && !THREE)) {
174
+ _context.n = 1;
175
+ break;
176
+ }
177
+ _context.n = 1;
178
+ return importDependencies();
179
+ case 1:
180
+ this.createTransformControls();
181
+ this.setupEventListeners();
182
+ this.setupKeyboardControls();
183
+ case 2:
184
+ return _context.a(2);
185
+ }
186
+ }, _callee, this);
187
+ }));
188
+ function init() {
189
+ return _init.apply(this, arguments);
190
+ }
191
+ return init;
192
+ }()
193
+ /**
194
+ * Register event callbacks
195
+ * @param {Object} callbacks - Object containing callback functions
196
+ */
197
+ )
198
+ }, {
199
+ key: "on",
200
+ value: function on(callbacks) {
201
+ if (callbacks.onObjectSelect) {
202
+ this.callbacks.onObjectSelect = callbacks.onObjectSelect;
203
+ }
204
+ if (callbacks.onTransformStart) {
205
+ this.callbacks.onTransformStart = callbacks.onTransformStart;
206
+ }
207
+ if (callbacks.onTransform) {
208
+ this.callbacks.onTransform = callbacks.onTransform;
209
+ }
210
+ if (callbacks.onTransformEnd) {
211
+ this.callbacks.onTransformEnd = callbacks.onTransformEnd;
212
+ }
213
+ if (callbacks.onModeChange) {
214
+ this.callbacks.onModeChange = callbacks.onModeChange;
215
+ }
216
+ }
217
+
218
+ /**
219
+ * Create transform controls and add to scene
220
+ */
221
+ }, {
222
+ key: "createTransformControls",
223
+ value: function createTransformControls() {
224
+ // Ensure THREE and TransformControls are available
225
+ if (!THREE || !TransformControls) {
226
+ console.warn('TransformControls cannot be created - THREE.js not loaded');
227
+ return;
228
+ }
229
+
230
+ // Create transform controls if they don't exist
231
+ if (!this.transformControls) {
232
+ this.transformControls = new TransformControls(this.camera, this.renderer.domElement);
233
+ this.transformControls.size = this.config.size;
234
+ this.transformControls.enabled = this.config.enabled;
235
+ this.transformControls.visible = this.config.enabled && !this.forceInvisible;
236
+
237
+ // Set initial mode
238
+ this.transformControls.setMode(this.currentMode);
239
+ this.transformControls.setSpace(this.currentSpace);
240
+
241
+ // Mark with userData for easy identification
242
+ this.transformControls.userData = {
243
+ isTransformControls: true
244
+ };
245
+
246
+ // Add to scene
247
+ this.scene.add(this.transformControls);
248
+ console.log('✅ Transform controls created and added to scene');
249
+ }
250
+ }
251
+
252
+ /**
253
+ * Set up event listeners for transform controls
254
+ */
255
+ }, {
256
+ key: "setupEventListeners",
257
+ value: function setupEventListeners() {
258
+ var _this2 = this;
259
+ if (!this.transformControls) return;
260
+
261
+ // Clean up any existing listeners to avoid duplicates
262
+ this.removeEventListeners();
263
+
264
+ // Event handler for transform start
265
+ this.eventHandlers.transformStart = function (event) {
266
+ _this2.transformState.isTransforming = true;
267
+ if (_this2.selectedObject) {
268
+ // Store initial transform for history/undo purposes
269
+ _this2.transformState.initialTransform = _this2.captureObjectTransform(_this2.selectedObject);
270
+
271
+ // Notify via callback if registered
272
+ if (_this2.callbacks.onTransformStart) {
273
+ _this2.callbacks.onTransformStart(_this2.selectedObject, _this2.transformState.initialTransform);
274
+ }
275
+ }
276
+ };
277
+
278
+ // Event handler for transform changes
279
+ this.eventHandlers.transforming = function (event) {
280
+ if (_this2.selectedObject && _this2.transformState.isTransforming) {
281
+ // Capture current transform
282
+ _this2.transformState.currentTransform = _this2.captureObjectTransform(_this2.selectedObject);
283
+
284
+ // Notify via callback if registered
285
+ if (_this2.callbacks.onTransform) {
286
+ _this2.callbacks.onTransform(_this2.selectedObject, _this2.transformState.currentTransform, _this2.transformState.initialTransform);
287
+ }
288
+
289
+ // Update bounding box if shown
290
+ _this2.updateBoundingBox();
291
+ }
292
+ };
293
+
294
+ // Event handler for transform end
295
+ this.eventHandlers.transformEnd = function (event) {
296
+ if (_this2.selectedObject) {
297
+ // Capture final transform
298
+ var finalTransform = _this2.captureObjectTransform(_this2.selectedObject);
299
+
300
+ // Notify via callback if registered
301
+ if (_this2.callbacks.onTransformEnd) {
302
+ _this2.callbacks.onTransformEnd(_this2.selectedObject, finalTransform, _this2.transformState.initialTransform);
303
+ }
304
+ }
305
+ _this2.transformState.isTransforming = false;
306
+ };
307
+
308
+ // Attach event listeners to transform controls
309
+ this.transformControls.addEventListener('mouseDown', this.eventHandlers.transformStart);
310
+ this.transformControls.addEventListener('objectChange', this.eventHandlers.transforming);
311
+ this.transformControls.addEventListener('mouseUp', this.eventHandlers.transformEnd);
312
+
313
+ // Disable orbit controls during transform (if orbit controls provided)
314
+ if (this.orbitControls) {
315
+ this.transformControls.addEventListener('dragging-changed', function (event) {
316
+ _this2.orbitControls.enabled = !event.value;
317
+ });
318
+ }
319
+ }
320
+
321
+ /**
322
+ * Set up keyboard controls for transform operations
323
+ */
324
+ }, {
325
+ key: "setupKeyboardControls",
326
+ value: function setupKeyboardControls() {
327
+ var _this3 = this;
328
+ // Skip if not in browser environment
329
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
330
+ return;
331
+ }
332
+
333
+ // Clean up any existing listeners first
334
+ if (this.eventHandlers.keydown) {
335
+ document.removeEventListener('keydown', this.eventHandlers.keydown);
336
+ }
337
+
338
+ // Keydown handler for keyboard shortcuts
339
+ this.eventHandlers.keydown = function (event) {
340
+ if (!_this3.config.enabled || !_this3.selectedObject) return;
341
+ switch (event.key.toLowerCase()) {
342
+ case 'g':
343
+ // Translate mode (grab)
344
+ _this3.setMode('translate');
345
+ break;
346
+ case 'r':
347
+ // Rotate mode
348
+ _this3.setMode('rotate');
349
+ break;
350
+ case 's':
351
+ // Scale mode
352
+ _this3.setMode('scale');
353
+ break;
354
+ case ' ':
355
+ // Toggle visibility
356
+ _this3.toggleVisibility();
357
+ break;
358
+ case 'escape':
359
+ // Deselect object
360
+ _this3.deselectObject();
361
+ break;
362
+ case 'x':
363
+ // X-axis constraint
364
+ if (event.shiftKey) {
365
+ // Shift + X to toggle X controls
366
+ _this3.config.showX = !_this3.config.showX;
367
+ _this3.updateAxisVisibility();
368
+ } else {
369
+ _this3.transformControls.showX = true;
370
+ _this3.transformControls.showY = false;
371
+ _this3.transformControls.showZ = false;
372
+ }
373
+ break;
374
+ case 'y':
375
+ // Y-axis constraint
376
+ if (event.shiftKey) {
377
+ // Shift + Y to toggle Y controls
378
+ _this3.config.showY = !_this3.config.showY;
379
+ _this3.updateAxisVisibility();
380
+ } else {
381
+ _this3.transformControls.showX = false;
382
+ _this3.transformControls.showY = true;
383
+ _this3.transformControls.showZ = false;
384
+ }
385
+ break;
386
+ case 'z':
387
+ // Z-axis constraint
388
+ if (event.shiftKey) {
389
+ // Shift + Z to toggle Z controls
390
+ _this3.config.showZ = !_this3.config.showZ;
391
+ _this3.updateAxisVisibility();
392
+ } else {
393
+ _this3.transformControls.showX = false;
394
+ _this3.transformControls.showY = false;
395
+ _this3.transformControls.showZ = true;
396
+ }
397
+ break;
398
+ case 'q':
399
+ // Toggle world/local space
400
+ _this3.toggleSpace();
401
+ break;
402
+ }
403
+ };
404
+
405
+ // Add keyboard event listener
406
+ document.addEventListener('keydown', this.eventHandlers.keydown);
407
+ }
408
+
409
+ /**
410
+ * Remove all event listeners
411
+ */
412
+ }, {
413
+ key: "removeEventListeners",
414
+ value: function removeEventListeners() {
415
+ if (this.transformControls) {
416
+ // Remove transform control event listeners
417
+ this.transformControls.removeEventListener('mouseDown', this.eventHandlers.transformStart);
418
+ this.transformControls.removeEventListener('objectChange', this.eventHandlers.transforming);
419
+ this.transformControls.removeEventListener('mouseUp', this.eventHandlers.transformEnd);
420
+ }
421
+
422
+ // Remove document event listeners if in browser
423
+ if (typeof document !== 'undefined') {
424
+ if (this.eventHandlers.keydown) {
425
+ document.removeEventListener('keydown', this.eventHandlers.keydown);
426
+ }
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Select an object for transformation
432
+ * @param {THREE.Object3D} object - The object to transform
433
+ */
434
+ }, {
435
+ key: "selectObject",
436
+ value: function selectObject(object) {
437
+ if (!this.config.enabled || !this.transformControls || !object) return;
438
+
439
+ // Deselect current object if any
440
+ this.deselectObject();
441
+
442
+ // Set new selected object
443
+ this.selectedObject = object;
444
+ this.transformControls.attach(object);
445
+
446
+ // Show bounding box if enabled
447
+ if (this.config.showBoundingBox) {
448
+ this.showBoundingBox(object);
449
+ }
450
+
451
+ // Notify via callback if registered
452
+ if (this.callbacks.onObjectSelect) {
453
+ this.callbacks.onObjectSelect(object, true);
454
+ }
455
+
456
+ // Make controls visible if not forced invisible
457
+ if (!this.forceInvisible) {
458
+ this.transformControls.visible = true;
459
+ }
460
+ return object;
461
+ }
462
+
463
+ /**
464
+ * Deselect the currently selected object
465
+ */
466
+ }, {
467
+ key: "deselectObject",
468
+ value: function deselectObject() {
469
+ if (this.selectedObject) {
470
+ // Detach from transform controls
471
+ if (this.transformControls) {
472
+ this.transformControls.detach();
473
+ }
474
+
475
+ // Hide bounding box
476
+ this.hideBoundingBox();
477
+
478
+ // Notify via callback if registered
479
+ if (this.callbacks.onObjectSelect) {
480
+ this.callbacks.onObjectSelect(this.selectedObject, false);
481
+ }
482
+
483
+ // Clear selection
484
+ var previousSelection = this.selectedObject;
485
+ this.selectedObject = null;
486
+
487
+ // Ensure transform controls are removed from scene
488
+ this.ensureSceneAttachment(false);
489
+ return previousSelection;
490
+ }
491
+ return null;
492
+ }
493
+
494
+ /**
495
+ * Set transformation mode
496
+ * @param {string} mode - The transform mode ('translate', 'rotate', or 'scale')
497
+ */
498
+ }, {
499
+ key: "setMode",
500
+ value: function setMode(mode) {
501
+ if (!this.transformControls) return;
502
+ if (['translate', 'rotate', 'scale'].includes(mode)) {
503
+ this.currentMode = mode;
504
+ this.transformControls.setMode(mode);
505
+
506
+ // Update snap values based on mode
507
+ switch (mode) {
508
+ case 'translate':
509
+ this.transformControls.setTranslationSnap(this.config.translationSnap);
510
+ break;
511
+ case 'rotate':
512
+ this.transformControls.setRotationSnap(this.config.rotationSnap);
513
+ break;
514
+ case 'scale':
515
+ this.transformControls.setScaleSnap(this.config.scaleSnap);
516
+ break;
517
+ }
518
+
519
+ // Notify via callback if registered
520
+ if (this.callbacks.onModeChange) {
521
+ this.callbacks.onModeChange(mode);
522
+ }
523
+ }
524
+ }
525
+
526
+ /**
527
+ * Toggle coordinate space between world and local
528
+ */
529
+ }, {
530
+ key: "toggleSpace",
531
+ value: function toggleSpace() {
532
+ if (!this.transformControls) return;
533
+ this.currentSpace = this.currentSpace === 'world' ? 'local' : 'world';
534
+ this.transformControls.setSpace(this.currentSpace);
535
+ }
536
+
537
+ /**
538
+ * Toggle visibility of transform controls
539
+ */
540
+ }, {
541
+ key: "toggleVisibility",
542
+ value: function toggleVisibility() {
543
+ if (!this.transformControls) return;
544
+ if (!this.forceInvisible) {
545
+ this.transformControls.visible = !this.transformControls.visible;
546
+ }
547
+ }
548
+
549
+ /**
550
+ * Set enabled state of transform controls
551
+ * @param {boolean} enabled - Whether transform controls should be enabled
552
+ */
553
+ }, {
554
+ key: "setEnabled",
555
+ value: function setEnabled(enabled) {
556
+ this.config.enabled = enabled;
557
+ if (this.transformControls) {
558
+ this.transformControls.enabled = enabled;
559
+ if (!enabled) {
560
+ this.deselectObject();
561
+ this.transformControls.visible = false;
562
+ } else if (this.selectedObject && !this.forceInvisible) {
563
+ this.transformControls.visible = true;
564
+ }
565
+ }
566
+ }
567
+
568
+ /**
569
+ * Update axis visibility based on config
570
+ */
571
+ }, {
572
+ key: "updateAxisVisibility",
573
+ value: function updateAxisVisibility() {
574
+ if (!this.transformControls) return;
575
+ this.transformControls.showX = this.config.showX;
576
+ this.transformControls.showY = this.config.showY;
577
+ this.transformControls.showZ = this.config.showZ;
578
+ }
579
+
580
+ /**
581
+ * Show bounding box for an object
582
+ * @param {THREE.Object3D} object - The object to show bounding box for
583
+ */
584
+ }, {
585
+ key: "showBoundingBox",
586
+ value: function showBoundingBox(object) {
587
+ if (!object || !THREE) return;
588
+ this.hideBoundingBox();
589
+
590
+ // Get bounding box (from cache or compute it)
591
+ var boundingBox = this.boundingBoxCache.get(object);
592
+ if (!boundingBox) {
593
+ boundingBox = new THREE.Box3().setFromObject(object);
594
+ this.boundingBoxCache.set(object, boundingBox);
595
+ }
596
+
597
+ // Create helper if needed
598
+ if (!this.boundingBoxHelper) {
599
+ this.boundingBoxHelper = new THREE.Box3Helper(boundingBox, this.config.boundingBoxColor);
600
+ this.scene.add(this.boundingBoxHelper);
601
+ } else {
602
+ this.boundingBoxHelper.box = boundingBox;
603
+ }
604
+
605
+ // Store bounding box in object userData for easy access
606
+ object.userData.worldBoundingBox = boundingBox;
607
+ }
608
+
609
+ /**
610
+ * Hide bounding box helper
611
+ */
612
+ }, {
613
+ key: "hideBoundingBox",
614
+ value: function hideBoundingBox() {
615
+ if (this.boundingBoxHelper) {
616
+ this.scene.remove(this.boundingBoxHelper);
617
+ this.boundingBoxHelper = null;
618
+ }
619
+ }
620
+
621
+ /**
622
+ * Update bounding box for selected object
623
+ */
624
+ }, {
625
+ key: "updateBoundingBox",
626
+ value: function updateBoundingBox() {
627
+ if (this.selectedObject && this.config.showBoundingBox) {
628
+ // Update bounding box to reflect current transform
629
+ var boundingBox = new THREE.Box3().setFromObject(this.selectedObject);
630
+
631
+ // Update cache
632
+ this.boundingBoxCache.set(this.selectedObject, boundingBox);
633
+
634
+ // Update helper if exists
635
+ if (this.boundingBoxHelper) {
636
+ this.boundingBoxHelper.box = boundingBox;
637
+ }
638
+
639
+ // Update userData
640
+ this.selectedObject.userData.worldBoundingBox = boundingBox;
641
+ }
642
+ }
643
+
644
+ /**
645
+ * Capture object transformation data
646
+ * @param {THREE.Object3D} object - The object to capture transform from
647
+ * @returns {Object} Object containing position, rotation and scale data
648
+ */
649
+ }, {
650
+ key: "captureObjectTransform",
651
+ value: function captureObjectTransform(object) {
652
+ if (!object) return null;
653
+ return {
654
+ position: {
655
+ x: object.position.x,
656
+ y: object.position.y,
657
+ z: object.position.z
658
+ },
659
+ rotation: {
660
+ x: object.rotation.x,
661
+ y: object.rotation.y,
662
+ z: object.rotation.z
663
+ },
664
+ scale: {
665
+ x: object.scale.x,
666
+ y: object.scale.y,
667
+ z: object.scale.z
668
+ }
669
+ };
670
+ }
671
+
672
+ /**
673
+ * Set snap values for transformations
674
+ * @param {Object} options - Snap options
675
+ * @param {number} options.translation - Translation snap value
676
+ * @param {number} options.rotation - Rotation snap value in degrees
677
+ * @param {number} options.scale - Scale snap value
678
+ */
679
+ }, {
680
+ key: "setSnapValues",
681
+ value: function setSnapValues() {
682
+ var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
683
+ if (!this.transformControls) return;
684
+ if (options.translation !== undefined) {
685
+ this.config.translationSnap = options.translation;
686
+ if (this.currentMode === 'translate') {
687
+ this.transformControls.setTranslationSnap(options.translation);
688
+ }
689
+ }
690
+ if (options.rotation !== undefined) {
691
+ // Convert degrees to radians for rotation snap
692
+ var rotationSnapRadians = options.rotation * (Math.PI / 180);
693
+ this.config.rotationSnap = rotationSnapRadians;
694
+ if (this.currentMode === 'rotate') {
695
+ this.transformControls.setRotationSnap(rotationSnapRadians);
696
+ }
697
+ }
698
+ if (options.scale !== undefined) {
699
+ this.config.scaleSnap = options.scale;
700
+ if (this.currentMode === 'scale') {
701
+ this.transformControls.setScaleSnap(options.scale);
702
+ }
703
+ }
704
+ }
705
+
706
+ /**
707
+ * Set size of transform controls
708
+ * @param {number} size - The size factor for transform controls
709
+ */
710
+ }, {
711
+ key: "setSize",
712
+ value: function setSize(size) {
713
+ this.config.size = size;
714
+ if (this.transformControls) {
715
+ this.transformControls.size = size;
716
+ }
717
+ }
718
+
719
+ /**
720
+ * Clean up resources and remove event listeners
721
+ */
722
+ }, {
723
+ key: "dispose",
724
+ value: function dispose() {
725
+ this.removeEventListeners();
726
+ this.hideBoundingBox();
727
+ if (this.transformControls) {
728
+ this.transformControls.detach();
729
+ this.scene.remove(this.transformControls);
730
+ this.transformControls = null;
731
+ }
732
+
733
+ // Clear references
734
+ this.selectedObject = null;
735
+ this.boundingBoxCache = new WeakMap();
736
+ console.log('🧹 TransformControlsManager disposed');
737
+ }
738
+
739
+ /**
740
+ * Ensures transform controls are properly attached to the scene
741
+ * @param {boolean} allowVisible - Whether to allow controls to be visible when reattached
742
+ * @returns {boolean} - True if controls were reattached, false if already attached
743
+ */
744
+ }, {
745
+ key: "ensureSceneAttachment",
746
+ value: function ensureSceneAttachment() {
747
+ var allowVisible = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
748
+ if (!this.transformControls || !this.scene) return false;
749
+
750
+ // Check if the controls are already in the scene
751
+ var isInScene = this.scene.children.includes(this.transformControls);
752
+ if (!isInScene) {
753
+ // Reattach to scene
754
+ this.scene.add(this.transformControls);
755
+
756
+ // Set visibility based on allowVisible parameter and forceInvisible flag
757
+ this.transformControls.visible = allowVisible && !this.forceInvisible && this.config.enabled;
758
+ return true; // Controls were reattached
759
+ }
760
+ return false; // Already properly attached
761
+ }
762
+
763
+ /**
764
+ * Get current transform data for the selected object
765
+ * @returns {Object|null} Object containing position, rotation, scale, and world coordinates
766
+ */
767
+ }, {
768
+ key: "getTransformData",
769
+ value: function getTransformData() {
770
+ if (!this.selectedObject) return null;
771
+ var worldPosition = new THREE.Vector3();
772
+ this.selectedObject.getWorldPosition(worldPosition);
773
+ var worldQuaternion = new THREE.Quaternion();
774
+ this.selectedObject.getWorldQuaternion(worldQuaternion);
775
+ var worldEuler = new THREE.Euler().setFromQuaternion(worldQuaternion);
776
+ var worldScale = new THREE.Vector3();
777
+ this.selectedObject.getWorldScale(worldScale);
778
+ return {
779
+ uuid: this.selectedObject.uuid,
780
+ position: {
781
+ x: this.selectedObject.position.x,
782
+ y: this.selectedObject.position.y,
783
+ z: this.selectedObject.position.z
784
+ },
785
+ rotation: {
786
+ x: this.selectedObject.rotation.x,
787
+ y: this.selectedObject.rotation.y,
788
+ z: this.selectedObject.rotation.z
789
+ },
790
+ scale: {
791
+ x: this.selectedObject.scale.x,
792
+ y: this.selectedObject.scale.y,
793
+ z: this.selectedObject.scale.z
794
+ },
795
+ worldPosition: {
796
+ x: worldPosition.x,
797
+ y: worldPosition.y,
798
+ z: worldPosition.z
799
+ },
800
+ worldRotation: {
801
+ x: worldEuler.x,
802
+ y: worldEuler.y,
803
+ z: worldEuler.z
804
+ },
805
+ worldScale: {
806
+ x: worldScale.x,
807
+ y: worldScale.y,
808
+ z: worldScale.z
809
+ }
810
+ };
811
+ }
812
+ }]);
813
+ }();
814
+
815
+ /**
816
+ * Factory function to get TransformControlsManager instance
817
+ * @param {THREE.Scene} scene - The Three.js scene
818
+ * @param {THREE.Camera} camera - The Three.js camera
819
+ * @param {THREE.WebGLRenderer} renderer - The Three.js renderer
820
+ * @param {THREE.OrbitControls} orbitControls - Optional orbit controls for camera
821
+ * @returns {TransformControlsManager} TransformControlsManager instance
822
+ */
823
+ function getTransformControlsManager(scene, camera, renderer, orbitControls) {
824
+ return new TransformControlsManager(scene, camera, renderer, orbitControls);
825
+ }
826
+
827
+ export { TransformControlsManager, TransformControlsManager as default, getTransformControlsManager };