u-space 0.0.0-alpha.2 → 0.0.2
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 +104 -76
- package/dist/plugins/object-controls/ObjectControls.d.ts +69 -0
- package/dist/plugins/object-controls/index.cjs +1 -0
- package/dist/plugins/object-controls/index.d.ts +1 -0
- package/dist/plugins/object-controls/index.js +44 -0
- package/dist/plugins/topology-drawer/TopologyDrawer.d.ts +97 -0
- package/dist/plugins/topology-drawer/index.cjs +1 -0
- package/dist/plugins/topology-drawer/index.d.ts +1 -0
- package/dist/plugins/topology-drawer/index.js +182 -0
- package/dist/src/interactions/InteractionEvent.d.ts +1 -1
- package/dist/src/interactions/InteractionManager.d.ts +2 -3
- package/dist/src/objects/Topology.d.ts +20 -1
- package/docs/api-animations.md +23 -23
- package/docs/api-effects.md +41 -41
- package/docs/api-interactions.md +47 -47
- package/docs/api-managers.md +24 -24
- package/docs/api-objects.md +85 -85
- package/docs/api-plugins.md +256 -113
- package/docs/api-viewer.md +45 -45
- package/docs/examples-guide.md +31 -31
- package/docs/getting-started.md +37 -36
- package/package.json +4 -3
package/docs/api-interactions.md
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
# Interactions API
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
`InteractionManager` 提供了一种统一的方式来处理 3D 场景中的用户输入(鼠标、触摸、指针)。它将屏幕空间的射线检测转换为世界空间坐标,并将对应事件直接分发到被命中的 3D 对象上。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
`InteractionManager` 在 `Viewer` 内部自动实例化,可通过 `viewer.interactionManager` 访问。
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## 启用交互事件
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
出于性能考虑,指针移动事件默认可能处于禁用状态。如需悬停和拖拽效果,必须显式开启。
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
-
//
|
|
12
|
+
// 启用鼠标移动事件(如 pointerenter 和 pointerleave)
|
|
13
13
|
viewer.interactionManager.pointerMoveEventsEnabled = true;
|
|
14
14
|
```
|
|
15
15
|
|
|
16
|
-
###
|
|
16
|
+
### 目标对象
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
可以限制射线检测所针对的对象范围。默认值为 `scene.children`(即整个场景的直接子级,含递归嵌套)。
|
|
19
19
|
|
|
20
20
|
```typescript
|
|
21
|
-
//
|
|
22
|
-
viewer.interactionManager.targetObjects = [];
|
|
21
|
+
// 仅检测指定对象
|
|
22
|
+
viewer.interactionManager.targetObjects = [myBox, myModel];
|
|
23
23
|
|
|
24
|
-
//
|
|
25
|
-
|
|
24
|
+
// 恢复默认:检测整个场景
|
|
25
|
+
viewer.interactionManager.targetObjects = viewer.scene.children;
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## 添加事件监听
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
由于 `u-space` 对象(以及继承自 `BaseMesh`、`BaseGroup` 的对象)支持自定义事件,你可以像操作 DOM 元素一样原生地绑定监听器。
|
|
31
31
|
|
|
32
32
|
```typescript
|
|
33
33
|
const myBox = new Mesh(geometry, material);
|
|
34
34
|
viewer.scene.add(myBox);
|
|
35
35
|
|
|
36
|
-
//
|
|
36
|
+
// 直接在 Mesh 或 Model 上绑定监听器
|
|
37
37
|
myBox.addEventListener('click', (eventData) => {
|
|
38
|
-
//
|
|
38
|
+
// 底层指针事件和射线检测数据
|
|
39
39
|
const intersect = eventData.event.intersect;
|
|
40
40
|
|
|
41
|
-
console.log('
|
|
41
|
+
console.log('点击位置:', intersect.point);
|
|
42
42
|
});
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
##
|
|
45
|
+
## 支持的事件类型
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
以下事件类型可在可交互对象上监听:
|
|
48
48
|
|
|
49
|
-
- `click
|
|
50
|
-
- `dblclick
|
|
51
|
-
- `contextmenu
|
|
52
|
-
- `pointerdown
|
|
53
|
-
- `pointerup
|
|
54
|
-
- `pointermove
|
|
55
|
-
- `pointerenter
|
|
56
|
-
- `pointerleave
|
|
49
|
+
- `click`:指针点击对象时触发(过滤:长按或大幅移动后忽略)。
|
|
50
|
+
- `dblclick`:快速双击对象时触发。
|
|
51
|
+
- `rightclick`:右键短按松开时触发(长按或拖拽不触发;浏览器原生上下文菜单已被阻止)。与原生 `contextmenu` 的区别在于,此事件在 `pointerup` 时派发,因此可以正确过滤相机拖拽等操作。
|
|
52
|
+
- `pointerdown`:指针按键在对象上按下时触发。
|
|
53
|
+
- `pointerup`:指针按键在对象上释放时触发。
|
|
54
|
+
- `pointermove`:指针在对象上移动时触发,需要 `pointerMoveEventsEnabled = true`。
|
|
55
|
+
- `pointerenter`:光标进入对象范围时触发,需要 `pointerMoveEventsEnabled = true`。
|
|
56
|
+
- `pointerleave`:光标离开对象范围时触发,需要 `pointerMoveEventsEnabled = true`。
|
|
57
57
|
|
|
58
|
-
###
|
|
58
|
+
### 事件冒泡
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
事件会沿父级链向上冒泡。若要阻止事件继续传播,可调用事件载荷上的 `stopPropagation()`:
|
|
61
61
|
|
|
62
62
|
```typescript
|
|
63
63
|
myObject.addEventListener('click', (e) => {
|
|
@@ -67,42 +67,42 @@ myObject.addEventListener('click', (e) => {
|
|
|
67
67
|
|
|
68
68
|
## `InteractionEvent`
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
传递给所有监听回调的事件对象,位于 `event` 键下。
|
|
71
71
|
|
|
72
|
-
###
|
|
72
|
+
### 属性
|
|
73
73
|
|
|
74
|
-
|
|
|
75
|
-
| :-------------- | :----------------------------------------- |
|
|
76
|
-
| `type` | `InteractionEventType` |
|
|
77
|
-
| `target` | `Object3D` |
|
|
78
|
-
| `currentTarget` | `Object3D` |
|
|
79
|
-
| `intersect` | `Intersection \| null` | Three.js
|
|
80
|
-
| `originalEvent` | `PointerEvent \| MouseEvent` |
|
|
74
|
+
| 属性 | 类型 | 说明 |
|
|
75
|
+
| :-------------- | :----------------------------------------- | :-------------------------------------------------------------------------- |
|
|
76
|
+
| `type` | `InteractionEventType` | 事件类型字符串(如 `'click'`)。 |
|
|
77
|
+
| `target` | `Object3D` | 触发事件的原始 3D 对象(第一个命中点)。 |
|
|
78
|
+
| `currentTarget` | `Object3D` | 冒泡链中当前处理事件的对象。 |
|
|
79
|
+
| `intersect` | `Intersection \| null` | Three.js 射线检测数据:`point`、`face`、`distance`、`uv` 等。 |
|
|
80
|
+
| `originalEvent` | `PointerEvent \| MouseEvent` | 原始 DOM 指针/鼠标事件。 |
|
|
81
81
|
|
|
82
|
-
###
|
|
82
|
+
### 方法
|
|
83
83
|
|
|
84
84
|
#### `stopPropagation()`
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
阻止事件继续向上冒泡。
|
|
87
87
|
|
|
88
88
|
## `InteractionManager` API
|
|
89
89
|
|
|
90
|
-
###
|
|
90
|
+
### 属性
|
|
91
91
|
|
|
92
|
-
|
|
|
93
|
-
|
|
|
94
|
-
| `targetObjects`
|
|
95
|
-
| `pointerMoveEventsEnabled
|
|
92
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
93
|
+
| :------------------------- | :---------------------------- | :------ | :--------------------------------------------------------- |
|
|
94
|
+
| `targetObjects` | `Object3D[]` | `scene.children` | 射线检测的目标对象列表,默认为场景的直接子级。 |
|
|
95
|
+
| `pointerMoveEventsEnabled` | `boolean` | `false` | 启用 `pointermove`、`pointerenter`、`pointerleave` 事件。 |
|
|
96
96
|
|
|
97
|
-
###
|
|
97
|
+
### 方法
|
|
98
98
|
|
|
99
99
|
#### `setCamera(camera)`
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
更新用于射线检测的相机。由 `viewer.setCamera()` 自动调用。
|
|
102
102
|
|
|
103
103
|
#### `dispose()`
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
移除所有 DOM 事件监听,清理内部状态。
|
|
106
106
|
|
|
107
107
|
```typescript
|
|
108
108
|
viewer.interactionManager.dispose();
|
package/docs/api-managers.md
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
# Managers API
|
|
2
2
|
|
|
3
|
-
`u-space`
|
|
3
|
+
`u-space` 使用专用管理器来处理特定领域的逻辑,例如用于缓存和注册 3D 对象的 `ObjectManager`。
|
|
4
4
|
|
|
5
5
|
## ObjectManager
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
`ObjectManager` 提供了一个集中式字典/映射层,让你无需递归遍历 Three.js 场景图,就能通过字符串 ID 或字符串名称轻松检索复杂模型或特定网格。
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
默认实例可通过 `viewer.objectManager` 访问。
|
|
10
10
|
|
|
11
|
-
###
|
|
11
|
+
### 添加对象
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
向管理器添加对象时,必须提供唯一标识符。
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
16
|
const myModel = new Model();
|
|
17
|
-
// ...
|
|
17
|
+
// ... 加载逻辑
|
|
18
18
|
|
|
19
|
-
//
|
|
19
|
+
// 用指定的唯一 ID 添加
|
|
20
20
|
viewer.objectManager.add('my-unique-car-id', myModel);
|
|
21
21
|
|
|
22
|
-
//
|
|
22
|
+
// 一个对象可以注册多个 ID
|
|
23
23
|
viewer.objectManager.add('player-vehicle', myModel);
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
###
|
|
26
|
+
### 检索对象
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
管理器提供快速访问对象的方法。
|
|
29
29
|
|
|
30
30
|
#### `getById(id: string)`
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
精确检索与指定 ID 匹配的一个对象(或 `undefined`)。
|
|
33
33
|
|
|
34
34
|
```typescript
|
|
35
35
|
const car = viewer.objectManager.getById('my-unique-car-id');
|
|
@@ -37,10 +37,10 @@ const car = viewer.objectManager.getById('my-unique-car-id');
|
|
|
37
37
|
|
|
38
38
|
#### `getByName(name: string)`
|
|
39
39
|
|
|
40
|
-
|
|
40
|
+
由于 Three.js 对象可以共享同一个 `.name` 属性,此方法返回一个 `Set<Object3D>`,包含所有与指定名称匹配的已注册对象。
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
|
-
//
|
|
43
|
+
// 假设 myModel.name = 'sedan'
|
|
44
44
|
const sedans = viewer.objectManager.getByName('sedan');
|
|
45
45
|
|
|
46
46
|
sedans.forEach((vehicle) => {
|
|
@@ -50,7 +50,7 @@ sedans.forEach((vehicle) => {
|
|
|
50
50
|
|
|
51
51
|
#### `getByType(type: string)`
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
返回一个 `Set<Object3D>`,包含所有 `object.type` 与指定类型匹配的已注册对象。
|
|
54
54
|
|
|
55
55
|
```typescript
|
|
56
56
|
const models = viewer.objectManager.getByType('Model');
|
|
@@ -58,17 +58,17 @@ const models = viewer.objectManager.getByType('Model');
|
|
|
58
58
|
|
|
59
59
|
#### `getObjectIds(object: Object3D)`
|
|
60
60
|
|
|
61
|
-
|
|
61
|
+
返回给定对象已注册的所有 ID 的 `Set<string>`。
|
|
62
62
|
|
|
63
63
|
```typescript
|
|
64
64
|
const ids = viewer.objectManager.getObjectIds(myModel);
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
###
|
|
67
|
+
### 移除对象
|
|
68
68
|
|
|
69
69
|
#### `remove(object: Object3D)`
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
从所有内部映射中移除该对象及其所有关联 ID。
|
|
72
72
|
|
|
73
73
|
```typescript
|
|
74
74
|
viewer.objectManager.remove(myModel);
|
|
@@ -76,7 +76,7 @@ viewer.objectManager.remove(myModel);
|
|
|
76
76
|
|
|
77
77
|
#### `removeById(id: string)`
|
|
78
78
|
|
|
79
|
-
|
|
79
|
+
移除注册在指定 ID 下的对象。
|
|
80
80
|
|
|
81
81
|
```typescript
|
|
82
82
|
viewer.objectManager.removeById('my-unique-car-id');
|
|
@@ -84,7 +84,7 @@ viewer.objectManager.removeById('my-unique-car-id');
|
|
|
84
84
|
|
|
85
85
|
#### `removeByName(name: string)`
|
|
86
86
|
|
|
87
|
-
|
|
87
|
+
移除所有具有指定 `.name` 的对象。
|
|
88
88
|
|
|
89
89
|
```typescript
|
|
90
90
|
viewer.objectManager.removeByName('sedan');
|
|
@@ -92,14 +92,14 @@ viewer.objectManager.removeByName('sedan');
|
|
|
92
92
|
|
|
93
93
|
#### `removeByType(type: string)`
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
移除所有具有指定 `.type` 的对象。
|
|
96
96
|
|
|
97
97
|
```typescript
|
|
98
98
|
viewer.objectManager.removeByType('Model');
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
-
###
|
|
101
|
+
### 工具方法
|
|
102
102
|
|
|
103
|
-
- `getAll()
|
|
104
|
-
- `clear()
|
|
105
|
-
- `size
|
|
103
|
+
- `getAll()`:返回所有已跟踪对象的 `Set<Object3D>`。
|
|
104
|
+
- `clear()`:从所有内部映射中移除所有对象。
|
|
105
|
+
- `size`:返回当前管理器跟踪的唯一对象总数。
|
package/docs/api-objects.md
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
# Objects API
|
|
2
2
|
|
|
3
|
-
`u-space`
|
|
3
|
+
`u-space` 提供了若干对象封装类,主要扩展自 Three.js 的基础节点,使 3D 资产的操作和加载更加便捷。
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## 基础类
|
|
6
6
|
|
|
7
7
|
### `BaseMesh`
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
继承自 `THREE.Mesh`,`u-space` 中所有基础网格类都继承于此。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
**关键属性:**
|
|
12
12
|
|
|
13
|
-
|
|
|
14
|
-
| :--------------------------- | :-------- |
|
|
15
|
-
| `ignoreInvisibleWhenRaycast` | `boolean` | `true`
|
|
13
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
14
|
+
| :--------------------------- | :-------- | :----- | :------------------------------------------------------------- |
|
|
15
|
+
| `ignoreInvisibleWhenRaycast` | `boolean` | `true` | 为 `true` 时,不可见的网格在射线检测时会被跳过(不参与碰撞)。 |
|
|
16
16
|
|
|
17
17
|
### `BaseGroup`
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
继承自 `THREE.Group`,`Model` 和 `Topology` 均继承于此。
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
**关键属性:**
|
|
22
22
|
|
|
23
|
-
|
|
|
24
|
-
| :--------------------------- | :-------- |
|
|
25
|
-
| `ignoreInvisibleWhenRaycast` | `boolean` | `true`
|
|
23
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
24
|
+
| :--------------------------- | :-------- | :----- | :--------------------------------------------------------------- |
|
|
25
|
+
| `ignoreInvisibleWhenRaycast` | `boolean` | `true` | 为 `true` 时,不可见的组在射线检测时会被跳过(不参与碰撞)。 |
|
|
26
26
|
|
|
27
|
-
##
|
|
27
|
+
## 模型
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
`Model` 类继承自 `BaseGroup`(进而继承自 `THREE.Group`),简化了异步加载 `glb`、`gltf` 等外部 3D 模型的流程,内置多层缓存支持。
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
32
|
import { Model } from 'u-space';
|
|
@@ -34,9 +34,9 @@ import { Model } from 'u-space';
|
|
|
34
34
|
const myModel = new Model();
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
###
|
|
37
|
+
### 加载资产
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
`loadAsync` 方法负责从 URL 加载资产并将其添加到组中。
|
|
40
40
|
|
|
41
41
|
```typescript
|
|
42
42
|
await myModel.loadAsync(options: ModelLoadOptions)
|
|
@@ -44,38 +44,38 @@ await myModel.loadAsync(options: ModelLoadOptions)
|
|
|
44
44
|
|
|
45
45
|
#### `ModelLoadOptions`
|
|
46
46
|
|
|
47
|
-
|
|
|
48
|
-
| :----------- | :-------- |
|
|
49
|
-
| `url` | `string` |
|
|
50
|
-
| `cache` | `boolean` |
|
|
51
|
-
| `persistent` | `boolean` |
|
|
47
|
+
| 属性 | 类型 | 说明 |
|
|
48
|
+
| :----------- | :-------- | :----------------------------------------------------------------------------------------------------------------- |
|
|
49
|
+
| `url` | `string` | `.gltf` 或 `.glb` 文件的 URL。 |
|
|
50
|
+
| `cache` | `boolean` | (可选)启用内存缓存。若模型已加载过,则直接从内存中获取。默认 `false`。 |
|
|
51
|
+
| `persistent` | `boolean` | (可选)使用浏览器 Cache API 启用持久化磁盘缓存,适合较大的模型。默认 `false`。 |
|
|
52
52
|
|
|
53
|
-
####
|
|
53
|
+
#### 缓存示例
|
|
54
54
|
|
|
55
55
|
```javascript
|
|
56
|
-
//
|
|
56
|
+
// 从网络加载并持久化
|
|
57
57
|
const model1 = new Model();
|
|
58
58
|
model1.loadAsync({ url: 'model.glb', persistent: true });
|
|
59
59
|
|
|
60
|
-
//
|
|
60
|
+
// 稍后,将从 Cache API 加载
|
|
61
61
|
const model2 = new Model();
|
|
62
62
|
model2.loadAsync({ url: 'model.glb', persistent: true });
|
|
63
63
|
|
|
64
|
-
//
|
|
64
|
+
// 从内存缓存快速加载
|
|
65
65
|
const model3 = new Model();
|
|
66
66
|
model3.loadAsync({ url: 'model.glb', cache: true, persistent: true });
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
-
###
|
|
69
|
+
### 清除缓存
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
可通过 `Model` 类的静态方法手动清除内部缓存:
|
|
72
72
|
|
|
73
|
-
- `Model.clearMemoryCache()
|
|
74
|
-
- `await Model.clearPersistentCache()
|
|
73
|
+
- `Model.clearMemoryCache()`:清除运行时内存缓存。
|
|
74
|
+
- `await Model.clearPersistentCache()`:完全清除浏览器中 `u-space` 模型的持久化缓存。
|
|
75
75
|
|
|
76
|
-
##
|
|
76
|
+
## 网格
|
|
77
77
|
|
|
78
|
-
`u-space`
|
|
78
|
+
`u-space` 提供了多种精简的网格类,均继承自 `BaseMesh`。所有类默认使用 `MeshStandardNodeMaterial`,构造函数接受 `{ geometryParameters, materialParameters }` 参数,并支持交互事件分发。
|
|
79
79
|
|
|
80
80
|
### `SphereMesh`
|
|
81
81
|
|
|
@@ -90,14 +90,14 @@ const sphere = new SphereMesh({
|
|
|
90
90
|
|
|
91
91
|
**`SphereMeshParameters`**
|
|
92
92
|
|
|
93
|
-
|
|
|
94
|
-
| :-------------------- |
|
|
95
|
-
| `geometryParameters` | `SphereGeometry`
|
|
96
|
-
| `materialParameters` | `MeshStandardNodeMaterialParameters
|
|
93
|
+
| 属性 | 类型 | 说明 |
|
|
94
|
+
| :-------------------- | :----------------------------------- | :----------------------------------------------- |
|
|
95
|
+
| `geometryParameters` | `SphereGeometry` 构造函数参数 | `radius`、`widthSegments`、`heightSegments` 等。 |
|
|
96
|
+
| `materialParameters` | `MeshStandardNodeMaterialParameters` | 标准材质选项(颜色等)。 |
|
|
97
97
|
|
|
98
98
|
### `PlaneMesh`
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
水平平面网格。
|
|
101
101
|
|
|
102
102
|
```typescript
|
|
103
103
|
import { PlaneMesh } from 'u-space';
|
|
@@ -110,7 +110,7 @@ const plane = new PlaneMesh({
|
|
|
110
110
|
|
|
111
111
|
### `CircleMesh`
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
圆形平面网格。
|
|
114
114
|
|
|
115
115
|
```typescript
|
|
116
116
|
import { CircleMesh } from 'u-space';
|
|
@@ -122,7 +122,7 @@ const circle = new CircleMesh({
|
|
|
122
122
|
|
|
123
123
|
### `TubeMesh`
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
沿指定 `Curve<Vector3>` 曲线生成的管道网格。
|
|
126
126
|
|
|
127
127
|
```typescript
|
|
128
128
|
import { TubeMesh } from 'u-space';
|
|
@@ -137,21 +137,21 @@ const tube = new TubeMesh({
|
|
|
137
137
|
|
|
138
138
|
### `ShapeMesh`
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
由 `THREE.Shape` 或 2D 点生成的平面网格。
|
|
141
141
|
|
|
142
142
|
```typescript
|
|
143
143
|
import { ShapeMesh } from 'u-space';
|
|
144
144
|
|
|
145
|
-
//
|
|
145
|
+
// 从显式 Shape 创建
|
|
146
146
|
const mesh = new ShapeMesh({ geometryParameters: { shape: myShape } });
|
|
147
147
|
|
|
148
|
-
//
|
|
148
|
+
// 静态辅助方法:从 x/z 点数组创建
|
|
149
149
|
const mesh2 = ShapeMesh.createFromPoints([{ x: 0, z: 0 }, { x: 5, z: 0 }, { x: 5, z: 5 }]);
|
|
150
150
|
```
|
|
151
151
|
|
|
152
152
|
### `ExtrudeMesh`
|
|
153
153
|
|
|
154
|
-
|
|
154
|
+
由 `THREE.Shape` 或 2D 点拉伸生成的 3D 实体网格。
|
|
155
155
|
|
|
156
156
|
```typescript
|
|
157
157
|
import { ExtrudeMesh } from 'u-space';
|
|
@@ -164,7 +164,7 @@ const solid = new ExtrudeMesh({
|
|
|
164
164
|
materialParameters: { color: 0xff8800 },
|
|
165
165
|
});
|
|
166
166
|
|
|
167
|
-
//
|
|
167
|
+
// 静态辅助方法
|
|
168
168
|
const solid2 = ExtrudeMesh.createFromPoints(
|
|
169
169
|
[{ x: 0, z: 0 }, { x: 5, z: 0 }, { x: 5, z: 5 }],
|
|
170
170
|
{ geometryParameters: { options: { depth: 2, bevelEnabled: false } } }
|
|
@@ -173,20 +173,20 @@ const solid2 = ExtrudeMesh.createFromPoints(
|
|
|
173
173
|
|
|
174
174
|
## Poi
|
|
175
175
|
|
|
176
|
-
`Poi`
|
|
176
|
+
`Poi` 是一个基于 canvas 渲染的公告板(精灵),用于在 3D 场景中放置图标和标签,继承自 `BaseSprite`。
|
|
177
177
|
|
|
178
178
|
```typescript
|
|
179
179
|
import { Poi } from 'u-space';
|
|
180
180
|
|
|
181
181
|
const poi = new Poi({
|
|
182
182
|
img: '/icons/marker.png',
|
|
183
|
-
text: '
|
|
183
|
+
text: '我的位置',
|
|
184
184
|
fontSize: 28,
|
|
185
185
|
color: '#ffffff',
|
|
186
186
|
backgroundColor: 'rgba(0,0,0,0.6)',
|
|
187
187
|
textPosition: 'right',
|
|
188
188
|
});
|
|
189
|
-
await poi.updateAsync(); //
|
|
189
|
+
await poi.updateAsync(); // 渲染 canvas 纹理
|
|
190
190
|
|
|
191
191
|
poi.position.set(10, 5, 10);
|
|
192
192
|
viewer.scene.add(poi);
|
|
@@ -194,37 +194,37 @@ viewer.scene.add(poi);
|
|
|
194
194
|
|
|
195
195
|
### `PoiParameters`
|
|
196
196
|
|
|
197
|
-
|
|
|
198
|
-
| :---------------- | :------------------------------------------ | :----------------------- |
|
|
199
|
-
| `img` | `string \| CanvasImageSource` | `''` |
|
|
200
|
-
| `text` | `string` | `''` |
|
|
201
|
-
| `fontSize` | `number` | `32` |
|
|
202
|
-
| `fontFamily` | `string` | `'Arial'` |
|
|
203
|
-
| `color` | `string` | `'#ffffff'` |
|
|
204
|
-
| `iconSize` | `number` | `64` |
|
|
205
|
-
| `padding` | `number` | `10` |
|
|
206
|
-
| `backgroundColor` | `string` | `'rgba(0, 0, 0, 0.5)'` |
|
|
207
|
-
| `borderRadius` | `number` | `8` |
|
|
208
|
-
| `textPosition` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'right'` |
|
|
209
|
-
|
|
210
|
-
###
|
|
197
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
198
|
+
| :---------------- | :------------------------------------------ | :----------------------- | :--------------------------------- |
|
|
199
|
+
| `img` | `string \| CanvasImageSource` | `''` | 图标图片 URL 或元素。 |
|
|
200
|
+
| `text` | `string` | `''` | 标签文字。 |
|
|
201
|
+
| `fontSize` | `number` | `32` | 字体大小(像素)。 |
|
|
202
|
+
| `fontFamily` | `string` | `'Arial'` | 字体族。 |
|
|
203
|
+
| `color` | `string` | `'#ffffff'` | 文字颜色。 |
|
|
204
|
+
| `iconSize` | `number` | `64` | 图标大小(像素)。 |
|
|
205
|
+
| `padding` | `number` | `10` | 内容四周的内边距。 |
|
|
206
|
+
| `backgroundColor` | `string` | `'rgba(0, 0, 0, 0.5)'` | 背景填充颜色。 |
|
|
207
|
+
| `borderRadius` | `number` | `8` | 背景圆角半径。 |
|
|
208
|
+
| `textPosition` | `'top' \| 'bottom' \| 'left' \| 'right'` | `'right'` | 文字相对图标的位置。 |
|
|
209
|
+
|
|
210
|
+
### 方法
|
|
211
211
|
|
|
212
212
|
#### `updateAsync(parameters?)`
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
使用可选的参数覆盖重新渲染 canvas 纹理。
|
|
215
215
|
|
|
216
216
|
```typescript
|
|
217
|
-
await poi.updateAsync({ text: '
|
|
217
|
+
await poi.updateAsync({ text: '更新后的标签', color: '#ffff00' });
|
|
218
218
|
viewer.render();
|
|
219
219
|
```
|
|
220
220
|
|
|
221
221
|
#### `dispose()`
|
|
222
222
|
|
|
223
|
-
|
|
223
|
+
释放 canvas 纹理和材质。
|
|
224
224
|
|
|
225
225
|
## Topology
|
|
226
226
|
|
|
227
|
-
`Topology`
|
|
227
|
+
`Topology` 是一个带有内置 3D 可视化的图数据结构。它存储节点(位置)和带权重的边,实现了 Dijkstra 最短路径算法,并将图渲染为球体和管道。
|
|
228
228
|
|
|
229
229
|
```typescript
|
|
230
230
|
import { Topology } from 'u-space';
|
|
@@ -243,54 +243,54 @@ topo.addNode('C', new Vector3(5, 0, 5));
|
|
|
243
243
|
topo.addEdge('A', 'B');
|
|
244
244
|
topo.addEdge('B', 'C');
|
|
245
245
|
|
|
246
|
-
topo.renderGraph(); //
|
|
246
|
+
topo.renderGraph(); // 创建球体 + 管道网格
|
|
247
247
|
viewer.scene.add(topo);
|
|
248
248
|
```
|
|
249
249
|
|
|
250
250
|
### `TopologyParameters`
|
|
251
251
|
|
|
252
|
-
|
|
|
253
|
-
| :------------ |
|
|
254
|
-
| `nodeColor` | `ColorRepresentation
|
|
255
|
-
| `nodeRadius` | `number`
|
|
256
|
-
| `edgeColor` | `ColorRepresentation
|
|
257
|
-
| `edgeRadius` | `number`
|
|
258
|
-
| `pathColor` | `ColorRepresentation
|
|
259
|
-
| `pathRadius` | `number`
|
|
252
|
+
| 属性 | 类型 | 默认值 | 说明 |
|
|
253
|
+
| :------------ | :-------------------- | :---------- | :----------------------- |
|
|
254
|
+
| `nodeColor` | `ColorRepresentation` | `0x0000ff` | 节点球体颜色。 |
|
|
255
|
+
| `nodeRadius` | `number` | `0.5` | 节点球体半径。 |
|
|
256
|
+
| `edgeColor` | `ColorRepresentation` | `0x00ff00` | 边管道颜色。 |
|
|
257
|
+
| `edgeRadius` | `number` | `0.1` | 边管道半径。 |
|
|
258
|
+
| `pathColor` | `ColorRepresentation` | `0xff00ff` | 路径可视化颜色。 |
|
|
259
|
+
| `pathRadius` | `number` | `0.2` | 路径管道半径。 |
|
|
260
260
|
|
|
261
|
-
###
|
|
261
|
+
### 方法
|
|
262
262
|
|
|
263
263
|
#### `addNode(id, position)`
|
|
264
264
|
|
|
265
|
-
|
|
265
|
+
向图中添加一个节点。
|
|
266
266
|
|
|
267
267
|
#### `removeNode(id)`
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
移除一个节点及其关联的边。
|
|
270
270
|
|
|
271
271
|
#### `addEdge(from, to, weight?, bidirectional?)`
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
在两个节点之间添加一条边。`weight` 默认为欧氏距离,`bidirectional` 默认为 `true`(双向)。
|
|
274
274
|
|
|
275
275
|
#### `removeEdge(from, to, bidirectional?)`
|
|
276
276
|
|
|
277
|
-
|
|
277
|
+
移除两个节点之间的边。
|
|
278
278
|
|
|
279
279
|
#### `getShortestPath(startId, endId): Vector3[]`
|
|
280
280
|
|
|
281
|
-
|
|
281
|
+
使用 Dijkstra 算法返回最短路径(世界坐标位置数组)。若不存在路径则返回 `[]`。
|
|
282
282
|
|
|
283
283
|
#### `renderGraph()`
|
|
284
284
|
|
|
285
|
-
|
|
285
|
+
根据当前节点和边构建球体/管道场景图。修改图后需调用此方法刷新可视化。
|
|
286
286
|
|
|
287
287
|
#### `clearGraph()`
|
|
288
288
|
|
|
289
|
-
|
|
289
|
+
移除并释放所有图网格。
|
|
290
290
|
|
|
291
291
|
#### `renderPath(points, color?): TubeMesh`
|
|
292
292
|
|
|
293
|
-
|
|
293
|
+
将给定点通过 CatmullRomCurve3 平滑处理后渲染为管道网格。
|
|
294
294
|
|
|
295
295
|
```typescript
|
|
296
296
|
const path = topo.getShortestPath('A', 'C');
|
|
@@ -300,12 +300,12 @@ viewer.render();
|
|
|
300
300
|
|
|
301
301
|
#### `clearPaths()`
|
|
302
302
|
|
|
303
|
-
|
|
303
|
+
移除并释放所有路径网格。
|
|
304
304
|
|
|
305
305
|
#### `getNeighbors(id): Map<string, number> | undefined`
|
|
306
306
|
|
|
307
|
-
|
|
307
|
+
返回节点的邻接表(邻居 ID → 边权重)。
|
|
308
308
|
|
|
309
309
|
#### `dispose()`
|
|
310
310
|
|
|
311
|
-
|
|
311
|
+
清除图和路径网格。
|