@realsee/five-webgpu 1.0.0-alpha.6 → 1.0.0-alpha.7
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/ai_guides/features/five.md +70 -1
- package/ai_guides/features/material.md +35 -8
- package/ai_guides/features/mode.md +23 -6
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/index.AdaptiveLuminancePass.html +1 -1
- package/docs/classes/index.BoundingMesh.html +1 -1
- package/docs/classes/index.Camera.html +1 -1
- package/docs/classes/index.EyeDomeLightingPass.html +1 -1
- package/docs/classes/index.Five.html +60 -59
- package/docs/classes/index.FivePass.html +1 -1
- package/docs/classes/index.FlowingFireworks3DPass.html +1 -1
- package/docs/classes/index.FlowingLight2DPass.html +1 -1
- package/docs/classes/index.FlowingLight3DPass.html +2 -2
- package/docs/classes/index.GaussianBlurPass.html +1 -1
- package/docs/classes/index.InternalWebGPURenderer.html +8 -5
- package/docs/classes/index.Model.html +1 -1
- package/docs/classes/index.ModelScene.html +1 -1
- package/docs/classes/index.NetworkSubscribe.html +1 -1
- package/docs/classes/index.PBMCustomNode.html +8 -8
- package/docs/classes/index.PBMGaussianSplattingNodeMaterial.html +2 -2
- package/docs/classes/index.PBMGaussianSplattingObject.html +1 -1
- package/docs/classes/index.PBMGaussianSplattingRenderMesh.html +1 -1
- package/docs/classes/index.PBMGroup.html +1 -1
- package/docs/classes/index.PBMMesh.html +1 -1
- package/docs/classes/index.PBMMeshBasicMaterial.html +7 -6
- package/docs/classes/index.PBMMeshBasicNodeMaterial.html +9 -8
- package/docs/classes/index.PBMMeshPanoOnlyMaterial.html +7 -6
- package/docs/classes/index.PBMMeshPanoOnlyNodeMaterial.html +7 -6
- package/docs/classes/index.PBMMeshPhongMaterial.html +7 -6
- package/docs/classes/index.PBMMeshPhongNodeMaterial.html +9 -8
- package/docs/classes/index.PBMMeshPhysicalMaterial.html +7 -6
- package/docs/classes/index.PBMMeshPhysicalNodeMaterial.html +9 -8
- package/docs/classes/index.PBMPanoFilter.html +8 -8
- package/docs/classes/index.PBMPointCloud.html +6 -7
- package/docs/classes/index.PBMPointCloudMaterial.html +83 -0
- package/docs/classes/index.PBMSkinnedMesh.html +1 -1
- package/docs/classes/index.PBMUpdateable.html +1 -1
- package/docs/classes/index.PanoCircleMesh.html +1 -1
- package/docs/classes/index.PanoCircleMeshCustom.html +1 -1
- package/docs/classes/index.PanoCircleMeshSolid.html +1 -1
- package/docs/classes/index.Parameter.html +57 -56
- package/docs/classes/index.Scene.html +1 -1
- package/docs/classes/index.Subscribe.html +1 -1
- package/docs/classes/index.Tile3D.html +1 -1
- package/docs/classes/index.TileNode.html +1 -1
- package/docs/classes/index.TrajectoryNode.html +1 -1
- package/docs/classes/index.WorkResolvedObserver.html +1 -1
- package/docs/classes/index.XRButton.html +3 -0
- package/docs/documents/features_five.html +45 -3
- package/docs/documents/features_material.html +20 -9
- package/docs/documents/features_mode.html +27 -2
- package/docs/functions/index.customNodesCacheKey.html +1 -1
- package/docs/hierarchy.html +1 -1
- package/docs/interfaces/index.AddableObject.html +1 -1
- package/docs/interfaces/index.AjaxOptions.html +1 -1
- package/docs/interfaces/index.BaseEvent.html +1 -1
- package/docs/interfaces/index.Clock.html +1 -1
- package/docs/interfaces/index.DeviceProfile.html +8 -0
- package/docs/interfaces/index.EventCallback.html +3 -3
- package/docs/interfaces/index.FiveInitArgs.html +40 -25
- package/docs/interfaces/index.GestureEvent.html +1 -1
- package/docs/interfaces/index.IPBMMaterial.html +6 -5
- package/docs/interfaces/index.ImageOptions.html +1 -1
- package/docs/interfaces/index.IntersectEvent.html +1 -1
- package/docs/interfaces/index.IntersectMesh.html +1 -1
- package/docs/interfaces/index.IntersectMeshInterface.html +1 -1
- package/docs/interfaces/index.Intersection.html +1 -1
- package/docs/interfaces/index.LooseWorkWithExtrinsics.html +1 -1
- package/docs/interfaces/index.ModeChangeEvent.html +2 -2
- package/docs/interfaces/index.ModelControllerCustomInitArgs.html +1 -1
- package/docs/interfaces/index.ModelEvent.html +2 -2
- package/docs/interfaces/index.ModelSceneEvent.html +2 -2
- package/docs/interfaces/index.ModelTileEvent.html +2 -2
- package/docs/interfaces/index.MovePanoOptions.html +1 -1
- package/docs/interfaces/index.NetworkAbortError.html +1 -1
- package/docs/interfaces/index.NetworkFirbiddenError.html +1 -1
- package/docs/interfaces/index.NetworkOptions.html +1 -1
- package/docs/interfaces/index.NetworkProxyError.html +1 -1
- package/docs/interfaces/index.NetworkResourceEvent.html +2 -2
- package/docs/interfaces/index.NetworkResponseError.html +1 -1
- package/docs/interfaces/index.NetworkTimeoutError.html +1 -1
- package/docs/interfaces/index.ObjectEvent.html +2 -2
- package/docs/interfaces/index.PBMClipperParameter.html +2 -2
- package/docs/interfaces/index.PBMCustomNodeContext.html +30 -30
- package/docs/interfaces/index.PBMCustomNodeOptions.html +4 -4
- package/docs/interfaces/index.PBMCustomNodePanoContext.html +6 -6
- package/docs/interfaces/index.PBMCustomNodeSlots.html +6 -6
- package/docs/interfaces/index.PBMGaussianSplattingNodeMaterialOptions.html +4 -0
- package/docs/interfaces/index.PBMPanoDepth.html +5 -5
- package/docs/interfaces/index.PBMPanoFilterValue.html +2 -2
- package/docs/interfaces/index.PBMPanoGainmap.html +3 -3
- package/docs/interfaces/index.PBMPanoPicture.html +8 -8
- package/docs/interfaces/index.PBMRefinedScreen.html +2 -2
- package/docs/interfaces/index.PanoCircleMeshInterface.html +1 -1
- package/docs/interfaces/index.PanoEvent.html +1 -1
- package/docs/interfaces/index.PanoPrepareEvent.html +15 -0
- package/docs/interfaces/index.PanoTextureEvent.html +1 -1
- package/docs/interfaces/index.PanoramaControllerCustomInitArgs.html +1 -1
- package/docs/interfaces/index.PanoramaLikeControllerCustomInitArgs.html +1 -1
- package/docs/interfaces/index.ParameterMaterialValue.html +42 -41
- package/docs/interfaces/index.ParameterTilesetValue.html +15 -15
- package/docs/interfaces/index.ParameterValue.html +56 -55
- package/docs/interfaces/index.Pose.html +1 -1
- package/docs/interfaces/index.RenderEvent.html +2 -2
- package/docs/interfaces/index.ResolvedParameterValue.html +56 -55
- package/docs/interfaces/index.State.html +1 -1
- package/docs/interfaces/index.StateEvent.html +1 -1
- package/docs/interfaces/index.TextureOptions.html +1 -1
- package/docs/interfaces/index.TopviewControllerCustomInitArgs.html +1 -1
- package/docs/interfaces/index.VRPanoramaControllerCustomInitArgs.html +1 -1
- package/docs/interfaces/index.ViewLayer.html +1 -1
- package/docs/interfaces/index.WorkCubeHdrGainmapImage.html +1 -1
- package/docs/interfaces/index.WorkCubeImage.html +1 -1
- package/docs/interfaces/index.WorkImage.html +1 -1
- package/docs/interfaces/index.WorkObserver.html +1 -1
- package/docs/interfaces/index.WorkTile.html +1 -1
- package/docs/interfaces/index.WorksEvent.html +2 -2
- package/docs/interfaces/index.XRControllerEvent.html +2 -2
- package/docs/interfaces/index.XRGestureEvent.html +2 -2
- package/docs/interfaces/index.XRPanoramaControllerCustomInitArgs.html +52 -0
- package/docs/interfaces/index.XRSessionEvent.html +2 -2
- package/docs/modules/index.html +1 -1
- package/docs/types/index.ControllerCustomInitTypes.html +3 -2
- package/docs/types/index.ControllerEventTypes.html +3 -3
- package/docs/types/index.DeviceProfileOverride.html +5 -0
- package/docs/types/index.FlowingLightLineInput.html +11 -0
- package/docs/types/index.Mode.html +6 -4
- package/docs/types/index.OutputTextureDataType.html +1 -1
- package/docs/types/index.PBMCustomNodeTargetType.html +1 -1
- package/docs/types/index.ParseOptions.html +1 -1
- package/docs/types/index.XRMachineType.html +7 -0
- package/docs/variables/index.PBMVertexMarkFlag.html +4 -0
- package/docs/variables/index.controllersDefaultInitArgs.html +1 -1
- package/five/application/controllers.d.ts +4 -0
- package/five/application/five.d.ts +3 -1
- package/five/application/fiveInitArgs.d.ts +19 -1
- package/five/application/mode.d.ts +7 -2
- package/five/controllers/xrPanorama.d.ts +506 -0
- package/five/core/internalWebGPURenderer.d.ts +7 -1
- package/five/core/webglAsyncReadFix.d.ts +25 -0
- package/five/index.d.ts +4 -1
- package/five/index.js +29 -29
- package/five/index.mjs +5201 -3668
- package/five/model/index.d.ts +3 -2
- package/five/model/materials/pbmMaterial.d.ts +13 -1
- package/five/model/materials/pbmMeshMaterial.d.ts +0 -9
- package/five/model/materials/pbmPointCloudNodeMaterial.d.ts +1 -1
- package/five/model/objects/pbmPointCloud.d.ts +0 -1
- package/five/model/objects/pbmPointCloudObject.d.ts +1 -1
- package/five/model/parameter.d.ts +5 -4
- package/five/renderer/index.d.ts +1 -1
- package/five/renderer/postprocessing/index.d.ts +1 -1
- package/five/utils/event.d.ts +9 -2
- package/five/webxr/XRControllerModelFactory.d.ts +55 -0
- package/five/webxr/buttonStateMachine.d.ts +31 -0
- package/five/webxr/deviceProfile.d.ts +70 -0
- package/five/webxr/inputSourceTracker.d.ts +59 -0
- package/five/webxr/referenceSpace.d.ts +60 -0
- package/five/webxr/renderTargetBridge.d.ts +45 -0
- package/five/webxr/xrButton.d.ts +4 -0
- package/five/webxr/xrManager.d.ts +174 -0
- package/gltf-loader/index.js +3 -3
- package/gltf-loader/index.mjs +3 -3
- package/line/circle_png.d.ts +1 -0
- package/line/index.d.ts +49 -0
- package/line/index.js +255 -0
- package/line/index.mjs +340 -0
- package/package.json +25 -5
- package/plugins/FloorplanPlugin/index.d.ts +1 -0
- package/plugins/FloorplanPlugin/typings/floorplanJson.d.ts +167 -0
- package/plugins/FloorplanPlugin/typings/index.d.ts +1 -0
- package/plugins/FloorplanPlugin/utils/formatFloorplanJson.d.ts +20 -0
- package/plugins/FloorplanPlugin/utils/polylabel.d.ts +8 -0
- package/plugins/index.js +361 -6
- package/plugins/index.mjs +25707 -363
- package/plugins/thirdParty/doctorstrange-model.d.ts +92 -0
- package/react/index.js +2 -2
- package/react/index.mjs +2 -2
- package/sticker/geometry.d.ts +3 -0
- package/sticker/index.d.ts +68 -0
- package/sticker/index.js +255 -0
- package/sticker/index.mjs +358 -0
- package/umd/five-gltf-loader.js +3 -3
- package/umd/five-line.js +322 -0
- package/umd/five-plugins.js +370 -15
- package/umd/five-react.js +2 -2
- package/umd/five-sticker.js +255 -0
- package/umd/five-vfx.js +323 -0
- package/umd/five.js +68 -68
- package/vfx/airflow/airflow.d.ts +18 -0
- package/vfx/common/simplex-noise.d.ts +2 -0
- package/vfx/frame/frame.d.ts +27 -0
- package/vfx/index.d.ts +7 -0
- package/vfx/index.js +255 -0
- package/vfx/index.mjs +738 -0
- package/vfx/particle/instance.d.ts +36 -0
- package/vfx/particle/particle.d.ts +119 -0
- package/vfx/particle/utils.d.ts +11 -0
- package/vfx/particle-gpu/particle.d.ts +75 -0
- package/vfx/particle-gpu/utils.d.ts +11 -0
- package/vfx/spotLight/spotLight.d.ts +15 -0
- package/work-downloader/components/model-3d-tile.d.ts +2 -0
- package/work-downloader/components/model.d.ts +3 -0
- package/work-downloader/components/observer.d.ts +9 -0
- package/work-downloader/download.d.ts +16 -0
- package/work-downloader/index.d.ts +2 -0
- package/work-downloader/index.js +255 -0
- package/work-downloader/index.mjs +595 -0
- package/work-downloader/type.d.ts +28 -0
- package/work-downloader/utils/download-to-file.d.ts +1 -0
- package/work-downloader/utils/image-processing.d.ts +7 -0
- package/work-downloader/utils/join-url.d.ts +2 -0
- package/work-downloader/utils/log.d.ts +1 -0
- package/work-downloader/utils/relative-url.d.ts +1 -0
|
@@ -43,6 +43,17 @@ interface FiveInitArgs {
|
|
|
43
43
|
plugins?: FivePlugin[];
|
|
44
44
|
/** 是否显示 Powered by Realsee */
|
|
45
45
|
poweredByRealsee?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* 强制使用 WebGL2 回落后端(默认 false)
|
|
48
|
+
* 进入 XRPanorama(WebXR 头显全景)的前置条件。
|
|
49
|
+
* 只在构造期生效,后端无法在运行时切换,设备检测必须在 new Five() 之前完成。
|
|
50
|
+
* 详见下方《forceWebGL 与 XR 回落后端》。
|
|
51
|
+
*/
|
|
52
|
+
forceWebGL?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* @deprecated 在 five-webgpu 中未接线、无效。需要 WebGL2 后端请使用 `forceWebGL`。
|
|
55
|
+
*/
|
|
56
|
+
webgl2?: boolean;
|
|
46
57
|
}
|
|
47
58
|
```
|
|
48
59
|
|
|
@@ -73,6 +84,64 @@ Five 内部维护了一个 `requestAnimationFrame` 循环。
|
|
|
73
84
|
| `antialias` | `boolean` | `false` | 抗锯齿,开启会增加性能消耗 |
|
|
74
85
|
| `modeChangeDuration` | `number` | `800` | 模式切换动画时长 (ms) |
|
|
75
86
|
| `enableWheel` | `boolean` | `true` | 是否支持滚轮缩放 |
|
|
87
|
+
| `forceWebGL` | `boolean` | `false` | 强制使用 WebGL2 回落后端,进入 `XRPanorama` 的前置条件,详见下文 |
|
|
88
|
+
| `webgl2` | `boolean` | — | **已废弃**,在 five-webgpu 中未接线。需要 WebGL2 请用 `forceWebGL` |
|
|
89
|
+
|
|
90
|
+
### forceWebGL 与 XR 回落后端
|
|
91
|
+
|
|
92
|
+
`forceWebGL` 让 five-webgpu 强制走 WebGL2 回落后端,而不是默认的 WebGPU 后端。它存在的唯一原因是 **进入 `XRPanorama`(WebXR 头显全景)模式**:`three` 的 WebGPU 后端目前不支持 WebXR,而 WebGL2 后端下 `renderer.xr` 完整可用。
|
|
93
|
+
|
|
94
|
+
**语义与使用约束**
|
|
95
|
+
|
|
96
|
+
- **语义**:`forceWebGL: true` 时,内部 `WebGPURenderer` 以 `{ forceWebGL: true }` 构造,使用 `WebGLBackend` 而非 WebGPU。
|
|
97
|
+
- **必须在 `new Five()` 时决定**:后端在 renderer 构造期定死,**运行时无法切换**。因此业务侧的「是否需要进入 XR」的设备检测必须发生在 `new Five()` 之前,不能等实例创建后再改。
|
|
98
|
+
- **与 `enableHDR` 互斥**:当 `forceWebGL` 为 `true` 时 `enableHDR` 不生效(`five.enableHDR` 会被置为 `false`),因为 XR 的 projection layer 固定 `colorFormat: RGBA8`,HDR 没有落地路径。
|
|
99
|
+
- **传入外部 `renderer` 时不生效**:如果通过 `renderer` 参数传入了外部渲染器,`forceWebGL` 不会对其生效,需由调用方自行在构造该 renderer 时设置 `forceWebGL`(与 `antialias` 等参数一致)。
|
|
100
|
+
- **`webgl2` 已废弃**:遗留的 `webgl2` 参数在 five-webgpu 中未接线、无任何效果;需要 WebGL2 后端请改用 `forceWebGL`。
|
|
101
|
+
|
|
102
|
+
**能力降级限制**(开启 `forceWebGL` 后不可规避)
|
|
103
|
+
|
|
104
|
+
1. **XR 下没有后处理**:`XRPanorama` 模式会整体旁路 `FiveRenderer` 的后处理链路(合成 / EffectComposer 全屏 pass 均不参与),滤镜、泛光等后处理在头显中不生效。
|
|
105
|
+
2. **点云走 NodeMaterial 路径**:`forceWebGL` 下点云不再走 WebGPU compute 光栅化,而是退回 NodeMaterial 渲染路径。
|
|
106
|
+
3. **3DGS 走 CPU 排序,且 VR 中性能预期需放低**:`forceWebGL` 下 3DGS 只能走 CPU 排序(`RASTER_CPU_SORT`);在 XR 中还要叠加双眼渲染开销,务必对点数 / 显示做降级,不要期待与 WebGPU 后端相同的帧率。
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { Five } from "@realsee/five-webgpu";
|
|
110
|
+
|
|
111
|
+
// 设备检测需在 new Five() 之前完成
|
|
112
|
+
const needXR = detectNeedXR();
|
|
113
|
+
|
|
114
|
+
const five = new Five({
|
|
115
|
+
forceWebGL: needXR, // 一旦创建就无法再切换后端
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
five.load(workData);
|
|
119
|
+
|
|
120
|
+
// 进入 XR(需在用户手势回调中调用,会触发 WebXR 权限请求)
|
|
121
|
+
button.addEventListener("click", () => {
|
|
122
|
+
five.changeMode("XRPanorama").catch((error) => {
|
|
123
|
+
// 后端非 WebGL2 或浏览器不支持 WebXR 时,这里会收到含 forceWebGL 字样的中文错误
|
|
124
|
+
console.error(error);
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// 用户摘下头显 / 退出 XR 时切回普通全景
|
|
129
|
+
five.on("xr.session.end", () => five.changeMode("Panorama"));
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
也可以直接使用内置的 `XRButton`,样式与 API 同原始 five 保持一致(`XRButton.createButton(onClickHook)`):
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { Five, XRButton } from "@realsee/five-webgpu";
|
|
136
|
+
|
|
137
|
+
const button = XRButton.createButton(() => five.changeMode("XRPanorama"));
|
|
138
|
+
document.body.appendChild(button);
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
- 浏览器没有 `navigator.xr` 时显示 `WEBXR NOT AVAILABLE`(非 HTTPS 时显示 `WEBXR NEEDS HTTPS`),不支持 `immersive-vr` 时显示 `VR NOT SUPPORTED`。
|
|
142
|
+
- 回调返回 Promise 时,`XRButton` 会接住 reject。若失败原因是没有开启 `forceWebGL`(后端是 WebGPU),按钮文案会临时变为「需降级到 WebGL2」,3 秒后恢复。其他失败原因不改变按钮,错误通过 `five.on("error")` 上报。
|
|
143
|
+
|
|
144
|
+
> 更多模式说明(含 `XRPanorama` 与 `VRPanorama` 的区别)见 [mode.md](./mode.md),可运行示例参见 `examples/xr`。
|
|
76
145
|
|
|
77
146
|
## Examples
|
|
78
147
|
|
|
@@ -180,5 +249,5 @@ five.updateCameraWithKeyframes(keyframes, 2000).then(() => {
|
|
|
180
249
|
---
|
|
181
250
|
|
|
182
251
|
```yaml
|
|
183
|
-
tags: [five, initialization, core, instance, lifecycle]
|
|
252
|
+
tags: [five, initialization, core, instance, lifecycle, forceWebGL, webgl2, xr, webxr]
|
|
184
253
|
```
|
|
@@ -51,12 +51,19 @@ Five 支持高性能的点云渲染(PBM),并提供灵活的样式配置:
|
|
|
51
51
|
|
|
52
52
|
### 4. Vertex Marks & Semantic Filtering (顶点标记与语义过滤)
|
|
53
53
|
|
|
54
|
-
`vertexMarks`
|
|
55
|
-
|
|
56
|
-
* **机制**: 模型顶点预置了 `_feature_id_rsmask`
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
54
|
+
`vertexMarks` 用于控制模型顶点上的语义标记(`_feature_id_rsmask`)逻辑。它是一个**按位掩码(bit flag)**,可以独立开关多类标注,而不再是单一的全局 `boolean` 开关。
|
|
55
|
+
|
|
56
|
+
* **机制**: 模型顶点预置了 `_feature_id_rsmask` 属性,不同的值代表不同的语义部分;每一类标注对应掩码中的一位,可按位独立启用。
|
|
57
|
+
* **标志位 (`PBMVertexMarkFlag`)**:
|
|
58
|
+
* `PBMVertexMarkFlag.roof` (`0b00000010`): 开盖标注(`_feature_id_rsmask=1`)。开启后,命中屋顶标记的顶点会按 `roofStyle` 裁切:`AUTO` 随相机俯仰角渐进隐藏,`HIDE` 始终隐藏。
|
|
59
|
+
* `PBMVertexMarkFlag.hidden` (`0b00000100`): 隐藏标注(`_feature_id_rsmask=2`)。开启后,命中隐藏标记且超过高度阈值的顶点会被裁掉。
|
|
60
|
+
* `PBMVertexMarkFlag.none` (`0b00000000`): 不启用任何标注。
|
|
61
|
+
* `PBMVertexMarkFlag.all` (`0b11111111`): 启用全部标注(默认全开,且包含未来新增的标注档位)。
|
|
62
|
+
* **按位组合**: 使用按位或组合多个标志,例如同时开启开盖与隐藏:
|
|
63
|
+
`PBMVertexMarkFlag.roof | PBMVertexMarkFlag.hidden`。
|
|
64
|
+
* **向后兼容**: `vertexMarks` 仍接受 `boolean`。传入 `true` 等价于 `PBMVertexMarkFlag.all`(全开),`false` 等价于 `PBMVertexMarkFlag.none`(全关)。
|
|
65
|
+
* **与自定义节点的关系**: 节点上下文中的 `isRoof` / `isHidden` 等标记判定**始终可用**,不受本开关影响;`vertexMarks` 只门控管线内置的自动裁切。
|
|
66
|
+
* **未来扩展**: 新增标注档位时,只需在 `PBMVertexMarkFlag` 中追加一个新的位,不影响现有标志。
|
|
60
67
|
|
|
61
68
|
## Configuration
|
|
62
69
|
|
|
@@ -74,7 +81,7 @@ Five 支持高性能的点云渲染(PBM),并提供灵活的样式配置:
|
|
|
74
81
|
| `pointMinPixel` | `number` | `0` | 点云最小像素尺寸。 |
|
|
75
82
|
| `pointMaxPixel` | `number` | `40` | 点云最大像素尺寸。 |
|
|
76
83
|
| `pointAppearAnimation` | `boolean` | `true` | 是否开启点云出现动画。 |
|
|
77
|
-
| `vertexMarks` | `boolean` | `true` |
|
|
84
|
+
| `vertexMarks` | `boolean \| number` | `true` | 顶点标注开关,按位控制(见 Concepts)。`PBMVertexMarkFlag` 位掩码;传入 `boolean` 时 `true`=全开、`false`=全关。 |
|
|
78
85
|
| `brightness` | `number` | `1.0` | 场景亮度倍数。 |
|
|
79
86
|
| `floorStyle` | `PBMFloorStyle` | `'OPACITY'` | 楼层显示样式。 |
|
|
80
87
|
| `shownFloorIndex` | `number` | `-1` | 当前显示的楼层索引。`-1` 表示显示所有楼层。 |
|
|
@@ -140,6 +147,26 @@ five.model.set({
|
|
|
140
147
|
});
|
|
141
148
|
```
|
|
142
149
|
|
|
150
|
+
### 3. Toggling Vertex Marks (控制顶点标注)
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { PBMVertexMarkFlag } from '@realsee/five-webgpu';
|
|
154
|
+
|
|
155
|
+
// 仅开启“开盖”标注
|
|
156
|
+
five.model.set({ vertexMarks: PBMVertexMarkFlag.roof });
|
|
157
|
+
|
|
158
|
+
// 同时开启“开盖”与“隐藏”标注
|
|
159
|
+
five.model.set({
|
|
160
|
+
vertexMarks: PBMVertexMarkFlag.roof | PBMVertexMarkFlag.hidden,
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
// 关闭全部标注
|
|
164
|
+
five.model.set({ vertexMarks: PBMVertexMarkFlag.none });
|
|
165
|
+
|
|
166
|
+
// 向后兼容:true 等价于全开,false 等价于全关
|
|
167
|
+
five.model.set({ vertexMarks: true });
|
|
168
|
+
```
|
|
169
|
+
|
|
143
170
|
## Related
|
|
144
171
|
|
|
145
172
|
* [Parameter](./parameter.md): 配置系统入口与继承逻辑。
|
|
@@ -149,5 +176,5 @@ five.model.set({
|
|
|
149
176
|
---
|
|
150
177
|
|
|
151
178
|
```yaml
|
|
152
|
-
tags: [material, appearance, pointcloud, parameter, roof, ceiling, config]
|
|
179
|
+
tags: [material, appearance, pointcloud, parameter, roof, hidden, ceiling, 开盖, 隐藏, 顶点标记, 位掩码, bitmask, vertex-mark, config]
|
|
153
180
|
```
|
|
@@ -13,11 +13,12 @@
|
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
15
|
type Mode =
|
|
16
|
-
| "Panorama"
|
|
17
|
-
| "Mapview"
|
|
18
|
-
| "Floorplan"
|
|
19
|
-
| "Topview"
|
|
20
|
-
| "Model"
|
|
16
|
+
| "Panorama" // 全景图游走模式
|
|
17
|
+
| "Mapview" // 模型地图模式
|
|
18
|
+
| "Floorplan" // 模型户型图模式
|
|
19
|
+
| "Topview" // 模型平面图模式
|
|
20
|
+
| "Model" // 模型游走模式
|
|
21
|
+
| "VRPanorama" // 手机 Cardboard 分屏全景模式(陀螺仪驱动)
|
|
21
22
|
```
|
|
22
23
|
|
|
23
24
|
## Concepts
|
|
@@ -32,6 +33,12 @@ type Mode =
|
|
|
32
33
|
* 交互:鼠标拖拽 / Pan手势平移相机;滚轮 / Pinch手势缩放画面;点击 / Tap切换到最近全景点。
|
|
33
34
|
* **Model (模型漫游)**: 适用于第一人称在场景中自由游览。交互同 Panorama,但不限制相机只能在观察点位置。
|
|
34
35
|
* 交互:鼠标拖拽 / Pan手势旋转视角;滚轮 / Pinch手势缩放视场角;点击 / Tap移动到指定位置。
|
|
36
|
+
* **XRPanorama (WebXR 头显全景)**: 适用于通过 WebXR 在 VR 头显(Pico / Quest / Apple Vision Pro 等)中沉浸式浏览全景。头显朝向决定看景方向,用手柄 / 注视射线指向并走动到全景点位。
|
|
37
|
+
* 交互:头显朝向看景;手柄指向射线(或 Vision Pro 的注视射线)拾取;手柄按键 tap / press 走点与触发事件。
|
|
38
|
+
* 前置条件:**必须在 `new Five({ forceWebGL: true })` 时开启 WebGL2 回落后端**(`three` 的 WebGPU 后端目前不支持 WebXR);浏览器需支持 WebXR(存在 `navigator.xr`)。
|
|
39
|
+
* 进入:`five.changeMode('XRPanorama')` 或 `five.setState({ mode: 'XRPanorama' })`,会触发一次 XR 会话权限请求(需在用户手势中调用)。
|
|
40
|
+
* 退出:监听 `xr.session.end` 事件后切回其他模式(如 `Panorama`)。
|
|
41
|
+
* **VRPanorama (Cardboard 分屏全景)**: 适用于手机配合 Cardboard 眼镜的分屏体验。使用陀螺仪驱动视角,左右眼分屏渲染。**不需要头显设备,也不需要 `forceWebGL`**。
|
|
35
42
|
|
|
36
43
|
## Configuration
|
|
37
44
|
|
|
@@ -235,15 +242,25 @@ document.querySelector('#btn-map').addEventListener('click', () => {
|
|
|
235
242
|
1. **相机类型差异**:`Topview` 模式使用的是正交相机 (OrthographicCamera),而其他模式使用的是透视相机 (PerspectiveCamera)。在进行自定义渲染或计算时需注意投影矩阵的差异。
|
|
236
243
|
2. **切换动画**:`setState` 触发的切换动画是自动规划的,而 `changeMode` 允许更细粒度的控制。如果需要精确控制动画时长或回调,请使用 `changeMode`。
|
|
237
244
|
3. **全景加载**:`Panorama` 模式下会自动使用瓦片(tile)方式加载全景图以平衡效率和清晰度,而其他模式(如 `Mapview`)主要展示模型几何。
|
|
245
|
+
4. **`XRPanorama` 与 `VRPanorama` 不要混淆**:
|
|
246
|
+
* `VRPanorama` 是手机 Cardboard 分屏 + 陀螺仪方案,**不需要头显、不需要 `forceWebGL`**,面向的是把手机塞进纸盒眼镜的场景。
|
|
247
|
+
* `XRPanorama` 走的是真正的 WebXR 头显设备(Pico / Quest / Apple Vision Pro 等),**必须 `new Five({ forceWebGL: true })`**,面向的是独立 VR 头显。
|
|
248
|
+
* 两者的驱动源(陀螺仪 vs WebXR viewer pose)、渲染路径(分屏 quad vs XR projection layer)、输入方式(无手柄 vs 手柄 / 注视射线)都不同,切换前请先确认目标设备。
|
|
249
|
+
5. **`XRPanorama` 的能力降级限制**(均源自 `forceWebGL` 的 WebGL2 回落后端,无法规避):
|
|
250
|
+
* **XR 下没有后处理**:XR 模式会整体旁路 `FiveRenderer` 的后处理链路(合成 / EffectComposer 全屏 pass 都不参与),滤镜、泛光等后处理效果在头显中不生效。
|
|
251
|
+
* **点云走 NodeMaterial 路径**:`forceWebGL` 下点云不再走 WebGPU compute 光栅化,而是退回 NodeMaterial 渲染路径。
|
|
252
|
+
* **3DGS 走 CPU 排序,且 VR 中性能预期需放低**:`forceWebGL` 下 3DGS 只能走 CPU 排序(`RASTER_CPU_SORT`);在 XR 中还叠加了双眼渲染的开销,务必对点数 / 显示做降级,不要期待与 WebGPU 后端相同的帧率。
|
|
238
253
|
|
|
239
254
|
## Related
|
|
240
255
|
|
|
241
256
|
* [State - 状态](./state.md): 了解 Mode 在 State 中的位置及其他状态属性。
|
|
242
257
|
* [Gesture - 手势](./gesture.md): 了解不同模式下的手势交互逻辑。
|
|
243
258
|
* [Event - 事件](./event.md): 了解模式切换等相关事件。
|
|
259
|
+
* [Five - 核心类](./five.md): 了解 `forceWebGL` 初始化参数(进入 `XRPanorama` 的前置条件)。
|
|
260
|
+
* XR 示例:参见 `examples/xr`(`forceWebGL: true` + 按钮进入 `XRPanorama`)。
|
|
244
261
|
|
|
245
262
|
---
|
|
246
263
|
|
|
247
264
|
```yaml
|
|
248
|
-
tags: [mode, state, interaction]
|
|
265
|
+
tags: [mode, state, interaction, xr, webxr, vr, forceWebGL, XRPanorama, VRPanorama]
|
|
249
266
|
```
|
package/docs/assets/hierarchy.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
window.hierarchyData = "
|
|
1
|
+
window.hierarchyData = "eJytmttu2zgQht9F12yXw5NI3zVpUwRImqDpdhcoeqHYrMNGlgJJThMUffeCUuOQshwPvXuToPH8+v4ZDg+i+zNr6rprs9kXoJISLRgBSQ0BxTjhhjEiVE5AGkY4cEYUN5wowQVRJteEM2YISJUToQ2RXEuiJKNEyZx/JVljv5V23rm6arPZz4xp4X9Vxcpms+yD7X7Uze3V+rqdN+7aZiS7ddUimwHTJFs3ZTbL5mXRtrb9y1UL+/B6rHh9063KjAxR2Szr2sUr/4hXwx9+kUxwGhDffC8eLu4GO08wJtUTzFWdbb4V8w0viN+J2oh6nMq3E0whxhIElGTzG1cuGltlsy+C06/ehTaBi4T6YgsbQZkWBBRnhCuQHq8FC/BH9bpauGr5uS7XK4sqQixJLYIBSoxUBCjt7RigkZ2Hgxw9JJvyaKkC9Ee7dHV1AH1KiDPgaxC2wt2NbewBDqaEWAcyKn/R2nf3tupwZX+KTu0BAEoJABgCvtkBeE4AhCAA0v/QigAYRYBRToABEGCMEmBcE2BCfR2ch6P33rbdukkwHwqQtQIa1urUf9baeYdnxhI0NVwuzuuFPb4pqmVCqiMNlgtjbvnJlYnYZwmWyvSYmkhMovF8TLua2yo1yWcNlismdtqPtq3XzTwBPiXEOpChg4vr70mNHMRjeQoC3mVR1XjaJhrL0mrE+mQf0laHsQhLNvGOUi1sg4cG8UgeozzcP7qiS8jxOTx5/aZ+Awd/DgUF/WrMIBzff+rmtsU7eQ7H5s3Clfjfj8mrfyzBUrmOqFe2bV1dpVBDCZYqVEQ9rquuqcsypbO2VFh2NJOeDhjntr3Zf1oNo/e/CQAzZjRpj10zLy0OFscjcFyxnbirunSLVGYvQoAF4zvBx+u2q1ep5EGFQZvJ80tUYdTx5cUaxx0ko9PL6apY2pQXrlCQvEpJxvq1SbJwrP8s6ykuYgk28+hl87JucWd5H5ieac6HTPOt/QC/FWDzMrtnzmngD7fJTmiTs2fGED+viJ/VfR1UNMmivk2zOC1NdigMHXzxsHYn7h7x1u+j9k9uTgWMj7LPa/6wRJxWrnvTLHE9/+ITcK3CqRyv6U2xKv6TrX0PQToDPm5i/9Azd2v/F3cvPSi1efzIEl9K30H+Qi80fnSO3B+HwJSLI7/590gZvSRdHp1f1q7qjst6vTgvOtu4okQZ2JYh2lqBjOF/3y2KzhbXJWLqROEpufOccsL1cGHm/zEqQFHVJ67sbINLfBOOSFiPEx6650O9wCX8HI6AmWhnPPVdMh7RF1fHQJB8GQoUiOBcEQGaEsGkJr7Vhh/Dp5sPhjgBmghJcyKkkUQo3W96PnR7ShwVrZsnteeWCnF9DZpuoy9v6mqZjI5UCDSTegr92Lp5UR5Aj4WYq3uuJgwUVX1RlY/pBkZChAEBExXoR9B3/2FjHyoRFiTNd4z/QRa2lBgLRu7ugwNdbIsRRpTmu/vhMCMT4v1G/Ldc4XHflZa/3c8c4lI2Calof/fhfwfAz87+OCseg73hpSV0E407uCim43u0pljZzjafi3KNPXSHktRVW3Ge+5z97+imq63Le7s4wM+0FFkNbvhUNZ6a5YCqRNLk6jDdd4T/AnbKl++x1nYH2AqVB7uS0a2Zv3Q7Xl/b/hUbfU23USS7kMwQpSD/Y8WMrKTZwFroWdFLsVdfXLe2uUfO0FCQnLSWQ74K8pEHP6Jovg9GZqvlmPQ0w7ay3rkWTqn2L7zKRN8p+PfWy2HRRLzh+siUxVcZI0hOOSU5yJzk/pSYM9Mf2P1/fYimX4t9e3vBw64RNlIMTBMm/2ZR3HXu3p6tV64qqjmyEpOy/ZX3dQjg7x7t23plz9zypnPVEoeeEGHA0dw6Kesfrlr2z2BvkYO/pUFgIWry8BH8ACzHYKNR93n7Uc/jU/j7Yt22rqiOynWDszFWIHJn0YHvTx4nrrH+q8A2Mf+Rbh/+16/foP0RJw=="
|
|
@@ -1 +1 @@
|
|
|
1
|
-
window.navigationData = "eJylnVtz2zYWgP+
|
|
1
|
+
window.navigationData = "eJylnVtz2zYWgP+L9zXOtnHqpnmzZcXx1opVSbnsdDoeiIQk1BTBAqBjZ6f/fQcUReF6zlH6an7nOyBIgiAu8u//OzH8yZy8PZmNL64m45MXJw0zm5O3J6Us2i2vjf737sjLjdlWJy9OHkRdnrx9c/bmzfkPb/5+McQzcVrK4nTdipJXouY6pYog1NqIpKcRWOS6kloz9ZwK3x/DHKI2SqYE3QEs+q9WFA+n2jBlUg7nMGbSbdPItKU/hBkM3zYVMzyl2B/DHCvOTKu6C1tsRFUqXp+8/X04fFYaUSUT7APvdwiWp2Bbrtgpq8WWGSFrUBnCqLwSTcMV7NwxqEpKVYqaGX6qn7XhW1ga0pieP/I6eckHZUegV008whfFAujDxLWFQU/P4CpzqgvFeX3aiCdeJdsJRxrQ6CO7ZWt+Kht7L8Bqj8S0lWTlKX8yXNWsOt3KklegPMGTUjRKrhXXcMk9EtNumeFKMLi4ewiVyRK+CSxAkSDFodTXVj7y04bV8pSvVryAH5UQRuVtZcTpV6keYO2AYcIu90pUBml7HI6kRNvcgSLp2kdc1j7iKsW2HD/VnsJ0ij0XTMMXuGdQFf+r5drYp+cp2TU4CF0SfUH3TZSSf2J3oo+iYpN5aR98hvDqbiuj2OmmhC/IQGG6R8G/nlbsGbnABwwTog9a/hH7w7u6FWea39fSZLsp5y/PU5m80Pvzl+dYkc9f/kzx/Ix73lA8b/CzF3XJnw6urSzbitu+asmf/OhX6ar5JKt2y6cVq/lNbbjS3r3M63a7t6XIoIBOwS5K1hjxyG/brahZXfApc99wRcW0HgqahH33j688+77r9842J7dSNll1RELeS9nWpajXE643OaPLQK5R10vNWXZHofhx99IayW0jtfvQ+R6fAn3P/Epu+a1Yb4yo19D1SKCQ+R03xSZfxP4waPA6rEF41FeNY6GT2R/HHDNel1wBp+EwoKuSX0W9ficUty2YPrsCS5ekCf7u4ryiuB2S6iWV2SFBb1tV8+4F+FvLyqzToyDfNWu1Fqy+rFoFlTLkIOd7oY1cK7bNyQYAsnTNYs2qz3x5Pf2I3U9pGvJP/E60r5vE/edE9LzgdfZJOxCwx/9ADx3xF7kf/4Ebe6fP26UulFhmSxNykHPKajkSqqg41HL7FN03arWR2VsjxdLdc1mJ7EORQGFz1AUPfcned2C5nOxO4oP34ReYXAix7R/EuR1xsu8TGzOJPlGjBGDcsTnvln4vHc+2izg2z+45Bu9CMArLp2Sb7evsj0eOFzvQdjZ5o3jBDC9PfDFSYkLRLHLJtCgIlzZiqW7irZPkCTnsA3dXV8/EFCF+RIYjTiQVQsm0kfWamsJlqe5jTiHkSTmetShYRU7h40dkOOpE4hAkk71874JBoMh9gDCbFLUZVbLNvzRciGwjnH8MI/b5g6hrXiJNi0Mhvo9NyQxnywp6LR0gyAb2g9AuENp3IXVaFvzJDnTcSlbm7w0PAm0iXy2LaCgwjj27gqLPrrD4ESs2YAE6ALNAfY79ccwx243izYsNt6Mh+apNsJhb82wfoj8MGhSzfQrpzlAGkoGgecD68ijI99kbivMtn6NRuDh2xrWsHnl5t9RcPeZrPMVC7i+zy9aY/MfG/jg4VFSWtjEI+3/Cfn2tWOGMQTlcMHT207kr/JM93YVzTbHuQIEyb3gK8nkgXTmSdfd3qrnnoQSXTPOxP1EZSQcGFPUjabuRRcjmgbDy6QjrE128G6+bSg0ZDxCoqmTxAFnscVDQVhXlBD0OEl7xR1HwqZIr7yUSCT0OFCpWSEhkj0OC7t4ZsapaMrCuPA4S2tG7m1qYC7WGHlsXw3T2nYw3BAEJSispVVOx2j6ESlYVV7uPbErBsVgo8TUT9ZY1o9X6ihkGZPFBULlbGYC1Ey4G6W7sxD1e2S6G6j7ObiesaUQNVmyIUrTEgh5IULqfbMHq0gdJSm8gLy+MRvQyOr+nn/fFfX1AeLPXUM1DAJjCftBF3zyx2MEg3a2UmtuPOL8rFfk8DhVSZGSRbQjgkw1RkjYYlM5LEwPUGWXcjcxb093IjNhWvGJbqIWLWJL4kyg59L7zQZLyszCb8ZNRotaigJqSTASUZMIaO0//Ha8ZJBJMKks+2rB6jb4UAhKTVt9zHlAcmpByAhWt7PirwsVQXTd0QSregUSl9suW5BxAWGlP5Vf+vEI+eXwQVj52jSqlMj0SkvbzTxdLqcxYKQk1RxFLEL8TainKktdEuc8TEuC14YME5dQujCKW98ASxHZUoFUFepulcJq+kbXmxKJ7OEG/EFsuW+pd4tKQfDcUgdWIQ0Gy1CwlfoMAUfRklA5cJoKe5NhzOfosutnXY7O4QVgq7EIPDCaaKt4w/NMrRDGt7Qx9x5sWC6WkvRUP/B+khsKx9P34O6UyXRTW9rPw+w+LT6xq4YcjFUBK0Q9KkzO4PCkB2UxQavhihkt4gvDLyWi3hyOxDCK2xTQmH5Y74EOqKZysJ7QxCZys7xqo487ACSGnmVfSkM+hgxE1uBqEVGcUA1IIWxNXvDHQKIeLEXS7WV/0MYpggrofrcO1PUhQTkXhbwrKKXsQUc74StS83C38g6UeCmqHaWpkMNMHYSU47I8N+M/4WsiaPC+RwmG9XTyEvaEcCpbtpufIDXw6AEyxXjLk0uwRSDNvNlxxcq2mcFhfMYMUc2BAkb+dI5bEmzkSAuzyHiBI1XdR8ObSB0FltzqAYHQ5TDgaNk7Og12WSW+IY/r33F9ykZTuIEyluSHZBo4gpFXmAQSV8nuH+pBIMOmw8gCvmwCFtJ8E/3rr70CKfAODifzN1UlPvMk60Mz+wXcRHgyl/syXX2YXT1x3zS6UJyBR6aE0NHXIgwmkehi1S/6+VH2Xo5sHg1KkIyhJqGqSkCKjidBZGOIEjIP9R4PTeAGJSQk2igabFyJNCQ0QoVADRxJi7YgP0pXUgg4wpiZMhlHnwVyOUE4XxbT7toygdVGqVh/h1RSxxvpTBwhTLeA1M3sE02BTiKTZQ7c5xs4wYmExcUGHD8LKf/D2xIPh1HOutZA1fjYuiK0K3E8bLJ4b544wz423KtClAuMPv/z840+vAGu/CIUm72E0R7RDFih/ksUy+B9d/qPs2mMONz/R5QkU86duLnvGOp0ji9PzdDcaKcWBRO3tkr/z5l88Y38Us3iL/+4euVKizCiTKOYfM203wrZ1sCzJFfsMakTqkl6D3R7iql2LTLkOx+kme3NgNsscY9TG7p7HrTsONSf3Jt+KOpchyxMzOTuV0SwBe0wG4nkE7DEZLH9TN23uAqdQzN+/V4H72SUw2y1fs+J5eALSwgBCnZKVM67bClJ6DGacyFwTM4m2NKSjq0xd7Y7hBtvO7OZzc54DQbTJeiUyr3CXoNlsCxHNIMZKB6N5USPRtVtuMw5+rcnXuQxm7NdQBEstXJ9LHGOLV5vnrJn15il7973H3UHkQLoHiCWd9r8ARipsCBNz7PuQoHsPEZ3BIHhCmBoGz9raoqBWQsASM+QbMAfAXHetaVrTD6XbaYK8NYlifvvUpHX2CCX6pszH35S4Qel4LsH3HAjUdjm5qJoNy7f5LkGwjWQl1dw855puD6H4hvnqBVNrDrzkMjAhR7eNAy7zASH47CKkeJl7YHQhgrObN73MPncuQbV1s7DzjZ0AAGs1BVNzzDcMM3cI2Se+YTrxjWKbSbmCL/lAEGwLxWot8p9QHoL6pDZTJW0DKuo1cGkiDjOnJrnzH+85Gs/Sbe/1hy38oSU/TQbH8swLoXWuQ9IfTDqwX+ZIzVrnqylHo8Xfb1fvuvoTd8mIpw8xzDts+wZfEiFFstrlSHUwPx9JDxDF2V/9O+XNWIZSlzrCOuwwR6siE0DJpbnpblmgtxVhqHeYoMXrPIVi/mAS8Vf+nJbH3JHmfOuVAFG3Hd/I2OwhLP7LbMKKjaiBsWIPwXzFUHp9xVesrUw8iP7IlLBb3PcJ8jF+tjM3Uenv7A2dZbyx1wu/nk9vLxb305vp+Pbmw/j+4uPiLm9L0UfIZxfzxXh2P5p+vJ/fzRb0PEHg8SmvvzflNZ5yejn5xJXhTxOmHt5VbJ1PEqGQdnb35b/3o7sPi9nd7e14dj/+NP6wuP9wMRnPgQxAFJDs8MPoeiE/dW3GIceqH9493KcR7KvPX7tqxZnhV3zZrtO/5hnp0wFoiqAJSGsTjYGvGj4TdPcK9Jq/SBnDgLrsn+l+p3HX6VtJtc37cxFAkjU3+5Uy84K5XdhQHpKAdMOZvQoLeSvrtTBtCWhjNhRjXazuN+Hn4X9bCPO4FFB0oXMLEiOhhtYiBtLwWz2Wpb7YPYn9AfkLcwZI9gQisb8MC0ssQZB8wy3fEM11ZVawxRKIZLoEnokewBQV8Nj2AKjo792FfL+7nyFbyB57w2/ZQ3bZbJgtZoHTsL8UP/6rdUcaQt+AIJpu4AjWdAiimdvd0GuxAq6Oh4E6FW7Ij1UqtR/f0yi+Ftpw5fyuAPASSdGA/LF7OS7kYT0s4E7AgLob85T+p2doPDCAqJt48TYyOWWMf7/8X93/hdj/r4rHPb8Tv/7xl9dnP7z2O0fX8/C3nhLWZrlda7nnANuwrB0uZbPcNi6ZM+5WQQdr4xI++88bzsr9f80g2HY/EBd9XMLqqgs6/OMUP88ff//xf3BmlmM="
|