@2112-lab/central-plant 0.3.12 → 0.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bundle/index.js +2736 -2643
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +12 -6
- package/dist/cjs/src/managers/scene/viewport2DManager.js +186 -102
- package/dist/cjs/src/utils/boundingBoxUtils.js +6 -1
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +12 -6
- package/dist/esm/src/managers/scene/viewport2DManager.js +186 -103
- package/dist/esm/src/utils/boundingBoxUtils.js +6 -1
- package/package.json +1 -1
|
@@ -3,6 +3,29 @@ import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
|
3
3
|
import * as THREE from 'three';
|
|
4
4
|
import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* WeakMap cache for storing base position data per Object3D.
|
|
8
|
+
* Used by _getOrComputeWorldBoundingBox() for O(1) bbox offset calculations.
|
|
9
|
+
* WeakMap ensures automatic cleanup when objects are garbage collected.
|
|
10
|
+
* @type {WeakMap<THREE.Object3D, {x: number, y: number, z: number, worldBoundingBox: {min: number[], max: number[]}}>}
|
|
11
|
+
*/
|
|
12
|
+
var _basePositionCache = new WeakMap();
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Store base position and worldBoundingBox for an Object3D.
|
|
16
|
+
* Called by modelManager after GLB loading to enable fast bbox updates.
|
|
17
|
+
* @param {THREE.Object3D} object - The loaded GLB model
|
|
18
|
+
* @param {{min: number[], max: number[]}} worldBoundingBox - Computed world bounding box
|
|
19
|
+
*/
|
|
20
|
+
function cacheBasePosition(object, worldBoundingBox) {
|
|
21
|
+
_basePositionCache.set(object, {
|
|
22
|
+
x: object.position.x,
|
|
23
|
+
y: object.position.y,
|
|
24
|
+
z: object.position.z,
|
|
25
|
+
worldBoundingBox: worldBoundingBox
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
6
29
|
/**
|
|
7
30
|
* Viewport2DInstance
|
|
8
31
|
* Represents a single 2D viewport with its own Konva stage and configuration
|
|
@@ -99,6 +122,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
99
122
|
// stacking up independent renderComponents() runs
|
|
100
123
|
_this2._refreshPending = false;
|
|
101
124
|
|
|
125
|
+
// Set of viewport keys pending refresh (collects keys across multiple refresh() calls in same frame)
|
|
126
|
+
_this2._pendingRefreshKeys = new Set();
|
|
127
|
+
|
|
102
128
|
// Event listener reference for cleanup
|
|
103
129
|
_this2._objectTransformedListener = null;
|
|
104
130
|
console.log('🔲 Viewport2DManager initialized (multi-instance support)');
|
|
@@ -188,8 +214,10 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
188
214
|
viewport._instanceKey = key;
|
|
189
215
|
this.viewports.set(key, viewport);
|
|
190
216
|
|
|
191
|
-
// Initialize the stage for this viewport
|
|
192
|
-
|
|
217
|
+
// Initialize the stage for this viewport (waits for DOM layout to settle)
|
|
218
|
+
_context.n = 4;
|
|
219
|
+
return this.initializeStage(viewport);
|
|
220
|
+
case 4:
|
|
193
221
|
return _context.a(2, viewport.isReady);
|
|
194
222
|
}
|
|
195
223
|
}, _callee, this);
|
|
@@ -283,50 +311,67 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
283
311
|
/**
|
|
284
312
|
* Initialize Konva stage for a specific viewport instance
|
|
285
313
|
* @param {Viewport2DInstance} viewport - The viewport instance to initialize
|
|
314
|
+
* @returns {Promise<void>} Resolves when viewport is fully ready
|
|
286
315
|
*/
|
|
287
316
|
)
|
|
288
317
|
}, {
|
|
289
318
|
key: "initializeStage",
|
|
290
319
|
value: function initializeStage(viewport) {
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
var width = rect.width || 800;
|
|
299
|
-
var height = rect.height || 600;
|
|
300
|
-
console.log("\uD83D\uDCD0 Initializing Konva stage (".concat(viewport.viewType, "): ").concat(width, "x").concat(height));
|
|
301
|
-
|
|
302
|
-
// Create Konva stage for this viewport
|
|
303
|
-
viewport.stage = new this.Konva.Stage({
|
|
304
|
-
container: viewport.container,
|
|
305
|
-
width: width,
|
|
306
|
-
height: height
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
// Create separate layers for grid and components
|
|
310
|
-
viewport.gridLayer = new this.Konva.Layer();
|
|
311
|
-
viewport.componentLayer = new this.Konva.Layer();
|
|
312
|
-
|
|
313
|
-
// Add layers to stage in order (grid first, then components)
|
|
314
|
-
viewport.stage.add(viewport.gridLayer);
|
|
315
|
-
viewport.stage.add(viewport.componentLayer);
|
|
316
|
-
|
|
317
|
-
// Setup resize handling
|
|
318
|
-
this.setupResizeListener(viewport);
|
|
319
|
-
|
|
320
|
-
// Setup zoom and pan handlers
|
|
321
|
-
this.setupZoomAndPanHandlers(viewport);
|
|
320
|
+
var _this4 = this;
|
|
321
|
+
return new Promise(function (resolve) {
|
|
322
|
+
if (!_this4.Konva || !viewport.container) {
|
|
323
|
+
console.error('❌ Cannot initialize stage: Konva or container missing');
|
|
324
|
+
resolve();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
322
327
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
328
|
+
// Get container dimensions
|
|
329
|
+
var rect = viewport.container.getBoundingClientRect();
|
|
330
|
+
var width = rect.width || 800;
|
|
331
|
+
var height = rect.height || 600;
|
|
332
|
+
console.log("\uD83D\uDCD0 Initializing Konva stage (".concat(viewport.viewType, "): ").concat(width, "x").concat(height));
|
|
333
|
+
|
|
334
|
+
// Create Konva stage for this viewport
|
|
335
|
+
viewport.stage = new _this4.Konva.Stage({
|
|
336
|
+
container: viewport.container,
|
|
337
|
+
width: width,
|
|
338
|
+
height: height
|
|
339
|
+
});
|
|
326
340
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
341
|
+
// Create separate layers for grid and components
|
|
342
|
+
viewport.gridLayer = new _this4.Konva.Layer();
|
|
343
|
+
viewport.componentLayer = new _this4.Konva.Layer();
|
|
344
|
+
|
|
345
|
+
// Add layers to stage in order (grid first, then components)
|
|
346
|
+
viewport.stage.add(viewport.gridLayer);
|
|
347
|
+
viewport.stage.add(viewport.componentLayer);
|
|
348
|
+
|
|
349
|
+
// Setup resize handling
|
|
350
|
+
_this4.setupResizeListener(viewport);
|
|
351
|
+
|
|
352
|
+
// Setup zoom and pan handlers
|
|
353
|
+
_this4.setupZoomAndPanHandlers(viewport);
|
|
354
|
+
|
|
355
|
+
// Draw initial grid (lightweight, safe to do immediately)
|
|
356
|
+
_this4.drawGrid(viewport);
|
|
357
|
+
|
|
358
|
+
// Defer component rendering to next frame to ensure DOM layout is finalized.
|
|
359
|
+
// Without this, getBoundingClientRect() may return stale/zero dimensions
|
|
360
|
+
// if the container hasn't been fully laid out by CSS yet.
|
|
361
|
+
requestAnimationFrame(function () {
|
|
362
|
+
// Re-check container dimensions after layout settles
|
|
363
|
+
var finalRect = viewport.container.getBoundingClientRect();
|
|
364
|
+
if (finalRect.width > 0 && finalRect.height > 0) {
|
|
365
|
+
viewport.stage.width(finalRect.width);
|
|
366
|
+
viewport.stage.height(finalRect.height);
|
|
367
|
+
_this4.drawGrid(viewport);
|
|
368
|
+
}
|
|
369
|
+
_this4.renderComponents(viewport);
|
|
370
|
+
viewport.isReady = true;
|
|
371
|
+
console.log("\u2705 Viewport2DManager stage initialized (".concat(viewport.viewType, ")"));
|
|
372
|
+
resolve();
|
|
373
|
+
});
|
|
374
|
+
});
|
|
330
375
|
}
|
|
331
376
|
|
|
332
377
|
/**
|
|
@@ -336,12 +381,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
336
381
|
}, {
|
|
337
382
|
key: "setupResizeListener",
|
|
338
383
|
value: function setupResizeListener(viewport) {
|
|
339
|
-
var
|
|
384
|
+
var _this5 = this;
|
|
340
385
|
if (typeof window === 'undefined' || !window.ResizeObserver || !viewport.container) {
|
|
341
386
|
return;
|
|
342
387
|
}
|
|
343
388
|
viewport._resizeObserver = new ResizeObserver(function () {
|
|
344
|
-
|
|
389
|
+
_this5.resizeStage(viewport);
|
|
345
390
|
});
|
|
346
391
|
viewport._resizeObserver.observe(viewport.container);
|
|
347
392
|
}
|
|
@@ -376,7 +421,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
376
421
|
}, {
|
|
377
422
|
key: "setupZoomAndPanHandlers",
|
|
378
423
|
value: function setupZoomAndPanHandlers(viewport) {
|
|
379
|
-
var
|
|
424
|
+
var _this6 = this;
|
|
380
425
|
if (!viewport.stage) return;
|
|
381
426
|
|
|
382
427
|
// Mouse wheel zoom
|
|
@@ -402,7 +447,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
402
447
|
y: pointer.y - mousePointTo.y * clampedScale
|
|
403
448
|
};
|
|
404
449
|
viewport.stage.position(newPos);
|
|
405
|
-
|
|
450
|
+
_this6.drawGrid(viewport);
|
|
406
451
|
viewport.stage.batchDraw();
|
|
407
452
|
});
|
|
408
453
|
|
|
@@ -422,7 +467,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
422
467
|
viewport.stage.x(viewport.stage.x() + dx);
|
|
423
468
|
viewport.stage.y(viewport.stage.y() + dy);
|
|
424
469
|
viewport.lastPanPoint = pos;
|
|
425
|
-
|
|
470
|
+
_this6.drawGrid(viewport);
|
|
426
471
|
viewport.stage.batchDraw();
|
|
427
472
|
});
|
|
428
473
|
viewport.stage.on('mouseup', function () {
|
|
@@ -514,7 +559,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
514
559
|
}, {
|
|
515
560
|
key: "renderComponents",
|
|
516
561
|
value: function renderComponents(viewport) {
|
|
517
|
-
var
|
|
562
|
+
var _this7 = this;
|
|
518
563
|
if (!viewport.componentLayer || !viewport.stage || !this.sceneViewer) return;
|
|
519
564
|
viewport.componentLayer.destroyChildren();
|
|
520
565
|
|
|
@@ -525,19 +570,18 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
525
570
|
return;
|
|
526
571
|
}
|
|
527
572
|
|
|
528
|
-
//
|
|
529
|
-
if (
|
|
530
|
-
|
|
531
|
-
viewport._lastComponentCount = components.length;
|
|
532
|
-
}
|
|
573
|
+
// Track render count for debugging
|
|
574
|
+
if (viewport._renderCount === undefined) viewport._renderCount = 0;
|
|
575
|
+
viewport._renderCount++;
|
|
533
576
|
var width = viewport.stage.width();
|
|
534
577
|
var height = viewport.stage.height();
|
|
535
578
|
var centerX = width / 2;
|
|
536
579
|
var centerY = height / 2;
|
|
537
580
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
581
|
+
console.log("\uD83C\uDFA8 RENDER #".concat(viewport._renderCount, " (").concat(viewport.viewType, "): ").concat(components.length, " components, stage=").concat(width, "x").concat(height, ", center=(").concat(centerX, ", ").concat(centerY, ")"));
|
|
538
582
|
components.forEach(function (component) {
|
|
539
583
|
try {
|
|
540
|
-
|
|
584
|
+
_this7.renderComponent(viewport, component, centerX, centerY, scale);
|
|
541
585
|
} catch (err) {
|
|
542
586
|
console.warn('⚠️ Error rendering component in 2D:', component.name, err);
|
|
543
587
|
}
|
|
@@ -568,6 +612,11 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
568
612
|
var screenX = centerX + posX * scale;
|
|
569
613
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
570
614
|
|
|
615
|
+
// Debug: Log ALL component positions on first render only
|
|
616
|
+
if (viewport._renderCount === 1) {
|
|
617
|
+
console.log("\uD83D\uDD0D [".concat(viewport.viewType, "] ").concat(component.name, ": bbox.z=").concat(bboxCenter.z.toFixed(2), ", posY=").concat(posY.toFixed(2), ", screenY=").concat(screenY.toFixed(0), ", centerY=").concat(centerY.toFixed(0)));
|
|
618
|
+
}
|
|
619
|
+
|
|
571
620
|
// Generate unique color for this component
|
|
572
621
|
var colors = this.generateComponentColor(component.id);
|
|
573
622
|
|
|
@@ -625,16 +674,15 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
625
674
|
}, {
|
|
626
675
|
key: "_getOrComputeWorldBoundingBox",
|
|
627
676
|
value: function _getOrComputeWorldBoundingBox(object) {
|
|
628
|
-
var _object$userData, _object$userData2;
|
|
629
677
|
// Fast path: offset the stored world bbox by the position delta since load time.
|
|
630
678
|
// Translation only shifts the bbox center — extents stay identical — so this is O(1)
|
|
631
679
|
// instead of O(meshes × vertices) from a full geometry traversal.
|
|
632
|
-
var
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
var
|
|
636
|
-
var
|
|
637
|
-
var
|
|
680
|
+
var cached = _basePositionCache.get(object);
|
|
681
|
+
if (cached) {
|
|
682
|
+
var dx = object.position.x - cached.x;
|
|
683
|
+
var dy = object.position.y - cached.y;
|
|
684
|
+
var dz = object.position.z - cached.z;
|
|
685
|
+
var stored = cached.worldBoundingBox;
|
|
638
686
|
if (dx === 0 && dy === 0 && dz === 0) return stored;
|
|
639
687
|
return {
|
|
640
688
|
min: [stored.min[0] + dx, stored.min[1] + dy, stored.min[2] + dz],
|
|
@@ -646,7 +694,14 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
646
694
|
if (this._bboxCache.has(object.uuid)) {
|
|
647
695
|
return this._bboxCache.get(object.uuid);
|
|
648
696
|
}
|
|
649
|
-
|
|
697
|
+
|
|
698
|
+
// Force matrix updates before computing bbox to ensure world-space accuracy
|
|
699
|
+
object.updateMatrix();
|
|
700
|
+
object.updateMatrixWorld(true);
|
|
701
|
+
|
|
702
|
+
// Exclude io-devices and connectors to match the stored worldBoundingBox
|
|
703
|
+
// computed in modelManager.replaceWithGLBModels()
|
|
704
|
+
var box = computeFilteredBoundingBox(object, ['io-device', 'connector']);
|
|
650
705
|
var result;
|
|
651
706
|
if (box.isEmpty()) {
|
|
652
707
|
// Object has no geometry; fall back to a point at world position
|
|
@@ -777,7 +832,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
777
832
|
}, {
|
|
778
833
|
key: "addComponentInteractions",
|
|
779
834
|
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter, label) {
|
|
780
|
-
var
|
|
835
|
+
var _this8 = this;
|
|
781
836
|
if (!this.Konva) return;
|
|
782
837
|
var colors = this.generateComponentColor(component.id);
|
|
783
838
|
|
|
@@ -806,12 +861,12 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
806
861
|
// CLICK EVENT
|
|
807
862
|
rect.on('click', function () {
|
|
808
863
|
if (!viewport.isDragging) {
|
|
809
|
-
var
|
|
864
|
+
var _this8$sceneViewer;
|
|
810
865
|
console.log("\uD83C\uDFAF Component clicked: ".concat(component.name));
|
|
811
866
|
|
|
812
867
|
// Use centralPlant API to select component
|
|
813
|
-
if ((
|
|
814
|
-
|
|
868
|
+
if ((_this8$sceneViewer = _this8.sceneViewer) !== null && _this8$sceneViewer !== void 0 && _this8$sceneViewer.centralPlant && component.uuid) {
|
|
869
|
+
_this8.sceneViewer.centralPlant.selectComponent(component.uuid);
|
|
815
870
|
}
|
|
816
871
|
}
|
|
817
872
|
});
|
|
@@ -841,7 +896,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
841
896
|
var worldOriginY = stageHeight / 2;
|
|
842
897
|
|
|
843
898
|
// Snap to grid
|
|
844
|
-
var snappedPos =
|
|
899
|
+
var snappedPos = _this8.snapScreenToGrid(viewport, currentPos.x, currentPos.y, scale, worldOriginX, worldOriginY);
|
|
845
900
|
componentGroup.position(snappedPos);
|
|
846
901
|
viewport.componentLayer.batchDraw();
|
|
847
902
|
});
|
|
@@ -849,7 +904,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
849
904
|
// DRAG END
|
|
850
905
|
componentGroup.on('dragend', function () {
|
|
851
906
|
setTimeout(function () {
|
|
852
|
-
var
|
|
907
|
+
var _this8$sceneViewer2;
|
|
853
908
|
viewport.isDragging = false;
|
|
854
909
|
var finalPos = componentGroup.position();
|
|
855
910
|
var stageWidth = viewport.stage.width();
|
|
@@ -859,17 +914,17 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
859
914
|
var worldOriginY = stageHeight / 2;
|
|
860
915
|
|
|
861
916
|
// Convert screen to world coordinates
|
|
862
|
-
var worldCoords =
|
|
917
|
+
var worldCoords = _this8.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
863
918
|
|
|
864
919
|
// Calculate new position: delta from old bbox center to new bbox center
|
|
865
920
|
var currentPos = component.position;
|
|
866
|
-
var newPosition =
|
|
921
|
+
var newPosition = _this8.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
867
922
|
|
|
868
923
|
// Apply translation via centralPlant API
|
|
869
924
|
var deltaX = newPosition.x - currentPos.x;
|
|
870
925
|
var deltaY = newPosition.y - currentPos.y;
|
|
871
926
|
var deltaZ = newPosition.z - currentPos.z;
|
|
872
|
-
if ((
|
|
927
|
+
if ((_this8$sceneViewer2 = _this8.sceneViewer) !== null && _this8$sceneViewer2 !== void 0 && _this8$sceneViewer2.centralPlant && component.uuid) {
|
|
873
928
|
var success = true;
|
|
874
929
|
|
|
875
930
|
// Suppress per-axis path updates so the pathfinder only runs once,
|
|
@@ -877,32 +932,32 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
877
932
|
// Running updatePaths() after each individual axis (the default
|
|
878
933
|
// translateComponent behaviour) produces intermediate wrong results on
|
|
879
934
|
// the first drag because no cached fingerprint exists yet to skip them.
|
|
880
|
-
var wasAutoUpdate =
|
|
881
|
-
|
|
935
|
+
var wasAutoUpdate = _this8.sceneViewer.shouldUpdatePaths;
|
|
936
|
+
_this8.sceneViewer.shouldUpdatePaths = false;
|
|
882
937
|
try {
|
|
883
938
|
if (Math.abs(deltaX) > 0.01) {
|
|
884
|
-
success = success &&
|
|
939
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'x', deltaX);
|
|
885
940
|
}
|
|
886
941
|
if (Math.abs(deltaY) > 0.01) {
|
|
887
|
-
success = success &&
|
|
942
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'y', deltaY);
|
|
888
943
|
}
|
|
889
944
|
if (Math.abs(deltaZ) > 0.01) {
|
|
890
|
-
success = success &&
|
|
945
|
+
success = success && _this8.sceneViewer.centralPlant.translate(component.uuid, 'z', deltaZ);
|
|
891
946
|
}
|
|
892
947
|
} finally {
|
|
893
|
-
|
|
948
|
+
_this8.sceneViewer.shouldUpdatePaths = wasAutoUpdate;
|
|
894
949
|
}
|
|
895
|
-
if (!success &&
|
|
950
|
+
if (!success && _this8.dragStartPosition) {
|
|
896
951
|
console.warn('⚠️ Failed to translate component, reverting position');
|
|
897
|
-
componentGroup.position(
|
|
952
|
+
componentGroup.position(_this8.dragStartPosition);
|
|
898
953
|
} else {
|
|
899
954
|
console.log("\u2705 Component ".concat(component.name, " translated successfully in 2D viewport"));
|
|
900
955
|
|
|
901
956
|
// Single path update with the final combined position
|
|
902
|
-
if (wasAutoUpdate &&
|
|
957
|
+
if (wasAutoUpdate && _this8.sceneViewer) {
|
|
903
958
|
console.log('🔄 Auto-updating paths after 2D viewport translation...');
|
|
904
959
|
try {
|
|
905
|
-
|
|
960
|
+
_this8.sceneViewer.updatePaths();
|
|
906
961
|
console.log('✅ Paths auto-updated successfully from 2D viewport');
|
|
907
962
|
} catch (error) {
|
|
908
963
|
console.error('❌ Error auto-updating paths from 2D viewport:', error);
|
|
@@ -1034,10 +1089,10 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
1034
1089
|
}
|
|
1035
1090
|
var components = [];
|
|
1036
1091
|
this.sceneViewer.scene.traverse(function (object) {
|
|
1037
|
-
var _object$
|
|
1092
|
+
var _object$userData, _object$userData2;
|
|
1038
1093
|
// Only match the ROOT component object — must have both objectType:'component'
|
|
1039
1094
|
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
1040
|
-
if (((_object$
|
|
1095
|
+
if (((_object$userData = object.userData) === null || _object$userData === void 0 ? void 0 : _object$userData.objectType) === 'component' && (_object$userData2 = object.userData) !== null && _object$userData2 !== void 0 && _object$userData2.libraryId) {
|
|
1041
1096
|
components.push(object);
|
|
1042
1097
|
}
|
|
1043
1098
|
});
|
|
@@ -1155,28 +1210,39 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
1155
1210
|
}, {
|
|
1156
1211
|
key: "refresh",
|
|
1157
1212
|
value: function refresh() {
|
|
1158
|
-
var
|
|
1213
|
+
var _this9 = this;
|
|
1159
1214
|
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
|
|
1215
|
+
// Collect viewport keys to refresh; null means "all viewports"
|
|
1216
|
+
if (key) {
|
|
1217
|
+
this._pendingRefreshKeys.add(key);
|
|
1218
|
+
} else {
|
|
1219
|
+
// null key means refresh all — mark with special sentinel
|
|
1220
|
+
this._pendingRefreshKeys.add('__ALL__');
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
// If already scheduled, the rAF callback will process our newly-added key
|
|
1160
1224
|
if (this._refreshPending) return;
|
|
1161
1225
|
this._refreshPending = true;
|
|
1162
1226
|
requestAnimationFrame(function () {
|
|
1163
|
-
|
|
1227
|
+
_this9._refreshPending = false;
|
|
1228
|
+
|
|
1164
1229
|
// Clear per-cycle caches so each component is measured/traversed once per paint
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1230
|
+
_this9._bboxCache.clear();
|
|
1231
|
+
_this9._componentListCache = null;
|
|
1232
|
+
|
|
1233
|
+
// Check if we need to refresh all viewports
|
|
1234
|
+
var refreshAll = _this9._pendingRefreshKeys.has('__ALL__');
|
|
1235
|
+
var keysToRefresh = new Set(_this9._pendingRefreshKeys);
|
|
1236
|
+
_this9._pendingRefreshKeys.clear();
|
|
1237
|
+
if (refreshAll) {
|
|
1238
|
+
// Refresh all viewports
|
|
1239
|
+
var _iterator = _createForOfIteratorHelper(_this9.viewports.values()),
|
|
1174
1240
|
_step;
|
|
1175
1241
|
try {
|
|
1176
1242
|
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
1177
|
-
var
|
|
1178
|
-
if (
|
|
1179
|
-
|
|
1243
|
+
var viewport = _step.value;
|
|
1244
|
+
if (viewport.isReady) {
|
|
1245
|
+
_this9.renderComponents(viewport);
|
|
1180
1246
|
}
|
|
1181
1247
|
}
|
|
1182
1248
|
} catch (err) {
|
|
@@ -1184,6 +1250,23 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
1184
1250
|
} finally {
|
|
1185
1251
|
_iterator.f();
|
|
1186
1252
|
}
|
|
1253
|
+
} else {
|
|
1254
|
+
// Refresh only the specific viewports that were requested
|
|
1255
|
+
var _iterator2 = _createForOfIteratorHelper(keysToRefresh),
|
|
1256
|
+
_step2;
|
|
1257
|
+
try {
|
|
1258
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
1259
|
+
var viewportKey = _step2.value;
|
|
1260
|
+
var _viewport = _this9.viewports.get(viewportKey);
|
|
1261
|
+
if (_viewport && _viewport.isReady) {
|
|
1262
|
+
_this9.renderComponents(_viewport);
|
|
1263
|
+
}
|
|
1264
|
+
}
|
|
1265
|
+
} catch (err) {
|
|
1266
|
+
_iterator2.e(err);
|
|
1267
|
+
} finally {
|
|
1268
|
+
_iterator2.f();
|
|
1269
|
+
}
|
|
1187
1270
|
}
|
|
1188
1271
|
});
|
|
1189
1272
|
}
|
|
@@ -1204,20 +1287,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
1204
1287
|
}
|
|
1205
1288
|
|
|
1206
1289
|
// Dispose all viewport instances
|
|
1207
|
-
var
|
|
1208
|
-
|
|
1290
|
+
var _iterator3 = _createForOfIteratorHelper(this.viewports.entries()),
|
|
1291
|
+
_step3;
|
|
1209
1292
|
try {
|
|
1210
|
-
for (
|
|
1211
|
-
var
|
|
1212
|
-
key =
|
|
1213
|
-
viewport =
|
|
1293
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
1294
|
+
var _step3$value = _slicedToArray(_step3.value, 2),
|
|
1295
|
+
key = _step3$value[0],
|
|
1296
|
+
viewport = _step3$value[1];
|
|
1214
1297
|
console.log("\uD83D\uDDD1\uFE0F Disposing viewport: ".concat(key));
|
|
1215
1298
|
viewport.dispose();
|
|
1216
1299
|
}
|
|
1217
1300
|
} catch (err) {
|
|
1218
|
-
|
|
1301
|
+
_iterator3.e(err);
|
|
1219
1302
|
} finally {
|
|
1220
|
-
|
|
1303
|
+
_iterator3.f();
|
|
1221
1304
|
}
|
|
1222
1305
|
this.viewports.clear();
|
|
1223
1306
|
this.Konva = null;
|
|
@@ -1228,4 +1311,4 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
1228
1311
|
}]);
|
|
1229
1312
|
}(BaseDisposable);
|
|
1230
1313
|
|
|
1231
|
-
export { Viewport2DManager };
|
|
1314
|
+
export { Viewport2DManager, cacheBasePosition };
|
|
@@ -95,7 +95,12 @@ function computeFilteredBoundingBox(object) {
|
|
|
95
95
|
|
|
96
96
|
// Build a Set for O(1) lookups
|
|
97
97
|
var excludeSet = new Set(excludeTypes);
|
|
98
|
-
|
|
98
|
+
|
|
99
|
+
// Force matrix updates to ensure world-space coordinates are accurate.
|
|
100
|
+
// Using force=true ensures matrices are updated even if matrixWorldNeedsUpdate is false,
|
|
101
|
+
// which can happen after positioning a model before the render loop runs.
|
|
102
|
+
object.updateMatrix();
|
|
103
|
+
object.updateMatrixWorld(true);
|
|
99
104
|
object.traverse(function (child) {
|
|
100
105
|
// Only process nodes with geometry (Mesh, SkinnedMesh, etc.)
|
|
101
106
|
if (!child.geometry) return;
|