gltf-parser-plugin 1.1.1 → 1.1.3
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.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Mesh, Vector3, Triangle, BufferGeometry, EventDispatcher, DataTexture, RGBAFormat, UnsignedByteType, SRGBColorSpace, Texture, MeshStandardMaterial, DoubleSide, FrontSide, BufferAttribute, OrthographicCamera, Float32BufferAttribute, Vector2, WebGLRenderer, WebGLRenderTarget, ShaderMaterial, OneFactor, ZeroFactor, CustomBlending, Box2, Matrix4, Matrix3, Matrix2, Vector4, MeshBasicMaterial, Loader, Scene, Group, InstancedMesh, Quaternion } from "three";
|
|
1
|
+
import { Mesh, Vector3, Triangle, BufferGeometry, EventDispatcher, DataTexture, RGBAFormat, UnsignedByteType, SRGBColorSpace, Texture, MeshStandardMaterial, DoubleSide, FrontSide, BufferAttribute, OrthographicCamera, Float32BufferAttribute, Vector2, WebGLRenderer, WebGLRenderTarget, ShaderMaterial, OneFactor, ZeroFactor, CustomBlending, Box2, Matrix4, Matrix3, Matrix2, Vector4, MeshBasicMaterial, Loader, Scene, Group, InstancedMesh, Quaternion, Box3 } from "three";
|
|
2
2
|
class FeatureIdUniforms {
|
|
3
3
|
mesh;
|
|
4
4
|
plugin;
|
|
@@ -1871,13 +1871,17 @@ class GLTFParserPlugin {
|
|
|
1871
1871
|
async _fetchStructureData() {
|
|
1872
1872
|
const url = this._getStructureUrl();
|
|
1873
1873
|
if (!url) {
|
|
1874
|
-
console.warn(
|
|
1874
|
+
console.warn(
|
|
1875
|
+
"[GLTFParserPlugin] Cannot derive structure.json URL: tiles not initialized"
|
|
1876
|
+
);
|
|
1875
1877
|
return null;
|
|
1876
1878
|
}
|
|
1877
1879
|
try {
|
|
1878
1880
|
const response = await fetch(url);
|
|
1879
1881
|
if (!response.ok) {
|
|
1880
|
-
console.warn(
|
|
1882
|
+
console.warn(
|
|
1883
|
+
`[GLTFParserPlugin] Failed to fetch structure.json: ${response.status}`
|
|
1884
|
+
);
|
|
1881
1885
|
return null;
|
|
1882
1886
|
}
|
|
1883
1887
|
const data = await response.json();
|
|
@@ -1932,6 +1936,142 @@ class GLTFParserPlugin {
|
|
|
1932
1936
|
return this._ensureStructureLoaded();
|
|
1933
1937
|
}
|
|
1934
1938
|
// =============================================
|
|
1939
|
+
// Spatial Query Methods
|
|
1940
|
+
// =============================================
|
|
1941
|
+
_pointInPolygon(px, py, polygon) {
|
|
1942
|
+
let inside = false;
|
|
1943
|
+
const n = polygon.length;
|
|
1944
|
+
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
1945
|
+
const xi = polygon[i].x, yi = polygon[i].y;
|
|
1946
|
+
const xj = polygon[j].x, yj = polygon[j].y;
|
|
1947
|
+
if (yi > py !== yj > py && px < (xj - xi) * (py - yi) / (yj - yi) + xi) {
|
|
1948
|
+
inside = !inside;
|
|
1949
|
+
}
|
|
1950
|
+
}
|
|
1951
|
+
return inside;
|
|
1952
|
+
}
|
|
1953
|
+
_segmentsIntersect(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
|
|
1954
|
+
const cross = (ox, oy, ax, ay, bx, by) => (ax - ox) * (by - oy) - (ay - oy) * (bx - ox);
|
|
1955
|
+
const d1 = cross(bx1, by1, bx2, by2, ax1, ay1);
|
|
1956
|
+
const d2 = cross(bx1, by1, bx2, by2, ax2, ay2);
|
|
1957
|
+
const d3 = cross(ax1, ay1, ax2, ay2, bx1, by1);
|
|
1958
|
+
const d4 = cross(ax1, ay1, ax2, ay2, bx2, by2);
|
|
1959
|
+
if ((d1 > 0 && d2 < 0 || d1 < 0 && d2 > 0) && (d3 > 0 && d4 < 0 || d3 < 0 && d4 > 0)) {
|
|
1960
|
+
return true;
|
|
1961
|
+
}
|
|
1962
|
+
const onSeg = (px, py, qx, qy, rx, ry) => Math.min(px, qx) <= rx && rx <= Math.max(px, qx) && Math.min(py, qy) <= ry && ry <= Math.max(py, qy);
|
|
1963
|
+
if (d1 === 0 && onSeg(bx1, by1, bx2, by2, ax1, ay1)) return true;
|
|
1964
|
+
if (d2 === 0 && onSeg(bx1, by1, bx2, by2, ax2, ay2)) return true;
|
|
1965
|
+
if (d3 === 0 && onSeg(ax1, ay1, ax2, ay2, bx1, by1)) return true;
|
|
1966
|
+
if (d4 === 0 && onSeg(ax1, ay1, ax2, ay2, bx2, by2)) return true;
|
|
1967
|
+
return false;
|
|
1968
|
+
}
|
|
1969
|
+
_polygonIntersectsRect(polygon, minX, minY, maxX, maxY) {
|
|
1970
|
+
const n = polygon.length;
|
|
1971
|
+
for (let i = 0; i < n; i++) {
|
|
1972
|
+
const p = polygon[i];
|
|
1973
|
+
if (p.x >= minX && p.x <= maxX && p.y >= minY && p.y <= maxY) {
|
|
1974
|
+
return true;
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
if (this._pointInPolygon(minX, minY, polygon) || this._pointInPolygon(maxX, minY, polygon) || this._pointInPolygon(maxX, maxY, polygon) || this._pointInPolygon(minX, maxY, polygon)) {
|
|
1978
|
+
return true;
|
|
1979
|
+
}
|
|
1980
|
+
const rx = [minX, maxX, maxX, minX];
|
|
1981
|
+
const ry = [minY, minY, maxY, maxY];
|
|
1982
|
+
for (let i = 0; i < n; i++) {
|
|
1983
|
+
const a = polygon[i];
|
|
1984
|
+
const b = polygon[(i + 1) % n];
|
|
1985
|
+
for (let j = 0; j < 4; j++) {
|
|
1986
|
+
const k = (j + 1) % 4;
|
|
1987
|
+
if (this._segmentsIntersect(
|
|
1988
|
+
a.x,
|
|
1989
|
+
a.y,
|
|
1990
|
+
b.x,
|
|
1991
|
+
b.y,
|
|
1992
|
+
rx[j],
|
|
1993
|
+
ry[j],
|
|
1994
|
+
rx[k],
|
|
1995
|
+
ry[k]
|
|
1996
|
+
)) {
|
|
1997
|
+
return true;
|
|
1998
|
+
}
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
return false;
|
|
2002
|
+
}
|
|
2003
|
+
/**
|
|
2004
|
+
* 选择包围盒范围内的构件(包含相交和包含两种情况)
|
|
2005
|
+
* @param box 查询用的 Box3 范围,坐标系与 structure.json 中 bbox 一致
|
|
2006
|
+
* @returns 范围内所有构件的 oid 数组
|
|
2007
|
+
*/
|
|
2008
|
+
async selectByBox(box) {
|
|
2009
|
+
await this._ensureStructureLoaded();
|
|
2010
|
+
const result = [];
|
|
2011
|
+
const nodeBox = new Box3();
|
|
2012
|
+
for (const [oid, node] of this._oidNodeMap) {
|
|
2013
|
+
if (!node.bbox || node.bbox.length < 6) continue;
|
|
2014
|
+
nodeBox.min.set(node.bbox[0], node.bbox[1], node.bbox[2]);
|
|
2015
|
+
nodeBox.max.set(node.bbox[3], node.bbox[4], node.bbox[5]);
|
|
2016
|
+
if (box.intersectsBox(nodeBox)) {
|
|
2017
|
+
result.push(oid);
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
return result;
|
|
2021
|
+
}
|
|
2022
|
+
/**
|
|
2023
|
+
* 选择多边形(平面投影)范围内的构件(包含相交和包含两种情况)
|
|
2024
|
+
* @param polygon 多边形顶点数组(Vector3),按顺序连接构成闭合多边形
|
|
2025
|
+
* @param axis 投影平面,决定使用 bbox 的哪两个轴做 2D 判定
|
|
2026
|
+
* - 'xz'(默认):俯视图,取 bbox 的 x/z 坐标
|
|
2027
|
+
* - 'xy':正视图,取 bbox 的 x/y 坐标
|
|
2028
|
+
* - 'yz':侧视图,取 bbox 的 y/z 坐标
|
|
2029
|
+
* @returns 范围内所有构件的 oid 数组
|
|
2030
|
+
*/
|
|
2031
|
+
async selectByPolygon(polygon, axis = "xz") {
|
|
2032
|
+
await this._ensureStructureLoaded();
|
|
2033
|
+
const result = [];
|
|
2034
|
+
const polygon2D = polygon.map((p) => {
|
|
2035
|
+
switch (axis) {
|
|
2036
|
+
case "xy":
|
|
2037
|
+
return new Vector2(p.x, p.y);
|
|
2038
|
+
case "yz":
|
|
2039
|
+
return new Vector2(p.y, p.z);
|
|
2040
|
+
case "xz":
|
|
2041
|
+
default:
|
|
2042
|
+
return new Vector2(p.x, p.z);
|
|
2043
|
+
}
|
|
2044
|
+
});
|
|
2045
|
+
for (const [oid, node] of this._oidNodeMap) {
|
|
2046
|
+
if (!node.bbox || node.bbox.length < 6) continue;
|
|
2047
|
+
let minU, minV, maxU, maxV;
|
|
2048
|
+
switch (axis) {
|
|
2049
|
+
case "xy":
|
|
2050
|
+
minU = node.bbox[0];
|
|
2051
|
+
minV = node.bbox[1];
|
|
2052
|
+
maxU = node.bbox[3];
|
|
2053
|
+
maxV = node.bbox[4];
|
|
2054
|
+
break;
|
|
2055
|
+
case "xz":
|
|
2056
|
+
minU = node.bbox[0];
|
|
2057
|
+
minV = node.bbox[2];
|
|
2058
|
+
maxU = node.bbox[3];
|
|
2059
|
+
maxV = node.bbox[5];
|
|
2060
|
+
break;
|
|
2061
|
+
case "yz":
|
|
2062
|
+
minU = node.bbox[1];
|
|
2063
|
+
minV = node.bbox[2];
|
|
2064
|
+
maxU = node.bbox[4];
|
|
2065
|
+
maxV = node.bbox[5];
|
|
2066
|
+
break;
|
|
2067
|
+
}
|
|
2068
|
+
if (this._polygonIntersectsRect(polygon2D, minU, minV, maxU, maxV)) {
|
|
2069
|
+
result.push(oid);
|
|
2070
|
+
}
|
|
2071
|
+
}
|
|
2072
|
+
return result;
|
|
2073
|
+
}
|
|
2074
|
+
// =============================================
|
|
1935
2075
|
// Model Info Methods
|
|
1936
2076
|
// =============================================
|
|
1937
2077
|
_getModelInfoUrl() {
|
|
@@ -1942,13 +2082,17 @@ class GLTFParserPlugin {
|
|
|
1942
2082
|
async _fetchModelInfo() {
|
|
1943
2083
|
const url = this._getModelInfoUrl();
|
|
1944
2084
|
if (!url) {
|
|
1945
|
-
console.warn(
|
|
2085
|
+
console.warn(
|
|
2086
|
+
"[GLTFParserPlugin] Cannot derive modelInfo.json URL: tiles not initialized"
|
|
2087
|
+
);
|
|
1946
2088
|
return null;
|
|
1947
2089
|
}
|
|
1948
2090
|
try {
|
|
1949
2091
|
const response = await fetch(url);
|
|
1950
2092
|
if (!response.ok) {
|
|
1951
|
-
console.warn(
|
|
2093
|
+
console.warn(
|
|
2094
|
+
`[GLTFParserPlugin] Failed to fetch modelInfo.json: ${response.status}`
|
|
2095
|
+
);
|
|
1952
2096
|
return null;
|
|
1953
2097
|
}
|
|
1954
2098
|
const data = await response.json();
|
|
@@ -2129,7 +2273,8 @@ class GLTFParserPlugin {
|
|
|
2129
2273
|
// =============================================
|
|
2130
2274
|
_isOidBlocked(oid) {
|
|
2131
2275
|
if (this._frozenOids.has(oid)) return true;
|
|
2132
|
-
if (this._isolatedOids.size > 0 && !this._isolatedOids.has(oid))
|
|
2276
|
+
if (this._isolatedOids.size > 0 && !this._isolatedOids.has(oid))
|
|
2277
|
+
return true;
|
|
2133
2278
|
return false;
|
|
2134
2279
|
}
|
|
2135
2280
|
_trackMesh(mesh, oid) {
|
|
@@ -2214,6 +2359,13 @@ class GLTFParserPlugin {
|
|
|
2214
2359
|
}
|
|
2215
2360
|
this._syncCollectorMeshes();
|
|
2216
2361
|
}
|
|
2362
|
+
/**
|
|
2363
|
+
* 冻结单个构件
|
|
2364
|
+
*/
|
|
2365
|
+
freezeByOid(oid) {
|
|
2366
|
+
this._frozenOids.add(oid);
|
|
2367
|
+
this._syncCollectorMeshes();
|
|
2368
|
+
}
|
|
2217
2369
|
/**
|
|
2218
2370
|
* 解冻指定构件
|
|
2219
2371
|
*/
|
|
@@ -2223,6 +2375,13 @@ class GLTFParserPlugin {
|
|
|
2223
2375
|
}
|
|
2224
2376
|
this._syncCollectorMeshes();
|
|
2225
2377
|
}
|
|
2378
|
+
/**
|
|
2379
|
+
* 解冻单个构件
|
|
2380
|
+
*/
|
|
2381
|
+
unfreezeByOid(oid) {
|
|
2382
|
+
this._frozenOids.delete(oid);
|
|
2383
|
+
this._syncCollectorMeshes();
|
|
2384
|
+
}
|
|
2226
2385
|
/**
|
|
2227
2386
|
* 解冻全部构件
|
|
2228
2387
|
*/
|
|
@@ -2245,6 +2404,13 @@ class GLTFParserPlugin {
|
|
|
2245
2404
|
}
|
|
2246
2405
|
this._syncCollectorMeshes();
|
|
2247
2406
|
}
|
|
2407
|
+
/**
|
|
2408
|
+
* 往隔离集合中添加单个构件
|
|
2409
|
+
*/
|
|
2410
|
+
isolateByOid(oid) {
|
|
2411
|
+
this._isolatedOids.add(oid);
|
|
2412
|
+
this._syncCollectorMeshes();
|
|
2413
|
+
}
|
|
2248
2414
|
/**
|
|
2249
2415
|
* 取消隔离指定构件
|
|
2250
2416
|
*/
|
|
@@ -2254,6 +2420,13 @@ class GLTFParserPlugin {
|
|
|
2254
2420
|
}
|
|
2255
2421
|
this._syncCollectorMeshes();
|
|
2256
2422
|
}
|
|
2423
|
+
/**
|
|
2424
|
+
* 从隔离集合中移除单个构件
|
|
2425
|
+
*/
|
|
2426
|
+
unisolateByOid(oid) {
|
|
2427
|
+
this._isolatedOids.delete(oid);
|
|
2428
|
+
this._syncCollectorMeshes();
|
|
2429
|
+
}
|
|
2257
2430
|
/**
|
|
2258
2431
|
* 取消全部隔离,恢复所有构件的交互能力
|
|
2259
2432
|
*/
|