u-space-mcp 0.0.11 → 0.0.13

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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # u-space-mcp
2
2
 
3
- Model Context Protocol server for the `u-space` documentation, including u-manager semantic APIs such as `SemanticLoader`, `SemanticSceneGroup`, `BuildingGroup`, `FloorMesh`, scene-level `Facilities` auto instancing, floor-mounted facility lookup/control, semantic elevator/vent shafts, per-kind floor-plane planishing for semantic instances and Facilities, atmosphere `skyBackground()` / `skyEnvironment()` output-effect setup, and core object defaults like `BaseMesh` shadow behavior.
3
+ Model Context Protocol server for the `u-space` documentation, including u-manager APIs and examples such as `UManagerLoader`, `examples/test_umanager_loader.html`, `SemanticInstanceObject`, `SemanticModelInstancedLayer`, `SceneLoader` semantic-id dedupe and path-based model instancing, `SceneInstanceObject`, `SceneInstancedLayer`, `SemanticLoader`, `SemanticGroup`, `BuildingGroup`, `FloorMesh`, `FacilityInstanceObject`, `FacilityInstancedLayer`, scene-level `Facilities` auto instancing, floor-mounted facility lookup/control, semantic elevator/vent shafts, per-kind floor-plane planishing for semantic instances and Facilities, atmosphere `skyBackground()` / `skyEnvironment()` output-effect setup, fire `FireEffect` WebGPU volumetric fire/smoke simulation, and core object defaults like `BaseMesh` shadow behavior.
4
+
5
+ The bundled docs index includes detailed `UManagerLoader`, `UManagerSceneGroup` direct `semanticGroup` / `sceneGroup` properties, `SceneLoader`, `SceneInstanceObject` fields and inherited semantic APIs (`setSemanticVisible()`, `setSemanticColor()`, `setSemanticOpacity()`, `setSemanticHighlight()`, `getSemanticBoundingBox()`, dirty callbacks, and fallback render-object access), and Facilities reference material for the unified `SemanticInstanceObject` API, the runnable `test_umanager_loader.html` example, flying a camera to path-instanced scene objects or Facilities through `objectManager.getById()`, `getSemanticBoundingBox()`, and `controls.flyToBox()`, shared `SemanticModelInstancedLayer` batch creation through `addSemanticBatch()`, dirty-driven instance synchronization, unsupported-model fallback wrappers, instanced raycast hit remapping, plus `FireEffect` emitter setup, simulation/grid options, volumetric pass bounds, dynamic lights, and RenderPipeline output-effect integration.
4
6
 
5
7
  ## Usage
6
8
 
@@ -110,7 +110,7 @@ export const docsIndex = [
110
110
  "id": "api-effects",
111
111
  "path": "api-effects.md",
112
112
  "title": "Effects API",
113
- "summary": "`u-space` 提供了两个基于 Three.js 着色语言(TSL/WebGPU 节点)的静态特效工具:`MaterialEffects` 用于为对象应用高亮、呼吸等材质特效,`TSLEffects` 用于生成动态颜色节点模式。 静态工具类,将基于 TSL 的视觉特效直接应用于对象的材质。适用于任何 `Object3D`(支持单个或数组),会自动遍历所有子网格。 特性:",
113
+ "summary": "`u-space` 提供了两个基于 Three.js 着色语言(TSL/WebGPU 节点)的静态特效工具:`MaterialEffects` 用于为对象应用高亮、呼吸等材质特效,`TSLEffects` 用于生成动态颜色节点模式。 静态工具类,将基于 TSL 的视觉特效直接应用于对象的材质。适用于任何 `Object3D`(支持单个或数组),会自动遍历所有子网格。 当对象是 `SemanticInstanceObject`(例如 `SceneInstanceObject`、`FacilityInstanceObject` 或楼层里的 `FloorSemanticInstanceObject`)时,`highlightColor()` / `removeHighlightColor()` 会通过 `setSemanticHighlight()` / `clearSemanticHighli",
114
114
  "headings": [
115
115
  {
116
116
  "level": 1,
@@ -173,7 +173,7 @@ export const docsIndex = [
173
173
  "text": "TSLEffects.fluid(parameters?)"
174
174
  }
175
175
  ],
176
- "content": "# Effects API\n\n`u-space` 提供了两个基于 Three.js 着色语言(TSL/WebGPU 节点)的静态特效工具:`MaterialEffects` 用于为对象应用高亮、呼吸等材质特效,`TSLEffects` 用于生成动态颜色节点模式。\n\n## `MaterialEffects`\n\n静态工具类,将基于 TSL 的视觉特效直接应用于对象的材质。适用于任何 `Object3D`(支持单个或数组),会自动遍历所有子网格。\n\n特性:\n- **效果可叠加**:高亮和呼吸效果可同时作用于同一对象,呼吸在高亮结果之上混合\n- **共享材质安全**:按材质跟踪引用计数,多个 Mesh 共享材质时互不干扰\n- **完整还原**:移除效果时自动恢复材质原始的 `colorNode`、`opacityNode`、`transparent` 和 `depthWrite` 状态\n\n### `MaterialEffects.highlightColor(object, options?)`\n\n为对象中所有网格应用颜色/透明度高亮。\n\n```typescript\nimport { MaterialEffects } from 'u-space';\n\n// 以 50% 透明度高亮为红色(叠加模式)\nMaterialEffects.highlightColor(myModel, {\n color: 0xff0000,\n opacity: 0.5,\n overwrite: false, // false = 叠加(相乘),true = 完全替换颜色\n});\n\n// 半透明效果\nMaterialEffects.highlightColor(myModel, { opacity: 0.3 });\n\n// X 光效果(替换颜色 + 关闭深度写入)\nMaterialEffects.highlightColor(myModel, {\n color: 0x0088ff,\n opacity: 0.25,\n overwrite: true,\n depthWrite: false,\n});\n\n// 支持数组\nMaterialEffects.highlightColor([model1, model2], { color: 0x00ff00 });\n```\n\n#### `HighlightColorOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :--------------------------------------------------------------------------- |\n| `color` | `ColorRepresentation` | `0xff0000` | 高亮颜色。 |\n| `opacity` | `number` | `0.5` | 高亮时材质的透明度。 |\n| `overwrite` | `boolean` | `false` | `false` = 与原始颜色相乘(叠加);`true` = 完全替换颜色。 |\n| `depthWrite` | `boolean` | — | 可选。设为 `false` 可产生 X 光透视效果。不设置时保持原始值。 |\n\n### `MaterialEffects.removeHighlightColor(object)`\n\n移除高亮效果。当对象上所有效果都被移除后,材质将完整恢复到原始状态。\n\n```typescript\nMaterialEffects.removeHighlightColor(myModel);\n```\n\n### `MaterialEffects.breatheColor(object, options?)`\n\n为对象应用呼吸灯效果,颜色在材质原色与目标颜色之间随时间脉冲变化。需要 `viewer.frameloop = 'always'`。\n\n```typescript\nMaterialEffects.breatheColor(myModel, {\n color: 0x00ff00,\n speed: 1.0,\n intensity: 2.0,\n});\nviewer.frameloop = 'always';\n```\n\n#### `BreatheColorOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :--------------------------------- |\n| `color` | `ColorRepresentation` | `0x00ff00` | 呼吸目标颜色。 |\n| `speed` | `number` | `1.0` | 振荡速度。 |\n| `intensity` | `number` | `2.0` | 控制峰值的锐度。 |\n\n### `MaterialEffects.removeBreatheColor(object)`\n\n移除呼吸效果。\n\n```typescript\nMaterialEffects.removeBreatheColor(myModel);\n```\n\n### `MaterialEffects.wireframe(object, enabled?)`\n\n开启或关闭线框渲染模式。\n\n```typescript\nMaterialEffects.wireframe(myModel); // 开启线框\nMaterialEffects.wireframe(myModel, false); // 关闭线框\nMaterialEffects.removeWireframe(myModel); // 等同于 wireframe(obj, false)\n```\n\n### `MaterialEffects.fadeIn(object, options?)` / `MaterialEffects.fadeOut(object, options?)`\n\n淡入/淡出动画效果。返回 `Promise`,在动画完成后 resolve。淡出后对象材质保持透明状态。\n\n```typescript\n// 淡出\nawait MaterialEffects.fadeOut(myModel, { duration: 1000 });\n\n// 淡入\nawait MaterialEffects.fadeIn(myModel, { duration: 500 });\n```\n\n> 动画期间需要持续渲染,建议配合 `viewer.frameloop = 'always'` 使用。\n\n#### `FadeOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :--------- | :------- | :----- | :------------------ |\n| `duration` | `number` | `500` | 动画时长(毫秒)。 |\n\n---\n\n## `TSLEffects`\n\n静态工厂类,返回 TSL 颜色节点。将返回值赋给 `NodeMaterial` 的 `material.colorNode` 即可应用动态着色器特效。持续动画需要 `viewer.frameloop = 'always'`。\n\n### `TSLEffects.flow(parameters?)`\n\n沿网格 UV X 轴方向的定向光扫效果,适用于道路、管道和流线。\n\n```typescript\nimport { TSLEffects } from 'u-space';\n\nmyTubeMesh.material.colorNode = TSLEffects.flow({\n baseColor: 0x001133,\n flowColor: 0x00aaff,\n speed: 1.5,\n scale: 4.0,\n intensity: 6.0,\n});\nviewer.frameloop = 'always';\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :------------------------------------------------ |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 背景/底色。 |\n| `flowColor` | `ColorRepresentation` | `0x00ff00` | 扫光高亮颜色。 |\n| `speed` | `number` | `1.0` | 动画速度(越高扫光越快)。 |\n| `scale` | `number` | `3.0` | 图案的空间频率。 |\n| `intensity` | `number` | `4.0` | 峰值锐度,值越高光束越细。 |\n\n### `TSLEffects.breathe(parameters?)`\n\n在两种颜色之间随时间振荡的脉冲发光效果,适合状态指示器和警报。\n\n```typescript\nmyMesh.material.colorNode = TSLEffects.breathe({\n baseColor: 0x333333,\n breathColor: 0x00ff88,\n speed: 2.0,\n intensity: 3.0,\n});\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------ | :-------------------- | :---------- | :--------------------------------- |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 低/静息状态的颜色。 |\n| `breathColor` | `ColorRepresentation` | `0x00ff00` | 峰值亮度时的颜色。 |\n| `speed` | `number` | `1.0` | 振荡速度。 |\n| `intensity` | `number` | `2.0` | 控制峰值的锐度。 |\n\n### `TSLEffects.fluid(parameters?)`\n\n噪声扭曲的流动效果,适用于水面、等离子体或有机流动材质。\n\n```typescript\nmyPlaneMesh.material.colorNode = TSLEffects.fluid({\n baseColor: 0x002244,\n flowColor: 0x0066ff,\n speed: 0.5,\n scale: 2.0,\n intensity: 1.5,\n distortion: 0.3,\n});\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :----------- | :-------------------- | :---------- | :-------------------------------------------- |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 基础颜色。 |\n| `flowColor` | `ColorRepresentation` | `0x0000ff` | 流体高亮颜色。 |\n| `speed` | `number` | `1.0` | 动画速度。 |\n| `scale` | `number` | `1.0` | 噪声图案的 UV 缩放比例。 |\n| `intensity` | `number` | `1.0` | 流体图案的锐度。 |\n| `distortion` | `number` | `0.5` | 采样前噪声对 UV 的扭曲程度。 |\n"
176
+ "content": "# Effects API\n\n`u-space` 提供了两个基于 Three.js 着色语言(TSL/WebGPU 节点)的静态特效工具:`MaterialEffects` 用于为对象应用高亮、呼吸等材质特效,`TSLEffects` 用于生成动态颜色节点模式。\n\n## `MaterialEffects`\n\n静态工具类,将基于 TSL 的视觉特效直接应用于对象的材质。适用于任何 `Object3D`(支持单个或数组),会自动遍历所有子网格。\n当对象是 `SemanticInstanceObject`(例如 `SceneInstanceObject`、`FacilityInstanceObject` 或楼层里的 `FloorSemanticInstanceObject`)时,`highlightColor()` / `removeHighlightColor()` 会通过 `setSemanticHighlight()` / `clearSemanticHighlight()` 改写该语义实例的颜色和透明度,而不是改动共享 batch 材质。\n`SemanticInstanceObject` 支持 `overwrite` 的替换/染色语义;`depthWrite` 属于共享 batch 材质状态,不能按单个实例设置,因此对该类对象不会生效。\n\n特性:\n- **效果可叠加**:高亮和呼吸效果可同时作用于同一对象,呼吸在高亮结果之上混合\n- **共享材质安全**:按材质跟踪引用计数,多个 Mesh 共享材质时互不干扰\n- **完整还原**:移除效果时自动恢复材质原始的 `colorNode`、`opacityNode`、`transparent` 和 `depthWrite` 状态\n\n### `MaterialEffects.highlightColor(object, options?)`\n\n为对象中所有网格应用颜色/透明度高亮。\n\n```typescript\nimport { MaterialEffects } from 'u-space';\n\n// 以 50% 透明度高亮为红色(叠加模式)\nMaterialEffects.highlightColor(myModel, {\n color: 0xff0000,\n opacity: 0.5,\n overwrite: false, // false = 叠加(相乘),true = 完全替换颜色\n});\n\n// 半透明效果\nMaterialEffects.highlightColor(myModel, { opacity: 0.3 });\n\n// X 光效果(替换颜色 + 关闭深度写入)\nMaterialEffects.highlightColor(myModel, {\n color: 0x0088ff,\n opacity: 0.25,\n overwrite: true,\n depthWrite: false,\n});\n\n// 支持数组\nMaterialEffects.highlightColor([model1, model2], { color: 0x00ff00 });\n```\n\n#### `HighlightColorOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :--------------------------------------------------------------------------- |\n| `color` | `ColorRepresentation` | `0xff0000` | 高亮颜色。 |\n| `opacity` | `number` | `0.5` | 高亮时材质的透明度。 |\n| `overwrite` | `boolean` | `false` | `false` = 与原始颜色相乘(叠加);`true` = 完全替换颜色。 |\n| `depthWrite` | `boolean` | — | 可选。设为 `false` 可产生 X 光透视效果。不设置时保持原始值。 |\n| `multiplyOpacity` | `boolean` | `false` | 可选。设为 `true` 时高亮透明度会与材质原始透明度相乘,主要用于语义 fallback 模型内部。 |\n\n### `MaterialEffects.removeHighlightColor(object)`\n\n移除高亮效果。当对象上所有效果都被移除后,材质将完整恢复到原始状态。\n\n```typescript\nMaterialEffects.removeHighlightColor(myModel);\n```\n\n### `MaterialEffects.breatheColor(object, options?)`\n\n为对象应用呼吸灯效果,颜色在材质原色与目标颜色之间随时间脉冲变化。需要 `viewer.frameloop = 'always'`。\n\n```typescript\nMaterialEffects.breatheColor(myModel, {\n color: 0x00ff00,\n speed: 1.0,\n intensity: 2.0,\n});\nviewer.frameloop = 'always';\n```\n\n#### `BreatheColorOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :--------------------------------- |\n| `color` | `ColorRepresentation` | `0x00ff00` | 呼吸目标颜色。 |\n| `speed` | `number` | `1.0` | 振荡速度。 |\n| `intensity` | `number` | `2.0` | 控制峰值的锐度。 |\n\n### `MaterialEffects.removeBreatheColor(object)`\n\n移除呼吸效果。\n\n```typescript\nMaterialEffects.removeBreatheColor(myModel);\n```\n\n### `MaterialEffects.wireframe(object, enabled?)`\n\n开启或关闭线框渲染模式。\n\n```typescript\nMaterialEffects.wireframe(myModel); // 开启线框\nMaterialEffects.wireframe(myModel, false); // 关闭线框\nMaterialEffects.removeWireframe(myModel); // 等同于 wireframe(obj, false)\n```\n\n### `MaterialEffects.fadeIn(object, options?)` / `MaterialEffects.fadeOut(object, options?)`\n\n淡入/淡出动画效果。返回 `Promise`,在动画完成后 resolve。淡出后对象材质保持透明状态。\n\n```typescript\n// 淡出\nawait MaterialEffects.fadeOut(myModel, { duration: 1000 });\n\n// 淡入\nawait MaterialEffects.fadeIn(myModel, { duration: 500 });\n```\n\n> 动画期间需要持续渲染,建议配合 `viewer.frameloop = 'always'` 使用。\n\n#### `FadeOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :--------- | :------- | :----- | :------------------ |\n| `duration` | `number` | `500` | 动画时长(毫秒)。 |\n\n---\n\n## `TSLEffects`\n\n静态工厂类,返回 TSL 颜色节点。将返回值赋给 `NodeMaterial` 的 `material.colorNode` 即可应用动态着色器特效。持续动画需要 `viewer.frameloop = 'always'`。\n\n### `TSLEffects.flow(parameters?)`\n\n沿网格 UV X 轴方向的定向光扫效果,适用于道路、管道和流线。\n\n```typescript\nimport { TSLEffects } from 'u-space';\n\nmyTubeMesh.material.colorNode = TSLEffects.flow({\n baseColor: 0x001133,\n flowColor: 0x00aaff,\n speed: 1.5,\n scale: 4.0,\n intensity: 6.0,\n});\nviewer.frameloop = 'always';\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :---------- | :------------------------------------------------ |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 背景/底色。 |\n| `flowColor` | `ColorRepresentation` | `0x00ff00` | 扫光高亮颜色。 |\n| `speed` | `number` | `1.0` | 动画速度(越高扫光越快)。 |\n| `scale` | `number` | `3.0` | 图案的空间频率。 |\n| `intensity` | `number` | `4.0` | 峰值锐度,值越高光束越细。 |\n\n### `TSLEffects.breathe(parameters?)`\n\n在两种颜色之间随时间振荡的脉冲发光效果,适合状态指示器和警报。\n\n```typescript\nmyMesh.material.colorNode = TSLEffects.breathe({\n baseColor: 0x333333,\n breathColor: 0x00ff88,\n speed: 2.0,\n intensity: 3.0,\n});\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------ | :-------------------- | :---------- | :--------------------------------- |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 低/静息状态的颜色。 |\n| `breathColor` | `ColorRepresentation` | `0x00ff00` | 峰值亮度时的颜色。 |\n| `speed` | `number` | `1.0` | 振荡速度。 |\n| `intensity` | `number` | `2.0` | 控制峰值的锐度。 |\n\n### `TSLEffects.fluid(parameters?)`\n\n噪声扭曲的流动效果,适用于水面、等离子体或有机流动材质。\n\n```typescript\nmyPlaneMesh.material.colorNode = TSLEffects.fluid({\n baseColor: 0x002244,\n flowColor: 0x0066ff,\n speed: 0.5,\n scale: 2.0,\n intensity: 1.5,\n distortion: 0.3,\n});\n```\n\n**参数:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :----------- | :-------------------- | :---------- | :-------------------------------------------- |\n| `baseColor` | `ColorRepresentation` | `0xffffff` | 基础颜色。 |\n| `flowColor` | `ColorRepresentation` | `0x0000ff` | 流体高亮颜色。 |\n| `speed` | `number` | `1.0` | 动画速度。 |\n| `scale` | `number` | `1.0` | 噪声图案的 UV 缩放比例。 |\n| `intensity` | `number` | `1.0` | 流体图案的锐度。 |\n| `distortion` | `number` | `0.5` | 采样前噪声对 UV 的扭曲程度。 |\n"
177
177
  },
178
178
  {
179
179
  "id": "api-interactions",
@@ -290,7 +290,7 @@ export const docsIndex = [
290
290
  "text": "dispose()"
291
291
  }
292
292
  ],
293
- "content": "# Interactions API\n\n`InteractionManager` 提供了一种统一的方式来处理 3D 场景中的用户输入(鼠标、触摸、指针)。它将屏幕空间的射线检测转换为世界空间坐标,并将对应事件直接分发到被命中的 3D 对象上。\n\n`InteractionManager` 在 `Viewer` 内部自动实例化,可通过 `viewer.interactionManager` 访问。\n\n## 启用交互事件\n\n出于性能考虑,指针移动事件默认处于禁用状态。如需悬停和拖拽效果,必须显式开启。\n\n```typescript\n// 启用鼠标移动事件(如 pointerenter 和 pointerleave)\nviewer.interactionManager.pointerMoveEventsEnabled = true;\n```\n\n### 目标对象\n\n可以限制射线检测所针对的对象范围。默认值为 `scene.children`(即整个场景的直接子级,含递归嵌套)。\n\n```typescript\n// 仅检测指定对象\nviewer.interactionManager.targetObjects = [myBox, myModel];\n\n// 恢复默认:检测整个场景\nviewer.interactionManager.targetObjects = viewer.scene.children;\n```\n\n## 添加事件监听\n\n由于 `u-space` 对象(以及继承自 `BaseMesh`、`BaseGroup` 的对象)支持自定义事件,你可以像操作 DOM 元素一样原生地绑定监听器。\n\n```typescript\nconst myBox = new Mesh(geometry, material);\nviewer.scene.add(myBox);\n\n// 直接在 Mesh 或 Model 上绑定监听器\nmyBox.addEventListener('click', (eventData) => {\n // 底层指针事件和射线检测数据\n const intersect = eventData.event.intersect;\n\n console.log('点击位置:', intersect.point);\n});\n```\n\n## 支持的事件类型\n\n以下事件类型可在可交互对象上监听:\n\n- `click`:指针点击对象时触发。内置智能过滤:长按(>500ms)或移动距离过大时忽略,双击时不重复触发。\n- `dblclick`:快速双击对象时触发。\n- `rightclick`:右键短按松开时触发(长按或拖拽不触发;浏览器原生上下文菜单已被阻止)。在 `pointerup` 时派发,因此可以正确过滤相机拖拽等操作。\n- `pointerdown`:指针按键在对象上按下时触发。\n- `pointerup`:指针按键在对象上释放时触发。\n- `pointermove`:指针在对象上移动时触发,需要 `pointerMoveEventsEnabled = true`。\n- `pointerenter`:光标进入对象范围时触发,需要 `pointerMoveEventsEnabled = true`。\n- `pointerleave`:光标离开对象范围时触发,需要 `pointerMoveEventsEnabled = true`。\n\n### 事件冒泡\n\n事件会沿父级链向上冒泡。若要阻止事件继续传播,可调用事件载荷上的 `stopPropagation()`:\n\n```typescript\nmyObject.addEventListener('click', (e) => {\n e.event.stopPropagation();\n});\n```\n\n## `InteractionEvent`\n\n传递给所有监听回调的事件对象,位于 `event` 键下。\n\n### 属性\n\n| 属性 | 类型 | 说明 |\n| :-------------- | :----------------------------------------- | :-------------------------------------------------------------------------- |\n| `type` | `InteractionEventType` | 事件类型字符串(如 `'click'`)。 |\n| `target` | `Object3D` | 触发事件的原始 3D 对象(第一个命中点)。 |\n| `currentTarget` | `Object3D` | 冒泡链中当前处理事件的对象。 |\n| `intersect` | `Intersection \\| null` | Three.js 射线检测数据:`point`、`face`、`distance`、`uv` 等。 |\n| `originalEvent` | `PointerEvent \\| MouseEvent` | 原始 DOM 指针/鼠标事件。 |\n\n### 方法\n\n#### `stopPropagation()`\n\n阻止事件继续向上冒泡。\n\n## `InteractionManager` API\n\n### 属性\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------------------- | :---------------------------- | :---------------- | :--------------------------------------------------------- |\n| `targetObjects` | `Object3D[]` | `scene.children` | 射线检测的目标对象列表,默认为场景的直接子级。 |\n| `pointerMoveEventsEnabled` | `boolean` | `false` | 启用 `pointermove`、`pointerenter`、`pointerleave` 事件。 |\n\n### 方法\n\n#### `enable()` / `disable()`\n\n全局启用或禁用所有交互事件。禁用后不再触发任何交互事件。\n\n```typescript\nviewer.interactionManager.disable(); // 暂停交互\nviewer.interactionManager.enable(); // 恢复交互\n```\n\n#### `setInteractable(object, interactable)`\n\n控制单个对象是否可交互。设为 `false` 后该对象及其所有子对象不再参与射线检测。\n\n```typescript\nviewer.interactionManager.setInteractable(myModel, false); // 禁止交互\nviewer.interactionManager.setInteractable(myModel, true); // 恢复交互\n```\n\n#### `addIgnore(object)` / `removeIgnore(object)`\n\n`setInteractable` 的别名。`addIgnore(obj)` 等同于 `setInteractable(obj, false)`,`removeIgnore(obj)` 等同于 `setInteractable(obj, true)`。\n\n```typescript\nviewer.interactionManager.addIgnore(helperObject); // 忽略辅助对象\nviewer.interactionManager.removeIgnore(helperObject); // 恢复\n```\n\n#### `setCamera(camera)`\n\n更新用于射线检测的相机。由 `viewer.setCamera()` 自动调用。\n\n#### `dispose()`\n\n移除所有 DOM 事件监听,清理内部状态。\n\n```typescript\nviewer.interactionManager.dispose();\n```\n\n---\n\n## Selection\n\n`Selection` 提供对象选择能力,包括单选、多选、toggle 和框选(rubber-band)。\n\n```typescript\nimport { Selection } from 'u-space';\n\nconst selection = new Selection(viewer.renderer.domElement, viewer.scene, viewer.camera);\n```\n\n### 基础选择\n\n```typescript\nselection.select(myObject); // 选中\nselection.select([obj1, obj2]); // 多选\nselection.deselect(myObject); // 取消选择\nselection.toggle(myObject); // 切换选择状态\nselection.clear(); // 清空选择\nselection.isSelected(myObject); // 检查是否已选\n```\n\n### 属性\n\n| 属性 | 类型 | 说明 |\n| :-------------- | :-------------- | :---------------------------------- |\n| `selected` | `Set<Object3D>` | 当前已选对象集合。 |\n| `selectedArray` | `Object3D[]` | 当前已选对象数组。 |\n| `targetObjects` | `Object3D[]` | 框选时的候选对象(默认为场景子级)。 |\n\n### 框选\n\n启用后可用鼠标拖动矩形区域选择多个对象。框选覆盖层会渲染在容器元素上。\n\n```typescript\nselection.enableBoxSelection({ deep: true }); // 开启框选\nselection.disableBoxSelection(); // 关闭框选\n```\n\n#### `BoxSelectionOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------- | :----- | :------------------------------ |\n| `className` | `string` | — | 框选矩形的 CSS 类名。 |\n| `deep` | `boolean` | `true` | 是否递归检测子对象。 |\n\n### 事件\n\n```typescript\nselection.addEventListener('select', (e) => {\n console.log('新选中:', e.objects);\n});\n\nselection.addEventListener('deselect', (e) => {\n console.log('取消选中:', e.objects);\n});\n\nselection.addEventListener('change', (e) => {\n console.log('当前选中:', e.selected.size, '个对象');\n});\n```\n\n### 方法\n\n#### `setCamera(camera)`\n\n更新用于框选投影计算的相机。切换相机时需调用。\n\n#### `dispose()`\n\n关闭框选、移除事件监听、清空选择集。\n"
293
+ "content": "# Interactions API\n\n`InteractionManager` 提供了一种统一的方式来处理 3D 场景中的用户输入(鼠标、触摸、指针)。它将屏幕空间的射线检测转换为世界空间坐标,并将对应事件直接分发到被命中的 3D 对象上。\n\n`InteractionManager` 在 `Viewer` 内部自动实例化,可通过 `viewer.interactionManager` 访问。\n\n## 启用交互事件\n\n出于性能考虑,指针移动事件默认处于禁用状态。如需悬停和拖拽效果,必须显式开启。\n\n```typescript\n// 启用鼠标移动事件(如 pointerenter 和 pointerleave)\nviewer.interactionManager.pointerMoveEventsEnabled = true;\n```\n\n### 目标对象\n\n可以限制射线检测所针对的对象范围。默认值为 `scene.children`(即整个场景的直接子级,含递归嵌套)。\n`BaseMesh` / `BaseGroup` 默认会在自身 `visible === false` 时让 `raycast()` 返回 `false`,从而阻止自身和子级继续参与递归射线检测;如需隐藏但仍可交互,可将对象的 `ignoreInvisibleWhenRaycast` 设为 `false`。`setInteractable(object, false)` / `addIgnore(object)` 会在命中后过滤该对象及其子对象。\n\n```typescript\n// 仅检测指定对象\nviewer.interactionManager.targetObjects = [myBox, myModel];\n\n// 恢复默认:检测整个场景\nviewer.interactionManager.targetObjects = viewer.scene.children;\n```\n\n## 添加事件监听\n\n由于 `u-space` 对象(以及继承自 `BaseMesh`、`BaseGroup` 的对象)支持自定义事件,你可以像操作 DOM 元素一样原生地绑定监听器。\n\n```typescript\nconst myBox = new Mesh(geometry, material);\nviewer.scene.add(myBox);\n\n// 直接在 Mesh 或 Model 上绑定监听器\nmyBox.addEventListener('click', (eventData) => {\n // 底层指针事件和射线检测数据\n const intersect = eventData.event.intersect;\n\n console.log('点击位置:', intersect.point);\n});\n```\n\n## 支持的事件类型\n\n以下事件类型可在可交互对象上监听:\n\n- `click`:指针点击对象时触发。内置智能过滤:长按(>500ms)或移动距离过大时忽略,双击时不重复触发。\n- `dblclick`:快速双击对象时触发。\n- `rightclick`:右键短按松开时触发(长按或拖拽不触发;浏览器原生上下文菜单已被阻止)。在 `pointerup` 时派发,因此可以正确过滤相机拖拽等操作。\n- `pointerdown`:指针按键在对象上按下时触发。\n- `pointerup`:指针按键在对象上释放时触发。\n- `pointermove`:指针在对象上移动时触发,需要 `pointerMoveEventsEnabled = true`。\n- `pointerenter`:光标进入对象范围时触发,需要 `pointerMoveEventsEnabled = true`。\n- `pointerleave`:光标离开对象范围时触发,需要 `pointerMoveEventsEnabled = true`。\n\n### 事件冒泡\n\n事件会沿父级链向上冒泡。若要阻止事件继续传播,可调用事件载荷上的 `stopPropagation()`:\n\n```typescript\nmyObject.addEventListener('click', (e) => {\n e.event.stopPropagation();\n});\n```\n\n## `InteractionEvent`\n\n传递给所有监听回调的事件对象,位于 `event` 键下。\n\n### 属性\n\n| 属性 | 类型 | 说明 |\n| :-------------- | :----------------------------------------- | :-------------------------------------------------------------------------- |\n| `type` | `InteractionEventType` | 事件类型字符串(如 `'click'`)。 |\n| `target` | `Object3D` | 触发事件的原始 3D 对象(第一个命中点)。 |\n| `currentTarget` | `Object3D` | 冒泡链中当前处理事件的对象。 |\n| `intersect` | `Intersection \\| null` | Three.js 射线检测数据:`point`、`face`、`distance`、`uv` 等。 |\n| `originalEvent` | `PointerEvent \\| MouseEvent` | 原始 DOM 指针/鼠标事件。 |\n\n### 方法\n\n#### `stopPropagation()`\n\n阻止事件继续向上冒泡。\n\n## `InteractionManager` API\n\n### 属性\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------------------- | :---------------------------- | :---------------- | :--------------------------------------------------------- |\n| `targetObjects` | `Object3D[]` | `scene.children` | 射线检测的目标对象列表,默认为场景的直接子级。 |\n| `pointerMoveEventsEnabled` | `boolean` | `false` | 启用 `pointermove`、`pointerenter`、`pointerleave` 事件。 |\n\n### 方法\n\n#### `enable()` / `disable()`\n\n全局启用或禁用所有交互事件。禁用后不再触发任何交互事件。\n\n```typescript\nviewer.interactionManager.disable(); // 暂停交互\nviewer.interactionManager.enable(); // 恢复交互\n```\n\n#### `setInteractable(object, interactable)`\n\n控制单个对象是否可交互。设为 `false` 后该对象及其所有子对象不再参与射线检测。\n\n```typescript\nviewer.interactionManager.setInteractable(myModel, false); // 禁止交互\nviewer.interactionManager.setInteractable(myModel, true); // 恢复交互\n```\n\n#### `addIgnore(object)` / `removeIgnore(object)`\n\n`setInteractable` 的别名。`addIgnore(obj)` 等同于 `setInteractable(obj, false)`,`removeIgnore(obj)` 等同于 `setInteractable(obj, true)`。\n\n```typescript\nviewer.interactionManager.addIgnore(helperObject); // 忽略辅助对象\nviewer.interactionManager.removeIgnore(helperObject); // 恢复\n```\n\n#### `setCamera(camera)`\n\n更新用于射线检测的相机。由 `viewer.setCamera()` 自动调用。\n\n#### `dispose()`\n\n移除所有 DOM 事件监听,清理内部状态。\n\n```typescript\nviewer.interactionManager.dispose();\n```\n\n---\n\n## Selection\n\n`Selection` 提供对象选择能力,包括单选、多选、toggle 和框选(rubber-band)。\n\n```typescript\nimport { Selection } from 'u-space';\n\nconst selection = new Selection(viewer.renderer.domElement, viewer.scene, viewer.camera);\n```\n\n### 基础选择\n\n```typescript\nselection.select(myObject); // 选中\nselection.select([obj1, obj2]); // 多选\nselection.deselect(myObject); // 取消选择\nselection.toggle(myObject); // 切换选择状态\nselection.clear(); // 清空选择\nselection.isSelected(myObject); // 检查是否已选\n```\n\n### 属性\n\n| 属性 | 类型 | 说明 |\n| :-------------- | :-------------- | :---------------------------------- |\n| `selected` | `Set<Object3D>` | 当前已选对象集合。 |\n| `selectedArray` | `Object3D[]` | 当前已选对象数组。 |\n| `targetObjects` | `Object3D[]` | 框选时的候选对象(默认为场景子级)。 |\n\n### 框选\n\n启用后可用鼠标拖动矩形区域选择多个对象。框选覆盖层会渲染在容器元素上。\n\n```typescript\nselection.enableBoxSelection({ deep: true }); // 开启框选\nselection.disableBoxSelection(); // 关闭框选\n```\n\n#### `BoxSelectionOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------- | :----- | :------------------------------ |\n| `className` | `string` | — | 框选矩形的 CSS 类名。 |\n| `deep` | `boolean` | `true` | 是否递归检测子对象。 |\n\n### 事件\n\n```typescript\nselection.addEventListener('select', (e) => {\n console.log('新选中:', e.objects);\n});\n\nselection.addEventListener('deselect', (e) => {\n console.log('取消选中:', e.objects);\n});\n\nselection.addEventListener('change', (e) => {\n console.log('当前选中:', e.selected.size, '个对象');\n});\n```\n\n### 方法\n\n#### `setCamera(camera)`\n\n更新用于框选投影计算的相机。切换相机时需调用。\n\n#### `dispose()`\n\n关闭框选、移除事件监听、清空选择集。\n"
294
294
  },
295
295
  {
296
296
  "id": "api-managers",
@@ -447,7 +447,7 @@ export const docsIndex = [
447
447
  "text": "管理"
448
448
  }
449
449
  ],
450
- "content": "# Managers API\n\n`u-space` 使用专用管理器来处理特定领域的逻辑,例如用于缓存和注册 3D 对象的 `ObjectManager`。\n\n## ObjectManager\n\n`ObjectManager` 提供了一个集中式字典/映射层,让你无需递归遍历 Three.js 场景图,就能通过字符串 ID 或字符串名称轻松检索复杂模型或特定网格。\n\n默认实例可通过 `viewer.objectManager` 访问。\n\n### 添加对象\n\n向管理器添加对象时,必须提供唯一标识符。\n\n```typescript\nconst myModel = new Model();\n// ... 加载逻辑\n\n// 用指定的唯一 ID 添加\nviewer.objectManager.add('my-unique-car-id', myModel);\n\n// 一个对象可以注册多个 ID\nviewer.objectManager.add('player-vehicle', myModel);\n```\n\n### 检索对象\n\n管理器提供快速访问对象的方法。\n\n#### `getById(id: string)`\n\n精确检索与指定 ID 匹配的一个对象(或 `undefined`)。\n\n```typescript\nconst car = viewer.objectManager.getById('my-unique-car-id');\n```\n\n#### `getByName(name: string)`\n\n由于 Three.js 对象可以共享同一个 `.name` 属性,此方法返回一个 `Set<Object3D>`,包含所有与指定名称匹配的已注册对象。\n\n```typescript\n// 假设 myModel.name = 'sedan'\nconst sedans = viewer.objectManager.getByName('sedan');\n\nsedans.forEach((vehicle) => {\n vehicle.position.y += 10;\n});\n```\n\n#### `getByType(type: string)`\n\n返回一个 `Set<Object3D>`,包含所有 `object.type` 与指定类型匹配的已注册对象。\n\n```typescript\nconst models = viewer.objectManager.getByType('Model');\n```\n\n#### `getObjectIds(object: Object3D)`\n\n返回给定对象已注册的所有 ID 的 `Set<string>`。\n\n```typescript\nconst ids = viewer.objectManager.getObjectIds(myModel);\n```\n\n### 移除对象\n\n#### `remove(object: Object3D)`\n\n从所有内部映射中移除该对象及其所有关联 ID。\n\n```typescript\nviewer.objectManager.remove(myModel);\n```\n\n#### `removeById(id: string)`\n\n移除注册在指定 ID 下的对象。\n\n```typescript\nviewer.objectManager.removeById('my-unique-car-id');\n```\n\n#### `removeByName(name: string)`\n\n移除所有具有指定 `.name` 的对象。\n\n```typescript\nviewer.objectManager.removeByName('sedan');\n```\n\n#### `removeByType(type: string)`\n\n移除所有具有指定 `.type` 的对象。\n\n```typescript\nviewer.objectManager.removeByType('Model');\n```\n\n### 显隐控制\n\n#### `show(id: string)` / `hide(id: string)`\n\n控制对象的可见性。\n\n```typescript\nviewer.objectManager.hide('car-01');\nviewer.objectManager.show('car-01');\n```\n\n#### `isolate(ids: string[])`\n\n孤立显示:仅显示指定 ID 的对象,隐藏其余所有。\n\n```typescript\nviewer.objectManager.isolate(['car-01', 'car-02']);\n```\n\n#### `showAll()`\n\n恢复显示所有已管理对象。\n\n```typescript\nviewer.objectManager.showAll();\n```\n\n### 材质操作\n\n#### `setOpacity(id: string, opacity: number)`\n\n设置指定对象所有材质的透明度。\n\n```typescript\nviewer.objectManager.setOpacity('building-01', 0.3);\nviewer.objectManager.setOpacity('building-01', 1.0); // 恢复不透明\n```\n\n### 空间查询\n\n#### `getBoundingBox(id?: string)`\n\n获取指定对象的包围盒,不传 `id` 则返回所有已管理对象的包围盒。\n\n```typescript\nconst box = viewer.objectManager.getBoundingBox('car-01');\nconst allBox = viewer.objectManager.getBoundingBox(); // 全部对象\n```\n\n### 遍历与过滤\n\n#### `forEach(callback)`\n\n遍历所有已管理对象。\n\n```typescript\nviewer.objectManager.forEach((object, ids) => {\n console.log(`对象: ${object.name}, IDs: ${Array.from(ids).join(', ')}`);\n});\n```\n\n#### `filter(predicate)`\n\n按条件过滤对象,返回匹配的数组。\n\n```typescript\nconst cars = viewer.objectManager.filter((obj) => obj.name.startsWith('car'));\n```\n\n### 工具方法\n\n- `getAll()`:返回所有已跟踪对象的 `Set<Object3D>`。\n- `clear()`:从所有内部映射中移除所有对象。\n- `size`:返回当前管理器跟踪的唯一对象总数。\n\n---\n\n## SceneManager\n\n`SceneManager` 用于管理多个场景的创建、注册、切换和序列化。\n\n```typescript\nimport { SceneManager } from 'u-space';\n\nconst sceneManager = new SceneManager();\n```\n\n### 方法\n\n#### `create(key, options?)`\n\n创建并注册一个新场景。\n\n```typescript\nconst scene = sceneManager.create('indoor', { background: 0x333333 });\n```\n\n#### `add(key, scene)` / `get(key)` / `remove(key)`\n\n手动注册、获取或移除场景。\n\n```typescript\nsceneManager.add('outdoor', existingScene);\nconst scene = sceneManager.get('outdoor');\nsceneManager.remove('outdoor');\n```\n\n#### `serialize(key)`\n\n将场景元数据序列化为 JSON 快照。\n\n```typescript\nconst snapshot = sceneManager.serialize('indoor');\n// { name, background, environmentRotation, children }\n```\n\n#### `keys()` / `size` / `clear()`\n\n列出所有场景 key、获取场景数量或清空。\n\n---\n\n## LightManager\n\n`LightManager` 提供灯光的便捷创建、预设和 Helper 可视化。\n\n```typescript\nimport { LightManager } from 'u-space';\n\nconst lightManager = new LightManager(viewer.scene);\n```\n\n### 灯光创建\n\n```typescript\nlightManager.addAmbient('ambient', { color: 0xffffff, intensity: 0.5 });\nlightManager.addDirectional('sun', { position: { x: 5, y: 10, z: 5 }, castShadow: true });\nlightManager.addPoint('bulb', { position: { x: 0, y: 3, z: 0 }, intensity: 2 });\nlightManager.addSpot('spot', { position: { x: 0, y: 10, z: 0 }, angle: Math.PI / 6 });\nlightManager.addHemisphere('hemi', { skyColor: 0x87ceeb, groundColor: 0x362907 });\n```\n\n### 灯光预设\n\n一键应用常见场景的灯光配置:\n\n```typescript\nlightManager.applyPreset('indoor'); // 室内:环境光 + 顶部点光源\nlightManager.applyPreset('outdoor'); // 室外:半球光 + 方向光(阳光)\nlightManager.applyPreset('studio'); // 摄影棚:三点布光\nlightManager.applyPreset('warehouse'); // 仓库:多点光源照明\n```\n\n| 预设 | 配置 |\n| :---------- | :-------------------------------------- |\n| `indoor` | 环境光 + 2 个点光源 |\n| `outdoor` | 半球光 + 方向光(带阴影) |\n| `studio` | 环境光 + 主光 + 补光 + 轮廓光 |\n| `warehouse` | 环境光 + 4 个点光源(四角分布) |\n\n### Helper 可视化\n\n```typescript\nlightManager.showHelper('sun'); // 显示单个灯光 Helper(默认 size=5, color=0xff0000)\nlightManager.showHelper('sun', 2, 0x00ff00); // 自定义尺寸和颜色\nlightManager.showAllHelpers(); // 显示所有灯光 Helper\nlightManager.hideHelper('sun'); // 隐藏单个\nlightManager.hideAllHelpers(); // 隐藏所有\n```\n\n#### `showHelper(id, size?, color?)`\n\n| 参数 | 类型 | 默认值 | 说明 |\n| :------ | :-------------------- | :---------- | :---------------- |\n| `id` | `string` | — | 灯光 ID。 |\n| `size` | `number` | `5` | Helper 尺寸。 |\n| `color` | `ColorRepresentation` | `0xff0000` | Helper 颜色。 |\n\n### 管理\n\n```typescript\nlightManager.get('sun'); // 获取灯光\nlightManager.remove('sun'); // 移除灯光\nlightManager.removeAll(); // 移除所有\nlightManager.dispose(); // 清理\n```\n"
450
+ "content": "# Managers API\n\n`u-space` 使用专用管理器来处理特定领域的逻辑,例如用于缓存和注册 3D 对象的 `ObjectManager`。\n\n## ObjectManager\n\n`ObjectManager` 提供了一个集中式字典/映射层,让你无需递归遍历 Three.js 场景图,就能通过字符串 ID 或字符串名称轻松检索复杂模型或特定网格。\n\n默认实例可通过 `viewer.objectManager` 访问。\n\n### 添加对象\n\n向管理器添加对象时,必须提供唯一标识符。\n\n```typescript\nconst myModel = new Model();\n// ... 加载逻辑\n\n// 用指定的唯一 ID 添加\nviewer.objectManager.add('my-unique-car-id', myModel);\n\n// 一个对象可以注册多个 ID\nviewer.objectManager.add('player-vehicle', myModel);\n```\n\n### 检索对象\n\n管理器提供快速访问对象的方法。\n\n#### `getById(id: string)`\n\n精确检索与指定 ID 匹配的一个对象(或 `undefined`)。\n\n```typescript\nconst car = viewer.objectManager.getById('my-unique-car-id');\n```\n\n#### `getByName(name: string)`\n\n由于 Three.js 对象可以共享同一个 `.name` 属性,此方法返回一个 `Set<Object3D>`,包含所有与指定名称匹配的已注册对象。\n\n```typescript\n// 假设 myModel.name = 'sedan'\nconst sedans = viewer.objectManager.getByName('sedan');\n\nsedans.forEach((vehicle) => {\n vehicle.position.y += 10;\n});\n```\n\n#### `getByType(type: string)`\n\n返回一个 `Set<Object3D>`,包含所有 `object.type` 与指定类型匹配的已注册对象。\n\n```typescript\nconst models = viewer.objectManager.getByType('Model');\n```\n\n#### `getObjectIds(object: Object3D)`\n\n返回给定对象已注册的所有 ID 的 `Set<string>`。\n\n```typescript\nconst ids = viewer.objectManager.getObjectIds(myModel);\n```\n\n### 移除对象\n\n#### `remove(object: Object3D)`\n\n从所有内部映射中移除该对象及其所有关联 ID。\n\n```typescript\nviewer.objectManager.remove(myModel);\n```\n\n#### `removeById(id: string)`\n\n移除注册在指定 ID 下的对象。\n\n```typescript\nviewer.objectManager.removeById('my-unique-car-id');\n```\n\n#### `removeByName(name: string)`\n\n移除所有具有指定 `.name` 的对象。\n\n```typescript\nviewer.objectManager.removeByName('sedan');\n```\n\n#### `removeByType(type: string)`\n\n移除所有具有指定 `.type` 的对象。\n\n```typescript\nviewer.objectManager.removeByType('Model');\n```\n\n### 显隐控制\n\n#### `show(id: string)` / `hide(id: string)`\n\n控制对象的可见性。\n\n```typescript\nviewer.objectManager.hide('car-01');\nviewer.objectManager.show('car-01');\n```\n\n#### `isolate(ids: string[])`\n\n孤立显示:仅显示指定 ID 的对象,隐藏其余所有。\n\n```typescript\nviewer.objectManager.isolate(['car-01', 'car-02']);\n```\n\n#### `showAll()`\n\n恢复显示所有已管理对象。\n\n```typescript\nviewer.objectManager.showAll();\n```\n\n### 材质操作\n\n#### `setOpacity(id: string, opacity: number)`\n\n设置指定对象所有材质的透明度。对于 `SemanticInstanceObject`(例如 `SceneInstanceObject`、`FacilityInstanceObject` 或 `FloorSemanticInstanceObject`),会调用 `setSemanticOpacity()` 写入该实例的透明度,而不会影响同一模型 path 或同一楼层内的其他实例。\n\n```typescript\nviewer.objectManager.setOpacity('building-01', 0.3);\nviewer.objectManager.setOpacity('building-01', 1.0); // 恢复不透明\n```\n\n### 空间查询\n\n#### `getBoundingBox(id?: string)`\n\n获取指定对象的包围盒,不传 `id` 则返回所有已管理对象的包围盒。\n\n```typescript\nconst box = viewer.objectManager.getBoundingBox('car-01');\nconst allBox = viewer.objectManager.getBoundingBox(); // 全部对象\n```\n\n### 遍历与过滤\n\n#### `forEach(callback)`\n\n遍历所有已管理对象。\n\n```typescript\nviewer.objectManager.forEach((object, ids) => {\n console.log(`对象: ${object.name}, IDs: ${Array.from(ids).join(', ')}`);\n});\n```\n\n#### `filter(predicate)`\n\n按条件过滤对象,返回匹配的数组。\n\n```typescript\nconst cars = viewer.objectManager.filter((obj) => obj.name.startsWith('car'));\n```\n\n### 工具方法\n\n- `getAll()`:返回所有已跟踪对象的 `Set<Object3D>`。\n- `clear()`:从所有内部映射中移除所有对象。\n- `size`:返回当前管理器跟踪的唯一对象总数。\n\n---\n\n## SceneManager\n\n`SceneManager` 用于管理多个场景的创建、注册、切换和序列化。\n\n```typescript\nimport { SceneManager } from 'u-space';\n\nconst sceneManager = new SceneManager();\n```\n\n### 方法\n\n#### `create(key, options?)`\n\n创建并注册一个新场景。\n\n```typescript\nconst scene = sceneManager.create('indoor', { background: 0x333333 });\n```\n\n#### `add(key, scene)` / `get(key)` / `remove(key)`\n\n手动注册、获取或移除场景。\n\n```typescript\nsceneManager.add('outdoor', existingScene);\nconst scene = sceneManager.get('outdoor');\nsceneManager.remove('outdoor');\n```\n\n#### `serialize(key)`\n\n将场景元数据序列化为 JSON 快照。\n\n```typescript\nconst snapshot = sceneManager.serialize('indoor');\n// { name, background, environmentRotation, children }\n```\n\n#### `keys()` / `size` / `clear()`\n\n列出所有场景 key、获取场景数量或清空。\n\n---\n\n## LightManager\n\n`LightManager` 提供灯光的便捷创建、预设和 Helper 可视化。\n\n```typescript\nimport { LightManager } from 'u-space';\n\nconst lightManager = new LightManager(viewer.scene);\n```\n\n### 灯光创建\n\n```typescript\nlightManager.addAmbient('ambient', { color: 0xffffff, intensity: 0.5 });\nlightManager.addDirectional('sun', { position: { x: 5, y: 10, z: 5 }, castShadow: true });\nlightManager.addPoint('bulb', { position: { x: 0, y: 3, z: 0 }, intensity: 2 });\nlightManager.addSpot('spot', { position: { x: 0, y: 10, z: 0 }, angle: Math.PI / 6 });\nlightManager.addHemisphere('hemi', { skyColor: 0x87ceeb, groundColor: 0x362907 });\n```\n\n### 灯光预设\n\n一键应用常见场景的灯光配置:\n\n```typescript\nlightManager.applyPreset('indoor'); // 室内:环境光 + 顶部点光源\nlightManager.applyPreset('outdoor'); // 室外:半球光 + 方向光(阳光)\nlightManager.applyPreset('studio'); // 摄影棚:三点布光\nlightManager.applyPreset('warehouse'); // 仓库:多点光源照明\n```\n\n| 预设 | 配置 |\n| :---------- | :-------------------------------------- |\n| `indoor` | 环境光 + 2 个点光源 |\n| `outdoor` | 半球光 + 方向光(带阴影) |\n| `studio` | 环境光 + 主光 + 补光 + 轮廓光 |\n| `warehouse` | 环境光 + 4 个点光源(四角分布) |\n\n### Helper 可视化\n\n```typescript\nlightManager.showHelper('sun'); // 显示单个灯光 Helper(默认 size=5, color=0xff0000)\nlightManager.showHelper('sun', 2, 0x00ff00); // 自定义尺寸和颜色\nlightManager.showAllHelpers(); // 显示所有灯光 Helper\nlightManager.hideHelper('sun'); // 隐藏单个\nlightManager.hideAllHelpers(); // 隐藏所有\n```\n\n#### `showHelper(id, size?, color?)`\n\n| 参数 | 类型 | 默认值 | 说明 |\n| :------ | :-------------------- | :---------- | :---------------- |\n| `id` | `string` | — | 灯光 ID。 |\n| `size` | `number` | `5` | Helper 尺寸。 |\n| `color` | `ColorRepresentation` | `0xff0000` | Helper 颜色。 |\n\n### 管理\n\n```typescript\nlightManager.get('sun'); // 获取灯光\nlightManager.remove('sun'); // 移除灯光\nlightManager.removeAll(); // 移除所有\nlightManager.dispose(); // 清理\n```\n"
451
451
  },
452
452
  {
453
453
  "id": "api-objects",
@@ -716,6 +716,79 @@ export const docsIndex = [
716
716
  ],
717
717
  "content": "# curve-movement\n\n沿样条路径对相机或对象进行动画。提供两个具体子类:`CurveMovementCamera` 和 `CurveMovementObject`。\n\n```typescript\nimport { CurveMovementObject } from 'u-space/plugins/curve-movement';\nimport { Vector3 } from 'three/webgpu';\n\nconst movement = new CurveMovementObject(viewer, myModel);\nmovement.setFromPoints([\n new Vector3(0, 0, 0),\n new Vector3(10, 2, 0),\n new Vector3(20, 0, 10),\n]);\nmovement.speed = 0.05; // 每秒进度\nmovement.loop = 'repeat'; // 'once' | 'repeat' | 'pingpong'\nmovement.autoLookAt = true;\n\nmovement.play();\n// movement.pause() / movement.resume() / movement.stop()\n\n// 监听事件\nmovement.addEventListener('update', ({ progress }) => console.log(progress));\nmovement.addEventListener('complete', () => console.log('完成'));\n```\n\n**`CurveMovement` 属性:**\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :-------------- | :--------------------------------- | :-------- | :----------------------------------- |\n| `path` | `Curve<Vector3> \\| null` | `null` | 样条路径。 |\n| `progress` | `number` | `0` | 当前归一化进度(0–1)。 |\n| `speed` | `number` | `0.1` | 每秒进度单位。 |\n| `loop` | `'once' \\| 'repeat' \\| 'pingpong'` | `'once'` | 循环行为。 |\n| `autoLookAt` | `boolean` | `true` | 朝向路径切线方向。 |\n| `lookAtOffset` | `number` | `0` | Y 轴旋转偏移量(弧度)。 |\n| `positionOffset`| `Vector3` | `(0,0,0)` | 叠加到每个位置上的世界坐标偏移量。 |\n| `direction` | `1 \\| -1` | `1` | 当前行进方向。 |\n"
718
718
  },
719
+ {
720
+ "id": "api-plugin-fire",
721
+ "path": "api-plugin-fire.md",
722
+ "title": "fire",
723
+ "summary": "体积火焰插件,基于 Three.js 官方 `webgpu_volume_fire` 示例封装。插件在 GPU 上运行 3D 流体模拟,并通过独立的 volumetric pass 叠加到 `Viewer.renderPipeline` output effect 链中,提供火焰、烟雾、扰动、阴影和动态点光源效果。 ```typescript import { Vector3 } from 'three/webgpu';",
724
+ "headings": [
725
+ {
726
+ "level": 1,
727
+ "text": "fire"
728
+ },
729
+ {
730
+ "level": 2,
731
+ "text": "能力"
732
+ },
733
+ {
734
+ "level": 2,
735
+ "text": "API"
736
+ },
737
+ {
738
+ "level": 3,
739
+ "text": "new FireEffect(viewer, options?)"
740
+ },
741
+ {
742
+ "level": 3,
743
+ "text": "enable(options?)"
744
+ },
745
+ {
746
+ "level": 3,
747
+ "text": "update(options?)"
748
+ },
749
+ {
750
+ "level": 3,
751
+ "text": "setPosition(position)"
752
+ },
753
+ {
754
+ "level": 3,
755
+ "text": "setEmitter(emitter, geometry?)"
756
+ },
757
+ {
758
+ "level": 3,
759
+ "text": "reset()"
760
+ },
761
+ {
762
+ "level": 3,
763
+ "text": "disable()"
764
+ },
765
+ {
766
+ "level": 3,
767
+ "text": "dispose()"
768
+ },
769
+ {
770
+ "level": 2,
771
+ "text": "Options"
772
+ },
773
+ {
774
+ "level": 2,
775
+ "text": "Emitter"
776
+ },
777
+ {
778
+ "level": 2,
779
+ "text": "光源与体积范围"
780
+ },
781
+ {
782
+ "level": 2,
783
+ "text": "与 RenderPipeline 的关系"
784
+ },
785
+ {
786
+ "level": 2,
787
+ "text": "示例"
788
+ }
789
+ ],
790
+ "content": "# fire\n\n体积火焰插件,基于 Three.js 官方 `webgpu_volume_fire` 示例封装。插件在 GPU 上运行 3D 流体模拟,并通过独立的 volumetric pass 叠加到 `Viewer.renderPipeline` output effect 链中,提供火焰、烟雾、扰动、阴影和动态点光源效果。\n\n```typescript\nimport { Vector3 } from 'three/webgpu';\nimport { FireEffect } from 'u-space/plugins/fire';\n\nconst fire = new FireEffect(viewer, {\n position: new Vector3(0, 0, 0),\n size: new Vector3(12, 12, 24),\n fireIntensity: 40,\n smokeLifespan: 3.5,\n});\n\nfire.enable();\n```\n\n## 能力\n\n- 按官方示例的 semi-Lagrangian advection、curl noise、buoyancy、Jacobi pressure projection 流程模拟体积火焰和烟雾。\n- 使用 3D storage texture 保存速度、密度、温度、压力和 curl noise 数据。\n- 默认使用 `TeapotGeometry(0.8, 28)` 作为 emitter 采样几何;也可以传入业务对象和自定义 `BufferGeometry`。\n- 通过 `RenderPipeline.addOutputEffect()` 叠加体积结果,不占用业务侧的 `setOutputComposer()`。\n- 内置 spot light 和 point light:spot light 负责体积阴影方向,point light 跟随火焰核心投射暖色动态光照。\n- 监听 `cameraChange`,相机对象切换后会重建 fire 自己的 volumetric pass。\n\n## API\n\n### `new FireEffect(viewer, options?)`\n\n创建火焰效果实例。构造函数不会立即往场景写入模拟资源;调用 `enable()` 后才会创建体积盒、storage texture、compute pass、灯光和 output effect。\n\n### `enable(options?)`\n\n开启火焰效果。重复调用时等同于 `update(options)`。启用期间会把 `viewer.frameloop` 临时切到 `always`,关闭时恢复启用前的值。\n\n```typescript\nfire.enable({\n position: new Vector3(0, 0, 0),\n size: new Vector3(12, 12, 24),\n renderResolution: 0.5,\n});\n```\n\n### `update(options?)`\n\n更新火焰参数。大多数视觉和模拟强度参数会通过 uniform 直接生效。`gridSize`、`emitterGeometry`、`volumeLayer` 或 `raymarchSteps` 改变时会重建相关资源。\n\n```typescript\nfire.update({\n emitTemperature: 6,\n emitDensity: 8,\n emitterRadius: 1.4,\n smokeLifespan: 6,\n});\n```\n\n### `setPosition(position)`\n\n更新体积盒底部中心位置。等同于 `update({ position })`。\n\n### `setEmitter(emitter, geometry?)`\n\n设置驱动 emitter 的对象和采样几何。`emitter` 的 `matrixWorld` 会在每帧写入模拟;如果只想使用默认内部 emitter,可以传入 `null`。\n\n### `reset()`\n\n清空当前模拟状态并重新创建模拟资源。\n\n### `disable()`\n\n关闭火焰效果,移除 `beforeRender` / `cameraChange` 监听、output effect、体积盒、灯光、storage texture 和 compute pass,并恢复启用前的 `viewer.frameloop`。\n\n### `dispose()`\n\n关闭效果并释放插件持有的默认 emitter geometry。\n\n## Options\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `position` | `Vector3` | `(0, 0, 0)` | 体积盒底部中心世界坐标 |\n| `size` | `Vector3` | `(12, 12, 24)` | 体积盒世界尺寸,也是烟雾扩散的约束范围 |\n| `gridSize` | `{ x?: number; y?: number; z?: number }` | `{ x: 100, y: 100, z: 200 }` | 3D 模拟网格尺寸,越大越细腻也越耗显存 |\n| `volumeLayer` | `number` | `10` | 体积盒所在 layer,用于隔离 volumetric pass |\n| `emitterGeometry` | `BufferGeometry \\| null` | `TeapotGeometry(0.8, 28)` | emit pass 采样的几何顶点 |\n| `emitter` | `Object3D \\| null` | 内部 `Object3D` | 驱动 emitter matrix 和扰动速度的对象 |\n| `emitterRadius` | `number` | `1` | emitter 移动时影响流场的半径,作为 uniform 更新 |\n| `simulate` | `boolean` | `true` | 是否推进流体模拟 |\n| `simSpeed` | `number` | `1.2` | 模拟速度倍率 |\n| `pressureIterations` | `number` | `2` | Jacobi pressure projection 次数,会自动向上限制为正偶数 |\n| `raymarchSteps` | `number` | `16` | 体积 raymarch 步数,改变后会重建体积材质 |\n| `renderResolution` | `number` | `0.5` | volumetric pass 分辨率倍率,范围 `0.1..1` |\n| `denoise` | `boolean` | `true` | 是否对体积 pass 做 Gaussian blur |\n| `denoiseStrength` | `number` | `0.5` | 降噪强度 |\n| `bloom` | `boolean` | `true` | 是否对火焰输出追加 bloom |\n| `bloomStrength` | `number` | `0.1` | bloom 强度 |\n| `bloomRadius` | `number` | `1` | bloom 半径 |\n| `bloomThreshold` | `number` | `0.5` | bloom 阈值 |\n| `smokeLifespan` | `number` | `3.5` | 烟雾寿命,越大烟雾保留越久 |\n| `smokeIntensity` | `number` | `1` | 烟雾散射可见度倍率 |\n| `smokeColor` | `ColorRepresentation` | `0xffffff` | 烟雾散射颜色 |\n| `fireLifespan` | `number` | `1.3` | 火焰温度衰减时间 |\n| `turbulence` | `number` | `3.2` | 火焰和烟雾湍流强度 |\n| `turbulenceDecay` | `number` | `0.1` | 湍流随年龄衰减速度 |\n| `turbulenceFrequency` | `number` | `10` | curl noise 频率 |\n| `buoyancy` | `number` | `3` | 热浮力 |\n| `velocityDamping` | `number` | `0.25` | 速度阻尼 |\n| `emitDensity` | `number` | `7` | emitter 注入密度 |\n| `emitTemperature` | `number` | `5.5` | emitter 注入温度 |\n| `motionBoost` | `number` | `0.25` | emitter 移动带来的额外发射量 |\n| `windStrength` | `number` | `6.5` | emitter 移动对流场的扰动强度 |\n| `fireIntensity` | `number` | `40` | 火焰发光强度 |\n| `glowSpread` | `number` | `5` | 火焰亮度扩散范围 |\n| `fireHue` | `number` | `0` | 火焰色相偏移,单位为度 |\n| `saturation` | `number` | `1.1` | 输出饱和度 |\n| `fireStartColor` | `ColorRepresentation` | `0xffe68c` | 高温火焰颜色 |\n| `fireMidColor` | `ColorRepresentation` | `0xff7305` | 中段火焰颜色 |\n| `fireEndColor` | `ColorRepresentation` | `0xff0000` | 低温火焰颜色 |\n| `phaseAsymmetry` | `number` | `0` | Henyey-Greenstein 相函数 g 值 |\n| `powderStrength` | `number` | `0.59` | powder effect 强度 |\n| `multiScattering` | `number` | `1` | 多次散射近似强度 |\n| `shadowAbsorption` | `number` | `2` | 体积阴影吸收系数 |\n| `shadowAmbient` | `number` | `0.5` | 阴影环境补光 |\n| `keyLight` | `boolean` | `true` | 是否创建体积阴影 spot light |\n| `pointLight` | `boolean` | `true` | 是否创建火焰动态点光源 |\n| `pointLightIntensity` | `number` | `1` | 动态点光源强度 |\n| `pointLightDistance` | `number` | `40` | 动态点光源距离 |\n\n## Emitter\n\n如果不设置 `emitterGeometry`,插件会创建一个内部 `TeapotGeometry(0.8, 28)`,这和官方示例保持一致。emit pass 会遍历该几何的 position 顶点,把密度和温度写入体积纹理。传入自定义 `emitterGeometry` 时,该几何必须包含 `position` attribute。\n\n如果不设置 `emitter`,插件会使用内部 `Object3D`,并把它放在 `position` 位置。传入业务对象后,插件每帧读取该对象的 `matrixWorld` 和世界位置变化,移动速度会影响流场扰动和额外发射量。\n\n```typescript\nconst fire = new FireEffect(viewer, {\n emitter: torchMesh,\n emitterGeometry: torchFlameGeometry,\n emitterRadius: 0.8,\n});\n```\n\n## 光源与体积范围\n\n火焰本体不是场景里的普通透明 mesh 直接混合,而是先放在 `volumeLayer` 的体积盒里单独渲染,再通过 output effect 叠加到主场景。烟雾和火焰的可见范围由 `position + size` 定义的体积盒限制,超出盒子的密度会在边界处淡出。要让烟雾扩散范围更大,优先增大 `size`;要提升细节,再同步增大 `gridSize`。\n\n插件会按需创建两个光源:\n\n- `FireEffect.keyLight`:`SpotLight`,用于体积阴影方向和烟雾散射计算。\n- `FireEffect.pointLight`:`PointLight`,跟随 emitter / 火焰核心移动,并通过 TSL `colorNode` 产生随温度、密度和噪声变化的暖色照明。\n\n如果业务场景已经有自己的灯光,可以通过 `keyLight: false` 或 `pointLight: false` 关闭插件内置光源。\n\n## 与 RenderPipeline 的关系\n\n`FireEffect` 使用 `viewer.renderPipeline.addOutputEffect()` 和 `removeOutputEffect()` 接入输出链。它不会调用 `setOutputComposer()`,因此不会覆盖业务或其他插件的 output effects。注意如果业务主动设置自定义 `setOutputComposer()`,RenderPipeline 会按自定义 composer 的语义跳过 output effects,火焰叠加也会被跳过。\n\n`renderResolution` 只影响独立 volumetric pass 的分辨率;主场景分辨率仍由 `Viewer` 和 renderer 控制。启用 `denoise` 和 `bloom` 时,插件会在 output effect 内创建并释放对应节点。\n\n## 示例\n\n示例页见 `examples/test_fire.html`。本地运行时先构建插件:\n\n```bash\npnpm build:plugins -- plugins/fire\n```\n\n然后通过本地静态服务访问:\n\n```text\nhttp://127.0.0.1:5174/examples/test_fire.html\n```\n"
791
+ },
719
792
  {
720
793
  "id": "api-plugin-keyboard-controls",
721
794
  "path": "api-plugin-keyboard-controls.md",
@@ -802,19 +875,23 @@ export const docsIndex = [
802
875
  "id": "api-plugin-u-manager",
803
876
  "path": "api-plugin-u-manager.md",
804
877
  "title": "u-manager",
805
- "summary": "`u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性、相机视点、楼层、井道和设备语义模型。 所有加载器均继承自 Three.js 的 `Loader`,并提供 `setPath(path)` 方法,在调用 `loadAsync()` 前配置基础数据目录。 加载 `db/semantic_model.json` 楼层语义数据。`loadAsync()` 返回顶层 `SemanticSceneGroup`,用于组织整次语义解析产生的建筑、楼层以及 scene-level facility layer。每个建筑包含多个 `FloorMesh`,每个楼层把墙、柱、空间、楼梯等语义对象合并为一个 TSL 材质驱动的网格;建筑级电梯井和通风井会使用 `ExtrudeMesh` 独立渲染。语义模型包含 `Facilities`",
878
+ "summary": "`u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性、相机视点、楼层、井道和设备语义模型。 所有加载器均继承自 Three.js 的 `Loader`,并提供 `setPath(path)` 方法,在调用 `loadAsync()` 前配置基础数据目录。 `UManagerLoader` 是推荐的一体化入口。它会在同一路径下同时加载 `SemanticLoader` `SceneLoader`:语义文件中已经存在的 `id` 会由 `SceneLoader` 自动跳过,避免建筑、楼层、设备被重复创建;非语义场景树节点仍会正常加载。返回值是一个 `UManagerSceneGroup`,可直接通过 `semanticGroup` 访问 `SemanticGroup`,通过 `sceneGroup` 访问非语义场",
806
879
  "headings": [
807
880
  {
808
881
  "level": 1,
809
882
  "text": "u-manager"
810
883
  },
884
+ {
885
+ "level": 2,
886
+ "text": "UManagerLoader"
887
+ },
811
888
  {
812
889
  "level": 2,
813
890
  "text": "SemanticLoader"
814
891
  },
815
892
  {
816
893
  "level": 3,
817
- "text": "SemanticSceneGroup"
894
+ "text": "SemanticGroup"
818
895
  },
819
896
  {
820
897
  "level": 3,
@@ -828,6 +905,18 @@ export const docsIndex = [
828
905
  "level": 3,
829
906
  "text": "设施设备"
830
907
  },
908
+ {
909
+ "level": 3,
910
+ "text": "FacilityInstanceObject"
911
+ },
912
+ {
913
+ "level": 3,
914
+ "text": "FacilityInstancedLayer"
915
+ },
916
+ {
917
+ "level": 3,
918
+ "text": "SemanticModelInstancedLayer"
919
+ },
831
920
  {
832
921
  "level": 3,
833
922
  "text": "FloorMesh"
@@ -844,6 +933,14 @@ export const docsIndex = [
844
933
  "level": 2,
845
934
  "text": "SceneLoader"
846
935
  },
936
+ {
937
+ "level": 3,
938
+ "text": "SceneInstanceObject"
939
+ },
940
+ {
941
+ "level": 3,
942
+ "text": "SceneInstancedLayer"
943
+ },
847
944
  {
848
945
  "level": 2,
849
946
  "text": "TopologiesLoader / TopologyParser"
@@ -861,7 +958,7 @@ export const docsIndex = [
861
958
  "text": "PropertiesLoader"
862
959
  }
863
960
  ],
864
- "content": "# u-manager\n\n`u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性、相机视点、楼层、井道和设备语义模型。\n\n所有加载器均继承自 Three.js 的 `Loader`,并提供 `setPath(path)` 方法,在调用 `loadAsync()` 前配置基础数据目录。\n\n## `SemanticLoader`\n\n加载 `db/semantic_model.json` 楼层语义数据。`loadAsync()` 返回顶层 `SemanticSceneGroup`,用于组织整次语义解析产生的建筑、楼层以及 scene-level facility layer。每个建筑包含多个 `FloorMesh`,每个楼层把墙、柱、空间、楼梯等语义对象合并为一个 TSL 材质驱动的网格;建筑级电梯井和通风井会使用 `ExtrudeMesh` 独立渲染。语义模型包含 `Facilities` 时,`SemanticLoader` 会额外读取 `SceneMetadata.json` 指向的 `tree_models`,按场景授权配置解密,再把对应设备模型挂载到所属楼层。\n\n```typescript\nimport { Vector3, Vector4 } from 'three';\nimport { SemanticLoader } from 'u-space/plugins/u-manager';\n\nconst loader = new SemanticLoader(viewer);\nloader.setPath('./scenes/my-scene');\nloader.setKey('YOUR_LICENSE_KEY'); // 官方授权场景解析 tree_models 时必需\n\nconst semanticScene = await loader.loadAsync(); // SemanticSceneGroup\nviewer.scene.add(semanticScene);\n\nconst building = semanticScene.getBuildingAt(0);\nconst floor = building.getFloorAt(0);\n\nbuilding.isolateFloor(floor);\nawait viewer.controls.flyToObject(floor);\n\nfloor.addEventListener('click', ({ event }) => {\n const { target, intersect } = event;\n const index = intersect.semanticIndex;\n\n target.setColorAt(index, new Vector4(1, 0, 0, 0.5));\n target.setScaleAt(index, new Vector3(1, 0.1, 1));\n viewer.render();\n});\n```\n\n### `SemanticSceneGroup`\n\n`SemanticSceneGroup` 继承自 `BaseGroup`,是单次 `SemanticParser` 解析结果的顶层容器。它管理所有 `BuildingGroup`,并把跨楼层共享的 Facilities `InstancedMesh` 渲染层作为建筑的同级对象挂在 `facilityLayer`,而不是挂到某个 `BuildingGroup` 内。\n\n建筑 ID 和设备 ID 查询使用内部 `Map` 索引维护;`getBuildingById()`、`getFacilityById()` 以及单设备控制方法不会通过数组扫描查找语义对象。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `buildings` | 当前语义场景内的 `BuildingGroup[]`。 |\n| `facilityLayer` | scene-level 设备渲染层;同模型 URL 的静态设备会合并为 `InstancedMesh` batch。 |\n| `addBuilding(group)` / `removeBuilding(group)` | 添加或移除建筑,并同步更新 group 子节点。 |\n| `getBuildingAt(index)` / `getBuildingById(id)` / `getBuildings()` | 按下标、`Building.ID` 或整体列表获取建筑。 |\n| `floorMeshes` | 聚合返回所有建筑内的 `FloorMesh[]`。 |\n| `setFacilityLayer(layer)` | 设置跨楼层设备渲染层;传入 `null` 会移除已有 layer。 |\n| `getFacilityById(id)` | 在整次语义解析结果中按 `Facility.ID` 或显式别名查找设备。 |\n| `showFacility(id \\| object)` / `hideFacility(id \\| object)` | 显示或隐藏单个设备。 |\n| `setFacilityVisible(id \\| object, visible)` | 设置单个设备显隐状态。 |\n| `setFacilityColor(id \\| object, color)` | 设置单个设备材质颜色。 |\n| `resetFacilityColor(id \\| object)` | 清除单个设备颜色 override,恢复模型原始颜色;透明度 override 不受影响。 |\n| `setFacilityOpacity(id \\| object, opacity)` | 设置单个设备材质透明度,`opacity` 会被限制在 `0..1`。 |\n| `showAllFacilities()` / `hideAllFacilities()` | 显示或隐藏整次语义解析结果中的全部设备。 |\n| `showAllFloors()` | 显示所有建筑的所有楼层。 |\n| `planishFloors(kind?)` / `unplanishFloors(kind?)` | 压扁或恢复所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面附近,同时添加稳定的轻微 Y 偏移以减少共面闪烁;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |\n\n### `BuildingGroup`\n\n`BuildingGroup` 继承自 `BaseGroup`,用于组织一个建筑下的所有楼层、电梯井和通风井。设备语义对象不会直接挂到 `BuildingGroup`;能 instancing 的设备会渲染到 `SemanticSceneGroup.facilityLayer`,同时在对应 `FloorMesh` 下保留可检索、可控制的轻量引用。\n\n建筑内设备 ID 到楼层的关系由内部 `Map` 索引维护,并通过楼层设备索引版本自动同步。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `floorMeshes` | 当前建筑内的 `FloorMesh[]`。 |\n| `elevatorMeshes` | 当前建筑内由 `Elevators` 语义生成的 `ExtrudeMesh[]`。 |\n| `ventMeshes` | 当前建筑内由 `Vents` 语义生成的 `ExtrudeMesh[]`。 |\n| `addFloor(floor)` | 添加楼层,并同步加入 group。 |\n| `removeFloor(floor)` | 移除楼层,并同步从 group 移除。 |\n| `getFloorAt(index)` | 按楼层下标获取 `FloorMesh`。 |\n| `getFloorById(id)` | 按楼层语义 ID 获取 `FloorMesh`,内部使用 `Map` 索引。 |\n| `addElevator(elevator)` / `removeElevator(elevator)` | 添加或移除电梯井,并同步更新 group。 |\n| `getElevatorAt(index)` | 按下标获取电梯井 `ExtrudeMesh`。 |\n| `getElevatorById(id)` | 按电梯井语义 ID 获取电梯井,内部使用 `Map` 索引。 |\n| `addVent(vent)` / `removeVent(vent)` | 添加或移除通风井,并同步更新 group。 |\n| `getVentAt(index)` | 按下标获取通风井 `ExtrudeMesh`。 |\n| `getVentById(id)` | 按通风井语义 ID 获取通风井,内部使用 `Map` 索引。 |\n| `isolateFloor(floor \\| index)` | 只显示指定楼层,隐藏其他楼层;也兼容传入楼层数组。 |\n| `isolateFloors(floors \\| indexes)` | 只显示指定多个楼层,隐藏其他楼层。 |\n| `showAllFloors()` | 显示全部楼层。 |\n| `getFacilityById(id)` | 在当前建筑的楼层中按 `Facility.ID` 或显式别名查找设备。 |\n| `showFacility(id \\| object)` / `hideFacility(id \\| object)` | 显示或隐藏当前建筑内的单个设备。 |\n| `setFacilityVisible(id \\| object, visible)` | 设置当前建筑内单个设备显隐状态。 |\n| `setFacilityColor(id \\| object, color)` | 设置当前建筑内单个设备材质颜色。 |\n| `resetFacilityColor(id \\| object)` | 清除当前建筑内单个设备颜色 override。 |\n| `setFacilityOpacity(id \\| object, opacity)` | 设置当前建筑内单个设备材质透明度。 |\n| `showAllFacilities()` | 显示整栋建筑内全部楼层设备。 |\n| `hideAllFacilities()` | 隐藏整栋建筑内全部楼层设备。 |\n| `planishFloors(kind?)` | 压扁所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面附近,同时添加稳定的轻微 Y 偏移以减少共面闪烁;传入 `kind` 时只压扁该语义类型,`kind` 可包含 `Facilities`。 |\n| `unplanishFloors(kind?)` | 恢复所有楼层;默认恢复所有合并语义实例和 Facilities;传入 `kind` 时只恢复该语义类型,`kind` 可包含 `Facilities`。 |\n\n### 电梯井和通风井\n\n`SemanticLoader` 会读取 `semantic_model.json` 中建筑引用的 `Elevators` 和 `Vents`。每个井道使用 `Polygon.shape` 作为底面轮廓,`Elevation` 作为底面高度,`TotalHeight` 作为拉伸高度,并以 building 级 `ExtrudeMesh` 加入 `BuildingGroup`。\n\n```typescript\nconst elevator = building.getElevatorAt(0);\nconst elevatorById = building.getElevatorById('ELEVATOR_001');\nconst vent = building.getVentAt(0);\nconst ventById = building.getVentById('VENT_001');\n\nif (elevator) {\n await viewer.controls.flyToObject(elevator);\n}\n\nif (vent) {\n building.removeVent(vent);\n}\n```\n\n电梯井和通风井会在渲染阶段沿法线轻微内收,减少与墙体共面时的闪面。`Spaces` 实例也会使用稳定的 per-instance 渲染偏移抖动,缓解完全重叠空间之间的 z-fighting;这些偏移只影响渲染顶点,不改变语义 ID、实例矩阵和包围体查询的使用方式。\n\n### 设施设备\n\n`SemanticLoader` 会从 `Stories[].Facilities` 读取设备索引,再从顶层 `Facilities` 数组取得 `Facility` 数据,并使用 `Facility.ID` 在解密后的 `tree_models` 中查找同 ID 节点。只有带 `renderType: '3D'` 和模型 `path` 的节点会被加载。\n\n`tree_models.matrix` 是相对父节点的本地矩阵;`SemanticLoader` 会沿树父级累乘得到设备世界矩阵,再转换为对应 `FloorMesh` 的局部矩阵。因此楼层移动、隔离或显示隐藏时设备会跟随楼层一起工作。即使某个 story 只有 `Facilities`、没有墙柱空间等合并几何,也会创建一个空的 `FloorMesh` 作为设备容器。\n\nFacilities 会在单次 `SemanticParser` 解析范围内按模型 URL 自动分组。静态模型会被转换为 scene-level `InstancedMesh` batch,挂到 `SemanticSceneGroup.facilityLayer`;每个设备仍会在所属 `FloorMesh` 下保留一个轻量引用,用于 `getFacilityById()`、显隐、颜色、透明度和 `viewer.objectManager` 检索。带动画、骨骼、morph target 或多材质 Mesh 的模型会自动回退为普通 `Model`,继续作为实际 `Object3D` 挂到所属 `FloorMesh`。\n\n`facilityLayer` 使用 `FacilityInstancedLayer`,并继承自 `BaseGroup`。当 `facilityLayer.visible = false` 时,layer 会阻止内部 `InstancedMesh` 继续参与射线检测,避免隐藏的批处理设备仍被点击命中;单个设备的显隐仍应通过楼层下的设备引用或 `showFacility()` / `hideFacility()` 控制。\n\nInstanced 设备通过 per-instance opacity attribute 控制单个设备透明度。batch 材质默认沿用源材质的透明状态;只有源材质本身透明,或当前参与渲染的设备存在 `opacity < 1` 时,材质才会切到 `transparent: true`,`setFacilityOpacity(id, 1)` 可在没有其他半透明实例时回到不透明渲染队列。`resetFacilityColor()` 只清除颜色 override,不影响透明度 override。`FacilityInstancedLayer` 会在渲染前同步实例矩阵、颜色和透明度,但只有检测到数据变化时才上传对应 buffer,静态设备不会每帧重复提交全部 instance 数据。layer 会把每个 Facility 的完整模板包围盒转成世界包围盒,并用当前相机视锥压缩本帧 active instance count;裁剪不再使用相机距离阈值,因此侧视、立面和俯视视角都只由包围盒是否进入视锥决定。`cameraDistanceCulling`、`cameraCullDistance`、`cameraCullOverviewFactor` 和 `cameraCullPlanViewThreshold` 旧字段仅保留兼容,不再影响裁剪结果。普通 fallback `Model` 的颜色和透明度控制依赖 `MaterialEffects`,单材质和多材质 Mesh 都会应用 override。\n\n加载成功后,设备引用会写入 `userData.facilityId`、`semanticId`、`semanticKind: 'Facilities'`、`semanticName`、`spaces`、`twinsIdentifier`、`storyId` 和 `floorIndex`,并按 `Facility.ID` 注册到 `viewer.objectManager`。自动 instancing 的引用还会带有 `userData.instanced: true` 和 `userData.modelUrl`。\n\n```typescript\nimport { Box3 } from 'three';\n\nconst floor = building.getFloorAt(0);\nconst box = new Box3();\n\nconst facility = floor.getFacilityById('FACILITY_001') ?? viewer.objectManager.getById('FACILITY_001');\nconst facilityEntity = floor.getSemanticById('FACILITY_001');\n\nif (facility && facilityEntity?.type === 'object') {\n const facilityBox =\n typeof facility.getFacilityBoundingBox === 'function'\n ? facility.getFacilityBoundingBox(box, true)\n : box.setFromObject(facility);\n\n await viewer.controls.flyToBox(facilityBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n}\n\nconst facilities = floor.getSemanticsByKind('Facilities');\n\nsemanticScene.hideFacility('FACILITY_001');\nsemanticScene\n .setFacilityColor('FACILITY_001', '#ff5533')\n .setFacilityOpacity('FACILITY_001', 0.45)\n .resetFacilityColor('FACILITY_001')\n .showFacility('FACILITY_001');\n```\n\n对 Facilities 推荐使用 `controls.flyToBox()` 飞向设备包围盒。instanced 设备引用是楼层下的轻量 `FacilityInstanceObject`,可通过 `getFacilityBoundingBox(box, true)` 取得完整世界包围盒;普通 fallback `Model` 也可以直接使用 `viewer.controls.flyToObject(facility)`。\n\n### `FloorMesh`\n\n`FloorMesh` 继承自 `BaseMesh`,表示一个楼层。它不是 `BatchedMesh`,而是把同一楼层内的语义对象合并为一份几何,并通过 TSL + `DataTexture` 在 GPU 侧按 `semanticIndex` 控制颜色、透明度、显示隐藏和实例矩阵。楼层语义网格会按实例透明度拆分为不透明和透明两个材质通道;墙、柱、门等默认不透明实例会进入 opaque pipeline,`Spaces`、`Windows` 或通过 `setOpacityAt()` 改成半透明的实例会进入 transparent pipeline。Facilities 通过楼层下的引用对象进行检索和控制;实际渲染可能来自 `SemanticSceneGroup.facilityLayer` 的 `InstancedMesh` batch,也可能是 fallback 的普通 `Model`。\n\n这种结构的目标是让每个楼层通常只占一个主渲染 draw call,同时仍保留实例级控制能力。`xxxAt` 方法全部作用于单个语义实例;没有 `At` 后缀的方法作用于整个楼层 mesh。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `semanticCount` / `instanceCount` | 当前楼层语义实例数量。 |\n| `semanticInstances` | `Map<string, number>`,从语义对象 ID 映射到实例下标。 |\n| `wallsInstances` / `columnsInstances` / `spacesInstances` / `doorsInstances` / `windowsInstances` / `staircasesInstances` | 按语义类型维护的 ID 到实例下标映射。 |\n| `semanticEntities` | `Map<string, FloorSemanticEntity>`,统一索引楼层内合并几何语义和 `Facilities` 对象语义。 |\n| `facilityObjectsById` | `Map<string, Object3D>`,按 `Facility.ID` 或显式别名查找设备引用。 |\n| `facilityObjects` | 当前楼层挂载的设备引用数组。 |\n| `getSemanticIndexById(id)` | 根据语义 ID 获取实例下标。 |\n| `getSemanticById(id)` | 根据语义 ID 或设备别名获取统一语义实体。 |\n| `getSemantics()` | 获取楼层内全部语义实体,包含合并几何和设备对象。 |\n| `getSemanticsByKind(kind)` | 按语义类型过滤实体;`kind` 可以是 `Walls`、`Columns`、`Spaces`、`Doors`、`Windows`、`Staircases` 或 `Facilities`。 |\n| `getSemanticIdAt(index)` | 获取实例语义 ID。 |\n| `getSemanticKindAt(index)` | 获取合并几何实例类型:`'Walls' \\| 'Columns' \\| 'Spaces' \\| 'Doors' \\| 'Windows' \\| 'Staircases'`。 |\n| `getSemanticNameAt(index)` | 获取实例名称;当前 `Spaces` 会从语义数据的 `Name` 写入,其他类型可能为 `undefined`。 |\n| `showAllFacilities()` | 显示当前楼层的全部设备对象。 |\n| `hideAllFacilities()` | 隐藏当前楼层的全部设备对象。 |\n| `addFacility(object, ids?)` | 把设备对象挂到楼层,并按显式 ID、`facilityId`、`semanticId`、`id` 建立检索别名。 |\n| `getFacilityById(id)` | 根据 `Facility.ID` 或别名获取设备对象。 |\n| `getFacilityAt(index)` | 按楼层设备数组下标获取设备对象。 |\n| `getFacilities()` | 获取当前楼层全部设备对象。 |\n| `showFacility(id \\| object)` / `hideFacility(id \\| object)` | 显示或隐藏当前楼层内的单个设备。 |\n| `setFacilityVisible(id \\| object, visible)` | 设置当前楼层内单个设备显隐状态。 |\n| `setFacilityColor(id \\| object, color)` | 设置当前楼层内单个设备材质颜色。 |\n| `resetFacilityColor(id \\| object)` | 清除当前楼层内单个设备颜色 override。 |\n| `setFacilityOpacity(id \\| object, opacity)` | 设置当前楼层内单个设备材质透明度。 |\n| `removeFacility(facility)` | 按设备对象或 ID 从楼层移除设备,并同步清理检索索引。 |\n| `setColorAt(index, color)` / `getColorAt(index, target?)` | 修改或读取实例颜色,支持 `Color`、`Vector3`、`Vector4`。 |\n| `setOpacityAt(index, opacity)` / `getOpacityAt(index)` | 修改或读取实例透明度。 |\n| `setVisibleAt(index, visible)` / `getVisibleAt(index)` | 修改或读取实例显隐状态。 |\n| `setMatrixAt(index, matrix)` / `getMatrixAt(index, target?)` | 设置或读取实例附加矩阵。 |\n| `setScaleAt(index, scale, y?, z?)` | 修改实例缩放,支持 `number` 或 `Vector3`。 |\n| `setScaleYAt(index, y)` | 只修改实例 Y 轴缩放,保留 X/Z 缩放和已有位移、旋转。 |\n| `getFinalMatrixAt(index, target?)` | 读取实例最终矩阵,包含语义对象原始基点矩阵。 |\n| `getBoundingBoxAt(index, target?, world?)` | 获取实例包围盒;`world = true` 时包含 `FloorMesh.matrixWorld`。 |\n| `getBoundingSphereAt(index, target?, world?)` | 获取实例包围球;`world = true` 时包含 `FloorMesh.matrixWorld`。 |\n| `computeBoundingBox()` / `computeBoundingSphere()` | 计算整个楼层的包围体。 |\n| `planish(kind?)` / `unplanish(kind?)` | 压扁或恢复楼层内所有合并语义实例和 Facilities;压平时按各自包围盒贴到楼层平面附近,并加入稳定的轻微 Y 偏移;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |\n\n### 飞向语义实例\n\n点击、射线检测命中 `FloorMesh` 里的语义几何或设备时,`intersect` 上会附加语义字段:`semanticIndex`、`semanticId`、`semanticKind`。普通楼层语义几何的事件目标是 `FloorMesh`;instanced Facilities 的事件目标是楼层下的 `FacilityInstanceObject` 引用,事件会继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticSceneGroup`。因此楼层监听器中应使用 `event.currentTarget` 操作楼层,用 `intersect.facility` 或 `event.target` 取得设备对象。\n\n```typescript\nimport { Box3 } from 'three';\n\nconst box = new Box3();\n\nfloor.addEventListener('click', async ({ event }) => {\n const { currentTarget, intersect } = event;\n if (!intersect) return;\n\n if (intersect.semanticKind === 'Facilities') {\n const facility = intersect.facility ?? event.target;\n const facilityBox =\n typeof facility.getFacilityBoundingBox === 'function'\n ? facility.getFacilityBoundingBox(box, true)\n : box.setFromObject(facility);\n\n await viewer.controls.flyToBox(facilityBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n return;\n }\n\n const semanticBox = currentTarget.getBoundingBoxAt(intersect.semanticIndex, box, true);\n\n if (semanticBox) {\n await viewer.controls.flyToBox(semanticBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n }\n});\n```\n\n如果要根据 ID 操作对象,先通过 `getSemanticIndexById(id)` 转为实例下标。\n\n```typescript\nconst index = floor.getSemanticIndexById('SPACE_001');\n\nif (index !== undefined) {\n floor.setVisibleAt(index, false);\n viewer.render();\n}\n```\n\n### 楼层压扁\n\n`planish()` / `unplanish()` 默认作用于当前楼层的全部合并语义实例,包含墙、柱、空间、门窗、楼梯等语义几何,也包含楼层下的 Facilities 引用;传入 `kind` 时只处理该类型,例如 `floor.planish('Walls')` 或 `floor.planish('Facilities')`。所有被压平的实例都会按自身包围盒把压平后的薄片贴到楼层平面 `FloorMesh.pivot.y` 附近,而不是围绕实例自身基点压缩;压平时还会按语义类型和实例 ID 加入稳定的轻微 Y 偏移,减少门、墙或其他重叠实例之间的共面闪烁。`unplanish()` 会恢复合并几何实例的原始矩阵,`unplanish('Facilities')` 会恢复设备原始 `position.y` 和 `scale.y`。instanced Facilities 会通过楼层下的 `FacilityInstanceObject` transform 同步到 `SemanticSceneGroup.facilityLayer`。\n\n如果只想调整单个合并几何实例,可以使用 `setScaleAt()` 或 `setScaleYAt()`,它们会保留该语义对象自己的基点矩阵,因此压扁墙、柱、房间时不会被压到世界原点。\n\n## `SceneLoader`\n\n从服务端场景包加载完整场景树(模型、组、形状、拉伸区域),并自动将所有已加载对象按 `id` 和 `sid` 注册到 `viewer.objectManager`。\n\n```typescript\nimport { SceneLoader } from 'u-space/plugins/u-manager';\n\nconst sceneLoader = new SceneLoader(viewer);\nsceneLoader.setPath('./scenes/my-scene');\nsceneLoader.setKey('YOUR_LICENSE_KEY'); // 官方授权场景必需\nconst group = await sceneLoader.loadAsync();\nviewer.scene.add(group);\n```\n\n**方法:**\n\n| 方法 | 说明 |\n| :--------------- | :------------------------------------------------------------ |\n| `setKey(key)` | 设置授权场景的 RSA 解密密钥。 |\n| `loadAsync()` | 加载并解析场景,返回包含完整层级的 `Group`。 |\n| `clearCache()` | 从 `objectManager` 中移除此加载器注册的所有 ID。 |\n| `dispose()` | 清除缓存并释放水印叠加层。 |\n\n## `TopologiesLoader` / `TopologyParser`\n\n加载拓扑图数据并将其转换为 `Topology` 对象。\n\n```typescript\nimport { TopologiesLoader } from 'u-space/plugins/u-manager';\n\nconst loader = new TopologiesLoader();\nloader.setPath('./scenes/my-scene');\nconst topologies = await loader.loadAsync(); // Topology[]\nviewer.scene.add(...topologies);\n```\n\n## `VisionsLoader` / `VisionsParser`\n\n加载命名相机视点,并将相机飞行到指定视点。\n\n```typescript\nimport { VisionsLoader, VisionsParser } from 'u-space/plugins/u-manager';\n\nconst visionsLoader = new VisionsLoader();\nvisionsLoader.setPath('./scenes/my-scene');\nconst visionsData = await visionsLoader.loadAsync();\n// visionsData 是 Record<string, IVisions[]>\n\nconst visionsParser = new VisionsParser(viewer);\n\n// 飞行到指定视点\nawait visionsParser.flyTo(visionsData['HOME'][0]);\n\n// 飞行到主(默认)视点\nawait visionsParser.flyToPrimary(visionsData['HOME']);\n```\n\n**`IVisions` 字段:**\n\n| 字段 | 类型 | 说明 |\n| :--------- | :------------ | :------------------------------ |\n| `camera` | `'P' \\| 'O'` | 相机类型:透视或正交。 |\n| `position` | `IVector3` | 相机世界位置。 |\n| `target` | `IVector3` | 相机朝向目标点。 |\n| `zoom` | `number` | 相机缩放级别。 |\n| `primary` | `boolean` | 是否为默认视点。 |\n\n## `AnimationsLoader` / `AnimationsParser`\n\n加载关键帧动画数据,并通过 `tweenAnimation` 驱动 `Object3D` 的变换。\n\n```typescript\nimport { AnimationsLoader, AnimationsParser } from 'u-space/plugins/u-manager';\n\nconst animLoader = new AnimationsLoader();\nanimLoader.setPath('./scenes/my-scene');\nconst animationsData = await animLoader.loadAsync(); // IAnimations[]\n\n// 查找特定对象的动画\nconst data = animationsData.find((a) => a.modelId === myModel.userData.id);\n\nconst parser = new AnimationsParser(viewer, myModel);\nparser.initTransform(); // 保存初始位置/旋转/缩放\n\nawait parser.play(data.keyframes); // 播放动画序列\n\n// 中途停止\nparser.stop();\n\n// 重置到初始变换\nparser.reset();\n```\n\n## `PropertiesLoader`\n\n加载与模型关联的结构化属性元数据(如 BIM 属性)。\n\n```typescript\nimport { PropertiesLoader } from 'u-space/plugins/u-manager';\n\nconst propsLoader = new PropertiesLoader();\npropsLoader.setPath('./scenes/my-scene');\nconst properties = await propsLoader.loadAsync(); // IProperties[]\n\n// 查找模型的属性\nconst modelProps = properties.filter(p => p.modelId === myModel.userData.id);\n```\n\n**`IProperties` 字段:**\n\n| 字段 | 类型 | 说明 |\n| :-------- | :--------------- | :----------------------- |\n| `modelId` | `string` | 关联模型的 ID。 |\n| `group` | `string` | 属性分组/类别名称。 |\n| `key` | `string` | 属性键名。 |\n| `value` | `string \\| null` | 属性值。 |\n| `label` | `string \\| null` | 属性的显示标签。 |\n"
961
+ "content": "# u-manager\n\n`u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性、相机视点、楼层、井道和设备语义模型。\n\n所有加载器均继承自 Three.js 的 `Loader`,并提供 `setPath(path)` 方法,在调用 `loadAsync()` 前配置基础数据目录。\n\n## `UManagerLoader`\n\n`UManagerLoader` 是推荐的一体化入口。它会在同一路径下同时加载 `SemanticLoader` 和 `SceneLoader`:语义文件中已经存在的 `id` 会由 `SceneLoader` 自动跳过,避免建筑、楼层、设备被重复创建;非语义场景树节点仍会正常加载。返回值是一个 `UManagerSceneGroup`,可直接通过 `semanticGroup` 访问 `SemanticGroup`,通过 `sceneGroup` 访问非语义场景组。\n\n```typescript\nimport { UManagerLoader } from 'u-space/plugins/u-manager';\n\nconst loader = new UManagerLoader(viewer);\nloader.setPath('./scenes/my-scene');\nloader.setKey('YOUR_LICENSE_KEY');\n\nconst group = await loader.loadAsync();\nviewer.scene.add(group);\n\nconst semanticGroup = group.semanticGroup;\nconst sceneGroup = group.sceneGroup;\n```\n\n完整可运行示例见 [`examples/test_umanager_loader.html`](https://u-space-phi.vercel.app/examples/test_umanager_loader.html)。该示例展示了如何从返回根组中直接读取 `semanticGroup` / `sceneGroup`,并通过 `viewer.objectManager` 获取 `SceneInstanceObject` / `FacilityInstanceObject` 后调用统一 `getSemanticBoundingBox()`、`setSemanticHighlight()`、`setSemanticVisible()` 和 `setSemanticOpacity()`。\n\n## `SemanticLoader`\n\n加载 `db/semantic_model.json` 楼层语义数据。`loadAsync()` 返回顶层 `SemanticGroup`,用于组织整次语义解析产生的建筑、楼层以及 scene-level facility layer。每个建筑包含多个 `FloorMesh`,每个楼层把墙、柱、空间、楼梯等语义对象合并为一个 TSL 材质驱动的网格;建筑级电梯井和通风井会使用 `ExtrudeMesh` 独立渲染。语义模型包含 `Facilities` 时,`SemanticLoader` 会额外读取 `SceneMetadata.json` 指向的 `tree_models`,按场景授权配置解密,再把对应设备模型挂载到所属楼层。\n\n```typescript\nimport { Vector3, Vector4 } from 'three';\nimport { SemanticLoader } from 'u-space/plugins/u-manager';\n\nconst loader = new SemanticLoader(viewer);\nloader.setPath('./scenes/my-scene');\nloader.setKey('YOUR_LICENSE_KEY'); // 官方授权场景解析 tree_models 时必需\n\nconst semanticGroup = await loader.loadAsync(); // SemanticGroup\nviewer.scene.add(semanticGroup);\n\nconst building = semanticGroup.getBuildingAt(0);\nconst floor = building.getFloorAt(0);\n\nbuilding.isolateFloor(floor);\nawait viewer.controls.flyToObject(floor);\n\nfloor.addEventListener('click', ({ event }) => {\n const { currentTarget, intersect } = event;\n if (!intersect) return;\n\n const index = intersect.semanticIndex;\n\n currentTarget.setColorAt(index, new Vector4(1, 0, 0, 0.5));\n currentTarget.setScaleAt(index, new Vector3(1, 0.1, 1));\n viewer.render();\n});\n```\n\n所有可按 ID 操作的实例都会尽量暴露统一的 `SemanticInstanceObject` API。楼层多边形语义使用轻量 `FloorSemanticInstanceObject` 代理合并几何中的一个实例;Facilities 和 SceneLoader path instancing 使用同一套模型实例化底层。业务代码优先使用 `setSemanticVisible()`、`setSemanticColor()`、`setSemanticOpacity()` 和 `getSemanticBoundingBox()`,而不是关心底层是合并几何、`InstancedMesh` 还是 fallback `Model`。\n\n### `SemanticGroup`\n\n`SemanticGroup` 继承自 `BaseGroup`,是单次 `SemanticParser` 解析结果的顶层容器。它管理所有 `BuildingGroup`,并把跨楼层共享的 Facilities `InstancedMesh` 渲染层作为建筑的同级对象挂在 `facilityLayer`,而不是挂到某个 `BuildingGroup` 内。\n\n建筑 ID 和设备 ID 查询使用内部 `Map` 索引维护;`getBuildingById()` 和 `getFacilityById()` 不会通过数组扫描查找语义对象。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `buildings` | 当前语义场景内的 `BuildingGroup[]`。 |\n| `facilityLayer` | scene-level 设备渲染层;同模型 URL 的静态设备会合并为 `InstancedMesh` batch。 |\n| `addBuilding(group)` / `removeBuilding(group)` | 添加或移除建筑,并同步更新 group 子节点。 |\n| `getBuildingAt(index)` / `getBuildingById(id)` / `getBuildings()` | 按下标、`Building.ID` 或整体列表获取建筑。 |\n| `floorMeshes` | 聚合返回所有建筑内的 `FloorMesh[]`。 |\n| `setFacilityLayer(layer)` | 设置跨楼层设备渲染层;传入 `null` 会移除已有 layer。 |\n| `getFacilityById(id)` | 在整次语义解析结果中按 `Facility.ID` 或显式别名查找设备。 |\n| `showAllFacilities()` / `hideAllFacilities()` | 显示或隐藏整次语义解析结果中的全部设备。 |\n| `showAllFloors()` | 显示所有建筑的所有楼层。 |\n| `planishFloors(kind?)` / `unplanishFloors(kind?)` | 压扁或恢复所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面附近,同时添加稳定的轻微 Y 偏移以减少共面闪烁;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |\n\n### `BuildingGroup`\n\n`BuildingGroup` 继承自 `BaseGroup`,用于组织一个建筑下的所有楼层、电梯井和通风井。设备语义对象不会直接挂到 `BuildingGroup`;能 instancing 的设备会渲染到 `SemanticGroup.facilityLayer`,同时在对应 `FloorMesh` 下保留可检索、可控制的轻量引用。\n\n建筑内设备 ID 到楼层的关系由内部 `Map` 索引维护,并通过楼层设备索引版本自动同步。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `floorMeshes` | 当前建筑内的 `FloorMesh[]`。 |\n| `elevatorMeshes` | 当前建筑内由 `Elevators` 语义生成的 `ExtrudeMesh[]`。 |\n| `ventMeshes` | 当前建筑内由 `Vents` 语义生成的 `ExtrudeMesh[]`。 |\n| `addFloor(floor)` | 添加楼层,并同步加入 group。 |\n| `removeFloor(floor)` | 移除楼层,并同步从 group 移除。 |\n| `getFloorAt(index)` | 按楼层下标获取 `FloorMesh`。 |\n| `getFloorById(id)` | 按楼层语义 ID 获取 `FloorMesh`,内部使用 `Map` 索引。 |\n| `addElevator(elevator)` / `removeElevator(elevator)` | 添加或移除电梯井,并同步更新 group。 |\n| `getElevatorAt(index)` | 按下标获取电梯井 `ExtrudeMesh`。 |\n| `getElevatorById(id)` | 按电梯井语义 ID 获取电梯井,内部使用 `Map` 索引。 |\n| `addVent(vent)` / `removeVent(vent)` | 添加或移除通风井,并同步更新 group。 |\n| `getVentAt(index)` | 按下标获取通风井 `ExtrudeMesh`。 |\n| `getVentById(id)` | 按通风井语义 ID 获取通风井,内部使用 `Map` 索引。 |\n| `isolateFloor(floor \\| index)` | 只显示指定楼层,隐藏其他楼层;也兼容传入楼层数组。 |\n| `isolateFloors(floors \\| indexes)` | 只显示指定多个楼层,隐藏其他楼层。 |\n| `showAllFloors()` | 显示全部楼层。 |\n| `getFacilityById(id)` | 在当前建筑的楼层中按 `Facility.ID` 或显式别名查找设备。 |\n| `showAllFacilities()` | 显示整栋建筑内全部楼层设备。 |\n| `hideAllFacilities()` | 隐藏整栋建筑内全部楼层设备。 |\n| `planishFloors(kind?)` | 压扁所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面附近,同时添加稳定的轻微 Y 偏移以减少共面闪烁;传入 `kind` 时只压扁该语义类型,`kind` 可包含 `Facilities`。 |\n| `unplanishFloors(kind?)` | 恢复所有楼层;默认恢复所有合并语义实例和 Facilities;传入 `kind` 时只恢复该语义类型,`kind` 可包含 `Facilities`。 |\n\n### 电梯井和通风井\n\n`SemanticLoader` 会读取 `semantic_model.json` 中建筑引用的 `Elevators` 和 `Vents`。每个井道使用 `Polygon.shape` 作为底面轮廓,`Elevation` 作为底面高度,`TotalHeight` 作为拉伸高度,并以 building 级 `ExtrudeMesh` 加入 `BuildingGroup`。\n\n```typescript\nconst elevator = building.getElevatorAt(0);\nconst elevatorById = building.getElevatorById('ELEVATOR_001');\nconst vent = building.getVentAt(0);\nconst ventById = building.getVentById('VENT_001');\n\nif (elevator) {\n await viewer.controls.flyToObject(elevator);\n}\n\nif (vent) {\n building.removeVent(vent);\n}\n```\n\n电梯井和通风井会在渲染阶段沿法线轻微内收,减少与墙体共面时的闪面。`Spaces` 实例也会使用稳定的 per-instance 渲染偏移抖动,缓解完全重叠空间之间的 z-fighting;这些偏移只影响渲染顶点,不改变语义 ID、实例矩阵和包围体查询的使用方式。\n\n### 设施设备\n\n`SemanticLoader` 会从 `Stories[].Facilities` 读取设备索引,再从顶层 `Facilities` 数组取得 `Facility` 数据,并使用 `Facility.ID` 在解密后的 `tree_models` 中查找同 ID 节点。只有带 `renderType: '3D'` 和模型 `path` 的节点会被加载。\n\n`tree_models.matrix` 是相对父节点的本地矩阵;`SemanticLoader` 会沿树父级累乘得到设备世界矩阵,再转换为对应 `FloorMesh` 的局部矩阵。因此楼层移动、隔离或显示隐藏时设备会跟随楼层一起工作。即使某个 story 只有 `Facilities`、没有墙柱空间等合并几何,也会创建一个空的 `FloorMesh` 作为设备容器。\n\nFacilities 会在单次 `SemanticParser` 解析范围内按模型 URL 自动分组。静态模型会被转换为 scene-level `InstancedMesh` batch 并挂到 `SemanticGroup.facilityLayer`;每个设备仍会在所属 `FloorMesh` 下保留一个 `FacilityInstanceObject` 语义实例引用,用于 `getFacilityById()`、显隐、颜色、透明度、包围盒和 `viewer.objectManager` 检索。设备 batch 使用普通 `Group` 包裹,以保证每帧渲染前都能执行相机实例裁剪和 hide/show 后的实例同步;带动画、骨骼、morph target 或缺少合法 `geometry.groups` 的多材质 Mesh 会自动回退为普通 `Model`,但普通 `Model` 也会挂到同一个 `FacilityInstanceObject` wrapper 下,对外 API 不变。\n\n`facilityLayer` 使用 `FacilityInstancedLayer`,并继承自 `BaseGroup`。当 `facilityLayer.visible = false` 时,layer 会阻止内部 `InstancedMesh` 继续参与射线检测,避免隐藏的批处理设备仍被点击命中;单个设备的显隐应先通过 `getFacilityById()` 或 `viewer.objectManager.getById()` 取回实例,再调用 `setSemanticVisible()` 控制。\n\nInstanced 设备通过 per-instance opacity attribute 控制单个设备透明度。batch 材质默认沿用源材质的透明状态;只有源材质本身透明,或当前参与渲染的设备存在 `opacity < 1` 时,材质才会切到 `transparent: true`,`setSemanticOpacity(1)` 可在没有其他半透明实例时回到不透明渲染队列。`resetSemanticColor()` 只清除颜色 override,不影响透明度 override。`FacilityInstancedLayer` 会在设备显隐、颜色、透明度、floor planish/unplanish 改变设备 transform,或相机矩阵、投影矩阵、viewport 高度变化时,在下一次渲染前同步实例矩阵、颜色、透明度和当前 active instance count。普通 fallback `Model` 的颜色和透明度控制由 wrapper 委托到 `MaterialEffects`,单材质和多材质 Mesh 都会应用 override。\n\n加载成功后,设备引用会写入 `userData.facilityId`、`semanticId`、`semanticKind: 'Facilities'`、`semanticName`、`spaces`、`twinsIdentifier`、`storyId` 和 `floorIndex`,并按 `Facility.ID` 注册到 `viewer.objectManager`。自动 instancing 的引用还会带有 `userData.instanced: true` 和 `userData.modelUrl`。\n\n```typescript\nimport { Box3 } from 'three';\n\nconst floor = building.getFloorAt(0);\nconst box = new Box3();\n\nconst facility = floor.getFacilityById('FACILITY_001') ?? viewer.objectManager.getById('FACILITY_001');\nconst facilityEntity = floor.getSemanticById('FACILITY_001');\n\nif (facility && facilityEntity?.type === 'object') {\n const facilityBox = facility.getSemanticBoundingBox(box, true);\n\n await viewer.controls.flyToBox(facilityBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n}\n\nconst facilities = floor.getSemanticsByKind('Facilities');\n\nfacility\n .setSemanticColor('#ff5533')\n .setSemanticOpacity(0.45)\n .resetSemanticColor()\n .setSemanticVisible(true);\n```\n\n对 Facilities 推荐使用 `controls.flyToBox()` 飞向设备包围盒。无论设备实际渲染来自 `InstancedMesh` 还是 fallback `Model`,都可以通过 `getSemanticBoundingBox(box, true)` 取得完整世界包围盒。\n\n### `FacilityInstanceObject`\n\n`FacilityInstanceObject` 继承自统一的 `SemanticInstanceObject`,表示一个设备语义实例。它会挂在所属 `FloorMesh` 下,用于 ID 检索、事件派发、显隐、颜色、透明度和包围盒查询;如果设备可以 instancing,真正几何由 `SemanticGroup.facilityLayer` 里的 `InstancedMesh` 统一渲染;如果不能 instancing,fallback `Model` 会作为它的子对象挂载。\n\n通常不需要手动创建 `FacilityInstanceObject`。`SemanticParser` 在解析 `Facilities` 时会自动创建它,并写入 `userData.facilityId`、`semanticId`、`semanticKind: 'Facilities'`、`semanticName`、`spaces`、`twinsIdentifier`、`storyId`、`floorIndex`、`instanced` 和 `modelUrl`。`userData.instanced` 表示当前设备是否由 `InstancedMesh` 渲染;fallback 时仍然保留同一套语义实例 API。\n\n加载完成后,设备可以按 `Facility.ID` 从全局 `objectManager` 取回。推荐使用 `getSemanticBoundingBox(box, true)` 取得完整世界包围盒,再调用 `viewer.controls.flyToBox()`。\n\n```typescript\nimport { Box3 } from 'three';\nimport { FacilityInstanceObject } from 'u-space/plugins/u-manager';\n\nconst facility = viewer.objectManager.getById<FacilityInstanceObject>('FACILITY_001');\n\nif (facility?.isFacilityInstanceObject) {\n const box = facility.getSemanticBoundingBox(new Box3(), true);\n\n await viewer.controls.flyToBox(box, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n enableTransition: true,\n });\n}\n```\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `isFacilityInstanceObject` | 类型标记,值为 `true`。 |\n| `type` | Three.js 对象类型名,值为 `'FacilityInstanceObject'`。 |\n| `setSemanticBounds(bounds)` | 设置模板在引用本地空间内的包围盒,并返回自身;主要由 `SemanticModelInstancedLayer.addSemanticBatch()` 在建 batch 时写入。 |\n| `getSemanticBoundingBox(target?, world?)` | 获取完整包围盒。`world = true` 时会应用 `matrixWorld`,适合传给 `viewer.controls.flyToBox()`;没有 bounds 时返回 empty `Box3`。 |\n| `setSemanticVisible(visible)` | 设置单个语义实例的 `visible`,并返回自身;渲染和射线检测都会跳过不可见引用。 |\n| `setSemanticColor(color)` | 设置单个语义实例的颜色 override,并返回自身。`color` 支持 Three.js `ColorRepresentation`。 |\n| `resetSemanticColor()` | 清除颜色 override,恢复使用源材质颜色,并返回自身;不会清除透明度 override。 |\n| `setSemanticOpacity(opacity)` | 设置单个语义实例透明度,并返回自身;值会被限制在 `0..1`。 |\n| `getSemanticColor(target?)` | 读取当前颜色 override;没有 override 时返回白色 `(1, 1, 1)`。 |\n| `hasSemanticColor()` | 判断当前实例是否存在颜色 override。 |\n| `getSemanticOpacity()` | 读取当前透明度 override。 |\n\n```typescript\nimport { Box3 } from 'three';\nimport { FacilityInstanceObject } from 'u-space/plugins/u-manager';\n\nconst box = new Box3();\nconst facility = floor.getFacilityById('FACILITY_001');\n\nif (facility instanceof FacilityInstanceObject) {\n facility\n .setSemanticColor('#29ccff')\n .setSemanticOpacity(0.6)\n .setSemanticVisible(true);\n\n await viewer.controls.flyToBox(facility.getSemanticBoundingBox(box, true), {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n}\n```\n\n### `FacilityInstancedLayer`\n\n`FacilityInstancedLayer` 继承自 `SemanticModelInstancedLayer`,是 scene-level Facilities 的批量渲染层。`SemanticGroup.facilityLayer` 默认就是该类型;它会按模型 URL 把同一模板的静态设备合并为一个或多个 `InstancedMesh`,并用普通 `Group` 包裹每个模型 URL batch,保证设备显隐、颜色、透明度和相机实例裁剪能在每帧渲染前同步,同时保留每个楼层下的 `FacilityInstanceObject` 引用用于业务 API 和事件冒泡。\n\n使用 `SemanticLoader` 时通常不需要直接调用 `addSemanticBatch()`;只有自定义语义解析或自建设备 batch 时才需要手动创建 layer,然后通过 `semanticGroup.setFacilityLayer(layer)` 挂回语义场景。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `isFacilityInstancedLayer` | 类型标记,值为 `true`。 |\n| `type` | Three.js 对象类型名,值为 `'FacilityInstancedLayer'`。 |\n| `name` | 构造函数默认设为 `'Facilities'`。 |\n| `getInstanceCulling()` | 返回当前实例裁剪配置:`enabled`、`frustum`、`minScreenRadius`。 |\n| `setInstanceCulling(options)` | 设置实例裁剪配置,并返回自身。默认 `enabled: false`、`frustum: true`、`minScreenRadius: 0`;默认不按相机裁剪设备,避免相机距离影响设备显隐。需要性能压缩时可设置 `enabled: true` 开启视锥裁剪,或再把 `minScreenRadius` 设为大于 0 的值开启屏幕尺寸裁剪。 |\n| `addSemanticBatch(url, template, instances)` | 尝试把同一模型 URL 的语义实例引用合并为 instanced batch。成功返回 `true`,失败返回 `false`,失败时调用方应回退为普通模型渲染。 |\n\n`addSemanticBatch(url, template, instances)` 会从 `template` 收集可 instancing 的可见 `Mesh`,克隆源材质,并为每个 batch 建立 instance matrix、颜色和透明度 attribute。没有动画、没有骨骼、没有 morph target,且每个多材质 `Mesh` 都有合法 `geometry.groups` 的模板会进入 instancing;不满足条件、模板没有可用 Mesh 或 `instances` 为空时会返回 `false`。\n\n渲染前,layer 会同步每个 `FacilityInstanceObject` 的世界矩阵、颜色和透明度,并只在数据变化时上传对应 buffer。默认情况下,相机移动不会改变设备 active instance 集合;显式调用 `setInstanceCulling({ enabled: true })` 后,layer 才会按当前渲染相机逐实例压缩 `InstancedMesh.count`,视锥外设备不会进入本帧实例 buffer;只有同时设置 `minScreenRadius > 0` 时,屏幕半径小于该阈值的设备才会被跳过。相机矩阵、投影矩阵或 viewport 高度未变化时不会重复压缩;设备显隐、透明度为 0、颜色/透明度变化或 `planish('Facilities')` / `unplanish('Facilities')` 改变 transform 时会标记 batch dirty。全部设备不可渲染时,内部 `InstancedMesh.visible` 会被关闭;只有被当前相机裁掉时,mesh 会保留可见并把 `count` 设为 0,以便相机移动后自动恢复。射线检测命中 batch 内实例时,`hit.object` 会被改写为对应的 `FacilityInstanceObject`,并附加 `semanticObject`、`semanticId`、`semanticKind: 'Facilities'`、`semanticName` 和 `semanticIndex`,事件随后会按楼层引用对象继续冒泡。\n\n```typescript\nimport { FacilityInstancedLayer, FacilityInstanceObject } from 'u-space/plugins/u-manager';\n\nconst layer = new FacilityInstancedLayer();\nconst refs = facilityItems.map(() => new FacilityInstanceObject());\n\nif (layer.addSemanticBatch('/models/camera.glb', templateObject, refs)) {\n semanticGroup.setFacilityLayer(layer);\n}\n```\n\n如果只想整体隐藏或禁用 scene-level batch,可以设置 `semanticGroup.facilityLayer.visible = false`;如果只想控制单个设备,推荐从 `floor.getFacilityById(id)` 或 `viewer.objectManager.getById(id)` 取回 `FacilityInstanceObject` 后调用 `setSemanticVisible()` / `setSemanticOpacity()`。\n\n### `SemanticModelInstancedLayer`\n\n`SemanticModelInstancedLayer` 是 `SceneInstancedLayer` 和 `FacilityInstancedLayer` 的共享实现。它负责模板 mesh 收集、材质克隆、`InstancedMesh` 创建、instance matrix/color/opacity buffer 同步、raycast hit remap、fallback 判定和可选相机实例裁剪。通常业务代码不需要直接使用它,除非要为新的语义实例类型复用同一套模型 instancing 能力。\n\n### `FloorMesh`\n\n`FloorMesh` 继承自 `BaseMesh`,表示一个楼层。它不是 `BatchedMesh`,而是把同一楼层内的语义对象合并为一份几何,并通过 TSL + `DataTexture` 在 GPU 侧按 `semanticIndex` 控制颜色、透明度、显示隐藏和实例矩阵。楼层语义网格会按实例透明度拆分为不透明和透明两个材质通道;墙、柱、门等默认不透明实例会进入 opaque pipeline,`Spaces`、`Windows` 或通过 `setOpacityAt()` 改成半透明的实例会进入 transparent pipeline。Facilities 通过楼层下的引用对象进行检索和控制;实际渲染可能来自 `SemanticGroup.facilityLayer` 的 `InstancedMesh` batch,也可能是 fallback 的普通 `Model`。\n\n这种结构的目标是让每个楼层通常只占一个主渲染 draw call,同时仍保留实例级控制能力。`xxxAt` 方法全部作用于单个语义实例;没有 `At` 后缀的方法作用于整个楼层 mesh。\n\n| 属性 / 方法 | 说明 |\n| :---------- | :--- |\n| `semanticCount` / `instanceCount` | 当前楼层语义实例数量。 |\n| `semanticInstances` | `Map<string, number>`,从语义对象 ID 映射到实例下标。 |\n| `wallsInstances` / `columnsInstances` / `spacesInstances` / `doorsInstances` / `windowsInstances` / `staircasesInstances` | 按语义类型维护的 ID 到实例下标映射。 |\n| `semanticEntities` | `Map<string, FloorSemanticEntity>`,统一索引楼层内合并几何语义和 `Facilities` 对象语义。 |\n| `facilityObjectsById` | `Map<string, FacilityInstanceObject>`,按 `Facility.ID` 或显式别名查找设备引用。 |\n| `facilityObjects` | 当前楼层挂载的设备引用数组。 |\n| `getSemanticIndexById(id)` | 根据语义 ID 获取实例下标。 |\n| `getSemanticById(id)` | 根据语义 ID 或设备别名获取统一语义实体。 |\n| `getSemantics()` | 获取楼层内全部语义实体,包含合并几何和设备对象。 |\n| `getSemanticsByKind(kind)` | 按语义类型过滤实体;`kind` 可以是 `Walls`、`Columns`、`Spaces`、`Doors`、`Windows`、`Staircases` 或 `Facilities`。 |\n| `getSemanticIdAt(index)` | 获取实例语义 ID。 |\n| `getSemanticKindAt(index)` | 获取合并几何实例类型:`'Walls' \\| 'Columns' \\| 'Spaces' \\| 'Doors' \\| 'Windows' \\| 'Staircases'`。 |\n| `getSemanticNameAt(index)` | 获取实例名称;当前 `Spaces` 会从语义数据的 `Name` 写入,其他类型可能为 `undefined`。 |\n| `getSemanticObjectAt(index)` | 获取合并几何实例对应的 `FloorSemanticInstanceObject` 轻量对象。 |\n| `showAllFacilities()` | 显示当前楼层的全部设备对象。 |\n| `hideAllFacilities()` | 隐藏当前楼层的全部设备对象。 |\n| `addFacility(object, ids?)` | 把设备对象挂到楼层,并按显式 ID、`facilityId`、`semanticId`、`id` 建立检索别名。 |\n| `getFacilityById(id)` | 根据 `Facility.ID` 或别名获取设备对象。 |\n| `getFacilityAt(index)` | 按楼层设备数组下标获取设备对象。 |\n| `getFacilities()` | 获取当前楼层全部设备对象。 |\n| `removeFacility(facility)` | 按设备对象或 ID 从楼层移除设备,并同步清理检索索引。 |\n| `setColorAt(index, color)` / `getColorAt(index, target?)` | 修改或读取实例颜色,支持 `Color`、`Vector3`、`Vector4`。 |\n| `setOpacityAt(index, opacity)` / `getOpacityAt(index)` | 修改或读取实例透明度。 |\n| `setVisibleAt(index, visible)` / `getVisibleAt(index)` | 修改或读取实例显隐状态。 |\n| `setMatrixAt(index, matrix)` / `getMatrixAt(index, target?)` | 设置或读取实例附加矩阵。 |\n| `setScaleAt(index, scale, y?, z?)` | 修改实例缩放,支持 `number` 或 `Vector3`。 |\n| `setScaleYAt(index, y)` | 只修改实例 Y 轴缩放,保留 X/Z 缩放和已有位移、旋转。 |\n| `getFinalMatrixAt(index, target?)` | 读取实例最终矩阵,包含语义对象原始基点矩阵。 |\n| `getBoundingBoxAt(index, target?, world?)` | 获取实例包围盒;`world = true` 时包含 `FloorMesh.matrixWorld`。 |\n| `getBoundingSphereAt(index, target?, world?)` | 获取实例包围球;`world = true` 时包含 `FloorMesh.matrixWorld`。 |\n| `computeBoundingBox()` / `computeBoundingSphere()` | 计算整个楼层的包围体。 |\n| `planish(kind?)` / `unplanish(kind?)` | 压扁或恢复楼层内所有合并语义实例和 Facilities;压平时按各自包围盒贴到楼层平面附近,并加入稳定的轻微 Y 偏移;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |\n\n### 飞向语义实例\n\n点击、射线检测命中 `FloorMesh` 里的语义几何或设备时,`intersect` 上会附加语义字段:`semanticIndex`、`semanticId`、`semanticKind` 和 `semanticObject`。普通楼层语义几何的事件目标是 `FloorSemanticInstanceObject`;instanced Facilities 的事件目标是楼层下的 `FacilityInstanceObject` 引用,事件会继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticGroup`。因此楼层监听器中应使用 `event.currentTarget` 操作楼层,用 `intersect.semanticObject` 或 `event.target` 取得具体语义实例。\n\n```typescript\nimport { Box3 } from 'three';\n\nconst box = new Box3();\n\nfloor.addEventListener('click', async ({ event }) => {\n const { currentTarget, intersect } = event;\n if (!intersect) return;\n\n if (intersect.semanticKind === 'Facilities') {\n const facility = intersect.semanticObject ?? event.target;\n const facilityBox = facility.getSemanticBoundingBox(box, true);\n\n await viewer.controls.flyToBox(facilityBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n return;\n }\n\n const semanticBox = intersect.semanticObject?.getSemanticBoundingBox(box, true)\n ?? currentTarget.getBoundingBoxAt(intersect.semanticIndex, box, true);\n\n if (semanticBox) {\n await viewer.controls.flyToBox(semanticBox, {\n viewpoint: 'rightFrontTop',\n padding: 0.2,\n });\n }\n});\n```\n\n如果要根据 ID 操作对象,先通过 `getSemanticIndexById(id)` 转为实例下标。\n\n```typescript\nconst index = floor.getSemanticIndexById('SPACE_001');\n\nif (index !== undefined) {\n floor.setVisibleAt(index, false);\n viewer.render();\n}\n```\n\n### 楼层压扁\n\n`planish()` / `unplanish()` 默认作用于当前楼层的全部合并语义实例,包含墙、柱、空间、门窗、楼梯等语义几何,也包含楼层下的 Facilities 引用;传入 `kind` 时只处理该类型,例如 `floor.planish('Walls')` 或 `floor.planish('Facilities')`。所有被压平的实例都会按自身包围盒把压平后的薄片贴到楼层平面 `FloorMesh.pivot.y` 附近,而不是围绕实例自身基点压缩;压平时还会按语义类型和实例 ID 加入稳定的轻微 Y 偏移,减少门、墙或其他重叠实例之间的共面闪烁。`unplanish()` 会恢复合并几何实例的原始矩阵,`unplanish('Facilities')` 会恢复设备原始 `position.y` 和 `scale.y`。instanced Facilities 会通过楼层下的 `FacilityInstanceObject` transform 同步到 `SemanticGroup.facilityLayer`。\n\n如果只想调整单个合并几何实例,可以使用 `setScaleAt()` 或 `setScaleYAt()`,它们会保留该语义对象自己的基点矩阵,因此压扁墙、柱、房间时不会被压到世界原点。\n\n## `SceneLoader`\n\n从服务端场景包加载完整场景树(模型、组、基础形状),并自动将所有已加载对象按 `id` 和 `sid` 注册到 `viewer.objectManager`。\n默认会尝试读取同一路径下的 `db/semantic_model.json`,如果场景树节点的 `id` 已存在于语义文件中,则跳过该节点,方便和 `SemanticLoader` 同时加载而不重复创建建筑或设备。\n对语义去重后仍保留的 3D 节点,`SceneLoader` 默认会按模型 `path` 自动合并重复静态模型:同一 `path` 的多个实例只加载一次模板,并由 `SceneInstancedLayer` 通过共享的 `SemanticModelInstancedLayer` 批量渲染。原场景树中仍会保留每个 `id` / `sid` 对应的 `SceneInstanceObject` 逻辑对象,用于业务检索、显隐、颜色、透明度、包围盒和事件派发。\n\n模板包含动画、骨骼、morph target、非法多材质 groups 或没有可实例化网格时,会自动回退为普通 `Model` 渲染;fallback `Model` 会挂在同一个 `SceneInstanceObject` 下,因此调用侧不需要额外配置。\n\n```typescript\nimport { SceneLoader } from 'u-space/plugins/u-manager';\n\nconst sceneLoader = new SceneLoader(viewer);\nsceneLoader.setPath('./scenes/my-scene');\nsceneLoader.setKey('YOUR_LICENSE_KEY'); // 官方授权场景必需\nconst group = await sceneLoader.loadAsync();\nviewer.scene.add(group);\n```\n\n**方法:**\n\n| 方法 | 说明 |\n| :------------------ | :------------------------------------------------------------------- |\n| `setKey(key)` | 设置授权场景的 RSA 解密密钥。 |\n| `loadAsync()` | 加载并解析场景,返回去除语义重复节点后的 `Group`。 |\n| `clearCache()` | 从 `objectManager` 中移除此加载器注册的所有 ID。 |\n| `dispose()` | 清除缓存并释放水印叠加层。 |\n\n### `SceneInstanceObject`\n\n`SceneInstanceObject` 继承自统一的 `SemanticInstanceObject`,表示一个由 `SceneInstancedLayer` 批量渲染或 fallback 普通渲染的场景模型引用。它会保留在原场景树层级中,并注册到 `viewer.objectManager`,因此 `getById()`、`show()` / `hide()`、`isolate()`、`showAll()`、`setOpacity()` 和 `getBoundingBox()` 可以继续按单个模型 ID 使用。\n\n`SceneInstanceObject` 本身只增加场景模型语义:`isSceneInstanceObject = true`、`type = 'SceneInstanceObject'`,并把 `userData.semanticKind` 设为 `SceneInstances`。加载器会把场景树节点的 `id` 和 `sid` 都注册到 `viewer.objectManager`,因此同一个对象可以通过任一 ID 取回。对重复模型的 instanced 路径,`userData.instanced = true`,并带有 `modelPath`、`modelUrl`、`semanticId` 和 `semanticName`;如果模板不支持 instancing,会退回普通 `Model`,但仍挂在同一个 `SceneInstanceObject` 下,对外 API 不变。\n\n**识别字段:**\n\n| 字段 | 说明 |\n| :--- | :--- |\n| `isSceneInstanceObject` | 固定为 `true`,用于判断对象是否来自 `SceneLoader` 的场景实例。 |\n| `isSemanticInstanceObject` | 固定为 `true`,表示它支持统一语义实例 API。 |\n| `type` | 固定为 `SceneInstanceObject`。 |\n| `userData.id` / `userData.sid` | 原始场景树节点 ID;两个 ID 都会注册到 `viewer.objectManager`。 |\n| `userData.semanticId` | 语义事件和 raycast remap 使用的实例 ID,默认等于场景树节点 `id`。 |\n| `userData.semanticKind` | 固定为 `SceneInstances`。 |\n| `userData.semanticName` | 原始场景树节点名称。 |\n| `userData.instanced` | `true` 表示实际渲染来自 `SceneInstancedLayer`;`false` 表示 fallback `Model` 挂在当前对象下。 |\n| `userData.modelPath` / `userData.modelUrl` | instanced 场景实例对应的模型相对路径和完整 URL。 |\n\n**方法:**\n\n| 方法 | 说明 |\n| :--- | :--- |\n| `setSemanticBounds(bounds)` | 设置本地包围盒。`SceneLoader` 会在创建 instanced batch 时根据模板模型自动设置;业务一般不需要手动调用。 |\n| `setSemanticRenderObject(object)` | 设置 fallback 渲染对象并作为子对象挂载。模板无法 instancing 时由 `SceneLoader` 自动调用;自定义语义实例渲染时可手动使用。 |\n| `getSemanticRenderObject()` | 返回 fallback 渲染对象;instanced 渲染路径通常返回 `null`,因为真实 Mesh 在 `SceneInstancedLayer` 中。 |\n| `getSemanticBoundingBox(target?, world?)` | 返回实例包围盒。`world = true` 时会应用 `matrixWorld`,适合直接传给 `viewer.controls.flyToBox()`;无 bounds 和 render object 时返回 empty `Box3`。 |\n| `setSemanticVisible(visible)` | 设置单个实例显隐并标记 batch dirty;隐藏后该实例不会继续渲染,也不会被 instanced raycast 命中。 |\n| `setSemanticColor(color)` | 设置单个实例颜色 override。instanced 路径写入 per-instance color;fallback `Model` 路径会委托到材质高亮逻辑。 |\n| `resetSemanticColor()` | 清除颜色 override,恢复使用源模型颜色;不会清除透明度 override。 |\n| `setSemanticOpacity(opacity)` | 设置单个实例透明度,值会限制在 `0..1`。instanced 路径写入 per-instance opacity;fallback 路径会按原始材质透明度相乘。 |\n| `getSemanticColor(target?)` | 获取当前生效颜色。存在颜色或高亮 override 时返回该颜色,否则返回白色。传入 `Color` 可复用对象。 |\n| `hasSemanticColor()` | 返回当前是否存在颜色或高亮颜色 override。 |\n| `getSemanticOpacity()` | 获取当前生效透明度;高亮存在时返回高亮透明度,否则返回基础透明度。 |\n| `setSemanticHighlight(color, opacity, overwrite?)` | 设置临时高亮样式。`overwrite = false` 时按 tint 模式与原色混合,`true` 时直接替换颜色;高亮会覆盖基础颜色/透明度直到调用 `clearSemanticHighlight()`。 |\n| `clearSemanticHighlight()` | 清除临时高亮,并恢复到基础颜色/透明度状态。 |\n| `getSemanticColorMode()` | 返回当前颜色模式:`SEMANTIC_COLOR_MODE_NONE`、`SEMANTIC_COLOR_MODE_OVERRIDE` 或 `SEMANTIC_COLOR_MODE_TINT`。 |\n| `onSemanticRenderDirty(callback)` | 监听实例渲染状态变化,返回取消监听函数。实例显隐、颜色、透明度或世界矩阵变化时会触发。 |\n| `markSemanticRenderDirty()` | 手动标记实例渲染状态已变化,通知所属 batch 在下一帧同步 instance buffer。 |\n\n`MaterialEffects.highlightColor()` / `removeHighlightColor()` 会识别 `SceneInstanceObject` 并调用 `setSemanticHighlight()` / `clearSemanticHighlight()`,不会直接修改共享 batch 材质。`ObjectManager.setOpacity()`、`ObjectManager.hide()`、`ObjectManager.show()` 也会通过统一 API 作用到单个实例。\n\n加载完成后可以按场景树节点 `id` 从 `objectManager` 取回 `SceneInstanceObject`,再用 `getSemanticBoundingBox(box, true)` 取得世界包围盒并传给 `viewer.controls.flyToBox()`。`SceneInstanceObject` 内部带有不可见的本地 bounds,因此不需要加载真实 Mesh 副本也能计算飞行包围盒。\n\n```typescript\nimport { Box3 } from 'three/webgpu';\nimport { SceneInstanceObject } from 'u-space/plugins/u-manager';\n\nconst object = viewer.objectManager.getById<SceneInstanceObject>('SCENE_NODE_ID');\n\nif (object?.isSceneInstanceObject) {\n const box = object.getSemanticBoundingBox(new Box3(), true);\n await viewer.controls.flyToBox(box, {\n viewpoint: 'current',\n padding: 0.2,\n enableTransition: true,\n });\n}\n```\n\n颜色、透明度和显隐可以直接链式调用:\n\n```typescript\nobject\n ?.setSemanticColor('#29ccff')\n .setSemanticOpacity(0.55)\n .setSemanticVisible(true);\n\nobject?.setSemanticHighlight('#ffb703', 0.75, true);\nobject?.clearSemanticHighlight();\nobject?.resetSemanticColor();\n```\n\n如果需要自己控制包围盒,也可以取世界包围盒后调用 `flyToBox()`:\n\n```typescript\nimport { Box3 } from 'three/webgpu';\n\nconst box = object.getSemanticBoundingBox(new Box3(), true);\nawait viewer.controls.flyToBox(box, { viewpoint: 'frontTop', padding: 0.2 });\n```\n\n射线检测命中批处理实例时,`intersect.object` 会被改写为对应的 `SceneInstanceObject`,并附加 `semanticObject`、`semanticId`、`semanticKind: 'SceneInstances'` 和 `semanticIndex`,事件会按逻辑对象所在的原场景树继续冒泡。\n\n### `SceneInstancedLayer`\n\n`SceneInstancedLayer` 是 `SceneLoader` 内部使用的批量渲染层,默认 `name = 'SceneInstances'`。它继承自 `SemanticModelInstancedLayer`,每个重复模型 URL 会生成一个 batch,batch 内按模板的可实例化 Mesh 创建 `InstancedMesh`。渲染前只在实例矩阵、显隐、颜色或透明度变化时同步 instance buffer;普通相机移动不会重新上传所有实例数据。\n\n## `TopologiesLoader` / `TopologyParser`\n\n加载拓扑图数据并将其转换为 `Topology` 对象。\n\n```typescript\nimport { TopologiesLoader } from 'u-space/plugins/u-manager';\n\nconst loader = new TopologiesLoader();\nloader.setPath('./scenes/my-scene');\nconst topologies = await loader.loadAsync(); // Topology[]\nviewer.scene.add(...topologies);\n```\n\n## `VisionsLoader` / `VisionsParser`\n\n加载命名相机视点,并将相机飞行到指定视点。\n\n```typescript\nimport { VisionsLoader, VisionsParser } from 'u-space/plugins/u-manager';\n\nconst visionsLoader = new VisionsLoader();\nvisionsLoader.setPath('./scenes/my-scene');\nconst visionsData = await visionsLoader.loadAsync();\n// visionsData 是 Record<string, IVisions[]>\n\nconst visionsParser = new VisionsParser(viewer);\n\n// 飞行到指定视点\nawait visionsParser.flyTo(visionsData['HOME'][0]);\n\n// 飞行到主(默认)视点\nawait visionsParser.flyToPrimary(visionsData['HOME']);\n```\n\n**`IVisions` 字段:**\n\n| 字段 | 类型 | 说明 |\n| :--------- | :------------ | :------------------------------ |\n| `camera` | `'P' \\| 'O'` | 相机类型:透视或正交。 |\n| `position` | `IVector3` | 相机世界位置。 |\n| `target` | `IVector3` | 相机朝向目标点。 |\n| `zoom` | `number` | 相机缩放级别。 |\n| `primary` | `boolean` | 是否为默认视点。 |\n\n## `AnimationsLoader` / `AnimationsParser`\n\n加载关键帧动画数据,并通过 `tweenAnimation` 驱动 `Object3D` 的变换。\n\n```typescript\nimport { AnimationsLoader, AnimationsParser } from 'u-space/plugins/u-manager';\n\nconst animLoader = new AnimationsLoader();\nanimLoader.setPath('./scenes/my-scene');\nconst animationsData = await animLoader.loadAsync(); // IAnimations[]\n\n// 查找特定对象的动画\nconst data = animationsData.find((a) => a.modelId === myModel.userData.id);\n\nconst parser = new AnimationsParser(viewer, myModel);\nparser.initTransform(); // 保存初始位置/旋转/缩放\n\nawait parser.play(data.keyframes); // 播放动画序列\n\n// 中途停止\nparser.stop();\n\n// 重置到初始变换\nparser.reset();\n```\n\n## `PropertiesLoader`\n\n加载与模型关联的结构化属性元数据(如 BIM 属性)。\n\n```typescript\nimport { PropertiesLoader } from 'u-space/plugins/u-manager';\n\nconst propsLoader = new PropertiesLoader();\npropsLoader.setPath('./scenes/my-scene');\nconst properties = await propsLoader.loadAsync(); // IProperties[]\n\n// 查找模型的属性\nconst modelProps = properties.filter(p => p.modelId === myModel.userData.id);\n```\n\n**`IProperties` 字段:**\n\n| 字段 | 类型 | 说明 |\n| :-------- | :--------------- | :----------------------- |\n| `modelId` | `string` | 关联模型的 ID。 |\n| `group` | `string` | 属性分组/类别名称。 |\n| `key` | `string` | 属性键名。 |\n| `value` | `string \\| null` | 属性值。 |\n| `label` | `string \\| null` | 属性的显示标签。 |\n"
865
962
  },
866
963
  {
867
964
  "id": "api-render-pipeline",
@@ -1015,7 +1112,7 @@ export const docsIndex = [
1015
1112
  "text": "管理方法"
1016
1113
  }
1017
1114
  ],
1018
- "content": "# Tools API\n\n`u-space` 提供了一组实用工具类,包括测量、剖切和标注功能。\n\n## MeasureTool\n\n用于 3D 场景中的距离测量、面积测量和角度测量,测量结果会以可视化线条渲染到场景中。\n\n```typescript\nimport { MeasureTool } from 'u-space';\n\nconst measureTool = new MeasureTool(viewer.scene);\n```\n\n### `measureDistance(pointA, pointB, options?)`\n\n测量两点之间的距离,并在场景中绘制连线。\n\n```typescript\nconst result = measureTool.measureDistance(\n { x: 0, y: 0, z: 0 },\n { x: 5, y: 0, z: 5 },\n { lineColor: 0xffff00 },\n);\nconsole.log(result.value, result.unit); // 7.071 m\n```\n\n### `measureArea(points, options?)`\n\n测量由 3 个或更多共面点围成的多边形面积。\n\n```typescript\nconst result = measureTool.measureArea([\n { x: 0, y: 0, z: 0 },\n { x: 5, y: 0, z: 0 },\n { x: 5, y: 0, z: 5 },\n { x: 0, y: 0, z: 5 },\n], { lineColor: 0x00ff00 });\nconsole.log(result.value, result.unit); // 25 m²\n```\n\n### `measureAngle(pointA, vertex, pointC, options?)`\n\n测量以中间点为顶点的夹角(单位:度)。\n\n```typescript\nconst result = measureTool.measureAngle(\n { x: 3, y: 0, z: 0 },\n { x: 0, y: 0, z: 0 },\n { x: 0, y: 0, z: 3 },\n);\nconsole.log(result.value, result.unit); // 90 °\n```\n\n### `MeasureResult`\n\n所有测量方法返回 `MeasureResult` 对象:\n\n| 属性 | 类型 | 说明 |\n| :------- | :---------- | :--------------------------------- |\n| `id` | `string` | 测量的唯一标识。 |\n| `type` | `string` | `'distance'` / `'area'` / `'angle'`。|\n| `value` | `number` | 测量值。 |\n| `unit` | `string` | 单位(`m`、`m²`、`°`)。 |\n| `points` | `Vector3[]` | 测量点坐标。 |\n| `object` | `Group` | 场景中的可视化对象。 |\n\n### `MeasureStyleOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :--------- | :----------- |\n| `lineColor` | `ColorRepresentation` | 因方法而异 | 线条颜色。 |\n\n### 管理方法\n\n```typescript\nmeasureTool.get('measure_dist_0'); // 获取指定测量\nmeasureTool.remove('measure_dist_0'); // 移除指定测量\nmeasureTool.removeAll(); // 清除全部\nmeasureTool.getAll(); // 获取所有测量结果\nmeasureTool.dispose(); // 释放资源\n```\n\n---\n\n## ClippingTool\n\n提供剖切面和剖切盒功能,基于 WebGPU 的 `ClippingGroup` 实现。需要被剖切的对象必须是 `ClippingGroup` 的子节点。\n\n```typescript\nimport { ClippingTool } from 'u-space';\n\nconst clippingTool = new ClippingTool(viewer.scene);\n\n// 将场景中已有的物体移入 ClippingGroup,使其受剖切影响\nclippingTool.attach();\n```\n\n### `attach()` / `detach()`\n\n`attach()` 将场景根节点的所有子对象移入内部的 `ClippingGroup`,使其受剖切面影响。`detach()` 反向操作,将对象移回场景根节点。\n\n也可以手动将对象添加到 `clippingTool.group` 中:\n\n```typescript\nclippingTool.group.add(myModel); // 仅 myModel 受剖切\n```\n\n### `addPlane(id, options?)`\n\n添加一个剖切面。\n\n```typescript\nclippingTool.addPlane('cutY', {\n normal: { x: 0, y: -1, z: 0 }, // 法线方向\n constant: 1.5, // 距离原点的偏移\n showHelper: true, // 显示 Helper\n helperSize: 5,\n helperColor: 0xff0000,\n});\n```\n\n#### `ClippingPlaneOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------ | :-------------------- | :----------------- | :----------------------- |\n| `normal` | `{x, y, z}` | `{x:0, y:-1, z:0}` | 法线方向。 |\n| `constant` | `number` | `0` | 距原点偏移。 |\n| `showHelper` | `boolean` | `false` | 是否显示 PlaneHelper。 |\n| `helperSize` | `number` | `5` | Helper 尺寸。 |\n| `helperColor` | `ColorRepresentation` | `0xff0000` | Helper 颜色。 |\n\n### `addBox(id, box, options?)` / `addBoxFromObject(id, object, padding?, options?)`\n\n添加由 6 个面组成的剖切盒。\n\n```typescript\nimport { Box3 } from 'three/webgpu';\n\n// 从 Box3 创建\nconst box = new Box3().setFromObject(myModel);\nclippingTool.addBox('clipBox', box);\n\n// 从对象创建(带边距)\nclippingTool.addBoxFromObject('clipBox', myModel, 0.5);\n```\n\n### 动态调整\n\n```typescript\nclippingTool.setPlaneConstant('cutY', 2.0); // 修改剖切位置\nviewer.render();\n```\n\n### Helper 控制\n\n```typescript\nclippingTool.showHelper('cutY', 5, 0xff0000);\nclippingTool.hideHelper('cutY');\n```\n\n### 管理方法\n\n```typescript\nclippingTool.get('cutY'); // 获取 Plane 对象\nclippingTool.removePlane('cutY'); // 移除单个\nclippingTool.removeBox('clipBox'); // 移除剖切盒(6 个面)\nclippingTool.removeAll(); // 移除全部\nclippingTool.enable(); // 启用剖切\nclippingTool.disable(); // 禁用剖切\nclippingTool.dispose(); // 释放资源(对象移回场景根节点)\n```\n\n---\n\n## AnnotationManager\n\n管理 3D 标注,支持引线标注和 HTML 标签。配合 `CSSRenderer` 使用可实现 HTML 浮动标签。\n\n```typescript\nimport { AnnotationManager } from 'u-space';\n\nconst annotationManager = new AnnotationManager(viewer.scene);\n```\n\n### `setCSSObjectFactory(factory)`\n\n设置 CSS 对象工厂函数(来自 `CSSRenderer`),使标注可渲染为 CSS 叠加元素。\n\n```typescript\nannotationManager.setCSSObjectFactory(\n (el) => viewer.cssRenderer.createCSS2DObject(el),\n);\n```\n\n### `add(id, options)`\n\n添加一个标注。\n\n```typescript\nannotationManager.add('label-01', {\n position: { x: 0, y: 3, z: 0 },\n content: '<b>设备 A</b><br>温度: 25°C',\n labelOffset: { x: 0, y: 2, z: 0 },\n showLeaderLine: true,\n lineColor: 0xffffff,\n labelStyle: {\n background: 'rgba(0, 0, 0, 0.8)',\n padding: '8px 12px',\n borderRadius: '6px',\n },\n});\n```\n\n#### `AnnotationOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :--------------- | :------------------------ | :---------- | :--------------------- |\n| `position` | `{x, y, z}` | — | 标注锚点位置。 |\n| `content` | `string` | — | HTML 内容。 |\n| `labelOffset` | `{x, y, z}` | `{0, 2, 0}` | 标签相对锚点的偏移。 |\n| `showLeaderLine` | `boolean` | `true` | 是否显示引线。 |\n| `lineColor` | `ColorRepresentation` | `0xffffff` | 引线颜色。 |\n| `labelStyle` | `Partial<CSSStyleDeclaration>` | — | 自定义 CSS 样式。 |\n\n### `addText(text, position, options?)`\n\n快捷添加纯文本标注。\n\n```typescript\nannotationManager.addText('入口', { x: 5, y: 0, z: 0 });\n```\n\n### 更新与控制\n\n```typescript\nannotationManager.updateContent('label-01', '温度: 30°C');\nannotationManager.updatePosition('label-01', { x: 1, y: 3, z: 0 });\nannotationManager.show('label-01');\nannotationManager.hide('label-01');\nannotationManager.showAll();\nannotationManager.hideAll();\n```\n\n### 管理方法\n\n```typescript\nannotationManager.get('label-01'); // 获取标注对象\nannotationManager.remove('label-01'); // 移除标注\nannotationManager.removeAll(); // 移除全部\nannotationManager.keys(); // 获取所有 ID\nannotationManager.size; // 标注数量\nannotationManager.dispose(); // 释放资源\n```\n"
1115
+ "content": "# Tools API\n\n`u-space` 提供了一组实用工具类,包括测量、剖切和标注功能。\n\n## MeasureTool\n\n用于 3D 场景中的距离测量、面积测量和角度测量,测量结果会以可视化线条渲染到场景中。\n\n```typescript\nimport { MeasureTool } from 'u-space';\n\nconst measureTool = new MeasureTool(viewer.scene);\n```\n\n### `measureDistance(pointA, pointB, options?)`\n\n测量两点之间的距离,并在场景中绘制连线。\n\n```typescript\nconst result = measureTool.measureDistance(\n { x: 0, y: 0, z: 0 },\n { x: 5, y: 0, z: 5 },\n { lineColor: 0xffff00 },\n);\nconsole.log(result.value, result.unit); // 7.071 m\n```\n\n### `measureArea(points, options?)`\n\n测量由 3 个或更多共面点围成的多边形面积。\n\n```typescript\nconst result = measureTool.measureArea([\n { x: 0, y: 0, z: 0 },\n { x: 5, y: 0, z: 0 },\n { x: 5, y: 0, z: 5 },\n { x: 0, y: 0, z: 5 },\n], { lineColor: 0x00ff00 });\nconsole.log(result.value, result.unit); // 25 m²\n```\n\n### `measureAngle(pointA, vertex, pointC, options?)`\n\n测量以中间点为顶点的夹角(单位:度)。\n\n```typescript\nconst result = measureTool.measureAngle(\n { x: 3, y: 0, z: 0 },\n { x: 0, y: 0, z: 0 },\n { x: 0, y: 0, z: 3 },\n);\nconsole.log(result.value, result.unit); // 90 °\n```\n\n### `MeasureResult`\n\n所有测量方法返回 `MeasureResult` 对象:\n\n| 属性 | 类型 | 说明 |\n| :------- | :---------- | :--------------------------------- |\n| `id` | `string` | 测量的唯一标识。 |\n| `type` | `string` | `'distance'` / `'area'` / `'angle'`。|\n| `value` | `number` | 测量值。 |\n| `unit` | `string` | 单位(`m`、`m²`、`°`)。 |\n| `points` | `Vector3[]` | 测量点坐标。 |\n| `object` | `Group` | 场景中的可视化对象。 |\n\n### `MeasureStyleOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :---------- | :-------------------- | :--------- | :----------- |\n| `lineColor` | `ColorRepresentation` | 因方法而异 | 线条颜色。 |\n\n### 管理方法\n\n```typescript\nmeasureTool.get('measure_dist_0'); // 获取指定测量\nmeasureTool.remove('measure_dist_0'); // 移除指定测量\nmeasureTool.removeAll(); // 清除全部\nmeasureTool.getAll(); // 获取所有测量结果\nmeasureTool.dispose(); // 释放资源\n```\n\n---\n\n## ClippingTool\n\n提供剖切面和剖切盒功能,基于 WebGPU 的 `ClippingGroup` 实现。需要被剖切的对象必须是 `ClippingGroup` 的子节点。\n\n```typescript\nimport { ClippingTool } from 'u-space';\n\nconst clippingTool = new ClippingTool(viewer.scene);\n\n// 将场景中已有的物体移入 ClippingGroup,使其受剖切影响\nclippingTool.attach();\n```\n\n### `attach()` / `detach()`\n\n`attach()` 将场景根节点的所有子对象移入内部的 `ClippingGroup`,使其受剖切面影响。`detach()` 反向操作,将对象移回场景根节点。\n\n也可以手动将对象添加到 `clippingTool.group` 中:\n\n```typescript\nclippingTool.group.add(myModel); // 仅 myModel 受剖切\n```\n\n### `addPlane(id, options?)`\n\n添加一个剖切面。\n\n```typescript\nclippingTool.addPlane('cutY', {\n normal: { x: 0, y: -1, z: 0 }, // 法线方向\n constant: 1.5, // 距离原点的偏移\n showHelper: true, // 显示 Helper\n helperSize: 5,\n helperColor: 0xff0000,\n});\n```\n\n#### `ClippingPlaneOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :------------ | :-------------------- | :----------------- | :----------------------- |\n| `normal` | `{x, y, z}` | `{x:0, y:-1, z:0}` | 法线方向。 |\n| `constant` | `number` | `0` | 距原点偏移。 |\n| `showHelper` | `boolean` | `false` | 是否显示 PlaneHelper。 |\n| `helperSize` | `number` | `5` | Helper 尺寸。 |\n| `helperColor` | `ColorRepresentation` | `0xff0000` | Helper 颜色。 |\n\n### `addBox(id, box, options?)` / `addBoxFromObject(id, object, padding?, options?)`\n\n添加由 6 个面组成的剖切盒。\n\n```typescript\nimport { Box3 } from 'three/webgpu';\n\n// 从 Box3 创建\nconst box = new Box3().setFromObject(myModel);\nclippingTool.addBox('clipBox', box);\n\n// 从对象创建(带边距)\nclippingTool.addBoxFromObject('clipBox', myModel, 0.5);\n```\n\n### 动态调整\n\n```typescript\nclippingTool.setPlaneConstant('cutY', 2.0); // 修改剖切位置\nviewer.render();\n```\n\n### Helper 控制\n\n```typescript\nclippingTool.showHelper('cutY', 5, 0xff0000);\nclippingTool.hideHelper('cutY');\n```\n\n### 管理方法\n\n```typescript\nclippingTool.get('cutY'); // 获取 Plane 对象\nclippingTool.removePlane('cutY'); // 移除单个\nclippingTool.removeBox('clipBox'); // 移除剖切盒(6 个面)\nclippingTool.removeAll(); // 移除全部\nclippingTool.enable(); // 启用剖切\nclippingTool.disable(); // 禁用剖切\nclippingTool.dispose(); // 释放资源(对象移回场景根节点)\n```\n\n---\n\n## AnnotationManager\n\n管理 3D 标注,支持引线标注和 HTML 标签。配合 `CSSRenderer` 使用可实现 HTML 浮动标签。\n\n```typescript\nimport { AnnotationManager } from 'u-space';\n\nconst annotationManager = new AnnotationManager(viewer.scene);\n```\n\n### `setCSSObjectFactory(factory)`\n\n设置 CSS 对象工厂函数(来自 `CSSRenderer`),使标注可渲染为 CSS 叠加元素。\n\n```typescript\nannotationManager.setCSSObjectFactory(\n (el) => viewer.cssRenderer.createCSS2DObject(el),\n);\n```\n\n### `add(id, options)`\n\n添加一个标注。\n\n```typescript\nannotationManager.add('label-01', {\n position: { x: 0, y: 3, z: 0 },\n content: '<b>设备 A</b><br>温度: 25°C',\n labelOffset: { x: 0, y: 2, z: 0 },\n showLeaderLine: true,\n lineColor: 0xffffff,\n labelStyle: {\n background: 'rgba(0, 0, 0, 0.8)',\n padding: '8px 12px',\n borderRadius: '6px',\n },\n});\n```\n\n#### `AnnotationOptions`\n\n| 属性 | 类型 | 默认值 | 说明 |\n| :--------------- | :------------------------ | :---------- | :--------------------- |\n| `position` | `{x, y, z}` | — | 标注锚点位置。 |\n| `content` | `string` | — | HTML 内容。 |\n| `labelOffset` | `{x, y, z}` | `{0, 2, 0}` | 标签相对锚点的偏移。 |\n| `showLeaderLine` | `boolean` | `true` | 是否显示引线。 |\n| `lineColor` | `ColorRepresentation` | `0xffffff` | 引线颜色。 |\n| `labelStyle` | `AnnotationLabelStyle` | — | 自定义 CSS 样式。 |\n\n### `addText(text, position, options?)`\n\n快捷添加纯文本标注。\n\n```typescript\nannotationManager.addText('入口', { x: 5, y: 0, z: 0 });\n```\n\n### 更新与控制\n\n```typescript\nannotationManager.updateContent('label-01', '温度: 30°C');\nannotationManager.updatePosition('label-01', { x: 1, y: 3, z: 0 });\nannotationManager.show('label-01');\nannotationManager.hide('label-01');\nannotationManager.showAll();\nannotationManager.hideAll();\n```\n\n### 管理方法\n\n```typescript\nannotationManager.get('label-01'); // 获取标注对象\nannotationManager.remove('label-01'); // 移除标注\nannotationManager.removeAll(); // 移除全部\nannotationManager.keys(); // 获取所有 ID\nannotationManager.size; // 标注数量\nannotationManager.dispose(); // 释放资源\n```\n"
1019
1116
  },
1020
1117
  {
1021
1118
  "id": "api-viewer",
@@ -1134,7 +1231,7 @@ export const docsIndex = [
1134
1231
  "id": "changelog",
1135
1232
  "path": "changelog.md",
1136
1233
  "title": "更新日志",
1137
- "summary": "- **u-manager semantics** — `FloorMesh.planish()` 会在压平后的语义实例和 Facilities 上加入稳定的轻微 Y 偏移,减少门、墙等重叠薄片之间的共面闪烁。 - **u-manager semantics** — `FloorMesh` 会按实例透明度把合并语义网格拆分到不透明和透明材质通道,避免墙、柱、门等完全不透明实例也走透明渲染队列,降低近距离压平场景的 overdraw 成本。 - **u-manager semantics** — `BuildingGroup` 新增 `getFloorById()`、`getElevatorById()` 和 `getVentById()`,内部通过 `Map` 维护楼层、电梯井和通风井语义 ID 索引。",
1234
+ "summary": "- **u-manager** — 新增 `UManagerLoader` 一体化入口,可同时加载 `SemanticLoader` `SceneLoader`,返回带 `semanticGroup` / `sceneGroup` 直接属性的 `UManagerSceneGroup`,并复用 semantic id 去重避免重复建筑/设备。 - **examples/docs/mcp**新增 `examples/test_umanager_loader.html`,演示 `UManagerLoader` 一次加载语义楼层、Facilities 和非语义场景树,并补充 Examples Guide 与 MCP 检索入口。 - **u-manager breaking** — `SceneInstanceObject`、`FacilityInstanceObject` 和楼层多边形语",
1138
1235
  "headings": [
1139
1236
  {
1140
1237
  "level": 1,
@@ -1144,6 +1241,34 @@ export const docsIndex = [
1144
1241
  "level": 2,
1145
1242
  "text": "未发布"
1146
1243
  },
1244
+ {
1245
+ "level": 2,
1246
+ "text": "0.0.28"
1247
+ },
1248
+ {
1249
+ "level": 3,
1250
+ "text": "新增"
1251
+ },
1252
+ {
1253
+ "level": 3,
1254
+ "text": "变更"
1255
+ },
1256
+ {
1257
+ "level": 3,
1258
+ "text": "示例与文档"
1259
+ },
1260
+ {
1261
+ "level": 2,
1262
+ "text": "0.0.27"
1263
+ },
1264
+ {
1265
+ "level": 3,
1266
+ "text": "变更"
1267
+ },
1268
+ {
1269
+ "level": 3,
1270
+ "text": "示例与文档"
1271
+ },
1147
1272
  {
1148
1273
  "level": 2,
1149
1274
  "text": "0.0.26"
@@ -1305,13 +1430,13 @@ export const docsIndex = [
1305
1430
  "text": "新增"
1306
1431
  }
1307
1432
  ],
1308
- "content": "# 更新日志\n\n## 未发布\n\n## 0.0.26\n\n### 修复\n\n- **u-manager semantics** — `FloorMesh.planish()` 会在压平后的语义实例和 Facilities 上加入稳定的轻微 Y 偏移,减少门、墙等重叠薄片之间的共面闪烁。\n- **u-manager semantics** — `FloorMesh` 会按实例透明度把合并语义网格拆分到不透明和透明材质通道,避免墙、柱、门等完全不透明实例也走透明渲染队列,降低近距离压平场景的 overdraw 成本。\n- **u-manager semantics** — `BuildingGroup` 新增 `getFloorById()`、`getElevatorById()` 和 `getVentById()`,内部通过 `Map` 维护楼层、电梯井和通风井语义 ID 索引。\n- **u-manager semantics** — `FacilityInstancedLayer` 只在实例矩阵、颜色或透明度变化时上传对应 instance buffer,静态 Facilities 不再每帧重复提交全部实例数据;渲染前会按每个 Facility 实例的世界包围盒和当前相机视锥压缩本帧 active instance count,不再通过相机距离阈值裁剪设备。\n- **u-manager semantics** — 修复 Facilities 视锥裁剪在视角切换后可能沿用上一帧 active subset 的 `visible` / `boundingSphere` 状态,导致某些视角下设备整批隐藏的问题;instanced batch 会保留完整包围球,同时用 `count` 控制本帧 active 实例。\n- **u-manager semantics** — Instanced Facilities 的 batch 材质默认保持不透明,只有源材质本身透明或当前渲染实例存在半透明 opacity 时才切到透明队列,减少完全不透明设备在近距离视角下的 overdraw。\n- **MaterialEffects** — 高亮、呼吸色、线框和淡入淡出效果支持材质数组,确保多材质 Mesh 和 `FloorMesh` 双材质通道都能正确应用并恢复材质状态。\n- **docs/mcp** — 补充 Facilities auto instancing 的动态材质透明度、包围盒视锥裁剪、`controls.flyToBox()` 飞向设备,以及多材质 fallback 对颜色/透明度 override 的支持说明。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.26`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.25\n\n### 新增\n\n- **u-manager semantics** — 新增 `SemanticSceneGroup`,作为单次 `SemanticParser` 解析结果的顶层容器;`SemanticLoader.loadAsync()` / `SemanticParser.parseAsync()` 直接返回完整语义场景。\n- **u-manager semantics** — `SemanticSceneGroup` 新增 `getBuildingById(id)`,支持按语义数据里的 `Building.ID` 获取建筑。\n- **u-manager semantics** — `SemanticSceneGroup` 和 `BuildingGroup` 的建筑/设备 ID 查询改为内部 `Map` 索引,并通过楼层设备索引版本自动同步,避免每次查询扫描数组。\n- **u-manager semantics** — `FloorMesh.planish()` / `unplanish()`、`BuildingGroup.planishFloors()` / `unplanishFloors()` 和 `SemanticSceneGroup.planishFloors()` / `unplanishFloors()` 会把所有合并语义实例和 Facilities 都按包围盒贴到楼层平面,而不是围绕实例自身基点压缩。\n- **u-manager semantics** — 新增 scene-level Facilities auto instancing:同模型 URL 的静态设备会合并到 `SemanticSceneGroup.facilityLayer` 的 `InstancedMesh` batch,同时保留楼层下的设备引用用于检索、显隐、颜色和透明度控制;带动画、骨骼、morph target 或多材质 Mesh 的设备自动回退为普通 `Model`。\n- **u-manager semantics** — `SemanticSceneGroup`、`BuildingGroup` 和 `FloorMesh` 新增单个设备控制 API:`getFacilityById()`、`showFacility()`、`hideFacility()`、`setFacilityVisible()`、`setFacilityColor()`、`resetFacilityColor()` 和 `setFacilityOpacity()`,同时支持普通设备模型和 scene-level instanced 设备引用。\n- **docs/mcp** — 补充 Facilities auto instancing 的材质透明度行为、`resetFacilityColor()` 语义,以及多材质 fallback 对颜色/透明度 override 的限制说明。\n\n### 修复\n\n- **u-manager semantics** — 修复 scene-level instanced Facilities 的点击和指针事件派发:射线命中会映射回楼层下的 `FacilityInstanceObject`,并继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticSceneGroup`。\n- **u-manager semantics** — `FacilityInstancedLayer` 继承 `BaseGroup`,避免 `facilityLayer.visible = false` 后内部 `InstancedMesh` 仍参与射线检测并触发隐藏设备点击事件。\n- **u-manager semantics** — 移除语义设备解析里的 `sid` 检索和注册逻辑;Facilities 只按 `Facility.ID` 以及显式传入的别名进入楼层索引和 `viewer.objectManager`。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.25`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.23\n\n### 新增\n\n- **u-manager semantics** — `BuildingGroup` 新增 `isolateFloors(floors)`,支持按多个 `FloorMesh` 或楼层下标同时隔离显示多个楼层;`isolateFloor()` 继续兼容单楼层调用,并可接收数组作为便捷写法。\n- **u-manager semantics** — `SemanticLoader` 新增 `Facilities` 解析:从 `Stories[].Facilities` 索引读取顶层设备语义,用 `Facility.ID` 匹配解密后的 `tree_models` 设备节点,沿父级累乘本地矩阵得到设备世界矩阵,加载 3D 设备模型并转换为楼层局部矩阵后挂载到对应 `FloorMesh`。\n- **u-manager semantics** — `FloorMesh` 新增楼层设备检索与统一语义实体 API:`getFacilityById()`、`getFacilityAt()`、`getFacilities()`、`removeFacility()`、`showAllFacilities()`、`hideAllFacilities()`、`getSemanticById()`、`getSemantics()` 和 `getSemanticsByKind('Facilities')`;`BuildingGroup.showAllFacilities()/hideAllFacilities()` 支持批量显示或隐藏整栋建筑内的楼层设备。\n- **u-space MCP** — 文档索引同步楼层 `Facilities` 解析和检索 API,MCP 客户端可检索设备按楼层挂载、`tree_models` 解密匹配、本地矩阵父级累乘和世界坐标转换规则。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.23`,部署流程仍会优先按 `package.json` 注入当前版本。\n\n## 0.0.21\n\n### 新增\n\n- **u-manager semantics** — `SemanticLoader` 支持解析建筑级 `Elevators` 和 `Vents`,以 `Polygon.shape` 作为底面轮廓、`Elevation` 作为底面高度、`TotalHeight` 作为拉伸高度生成 `ExtrudeMesh`,并通过 `BuildingGroup.elevatorMeshes`、`BuildingGroup.ventMeshes` 及 add/get/remove 方法管理。\n\n### 修复\n\n- **透明语义体块渲染** — 电梯井/通风井在渲染阶段沿法线轻微内收,`Spaces` 实例使用稳定 per-instance 渲染偏移抖动,缓解与墙体或完全重叠空间共面时的 z-fighting。\n- **atmosphere 插件** — 后处理链移除 aerial perspective 节点,保留 lens flare、tone mapping、temporal antialias 和 dithering;`scene.backgroundNode` 使用 `skyBackground()`,`scene.environmentNode` 使用 `skyEnvironment()`,并继续在关闭插件时恢复启用前的背景和环境节点。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.21`,部署流程仍会优先按 `package.json` 注入当前版本。\n\n## 0.0.18\n\n### 变更\n\n- **版本发布** — 同步发布包含新版大气插件实现、RenderPipeline output effects 和一键 MCP 发布脚本的 npm 包。\n\n## 0.0.17\n\n### 新增\n\n- **atmosphere 插件** — `Atmosphere.enable(options)` 从占位实现升级为可用的大气渲染:支持 WGS84 经纬高定位、太阳/月亮方向、天空背景、天空环境、aerial perspective、lens flare、tone mapping、temporal antialias、dithering 和 `AtmosphereLight` 阴影。\n- **RenderPipeline** — 新增 `addOutputEffect()` / `removeOutputEffect()` 与 `addMRTChannel()` / `removeMRTChannel()`,插件可追加输出后处理和独立 MRT 通道,不再占用业务侧 `setOutputComposer()`。\n\n### 变更\n\n- **大气状态更新** — 大气插件在 `beforeRender` 中刷新相机 ECEF 位置、太阳/月亮方向和阴影 target,相机控制器驱动的移动也能逐帧更新大气状态。\n- **MCP 发布** — 根目录 MCP 发布入口合并为 `pnpm publish:mcp`,命令会先递增 `u-space-mcp` 的 patch 版本,再构建文档索引并发布 npm 包。\n\n## 0.0.16\n\n### 新增\n\n- **u-manager semantics** — `FloorMesh.planish(kind?)`、`FloorMesh.unplanish(kind?)`、`BuildingGroup.planishFloors(kind?)` 和 `BuildingGroup.unplanishFloors(kind?)` 支持按 `Walls`、`Columns`、`Spaces`、`Doors`、`Windows` 语义类型压平或恢复;`setScaleYAt(index, y)` 可只调整单个语义实例的 Y 轴缩放。\n- **BaseMesh** — 默认开启 `castShadow` 与 `receiveShadow`,基础网格和继承自 `BaseMesh` 的对象会直接参与阴影投射与接收。\n\n### 变更\n\n- **语义类型命名** — `SemanticKind` 统一为数据源字段风格:`Walls`、`Columns`、`Spaces`、`Doors`、`Windows`。\n- **示例与依赖** — 更新 `load_tiles.html` 示例依赖,新增 `@takram/three-atmosphere`、`postprocessing` peer dependency,并将 Vite 外部依赖边界扩展到所有 `@takram/*` 包。\n\n## 0.0.12\n\n### 新增\n\n- **u-manager semantics** — 新增 `SemanticLoader`、`BuildingGroup`、`FloorMesh` 语义楼层 API,支持楼层隔离、实例级颜色/透明度/显隐/matrix/scale 控制,以及实例包围盒/包围球查询。\n- **u-space MCP** — 内置文档索引同步语义楼层 API,MCP 客户端可检索 `SemanticLoader`、`BuildingGroup` 和 `FloorMesh` 用法。\n\n## 0.0.8\n\n### 新增\n\n- **Viewer** — `resize()`、`screenshot()`、`setBackground()`、`setEnvironment()`、`enableShadow()`/`disableShadow()`、`enableFog()`/`enableFogExp2()`/`disableFog()`\n- **CameraControls** — `flyTo()`、`getCameraViewpoint()`、`lock()`/`unlock()`、`setViewMode('2d' | '3d')`\n- **ObjectManager** — `show()`/`hide()`、`isolate()`、`showAll()`、`setOpacity()`、`getBoundingBox()`、`forEach()`、`filter()`\n- **InteractionManager** — `enable()`/`disable()`、`setInteractable()`、`addIgnore()`/`removeIgnore()`\n- **Selection** — 新增框选(rubber-band)和单选/多选/切换模块,支持 `select`/`deselect`/`change` 事件\n- **MaterialEffects** — `wireframe()`/`removeWireframe()`、`transparent()`/`removeTransparent()`、`xray()`/`removeXray()`、`fadeIn()`/`fadeOut()`\n- **Model** — `getBoundingBox()`、`getCenter()`、`setMaterial()`\n- **SceneManager** — 新模块,多场景创建、注册、切换与序列化\n- **LightManager** — 新模块,灯光便捷创建、4 种预设(indoor/outdoor/studio/warehouse)、Helper 可视化\n- **MeasureTool** — 新工具,距离/面积/角度测量,结果可视化渲染到场景\n- **ClippingTool** — 新工具,基于 WebGPU `ClippingGroup` 的剖切面与剖切盒\n- **AnnotationManager** — 新工具,3D 引线标注 + HTML 浮动标签\n- **示例** — 新增 8 个交互式示例页面\n\n### 修复\n\n- **Selection** — 框选覆盖层改为挂载到容器元素(而非 canvas),修复框选矩形不可见的问题\n- **ClippingTool** — 从 `renderer.clippingPlanes`(WebGL API)重写为 `ClippingGroup`(WebGPU API),修复剖切无效的问题\n- **MaterialEffects** — fade 动画在对象移除场景后自动停止,避免内存泄漏\n- **InteractionManager** — `dispose()` 中清除 `clickTimer`,避免定时器泄漏\n- **LightManager** — 修复 `removeAll()`/`hideAllHelpers()` 中遍历 Map 同时删除的问题\n- **ObjectManager** — `setOpacity()` 先检查 `isMesh` 再类型转换\n- **ClippingTool** — `PlaneHelper` 颜色使用 `new Color(color).getHex()` 替代直接 `as number`\n- **MeasureTool** — 移除 WebGPU 不支持的 `linewidth` 属性\n\n---\n\n## 0.0.7\n\n### 变更\n\n- 文档拆分:将插件文档拆分为独立文件\n- 新增 CameraControls 独立文档页\n- 修复 getting-started 中的死链\n- 修复 sbmx loader 示例使用新的 MaterialEffects API\n\n---\n\n## 0.0.6\n\n### 新增\n\n- **MaterialEffects** — 可组合的材质特效系统,支持安全共享材质和 remove API\n- **RenderPipeline** — 内置 Bloom、SSGI、TRAA 后处理及 OutputComposer API\n- **CSSRenderer** — CSS2D / CSS2.5D / CSS3D 叠加渲染 HTML 元素\n- 从 `package.json` 导出 `version`,统一示例 importmap\n\n---\n\n## 0.0.5\n\n### 变更\n\n- 版本发布(无重大功能变更)\n\n---\n\n## 0.0.4\n\n### 新增\n\n- **Model** — 动画播放支持(`playAnimation`、`stopAnimation`、`updateAnimation`)\n- **ViewerEventMap** — 事件回调新增 `delta` 时间参数\n\n---\n\n## 0.0.3\n\n### 新增\n\n- **ObjectControls** 插件 — 交互式移动、旋转、缩放 3D 对象\n- **TopologyDrawer** 插件 — 在场景任意表面交互式绘制拓扑路径图\n- **Topology** — `exportData()` / `importData()` 数据序列化\n\n### 变更\n\n- **Interactions** — `contextmenu` 事件替换为 `rightclick`\n- **Poi** — 优化渲染性能,新增 `scaleFactor` 参数\n- 文档全面完善:本地搜索、侧边栏优化、各插件文档页\n\n---\n\n## 0.0.0\n\n### 新增\n\n- 项目初始化:Viewer 核心、WebGPU 渲染器、场景/相机/控制器\n- 模型加载系统:双层缓存(内存 + 持久化)、Draco/KTX2/Meshopt 支持\n- 交互系统:射线检测、事件冒泡、自定义 3D 对象事件\n- 对象系统:Model、Poi、Topology、基础网格(Sphere/Plane/Circle/Tube/Extrude/Shape)\n- ObjectManager 集中式对象注册\n- 补间动画系统\n- u-manager 插件:场景加载、动画、属性、视点管理\n- tiles 插件:ArcGIS 3D 瓦片 / GIS 地球渲染\n- minimap 插件:2D 小地图\n- keyboard-controls 插件:WASD 键盘控制\n- tracking-controls 插件:相机跟随\n- atmosphere 插件:天空/大气渲染\n- curve-movement 插件:曲线路径动画\n"
1433
+ "content": "# 更新日志\n\n## 未发布\n\n## 0.0.28\n\n### 新增\n\n- **u-manager** — 新增 `UManagerLoader` 一体化入口,可同时加载 `SemanticLoader` 和 `SceneLoader`,返回带 `semanticGroup` / `sceneGroup` 直接属性的 `UManagerSceneGroup`,并复用 semantic id 去重避免重复建筑/设备。\n- **examples/docs/mcp** — 新增 `examples/test_umanager_loader.html`,演示 `UManagerLoader` 一次加载语义楼层、Facilities 和非语义场景树,并补充 Examples Guide 与 MCP 检索入口。\n\n### 变更\n\n- **u-manager breaking** — `SceneInstanceObject`、`FacilityInstanceObject` 和楼层多边形语义统一到 `SemanticInstanceObject` API:使用 `setSemanticVisible()`、`setSemanticColor()`、`setSemanticOpacity()`、`getSemanticBoundingBox()` 等方法,不再使用 scene/facility 专属实例方法。\n- **u-manager** — 新增共享 `SemanticModelInstancedLayer`,`SceneInstancedLayer` 和 `FacilityInstancedLayer` 共用同一套模型模板 instancing、material groups、多材质、dirty sync、raycast remap 和 fallback wrapper 逻辑。\n- **ObjectManager / MaterialEffects** — 对语义实例的显隐、透明度和高亮控制统一识别 `SemanticInstanceObject`,不再维护 SceneInstance/FacilityInstance 两套特殊分支。\n- **u-manager loader** — `SceneLoader` 不再解析场景树里的 `AREA`、`FLOOR`、`ROOM` 语义面;楼层、区域和房间统一由 `SemanticLoader` / `SemanticGroup` 处理,避免同一语义对象在组合加载时重复出现。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.28`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.27\n\n### 变更\n\n- **u-manager semantics** — `FacilityInstancedLayer` 的相机逐实例裁剪改为显式开启:默认不再按当前相机视锥或 `minScreenRadius` 压缩 active instances,避免相机距离影响设备显隐;需要性能压缩时可通过 `setInstanceCulling({ enabled: true })` 开启。\n- **u-manager semantics** — `FacilityInstancedLayer` 使用动态 `Group` 包裹 Facilities `InstancedMesh` batch,避免 Three.js WebGPU render bundle 缓存跳过子 mesh 的渲染前同步;`hideAllFacilities()` 后再 `showAllFacilities()` 不会复用过期 active instance 状态。\n- **u-manager semantics** — `FacilityInstancedLayer` 支持合法 `material[]` + `geometry.groups` 的设备模板进入 instancing;只有 groups 缺失或材质索引非法的多材质 Mesh 才回退为普通 `Model`。\n- **u-manager semantics** — Facilities instancing 会在相机矩阵、投影矩阵或 viewport 高度变化时重新压缩当前帧实例;设备显隐、颜色、透明度和 `planish('Facilities')` / `unplanish('Facilities')` 改变 transform 时刷新 instance data。\n- **u-manager semantics** — 全部设备隐藏或透明度为 0 时,`FacilityInstancedLayer` 会关闭空的内部 `InstancedMesh`;通过 `showAllFacilities()` 或单设备 API 恢复时会重新加入渲染同步。\n- **fire 插件** — 新增 `FireEffect`,封装 Three.js 官方 `webgpu_volume_fire` 体积火焰示例,支持 WebGPU 3D 流体模拟、烟雾散射、动态光照、体积阴影、output effect 叠加和 `cameraChange` 相机切换同步。\n- **u-manager loader** — `SceneLoader` 默认读取同路径 `db/semantic_model.json` 并按语义 `ID` 跳过重复场景树节点,支持与 `SemanticLoader` 同时加载。\n- **u-manager loader** — `SceneLoader` 默认按模型 `path` 合并重复静态 3D 节点,通过 `SceneInstancedLayer` 批量渲染,同时保留 `SceneInstanceObject` 逻辑对象用于单模型 ID 检索、显隐、颜色、透明度、包围盒和事件派发。\n- **docs/mcp** — 补充 `SceneInstanceObject` 和 `FacilityInstanceObject` 通过 `objectManager.getById()` + `getSemanticBoundingBox()` + `controls.flyToBox()` 飞向单个实例的示例与 MCP 检索说明。\n- **ObjectManager / MaterialEffects** — `setOpacity()`、`show()` / `hide()`、`isolate()`、`showAll()` 以及 `highlightColor()` / `removeHighlightColor()` 支持 `SceneInstanceObject` 的 per-instance 控制。\n- **u-manager loader** — `SceneLoader` 创建的根组、`GROUP` 和 `STUB` 节点改为 `BaseGroup`,隐藏后可通过对象自身 `raycast()` 返回值阻止子级继续参与递归射线检测。\n- **Viewer** — 默认使用 Three.js `reversedDepthBuffer` 替代 `logarithmicDepthBuffer`,减少 WebGPU 顶视角多层透明场景的 fragment 压力,同时保留远距离深度精度。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.27`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.26\n\n### 修复\n\n- **u-manager semantics** — `FloorMesh.planish()` 会在压平后的语义实例和 Facilities 上加入稳定的轻微 Y 偏移,减少门、墙等重叠薄片之间的共面闪烁。\n- **u-manager semantics** — `FloorMesh` 会按实例透明度把合并语义网格拆分到不透明和透明材质通道,避免墙、柱、门等完全不透明实例也走透明渲染队列,降低近距离压平场景的 overdraw 成本。\n- **u-manager semantics** — `BuildingGroup` 新增 `getFloorById()`、`getElevatorById()` 和 `getVentById()`,内部通过 `Map` 维护楼层、电梯井和通风井语义 ID 索引。\n- **u-manager semantics** — `FacilityInstancedLayer` 只在实例矩阵、颜色或透明度变化时上传对应 instance buffer,静态 Facilities 不再每帧重复提交全部实例数据;渲染前会按每个 Facility 实例的世界包围盒和当前相机视锥压缩本帧 active instance count,不再通过相机距离阈值裁剪设备。\n- **u-manager semantics** — 修复 Facilities 视锥裁剪在视角切换后可能沿用上一帧 active subset 的 `visible` / `boundingSphere` 状态,导致某些视角下设备整批隐藏的问题;instanced batch 会保留完整包围球,同时用 `count` 控制本帧 active 实例。\n- **u-manager semantics** — Instanced Facilities 的 batch 材质默认保持不透明,只有源材质本身透明或当前渲染实例存在半透明 opacity 时才切到透明队列,减少完全不透明设备在近距离视角下的 overdraw。\n- **MaterialEffects** — 高亮、呼吸色、线框和淡入淡出效果支持材质数组,确保多材质 Mesh 和 `FloorMesh` 双材质通道都能正确应用并恢复材质状态。\n- **docs/mcp** — 补充 Facilities auto instancing 的动态材质透明度、包围盒视锥裁剪、`controls.flyToBox()` 飞向设备,以及多材质 fallback 对颜色/透明度 override 的支持说明。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.26`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.25\n\n### 新增\n\n- **u-manager semantics** — 新增 `SemanticGroup`,作为单次 `SemanticParser` 解析结果的顶层容器;`SemanticLoader.loadAsync()` / `SemanticParser.parseAsync()` 直接返回完整语义场景。\n- **u-manager semantics** — `SemanticGroup` 新增 `getBuildingById(id)`,支持按语义数据里的 `Building.ID` 获取建筑。\n- **u-manager semantics** — `SemanticGroup` 和 `BuildingGroup` 的建筑/设备 ID 查询改为内部 `Map` 索引,并通过楼层设备索引版本自动同步,避免每次查询扫描数组。\n- **u-manager semantics** — `FloorMesh.planish()` / `unplanish()`、`BuildingGroup.planishFloors()` / `unplanishFloors()` 和 `SemanticGroup.planishFloors()` / `unplanishFloors()` 会把所有合并语义实例和 Facilities 都按包围盒贴到楼层平面,而不是围绕实例自身基点压缩。\n- **u-manager semantics** — 新增 scene-level Facilities auto instancing:同模型 URL 的静态设备会合并到 `SemanticGroup.facilityLayer` 的 `InstancedMesh` batch,同时保留楼层下的设备引用用于检索、显隐、颜色和透明度控制;带动画、骨骼、morph target 或多材质 Mesh 的设备自动回退为普通 `Model`。\n- **u-manager semantics** — `SemanticGroup`、`BuildingGroup` 和 `FloorMesh` 新增 `getFacilityById()` 设备检索,返回的 `FacilityInstanceObject` 可通过统一 `setSemanticVisible()`、`setSemanticColor()`、`resetSemanticColor()` 和 `setSemanticOpacity()` 控制普通设备模型或 scene-level instanced 设备引用。\n- **docs/mcp** — 补充 Facilities auto instancing 的材质透明度行为、`resetSemanticColor()` 语义,以及多材质 fallback 对颜色/透明度 override 的限制说明。\n\n### 修复\n\n- **u-manager semantics** — 修复 scene-level instanced Facilities 的点击和指针事件派发:射线命中会映射回楼层下的 `FacilityInstanceObject`,并继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticGroup`。\n- **u-manager semantics** — `FacilityInstancedLayer` 继承 `BaseGroup`,避免 `facilityLayer.visible = false` 后内部 `InstancedMesh` 仍参与射线检测并触发隐藏设备点击事件。\n- **u-manager semantics** — 移除语义设备解析里的 `sid` 检索和注册逻辑;Facilities 只按 `Facility.ID` 以及显式传入的别名进入楼层索引和 `viewer.objectManager`。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.25`,Vercel 部署会继续按 `package.json` 注入当前版本。\n\n## 0.0.23\n\n### 新增\n\n- **u-manager semantics** — `BuildingGroup` 新增 `isolateFloors(floors)`,支持按多个 `FloorMesh` 或楼层下标同时隔离显示多个楼层;`isolateFloor()` 继续兼容单楼层调用,并可接收数组作为便捷写法。\n- **u-manager semantics** — `SemanticLoader` 新增 `Facilities` 解析:从 `Stories[].Facilities` 索引读取顶层设备语义,用 `Facility.ID` 匹配解密后的 `tree_models` 设备节点,沿父级累乘本地矩阵得到设备世界矩阵,加载 3D 设备模型并转换为楼层局部矩阵后挂载到对应 `FloorMesh`。\n- **u-manager semantics** — `FloorMesh` 新增楼层设备检索与统一语义实体 API:`getFacilityById()`、`getFacilityAt()`、`getFacilities()`、`removeFacility()`、`showAllFacilities()`、`hideAllFacilities()`、`getSemanticById()`、`getSemantics()` 和 `getSemanticsByKind('Facilities')`;`BuildingGroup.showAllFacilities()/hideAllFacilities()` 支持批量显示或隐藏整栋建筑内的楼层设备。\n- **u-space MCP** — 文档索引同步楼层 `Facilities` 解析和检索 API,MCP 客户端可检索设备按楼层挂载、`tree_models` 解密匹配、本地矩阵父级累乘和世界坐标转换规则。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.23`,部署流程仍会优先按 `package.json` 注入当前版本。\n\n## 0.0.21\n\n### 新增\n\n- **u-manager semantics** — `SemanticLoader` 支持解析建筑级 `Elevators` 和 `Vents`,以 `Polygon.shape` 作为底面轮廓、`Elevation` 作为底面高度、`TotalHeight` 作为拉伸高度生成 `ExtrudeMesh`,并通过 `BuildingGroup.elevatorMeshes`、`BuildingGroup.ventMeshes` 及 add/get/remove 方法管理。\n\n### 修复\n\n- **透明语义体块渲染** — 电梯井/通风井在渲染阶段沿法线轻微内收,`Spaces` 实例使用稳定 per-instance 渲染偏移抖动,缓解与墙体或完全重叠空间共面时的 z-fighting。\n- **atmosphere 插件** — 后处理链移除 aerial perspective 节点,保留 lens flare、tone mapping、temporal antialias 和 dithering;`scene.backgroundNode` 使用 `skyBackground()`,`scene.environmentNode` 使用 `skyEnvironment()`,并继续在关闭插件时恢复启用前的背景和环境节点。\n\n### 示例与文档\n\n- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.21`,部署流程仍会优先按 `package.json` 注入当前版本。\n\n## 0.0.18\n\n### 变更\n\n- **版本发布** — 同步发布包含新版大气插件实现、RenderPipeline output effects 和一键 MCP 发布脚本的 npm 包。\n\n## 0.0.17\n\n### 新增\n\n- **atmosphere 插件** — `Atmosphere.enable(options)` 从占位实现升级为可用的大气渲染:支持 WGS84 经纬高定位、太阳/月亮方向、天空背景、天空环境、aerial perspective、lens flare、tone mapping、temporal antialias、dithering 和 `AtmosphereLight` 阴影。\n- **RenderPipeline** — 新增 `addOutputEffect()` / `removeOutputEffect()` 与 `addMRTChannel()` / `removeMRTChannel()`,插件可追加输出后处理和独立 MRT 通道,不再占用业务侧 `setOutputComposer()`。\n\n### 变更\n\n- **大气状态更新** — 大气插件在 `beforeRender` 中刷新相机 ECEF 位置、太阳/月亮方向和阴影 target,相机控制器驱动的移动也能逐帧更新大气状态。\n- **MCP 发布** — 根目录 MCP 发布入口合并为 `pnpm publish:mcp`,命令会先递增 `u-space-mcp` 的 patch 版本,再构建文档索引并发布 npm 包。\n\n## 0.0.16\n\n### 新增\n\n- **u-manager semantics** — `FloorMesh.planish(kind?)`、`FloorMesh.unplanish(kind?)`、`BuildingGroup.planishFloors(kind?)` 和 `BuildingGroup.unplanishFloors(kind?)` 支持按 `Walls`、`Columns`、`Spaces`、`Doors`、`Windows` 语义类型压平或恢复;`setScaleYAt(index, y)` 可只调整单个语义实例的 Y 轴缩放。\n- **BaseMesh** — 默认开启 `castShadow` 与 `receiveShadow`,基础网格和继承自 `BaseMesh` 的对象会直接参与阴影投射与接收。\n\n### 变更\n\n- **语义类型命名** — `SemanticKind` 统一为数据源字段风格:`Walls`、`Columns`、`Spaces`、`Doors`、`Windows`。\n- **示例与依赖** — 更新 `load_tiles.html` 示例依赖,新增 `@takram/three-atmosphere`、`postprocessing` peer dependency,并将 Vite 外部依赖边界扩展到所有 `@takram/*` 包。\n\n## 0.0.12\n\n### 新增\n\n- **u-manager semantics** — 新增 `SemanticLoader`、`BuildingGroup`、`FloorMesh` 语义楼层 API,支持楼层隔离、实例级颜色/透明度/显隐/matrix/scale 控制,以及实例包围盒/包围球查询。\n- **u-space MCP** — 内置文档索引同步语义楼层 API,MCP 客户端可检索 `SemanticLoader`、`BuildingGroup` 和 `FloorMesh` 用法。\n\n## 0.0.8\n\n### 新增\n\n- **Viewer** — `resize()`、`screenshot()`、`setBackground()`、`setEnvironment()`、`enableShadow()`/`disableShadow()`、`enableFog()`/`enableFogExp2()`/`disableFog()`\n- **CameraControls** — `flyTo()`、`getCameraViewpoint()`、`lock()`/`unlock()`、`setViewMode('2d' | '3d')`\n- **ObjectManager** — `show()`/`hide()`、`isolate()`、`showAll()`、`setOpacity()`、`getBoundingBox()`、`forEach()`、`filter()`\n- **InteractionManager** — `enable()`/`disable()`、`setInteractable()`、`addIgnore()`/`removeIgnore()`\n- **Selection** — 新增框选(rubber-band)和单选/多选/切换模块,支持 `select`/`deselect`/`change` 事件\n- **MaterialEffects** — `wireframe()`/`removeWireframe()`、`transparent()`/`removeTransparent()`、`xray()`/`removeXray()`、`fadeIn()`/`fadeOut()`\n- **Model** — `getBoundingBox()`、`getCenter()`、`setMaterial()`\n- **SceneManager** — 新模块,多场景创建、注册、切换与序列化\n- **LightManager** — 新模块,灯光便捷创建、4 种预设(indoor/outdoor/studio/warehouse)、Helper 可视化\n- **MeasureTool** — 新工具,距离/面积/角度测量,结果可视化渲染到场景\n- **ClippingTool** — 新工具,基于 WebGPU `ClippingGroup` 的剖切面与剖切盒\n- **AnnotationManager** — 新工具,3D 引线标注 + HTML 浮动标签\n- **示例** — 新增 8 个交互式示例页面\n\n### 修复\n\n- **Selection** — 框选覆盖层改为挂载到容器元素(而非 canvas),修复框选矩形不可见的问题\n- **ClippingTool** — 从 `renderer.clippingPlanes`(WebGL API)重写为 `ClippingGroup`(WebGPU API),修复剖切无效的问题\n- **MaterialEffects** — fade 动画在对象移除场景后自动停止,避免内存泄漏\n- **InteractionManager** — `dispose()` 中清除 `clickTimer`,避免定时器泄漏\n- **LightManager** — 修复 `removeAll()`/`hideAllHelpers()` 中遍历 Map 同时删除的问题\n- **ObjectManager** — `setOpacity()` 先检查 `isMesh` 再类型转换\n- **ClippingTool** — `PlaneHelper` 颜色使用 `new Color(color).getHex()` 替代直接 `as number`\n- **MeasureTool** — 移除 WebGPU 不支持的 `linewidth` 属性\n\n---\n\n## 0.0.7\n\n### 变更\n\n- 文档拆分:将插件文档拆分为独立文件\n- 新增 CameraControls 独立文档页\n- 修复 getting-started 中的死链\n- 修复 sbmx loader 示例使用新的 MaterialEffects API\n\n---\n\n## 0.0.6\n\n### 新增\n\n- **MaterialEffects** — 可组合的材质特效系统,支持安全共享材质和 remove API\n- **RenderPipeline** — 内置 Bloom、SSGI、TRAA 后处理及 OutputComposer API\n- **CSSRenderer** — CSS2D / CSS2.5D / CSS3D 叠加渲染 HTML 元素\n- 从 `package.json` 导出 `version`,统一示例 importmap\n\n---\n\n## 0.0.5\n\n### 变更\n\n- 版本发布(无重大功能变更)\n\n---\n\n## 0.0.4\n\n### 新增\n\n- **Model** — 动画播放支持(`playAnimation`、`stopAnimation`、`updateAnimation`)\n- **ViewerEventMap** — 事件回调新增 `delta` 时间参数\n\n---\n\n## 0.0.3\n\n### 新增\n\n- **ObjectControls** 插件 — 交互式移动、旋转、缩放 3D 对象\n- **TopologyDrawer** 插件 — 在场景任意表面交互式绘制拓扑路径图\n- **Topology** — `exportData()` / `importData()` 数据序列化\n\n### 变更\n\n- **Interactions** — `contextmenu` 事件替换为 `rightclick`\n- **Poi** — 优化渲染性能,新增 `scaleFactor` 参数\n- 文档全面完善:本地搜索、侧边栏优化、各插件文档页\n\n---\n\n## 0.0.0\n\n### 新增\n\n- 项目初始化:Viewer 核心、WebGPU 渲染器、场景/相机/控制器\n- 模型加载系统:双层缓存(内存 + 持久化)、Draco/KTX2/Meshopt 支持\n- 交互系统:射线检测、事件冒泡、自定义 3D 对象事件\n- 对象系统:Model、Poi、Topology、基础网格(Sphere/Plane/Circle/Tube/Extrude/Shape)\n- ObjectManager 集中式对象注册\n- 补间动画系统\n- u-manager 插件:场景加载、动画、属性、视点管理\n- tiles 插件:ArcGIS 3D 瓦片 / GIS 地球渲染\n- minimap 插件:2D 小地图\n- keyboard-controls 插件:WASD 键盘控制\n- tracking-controls 插件:相机跟随\n- atmosphere 插件:天空/大气渲染\n- curve-movement 插件:曲线路径动画\n"
1309
1434
  },
1310
1435
  {
1311
1436
  "id": "examples-guide",
1312
1437
  "path": "examples-guide.md",
1313
1438
  "title": "示例指南",
1314
- "summary": "`u-space` 的 `examples/` 目录中包含了大量演示引擎功能的示例。以下是几个关键示例及其所展示的系统特性。 示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1`、`0.0.0.0` 或 `192.168.x.x` 访问时会加载仓库里的 `../dist/` 构建产物;在线部署或非本地域名访问时会从 jsDelivr 加载当前发布版本 `u-space@0.0.26`。Vercel 文档部署会继续把 `__VERSION__` 占位符替换为 `package.json` 中的版本号,源码里的 `0.0.26` 作为直接托管 `examples/` 时的 fallback。 插件示例可以在页面加载 `importmap.js` 前通过 `window.__IMPORTS__` 声明额",
1439
+ "summary": "`u-space` 的 `examples/` 目录中包含了大量演示引擎功能的示例。以下是几个关键示例及其所展示的系统特性。 示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1`、`0.0.0.0` 或 `192.168.x.x` 访问时会加载仓库里的 `../dist/` 构建产物;在线部署或非本地域名访问时会从 jsDelivr 加载当前发布版本 `u-space@0.0.28`。Vercel 文档部署会继续把 `__VERSION__` 占位符替换为 `package.json` 中的版本号,源码里的 `0.0.28` 作为直接托管 `examples/` 时的 fallback。 插件示例可以在页面加载 `importmap.js` 前通过 `window.__IMPORTS__` 声明额",
1315
1440
  "headings": [
1316
1441
  {
1317
1442
  "level": 1,
@@ -1355,7 +1480,7 @@ export const docsIndex = [
1355
1480
  },
1356
1481
  {
1357
1482
  "level": 2,
1358
- "text": "5. test_model_animation.html:模型内置动画"
1483
+ "text": "5. test_umanager_loader.html:UManagerLoader 一体化加载"
1359
1484
  },
1360
1485
  {
1361
1486
  "level": 3,
@@ -1363,7 +1488,7 @@ export const docsIndex = [
1363
1488
  },
1364
1489
  {
1365
1490
  "level": 2,
1366
- "text": "6. test_css_renderer.html:CSS2D / CSS2.5D / CSS3D 渲染器"
1491
+ "text": "6. test_model_animation.html:模型内置动画"
1367
1492
  },
1368
1493
  {
1369
1494
  "level": 3,
@@ -1371,7 +1496,7 @@ export const docsIndex = [
1371
1496
  },
1372
1497
  {
1373
1498
  "level": 2,
1374
- "text": "7. test_postprocessing.html:后处理效果"
1499
+ "text": "7. test_css_renderer.html:CSS2D / CSS2.5D / CSS3D 渲染器"
1375
1500
  },
1376
1501
  {
1377
1502
  "level": 3,
@@ -1379,7 +1504,7 @@ export const docsIndex = [
1379
1504
  },
1380
1505
  {
1381
1506
  "level": 2,
1382
- "text": "8. test_viewer_utils.html:Viewer 工具方法"
1507
+ "text": "8. test_postprocessing.html:后处理效果"
1383
1508
  },
1384
1509
  {
1385
1510
  "level": 3,
@@ -1387,7 +1512,7 @@ export const docsIndex = [
1387
1512
  },
1388
1513
  {
1389
1514
  "level": 2,
1390
- "text": "9. test_camera_controls.html:CameraControls 增强方法"
1515
+ "text": "9. test_viewer_utils.html:Viewer 工具方法"
1391
1516
  },
1392
1517
  {
1393
1518
  "level": 3,
@@ -1395,7 +1520,7 @@ export const docsIndex = [
1395
1520
  },
1396
1521
  {
1397
1522
  "level": 2,
1398
- "text": "10. test_object_manager.html:ObjectManager 增强方法"
1523
+ "text": "10. test_camera_controls.html:CameraControls 增强方法"
1399
1524
  },
1400
1525
  {
1401
1526
  "level": 3,
@@ -1403,7 +1528,7 @@ export const docsIndex = [
1403
1528
  },
1404
1529
  {
1405
1530
  "level": 2,
1406
- "text": "11. test_material_effects.html:MaterialEffects 增强效果"
1531
+ "text": "11. test_object_manager.html:ObjectManager 增强方法"
1407
1532
  },
1408
1533
  {
1409
1534
  "level": 3,
@@ -1411,7 +1536,7 @@ export const docsIndex = [
1411
1536
  },
1412
1537
  {
1413
1538
  "level": 2,
1414
- "text": "12. test_selection.html:Selection 选择系统"
1539
+ "text": "12. test_material_effects.html:MaterialEffects 增强效果"
1415
1540
  },
1416
1541
  {
1417
1542
  "level": 3,
@@ -1419,7 +1544,7 @@ export const docsIndex = [
1419
1544
  },
1420
1545
  {
1421
1546
  "level": 2,
1422
- "text": "13. test_measure.html:MeasureTool 测量工具"
1547
+ "text": "13. test_selection.html:Selection 选择系统"
1423
1548
  },
1424
1549
  {
1425
1550
  "level": 3,
@@ -1427,7 +1552,7 @@ export const docsIndex = [
1427
1552
  },
1428
1553
  {
1429
1554
  "level": 2,
1430
- "text": "14. test_annotation.html:AnnotationManager 标注管理"
1555
+ "text": "14. test_measure.html:MeasureTool 测量工具"
1431
1556
  },
1432
1557
  {
1433
1558
  "level": 3,
@@ -1435,7 +1560,7 @@ export const docsIndex = [
1435
1560
  },
1436
1561
  {
1437
1562
  "level": 2,
1438
- "text": "15. test_clipping.html:ClippingTool 剖切工具"
1563
+ "text": "15. test_annotation.html:AnnotationManager 标注管理"
1439
1564
  },
1440
1565
  {
1441
1566
  "level": 3,
@@ -1443,14 +1568,30 @@ export const docsIndex = [
1443
1568
  },
1444
1569
  {
1445
1570
  "level": 2,
1446
- "text": "16. test_lights.html:LightManager 灯光管理"
1571
+ "text": "16. test_clipping.html:ClippingTool 剖切工具"
1572
+ },
1573
+ {
1574
+ "level": 3,
1575
+ "text": "核心要点:"
1576
+ },
1577
+ {
1578
+ "level": 2,
1579
+ "text": "17. test_lights.html:LightManager 灯光管理"
1580
+ },
1581
+ {
1582
+ "level": 3,
1583
+ "text": "核心要点:"
1584
+ },
1585
+ {
1586
+ "level": 2,
1587
+ "text": "18. test_fire.html:WebGPU 体积火焰"
1447
1588
  },
1448
1589
  {
1449
1590
  "level": 3,
1450
1591
  "text": "核心要点:"
1451
1592
  }
1452
1593
  ],
1453
- "content": "# 示例指南\n\n`u-space` 的 `examples/` 目录中包含了大量演示引擎功能的示例。以下是几个关键示例及其所展示的系统特性。\n\n## 运行方式与版本\n\n示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1`、`0.0.0.0` 或 `192.168.x.x` 访问时会加载仓库里的 `../dist/` 构建产物;在线部署或非本地域名访问时会从 jsDelivr 加载当前发布版本 `u-space@0.0.26`。Vercel 文档部署会继续把 `__VERSION__` 占位符替换为 `package.json` 中的版本号,源码里的 `0.0.26` 作为直接托管 `examples/` 时的 fallback。\n\n插件示例可以在页面加载 `importmap.js` 前通过 `window.__IMPORTS__` 声明额外依赖。将 `u-space/plugins/<name>` 的值设为 `true` 时,`importmap.js` 会自动在本地和 CDN 路径之间切换。\n\n## 1. `demo01.html`:基础配置与交互\n\n该示例演示了通过 WebGPU 渲染 3D 场景所需的最少配置,与 [快速上手](./getting-started.md) 指南中的内容一致。\n\n### 核心要点:\n\n- 将 `Viewer` 注入 DOM 元素。\n- 使用 WebGPU `Color` 设置场景背景。\n- 添加基础几何体(如 `BoxGeometry`)。\n- 通过 `viewer.interactionManager.pointerMoveEventsEnabled` 启用全局交互。\n- 像操作 DOM 元素一样,为 3D 网格原生绑定事件监听(`click`、`pointerenter`、`pointerleave`)。\n\n## 2. `test_loader.html`:模型缓存机制\n\n该示例深入解析了 `u-space` 的模型加载管线,阐明运行时缓存与浏览器持久化缓存之间的区别。\n\n### 核心要点:\n\n- 使用全局 `Model` 类通过 `Model.prototype.loadAsync()` 异步加载 `.glb` 文件。\n- 理解 `cache: true`(将模型节点保留在内存中,可实现即时克隆/实例化)。\n- 理解 `persistent: true`(使用 Service Worker / Cache Storage API 对实际网络请求数据进行持久化缓存)。\n- 演示如何将这些异步加载的资源安全地注册到 `viewer.objectManager`。\n- 提供通过 `Model.clearMemoryCache()` 和 `Model.clearPersistentCache()` 手动清除缓存的示例。\n\n## 3. `load_tiles.html`:GIS 与地球渲染\n\n该示例使用外部对等依赖 `3d-tiles-renderer`,通过 `u-space` 插件安全封装后,渲染大规模 LOD GIS 地球。\n\n### 核心要点:\n\n- 动态实例化复杂插件(`ArcgisTilesRenderer`),并传入核心 viewer 引用。\n- 由于瓦片是异步流式加载并持续更新视口的,需使用 `viewer.frameloop = 'always'`。\n- 通过插件的 `invalidate(lon, lat, alt)` 方法定位到指定的经纬高位置。\n- 使用 `lonLatHeightToPosition()` / `positionToLonLatHeight()` 在 WGS84 经纬高和场景世界坐标之间互转。\n\n## 4. `test_umanager.html`:场景组合与解析器\n\n该综合示例融合了多种工具,展示如何构建完整的应用程序,而不仅仅是放置单个模型。\n\n### 核心要点:\n\n- 同时初始化多个插件(minimap、tracking、keyboard-controls),并通过 `.enable()` / `.disable()` 切换其状态。\n- 流式传输结构化场景布局,解析场景描述(`SceneLoader`、`TopologiesLoader`)。\n- 使用相机动画(`VisionsLoader` 和 `VisionsParser`)在场景中编排预定义的飞行路径。\n- 获取复杂的节点材质,并自定义 WebGPU 专属的 TSL(Three Shading Language)节点,如 `TSLEffects.fluid()`。\n\n## 5. `test_model_animation.html`:模型内置动画\n\n[在线演示](https://u-space-phi.vercel.app/examples/test_model_animation.html)\n\n该示例演示了如何加载含内置动画的 glTF 模型,并通过 `Model` 类的动画 API 控制播放。\n\n### 核心要点:\n\n- 使用 `Model.loadAsync()` 加载带动画的 `.glb` 文件,动画片段自动初始化。\n- 使用 `viewer.frameloop = 'always'` 开启持续渲染以驱动动画。\n- 监听 `beforeRender` 事件,通过 `model.updateAnimation(e.delta)` 推进动画时间。\n- 使用 `model.playAnimation(name)` 按名称播放单个动画,`model.playAllAnimations()` 播放全部。\n- 使用 `model.stopAnimation()` 停止动画播放。\n\n## 6. `test_css_renderer.html`:CSS2D / CSS2.5D / CSS3D 渲染器\n\n该示例演示了如何在 3D 场景中叠加渲染 HTML 元素,展示三种 CSS 渲染模式的效果差异。\n\n### 核心要点:\n\n- 使用 `viewer.cssRenderer.createCSS2DObject()` 创建始终面向相机、固定屏幕尺寸的 2D 标签。\n- 使用 `viewer.cssRenderer.createCSS25DObject()` 创建面向相机但随距离缩放的 2.5D 精灵。\n- 使用 `viewer.cssRenderer.createCSS3DObject()` 创建具有完整 3D 变换的面板。\n- CSS2.5D 和 CSS3D 对象需要设置 `scale`(通常 `0.01`),因为 HTML 元素的像素尺寸远大于 3D 世界单位。\n- 渲染器采用懒加载,仅在首次创建对应类型对象时初始化。\n\n## 7. `test_postprocessing.html`:后处理效果\n\n该示例演示了 `RenderPipeline` 的内置后处理功能,包括 Bloom、SSGI、TRAA 以及自定义后处理组合器。\n\n### 核心要点:\n\n- 使用 `viewer.renderPipeline.enableBloom()` / `disableBloom()` 运行时切换 Bloom 效果。\n- 使用 `viewer.renderPipeline.updateBloom()` 实时调整 strength、radius、threshold 参数。\n- 使用 `viewer.renderPipeline.enableSSGI()` / `disableSSGI()` 切换屏幕空间全局光照。\n- 使用 `viewer.renderPipeline.updateSSGI()` 实时调整 SSGI 参数(直接修改 uniform,无需重建节点图)。\n- 使用 `viewer.renderPipeline.enableTRAA()` / `disableTRAA()` 切换时间抗锯齿。\n- 使用 `viewer.renderPipeline.setOutputComposer()` 自定义后处理链(示例中实现了灰度滤镜)。\n- 使用 `setOutputComposer(null)` 恢复默认渲染管线。\n\n## 8. `test_viewer_utils.html`:Viewer 工具方法\n\n该示例演示了 `Viewer` 新增的便捷方法:截图导出、背景切换、雾效控制和阴影开关。\n\n### 核心要点:\n\n- 使用 `viewer.screenshot()` 导出当前渲染画面为 PNG 文件。\n- 使用 `viewer.setBackground(color)` 快速切换场景背景颜色。\n- 使用 `viewer.enableFog()` / `viewer.disableFog()` 控制雾效。\n- 使用 `viewer.enableShadow()` / `viewer.disableShadow()` 控制阴影渲染。\n- 使用 `viewer.resize(width, height)` 手动触发尺寸更新。\n\n## 9. `test_camera_controls.html`:CameraControls 增强方法\n\n该示例演示了 `CameraControls` 的飞行定位、视角存取、锁定和二三维切换功能。\n\n### 核心要点:\n\n- 使用 `viewer.controls.flyTo(position, target)` 将相机飞行到指定坐标。\n- 使用 `viewer.controls.getCameraViewpoint()` 获取当前视角数据。\n- 使用 `viewer.controls.setCameraViewpoint(data)` 恢复保存的视角。\n- 使用 `viewer.controls.lock()` / `unlock()` 锁定或解锁相机控制。\n- 使用 `viewer.controls.setViewMode('2d')` / `setViewMode('3d')` 在二三维视图间切换。\n\n## 10. `test_object_manager.html`:ObjectManager 增强方法\n\n该示例演示了 `ObjectManager` 的显隐控制、孤立显示、透明度设置、包围盒查询和过滤功能。\n\n### 核心要点:\n\n- 使用 `viewer.objectManager.show(id)` / `hide(id)` 控制对象可见性。\n- 使用 `viewer.objectManager.isolate(ids)` 孤立显示指定对象。\n- 使用 `viewer.objectManager.setOpacity(id, value)` 设置材质透明度。\n- 使用 `viewer.objectManager.getBoundingBox()` 查询所有对象的包围盒。\n- 使用 `viewer.objectManager.filter(predicate)` 按条件过滤对象。\n\n## 11. `test_material_effects.html`:MaterialEffects 增强效果\n\n该示例演示了材质效果系统的线框、半透明、X 光和淡入淡出功能。\n\n### 核心要点:\n\n- 使用 `MaterialEffects.wireframe(object)` 开启线框渲染模式。\n- 使用 `MaterialEffects.highlightColor(object, { opacity })` 设置半透明效果。\n- 使用 `MaterialEffects.highlightColor(object, { color, opacity, overwrite: true, depthWrite: false })` 实现 X 光透视效果。\n- 使用 `MaterialEffects.fadeOut(object)` / `fadeIn(object)` 执行淡入淡出动画。\n- 使用 `MaterialEffects.removeHighlightColor(object)` 恢复原始材质状态。\n\n## 12. `test_selection.html`:Selection 选择系统\n\n该示例演示了对象选择系统的单选和框选功能。\n\n### 核心要点:\n\n- 创建 `Selection` 实例并监听 `select`、`deselect`、`change` 事件。\n- 使用 `selection.select()` / `deselect()` / `toggle()` / `clear()` 进行程序化选择操作。\n- 使用 `selection.enableBoxSelection()` 开启鼠标框选模式。\n- 框选模式下可配合 `viewer.controls.lock()` 避免框选与相机旋转冲突。\n\n## 13. `test_measure.html`:MeasureTool 测量工具\n\n该示例演示了 3D 场景中的距离、面积和角度测量。\n\n### 核心要点:\n\n- 使用 `measureTool.measureDistance(pointA, pointB)` 测量两点距离。\n- 使用 `measureTool.measureArea(points)` 测量多边形面积。\n- 使用 `measureTool.measureAngle(pointA, vertex, pointC)` 测量夹角。\n- 测量结果以可视化线条渲染到场景中,返回的 `MeasureResult` 包含数值和单位。\n\n## 14. `test_annotation.html`:AnnotationManager 标注管理\n\n该示例演示了 3D 标注的创建、更新和管理,配合 `CSSRenderer` 实现 HTML 浮动标签。\n\n### 核心要点:\n\n- 创建 `AnnotationManager` 实例并通过 `setCSSObjectFactory()` 绑定 `CSSRenderer`。\n- 使用 `annotationManager.add(id, options)` 添加带引线和自定义样式的标注。\n- 使用 `annotationManager.addText(text, position)` 快捷添加纯文本标注。\n- 使用 `updateContent()` 动态更新标注内容,`updatePosition()` 移动标注位置。\n- 使用 `hideAll()` / `showAll()` 批量控制标注显隐。\n\n## 15. `test_clipping.html`:ClippingTool 剖切工具\n\n该示例演示了剖切面的创建和实时调整。\n\n### 核心要点:\n\n- 创建 `ClippingTool` 实例并调用 `attach()` 将场景物体移入 ClippingGroup。\n- 使用 `clippingTool.addPlane(id, options)` 添加剖切面。\n- 使用滑块通过 `clippingTool.setPlaneConstant()` 实时调整剖切位置。\n- 使用 `showHelper()` / `hideHelper()` 切换剖切面可视化辅助。\n\n## 16. `test_lights.html`:LightManager 灯光管理\n\n该示例演示了灯光管理器的灯光预设和 Helper 可视化功能。\n\n### 核心要点:\n\n- 创建 `LightManager` 实例并使用 `applyPreset()` 一键应用灯光预设。\n- 支持 4 种预设:`indoor`(室内)、`outdoor`(室外)、`studio`(摄影棚)、`warehouse`(仓库)。\n- 使用 `showAllHelpers()` / `hideAllHelpers()` 显示或隐藏灯光辅助可视化。\n- 每种预设会自动清除旧灯光并创建新的灯光组合。\n"
1594
+ "content": "# 示例指南\n\n`u-space` 的 `examples/` 目录中包含了大量演示引擎功能的示例。以下是几个关键示例及其所展示的系统特性。\n\n## 运行方式与版本\n\n示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1`、`0.0.0.0` 或 `192.168.x.x` 访问时会加载仓库里的 `../dist/` 构建产物;在线部署或非本地域名访问时会从 jsDelivr 加载当前发布版本 `u-space@0.0.28`。Vercel 文档部署会继续把 `__VERSION__` 占位符替换为 `package.json` 中的版本号,源码里的 `0.0.28` 作为直接托管 `examples/` 时的 fallback。\n\n插件示例可以在页面加载 `importmap.js` 前通过 `window.__IMPORTS__` 声明额外依赖。将 `u-space/plugins/<name>` 的值设为 `true` 时,`importmap.js` 会自动在本地和 CDN 路径之间切换。\n\n## 1. `demo01.html`:基础配置与交互\n\n该示例演示了通过 WebGPU 渲染 3D 场景所需的最少配置,与 [快速上手](./getting-started.md) 指南中的内容一致。\n\n### 核心要点:\n\n- 将 `Viewer` 注入 DOM 元素。\n- 使用 WebGPU `Color` 设置场景背景。\n- 添加基础几何体(如 `BoxGeometry`)。\n- 通过 `viewer.interactionManager.pointerMoveEventsEnabled` 启用全局交互。\n- 像操作 DOM 元素一样,为 3D 网格原生绑定事件监听(`click`、`pointerenter`、`pointerleave`)。\n\n## 2. `test_loader.html`:模型缓存机制\n\n该示例深入解析了 `u-space` 的模型加载管线,阐明运行时缓存与浏览器持久化缓存之间的区别。\n\n### 核心要点:\n\n- 使用全局 `Model` 类通过 `Model.prototype.loadAsync()` 异步加载 `.glb` 文件。\n- 理解 `cache: true`(将模型节点保留在内存中,可实现即时克隆/实例化)。\n- 理解 `persistent: true`(使用 Service Worker / Cache Storage API 对实际网络请求数据进行持久化缓存)。\n- 演示如何将这些异步加载的资源安全地注册到 `viewer.objectManager`。\n- 提供通过 `Model.clearMemoryCache()` 和 `Model.clearPersistentCache()` 手动清除缓存的示例。\n\n## 3. `load_tiles.html`:GIS 与地球渲染\n\n该示例使用外部对等依赖 `3d-tiles-renderer`,通过 `u-space` 插件安全封装后,渲染大规模 LOD GIS 地球。\n\n### 核心要点:\n\n- 动态实例化复杂插件(`ArcgisTilesRenderer`),并传入核心 viewer 引用。\n- 由于瓦片是异步流式加载并持续更新视口的,需使用 `viewer.frameloop = 'always'`。\n- 通过插件的 `invalidate(lon, lat, alt)` 方法定位到指定的经纬高位置。\n- 使用 `lonLatHeightToPosition()` / `positionToLonLatHeight()` 在 WGS84 经纬高和场景世界坐标之间互转。\n\n## 4. `test_umanager.html`:场景组合与解析器\n\n该综合示例融合了多种工具,展示如何构建完整的应用程序,而不仅仅是放置单个模型。\n\n### 核心要点:\n\n- 同时初始化多个插件(minimap、tracking、keyboard-controls),并通过 `.enable()` / `.disable()` 切换其状态。\n- 流式传输结构化场景布局,解析场景描述(`SceneLoader`、`TopologiesLoader`)。\n- 使用相机动画(`VisionsLoader` 和 `VisionsParser`)在场景中编排预定义的飞行路径。\n- 获取复杂的节点材质,并自定义 WebGPU 专属的 TSL(Three Shading Language)节点,如 `TSLEffects.fluid()`。\n\n## 5. `test_umanager_loader.html`:UManagerLoader 一体化加载\n\n[在线演示](https://u-space-phi.vercel.app/examples/test_umanager_loader.html)\n\n该示例演示通过 `UManagerLoader` 在同一个路径下同时加载语义楼层、Facilities 和非语义场景树内容。加载结果会返回一个 `UManagerSceneGroup`,其中 `semanticGroup` 指向 `SemanticGroup`,`sceneGroup` 指向非语义场景组。\n\n### 核心要点:\n\n- 使用 `UManagerLoader.setPath()` 配置场景根目录,并通过一次 `loadAsync()` 完成 `SemanticLoader` + `SceneLoader` 组合加载。\n- `SceneLoader` 会自动跳过语义文件中已存在的 `id`,避免建筑、楼层或设备重复加载。\n- 通过 `viewer.objectManager` 获取 `SceneInstanceObject` 和 `FacilityInstanceObject`,再使用统一 `getSemanticBoundingBox()` + `viewer.controls.flyToBox()` 飞向单个实例。\n- 使用 `setSemanticHighlight()`、`setSemanticVisible()`、`setSemanticOpacity()` 等统一 API 控制实例,不需要关心底层是合并几何、`InstancedMesh` 还是 fallback `Model`。\n- 示例把 `viewer`、`loader`、`root`、`semanticGroup`、`sceneGroup`、`sceneInstances` 和 `facilities` 暴露到 `window.uManagerExample`,方便在控制台调试。\n\n## 6. `test_model_animation.html`:模型内置动画\n\n[在线演示](https://u-space-phi.vercel.app/examples/test_model_animation.html)\n\n该示例演示了如何加载含内置动画的 glTF 模型,并通过 `Model` 类的动画 API 控制播放。\n\n### 核心要点:\n\n- 使用 `Model.loadAsync()` 加载带动画的 `.glb` 文件,动画片段自动初始化。\n- 使用 `viewer.frameloop = 'always'` 开启持续渲染以驱动动画。\n- 监听 `beforeRender` 事件,通过 `model.updateAnimation(e.delta)` 推进动画时间。\n- 使用 `model.playAnimation(name)` 按名称播放单个动画,`model.playAllAnimations()` 播放全部。\n- 使用 `model.stopAnimation()` 停止动画播放。\n\n## 7. `test_css_renderer.html`:CSS2D / CSS2.5D / CSS3D 渲染器\n\n该示例演示了如何在 3D 场景中叠加渲染 HTML 元素,展示三种 CSS 渲染模式的效果差异。\n\n### 核心要点:\n\n- 使用 `viewer.cssRenderer.createCSS2DObject()` 创建始终面向相机、固定屏幕尺寸的 2D 标签。\n- 使用 `viewer.cssRenderer.createCSS25DObject()` 创建面向相机但随距离缩放的 2.5D 精灵。\n- 使用 `viewer.cssRenderer.createCSS3DObject()` 创建具有完整 3D 变换的面板。\n- CSS2.5D 和 CSS3D 对象需要设置 `scale`(通常 `0.01`),因为 HTML 元素的像素尺寸远大于 3D 世界单位。\n- 渲染器采用懒加载,仅在首次创建对应类型对象时初始化。\n\n## 8. `test_postprocessing.html`:后处理效果\n\n该示例演示了 `RenderPipeline` 的内置后处理功能,包括 Bloom、SSGI、TRAA 以及自定义后处理组合器。\n\n### 核心要点:\n\n- 使用 `viewer.renderPipeline.enableBloom()` / `disableBloom()` 运行时切换 Bloom 效果。\n- 使用 `viewer.renderPipeline.updateBloom()` 实时调整 strength、radius、threshold 参数。\n- 使用 `viewer.renderPipeline.enableSSGI()` / `disableSSGI()` 切换屏幕空间全局光照。\n- 使用 `viewer.renderPipeline.updateSSGI()` 实时调整 SSGI 参数(直接修改 uniform,无需重建节点图)。\n- 使用 `viewer.renderPipeline.enableTRAA()` / `disableTRAA()` 切换时间抗锯齿。\n- 使用 `viewer.renderPipeline.setOutputComposer()` 自定义后处理链(示例中实现了灰度滤镜)。\n- 使用 `setOutputComposer(null)` 恢复默认渲染管线。\n\n## 9. `test_viewer_utils.html`:Viewer 工具方法\n\n该示例演示了 `Viewer` 新增的便捷方法:截图导出、背景切换、雾效控制和阴影开关。\n\n### 核心要点:\n\n- 使用 `viewer.screenshot()` 导出当前渲染画面为 PNG 文件。\n- 使用 `viewer.setBackground(color)` 快速切换场景背景颜色。\n- 使用 `viewer.enableFog()` / `viewer.disableFog()` 控制雾效。\n- 使用 `viewer.enableShadow()` / `viewer.disableShadow()` 控制阴影渲染。\n- 使用 `viewer.resize(width, height)` 手动触发尺寸更新。\n\n## 10. `test_camera_controls.html`:CameraControls 增强方法\n\n该示例演示了 `CameraControls` 的飞行定位、视角存取、锁定和二三维切换功能。\n\n### 核心要点:\n\n- 使用 `viewer.controls.flyTo(position, target)` 将相机飞行到指定坐标。\n- 使用 `viewer.controls.getCameraViewpoint()` 获取当前视角数据。\n- 使用 `viewer.controls.setCameraViewpoint(data)` 恢复保存的视角。\n- 使用 `viewer.controls.lock()` / `unlock()` 锁定或解锁相机控制。\n- 使用 `viewer.controls.setViewMode('2d')` / `setViewMode('3d')` 在二三维视图间切换。\n\n## 11. `test_object_manager.html`:ObjectManager 增强方法\n\n该示例演示了 `ObjectManager` 的显隐控制、孤立显示、透明度设置、包围盒查询和过滤功能。\n\n### 核心要点:\n\n- 使用 `viewer.objectManager.show(id)` / `hide(id)` 控制对象可见性。\n- 使用 `viewer.objectManager.isolate(ids)` 孤立显示指定对象。\n- 使用 `viewer.objectManager.setOpacity(id, value)` 设置材质透明度。\n- 使用 `viewer.objectManager.getBoundingBox()` 查询所有对象的包围盒。\n- 使用 `viewer.objectManager.filter(predicate)` 按条件过滤对象。\n\n## 12. `test_material_effects.html`:MaterialEffects 增强效果\n\n该示例演示了材质效果系统的线框、半透明、X 光和淡入淡出功能。\n\n### 核心要点:\n\n- 使用 `MaterialEffects.wireframe(object)` 开启线框渲染模式。\n- 使用 `MaterialEffects.highlightColor(object, { opacity })` 设置半透明效果。\n- 使用 `MaterialEffects.highlightColor(object, { color, opacity, overwrite: true, depthWrite: false })` 实现 X 光透视效果。\n- 使用 `MaterialEffects.fadeOut(object)` / `fadeIn(object)` 执行淡入淡出动画。\n- 使用 `MaterialEffects.removeHighlightColor(object)` 恢复原始材质状态。\n\n## 13. `test_selection.html`:Selection 选择系统\n\n该示例演示了对象选择系统的单选和框选功能。\n\n### 核心要点:\n\n- 创建 `Selection` 实例并监听 `select`、`deselect`、`change` 事件。\n- 使用 `selection.select()` / `deselect()` / `toggle()` / `clear()` 进行程序化选择操作。\n- 使用 `selection.enableBoxSelection()` 开启鼠标框选模式。\n- 框选模式下可配合 `viewer.controls.lock()` 避免框选与相机旋转冲突。\n\n## 14. `test_measure.html`:MeasureTool 测量工具\n\n该示例演示了 3D 场景中的距离、面积和角度测量。\n\n### 核心要点:\n\n- 使用 `measureTool.measureDistance(pointA, pointB)` 测量两点距离。\n- 使用 `measureTool.measureArea(points)` 测量多边形面积。\n- 使用 `measureTool.measureAngle(pointA, vertex, pointC)` 测量夹角。\n- 测量结果以可视化线条渲染到场景中,返回的 `MeasureResult` 包含数值和单位。\n\n## 15. `test_annotation.html`:AnnotationManager 标注管理\n\n该示例演示了 3D 标注的创建、更新和管理,配合 `CSSRenderer` 实现 HTML 浮动标签。\n\n### 核心要点:\n\n- 创建 `AnnotationManager` 实例并通过 `setCSSObjectFactory()` 绑定 `CSSRenderer`。\n- 使用 `annotationManager.add(id, options)` 添加带引线和自定义样式的标注。\n- 使用 `annotationManager.addText(text, position)` 快捷添加纯文本标注。\n- 使用 `updateContent()` 动态更新标注内容,`updatePosition()` 移动标注位置。\n- 使用 `hideAll()` / `showAll()` 批量控制标注显隐。\n\n## 16. `test_clipping.html`:ClippingTool 剖切工具\n\n该示例演示了剖切面的创建和实时调整。\n\n### 核心要点:\n\n- 创建 `ClippingTool` 实例并调用 `attach()` 将场景物体移入 ClippingGroup。\n- 使用 `clippingTool.addPlane(id, options)` 添加剖切面。\n- 使用滑块通过 `clippingTool.setPlaneConstant()` 实时调整剖切位置。\n- 使用 `showHelper()` / `hideHelper()` 切换剖切面可视化辅助。\n\n## 17. `test_lights.html`:LightManager 灯光管理\n\n该示例演示了灯光管理器的灯光预设和 Helper 可视化功能。\n\n### 核心要点:\n\n- 创建 `LightManager` 实例并使用 `applyPreset()` 一键应用灯光预设。\n- 支持 4 种预设:`indoor`(室内)、`outdoor`(室外)、`studio`(摄影棚)、`warehouse`(仓库)。\n- 使用 `showAllHelpers()` / `hideAllHelpers()` 显示或隐藏灯光辅助可视化。\n- 每种预设会自动清除旧灯光并创建新的灯光组合。\n\n## 18. `test_fire.html`:WebGPU 体积火焰\n\n该示例演示了 `u-space/plugins/fire` 的 `FireEffect` 插件,封装 Three.js 官方体积火焰示例,在独立 volumetric pass 中模拟火焰和烟雾后叠加到主场景。\n\n### 核心要点:\n\n- 使用 `FireEffect` 创建 WebGPU 体积火焰、烟雾、扰动、动态点光源和体积阴影。\n- 通过 `position` 和 `size` 设置体积盒底部中心和烟雾扩散约束范围。\n- 默认使用 `TeapotGeometry(0.8, 28)` 作为 emitter;也可以传入业务 `Object3D` 和自定义 `emitterGeometry`。\n- 通过 `fire.update()` 实时调整 `fireIntensity`、`smokeLifespan`、`emitterRadius` 等参数。\n- 插件使用 RenderPipeline output effect 接入,不占用业务侧的 `setOutputComposer()`。\n"
1454
1595
  },
1455
1596
  {
1456
1597
  "id": "getting-started",
@@ -1495,7 +1636,7 @@ export const docsIndex = [
1495
1636
  "text": "下一步"
1496
1637
  }
1497
1638
  ],
1498
- "content": "# 快速上手 `u-space`\n\n`u-space` 是一个基于 Three.js 的 WebGPU 3D 引擎。本指南将向你展示如何搭建一个基础的 `u-space` 应用。\n\n## 安装\n\n确保已将 `@types/three` 和 `three` 安装为对等依赖。如果你计划使用交互功能,还需要安装 `camera-controls`。\n\n```bash\npnpm install three camera-controls\n```\n\n## 基础配置\n\n以下是一个最小示例,展示如何初始化 `u-space` 的 `Viewer` 并向场景中添加一个可交互对象。\n\n### 1. HTML 结构\n\n创建一个容纳 3D 查看器的元素。\n\n```html\n<!DOCTYPE html>\n<html lang=\"zh\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>u-space App</title>\n </head>\n <body style=\"margin: 0\">\n <div id=\"app\" style=\"width: 100vw; height: 100vh\"></div>\n <!-- 脚本放这里 -->\n </body>\n</html>\n```\n\n### 2. Import Maps\n\n由于 `u-space` 依赖 Three.js 的 WebGPU 特性,建议配置 Import Map 以解析 Three.js 的 WebGPU 构建版本。\n\n```html\n<script type=\"importmap\">\n {\n \"imports\": {\n \"three\": \"/node_modules/three/build/three.webgpu.js\",\n \"three/webgpu\": \"/node_modules/three/build/three.webgpu.js\",\n \"three/addons/\": \"/node_modules/three/examples/jsm/\",\n \"camera-controls\": \"/node_modules/camera-controls/dist/camera-controls.module.js\",\n \"u-space\": \"path/to/u-space/dist/index.js\"\n }\n }\n</script>\n```\n\n### 3. 初始化 Viewer 并添加对象\n\n初始化 `Viewer` 并向场景中添加一个基础 Three.js 对象。\n\n```html\n<script type=\"module\">\n import { Color, GridHelper, Mesh, BoxGeometry, MeshBasicMaterial } from 'three/webgpu';\n import { Viewer } from 'u-space';\n\n const app = document.getElementById('app');\n\n // 初始化查看器\n const viewer = new Viewer({\n el: app,\n rendererOptions: { forceWebGL: false }, // 优先使用 WebGPU\n });\n await viewer.init();\n\n // 设置背景颜色\n viewer.scene.background = new Color(0x666666);\n\n // 添加网格辅助线\n const gridHelper = new GridHelper(10, 10);\n viewer.scene.add(gridHelper);\n\n // 添加一个立方体\n const geometry = new BoxGeometry(1, 1, 1);\n const material = new MeshBasicMaterial({ color: 0xff0000 });\n const box = new Mesh(geometry, material);\n box.position.set(0, 0.5, 0);\n viewer.scene.add(box);\n\n // 渲染场景\n viewer.render();\n</script>\n```\n\n### 4. 启用交互\n\n`u-space` 内置了 `InteractionManager`,可以轻松为 3D 对象添加事件监听。\n\n```javascript\n// 启用指针移动事件(pointerenter / pointerleave 需要此开关)\nviewer.interactionManager.pointerMoveEventsEnabled = true;\n\n// 添加点击事件\nbox.addEventListener('click', (e) => {\n console.log('点击位置:', e.event.intersect.point);\n material.color.set(Math.random() * 0xffffff);\n viewer.render(); // 请求新一帧渲染\n});\n\n// 添加悬停事件\nbox.addEventListener('pointerenter', (e) => {\n document.body.style.cursor = 'pointer';\n material.color.set(0x00ff00);\n viewer.render();\n});\n\nbox.addEventListener('pointerleave', (e) => {\n document.body.style.cursor = 'default';\n material.color.set(0xff0000);\n viewer.render();\n});\n```\n\n这样就完成了!你现在拥有一个基础的 `u-space` 应用。\n\n## 版本信息\n\n`u-space` 导出了 `version` 常量,同时在 `window.__USPACE__` 上挂载了版本信息,方便调试和版本检查。\n\n```typescript\nimport { version } from 'u-space';\nconsole.log(version); // e.g. '0.0.26'\n\n// 也可以通过全局变量访问\nconsole.log(window.__USPACE__.version);\n```\n\n## 下一步\n\n- 深入了解 [Viewer API](./api-viewer.md)\n- 探索如何 [加载模型与使用对象](./api-objects.md)\n- 理解 [交互系统](./api-interactions.md)\n- 使用 [Managers API](./api-managers.md) 注册和检索对象\n- 通过插件添加 [瓦片地图](./api-plugin-tiles.md)、[小地图](./api-plugin-minimap.md)、[键盘控制](./api-plugin-keyboard-controls.md) 等功能\n- 使用 [Animations API](./api-animations.md) 为属性添加动画\n- 使用 [Effects API](./api-effects.md) 应用视觉特效\n- 浏览 [示例指南](./examples-guide.md)\n"
1639
+ "content": "# 快速上手 `u-space`\n\n`u-space` 是一个基于 Three.js 的 WebGPU 3D 引擎。本指南将向你展示如何搭建一个基础的 `u-space` 应用。\n\n## 安装\n\n确保已将 `@types/three` 和 `three` 安装为对等依赖。如果你计划使用交互功能,还需要安装 `camera-controls`。\n\n```bash\npnpm install three camera-controls\n```\n\n## 基础配置\n\n以下是一个最小示例,展示如何初始化 `u-space` 的 `Viewer` 并向场景中添加一个可交互对象。\n\n### 1. HTML 结构\n\n创建一个容纳 3D 查看器的元素。\n\n```html\n<!DOCTYPE html>\n<html lang=\"zh\">\n <head>\n <meta charset=\"UTF-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>u-space App</title>\n </head>\n <body style=\"margin: 0\">\n <div id=\"app\" style=\"width: 100vw; height: 100vh\"></div>\n <!-- 脚本放这里 -->\n </body>\n</html>\n```\n\n### 2. Import Maps\n\n由于 `u-space` 依赖 Three.js 的 WebGPU 特性,建议配置 Import Map 以解析 Three.js 的 WebGPU 构建版本。\n\n```html\n<script type=\"importmap\">\n {\n \"imports\": {\n \"three\": \"/node_modules/three/build/three.webgpu.js\",\n \"three/webgpu\": \"/node_modules/three/build/three.webgpu.js\",\n \"three/addons/\": \"/node_modules/three/examples/jsm/\",\n \"camera-controls\": \"/node_modules/camera-controls/dist/camera-controls.module.js\",\n \"u-space\": \"path/to/u-space/dist/index.js\"\n }\n }\n</script>\n```\n\n### 3. 初始化 Viewer 并添加对象\n\n初始化 `Viewer` 并向场景中添加一个基础 Three.js 对象。\n\n```html\n<script type=\"module\">\n import { Color, GridHelper, Mesh, BoxGeometry, MeshBasicMaterial } from 'three/webgpu';\n import { Viewer } from 'u-space';\n\n const app = document.getElementById('app');\n\n // 初始化查看器\n const viewer = new Viewer({\n el: app,\n rendererOptions: { forceWebGL: false }, // 优先使用 WebGPU\n });\n await viewer.init();\n\n // 设置背景颜色\n viewer.scene.background = new Color(0x666666);\n\n // 添加网格辅助线\n const gridHelper = new GridHelper(10, 10);\n viewer.scene.add(gridHelper);\n\n // 添加一个立方体\n const geometry = new BoxGeometry(1, 1, 1);\n const material = new MeshBasicMaterial({ color: 0xff0000 });\n const box = new Mesh(geometry, material);\n box.position.set(0, 0.5, 0);\n viewer.scene.add(box);\n\n // 渲染场景\n viewer.render();\n</script>\n```\n\n### 4. 启用交互\n\n`u-space` 内置了 `InteractionManager`,可以轻松为 3D 对象添加事件监听。\n\n```javascript\n// 启用指针移动事件(pointerenter / pointerleave 需要此开关)\nviewer.interactionManager.pointerMoveEventsEnabled = true;\n\n// 添加点击事件\nbox.addEventListener('click', (e) => {\n console.log('点击位置:', e.event.intersect.point);\n material.color.set(Math.random() * 0xffffff);\n viewer.render(); // 请求新一帧渲染\n});\n\n// 添加悬停事件\nbox.addEventListener('pointerenter', (e) => {\n document.body.style.cursor = 'pointer';\n material.color.set(0x00ff00);\n viewer.render();\n});\n\nbox.addEventListener('pointerleave', (e) => {\n document.body.style.cursor = 'default';\n material.color.set(0xff0000);\n viewer.render();\n});\n```\n\n这样就完成了!你现在拥有一个基础的 `u-space` 应用。\n\n## 版本信息\n\n`u-space` 导出了 `version` 常量,同时在 `window.__USPACE__` 上挂载了版本信息,方便调试和版本检查。\n\n```typescript\nimport { version } from 'u-space';\nconsole.log(version); // e.g. '0.0.28'\n\n// 也可以通过全局变量访问\nconsole.log(window.__USPACE__.version);\n```\n\n## 下一步\n\n- 深入了解 [Viewer API](./api-viewer.md)\n- 探索如何 [加载模型与使用对象](./api-objects.md)\n- 理解 [交互系统](./api-interactions.md)\n- 使用 [Managers API](./api-managers.md) 注册和检索对象\n- 通过插件添加 [瓦片地图](./api-plugin-tiles.md)、[小地图](./api-plugin-minimap.md)、[键盘控制](./api-plugin-keyboard-controls.md) 等功能\n- 使用 [Animations API](./api-animations.md) 为属性添加动画\n- 使用 [Effects API](./api-effects.md) 应用视觉特效\n- 浏览 [示例指南](./examples-guide.md)\n"
1499
1640
  },
1500
1641
  {
1501
1642
  "id": "index",
@@ -1520,13 +1661,13 @@ export const docsIndex = [
1520
1661
  "text": "MCP"
1521
1662
  }
1522
1663
  ],
1523
- "content": "---\nlayout: home\n\nhero:\n name: u-space\n text: WebGPU-ready 3D Engine\n tagline: 基于 Three.js 的插件化 3D 可视化库,支持 GIS 瓦片、动画、场景管理与交互系统。\n actions:\n - theme: brand\n text: 快速上手\n link: /getting-started\n - theme: alt\n text: API 文档\n link: /api-viewer\n - theme: alt\n text: 在线示例\n link: /examples/\n target: _self\n\nfeatures:\n - title: WebGPU 优先\n details: 基于 Three.js WebGPU 渲染器,支持 TSL(Three Shading Language)着色器节点,同时保持 WebGL 兼容回退。\n - title: 插件化架构\n details: 核心轻量,通过独立插件按需扩展:GIS 瓦片、小地图、键盘控制、场景管理、曲线动画等。\n - title: 交互系统\n details: 内置射线检测与事件冒泡,像操作 DOM 元素一样为 3D 对象添加 click、pointerenter 等事件。\n---\n\n## 文档目录\n\n### 核心 API\n\n| 文档 | 说明 |\n| :--- | :--- |\n| [Viewer](./api-viewer) | 核心类:渲染器、场景、相机、控制器、事件 |\n| [CameraControls](./api-camera-controls) | 相机控制:飞行、视角切换、视点过渡 |\n| [CSSRenderer](./api-css-renderer) | CSS 渲染器:CSS2D / CSS2.5D / CSS3D 叠加 HTML 元素 |\n| [RenderPipeline](./api-render-pipeline) | 后处理管线:Bloom、SSGI、TRAA、自定义后处理 |\n| [Objects](./api-objects) | 3D 对象:模型加载、基础网格、Poi、Topology |\n| [Interactions](./api-interactions) | 交互管理:射线检测、鼠标/触摸事件、框选 |\n| [Managers](./api-managers) | 对象管理、场景管理、灯光管理 |\n| [Animations](./api-animations) | 补间动画:`tweenAnimation`、`Tween`、缓动模式 |\n| [Effects](./api-effects) | 视觉特效:高亮、呼吸、线框、淡入淡出、流动、流体(TSL) |\n| [Tools](./api-tools) | 工具:测量(距离/面积/角度)、剖切(面/盒)、标注管理 |\n\n### 插件\n\n所有插件从 `u-space/plugins/<name>` 导入。\n\n| 插件 | 说明 |\n| :--- | :--- |\n| [keyboard-controls](./api-plugin-keyboard-controls) | WASD / 方向键控制相机移动与旋转 |\n| [minimap](./api-plugin-minimap) | 2D 小地图叠加层 |\n| [tiles](./api-plugin-tiles) | ArcGIS 3D 瓦片 / GIS 地球渲染 |\n| [u-manager](./api-plugin-u-manager) | 场景加载、语义楼层、语义井道、楼层设备、拓扑、动画、属性、视点管理 |\n| [curve-movement](./api-plugin-curve-movement) | 沿样条曲线移动相机或对象 |\n| [tracking-controls](./api-plugin-tracking-controls) | 相机跟随移动目标 |\n| [atmosphere](./api-plugin-atmosphere) | 天空背景、天空环境、太阳/月亮光照与阴影 |\n| [object-controls](./api-plugin-object-controls) | 交互式移动、旋转、缩放 3D 对象 |\n| [topology-drawer](./api-plugin-topology-drawer) | 在场景任意表面交互式绘制拓扑路径图 |\n\n### MCP\n\n| 文档 | 说明 |\n| :--- | :--- |\n| [u-space MCP](./mcp) | 面向 Mastra、Claude Desktop、Cursor 等 MCP 客户端的只读文档检索服务器 |\n"
1664
+ "content": "---\nlayout: home\n\nhero:\n name: u-space\n text: WebGPU-ready 3D Engine\n tagline: 基于 Three.js 的插件化 3D 可视化库,支持 GIS 瓦片、动画、场景管理与交互系统。\n actions:\n - theme: brand\n text: 快速上手\n link: /getting-started\n - theme: alt\n text: API 文档\n link: /api-viewer\n - theme: alt\n text: 在线示例\n link: /examples/\n target: _self\n\nfeatures:\n - title: WebGPU 优先\n details: 基于 Three.js WebGPU 渲染器,支持 TSL(Three Shading Language)着色器节点,同时保持 WebGL 兼容回退。\n - title: 插件化架构\n details: 核心轻量,通过独立插件按需扩展:GIS 瓦片、小地图、键盘控制、场景管理、曲线动画等。\n - title: 交互系统\n details: 内置射线检测与事件冒泡,像操作 DOM 元素一样为 3D 对象添加 click、pointerenter 等事件。\n---\n\n## 文档目录\n\n### 核心 API\n\n| 文档 | 说明 |\n| :--- | :--- |\n| [Viewer](./api-viewer) | 核心类:渲染器、场景、相机、控制器、事件 |\n| [CameraControls](./api-camera-controls) | 相机控制:飞行、视角切换、视点过渡 |\n| [CSSRenderer](./api-css-renderer) | CSS 渲染器:CSS2D / CSS2.5D / CSS3D 叠加 HTML 元素 |\n| [RenderPipeline](./api-render-pipeline) | 后处理管线:Bloom、SSGI、TRAA、自定义后处理 |\n| [Objects](./api-objects) | 3D 对象:模型加载、基础网格、Poi、Topology |\n| [Interactions](./api-interactions) | 交互管理:射线检测、鼠标/触摸事件、框选 |\n| [Managers](./api-managers) | 对象管理、场景管理、灯光管理 |\n| [Animations](./api-animations) | 补间动画:`tweenAnimation`、`Tween`、缓动模式 |\n| [Effects](./api-effects) | 视觉特效:高亮、呼吸、线框、淡入淡出、流动、流体(TSL) |\n| [Tools](./api-tools) | 工具:测量(距离/面积/角度)、剖切(面/盒)、标注管理 |\n\n### 插件\n\n所有插件从 `u-space/plugins/<name>` 导入。\n\n| 插件 | 说明 |\n| :--- | :--- |\n| [keyboard-controls](./api-plugin-keyboard-controls) | WASD / 方向键控制相机移动与旋转 |\n| [minimap](./api-plugin-minimap) | 2D 小地图叠加层 |\n| [tiles](./api-plugin-tiles) | ArcGIS 3D 瓦片 / GIS 地球渲染 |\n| [u-manager](./api-plugin-u-manager) | 场景加载、语义楼层、语义井道、楼层设备、拓扑、动画、属性、视点管理 |\n| [curve-movement](./api-plugin-curve-movement) | 沿样条曲线移动相机或对象 |\n| [tracking-controls](./api-plugin-tracking-controls) | 相机跟随移动目标 |\n| [atmosphere](./api-plugin-atmosphere) | 天空背景、天空环境、太阳/月亮光照与阴影 |\n| [fire](./api-plugin-fire) | WebGPU 体积火焰、烟雾、湍流、动态光照与阴影 |\n| [object-controls](./api-plugin-object-controls) | 交互式移动、旋转、缩放 3D 对象 |\n| [topology-drawer](./api-plugin-topology-drawer) | 在场景任意表面交互式绘制拓扑路径图 |\n\n### MCP\n\n| 文档 | 说明 |\n| :--- | :--- |\n| [u-space MCP](./mcp) | 面向 Mastra、Claude Desktop、Cursor 等 MCP 客户端的只读文档检索服务器 |\n"
1524
1665
  },
1525
1666
  {
1526
1667
  "id": "mcp",
1527
1668
  "path": "mcp.md",
1528
1669
  "title": "u-space MCP",
1529
- "summary": "`u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括 `u-manager` 的 `SemanticLoader`、`SemanticSceneGroup`、`BuildingGroup`、`FloorMesh` 语义楼层 API、楼层 `Facilities` 设备检索与 scene-level auto instancing、设备显隐/颜色/透明度控制、电梯井/通风井语义体块,以及 atmosphere 插件的 `skyBackground()`、`skyEnvironment()` 和 RenderPipeline ou",
1670
+ "summary": "`u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括 `u-manager` 的 `UManagerLoader` 一体化加载入口、`SceneLoader` 语义去重与 path-based model instancing、统一 `SemanticInstanceObject` API、`SemanticModelInstancedLayer` 共享模型合批层、`SceneInstanceObject` 场景模型引用、`SceneInstancedLayer` 批量渲染层、`SemanticLoader`、`Semanti",
1530
1671
  "headings": [
1531
1672
  {
1532
1673
  "level": 1,
@@ -1544,12 +1685,24 @@ export const docsIndex = [
1544
1685
  "level": 2,
1545
1686
  "text": "工具列表"
1546
1687
  },
1688
+ {
1689
+ "level": 2,
1690
+ "text": "示例检索"
1691
+ },
1692
+ {
1693
+ "level": 2,
1694
+ "text": "u-manager 检索范围"
1695
+ },
1696
+ {
1697
+ "level": 2,
1698
+ "text": "fire 检索范围"
1699
+ },
1547
1700
  {
1548
1701
  "level": 2,
1549
1702
  "text": "包结构"
1550
1703
  }
1551
1704
  ],
1552
- "content": "# u-space MCP\n\n`u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括 `u-manager` 的 `SemanticLoader`、`SemanticSceneGroup`、`BuildingGroup`、`FloorMesh` 语义楼层 API、楼层 `Facilities` 设备检索与 scene-level auto instancing、设备显隐/颜色/透明度控制、电梯井/通风井语义体块,以及 atmosphere 插件的 `skyBackground()`、`skyEnvironment()` 和 RenderPipeline output effect 配置。\n\n## 安装与启动\n\n推荐通过 `npx` 使用已发布的 npm 包:\n\n```json\n{\n \"mcpServers\": {\n \"uSpace\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"u-space-mcp@latest\"]\n }\n }\n}\n```\n\n本地开发文档时,可以通过 `--docs` 指向仓库里的 docs 目录:\n\n```json\n{\n \"mcpServers\": {\n \"uSpace\": {\n \"command\": \"npx\",\n \"args\": [\n \"-y\",\n \"u-space-mcp@latest\",\n \"--docs\",\n \"/Users/jiangqi/Desktop/xunwei/SoonSpace/u-space/docs\"\n ]\n }\n }\n}\n```\n\n也可以使用环境变量:\n\n```bash\nU_SPACE_DOCS_PATH=/path/to/u-space/docs npx -y u-space-mcp@latest\n```\n\n## Mastra 接入\n\n在 Mastra 中通过 `MCPClient` 使用 stdio 形式接入:\n\n```typescript\nimport { MCPClient } from '@mastra/mcp';\n\nexport const uSpaceMcpClient = new MCPClient({\n id: 'u-space-mcp-client',\n servers: {\n uSpace: {\n command: 'npx',\n args: ['-y', 'u-space-mcp@latest'],\n stderr: 'pipe',\n },\n },\n});\n```\n\n然后把工具挂到 Agent 上:\n\n```typescript\nexport const codingAgent = new Agent({\n // ...\n tools: {\n ...(await uSpaceMcpClient.listTools()),\n },\n});\n```\n\n## 工具列表\n\n`u-space-mcp` 只提供只读工具:\n\n| 工具 | 说明 |\n| :--- | :--- |\n| `list_docs` | 列出可用文档页 |\n| `search_docs` | 按关键词、API 名、插件名或概念检索文档 |\n| `get_doc` | 按 path 或 id 读取单篇文档 |\n| `get_api_reference` | 面向 API / 类 / 方法 / 插件的检索 |\n| `find_examples` | 查找示例和用法相关文档 |\n| `get_changelog` | 读取更新日志 |\n\n## 包结构\n\n源码位于 `packages/u-space-mcp`。根目录只保留一个 MCP 发布入口;执行时会先递增 `u-space-mcp` 的 patch 版本,再从 `docs/*.md` 生成内置文档索引,编译 MCP 包,然后发布到 npm:\n\n```bash\npnpm publish:mcp\n```\n\n发布后的包不依赖本机绝对路径;只有在传入 `--docs` 或设置 `U_SPACE_DOCS_PATH` 时,才会读取本地文档目录。\n"
1705
+ "content": "# u-space MCP\n\n`u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括 `u-manager` 的 `UManagerLoader` 一体化加载入口、`SceneLoader` 语义去重与 path-based model instancing、统一 `SemanticInstanceObject` API、`SemanticModelInstancedLayer` 共享模型合批层、`SceneInstanceObject` 场景模型引用、`SceneInstancedLayer` 批量渲染层、`SemanticLoader`、`SemanticGroup`、`BuildingGroup`、`FloorMesh` 语义楼层 API、`FacilityInstanceObject` 设备引用、`FacilityInstancedLayer` scene-level batch 渲染层、Facilities auto instancing、camera-based active instance culling、dirty-driven instance sync、楼层 `Facilities` 设备检索与控制、电梯井/通风井语义体块,atmosphere 插件的 `skyBackground()`、`skyEnvironment()` 和 RenderPipeline output effect 配置,以及 fire 插件的 `FireEffect` WebGPU 体积火焰、烟雾、emitter、体积盒、动态光照和 output effect 接入方式。\n\n## 安装与启动\n\n推荐通过 `npx` 使用已发布的 npm 包:\n\n```json\n{\n \"mcpServers\": {\n \"uSpace\": {\n \"command\": \"npx\",\n \"args\": [\"-y\", \"u-space-mcp@latest\"]\n }\n }\n}\n```\n\n本地开发文档时,可以通过 `--docs` 指向仓库里的 docs 目录:\n\n```json\n{\n \"mcpServers\": {\n \"uSpace\": {\n \"command\": \"npx\",\n \"args\": [\n \"-y\",\n \"u-space-mcp@latest\",\n \"--docs\",\n \"/Users/jiangqi/Desktop/xunwei/SoonSpace/u-space/docs\"\n ]\n }\n }\n}\n```\n\n也可以使用环境变量:\n\n```bash\nU_SPACE_DOCS_PATH=/path/to/u-space/docs npx -y u-space-mcp@latest\n```\n\n## Mastra 接入\n\n在 Mastra 中通过 `MCPClient` 使用 stdio 形式接入:\n\n```typescript\nimport { MCPClient } from '@mastra/mcp';\n\nexport const uSpaceMcpClient = new MCPClient({\n id: 'u-space-mcp-client',\n servers: {\n uSpace: {\n command: 'npx',\n args: ['-y', 'u-space-mcp@latest'],\n stderr: 'pipe',\n },\n },\n});\n```\n\n然后把工具挂到 Agent 上:\n\n```typescript\nexport const codingAgent = new Agent({\n // ...\n tools: {\n ...(await uSpaceMcpClient.listTools()),\n },\n});\n```\n\n## 工具列表\n\n`u-space-mcp` 只提供只读工具:\n\n| 工具 | 说明 |\n| :--- | :--- |\n| `list_docs` | 列出可用文档页 |\n| `search_docs` | 按关键词、API 名、插件名或概念检索文档 |\n| `get_doc` | 按 path 或 id 读取单篇文档 |\n| `get_api_reference` | 面向 API / 类 / 方法 / 插件的检索 |\n| `find_examples` | 查找示例和用法相关文档 |\n| `get_changelog` | 读取更新日志 |\n\n## 示例检索\n\nMCP 文档索引包含 `examples/test_umanager_loader.html` 的说明。检索 `UManagerLoader example`、`test_umanager_loader` 或 `UManagerLoader 用法` 可以找到一体化加载语义楼层、Facilities 和非语义场景树的示例入口,以及 `window.uManagerExample` 控制台调试对象说明。\n\n## u-manager 检索范围\n\nMCP 文档索引会同步 `docs/api-plugin-u-manager.md` 中的 UManagerLoader、SemanticInstanceObject、SceneLoader、SceneInstanceObject、SceneInstancedLayer 和 Facilities 详细 API。客户端可以直接检索以下关键词:\n\n| 关键词 / API | 可检索内容 |\n| :----------- | :--------- |\n| `UManagerLoader` | 同时加载 `SemanticLoader` 和 `SceneLoader`、自动复用 semantic id 去重、返回带 `semanticGroup` / `sceneGroup` 直接属性的 `UManagerSceneGroup`。 |\n| `SemanticInstanceObject` | 统一语义实例 API:`setSemanticVisible()`、`setSemanticColor()`、`setSemanticOpacity()`、`getSemanticBoundingBox()`、`setSemanticHighlight()`,覆盖楼层多边形、Facilities、SceneLoader path instances 和 fallback Model wrapper。 |\n| `SemanticModelInstancedLayer` | `SceneInstancedLayer` 与 `FacilityInstancedLayer` 的共享实现:模板 mesh 收集、合法 material groups、多材质 instancing、dirty-driven buffer sync、raycast hit remap 和可选相机实例裁剪。 |\n| `SceneLoader` | 场景树加载、语义 `ID` 去重、重复 3D 模型按 `path` 自动合并、unsupported template 回退普通 `Model`。 |\n| `SceneInstanceObject` | `SceneLoader` path instancing 下的单模型逻辑引用、`id` / `sid` 检索、`userData.semanticKind = 'SceneInstances'`、`setSemanticVisible()`、`setSemanticColor()`、`resetSemanticColor()`、`setSemanticOpacity()`、`getSemanticColor()`、`getSemanticOpacity()`、`setSemanticHighlight()`、`clearSemanticHighlight()`、`getSemanticBoundingBox()` + `controls.flyToBox()` 飞向单模型、dirty 监听和事件目标。 |\n| `SceneInstancedLayer` | `SceneLoader` 内部批量渲染层、共享 `SemanticModelInstancedLayer`、dirty-driven instance buffer 同步、raycast hit remap。 |\n| `FacilityInstanceObject` | 楼层下的设备引用、`objectManager.getById()` 全局检索、`getSemanticBoundingBox()` + `controls.flyToBox()` 飞向单设备、统一 `setSemantic*` 控制、fallback `Model` wrapper 和事件目标。 |\n| `FacilityInstancedLayer` | `SemanticGroup.facilityLayer`、`addSemanticBatch()`、batch 创建条件、`setInstanceCulling()`、动态 Facilities batch、可选按相机视锥压缩 active instances、可选 `minScreenRadius` 屏幕尺寸裁剪、dirty-driven instance buffer 同步和 raycast hit remap。 |\n| `Facilities` | `SemanticLoader` 解析、`FloorMesh.getFacilityById()`、`FacilityInstanceObject.setSemanticOpacity()`、普通 `Model` fallback wrapper 与 scene-level instancing 的一致 API。 |\n\n## fire 检索范围\n\nMCP 文档索引会同步 `docs/api-plugin-fire.md` 中的 FireEffect API、参数和示例。客户端可以直接检索以下关键词:\n\n| 关键词 / API | 可检索内容 |\n| :----------- | :--------- |\n| `FireEffect` | 插件创建、`enable()`、`update()`、`setEmitter()`、`reset()`、`disable()` 和 `dispose()`。 |\n| `fire` / `volumetric fire` | WebGPU 体积火焰、烟雾散射、curl noise、buoyancy、Jacobi pressure projection 和 raymarch 输出。 |\n| `emitterGeometry` / `emitterRadius` | 默认 `TeapotGeometry(0.8, 28)`、自定义 emitter 几何、业务 `Object3D` matrix 驱动和移动扰动半径。 |\n| `size` / `gridSize` | 体积盒世界范围、烟雾扩散边界和 3D 模拟网格尺寸。 |\n| `addOutputEffect` | `FireEffect` 通过 RenderPipeline output effect 叠加体积 pass,不占用业务 `setOutputComposer()`。 |\n| `keyLight` / `pointLight` | 体积阴影 spot light、跟随火焰核心的动态点光源和可关闭的内置光源。 |\n\n## 包结构\n\n源码位于 `packages/u-space-mcp`。根目录只保留一个 MCP 发布入口;执行时会先递增 `u-space-mcp` 的 patch 版本,再从 `docs/*.md` 生成内置文档索引,编译 MCP 包,然后发布到 npm:\n\n```bash\npnpm publish:mcp\n```\n\n发布后的包不依赖本机绝对路径;只有在传入 `--docs` 或设置 `U_SPACE_DOCS_PATH` 时,才会读取本地文档目录。\n"
1553
1706
  }
1554
1707
  ];
1555
1708
  //# sourceMappingURL=docs-index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"docs-index.js","sourceRoot":"","sources":["../../src/generated/docs-index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs-index.js","sourceRoot":"","sources":["../../src/generated/docs-index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u-space-mcp",
3
- "version": "0.0.11",
3
+ "version": "0.0.13",
4
4
  "description": "Model Context Protocol server for u-space documentation.",
5
5
  "type": "module",
6
6
  "bin": {