@2112-lab/central-plant 0.3.2 → 0.3.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.
- package/dist/bundle/index.js +168 -178
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +18 -6
- package/dist/cjs/src/managers/scene/sceneExportManager.js +25 -68
- package/dist/cjs/src/managers/scene/viewport2DManager.js +128 -102
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/managers/scene/modelManager.js +18 -6
- package/dist/esm/src/managers/scene/sceneExportManager.js +25 -68
- package/dist/esm/src/managers/scene/viewport2DManager.js +127 -103
- package/package.json +1 -1
|
@@ -215,40 +215,17 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
215
215
|
};
|
|
216
216
|
}
|
|
217
217
|
|
|
218
|
-
// For components:
|
|
219
|
-
//
|
|
220
|
-
//
|
|
218
|
+
// For components: no children exported — connector positions are defined in the component
|
|
219
|
+
// dictionary GLB and will be re-injected at import time via _injectConnectorChildrenFromDictionary.
|
|
220
|
+
// Exporting them here would prevent that injection (it skips if children already exist)
|
|
221
|
+
// and would leave the pathfinder with connectors in incompatible local-position format.
|
|
221
222
|
if (threeObject.children && threeObject.children.length > 0) {
|
|
222
223
|
var exportableChildren = [];
|
|
223
|
-
if (
|
|
224
|
-
// Export connector children (skip mesh geometry - it lives in the component dictionary GLB)
|
|
225
|
-
threeObject.children.forEach(function (child) {
|
|
226
|
-
var _child$userData;
|
|
227
|
-
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'connector') {
|
|
228
|
-
var connectorJson = {
|
|
229
|
-
// Use the raw Three.js UUID — connections in currentSceneData reference this exact value
|
|
230
|
-
uuid: child.uuid,
|
|
231
|
-
userData: _objectSpread2(_objectSpread2({
|
|
232
|
-
objectType: 'connector'
|
|
233
|
-
}, child.userData.direction ? {
|
|
234
|
-
direction: child.userData.direction
|
|
235
|
-
} : {}), child.userData.group ? {
|
|
236
|
-
group: child.userData.group
|
|
237
|
-
} : {}),
|
|
238
|
-
position: {
|
|
239
|
-
x: roundIfClose(child.position.x),
|
|
240
|
-
y: roundIfClose(child.position.y),
|
|
241
|
-
z: roundIfClose(child.position.z)
|
|
242
|
-
}
|
|
243
|
-
};
|
|
244
|
-
exportableChildren.push(connectorJson);
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
} else if (isManualSegment) {
|
|
224
|
+
if (isManualSegment) {
|
|
248
225
|
// For manual segments, export their connector children
|
|
249
226
|
threeObject.children.forEach(function (child) {
|
|
250
|
-
var _child$
|
|
251
|
-
if (((_child$
|
|
227
|
+
var _child$userData;
|
|
228
|
+
if (((_child$userData = child.userData) === null || _child$userData === void 0 ? void 0 : _child$userData.objectType) === 'segment-connector') {
|
|
252
229
|
// Call the class method using bound reference
|
|
253
230
|
var connectorJson = convertSegmentConnectorToJson(child, threeObject);
|
|
254
231
|
if (connectorJson) {
|
|
@@ -267,38 +244,18 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
267
244
|
// Bind the convertSegmentConnectorToJson method for use in nested function
|
|
268
245
|
var convertSegmentConnectorToJson = this.convertSegmentConnectorToJson.bind(this);
|
|
269
246
|
|
|
270
|
-
// Extract main scene objects (components and standalone connectors
|
|
247
|
+
// Extract main scene objects (components and standalone connectors)
|
|
271
248
|
var sceneChildren = [];
|
|
272
|
-
|
|
273
|
-
// Helper to recursively find manual segments within polylines
|
|
274
|
-
var findManualSegments = function findManualSegments(object) {
|
|
275
|
-
var manualSegments = [];
|
|
276
|
-
object.traverse(function (child) {
|
|
277
|
-
var _child$userData3;
|
|
278
|
-
// Check if this is a manual segment
|
|
279
|
-
if (((_child$userData3 = child.userData) === null || _child$userData3 === void 0 ? void 0 : _child$userData3.objectType) === 'segment') {
|
|
280
|
-
manualSegments.push(child);
|
|
281
|
-
}
|
|
282
|
-
});
|
|
283
|
-
return manualSegments;
|
|
284
|
-
};
|
|
285
249
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
286
|
-
var _child$
|
|
287
|
-
//
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
});
|
|
296
|
-
} else {
|
|
297
|
-
// Regular scene object export
|
|
298
|
-
var jsonChild = convertObjectToJson(child);
|
|
299
|
-
if (jsonChild) {
|
|
300
|
-
sceneChildren.push(jsonChild);
|
|
301
|
-
}
|
|
250
|
+
var _child$userData2;
|
|
251
|
+
// Only export components and connectors; skip segments, gateways, polylines, etc.
|
|
252
|
+
var objectType = (_child$userData2 = child.userData) === null || _child$userData2 === void 0 ? void 0 : _child$userData2.objectType;
|
|
253
|
+
if (objectType !== 'component' && objectType !== 'connector') {
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
var jsonChild = convertObjectToJson(child);
|
|
257
|
+
if (jsonChild) {
|
|
258
|
+
sceneChildren.push(jsonChild);
|
|
302
259
|
}
|
|
303
260
|
});
|
|
304
261
|
|
|
@@ -476,14 +433,14 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
476
433
|
BufferGeometryUtils = BufferGeometryUtilsModule.BufferGeometryUtils || BufferGeometryUtilsModule.default || BufferGeometryUtilsModule; // Create a new scene for export instead of cloning
|
|
477
434
|
exportScene = new _THREE.Scene(); // Helper function to check if an object should be exported
|
|
478
435
|
shouldExport = function shouldExport(child) {
|
|
479
|
-
var _child$
|
|
480
|
-
if ((_child$
|
|
436
|
+
var _child$name, _child$userData3, _child$userData4, _child$userData5, _child$userData6;
|
|
437
|
+
if ((_child$name = child.name) !== null && _child$name !== void 0 && _child$name.includes('Polyline')) return false; // Will handle separately
|
|
481
438
|
if (child.name === 'fogPlane') return false; // Skip fog plane
|
|
482
|
-
if ((_child$
|
|
483
|
-
if ((_child$
|
|
484
|
-
if ((_child$
|
|
439
|
+
if ((_child$userData3 = child.userData) !== null && _child$userData3 !== void 0 && _child$userData3.isBrickWall) return false; // Skip environment
|
|
440
|
+
if ((_child$userData4 = child.userData) !== null && _child$userData4 !== void 0 && _child$userData4.isBaseGround) return false; // Skip environment
|
|
441
|
+
if ((_child$userData5 = child.userData) !== null && _child$userData5 !== void 0 && _child$userData5.isBaseGrid) return false; // Skip environment
|
|
485
442
|
if (child.isLight) return false; // Skip lights
|
|
486
|
-
if ((_child$
|
|
443
|
+
if ((_child$userData6 = child.userData) !== null && _child$userData6 !== void 0 && _child$userData6.isTransformControls) return false; // Skip transform controls
|
|
487
444
|
if (child.isTransformControls) return false; // Skip transform controls
|
|
488
445
|
if (child.type && child.type.includes('TransformControls')) return false;
|
|
489
446
|
if (child.type && child.type.includes('Helper')) return false; // Skip helpers
|
|
@@ -492,8 +449,8 @@ var SceneExportManager = /*#__PURE__*/function () {
|
|
|
492
449
|
pipeGeometries = [];
|
|
493
450
|
pipeMaterial = null;
|
|
494
451
|
this.sceneViewer.scene.children.forEach(function (child) {
|
|
495
|
-
var _child$
|
|
496
|
-
if ((_child$
|
|
452
|
+
var _child$name2;
|
|
453
|
+
if ((_child$name2 = child.name) !== null && _child$name2 !== void 0 && _child$name2.includes('Polyline')) {
|
|
497
454
|
// Traverse the polyline to collect all mesh geometries
|
|
498
455
|
child.traverse(function (obj) {
|
|
499
456
|
if (obj.isMesh && obj.geometry) {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { inherits as _inherits, createClass as _createClass,
|
|
1
|
+
import { inherits as _inherits, createClass as _createClass, slicedToArray as _slicedToArray, createForOfIteratorHelper as _createForOfIteratorHelper, superPropGet as _superPropGet, classCallCheck as _classCallCheck, callSuper as _callSuper, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
2
|
import { BaseDisposable } from '../../core/baseDisposable.js';
|
|
3
|
+
import * as THREE from 'three';
|
|
4
|
+
import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
|
|
3
5
|
|
|
4
6
|
/**
|
|
5
7
|
* Viewport2DInstance
|
|
@@ -528,32 +530,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
528
530
|
}, {
|
|
529
531
|
key: "renderComponent",
|
|
530
532
|
value: function renderComponent(viewport, component, centerX, centerY, scale) {
|
|
531
|
-
|
|
532
|
-
// Get component position and rotation
|
|
533
|
-
var pos3D = {
|
|
534
|
-
x: (_component$position$x = (_component$position = component.position) === null || _component$position === void 0 ? void 0 : _component$position.x) !== null && _component$position$x !== void 0 ? _component$position$x : 0,
|
|
535
|
-
y: (_component$position$y = (_component$position2 = component.position) === null || _component$position2 === void 0 ? void 0 : _component$position2.y) !== null && _component$position$y !== void 0 ? _component$position$y : 0,
|
|
536
|
-
z: (_component$position$z = (_component$position3 = component.position) === null || _component$position3 === void 0 ? void 0 : _component$position3.z) !== null && _component$position$z !== void 0 ? _component$position$z : 0
|
|
537
|
-
};
|
|
538
|
-
var rot3D = {
|
|
539
|
-
x: (_component$rotation$x = (_component$rotation = component.rotation) === null || _component$rotation === void 0 ? void 0 : _component$rotation.x) !== null && _component$rotation$x !== void 0 ? _component$rotation$x : 0,
|
|
540
|
-
y: (_component$rotation$y = (_component$rotation2 = component.rotation) === null || _component$rotation2 === void 0 ? void 0 : _component$rotation2.y) !== null && _component$rotation$y !== void 0 ? _component$rotation$y : 0,
|
|
541
|
-
z: (_component$rotation$z = (_component$rotation3 = component.rotation) === null || _component$rotation3 === void 0 ? void 0 : _component$rotation3.z) !== null && _component$rotation$z !== void 0 ? _component$rotation$z : 0
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
// Get bounding box dimensions
|
|
533
|
+
// Get world-space bounding box dimensions and center
|
|
545
534
|
var _this$getComponentDim = this.getComponentDimensions(component),
|
|
546
535
|
worldWidth = _this$getComponentDim.worldWidth,
|
|
547
536
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
548
|
-
worldHeight = _this$getComponentDim.worldHeight
|
|
537
|
+
worldHeight = _this$getComponentDim.worldHeight,
|
|
538
|
+
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
539
|
+
console.log("[2D] ".concat(component.name, " | w=").concat(worldWidth.toFixed(3), " d=").concat(worldDepth.toFixed(3), " h=").concat(worldHeight.toFixed(3), " | center=(").concat(bboxCenter.x.toFixed(2), ",").concat(bboxCenter.y.toFixed(2), ",").concat(bboxCenter.z.toFixed(2), ")"));
|
|
549
540
|
|
|
550
|
-
// Project 3D
|
|
551
|
-
var _this$project3DTo2D = this.project3DTo2D(viewport,
|
|
541
|
+
// Project 3D bbox center to 2D based on view type
|
|
542
|
+
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
552
543
|
posX = _this$project3DTo2D.posX,
|
|
553
544
|
posY = _this$project3DTo2D.posY,
|
|
554
545
|
rectWidth = _this$project3DTo2D.rectWidth,
|
|
555
546
|
rectHeight = _this$project3DTo2D.rectHeight;
|
|
556
|
-
_this$project3DTo2D.rotationDegrees;
|
|
557
547
|
var screenX = centerX + posX * scale;
|
|
558
548
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
559
549
|
|
|
@@ -597,105 +587,131 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
597
587
|
});
|
|
598
588
|
|
|
599
589
|
// Add mouse event handlers
|
|
600
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight);
|
|
590
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
601
591
|
componentGroup.add(rect);
|
|
602
592
|
componentGroup.add(label);
|
|
603
593
|
viewport.componentLayer.add(componentGroup);
|
|
604
594
|
}
|
|
605
595
|
|
|
606
596
|
/**
|
|
607
|
-
*
|
|
597
|
+
* Compute worldBoundingBox for a live Three.js Object3D using the same
|
|
598
|
+
* vertex-accurate approach as computeFilteredBoundingBox (explicitly calls
|
|
599
|
+
* geometry.computeBoundingBox() on each mesh before measuring).
|
|
600
|
+
* @param {THREE.Object3D} object
|
|
601
|
+
* @returns {{min: number[], max: number[]}}
|
|
602
|
+
*/
|
|
603
|
+
}, {
|
|
604
|
+
key: "_getOrComputeWorldBoundingBox",
|
|
605
|
+
value: function _getOrComputeWorldBoundingBox(object) {
|
|
606
|
+
// computeFilteredBoundingBox with no exclusions = full object bbox
|
|
607
|
+
var box = computeFilteredBoundingBox(object, []);
|
|
608
|
+
if (box.isEmpty()) {
|
|
609
|
+
// Object has no geometry; fall back to a point at world position
|
|
610
|
+
var wp = new THREE.Vector3();
|
|
611
|
+
object.getWorldPosition(wp);
|
|
612
|
+
return {
|
|
613
|
+
min: [wp.x, wp.y, wp.z],
|
|
614
|
+
max: [wp.x, wp.y, wp.z]
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
return {
|
|
618
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
619
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
620
|
+
};
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Get component dimensions and world-space center from worldBoundingBox
|
|
608
625
|
*/
|
|
609
626
|
}, {
|
|
610
627
|
key: "getComponentDimensions",
|
|
611
628
|
value: function getComponentDimensions(component) {
|
|
612
|
-
var _component$userData, _component$
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
629
|
+
var _component$userData$w, _component$userData, _component$getWorldPo;
|
|
630
|
+
// Prefer worldBoundingBox already stored on the object — set after GLB loading
|
|
631
|
+
// by modelManager.replaceWithGLBModels using computeFilteredBoundingBox.
|
|
632
|
+
// Fall back to computing live if not yet available (e.g. first render before GLB load).
|
|
633
|
+
var wbb = (_component$userData$w = (_component$userData = component.userData) === null || _component$userData === void 0 ? void 0 : _component$userData.worldBoundingBox) !== null && _component$userData$w !== void 0 ? _component$userData$w : this._getOrComputeWorldBoundingBox(component);
|
|
634
|
+
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
635
|
+
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
636
|
+
minX = _wbb$min[0],
|
|
637
|
+
minY = _wbb$min[1],
|
|
638
|
+
minZ = _wbb$min[2];
|
|
639
|
+
var _wbb$max = _slicedToArray(wbb.max, 3),
|
|
640
|
+
maxX = _wbb$max[0],
|
|
641
|
+
maxY = _wbb$max[1],
|
|
642
|
+
maxZ = _wbb$max[2];
|
|
643
|
+
var cx = (minX + maxX) / 2;
|
|
644
|
+
var cy = (minY + maxY) / 2;
|
|
645
|
+
var cz = (minZ + maxZ) / 2;
|
|
646
|
+
// Guard against Infinity/NaN from empty or degenerate boxes
|
|
647
|
+
if (isFinite(cx) && isFinite(cy) && isFinite(cz)) {
|
|
648
|
+
return {
|
|
649
|
+
worldWidth: Math.max(maxX - minX, 0.01),
|
|
650
|
+
worldDepth: Math.max(maxY - minY, 0.01),
|
|
651
|
+
worldHeight: Math.max(maxZ - minZ, 0.01),
|
|
652
|
+
bboxCenter: {
|
|
653
|
+
x: cx,
|
|
654
|
+
y: cy,
|
|
655
|
+
z: cz
|
|
656
|
+
}
|
|
657
|
+
};
|
|
624
658
|
}
|
|
625
659
|
}
|
|
626
|
-
// Fallback
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
worldWidth = Math.abs(dims.x);
|
|
630
|
-
worldDepth = Math.abs(dims.y);
|
|
631
|
-
worldHeight = Math.abs(dims.z);
|
|
632
|
-
}
|
|
633
|
-
// Last resort: geometry bounding box
|
|
634
|
-
else if ((_component$geometry = component.geometry) !== null && _component$geometry !== void 0 && _component$geometry.boundingBox) {
|
|
635
|
-
var _bbox = component.geometry.boundingBox;
|
|
636
|
-
worldWidth = Math.abs(_bbox.max.x - _bbox.min.x);
|
|
637
|
-
worldDepth = Math.abs(_bbox.max.y - _bbox.min.y);
|
|
638
|
-
worldHeight = Math.abs(_bbox.max.z - _bbox.min.z);
|
|
639
|
-
}
|
|
660
|
+
// Fallback: world position of the object, unit dimensions
|
|
661
|
+
var wp = new THREE.Vector3();
|
|
662
|
+
(_component$getWorldPo = component.getWorldPosition) === null || _component$getWorldPo === void 0 || _component$getWorldPo.call(component, wp);
|
|
640
663
|
return {
|
|
641
|
-
worldWidth:
|
|
642
|
-
worldDepth:
|
|
643
|
-
worldHeight:
|
|
664
|
+
worldWidth: 1,
|
|
665
|
+
worldDepth: 1,
|
|
666
|
+
worldHeight: 1,
|
|
667
|
+
bboxCenter: {
|
|
668
|
+
x: wp.x,
|
|
669
|
+
y: wp.y,
|
|
670
|
+
z: wp.z
|
|
671
|
+
}
|
|
644
672
|
};
|
|
645
673
|
}
|
|
646
674
|
|
|
647
675
|
/**
|
|
648
|
-
* Project
|
|
676
|
+
* Project world-space bbox center to 2D based on view type.
|
|
677
|
+
* worldBoundingBox is an AABB so rotation is already encoded in the extents —
|
|
678
|
+
* no separate rotation correction is needed.
|
|
649
679
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
680
|
+
* @param {Object} bboxCenter - World-space center {x, y, z}
|
|
681
|
+
* @param {number} worldWidth - X extent (max[0] - min[0])
|
|
682
|
+
* @param {number} worldDepth - Y extent (max[1] - min[1])
|
|
683
|
+
* @param {number} worldHeight - Z extent (max[2] - min[2])
|
|
650
684
|
*/
|
|
651
685
|
}, {
|
|
652
686
|
key: "project3DTo2D",
|
|
653
|
-
value: function project3DTo2D(viewport,
|
|
654
|
-
var posX, posY, rectWidth, rectHeight;
|
|
655
|
-
var rotationAngle = rot3D.z;
|
|
656
|
-
var rotationDegrees = rotationAngle * 180 / Math.PI;
|
|
687
|
+
value: function project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight) {
|
|
657
688
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
689
|
+
var posX, posY, rectWidth, rectHeight;
|
|
658
690
|
switch (viewport.viewType) {
|
|
659
691
|
case 'top':
|
|
660
|
-
//
|
|
661
|
-
posX =
|
|
662
|
-
posY =
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
666
|
-
rectWidth = worldDepth * scale;
|
|
667
|
-
rectHeight = worldWidth * scale;
|
|
668
|
-
} else {
|
|
669
|
-
rectWidth = worldWidth * scale;
|
|
670
|
-
rectHeight = worldDepth * scale;
|
|
671
|
-
}
|
|
692
|
+
// Looking down Z-axis — X/Y plane
|
|
693
|
+
posX = bboxCenter.x;
|
|
694
|
+
posY = bboxCenter.y;
|
|
695
|
+
rectWidth = worldWidth * scale;
|
|
696
|
+
rectHeight = worldDepth * scale;
|
|
672
697
|
break;
|
|
673
698
|
case 'front':
|
|
674
|
-
//
|
|
675
|
-
posX =
|
|
676
|
-
posY =
|
|
677
|
-
|
|
678
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
679
|
-
rectWidth = worldDepth * scale;
|
|
680
|
-
} else {
|
|
681
|
-
rectWidth = worldWidth * scale;
|
|
682
|
-
}
|
|
699
|
+
// Looking along Y-axis — X/Z plane
|
|
700
|
+
posX = bboxCenter.x;
|
|
701
|
+
posY = bboxCenter.z;
|
|
702
|
+
rectWidth = worldWidth * scale;
|
|
683
703
|
rectHeight = worldHeight * scale;
|
|
684
704
|
break;
|
|
685
705
|
case 'side':
|
|
686
|
-
//
|
|
687
|
-
posX = -
|
|
688
|
-
posY =
|
|
689
|
-
|
|
690
|
-
rectWidth = worldWidth * scale;
|
|
691
|
-
} else {
|
|
692
|
-
rectWidth = worldDepth * scale;
|
|
693
|
-
}
|
|
706
|
+
// Looking along X-axis — Y/Z plane (Y negated for left-right orientation)
|
|
707
|
+
posX = -bboxCenter.y;
|
|
708
|
+
posY = bboxCenter.z;
|
|
709
|
+
rectWidth = worldDepth * scale;
|
|
694
710
|
rectHeight = worldHeight * scale;
|
|
695
711
|
break;
|
|
696
712
|
default:
|
|
697
|
-
posX =
|
|
698
|
-
posY =
|
|
713
|
+
posX = bboxCenter.x;
|
|
714
|
+
posY = bboxCenter.y;
|
|
699
715
|
rectWidth = worldWidth * scale;
|
|
700
716
|
rectHeight = worldDepth * scale;
|
|
701
717
|
}
|
|
@@ -703,8 +719,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
703
719
|
posX: posX,
|
|
704
720
|
posY: posY,
|
|
705
721
|
rectWidth: rectWidth,
|
|
706
|
-
rectHeight: rectHeight
|
|
707
|
-
rotationDegrees: rotationDegrees
|
|
722
|
+
rectHeight: rectHeight
|
|
708
723
|
};
|
|
709
724
|
}
|
|
710
725
|
|
|
@@ -714,7 +729,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
714
729
|
*/
|
|
715
730
|
}, {
|
|
716
731
|
key: "addComponentInteractions",
|
|
717
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight) {
|
|
732
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
718
733
|
var _this6 = this;
|
|
719
734
|
if (!this.Konva) return;
|
|
720
735
|
var colors = this.generateComponentColor(component.id);
|
|
@@ -797,9 +812,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
797
812
|
// Convert screen to world coordinates
|
|
798
813
|
var worldCoords = _this6.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
799
814
|
|
|
800
|
-
// Calculate new position
|
|
815
|
+
// Calculate new position: delta from old bbox center to new bbox center
|
|
801
816
|
var currentPos = component.position;
|
|
802
|
-
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos,
|
|
817
|
+
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
803
818
|
|
|
804
819
|
// Apply translation via centralPlant API
|
|
805
820
|
var deltaX = newPosition.x - currentPos.x;
|
|
@@ -902,37 +917,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
902
917
|
}
|
|
903
918
|
|
|
904
919
|
/**
|
|
905
|
-
* Convert world coordinates to 3D object position
|
|
920
|
+
* Convert dragged 2D world coordinates to a new 3D object position.
|
|
921
|
+
* coord1/coord2 represent where the bbox CENTER should be in the view's 2D plane;
|
|
922
|
+
* we compute the delta from the old bbox center and apply it to the pivot position.
|
|
906
923
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
924
|
+
* @param {{coord1, coord2}} worldCoords - Projected world coordinates from screen
|
|
925
|
+
* @param {{x,y,z}} currentPosition - Current Three.js object position (pivot)
|
|
926
|
+
* @param {{x,y,z}} bboxCenter - Old world-space bbox center
|
|
907
927
|
*/
|
|
908
928
|
}, {
|
|
909
929
|
key: "worldCoordsToObjectPosition",
|
|
910
|
-
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition,
|
|
930
|
+
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition, bboxCenter) {
|
|
911
931
|
var coord1 = worldCoords.coord1,
|
|
912
932
|
coord2 = worldCoords.coord2;
|
|
913
933
|
switch (viewport.viewType) {
|
|
914
934
|
case 'top':
|
|
935
|
+
// coord1=X, coord2=Y in world space
|
|
915
936
|
return {
|
|
916
|
-
x: coord1,
|
|
917
|
-
y: coord2,
|
|
937
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
938
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
918
939
|
z: currentPosition.z
|
|
919
940
|
};
|
|
920
941
|
case 'front':
|
|
942
|
+
// coord1=X, coord2=Z in world space
|
|
921
943
|
return {
|
|
922
|
-
x: coord1,
|
|
944
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
923
945
|
y: currentPosition.y,
|
|
924
|
-
z: coord2 -
|
|
946
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
925
947
|
};
|
|
926
948
|
case 'side':
|
|
949
|
+
// coord1=-Y (negated), coord2=Z in world space
|
|
927
950
|
return {
|
|
928
951
|
x: currentPosition.x,
|
|
929
|
-
y: -coord1,
|
|
930
|
-
z: coord2 -
|
|
952
|
+
y: currentPosition.y + (-coord1 - bboxCenter.y),
|
|
953
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
931
954
|
};
|
|
932
955
|
default:
|
|
933
956
|
return {
|
|
934
|
-
x: coord1,
|
|
935
|
-
y: coord2,
|
|
957
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
958
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
936
959
|
z: currentPosition.z
|
|
937
960
|
};
|
|
938
961
|
}
|
|
@@ -950,8 +973,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
950
973
|
var components = [];
|
|
951
974
|
this.sceneViewer.scene.traverse(function (object) {
|
|
952
975
|
var _object$userData, _object$userData2;
|
|
953
|
-
|
|
954
|
-
|
|
976
|
+
// Only match the ROOT component object — must have both objectType:'component'
|
|
977
|
+
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
978
|
+
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) {
|
|
955
979
|
components.push(object);
|
|
956
980
|
}
|
|
957
981
|
});
|