u-space 0.0.22 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/plugins/u-manager/index.cjs +60 -60
- package/dist/plugins/u-manager/index.js +10894 -10183
- package/dist/plugins/u-manager/semantics/SemanticLoader.d.ts +8 -2
- package/dist/plugins/u-manager/semantics/SemanticParser.d.ts +12 -2
- package/dist/plugins/u-manager/semantics/index.d.ts +2 -0
- package/dist/plugins/u-manager/semantics/objects/BuildingGroup.d.ts +23 -5
- package/dist/plugins/u-manager/semantics/objects/FacilityInstancedLayer.d.ts +22 -0
- package/dist/plugins/u-manager/semantics/objects/FloorMesh.d.ts +49 -6
- package/dist/plugins/u-manager/semantics/objects/SemanticSceneGroup.d.ts +31 -0
- package/dist/plugins/u-manager/semantics/semantic.types.d.ts +8 -1
- package/docs/api-plugin-u-manager.md +115 -17
- package/docs/changelog.md +28 -1
- package/docs/examples-guide.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/index.md +1 -1
- package/docs/mcp.md +1 -1
- package/package.json +2 -2
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { Loader } from 'three/webgpu';
|
|
2
2
|
import type { Viewer } from 'u-space';
|
|
3
|
-
import {
|
|
3
|
+
import { SemanticSceneGroup } from './objects/SemanticSceneGroup';
|
|
4
4
|
export declare class SemanticLoader extends Loader {
|
|
5
|
+
#private;
|
|
5
6
|
viewer: Viewer;
|
|
7
|
+
key: string;
|
|
8
|
+
cachedIds: Set<string>;
|
|
6
9
|
constructor(viewer: Viewer);
|
|
7
|
-
|
|
10
|
+
setKey(key: string): this;
|
|
11
|
+
loadAsync(): Promise<SemanticSceneGroup>;
|
|
12
|
+
clearCache(): void;
|
|
13
|
+
dispose(): void;
|
|
8
14
|
}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { type LoadingManager, type Object3D } from 'three/webgpu';
|
|
2
|
+
import { SemanticSceneGroup } from './objects/SemanticSceneGroup';
|
|
2
3
|
import type { SemanticObject } from './semantic.types';
|
|
4
|
+
import type { ITreeData } from '../types';
|
|
5
|
+
export interface SemanticParserOptions {
|
|
6
|
+
treeData?: ITreeData[];
|
|
7
|
+
path?: string;
|
|
8
|
+
manager?: LoadingManager;
|
|
9
|
+
registerObject?: (id: string, object: Object3D) => void;
|
|
10
|
+
}
|
|
3
11
|
export declare class SemanticParser {
|
|
4
|
-
|
|
12
|
+
#private;
|
|
13
|
+
parse(semanticData: SemanticObject): SemanticSceneGroup;
|
|
14
|
+
parseAsync(semanticData: SemanticObject, options?: SemanticParserOptions): Promise<SemanticSceneGroup>;
|
|
5
15
|
}
|
|
@@ -5,5 +5,7 @@ export * from './objects/VerticalShaftMesh';
|
|
|
5
5
|
export * from './objects/ElevatorMesh';
|
|
6
6
|
export * from './objects/VentMesh';
|
|
7
7
|
export * from './objects/BuildingGroup';
|
|
8
|
+
export * from './objects/SemanticSceneGroup';
|
|
9
|
+
export * from './objects/FacilityInstancedLayer';
|
|
8
10
|
export * from './SemanticParser';
|
|
9
11
|
export * from './SemanticLoader';
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import type { ColorRepresentation, Object3D } from 'three/webgpu';
|
|
1
2
|
import { BaseGroup } from 'u-space';
|
|
2
3
|
import type { ElevatorMesh } from './ElevatorMesh';
|
|
3
|
-
import type { FloorMesh } from './FloorMesh';
|
|
4
|
-
import type { SemanticKind } from '../types';
|
|
4
|
+
import type { FloorMesh, FloorSemanticKind } from './FloorMesh';
|
|
5
5
|
import type { VentMesh } from './VentMesh';
|
|
6
|
+
export type BuildingFloorReference = FloorMesh | number;
|
|
7
|
+
export type BuildingFacilityReference = Object3D | string;
|
|
6
8
|
export declare class BuildingGroup extends BaseGroup {
|
|
9
|
+
#private;
|
|
7
10
|
isBuildingGroup: boolean;
|
|
8
11
|
type: string;
|
|
9
12
|
floorMeshes: FloorMesh[];
|
|
@@ -11,6 +14,7 @@ export declare class BuildingGroup extends BaseGroup {
|
|
|
11
14
|
ventMeshes: VentMesh[];
|
|
12
15
|
constructor();
|
|
13
16
|
addFloor(mesh: FloorMesh): this;
|
|
17
|
+
hasFloor(mesh: FloorMesh): boolean;
|
|
14
18
|
getFloorAt(index: number): FloorMesh;
|
|
15
19
|
removeFloor(mesh: FloorMesh): this;
|
|
16
20
|
addElevator(mesh: ElevatorMesh): this;
|
|
@@ -19,8 +23,22 @@ export declare class BuildingGroup extends BaseGroup {
|
|
|
19
23
|
addVent(mesh: VentMesh): this;
|
|
20
24
|
getVentAt(index: number): VentMesh;
|
|
21
25
|
removeVent(mesh: VentMesh): this;
|
|
22
|
-
isolateFloor(
|
|
26
|
+
isolateFloor(floor: BuildingFloorReference | BuildingFloorReference[]): this;
|
|
27
|
+
isolateFloors(floors: BuildingFloorReference[]): this;
|
|
23
28
|
showAllFloors(): this;
|
|
24
|
-
|
|
25
|
-
|
|
29
|
+
showAllFacilities(): this;
|
|
30
|
+
hideAllFacilities(): this;
|
|
31
|
+
getFacilityById(id: string): Object3D<import("three").Object3DEventMap> | undefined;
|
|
32
|
+
setFacilityVisible(facility: BuildingFacilityReference, visible: boolean): this;
|
|
33
|
+
showFacility(facility: BuildingFacilityReference): this;
|
|
34
|
+
hideFacility(facility: BuildingFacilityReference): this;
|
|
35
|
+
setFacilityColor(facility: BuildingFacilityReference, color: ColorRepresentation): this;
|
|
36
|
+
resetFacilityColor(facility: BuildingFacilityReference): this;
|
|
37
|
+
setFacilityOpacity(facility: BuildingFacilityReference, opacity: number): this;
|
|
38
|
+
syncFacilityIndexes(): this;
|
|
39
|
+
get facilityIndexVersion(): number;
|
|
40
|
+
getFacilityIndexIds(): MapIterator<string>;
|
|
41
|
+
getFacilityIndexObjects(): MapIterator<Object3D<import("three").Object3DEventMap>>;
|
|
42
|
+
planishFloors(kind?: FloorSemanticKind): this;
|
|
43
|
+
unplanishFloors(kind?: FloorSemanticKind): this;
|
|
26
44
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Box3, Color, Group, Object3D, type ColorRepresentation } from 'three/webgpu';
|
|
2
|
+
import { BaseGroup } from 'u-space';
|
|
3
|
+
export declare class FacilityInstanceObject extends Group {
|
|
4
|
+
#private;
|
|
5
|
+
isFacilityInstanceObject: boolean;
|
|
6
|
+
type: string;
|
|
7
|
+
setLocalBounds(bounds: Box3): this;
|
|
8
|
+
setFacilityVisible(visible: boolean): this;
|
|
9
|
+
setFacilityColor(color: ColorRepresentation): this;
|
|
10
|
+
resetFacilityColor(): this;
|
|
11
|
+
setFacilityOpacity(opacity: number): this;
|
|
12
|
+
getFacilityColor(target?: Color): Color;
|
|
13
|
+
hasFacilityColor(): boolean;
|
|
14
|
+
getFacilityOpacity(): number;
|
|
15
|
+
}
|
|
16
|
+
export declare class FacilityInstancedLayer extends BaseGroup {
|
|
17
|
+
#private;
|
|
18
|
+
isFacilityInstancedLayer: boolean;
|
|
19
|
+
type: string;
|
|
20
|
+
constructor();
|
|
21
|
+
addFacilityBatch(url: string, template: Object3D, facilities: FacilityInstanceObject[]): boolean;
|
|
22
|
+
}
|
|
@@ -1,20 +1,42 @@
|
|
|
1
|
-
import { Box3, BufferGeometry, Matrix4, MeshStandardNodeMaterial, Sphere, Vector3, Vector4, type Intersection, type Raycaster } from 'three/webgpu';
|
|
1
|
+
import { Box3, BufferGeometry, Matrix4, MeshStandardNodeMaterial, Sphere, Vector3, Vector4, type ColorRepresentation, type Intersection, type Object3D, type Raycaster } from 'three/webgpu';
|
|
2
2
|
import { BaseMesh, type InteractionEvent, type InteractionEventMap } from 'u-space';
|
|
3
3
|
import type { SemanticColor, SemanticGeometryEntry, SemanticKind } from '../types';
|
|
4
|
+
type FacilityReference = Object3D | string;
|
|
5
|
+
type FacilitySemanticKind = 'Facilities';
|
|
6
|
+
export type FloorSemanticKind = SemanticKind | FacilitySemanticKind;
|
|
7
|
+
export interface FloorGeometrySemanticEntity {
|
|
8
|
+
type: 'geometry';
|
|
9
|
+
kind: SemanticKind;
|
|
10
|
+
id: string;
|
|
11
|
+
name?: string;
|
|
12
|
+
index: number;
|
|
13
|
+
}
|
|
14
|
+
export interface FloorFacilitySemanticEntity {
|
|
15
|
+
type: 'object';
|
|
16
|
+
kind: FacilitySemanticKind;
|
|
17
|
+
id: string;
|
|
18
|
+
name?: string;
|
|
19
|
+
index: number;
|
|
20
|
+
object: Object3D;
|
|
21
|
+
aliases: string[];
|
|
22
|
+
}
|
|
23
|
+
export type FloorSemanticEntity = FloorGeometrySemanticEntity | FloorFacilitySemanticEntity;
|
|
4
24
|
type FloorMeshEventPayload<T> = T extends {
|
|
5
25
|
event: InteractionEvent;
|
|
6
26
|
} ? {
|
|
7
27
|
event: FloorMeshInteractionEvent;
|
|
8
28
|
} : T;
|
|
9
|
-
export interface FloorMeshIntersection extends Intersection<
|
|
29
|
+
export interface FloorMeshIntersection extends Intersection<Object3D> {
|
|
10
30
|
semanticId: string;
|
|
11
|
-
semanticKind:
|
|
31
|
+
semanticKind: FloorSemanticKind;
|
|
12
32
|
semanticName?: string;
|
|
13
33
|
semanticIndex: number;
|
|
14
34
|
instanceId: number;
|
|
35
|
+
facility?: Object3D;
|
|
36
|
+
facilityId?: string;
|
|
15
37
|
}
|
|
16
38
|
export type FloorMeshInteractionEvent = Omit<InteractionEvent, 'target' | 'currentTarget' | 'intersect'> & {
|
|
17
|
-
readonly target:
|
|
39
|
+
readonly target: Object3D<InteractionEventMap>;
|
|
18
40
|
currentTarget: FloorMesh;
|
|
19
41
|
readonly intersect: FloorMeshIntersection | null;
|
|
20
42
|
};
|
|
@@ -25,6 +47,7 @@ export declare class FloorMesh extends BaseMesh<BufferGeometry, MeshStandardNode
|
|
|
25
47
|
#private;
|
|
26
48
|
isFloorMergedSemanticMesh: boolean;
|
|
27
49
|
type: string;
|
|
50
|
+
pivot: Vector3;
|
|
28
51
|
boundingBox: Box3 | null;
|
|
29
52
|
boundingSphere: Sphere | null;
|
|
30
53
|
wallsInstances: Map<string, number>;
|
|
@@ -34,15 +57,35 @@ export declare class FloorMesh extends BaseMesh<BufferGeometry, MeshStandardNode
|
|
|
34
57
|
windowsInstances: Map<string, number>;
|
|
35
58
|
staircasesInstances: Map<string, number>;
|
|
36
59
|
semanticInstances: Map<string, number>;
|
|
60
|
+
semanticEntities: Map<string, FloorSemanticEntity>;
|
|
61
|
+
facilityObjectsById: Map<string, Object3D>;
|
|
62
|
+
facilityObjects: Object3D[];
|
|
63
|
+
facilityIndexVersion: number;
|
|
37
64
|
constructor(entries: SemanticGeometryEntry[]);
|
|
38
|
-
planish(kind?:
|
|
39
|
-
unplanish(kind?:
|
|
65
|
+
planish(kind?: FloorSemanticKind): this;
|
|
66
|
+
unplanish(kind?: FloorSemanticKind): this;
|
|
40
67
|
get semanticCount(): number;
|
|
41
68
|
get instanceCount(): number;
|
|
42
69
|
getSemanticIndexById(id: string): number | undefined;
|
|
70
|
+
getSemanticById(id: string): FloorSemanticEntity | undefined;
|
|
71
|
+
getSemantics(): FloorSemanticEntity[];
|
|
72
|
+
getSemanticsByKind(kind: FloorSemanticKind): FloorSemanticEntity[];
|
|
43
73
|
getSemanticIdAt(index: number): string;
|
|
44
74
|
getSemanticKindAt(index: number): SemanticKind;
|
|
45
75
|
getSemanticNameAt(index: number): string | undefined;
|
|
76
|
+
showAllFacilities(): this;
|
|
77
|
+
hideAllFacilities(): this;
|
|
78
|
+
addFacility(object: Object3D, ids?: string | string[]): this;
|
|
79
|
+
getFacilityById(id: string): Object3D<import("three").Object3DEventMap> | undefined;
|
|
80
|
+
getFacilityAt(index: number): Object3D<import("three").Object3DEventMap>;
|
|
81
|
+
getFacilities(): Object3D<import("three").Object3DEventMap>[];
|
|
82
|
+
setFacilityVisible(facility: FacilityReference, visible: boolean): this;
|
|
83
|
+
showFacility(facility: FacilityReference): this;
|
|
84
|
+
hideFacility(facility: FacilityReference): this;
|
|
85
|
+
setFacilityColor(facility: FacilityReference, color: ColorRepresentation): this;
|
|
86
|
+
resetFacilityColor(facility: FacilityReference): this;
|
|
87
|
+
setFacilityOpacity(facility: FacilityReference, opacity: number): this;
|
|
88
|
+
removeFacility(facility: FacilityReference): this;
|
|
46
89
|
setColorAt(index: number, color: SemanticColor): this;
|
|
47
90
|
getColorAt(index: number, target?: Vector4): Vector4;
|
|
48
91
|
setOpacityAt(index: number, opacity: number): this;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ColorRepresentation, type Object3D } from 'three/webgpu';
|
|
2
|
+
import { BaseGroup } from 'u-space';
|
|
3
|
+
import type { BuildingFacilityReference, BuildingGroup } from './BuildingGroup';
|
|
4
|
+
import type { FloorMesh, FloorSemanticKind } from './FloorMesh';
|
|
5
|
+
export declare class SemanticSceneGroup extends BaseGroup {
|
|
6
|
+
#private;
|
|
7
|
+
isSemanticSceneGroup: boolean;
|
|
8
|
+
type: string;
|
|
9
|
+
buildings: BuildingGroup[];
|
|
10
|
+
facilityLayer: Object3D | null;
|
|
11
|
+
constructor();
|
|
12
|
+
addBuilding(group: BuildingGroup): this;
|
|
13
|
+
getBuildingAt(index: number): BuildingGroup;
|
|
14
|
+
getBuildingById(id: string): BuildingGroup | undefined;
|
|
15
|
+
getBuildings(): BuildingGroup[];
|
|
16
|
+
removeBuilding(group: BuildingGroup): this;
|
|
17
|
+
get floorMeshes(): FloorMesh[];
|
|
18
|
+
setFacilityLayer(layer: Object3D | null): this;
|
|
19
|
+
showAllFacilities(): this;
|
|
20
|
+
hideAllFacilities(): this;
|
|
21
|
+
getFacilityById(id: string): Object3D<import("three").Object3DEventMap> | undefined;
|
|
22
|
+
setFacilityVisible(facility: BuildingFacilityReference, visible: boolean): this;
|
|
23
|
+
showFacility(facility: BuildingFacilityReference): this;
|
|
24
|
+
hideFacility(facility: BuildingFacilityReference): this;
|
|
25
|
+
setFacilityColor(facility: BuildingFacilityReference, color: ColorRepresentation): this;
|
|
26
|
+
resetFacilityColor(facility: BuildingFacilityReference): this;
|
|
27
|
+
setFacilityOpacity(facility: BuildingFacilityReference, opacity: number): this;
|
|
28
|
+
showAllFloors(): this;
|
|
29
|
+
planishFloors(kind?: FloorSemanticKind): this;
|
|
30
|
+
unplanishFloors(kind?: FloorSemanticKind): this;
|
|
31
|
+
}
|
|
@@ -35,11 +35,17 @@ export interface Staircase {
|
|
|
35
35
|
Polyline: number[];
|
|
36
36
|
Spaces: number[];
|
|
37
37
|
}
|
|
38
|
+
export interface Facility {
|
|
39
|
+
ID: string;
|
|
40
|
+
Name: string;
|
|
41
|
+
Spaces: number[];
|
|
42
|
+
TwinsIdentifier: string;
|
|
43
|
+
}
|
|
38
44
|
export interface Story {
|
|
39
45
|
Columns?: any[];
|
|
40
46
|
Doors?: number[];
|
|
41
47
|
Elevation?: number;
|
|
42
|
-
Facilities?:
|
|
48
|
+
Facilities?: number[];
|
|
43
49
|
FloorIndex?: any;
|
|
44
50
|
Height?: number;
|
|
45
51
|
ID?: string;
|
|
@@ -103,6 +109,7 @@ export interface Asset {
|
|
|
103
109
|
export interface SemanticObject {
|
|
104
110
|
Buildings?: Building[];
|
|
105
111
|
Doors?: Door[];
|
|
112
|
+
Facilities?: Facility[];
|
|
106
113
|
Spaces?: Space[];
|
|
107
114
|
Staircases?: Staircase[];
|
|
108
115
|
Stories?: Story[];
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# u-manager
|
|
2
2
|
|
|
3
|
-
`u-manager`
|
|
3
|
+
`u-manager` 是一套全面的加载器和解析器,用于从服务器路径流式传输、解密并显示结构化场景数据。支持场景、拓扑、动画、属性、相机视点、楼层、井道和设备语义模型。
|
|
4
4
|
|
|
5
5
|
所有加载器均继承自 Three.js 的 `Loader`,并提供 `setPath(path)` 方法,在调用 `loadAsync()` 前配置基础数据目录。
|
|
6
6
|
|
|
7
7
|
## `SemanticLoader`
|
|
8
8
|
|
|
9
|
-
加载 `db/semantic_model.json`
|
|
9
|
+
加载 `db/semantic_model.json` 楼层语义数据。`loadAsync()` 返回顶层 `SemanticSceneGroup`,用于组织整次语义解析产生的建筑、楼层以及 scene-level facility layer。每个建筑包含多个 `FloorMesh`,每个楼层把墙、柱、空间、楼梯等语义对象合并为一个 TSL 材质驱动的网格;建筑级电梯井和通风井会使用 `ExtrudeMesh` 独立渲染。语义模型包含 `Facilities` 时,`SemanticLoader` 会额外读取 `SceneMetadata.json` 指向的 `tree_models`,按场景授权配置解密,再把对应设备模型挂载到所属楼层。
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
12
|
import { Vector3, Vector4 } from 'three';
|
|
@@ -14,11 +14,12 @@ import { SemanticLoader } from 'u-space/plugins/u-manager';
|
|
|
14
14
|
|
|
15
15
|
const loader = new SemanticLoader(viewer);
|
|
16
16
|
loader.setPath('./scenes/my-scene');
|
|
17
|
+
loader.setKey('YOUR_LICENSE_KEY'); // 官方授权场景解析 tree_models 时必需
|
|
17
18
|
|
|
18
|
-
const
|
|
19
|
-
viewer.scene.add(
|
|
19
|
+
const semanticScene = await loader.loadAsync(); // SemanticSceneGroup
|
|
20
|
+
viewer.scene.add(semanticScene);
|
|
20
21
|
|
|
21
|
-
const building =
|
|
22
|
+
const building = semanticScene.getBuildingAt(0);
|
|
22
23
|
const floor = building.getFloorAt(0);
|
|
23
24
|
|
|
24
25
|
building.isolateFloor(floor);
|
|
@@ -34,9 +35,35 @@ floor.addEventListener('click', ({ event }) => {
|
|
|
34
35
|
});
|
|
35
36
|
```
|
|
36
37
|
|
|
38
|
+
### `SemanticSceneGroup`
|
|
39
|
+
|
|
40
|
+
`SemanticSceneGroup` 继承自 `BaseGroup`,是单次 `SemanticParser` 解析结果的顶层容器。它管理所有 `BuildingGroup`,并把跨楼层共享的 Facilities `InstancedMesh` 渲染层作为建筑的同级对象挂在 `facilityLayer`,而不是挂到某个 `BuildingGroup` 内。
|
|
41
|
+
|
|
42
|
+
建筑 ID 和设备 ID 查询使用内部 `Map` 索引维护;`getBuildingById()`、`getFacilityById()` 以及单设备控制方法不会通过数组扫描查找语义对象。
|
|
43
|
+
|
|
44
|
+
| 属性 / 方法 | 说明 |
|
|
45
|
+
| :---------- | :--- |
|
|
46
|
+
| `buildings` | 当前语义场景内的 `BuildingGroup[]`。 |
|
|
47
|
+
| `facilityLayer` | scene-level 设备渲染层;同模型 URL 的静态设备会合并为 `InstancedMesh` batch。 |
|
|
48
|
+
| `addBuilding(group)` / `removeBuilding(group)` | 添加或移除建筑,并同步更新 group 子节点。 |
|
|
49
|
+
| `getBuildingAt(index)` / `getBuildingById(id)` / `getBuildings()` | 按下标、`Building.ID` 或整体列表获取建筑。 |
|
|
50
|
+
| `floorMeshes` | 聚合返回所有建筑内的 `FloorMesh[]`。 |
|
|
51
|
+
| `setFacilityLayer(layer)` | 设置跨楼层设备渲染层;传入 `null` 会移除已有 layer。 |
|
|
52
|
+
| `getFacilityById(id)` | 在整次语义解析结果中按 `Facility.ID` 或显式别名查找设备。 |
|
|
53
|
+
| `showFacility(id \| object)` / `hideFacility(id \| object)` | 显示或隐藏单个设备。 |
|
|
54
|
+
| `setFacilityVisible(id \| object, visible)` | 设置单个设备显隐状态。 |
|
|
55
|
+
| `setFacilityColor(id \| object, color)` | 设置单个设备材质颜色。 |
|
|
56
|
+
| `resetFacilityColor(id \| object)` | 清除单个设备颜色 override,恢复模型原始颜色;透明度 override 不受影响。 |
|
|
57
|
+
| `setFacilityOpacity(id \| object, opacity)` | 设置单个设备材质透明度,`opacity` 会被限制在 `0..1`。 |
|
|
58
|
+
| `showAllFacilities()` / `hideAllFacilities()` | 显示或隐藏整次语义解析结果中的全部设备。 |
|
|
59
|
+
| `showAllFloors()` | 显示所有建筑的所有楼层。 |
|
|
60
|
+
| `planishFloors(kind?)` / `unplanishFloors(kind?)` | 压扁或恢复所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |
|
|
61
|
+
|
|
37
62
|
### `BuildingGroup`
|
|
38
63
|
|
|
39
|
-
`BuildingGroup` 继承自 `BaseGroup
|
|
64
|
+
`BuildingGroup` 继承自 `BaseGroup`,用于组织一个建筑下的所有楼层、电梯井和通风井。设备语义对象不会直接挂到 `BuildingGroup`;能 instancing 的设备会渲染到 `SemanticSceneGroup.facilityLayer`,同时在对应 `FloorMesh` 下保留可检索、可控制的轻量引用。
|
|
65
|
+
|
|
66
|
+
建筑内设备 ID 到楼层的关系由内部 `Map` 索引维护,并通过楼层设备索引版本自动同步。
|
|
40
67
|
|
|
41
68
|
| 属性 / 方法 | 说明 |
|
|
42
69
|
| :---------- | :--- |
|
|
@@ -50,10 +77,19 @@ floor.addEventListener('click', ({ event }) => {
|
|
|
50
77
|
| `getElevatorAt(index)` | 按下标获取电梯井 `ExtrudeMesh`。 |
|
|
51
78
|
| `addVent(vent)` / `removeVent(vent)` | 添加或移除通风井,并同步更新 group。 |
|
|
52
79
|
| `getVentAt(index)` | 按下标获取通风井 `ExtrudeMesh`。 |
|
|
53
|
-
| `isolateFloor(floor \| index)` |
|
|
80
|
+
| `isolateFloor(floor \| index)` | 只显示指定楼层,隐藏其他楼层;也兼容传入楼层数组。 |
|
|
81
|
+
| `isolateFloors(floors \| indexes)` | 只显示指定多个楼层,隐藏其他楼层。 |
|
|
54
82
|
| `showAllFloors()` | 显示全部楼层。 |
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
83
|
+
| `getFacilityById(id)` | 在当前建筑的楼层中按 `Facility.ID` 或显式别名查找设备。 |
|
|
84
|
+
| `showFacility(id \| object)` / `hideFacility(id \| object)` | 显示或隐藏当前建筑内的单个设备。 |
|
|
85
|
+
| `setFacilityVisible(id \| object, visible)` | 设置当前建筑内单个设备显隐状态。 |
|
|
86
|
+
| `setFacilityColor(id \| object, color)` | 设置当前建筑内单个设备材质颜色。 |
|
|
87
|
+
| `resetFacilityColor(id \| object)` | 清除当前建筑内单个设备颜色 override。 |
|
|
88
|
+
| `setFacilityOpacity(id \| object, opacity)` | 设置当前建筑内单个设备材质透明度。 |
|
|
89
|
+
| `showAllFacilities()` | 显示整栋建筑内全部楼层设备。 |
|
|
90
|
+
| `hideAllFacilities()` | 隐藏整栋建筑内全部楼层设备。 |
|
|
91
|
+
| `planishFloors(kind?)` | 压扁所有楼层;默认覆盖所有合并语义实例和 Facilities,并按包围盒贴到楼层平面;传入 `kind` 时只压扁该语义类型,`kind` 可包含 `Facilities`。 |
|
|
92
|
+
| `unplanishFloors(kind?)` | 恢复所有楼层;默认恢复所有合并语义实例和 Facilities;传入 `kind` 时只恢复该语义类型,`kind` 可包含 `Facilities`。 |
|
|
57
93
|
|
|
58
94
|
### 电梯井和通风井
|
|
59
95
|
|
|
@@ -74,9 +110,43 @@ if (vent) {
|
|
|
74
110
|
|
|
75
111
|
电梯井和通风井会在渲染阶段沿法线轻微内收,减少与墙体共面时的闪面。`Spaces` 实例也会使用稳定的 per-instance 渲染偏移抖动,缓解完全重叠空间之间的 z-fighting;这些偏移只影响渲染顶点,不改变语义 ID、实例矩阵和包围体查询的使用方式。
|
|
76
112
|
|
|
113
|
+
### 设施设备
|
|
114
|
+
|
|
115
|
+
`SemanticLoader` 会从 `Stories[].Facilities` 读取设备索引,再从顶层 `Facilities` 数组取得 `Facility` 数据,并使用 `Facility.ID` 在解密后的 `tree_models` 中查找同 ID 节点。只有带 `renderType: '3D'` 和模型 `path` 的节点会被加载。
|
|
116
|
+
|
|
117
|
+
`tree_models.matrix` 是相对父节点的本地矩阵;`SemanticLoader` 会沿树父级累乘得到设备世界矩阵,再转换为对应 `FloorMesh` 的局部矩阵。因此楼层移动、隔离或显示隐藏时设备会跟随楼层一起工作。即使某个 story 只有 `Facilities`、没有墙柱空间等合并几何,也会创建一个空的 `FloorMesh` 作为设备容器。
|
|
118
|
+
|
|
119
|
+
Facilities 会在单次 `SemanticParser` 解析范围内按模型 URL 自动分组。静态模型会被转换为 scene-level `InstancedMesh` batch,挂到 `SemanticSceneGroup.facilityLayer`;每个设备仍会在所属 `FloorMesh` 下保留一个轻量引用,用于 `getFacilityById()`、显隐、颜色、透明度和 `viewer.objectManager` 检索。带动画、骨骼、morph target 或多材质 Mesh 的模型会自动回退为普通 `Model`,继续作为实际 `Object3D` 挂到所属 `FloorMesh`。
|
|
120
|
+
|
|
121
|
+
`facilityLayer` 使用 `FacilityInstancedLayer`,并继承自 `BaseGroup`。当 `facilityLayer.visible = false` 时,layer 会阻止内部 `InstancedMesh` 继续参与射线检测,避免隐藏的批处理设备仍被点击命中;单个设备的显隐仍应通过楼层下的设备引用或 `showFacility()` / `hideFacility()` 控制。
|
|
122
|
+
|
|
123
|
+
Instanced 设备为了支持单个设备的透明度控制,会把 batch 材质保持为 `transparent: true`,并通过 per-instance opacity attribute 控制每个设备的可见透明度;`setFacilityOpacity(id, 1)` 会恢复完全不透明显示,但不会把 batch 材质的 `transparent` 属性改回 `false`。`resetFacilityColor()` 只清除颜色 override,不影响透明度 override。普通 fallback `Model` 的颜色和透明度控制依赖 `MaterialEffects`,当前支持单材质 Mesh;多材质 Mesh fallback 会保留原始材质数组,支持挂载、检索和显隐,但不会改写颜色或透明度 override。
|
|
124
|
+
|
|
125
|
+
加载成功后,设备引用会写入 `userData.facilityId`、`semanticId`、`semanticKind: 'Facilities'`、`semanticName`、`spaces`、`twinsIdentifier`、`storyId` 和 `floorIndex`,并按 `Facility.ID` 注册到 `viewer.objectManager`。自动 instancing 的引用还会带有 `userData.instanced: true` 和 `userData.modelUrl`。
|
|
126
|
+
|
|
127
|
+
```typescript
|
|
128
|
+
const floor = building.getFloorAt(0);
|
|
129
|
+
|
|
130
|
+
const facility = floor.getFacilityById('FACILITY_001') ?? viewer.objectManager.getById('FACILITY_001');
|
|
131
|
+
const facilityEntity = floor.getSemanticById('FACILITY_001');
|
|
132
|
+
|
|
133
|
+
if (facility && facilityEntity?.type === 'object') {
|
|
134
|
+
await viewer.controls.flyToObject(facility);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const facilities = floor.getSemanticsByKind('Facilities');
|
|
138
|
+
|
|
139
|
+
semanticScene.hideFacility('FACILITY_001');
|
|
140
|
+
semanticScene
|
|
141
|
+
.setFacilityColor('FACILITY_001', '#ff5533')
|
|
142
|
+
.setFacilityOpacity('FACILITY_001', 0.45)
|
|
143
|
+
.resetFacilityColor('FACILITY_001')
|
|
144
|
+
.showFacility('FACILITY_001');
|
|
145
|
+
```
|
|
146
|
+
|
|
77
147
|
### `FloorMesh`
|
|
78
148
|
|
|
79
|
-
`FloorMesh` 继承自 `BaseMesh`,表示一个楼层。它不是 `BatchedMesh`,而是把同一楼层内的语义对象合并为一份几何,并通过 TSL + `DataTexture` 在 GPU 侧按 `semanticIndex` 控制颜色、透明度、显示隐藏和实例矩阵。
|
|
149
|
+
`FloorMesh` 继承自 `BaseMesh`,表示一个楼层。它不是 `BatchedMesh`,而是把同一楼层内的语义对象合并为一份几何,并通过 TSL + `DataTexture` 在 GPU 侧按 `semanticIndex` 控制颜色、透明度、显示隐藏和实例矩阵。Facilities 通过楼层下的引用对象进行检索和控制;实际渲染可能来自 `SemanticSceneGroup.facilityLayer` 的 `InstancedMesh` batch,也可能是 fallback 的普通 `Model`。
|
|
80
150
|
|
|
81
151
|
这种结构的目标是让每个楼层通常只占一个主渲染 draw call,同时仍保留实例级控制能力。`xxxAt` 方法全部作用于单个语义实例;没有 `At` 后缀的方法作用于整个楼层 mesh。
|
|
82
152
|
|
|
@@ -84,11 +154,29 @@ if (vent) {
|
|
|
84
154
|
| :---------- | :--- |
|
|
85
155
|
| `semanticCount` / `instanceCount` | 当前楼层语义实例数量。 |
|
|
86
156
|
| `semanticInstances` | `Map<string, number>`,从语义对象 ID 映射到实例下标。 |
|
|
87
|
-
| `wallsInstances` / `columnsInstances` / `spacesInstances` / `doorsInstances` / `windowsInstances` | 按语义类型维护的 ID 到实例下标映射。 |
|
|
157
|
+
| `wallsInstances` / `columnsInstances` / `spacesInstances` / `doorsInstances` / `windowsInstances` / `staircasesInstances` | 按语义类型维护的 ID 到实例下标映射。 |
|
|
158
|
+
| `semanticEntities` | `Map<string, FloorSemanticEntity>`,统一索引楼层内合并几何语义和 `Facilities` 对象语义。 |
|
|
159
|
+
| `facilityObjectsById` | `Map<string, Object3D>`,按 `Facility.ID` 或显式别名查找设备引用。 |
|
|
160
|
+
| `facilityObjects` | 当前楼层挂载的设备引用数组。 |
|
|
88
161
|
| `getSemanticIndexById(id)` | 根据语义 ID 获取实例下标。 |
|
|
162
|
+
| `getSemanticById(id)` | 根据语义 ID 或设备别名获取统一语义实体。 |
|
|
163
|
+
| `getSemantics()` | 获取楼层内全部语义实体,包含合并几何和设备对象。 |
|
|
164
|
+
| `getSemanticsByKind(kind)` | 按语义类型过滤实体;`kind` 可以是 `Walls`、`Columns`、`Spaces`、`Doors`、`Windows`、`Staircases` 或 `Facilities`。 |
|
|
89
165
|
| `getSemanticIdAt(index)` | 获取实例语义 ID。 |
|
|
90
|
-
| `getSemanticKindAt(index)` |
|
|
166
|
+
| `getSemanticKindAt(index)` | 获取合并几何实例类型:`'Walls' \| 'Columns' \| 'Spaces' \| 'Doors' \| 'Windows' \| 'Staircases'`。 |
|
|
91
167
|
| `getSemanticNameAt(index)` | 获取实例名称;当前 `Spaces` 会从语义数据的 `Name` 写入,其他类型可能为 `undefined`。 |
|
|
168
|
+
| `showAllFacilities()` | 显示当前楼层的全部设备对象。 |
|
|
169
|
+
| `hideAllFacilities()` | 隐藏当前楼层的全部设备对象。 |
|
|
170
|
+
| `addFacility(object, ids?)` | 把设备对象挂到楼层,并按显式 ID、`facilityId`、`semanticId`、`id` 建立检索别名。 |
|
|
171
|
+
| `getFacilityById(id)` | 根据 `Facility.ID` 或别名获取设备对象。 |
|
|
172
|
+
| `getFacilityAt(index)` | 按楼层设备数组下标获取设备对象。 |
|
|
173
|
+
| `getFacilities()` | 获取当前楼层全部设备对象。 |
|
|
174
|
+
| `showFacility(id \| object)` / `hideFacility(id \| object)` | 显示或隐藏当前楼层内的单个设备。 |
|
|
175
|
+
| `setFacilityVisible(id \| object, visible)` | 设置当前楼层内单个设备显隐状态。 |
|
|
176
|
+
| `setFacilityColor(id \| object, color)` | 设置当前楼层内单个设备材质颜色。 |
|
|
177
|
+
| `resetFacilityColor(id \| object)` | 清除当前楼层内单个设备颜色 override。 |
|
|
178
|
+
| `setFacilityOpacity(id \| object, opacity)` | 设置当前楼层内单个设备材质透明度。 |
|
|
179
|
+
| `removeFacility(facility)` | 按设备对象或 ID 从楼层移除设备,并同步清理检索索引。 |
|
|
92
180
|
| `setColorAt(index, color)` / `getColorAt(index, target?)` | 修改或读取实例颜色,支持 `Color`、`Vector3`、`Vector4`。 |
|
|
93
181
|
| `setOpacityAt(index, opacity)` / `getOpacityAt(index)` | 修改或读取实例透明度。 |
|
|
94
182
|
| `setVisibleAt(index, visible)` / `getVisibleAt(index)` | 修改或读取实例显隐状态。 |
|
|
@@ -99,11 +187,11 @@ if (vent) {
|
|
|
99
187
|
| `getBoundingBoxAt(index, target?, world?)` | 获取实例包围盒;`world = true` 时包含 `FloorMesh.matrixWorld`。 |
|
|
100
188
|
| `getBoundingSphereAt(index, target?, world?)` | 获取实例包围球;`world = true` 时包含 `FloorMesh.matrixWorld`。 |
|
|
101
189
|
| `computeBoundingBox()` / `computeBoundingSphere()` | 计算整个楼层的包围体。 |
|
|
102
|
-
| `planish(kind?)` / `unplanish(kind?)` |
|
|
190
|
+
| `planish(kind?)` / `unplanish(kind?)` | 压扁或恢复楼层内所有合并语义实例和 Facilities;压平时按各自包围盒贴到楼层平面;传入 `kind` 时只作用于该语义类型,`kind` 可包含 `Facilities`。 |
|
|
103
191
|
|
|
104
192
|
### 飞向语义实例
|
|
105
193
|
|
|
106
|
-
点击、射线检测命中 `FloorMesh`
|
|
194
|
+
点击、射线检测命中 `FloorMesh` 里的语义几何或设备时,`intersect` 上会附加语义字段:`semanticIndex`、`semanticId`、`semanticKind`。普通楼层语义几何的事件目标是 `FloorMesh`;instanced Facilities 的事件目标是楼层下的 `FacilityInstanceObject` 引用,事件会继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticSceneGroup`。因此楼层监听器中应使用 `event.currentTarget` 操作楼层,用 `intersect.facility` 或 `event.target` 取得设备对象。
|
|
107
195
|
|
|
108
196
|
```typescript
|
|
109
197
|
import { Box3 } from 'three';
|
|
@@ -111,8 +199,16 @@ import { Box3 } from 'three';
|
|
|
111
199
|
const box = new Box3();
|
|
112
200
|
|
|
113
201
|
floor.addEventListener('click', async ({ event }) => {
|
|
114
|
-
const {
|
|
115
|
-
|
|
202
|
+
const { currentTarget, intersect } = event;
|
|
203
|
+
if (!intersect) return;
|
|
204
|
+
|
|
205
|
+
if (intersect.semanticKind === 'Facilities') {
|
|
206
|
+
const facility = intersect.facility ?? event.target;
|
|
207
|
+
await viewer.controls.flyToObject(facility);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const semanticBox = currentTarget.getBoundingBoxAt(intersect.semanticIndex, box, true);
|
|
116
212
|
|
|
117
213
|
if (semanticBox) {
|
|
118
214
|
await viewer.controls.flyToBox(semanticBox, {
|
|
@@ -136,7 +232,9 @@ if (index !== undefined) {
|
|
|
136
232
|
|
|
137
233
|
### 楼层压扁
|
|
138
234
|
|
|
139
|
-
`planish()` / `unplanish()`
|
|
235
|
+
`planish()` / `unplanish()` 默认作用于当前楼层的全部合并语义实例,包含墙、柱、空间、门窗、楼梯等语义几何,也包含楼层下的 Facilities 引用;传入 `kind` 时只处理该类型,例如 `floor.planish('Walls')` 或 `floor.planish('Facilities')`。所有被压平的实例都会按自身包围盒把压平后的薄片贴到楼层平面 `FloorMesh.pivot.y`,而不是围绕实例自身基点压缩;`unplanish()` 会恢复合并几何实例的原始矩阵,`unplanish('Facilities')` 会恢复设备原始 `position.y` 和 `scale.y`。instanced Facilities 会通过楼层下的 `FacilityInstanceObject` transform 同步到 `SemanticSceneGroup.facilityLayer`。
|
|
236
|
+
|
|
237
|
+
如果只想调整单个合并几何实例,可以使用 `setScaleAt()` 或 `setScaleYAt()`,它们会保留该语义对象自己的基点矩阵,因此压扁墙、柱、房间时不会被压到世界原点。
|
|
140
238
|
|
|
141
239
|
## `SceneLoader`
|
|
142
240
|
|
package/docs/changelog.md
CHANGED
|
@@ -2,7 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
## 未发布
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
### 新增
|
|
6
|
+
|
|
7
|
+
- **u-manager semantics** — 新增 `SemanticSceneGroup`,作为单次 `SemanticParser` 解析结果的顶层容器;`SemanticLoader.loadAsync()` / `SemanticParser.parseAsync()` 直接返回完整语义场景。
|
|
8
|
+
- **u-manager semantics** — `SemanticSceneGroup` 新增 `getBuildingById(id)`,支持按语义数据里的 `Building.ID` 获取建筑。
|
|
9
|
+
- **u-manager semantics** — `SemanticSceneGroup` 和 `BuildingGroup` 的建筑/设备 ID 查询改为内部 `Map` 索引,并通过楼层设备索引版本自动同步,避免每次查询扫描数组。
|
|
10
|
+
- **u-manager semantics** — `FloorMesh.planish()` / `unplanish()`、`BuildingGroup.planishFloors()` / `unplanishFloors()` 和 `SemanticSceneGroup.planishFloors()` / `unplanishFloors()` 会把所有合并语义实例和 Facilities 都按包围盒贴到楼层平面,而不是围绕实例自身基点压缩。
|
|
11
|
+
- **u-manager semantics** — 新增 scene-level Facilities auto instancing:同模型 URL 的静态设备会合并到 `SemanticSceneGroup.facilityLayer` 的 `InstancedMesh` batch,同时保留楼层下的设备引用用于检索、显隐、颜色和透明度控制;带动画、骨骼、morph target 或多材质 Mesh 的设备自动回退为普通 `Model`。
|
|
12
|
+
- **u-manager semantics** — `SemanticSceneGroup`、`BuildingGroup` 和 `FloorMesh` 新增单个设备控制 API:`getFacilityById()`、`showFacility()`、`hideFacility()`、`setFacilityVisible()`、`setFacilityColor()`、`resetFacilityColor()` 和 `setFacilityOpacity()`,同时支持普通设备模型和 scene-level instanced 设备引用。
|
|
13
|
+
- **docs/mcp** — 补充 Facilities auto instancing 的材质透明度行为、`resetFacilityColor()` 语义,以及多材质 fallback 对颜色/透明度 override 的限制说明。
|
|
14
|
+
|
|
15
|
+
### 修复
|
|
16
|
+
|
|
17
|
+
- **u-manager semantics** — 修复 scene-level instanced Facilities 的点击和指针事件派发:射线命中会映射回楼层下的 `FacilityInstanceObject`,并继续冒泡到所属 `FloorMesh`、`BuildingGroup` 和 `SemanticSceneGroup`。
|
|
18
|
+
- **u-manager semantics** — `FacilityInstancedLayer` 继承 `BaseGroup`,避免 `facilityLayer.visible = false` 后内部 `InstancedMesh` 仍参与射线检测并触发隐藏设备点击事件。
|
|
19
|
+
- **u-manager semantics** — 移除语义设备解析里的 `sid` 检索和注册逻辑;Facilities 只按 `Facility.ID` 以及显式传入的别名进入楼层索引和 `viewer.objectManager`。
|
|
20
|
+
|
|
21
|
+
## 0.0.23
|
|
22
|
+
|
|
23
|
+
### 新增
|
|
24
|
+
|
|
25
|
+
- **u-manager semantics** — `BuildingGroup` 新增 `isolateFloors(floors)`,支持按多个 `FloorMesh` 或楼层下标同时隔离显示多个楼层;`isolateFloor()` 继续兼容单楼层调用,并可接收数组作为便捷写法。
|
|
26
|
+
- **u-manager semantics** — `SemanticLoader` 新增 `Facilities` 解析:从 `Stories[].Facilities` 索引读取顶层设备语义,用 `Facility.ID` 匹配解密后的 `tree_models` 设备节点,沿父级累乘本地矩阵得到设备世界矩阵,加载 3D 设备模型并转换为楼层局部矩阵后挂载到对应 `FloorMesh`。
|
|
27
|
+
- **u-manager semantics** — `FloorMesh` 新增楼层设备检索与统一语义实体 API:`getFacilityById()`、`getFacilityAt()`、`getFacilities()`、`removeFacility()`、`showAllFacilities()`、`hideAllFacilities()`、`getSemanticById()`、`getSemantics()` 和 `getSemanticsByKind('Facilities')`;`BuildingGroup.showAllFacilities()/hideAllFacilities()` 支持批量显示或隐藏整栋建筑内的楼层设备。
|
|
28
|
+
- **u-space MCP** — 文档索引同步楼层 `Facilities` 解析和检索 API,MCP 客户端可检索设备按楼层挂载、`tree_models` 解密匹配、本地矩阵父级累乘和世界坐标转换规则。
|
|
29
|
+
|
|
30
|
+
### 示例与文档
|
|
31
|
+
|
|
32
|
+
- **在线示例** — `examples/importmap.js` 的 CDN fallback 版本更新为 `0.0.23`,部署流程仍会优先按 `package.json` 注入当前版本。
|
|
6
33
|
|
|
7
34
|
## 0.0.21
|
|
8
35
|
|
package/docs/examples-guide.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 运行方式与版本
|
|
6
6
|
|
|
7
|
-
示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1` 或 `
|
|
7
|
+
示例统一通过 `examples/importmap.js` 注入 Import Map。本地通过 `localhost`、`127.0.0.1`、`0.0.0.0` 或 `192.168.x.x` 访问时会加载仓库里的 `../dist/` 构建产物;在线部署或非本地域名访问时会从 jsDelivr 加载当前发布版本 `u-space@0.0.23`。Vercel 文档部署会继续把 `__VERSION__` 占位符替换为 `package.json` 中的版本号,源码里的 `0.0.23` 作为直接托管 `examples/` 时的 fallback。
|
|
8
8
|
|
|
9
9
|
插件示例可以在页面加载 `importmap.js` 前通过 `window.__IMPORTS__` 声明额外依赖。将 `u-space/plugins/<name>` 的值设为 `true` 时,`importmap.js` 会自动在本地和 CDN 路径之间切换。
|
|
10
10
|
|
package/docs/getting-started.md
CHANGED
|
@@ -125,7 +125,7 @@ box.addEventListener('pointerleave', (e) => {
|
|
|
125
125
|
|
|
126
126
|
```typescript
|
|
127
127
|
import { version } from 'u-space';
|
|
128
|
-
console.log(version); // e.g. '0.0.
|
|
128
|
+
console.log(version); // e.g. '0.0.23'
|
|
129
129
|
|
|
130
130
|
// 也可以通过全局变量访问
|
|
131
131
|
console.log(window.__USPACE__.version);
|
package/docs/index.md
CHANGED
|
@@ -52,7 +52,7 @@ features:
|
|
|
52
52
|
| [keyboard-controls](./api-plugin-keyboard-controls) | WASD / 方向键控制相机移动与旋转 |
|
|
53
53
|
| [minimap](./api-plugin-minimap) | 2D 小地图叠加层 |
|
|
54
54
|
| [tiles](./api-plugin-tiles) | ArcGIS 3D 瓦片 / GIS 地球渲染 |
|
|
55
|
-
| [u-manager](./api-plugin-u-manager) |
|
|
55
|
+
| [u-manager](./api-plugin-u-manager) | 场景加载、语义楼层、语义井道、楼层设备、拓扑、动画、属性、视点管理 |
|
|
56
56
|
| [curve-movement](./api-plugin-curve-movement) | 沿样条曲线移动相机或对象 |
|
|
57
57
|
| [tracking-controls](./api-plugin-tracking-controls) | 相机跟随移动目标 |
|
|
58
58
|
| [atmosphere](./api-plugin-atmosphere) | 天空背景、天空环境、太阳/月亮光照与阴影 |
|
package/docs/mcp.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# u-space MCP
|
|
2
2
|
|
|
3
|
-
`u-space-mcp` 是面向 `u-space` 文档的 Model Context Protocol(MCP)服务器。它把当前文档打包成只读 MCP 工具,方便 Mastra、Claude Desktop、Cursor 等 MCP 客户端在回答 `u-space` API、插件和示例问题时直接检索官方文档,包括 `u-manager` 的 `SemanticLoader`、`BuildingGroup`、`FloorMesh` 语义楼层 API
|
|
3
|
+
`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 配置。
|
|
4
4
|
|
|
5
5
|
## 安装与启动
|
|
6
6
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u-space",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"types": "dist/src/index.d.ts",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"docs:build": "vitepress build docs",
|
|
30
30
|
"docs:preview": "vitepress preview docs",
|
|
31
31
|
"docs:deploy": "pnpm docs:build && vercel --prod",
|
|
32
|
-
"publish:mcp": "npm --prefix ./packages/u-space-mcp version patch
|
|
32
|
+
"publish:mcp": "npm --prefix ./packages/u-space-mcp version patch && pnpm --filter u-space-mcp build && npm publish ./packages/u-space-mcp --access public --ignore-scripts",
|
|
33
33
|
"release": "npm version patch && pnpm build && npm publish --access=public"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|