s3m-three 0.4.18 → 0.4.20
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-DvAUA8NJ.js +1 -0
- package/dist/browser/s3m-three.iife.ext-three.js +619 -304
- package/dist/browser/s3m-three.iife.js +647 -332
- 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/GaussianSplat.d.ts +64 -0
- package/dist/core/GaussianSplat.d.ts.map +1 -0
- package/dist/core/GaussianSplat.js +139 -0
- package/dist/core/GaussianSplat.js.map +1 -0
- package/dist/core/S3M1Parser.d.ts +1 -1
- package/dist/core/S3M1Parser.d.ts.map +1 -1
- package/dist/core/S3M1Parser.js +320 -25
- package/dist/core/S3M1Parser.js.map +1 -1
- package/dist/core/S3MBParser.d.ts.map +1 -1
- package/dist/core/S3MBParser.js +13 -0
- package/dist/core/S3MBParser.js.map +1 -1
- package/dist/core/S3MBlockParser.d.ts.map +1 -1
- package/dist/core/S3MBlockParser.js +83 -28
- package/dist/core/S3MBlockParser.js.map +1 -1
- package/dist/core/SplatLod.d.ts +36 -0
- package/dist/core/SplatLod.d.ts.map +1 -0
- package/dist/core/SplatLod.js +54 -0
- package/dist/core/SplatLod.js.map +1 -0
- package/dist/core/SplatProjection.d.ts +75 -0
- package/dist/core/SplatProjection.d.ts.map +1 -0
- package/dist/core/SplatProjection.js +162 -0
- package/dist/core/SplatProjection.js.map +1 -0
- package/dist/core/SplatSort.d.ts +26 -0
- package/dist/core/SplatSort.d.ts.map +1 -0
- package/dist/core/SplatSort.js +61 -0
- package/dist/core/SplatSort.js.map +1 -0
- package/dist/core/TexCoordZ.d.ts +94 -0
- package/dist/core/TexCoordZ.d.ts.map +1 -0
- package/dist/core/TexCoordZ.js +125 -0
- package/dist/core/TexCoordZ.js.map +1 -0
- package/dist/core/TextureDecode.d.ts +19 -0
- package/dist/core/TextureDecode.d.ts.map +1 -1
- package/dist/core/TextureDecode.js +53 -11
- package/dist/core/TextureDecode.js.map +1 -1
- package/dist/core/TileGeometry.d.ts +39 -0
- package/dist/core/TileGeometry.d.ts.map +1 -1
- package/dist/core/TileGeometry.js +133 -14
- package/dist/core/TileGeometry.js.map +1 -1
- package/dist/core/degradations.d.ts +37 -0
- package/dist/core/degradations.d.ts.map +1 -0
- package/dist/core/degradations.js +32 -0
- package/dist/core/degradations.js.map +1 -0
- package/dist/core/types.d.ts +36 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/render/DatasetManager.d.ts +11 -0
- package/dist/render/DatasetManager.d.ts.map +1 -1
- package/dist/render/DatasetManager.js +2 -0
- package/dist/render/DatasetManager.js.map +1 -1
- package/dist/render/FeatureStyleManager.d.ts.map +1 -1
- package/dist/render/FeatureStyleManager.js +7 -5
- package/dist/render/FeatureStyleManager.js.map +1 -1
- package/dist/render/GeometryBuilder.d.ts +31 -0
- package/dist/render/GeometryBuilder.d.ts.map +1 -1
- package/dist/render/GeometryBuilder.js +229 -6
- package/dist/render/GeometryBuilder.js.map +1 -1
- package/dist/render/Picker.d.ts.map +1 -1
- package/dist/render/Picker.js +19 -5
- package/dist/render/Picker.js.map +1 -1
- package/dist/render/S3MViewer.d.ts +106 -379
- package/dist/render/S3MViewer.d.ts.map +1 -1
- package/dist/render/S3MViewer.js +324 -1494
- package/dist/render/S3MViewer.js.map +1 -1
- package/dist/render/SplatMaterial.d.ts +103 -0
- package/dist/render/SplatMaterial.d.ts.map +1 -0
- package/dist/render/SplatMaterial.js +388 -0
- package/dist/render/SplatMaterial.js.map +1 -0
- package/dist/render/SplatSorter.d.ts +14 -0
- package/dist/render/SplatSorter.d.ts.map +1 -0
- package/dist/render/SplatSorter.js +66 -0
- package/dist/render/SplatSorter.js.map +1 -0
- package/dist/render/StyleMaterial.d.ts +48 -0
- package/dist/render/StyleMaterial.d.ts.map +1 -1
- package/dist/render/StyleMaterial.js +292 -69
- package/dist/render/StyleMaterial.js.map +1 -1
- package/dist/render/TextureFactory.d.ts +10 -0
- package/dist/render/TextureFactory.d.ts.map +1 -1
- package/dist/render/TextureFactory.js +35 -5
- package/dist/render/TextureFactory.js.map +1 -1
- package/dist/render/lightingPreset.d.ts +53 -0
- package/dist/render/lightingPreset.d.ts.map +1 -0
- package/dist/render/lightingPreset.js +36 -0
- package/dist/render/lightingPreset.js.map +1 -0
- package/dist/render/materialAlpha.d.ts +51 -0
- package/dist/render/materialAlpha.d.ts.map +1 -0
- package/dist/render/materialAlpha.js +68 -0
- package/dist/render/materialAlpha.js.map +1 -0
- 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 +250 -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 +42 -1
- package/dist/tileset/S3MTileset.d.ts.map +1 -1
- package/dist/tileset/S3MTileset.js +52 -2
- package/dist/tileset/S3MTileset.js.map +1 -1
- package/dist/vendor/browser-node-stub.js +10 -0
- package/dist/worker/s3mWorker.js +1166 -979
- package/dist/worker/s3mWorker.js.map +1 -1
- package/docs/API.md +55 -1
- package/docs/FORMAT-NOTES.md +362 -0
- package/package.json +1 -1
- package/src/core/Draco.ts +1 -2
- package/src/core/GaussianSplat.ts +175 -0
- package/src/core/S3M1Parser.ts +330 -24
- package/src/core/S3MBParser.ts +18 -0
- package/src/core/S3MBlockParser.ts +83 -27
- package/src/core/SplatLod.ts +83 -0
- package/src/core/SplatProjection.ts +231 -0
- package/src/core/SplatSort.ts +92 -0
- package/src/core/TexCoordZ.ts +160 -0
- package/src/core/TextureDecode.ts +63 -11
- package/src/core/TileGeometry.ts +151 -14
- package/src/core/degradations.ts +74 -0
- package/src/core/types.ts +32 -0
- package/src/index.ts +8 -1
- package/src/render/DatasetManager.ts +10 -0
- package/src/render/FeatureStyleManager.ts +8 -6
- package/src/render/GeometryBuilder.ts +271 -7
- package/src/render/Picker.ts +21 -5
- package/src/render/S3MViewer.ts +358 -1727
- package/src/render/SplatMaterial.ts +433 -0
- package/src/render/SplatSorter.ts +66 -0
- package/src/render/StyleMaterial.ts +339 -69
- package/src/render/TextureFactory.ts +39 -5
- package/src/render/lightingPreset.ts +76 -0
- package/src/render/materialAlpha.ts +75 -0
- 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 +258 -0
- package/src/tileset/S3MTileset.ts +78 -2
- package/src/vendor/browser-node-stub.js +10 -0
- package/dist/browser/assets/s3mWorker-BjPOUgjg.js +0 -1
|
@@ -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"}
|