u-space 0.0.7 → 0.0.11

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.
Files changed (43) hide show
  1. package/dist/index.cjs +16 -1
  2. package/dist/index.js +1578 -534
  3. package/dist/plugins/u-manager/index.cjs +21 -21
  4. package/dist/plugins/u-manager/index.js +5 -5
  5. package/dist/src/effects/MaterialEffects.d.ts +23 -0
  6. package/dist/src/index.d.ts +1 -0
  7. package/dist/src/interactions/InteractionManager.d.ts +31 -0
  8. package/dist/src/interactions/Selection.d.ts +77 -0
  9. package/dist/src/interactions/index.d.ts +1 -0
  10. package/dist/src/managers/LightManager.d.ts +101 -0
  11. package/dist/src/managers/ObjectManager.d.ts +33 -1
  12. package/dist/src/managers/SceneManager.d.ts +57 -0
  13. package/dist/src/managers/index.d.ts +2 -0
  14. package/dist/src/objects/ExtrudeMesh.d.ts +1 -1
  15. package/dist/src/objects/Model.d.ts +13 -1
  16. package/dist/src/tools/AnnotationManager.d.ts +104 -0
  17. package/dist/src/tools/ClippingTool.d.ts +96 -0
  18. package/dist/src/tools/MeasureTool.d.ts +80 -0
  19. package/dist/src/tools/index.d.ts +3 -0
  20. package/dist/src/viewers/CameraControls.d.ts +23 -0
  21. package/dist/src/viewers/Viewer.d.ts +52 -1
  22. package/docs/api-camera-controls.md +146 -0
  23. package/docs/api-effects.md +47 -5
  24. package/docs/api-interactions.md +107 -7
  25. package/docs/api-managers.md +181 -0
  26. package/docs/api-objects.md +46 -13
  27. package/docs/api-plugin-atmosphere.md +10 -0
  28. package/docs/api-plugin-curve-movement.md +38 -0
  29. package/docs/api-plugin-keyboard-controls.md +40 -0
  30. package/docs/api-plugin-minimap.md +36 -0
  31. package/docs/api-plugin-object-controls.md +67 -0
  32. package/docs/api-plugin-tiles.md +26 -0
  33. package/docs/api-plugin-topology-drawer.md +74 -0
  34. package/docs/api-plugin-tracking-controls.md +23 -0
  35. package/docs/api-plugin-u-manager.md +123 -0
  36. package/docs/api-tools.md +254 -0
  37. package/docs/api-viewer.md +85 -19
  38. package/docs/changelog.md +105 -0
  39. package/docs/examples-guide.md +104 -0
  40. package/docs/getting-started.md +1 -1
  41. package/docs/index.md +14 -12
  42. package/package.json +2 -2
  43. package/docs/api-plugins.md +0 -449
@@ -98,8 +98,189 @@ viewer.objectManager.removeByName('sedan');
98
98
  viewer.objectManager.removeByType('Model');
99
99
  ```
100
100
 
101
+ ### 显隐控制
102
+
103
+ #### `show(id: string)` / `hide(id: string)`
104
+
105
+ 控制对象的可见性。
106
+
107
+ ```typescript
108
+ viewer.objectManager.hide('car-01');
109
+ viewer.objectManager.show('car-01');
110
+ ```
111
+
112
+ #### `isolate(ids: string[])`
113
+
114
+ 孤立显示:仅显示指定 ID 的对象,隐藏其余所有。
115
+
116
+ ```typescript
117
+ viewer.objectManager.isolate(['car-01', 'car-02']);
118
+ ```
119
+
120
+ #### `showAll()`
121
+
122
+ 恢复显示所有已管理对象。
123
+
124
+ ```typescript
125
+ viewer.objectManager.showAll();
126
+ ```
127
+
128
+ ### 材质操作
129
+
130
+ #### `setOpacity(id: string, opacity: number)`
131
+
132
+ 设置指定对象所有材质的透明度。
133
+
134
+ ```typescript
135
+ viewer.objectManager.setOpacity('building-01', 0.3);
136
+ viewer.objectManager.setOpacity('building-01', 1.0); // 恢复不透明
137
+ ```
138
+
139
+ ### 空间查询
140
+
141
+ #### `getBoundingBox(id?: string)`
142
+
143
+ 获取指定对象的包围盒,不传 `id` 则返回所有已管理对象的包围盒。
144
+
145
+ ```typescript
146
+ const box = viewer.objectManager.getBoundingBox('car-01');
147
+ const allBox = viewer.objectManager.getBoundingBox(); // 全部对象
148
+ ```
149
+
150
+ ### 遍历与过滤
151
+
152
+ #### `forEach(callback)`
153
+
154
+ 遍历所有已管理对象。
155
+
156
+ ```typescript
157
+ viewer.objectManager.forEach((object, ids) => {
158
+ console.log(`对象: ${object.name}, IDs: ${Array.from(ids).join(', ')}`);
159
+ });
160
+ ```
161
+
162
+ #### `filter(predicate)`
163
+
164
+ 按条件过滤对象,返回匹配的数组。
165
+
166
+ ```typescript
167
+ const cars = viewer.objectManager.filter((obj) => obj.name.startsWith('car'));
168
+ ```
169
+
101
170
  ### 工具方法
102
171
 
103
172
  - `getAll()`:返回所有已跟踪对象的 `Set<Object3D>`。
104
173
  - `clear()`:从所有内部映射中移除所有对象。
105
174
  - `size`:返回当前管理器跟踪的唯一对象总数。
175
+
176
+ ---
177
+
178
+ ## SceneManager
179
+
180
+ `SceneManager` 用于管理多个场景的创建、注册、切换和序列化。
181
+
182
+ ```typescript
183
+ import { SceneManager } from 'u-space';
184
+
185
+ const sceneManager = new SceneManager();
186
+ ```
187
+
188
+ ### 方法
189
+
190
+ #### `create(key, options?)`
191
+
192
+ 创建并注册一个新场景。
193
+
194
+ ```typescript
195
+ const scene = sceneManager.create('indoor', { background: 0x333333 });
196
+ ```
197
+
198
+ #### `add(key, scene)` / `get(key)` / `remove(key)`
199
+
200
+ 手动注册、获取或移除场景。
201
+
202
+ ```typescript
203
+ sceneManager.add('outdoor', existingScene);
204
+ const scene = sceneManager.get('outdoor');
205
+ sceneManager.remove('outdoor');
206
+ ```
207
+
208
+ #### `serialize(key)`
209
+
210
+ 将场景元数据序列化为 JSON 快照。
211
+
212
+ ```typescript
213
+ const snapshot = sceneManager.serialize('indoor');
214
+ // { name, background, environmentRotation, children }
215
+ ```
216
+
217
+ #### `keys()` / `size` / `clear()`
218
+
219
+ 列出所有场景 key、获取场景数量或清空。
220
+
221
+ ---
222
+
223
+ ## LightManager
224
+
225
+ `LightManager` 提供灯光的便捷创建、预设和 Helper 可视化。
226
+
227
+ ```typescript
228
+ import { LightManager } from 'u-space';
229
+
230
+ const lightManager = new LightManager(viewer.scene);
231
+ ```
232
+
233
+ ### 灯光创建
234
+
235
+ ```typescript
236
+ lightManager.addAmbient('ambient', { color: 0xffffff, intensity: 0.5 });
237
+ lightManager.addDirectional('sun', { position: { x: 5, y: 10, z: 5 }, castShadow: true });
238
+ lightManager.addPoint('bulb', { position: { x: 0, y: 3, z: 0 }, intensity: 2 });
239
+ lightManager.addSpot('spot', { position: { x: 0, y: 10, z: 0 }, angle: Math.PI / 6 });
240
+ lightManager.addHemisphere('hemi', { skyColor: 0x87ceeb, groundColor: 0x362907 });
241
+ ```
242
+
243
+ ### 灯光预设
244
+
245
+ 一键应用常见场景的灯光配置:
246
+
247
+ ```typescript
248
+ lightManager.applyPreset('indoor'); // 室内:环境光 + 顶部点光源
249
+ lightManager.applyPreset('outdoor'); // 室外:半球光 + 方向光(阳光)
250
+ lightManager.applyPreset('studio'); // 摄影棚:三点布光
251
+ lightManager.applyPreset('warehouse'); // 仓库:多点光源照明
252
+ ```
253
+
254
+ | 预设 | 配置 |
255
+ | :---------- | :-------------------------------------- |
256
+ | `indoor` | 环境光 + 2 个点光源 |
257
+ | `outdoor` | 半球光 + 方向光(带阴影) |
258
+ | `studio` | 环境光 + 主光 + 补光 + 轮廓光 |
259
+ | `warehouse` | 环境光 + 4 个点光源(四角分布) |
260
+
261
+ ### Helper 可视化
262
+
263
+ ```typescript
264
+ lightManager.showHelper('sun'); // 显示单个灯光 Helper(默认 size=5, color=0xff0000)
265
+ lightManager.showHelper('sun', 2, 0x00ff00); // 自定义尺寸和颜色
266
+ lightManager.showAllHelpers(); // 显示所有灯光 Helper
267
+ lightManager.hideHelper('sun'); // 隐藏单个
268
+ lightManager.hideAllHelpers(); // 隐藏所有
269
+ ```
270
+
271
+ #### `showHelper(id, size?, color?)`
272
+
273
+ | 参数 | 类型 | 默认值 | 说明 |
274
+ | :------ | :-------------------- | :---------- | :---------------- |
275
+ | `id` | `string` | — | 灯光 ID。 |
276
+ | `size` | `number` | `5` | Helper 尺寸。 |
277
+ | `color` | `ColorRepresentation` | `0xff0000` | Helper 颜色。 |
278
+
279
+ ### 管理
280
+
281
+ ```typescript
282
+ lightManager.get('sun'); // 获取灯光
283
+ lightManager.remove('sun'); // 移除灯光
284
+ lightManager.removeAll(); // 移除所有
285
+ lightManager.dispose(); // 清理
286
+ ```
@@ -39,31 +39,31 @@ const myModel = new Model();
39
39
  `loadAsync` 方法负责从 URL 加载资产并将其添加到组中。
40
40
 
41
41
  ```typescript
42
- await myModel.loadAsync(options: ModelLoadOptions)
42
+ await myModel.loadAsync(parameters: ModelParameters)
43
43
  ```
44
44
 
45
- #### `ModelLoadOptions`
45
+ #### `ModelParameters`
46
46
 
47
- | 属性 | 类型 | 说明 |
48
- | :----------- | :-------- | :----------------------------------------------------------------------------------------------------------------- |
49
- | `url` | `string` | `.gltf` 或 `.glb` 文件的 URL。 |
50
- | `cache` | `boolean` | (可选)启用内存缓存。若模型已加载过,则直接从内存中获取。默认 `false`。 |
51
- | `persistent` | `boolean` | (可选)使用浏览器 Cache API 启用持久化磁盘缓存,适合较大的模型。默认 `false`。 |
47
+ | 属性 | 类型 | 默认值 | 说明 |
48
+ | :----------- | :-------- | :----- | :-------------------------------------------------------------------------------------- |
49
+ | `url` | `string` | — | `.gltf` 或 `.glb` 文件的 URL。 |
50
+ | `cache` | `boolean` | `true` | 启用内存缓存。若模型已加载过,则直接从内存中获取并克隆。 |
51
+ | `persistent` | `boolean` | `true` | 使用浏览器 Cache API 启用持久化磁盘缓存,适合较大的模型。 |
52
52
 
53
53
  #### 缓存示例
54
54
 
55
55
  ```javascript
56
- // 从网络加载并持久化
56
+ // 默认开启双层缓存,直接加载即可
57
57
  const model1 = new Model();
58
- model1.loadAsync({ url: 'model.glb', persistent: true });
58
+ model1.loadAsync({ url: 'model.glb' });
59
59
 
60
- // 稍后,将从 Cache API 加载
60
+ // 禁用内存缓存(每次都从网络或持久化缓存重新加载)
61
61
  const model2 = new Model();
62
- model2.loadAsync({ url: 'model.glb', persistent: true });
62
+ model2.loadAsync({ url: 'model.glb', cache: false });
63
63
 
64
- // 从内存缓存快速加载
64
+ // 完全禁用缓存
65
65
  const model3 = new Model();
66
- model3.loadAsync({ url: 'model.glb', cache: true, persistent: true });
66
+ model3.loadAsync({ url: 'model.glb', cache: false, persistent: false });
67
67
  ```
68
68
 
69
69
  ### 动画
@@ -124,6 +124,39 @@ viewer.addEventListener('beforeRender', (e) => {
124
124
  });
125
125
  ```
126
126
 
127
+ ### 空间查询
128
+
129
+ #### `getBoundingBox()`
130
+
131
+ 获取模型的轴对齐包围盒(AABB)。
132
+
133
+ ```typescript
134
+ const box = myModel.getBoundingBox();
135
+ const size = box.getSize(new Vector3());
136
+ console.log('模型尺寸:', size);
137
+ ```
138
+
139
+ #### `getCenter()`
140
+
141
+ 获取模型包围盒的中心点。
142
+
143
+ ```typescript
144
+ const center = myModel.getCenter();
145
+ console.log('模型中心:', center);
146
+ ```
147
+
148
+ ### 材质操作
149
+
150
+ #### `setMaterial(material)`
151
+
152
+ 将模型内所有 Mesh 的材质统一替换为指定材质。
153
+
154
+ ```typescript
155
+ import { MeshStandardMaterial } from 'three/webgpu';
156
+
157
+ myModel.setMaterial(new MeshStandardMaterial({ color: 0xff0000 }));
158
+ ```
159
+
127
160
  ### 清除缓存
128
161
 
129
162
  可通过 `Model` 类的静态方法手动清除内部缓存:
@@ -0,0 +1,10 @@
1
+ # atmosphere
2
+
3
+ 天空和大气渲染插件。目前为占位实现,`enable()` / `disable()` / `dispose()` 方法可用,但尚未实现具体功能。
4
+
5
+ ```typescript
6
+ import { Atmosphere } from 'u-space/plugins/atmosphere';
7
+
8
+ const atmosphere = new Atmosphere(viewer);
9
+ atmosphere.enable();
10
+ ```
@@ -0,0 +1,38 @@
1
+ # curve-movement
2
+
3
+ 沿样条路径对相机或对象进行动画。提供两个具体子类:`CurveMovementCamera` 和 `CurveMovementObject`。
4
+
5
+ ```typescript
6
+ import { CurveMovementObject } from 'u-space/plugins/curve-movement';
7
+ import { Vector3 } from 'three/webgpu';
8
+
9
+ const movement = new CurveMovementObject(viewer, myModel);
10
+ movement.setFromPoints([
11
+ new Vector3(0, 0, 0),
12
+ new Vector3(10, 2, 0),
13
+ new Vector3(20, 0, 10),
14
+ ]);
15
+ movement.speed = 0.05; // 每秒进度
16
+ movement.loop = 'repeat'; // 'once' | 'repeat' | 'pingpong'
17
+ movement.autoLookAt = true;
18
+
19
+ movement.play();
20
+ // movement.pause() / movement.resume() / movement.stop()
21
+
22
+ // 监听事件
23
+ movement.addEventListener('update', ({ progress }) => console.log(progress));
24
+ movement.addEventListener('complete', () => console.log('完成'));
25
+ ```
26
+
27
+ **`CurveMovement` 属性:**
28
+
29
+ | 属性 | 类型 | 默认值 | 说明 |
30
+ | :-------------- | :--------------------------------- | :-------- | :----------------------------------- |
31
+ | `path` | `Curve<Vector3> \| null` | `null` | 样条路径。 |
32
+ | `progress` | `number` | `0` | 当前归一化进度(0–1)。 |
33
+ | `speed` | `number` | `0.1` | 每秒进度单位。 |
34
+ | `loop` | `'once' \| 'repeat' \| 'pingpong'` | `'once'` | 循环行为。 |
35
+ | `autoLookAt` | `boolean` | `true` | 朝向路径切线方向。 |
36
+ | `lookAtOffset` | `number` | `0` | Y 轴旋转偏移量(弧度)。 |
37
+ | `positionOffset`| `Vector3` | `(0,0,0)` | 叠加到每个位置上的世界坐标偏移量。 |
38
+ | `direction` | `1 \| -1` | `1` | 当前行进方向。 |
@@ -0,0 +1,40 @@
1
+ # keyboard-controls
2
+
3
+ 为激活相机提供 WASD 或方向键的平移和旋转控制。
4
+
5
+ ```typescript
6
+ import { KeyboardControls, ACTION } from 'u-space/plugins/keyboard-controls';
7
+
8
+ const keyboardControls = new KeyboardControls(viewer);
9
+
10
+ // 可选:自定义移动速度
11
+ keyboardControls.moveDistanceDelta = 0.5;
12
+ keyboardControls.rotateAngleDelta = (Math.PI / 180) * 2;
13
+
14
+ // 激活监听
15
+ keyboardControls.enable();
16
+ // 之后:
17
+ keyboardControls.disable();
18
+ ```
19
+
20
+ **默认按键绑定**(`keyboardControls.keys`):
21
+
22
+ | 按键 | 动作 |
23
+ | :----------- | :------- |
24
+ | `W` | 向前移动 |
25
+ | `S` | 向后移动 |
26
+ | `A` | 向左移动 |
27
+ | `D` | 向右移动 |
28
+ | `Q` | 向上移动 |
29
+ | `E` | 向下移动 |
30
+ | `ArrowLeft` | 向左旋转 |
31
+ | `ArrowRight` | 向右旋转 |
32
+ | `ArrowUp` | 向上旋转 |
33
+ | `ArrowDown` | 向下旋转 |
34
+
35
+ 通过 `ACTION` 常量重新绑定任意按键:
36
+
37
+ ```typescript
38
+ import { ACTION } from 'u-space/plugins/keyboard-controls';
39
+ keyboardControls.keys['Space'] = ACTION.MOVE_UP;
40
+ ```
@@ -0,0 +1,36 @@
1
+ # minimap
2
+
3
+ 生成一个 2D 小地图叠加层,在 3D 场景中跟踪目标对象。渲染到注入 `viewer.el` 的 `<canvas>` 元素中。
4
+
5
+ ```typescript
6
+ import { Minimap } from 'u-space/plugins/minimap';
7
+
8
+ const minimap = new Minimap(viewer);
9
+ minimap.target = myCharacterModel; // 要跟踪并显示的 Object3D
10
+ minimap.setSize(300, 300); // 宽高(像素)
11
+
12
+ // 可选:设置小地图场景样式
13
+ minimap.scene.background = new THREE.Color(0x111111);
14
+
15
+ minimap.enable();
16
+ // 之后:
17
+ minimap.disable();
18
+ minimap.dispose();
19
+ ```
20
+
21
+ **属性:**
22
+
23
+ | 属性 | 类型 | 说明 |
24
+ | :------------ | :-------------------- | :--------------------------------------- |
25
+ | `target` | `Object3D \| null` | 小地图居中显示的对象。 |
26
+ | `scene` | `Scene` | 小地图内部的 Three.js 场景。 |
27
+ | `camera` | `OrthographicCamera` | 正交俯视相机。 |
28
+ | `marker` | `Object3D` | 显示主相机位置/朝向的箭头网格。 |
29
+ | `needsUpdate` | `boolean` | 设置为 `true` 可强制重新渲染小地图。 |
30
+
31
+ **方法:**
32
+
33
+ - `setSize(width, height)` — 调整小地图画布和相机视锥大小。
34
+ - `enable()` — 将画布附加到 `viewer.el` 并开始渲染。
35
+ - `disable()` — 移除画布并停止渲染。
36
+ - `dispose()` — 禁用并清理所有资源。
@@ -0,0 +1,67 @@
1
+ # object-controls
2
+
3
+ 对场景中的 3D 对象进行交互式移动、旋转、缩放操作。继承自 Three.js `TransformControls`,集成了 u-space `Viewer` 生命周期管理。
4
+
5
+ ```typescript
6
+ import { ObjectControls } from 'u-space/plugins/object-controls';
7
+
8
+ const controls = new ObjectControls(viewer, {
9
+ mode: 'translate', // 'translate' | 'rotate' | 'scale',默认 'translate'
10
+ space: 'world', // 'world' | 'local',默认 'world'
11
+ size: 1, // 控件显示大小,默认 1
12
+ });
13
+
14
+ controls.enable();
15
+ controls.attach(myMesh); // 将控件附加到目标对象
16
+
17
+ // 切换模式(直接赋值,继承自 TransformControls)
18
+ controls.mode = 'rotate';
19
+ controls.space = 'local';
20
+
21
+ // 监听变换事件
22
+ controls.addEventListener('objectChange', () => {
23
+ console.log(myMesh.position);
24
+ });
25
+
26
+ controls.addEventListener('dragging-changed', ({ value }) => {
27
+ console.log('拖拽中:', value); // true = 开始,false = 结束
28
+ });
29
+ ```
30
+
31
+ **说明:**
32
+
33
+ - `enable()` 时将 gizmo 加入场景并切换 `frameloop` 为 `'always'`,确保拖拽时连续渲染。
34
+ - 拖拽期间自动挂起 `viewer.controls`(CameraControls)以避免冲突;`disable()` 时无论如何都强制还原相机控制,防止 mid-drag 调用 disable 导致相机卡死。
35
+ - 监听 `viewer` 的 `cameraChange` 事件,`viewer.setCamera()` 切换相机后 gizmo 自动同步,无需手动更新。
36
+
37
+ **构造选项(`ObjectControlsOptions`):**
38
+
39
+ | 选项 | 类型 | 默认值 | 说明 |
40
+ | :------- | :--------------------------------- | :------------ | :--------------- |
41
+ | `mode` | `'translate' \| 'rotate' \| 'scale'` | `'translate'` | 初始变换模式。 |
42
+ | `space` | `'world' \| 'local'` | `'world'` | 初始变换空间。 |
43
+ | `size` | `number` | `1` | gizmo 大小。 |
44
+ | `showX` | `boolean` | `true` | 显示 X 轴手柄。 |
45
+ | `showY` | `boolean` | `true` | 显示 Y 轴手柄。 |
46
+ | `showZ` | `boolean` | `true` | 显示 Z 轴手柄。 |
47
+
48
+ **方法:**
49
+
50
+ | 方法 | 说明 |
51
+ | :---------- | :----------------------------------------------------------- |
52
+ | `enable()` | 将 gizmo 加入场景,切换 frameloop 为 `'always'`。 |
53
+ | `disable()` | 移除 gizmo,还原 frameloop 和 CameraControls。 |
54
+ | `attach(object)` | 将控件附加到指定 Object3D。 |
55
+ | `detach()` | 解除当前附加对象。 |
56
+ | `dispose()` | 完全释放所有资源。 |
57
+
58
+ **属性:**
59
+
60
+ | 属性 | 类型 | 说明 |
61
+ | :--------- | :-------- | :------------------------------------ |
62
+ | `isActive` | `boolean` | 当前是否已调用 `enable()`(只读)。 |
63
+ | `object` | `Object3D \| undefined` | 当前附加的对象(继承自 TransformControls)。 |
64
+ | `mode` | `string` | 当前变换模式,可直接赋值切换。 |
65
+ | `space` | `string` | 当前变换空间,可直接赋值切换。 |
66
+
67
+ > 由于 `ObjectControls` 直接继承 `TransformControls`,所有原生属性(`translationSnap`、`rotationSnap`、`scaleSnap`、`showX/Y/Z` 等)和事件均可直接使用,参考 [Three.js TransformControls 文档](https://threejs.org/docs/#examples/en/controls/TransformControls)。
@@ -0,0 +1,26 @@
1
+ # tiles
2
+
3
+ 提供与 `3d-tiles-renderer` 和地理空间数据的集成。主要导出 `ArcgisTilesRenderer`,可流式加载 ArcGIS Online 3D 瓦片并将地球重新定向到指定地理位置。
4
+
5
+ ```typescript
6
+ import { ArcgisTilesRenderer } from 'u-space/plugins/tiles';
7
+
8
+ const arcgisTilesRenderer = new ArcgisTilesRenderer(viewer);
9
+
10
+ // 设置原点为经度、纬度、高度
11
+ arcgisTilesRenderer.invalidate(120.002269, 30.284849, 4);
12
+
13
+ // 瓦片持续流式加载,使用 always 模式
14
+ viewer.frameloop = 'always';
15
+
16
+ arcgisTilesRenderer.enable();
17
+ ```
18
+
19
+ **方法:**
20
+
21
+ | 方法 | 说明 |
22
+ | :-------------------------- | :--------------------------------------------------------------------------------------------- |
23
+ | `invalidate(lon, lat, alt)` | 将瓦片原点设置为指定的 WGS84 坐标(度)。可多次调用。返回一个取消订阅的函数。 |
24
+ | `enable()` | 将瓦片添加到场景并启动更新循环。 |
25
+ | `disable()` | 从场景中移除瓦片并暂停更新循环。 |
26
+ | `dispose()` | 禁用并完全释放瓦片渲染器。 |
@@ -0,0 +1,74 @@
1
+ # topology-drawer
2
+
3
+ 在 3D 场景中交互式绘制拓扑路径图。点击场景中的任意对象表面放置节点,自动连接成路径;点击空白处则落回不可见的地面平面。事件检测通过 `viewer.interactionManager` 实现(`scene.addEventListener` 冒泡)。
4
+
5
+ ```typescript
6
+ import { TopologyDrawer } from 'u-space/plugins/topology-drawer';
7
+
8
+ const drawer = new TopologyDrawer(viewer, {
9
+ groundY: 0, // 空白区域兜底地面的 Y 坐标,默认 0
10
+ snapRadius: 1.0, // 自动吸附已有节点的世界单位半径,默认 1.0
11
+ nodeRadius: 0.3,
12
+ nodeColor: 0x0088ff,
13
+ edgeRadius: 0.1,
14
+ edgeColor: 0x00ddff,
15
+ previewColor: 0xffff00, // 预览线颜色
16
+ });
17
+
18
+ drawer.enable();
19
+ ```
20
+
21
+ **操作说明:**
22
+
23
+ | 操作 | 效果 |
24
+ | :--- | :--- |
25
+ | 左键点击空白 / 模型表面 | 放置新节点,与上一节点自动连边 |
26
+ | 左键点击已有节点(`snapRadius` 范围内) | 吸附并连接到该节点,不新增节点 |
27
+ | 左键点击已有边 | 切断该边,在点击处插入新节点并重连两端 |
28
+ | 右键 / `Escape` | 结束当前路径链,下次点击开始新路径 |
29
+ | `Ctrl / Cmd + Z` | 撤销最后一步(节点、边或结束路径) |
30
+
31
+ **方法:**
32
+
33
+ | 方法 | 说明 |
34
+ | :--- | :--- |
35
+ | `enable()` | 进入绘制模式,将拓扑与地面平面加入场景。同时自动将 `viewer.interactionManager.pointerMoveEventsEnabled` 置为 `true`(用于预览线跟随光标),并在 `disable()` 时恢复为原值。 |
36
+ | `disable()` | 退出绘制模式,已绘内容仍保留在场景中。恢复 `pointerMoveEventsEnabled` 为调用 `enable()` 前的值。 |
37
+ | `finishPath()` | 结束当前路径链(等同于右键 / Escape)。 |
38
+ | `undo()` | 撤销最后一步操作。 |
39
+ | `clear()` | 清空所有已绘节点、边和路径。 |
40
+ | `exportData()` | 以 JSON 可序列化格式导出当前拓扑数据。 |
41
+ | `importData(data)` | 加载 `exportData()` 返回的数据,替换当前内容。 |
42
+ | `dispose()` | 完全释放所有资源并从场景移除拓扑。 |
43
+
44
+ **属性:**
45
+
46
+ | 属性 | 类型 | 说明 |
47
+ | :--- | :--- | :--- |
48
+ | `topology` | `Topology` | 底层 `Topology` 对象,可进一步访问节点、边和路径方法。 |
49
+
50
+ **导出 / 导入:**
51
+
52
+ ```typescript
53
+ // 导出
54
+ const data = drawer.exportData();
55
+ // data: { nodes: Record<string, {x,y,z}>, edges: Array<{from,to,weight}> }
56
+
57
+ // 导入
58
+ drawer.importData(data);
59
+ ```
60
+
61
+ **结合 `SceneLoader` 在模型表面绘制:**
62
+
63
+ ```typescript
64
+ import { SceneLoader } from 'u-space/plugins/u-manager';
65
+ import { TopologyDrawer } from 'u-space/plugins/topology-drawer';
66
+
67
+ const sceneLoader = new SceneLoader(viewer);
68
+ sceneLoader.setPath('./scenes/my-scene');
69
+ const group = await sceneLoader.loadAsync();
70
+ viewer.scene.add(group);
71
+
72
+ const drawer = new TopologyDrawer(viewer, { snapRadius: 1.0 });
73
+ drawer.enable(); // 可直接在加载的模型表面点击绘制
74
+ ```
@@ -0,0 +1,23 @@
1
+ # tracking-controls
2
+
3
+ 使相机平滑跟随移动的 `Object3D` 目标。
4
+
5
+ ```typescript
6
+ import { TrackingControls } from 'u-space/plugins/tracking-controls';
7
+
8
+ const tracking = new TrackingControls(viewer);
9
+ tracking.target = myMovingObject;
10
+ tracking.type = 'box3'; // 'position'(世界原点)或 'box3'(包围盒中心)
11
+ tracking.offset.set(0, 5, 0); // 相机目标偏移量
12
+
13
+ tracking.enable();
14
+ // tracking.disable();
15
+ ```
16
+
17
+ **属性:**
18
+
19
+ | 属性 | 类型 | 默认值 | 说明 |
20
+ | :------- | :---------------------- | :----------- | :-------------------------------------------------------- |
21
+ | `target` | `Object3D \| null` | `null` | 要跟踪的对象。 |
22
+ | `type` | `'position' \| 'box3'` | `'position'` | 跟踪世界位置还是包围盒中心。 |
23
+ | `offset` | `Vector3` | `(0,0,0)` | 在移动相机前叠加到跟踪位置上的偏移量。 |