fl-web-component 2.0.19-beta.3 → 2.1.1-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fl-web-component.common.js +4417 -687
- 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 +134 -1
- package/packages/components/com-flcanvas/index.vue +335 -239
- package/packages/components/com-graphics/index.vue +333 -24
- package/src/utils/dxf-parser/AutoCadColorIndex.js +265 -0
- package/src/utils/dxf-parser/DimStyleCodes.js +33 -0
- package/src/utils/dxf-parser/DxfArrayScanner.js +151 -0
- package/src/utils/dxf-parser/DxfParser.js +918 -0
- package/src/utils/dxf-parser/ExtendedDataParser.js +117 -0
- package/src/utils/dxf-parser/LICENSE +21 -0
- package/src/utils/dxf-parser/ParseHelpers.js +140 -0
- package/src/utils/dxf-parser/README.md +8 -0
- package/src/utils/dxf-parser/entities/3dface.js +83 -0
- package/src/utils/dxf-parser/entities/arc.js +38 -0
- package/src/utils/dxf-parser/entities/attdef.js +89 -0
- package/src/utils/dxf-parser/entities/attribute.js +109 -0
- package/src/utils/dxf-parser/entities/circle.js +43 -0
- package/src/utils/dxf-parser/entities/dimension.js +71 -0
- package/src/utils/dxf-parser/entities/ellipse.js +48 -0
- package/src/utils/dxf-parser/entities/hatch.js +348 -0
- package/src/utils/dxf-parser/entities/insert.js +57 -0
- package/src/utils/dxf-parser/entities/line.js +34 -0
- package/src/utils/dxf-parser/entities/lwpolyline.js +103 -0
- package/src/utils/dxf-parser/entities/mtext.js +57 -0
- package/src/utils/dxf-parser/entities/point.js +35 -0
- package/src/utils/dxf-parser/entities/polyline.js +92 -0
- package/src/utils/dxf-parser/entities/solid.js +40 -0
- package/src/utils/dxf-parser/entities/spline.js +70 -0
- package/src/utils/dxf-parser/entities/text.js +50 -0
- package/src/utils/dxf-parser/entities/vertex.js +62 -0
- package/src/utils/threejs/measure-clear-distance.js +1 -1
|
@@ -165,7 +165,9 @@ import { onContextHandle } from './component/context';
|
|
|
165
165
|
|
|
166
166
|
const isDebug = process.env.NODE_ENV !== 'production' || process.env.VUE_APP_IS_WATCH === true;
|
|
167
167
|
// const isDebug = false;
|
|
168
|
-
const COLLISION_PENETRATION_EPSILON =
|
|
168
|
+
const COLLISION_PENETRATION_EPSILON = 10;
|
|
169
|
+
const COLLISION_OBB_AXIS_EPSILON = 1e-8;
|
|
170
|
+
const COLLISION_DEBUG_GROUP_NAME = '__collision_obb_debug_group__';
|
|
169
171
|
|
|
170
172
|
export default {
|
|
171
173
|
name: 'FlModel',
|
|
@@ -213,6 +215,7 @@ export default {
|
|
|
213
215
|
isPaused: false,
|
|
214
216
|
},
|
|
215
217
|
isolateMode: false,
|
|
218
|
+
collisionObbDebugEnabled: true,
|
|
216
219
|
};
|
|
217
220
|
},
|
|
218
221
|
watch: {
|
|
@@ -254,6 +257,7 @@ export default {
|
|
|
254
257
|
'centeringDebounceTimer',
|
|
255
258
|
'sceneBoundingBox',
|
|
256
259
|
'sceneBoundingBoxHelper',
|
|
260
|
+
'collisionObbDebugGroup',
|
|
257
261
|
];
|
|
258
262
|
arr.forEach(item => {
|
|
259
263
|
this[item] = null;
|
|
@@ -274,6 +278,7 @@ export default {
|
|
|
274
278
|
'needsCenteringAfterInteraction',
|
|
275
279
|
'isDragging',
|
|
276
280
|
'boundingBoxVisible',
|
|
281
|
+
'collisionObbDebugEnabled',
|
|
277
282
|
].forEach(item => {
|
|
278
283
|
this[item] = false;
|
|
279
284
|
});
|
|
@@ -1551,12 +1556,14 @@ export default {
|
|
|
1551
1556
|
const min = new this.THREE.Vector3(it.min[0], it.min[1], it.min[2]);
|
|
1552
1557
|
const max = new this.THREE.Vector3(it.max[0], it.max[1], it.max[2]);
|
|
1553
1558
|
|
|
1554
|
-
|
|
1555
|
-
|
|
1559
|
+
const sourceBox = new this.THREE.Box3(min.clone(), max.clone());
|
|
1560
|
+
// 八叉树仍使用 AABB 粗筛,最终碰撞使用 sourceBox 派生的 OBB 精筛
|
|
1561
|
+
const boxThree = sourceBox.clone();
|
|
1556
1562
|
|
|
1557
1563
|
const hasMatrix = Array.isArray(it.matrix) && it.matrix.length >= 16;
|
|
1558
1564
|
const hasMeshMatrix = Array.isArray(it.meshMatrix) && it.meshMatrix.length >= 16;
|
|
1559
1565
|
let localMatrix = null;
|
|
1566
|
+
let collisionMatrix = null;
|
|
1560
1567
|
if (hasMatrix || hasMeshMatrix) {
|
|
1561
1568
|
localMatrix = new this.THREE.Matrix4();
|
|
1562
1569
|
if (hasMeshMatrix) {
|
|
@@ -1573,10 +1580,12 @@ export default {
|
|
|
1573
1580
|
if (this.bizToThreeMatrix) {
|
|
1574
1581
|
worldMatrix.premultiply(this.bizToThreeMatrix);
|
|
1575
1582
|
}
|
|
1583
|
+
collisionMatrix = worldMatrix;
|
|
1576
1584
|
boxThree.applyMatrix4(worldMatrix);
|
|
1577
1585
|
} else if (this.bizToThreeMatrix) {
|
|
1578
1586
|
// 注意:applyMatrix4 会重新计算 AABB
|
|
1579
|
-
|
|
1587
|
+
collisionMatrix = this.bizToThreeMatrix.clone();
|
|
1588
|
+
boxThree.applyMatrix4(collisionMatrix);
|
|
1580
1589
|
}
|
|
1581
1590
|
|
|
1582
1591
|
const userData = {
|
|
@@ -1619,18 +1628,43 @@ export default {
|
|
|
1619
1628
|
center: center,
|
|
1620
1629
|
halfSize: halfSize,
|
|
1621
1630
|
};
|
|
1631
|
+
|
|
1632
|
+
const collisionObb = new OBB(center.clone(), halfSize.clone(), rotation.clone());
|
|
1633
|
+
if (collisionMatrix) {
|
|
1634
|
+
collisionObb.applyMatrix4(collisionMatrix);
|
|
1635
|
+
}
|
|
1636
|
+
userData.collisionObbs = [collisionObb];
|
|
1622
1637
|
}
|
|
1623
1638
|
// 如果是 flag=2,解析并存储多个子包围盒 (min, max)
|
|
1624
1639
|
else if (it.flag === 2 && it.obb && it.obb.length > 0) {
|
|
1625
1640
|
const subBoxes = [];
|
|
1641
|
+
const collisionObbs = [];
|
|
1626
1642
|
for (let k = 0; k < it.obb.length; k += 6) {
|
|
1627
1643
|
if (k + 5 < it.obb.length) {
|
|
1628
1644
|
const min = new this.THREE.Vector3(it.obb[k], it.obb[k + 1], it.obb[k + 2]);
|
|
1629
1645
|
const max = new this.THREE.Vector3(it.obb[k + 3], it.obb[k + 4], it.obb[k + 5]);
|
|
1630
1646
|
subBoxes.push({ min, max });
|
|
1647
|
+
|
|
1648
|
+
const subBox = new this.THREE.Box3(min.clone(), max.clone());
|
|
1649
|
+
const collisionObb = new OBB().fromBox3(subBox);
|
|
1650
|
+
if (collisionMatrix) {
|
|
1651
|
+
collisionObb.applyMatrix4(collisionMatrix);
|
|
1652
|
+
}
|
|
1653
|
+
collisionObbs.push(collisionObb);
|
|
1631
1654
|
}
|
|
1632
1655
|
}
|
|
1633
1656
|
userData.subBoxes = subBoxes;
|
|
1657
|
+
if (collisionObbs.length > 0) {
|
|
1658
|
+
userData.collisionObbs = collisionObbs;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
if (!userData.collisionObbs || userData.collisionObbs.length === 0) {
|
|
1663
|
+
const collisionObb = new OBB().fromBox3(sourceBox);
|
|
1664
|
+
if (collisionMatrix) {
|
|
1665
|
+
collisionObb.applyMatrix4(collisionMatrix);
|
|
1666
|
+
}
|
|
1667
|
+
userData.collisionObbs = [collisionObb];
|
|
1634
1668
|
}
|
|
1635
1669
|
|
|
1636
1670
|
boxThree.userData = userData;
|
|
@@ -1655,6 +1689,7 @@ export default {
|
|
|
1655
1689
|
}
|
|
1656
1690
|
}
|
|
1657
1691
|
this.buildOctreeFromBoxIndex();
|
|
1692
|
+
this.refreshCollisionObbDebug();
|
|
1658
1693
|
console.log('time end', Date.now());
|
|
1659
1694
|
},
|
|
1660
1695
|
shouldApplyOcclusionByBox(box) {
|
|
@@ -1780,17 +1815,261 @@ export default {
|
|
|
1780
1815
|
const numberValue = Number(value);
|
|
1781
1816
|
return Number.isFinite(numberValue) ? numberValue : id;
|
|
1782
1817
|
},
|
|
1783
|
-
|
|
1784
|
-
const x = Math.min(boxA.max.x - boxB.min.x, boxB.max.x - boxA.min.x);
|
|
1785
|
-
const y = Math.min(boxA.max.y - boxB.min.y, boxB.max.y - boxA.min.y);
|
|
1786
|
-
const z = Math.min(boxA.max.z - boxB.min.z, boxB.max.z - boxA.min.z);
|
|
1787
|
-
return Math.min(x, y, z);
|
|
1788
|
-
},
|
|
1789
|
-
_isCollisionBoxMatched(boxA, boxB) {
|
|
1818
|
+
_isCollisionAabbOverlapped(boxA, boxB) {
|
|
1790
1819
|
if (!this._isCollisionBoxAvailable(boxA) || !this._isCollisionBoxAvailable(boxB))
|
|
1791
1820
|
return false;
|
|
1792
|
-
|
|
1793
|
-
|
|
1821
|
+
return boxA.intersectsBox(boxB);
|
|
1822
|
+
},
|
|
1823
|
+
_getCollisionObbs(box) {
|
|
1824
|
+
if (!this._isCollisionBoxAvailable(box)) return [];
|
|
1825
|
+
const userData = box.userData || {};
|
|
1826
|
+
if (Array.isArray(userData.collisionObbs) && userData.collisionObbs.length > 0) {
|
|
1827
|
+
return userData.collisionObbs;
|
|
1828
|
+
}
|
|
1829
|
+
|
|
1830
|
+
const fallbackCollisionObb = new OBB().fromBox3(box);
|
|
1831
|
+
userData.collisionObbs = [fallbackCollisionObb];
|
|
1832
|
+
box.userData = userData;
|
|
1833
|
+
return userData.collisionObbs;
|
|
1834
|
+
},
|
|
1835
|
+
_getCollisionDebugGroup() {
|
|
1836
|
+
if (!this.scene) return null;
|
|
1837
|
+
if (this.collisionObbDebugGroup && this.collisionObbDebugGroup.parent === this.scene) {
|
|
1838
|
+
return this.collisionObbDebugGroup;
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
const group = new this.THREE.Group();
|
|
1842
|
+
group.name = COLLISION_DEBUG_GROUP_NAME;
|
|
1843
|
+
group.userData.transformControlHelper = true;
|
|
1844
|
+
group.userData.collisionObbDebugHelper = true;
|
|
1845
|
+
this.scene.add(group);
|
|
1846
|
+
this.collisionObbDebugGroup = group;
|
|
1847
|
+
return group;
|
|
1848
|
+
},
|
|
1849
|
+
_createCollisionObbLineSegments(obb, color) {
|
|
1850
|
+
if (!obb) return null;
|
|
1851
|
+
|
|
1852
|
+
const axisInfo = this._getObbAxisInfo(obb);
|
|
1853
|
+
const center = axisInfo.center;
|
|
1854
|
+
const axes = axisInfo.axes;
|
|
1855
|
+
const halfSizes = axisInfo.halfSizes;
|
|
1856
|
+
|
|
1857
|
+
const corners = [];
|
|
1858
|
+
for (let x = -1; x <= 1; x += 2) {
|
|
1859
|
+
for (let y = -1; y <= 1; y += 2) {
|
|
1860
|
+
for (let z = -1; z <= 1; z += 2) {
|
|
1861
|
+
const corner = new this.THREE.Vector3().copy(center);
|
|
1862
|
+
corner.add(axes[0].clone().multiplyScalar(halfSizes[0] * x));
|
|
1863
|
+
corner.add(axes[1].clone().multiplyScalar(halfSizes[1] * y));
|
|
1864
|
+
corner.add(axes[2].clone().multiplyScalar(halfSizes[2] * z));
|
|
1865
|
+
corners.push(corner);
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
}
|
|
1869
|
+
|
|
1870
|
+
const edgeIndices = [
|
|
1871
|
+
[0, 1],
|
|
1872
|
+
[0, 2],
|
|
1873
|
+
[0, 4],
|
|
1874
|
+
[1, 3],
|
|
1875
|
+
[1, 5],
|
|
1876
|
+
[2, 3],
|
|
1877
|
+
[2, 6],
|
|
1878
|
+
[3, 7],
|
|
1879
|
+
[4, 5],
|
|
1880
|
+
[4, 6],
|
|
1881
|
+
[5, 7],
|
|
1882
|
+
[6, 7],
|
|
1883
|
+
];
|
|
1884
|
+
const positions = new Float32Array(edgeIndices.length * 2 * 3);
|
|
1885
|
+
let offset = 0;
|
|
1886
|
+
for (let i = 0; i < edgeIndices.length; i++) {
|
|
1887
|
+
const start = corners[edgeIndices[i][0]];
|
|
1888
|
+
const end = corners[edgeIndices[i][1]];
|
|
1889
|
+
positions[offset++] = start.x;
|
|
1890
|
+
positions[offset++] = start.y;
|
|
1891
|
+
positions[offset++] = start.z;
|
|
1892
|
+
positions[offset++] = end.x;
|
|
1893
|
+
positions[offset++] = end.y;
|
|
1894
|
+
positions[offset++] = end.z;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
const geometry = new this.THREE.BufferGeometry();
|
|
1898
|
+
geometry.setAttribute('position', new this.THREE.BufferAttribute(positions, 3));
|
|
1899
|
+
const material = new this.THREE.LineBasicMaterial({
|
|
1900
|
+
color,
|
|
1901
|
+
transparent: true,
|
|
1902
|
+
opacity: 0.95,
|
|
1903
|
+
depthTest: false,
|
|
1904
|
+
depthWrite: false,
|
|
1905
|
+
toneMapped: false,
|
|
1906
|
+
});
|
|
1907
|
+
const lineSegments = new this.THREE.LineSegments(geometry, material);
|
|
1908
|
+
lineSegments.renderOrder = 999;
|
|
1909
|
+
lineSegments.userData.transformControlHelper = true;
|
|
1910
|
+
lineSegments.userData.collisionObbDebugHelper = true;
|
|
1911
|
+
return lineSegments;
|
|
1912
|
+
},
|
|
1913
|
+
_clearCollisionObbDebugGroup(removeGroup = false) {
|
|
1914
|
+
const group = this.collisionObbDebugGroup;
|
|
1915
|
+
if (!group) return;
|
|
1916
|
+
|
|
1917
|
+
while (group.children.length > 0) {
|
|
1918
|
+
const child = group.children[group.children.length - 1];
|
|
1919
|
+
group.remove(child);
|
|
1920
|
+
if (child.geometry) child.geometry.dispose();
|
|
1921
|
+
if (child.material) child.material.dispose();
|
|
1922
|
+
}
|
|
1923
|
+
|
|
1924
|
+
if (removeGroup && this.scene && group.parent === this.scene) {
|
|
1925
|
+
this.scene.remove(group);
|
|
1926
|
+
this.collisionObbDebugGroup = null;
|
|
1927
|
+
} else if (!this.scene) {
|
|
1928
|
+
this.collisionObbDebugGroup = null;
|
|
1929
|
+
}
|
|
1930
|
+
},
|
|
1931
|
+
hideCollisionObbDebug() {
|
|
1932
|
+
this._clearCollisionObbDebugGroup();
|
|
1933
|
+
this.collisionObbDebugEnabled = false;
|
|
1934
|
+
},
|
|
1935
|
+
_buildCollisionPairMap() {
|
|
1936
|
+
const pairMap = new Map();
|
|
1937
|
+
const collisionPairs = this.getOctreeCollisionPairs();
|
|
1938
|
+
const pairs = collisionPairs && Array.isArray(collisionPairs.pairs) ? collisionPairs.pairs : [];
|
|
1939
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
1940
|
+
const pair = pairs[i];
|
|
1941
|
+
if (!pair) continue;
|
|
1942
|
+
const idA = String(pair.idA);
|
|
1943
|
+
const idB = String(pair.idB);
|
|
1944
|
+
if (!idA || !idB) continue;
|
|
1945
|
+
if (!pairMap.has(idA)) pairMap.set(idA, new Set());
|
|
1946
|
+
if (!pairMap.has(idB)) pairMap.set(idB, new Set());
|
|
1947
|
+
pairMap.get(idA).add(idB);
|
|
1948
|
+
pairMap.get(idB).add(idA);
|
|
1949
|
+
}
|
|
1950
|
+
return pairMap;
|
|
1951
|
+
},
|
|
1952
|
+
refreshCollisionObbDebug() {
|
|
1953
|
+
if (!this.collisionObbDebugEnabled) return;
|
|
1954
|
+
const group = this._getCollisionDebugGroup();
|
|
1955
|
+
if (!group) return;
|
|
1956
|
+
|
|
1957
|
+
this._clearCollisionObbDebugGroup(false);
|
|
1958
|
+
const pairMap = this._buildCollisionPairMap();
|
|
1959
|
+
if (pairMap.size === 0) return;
|
|
1960
|
+
|
|
1961
|
+
pairMap.forEach((relatedIds, modelId) => {
|
|
1962
|
+
const box =
|
|
1963
|
+
this._boxIndex && this._boxIndex.has(String(modelId))
|
|
1964
|
+
? this._boxIndex.get(String(modelId))
|
|
1965
|
+
: this._boxIndex && this._boxIndex.has(modelId)
|
|
1966
|
+
? this._boxIndex.get(modelId)
|
|
1967
|
+
: null;
|
|
1968
|
+
if (!this._isCollisionBoxAvailable(box)) return;
|
|
1969
|
+
|
|
1970
|
+
const obbs = this._getCollisionObbs(box);
|
|
1971
|
+
if (!obbs.length) return;
|
|
1972
|
+
|
|
1973
|
+
const isColliding = relatedIds && relatedIds.size > 0;
|
|
1974
|
+
const color = isColliding ? 0xff3b30 : 0x36cfc9;
|
|
1975
|
+
for (let i = 0; i < obbs.length; i++) {
|
|
1976
|
+
const lineSegments = this._createCollisionObbLineSegments(obbs[i], color);
|
|
1977
|
+
if (!lineSegments) continue;
|
|
1978
|
+
lineSegments.name = `${COLLISION_DEBUG_GROUP_NAME}:${modelId}:${i}`;
|
|
1979
|
+
lineSegments.userData.modelId = modelId;
|
|
1980
|
+
lineSegments.userData.colliding = isColliding;
|
|
1981
|
+
group.add(lineSegments);
|
|
1982
|
+
}
|
|
1983
|
+
});
|
|
1984
|
+
},
|
|
1985
|
+
showCollisionObbDebug() {
|
|
1986
|
+
this.collisionObbDebugEnabled = true;
|
|
1987
|
+
this.refreshCollisionObbDebug();
|
|
1988
|
+
},
|
|
1989
|
+
toggleCollisionObbDebug(forceVisible) {
|
|
1990
|
+
const nextVisible =
|
|
1991
|
+
typeof forceVisible === 'boolean' ? forceVisible : !this.collisionObbDebugEnabled;
|
|
1992
|
+
if (nextVisible) {
|
|
1993
|
+
this.showCollisionObbDebug();
|
|
1994
|
+
} else {
|
|
1995
|
+
this.hideCollisionObbDebug();
|
|
1996
|
+
}
|
|
1997
|
+
},
|
|
1998
|
+
_getObbAxisInfo(obb) {
|
|
1999
|
+
const xAxis = new this.THREE.Vector3();
|
|
2000
|
+
const yAxis = new this.THREE.Vector3();
|
|
2001
|
+
const zAxis = new this.THREE.Vector3();
|
|
2002
|
+
obb.rotation.extractBasis(xAxis, yAxis, zAxis);
|
|
2003
|
+
return {
|
|
2004
|
+
center: obb.center,
|
|
2005
|
+
halfSizes: [obb.halfSize.x, obb.halfSize.y, obb.halfSize.z],
|
|
2006
|
+
axes: [xAxis, yAxis, zAxis],
|
|
2007
|
+
};
|
|
2008
|
+
},
|
|
2009
|
+
_getObbProjectionRadius(axisInfo, axis) {
|
|
2010
|
+
return (
|
|
2011
|
+
axisInfo.halfSizes[0] * Math.abs(axis.dot(axisInfo.axes[0])) +
|
|
2012
|
+
axisInfo.halfSizes[1] * Math.abs(axis.dot(axisInfo.axes[1])) +
|
|
2013
|
+
axisInfo.halfSizes[2] * Math.abs(axis.dot(axisInfo.axes[2]))
|
|
2014
|
+
);
|
|
2015
|
+
},
|
|
2016
|
+
_getObbMinPenetration(obbA, obbB) {
|
|
2017
|
+
const axisInfoA = this._getObbAxisInfo(obbA);
|
|
2018
|
+
const axisInfoB = this._getObbAxisInfo(obbB);
|
|
2019
|
+
const centerDelta = new this.THREE.Vector3().subVectors(axisInfoB.center, axisInfoA.center);
|
|
2020
|
+
let minPenetration = Infinity;
|
|
2021
|
+
|
|
2022
|
+
const testAxis = axis => {
|
|
2023
|
+
const lengthSq = axis.lengthSq();
|
|
2024
|
+
if (lengthSq <= COLLISION_OBB_AXIS_EPSILON) return true;
|
|
2025
|
+
|
|
2026
|
+
const normalizedAxis = axis.clone().multiplyScalar(1 / Math.sqrt(lengthSq));
|
|
2027
|
+
const projectionDistance = Math.abs(centerDelta.dot(normalizedAxis));
|
|
2028
|
+
const penetration =
|
|
2029
|
+
this._getObbProjectionRadius(axisInfoA, normalizedAxis) +
|
|
2030
|
+
this._getObbProjectionRadius(axisInfoB, normalizedAxis) -
|
|
2031
|
+
projectionDistance;
|
|
2032
|
+
|
|
2033
|
+
if (penetration <= 0) {
|
|
2034
|
+
minPenetration = penetration;
|
|
2035
|
+
return false;
|
|
2036
|
+
}
|
|
2037
|
+
if (penetration < minPenetration) {
|
|
2038
|
+
minPenetration = penetration;
|
|
2039
|
+
}
|
|
2040
|
+
return true;
|
|
2041
|
+
};
|
|
2042
|
+
|
|
2043
|
+
for (let i = 0; i < 3; i++) {
|
|
2044
|
+
if (!testAxis(axisInfoA.axes[i]) || !testAxis(axisInfoB.axes[i])) {
|
|
2045
|
+
return minPenetration;
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
for (let i = 0; i < 3; i++) {
|
|
2050
|
+
for (let j = 0; j < 3; j++) {
|
|
2051
|
+
const crossAxis = axisInfoA.axes[i].clone().cross(axisInfoB.axes[j]);
|
|
2052
|
+
if (!testAxis(crossAxis)) {
|
|
2053
|
+
return minPenetration;
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
return minPenetration === Infinity ? 0 : minPenetration;
|
|
2059
|
+
},
|
|
2060
|
+
_isCollisionBoxMatched(boxA, boxB) {
|
|
2061
|
+
if (!this._isCollisionAabbOverlapped(boxA, boxB)) return false;
|
|
2062
|
+
|
|
2063
|
+
const obbsA = this._getCollisionObbs(boxA);
|
|
2064
|
+
const obbsB = this._getCollisionObbs(boxB);
|
|
2065
|
+
for (let i = 0; i < obbsA.length; i++) {
|
|
2066
|
+
for (let j = 0; j < obbsB.length; j++) {
|
|
2067
|
+
if (this._getObbMinPenetration(obbsA[i], obbsB[j]) > COLLISION_PENETRATION_EPSILON) {
|
|
2068
|
+
return true;
|
|
2069
|
+
}
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
return false;
|
|
1794
2073
|
},
|
|
1795
2074
|
_queryOctreeByBox(box) {
|
|
1796
2075
|
const results = [];
|
|
@@ -1800,7 +2079,7 @@ export default {
|
|
|
1800
2079
|
const stack = [root];
|
|
1801
2080
|
while (stack.length) {
|
|
1802
2081
|
const node = stack.pop();
|
|
1803
|
-
if (!node || !node.box || !this.
|
|
2082
|
+
if (!node || !node.box || !this._isCollisionAabbOverlapped(node.box, box)) continue;
|
|
1804
2083
|
|
|
1805
2084
|
if (node.children) {
|
|
1806
2085
|
for (let i = 0; i < 8; i++) {
|
|
@@ -1811,7 +2090,7 @@ export default {
|
|
|
1811
2090
|
if (node.items && node.items.length) {
|
|
1812
2091
|
for (let i = 0; i < node.items.length; i++) {
|
|
1813
2092
|
const item = node.items[i];
|
|
1814
|
-
if (item && this.
|
|
2093
|
+
if (item && this._isCollisionAabbOverlapped(item.box, box)) {
|
|
1815
2094
|
results.push(item);
|
|
1816
2095
|
}
|
|
1817
2096
|
}
|
|
@@ -3891,6 +4170,9 @@ export default {
|
|
|
3891
4170
|
this.setPointerCameraGuard(true);
|
|
3892
4171
|
} else {
|
|
3893
4172
|
this.setPointerCameraGuard(false);
|
|
4173
|
+
if (event.button === 0) {
|
|
4174
|
+
this.setOrbitPointByIntersection(this.getPrimaryIntersection(intersects));
|
|
4175
|
+
}
|
|
3894
4176
|
}
|
|
3895
4177
|
this.firstTime = new Date().getTime();
|
|
3896
4178
|
let params = {
|
|
@@ -3924,6 +4206,26 @@ export default {
|
|
|
3924
4206
|
}
|
|
3925
4207
|
return [];
|
|
3926
4208
|
},
|
|
4209
|
+
setOrbitPointByIntersection(intersection) {
|
|
4210
|
+
if (
|
|
4211
|
+
!intersection ||
|
|
4212
|
+
!intersection.point ||
|
|
4213
|
+
!this.cameraControls ||
|
|
4214
|
+
typeof this.cameraControls.setOrbitPoint !== 'function'
|
|
4215
|
+
) {
|
|
4216
|
+
return;
|
|
4217
|
+
}
|
|
4218
|
+
const { x, y, z } = intersection.point;
|
|
4219
|
+
if (![x, y, z].every(Number.isFinite)) return;
|
|
4220
|
+
|
|
4221
|
+
// 左键旋转前先将旋转中心切到鼠标命中点,避免继续围绕默认目标点旋转。
|
|
4222
|
+
this.cameraControls.setOrbitPoint(x, y, z);
|
|
4223
|
+
this.cameraControls.update(0);
|
|
4224
|
+
},
|
|
4225
|
+
resetCameraFocalOffset(enableTransition = false) {
|
|
4226
|
+
if (!this.cameraControls || typeof this.cameraControls.setFocalOffset !== 'function') return;
|
|
4227
|
+
this.cameraControls.setFocalOffset(0, 0, 0, enableTransition);
|
|
4228
|
+
},
|
|
3927
4229
|
isTransformControlIntersection(intersection) {
|
|
3928
4230
|
let current = intersection && intersection.object ? intersection.object : null;
|
|
3929
4231
|
while (current) {
|
|
@@ -4341,6 +4643,7 @@ export default {
|
|
|
4341
4643
|
}
|
|
4342
4644
|
children.instanceMatrix.needsUpdate = true;
|
|
4343
4645
|
});
|
|
4646
|
+
this.refreshCollisionObbDebug();
|
|
4344
4647
|
this.notifyCameraChange(); // 触发场景更新
|
|
4345
4648
|
break;
|
|
4346
4649
|
}
|
|
@@ -4445,6 +4748,7 @@ export default {
|
|
|
4445
4748
|
if (this._boxIndex) {
|
|
4446
4749
|
this.buildOctreeFromBoxIndex();
|
|
4447
4750
|
}
|
|
4751
|
+
this.refreshCollisionObbDebug();
|
|
4448
4752
|
},
|
|
4449
4753
|
showOutlinePass(instanceId) {
|
|
4450
4754
|
let targetObj = this.getObjectByName(instanceId);
|
|
@@ -4591,6 +4895,7 @@ export default {
|
|
|
4591
4895
|
}
|
|
4592
4896
|
children.instanceMatrix.needsUpdate = true;
|
|
4593
4897
|
});
|
|
4898
|
+
this.refreshCollisionObbDebug();
|
|
4594
4899
|
break;
|
|
4595
4900
|
}
|
|
4596
4901
|
case 'opacity':
|
|
@@ -4604,6 +4909,7 @@ export default {
|
|
|
4604
4909
|
children.geometry.attributes.opacity.needsUpdate = true;
|
|
4605
4910
|
}
|
|
4606
4911
|
});
|
|
4912
|
+
break;
|
|
4607
4913
|
}
|
|
4608
4914
|
}
|
|
4609
4915
|
}
|
|
@@ -4721,6 +5027,7 @@ export default {
|
|
|
4721
5027
|
*/
|
|
4722
5028
|
cameraLocation(params) {
|
|
4723
5029
|
const { enableTransition = true } = params;
|
|
5030
|
+
this.resetCameraFocalOffset(enableTransition);
|
|
4724
5031
|
this.cameraControls.setLookAt(
|
|
4725
5032
|
params.x,
|
|
4726
5033
|
params.y,
|
|
@@ -4757,15 +5064,15 @@ export default {
|
|
|
4757
5064
|
let cameraCenter = viewAll
|
|
4758
5065
|
? new this.THREE.Vector3(p.x, p.y, p.z)
|
|
4759
5066
|
: new this.THREE.Vector3(p.x, p.y, p.z).addScalar(Math.max(size.x, size.y, size.z));
|
|
4760
|
-
this.
|
|
4761
|
-
cameraCenter.x,
|
|
4762
|
-
cameraCenter.y,
|
|
4763
|
-
cameraCenter.z,
|
|
4764
|
-
center.x,
|
|
4765
|
-
center.y,
|
|
4766
|
-
center.z,
|
|
4767
|
-
true
|
|
4768
|
-
);
|
|
5067
|
+
this.cameraLocation({
|
|
5068
|
+
x: cameraCenter.x,
|
|
5069
|
+
y: cameraCenter.y,
|
|
5070
|
+
z: cameraCenter.z,
|
|
5071
|
+
heading: center.x,
|
|
5072
|
+
pitch: center.y,
|
|
5073
|
+
roll: center.z,
|
|
5074
|
+
enableTransition: true,
|
|
5075
|
+
});
|
|
4769
5076
|
},
|
|
4770
5077
|
// 添加广告牌
|
|
4771
5078
|
/*
|
|
@@ -5009,6 +5316,7 @@ export default {
|
|
|
5009
5316
|
this.modelStateManager.debounceTimer = null;
|
|
5010
5317
|
}
|
|
5011
5318
|
this.clearBypassCullingModelIds();
|
|
5319
|
+
this.hideCollisionObbDebug();
|
|
5012
5320
|
|
|
5013
5321
|
if (this.scene) {
|
|
5014
5322
|
this.removeTraverse();
|
|
@@ -5273,6 +5581,7 @@ export default {
|
|
|
5273
5581
|
const nodeType = userData.nodeType || userData.rootType || '';
|
|
5274
5582
|
if (nodeType === 'custom-root') return true;
|
|
5275
5583
|
if (userData.transformControlHelper === true) return true;
|
|
5584
|
+
if (userData.collisionObbDebugHelper === true) return true;
|
|
5276
5585
|
if (object.isCamera || object.isLight) return true;
|
|
5277
5586
|
if (typeof object.type === 'string' && /Helper$/i.test(object.type)) return true;
|
|
5278
5587
|
return object.type === 'CSS2DObject' || object.type === 'TransformControlsRoot';
|