fl-web-component 2.1.1-beta.4 → 2.1.1-beta.6
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/fl-web-component.common.js +314 -161
- package/dist/fl-web-component.common.js.map +1 -1
- package/dist/fl-web-component.css +1 -1
- package/package.json +1 -1
- package/packages/components/com-flcanvas/components/entityFormatting.js +6 -8
- package/packages/components/com-flcanvas/index.vue +61 -63
- package/packages/components/com-graphics/index.vue +239 -56
- package/src/utils/instance-parser.js +16 -16
|
@@ -215,6 +215,7 @@ export default {
|
|
|
215
215
|
isPaused: false,
|
|
216
216
|
},
|
|
217
217
|
isolateMode: false,
|
|
218
|
+
sceneBoundingBoxDebugEnabled: false,
|
|
218
219
|
// collisionObbDebugEnabled: isDebug,
|
|
219
220
|
collisionObbDebugEnabled: false,
|
|
220
221
|
};
|
|
@@ -225,6 +226,13 @@ export default {
|
|
|
225
226
|
this.detachTransformControls();
|
|
226
227
|
}
|
|
227
228
|
},
|
|
229
|
+
sceneBoundingBoxDebugEnabled(val) {
|
|
230
|
+
if (val) {
|
|
231
|
+
this.refreshSceneBoundingBoxHelper(true);
|
|
232
|
+
} else {
|
|
233
|
+
this.hideSceneBoundingBox();
|
|
234
|
+
}
|
|
235
|
+
},
|
|
228
236
|
},
|
|
229
237
|
beforeCreate() {
|
|
230
238
|
this.spaceUp = true;
|
|
@@ -366,6 +374,7 @@ export default {
|
|
|
366
374
|
isObserverEnabled: true, // 标记相机变更观察者是否启用
|
|
367
375
|
sceneBoxes: new Map(),
|
|
368
376
|
documentModelIds: new Map(),
|
|
377
|
+
documentSceneBoundsIds: new Map(),
|
|
369
378
|
outlineInstanceProxyMap: new Map(),
|
|
370
379
|
occlusionWorker: null,
|
|
371
380
|
occlusionWorkerRequestMap: new Map(),
|
|
@@ -1470,71 +1479,108 @@ export default {
|
|
|
1470
1479
|
updateGlobalSceneBoundingBox() {
|
|
1471
1480
|
const state = this.noObserver || {};
|
|
1472
1481
|
const occScene = state.occlusionState && state.occlusionState._occScene;
|
|
1482
|
+
const mergedBox = new this.THREE.Box3();
|
|
1483
|
+
let hasValidBox = false;
|
|
1484
|
+
const mergeBox = box => {
|
|
1485
|
+
if (!box || !box.isBox3 || box.isEmpty()) return;
|
|
1486
|
+
if (!hasValidBox) {
|
|
1487
|
+
mergedBox.copy(box);
|
|
1488
|
+
hasValidBox = true;
|
|
1489
|
+
return;
|
|
1490
|
+
}
|
|
1491
|
+
mergedBox.union(box);
|
|
1492
|
+
};
|
|
1473
1493
|
|
|
1474
|
-
//
|
|
1494
|
+
// 离屏遮挡场景只包含参与遮挡的模型,需要继续合并场景范围索引中的二维图形范围。
|
|
1475
1495
|
if (occScene && occScene.children && occScene.children.length > 0) {
|
|
1476
1496
|
const occBox = new this.THREE.Box3().setFromObject(occScene);
|
|
1477
|
-
|
|
1478
|
-
this.sceneBoundingBox = occBox;
|
|
1479
|
-
return this.sceneBoundingBox;
|
|
1480
|
-
}
|
|
1497
|
+
mergeBox(occBox);
|
|
1481
1498
|
}
|
|
1482
1499
|
|
|
1483
|
-
//
|
|
1484
|
-
if (this.
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
minZ = Infinity;
|
|
1488
|
-
let maxX = -Infinity,
|
|
1489
|
-
maxY = -Infinity,
|
|
1490
|
-
maxZ = -Infinity;
|
|
1491
|
-
this._boxIndex.forEach(box => {
|
|
1492
|
-
if (!box || !box.isBox3 || box.isEmpty()) return;
|
|
1493
|
-
const mn = box.min;
|
|
1494
|
-
const mx = box.max;
|
|
1495
|
-
if (mn.x < minX) minX = mn.x;
|
|
1496
|
-
if (mn.y < minY) minY = mn.y;
|
|
1497
|
-
if (mn.z < minZ) minZ = mn.z;
|
|
1498
|
-
if (mx.x > maxX) maxX = mx.x;
|
|
1499
|
-
if (mx.y > maxY) maxY = mx.y;
|
|
1500
|
-
if (mx.z > maxZ) maxZ = mx.z;
|
|
1500
|
+
// sceneBoundsIndex 包含二维和三维图形,是全场景 dolly 距离的主要范围来源。
|
|
1501
|
+
if (this._sceneBoundsIndex && this._sceneBoundsIndex.size > 0) {
|
|
1502
|
+
this._sceneBoundsIndex.forEach(box => {
|
|
1503
|
+
mergeBox(box);
|
|
1501
1504
|
});
|
|
1502
|
-
if (
|
|
1503
|
-
Number.isFinite(minX) &&
|
|
1504
|
-
Number.isFinite(minY) &&
|
|
1505
|
-
Number.isFinite(minZ) &&
|
|
1506
|
-
Number.isFinite(maxX) &&
|
|
1507
|
-
Number.isFinite(maxY) &&
|
|
1508
|
-
Number.isFinite(maxZ)
|
|
1509
|
-
) {
|
|
1510
|
-
this.sceneBoundingBox = new this.THREE.Box3(
|
|
1511
|
-
new this.THREE.Vector3(minX, minY, minZ),
|
|
1512
|
-
new this.THREE.Vector3(maxX, maxY, maxZ)
|
|
1513
|
-
);
|
|
1514
|
-
return this.sceneBoundingBox;
|
|
1515
|
-
}
|
|
1516
1505
|
}
|
|
1517
1506
|
|
|
1518
1507
|
const boxes = Array.from((state.sceneBoxes && state.sceneBoxes.values()) || []);
|
|
1519
1508
|
if (boxes.length > 0) {
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
firstBox.union(boxes[i]);
|
|
1509
|
+
for (let i = 0; i < boxes.length; i++) {
|
|
1510
|
+
mergeBox(boxes[i]);
|
|
1523
1511
|
}
|
|
1524
|
-
|
|
1512
|
+
}
|
|
1513
|
+
|
|
1514
|
+
if (hasValidBox) {
|
|
1515
|
+
this.sceneBoundingBox = mergedBox;
|
|
1516
|
+
this.refreshSceneBoundingBoxHelper(this.sceneBoundingBoxDebugEnabled);
|
|
1525
1517
|
return this.sceneBoundingBox;
|
|
1526
1518
|
}
|
|
1527
1519
|
|
|
1528
1520
|
this.sceneBoundingBox = new this.THREE.Box3();
|
|
1521
|
+
this.refreshSceneBoundingBoxHelper(this.sceneBoundingBoxDebugEnabled);
|
|
1529
1522
|
return this.sceneBoundingBox;
|
|
1530
1523
|
},
|
|
1524
|
+
upsertIndexedBox(indexMap, modelId, box) {
|
|
1525
|
+
if (!indexMap || !modelId || !box || !box.isBox3) return null;
|
|
1526
|
+
const key = String(modelId);
|
|
1527
|
+
const existingBox = indexMap.get(key);
|
|
1528
|
+
if (!existingBox) {
|
|
1529
|
+
indexMap.set(key, box);
|
|
1530
|
+
return box;
|
|
1531
|
+
}
|
|
1532
|
+
existingBox.union(box);
|
|
1533
|
+
return existingBox;
|
|
1534
|
+
},
|
|
1535
|
+
mergeModelBoxUserData(targetBox, sourceUserData) {
|
|
1536
|
+
if (!targetBox || !sourceUserData) return;
|
|
1537
|
+
if (!targetBox.userData) {
|
|
1538
|
+
targetBox.userData = sourceUserData;
|
|
1539
|
+
return;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
const targetUserData = targetBox.userData;
|
|
1543
|
+
targetUserData.visible = targetUserData.visible !== false || sourceUserData.visible !== false;
|
|
1544
|
+
targetUserData.sourceVisible =
|
|
1545
|
+
targetUserData.sourceVisible !== false || sourceUserData.sourceVisible !== false;
|
|
1546
|
+
targetUserData.transparent = !!targetUserData.transparent && !!sourceUserData.transparent;
|
|
1547
|
+
targetUserData.mergedBoxCount = (targetUserData.mergedBoxCount || 1) + 1;
|
|
1548
|
+
// 同一模型包含多个图元时,单个图元的遮挡代理不再可靠,改由视锥体合并盒兜底加载。
|
|
1549
|
+
targetUserData.occlusionEnabled = false;
|
|
1550
|
+
|
|
1551
|
+
const targetObbs = Array.isArray(targetUserData.collisionObbs)
|
|
1552
|
+
? targetUserData.collisionObbs
|
|
1553
|
+
: [];
|
|
1554
|
+
const sourceObbs = Array.isArray(sourceUserData.collisionObbs)
|
|
1555
|
+
? sourceUserData.collisionObbs
|
|
1556
|
+
: [];
|
|
1557
|
+
if (sourceObbs.length > 0) {
|
|
1558
|
+
targetUserData.collisionObbs = targetObbs.concat(sourceObbs);
|
|
1559
|
+
}
|
|
1560
|
+
},
|
|
1561
|
+
upsertModelBox(modelId, box) {
|
|
1562
|
+
if (!this._boxIndex || !modelId || !box || !box.isBox3) return;
|
|
1563
|
+
const key = String(modelId);
|
|
1564
|
+
const existingBox = this._boxIndex.get(key);
|
|
1565
|
+
if (!existingBox) {
|
|
1566
|
+
this._boxIndex.set(key, box);
|
|
1567
|
+
return;
|
|
1568
|
+
}
|
|
1569
|
+
existingBox.union(box);
|
|
1570
|
+
this.mergeModelBoxUserData(existingBox, box.userData);
|
|
1571
|
+
},
|
|
1531
1572
|
setBoxIndex(boxJson, documentId, isAdd = true) {
|
|
1532
1573
|
if (!this._boxIndex) this._boxIndex = new Map();
|
|
1574
|
+
if (!this._sceneBoundsIndex) this._sceneBoundsIndex = new Map();
|
|
1533
1575
|
if (!documentId) {
|
|
1534
1576
|
this._boxIndex.clear();
|
|
1577
|
+
this._sceneBoundsIndex.clear();
|
|
1535
1578
|
if (this.noObserver && this.noObserver.documentModelIds) {
|
|
1536
1579
|
this.noObserver.documentModelIds.clear();
|
|
1537
1580
|
}
|
|
1581
|
+
if (this.noObserver && this.noObserver.documentSceneBoundsIds) {
|
|
1582
|
+
this.noObserver.documentSceneBoundsIds.clear();
|
|
1583
|
+
}
|
|
1538
1584
|
this.hasExecutedCentering = false;
|
|
1539
1585
|
this.buildOctreeFromBoxIndex();
|
|
1540
1586
|
return;
|
|
@@ -1543,19 +1589,35 @@ export default {
|
|
|
1543
1589
|
if (isAdd && boxJson) {
|
|
1544
1590
|
const arr = boxJson ? boxJson : [];
|
|
1545
1591
|
const modelIds = new Set();
|
|
1592
|
+
const sceneBoundIds = new Set();
|
|
1546
1593
|
const validGeomTypes = new Set(Object.values(GEOM_TYPES));
|
|
1547
1594
|
for (let i = 0; i < arr.length; i++) {
|
|
1548
1595
|
const it = arr[i];
|
|
1549
1596
|
if (!validGeomTypes.has(it.geomType)) {
|
|
1550
1597
|
continue;
|
|
1551
1598
|
}
|
|
1552
|
-
|
|
1599
|
+
const minSource = it.min;
|
|
1600
|
+
const maxSource = it.max;
|
|
1601
|
+
const hasValidMinMax =
|
|
1602
|
+
minSource &&
|
|
1603
|
+
maxSource &&
|
|
1604
|
+
minSource.length >= 3 &&
|
|
1605
|
+
maxSource.length >= 3 &&
|
|
1606
|
+
Number.isFinite(minSource[0]) &&
|
|
1607
|
+
Number.isFinite(minSource[1]) &&
|
|
1608
|
+
Number.isFinite(minSource[2]) &&
|
|
1609
|
+
Number.isFinite(maxSource[0]) &&
|
|
1610
|
+
Number.isFinite(maxSource[1]) &&
|
|
1611
|
+
Number.isFinite(maxSource[2]);
|
|
1612
|
+
if (!hasValidMinMax) {
|
|
1553
1613
|
continue;
|
|
1554
1614
|
}
|
|
1615
|
+
const obbData = it.obb || [];
|
|
1616
|
+
const modelId = String(it.id);
|
|
1555
1617
|
|
|
1556
1618
|
// 使用新的 min/max 数据结构
|
|
1557
|
-
const min = new this.THREE.Vector3(
|
|
1558
|
-
const max = new this.THREE.Vector3(
|
|
1619
|
+
const min = new this.THREE.Vector3(minSource[0], minSource[1], minSource[2]);
|
|
1620
|
+
const max = new this.THREE.Vector3(maxSource[0], maxSource[1], maxSource[2]);
|
|
1559
1621
|
|
|
1560
1622
|
const sourceBox = new this.THREE.Box3(min.clone(), max.clone());
|
|
1561
1623
|
// 八叉树仍使用 AABB 粗筛,最终碰撞使用 sourceBox 派生的 OBB 精筛
|
|
@@ -1589,10 +1651,18 @@ export default {
|
|
|
1589
1651
|
boxThree.applyMatrix4(collisionMatrix);
|
|
1590
1652
|
}
|
|
1591
1653
|
|
|
1654
|
+
this.upsertIndexedBox(this._sceneBoundsIndex, modelId, boxThree.clone());
|
|
1655
|
+
sceneBoundIds.add(modelId);
|
|
1656
|
+
|
|
1657
|
+
// 没有 OBB 数据的二维图形只参与全场景范围,不纳入碰撞和遮挡索引。
|
|
1658
|
+
if (obbData.length === 0) {
|
|
1659
|
+
continue;
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1592
1662
|
const userData = {
|
|
1593
1663
|
flag: it.flag || 1, // 默认为 1
|
|
1594
1664
|
geomType: it.geomType,
|
|
1595
|
-
obbData
|
|
1665
|
+
obbData, // 存储原始 OBB 数据
|
|
1596
1666
|
transparent: it.transp > 0,
|
|
1597
1667
|
sourceVisible: it.visible === false ? false : true,
|
|
1598
1668
|
visible: it.visible === false ? false : true, // 默认显示
|
|
@@ -1606,8 +1676,7 @@ export default {
|
|
|
1606
1676
|
// userData.matrix = new this.THREE.Matrix4().identity();
|
|
1607
1677
|
}
|
|
1608
1678
|
// 如果是 flag=3,解析并存储中心点、半轴长、旋转矩阵
|
|
1609
|
-
else if (it.flag === 3 &&
|
|
1610
|
-
const obbData = it.obb;
|
|
1679
|
+
else if (it.flag === 3 && obbData.length === 15) {
|
|
1611
1680
|
const center = new this.THREE.Vector3(obbData[0], obbData[1], obbData[2]);
|
|
1612
1681
|
const halfSize = new this.THREE.Vector3(obbData[3], obbData[4], obbData[5]);
|
|
1613
1682
|
const rotation = new this.THREE.Matrix3().fromArray(obbData.slice(6, 15));
|
|
@@ -1637,13 +1706,13 @@ export default {
|
|
|
1637
1706
|
userData.collisionObbs = [collisionObb];
|
|
1638
1707
|
}
|
|
1639
1708
|
// 如果是 flag=2,解析并存储多个子包围盒 (min, max)
|
|
1640
|
-
else if (it.flag === 2 &&
|
|
1709
|
+
else if (it.flag === 2 && obbData.length > 0) {
|
|
1641
1710
|
const subBoxes = [];
|
|
1642
1711
|
const collisionObbs = [];
|
|
1643
|
-
for (let k = 0; k <
|
|
1644
|
-
if (k + 5 <
|
|
1645
|
-
const min = new this.THREE.Vector3(
|
|
1646
|
-
const max = new this.THREE.Vector3(
|
|
1712
|
+
for (let k = 0; k < obbData.length; k += 6) {
|
|
1713
|
+
if (k + 5 < obbData.length) {
|
|
1714
|
+
const min = new this.THREE.Vector3(obbData[k], obbData[k + 1], obbData[k + 2]);
|
|
1715
|
+
const max = new this.THREE.Vector3(obbData[k + 3], obbData[k + 4], obbData[k + 5]);
|
|
1647
1716
|
subBoxes.push({ min, max });
|
|
1648
1717
|
|
|
1649
1718
|
const subBox = new this.THREE.Box3(min.clone(), max.clone());
|
|
@@ -1670,11 +1739,11 @@ export default {
|
|
|
1670
1739
|
|
|
1671
1740
|
boxThree.userData = userData;
|
|
1672
1741
|
|
|
1673
|
-
|
|
1674
|
-
this._boxIndex.set(modelId, boxThree);
|
|
1742
|
+
this.upsertModelBox(modelId, boxThree);
|
|
1675
1743
|
modelIds.add(modelId);
|
|
1676
1744
|
}
|
|
1677
1745
|
this.noObserver.documentModelIds.set(documentId, modelIds);
|
|
1746
|
+
this.noObserver.documentSceneBoundsIds.set(documentId, sceneBoundIds);
|
|
1678
1747
|
} else {
|
|
1679
1748
|
const modelIds = this.noObserver.documentModelIds.get(documentId);
|
|
1680
1749
|
if (modelIds) {
|
|
@@ -1688,6 +1757,15 @@ export default {
|
|
|
1688
1757
|
this.hasExecutedCentering = false;
|
|
1689
1758
|
}
|
|
1690
1759
|
}
|
|
1760
|
+
const sceneBoundIds =
|
|
1761
|
+
this.noObserver.documentSceneBoundsIds &&
|
|
1762
|
+
this.noObserver.documentSceneBoundsIds.get(documentId);
|
|
1763
|
+
if (sceneBoundIds) {
|
|
1764
|
+
sceneBoundIds.forEach(id => {
|
|
1765
|
+
this._sceneBoundsIndex.delete(id);
|
|
1766
|
+
});
|
|
1767
|
+
this.noObserver.documentSceneBoundsIds.delete(documentId);
|
|
1768
|
+
}
|
|
1691
1769
|
}
|
|
1692
1770
|
this.buildOctreeFromBoxIndex();
|
|
1693
1771
|
this.refreshCollisionObbDebug();
|
|
@@ -1704,7 +1782,9 @@ export default {
|
|
|
1704
1782
|
this.sceneBoundingBox.isEmpty()
|
|
1705
1783
|
)
|
|
1706
1784
|
return;
|
|
1707
|
-
|
|
1785
|
+
const hasBoxIndex = this._boxIndex && this._boxIndex.size > 0;
|
|
1786
|
+
const hasSceneBoundsIndex = this._sceneBoundsIndex && this._sceneBoundsIndex.size > 0;
|
|
1787
|
+
if (!hasBoxIndex && !hasSceneBoundsIndex) return;
|
|
1708
1788
|
|
|
1709
1789
|
this.smartModelCenter(this.sceneBoundingBox, 0);
|
|
1710
1790
|
},
|
|
@@ -4247,12 +4327,37 @@ export default {
|
|
|
4247
4327
|
},
|
|
4248
4328
|
// 动态设置视角滚轮的距离
|
|
4249
4329
|
setCameraConfig() {
|
|
4330
|
+
if (
|
|
4331
|
+
!this.sceneBoundingBox ||
|
|
4332
|
+
!this.sceneBoundingBox.isBox3 ||
|
|
4333
|
+
this.sceneBoundingBox.isEmpty()
|
|
4334
|
+
) {
|
|
4335
|
+
return;
|
|
4336
|
+
}
|
|
4250
4337
|
// let box3 = new this.THREE.Box3().setFromObject(this.sceneBoundingBox);
|
|
4251
4338
|
let size = new this.THREE.Vector3();
|
|
4252
4339
|
this.sceneBoundingBox.getSize(size);
|
|
4253
4340
|
const maxBorder = Math.max(size.x, size.y, size.z);
|
|
4341
|
+
if (isDebug) {
|
|
4342
|
+
const center = this.sceneBoundingBox.getCenter(new this.THREE.Vector3());
|
|
4343
|
+
console.log('sceneBoundingBox 调试信息', {
|
|
4344
|
+
size: {
|
|
4345
|
+
x: size.x,
|
|
4346
|
+
y: size.y,
|
|
4347
|
+
z: size.z,
|
|
4348
|
+
},
|
|
4349
|
+
center: {
|
|
4350
|
+
x: center.x,
|
|
4351
|
+
y: center.y,
|
|
4352
|
+
z: center.z,
|
|
4353
|
+
},
|
|
4354
|
+
maxBorder,
|
|
4355
|
+
});
|
|
4356
|
+
this.refreshSceneBoundingBoxHelper(this.sceneBoundingBoxDebugEnabled);
|
|
4357
|
+
}
|
|
4254
4358
|
// this.cameraControls.this.camera.far = maxBorder * 10; // 设置相机的远裁剪面
|
|
4255
4359
|
this.cameraControls.minDistance = maxBorder * 0.2; // 动态设置视角滚轮的距离
|
|
4360
|
+
// this.cameraControls.minDistance = 1000; // 动态设置视角滚轮的距离
|
|
4256
4361
|
this.camera.updateProjectionMatrix();
|
|
4257
4362
|
},
|
|
4258
4363
|
// 获取mesh的中心点
|
|
@@ -7476,9 +7581,87 @@ export default {
|
|
|
7476
7581
|
/**
|
|
7477
7582
|
* 隐藏场景包围盒
|
|
7478
7583
|
*/
|
|
7584
|
+
refreshSceneBoundingBoxHelper(forceVisible = this.boundingBoxVisible) {
|
|
7585
|
+
if (this.sceneBoundingBoxHelper && this.scene) {
|
|
7586
|
+
this.scene.remove(this.sceneBoundingBoxHelper);
|
|
7587
|
+
this.sceneBoundingBoxHelper.geometry && this.sceneBoundingBoxHelper.geometry.dispose();
|
|
7588
|
+
if (Array.isArray(this.sceneBoundingBoxHelper.material)) {
|
|
7589
|
+
this.sceneBoundingBoxHelper.material.forEach(material => {
|
|
7590
|
+
material && material.dispose && material.dispose();
|
|
7591
|
+
});
|
|
7592
|
+
} else if (
|
|
7593
|
+
this.sceneBoundingBoxHelper.material &&
|
|
7594
|
+
this.sceneBoundingBoxHelper.material.dispose
|
|
7595
|
+
) {
|
|
7596
|
+
this.sceneBoundingBoxHelper.material.dispose();
|
|
7597
|
+
}
|
|
7598
|
+
this.sceneBoundingBoxHelper = null;
|
|
7599
|
+
}
|
|
7600
|
+
|
|
7601
|
+
if (
|
|
7602
|
+
!forceVisible ||
|
|
7603
|
+
!this.scene ||
|
|
7604
|
+
!this.sceneBoundingBox ||
|
|
7605
|
+
!this.sceneBoundingBox.isBox3 ||
|
|
7606
|
+
this.sceneBoundingBox.isEmpty()
|
|
7607
|
+
) {
|
|
7608
|
+
this.boundingBoxVisible = false;
|
|
7609
|
+
return false;
|
|
7610
|
+
}
|
|
7611
|
+
|
|
7612
|
+
const helper = new this.THREE.Box3Helper(this.sceneBoundingBox, 0x00ff88);
|
|
7613
|
+
helper.name = 'sceneBoundingBoxHelper';
|
|
7614
|
+
helper.renderOrder = 999;
|
|
7615
|
+
if (helper.material) {
|
|
7616
|
+
helper.material.depthTest = false;
|
|
7617
|
+
helper.material.transparent = true;
|
|
7618
|
+
helper.material.opacity = 0.9;
|
|
7619
|
+
}
|
|
7620
|
+
this.scene.add(helper);
|
|
7621
|
+
this.sceneBoundingBoxHelper = helper;
|
|
7622
|
+
this.boundingBoxVisible = true;
|
|
7623
|
+
return true;
|
|
7624
|
+
},
|
|
7625
|
+
|
|
7626
|
+
showSceneBoundingBox() {
|
|
7627
|
+
this.sceneBoundingBoxDebugEnabled = true;
|
|
7628
|
+
const shown = this.refreshSceneBoundingBoxHelper(true);
|
|
7629
|
+
if (!shown) {
|
|
7630
|
+
console.warn('sceneBoundingBox 无有效范围,无法绘制调试线框');
|
|
7631
|
+
return;
|
|
7632
|
+
}
|
|
7633
|
+
|
|
7634
|
+
const size = this.sceneBoundingBox.getSize(new this.THREE.Vector3());
|
|
7635
|
+
const center = this.sceneBoundingBox.getCenter(new this.THREE.Vector3());
|
|
7636
|
+
console.log('sceneBoundingBox 线框已绘制', {
|
|
7637
|
+
size: {
|
|
7638
|
+
x: size.x,
|
|
7639
|
+
y: size.y,
|
|
7640
|
+
z: size.z,
|
|
7641
|
+
},
|
|
7642
|
+
center: {
|
|
7643
|
+
x: center.x,
|
|
7644
|
+
y: center.y,
|
|
7645
|
+
z: center.z,
|
|
7646
|
+
},
|
|
7647
|
+
});
|
|
7648
|
+
},
|
|
7649
|
+
|
|
7479
7650
|
hideSceneBoundingBox() {
|
|
7651
|
+
this.sceneBoundingBoxDebugEnabled = false;
|
|
7480
7652
|
if (this.sceneBoundingBoxHelper && this.scene) {
|
|
7481
7653
|
this.scene.remove(this.sceneBoundingBoxHelper);
|
|
7654
|
+
this.sceneBoundingBoxHelper.geometry && this.sceneBoundingBoxHelper.geometry.dispose();
|
|
7655
|
+
if (Array.isArray(this.sceneBoundingBoxHelper.material)) {
|
|
7656
|
+
this.sceneBoundingBoxHelper.material.forEach(material => {
|
|
7657
|
+
material && material.dispose && material.dispose();
|
|
7658
|
+
});
|
|
7659
|
+
} else if (
|
|
7660
|
+
this.sceneBoundingBoxHelper.material &&
|
|
7661
|
+
this.sceneBoundingBoxHelper.material.dispose
|
|
7662
|
+
) {
|
|
7663
|
+
this.sceneBoundingBoxHelper.material.dispose();
|
|
7664
|
+
}
|
|
7482
7665
|
this.sceneBoundingBoxHelper = null;
|
|
7483
7666
|
this.boundingBoxVisible = false;
|
|
7484
7667
|
console.log('场景包围盒已隐藏');
|
|
@@ -7489,7 +7672,7 @@ export default {
|
|
|
7489
7672
|
* 切换场景包围盒显示状态
|
|
7490
7673
|
*/
|
|
7491
7674
|
toggleSceneBoundingBox() {
|
|
7492
|
-
if (this.
|
|
7675
|
+
if (this.sceneBoundingBoxDebugEnabled) {
|
|
7493
7676
|
this.hideSceneBoundingBox();
|
|
7494
7677
|
} else {
|
|
7495
7678
|
this.showSceneBoundingBox();
|
|
@@ -1068,10 +1068,10 @@ function draw3Dmodel(
|
|
|
1068
1068
|
* @param {String} instanceName - 模型实例的名称
|
|
1069
1069
|
* @returns {Object} - 包含所有 2D 模型的组对象
|
|
1070
1070
|
*/
|
|
1071
|
-
function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
|
|
1072
|
-
const points = geom.points;
|
|
1073
|
-
const normals = geom.normals;
|
|
1074
|
-
const geometry = new THREE.BufferGeometry();
|
|
1071
|
+
function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, options = {}) {
|
|
1072
|
+
const points = geom.points;
|
|
1073
|
+
const normals = geom.normals;
|
|
1074
|
+
const geometry = new THREE.BufferGeometry();
|
|
1075
1075
|
|
|
1076
1076
|
if (points && points.length) {
|
|
1077
1077
|
const position = new Float32Array(points);
|
|
@@ -1082,18 +1082,18 @@ function draw2Dmodel(geom, instanceName, instanceCount, nColor, nOpacity, option
|
|
|
1082
1082
|
const normal = new Float32Array(normals);
|
|
1083
1083
|
geometry.setAttribute('normal', new THREE.BufferAttribute(normal, 3));
|
|
1084
1084
|
}
|
|
1085
|
-
|
|
1086
|
-
const { color, linewidth } = geom.prop;
|
|
1087
|
-
const formatLinewidth = (linewidth < 1 ? linewidth * 50 : linewidth) || 5;
|
|
1088
|
-
const meshLineResolution = options.meshLineResolution || {};
|
|
1089
|
-
const resolutionWidth = meshLineResolution.width || window.innerWidth || 1;
|
|
1090
|
-
const resolutionHeight = meshLineResolution.height || window.innerHeight || 1;
|
|
1091
|
-
const material = new MeshLineMaterial({
|
|
1092
|
-
color: new THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`),
|
|
1093
|
-
lineWidth: formatLinewidth,
|
|
1094
|
-
resolution: new THREE.Vector2(resolutionWidth, resolutionHeight),
|
|
1095
|
-
sizeAttenuation: 0,
|
|
1096
|
-
});
|
|
1085
|
+
|
|
1086
|
+
const { color, linewidth } = geom.prop;
|
|
1087
|
+
const formatLinewidth = (linewidth < 1 ? linewidth * 50 : linewidth) || 5;
|
|
1088
|
+
const meshLineResolution = options.meshLineResolution || {};
|
|
1089
|
+
const resolutionWidth = meshLineResolution.width || window.innerWidth || 1;
|
|
1090
|
+
const resolutionHeight = meshLineResolution.height || window.innerHeight || 1;
|
|
1091
|
+
const material = new MeshLineMaterial({
|
|
1092
|
+
color: new THREE.Color(`rgb(${color[0]}, ${color[1]}, ${color[2]})`),
|
|
1093
|
+
lineWidth: formatLinewidth,
|
|
1094
|
+
resolution: new THREE.Vector2(resolutionWidth, resolutionHeight),
|
|
1095
|
+
sizeAttenuation: 0,
|
|
1096
|
+
});
|
|
1097
1097
|
|
|
1098
1098
|
const lineGeometry = new MeshLineGeometry();
|
|
1099
1099
|
lineGeometry.setPoints(geometry);
|