s3m-three 0.4.19 → 0.4.21
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/browser/assets/{s3mWorker-4iTAmWIu.js → s3mWorker-DvAUA8NJ.js} +1 -1
- package/dist/browser/s3m-three.iife.ext-three.js +243 -243
- package/dist/browser/s3m-three.iife.js +227 -227
- package/dist/core/Draco.d.ts.map +1 -1
- package/dist/core/Draco.js +0 -1
- package/dist/core/Draco.js.map +1 -1
- package/dist/core/S3MBlockParser.d.ts.map +1 -1
- package/dist/core/S3MBlockParser.js +27 -14
- package/dist/core/S3MBlockParser.js.map +1 -1
- package/dist/core/SplatSort.d.ts +14 -1
- package/dist/core/SplatSort.d.ts.map +1 -1
- package/dist/core/SplatSort.js +51 -4
- package/dist/core/SplatSort.js.map +1 -1
- package/dist/core/TileGeometry.d.ts +10 -0
- package/dist/core/TileGeometry.d.ts.map +1 -1
- package/dist/core/TileGeometry.js +17 -14
- package/dist/core/TileGeometry.js.map +1 -1
- package/dist/render/DatasetManager.d.ts +3 -1
- package/dist/render/DatasetManager.d.ts.map +1 -1
- package/dist/render/DatasetManager.js +2 -1
- package/dist/render/DatasetManager.js.map +1 -1
- package/dist/render/FeatureStyleManager.d.ts.map +1 -1
- package/dist/render/GeometryBuilder.d.ts +8 -0
- package/dist/render/GeometryBuilder.d.ts.map +1 -1
- package/dist/render/GeometryBuilder.js +62 -7
- package/dist/render/GeometryBuilder.js.map +1 -1
- package/dist/render/S3MViewer.d.ts +106 -440
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +297 -1653
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/SplatSorter.d.ts.map +1 -1
- package/dist/render/SplatSorter.js +8 -1
- package/dist/render/SplatSorter.js.map +1 -1
- package/dist/render/viewer/EdgeDecorator.d.ts +206 -0
- package/dist/render/viewer/EdgeDecorator.d.ts.map +1 -0
- package/dist/render/viewer/EdgeDecorator.js +628 -0
- package/dist/render/viewer/EdgeDecorator.js.map +1 -0
- package/dist/render/viewer/HeightIndex.d.ts +36 -0
- package/dist/render/viewer/HeightIndex.d.ts.map +1 -0
- package/dist/render/viewer/HeightIndex.js +98 -0
- package/dist/render/viewer/HeightIndex.js.map +1 -0
- package/dist/render/viewer/LightRig.d.ts +88 -0
- package/dist/render/viewer/LightRig.d.ts.map +1 -0
- package/dist/render/viewer/LightRig.js +229 -0
- package/dist/render/viewer/LightRig.js.map +1 -0
- package/dist/render/viewer/PickService.d.ts +109 -0
- package/dist/render/viewer/PickService.d.ts.map +1 -0
- package/dist/render/viewer/PickService.js +591 -0
- package/dist/render/viewer/PickService.js.map +1 -0
- package/dist/render/viewer/SelectionDecorator.d.ts +84 -0
- package/dist/render/viewer/SelectionDecorator.d.ts.map +1 -0
- package/dist/render/viewer/SelectionDecorator.js +339 -0
- package/dist/render/viewer/SelectionDecorator.js.map +1 -0
- package/dist/render/viewer/SplatLayer.d.ts +26 -0
- package/dist/render/viewer/SplatLayer.d.ts.map +1 -0
- package/dist/render/viewer/SplatLayer.js +44 -0
- package/dist/render/viewer/SplatLayer.js.map +1 -0
- package/dist/render/viewer/types.d.ts +256 -0
- package/dist/render/viewer/types.d.ts.map +1 -0
- package/dist/render/viewer/types.js +3 -0
- package/dist/render/viewer/types.js.map +1 -0
- package/dist/tileset/S3MTileset.d.ts +30 -3
- package/dist/tileset/S3MTileset.d.ts.map +1 -1
- package/dist/tileset/S3MTileset.js +99 -5
- package/dist/tileset/S3MTileset.js.map +1 -1
- package/dist/worker/s3mWorker.js +1 -1
- package/dist/worker/s3mWorker.js.map +1 -1
- package/docs/API.md +9 -28
- package/docs/FORMAT-NOTES.md +38 -14
- package/package.json +1 -1
- package/src/core/Draco.ts +1 -2
- package/src/core/S3MBlockParser.ts +27 -16
- package/src/core/SplatSort.ts +67 -5
- package/src/core/TileGeometry.ts +24 -11
- package/src/render/DatasetManager.ts +5 -1
- package/src/render/FeatureStyleManager.ts +1 -1
- package/src/render/GeometryBuilder.ts +59 -7
- package/src/render/S3MViewer.ts +327 -1916
- package/src/render/SplatSorter.ts +8 -1
- package/src/render/viewer/EdgeDecorator.ts +722 -0
- package/src/render/viewer/HeightIndex.ts +94 -0
- package/src/render/viewer/LightRig.ts +267 -0
- package/src/render/viewer/PickService.ts +651 -0
- package/src/render/viewer/SelectionDecorator.ts +377 -0
- package/src/render/viewer/SplatLayer.ts +44 -0
- package/src/render/viewer/types.ts +264 -0
- package/src/tileset/S3MTileset.ts +106 -6
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 选中态:高亮写入、轮廓 / 棱线装饰、跨瓦片重放。
|
|
3
|
+
*
|
|
4
|
+
* 从 `S3MViewer` 搬出来的第三块。它持有 `selection` 与 `selectedMeshes` 两份状态,
|
|
5
|
+
* 其余(uniform、样式、轮廓材质、逐网格棱线材质)都从宿主取。
|
|
6
|
+
*
|
|
7
|
+
* ## 为什么需要「重放」
|
|
8
|
+
*
|
|
9
|
+
* 选中高亮是直接写在各 mesh 材质的 `uSelBatch` / `uSelWhole` 上的,而 LOD 细化、
|
|
10
|
+
* 瓦片重载、淘汰回补都会换掉 mesh —— 不重放的话,用户点中的那栋楼一细化就失去高亮
|
|
11
|
+
* (状态还在 `selection.smid` 里,只是没人往新 mesh 上刷)。
|
|
12
|
+
*
|
|
13
|
+
* ## 没有单体化信息时的退路
|
|
14
|
+
*
|
|
15
|
+
* 倾斜摄影 / 白模整块没有 smid,`uSelBatch` 给 -1 会让「点中了但什么都没亮」。
|
|
16
|
+
* 这时改置 `uSelWhole = 1` 整块高亮,至少让用户看见自己点到了什么。
|
|
17
|
+
*/
|
|
18
|
+
import * as THREE from 'three';
|
|
19
|
+
import type { OutlineMaterial, S3MStyle } from '../StyleMaterial.js';
|
|
20
|
+
import type { ThickLineMaterial } from '../EdgeLines.js';
|
|
21
|
+
import type { FeatureStyleManager } from '../FeatureStyleManager.js';
|
|
22
|
+
import type { StyleUniforms } from '../../core/types.js';
|
|
23
|
+
import type { PickResult } from '../S3MViewer.js';
|
|
24
|
+
export interface SelectionHost {
|
|
25
|
+
readonly uniforms: StyleUniforms;
|
|
26
|
+
readonly style: S3MStyle;
|
|
27
|
+
readonly outlineMaterial: OutlineMaterial;
|
|
28
|
+
/** 选中棱线的全局材质(外观 uniform 的持有者) */
|
|
29
|
+
readonly selectionEdgeMaterial: ThickLineMaterial;
|
|
30
|
+
/** 单体样式 / 过滤状态(判断被隐藏的单体不该被高亮) */
|
|
31
|
+
readonly featureStyleManager: FeatureStyleManager;
|
|
32
|
+
/** SMID → 包含它的网格 */
|
|
33
|
+
readonly smidMeshes: Map<number, Set<THREE.Mesh>>;
|
|
34
|
+
readonly pointClouds: Set<THREE.Points>;
|
|
35
|
+
applyPointCloudStyle(pc: THREE.Points, selected?: boolean): void;
|
|
36
|
+
onPick(result: PickResult | null): void;
|
|
37
|
+
requestRepaint(): void;
|
|
38
|
+
/** 选中棱线的逐网格材质(由 EdgeDecorator 提供) */
|
|
39
|
+
createSelectionEdgeMaterial(mesh: THREE.Mesh): ThickLineMaterial;
|
|
40
|
+
}
|
|
41
|
+
export declare class SelectionDecorator {
|
|
42
|
+
private readonly host;
|
|
43
|
+
/** 当前选中(null = 没选中) */
|
|
44
|
+
selection: PickResult | null;
|
|
45
|
+
/** 被高亮的网格(点云也在这份列表里) */
|
|
46
|
+
selectedMeshes: THREE.Object3D[];
|
|
47
|
+
private _outlineMeshes;
|
|
48
|
+
private _selectionEdgeMeshes;
|
|
49
|
+
constructor(host: SelectionHost);
|
|
50
|
+
/** @internal 测试用:选中棱线的网格列表 */
|
|
51
|
+
get selectionEdgeMeshes(): THREE.Mesh[];
|
|
52
|
+
/** 场景清空 / 卸载时调用:丢掉所有装饰引用,不做逐对象清理 */
|
|
53
|
+
reset(): void;
|
|
54
|
+
select(result: PickResult | null, { silent }?: {
|
|
55
|
+
silent?: boolean;
|
|
56
|
+
}): void;
|
|
57
|
+
/**
|
|
58
|
+
* 选中单体的棱线:只挑这个单体自己的三角面算折边,再画成屏幕空间等宽线。
|
|
59
|
+
* 抽出来的线段数很少(一栋楼通常几百到几千条),所以选中开销可以忽略。
|
|
60
|
+
*/
|
|
61
|
+
addSelectionEdges(result: PickResult, meshes: Iterable<THREE.Mesh>): void;
|
|
62
|
+
/** 实例化几何:把某个实例的矩阵套到一个普通 Mesh/子节点上(子节点不参与父级的 instanceMatrix) */
|
|
63
|
+
applyInstanceTransform(obj: THREE.Object3D, result: PickResult): void;
|
|
64
|
+
/** 旧的描边画法:背面外扩法,整块几何一起上,靠 uSelBatch 只显示选中那栋 */
|
|
65
|
+
addSelectionHull(result: PickResult, meshes: Iterable<THREE.Mesh>): void;
|
|
66
|
+
/** 只改 uniform:颜色 / 粗细 / 拔高,拖着滑块实时生效,不重建几何 */
|
|
67
|
+
syncStyle(): void;
|
|
68
|
+
/** 选中单体的实际拔高 = 全局选中拔高 + 该单体的独立拔高(与着色器口径一致) */
|
|
69
|
+
selectionElevation(result: PickResult): number;
|
|
70
|
+
clearDecoration(): void;
|
|
71
|
+
/**
|
|
72
|
+
* 把「当前选中」重放到一块新登记的 mesh 上。
|
|
73
|
+
*
|
|
74
|
+
* 为什么需要:选中高亮是直接写在各 mesh 材质的 uSelBatch / uSelWhole 上的,
|
|
75
|
+
* 而 LOD 细化、瓦片重载、淘汰回补都会换掉 mesh —— 不重放的话,用户点中的那栋楼
|
|
76
|
+
* 一细化就失去高亮(状态还在 selection.smid 里,只是没人往新 mesh 上刷)。
|
|
77
|
+
*/
|
|
78
|
+
/**
|
|
79
|
+
* 判断一块无 SMID 单体化信息的网格(如倾斜摄影或白模整块)是否空间覆盖当前选中命中点
|
|
80
|
+
*/
|
|
81
|
+
isMeshCoveringSelection(mesh: THREE.Mesh, sel: PickResult): boolean;
|
|
82
|
+
replayOnto(mesh: THREE.Mesh): void;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=SelectionDecorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionDecorator.d.ts","sourceRoot":"","sources":["../../../src/render/viewer/SelectionDecorator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAkB,MAAM,qBAAqB,CAAC;AACrF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACzD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAmB,aAAa,EAAe,MAAM,qBAAqB,CAAC;AAGvF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAwBlD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,iCAAiC;IACjC,QAAQ,CAAC,qBAAqB,EAAE,iBAAiB,CAAC;IAClD,iCAAiC;IACjC,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,CAAC;IAClD,oBAAoB;IACpB,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAClD,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACjE,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IACxC,cAAc,IAAI,IAAI,CAAC;IACvB,qCAAqC;IACrC,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,iBAAiB,CAAC;CAClE;AAED,qBAAa,kBAAkB;IASjB,OAAO,CAAC,QAAQ,CAAC,IAAI;IARjC,uBAAuB;IACvB,SAAS,EAAE,UAAU,GAAG,IAAI,CAAQ;IACpC,wBAAwB;IACxB,cAAc,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAM;IAEtC,OAAO,CAAC,cAAc,CAAoB;IAC1C,OAAO,CAAC,oBAAoB,CAAoB;gBAEnB,IAAI,EAAE,aAAa;IAEhD,8BAA8B;IAC9B,IAAI,mBAAmB,IAAI,KAAK,CAAC,IAAI,EAAE,CAEtC;IAED,oCAAoC;IACpC,KAAK,IAAI,IAAI;IAOb,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE,MAAc,EAAE,GAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAO,GAAG,IAAI;IAiFtF;;;OAGG;IACH,iBAAiB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI;IAwDzE,+DAA+D;IAC/D,sBAAsB,CAAC,GAAG,EAAE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI;IAQrE,+CAA+C;IAC/C,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI;IA6BxE,6CAA6C;IAC7C,SAAS,IAAI,IAAI;IAuBjB,8CAA8C;IAC9C,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM;IAS9C,eAAe,IAAI,IAAI;IAavB;;;;;;OAMG;IACH;;OAEG;IACH,uBAAuB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,OAAO;IAkBnE,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,GAAG,IAAI;CA+BnC"}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 选中态:高亮写入、轮廓 / 棱线装饰、跨瓦片重放。
|
|
3
|
+
*
|
|
4
|
+
* 从 `S3MViewer` 搬出来的第三块。它持有 `selection` 与 `selectedMeshes` 两份状态,
|
|
5
|
+
* 其余(uniform、样式、轮廓材质、逐网格棱线材质)都从宿主取。
|
|
6
|
+
*
|
|
7
|
+
* ## 为什么需要「重放」
|
|
8
|
+
*
|
|
9
|
+
* 选中高亮是直接写在各 mesh 材质的 `uSelBatch` / `uSelWhole` 上的,而 LOD 细化、
|
|
10
|
+
* 瓦片重载、淘汰回补都会换掉 mesh —— 不重放的话,用户点中的那栋楼一细化就失去高亮
|
|
11
|
+
* (状态还在 `selection.smid` 里,只是没人往新 mesh 上刷)。
|
|
12
|
+
*
|
|
13
|
+
* ## 没有单体化信息时的退路
|
|
14
|
+
*
|
|
15
|
+
* 倾斜摄影 / 白模整块没有 smid,`uSelBatch` 给 -1 会让「点中了但什么都没亮」。
|
|
16
|
+
* 这时改置 `uSelWhole = 1` 整块高亮,至少让用户看见自己点到了什么。
|
|
17
|
+
*/
|
|
18
|
+
import * as THREE from 'three';
|
|
19
|
+
import { pickEntryId, resolveFeature } from '../../core/FeatureInfo.js';
|
|
20
|
+
import { buildFeatureEdgeSegments, buildThickLineGeometry } from '../EdgeLines.js';
|
|
21
|
+
/** 取网格上的 styled 材质(与 S3MViewer 里那份逐字一致) */
|
|
22
|
+
function styledMaterialOf(mesh) {
|
|
23
|
+
const m = Array.isArray(mesh.material) ? mesh.material[0] : mesh.material;
|
|
24
|
+
return m?.userData?.isStyled ? m : null;
|
|
25
|
+
}
|
|
26
|
+
function clampOpacity(v) {
|
|
27
|
+
const n = v ?? 1;
|
|
28
|
+
return n < 0 ? 0 : n > 1 ? 1 : n;
|
|
29
|
+
}
|
|
30
|
+
function isPointCloud(o) {
|
|
31
|
+
return o.isPoints === true;
|
|
32
|
+
}
|
|
33
|
+
export class SelectionDecorator {
|
|
34
|
+
host;
|
|
35
|
+
/** 当前选中(null = 没选中) */
|
|
36
|
+
selection = null;
|
|
37
|
+
/** 被高亮的网格(点云也在这份列表里) */
|
|
38
|
+
selectedMeshes = [];
|
|
39
|
+
_outlineMeshes = [];
|
|
40
|
+
_selectionEdgeMeshes = [];
|
|
41
|
+
constructor(host) {
|
|
42
|
+
this.host = host;
|
|
43
|
+
}
|
|
44
|
+
/** @internal 测试用:选中棱线的网格列表 */
|
|
45
|
+
get selectionEdgeMeshes() {
|
|
46
|
+
return this._selectionEdgeMeshes;
|
|
47
|
+
}
|
|
48
|
+
/** 场景清空 / 卸载时调用:丢掉所有装饰引用,不做逐对象清理 */
|
|
49
|
+
reset() {
|
|
50
|
+
this.selection = null;
|
|
51
|
+
this.selectedMeshes = [];
|
|
52
|
+
this._outlineMeshes = [];
|
|
53
|
+
this._selectionEdgeMeshes = [];
|
|
54
|
+
}
|
|
55
|
+
select(result, { silent = false } = {}) {
|
|
56
|
+
// 清掉上一次
|
|
57
|
+
if (this.selection) {
|
|
58
|
+
for (const obj of this.selectedMeshes) {
|
|
59
|
+
// 点云:恢复成当前着色模式(去掉选中混色)
|
|
60
|
+
if (isPointCloud(obj)) {
|
|
61
|
+
this.host.applyPointCloudStyle(obj, false);
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const mat = styledMaterialOf(obj);
|
|
65
|
+
if (mat) {
|
|
66
|
+
mat.userData.uSelBatch.value = -1;
|
|
67
|
+
mat.userData.uSelWhole.value = 0;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
this.selectedMeshes = [];
|
|
71
|
+
this.clearDecoration();
|
|
72
|
+
this.selection = null;
|
|
73
|
+
}
|
|
74
|
+
if (!result) {
|
|
75
|
+
this.host.uniforms.uSelMix.value = 0;
|
|
76
|
+
this.host.uniforms.uDim.value = 0;
|
|
77
|
+
this.host.outlineMaterial.uniforms.uSelBatch.value = -1;
|
|
78
|
+
this.host.outlineMaterial.uniforms.uSelWhole.value = 0;
|
|
79
|
+
this.host.outlineMaterial.uniforms.uElevation.value = 0;
|
|
80
|
+
this.host.requestRepaint();
|
|
81
|
+
if (!silent)
|
|
82
|
+
this.host.onPick(null);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.selection = result;
|
|
86
|
+
const targetMeshes = new Set();
|
|
87
|
+
if (result.smid != null) {
|
|
88
|
+
const smidSet = this.host.smidMeshes.get(result.smid);
|
|
89
|
+
if (smidSet) {
|
|
90
|
+
for (const m of smidSet)
|
|
91
|
+
targetMeshes.add(m);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
targetMeshes.add(result.mesh);
|
|
95
|
+
for (const mesh of targetMeshes) {
|
|
96
|
+
const mat = styledMaterialOf(mesh);
|
|
97
|
+
if (!mat)
|
|
98
|
+
continue;
|
|
99
|
+
let batchId = result.batchId;
|
|
100
|
+
if (result.instanceIndex != null && mesh === result.mesh) {
|
|
101
|
+
batchId = result.batchId;
|
|
102
|
+
}
|
|
103
|
+
else if (result.smid != null) {
|
|
104
|
+
const ud = mesh.userData;
|
|
105
|
+
const pickInfo = ud.geoRef?.pickInfo;
|
|
106
|
+
const entry = pickInfo?.[result.smid] ??
|
|
107
|
+
pickInfo?.[String(result.smid)];
|
|
108
|
+
const bId = entry ? pickEntryId(entry) : -1;
|
|
109
|
+
batchId = bId >= 0 ? bId : (mesh === result.mesh ? result.batchId : -1);
|
|
110
|
+
}
|
|
111
|
+
mat.userData.uSelBatch.value = batchId;
|
|
112
|
+
// 没有单体化信息时整块高亮,否则会出现「点中了但什么都没亮、其他全暗了」
|
|
113
|
+
mat.userData.uSelWhole.value = batchId < 0 ? 1 : 0;
|
|
114
|
+
this.selectedMeshes.push(mesh);
|
|
115
|
+
}
|
|
116
|
+
// 点云没有单体粒度:整块混成 selectColor,让选中至少看得见
|
|
117
|
+
for (const mesh of this.selectedMeshes) {
|
|
118
|
+
if (isPointCloud(mesh))
|
|
119
|
+
this.host.applyPointCloudStyle(mesh, true);
|
|
120
|
+
}
|
|
121
|
+
this.host.uniforms.uSelMix.value = 1;
|
|
122
|
+
this.host.uniforms.uDim.value = this.host.style.dimOthers ? 1 : 0;
|
|
123
|
+
if (this.host.style.outline) {
|
|
124
|
+
// 棱线 / 外扩轮廓都是按「面」设计的,点云画不出来也不该画
|
|
125
|
+
const decoMeshes = [...targetMeshes].filter((m) => !isPointCloud(m));
|
|
126
|
+
if (decoMeshes.length) {
|
|
127
|
+
if ((this.host.style.outlineStyle ?? 'edges') === 'edges') {
|
|
128
|
+
this.addSelectionEdges(result, decoMeshes);
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.addSelectionHull(result, decoMeshes);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
this.host.requestRepaint();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* 选中单体的棱线:只挑这个单体自己的三角面算折边,再画成屏幕空间等宽线。
|
|
139
|
+
* 抽出来的线段数很少(一栋楼通常几百到几千条),所以选中开销可以忽略。
|
|
140
|
+
*/
|
|
141
|
+
addSelectionEdges(result, meshes) {
|
|
142
|
+
this.syncStyle();
|
|
143
|
+
for (const mesh of meshes) {
|
|
144
|
+
const ud = mesh.userData;
|
|
145
|
+
const geoRef = ud.geoRef;
|
|
146
|
+
let segments = [];
|
|
147
|
+
// 这块网格上的棱线全部属于选中的那个单体,整批填同一个 batchId,
|
|
148
|
+
// 顶点着色器才能从状态纹理里取到平移 / 拔高——选中跟随移动靠它。
|
|
149
|
+
let batchId = -1;
|
|
150
|
+
if (mesh === result.mesh && result.instanceIndex != null) {
|
|
151
|
+
// 实例化几何没有逐单体的顶点区间,整个 base mesh 就是这一栋的外形
|
|
152
|
+
segments = [{ vertexOffset: 0, vertexCount: mesh.geometry.getAttribute('position')?.count ?? 0 }];
|
|
153
|
+
const pickInfo = geoRef?.pickInfo;
|
|
154
|
+
const entry = pickInfo?.[result.smid ?? ''] ??
|
|
155
|
+
pickInfo?.[String(result.smid)];
|
|
156
|
+
batchId = entry ? pickEntryId(entry) : -1;
|
|
157
|
+
}
|
|
158
|
+
else if (result.smid != null) {
|
|
159
|
+
const pickInfo = geoRef?.pickInfo;
|
|
160
|
+
const entry = pickInfo?.[result.smid] ??
|
|
161
|
+
pickInfo?.[String(result.smid)];
|
|
162
|
+
const bId = entry ? pickEntryId(entry) : -1;
|
|
163
|
+
batchId = bId;
|
|
164
|
+
segments = entry?.segments ?? (bId >= 0 ? resolveFeature(geoRef, bId).segments : []);
|
|
165
|
+
}
|
|
166
|
+
else if (mesh === result.mesh) {
|
|
167
|
+
const localGeo = ud.geoByBatchId?.get(result.batchId) ?? geoRef;
|
|
168
|
+
segments = resolveFeature(localGeo, result.batchId).segments;
|
|
169
|
+
batchId = result.batchId;
|
|
170
|
+
}
|
|
171
|
+
const pairs = buildFeatureEdgeSegments(mesh.geometry, segments);
|
|
172
|
+
if (pairs && pairs.length > 0) {
|
|
173
|
+
const batchIds = batchId >= 0 ? new Float32Array(pairs.length / 6).fill(batchId) : undefined;
|
|
174
|
+
const lines = new THREE.Mesh(buildThickLineGeometry(pairs, batchIds), this.host.createSelectionEdgeMaterial(mesh));
|
|
175
|
+
lines.renderOrder = 4;
|
|
176
|
+
// 屏幕空间外扩后可能超出原包围球,关掉剔除更稳
|
|
177
|
+
lines.frustumCulled = false;
|
|
178
|
+
lines.raycast = () => { };
|
|
179
|
+
lines.userData.isSelectionEdge = true;
|
|
180
|
+
if (mesh === result.mesh && result.instanceIndex != null) {
|
|
181
|
+
this.applyInstanceTransform(lines, result);
|
|
182
|
+
}
|
|
183
|
+
mesh.add(lines); // 作为子节点,直接继承世界变换
|
|
184
|
+
this._selectionEdgeMeshes.push(lines);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (this._selectionEdgeMeshes.length === 0) {
|
|
188
|
+
// 抽不出折边(退化几何 / 没有任何夹角)时退回外扩轮廓,至少保证选中可见
|
|
189
|
+
this.addSelectionHull(result, meshes);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/** 实例化几何:把某个实例的矩阵套到一个普通 Mesh/子节点上(子节点不参与父级的 instanceMatrix) */
|
|
194
|
+
applyInstanceTransform(obj, result) {
|
|
195
|
+
const im = result.mesh;
|
|
196
|
+
if (result.instanceIndex == null || !im.isInstancedMesh)
|
|
197
|
+
return;
|
|
198
|
+
const m = new THREE.Matrix4();
|
|
199
|
+
im.getMatrixAt(result.instanceIndex, m);
|
|
200
|
+
m.decompose(obj.position, obj.quaternion, obj.scale);
|
|
201
|
+
}
|
|
202
|
+
/** 旧的描边画法:背面外扩法,整块几何一起上,靠 uSelBatch 只显示选中那栋 */
|
|
203
|
+
addSelectionHull(result, meshes) {
|
|
204
|
+
const instanced = result.instanceIndex != null;
|
|
205
|
+
// 实例化:轮廓是这个实例的单独一份副本(普通 Mesh),所以整份都画;
|
|
206
|
+
// 顶点区间型:整块几何一起画,靠 uSelBatch 只显示选中那栋。
|
|
207
|
+
this.host.outlineMaterial.uniforms.uSelBatch.value = instanced ? -1 : result.batchId;
|
|
208
|
+
this.host.outlineMaterial.uniforms.uSelWhole.value = instanced || result.batchId < 0 ? 1 : 0;
|
|
209
|
+
this.host.outlineMaterial.uniforms.uElevation.value = instanced
|
|
210
|
+
? this.selectionElevation(result)
|
|
211
|
+
: this.host.style.selectElevation ?? 0;
|
|
212
|
+
for (const mesh of meshes) {
|
|
213
|
+
const mat = styledMaterialOf(mesh);
|
|
214
|
+
if (mat?.userData?.uBatchTex) {
|
|
215
|
+
this.host.outlineMaterial.uniforms.uBatchTex.value = mat.userData.uBatchTex.value;
|
|
216
|
+
this.host.outlineMaterial.uniforms.uBatchTexWidth.value = mat.userData.uBatchTexWidth.value;
|
|
217
|
+
this.host.outlineMaterial.uniforms.uBatchTexActive.value = mat.userData.uBatchTexActive.value;
|
|
218
|
+
}
|
|
219
|
+
const outline = new THREE.Mesh(mesh.geometry, this.host.outlineMaterial);
|
|
220
|
+
outline.renderOrder = 3;
|
|
221
|
+
outline.frustumCulled = false;
|
|
222
|
+
outline.raycast = () => { };
|
|
223
|
+
if (mesh === result.mesh && result.instanceIndex != null) {
|
|
224
|
+
this.applyInstanceTransform(outline, result);
|
|
225
|
+
}
|
|
226
|
+
mesh.add(outline); // 作为子节点,直接继承世界变换
|
|
227
|
+
this._outlineMeshes.push(outline);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/** 只改 uniform:颜色 / 粗细 / 拔高,拖着滑块实时生效,不重建几何 */
|
|
231
|
+
syncStyle() {
|
|
232
|
+
const s = this.host.style;
|
|
233
|
+
const u = this.host.selectionEdgeMaterial.uniforms;
|
|
234
|
+
u.uColor.value.set(s.outlineColor ?? s.selectColor);
|
|
235
|
+
u.uWidth.value = Math.max(0.1, s.outlineWidthPx ?? 3);
|
|
236
|
+
u.uOpacity.value = clampOpacity(s.opacity);
|
|
237
|
+
// 只加全局 selectElevation:单体自己的拔高已经写在状态纹理第 2 行 z 里,
|
|
238
|
+
// 顶点着色器采样时带出来了,这里再加一次就会双重拔高
|
|
239
|
+
if (u.uElevation)
|
|
240
|
+
u.uElevation.value = s.selectElevation ?? 0;
|
|
241
|
+
// 外扩描边是另一个材质实例,单体状态纹理的开关是建的时候抄过去的。
|
|
242
|
+
// 先选中、再抬高(或反过来)时模板会停留在旧值,这里补一次同步。
|
|
243
|
+
for (const outline of this._outlineMeshes) {
|
|
244
|
+
const parent = outline.parent;
|
|
245
|
+
const ud = parent ? styledMaterialOf(parent)?.userData : null;
|
|
246
|
+
if (ud?.uBatchTex) {
|
|
247
|
+
this.host.outlineMaterial.uniforms.uBatchTex.value = ud.uBatchTex.value;
|
|
248
|
+
this.host.outlineMaterial.uniforms.uBatchTexWidth.value = ud.uBatchTexWidth.value;
|
|
249
|
+
this.host.outlineMaterial.uniforms.uBatchTexActive.value = ud.uBatchTexActive.value;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
/** 选中单体的实际拔高 = 全局选中拔高 + 该单体的独立拔高(与着色器口径一致) */
|
|
254
|
+
selectionElevation(result) {
|
|
255
|
+
let elev = this.host.style.selectElevation ?? 0;
|
|
256
|
+
if (result.smid != null) {
|
|
257
|
+
const off = this.host.featureStyleManager.getFeatureEffectiveOffset(result.smid);
|
|
258
|
+
if (off.elevation)
|
|
259
|
+
elev += off.elevation;
|
|
260
|
+
}
|
|
261
|
+
return elev;
|
|
262
|
+
}
|
|
263
|
+
clearDecoration() {
|
|
264
|
+
for (const outline of this._outlineMeshes) {
|
|
265
|
+
outline.parent?.remove(outline);
|
|
266
|
+
}
|
|
267
|
+
this._outlineMeshes = [];
|
|
268
|
+
for (const edges of this._selectionEdgeMeshes) {
|
|
269
|
+
edges.parent?.remove(edges);
|
|
270
|
+
edges.geometry.dispose();
|
|
271
|
+
}
|
|
272
|
+
this._selectionEdgeMeshes = [];
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* 把「当前选中」重放到一块新登记的 mesh 上。
|
|
276
|
+
*
|
|
277
|
+
* 为什么需要:选中高亮是直接写在各 mesh 材质的 uSelBatch / uSelWhole 上的,
|
|
278
|
+
* 而 LOD 细化、瓦片重载、淘汰回补都会换掉 mesh —— 不重放的话,用户点中的那栋楼
|
|
279
|
+
* 一细化就失去高亮(状态还在 selection.smid 里,只是没人往新 mesh 上刷)。
|
|
280
|
+
*/
|
|
281
|
+
/**
|
|
282
|
+
* 判断一块无 SMID 单体化信息的网格(如倾斜摄影或白模整块)是否空间覆盖当前选中命中点
|
|
283
|
+
*/
|
|
284
|
+
isMeshCoveringSelection(mesh, sel) {
|
|
285
|
+
if (!sel.point)
|
|
286
|
+
return false;
|
|
287
|
+
const geom = mesh.geometry;
|
|
288
|
+
if (!geom)
|
|
289
|
+
return false;
|
|
290
|
+
if (!geom.boundingBox)
|
|
291
|
+
geom.computeBoundingBox();
|
|
292
|
+
if (!geom.boundingBox)
|
|
293
|
+
return false;
|
|
294
|
+
// 将选中的三维场景点转入网格局部坐标系进行包围盒检测
|
|
295
|
+
const pt = new THREE.Vector3(sel.point[0], sel.point[1], sel.point[2]);
|
|
296
|
+
mesh.updateWorldMatrix(true, false);
|
|
297
|
+
const inv = mesh.matrixWorld.clone().invert();
|
|
298
|
+
const localPt = pt.applyMatrix4(inv);
|
|
299
|
+
// 留出 0.5 米容差,避免刚好处于三角网格边缘缝隙时漏判
|
|
300
|
+
const box = geom.boundingBox.clone().expandByScalar(0.5);
|
|
301
|
+
return box.containsPoint(localPt);
|
|
302
|
+
}
|
|
303
|
+
replayOnto(mesh) {
|
|
304
|
+
const sel = this.selection;
|
|
305
|
+
if (!sel)
|
|
306
|
+
return;
|
|
307
|
+
const mat = styledMaterialOf(mesh);
|
|
308
|
+
if (!mat)
|
|
309
|
+
return;
|
|
310
|
+
const ud = mesh.userData;
|
|
311
|
+
let batchId = -1;
|
|
312
|
+
if (sel.smid != null) {
|
|
313
|
+
const pickInfo = ud.geoRef?.pickInfo;
|
|
314
|
+
const entry = pickInfo?.[sel.smid] ?? pickInfo?.[String(sel.smid)];
|
|
315
|
+
batchId = entry ? pickEntryId(entry) : -1;
|
|
316
|
+
}
|
|
317
|
+
// 拾取命中的那块 mesh 用原始 batchId;同一 smid 散在别的几何里时按各自的区间算
|
|
318
|
+
if (mesh === sel.mesh)
|
|
319
|
+
batchId = sel.batchId;
|
|
320
|
+
// 这块几何里根本没有这个单体 → 不动它(否则会把无关瓦片一起点亮)
|
|
321
|
+
if (batchId < 0 && mesh !== sel.mesh) {
|
|
322
|
+
if (sel.smid == null && ud.datasetId === sel.datasetId && this.isMeshCoveringSelection(mesh, sel)) {
|
|
323
|
+
batchId = -1;
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
mat.userData.uSelBatch.value = batchId;
|
|
330
|
+
mat.userData.uSelWhole.value = batchId < 0 ? 1 : 0;
|
|
331
|
+
if (!this.selectedMeshes.includes(mesh))
|
|
332
|
+
this.selectedMeshes.push(mesh);
|
|
333
|
+
if (isPointCloud(mesh))
|
|
334
|
+
this.host.applyPointCloudStyle(mesh, true);
|
|
335
|
+
this.host.uniforms.uSelMix.value = 1;
|
|
336
|
+
this.host.uniforms.uDim.value = this.host.style.dimOthers ? 1 : 0;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
//# sourceMappingURL=SelectionDecorator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectionDecorator.js","sourceRoot":"","sources":["../../../src/render/viewer/SelectionDecorator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 泼溅排序的调度:什么时候重排、什么时候整帧跳过。
|
|
3
|
+
*
|
|
4
|
+
* 排序算法本身在 `core/SplatSort.ts`,单瓦片的重写在 `render/SplatSorter.ts`。
|
|
5
|
+
* 这里只管一件事:**相机没动且没有新瓦片时,一帧都不要排**。
|
|
6
|
+
*
|
|
7
|
+
* 跳过条件用的是「视图矩阵完全相等」。地图交互时相机每帧都在变,所以这个条件
|
|
8
|
+
* 实际上只在静止时命中 —— 这是刻意的:移动中必须每帧重排,否则 alpha 混合顺序
|
|
9
|
+
* 会错,画面是彩色噪点。真正把代价压下去的是排序算法本身(基数排序,见 SplatSort)。
|
|
10
|
+
*/
|
|
11
|
+
import * as THREE from 'three';
|
|
12
|
+
export declare class SplatLayer {
|
|
13
|
+
private readonly _lastView;
|
|
14
|
+
private _sorted;
|
|
15
|
+
/** 有新瓦片进来 / 瓦片被淘汰:下一帧必须重排 */
|
|
16
|
+
markDirty(): void;
|
|
17
|
+
/**
|
|
18
|
+
* 按当前视角重排所有泼溅瓦片。
|
|
19
|
+
*
|
|
20
|
+
* @param pointClouds 场景里的点云集合(含非泼溅的,按 `userData.isGaussianSplat` 过滤)
|
|
21
|
+
*/
|
|
22
|
+
sort(camera: THREE.Camera | null, pointClouds: Iterable<THREE.Points>): void;
|
|
23
|
+
/** 场景清空 / 换相机后重置,避免拿旧矩阵误判「已排过」 */
|
|
24
|
+
reset(): void;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=SplatLayer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplatLayer.d.ts","sourceRoot":"","sources":["../../../src/render/viewer/SplatLayer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;IACjD,OAAO,CAAC,OAAO,CAAS;IAExB,6BAA6B;IAC7B,SAAS,IAAI,IAAI;IAIjB;;;;OAIG;IACH,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI;IAW5E,kCAAkC;IAClC,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 泼溅排序的调度:什么时候重排、什么时候整帧跳过。
|
|
3
|
+
*
|
|
4
|
+
* 排序算法本身在 `core/SplatSort.ts`,单瓦片的重写在 `render/SplatSorter.ts`。
|
|
5
|
+
* 这里只管一件事:**相机没动且没有新瓦片时,一帧都不要排**。
|
|
6
|
+
*
|
|
7
|
+
* 跳过条件用的是「视图矩阵完全相等」。地图交互时相机每帧都在变,所以这个条件
|
|
8
|
+
* 实际上只在静止时命中 —— 这是刻意的:移动中必须每帧重排,否则 alpha 混合顺序
|
|
9
|
+
* 会错,画面是彩色噪点。真正把代价压下去的是排序算法本身(基数排序,见 SplatSort)。
|
|
10
|
+
*/
|
|
11
|
+
import * as THREE from 'three';
|
|
12
|
+
import { sortSplatMesh } from '../SplatSorter.js';
|
|
13
|
+
export class SplatLayer {
|
|
14
|
+
_lastView = new THREE.Matrix4();
|
|
15
|
+
_sorted = false;
|
|
16
|
+
/** 有新瓦片进来 / 瓦片被淘汰:下一帧必须重排 */
|
|
17
|
+
markDirty() {
|
|
18
|
+
this._sorted = false;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 按当前视角重排所有泼溅瓦片。
|
|
22
|
+
*
|
|
23
|
+
* @param pointClouds 场景里的点云集合(含非泼溅的,按 `userData.isGaussianSplat` 过滤)
|
|
24
|
+
*/
|
|
25
|
+
sort(camera, pointClouds) {
|
|
26
|
+
if (!camera)
|
|
27
|
+
return;
|
|
28
|
+
if (this._sorted && this._lastView.equals(camera.matrixWorldInverse))
|
|
29
|
+
return;
|
|
30
|
+
for (const pc of pointClouds) {
|
|
31
|
+
if (!pc.userData.isGaussianSplat)
|
|
32
|
+
continue;
|
|
33
|
+
sortSplatMesh(pc, camera.matrixWorldInverse);
|
|
34
|
+
}
|
|
35
|
+
this._lastView.copy(camera.matrixWorldInverse);
|
|
36
|
+
this._sorted = true;
|
|
37
|
+
}
|
|
38
|
+
/** 场景清空 / 换相机后重置,避免拿旧矩阵误判「已排过」 */
|
|
39
|
+
reset() {
|
|
40
|
+
this._sorted = false;
|
|
41
|
+
this._lastView.identity();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=SplatLayer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SplatLayer.js","sourceRoot":"","sources":["../../../src/render/viewer/SplatLayer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,OAAO,UAAU;IACJ,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;IACzC,OAAO,GAAG,KAAK,CAAC;IAExB,6BAA6B;IAC7B,SAAS;QACP,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED;;;;OAIG;IACH,IAAI,CAAC,MAA2B,EAAE,WAAmC;QACnE,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,CAAC,kBAAkB,CAAC;YAAE,OAAO;QAC7E,KAAK,MAAM,EAAE,IAAI,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAE,EAAE,CAAC,QAA0C,CAAC,eAAe;gBAAE,SAAS;YAC9E,aAAa,CAAC,EAA2B,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC/C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED,kCAAkC;IAClC,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;IAC5B,CAAC;CACF"}
|