@2112-lab/central-plant 0.3.4 → 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 +138 -110
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/managers/scene/modelManager.js +13 -6
- 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 +13 -6
- package/dist/esm/src/managers/scene/viewport2DManager.js +127 -103
- package/package.json +1 -1
package/dist/bundle/index.js
CHANGED
|
@@ -29813,15 +29813,21 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
29813
29813
|
_context5.n = 2;
|
|
29814
29814
|
return Promise.all(glbLoadingPromises);
|
|
29815
29815
|
case 2:
|
|
29816
|
-
// Update world bounding boxes for loaded models
|
|
29816
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
29817
29817
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
29818
|
-
var _jsonData$userData2;
|
|
29819
29818
|
var jsonData = _ref2.jsonData,
|
|
29820
29819
|
glbModel = _ref2.glbModel;
|
|
29821
|
-
if (glbModel
|
|
29822
|
-
|
|
29823
|
-
|
|
29824
|
-
|
|
29820
|
+
if (!glbModel) return;
|
|
29821
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
29822
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
29823
|
+
var filteredBox = computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
29824
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
29825
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
29826
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
29827
|
+
};
|
|
29828
|
+
// Update both the JSON data object AND the live scene object
|
|
29829
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
29830
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
29825
29831
|
});
|
|
29826
29832
|
|
|
29827
29833
|
// Dispatch completion event
|
|
@@ -35922,32 +35928,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35922
35928
|
}, {
|
|
35923
35929
|
key: "renderComponent",
|
|
35924
35930
|
value: function renderComponent(viewport, component, centerX, centerY, scale) {
|
|
35925
|
-
|
|
35926
|
-
// Get component position and rotation
|
|
35927
|
-
var pos3D = {
|
|
35928
|
-
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,
|
|
35929
|
-
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,
|
|
35930
|
-
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
|
|
35931
|
-
};
|
|
35932
|
-
var rot3D = {
|
|
35933
|
-
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,
|
|
35934
|
-
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,
|
|
35935
|
-
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
|
|
35936
|
-
};
|
|
35937
|
-
|
|
35938
|
-
// Get bounding box dimensions
|
|
35931
|
+
// Get world-space bounding box dimensions and center
|
|
35939
35932
|
var _this$getComponentDim = this.getComponentDimensions(component),
|
|
35940
35933
|
worldWidth = _this$getComponentDim.worldWidth,
|
|
35941
35934
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
35942
|
-
worldHeight = _this$getComponentDim.worldHeight
|
|
35935
|
+
worldHeight = _this$getComponentDim.worldHeight,
|
|
35936
|
+
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
35937
|
+
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), ")"));
|
|
35943
35938
|
|
|
35944
|
-
// Project 3D
|
|
35945
|
-
var _this$project3DTo2D = this.project3DTo2D(viewport,
|
|
35939
|
+
// Project 3D bbox center to 2D based on view type
|
|
35940
|
+
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
35946
35941
|
posX = _this$project3DTo2D.posX,
|
|
35947
35942
|
posY = _this$project3DTo2D.posY,
|
|
35948
35943
|
rectWidth = _this$project3DTo2D.rectWidth,
|
|
35949
35944
|
rectHeight = _this$project3DTo2D.rectHeight;
|
|
35950
|
-
_this$project3DTo2D.rotationDegrees;
|
|
35951
35945
|
var screenX = centerX + posX * scale;
|
|
35952
35946
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
35953
35947
|
|
|
@@ -35991,105 +35985,131 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
35991
35985
|
});
|
|
35992
35986
|
|
|
35993
35987
|
// Add mouse event handlers
|
|
35994
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight);
|
|
35988
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
35995
35989
|
componentGroup.add(rect);
|
|
35996
35990
|
componentGroup.add(label);
|
|
35997
35991
|
viewport.componentLayer.add(componentGroup);
|
|
35998
35992
|
}
|
|
35999
35993
|
|
|
36000
35994
|
/**
|
|
36001
|
-
*
|
|
35995
|
+
* Compute worldBoundingBox for a live Three.js Object3D using the same
|
|
35996
|
+
* vertex-accurate approach as computeFilteredBoundingBox (explicitly calls
|
|
35997
|
+
* geometry.computeBoundingBox() on each mesh before measuring).
|
|
35998
|
+
* @param {THREE.Object3D} object
|
|
35999
|
+
* @returns {{min: number[], max: number[]}}
|
|
36000
|
+
*/
|
|
36001
|
+
}, {
|
|
36002
|
+
key: "_getOrComputeWorldBoundingBox",
|
|
36003
|
+
value: function _getOrComputeWorldBoundingBox(object) {
|
|
36004
|
+
// computeFilteredBoundingBox with no exclusions = full object bbox
|
|
36005
|
+
var box = computeFilteredBoundingBox(object, []);
|
|
36006
|
+
if (box.isEmpty()) {
|
|
36007
|
+
// Object has no geometry; fall back to a point at world position
|
|
36008
|
+
var wp = new THREE__namespace.Vector3();
|
|
36009
|
+
object.getWorldPosition(wp);
|
|
36010
|
+
return {
|
|
36011
|
+
min: [wp.x, wp.y, wp.z],
|
|
36012
|
+
max: [wp.x, wp.y, wp.z]
|
|
36013
|
+
};
|
|
36014
|
+
}
|
|
36015
|
+
return {
|
|
36016
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
36017
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
36018
|
+
};
|
|
36019
|
+
}
|
|
36020
|
+
|
|
36021
|
+
/**
|
|
36022
|
+
* Get component dimensions and world-space center from worldBoundingBox
|
|
36002
36023
|
*/
|
|
36003
36024
|
}, {
|
|
36004
36025
|
key: "getComponentDimensions",
|
|
36005
36026
|
value: function getComponentDimensions(component) {
|
|
36006
|
-
var _component$userData, _component$
|
|
36007
|
-
|
|
36008
|
-
|
|
36009
|
-
|
|
36010
|
-
|
|
36011
|
-
|
|
36012
|
-
|
|
36013
|
-
|
|
36014
|
-
|
|
36015
|
-
|
|
36016
|
-
|
|
36017
|
-
|
|
36018
|
-
|
|
36019
|
-
|
|
36020
|
-
|
|
36021
|
-
|
|
36022
|
-
var
|
|
36023
|
-
|
|
36024
|
-
|
|
36025
|
-
|
|
36026
|
-
|
|
36027
|
-
|
|
36028
|
-
|
|
36029
|
-
|
|
36030
|
-
|
|
36031
|
-
|
|
36032
|
-
|
|
36027
|
+
var _component$userData$w, _component$userData, _component$getWorldPo;
|
|
36028
|
+
// Prefer worldBoundingBox already stored on the object — set after GLB loading
|
|
36029
|
+
// by modelManager.replaceWithGLBModels using computeFilteredBoundingBox.
|
|
36030
|
+
// Fall back to computing live if not yet available (e.g. first render before GLB load).
|
|
36031
|
+
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);
|
|
36032
|
+
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
36033
|
+
var _wbb$min = _slicedToArray(wbb.min, 3),
|
|
36034
|
+
minX = _wbb$min[0],
|
|
36035
|
+
minY = _wbb$min[1],
|
|
36036
|
+
minZ = _wbb$min[2];
|
|
36037
|
+
var _wbb$max = _slicedToArray(wbb.max, 3),
|
|
36038
|
+
maxX = _wbb$max[0],
|
|
36039
|
+
maxY = _wbb$max[1],
|
|
36040
|
+
maxZ = _wbb$max[2];
|
|
36041
|
+
var cx = (minX + maxX) / 2;
|
|
36042
|
+
var cy = (minY + maxY) / 2;
|
|
36043
|
+
var cz = (minZ + maxZ) / 2;
|
|
36044
|
+
// Guard against Infinity/NaN from empty or degenerate boxes
|
|
36045
|
+
if (isFinite(cx) && isFinite(cy) && isFinite(cz)) {
|
|
36046
|
+
return {
|
|
36047
|
+
worldWidth: Math.max(maxX - minX, 0.01),
|
|
36048
|
+
worldDepth: Math.max(maxY - minY, 0.01),
|
|
36049
|
+
worldHeight: Math.max(maxZ - minZ, 0.01),
|
|
36050
|
+
bboxCenter: {
|
|
36051
|
+
x: cx,
|
|
36052
|
+
y: cy,
|
|
36053
|
+
z: cz
|
|
36054
|
+
}
|
|
36055
|
+
};
|
|
36056
|
+
}
|
|
36033
36057
|
}
|
|
36058
|
+
// Fallback: world position of the object, unit dimensions
|
|
36059
|
+
var wp = new THREE__namespace.Vector3();
|
|
36060
|
+
(_component$getWorldPo = component.getWorldPosition) === null || _component$getWorldPo === void 0 || _component$getWorldPo.call(component, wp);
|
|
36034
36061
|
return {
|
|
36035
|
-
worldWidth:
|
|
36036
|
-
worldDepth:
|
|
36037
|
-
worldHeight:
|
|
36062
|
+
worldWidth: 1,
|
|
36063
|
+
worldDepth: 1,
|
|
36064
|
+
worldHeight: 1,
|
|
36065
|
+
bboxCenter: {
|
|
36066
|
+
x: wp.x,
|
|
36067
|
+
y: wp.y,
|
|
36068
|
+
z: wp.z
|
|
36069
|
+
}
|
|
36038
36070
|
};
|
|
36039
36071
|
}
|
|
36040
36072
|
|
|
36041
36073
|
/**
|
|
36042
|
-
* Project
|
|
36074
|
+
* Project world-space bbox center to 2D based on view type.
|
|
36075
|
+
* worldBoundingBox is an AABB so rotation is already encoded in the extents —
|
|
36076
|
+
* no separate rotation correction is needed.
|
|
36043
36077
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36078
|
+
* @param {Object} bboxCenter - World-space center {x, y, z}
|
|
36079
|
+
* @param {number} worldWidth - X extent (max[0] - min[0])
|
|
36080
|
+
* @param {number} worldDepth - Y extent (max[1] - min[1])
|
|
36081
|
+
* @param {number} worldHeight - Z extent (max[2] - min[2])
|
|
36044
36082
|
*/
|
|
36045
36083
|
}, {
|
|
36046
36084
|
key: "project3DTo2D",
|
|
36047
|
-
value: function project3DTo2D(viewport,
|
|
36048
|
-
var posX, posY, rectWidth, rectHeight;
|
|
36049
|
-
var rotationAngle = rot3D.z;
|
|
36050
|
-
var rotationDegrees = rotationAngle * 180 / Math.PI;
|
|
36085
|
+
value: function project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight) {
|
|
36051
36086
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
36087
|
+
var posX, posY, rectWidth, rectHeight;
|
|
36052
36088
|
switch (viewport.viewType) {
|
|
36053
36089
|
case 'top':
|
|
36054
|
-
//
|
|
36055
|
-
posX =
|
|
36056
|
-
posY =
|
|
36057
|
-
|
|
36058
|
-
|
|
36059
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36060
|
-
rectWidth = worldDepth * scale;
|
|
36061
|
-
rectHeight = worldWidth * scale;
|
|
36062
|
-
} else {
|
|
36063
|
-
rectWidth = worldWidth * scale;
|
|
36064
|
-
rectHeight = worldDepth * scale;
|
|
36065
|
-
}
|
|
36090
|
+
// Looking down Z-axis — X/Y plane
|
|
36091
|
+
posX = bboxCenter.x;
|
|
36092
|
+
posY = bboxCenter.y;
|
|
36093
|
+
rectWidth = worldWidth * scale;
|
|
36094
|
+
rectHeight = worldDepth * scale;
|
|
36066
36095
|
break;
|
|
36067
36096
|
case 'front':
|
|
36068
|
-
//
|
|
36069
|
-
posX =
|
|
36070
|
-
posY =
|
|
36071
|
-
|
|
36072
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
36073
|
-
rectWidth = worldDepth * scale;
|
|
36074
|
-
} else {
|
|
36075
|
-
rectWidth = worldWidth * scale;
|
|
36076
|
-
}
|
|
36097
|
+
// Looking along Y-axis — X/Z plane
|
|
36098
|
+
posX = bboxCenter.x;
|
|
36099
|
+
posY = bboxCenter.z;
|
|
36100
|
+
rectWidth = worldWidth * scale;
|
|
36077
36101
|
rectHeight = worldHeight * scale;
|
|
36078
36102
|
break;
|
|
36079
36103
|
case 'side':
|
|
36080
|
-
//
|
|
36081
|
-
posX = -
|
|
36082
|
-
posY =
|
|
36083
|
-
|
|
36084
|
-
rectWidth = worldWidth * scale;
|
|
36085
|
-
} else {
|
|
36086
|
-
rectWidth = worldDepth * scale;
|
|
36087
|
-
}
|
|
36104
|
+
// Looking along X-axis — Y/Z plane (Y negated for left-right orientation)
|
|
36105
|
+
posX = -bboxCenter.y;
|
|
36106
|
+
posY = bboxCenter.z;
|
|
36107
|
+
rectWidth = worldDepth * scale;
|
|
36088
36108
|
rectHeight = worldHeight * scale;
|
|
36089
36109
|
break;
|
|
36090
36110
|
default:
|
|
36091
|
-
posX =
|
|
36092
|
-
posY =
|
|
36111
|
+
posX = bboxCenter.x;
|
|
36112
|
+
posY = bboxCenter.y;
|
|
36093
36113
|
rectWidth = worldWidth * scale;
|
|
36094
36114
|
rectHeight = worldDepth * scale;
|
|
36095
36115
|
}
|
|
@@ -36097,8 +36117,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36097
36117
|
posX: posX,
|
|
36098
36118
|
posY: posY,
|
|
36099
36119
|
rectWidth: rectWidth,
|
|
36100
|
-
rectHeight: rectHeight
|
|
36101
|
-
rotationDegrees: rotationDegrees
|
|
36120
|
+
rectHeight: rectHeight
|
|
36102
36121
|
};
|
|
36103
36122
|
}
|
|
36104
36123
|
|
|
@@ -36108,7 +36127,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36108
36127
|
*/
|
|
36109
36128
|
}, {
|
|
36110
36129
|
key: "addComponentInteractions",
|
|
36111
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight) {
|
|
36130
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
36112
36131
|
var _this6 = this;
|
|
36113
36132
|
if (!this.Konva) return;
|
|
36114
36133
|
var colors = this.generateComponentColor(component.id);
|
|
@@ -36191,9 +36210,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36191
36210
|
// Convert screen to world coordinates
|
|
36192
36211
|
var worldCoords = _this6.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
36193
36212
|
|
|
36194
|
-
// Calculate new position
|
|
36213
|
+
// Calculate new position: delta from old bbox center to new bbox center
|
|
36195
36214
|
var currentPos = component.position;
|
|
36196
|
-
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos,
|
|
36215
|
+
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
36197
36216
|
|
|
36198
36217
|
// Apply translation via centralPlant API
|
|
36199
36218
|
var deltaX = newPosition.x - currentPos.x;
|
|
@@ -36296,37 +36315,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36296
36315
|
}
|
|
36297
36316
|
|
|
36298
36317
|
/**
|
|
36299
|
-
* Convert world coordinates to 3D object position
|
|
36318
|
+
* Convert dragged 2D world coordinates to a new 3D object position.
|
|
36319
|
+
* coord1/coord2 represent where the bbox CENTER should be in the view's 2D plane;
|
|
36320
|
+
* we compute the delta from the old bbox center and apply it to the pivot position.
|
|
36300
36321
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
36322
|
+
* @param {{coord1, coord2}} worldCoords - Projected world coordinates from screen
|
|
36323
|
+
* @param {{x,y,z}} currentPosition - Current Three.js object position (pivot)
|
|
36324
|
+
* @param {{x,y,z}} bboxCenter - Old world-space bbox center
|
|
36301
36325
|
*/
|
|
36302
36326
|
}, {
|
|
36303
36327
|
key: "worldCoordsToObjectPosition",
|
|
36304
|
-
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition,
|
|
36328
|
+
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition, bboxCenter) {
|
|
36305
36329
|
var coord1 = worldCoords.coord1,
|
|
36306
36330
|
coord2 = worldCoords.coord2;
|
|
36307
36331
|
switch (viewport.viewType) {
|
|
36308
36332
|
case 'top':
|
|
36333
|
+
// coord1=X, coord2=Y in world space
|
|
36309
36334
|
return {
|
|
36310
|
-
x: coord1,
|
|
36311
|
-
y: coord2,
|
|
36335
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36336
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36312
36337
|
z: currentPosition.z
|
|
36313
36338
|
};
|
|
36314
36339
|
case 'front':
|
|
36340
|
+
// coord1=X, coord2=Z in world space
|
|
36315
36341
|
return {
|
|
36316
|
-
x: coord1,
|
|
36342
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36317
36343
|
y: currentPosition.y,
|
|
36318
|
-
z: coord2 -
|
|
36344
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36319
36345
|
};
|
|
36320
36346
|
case 'side':
|
|
36347
|
+
// coord1=-Y (negated), coord2=Z in world space
|
|
36321
36348
|
return {
|
|
36322
36349
|
x: currentPosition.x,
|
|
36323
|
-
y: -coord1,
|
|
36324
|
-
z: coord2 -
|
|
36350
|
+
y: currentPosition.y + (-coord1 - bboxCenter.y),
|
|
36351
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
36325
36352
|
};
|
|
36326
36353
|
default:
|
|
36327
36354
|
return {
|
|
36328
|
-
x: coord1,
|
|
36329
|
-
y: coord2,
|
|
36355
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
36356
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
36330
36357
|
z: currentPosition.z
|
|
36331
36358
|
};
|
|
36332
36359
|
}
|
|
@@ -36344,8 +36371,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
36344
36371
|
var components = [];
|
|
36345
36372
|
this.sceneViewer.scene.traverse(function (object) {
|
|
36346
36373
|
var _object$userData, _object$userData2;
|
|
36347
|
-
|
|
36348
|
-
|
|
36374
|
+
// Only match the ROOT component object — must have both objectType:'component'
|
|
36375
|
+
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
36376
|
+
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) {
|
|
36349
36377
|
components.push(object);
|
|
36350
36378
|
}
|
|
36351
36379
|
});
|
|
@@ -37802,7 +37830,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
37802
37830
|
* Initialize the CentralPlant manager
|
|
37803
37831
|
*
|
|
37804
37832
|
* @constructor
|
|
37805
|
-
* @version 0.3.
|
|
37833
|
+
* @version 0.3.5
|
|
37806
37834
|
* @updated 2025-10-22
|
|
37807
37835
|
*
|
|
37808
37836
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -35,7 +35,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
35
35
|
* Initialize the CentralPlant manager
|
|
36
36
|
*
|
|
37
37
|
* @constructor
|
|
38
|
-
* @version 0.3.
|
|
38
|
+
* @version 0.3.5
|
|
39
39
|
* @updated 2025-10-22
|
|
40
40
|
*
|
|
41
41
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -6,6 +6,7 @@ var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHel
|
|
|
6
6
|
var THREE = require('three');
|
|
7
7
|
var ioDeviceUtils = require('../../utils/ioDeviceUtils.js');
|
|
8
8
|
var modelPreloader = require('../../rendering/modelPreloader.js');
|
|
9
|
+
var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
|
|
9
10
|
|
|
10
11
|
function _interopNamespace(e) {
|
|
11
12
|
if (e && e.__esModule) return e;
|
|
@@ -579,15 +580,21 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
579
580
|
_context5.n = 2;
|
|
580
581
|
return Promise.all(glbLoadingPromises);
|
|
581
582
|
case 2:
|
|
582
|
-
// Update world bounding boxes for loaded models
|
|
583
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
583
584
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
584
|
-
var _jsonData$userData2;
|
|
585
585
|
var jsonData = _ref2.jsonData,
|
|
586
586
|
glbModel = _ref2.glbModel;
|
|
587
|
-
if (glbModel
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
587
|
+
if (!glbModel) return;
|
|
588
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
589
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
590
|
+
var filteredBox = boundingBoxUtils.computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
591
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
592
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
593
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
594
|
+
};
|
|
595
|
+
// Update both the JSON data object AND the live scene object
|
|
596
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
597
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
591
598
|
});
|
|
592
599
|
|
|
593
600
|
// Dispatch completion event
|
|
@@ -4,6 +4,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
4
4
|
|
|
5
5
|
var _rollupPluginBabelHelpers = require('../../../_virtual/_rollupPluginBabelHelpers.js');
|
|
6
6
|
var baseDisposable = require('../../core/baseDisposable.js');
|
|
7
|
+
var THREE = require('three');
|
|
8
|
+
var boundingBoxUtils = require('../../utils/boundingBoxUtils.js');
|
|
7
9
|
|
|
8
10
|
function _interopNamespace(e) {
|
|
9
11
|
if (e && e.__esModule) return e;
|
|
@@ -23,6 +25,8 @@ function _interopNamespace(e) {
|
|
|
23
25
|
return Object.freeze(n);
|
|
24
26
|
}
|
|
25
27
|
|
|
28
|
+
var THREE__namespace = /*#__PURE__*/_interopNamespace(THREE);
|
|
29
|
+
|
|
26
30
|
/**
|
|
27
31
|
* Viewport2DInstance
|
|
28
32
|
* Represents a single 2D viewport with its own Konva stage and configuration
|
|
@@ -550,32 +554,20 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
550
554
|
}, {
|
|
551
555
|
key: "renderComponent",
|
|
552
556
|
value: function renderComponent(viewport, component, centerX, centerY, scale) {
|
|
553
|
-
|
|
554
|
-
// Get component position and rotation
|
|
555
|
-
var pos3D = {
|
|
556
|
-
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,
|
|
557
|
-
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,
|
|
558
|
-
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
|
|
559
|
-
};
|
|
560
|
-
var rot3D = {
|
|
561
|
-
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,
|
|
562
|
-
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,
|
|
563
|
-
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
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
// Get bounding box dimensions
|
|
557
|
+
// Get world-space bounding box dimensions and center
|
|
567
558
|
var _this$getComponentDim = this.getComponentDimensions(component),
|
|
568
559
|
worldWidth = _this$getComponentDim.worldWidth,
|
|
569
560
|
worldDepth = _this$getComponentDim.worldDepth,
|
|
570
|
-
worldHeight = _this$getComponentDim.worldHeight
|
|
561
|
+
worldHeight = _this$getComponentDim.worldHeight,
|
|
562
|
+
bboxCenter = _this$getComponentDim.bboxCenter;
|
|
563
|
+
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), ")"));
|
|
571
564
|
|
|
572
|
-
// Project 3D
|
|
573
|
-
var _this$project3DTo2D = this.project3DTo2D(viewport,
|
|
565
|
+
// Project 3D bbox center to 2D based on view type
|
|
566
|
+
var _this$project3DTo2D = this.project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight),
|
|
574
567
|
posX = _this$project3DTo2D.posX,
|
|
575
568
|
posY = _this$project3DTo2D.posY,
|
|
576
569
|
rectWidth = _this$project3DTo2D.rectWidth,
|
|
577
570
|
rectHeight = _this$project3DTo2D.rectHeight;
|
|
578
|
-
_this$project3DTo2D.rotationDegrees;
|
|
579
571
|
var screenX = centerX + posX * scale;
|
|
580
572
|
var screenY = centerY - posY * scale; // Flip Y for screen coords
|
|
581
573
|
|
|
@@ -619,105 +611,131 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
619
611
|
});
|
|
620
612
|
|
|
621
613
|
// Add mouse event handlers
|
|
622
|
-
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight);
|
|
614
|
+
this.addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter);
|
|
623
615
|
componentGroup.add(rect);
|
|
624
616
|
componentGroup.add(label);
|
|
625
617
|
viewport.componentLayer.add(componentGroup);
|
|
626
618
|
}
|
|
627
619
|
|
|
628
620
|
/**
|
|
629
|
-
*
|
|
621
|
+
* Compute worldBoundingBox for a live Three.js Object3D using the same
|
|
622
|
+
* vertex-accurate approach as computeFilteredBoundingBox (explicitly calls
|
|
623
|
+
* geometry.computeBoundingBox() on each mesh before measuring).
|
|
624
|
+
* @param {THREE.Object3D} object
|
|
625
|
+
* @returns {{min: number[], max: number[]}}
|
|
626
|
+
*/
|
|
627
|
+
}, {
|
|
628
|
+
key: "_getOrComputeWorldBoundingBox",
|
|
629
|
+
value: function _getOrComputeWorldBoundingBox(object) {
|
|
630
|
+
// computeFilteredBoundingBox with no exclusions = full object bbox
|
|
631
|
+
var box = boundingBoxUtils.computeFilteredBoundingBox(object, []);
|
|
632
|
+
if (box.isEmpty()) {
|
|
633
|
+
// Object has no geometry; fall back to a point at world position
|
|
634
|
+
var wp = new THREE__namespace.Vector3();
|
|
635
|
+
object.getWorldPosition(wp);
|
|
636
|
+
return {
|
|
637
|
+
min: [wp.x, wp.y, wp.z],
|
|
638
|
+
max: [wp.x, wp.y, wp.z]
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
return {
|
|
642
|
+
min: [box.min.x, box.min.y, box.min.z],
|
|
643
|
+
max: [box.max.x, box.max.y, box.max.z]
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Get component dimensions and world-space center from worldBoundingBox
|
|
630
649
|
*/
|
|
631
650
|
}, {
|
|
632
651
|
key: "getComponentDimensions",
|
|
633
652
|
value: function getComponentDimensions(component) {
|
|
634
|
-
var _component$userData, _component$
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
653
|
+
var _component$userData$w, _component$userData, _component$getWorldPo;
|
|
654
|
+
// Prefer worldBoundingBox already stored on the object — set after GLB loading
|
|
655
|
+
// by modelManager.replaceWithGLBModels using computeFilteredBoundingBox.
|
|
656
|
+
// Fall back to computing live if not yet available (e.g. first render before GLB load).
|
|
657
|
+
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);
|
|
658
|
+
if (wbb !== null && wbb !== void 0 && wbb.min && wbb !== null && wbb !== void 0 && wbb.max) {
|
|
659
|
+
var _wbb$min = _rollupPluginBabelHelpers.slicedToArray(wbb.min, 3),
|
|
660
|
+
minX = _wbb$min[0],
|
|
661
|
+
minY = _wbb$min[1],
|
|
662
|
+
minZ = _wbb$min[2];
|
|
663
|
+
var _wbb$max = _rollupPluginBabelHelpers.slicedToArray(wbb.max, 3),
|
|
664
|
+
maxX = _wbb$max[0],
|
|
665
|
+
maxY = _wbb$max[1],
|
|
666
|
+
maxZ = _wbb$max[2];
|
|
667
|
+
var cx = (minX + maxX) / 2;
|
|
668
|
+
var cy = (minY + maxY) / 2;
|
|
669
|
+
var cz = (minZ + maxZ) / 2;
|
|
670
|
+
// Guard against Infinity/NaN from empty or degenerate boxes
|
|
671
|
+
if (isFinite(cx) && isFinite(cy) && isFinite(cz)) {
|
|
672
|
+
return {
|
|
673
|
+
worldWidth: Math.max(maxX - minX, 0.01),
|
|
674
|
+
worldDepth: Math.max(maxY - minY, 0.01),
|
|
675
|
+
worldHeight: Math.max(maxZ - minZ, 0.01),
|
|
676
|
+
bboxCenter: {
|
|
677
|
+
x: cx,
|
|
678
|
+
y: cy,
|
|
679
|
+
z: cz
|
|
680
|
+
}
|
|
681
|
+
};
|
|
646
682
|
}
|
|
647
683
|
}
|
|
648
|
-
// Fallback
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
worldWidth = Math.abs(dims.x);
|
|
652
|
-
worldDepth = Math.abs(dims.y);
|
|
653
|
-
worldHeight = Math.abs(dims.z);
|
|
654
|
-
}
|
|
655
|
-
// Last resort: geometry bounding box
|
|
656
|
-
else if ((_component$geometry = component.geometry) !== null && _component$geometry !== void 0 && _component$geometry.boundingBox) {
|
|
657
|
-
var _bbox = component.geometry.boundingBox;
|
|
658
|
-
worldWidth = Math.abs(_bbox.max.x - _bbox.min.x);
|
|
659
|
-
worldDepth = Math.abs(_bbox.max.y - _bbox.min.y);
|
|
660
|
-
worldHeight = Math.abs(_bbox.max.z - _bbox.min.z);
|
|
661
|
-
}
|
|
684
|
+
// Fallback: world position of the object, unit dimensions
|
|
685
|
+
var wp = new THREE__namespace.Vector3();
|
|
686
|
+
(_component$getWorldPo = component.getWorldPosition) === null || _component$getWorldPo === void 0 || _component$getWorldPo.call(component, wp);
|
|
662
687
|
return {
|
|
663
|
-
worldWidth:
|
|
664
|
-
worldDepth:
|
|
665
|
-
worldHeight:
|
|
688
|
+
worldWidth: 1,
|
|
689
|
+
worldDepth: 1,
|
|
690
|
+
worldHeight: 1,
|
|
691
|
+
bboxCenter: {
|
|
692
|
+
x: wp.x,
|
|
693
|
+
y: wp.y,
|
|
694
|
+
z: wp.z
|
|
695
|
+
}
|
|
666
696
|
};
|
|
667
697
|
}
|
|
668
698
|
|
|
669
699
|
/**
|
|
670
|
-
* Project
|
|
700
|
+
* Project world-space bbox center to 2D based on view type.
|
|
701
|
+
* worldBoundingBox is an AABB so rotation is already encoded in the extents —
|
|
702
|
+
* no separate rotation correction is needed.
|
|
671
703
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
704
|
+
* @param {Object} bboxCenter - World-space center {x, y, z}
|
|
705
|
+
* @param {number} worldWidth - X extent (max[0] - min[0])
|
|
706
|
+
* @param {number} worldDepth - Y extent (max[1] - min[1])
|
|
707
|
+
* @param {number} worldHeight - Z extent (max[2] - min[2])
|
|
672
708
|
*/
|
|
673
709
|
}, {
|
|
674
710
|
key: "project3DTo2D",
|
|
675
|
-
value: function project3DTo2D(viewport,
|
|
676
|
-
var posX, posY, rectWidth, rectHeight;
|
|
677
|
-
var rotationAngle = rot3D.z;
|
|
678
|
-
var rotationDegrees = rotationAngle * 180 / Math.PI;
|
|
711
|
+
value: function project3DTo2D(viewport, bboxCenter, worldWidth, worldDepth, worldHeight) {
|
|
679
712
|
var scale = viewport.PIXELS_PER_UNIT;
|
|
713
|
+
var posX, posY, rectWidth, rectHeight;
|
|
680
714
|
switch (viewport.viewType) {
|
|
681
715
|
case 'top':
|
|
682
|
-
//
|
|
683
|
-
posX =
|
|
684
|
-
posY =
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
688
|
-
rectWidth = worldDepth * scale;
|
|
689
|
-
rectHeight = worldWidth * scale;
|
|
690
|
-
} else {
|
|
691
|
-
rectWidth = worldWidth * scale;
|
|
692
|
-
rectHeight = worldDepth * scale;
|
|
693
|
-
}
|
|
716
|
+
// Looking down Z-axis — X/Y plane
|
|
717
|
+
posX = bboxCenter.x;
|
|
718
|
+
posY = bboxCenter.y;
|
|
719
|
+
rectWidth = worldWidth * scale;
|
|
720
|
+
rectHeight = worldDepth * scale;
|
|
694
721
|
break;
|
|
695
722
|
case 'front':
|
|
696
|
-
//
|
|
697
|
-
posX =
|
|
698
|
-
posY =
|
|
699
|
-
|
|
700
|
-
if (Math.abs(rotationDegrees) === 90 || Math.abs(rotationDegrees) === 270) {
|
|
701
|
-
rectWidth = worldDepth * scale;
|
|
702
|
-
} else {
|
|
703
|
-
rectWidth = worldWidth * scale;
|
|
704
|
-
}
|
|
723
|
+
// Looking along Y-axis — X/Z plane
|
|
724
|
+
posX = bboxCenter.x;
|
|
725
|
+
posY = bboxCenter.z;
|
|
726
|
+
rectWidth = worldWidth * scale;
|
|
705
727
|
rectHeight = worldHeight * scale;
|
|
706
728
|
break;
|
|
707
729
|
case 'side':
|
|
708
|
-
//
|
|
709
|
-
posX = -
|
|
710
|
-
posY =
|
|
711
|
-
|
|
712
|
-
rectWidth = worldWidth * scale;
|
|
713
|
-
} else {
|
|
714
|
-
rectWidth = worldDepth * scale;
|
|
715
|
-
}
|
|
730
|
+
// Looking along X-axis — Y/Z plane (Y negated for left-right orientation)
|
|
731
|
+
posX = -bboxCenter.y;
|
|
732
|
+
posY = bboxCenter.z;
|
|
733
|
+
rectWidth = worldDepth * scale;
|
|
716
734
|
rectHeight = worldHeight * scale;
|
|
717
735
|
break;
|
|
718
736
|
default:
|
|
719
|
-
posX =
|
|
720
|
-
posY =
|
|
737
|
+
posX = bboxCenter.x;
|
|
738
|
+
posY = bboxCenter.y;
|
|
721
739
|
rectWidth = worldWidth * scale;
|
|
722
740
|
rectHeight = worldDepth * scale;
|
|
723
741
|
}
|
|
@@ -725,8 +743,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
725
743
|
posX: posX,
|
|
726
744
|
posY: posY,
|
|
727
745
|
rectWidth: rectWidth,
|
|
728
|
-
rectHeight: rectHeight
|
|
729
|
-
rotationDegrees: rotationDegrees
|
|
746
|
+
rectHeight: rectHeight
|
|
730
747
|
};
|
|
731
748
|
}
|
|
732
749
|
|
|
@@ -736,7 +753,7 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
736
753
|
*/
|
|
737
754
|
}, {
|
|
738
755
|
key: "addComponentInteractions",
|
|
739
|
-
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight) {
|
|
756
|
+
value: function addComponentInteractions(viewport, rect, componentGroup, component, worldWidth, worldDepth, worldHeight, bboxCenter) {
|
|
740
757
|
var _this6 = this;
|
|
741
758
|
if (!this.Konva) return;
|
|
742
759
|
var colors = this.generateComponentColor(component.id);
|
|
@@ -819,9 +836,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
819
836
|
// Convert screen to world coordinates
|
|
820
837
|
var worldCoords = _this6.screenToWorldCoords(viewport, finalPos.x, finalPos.y, scale, worldOriginX, worldOriginY);
|
|
821
838
|
|
|
822
|
-
// Calculate new position
|
|
839
|
+
// Calculate new position: delta from old bbox center to new bbox center
|
|
823
840
|
var currentPos = component.position;
|
|
824
|
-
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos,
|
|
841
|
+
var newPosition = _this6.worldCoordsToObjectPosition(viewport, worldCoords, currentPos, bboxCenter);
|
|
825
842
|
|
|
826
843
|
// Apply translation via centralPlant API
|
|
827
844
|
var deltaX = newPosition.x - currentPos.x;
|
|
@@ -924,37 +941,45 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
924
941
|
}
|
|
925
942
|
|
|
926
943
|
/**
|
|
927
|
-
* Convert world coordinates to 3D object position
|
|
944
|
+
* Convert dragged 2D world coordinates to a new 3D object position.
|
|
945
|
+
* coord1/coord2 represent where the bbox CENTER should be in the view's 2D plane;
|
|
946
|
+
* we compute the delta from the old bbox center and apply it to the pivot position.
|
|
928
947
|
* @param {Viewport2DInstance} viewport - The viewport instance
|
|
948
|
+
* @param {{coord1, coord2}} worldCoords - Projected world coordinates from screen
|
|
949
|
+
* @param {{x,y,z}} currentPosition - Current Three.js object position (pivot)
|
|
950
|
+
* @param {{x,y,z}} bboxCenter - Old world-space bbox center
|
|
929
951
|
*/
|
|
930
952
|
}, {
|
|
931
953
|
key: "worldCoordsToObjectPosition",
|
|
932
|
-
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition,
|
|
954
|
+
value: function worldCoordsToObjectPosition(viewport, worldCoords, currentPosition, bboxCenter) {
|
|
933
955
|
var coord1 = worldCoords.coord1,
|
|
934
956
|
coord2 = worldCoords.coord2;
|
|
935
957
|
switch (viewport.viewType) {
|
|
936
958
|
case 'top':
|
|
959
|
+
// coord1=X, coord2=Y in world space
|
|
937
960
|
return {
|
|
938
|
-
x: coord1,
|
|
939
|
-
y: coord2,
|
|
961
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
962
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
940
963
|
z: currentPosition.z
|
|
941
964
|
};
|
|
942
965
|
case 'front':
|
|
966
|
+
// coord1=X, coord2=Z in world space
|
|
943
967
|
return {
|
|
944
|
-
x: coord1,
|
|
968
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
945
969
|
y: currentPosition.y,
|
|
946
|
-
z: coord2 -
|
|
970
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
947
971
|
};
|
|
948
972
|
case 'side':
|
|
973
|
+
// coord1=-Y (negated), coord2=Z in world space
|
|
949
974
|
return {
|
|
950
975
|
x: currentPosition.x,
|
|
951
|
-
y: -coord1,
|
|
952
|
-
z: coord2 -
|
|
976
|
+
y: currentPosition.y + (-coord1 - bboxCenter.y),
|
|
977
|
+
z: currentPosition.z + (coord2 - bboxCenter.z)
|
|
953
978
|
};
|
|
954
979
|
default:
|
|
955
980
|
return {
|
|
956
|
-
x: coord1,
|
|
957
|
-
y: coord2,
|
|
981
|
+
x: currentPosition.x + (coord1 - bboxCenter.x),
|
|
982
|
+
y: currentPosition.y + (coord2 - bboxCenter.y),
|
|
958
983
|
z: currentPosition.z
|
|
959
984
|
};
|
|
960
985
|
}
|
|
@@ -972,8 +997,9 @@ var Viewport2DManager = /*#__PURE__*/function (_BaseDisposable2) {
|
|
|
972
997
|
var components = [];
|
|
973
998
|
this.sceneViewer.scene.traverse(function (object) {
|
|
974
999
|
var _object$userData, _object$userData2;
|
|
975
|
-
|
|
976
|
-
|
|
1000
|
+
// Only match the ROOT component object — must have both objectType:'component'
|
|
1001
|
+
// AND libraryId (inner GLB mesh nodes don't have libraryId)
|
|
1002
|
+
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) {
|
|
977
1003
|
components.push(object);
|
|
978
1004
|
}
|
|
979
1005
|
});
|
|
@@ -31,7 +31,7 @@ var CentralPlant = /*#__PURE__*/function (_BaseDisposable) {
|
|
|
31
31
|
* Initialize the CentralPlant manager
|
|
32
32
|
*
|
|
33
33
|
* @constructor
|
|
34
|
-
* @version 0.3.
|
|
34
|
+
* @version 0.3.5
|
|
35
35
|
* @updated 2025-10-22
|
|
36
36
|
*
|
|
37
37
|
* @description Creates a new CentralPlant instance and initializes internal managers and utilities.
|
|
@@ -2,6 +2,7 @@ import { createClass as _createClass, objectSpread2 as _objectSpread2, toConsuma
|
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { attachIODevicesToComponent } from '../../utils/ioDeviceUtils.js';
|
|
4
4
|
import modelPreloader from '../../rendering/modelPreloader.js';
|
|
5
|
+
import { computeFilteredBoundingBox } from '../../utils/boundingBoxUtils.js';
|
|
5
6
|
|
|
6
7
|
var ModelManager = /*#__PURE__*/function () {
|
|
7
8
|
function ModelManager(sceneViewer) {
|
|
@@ -555,15 +556,21 @@ var ModelManager = /*#__PURE__*/function () {
|
|
|
555
556
|
_context5.n = 2;
|
|
556
557
|
return Promise.all(glbLoadingPromises);
|
|
557
558
|
case 2:
|
|
558
|
-
// Update world bounding boxes for loaded models
|
|
559
|
+
// Update world bounding boxes for loaded models and propagate to the live Three.js objects
|
|
559
560
|
libraryObjectsToReplace.forEach(function (_ref2) {
|
|
560
|
-
var _jsonData$userData2;
|
|
561
561
|
var jsonData = _ref2.jsonData,
|
|
562
562
|
glbModel = _ref2.glbModel;
|
|
563
|
-
if (glbModel
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
563
|
+
if (!glbModel) return;
|
|
564
|
+
// Use filtered bbox (excludes connectors + io-devices) so it matches
|
|
565
|
+
// what pathfindingManager._enrichSceneDataWithBoundingBoxes produces
|
|
566
|
+
var filteredBox = computeFilteredBoundingBox(glbModel, ['io-device', 'connector']);
|
|
567
|
+
var worldBoundingBox = filteredBox.isEmpty() ? _this3._calculateWorldBoundingBox(glbModel) : {
|
|
568
|
+
min: [filteredBox.min.x, filteredBox.min.y, filteredBox.min.z],
|
|
569
|
+
max: [filteredBox.max.x, filteredBox.max.y, filteredBox.max.z]
|
|
570
|
+
};
|
|
571
|
+
// Update both the JSON data object AND the live scene object
|
|
572
|
+
jsonData.userData.worldBoundingBox = worldBoundingBox;
|
|
573
|
+
glbModel.userData.worldBoundingBox = worldBoundingBox;
|
|
567
574
|
});
|
|
568
575
|
|
|
569
576
|
// Dispatch completion event
|
|
@@ -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
|
});
|